From 18f589c9c779c0a6babafdcd9f3308d02b4b9cb3 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Thu, 1 Jul 2021 03:49:30 +0900 Subject: [PATCH 001/297] fix: fix examples of namePrefix --- examples/src/collection.ts | 11 +---------- examples/src/index.ts | 35 +++++++++++++++++++++++++---------- 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/examples/src/collection.ts b/examples/src/collection.ts index 1b132f67..e3d94f0a 100644 --- a/examples/src/collection.ts +++ b/examples/src/collection.ts @@ -88,16 +88,7 @@ const collection_example = async () => { console.log(`\n_id of the JSON document is automatically generated with a specified prefix.`); console.log(pencil); // log: { name: 'pencil', _id: 'item_XXXXXXXXXXXXXXXXXXXXXXXXXX' } - - // Add a prefix to a new root collection whose collectionPath is ''. - const myCollection = new Collection(gitDDB, '', undefined, { namePrefix: 'fruit_' }); - // '/your/path/to/the/example/git-documentdb/db_collection/item_XXXXXXXXXXXXXXXXXXXXXXXXXX.json' is created. - const durianResult = await myCollection.put({ name: 'durian' }); - const durian = await gitDDB.get(durianResult._id); - console.log(`\nJSON document is created under the working directory with a specified prefix`); - console.log(durian); - // log: { name: 'durian', _id: 'fruit_XXXXXXXXXXXXXXXXXXXXXXXXXX' } - + await gitDDB.close(); }; collection_example(); diff --git a/examples/src/index.ts b/examples/src/index.ts index 80020638..b1d4b909 100644 --- a/examples/src/index.ts +++ b/examples/src/index.ts @@ -9,7 +9,7 @@ import { DEFAULT_SYNC_INTERVAL, GitDocumentDB, Err, Sync, Collection } from 'git-documentdb'; const gitddb_example = async () => { - let gitDDB = new GitDocumentDB({ + const gitDDB = new GitDocumentDB({ dbName: 'db01', // Git working directory }); @@ -65,12 +65,26 @@ const gitddb_example = async () => { /** * Use an auto-generated _id */ - const appleResult = await gitDDB.put({ name: 'apple' }); // _id does not exist. - const apple = await gitDDB.get(appleResult._id); - console.log(`\n_id of the JSON document is automatically generated`); - console.log(apple); - // log: { name: 'apple', _id: 'XXXXXXXXXXXXXXXXXXXXXXXXXX' } - + const appleResult = await gitDDB.put({ name: 'apple' }); // _id does not exist. + const apple = await gitDDB.get(appleResult._id); + console.log(`\n_id of the JSON document is automatically generated`); + console.log(apple); + // log: { name: 'apple', _id: 'XXXXXXXXXXXXXXXXXXXXXXXXXX' } + + /** + * Set namePrefix to add a prefix to an auto-generated _id + */ + const gitDDBPrefix = new GitDocumentDB({ + dbName: 'db_prefix', + namePrefix: 'fruit_', + }); + await gitDDBPrefix.open(); + const fruitAppleResult = await gitDDBPrefix.put({ name: 'apple' }); + const fruitApple = await gitDDBPrefix.get(fruitAppleResult._id); + console.log(fruitApple); + // log: { name: 'apple', _id: 'fruit_XXXXXXXXXXXXXXXXXXXXXXXXXX' } + + /** * Revisions * @@ -102,7 +116,7 @@ const gitddb_example = async () => { * - GITDDB_PERSONAL_ACCESS_TOKEN * A personal access token of your GitHub account */ - if (process.env.GITDDB_GITHUB_USER_URL) github_repository = process.env.GITDDB_GITHUB_USER_URL + 'git-documentdb-example.git'; + if (process.env.GITDDB_GITHUB_USER_URL) github_repository = process.env.GITDDB_GITHUB_USER_URL + 'git-documentdb-example.git'; if (process.env.GITDDB_PERSONAL_ACCESS_TOKEN) your_github_personal_access_token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN; let sync: Sync | undefined; @@ -164,13 +178,14 @@ const gitddb_example = async () => { ] */ - if (sync) { + if (sync !== undefined) { console.log('\n# Sync immediately..'); - await sync.trySync(); + await sync.trySync(); } console.log('\n# All the local documents are pushed to the remote repository.'); // Close database await gitDDB.close(); + await gitDDBPrefix.close(); }; gitddb_example(); From 3c5db05f663995109974b1ddf32c93fc552488fe Mon Sep 17 00:00:00 2001 From: sosuisen Date: Thu, 8 Jul 2021 14:31:26 +0900 Subject: [PATCH 002/297] fix: fast-forward does not invoke conflict --- src/remote/sync_worker.ts | 10 +++++----- test/remote/remote_repository.test.ts | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/remote/sync_worker.ts b/src/remote/sync_worker.ts index 8570b87d..1b4367a8 100644 --- a/src/remote/sync_worker.ts +++ b/src/remote/sync_worker.ts @@ -113,11 +113,11 @@ export async function syncWorker ( } else if (distance.ahead === 0 && distance.behind > 0) { newCommitOid = await repos - .mergeBranches(gitDDB.defaultBranch, `origin/${gitDDB.defaultBranch}`) - .catch((res: nodegit.Index) => { - /* returns conflicted index */ conflictedIndex = res; - return undefined; - }); + .mergeBranches(gitDDB.defaultBranch, `origin/${gitDDB.defaultBranch}`); +// .catch((res: nodegit.Index) => { +// /* returns conflicted index */ conflictedIndex = res; +// return undefined; +// }); } else if (distance.ahead > 0 && distance.behind > 0) { newCommitOid = await repos diff --git a/test/remote/remote_repository.test.ts b/test/remote/remote_repository.test.ts index e39e6c59..6370ce48 100644 --- a/test/remote/remote_repository.test.ts +++ b/test/remote/remote_repository.test.ts @@ -660,7 +660,7 @@ maybe(' RemoteRepository', () => { }); // eslint-disable-next-line dot-notation const error = await remoteRepos['_checkPush'](remote, cred).catch(err => err); - if (error instanceof Err.PushConnectionFailedError) { + if (error instanceof Err.PushPermissionDeniedError) { // Notice that it sometimes throw Err.RemoteRepositoryNotFoundError } else { From 7b5dda7efcc52ec7c1fab83d9774d0b47b762c13 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Thu, 8 Jul 2021 14:55:01 +0900 Subject: [PATCH 003/297] fix: judege fast-forward only by distance --- src/remote/sync_worker.ts | 74 +++++++++++++++------------------------ 1 file changed, 29 insertions(+), 45 deletions(-) diff --git a/src/remote/sync_worker.ts b/src/remote/sync_worker.ts index 1b4367a8..9695c01d 100644 --- a/src/remote/sync_worker.ts +++ b/src/remote/sync_worker.ts @@ -112,12 +112,34 @@ export async function syncWorker ( return { action: 'nop' }; } else if (distance.ahead === 0 && distance.behind > 0) { - newCommitOid = await repos - .mergeBranches(gitDDB.defaultBranch, `origin/${gitDDB.defaultBranch}`); -// .catch((res: nodegit.Index) => { -// /* returns conflicted index */ conflictedIndex = res; -// return undefined; -// }); + newCommitOid = await repos.mergeBranches( + gitDDB.defaultBranch, + `origin/${gitDDB.defaultBranch}` + ); + if (newCommitOid instanceof nodegit.Oid) { + newCommitOid = newCommitOid.tostrS(); + } + const localChanges = await getChanges(gitDDB.workingDir, oldCommitOid, newCommitOid!); + + const syncResultFastForwardMerge: SyncResult = { + action: 'fast-forward merge', + changes: { + local: localChanges, + }, + }; + + if (sync.options.includeCommits) { + // Get list of commits which has been merged to local + const commitsFromRemote = await getCommitLogs( + gitDDB.workingDir, + oldRemoteCommitOid, + oldCommitOid + ); + syncResultFastForwardMerge.commits = { + local: commitsFromRemote, + }; + } + return syncResultFastForwardMerge; } else if (distance.ahead > 0 && distance.behind > 0) { newCommitOid = await repos @@ -149,45 +171,7 @@ export async function syncWorker ( if (conflictedIndex === undefined) { // Conflict has not been occurred. - // Exec fast-forward or normal merge. - - // When a local file is removed and the same remote file is removed, - // they cannot be merged by fast-forward. They are merged as usual. - const distanceAgain = await calcDistance( - gitDDB.workingDir, - newCommitOid!, - await git.resolveRef({ - fs, - dir: gitDDB.workingDir, - ref: 'refs/remotes/origin/main', - }) - ); - - if (distanceAgain.ahead === 0) { - const localChanges = await getChanges(gitDDB.workingDir, oldCommitOid, newCommitOid!); - - const syncResultFastForwardMerge: SyncResult = { - action: 'fast-forward merge', - changes: { - local: localChanges, - }, - }; - - if (sync.options.includeCommits) { - // Get list of commits which has been merged to local - const commitsFromRemote = await getCommitLogs( - gitDDB.workingDir, - oldRemoteCommitOid, - oldCommitOid - ); - syncResultFastForwardMerge.commits = { - local: commitsFromRemote, - }; - } - return syncResultFastForwardMerge; - } - - // distance_again.ahead > 0 + // Exec normal merge. // This case is occurred when not fast-forward. // - insert/update a remote file, and insert/update another local file From 7030b43dc93120aed79394c3ab1d4972e7d8a556 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Thu, 8 Jul 2021 16:45:10 +0900 Subject: [PATCH 004/297] fix: rewrite fast-forward by isomorphic-git instead of NodeGit --- src/remote/3way_merge.ts | 16 ++--- src/remote/sync_worker.ts | 32 ++++++++-- src/remote/worker_utils.ts | 105 +++++++++++++++++++++++++++++++-- test/remote/3way_merge.test.ts | 2 +- 4 files changed, 138 insertions(+), 17 deletions(-) diff --git a/src/remote/3way_merge.ts b/src/remote/3way_merge.ts index 1cc3f528..05d49940 100644 --- a/src/remote/3way_merge.ts +++ b/src/remote/3way_merge.ts @@ -157,7 +157,7 @@ export async function threeWayMerge ( // A new file has been inserted on theirs. // Write it to the file. // console.log(' #case 1 - Accept theirs (insert): ' + path); - await writeBlobToFile(gitDDB, fullDocPath, utf8decode(theirs!.blob)); + await writeBlobToFile(gitDDB.workingDir, fullDocPath, utf8decode(theirs!.blob)); await resolvedIndex.addByPath(fullDocPath); } else if (!base && ours && !theirs) { @@ -192,7 +192,7 @@ export async function threeWayMerge ( JSON.parse(utf8decode(theirs!.blob)) ); - await writeBlobToFile(gitDDB, fullDocPath, data); + await writeBlobToFile(gitDDB.workingDir, fullDocPath, data); await resolvedIndex.addByPath(fullDocPath); @@ -215,7 +215,7 @@ export async function threeWayMerge ( JSON.parse(utf8decode(ours!.blob)), JSON.parse(utf8decode(theirs!.blob)) ); - await writeBlobToFile(gitDDB, fullDocPath, data); + await writeBlobToFile(gitDDB.workingDir, fullDocPath, data); await resolvedIndex.addByPath(fullDocPath); @@ -282,7 +282,7 @@ export async function threeWayMerge ( const data = utf8decode(theirs!.blob); - await writeBlobToFile(gitDDB, fullDocPath, data); + await writeBlobToFile(gitDDB.workingDir, fullDocPath, data); await resolvedIndex.addByPath(fullDocPath); } @@ -322,7 +322,7 @@ export async function threeWayMerge ( const data = utf8decode(ours!.blob); - await writeBlobToFile(gitDDB, fullDocPath, data); + await writeBlobToFile(gitDDB.workingDir, fullDocPath, data); await resolvedIndex.addByPath(fullDocPath); } @@ -359,7 +359,7 @@ export async function threeWayMerge ( // Write theirs to the file. // console.log(' #case 14 - Accept theirs (update): ' + path); const data = utf8decode(theirs!.blob); - await writeBlobToFile(gitDDB, fullDocPath, data); + await writeBlobToFile(gitDDB.workingDir, fullDocPath, data); await resolvedIndex.addByPath(fullDocPath); } else if (base.oid === theirs.oid) { @@ -386,7 +386,7 @@ export async function threeWayMerge ( JSON.parse(utf8decode(theirs!.blob)) ); - await writeBlobToFile(gitDDB, fullDocPath, data); + await writeBlobToFile(gitDDB.workingDir, fullDocPath, data); await resolvedIndex.addByPath(fullDocPath); @@ -410,7 +410,7 @@ export async function threeWayMerge ( JSON.parse(utf8decode(theirs!.blob)) ); - await writeBlobToFile(gitDDB, fullDocPath, data); + await writeBlobToFile(gitDDB.workingDir, fullDocPath, data); await resolvedIndex.addByPath(fullDocPath); diff --git a/src/remote/sync_worker.ts b/src/remote/sync_worker.ts index 9695c01d..88e5d933 100644 --- a/src/remote/sync_worker.ts +++ b/src/remote/sync_worker.ts @@ -27,7 +27,13 @@ import { } from '../types'; import { SyncInterface } from '../types_sync'; import { pushWorker } from './push_worker'; -import { calcDistance, getChanges, getCommitLogs, writeBlobToFile } from './worker_utils'; +import { + calcDistance, + getAndWriteLocalChanges, + getChanges, + getCommitLogs, + writeBlobToFile, +} from './worker_utils'; import { threeWayMerge } from './3way_merge'; /** @@ -112,14 +118,29 @@ export async function syncWorker ( return { action: 'nop' }; } else if (distance.ahead === 0 && distance.behind > 0) { + // Fast forward + const mergeResult = await git.merge({ + fs, + dir: gitDDB.workingDir, + ours: gitDDB.defaultBranch, + theirs: 'remotes/origin/' + gitDDB.defaultBranch, + fastForwardOnly: true, + }); + newCommitOid = mergeResult.oid; + /* newCommitOid = await repos.mergeBranches( gitDDB.defaultBranch, `origin/${gitDDB.defaultBranch}` ); - if (newCommitOid instanceof nodegit.Oid) { + if (newCommitOid instanceof nodegit.Oid) { newCommitOid = newCommitOid.tostrS(); } - const localChanges = await getChanges(gitDDB.workingDir, oldCommitOid, newCommitOid!); + */ + const localChanges = await getAndWriteLocalChanges( + gitDDB.workingDir, + oldCommitOid, + newCommitOid! + ); const syncResultFastForwardMerge: SyncResult = { action: 'fast-forward merge', @@ -205,10 +226,13 @@ export async function syncWorker ( const { blob } = await git.readBlob({ fs, dir: gitDDB.workingDir, + /** + * NOTE: Is it true? change.new._id may be correct. + */ oid: change.old._id, }); const data = utf8decode(blob); - await writeBlobToFile(gitDDB, filename, data); + await writeBlobToFile(gitDDB.workingDir, filename, data); await currentIndex.addByPath(filename); } } diff --git a/src/remote/worker_utils.ts b/src/remote/worker_utils.ts index 240f98ac..18c5f313 100644 --- a/src/remote/worker_utils.ts +++ b/src/remote/worker_utils.ts @@ -9,7 +9,7 @@ import nodePath from 'path'; import git, { ReadBlobResult, ReadCommitResult } from 'isomorphic-git'; import fs from 'fs-extra'; -import { normalizeCommit } from '../utils'; +import { normalizeCommit, toSortedJSONString } from '../utils'; import { GIT_DOCUMENTDB_METADATA_DIR, JSON_EXT } from '../const'; import { Err } from '../error'; import { @@ -31,11 +31,11 @@ import { blobToBinary, blobToJsonDoc, blobToText } from '../crud/blob'; * @throws {@link Err.CannotCreateDirectoryError} */ export async function writeBlobToFile ( - gitDDB: GitDDBInterface, + workingDir: string, name: string, - data: string + data: string | Uint8Array ) { - const filePath = nodePath.resolve(gitDDB.workingDir, name); + const filePath = nodePath.resolve(workingDir, name); const dir = nodePath.dirname(filePath); await fs.ensureDir(dir).catch((err: Error) => { return Promise.reject(new Err.CannotCreateDirectoryError(err.message)); @@ -200,6 +200,103 @@ export async function getChanges ( }); } +/** + * Get and write changed files on local + * + * @throws {@link Err.InvalidJsonObjectError} (from getDocument()) + * + * @internal + */ +export async function getAndWriteLocalChanges ( + workingDir: string, + oldCommitOid: string, + newCommitOid: string +) { + return await git.walk({ + fs, + dir: workingDir, + trees: [git.TREE({ ref: oldCommitOid }), git.TREE({ ref: newCommitOid })], + // @ts-ignore + // eslint-disable-next-line complexity + map: async function (fullDocPath, [a, b]) { + // ignore directories + if (fullDocPath === '.') { + return; + } + if (fullDocPath.startsWith(GIT_DOCUMENTDB_METADATA_DIR)) { + return; + } + + const docType: DocType = fullDocPath.endsWith('.json') ? 'json' : 'text'; + if (docType === 'text') { + // TODO: select binary or text by .gitattribtues + } + + const aType = a === null ? undefined : await a.type(); + const bType = b === null ? undefined : await b.type(); + + if (aType === 'tree' || bType === 'tree') { + return; + } + // generate ids + const aOid = a === null ? undefined : await a.oid(); + const bOid = b === null ? undefined : await b.oid(); + + let change: ChangedFile; + if (bOid === undefined && aOid !== undefined) { + change = { + operation: 'delete', + old: await getFatDocFromOid(workingDir, fullDocPath, aOid, docType), + }; + await git.remove({ fs, dir: workingDir, filepath: fullDocPath }); + const path = nodePath.resolve(workingDir, fullDocPath); + await fs.remove(path).catch(() => { + throw new Err.CannotDeleteDataError(); + }); + } + else if (aOid === undefined && bOid !== undefined) { + change = { + operation: 'insert', + new: await getFatDocFromOid(workingDir, fullDocPath, bOid, docType), + }; + if (change.new.type === 'json') { + await writeBlobToFile( + workingDir, + fullDocPath, + toSortedJSONString(change.new.doc) + ); + } + else if (change.new.type === 'text' || change.new.type === 'binary') { + await writeBlobToFile(workingDir, fullDocPath, change.new.doc); + } + await git.add({ fs, dir: workingDir, filepath: fullDocPath }); + } + else if (aOid !== undefined && bOid !== undefined && aOid !== bOid) { + change = { + operation: 'update', + old: await getFatDocFromOid(workingDir, fullDocPath, aOid, docType), + new: await getFatDocFromOid(workingDir, fullDocPath, bOid, docType), + }; + if (change.new.type === 'json') { + await writeBlobToFile( + workingDir, + fullDocPath, + toSortedJSONString(change.new.doc) + ); + } + else if (change.new.type === 'text' || change.new.type === 'binary') { + await writeBlobToFile(workingDir, fullDocPath, change.new.doc); + } + await git.add({ fs, dir: workingDir, filepath: fullDocPath }); + } + else { + return; + } + return change; + }, + }); +} + /** * Get commit logs by walking backward * diff --git a/test/remote/3way_merge.test.ts b/test/remote/3way_merge.test.ts index dd98ecce..d676c47f 100644 --- a/test/remote/3way_merge.test.ts +++ b/test/remote/3way_merge.test.ts @@ -177,7 +177,7 @@ maybe('', () => { expect(getWorkingDirDocs(dbB)).toEqual([jsonB1, jsonA2, jsonB3]); // Sync dbA - const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; + await syncA.trySync(); expect(getWorkingDirDocs(dbA)).toEqual([jsonB1, jsonA2, jsonB3]); await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); From 550f309d022fb90757d111267d1f2a567f8e09be Mon Sep 17 00:00:00 2001 From: sosuisen Date: Thu, 8 Jul 2021 17:32:14 +0900 Subject: [PATCH 005/297] fix: rewrite index operations after merge by isomorphic-git instead of NodeGit --- src/remote/sync_worker.ts | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/remote/sync_worker.ts b/src/remote/sync_worker.ts index 88e5d933..d82e9495 100644 --- a/src/remote/sync_worker.ts +++ b/src/remote/sync_worker.ts @@ -202,15 +202,21 @@ export async function syncWorker ( // - remove a remote file, and remove the same local file // Compare trees before and after merge - const currentIndex = await repos.refreshIndex(); - const localChanges = await getChanges(gitDDB.workingDir, oldCommitOid, newCommitOid!); + // const currentIndex = await repos.refreshIndex(); + + const localChanges = await getAndWriteLocalChanges( + gitDDB.workingDir, + oldCommitOid, + newCommitOid! + ); /** * Repository.mergeBranches does not handle updating and deleting file. * So a file updated/deleted on remote side is not applied to * on both local filesystem and local index. * Change them by hand. */ + /* // Cannot use await in forEach. Use for-of. for (const change of localChanges) { if (change.operation === 'delete') { @@ -226,9 +232,7 @@ export async function syncWorker ( const { blob } = await git.readBlob({ fs, dir: gitDDB.workingDir, - /** - * NOTE: Is it true? change.new._id may be correct. - */ + // NOTE: Is it true? change.new._id may be correct. oid: change.old._id, }); const data = utf8decode(blob); @@ -238,7 +242,7 @@ export async function syncWorker ( } await currentIndex.write(); - +*/ /** * Amend (move HEAD and commit again) */ From 9a9423aee6de4f03c5b77df8d4d8deeaa7743c8f Mon Sep 17 00:00:00 2001 From: sosuisen Date: Thu, 8 Jul 2021 17:33:25 +0900 Subject: [PATCH 006/297] fix: remove commented out code blocks --- src/remote/sync_worker.ts | 46 +-------------------------------------- 1 file changed, 1 insertion(+), 45 deletions(-) diff --git a/src/remote/sync_worker.ts b/src/remote/sync_worker.ts index d82e9495..a48b073a 100644 --- a/src/remote/sync_worker.ts +++ b/src/remote/sync_worker.ts @@ -127,15 +127,7 @@ export async function syncWorker ( fastForwardOnly: true, }); newCommitOid = mergeResult.oid; - /* - newCommitOid = await repos.mergeBranches( - gitDDB.defaultBranch, - `origin/${gitDDB.defaultBranch}` - ); - if (newCommitOid instanceof nodegit.Oid) { - newCommitOid = newCommitOid.tostrS(); - } - */ + const localChanges = await getAndWriteLocalChanges( gitDDB.workingDir, oldCommitOid, @@ -201,48 +193,12 @@ export async function syncWorker ( // - remove a remote file, and insert/update another local file // - remove a remote file, and remove the same local file - // Compare trees before and after merge - - // const currentIndex = await repos.refreshIndex(); - const localChanges = await getAndWriteLocalChanges( gitDDB.workingDir, oldCommitOid, newCommitOid! ); - /** - * Repository.mergeBranches does not handle updating and deleting file. - * So a file updated/deleted on remote side is not applied to - * on both local filesystem and local index. - * Change them by hand. - */ - /* - // Cannot use await in forEach. Use for-of. - for (const change of localChanges) { - if (change.operation === 'delete') { - const filename = change.old._id + JSON_EXT; - const path = nodePath.resolve(repos.workdir(), filename); - await fs.remove(path).catch(() => { - throw new Err.CannotDeleteDataError(); - }); - await currentIndex.removeByPath(filename); - } - else if (change.operation === 'update') { - const filename = change.old._id + JSON_EXT; - const { blob } = await git.readBlob({ - fs, - dir: gitDDB.workingDir, - // NOTE: Is it true? change.new._id may be correct. - oid: change.old._id, - }); - const data = utf8decode(blob); - await writeBlobToFile(gitDDB.workingDir, filename, data); - await currentIndex.addByPath(filename); - } - } - await currentIndex.write(); -*/ /** * Amend (move HEAD and commit again) */ From dc56e582eb43bff62094205b8bb3e674f992ce68 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Thu, 8 Jul 2021 18:21:22 +0900 Subject: [PATCH 007/297] fix: rewrite NoMergeBaseError condition by calcDistance --- src/remote/push_worker.ts | 11 ++++++++++- src/remote/sync_worker.ts | 10 ++++++---- src/remote/worker_utils.ts | 6 ++++++ 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/remote/push_worker.ts b/src/remote/push_worker.ts index 28a233f8..2eb43ee2 100644 --- a/src/remote/push_worker.ts +++ b/src/remote/push_worker.ts @@ -76,7 +76,16 @@ async function validatePushResult ( }); const distance = await calcDistance(gitDDB.workingDir, localCommitOid, remoteCommitOid); - if (distance.behind > 0) { + if (distance.behind === undefined) { + // This will not be occurred. + gitDDB.logger.debug( + CONSOLE_STYLE.bgWhite() + .fgBlack() + .tag()`sync_worker: push failed: cannot get merge base}` + ); + throw new Err.NoMergeBaseFoundError(); + } + else if (distance.behind > 0) { gitDDB.logger.debug( CONSOLE_STYLE.bgWhite() .fgBlack() diff --git a/src/remote/sync_worker.ts b/src/remote/sync_worker.ts index a48b073a..59c22c6b 100644 --- a/src/remote/sync_worker.ts +++ b/src/remote/sync_worker.ts @@ -114,7 +114,10 @@ export async function syncWorker ( let conflictedIndex: nodegit.Index | undefined; let newCommitOid: nodegit.Oid | string | undefined; - if (distance.ahead === 0 && distance.behind === 0) { + if (distance.ahead === undefined || distance.behind === undefined) { + throw new Err.NoMergeBaseFoundError(); + } + else if (distance.ahead === 0 && distance.behind === 0) { return { action: 'nop' }; } else if (distance.ahead === 0 && distance.behind > 0) { @@ -158,13 +161,12 @@ export async function syncWorker ( newCommitOid = await repos .mergeBranches(gitDDB.defaultBranch, `origin/${gitDDB.defaultBranch}`) .catch((res: nodegit.Index) => { - // Exception locks files. Try cleanup - repos.cleanup(); - if (res instanceof Error) { + /* if (res.message.startsWith('no merge base found')) { throw new Err.NoMergeBaseFoundError(); } + */ throw new Err.GitMergeBranchError(res.message); } /* returns conflicted index */ conflictedIndex = res; diff --git a/src/remote/worker_utils.ts b/src/remote/worker_utils.ts index 18c5f313..32308a43 100644 --- a/src/remote/worker_utils.ts +++ b/src/remote/worker_utils.ts @@ -357,6 +357,12 @@ export async function calcDistance ( dir: workingDir, oids: [localCommitOid, remoteCommitOid], }); + if (baseCommitOid === undefined) { + return { + ahead: undefined, + behind: undefined, + }; + } return { ahead: localCommitOid !== baseCommitOid ? 1 : 0, behind: remoteCommitOid !== baseCommitOid ? 1 : 0, From 89b5f6f726be42fa12d9bdb10a352a9f1d62986a Mon Sep 17 00:00:00 2001 From: sosuisen Date: Thu, 8 Jul 2021 19:27:36 +0900 Subject: [PATCH 008/297] fix: replacing fast forward with plumbing commands --- src/remote/sync_worker.ts | 91 ++++++++++++++-------------------- test/remote/3way_merge.test.ts | 1 + 2 files changed, 39 insertions(+), 53 deletions(-) diff --git a/src/remote/sync_worker.ts b/src/remote/sync_worker.ts index 59c22c6b..3fd370db 100644 --- a/src/remote/sync_worker.ts +++ b/src/remote/sync_worker.ts @@ -7,7 +7,6 @@ * found in the LICENSE file in the root directory of gitDDB source tree. */ -import nodePath from 'path'; import nodegit from '@sosuisen/nodegit'; import git from 'isomorphic-git'; import fs from 'fs-extra'; @@ -112,8 +111,6 @@ export async function syncWorker ( // ahead: 1, behind 0 => Push : Local has new commits. Remote has not pushed new commits. // ahead: 1, behind 1 => Merge, may resolve conflict and push: Local has new commits. Remote has pushed new commits. - let conflictedIndex: nodegit.Index | undefined; - let newCommitOid: nodegit.Oid | string | undefined; if (distance.ahead === undefined || distance.behind === undefined) { throw new Err.NoMergeBaseFoundError(); } @@ -122,6 +119,14 @@ export async function syncWorker ( } else if (distance.ahead === 0 && distance.behind > 0) { // Fast forward + await git.writeRef({ + fs, + dir: gitDDB.workingDir, + ref: gitDDB.defaultBranch, + value: oldRemoteCommitOid, + }); + const newCommitOid = oldRemoteCommitOid; + /* const mergeResult = await git.merge({ fs, dir: gitDDB.workingDir, @@ -129,8 +134,8 @@ export async function syncWorker ( theirs: 'remotes/origin/' + gitDDB.defaultBranch, fastForwardOnly: true, }); - newCommitOid = mergeResult.oid; - + const newCommitOid = mergeResult.oid; + */ const localChanges = await getAndWriteLocalChanges( gitDDB.workingDir, oldCommitOid, @@ -157,22 +162,6 @@ export async function syncWorker ( } return syncResultFastForwardMerge; } - else if (distance.ahead > 0 && distance.behind > 0) { - newCommitOid = await repos - .mergeBranches(gitDDB.defaultBranch, `origin/${gitDDB.defaultBranch}`) - .catch((res: nodegit.Index) => { - if (res instanceof Error) { - /* - if (res.message.startsWith('no merge base found')) { - throw new Err.NoMergeBaseFoundError(); - } - */ - throw new Err.GitMergeBranchError(res.message); - } - /* returns conflicted index */ conflictedIndex = res; - return undefined; - }); - } else if (distance.ahead > 0 && distance.behind === 0) { // Push return await pushWorker(gitDDB, sync, taskMetadata, true).catch(err => { @@ -180,11 +169,28 @@ export async function syncWorker ( }); } - if (newCommitOid instanceof nodegit.Oid) { - newCommitOid = newCommitOid.tostrS(); - } + // distance.ahead > 0 && distance.behind > 0 + + const mergeResult = await git + .merge({ + fs, + dir: gitDDB.workingDir, + ours: gitDDB.defaultBranch, + theirs: 'remotes/origin/' + gitDDB.defaultBranch, + author: gitDDB.author, + committer: gitDDB.committer, + message: 'merge', + }) + .catch(e => { + if (e instanceof git.Errors.MergeNotSupportedError) { + // has conflict + return undefined; + } + + throw new Err.GitMergeBranchError(e.message); + }); - if (conflictedIndex === undefined) { + if (mergeResult !== undefined) { // Conflict has not been occurred. // Exec normal merge. @@ -195,30 +201,14 @@ export async function syncWorker ( // - remove a remote file, and insert/update another local file // - remove a remote file, and remove the same local file + const newCommitOid = mergeResult.oid; + const localChanges = await getAndWriteLocalChanges( gitDDB.workingDir, oldCommitOid, newCommitOid! ); - /** - * Amend (move HEAD and commit again) - */ - const newCommit = await git.readCommit({ - fs, - dir: gitDDB.workingDir, - oid: newCommitOid!, - }); - const mergeParents = newCommit.commit.parent; - const amendedNewCommitOid = await git.commit({ - fs, - dir: gitDDB.workingDir, - author: gitDDB.author, - committer: gitDDB.committer, - message: 'merge', - parent: mergeParents, - }); - let localCommits: NormalizedCommit[] | undefined; // Get list of commits which has been added to local @@ -226,7 +216,7 @@ export async function syncWorker ( const amendedNewCommit = await git.readCommit({ fs, dir: gitDDB.workingDir, - oid: amendedNewCommitOid, + oid: newCommitOid!, }); const [baseCommitOid] = await git.findMergeBase({ @@ -289,6 +279,7 @@ export async function syncWorker ( */ const allFileObj: { [key: string]: boolean } = {}; + /* conflictedIndex.entries().forEach((entry: nodegit.IndexEntry) => { const stage = nodegit.Index.entryStage(entry); gitDDB.logger.debug( @@ -301,14 +292,7 @@ export async function syncWorker ( allFileObj[entry.path] = true; }); - /** - * NOTE: - * Index from Repository.mergeBranch, Merge.merge or Merge.commit is in-memory only. - * It cannot be used for commit operations. - * Create a new copy of index for commit. - * Repository#refreshIndex() grabs copy of latest index - * See https://github.com/nodegit/nodegit/blob/master/examples/merge-with-conflicts.js - */ + const resolvedIndex = await repos.refreshIndex(); const acceptedConflicts: AcceptedConflict[] = []; @@ -449,6 +433,7 @@ export async function syncWorker ( remote: syncResultPush.commits!.remote, }; } - return syncResultResolveConflictsAndPush; + */ + return { action: 'nop' }; } diff --git a/test/remote/3way_merge.test.ts b/test/remote/3way_merge.test.ts index d676c47f..90684e6f 100644 --- a/test/remote/3way_merge.test.ts +++ b/test/remote/3way_merge.test.ts @@ -117,6 +117,7 @@ maybe('', () => { conflictResolutionStrategy: 'ours', } ); + // dbB.logLevel = 'trace'; // A puts and pushes const jsonA1 = { _id: '1', name: 'fromA' }; From 4138d9838d91b22c185caa2482e1a13fee73d72d Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 9 Jul 2021 16:43:03 +0900 Subject: [PATCH 009/297] fix: replace fast forward with plumbing commands --- src/remote/sync_worker.ts | 16 ++++------------ test/remote/sync_trysync.test.ts | 33 +++++++++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/src/remote/sync_worker.ts b/src/remote/sync_worker.ts index 3fd370db..b2045577 100644 --- a/src/remote/sync_worker.ts +++ b/src/remote/sync_worker.ts @@ -103,7 +103,7 @@ export async function syncWorker ( const oldRemoteCommitOid = await git.resolveRef({ fs, dir: gitDDB.workingDir, - ref: 'refs/remotes/origin/main', + ref: 'refs/remotes/origin/' + gitDDB.defaultBranch, }); const distance = await calcDistance(gitDDB.workingDir, oldCommitOid, oldRemoteCommitOid); // ahead: 0, behind 0 => Nothing to do: Local does not have new commits. Remote has not pushed new commits. @@ -122,20 +122,12 @@ export async function syncWorker ( await git.writeRef({ fs, dir: gitDDB.workingDir, - ref: gitDDB.defaultBranch, + ref: 'refs/heads/' + gitDDB.defaultBranch, value: oldRemoteCommitOid, + force: true, }); const newCommitOid = oldRemoteCommitOid; - /* - const mergeResult = await git.merge({ - fs, - dir: gitDDB.workingDir, - ours: gitDDB.defaultBranch, - theirs: 'remotes/origin/' + gitDDB.defaultBranch, - fastForwardOnly: true, - }); - const newCommitOid = mergeResult.oid; - */ + const localChanges = await getAndWriteLocalChanges( gitDDB.workingDir, oldCommitOid, diff --git a/test/remote/sync_trysync.test.ts b/test/remote/sync_trysync.test.ts index 8c644cc8..55f67e0c 100644 --- a/test/remote/sync_trysync.test.ts +++ b/test/remote/sync_trysync.test.ts @@ -13,6 +13,7 @@ * These tests create a new repository on GitHub if not exists. */ import path from 'path'; +import git from 'isomorphic-git'; import fs from 'fs-extra'; import expect from 'expect'; import { GitDocumentDB } from '../../src/git_documentdb'; @@ -248,7 +249,7 @@ maybe(': Sync#trySync()', () => { await syncA.tryPush(); // B syncs - const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; + const syncResult1 = (await syncB.trySync()) as SyncResultFastForwardMerge; expect(syncResult1.action).toBe('fast-forward merge'); expect(syncResult1.commits!.local.length).toBe(2); expect(syncResult1.commits!.local[0].oid).toBe(putResult1.commit.oid); @@ -270,6 +271,36 @@ maybe(': Sync#trySync()', () => { await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + // Check HEAD + const headCommitA = await git.resolveRef({ + fs, + dir: dbA.workingDir, + ref: 'HEAD', + }); + expect(headCommitA).toBe(putResult2.commit.oid); + + const headCommitB = await git.resolveRef({ + fs, + dir: dbB.workingDir, + ref: 'HEAD', + }); + expect(headCommitB).toBe(putResult2.commit.oid); + + // Check defaultBranch + const mainBranchA = await git.resolveRef({ + fs, + dir: dbA.workingDir, + ref: 'refs/heads/main', + }); + expect(mainBranchA).toBe(putResult2.commit.oid); + + const mainBranchB = await git.resolveRef({ + fs, + dir: dbB.workingDir, + ref: 'refs/heads/main', + }); + expect(mainBranchB).toBe(putResult2.commit.oid); + await destroyDBs([dbA, dbB]); }); }); From 0267bd8e527979ba38898d7d8020a63fdd05175f Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 9 Jul 2021 19:19:41 +0900 Subject: [PATCH 010/297] fix: implement merge function for case 1 to 5 --- src/error.ts | 9 + src/remote/3way_merge.ts | 351 +++++++++++++++++++++++++++---------- src/remote/push_worker.ts | 9 +- src/remote/sync_worker.ts | 43 +++-- src/remote/worker_utils.ts | 16 +- 5 files changed, 305 insertions(+), 123 deletions(-) diff --git a/src/error.ts b/src/error.ts index af5ed7f0..a63ebdb8 100644 --- a/src/error.ts +++ b/src/error.ts @@ -430,6 +430,15 @@ Current value is '${type}'`); } } + /** + * @public + */ + export class InvalidConflictResolutionStrategyError extends BaseError { + constructor () { + super(`Conflict resolution strategy is invalid.`); + } + } + /** * @public */ diff --git a/src/remote/3way_merge.ts b/src/remote/3way_merge.ts index 05d49940..338227b8 100644 --- a/src/remote/3way_merge.ts +++ b/src/remote/3way_merge.ts @@ -1,6 +1,6 @@ -import nodePath from 'path'; -import nodegit from '@sosuisen/nodegit'; -import git from 'isomorphic-git'; +import nodePath, { basename } from 'path'; +import nodegit, { Oid } from '@sosuisen/nodegit'; +import git, { TREE, TreeEntry, WalkerEntry } from 'isomorphic-git'; import fs from 'fs-extra'; import { DEFAULT_CONFLICT_RESOLUTION_STRATEGY, JSON_EXT } from '../const'; import { Err } from '../error'; @@ -8,6 +8,7 @@ import { AcceptedConflict, ConflictResolutionStrategies, ConflictResolutionStrategyLabels, + Doc, DocType, FatDoc, IJsonPatch, @@ -48,7 +49,10 @@ function getStrategy ( return strategy; } -function getMergedDocument ( +/** + * @throws {@link Err.InvalidConflictResolutionStrategyError} + */ +function getMergedJsonDoc ( jsonDiff: JsonDiff, jsonPatch: IJsonPatch, strategy: ConflictResolutionStrategyLabels, @@ -82,65 +86,191 @@ function getMergedDocument ( ); } else { - result = {}; + throw new Err.InvalidConflictResolutionStrategyError(); } return toSortedJSONString(result); } +/** + * @throws {@link Err.InvalidConflictResolutionStrategyError} + */ +function getMergedTextDoc ( + strategy: ConflictResolutionStrategyLabels, + base: string | undefined, + ours: string, + theirs: string +): string { + if (strategy === 'ours') { + return ours; + } + else if (strategy === 'theirs') { + return theirs; + } + else if (strategy === 'ours-diff') { + // TODO: implement diff and patch + return ours; + } + else if (strategy === 'theirs-diff') { + // TODO: implement diff and patch + return theirs; + } + + throw new Err.InvalidConflictResolutionStrategyError(); +} + +/** + * @throws {@link Err.InvalidConflictResolutionStrategyError} + */ +function getMergedBinaryDoc ( + strategy: ConflictResolutionStrategyLabels, + ours: Uint8Array, + theirs: Uint8Array +): Uint8Array { + if (strategy === 'ours') { + return ours; + } + else if (strategy === 'theirs') { + return theirs; + } + + throw new Err.InvalidConflictResolutionStrategyError(); +} + +/** + * @throws {@link Err.InvalidDocTypeError} + * @throws {@link Err.InvalidConflictResolutionStrategyError} + */ +function getMergedDocument ( + jsonDiff: JsonDiff, + jsonPatch: IJsonPatch, + strategy: ConflictResolutionStrategyLabels, + base: Uint8Array | undefined, + ours: Uint8Array, + theirs: Uint8Array, + docType: DocType +): string | Uint8Array { + if (docType === 'json') { + const oursDoc = JSON.parse(utf8decode(ours)); + const theirsDoc = JSON.parse(utf8decode(theirs)); + let baseDoc: JsonDoc | undefined; + if (base) { + baseDoc = JSON.parse(utf8decode(base)); + } + else { + baseDoc = undefined; + } + return getMergedJsonDoc(jsonDiff, jsonPatch, strategy, baseDoc, oursDoc, theirsDoc); + } + else if (docType === 'text') { + const oursDoc = utf8decode(ours); + const theirsDoc = utf8decode(theirs); + let baseDoc: string | undefined; + if (base) { + baseDoc = utf8decode(base); + } + else { + baseDoc = undefined; + } + return getMergedTextDoc(strategy, baseDoc, oursDoc, theirsDoc); + } + else if (docType === 'binary') { + return getMergedBinaryDoc(strategy, ours, theirs); + } + + throw new Err.InvalidDocTypeError(docType); +} + +export async function merge ( + gitDDB: GitDDBInterface, + sync: SyncInterface, + baseCommitOid: string, + oursCommitOid: string, + theirsCommitOid: string +): Promise<[string, AcceptedConflict[]]> { + const acceptedConflicts: AcceptedConflict[] = []; + + const strategy = sync.options.conflictResolutionStrategy!; + const results = await git.walk({ + fs, + dir: gitDDB.workingDir, + trees: [ + TREE({ ref: baseCommitOid }), + TREE({ ref: oursCommitOid }), + TREE({ ref: theirsCommitOid }), + ], + // @ts-ignore + map: async function (fullDocPath, [base, ours, theirs]) { + const baseType = base === null ? undefined : await base.type(); + const oursType = ours === null ? undefined : await ours.type(); + const theirsType = theirs === null ? undefined : await theirs.type(); + + if (baseType === 'tree' || oursType === 'tree' || theirsType === 'tree') { + return; + } + + const [treeEntry, conflict] = await threeWayMerge( + gitDDB, + sync, + strategy, + fullDocPath, + base, + ours, + theirs + ); + if (conflict !== undefined) { + acceptedConflicts.push(conflict); + } + + return treeEntry; + }, + reduce: async (parent, children) => { + if (!parent) return; + + const entries = children.filter(treeEntry => treeEntry !== undefined); + if (entries.length === 0) return; + + const newTreeOid = await git.writeTree({ fs, dir: gitDDB.workingDir, tree: entries }); + // eslint-disable-next-line require-atomic-updates + parent.oid = newTreeOid; + + return parent; + }, + }); + + const mergeCommitOid = results.oid; + + return [mergeCommitOid, acceptedConflicts]; +} + /** * 3-way merge * * @throws {@link Err.RepositoryNotOpenError} * @throws {@link Err.InvalidConflictStateError} + * + * @throws {@link Err.InvalidDocTypeError} + * @throws {@link Err.InvalidConflictResolutionStrategyError} + * * @throws {@link Err.CannotDeleteDataError} * @throws {@link Err.CannotCreateDirectoryError} (from writeBlobToFile) * @throws {@link Err.InvalidJsonObjectError} (from getFatDocFromData, getFatDocFromReadBlobResult) + * */ // eslint-disable-next-line complexity export async function threeWayMerge ( gitDDB: GitDDBInterface, sync: SyncInterface, conflictResolutionStrategy: ConflictResolutionStrategies, - resolvedIndex: nodegit.Index, fullDocPath: string, - mergeBaseOid: string, - oursCommitOid: string, - theirsCommitOid: string, - acceptedConflicts: AcceptedConflict[] -): Promise { + base: WalkerEntry, + ours: WalkerEntry, + theirs: WalkerEntry +): Promise<[TreeEntry, AcceptedConflict | undefined]> { const repos = gitDDB.repository(); if (repos === undefined) { throw new Err.RepositoryNotOpenError(); } - // Try 3-way merge on the assumption that their is no conflict. - const base = await git - .readBlob({ - fs, - dir: gitDDB.workingDir, - oid: mergeBaseOid, - filepath: fullDocPath, - }) - .catch(() => undefined); - - const ours = await git - .readBlob({ - fs, - dir: gitDDB.workingDir, - oid: oursCommitOid, - filepath: fullDocPath, - }) - .catch(() => undefined); - - const theirs = await git - .readBlob({ - fs, - dir: gitDDB.workingDir, - oid: theirsCommitOid, - filepath: fullDocPath, - }) - .catch(() => undefined); - - const _id = fullDocPath.replace(new RegExp(JSON_EXT + '$'), ''); + const docType: DocType = fullDocPath.endsWith('.json') ? 'json' : 'text'; if (docType === 'text') { // TODO: select binary or text by .gitattribtues @@ -155,79 +285,112 @@ export async function threeWayMerge ( } else if (!base && !ours && theirs) { // A new file has been inserted on theirs. - // Write it to the file. + // Write it to the working directory. // console.log(' #case 1 - Accept theirs (insert): ' + path); - await writeBlobToFile(gitDDB.workingDir, fullDocPath, utf8decode(theirs!.blob)); - await resolvedIndex.addByPath(fullDocPath); + await writeBlobToFile(gitDDB.workingDir, fullDocPath, (await theirs.content())!); + return [ + { + mode: (await theirs.mode()).toString(8), + path: basename(fullDocPath), + oid: await theirs.oid(), + type: 'blob', + }, + undefined, + ]; } else if (!base && ours && !theirs) { // A new file has been inserted on ours. // Just add it to the index. // console.log(' #case 2 - Accept ours (insert): ' + path); - await resolvedIndex.addByPath(fullDocPath); + return [ + { + mode: (await ours.mode()).toString(8), + path: basename(fullDocPath), + oid: await ours.oid(), + type: 'blob', + }, + undefined, + ]; } else if (!base && ours && theirs) { if (ours.oid === theirs.oid) { // The same filenames with exactly the same contents are inserted on both local and remote. // console.log(' #case 3 - Accept both (insert): ' + path); // Jut add it to the index. - await resolvedIndex.addByPath(fullDocPath); + return [ + { + mode: (await ours.mode()).toString(8), + path: basename(fullDocPath), + oid: await ours.oid(), + type: 'blob', + }, + undefined, + ]; } - else { - // ! Conflict - const strategy = await getStrategy( - conflictResolutionStrategy, - getFatDocFromReadBlobResult(fullDocPath, ours, docType), - getFatDocFromReadBlobResult(fullDocPath, theirs, docType) - ); - if (strategy === 'ours' || strategy === 'ours-diff') { - // Just add it to the index. - // console.log(' #case 4 - Conflict. Accept ours (insert): ' + path); - const data = await getMergedDocument( - sync.jsonDiff, - sync.jsonPatch, - strategy, - undefined, - JSON.parse(utf8decode(ours!.blob)), - JSON.parse(utf8decode(theirs!.blob)) - ); - await writeBlobToFile(gitDDB.workingDir, fullDocPath, data); - - await resolvedIndex.addByPath(fullDocPath); + // ! Conflict - const fatDoc: FatDoc = await getFatDocFromData(data, fullDocPath, docType); - - acceptedConflicts.push({ - fatDoc, - strategy: strategy, - operation: strategy === 'ours' ? 'insert' : 'insert-merge', - }); - } - else if (strategy === 'theirs' || strategy === 'theirs-diff') { - // Write theirs to the file. - // console.log(' #case 5 - Conflict. Accept theirs (insert): ' + path); - const data = await getMergedDocument( - sync.jsonDiff, - sync.jsonPatch, - strategy, - undefined, - JSON.parse(utf8decode(ours!.blob)), - JSON.parse(utf8decode(theirs!.blob)) - ); - await writeBlobToFile(gitDDB.workingDir, fullDocPath, data); + const oursData = (await ours.content())!; + const theirsData = (await theirs.content())!; + const oursFatDoc = await getFatDocFromData(oursData, fullDocPath, docType); + const theirsFatDoc = await getFatDocFromData(theirsData, fullDocPath, docType); + const strategy = await getStrategy( + conflictResolutionStrategy, + oursFatDoc, + theirsFatDoc + ); - await resolvedIndex.addByPath(fullDocPath); + let resultFatDoc: FatDoc; + if (strategy === 'ours') { + // Can skip getMergedDocument(). + resultFatDoc = oursFatDoc; + // Can skip writeBlobToFile() + } + else if (strategy === 'theirs') { + // Can skip getMergedDocument(). + resultFatDoc = theirsFatDoc; + await writeBlobToFile(gitDDB.workingDir, fullDocPath, theirsData); + } + else { + // Diff and patch + const data = await getMergedDocument( + sync.jsonDiff, + sync.jsonPatch, + strategy, + undefined, + oursData, + theirsData, + docType + ); + resultFatDoc = await getFatDocFromData(data, fullDocPath, docType); + await writeBlobToFile(gitDDB.workingDir, fullDocPath, data); + } - const fatDoc: FatDoc = await getFatDocFromData(data, fullDocPath, docType); + const acceptedConflict: AcceptedConflict = { + fatDoc: resultFatDoc, + strategy, + operation: strategy.endsWith('-diff') ? 'insert-merge' : 'insert', + }; - acceptedConflicts.push({ - fatDoc, - strategy: strategy, - operation: strategy === 'theirs' ? 'insert' : 'insert-merge', - }); - } + let mode = ''; + if (strategy === 'ours' || strategy === 'ours-diff') { + // console.log(' #case 4 - Conflict. Accept ours (insert): ' + path); + mode = (await ours.mode()).toString(8); + } + else if (strategy === 'theirs' || strategy === 'theirs-diff') { + // console.log(' #case 5 - Conflict. Accept theirs (insert): ' + path); + mode = (await theirs.mode()).toString(8); } + + return [ + { + mode, + path: basename(fullDocPath), + oid: resultFatDoc.fileOid, + type: 'blob', + }, + acceptedConflict, + ]; } else if (base && !ours && !theirs) { // The same files are removed. diff --git a/src/remote/push_worker.ts b/src/remote/push_worker.ts index 2eb43ee2..1f3b7c52 100644 --- a/src/remote/push_worker.ts +++ b/src/remote/push_worker.ts @@ -74,7 +74,14 @@ async function validatePushResult ( dir: gitDDB.workingDir, ref: 'refs/remotes/origin/main', }); - const distance = await calcDistance(gitDDB.workingDir, localCommitOid, remoteCommitOid); + + const [baseCommitOid] = await git.findMergeBase({ + fs, + dir: gitDDB.workingDir, + oids: [localCommitOid, remoteCommitOid], + }); + + const distance = await calcDistance(baseCommitOid, localCommitOid, remoteCommitOid); if (distance.behind === undefined) { // This will not be occurred. diff --git a/src/remote/sync_worker.ts b/src/remote/sync_worker.ts index b2045577..e593e1e1 100644 --- a/src/remote/sync_worker.ts +++ b/src/remote/sync_worker.ts @@ -33,7 +33,7 @@ import { getCommitLogs, writeBlobToFile, } from './worker_utils'; -import { threeWayMerge } from './3way_merge'; +import { merge, threeWayMerge } from './3way_merge'; /** * git fetch @@ -105,7 +105,14 @@ export async function syncWorker ( dir: gitDDB.workingDir, ref: 'refs/remotes/origin/' + gitDDB.defaultBranch, }); - const distance = await calcDistance(gitDDB.workingDir, oldCommitOid, oldRemoteCommitOid); + + const [baseCommitOid] = await git.findMergeBase({ + fs, + dir: gitDDB.workingDir, + oids: [oldCommitOid, oldRemoteCommitOid], + }); + + const distance = await calcDistance(baseCommitOid, oldCommitOid, oldRemoteCommitOid); // ahead: 0, behind 0 => Nothing to do: Local does not have new commits. Remote has not pushed new commits. // ahead: 0, behind 1 => Fast-forward merge : Local does not have new commits. Remote has pushed new commits. // ahead: 1, behind 0 => Push : Local has new commits. Remote has not pushed new commits. @@ -161,8 +168,16 @@ export async function syncWorker ( }); } - // distance.ahead > 0 && distance.behind > 0 + // Merge (distance.ahead > 0 && distance.behind > 0) + const [mergeCommitOid, acceptedConflicts] = await merge( + gitDDB, + sync, + baseCommitOid, + oldCommitOid, + oldRemoteCommitOid + ); + /* const mergeResult = await git .merge({ fs, @@ -181,8 +196,8 @@ export async function syncWorker ( throw new Err.GitMergeBranchError(e.message); }); - - if (mergeResult !== undefined) { +*/ + if (mergeCommitOid !== undefined) { // Conflict has not been occurred. // Exec normal merge. @@ -193,28 +208,20 @@ export async function syncWorker ( // - remove a remote file, and insert/update another local file // - remove a remote file, and remove the same local file - const newCommitOid = mergeResult.oid; - const localChanges = await getAndWriteLocalChanges( gitDDB.workingDir, oldCommitOid, - newCommitOid! + mergeCommitOid! ); let localCommits: NormalizedCommit[] | undefined; // Get list of commits which has been added to local if (sync.options.includeCommits) { - const amendedNewCommit = await git.readCommit({ - fs, - dir: gitDDB.workingDir, - oid: newCommitOid!, - }); - - const [baseCommitOid] = await git.findMergeBase({ + const mergeCommit = await git.readCommit({ fs, dir: gitDDB.workingDir, - oids: [oldCommitOid, oldRemoteCommitOid], + oid: mergeCommitOid!, }); const commitsFromRemote = await getCommitLogs( @@ -223,7 +230,7 @@ export async function syncWorker ( baseCommitOid ); // Add merge commit - localCommits = [...commitsFromRemote, normalizeCommit(amendedNewCommit)]; + localCommits = [...commitsFromRemote, normalizeCommit(mergeCommit)]; } // Need push because it is merged normally. const syncResultPush = await pushWorker(gitDDB, sync, taskMetadata, true).catch( @@ -287,8 +294,6 @@ export async function syncWorker ( const resolvedIndex = await repos.refreshIndex(); - const acceptedConflicts: AcceptedConflict[] = []; - // Try to check conflict for all files in conflicted index. // console.log('3-way merge..'); const [mergeBaseCommitOid] = await git.findMergeBase({ diff --git a/src/remote/worker_utils.ts b/src/remote/worker_utils.ts index 32308a43..d9ea6510 100644 --- a/src/remote/worker_utils.ts +++ b/src/remote/worker_utils.ts @@ -9,7 +9,7 @@ import nodePath from 'path'; import git, { ReadBlobResult, ReadCommitResult } from 'isomorphic-git'; import fs from 'fs-extra'; -import { normalizeCommit, toSortedJSONString } from '../utils'; +import { normalizeCommit, toSortedJSONString, utf8decode } from '../utils'; import { GIT_DOCUMENTDB_METADATA_DIR, JSON_EXT } from '../const'; import { Err } from '../error'; import { @@ -56,7 +56,7 @@ async function getFatDocFromData ( if (docType === 'json') { const _id = fullDocPath.replace(new RegExp(JSON_EXT + '$'), ''); if (typeof data !== 'string') { - throw new Err.InvalidJsonObjectError(_id); + data = utf8decode(data); } try { const jsonDoc = (JSON.parse(data) as unknown) as JsonDoc; @@ -76,6 +76,9 @@ async function getFatDocFromData ( } } else if (docType === 'text') { + if (typeof data !== 'string') { + data = utf8decode(data); + } fatDoc = { name: fullDocPath, fileOid: oid, @@ -347,16 +350,11 @@ export async function getCommitLogs ( /** * Calc distance */ -export async function calcDistance ( - workingDir: string, +export function calcDistance ( + baseCommitOid: string, localCommitOid: string, remoteCommitOid: string ) { - const [baseCommitOid] = await git.findMergeBase({ - fs, - dir: workingDir, - oids: [localCommitOid, remoteCommitOid], - }); if (baseCommitOid === undefined) { return { ahead: undefined, From 50ed7147ad1224e00bc55afd4704113571668384 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sat, 10 Jul 2021 01:52:56 +0900 Subject: [PATCH 011/297] fix: testing 3-way merge case 1-5 --- src/remote/3way_merge.ts | 6 ++++++ test/remote/3way_merge.test.ts | 13 ++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/remote/3way_merge.ts b/src/remote/3way_merge.ts index 338227b8..98466f92 100644 --- a/src/remote/3way_merge.ts +++ b/src/remote/3way_merge.ts @@ -24,6 +24,7 @@ import { import { toSortedJSONString, utf8decode } from '../utils'; import { JsonDiff } from './json_diff'; import { SyncInterface } from '../types_sync'; +import { Logger } from 'tslog'; function getStrategy ( strategy: ConflictResolutionStrategies | undefined, @@ -270,6 +271,7 @@ export async function threeWayMerge ( if (repos === undefined) { throw new Err.RepositoryNotOpenError(); } + console.log(arguments); const docType: DocType = fullDocPath.endsWith('.json') ? 'json' : 'text'; if (docType === 'text') { @@ -392,6 +394,9 @@ export async function threeWayMerge ( acceptedConflict, ]; } + + throw new Err.InvalidConflictStateError('Not implemented'); + /* else if (base && !ours && !theirs) { // The same files are removed. // console.log(' #case 6 - Accept both (delete): ' + path); @@ -587,4 +592,5 @@ export async function threeWayMerge ( } } } + */ } diff --git a/test/remote/3way_merge.test.ts b/test/remote/3way_merge.test.ts index 90684e6f..37531bdf 100644 --- a/test/remote/3way_merge.test.ts +++ b/test/remote/3way_merge.test.ts @@ -14,6 +14,7 @@ */ import path from 'path'; import fs from 'fs-extra'; +import git, { WalkerEntry } from 'isomorphic-git'; import expect from 'expect'; import { Err } from '../../src/error'; import { threeWayMerge } from '../../src/remote/3way_merge'; @@ -88,12 +89,10 @@ maybe('', () => { conflictResolutionStrategy: 'ours', } ); - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResultA1 = await dbA.put(jsonA1); - const commit = putResultA1.commit.oid; - const index = await dbA.repository()?.refreshIndex(); + await expect( - threeWayMerge(dbA, syncA, 'ours-diff', index!, 'foo', commit!, commit!, commit!, []) + // @ts-ignore + threeWayMerge(dbA, syncA, 'ours-diff', 'foo', undefined, undefined, undefined) ).rejects.toThrowError(Err.InvalidConflictStateError); }); @@ -108,7 +107,7 @@ maybe('', () => { * jsonA2: 1 - Accept theirs (insert) * jsonB3: 2 - Accept ours (insert) */ - it('resolves case 1 - Accept theirs (insert), case 2 - Accept ours (insert), case 4 - Conflict. Accept ours (insert)', async () => { + it.only('resolves case 1 - Accept theirs (insert), case 2 - Accept ours (insert), case 4 - Conflict. Accept ours (insert)', async () => { const [dbA, dbB, syncA, syncB] = await createClonedDatabases( remoteURLBase, localDir, @@ -117,7 +116,7 @@ maybe('', () => { conflictResolutionStrategy: 'ours', } ); - // dbB.logLevel = 'trace'; + dbB.logLevel = 'trace'; // A puts and pushes const jsonA1 = { _id: '1', name: 'fromA' }; From df156feaac862573499ad6f01a2b36e88e7b57a0 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sun, 11 Jul 2021 01:43:37 +0900 Subject: [PATCH 012/297] fix: rewrite 3-way merge by using isomorphic-git --- .vscode/launch.json | 2 +- src/remote/3way_merge.ts | 454 ++++++++++++++++++--------------- src/remote/sync_worker.ts | 115 +-------- test/remote/3way_merge.test.ts | 4 +- test/remote_utils.ts | 16 +- 5 files changed, 283 insertions(+), 308 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 06a25ddd..cfc101bc 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,7 +4,7 @@ "type": "pickString", "id": "choice", "description": "select a file", - "options": ["test/collection.test.js"], + "options": ["test/remote/3way_merge.test.js"], }], "configurations": [ { diff --git a/src/remote/3way_merge.ts b/src/remote/3way_merge.ts index 98466f92..3e8b1609 100644 --- a/src/remote/3way_merge.ts +++ b/src/remote/3way_merge.ts @@ -1,6 +1,5 @@ import nodePath, { basename } from 'path'; -import nodegit, { Oid } from '@sosuisen/nodegit'; -import git, { TREE, TreeEntry, WalkerEntry } from 'isomorphic-git'; +import git, { TreeEntry, WalkerEntry } from 'isomorphic-git'; import fs from 'fs-extra'; import { DEFAULT_CONFLICT_RESOLUTION_STRATEGY, JSON_EXT } from '../const'; import { Err } from '../error'; @@ -8,23 +7,16 @@ import { AcceptedConflict, ConflictResolutionStrategies, ConflictResolutionStrategyLabels, - Doc, DocType, FatDoc, IJsonPatch, JsonDoc, } from '../types'; import { GitDDBInterface } from '../types_gitddb'; -import { - getFatDocFromData, - getFatDocFromOid, - getFatDocFromReadBlobResult, - writeBlobToFile, -} from './worker_utils'; +import { getFatDocFromData, writeBlobToFile } from './worker_utils'; import { toSortedJSONString, utf8decode } from '../utils'; import { JsonDiff } from './json_diff'; import { SyncInterface } from '../types_sync'; -import { Logger } from 'tslog'; function getStrategy ( strategy: ConflictResolutionStrategies | undefined, @@ -195,18 +187,40 @@ export async function merge ( fs, dir: gitDDB.workingDir, trees: [ - TREE({ ref: baseCommitOid }), - TREE({ ref: oursCommitOid }), - TREE({ ref: theirsCommitOid }), + git.TREE({ ref: baseCommitOid }), + git.TREE({ ref: oursCommitOid }), + git.TREE({ ref: theirsCommitOid }), ], // @ts-ignore map: async function (fullDocPath, [base, ours, theirs]) { const baseType = base === null ? undefined : await base.type(); + if (baseType === 'tree') { + return { + mode: (await base.mode()).toString(8), + path: basename(fullDocPath), + oid: await base.oid(), + type: await base.type(), + }; + } + const oursType = ours === null ? undefined : await ours.type(); - const theirsType = theirs === null ? undefined : await theirs.type(); + if (oursType === 'tree') { + return { + mode: (await ours.mode()).toString(8), + path: basename(fullDocPath), + oid: await ours.oid(), + type: await ours.type(), + }; + } - if (baseType === 'tree' || oursType === 'tree' || theirsType === 'tree') { - return; + const theirsType = theirs === null ? undefined : await theirs.type(); + if (theirsType === 'tree') { + return { + mode: (await theirs.mode()).toString(8), + path: basename(fullDocPath), + oid: await theirs.oid(), + type: await theirs.type(), + }; } const [treeEntry, conflict] = await threeWayMerge( @@ -222,25 +236,32 @@ export async function merge ( acceptedConflicts.push(conflict); } + if (treeEntry === undefined) { + return; + } return treeEntry; }, reduce: async (parent, children) => { if (!parent) return; - const entries = children.filter(treeEntry => treeEntry !== undefined); - if (entries.length === 0) return; - - const newTreeOid = await git.writeTree({ fs, dir: gitDDB.workingDir, tree: entries }); - // eslint-disable-next-line require-atomic-updates - parent.oid = newTreeOid; + if (parent.type === 'tree') { + if (children.length === 0) return; + const newTreeOid = await git.writeTree({ + fs, + dir: gitDDB.workingDir, + tree: children, + }); + // eslint-disable-next-line require-atomic-updates + parent.oid = newTreeOid; + } return parent; }, }); - const mergeCommitOid = results.oid; + const mergedTreeOid = results.oid; - return [mergeCommitOid, acceptedConflicts]; + return [mergedTreeOid, acceptedConflicts]; } /** @@ -266,12 +287,11 @@ export async function threeWayMerge ( base: WalkerEntry, ours: WalkerEntry, theirs: WalkerEntry -): Promise<[TreeEntry, AcceptedConflict | undefined]> { +): Promise<[TreeEntry | undefined, AcceptedConflict | undefined]> { const repos = gitDDB.repository(); if (repos === undefined) { throw new Err.RepositoryNotOpenError(); } - console.log(arguments); const docType: DocType = fullDocPath.endsWith('.json') ? 'json' : 'text'; if (docType === 'text') { @@ -288,8 +308,9 @@ export async function threeWayMerge ( else if (!base && !ours && theirs) { // A new file has been inserted on theirs. // Write it to the working directory. - // console.log(' #case 1 - Accept theirs (insert): ' + path); + // console.log(' #case 1 - Accept theirs (insert): ' + fullDocPath); await writeBlobToFile(gitDDB.workingDir, fullDocPath, (await theirs.content())!); + await git.add({ fs, dir: gitDDB.workingDir, filepath: fullDocPath }); return [ { mode: (await theirs.mode()).toString(8), @@ -303,7 +324,7 @@ export async function threeWayMerge ( else if (!base && ours && !theirs) { // A new file has been inserted on ours. // Just add it to the index. - // console.log(' #case 2 - Accept ours (insert): ' + path); + // console.log(' #case 2 - Accept ours (insert): ' + fullDocPath); return [ { mode: (await ours.mode()).toString(8), @@ -315,15 +336,17 @@ export async function threeWayMerge ( ]; } else if (!base && ours && theirs) { - if (ours.oid === theirs.oid) { + const oursOid = await ours.oid(); + const theirsOid = await theirs.oid(); + if (oursOid === theirsOid) { // The same filenames with exactly the same contents are inserted on both local and remote. - // console.log(' #case 3 - Accept both (insert): ' + path); + // console.log(' #case 3 - Accept both (insert): ' + fullDocPath); // Jut add it to the index. return [ { mode: (await ours.mode()).toString(8), path: basename(fullDocPath), - oid: await ours.oid(), + oid: oursOid, type: 'blob', }, undefined, @@ -352,6 +375,7 @@ export async function threeWayMerge ( // Can skip getMergedDocument(). resultFatDoc = theirsFatDoc; await writeBlobToFile(gitDDB.workingDir, fullDocPath, theirsData); + await git.add({ fs, dir: gitDDB.workingDir, filepath: fullDocPath }); } else { // Diff and patch @@ -366,6 +390,7 @@ export async function threeWayMerge ( ); resultFatDoc = await getFatDocFromData(data, fullDocPath, docType); await writeBlobToFile(gitDDB.workingDir, fullDocPath, data); + await git.add({ fs, dir: gitDDB.workingDir, filepath: fullDocPath }); } const acceptedConflict: AcceptedConflict = { @@ -376,11 +401,11 @@ export async function threeWayMerge ( let mode = ''; if (strategy === 'ours' || strategy === 'ours-diff') { - // console.log(' #case 4 - Conflict. Accept ours (insert): ' + path); + // console.log(' #case 4 - Conflict. Accept ours (insert): ' + fullDocPath); mode = (await ours.mode()).toString(8); } else if (strategy === 'theirs' || strategy === 'theirs-diff') { - // console.log(' #case 5 - Conflict. Accept theirs (insert): ' + path); + // console.log(' #case 5 - Conflict. Accept theirs (insert): ' + fullDocPath); mode = (await theirs.mode()).toString(8); } @@ -394,203 +419,232 @@ export async function threeWayMerge ( acceptedConflict, ]; } - - throw new Err.InvalidConflictStateError('Not implemented'); - /* else if (base && !ours && !theirs) { // The same files are removed. - // console.log(' #case 6 - Accept both (delete): ' + path); - await resolvedIndex.removeByPath(fullDocPath); + // console.log(' #case 6 - Accept both (delete): ' + fullDocPath); + + return [undefined, undefined]; } else if (base && !ours && theirs) { - if (base.oid === theirs.oid) { + const baseOid = await base.oid(); + const theirsOid = await theirs.oid(); + + if (baseOid === theirsOid) { // A file has been removed on ours. - // console.log(' #case 7 - Accept ours (delete): ' + path); - await resolvedIndex.removeByPath(fullDocPath); + // console.log(' #case 7 - Accept ours (delete): ' + fullDocPath); + + return [undefined, undefined]; } - else { - // ! Conflict - const strategy = await getStrategy( - conflictResolutionStrategy, - undefined, - getFatDocFromReadBlobResult(fullDocPath, theirs, docType) - ); - if (strategy === 'ours' || strategy === 'ours-diff') { - // Just add it to the index. - // console.log(' #case 8 - Conflict. Accept ours (delete): ' + path); - const fatDoc: FatDoc = await getFatDocFromOid( - gitDDB.workingDir, - fullDocPath, - base.oid, - docType - ); - - acceptedConflicts.push({ - fatDoc, - strategy: strategy, - operation: 'delete', - }); - await resolvedIndex.removeByPath(fullDocPath); - } - else if (strategy === 'theirs' || strategy === 'theirs-diff') { - // Write theirs to the file. - // console.log(' #case 9 - Conflict. Accept theirs (update): ' + path); - const fatDoc: FatDoc = await getFatDocFromOid( - gitDDB.workingDir, - fullDocPath, - theirs.oid, - docType - ); - - acceptedConflicts.push({ - fatDoc, - strategy: strategy, - operation: 'update', - }); - const data = utf8decode(theirs!.blob); + // ! Conflict - await writeBlobToFile(gitDDB.workingDir, fullDocPath, data); + const theirsData = (await theirs.content())!; + const theirsFatDoc = await getFatDocFromData(theirsData, fullDocPath, docType); + const strategy = await getStrategy(conflictResolutionStrategy, undefined, theirsFatDoc); - await resolvedIndex.addByPath(fullDocPath); - } + if (strategy === 'ours' || strategy === 'ours-diff') { + // Just add it to the index. + // console.log(' #case 8 - Conflict. Accept ours (delete): ' + fullDocPath); + const baseData = (await base.content())!; + const baseFatDoc = await getFatDocFromData(baseData, fullDocPath, docType); + const acceptedConflict: AcceptedConflict = { + fatDoc: baseFatDoc, + strategy: strategy, + operation: 'delete', + }; + return [undefined, acceptedConflict]; + } + else if (strategy === 'theirs' || strategy === 'theirs-diff') { + // Write theirs to the file. + // console.log(' #case 9 - Conflict. Accept theirs (update): ' + fullDocPath); + const acceptedConflict: AcceptedConflict = { + fatDoc: theirsFatDoc, + strategy: strategy, + operation: 'update', + }; + await writeBlobToFile(gitDDB.workingDir, fullDocPath, theirsData); + await git.add({ fs, dir: gitDDB.workingDir, filepath: fullDocPath }); + return [ + { + mode: (await theirs.mode()).toString(8), + path: basename(fullDocPath), + oid: theirsFatDoc.fileOid, + type: 'blob', + }, + acceptedConflict, + ]; } } else if (base && ours && !theirs) { - if (base.oid === ours.oid) { + const baseOid = await base.oid(); + const oursOid = await ours.oid(); + + if (baseOid === oursOid) { // A file has been removed on theirs. - // console.log(' #case 10 - Accept theirs (delete): ' + path); + // console.log(' #case 10 - Accept theirs (delete): ' + fullDocPath); await fs.remove(nodePath.resolve(repos.workdir(), fullDocPath)).catch(() => { throw new Err.CannotDeleteDataError(); }); - await resolvedIndex.removeByPath(fullDocPath); + await git.remove({ fs, dir: gitDDB.workingDir, filepath: fullDocPath }); + return [undefined, undefined]; } - else { - // ! Conflict - const strategy = await getStrategy( - conflictResolutionStrategy, - getFatDocFromReadBlobResult(fullDocPath, ours, docType), - undefined - ); - if (strategy === 'ours' || strategy === 'ours-diff') { - // Just add to the index. - // console.log(' #case 11 - Conflict. Accept ours (update): ' + path); - const fatDoc: FatDoc = await getFatDocFromOid( - gitDDB.workingDir, - fullDocPath, - ours.oid, - docType - ); - - acceptedConflicts.push({ - fatDoc, - strategy: strategy, - operation: 'update', - }); - const data = utf8decode(ours!.blob); + // ! Conflict - await writeBlobToFile(gitDDB.workingDir, fullDocPath, data); + const oursData = (await ours.content())!; + const oursFatDoc = await getFatDocFromData(oursData, fullDocPath, docType); + const strategy = await getStrategy(conflictResolutionStrategy, oursFatDoc, undefined); - await resolvedIndex.addByPath(fullDocPath); - } - else if (strategy === 'theirs' || strategy === 'theirs-diff') { - // Remove file - // console.log(' #case 12 - Conflict. Accept theirs (delete): ' + path); - const fatDoc: FatDoc = await getFatDocFromOid( - gitDDB.workingDir, - fullDocPath, - base.oid, - docType - ); - - acceptedConflicts.push({ - fatDoc, - strategy: strategy, - operation: 'delete', - }); - await fs.remove(nodePath.resolve(repos.workdir(), fullDocPath)).catch(() => { - throw new Err.CannotDeleteDataError(); - }); - await resolvedIndex.removeByPath(fullDocPath); - } + if (strategy === 'ours' || strategy === 'ours-diff') { + // Just add to the index. + // console.log(' #case 11 - Conflict. Accept ours (update): ' + fullDocPath); + const acceptedConflict: AcceptedConflict = { + fatDoc: oursFatDoc, + strategy: strategy, + operation: 'update', + }; + await writeBlobToFile(gitDDB.workingDir, fullDocPath, oursData); + await git.add({ fs, dir: gitDDB.workingDir, filepath: fullDocPath }); + return [ + { + mode: (await ours.mode()).toString(8), + path: basename(fullDocPath), + oid: oursFatDoc.fileOid, + type: 'blob', + }, + acceptedConflict, + ]; + } + else if (strategy === 'theirs' || strategy === 'theirs-diff') { + // Remove file + // console.log(' #case 12 - Conflict. Accept theirs (delete): ' + fullDocPath); + const baseData = (await base.content())!; + const baseFatDoc = await getFatDocFromData(baseData, fullDocPath, docType); + const acceptedConflicts: AcceptedConflict = { + fatDoc: baseFatDoc, + strategy: strategy, + operation: 'delete', + }; + await fs.remove(nodePath.resolve(repos.workdir(), fullDocPath)).catch(() => { + throw new Err.CannotDeleteDataError(); + }); + await git.remove({ fs, dir: gitDDB.workingDir, filepath: fullDocPath }); + return [undefined, acceptedConflicts]; } } else if (base && ours && theirs) { - if (ours.oid === theirs.oid) { + const baseOid = await base.oid(); + const oursOid = await ours.oid(); + const theirsOid = await theirs.oid(); + + if (oursOid === theirsOid) { // The same filenames with exactly the same contents are inserted on both local and remote. // Jut add it to the index. - // console.log(' #case 13 - Accept both (update): ' + path); - await resolvedIndex.addByPath(fullDocPath); + // console.log(' #case 13 - Accept both (update): ' + fullDocPath); + return [ + { + // TODO: check whether mode is the same. + mode: (await ours.mode()).toString(8), + path: basename(fullDocPath), + oid: oursOid, + type: 'blob', + }, + undefined, + ]; } - else if (base.oid === ours.oid) { + else if (baseOid === oursOid) { // Write theirs to the file. - // console.log(' #case 14 - Accept theirs (update): ' + path); - const data = utf8decode(theirs!.blob); - await writeBlobToFile(gitDDB.workingDir, fullDocPath, data); - await resolvedIndex.addByPath(fullDocPath); + // console.log(' #case 14 - Accept theirs (update): ' + fullDocPath); + const theirsData = (await theirs.content())!; + const theirsFatDoc = await getFatDocFromData(theirsData, fullDocPath, docType); + await writeBlobToFile(gitDDB.workingDir, fullDocPath, theirsData); + await git.add({ fs, dir: gitDDB.workingDir, filepath: fullDocPath }); + return [ + { + mode: (await theirs.mode()).toString(8), + path: basename(fullDocPath), + oid: theirsFatDoc.fileOid, + type: 'blob', + }, + undefined, + ]; } - else if (base.oid === theirs.oid) { + else if (baseOid === theirsOid) { // Jut add it to the index. - // console.log(' #case 15 - Accept ours (update): ' + path); - await resolvedIndex.addByPath(fullDocPath); + // console.log(' #case 15 - Accept ours (update): ' + fullDocPath); + const oursData = (await ours.content())!; + const oursFatDoc = await getFatDocFromData(oursData, fullDocPath, docType); + return [ + { + mode: (await theirs.mode()).toString(8), + path: basename(fullDocPath), + oid: oursFatDoc.fileOid, + type: 'blob', + }, + undefined, + ]; } - else { - // ! Conflict - const strategy = await getStrategy( - conflictResolutionStrategy, - getFatDocFromReadBlobResult(fullDocPath, ours, docType), - getFatDocFromReadBlobResult(fullDocPath, theirs, docType) - ); - if (strategy === 'ours' || strategy === 'ours-diff') { - // Just add it to the index. - // console.log(' #case 16 - Conflict. Accept ours (update): ' + path); - const data = await getMergedDocument( - sync.jsonDiff, - sync.jsonPatch, - strategy, - JSON.parse(utf8decode(base!.blob)), - JSON.parse(utf8decode(ours!.blob)), - JSON.parse(utf8decode(theirs!.blob)) - ); - - await writeBlobToFile(gitDDB.workingDir, fullDocPath, data); - - await resolvedIndex.addByPath(fullDocPath); - - const fatDoc: FatDoc = await getFatDocFromData(data, fullDocPath, docType); - - acceptedConflicts.push({ - fatDoc, - strategy: strategy, - operation: strategy === 'ours' ? 'update' : 'update-merge', - }); - } - else if (strategy === 'theirs' || strategy === 'theirs-diff') { - // Write theirs to the file. - // console.log(' #case 17 - Conflict. Accept theirs (update): ' + path); - const data = await getMergedDocument( - sync.jsonDiff, - sync.jsonPatch, - strategy, - JSON.parse(utf8decode(base!.blob)), - JSON.parse(utf8decode(ours!.blob)), - JSON.parse(utf8decode(theirs!.blob)) - ); - - await writeBlobToFile(gitDDB.workingDir, fullDocPath, data); - - await resolvedIndex.addByPath(fullDocPath); - - const fatDoc: FatDoc = await getFatDocFromData(data, fullDocPath, docType); - - acceptedConflicts.push({ - fatDoc, - strategy: strategy, - operation: strategy === 'theirs' ? 'update' : 'update-merge', - }); - } + + // ! Conflict + + const baseData = (await base.content())!; + const oursData = (await ours.content())!; + const theirsData = (await theirs.content())!; + const oursFatDoc = await getFatDocFromData(oursData, fullDocPath, docType); + const theirsFatDoc = await getFatDocFromData(theirsData, fullDocPath, docType); + const strategy = await getStrategy( + conflictResolutionStrategy, + oursFatDoc, + theirsFatDoc + ); + + const data = await getMergedDocument( + sync.jsonDiff, + sync.jsonPatch, + strategy, + baseData, + oursData, + theirsData, + docType + ); + const resultFatDoc = await getFatDocFromData(data, fullDocPath, docType); + await writeBlobToFile(gitDDB.workingDir, fullDocPath, data); + await git.add({ fs, dir: gitDDB.workingDir, filepath: fullDocPath }); + + let acceptedConflict: AcceptedConflict; + + let mode = ''; + if (strategy === 'ours' || strategy === 'ours-diff') { + // Just add it to the index. + // console.log(' #case 16 - Conflict. Accept ours (update): ' + fullDocPath); + acceptedConflict = { + fatDoc: resultFatDoc, + strategy: strategy, + operation: strategy === 'ours' ? 'update' : 'update-merge', + }; + + mode = (await ours.mode()).toString(8); + } + else if (strategy === 'theirs' || strategy === 'theirs-diff') { + // Write theirs to the file. + // console.log(' #case 17 - Conflict. Accept theirs (update): ' + fullDocPath); + acceptedConflict = { + fatDoc: resultFatDoc, + strategy: strategy, + operation: strategy === 'theirs' ? 'update' : 'update-merge', + }; + mode = (await theirs.mode()).toString(8); } + + return [ + { + mode, + path: basename(fullDocPath), + oid: resultFatDoc.fileOid, + type: 'blob', + }, + acceptedConflict!, + ]; } - */ + throw new Err.InvalidConflictStateError('Invalid case'); } diff --git a/src/remote/sync_worker.ts b/src/remote/sync_worker.ts index e593e1e1..45decf0b 100644 --- a/src/remote/sync_worker.ts +++ b/src/remote/sync_worker.ts @@ -170,43 +170,24 @@ export async function syncWorker ( // Merge (distance.ahead > 0 && distance.behind > 0) - const [mergeCommitOid, acceptedConflicts] = await merge( + const [mergedTreeOid, acceptedConflicts] = await merge( gitDDB, sync, baseCommitOid, oldCommitOid, oldRemoteCommitOid ); - /* - const mergeResult = await git - .merge({ + + if (acceptedConflicts.length === 0) { + const mergeCommitOid = await git.commit({ fs, dir: gitDDB.workingDir, - ours: gitDDB.defaultBranch, - theirs: 'remotes/origin/' + gitDDB.defaultBranch, author: gitDDB.author, committer: gitDDB.committer, + parent: [oldCommitOid, oldRemoteCommitOid], message: 'merge', - }) - .catch(e => { - if (e instanceof git.Errors.MergeNotSupportedError) { - // has conflict - return undefined; - } - - throw new Err.GitMergeBranchError(e.message); + tree: mergedTreeOid, }); -*/ - if (mergeCommitOid !== undefined) { - // Conflict has not been occurred. - // Exec normal merge. - - // This case is occurred when not fast-forward. - // - insert/update a remote file, and insert/update another local file - // - insert/update a remote file, and insert/update the same local file with the same contents - // - insert/update a remote file, and remove another local file - // - remove a remote file, and insert/update another local file - // - remove a remote file, and remove the same local file const localChanges = await getAndWriteLocalChanges( gitDDB.workingDir, @@ -277,56 +258,6 @@ export async function syncWorker ( * https://git-scm.com/docs/git-merge#_true_merge */ - const allFileObj: { [key: string]: boolean } = {}; - /* - conflictedIndex.entries().forEach((entry: nodegit.IndexEntry) => { - const stage = nodegit.Index.entryStage(entry); - gitDDB.logger.debug( - CONSOLE_STYLE.bgWhite().fgBlack().tag()`sync_worker: ${stage} : ${entry.path}` - ); - - // entries() returns all files in stage 0, 1, 2 and 3. - // A file may exist in multiple stages. - // Add once per file to allFileObj. - allFileObj[entry.path] = true; - }); - - - const resolvedIndex = await repos.refreshIndex(); - - // Try to check conflict for all files in conflicted index. - // console.log('3-way merge..'); - const [mergeBaseCommitOid] = await git.findMergeBase({ - fs, - dir: gitDDB.workingDir, - oids: [oldCommitOid, oldRemoteCommitOid], - }); - - const resolvers: Promise[] = []; - const strategy = sync.options.conflictResolutionStrategy; - // eslint-disable-next-line complexity - Object.keys(allFileObj).forEach(path => { - resolvers.push( - threeWayMerge( - gitDDB, - sync, - strategy!, - resolvedIndex, - path, - mergeBaseCommitOid, - oldCommitOid, - oldRemoteCommitOid, - acceptedConflicts - ).catch(err => { - throw new Err.ThreeWayMergeError(err.message); - }) - ); - }); - await Promise.all(resolvers); - resolvedIndex.conflictCleanup(); - await resolvedIndex.write(); - await resolvedIndex.writeTree(); - acceptedConflicts.sort((a, b) => { return a.fatDoc.name === b.fatDoc.name ? 0 : a.fatDoc.name > b.fatDoc.name ? 1 : -1; }); @@ -343,33 +274,17 @@ export async function syncWorker ( commitMessage = commitMessage.slice(0, -2); } - const overwriteCommitOid = await git.commit({ + const mergeCommitOid = await git.commit({ fs, dir: gitDDB.workingDir, author: gitDDB.author, committer: gitDDB.committer, - parent: [ - await git.resolveRef({ - fs, - dir: gitDDB.workingDir, - ref: 'HEAD', - }), - await git.resolveRef({ - fs, - dir: gitDDB.workingDir, - ref: 'refs/remotes/origin/main', - }), - ], + parent: [oldCommitOid, oldRemoteCommitOid], message: commitMessage, + tree: mergedTreeOid, }); - repos.stateCleanup(); - - const localChanges = await getChanges( - gitDDB.workingDir, - oldCommitOid, - overwriteCommitOid - ); + const localChanges = await getChanges(gitDDB.workingDir, oldCommitOid, mergeCommitOid); // Get list of commits which has been added to local let localCommits: NormalizedCommit[] | undefined; @@ -377,21 +292,17 @@ export async function syncWorker ( const commitsFromRemote = await getCommitLogs( gitDDB.workingDir, oldRemoteCommitOid, - mergeBaseCommitOid + baseCommitOid ); const overwriteCommit = await git.readCommit({ fs, dir: gitDDB.workingDir, - oid: overwriteCommitOid, + oid: mergeCommitOid, }); // Add merge commit localCommits = [...commitsFromRemote, normalizeCommit(overwriteCommit)]; } - const opt = new nodegit.CheckoutOptions(); - opt.checkoutStrategy = nodegit.Checkout.STRATEGY.FORCE; - await nodegit.Checkout.head(repos, opt); - // Push const syncResultPush = await pushWorker(gitDDB, sync, taskMetadata, true).catch( (err: Error) => { @@ -431,6 +342,4 @@ export async function syncWorker ( }; } return syncResultResolveConflictsAndPush; - */ - return { action: 'nop' }; } diff --git a/test/remote/3way_merge.test.ts b/test/remote/3way_merge.test.ts index 37531bdf..f9d7c292 100644 --- a/test/remote/3way_merge.test.ts +++ b/test/remote/3way_merge.test.ts @@ -14,7 +14,6 @@ */ import path from 'path'; import fs from 'fs-extra'; -import git, { WalkerEntry } from 'isomorphic-git'; import expect from 'expect'; import { Err } from '../../src/error'; import { threeWayMerge } from '../../src/remote/3way_merge'; @@ -107,7 +106,7 @@ maybe('', () => { * jsonA2: 1 - Accept theirs (insert) * jsonB3: 2 - Accept ours (insert) */ - it.only('resolves case 1 - Accept theirs (insert), case 2 - Accept ours (insert), case 4 - Conflict. Accept ours (insert)', async () => { + it('resolves case 1 - Accept theirs (insert), case 2 - Accept ours (insert), case 4 - Conflict. Accept ours (insert)', async () => { const [dbA, dbB, syncA, syncB] = await createClonedDatabases( remoteURLBase, localDir, @@ -116,7 +115,6 @@ maybe('', () => { conflictResolutionStrategy: 'ours', } ); - dbB.logLevel = 'trace'; // A puts and pushes const jsonA1 = { _id: '1', name: 'fromA' }; diff --git a/test/remote_utils.ts b/test/remote_utils.ts index 21ed0698..6dafbd17 100644 --- a/test/remote_utils.ts +++ b/test/remote_utils.ts @@ -1,6 +1,7 @@ /* eslint-disable @typescript-eslint/naming-convention */ import fs from 'fs-extra'; import { Octokit } from '@octokit/rest'; +import git from 'isomorphic-git'; import sinon from 'sinon'; import expect from 'expect'; import nodegit from '@sosuisen/nodegit'; @@ -333,8 +334,21 @@ export const compareWorkingDirAndBlobs = async ( ): Promise => { const files = listFiles(gitDDB, gitDDB.workingDir); + /* + const headCommitOid = await git.resolveRef({ fs, dir: gitDDB.workingDir, ref: 'HEAD' }); + await git.walk({ + fs, + dir: gitDDB.workingDir, + trees: [git.TREE({ ref: headCommitOid })], + // @ts-ignore + map: function (fullDocPath, [a]) { + console.log('myres: ' + fullDocPath); + return ''; + }, + }); */ + const currentIndex = await gitDDB.repository()?.refreshIndex(); - const entryCount = currentIndex!.entryCount() - 1; // Reduce by 1 due to '.gitddb/lib_version' + const entryCount = currentIndex!.entryCount() - 1; // Reduce by 1 due to '.gitddb/info.json' // console.log('# check count: fromFiles: ' + files.length + ', fromIndex: ' + entryCount); if (files.length !== entryCount) { return false; From caecb8c08e16f9265c65e668f692a4566ec050e8 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Mon, 12 Jul 2021 11:46:17 +0900 Subject: [PATCH 013/297] fix: get localChanges and remoteChanges in threeWayMerge function --- src/remote/3way_merge.ts | 289 +++++++++++++++++++++++++++++--------- src/remote/push_worker.ts | 13 +- src/remote/sync_worker.ts | 30 ++-- 3 files changed, 252 insertions(+), 80 deletions(-) diff --git a/src/remote/3way_merge.ts b/src/remote/3way_merge.ts index 3e8b1609..7e9fe0cc 100644 --- a/src/remote/3way_merge.ts +++ b/src/remote/3way_merge.ts @@ -5,6 +5,7 @@ import { DEFAULT_CONFLICT_RESOLUTION_STRATEGY, JSON_EXT } from '../const'; import { Err } from '../error'; import { AcceptedConflict, + ChangedFile, ConflictResolutionStrategies, ConflictResolutionStrategyLabels, DocType, @@ -179,8 +180,10 @@ export async function merge ( baseCommitOid: string, oursCommitOid: string, theirsCommitOid: string -): Promise<[string, AcceptedConflict[]]> { +): Promise<[string, ChangedFile[], ChangedFile[], AcceptedConflict[]]> { const acceptedConflicts: AcceptedConflict[] = []; + const localChanges: ChangedFile[] = []; + const remoteChanges: ChangedFile[] = []; const strategy = sync.options.conflictResolutionStrategy!; const results = await git.walk({ @@ -192,6 +195,7 @@ export async function merge ( git.TREE({ ref: theirsCommitOid }), ], // @ts-ignore + // eslint-disable-next-line complexity map: async function (fullDocPath, [base, ours, theirs]) { const baseType = base === null ? undefined : await base.type(); if (baseType === 'tree') { @@ -223,7 +227,7 @@ export async function merge ( }; } - const [treeEntry, conflict] = await threeWayMerge( + const [treeEntry, localChange, remoteChange, conflict] = await threeWayMerge( gitDDB, sync, strategy, @@ -232,6 +236,13 @@ export async function merge ( ours, theirs ); + + if (localChange !== undefined) { + localChanges.push(localChange); + } + if (remoteChange !== undefined) { + remoteChanges.push(remoteChange); + } if (conflict !== undefined) { acceptedConflicts.push(conflict); } @@ -261,7 +272,7 @@ export async function merge ( const mergedTreeOid = results.oid; - return [mergedTreeOid, acceptedConflicts]; + return [mergedTreeOid, localChanges, remoteChanges, acceptedConflicts]; } /** @@ -287,7 +298,14 @@ export async function threeWayMerge ( base: WalkerEntry, ours: WalkerEntry, theirs: WalkerEntry -): Promise<[TreeEntry | undefined, AcceptedConflict | undefined]> { +): Promise< + [ + TreeEntry | undefined, + ChangedFile | undefined, + ChangedFile | undefined, + AcceptedConflict | undefined + ] +> { const repos = gitDDB.repository(); if (repos === undefined) { throw new Err.RepositoryNotOpenError(); @@ -306,10 +324,13 @@ export async function threeWayMerge ( ); } else if (!base && !ours && theirs) { - // A new file has been inserted on theirs. + // A new file has been inserted into theirs. // Write it to the working directory. + // Write it to the index. // console.log(' #case 1 - Accept theirs (insert): ' + fullDocPath); - await writeBlobToFile(gitDDB.workingDir, fullDocPath, (await theirs.content())!); + const theirsData = (await theirs.content())!; + const theirsFatDoc = await getFatDocFromData(theirsData, fullDocPath, docType); + await writeBlobToFile(gitDDB.workingDir, fullDocPath, theirsData); await git.add({ fs, dir: gitDDB.workingDir, filepath: fullDocPath }); return [ { @@ -318,13 +339,21 @@ export async function threeWayMerge ( oid: await theirs.oid(), type: 'blob', }, + { + operation: 'insert', + new: theirsFatDoc, + }, + undefined, undefined, ]; } else if (!base && ours && !theirs) { - // A new file has been inserted on ours. - // Just add it to the index. + // A new file has been inserted into ours. + // It has already been created on the working directory. + // It has already been added to the index. // console.log(' #case 2 - Accept ours (insert): ' + fullDocPath); + const oursData = (await ours.content())!; + const oursFatDoc = await getFatDocFromData(oursData, fullDocPath, docType); return [ { mode: (await ours.mode()).toString(8), @@ -333,6 +362,11 @@ export async function threeWayMerge ( type: 'blob', }, undefined, + { + operation: 'insert', + new: oursFatDoc, + }, + undefined, ]; } else if (!base && ours && theirs) { @@ -340,8 +374,9 @@ export async function threeWayMerge ( const theirsOid = await theirs.oid(); if (oursOid === theirsOid) { // The same filenames with exactly the same contents are inserted on both local and remote. + // It has already been created on the both working directory. + // It has already been added to the both index. // console.log(' #case 3 - Accept both (insert): ' + fullDocPath); - // Jut add it to the index. return [ { mode: (await ours.mode()).toString(8), @@ -350,11 +385,12 @@ export async function threeWayMerge ( type: 'blob', }, undefined, + undefined, + undefined, ]; } // ! Conflict - const oursData = (await ours.content())!; const theirsData = (await theirs.content())!; const oursFatDoc = await getFatDocFromData(oursData, fullDocPath, docType); @@ -364,18 +400,41 @@ export async function threeWayMerge ( oursFatDoc, theirsFatDoc ); + let mode = ''; + if (strategy === 'ours' || strategy === 'ours-diff') { + // console.log(' #case 4 - Conflict. Accept ours (insert): ' + fullDocPath); + mode = (await ours.mode()).toString(8); + } + else if (strategy === 'theirs' || strategy === 'theirs-diff') { + // console.log(' #case 5 - Conflict. Accept theirs (insert): ' + fullDocPath); + mode = (await theirs.mode()).toString(8); + } let resultFatDoc: FatDoc; + let localChange: ChangedFile | undefined; + let remoteChange: ChangedFile | undefined; if (strategy === 'ours') { // Can skip getMergedDocument(). resultFatDoc = oursFatDoc; - // Can skip writeBlobToFile() + + localChange = undefined; + remoteChange = { + operation: 'update', + old: theirsFatDoc, + new: oursFatDoc, + }; } else if (strategy === 'theirs') { // Can skip getMergedDocument(). resultFatDoc = theirsFatDoc; await writeBlobToFile(gitDDB.workingDir, fullDocPath, theirsData); await git.add({ fs, dir: gitDDB.workingDir, filepath: fullDocPath }); + localChange = { + operation: 'update', + old: oursFatDoc, + new: theirsFatDoc, + }; + remoteChange = undefined; } else { // Diff and patch @@ -391,6 +450,16 @@ export async function threeWayMerge ( resultFatDoc = await getFatDocFromData(data, fullDocPath, docType); await writeBlobToFile(gitDDB.workingDir, fullDocPath, data); await git.add({ fs, dir: gitDDB.workingDir, filepath: fullDocPath }); + localChange = { + operation: 'update', + old: oursFatDoc, + new: resultFatDoc, + }; + remoteChange = { + operation: 'update', + old: theirsFatDoc, + new: resultFatDoc, + }; } const acceptedConflict: AcceptedConflict = { @@ -399,16 +468,6 @@ export async function threeWayMerge ( operation: strategy.endsWith('-diff') ? 'insert-merge' : 'insert', }; - let mode = ''; - if (strategy === 'ours' || strategy === 'ours-diff') { - // console.log(' #case 4 - Conflict. Accept ours (insert): ' + fullDocPath); - mode = (await ours.mode()).toString(8); - } - else if (strategy === 'theirs' || strategy === 'theirs-diff') { - // console.log(' #case 5 - Conflict. Accept theirs (insert): ' + fullDocPath); - mode = (await theirs.mode()).toString(8); - } - return [ { mode, @@ -416,34 +475,41 @@ export async function threeWayMerge ( oid: resultFatDoc.fileOid, type: 'blob', }, + localChange, + remoteChange, acceptedConflict, ]; } else if (base && !ours && !theirs) { - // The same files are removed. + // The same files have been removed from both local and remote. // console.log(' #case 6 - Accept both (delete): ' + fullDocPath); - - return [undefined, undefined]; + return [undefined, undefined, undefined, undefined]; } else if (base && !ours && theirs) { const baseOid = await base.oid(); const theirsOid = await theirs.oid(); + const theirsData = (await theirs.content())!; + const theirsFatDoc = await getFatDocFromData(theirsData, fullDocPath, docType); if (baseOid === theirsOid) { - // A file has been removed on ours. + // A file has been removed from ours. // console.log(' #case 7 - Accept ours (delete): ' + fullDocPath); - - return [undefined, undefined]; + return [ + undefined, + undefined, + { + operation: 'delete', + old: theirsFatDoc, + }, + undefined, + ]; } // ! Conflict - const theirsData = (await theirs.content())!; - const theirsFatDoc = await getFatDocFromData(theirsData, fullDocPath, docType); const strategy = await getStrategy(conflictResolutionStrategy, undefined, theirsFatDoc); if (strategy === 'ours' || strategy === 'ours-diff') { - // Just add it to the index. // console.log(' #case 8 - Conflict. Accept ours (delete): ' + fullDocPath); const baseData = (await base.content())!; const baseFatDoc = await getFatDocFromData(baseData, fullDocPath, docType); @@ -452,10 +518,17 @@ export async function threeWayMerge ( strategy: strategy, operation: 'delete', }; - return [undefined, acceptedConflict]; + return [ + undefined, + undefined, + { + operation: 'delete', + old: theirsFatDoc, + }, + acceptedConflict, + ]; } else if (strategy === 'theirs' || strategy === 'theirs-diff') { - // Write theirs to the file. // console.log(' #case 9 - Conflict. Accept theirs (update): ' + fullDocPath); const acceptedConflict: AcceptedConflict = { fatDoc: theirsFatDoc, @@ -471,6 +544,11 @@ export async function threeWayMerge ( oid: theirsFatDoc.fileOid, type: 'blob', }, + { + operation: 'insert', + new: theirsFatDoc, + }, + undefined, acceptedConflict, ]; } @@ -478,45 +556,54 @@ export async function threeWayMerge ( else if (base && ours && !theirs) { const baseOid = await base.oid(); const oursOid = await ours.oid(); + const oursData = (await ours.content())!; + const oursFatDoc = await getFatDocFromData(oursData, fullDocPath, docType); if (baseOid === oursOid) { - // A file has been removed on theirs. + // A file has been removed from theirs. // console.log(' #case 10 - Accept theirs (delete): ' + fullDocPath); await fs.remove(nodePath.resolve(repos.workdir(), fullDocPath)).catch(() => { throw new Err.CannotDeleteDataError(); }); await git.remove({ fs, dir: gitDDB.workingDir, filepath: fullDocPath }); - return [undefined, undefined]; + return [ + undefined, + { + operation: 'delete', + old: oursFatDoc, + }, + undefined, + undefined, + ]; } // ! Conflict - const oursData = (await ours.content())!; - const oursFatDoc = await getFatDocFromData(oursData, fullDocPath, docType); const strategy = await getStrategy(conflictResolutionStrategy, oursFatDoc, undefined); if (strategy === 'ours' || strategy === 'ours-diff') { - // Just add to the index. // console.log(' #case 11 - Conflict. Accept ours (update): ' + fullDocPath); const acceptedConflict: AcceptedConflict = { fatDoc: oursFatDoc, strategy: strategy, operation: 'update', }; - await writeBlobToFile(gitDDB.workingDir, fullDocPath, oursData); - await git.add({ fs, dir: gitDDB.workingDir, filepath: fullDocPath }); return [ { mode: (await ours.mode()).toString(8), path: basename(fullDocPath), - oid: oursFatDoc.fileOid, + oid: oursOid, type: 'blob', }, + undefined, + { + operation: 'insert', + new: oursFatDoc, + }, acceptedConflict, ]; } else if (strategy === 'theirs' || strategy === 'theirs-diff') { - // Remove file // console.log(' #case 12 - Conflict. Accept theirs (delete): ' + fullDocPath); const baseData = (await base.content())!; const baseFatDoc = await getFatDocFromData(baseData, fullDocPath, docType); @@ -529,7 +616,15 @@ export async function threeWayMerge ( throw new Err.CannotDeleteDataError(); }); await git.remove({ fs, dir: gitDDB.workingDir, filepath: fullDocPath }); - return [undefined, acceptedConflicts]; + return [ + undefined, + { + operation: 'delete', + old: oursFatDoc, + }, + undefined, + acceptedConflicts, + ]; } } else if (base && ours && theirs) { @@ -538,8 +633,7 @@ export async function threeWayMerge ( const theirsOid = await theirs.oid(); if (oursOid === theirsOid) { - // The same filenames with exactly the same contents are inserted on both local and remote. - // Jut add it to the index. + // The same filenames with exactly the same contents are inserted into both local and remote. // console.log(' #case 13 - Accept both (update): ' + fullDocPath); return [ { @@ -550,11 +644,14 @@ export async function threeWayMerge ( type: 'blob', }, undefined, + undefined, + undefined, ]; } else if (baseOid === oursOid) { - // Write theirs to the file. // console.log(' #case 14 - Accept theirs (update): ' + fullDocPath); + const oursData = (await ours.content())!; + const oursFatDoc = await getFatDocFromData(oursData, fullDocPath, docType); const theirsData = (await theirs.content())!; const theirsFatDoc = await getFatDocFromData(theirsData, fullDocPath, docType); await writeBlobToFile(gitDDB.workingDir, fullDocPath, theirsData); @@ -566,14 +663,21 @@ export async function threeWayMerge ( oid: theirsFatDoc.fileOid, type: 'blob', }, + { + operation: 'update', + old: oursFatDoc, + new: theirsFatDoc, + }, + undefined, undefined, ]; } else if (baseOid === theirsOid) { - // Jut add it to the index. // console.log(' #case 15 - Accept ours (update): ' + fullDocPath); const oursData = (await ours.content())!; const oursFatDoc = await getFatDocFromData(oursData, fullDocPath, docType); + const theirsData = (await theirs.content())!; + const theirsFatDoc = await getFatDocFromData(theirsData, fullDocPath, docType); return [ { mode: (await theirs.mode()).toString(8), @@ -582,6 +686,12 @@ export async function threeWayMerge ( type: 'blob', }, undefined, + { + operation: 'update', + old: theirsFatDoc, + new: oursFatDoc, + }, + undefined, ]; } @@ -598,6 +708,54 @@ export async function threeWayMerge ( theirsFatDoc ); + if (strategy === 'ours') { + // console.log(' #case 16 - Conflict. Accept ours (update): ' + fullDocPath); + return [ + { + mode: (await ours.mode()).toString(8), + path: basename(fullDocPath), + oid: oursFatDoc.fileOid, + type: 'blob', + }, + undefined, + { + operation: 'update', + old: theirsFatDoc, + new: oursFatDoc, + }, + { + fatDoc: oursFatDoc, + strategy: strategy, + operation: 'update', + }, + ]; + } + else if (strategy === 'theirs') { + // console.log(' #case 17 - Conflict. Accept theirs (update): ' + fullDocPath); + await writeBlobToFile(gitDDB.workingDir, fullDocPath, theirsData); + await git.add({ fs, dir: gitDDB.workingDir, filepath: fullDocPath }); + + return [ + { + mode: (await theirs.mode()).toString(8), + path: basename(fullDocPath), + oid: theirsFatDoc.fileOid, + type: 'blob', + }, + { + operation: 'update', + old: oursFatDoc, + new: theirsFatDoc, + }, + undefined, + { + fatDoc: theirsFatDoc, + strategy: strategy, + operation: 'update', + }, + ]; + } + const data = await getMergedDocument( sync.jsonDiff, sync.jsonPatch, @@ -611,28 +769,13 @@ export async function threeWayMerge ( await writeBlobToFile(gitDDB.workingDir, fullDocPath, data); await git.add({ fs, dir: gitDDB.workingDir, filepath: fullDocPath }); - let acceptedConflict: AcceptedConflict; - let mode = ''; - if (strategy === 'ours' || strategy === 'ours-diff') { - // Just add it to the index. - // console.log(' #case 16 - Conflict. Accept ours (update): ' + fullDocPath); - acceptedConflict = { - fatDoc: resultFatDoc, - strategy: strategy, - operation: strategy === 'ours' ? 'update' : 'update-merge', - }; - + if (strategy === 'ours-diff') { + // console.log(' #case 16 (diff) - Conflict. Accept ours (update): ' + fullDocPath); mode = (await ours.mode()).toString(8); } - else if (strategy === 'theirs' || strategy === 'theirs-diff') { - // Write theirs to the file. - // console.log(' #case 17 - Conflict. Accept theirs (update): ' + fullDocPath); - acceptedConflict = { - fatDoc: resultFatDoc, - strategy: strategy, - operation: strategy === 'theirs' ? 'update' : 'update-merge', - }; + else if (strategy === 'theirs-diff') { + // console.log(' #case 17 (diff) - Conflict. Accept theirs (update): ' + fullDocPath); mode = (await theirs.mode()).toString(8); } @@ -643,7 +786,21 @@ export async function threeWayMerge ( oid: resultFatDoc.fileOid, type: 'blob', }, - acceptedConflict!, + { + operation: 'update', + old: oursFatDoc, + new: resultFatDoc, + }, + { + operation: 'update', + old: theirsFatDoc, + new: resultFatDoc, + }, + { + fatDoc: resultFatDoc, + strategy: strategy, + operation: 'update-merge', + }, ]; } throw new Err.InvalidConflictStateError('Invalid case'); diff --git a/src/remote/push_worker.ts b/src/remote/push_worker.ts index 1f3b7c52..bcf10c34 100644 --- a/src/remote/push_worker.ts +++ b/src/remote/push_worker.ts @@ -12,7 +12,7 @@ import fs from 'fs-extra'; import { CONSOLE_STYLE } from '../utils'; import { Err } from '../error'; import { GitDDBInterface } from '../types_gitddb'; -import { NormalizedCommit, SyncResultPush, TaskMetadata } from '../types'; +import { ChangedFile, NormalizedCommit, SyncResultPush, TaskMetadata } from '../types'; import { SyncInterface } from '../types_sync'; import { calcDistance, getChanges, getCommitLogs } from './worker_utils'; @@ -116,7 +116,8 @@ export async function pushWorker ( gitDDB: GitDDBInterface, sync: SyncInterface, taskMetadata: TaskMetadata, - skipStartEvent = false + skipStartEvent = false, + skipGetChanges = false ): Promise { if (!skipStartEvent) { sync.eventHandlers.start.forEach(listener => { @@ -186,7 +187,13 @@ export async function pushWorker ( // Push await push(gitDDB, sync); - const remoteChanges = await getChanges(gitDDB.workingDir, remoteCommitOid, headCommitOid); + let remoteChanges: ChangedFile[] | undefined; + if (skipGetChanges) { + remoteChanges = undefined; + } + else { + remoteChanges = await getChanges(gitDDB.workingDir, remoteCommitOid, headCommitOid); + } const syncResult: SyncResultPush = { action: 'push', diff --git a/src/remote/sync_worker.ts b/src/remote/sync_worker.ts index 45decf0b..cd1bf60c 100644 --- a/src/remote/sync_worker.ts +++ b/src/remote/sync_worker.ts @@ -125,7 +125,9 @@ export async function syncWorker ( return { action: 'nop' }; } else if (distance.ahead === 0 && distance.behind > 0) { - // Fast forward + /** + * Fast forward + */ await git.writeRef({ fs, dir: gitDDB.workingDir, @@ -162,15 +164,18 @@ export async function syncWorker ( return syncResultFastForwardMerge; } else if (distance.ahead > 0 && distance.behind === 0) { - // Push + /** + * Push + */ return await pushWorker(gitDDB, sync, taskMetadata, true).catch(err => { throw err; }); } - // Merge (distance.ahead > 0 && distance.behind > 0) - - const [mergedTreeOid, acceptedConflicts] = await merge( + /** + * Merge (distance.ahead > 0 && distance.behind > 0) + */ + const [mergedTreeOid, localChanges, remoteChanges, acceptedConflicts] = await merge( gitDDB, sync, baseCommitOid, @@ -189,12 +194,13 @@ export async function syncWorker ( tree: mergedTreeOid, }); + /* const localChanges = await getAndWriteLocalChanges( gitDDB.workingDir, oldCommitOid, mergeCommitOid! ); - + */ let localCommits: NormalizedCommit[] | undefined; // Get list of commits which has been added to local @@ -214,7 +220,7 @@ export async function syncWorker ( localCommits = [...commitsFromRemote, normalizeCommit(mergeCommit)]; } // Need push because it is merged normally. - const syncResultPush = await pushWorker(gitDDB, sync, taskMetadata, true).catch( + const syncResultPush = await pushWorker(gitDDB, sync, taskMetadata, true, true).catch( (err: Error) => { return err; } @@ -240,7 +246,8 @@ export async function syncWorker ( action: 'merge and push', changes: { local: localChanges, - remote: syncResultPush.changes.remote, + // remote: syncResultPush.changes.remote, + remote: remoteChanges, }, }; if (localCommits) { @@ -284,7 +291,7 @@ export async function syncWorker ( tree: mergedTreeOid, }); - const localChanges = await getChanges(gitDDB.workingDir, oldCommitOid, mergeCommitOid); + // const localChanges = await getChanges(gitDDB.workingDir, oldCommitOid, mergeCommitOid); // Get list of commits which has been added to local let localCommits: NormalizedCommit[] | undefined; @@ -304,7 +311,7 @@ export async function syncWorker ( } // Push - const syncResultPush = await pushWorker(gitDDB, sync, taskMetadata, true).catch( + const syncResultPush = await pushWorker(gitDDB, sync, taskMetadata, true, true).catch( (err: Error) => { return err; } @@ -332,7 +339,8 @@ export async function syncWorker ( conflicts: acceptedConflicts, changes: { local: localChanges, - remote: syncResultPush.changes.remote, + // remote: syncResultPush.changes.remote, + remote: remoteChanges, }, }; if (localCommits) { From 4a06d04250e52541a06731ffd3f9b8e431ac2f51 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Mon, 12 Jul 2021 12:31:17 +0900 Subject: [PATCH 014/297] test: test sync of files under .gitddb/ --- test/remote/sync_trysync.test.ts | 41 +++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/test/remote/sync_trysync.test.ts b/test/remote/sync_trysync.test.ts index 55f67e0c..ab43d9b4 100644 --- a/test/remote/sync_trysync.test.ts +++ b/test/remote/sync_trysync.test.ts @@ -18,6 +18,7 @@ import fs from 'fs-extra'; import expect from 'expect'; import { GitDocumentDB } from '../../src/git_documentdb'; import { + FatJsonDoc, SyncResult, SyncResultFastForwardMerge, SyncResultMergeAndPush, @@ -37,7 +38,7 @@ import { getWorkingDirDocs, removeRemoteRepositories, } from '../remote_utils'; -import { sleep } from '../../src/utils'; +import { sleep, toSortedJSONString } from '../../src/utils'; const reposPrefix = 'test_sync_trysync___'; const localDir = `./test/database_sync_trysync`; @@ -766,4 +767,42 @@ maybe(': Sync#trySync()', () => { await destroyDBs([dbA, dbB]); }); + + it('syncs files under .gitddb', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir, + }); + // Clone dbA + await dbB.open(); + const syncB = await dbB.sync(syncA.options); + + const info = { + dbId: 'foo', + creator: 'bar', + version: 'baz', + }; + const putResult = await dbA.putFatDoc('.gitddb/info.json', toSortedJSONString(info)); + + const appInfo = { ver: 1.0 }; + await dbA.saveAppInfo(appInfo); + + await syncA.tryPush(); + await syncB.trySync(); + await expect(dbB.loadAppInfo()).resolves.toEqual(appInfo); + + const fatDoc = { + _id: '.gitddb/info', + name: '.gitddb/info.json', + fileOid: putResult.fileOid, + type: 'json', + doc: info, + }; + await expect(dbB.getFatDoc('.gitddb/info.json')).resolves.toEqual(fatDoc); + + await destroyDBs([dbA, dbB]); + }); }); From 6dfee1659c8aaf7b2cb6611a8433fba2e2870519 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Mon, 12 Jul 2021 21:56:25 +0900 Subject: [PATCH 015/297] fix: add plugin function --- package-lock.json | 4852 ++++++++++++++++++++++------------------- package.json | 2 +- src/error.ts | 10 - src/git_documentdb.ts | 17 + src/remote/sync.ts | 18 + src/types.ts | 5 + 6 files changed, 2635 insertions(+), 2269 deletions(-) diff --git a/package-lock.json b/package-lock.json index d2005dce..143e9407 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "git-documentdb", - "version": "0.4.0-alpha.9", + "version": "0.4.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -11,37 +11,64 @@ "dev": true }, "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", "dev": true, "requires": { - "@babel/highlight": "^7.10.4" + "@babel/highlight": "^7.14.5" } }, + "@babel/compat-data": { + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.7.tgz", + "integrity": "sha512-nS6dZaISCXJ3+518CWiBfEr//gHyMO02uDxBkXTKZDN5POruCnOZ1N4YBRZDCabwF8nZMWBpRxIicmXtBs+fvw==", + "dev": true + }, "@babel/core": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.10.tgz", - "integrity": "sha512-eTAlQKq65zHfkHZV0sIVODCPGVgoo1HdBlbSLi9CqOzuZanMv2ihzY+4paiKr1mH+XmYESMAmJ/dpZ68eN6d8w==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.12.10", - "@babel/helper-module-transforms": "^7.12.1", - "@babel/helpers": "^7.12.5", - "@babel/parser": "^7.12.10", - "@babel/template": "^7.12.7", - "@babel/traverse": "^7.12.10", - "@babel/types": "^7.12.10", + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.6.tgz", + "integrity": "sha512-gJnOEWSqTk96qG5BoIrl5bVtc23DCycmIePPYnamY9RboYdI4nFy5vAQMSl81O5K/W0sLDWfGysnOECC+KUUCA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.14.5", + "@babel/helper-compilation-targets": "^7.14.5", + "@babel/helper-module-transforms": "^7.14.5", + "@babel/helpers": "^7.14.6", + "@babel/parser": "^7.14.6", + "@babel/template": "^7.14.5", + "@babel/traverse": "^7.14.5", + "@babel/types": "^7.14.5", "convert-source-map": "^1.7.0", "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", + "gensync": "^1.0.0-beta.2", "json5": "^2.1.2", - "lodash": "^4.17.19", - "semver": "^5.4.1", + "semver": "^6.3.0", "source-map": "^0.5.0" }, "dependencies": { + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -50,13 +77,32 @@ } } }, + "@babel/eslint-parser": { + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.14.7.tgz", + "integrity": "sha512-6WPwZqO5priAGIwV6msJcdc9TsEPzYeYdS/Xuoap+/ihkgN6dzHp2bcAAwyWZ5bLzk0vvjDmKvRwkqNaiJ8BiQ==", + "dev": true, + "requires": { + "eslint-scope": "^5.1.1", + "eslint-visitor-keys": "^2.1.0", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, "@babel/generator": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", - "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz", + "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==", "dev": true, "requires": { - "@babel/types": "^7.12.11", + "@babel/types": "^7.14.5", "jsesc": "^2.5.1", "source-map": "^0.5.0" }, @@ -69,250 +115,253 @@ } } }, + "@babel/helper-compilation-targets": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.14.5.tgz", + "integrity": "sha512-v+QtZqXEiOnpO6EYvlImB6zCD2Lel06RzOPzmkz/D/XgQiUu3C/Jb1LOqSt/AIA34TYi/Q+KlT8vTQrgdxkbLw==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.14.5", + "@babel/helper-validator-option": "^7.14.5", + "browserslist": "^4.16.6", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, "@babel/helper-function-name": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", - "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz", + "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.12.10", - "@babel/template": "^7.12.7", - "@babel/types": "^7.12.11" + "@babel/helper-get-function-arity": "^7.14.5", + "@babel/template": "^7.14.5", + "@babel/types": "^7.14.5" } }, "@babel/helper-get-function-arity": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", - "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz", + "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.14.5.tgz", + "integrity": "sha512-R1PXiz31Uc0Vxy4OEOm07x0oSjKAdPPCh3tPivn/Eo8cvz6gveAeuyUUPB21Hoiif0uoPQSSdhIPS3352nvdyQ==", "dev": true, "requires": { - "@babel/types": "^7.12.10" + "@babel/types": "^7.14.5" } }, "@babel/helper-member-expression-to-functions": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", - "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.14.7.tgz", + "integrity": "sha512-TMUt4xKxJn6ccjcOW7c4hlwyJArizskAhoSTOCkA0uZ+KghIaci0Qg9R043kUMWI9mtQfgny+NQ5QATnZ+paaA==", "dev": true, "requires": { - "@babel/types": "^7.12.7" + "@babel/types": "^7.14.5" } }, "@babel/helper-module-imports": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", - "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz", + "integrity": "sha512-SwrNHu5QWS84XlHwGYPDtCxcA0hrSlL2yhWYLgeOc0w7ccOl2qv4s/nARI0aYZW+bSwAL5CukeXA47B/1NKcnQ==", "dev": true, "requires": { - "@babel/types": "^7.12.5" + "@babel/types": "^7.14.5" } }, "@babel/helper-module-transforms": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz", - "integrity": "sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.5.tgz", + "integrity": "sha512-iXpX4KW8LVODuAieD7MzhNjmM6dzYY5tfRqT+R9HDXWl0jPn/djKmA+G9s/2C2T9zggw5tK1QNqZ70USfedOwA==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.12.1", - "@babel/helper-replace-supers": "^7.12.1", - "@babel/helper-simple-access": "^7.12.1", - "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/helper-validator-identifier": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.12.1", - "@babel/types": "^7.12.1", - "lodash": "^4.17.19" + "@babel/helper-module-imports": "^7.14.5", + "@babel/helper-replace-supers": "^7.14.5", + "@babel/helper-simple-access": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5", + "@babel/helper-validator-identifier": "^7.14.5", + "@babel/template": "^7.14.5", + "@babel/traverse": "^7.14.5", + "@babel/types": "^7.14.5" } }, "@babel/helper-optimise-call-expression": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz", - "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.14.5.tgz", + "integrity": "sha512-IqiLIrODUOdnPU9/F8ib1Fx2ohlgDhxnIDU7OEVi+kAbEZcyiF7BLU8W6PfvPi9LzztjS7kcbzbmL7oG8kD6VA==", "dev": true, "requires": { - "@babel/types": "^7.12.10" + "@babel/types": "^7.14.5" } }, "@babel/helper-replace-supers": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz", - "integrity": "sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.14.5.tgz", + "integrity": "sha512-3i1Qe9/8x/hCHINujn+iuHy+mMRLoc77b2nI9TB0zjH1hvn9qGlXjWlggdwUcju36PkPCy/lpM7LLUdcTyH4Ow==", "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "^7.12.7", - "@babel/helper-optimise-call-expression": "^7.12.10", - "@babel/traverse": "^7.12.10", - "@babel/types": "^7.12.11" + "@babel/helper-member-expression-to-functions": "^7.14.5", + "@babel/helper-optimise-call-expression": "^7.14.5", + "@babel/traverse": "^7.14.5", + "@babel/types": "^7.14.5" } }, "@babel/helper-simple-access": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz", - "integrity": "sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.14.5.tgz", + "integrity": "sha512-nfBN9xvmCt6nrMZjfhkl7i0oTV3yxR4/FztsbOASyTvVcoYd0TRHh7eMLdlEcCqobydC0LAF3LtC92Iwxo0wyw==", "dev": true, "requires": { - "@babel/types": "^7.12.1" + "@babel/types": "^7.14.5" } }, "@babel/helper-split-export-declaration": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", - "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz", + "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==", "dev": true, "requires": { - "@babel/types": "^7.12.11" + "@babel/types": "^7.14.5" } }, "@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", + "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", + "dev": true + }, + "@babel/helper-validator-option": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", + "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", "dev": true }, "@babel/helpers": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.12.5.tgz", - "integrity": "sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA==", + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.14.6.tgz", + "integrity": "sha512-yesp1ENQBiLI+iYHSJdoZKUtRpfTlL1grDIX9NRlAVppljLw/4tTyYupIB7uIYmC3stW/imAv8EqaKaS/ibmeA==", "dev": true, "requires": { - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.12.5", - "@babel/types": "^7.12.5" + "@babel/template": "^7.14.5", + "@babel/traverse": "^7.14.5", + "@babel/types": "^7.14.5" } }, "@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.14.5", "chalk": "^2.0.0", "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "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==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } } }, "@babel/parser": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", - "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.7.tgz", + "integrity": "sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==", "dev": true }, "@babel/template": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", - "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", + "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", "dev": true, "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.12.7", - "@babel/types": "^7.12.7" + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.14.5", + "@babel/types": "^7.14.5" } }, "@babel/traverse": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", - "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.11", - "@babel/generator": "^7.12.11", - "@babel/helper-function-name": "^7.12.11", - "@babel/helper-split-export-declaration": "^7.12.11", - "@babel/parser": "^7.12.11", - "@babel/types": "^7.12.12", + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.7.tgz", + "integrity": "sha512-9vDr5NzHu27wgwejuKL7kIOm4bwEtaPQ4Z6cpCmjSuaRqpH/7xc4qcGEscwMqlkwgcXl6MvqoAjZkQ24uSdIZQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.14.5", + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-hoist-variables": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5", + "@babel/parser": "^7.14.7", + "@babel/types": "^7.14.5", "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.19" + "globals": "^11.1.0" + }, + "dependencies": { + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } } }, "@babel/types": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", - "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "lodash": "^4.17.19", + "@babel/helper-validator-identifier": "^7.14.5", "to-fast-properties": "^2.0.0" } }, "@eslint/eslintrc": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.2.2.tgz", - "integrity": "sha512-EfB5OHNYp1F4px/LI/FEnGylop7nOqkQ1LRzCM0KccA2U8tvV8w01KBv37LbO7nW4H+YhKyo2LcJhRwjjV17QQ==", + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.2.tgz", + "integrity": "sha512-8nmGq/4ycLpIwzvhI4tNDmQztZ8sp+hI7cyG8i1nQDhkAbRzHpXPidRAHlNvCZQpJTKw5ItIpMw9RSToGF00mg==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.1.1", "espree": "^7.3.0", - "globals": "^12.1.0", + "globals": "^13.9.0", "ignore": "^4.0.6", "import-fresh": "^3.2.1", "js-yaml": "^3.13.1", - "lodash": "^4.17.19", "minimatch": "^3.0.4", "strip-json-comments": "^3.1.1" }, "dependencies": { - "globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "dev": true, "requires": { - "type-fest": "^0.8.1" + "ms": "2.1.2" } }, "ignore": { @@ -320,6 +369,18 @@ "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "strip-json-comments": { + "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==", + "dev": true } } }, @@ -330,9 +391,9 @@ "dev": true }, "@glimmer/interfaces": { - "version": "0.56.1", - "resolved": "https://registry.npmjs.org/@glimmer/interfaces/-/interfaces-0.56.1.tgz", - "integrity": "sha512-+0KvSd7c9QmkEeCFHaBDub1DBeTONw+x6MZUcb/MlA3FfNis2aFs7kHVkjkdzp0Ust54Wn448dgWZFW27EuVJA==", + "version": "0.56.2", + "resolved": "https://registry.npmjs.org/@glimmer/interfaces/-/interfaces-0.56.2.tgz", + "integrity": "sha512-nRgcsTuyZ90aEoCuYVHKGDs3LpAv9n/JKiJ6iecpEYtyGgcPqSI3GjrJRl6k+1s5wnldEH1kjWq+ccCiXmA99w==", "dev": true, "requires": { "@simple-dom/interface": "^1.4.0" @@ -351,16 +412,50 @@ } }, "@glimmer/util": { - "version": "0.56.1", - "resolved": "https://registry.npmjs.org/@glimmer/util/-/util-0.56.1.tgz", - "integrity": "sha512-g7R5hMtZ2BLF+AsYhSE1xoh0gOJALof4/JL6zovYvqrsKTLYGK1Qe3RKXSt8dPav8Ac0LXt+cOd6jHPGSrEs+A==", + "version": "0.56.2", + "resolved": "https://registry.npmjs.org/@glimmer/util/-/util-0.56.2.tgz", + "integrity": "sha512-AljXCX5HBjJkmNt4DNYmJmVvwqKjFF4lU6e0SBftwhzK85RbETYwpb3YWrghcjSCxoodwIu1zNFiKOA+xD6txw==", "dev": true, "requires": { "@glimmer/env": "0.1.7", - "@glimmer/interfaces": "^0.56.1", + "@glimmer/interfaces": "^0.56.2", "@simple-dom/interface": "^1.4.0" } }, + "@humanwhocodes/config-array": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "dependencies": { + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "@humanwhocodes/object-schema": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", + "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", + "dev": true + }, "@iarna/toml": { "version": "2.2.5", "resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-2.2.5.tgz", @@ -378,18 +473,81 @@ "get-package-type": "^0.1.0", "js-yaml": "^3.13.1", "resolve-from": "^5.0.0" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + } } }, "@istanbuljs/schema": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", - "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true }, "@jest/types": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.2.tgz", - "integrity": "sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz", + "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -397,6 +555,57 @@ "@types/node": "*", "@types/yargs": "^16.0.0", "chalk": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "@jsbits/deep-clone": { @@ -406,17 +615,17 @@ "dev": true }, "@microsoft/api-extractor": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.16.0.tgz", - "integrity": "sha512-6CIpg4Iw4DWJszZMwYhh8OQ0bsmKq6CFjeCHfciDzmV+cUJ8ysJrO4LhYKNHEMOcfUYIv0EVoYul7/zMXTv9eA==", + "version": "7.18.1", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.18.1.tgz", + "integrity": "sha512-qljUF2Q0zAx1vJrjKkJVGN7OVbsXki+Pji99jywyl6L/FK3YZ7PpstUJYE6uBcLPy6rhNPWPAsHNTMpG/kHIsg==", "dev": true, "requires": { - "@microsoft/api-extractor-model": "7.13.2", + "@microsoft/api-extractor-model": "7.13.3", "@microsoft/tsdoc": "0.13.2", "@microsoft/tsdoc-config": "~0.15.2", - "@rushstack/node-core-library": "3.38.0", + "@rushstack/node-core-library": "3.39.0", "@rushstack/rig-package": "0.2.12", - "@rushstack/ts-command-line": "4.7.10", + "@rushstack/ts-command-line": "4.8.0", "colors": "~1.2.1", "lodash": "~4.17.15", "resolve": "~1.17.0", @@ -425,69 +634,6 @@ "typescript": "~4.3.2" }, "dependencies": { - "@microsoft/api-extractor-model": { - "version": "7.13.2", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.13.2.tgz", - "integrity": "sha512-gA9Q8q5TPM2YYk7rLinAv9KqcodrmRC13BVmNzLswjtFxpz13lRh0BmrqD01/sddGpGMIuWFYlfUM4VSWxnggA==", - "dev": true, - "requires": { - "@microsoft/tsdoc": "0.13.2", - "@microsoft/tsdoc-config": "~0.15.2", - "@rushstack/node-core-library": "3.38.0" - } - }, - "@rushstack/node-core-library": { - "version": "3.38.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.38.0.tgz", - "integrity": "sha512-cmvl0yQx8sSmbuXwiRYJi8TO+jpTtrLJQ8UmFHhKvgPVJAW8cV8dnpD1Xx/BvTGrJZ2XtRAIkAhBS9okBnap4w==", - "dev": true, - "requires": { - "@types/node": "10.17.13", - "colors": "~1.2.1", - "fs-extra": "~7.0.1", - "import-lazy": "~4.0.0", - "jju": "~1.4.0", - "resolve": "~1.17.0", - "semver": "~7.3.0", - "timsort": "~0.3.0", - "z-schema": "~3.18.3" - } - }, - "@types/node": { - "version": "10.17.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.13.tgz", - "integrity": "sha512-pMCcqU2zT4TjqYFrWtYHKal7Sl30Ims6ulZ4UFXxI4xbtQqK/qqKwkDoBFCfooRqqmRu9vY3xaJRwxSh673aYg==", - "dev": true - }, - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, "semver": { "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", @@ -496,12 +642,6 @@ "requires": { "lru-cache": "^6.0.0" } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true } } }, @@ -534,37 +674,41 @@ "resolve": "~1.19.0" }, "dependencies": { - "@microsoft/tsdoc": { - "version": "0.13.2", - "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.13.2.tgz", - "integrity": "sha512-WrHvO8PDL8wd8T2+zBGKrMwVL5IyzR3ryWUsl0PXgEV0QHup4mTLi0QcATefGI6Gx9Anu7vthPyyyLpY0EpiQg==", - "dev": true + "resolve": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "dev": true, + "requires": { + "is-core-module": "^2.1.0", + "path-parse": "^1.0.6" + } } } }, "@nodelib/fs.scandir": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz", - "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, "requires": { - "@nodelib/fs.stat": "2.0.4", + "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "@nodelib/fs.stat": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz", - "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true }, "@nodelib/fs.walk": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz", - "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, "requires": { - "@nodelib/fs.scandir": "2.1.4", + "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, @@ -577,13 +721,13 @@ } }, "@octokit/core": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.3.0.tgz", - "integrity": "sha512-GGMpjaodCBY7JrtOwfolMocwZw9Pj5NxuQqfaJhGau4tkyonm0JRV9D6juQYLMb1Kl261++4Q980o0FlAtg8jg==", + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.5.1.tgz", + "integrity": "sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw==", "requires": { "@octokit/auth-token": "^2.4.4", "@octokit/graphql": "^4.5.8", - "@octokit/request": "^5.4.12", + "@octokit/request": "^5.6.0", "@octokit/request-error": "^2.0.5", "@octokit/types": "^6.0.3", "before-after-hook": "^2.2.0", @@ -591,85 +735,69 @@ } }, "@octokit/endpoint": { - "version": "6.0.11", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.11.tgz", - "integrity": "sha512-fUIPpx+pZyoLW4GCs3yMnlj2LfoXTWDUVPTC4V3MUEKZm48W+XYpeWSZCv+vYF1ZABUm2CqnDVf1sFtIYrj7KQ==", + "version": "6.0.12", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz", + "integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==", "requires": { "@octokit/types": "^6.0.3", "is-plain-object": "^5.0.0", "universal-user-agent": "^6.0.0" - }, - "dependencies": { - "is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==" - } } }, "@octokit/graphql": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.6.1.tgz", - "integrity": "sha512-2lYlvf4YTDgZCTXTW4+OX+9WTLFtEUc6hGm4qM1nlZjzxj+arizM4aHWzBVBCxY9glh7GIs0WEuiSgbVzv8cmA==", + "version": "4.6.4", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.6.4.tgz", + "integrity": "sha512-SWTdXsVheRmlotWNjKzPOb6Js6tjSqA2a8z9+glDJng0Aqjzti8MEWOtuT8ZSu6wHnci7LZNuarE87+WJBG4vg==", "requires": { - "@octokit/request": "^5.3.0", + "@octokit/request": "^5.6.0", "@octokit/types": "^6.0.3", "universal-user-agent": "^6.0.0" } }, "@octokit/openapi-types": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-5.3.2.tgz", - "integrity": "sha512-NxF1yfYOUO92rCx3dwvA2onF30Vdlg7YUkMVXkeptqpzA3tRLplThhFleV/UKWFgh7rpKu1yYRbvNDUtzSopKA==" + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-8.2.1.tgz", + "integrity": "sha512-BJz6kWuL3n+y+qM8Pv+UGbSxH6wxKf/SBs5yzGufMHwDefsa+Iq7ZGy1BINMD2z9SkXlIzk1qiu988rMuGXEMg==" }, "@octokit/plugin-paginate-rest": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.11.0.tgz", - "integrity": "sha512-7L9xQank2G3r1dGqrVPo1z62V5utbykOUzlmNHPz87Pww/JpZQ9KyG5CHtUzgmB4n5iDRKYNK/86A8D98HP0yA==", + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.14.0.tgz", + "integrity": "sha512-S2uEu2uHeI7Vf+Lvj8tv3O5/5TCAa8GHS0dUQN7gdM7vKA6ZHAbR6HkAVm5yMb1mbedLEbxOuQ+Fa0SQ7tCDLA==", "requires": { - "@octokit/types": "^6.11.0" + "@octokit/types": "^6.18.0" } }, "@octokit/plugin-request-log": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.3.tgz", - "integrity": "sha512-4RFU4li238jMJAzLgAwkBAw+4Loile5haQMQr+uhFq27BmyJXcXSKvoQKqh0agsZEiUlW6iSv3FAgvmGkur7OQ==" + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz", + "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==" }, "@octokit/plugin-rest-endpoint-methods": { - "version": "4.13.5", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-4.13.5.tgz", - "integrity": "sha512-kYKcWkFm4Ldk8bZai2RVEP1z97k1C/Ay2FN9FNTBg7JIyKoiiJjks4OtT6cuKeZX39tqa+C3J9xeYc6G+6g8uQ==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.4.1.tgz", + "integrity": "sha512-Nx0g7I5ayAYghsLJP4Q1Ch2W9jYYM0FlWWWZocUro8rNxVwuZXGfFd7Rcqi9XDWepSXjg1WByiNJnZza2hIOvQ==", "requires": { - "@octokit/types": "^6.12.2", + "@octokit/types": "^6.18.1", "deprecation": "^2.3.1" } }, "@octokit/request": { - "version": "5.4.14", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.4.14.tgz", - "integrity": "sha512-VkmtacOIQp9daSnBmDI92xNIeLuSRDOIuplp/CJomkvzt7M18NXgG044Cx/LFKLgjKt9T2tZR6AtJayba9GTSA==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.0.tgz", + "integrity": "sha512-4cPp/N+NqmaGQwbh3vUsYqokQIzt7VjsgTYVXiwpUP2pxd5YiZB2XuTedbb0SPtv9XS7nzAKjAuQxmY8/aZkiA==", "requires": { "@octokit/endpoint": "^6.0.1", - "@octokit/request-error": "^2.0.0", - "@octokit/types": "^6.7.1", - "deprecation": "^2.0.0", + "@octokit/request-error": "^2.1.0", + "@octokit/types": "^6.16.1", "is-plain-object": "^5.0.0", "node-fetch": "^2.6.1", - "once": "^1.4.0", "universal-user-agent": "^6.0.0" - }, - "dependencies": { - "is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==" - } } }, "@octokit/request-error": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.0.5.tgz", - "integrity": "sha512-T/2wcCFyM7SkXzNoyVNWjyVlUwBvW3igM3Btr/eKYiPmucXTtkxt2RBsf6gn3LTzaLSLTQtNmvg+dGsOxQrjZg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz", + "integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==", "requires": { "@octokit/types": "^6.0.3", "deprecation": "^2.0.0", @@ -677,22 +805,22 @@ } }, "@octokit/rest": { - "version": "18.3.5", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.3.5.tgz", - "integrity": "sha512-ZPeRms3WhWxQBEvoIh0zzf8xdU2FX0Capa7+lTca8YHmRsO3QNJzf1H3PcuKKsfgp91/xVDRtX91sTe1kexlbw==", + "version": "18.6.7", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.6.7.tgz", + "integrity": "sha512-Kn6WrI2ZvmAztdx+HEaf88RuJn+LK72S8g6OpciE4kbZddAN84fu4fiPGxcEu052WmqKVnA/cnQsbNlrYC6rqQ==", "requires": { - "@octokit/core": "^3.2.3", + "@octokit/core": "^3.5.0", "@octokit/plugin-paginate-rest": "^2.6.2", "@octokit/plugin-request-log": "^1.0.2", - "@octokit/plugin-rest-endpoint-methods": "4.13.5" + "@octokit/plugin-rest-endpoint-methods": "5.4.1" } }, "@octokit/types": { - "version": "6.12.2", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.12.2.tgz", - "integrity": "sha512-kCkiN8scbCmSq+gwdJV0iLgHc0O/GTPY1/cffo9kECu1MvatLPh9E+qFhfRIktKfHEA6ZYvv6S1B4Wnv3bi3pA==", + "version": "6.18.1", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.18.1.tgz", + "integrity": "sha512-5YsddjO1U+xC8ZYKV8yZYebW55PCc7qiEEeZ+wZRr6qyclynzfyD65KZ5FdtIeP0/cANyFaD7hV69qElf1nMsQ==", "requires": { - "@octokit/openapi-types": "^5.3.2" + "@octokit/openapi-types": "^8.2.1" } }, "@rushstack/node-core-library": { @@ -720,31 +848,13 @@ }, "fs-extra": { "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", "dev": true, "requires": { - "path-parse": "^1.0.6" + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" } }, "semver": { @@ -755,12 +865,6 @@ "requires": { "lru-cache": "^6.0.0" } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true } } }, @@ -774,21 +878,18 @@ "strip-json-comments": "~3.1.1" }, "dependencies": { - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } + "strip-json-comments": { + "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==", + "dev": true } } }, "@rushstack/ts-command-line": { - "version": "4.7.10", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.7.10.tgz", - "integrity": "sha512-8t042g8eerypNOEcdpxwRA3uCmz0duMo21rG4Z2mdz7JxJeylDmzjlU3wDdef2t3P1Z61JCdZB6fbm1Mh0zi7w==", + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.8.0.tgz", + "integrity": "sha512-nZ8cbzVF1VmFPfSJfy8vEohdiFAH/59Y/Y+B4nsJbn4SkifLJ8LqNZ5+LxCC2UR242EXFumxlsY1d6fPBxck5Q==", "dev": true, "requires": { "@types/argparse": "1.0.38", @@ -809,9 +910,9 @@ "integrity": "sha512-/aPsuoj/1Dw/kzhkgz+ES6TxG0zfTMGLwuK2ZG00k/iJzYHTLCE8mVU8EPqEOp/lmxPoq1C1C9RYToRKb2KEfg==" }, "@sinonjs/commons": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.2.tgz", - "integrity": "sha512-sruwd86RJHdsVf/AtBoijDmUqJp3B6hF/DGC23C+JaegnDHaZyewCjoVGTdg3J0uz3Zs7NnIT05OBOmML72lQw==", + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", + "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", "dev": true, "requires": { "type-detect": "4.0.8" @@ -856,27 +957,6 @@ "colors": "~1.2.1", "js-yaml": "~3.13.1", "resolve": "~1.17.0" - }, - "dependencies": { - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - } } }, "@sosuisen/jsondiffpatch": { @@ -886,52 +966,6 @@ "requires": { "chalk": "^2.3.0", "diff-match-patch": "^1.0.0" - }, - "dependencies": { - "ansi-styles": { - "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==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } } }, "@sosuisen/nodegit": { @@ -959,19 +993,6 @@ "jsonfile": "^4.0.0", "universalify": "^0.1.0" } - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" } } }, @@ -990,28 +1011,28 @@ "dev": true }, "@types/async-lock": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@types/async-lock/-/async-lock-1.1.2.tgz", - "integrity": "sha512-j9n4bb6RhgFIydBe0+kpjnBPYumDaDyU8zvbWykyVMkku+c2CSu31MZkLeaBfqIwU+XCxlDpYDfyMQRkM0AkeQ==" + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@types/async-lock/-/async-lock-1.1.3.tgz", + "integrity": "sha512-UpeDcjGKsYEQMeqEbfESm8OWJI305I7b9KE4ji3aBjoKWyN5CTdn8izcA1FM1DVDne30R5fNEnIy89vZw5LXJQ==" }, "@types/cacheable-request": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.1.tgz", - "integrity": "sha512-ykFq2zmBGOCbpIXtoVbz4SKY5QriWPh3AjyU4G74RYbtt5yOc5OfaY75ftjg7mikMOla1CTGpX3lLbuJh8DTrQ==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", + "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", "requires": { "@types/http-cache-semantics": "*", "@types/keyv": "*", "@types/node": "*", "@types/responselike": "*" + }, + "dependencies": { + "@types/node": { + "version": "16.3.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.3.1.tgz", + "integrity": "sha512-N87VuQi7HEeRJkhzovao/JviiqKjDKMVKxKMfUvSKw+MbkbW8R0nA3fi/MQhhlxV2fQ+2ReM+/Nt4efdrJx3zA==" + } } }, - "@types/eslint-visitor-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", - "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==", - "dev": true, - "optional": true - }, "@types/expect": { "version": "24.3.0", "resolved": "https://registry.npmjs.org/@types/expect/-/expect-24.3.0.tgz", @@ -1022,18 +1043,18 @@ } }, "@types/fs-extra": { - "version": "9.0.6", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.6.tgz", - "integrity": "sha512-ecNRHw4clCkowNOBJH1e77nvbPxHYnWIXMv1IAoG/9+MYGkgoyr3Ppxr7XYFNL41V422EDhyV4/4SSK8L2mlig==", + "version": "9.0.12", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.12.tgz", + "integrity": "sha512-I+bsBr67CurCGnSenZZ7v94gd3tc3+Aj2taxMT4yu4ABLuOgOjeFxX3dokG24ztSRg5tnT00sL8BszO7gSMoIw==", "dev": true, "requires": { "@types/node": "*" } }, "@types/glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==", + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-w+LsMxKyYQm347Otw+IfBXOv9UWVjpHpCDdbBMt8Kz/xbvCYNjP+0qPh91Km3iKfSRLBB0P7fAMf0KHrPu+MyA==", "dev": true, "requires": { "@types/minimatch": "*", @@ -1041,9 +1062,9 @@ } }, "@types/http-cache-semantics": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.0.tgz", - "integrity": "sha512-c3Xy026kOF7QOTn00hbIllV1dLR9hG9NkSrLQgCVs8NF6sBU+VGWjD3wLPhmh1TYAc7ugCFsvHYMN4VcBN1U1A==" + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", + "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==" }, "@types/istanbul-lib-coverage": { "version": "2.0.3", @@ -1070,53 +1091,54 @@ } }, "@types/json-schema": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz", - "integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==", - "dev": true, - "optional": true - }, - "@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "version": "7.0.8", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.8.tgz", + "integrity": "sha512-YSBPTLTVm2e2OoQIDYx8HaeWJ5tTToLH67kXR7zYNGupXMEHa2++G8k+DczX2cFVgalypqtyZIcU19AFcmOpmg==", "dev": true }, "@types/keyv": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.1.tgz", - "integrity": "sha512-MPtoySlAZQ37VoLaPcTHCu1RWJ4llDkULYZIzOYxlhxBqYPB0RsRlmMU0R6tahtFe27mIdkHV+551ZWV4PLmVw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.2.tgz", + "integrity": "sha512-/FvAK2p4jQOaJ6CGDHJTqZcUtbZe820qIeTg7o0Shg7drB4JHeL+V/dhSaly7NXx6u8eSee+r7coT+yuJEvDLg==", "requires": { "@types/node": "*" + }, + "dependencies": { + "@types/node": { + "version": "16.3.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.3.1.tgz", + "integrity": "sha512-N87VuQi7HEeRJkhzovao/JviiqKjDKMVKxKMfUvSKw+MbkbW8R0nA3fi/MQhhlxV2fQ+2ReM+/Nt4efdrJx3zA==" + } } }, "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", "dev": true }, "@types/mocha": { - "version": "8.2.2", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.2.tgz", - "integrity": "sha512-Lwh0lzzqT5Pqh6z61P3c3P5nm6fzQK/MMHl9UKeneAeInVflBSz1O2EkX6gM6xfJd7FBXBY5purtLx7fUiZ7Hw==", + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.3.tgz", + "integrity": "sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw==", "dev": true }, "@types/node": { - "version": "14.14.20", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.20.tgz", - "integrity": "sha512-Y93R97Ouif9JEOWPIUyU+eyIdyRqQR0I8Ez1dzku4hDx34NWh4HbtIc3WNzwB1Y9ULvNGeu5B8h8bVL5cAk4/A==" + "version": "14.17.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.5.tgz", + "integrity": "sha512-bjqH2cX/O33jXT/UmReo2pM7DIJREPMnarixbQ57DOOzzFaI6D2+IcwaJQaJpv0M1E9TIhPCYVxrkcityLjlqA==", + "dev": true }, "@types/normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", + "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", "dev": true }, "@types/parse-git-config": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-git-config/-/parse-git-config-3.0.0.tgz", - "integrity": "sha512-5C14/81ohSwjB5I0EweuG3qyn6CqgVOgk9orxHDwVvUdDbS4FMXANXnKz3CA3H2Jk2oa3vzMEpXtDQ5u0dCcTQ==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/parse-git-config/-/parse-git-config-3.0.1.tgz", + "integrity": "sha512-cBVLXlpIpP23p+jQm8d2TrTfxyub3aiqfqgd0TWRnMqwCJMskYiveNJT11YwN+gbo3+0ZFFmtaepKzN7pxExlA==", "dev": true }, "@types/parse-json": { @@ -1131,12 +1153,19 @@ "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", "requires": { "@types/node": "*" + }, + "dependencies": { + "@types/node": { + "version": "16.3.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.3.1.tgz", + "integrity": "sha512-N87VuQi7HEeRJkhzovao/JviiqKjDKMVKxKMfUvSKw+MbkbW8R0nA3fi/MQhhlxV2fQ+2ReM+/Nt4efdrJx3zA==" + } } }, "@types/rimraf": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-3.0.0.tgz", - "integrity": "sha512-7WhJ0MdpFgYQPXlF4Dx+DhgvlPCfz/x5mHaeDQAKhcenvQP1KCpLQ18JklAqeGMYSAT2PxLpzd0g2/HE7fj7hQ==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-3.0.1.tgz", + "integrity": "sha512-CAoSlbco40aKZ0CkelBF2g3JeN6aioRaTVnqSX5pWsn/WApm6IDxI4e4tD9D0dY/meCkyyleP1IQDVN13F4maA==", "dev": true, "requires": { "@types/glob": "*", @@ -1153,46 +1182,46 @@ } }, "@types/sinonjs__fake-timers": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.2.tgz", - "integrity": "sha512-dIPoZ3g5gcx9zZEszaxLSVTvMReD3xxyyDnQUjA6IYDG9Ba2AV0otMPs+77sG9ojB4Qr2N2Vk5RnKeuA0X/0bg==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.3.tgz", + "integrity": "sha512-E1dU4fzC9wN2QK2Cr1MLCfyHM8BoNnRFvuf45LYMPNDA+WqbNzC45S4UzPxvp1fFJ1rvSGU0bPvdd35VLmXG8g==", "dev": true }, "@types/stack-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", - "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "dev": true }, "@types/unist": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz", - "integrity": "sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.5.tgz", + "integrity": "sha512-wnra4Vw9dopnuybR6HBywJ/URYpYrKLoepBTEtgfJup8Ahoi2zJECPP2cwiXp7btTvOT2CULv87aQRA4eZSP6g==", "dev": true }, "@types/yargs": { - "version": "16.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz", - "integrity": "sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ==", + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", "dev": true, "requires": { "@types/yargs-parser": "*" } }, "@types/yargs-parser": { - "version": "20.2.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.0.tgz", - "integrity": "sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==", + "version": "20.2.1", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", + "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.28.0.tgz", - "integrity": "sha512-KcF6p3zWhf1f8xO84tuBailV5cN92vhS+VT7UJsPzGBm9VnQqfI9AsiMUFUCYHTYPg1uCCo+HyiDnpDuvkAMfQ==", + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.28.2.tgz", + "integrity": "sha512-PGqpLLzHSxq956rzNGasO3GsAPf2lY9lDUBXhS++SKonglUmJypaUtcKzRtUte8CV7nruwnDxtLUKpVxs0wQBw==", "dev": true, "requires": { - "@typescript-eslint/experimental-utils": "4.28.0", - "@typescript-eslint/scope-manager": "4.28.0", + "@typescript-eslint/experimental-utils": "4.28.2", + "@typescript-eslint/scope-manager": "4.28.2", "debug": "^4.3.1", "functional-red-black-tree": "^1.0.1", "regexpp": "^3.1.0", @@ -1200,32 +1229,21 @@ "tsutils": "^3.21.0" }, "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.28.0.tgz", - "integrity": "sha512-eCALCeScs5P/EYjwo6se9bdjtrh8ByWjtHzOkC4Tia6QQWtQr3PHovxh3TdYTuFcurkYI4rmFsRFpucADIkseg==", + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "dev": true, "requires": { - "@typescript-eslint/types": "4.28.0", - "@typescript-eslint/visitor-keys": "4.28.0" + "ms": "2.1.2" } }, - "@typescript-eslint/types": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.28.0.tgz", - "integrity": "sha512-p16xMNKKoiJCVZY5PW/AfILw2xe1LfruTcfAKBj3a+wgNYP5I9ZEKNDOItoRt53p4EiPV6iRSICy8EPanG9ZVA==", + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "@typescript-eslint/visitor-keys": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.0.tgz", - "integrity": "sha512-PjJyTWwrlrvM5jazxYF5ZPs/nl0kHDZMVbuIcbpawVXaDPelp3+S9zpOz5RmVUfS/fD5l5+ZXNKnWhNYjPzCvw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.28.0", - "eslint-visitor-keys": "^2.0.0" - } - }, "semver": { "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", @@ -1234,158 +1252,76 @@ "requires": { "lru-cache": "^6.0.0" } - }, - "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } } } }, "@typescript-eslint/experimental-utils": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.28.0.tgz", - "integrity": "sha512-9XD9s7mt3QWMk82GoyUpc/Ji03vz4T5AYlHF9DcoFNfJ/y3UAclRsfGiE2gLfXtyC+JRA3trR7cR296TEb1oiQ==", + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.28.2.tgz", + "integrity": "sha512-MwHPsL6qo98RC55IoWWP8/opTykjTp4JzfPu1VfO2Z0MshNP0UZ1GEV5rYSSnZSUI8VD7iHvtIPVGW5Nfh7klQ==", "dev": true, "requires": { "@types/json-schema": "^7.0.7", - "@typescript-eslint/scope-manager": "4.28.0", - "@typescript-eslint/types": "4.28.0", - "@typescript-eslint/typescript-estree": "4.28.0", + "@typescript-eslint/scope-manager": "4.28.2", + "@typescript-eslint/types": "4.28.2", + "@typescript-eslint/typescript-estree": "4.28.2", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0" + } + }, + "@typescript-eslint/parser": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.28.2.tgz", + "integrity": "sha512-Q0gSCN51eikAgFGY+gnd5p9bhhCUAl0ERMiDKrTzpSoMYRubdB8MJrTTR/BBii8z+iFwz8oihxd0RAdP4l8w8w==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "4.28.2", + "@typescript-eslint/types": "4.28.2", + "@typescript-eslint/typescript-estree": "4.28.2", + "debug": "^4.3.1" }, "dependencies": { - "@types/json-schema": { - "version": "7.0.7", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", - "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", - "dev": true - }, - "@typescript-eslint/scope-manager": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.28.0.tgz", - "integrity": "sha512-eCALCeScs5P/EYjwo6se9bdjtrh8ByWjtHzOkC4Tia6QQWtQr3PHovxh3TdYTuFcurkYI4rmFsRFpucADIkseg==", + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "dev": true, "requires": { - "@typescript-eslint/types": "4.28.0", - "@typescript-eslint/visitor-keys": "4.28.0" + "ms": "2.1.2" } }, - "@typescript-eslint/types": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.28.0.tgz", - "integrity": "sha512-p16xMNKKoiJCVZY5PW/AfILw2xe1LfruTcfAKBj3a+wgNYP5I9ZEKNDOItoRt53p4EiPV6iRSICy8EPanG9ZVA==", + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.0.tgz", - "integrity": "sha512-m19UQTRtxMzKAm8QxfKpvh6OwQSXaW1CdZPoCaQuLwAq7VZMNuhJmZR4g5281s2ECt658sldnJfdpSZZaxUGMQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.28.0", - "@typescript-eslint/visitor-keys": "4.28.0", - "debug": "^4.3.1", - "globby": "^11.0.3", - "is-glob": "^4.0.1", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.0.tgz", - "integrity": "sha512-PjJyTWwrlrvM5jazxYF5ZPs/nl0kHDZMVbuIcbpawVXaDPelp3+S9zpOz5RmVUfS/fD5l5+ZXNKnWhNYjPzCvw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.28.0", - "eslint-visitor-keys": "^2.0.0" - } - }, - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^2.0.0" - } - }, - "globby": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", - "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" - } - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } } } }, - "@typescript-eslint/parser": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.28.0.tgz", - "integrity": "sha512-7x4D22oPY8fDaOCvkuXtYYTQ6mTMmkivwEzS+7iml9F9VkHGbbZ3x4fHRwxAb5KeuSkLqfnYjs46tGx2Nour4A==", - "dev": true, - "requires": { - "@typescript-eslint/scope-manager": "4.28.0", - "@typescript-eslint/types": "4.28.0", - "@typescript-eslint/typescript-estree": "4.28.0", - "debug": "^4.3.1" - } - }, "@typescript-eslint/scope-manager": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.28.0.tgz", - "integrity": "sha512-eCALCeScs5P/EYjwo6se9bdjtrh8ByWjtHzOkC4Tia6QQWtQr3PHovxh3TdYTuFcurkYI4rmFsRFpucADIkseg==", + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.28.2.tgz", + "integrity": "sha512-MqbypNjIkJFEFuOwPWNDjq0nqXAKZvDNNs9yNseoGBB1wYfz1G0WHC2AVOy4XD7di3KCcW3+nhZyN6zruqmp2A==", "dev": true, "requires": { - "@typescript-eslint/types": "4.28.0", - "@typescript-eslint/visitor-keys": "4.28.0" + "@typescript-eslint/types": "4.28.2", + "@typescript-eslint/visitor-keys": "4.28.2" } }, "@typescript-eslint/types": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.28.0.tgz", - "integrity": "sha512-p16xMNKKoiJCVZY5PW/AfILw2xe1LfruTcfAKBj3a+wgNYP5I9ZEKNDOItoRt53p4EiPV6iRSICy8EPanG9ZVA==", + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.28.2.tgz", + "integrity": "sha512-Gr15fuQVd93uD9zzxbApz3wf7ua3yk4ZujABZlZhaxxKY8ojo448u7XTm/+ETpy0V0dlMtj6t4VdDvdc0JmUhA==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.0.tgz", - "integrity": "sha512-m19UQTRtxMzKAm8QxfKpvh6OwQSXaW1CdZPoCaQuLwAq7VZMNuhJmZR4g5281s2ECt658sldnJfdpSZZaxUGMQ==", + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.2.tgz", + "integrity": "sha512-86lLstLvK6QjNZjMoYUBMMsULFw0hPHJlk1fzhAVoNjDBuPVxiwvGuPQq3fsBMCxuDJwmX87tM/AXoadhHRljg==", "dev": true, "requires": { - "@typescript-eslint/types": "4.28.0", - "@typescript-eslint/visitor-keys": "4.28.0", + "@typescript-eslint/types": "4.28.2", + "@typescript-eslint/visitor-keys": "4.28.2", "debug": "^4.3.1", "globby": "^11.0.3", "is-glob": "^4.0.1", @@ -1393,6 +1329,21 @@ "tsutils": "^3.21.0" }, "dependencies": { + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, "semver": { "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", @@ -1401,25 +1352,16 @@ "requires": { "lru-cache": "^6.0.0" } - }, - "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } } } }, "@typescript-eslint/visitor-keys": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.0.tgz", - "integrity": "sha512-PjJyTWwrlrvM5jazxYF5ZPs/nl0kHDZMVbuIcbpawVXaDPelp3+S9zpOz5RmVUfS/fD5l5+ZXNKnWhNYjPzCvw==", + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.2.tgz", + "integrity": "sha512-aT2B4PLyyRDUVUafXzpZFoc0C9t0za4BJAKP5sgWIhG+jHECQZUEjuQSCIwZdiJJ4w4cgu5r3Kh20SOdtEBl0w==", "dev": true, "requires": { - "@typescript-eslint/types": "4.28.0", + "@typescript-eslint/types": "4.28.2", "eslint-visitor-keys": "^2.0.0" } }, @@ -1441,9 +1383,9 @@ "dev": true }, "acorn-jsx": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", - "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true }, "aggregate-error": { @@ -1493,24 +1435,22 @@ "dev": true }, "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" }, "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, + "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==", "requires": { - "color-convert": "^2.0.1" + "color-convert": "^1.9.0" } }, "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", "dev": true, "requires": { "normalize-path": "^3.0.0", @@ -1562,15 +1502,15 @@ } }, "array-includes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.2.tgz", - "integrity": "sha512-w2GspexNQpx+PutG3QpT437/BenZBj0M/MZGn5mzv/MofYqo0xmRHzn4lFsoDlWJ+THYsGJmFlW68WlDFx7VRw==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", + "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==", "dev": true, "requires": { - "call-bind": "^1.0.0", + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1", - "get-intrinsic": "^1.0.1", + "es-abstract": "^1.18.0-next.2", + "get-intrinsic": "^1.1.1", "is-string": "^1.0.5" } }, @@ -1647,28 +1587,6 @@ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" }, - "babel-eslint": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", - "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.0", - "@babel/traverse": "^7.7.0", - "@babel/types": "^7.7.0", - "eslint-visitor-keys": "^1.0.0", - "resolve": "^1.12.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } - } - }, "bail": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", @@ -1676,9 +1594,9 @@ "dev": true }, "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "bcrypt-pbkdf": { "version": "1.0.2", @@ -1689,9 +1607,9 @@ } }, "before-after-hook": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.0.tgz", - "integrity": "sha512-jH6rKQIfroBbhEXVmI7XmXe3ix5S/PgJqpzdDPnR8JGLHWNYLsYZ6tK5iWOF/Ra3oqEX0NobXGlzbiylIzVphQ==" + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz", + "integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ==" }, "binary-extensions": { "version": "2.2.0", @@ -1709,9 +1627,9 @@ } }, "blob-polyfill": { - "version": "4.0.20200601", - "resolved": "https://registry.npmjs.org/blob-polyfill/-/blob-polyfill-4.0.20200601.tgz", - "integrity": "sha512-1jB6WOIp6IDxNyng5+9A8g/f0uiphib2ELCN+XAnlssinsW8s1k4VYG9b1TxIUd3pdm9RJSLQuBh6iohYmD4hA==" + "version": "5.0.20210201", + "resolved": "https://registry.npmjs.org/blob-polyfill/-/blob-polyfill-5.0.20210201.tgz", + "integrity": "sha512-SrH6IG6aXL9pCgSysBCiDpGcAJ1j6/c1qCwR3sTEQJhb+MTk6FITNA6eW6WNYQDNZVi4Z9GjxH5v2MMTv59CrQ==" }, "brace-expansion": { "version": "1.1.11", @@ -1737,6 +1655,19 @@ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, + "browserslist": { + "version": "4.16.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", + "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001219", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.723", + "escalade": "^3.1.1", + "node-releases": "^1.1.71" + } + }, "buffer-alloc": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", @@ -1771,27 +1702,17 @@ } }, "cacheable-request": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.1.tgz", - "integrity": "sha512-lt0mJ6YAnsrBErpTMWeu5kl/tg9xMAWjavYTN6VQXM1A/teBITuNcccXsCxF0tDQQJf9DfAaX5O4e0zp0KlfZw==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", + "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", "requires": { "clone-response": "^1.0.2", "get-stream": "^5.1.0", "http-cache-semantics": "^4.0.0", "keyv": "^4.0.0", "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", + "normalize-url": "^6.0.1", "responselike": "^2.0.0" - }, - "dependencies": { - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "requires": { - "pump": "^3.0.0" - } - } } }, "caching-transform": { @@ -1807,13 +1728,13 @@ } }, "call-bind": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.0.tgz", - "integrity": "sha512-AEXsYIyyDY3MCzbwdhzG3Jx1R0J2wetQyUynn6dYHAO+bg8l1k7jwZtRv4ryryFs7EP+NDlikJlVe59jr0cM2w==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", "dev": true, "requires": { "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.0" + "get-intrinsic": "^1.0.2" } }, "callsites": { @@ -1823,9 +1744,15 @@ "dev": true }, "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30001243", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001243.tgz", + "integrity": "sha512-vNxw9mkTBtkmLFnJRv/2rhs1yufpDfCkBZexG3Y0xdOH2Z/eE/85E4Dl5j1YUN34nZVsSp6vVRFQRrez9wJMRA==", "dev": true }, "caseless": { @@ -1834,13 +1761,13 @@ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" }, "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, "character-entities": { @@ -1930,14 +1857,48 @@ "dev": true }, "cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "requires": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" + "wrap-ansi": "^7.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } } }, "clone-response": { @@ -1967,18 +1928,22 @@ "dev": true }, "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "requires": { - "color-name": "~1.1.4" + "color-name": "1.1.3" } }, "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "colorette": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", "dev": true }, "colors": { @@ -2030,9 +1995,9 @@ "dev": true }, "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", "dev": true, "requires": { "safe-buffer": "~5.1.1" @@ -2054,12 +2019,26 @@ "parse-json": "^5.0.0", "path-type": "^4.0.0", "yaml": "^1.10.0" + }, + "dependencies": { + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + } } }, "coveralls": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.1.0.tgz", - "integrity": "sha512-sHxOu2ELzW8/NC1UP5XVLbZDzO4S3VxfFye3XYCznopHy02YjNkHcj5bKaVw2O7hVaBdBjEdQGpie4II1mWhuQ==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.1.1.tgz", + "integrity": "sha512-+dxnG2NHncSD1NrqbSM3dn/lE57O6Qf/koe9+I7c+wzkqRmEvcp0kgJdxKInzYzkICKkFMZsX3Vct3++tsF9ww==", "dev": true, "requires": { "js-yaml": "^3.13.1", @@ -2095,12 +2074,12 @@ } }, "cross-blob": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/cross-blob/-/cross-blob-2.0.0.tgz", - "integrity": "sha512-NWzFuyG4GTZnM9MtQvjPYVlO12lZCSBdoHIHCZl9WKShsK3CqO+bEH7nuKwlVomlByb37XvT6nVY5uQxDBmk5Q==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/cross-blob/-/cross-blob-2.0.1.tgz", + "integrity": "sha512-ARuKPPo3I6DSqizal4UCyMCiGPQdMpMJS3Owx6Lleuh26vSt2UnfWRwbMLCYqbJUrcol+KzGVSLR91ezSHP80A==", "requires": { - "blob-polyfill": "^4.0.20200601", - "fetch-blob": "^2.0.1" + "blob-polyfill": "^5.0.20210201", + "fetch-blob": "^2.1.2" } }, "cross-env": { @@ -2110,40 +2089,19 @@ "dev": true, "requires": { "cross-spawn": "^7.0.1" + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" }, "dependencies": { - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -2170,18 +2128,17 @@ "dev": true }, "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "requires": { - "ms": "2.1.2" + "ms": "^2.1.1" } }, "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", "dev": true }, "decompress-response": { @@ -2222,12 +2179,20 @@ "dev": true, "requires": { "strip-bom": "^4.0.0" + }, + "dependencies": { + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true + } } }, "defer-to-connect": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.0.tgz", - "integrity": "sha512-bYL2d05vOSf1JEZNx5vSAtPuBMkX8K9EUutg7zlKvTqKXHt7RhWJFbmd7qakVuf13i+IkGmp6FwSsONOf6VYIg==" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==" }, "define-properties": { "version": "1.1.3", @@ -2276,9 +2241,9 @@ "integrity": "sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==" }, "diff-sequences": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.1.tgz", - "integrity": "sha512-XPLijkfJUh/PIBnfkcSHgvD6tlYixmcMAn3osTk6jt+H0v/mgURto1XUiD9DKuGX5NDoVS6dSlA23gd9FUaCFg==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz", + "integrity": "sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==", "dev": true }, "diff3": { @@ -2340,6 +2305,12 @@ "yallist": "^2.1.2" } }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", @@ -2354,6 +2325,12 @@ "integrity": "sha512-MMadSSVRDb4uKdxV6bCXXN4cTsxIsXYtV4XdPu6FOCSAw6zsCIDA+QEktEU+u6h+c/mTrul5NR+pwFpPxwetiQ==", "dev": true }, + "electron-to-chromium": { + "version": "1.3.772", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.772.tgz", + "integrity": "sha512-X/6VRCXWALzdX+RjCtBU6cyg8WZgoxm9YA02COmDOiNJEZ59WkQggDbWZ4t/giHi/3GS+cvdrP6gbLISANAGYA==", + "dev": true + }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -2387,23 +2364,27 @@ } }, "es-abstract": { - "version": "1.18.0-next.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", - "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz", + "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==", "dev": true, "requires": { + "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-negative-zero": "^2.0.0", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", + "has-symbols": "^1.0.2", + "is-callable": "^1.2.3", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.3", + "is-string": "^1.0.6", + "object-inspect": "^1.10.3", "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" } }, "es-to-primitive": { @@ -2435,29 +2416,32 @@ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "eslint": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.17.0.tgz", - "integrity": "sha512-zJk08MiBgwuGoxes5sSQhOtibZ75pz0J35XTRlZOk9xMffhpA9BTbQZxoXZzOl5zMbleShbGwtw+1kGferfFwQ==", + "version": "7.30.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.30.0.tgz", + "integrity": "sha512-VLqz80i3as3NdloY44BQSJpFw534L9Oh+6zJOUaViV4JPd+DaHwutqP7tcpkW3YiXbK6s05RZl7yl7cQn+lijg==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "@eslint/eslintrc": "^0.2.2", + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.2", + "@humanwhocodes/config-array": "^0.5.0", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.0.1", "doctrine": "^3.0.0", "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", "eslint-scope": "^5.1.1", "eslint-utils": "^2.1.0", "eslint-visitor-keys": "^2.0.0", "espree": "^7.3.1", - "esquery": "^1.2.0", + "esquery": "^1.4.0", "esutils": "^2.0.2", - "file-entry-cache": "^6.0.0", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^12.1.0", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", "ignore": "^4.0.6", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", @@ -2465,7 +2449,7 @@ "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", - "lodash": "^4.17.19", + "lodash.merge": "^4.6.2", "minimatch": "^3.0.4", "natural-compare": "^1.4.0", "optionator": "^0.9.1", @@ -2474,113 +2458,141 @@ "semver": "^7.2.1", "strip-ansi": "^6.0.0", "strip-json-comments": "^3.1.0", - "table": "^6.0.4", + "table": "^6.0.9", "text-table": "^0.2.0", "v8-compile-cache": "^2.0.3" }, "dependencies": { - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dev": true, "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "@babel/highlight": "^7.10.4" } }, - "globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "type-fest": "^0.8.1" + "color-convert": "^2.0.1" } }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "dev": true, "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" + "ms": "2.1.2" } }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } } }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "semver": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", - "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, "requires": { "lru-cache": "^6.0.0" } }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { - "shebang-regex": "^3.0.0" + "ansi-regex": "^5.0.0" } }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "strip-json-comments": { + "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==", "dev": true }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { - "isexe": "^2.0.0" + "has-flag": "^4.0.0" } } } @@ -2605,126 +2617,29 @@ } }, "eslint-config-standard": { - "version": "14.1.1", - "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-14.1.1.tgz", - "integrity": "sha512-Z9B+VR+JIXRxz21udPTL9HpFMyoMUEeX1G251EQ6e05WD9aPVtVBn09XUmZ259wCMlCDmYDSZG62Hhm+ZTJcUg==", + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-16.0.3.tgz", + "integrity": "sha512-x4fmJL5hGqNJKGHSjnLdgA6U6h1YW/G2dW9fA+cyVur4SK6lyue8+UgNKWlZtUDTXvgKDD/Oa3GQjmB5kjtVvg==", "dev": true }, "eslint-config-standardize": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/eslint-config-standardize/-/eslint-config-standardize-0.7.1.tgz", - "integrity": "sha512-8tut4nppZ+kpOHPa/AG8Wzr/HAEmNGnJXrGa10dCBKmNGaBsXtLkYL1hb1s80EGyw1JchIyHOpy/z9vHWeqAeQ==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/eslint-config-standardize/-/eslint-config-standardize-0.7.2.tgz", + "integrity": "sha512-n2dt7la221Qig7FjQsrKn5NyK5jSEkkAy7xWSnY96XdG7H9FcUSDt5I1THyA6zHwEYcAtUFv8VOPBOK6oYEvfg==", "dev": true, "requires": { "@jsbits/deep-clone": "~1.1.1", - "@typescript-eslint/eslint-plugin": "~3.9.0", - "@typescript-eslint/parser": "~3.9.0", + "@typescript-eslint/eslint-plugin": "^4.14.0", + "@typescript-eslint/parser": "^4.14.0", "confusing-browser-globals": "*", "deepmerge": "~4.2.2", - "eslint-config-standard": "~14.1.1", - "eslint-plugin-import": "~2.22.0", + "eslint-config-standard": "~16.0.2", + "eslint-plugin-import": "~2.22.1", "eslint-plugin-node": "~11.1.0", "eslint-plugin-promise": "~4.2.1", - "eslint-plugin-react": "~7.20.5", - "eslint-plugin-react-hooks": "~4.0.8", - "eslint-plugin-standard": "~4.0.1", - "eslint-plugin-unicorn": "~21.0.0" - }, - "dependencies": { - "@typescript-eslint/eslint-plugin": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.9.1.tgz", - "integrity": "sha512-XIr+Mfv7i4paEdBf0JFdIl9/tVxyj+rlilWIfZ97Be0lZ7hPvUbS5iHt9Glc8kRI53dsr0PcAEudbf8rO2wGgg==", - "dev": true, - "optional": true, - "requires": { - "@typescript-eslint/experimental-utils": "3.9.1", - "debug": "^4.1.1", - "functional-red-black-tree": "^1.0.1", - "regexpp": "^3.0.0", - "semver": "^7.3.2", - "tsutils": "^3.17.1" - } - }, - "@typescript-eslint/experimental-utils": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-3.9.1.tgz", - "integrity": "sha512-lkiZ8iBBaYoyEKhCkkw4SAeatXyBq9Ece5bZXdLe1LWBUwTszGbmbiqmQbwWA8cSYDnjWXp9eDbXpf9Sn0hLAg==", - "dev": true, - "optional": true, - "requires": { - "@types/json-schema": "^7.0.3", - "@typescript-eslint/types": "3.9.1", - "@typescript-eslint/typescript-estree": "3.9.1", - "eslint-scope": "^5.0.0", - "eslint-utils": "^2.0.0" - } - }, - "@typescript-eslint/parser": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-3.9.1.tgz", - "integrity": "sha512-y5QvPFUn4Vl4qM40lI+pNWhTcOWtpZAJ8pOEQ21fTTW4xTJkRplMjMRje7LYTXqVKKX9GJhcyweMz2+W1J5bMg==", - "dev": true, - "optional": true, - "requires": { - "@types/eslint-visitor-keys": "^1.0.0", - "@typescript-eslint/experimental-utils": "3.9.1", - "@typescript-eslint/types": "3.9.1", - "@typescript-eslint/typescript-estree": "3.9.1", - "eslint-visitor-keys": "^1.1.0" - } - }, - "@typescript-eslint/types": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-3.9.1.tgz", - "integrity": "sha512-15JcTlNQE1BsYy5NBhctnEhEoctjXOjOK+Q+rk8ugC+WXU9rAcS2BYhoh6X4rOaXJEpIYDl+p7ix+A5U0BqPTw==", - "dev": true, - "optional": true - }, - "@typescript-eslint/typescript-estree": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-3.9.1.tgz", - "integrity": "sha512-IqM0gfGxOmIKPhiHW/iyAEXwSVqMmR2wJ9uXHNdFpqVvPaQ3dWg302vW127sBpAiqM9SfHhyS40NKLsoMpN2KA==", - "dev": true, - "optional": true, - "requires": { - "@typescript-eslint/types": "3.9.1", - "@typescript-eslint/visitor-keys": "3.9.1", - "debug": "^4.1.1", - "glob": "^7.1.6", - "is-glob": "^4.0.1", - "lodash": "^4.17.15", - "semver": "^7.3.2", - "tsutils": "^3.17.1" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-3.9.1.tgz", - "integrity": "sha512-zxdtUjeoSh+prCpogswMwVUJfEFmCOjdzK9rpNjNBfm6EyPt99x3RrJoBOGZO23FCt0WPKUCOL5mb/9D5LjdwQ==", - "dev": true, - "optional": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - } - }, - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "optional": true - }, - "semver": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", - "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", - "dev": true, - "optional": true, - "requires": { - "lru-cache": "^6.0.0" - } - } + "eslint-plugin-react": "~7.22.0", + "eslint-plugin-react-hooks": "~4.2.0", + "eslint-plugin-unicorn": "~26.0.1" } }, "eslint-import-resolver-node": { @@ -2755,88 +2670,13 @@ } }, "eslint-module-utils": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz", - "integrity": "sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.1.tgz", + "integrity": "sha512-ZXI9B8cxAJIH4nfkhTwcRTEAnrVfobYqwjWy/QMCZ8rHkZHFjf9yO4BzpiF9kCSfNlMG54eKigISHpX0+AaT4A==", "dev": true, "requires": { - "debug": "^2.6.9", + "debug": "^3.2.7", "pkg-dir": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "dev": true, - "requires": { - "find-up": "^2.1.0" - } - } } }, "eslint-plugin-es": { @@ -2847,6 +2687,23 @@ "requires": { "eslint-utils": "^2.0.0", "regexpp": "^3.0.0" + }, + "dependencies": { + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } } }, "eslint-plugin-import": { @@ -2889,90 +2746,11 @@ "isarray": "^1.0.0" } }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", - "dev": true, - "requires": { - "pify": "^2.0.0" - } - }, - "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", - "dev": true, - "requires": { - "load-json-file": "^2.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" - } - }, - "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" - } } } }, @@ -2990,6 +2768,21 @@ "semver": "^6.1.0" }, "dependencies": { + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -3016,21 +2809,21 @@ "dev": true }, "eslint-plugin-react": { - "version": "7.20.6", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.20.6.tgz", - "integrity": "sha512-kidMTE5HAEBSLu23CUDvj8dc3LdBU0ri1scwHBZjI41oDv4tjsWZKU7MQccFzH1QYPYhsnTF2ovh7JlcIcmxgg==", + "version": "7.22.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.22.0.tgz", + "integrity": "sha512-p30tuX3VS+NWv9nQot9xIGAHBXR0+xJVaZriEsHoJrASGCJZDJ8JLNM0YqKqI0AKm6Uxaa1VUHoNEibxRCMQHA==", "dev": true, "requires": { "array-includes": "^3.1.1", "array.prototype.flatmap": "^1.2.3", "doctrine": "^2.1.0", "has": "^1.0.3", - "jsx-ast-utils": "^2.4.1", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", "object.entries": "^1.1.2", "object.fromentries": "^2.0.2", "object.values": "^1.1.1", "prop-types": "^15.7.2", - "resolve": "^1.17.0", + "resolve": "^1.18.1", "string.prototype.matchall": "^4.0.2" }, "dependencies": { @@ -3042,59 +2835,167 @@ "requires": { "esutils": "^2.0.2" } + }, + "resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dev": true, + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } } } }, "eslint-plugin-react-hooks": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.0.8.tgz", - "integrity": "sha512-6SSb5AiMCPd8FDJrzah+Z4F44P2CdOaK026cXFV+o/xSRzfOiV1FNFeLl2z6xm3yqWOQEZ5OfVgiec90qV2xrQ==", - "dev": true - }, - "eslint-plugin-standard": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-4.0.2.tgz", - "integrity": "sha512-nKptN8l7jksXkwFk++PhJB3cCDTcXOEyhISIN86Ue2feJ1LFyY3PrY3/xT2keXlJSY5bpmbiTG0f885/YKAvTA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.2.0.tgz", + "integrity": "sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ==", "dev": true }, "eslint-plugin-unicorn": { - "version": "21.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-21.0.0.tgz", - "integrity": "sha512-S8v7+v4gZTQPj4pKKvexhgSUaLQSyItvxW2SVZDaX9Iu5IjlAmF2eni+L6w8a2aqshxgU8Lle4FIAVDtuejSKQ==", + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-26.0.1.tgz", + "integrity": "sha512-SWgF9sIVY74zqkkSN2dclSCqRfocWSUGD0haC0NX2oRfmdp9p8dQvJYkYSQePaCyssPUE/pqpsIEEZNTh8crUA==", "dev": true, "requires": { "ci-info": "^2.0.0", "clean-regexp": "^1.0.0", "eslint-ast-utils": "^1.1.0", - "eslint-template-visitor": "^2.0.0", + "eslint-template-visitor": "^2.2.2", "eslint-utils": "^2.1.0", - "import-modules": "^2.0.0", - "lodash": "^4.17.15", + "import-modules": "^2.1.0", + "lodash": "^4.17.20", "pluralize": "^8.0.0", "read-pkg-up": "^7.0.1", "regexp-tree": "^0.1.21", "reserved-words": "^0.1.2", "safe-regex": "^2.1.1", - "semver": "^7.3.2" + "semver": "^7.3.4" }, "dependencies": { - "safe-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz", - "integrity": "sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==", + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", "dev": true, "requires": { - "regexp-tree": "~0.1.1" + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" } }, "semver": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", - "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, "requires": { "lru-cache": "^6.0.0" } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true } } }, @@ -3109,38 +3010,31 @@ } }, "eslint-template-visitor": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/eslint-template-visitor/-/eslint-template-visitor-2.2.2.tgz", - "integrity": "sha512-SkcLjzKw3JjKTWHacRDeLBa2gxb600zbCKTkXj/V97QnZ9yxkknoPL8vc8PFueqbFXP7mYNTQzjCjcMpTRdRaA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/eslint-template-visitor/-/eslint-template-visitor-2.3.2.tgz", + "integrity": "sha512-3ydhqFpuV7x1M9EK52BPNj6V0Kwu0KKkcIAfpUhwHbR8ocRln/oUHgfxQupY8O1h4Qv/POHDumb/BwwNfxbtnA==", "dev": true, "requires": { - "babel-eslint": "^10.1.0", + "@babel/core": "^7.12.16", + "@babel/eslint-parser": "^7.12.16", "eslint-visitor-keys": "^2.0.0", "esquery": "^1.3.1", "multimap": "^1.1.0" } }, "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", "dev": true, "requires": { - "eslint-visitor-keys": "^1.1.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } + "eslint-visitor-keys": "^2.0.0" } }, "eslint-visitor-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", - "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", "dev": true }, "espree": { @@ -3169,9 +3063,9 @@ "dev": true }, "esquery": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", - "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", "dev": true, "requires": { "estraverse": "^5.1.0" @@ -3220,17 +3114,17 @@ "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==" }, "expect": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.0.2.tgz", - "integrity": "sha512-YJFNJe2+P2DqH+ZrXy+ydRQYO87oxRUonZImpDodR1G7qo3NYd3pL+NQ9Keqpez3cehczYwZDBC3A7xk3n7M/w==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.0.6.tgz", + "integrity": "sha512-psNLt8j2kwg42jGBDSfAlU49CEZxejN1f1PlANWDZqIhBOVU/c2Pm888FcjWJzFewhIsNWfZJeLjUjtKGiPuSw==", "dev": true, "requires": { - "@jest/types": "^27.0.2", + "@jest/types": "^27.0.6", "ansi-styles": "^5.0.0", - "jest-get-type": "^27.0.1", - "jest-matcher-utils": "^27.0.2", - "jest-message-util": "^27.0.2", - "jest-regex-util": "^27.0.1" + "jest-get-type": "^27.0.6", + "jest-matcher-utils": "^27.0.6", + "jest-message-util": "^27.0.6", + "jest-regex-util": "^27.0.6" }, "dependencies": { "ansi-styles": { @@ -3263,17 +3157,16 @@ "dev": true }, "fast-glob": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", - "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", + "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.0", + "glob-parent": "^5.1.2", "merge2": "^1.3.0", - "micromatch": "^4.0.2", - "picomatch": "^2.2.1" + "micromatch": "^4.0.4" } }, "fast-json-stable-stringify": { @@ -3288,9 +3181,9 @@ "dev": true }, "fastq": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.10.0.tgz", - "integrity": "sha512-NL2Qc5L3iQEsyYzweq7qfgy5OtXCmGzGvhElGEd/SoFWEMOEczNh5s5ocaF01HDetxz+p8ecjNPA6cZxxIHmzA==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.1.tgz", + "integrity": "sha512-HOnr8Mc60eNYl1gzwp6r5RoUyAn5/glBolUzP/Ez6IFVPMPirxn/9phgL6zhOtaTy7ISwPvQ+wT+hfcRZh/bzw==", "dev": true, "requires": { "reusify": "^1.0.4" @@ -3302,9 +3195,9 @@ "integrity": "sha512-YKqtUDwqLyfyMnmbw8XD6Q8j9i/HggKtPEI+pZ1+8bvheBu78biSmNaXWusx1TauGqtUUGx/cBb1mKdq2rLYow==" }, "file-entry-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.0.tgz", - "integrity": "sha512-fqoO76jZ3ZnYrXLDRxBR1YvOvc0k844kcOg40bgsPrE25LAb/PDqTY+ho64Xh2c8ZXgIKldchCFHczG2UVRcWA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, "requires": { "flat-cache": "^3.0.4" @@ -3328,6 +3221,66 @@ "commondir": "^1.0.1", "make-dir": "^3.0.2", "pkg-dir": "^4.1.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + } } }, "find-parent-dir": { @@ -3343,13 +3296,12 @@ "dev": true }, "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", "dev": true, "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "locate-path": "^2.0.0" } }, "flat": { @@ -3368,69 +3320,26 @@ "rimraf": "^3.0.2" } }, - "flatted": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.0.tgz", - "integrity": "sha512-tW+UkmtNg/jv9CSofAKvgVcO7c2URjhTdW1ZTkcAritblu8tajiYy7YisnIflEwtKssCtOxpnBRoCB7iap0/TA==", - "dev": true - }, - "flatten": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.3.tgz", - "integrity": "sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg==", - "dev": true - }, - "foreground-child": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", - "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.0", - "signal-exit": "^3.0.2" - }, - "dependencies": { - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } + "flatted": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.1.tgz", + "integrity": "sha512-OMQjaErSFHmHqZe+PSidH5n8j3O0F2DdnVh8JB4j4eUQ2k6KvB0qGfrKIhapvez5JerBbmWkaLYUYWISaESoXg==", + "dev": true + }, + "flatten": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.3.tgz", + "integrity": "sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg==", + "dev": true + }, + "foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" } }, "forever-agent": { @@ -3468,6 +3377,22 @@ "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" + }, + "dependencies": { + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" + } } }, "fs-minipass": { @@ -3515,39 +3440,6 @@ "string-width": "^1.0.1", "strip-ansi": "^3.0.1", "wide-align": "^1.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "^2.0.0" - } - } } }, "gensync": { @@ -3563,9 +3455,9 @@ "dev": true }, "get-intrinsic": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.0.2.tgz", - "integrity": "sha512-aeX0vrFm21ILl3+JpFFRNe9aUvp6VFZb2/CTbgLb8j75kOhvoNYjt9d8KA/tJG4gSo8nzEDedRl0h7vDmBYRVg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", "dev": true, "requires": { "function-bind": "^1.1.1", @@ -3585,6 +3477,14 @@ "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", "dev": true }, + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "requires": { + "pump": "^3.0.0" + } + }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -3600,9 +3500,9 @@ "dev": true }, "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -3613,19 +3513,30 @@ } }, "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "requires": { "is-glob": "^4.0.1" } }, "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true + "version": "13.10.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.10.0.tgz", + "integrity": "sha512-piHC3blgLGFjvOuMmWZX60f+na1lXFDhQXBf1UYp2fXPXqvEUbOhNwi6BsQ0bQishwedgnjkwv1d9zKf+MWw3g==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + }, + "dependencies": { + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + } + } }, "globby": { "version": "11.0.4", @@ -3686,27 +3597,12 @@ "responselike": "^2.0.0", "to-readable-stream": "^2.0.0", "type-fest": "^0.10.0" - }, - "dependencies": { - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "requires": { - "pump": "^3.0.0" - } - }, - "type-fest": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.10.0.tgz", - "integrity": "sha512-EUV9jo4sffrwlg8s0zDhP0T2WD3pru5Xi0+HTE3zTUmBaZNhfkite9PdSJwdXLwPVW0jnAHT56pZHIOYckPEiw==" - } } }, "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" }, "graphql": { "version": "15.3.0", @@ -3721,9 +3617,9 @@ "dev": true }, "handlebars": { - "version": "4.7.6", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.6.tgz", - "integrity": "sha512-1f2BACcBfiwAfStCKZNrUCgqNZkGsAT7UM3kkYtXuLo0KnaVfjKOyf7PRzB6++aK9STyT1Pd2ZCPe3EGOXleXA==", + "version": "4.7.7", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", + "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", "dev": true, "requires": { "minimist": "^1.2.5", @@ -3756,16 +3652,21 @@ "function-bind": "^1.1.1" } }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", "dev": true }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", "dev": true }, "has-unicode": { @@ -3783,10 +3684,10 @@ "type-fest": "^0.8.0" }, "dependencies": { - "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true } } @@ -3798,9 +3699,9 @@ "dev": true }, "hosted-git-info": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", - "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, "html-element-attributes": { @@ -3856,9 +3757,9 @@ "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==" }, "ignore-walk": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz", - "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.4.tgz", + "integrity": "sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ==", "requires": { "minimatch": "^3.0.4" } @@ -3871,14 +3772,6 @@ "requires": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - } } }, "import-lazy": { @@ -3931,35 +3824,14 @@ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" }, "internal-slot": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.2.tgz", - "integrity": "sha512-2cQNfwhAfJIkU4KZPkDI+Gj5yNNnbqi40W9Gge6dfnk4TocEVm00B3bdiL+JINrbGJil2TeHvM4rETGzk/f/0g==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", "dev": true, "requires": { - "es-abstract": "^1.17.0-next.1", + "get-intrinsic": "^1.1.0", "has": "^1.0.3", - "side-channel": "^1.0.2" - }, - "dependencies": { - "es-abstract": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", - "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - } + "side-channel": "^1.0.4" } }, "is-alphabetical": { @@ -3984,6 +3856,12 @@ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, + "is-bigint": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz", + "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==", + "dev": true + }, "is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -3993,25 +3871,40 @@ "binary-extensions": "^2.0.0" } }, + "is-boolean-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz", + "integrity": "sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "dev": true + }, "is-callable": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", - "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", "dev": true }, "is-core-module": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", - "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", + "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", "dev": true, "requires": { "has": "^1.0.3" } }, "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz", + "integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==", "dev": true }, "is-decimal": { @@ -4027,10 +3920,12 @@ "dev": true }, "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } }, "is-glob": { "version": "4.0.1", @@ -4059,34 +3954,52 @@ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, + "is-number-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz", + "integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==", + "dev": true + }, "is-plain-obj": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true }, + "is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==" + }, "is-regex": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", - "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", + "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", "dev": true, "requires": { - "has-symbols": "^1.0.1" + "call-bind": "^1.0.2", + "has-symbols": "^1.0.2" } }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true + }, "is-string": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", - "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz", + "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==", "dev": true }, "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", "dev": true, "requires": { - "has-symbols": "^1.0.1" + "has-symbols": "^1.0.2" } }, "is-typedarray": { @@ -4123,9 +4036,9 @@ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, "isomorphic-git": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/isomorphic-git/-/isomorphic-git-1.8.2.tgz", - "integrity": "sha512-wp3on2Kks1sE/tLUmGLPV7EEAj+JRK8WoL2ZSfJHVQfWzRqMRv96bqzDjyYpC6COGKlDQnhTNCucRf83S3cuMw==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/isomorphic-git/-/isomorphic-git-1.9.1.tgz", + "integrity": "sha512-vzceJaiBdaJI5aT1di4dxWWf6sao3WQFQJ6UTi1tXO4zyDfsuyIadVOA4YQzdwKhLilV9msgM8HIvpOE94kmQg==", "requires": { "async-lock": "^1.1.0", "clean-git-ref": "^2.0.1", @@ -4140,11 +4053,6 @@ "simple-get": "^3.0.2" }, "dependencies": { - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" - }, "readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", @@ -4210,55 +4118,6 @@ "p-map": "^3.0.0", "rimraf": "^3.0.0", "uuid": "^3.3.3" - }, - "dependencies": { - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } } }, "istanbul-lib-report": { @@ -4270,6 +4129,23 @@ "istanbul-lib-coverage": "^3.0.0", "make-dir": "^3.0.0", "supports-color": "^7.1.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "istanbul-lib-source-maps": { @@ -4281,6 +4157,23 @@ "debug": "^4.1.1", "istanbul-lib-coverage": "^3.0.0", "source-map": "^0.6.1" + }, + "dependencies": { + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } } }, "istanbul-reports": { @@ -4294,15 +4187,66 @@ } }, "jest-diff": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.0.2.tgz", - "integrity": "sha512-BFIdRb0LqfV1hBt8crQmw6gGQHVDhM87SpMIZ45FPYKReZYG5er1+5pIn2zKqvrJp6WNox0ylR8571Iwk2Dmgw==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.0.6.tgz", + "integrity": "sha512-Z1mqgkTCSYaFgwTlP/NUiRzdqgxmmhzHY1Tq17zL94morOHfHu3K4bgSgl+CR4GLhpV8VxkuOYuIWnQ9LnFqmg==", "dev": true, "requires": { "chalk": "^4.0.0", - "diff-sequences": "^27.0.1", - "jest-get-type": "^27.0.1", - "pretty-format": "^27.0.2" + "diff-sequences": "^27.0.6", + "jest-get-type": "^27.0.6", + "pretty-format": "^27.0.6" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "jest-docblock": { @@ -4315,140 +4259,146 @@ } }, "jest-get-type": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.1.tgz", - "integrity": "sha512-9Tggo9zZbu0sHKebiAijyt1NM77Z0uO4tuWOxUCujAiSeXv30Vb5D4xVF4UR4YWNapcftj+PbByU54lKD7/xMg==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", + "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", "dev": true }, "jest-matcher-utils": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.0.2.tgz", - "integrity": "sha512-Qczi5xnTNjkhcIB0Yy75Txt+Ez51xdhOxsukN7awzq2auZQGPHcQrJ623PZj0ECDEMOk2soxWx05EXdXGd1CbA==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.0.6.tgz", + "integrity": "sha512-OFgF2VCQx9vdPSYTHWJ9MzFCehs20TsyFi6bIHbk5V1u52zJOnvF0Y/65z3GLZHKRuTgVPY4Z6LVePNahaQ+tA==", "dev": true, "requires": { "chalk": "^4.0.0", - "jest-diff": "^27.0.2", - "jest-get-type": "^27.0.1", - "pretty-format": "^27.0.2" + "jest-diff": "^27.0.6", + "jest-get-type": "^27.0.6", + "pretty-format": "^27.0.6" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "jest-message-util": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.0.2.tgz", - "integrity": "sha512-rTqWUX42ec2LdMkoUPOzrEd1Tcm+R1KfLOmFK+OVNo4MnLsEaxO5zPDb2BbdSmthdM/IfXxOZU60P/WbWF8BTw==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.0.6.tgz", + "integrity": "sha512-rBxIs2XK7rGy+zGxgi+UJKP6WqQ+KrBbD1YMj517HYN3v2BG66t3Xan3FWqYHKZwjdB700KiAJ+iES9a0M+ixw==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.0.2", + "@jest/types": "^27.0.6", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.4", - "pretty-format": "^27.0.2", + "pretty-format": "^27.0.6", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, "dependencies": { - "@babel/code-frame": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", - "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.14.5" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", - "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", - "dev": true - }, - "@babel/highlight": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", - "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.14.5", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - } + "color-convert": "^2.0.1" } }, - "ansi-styles": { - "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==", + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { - "color-convert": "^1.9.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { - "color-name": "1.1.3" + "color-name": "~1.1.4" } }, "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - } - }, - "picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "has-flag": "^4.0.0" } } } }, "jest-regex-util": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.0.1.tgz", - "integrity": "sha512-6nY6QVcpTgEKQy1L41P4pr3aOddneK17kn3HJw6SdwGiKfgCGTvH02hVXL0GU8GEKtPH83eD2DIDgxHXOxVohQ==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.0.6.tgz", + "integrity": "sha512-SUhPzBsGa1IKm8hx2F4NfTGGp+r7BXJ4CulsZ1k2kI+mGLG+lxGrs76veN2LF/aUdGosJBzKgXmNCw+BzFqBDQ==", "dev": true }, "jju": { @@ -4464,9 +4414,9 @@ "dev": true }, "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", "dev": true, "requires": { "argparse": "^1.0.7", @@ -4526,20 +4476,19 @@ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, "json5": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", - "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", "requires": { "minimist": "^1.2.5" } }, "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" + "graceful-fs": "^4.1.6" } }, "jsonify": { @@ -4560,13 +4509,13 @@ } }, "jsx-ast-utils": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.4.1.tgz", - "integrity": "sha512-z1xSldJ6imESSzOjd3NNkieVJKRlKYSOtMG8SFyCj2FIrvSaSuli/WjpBkEzCBoR9bYYYFgqJw61Xhu7Lcgk+w==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz", + "integrity": "sha512-EIsmt3O3ljsU6sot/J4E1zDRxfBNrhjyf/OKjlydwgEimQuznlM4Wv7U+ueONJMyEn1WRE0K8dhi3dVAXYT24Q==", "dev": true, "requires": { - "array-includes": "^3.1.1", - "object.assign": "^4.1.0" + "array-includes": "^3.1.2", + "object.assign": "^4.1.2" } }, "just-extend": { @@ -4595,6 +4544,16 @@ "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", "dev": true }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, "lines-and-columns": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", @@ -4619,36 +4578,34 @@ "strip-bom": "^3.0.0" }, "dependencies": { - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "^1.2.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true } } }, "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", "dev": true, "requires": { - "p-locate": "^4.1.0" + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" } }, "lodash": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true }, "lodash.flattendeep": { "version": "4.4.0", @@ -4668,6 +4625,18 @@ "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=", "dev": true }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, "lodash.zip": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.zip/-/lodash.zip-4.2.0.tgz", @@ -4687,6 +4656,57 @@ "dev": true, "requires": { "chalk": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "loose-envify": { @@ -4710,6 +4730,14 @@ "dev": true, "requires": { "yallist": "^4.0.0" + }, + "dependencies": { + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } } }, "make-dir": { @@ -4758,14 +4786,6 @@ "requires": { "map-age-cleaner": "^0.1.3", "mimic-fn": "^3.0.0" - }, - "dependencies": { - "mimic-fn": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz", - "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==", - "dev": true - } } }, "merge2": { @@ -4775,28 +4795,34 @@ "dev": true }, "micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", "dev": true, "requires": { "braces": "^3.0.1", - "picomatch": "^2.0.5" + "picomatch": "^2.2.3" } }, "mime-db": { - "version": "1.45.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz", - "integrity": "sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==" + "version": "1.48.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz", + "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==" }, "mime-types": { - "version": "2.1.28", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.28.tgz", - "integrity": "sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ==", + "version": "2.1.31", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz", + "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==", "requires": { - "mime-db": "1.45.0" + "mime-db": "1.48.0" } }, + "mimic-fn": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz", + "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==", + "dev": true + }, "mimic-response": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", @@ -4830,13 +4856,6 @@ "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" - }, - "dependencies": { - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - } } }, "minizlib": { @@ -4847,10 +4866,18 @@ "minipass": "^2.9.0" } }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "requires": { + "minimist": "^1.2.5" + } + }, "mocha": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.3.2.tgz", - "integrity": "sha512-UdmISwr/5w+uXLPKspgoV7/RXZwKRTiTjJ2/AC5ZiEztIoOYdfKb19+9jNmEInzx5pBsCyJQzarAxqIGBNYJhg==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.4.0.tgz", + "integrity": "sha512-hJaO0mwDXmZS4ghXsvPVriOhsxQ7ofcpQdm8dE+jISUOKopitvnXFQmpRR7jd2K6VBG6E26gU3IAbXXGIbu4sQ==", "dev": true, "requires": { "@ungap/promise-all-settled": "1.1.2", @@ -4886,15 +4913,21 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" + "ms": "2.1.2" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } } }, "diff": { @@ -4919,6 +4952,26 @@ "path-exists": "^4.0.0" } }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "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" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, "js-yaml": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", @@ -4937,12 +4990,6 @@ "p-locate": "^5.0.0" } }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, "p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -4961,6 +5008,18 @@ "p-limit": "^3.0.2" } }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "strip-json-comments": { + "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==", + "dev": true + }, "supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -4978,51 +5037,13 @@ "requires": { "isexe": "^2.0.0" } - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "y18n": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", - "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==", - "dev": true - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - }, - "yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "dev": true } } }, "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "multimap": { "version": "1.1.0", @@ -5054,23 +5075,13 @@ "dev": true }, "needle": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/needle/-/needle-2.6.0.tgz", - "integrity": "sha512-KKYdza4heMsEfSWD7VPUIz3zX2XDwOyX2d+geb4vrERZMT5RMU6ujjaD+I5Yr54uZxQ2w6XRTAhHBbSCyovZBg==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-2.8.0.tgz", + "integrity": "sha512-ZTq6WYkN/3782H1393me3utVYdq2XyqNUFBsprEE3VMAT0+hP/cItpnITpqsY6ep2yeFE4Tqtqwc74VqUlUYtw==", "requires": { "debug": "^3.2.6", "iconv-lite": "^0.4.4", "sax": "^1.2.4" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "requires": { - "ms": "^2.1.1" - } - } } }, "neo-async": { @@ -5115,14 +5126,6 @@ "which": "1" }, "dependencies": { - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "requires": { - "minimist": "^1.2.5" - } - }, "rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -5130,11 +5133,6 @@ "requires": { "glob": "^7.1.3" } - }, - "semver": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", - "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" } } }, @@ -5155,14 +5153,6 @@ "tar": "^4" }, "dependencies": { - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "requires": { - "minimist": "^1.2.5" - } - }, "nopt": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", @@ -5191,6 +5181,12 @@ "process-on-spawn": "^1.0.0" } }, + "node-releases": { + "version": "1.1.73", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz", + "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==", + "dev": true + }, "nopt": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", @@ -5218,14 +5214,14 @@ "dev": true }, "normalize-url": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", - "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==" + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==" }, "npm-bundled": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.1.tgz", - "integrity": "sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.2.tgz", + "integrity": "sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ==", "requires": { "npm-normalize-package-bin": "^1.0.1" } @@ -5294,6 +5290,188 @@ "spawn-wrap": "^2.0.0", "test-exclude": "^6.0.0", "yargs": "^15.0.2" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.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": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } } }, "oauth-sign": { @@ -5307,9 +5485,9 @@ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, "object-inspect": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", - "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==", + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz", + "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==", "dev": true }, "object-keys": { @@ -5331,39 +5509,37 @@ } }, "object.entries": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.3.tgz", - "integrity": "sha512-ym7h7OZebNS96hn5IJeyUmaWhaSM4SVtAPPfNLQEI2MYWCO2egsITb9nab2+i/Pwibx+R0mtn+ltKJXRSeTMGg==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.4.tgz", + "integrity": "sha512-h4LWKWE+wKQGhtMjZEBud7uLGhqyLwj8fpHOarZhD2uY3C9cRtk57VQ89ke3moByLXMedqs3XCHzyb4AmA2DjA==", "dev": true, "requires": { - "call-bind": "^1.0.0", + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1", - "has": "^1.0.3" + "es-abstract": "^1.18.2" } }, "object.fromentries": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.3.tgz", - "integrity": "sha512-IDUSMXs6LOSJBWE++L0lzIbSqHl9KDCfff2x/JSEIDtEUavUnyMYC2ZGay/04Zq4UT8lvd4xNhU4/YHKibAOlw==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.4.tgz", + "integrity": "sha512-EsFBshs5RUUpQEY1D4q/m59kMfz4YJvxuNCJcv/jWwOJr34EaVnG11ZrZa0UHB3wnzV1wx8m58T4hQL8IuNXlQ==", "dev": true, "requires": { - "call-bind": "^1.0.0", + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1", + "es-abstract": "^1.18.0-next.2", "has": "^1.0.3" } }, "object.values": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.2.tgz", - "integrity": "sha512-MYC0jvJopr8EK6dPBiO8Nb9mvjdypOachO5REGk6MXzujbBrAisKo3HmdEI6kZDL6fC31Mwee/5YbtMebixeag==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.4.tgz", + "integrity": "sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg==", "dev": true, "requires": { - "call-bind": "^1.0.0", + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1", - "has": "^1.0.3" + "es-abstract": "^1.18.2" } }, "once": { @@ -5374,6 +5550,20 @@ "wrappy": "1" } }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, "os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", @@ -5417,9 +5607,9 @@ } }, "p-cancelable": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.0.0.tgz", - "integrity": "sha512-wvPXDmbMmu2ksjkB4Z3nZWTSkJEb9lqVdMaCKpZUGJG9TMiNp9XcbG3fn9fPKjem04fJMJnXoyFPk2FmgiaiNg==" + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==" }, "p-defer": { "version": "1.0.0", @@ -5441,21 +5631,21 @@ "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" }, "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", "dev": true, "requires": { - "p-try": "^2.0.0" + "p-try": "^1.0.0" } }, "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", "dev": true, "requires": { - "p-limit": "^2.2.0" + "p-limit": "^1.1.0" } }, "p-map": { @@ -5476,9 +5666,9 @@ } }, "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", "dev": true }, "package-hash": { @@ -5532,21 +5722,18 @@ } }, "parse-json": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.1.0.tgz", - "integrity": "sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" + "error-ex": "^1.2.0" } }, "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true }, "path-is-absolute": { @@ -5554,10 +5741,16 @@ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, "path-to-regexp": { @@ -5589,24 +5782,23 @@ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", "dev": true }, "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" }, "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", "dev": true, "requires": { - "find-up": "^4.0.0" + "find-up": "^2.1.0" } }, "please-upgrade-node": { @@ -5625,9 +5817,9 @@ "dev": true }, "postcss": { - "version": "7.0.35", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", - "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -5635,58 +5827,6 @@ "supports-color": "^6.1.0" }, "dependencies": { - "ansi-styles": { - "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==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, "supports-color": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", @@ -5744,6 +5884,12 @@ "uniq": "^1.0.1" } }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, "prettier-linter-helpers": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", @@ -5819,6 +5965,15 @@ "yaml-unist-parser": "1.3.1" }, "dependencies": { + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, "@babel/parser": { "version": "7.12.0", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.0.tgz", @@ -5840,12 +5995,55 @@ "tsutils": "^3.17.1" } }, - "camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -5858,6 +6056,20 @@ "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true }, + "fast-glob": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", + "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" + } + }, "get-stream": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.0.tgz", @@ -5886,12 +6098,46 @@ } } }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, "ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "resolve": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "dev": true, + "requires": { + "is-core-module": "^2.1.0", + "path-parse": "^1.0.6" + } + }, "semver": { "version": "7.3.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", @@ -5900,21 +6146,56 @@ "requires": { "lru-cache": "^6.0.0" } + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } } } }, "pretty-format": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.2.tgz", - "integrity": "sha512-mXKbbBPnYTG7Yra9qFBtqj+IXcsvxsvOBco3QHxtxTl+hHKq6QdzMZ+q0CtL4ORHZgwGImRr2XZUX2EWzORxig==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.6.tgz", + "integrity": "sha512-8tGD7gBIENgzqA+UBzObyWqQ5B778VIFZA/S66cclyd5YkFLYs2Js7gxDKf0MXtTc9zcS7t1xhdfcElJ3YIvkQ==", "dev": true, "requires": { - "@jest/types": "^27.0.2", + "@jest/types": "^27.0.6", "ansi-regex": "^5.0.0", "ansi-styles": "^5.0.0", "react-is": "^17.0.1" }, "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, "ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", @@ -5997,6 +6278,12 @@ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, "ramda": { "version": "0.25.0", "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.25.0.tgz", @@ -6020,13 +6307,6 @@ "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" - } } }, "react-is": { @@ -6036,34 +6316,41 @@ "dev": true }, "read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", "dev": true, "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" }, "dependencies": { - "type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true } } }, "read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", "dev": true, "requires": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" } }, "readable-stream": { @@ -6090,9 +6377,9 @@ } }, "regexp-tree": { - "version": "0.1.21", - "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.21.tgz", - "integrity": "sha512-kUUXjX4AnqnR8KRTCrayAo9PzYMRKmVoGgaz2tBuz0MF3g1ZbGebmtW0yFHfFK9CmBjQKeYIgoL22pFLBJY7sw==", + "version": "0.1.23", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.23.tgz", + "integrity": "sha512-+7HWfb4Bvu8Rs2eQTUIpX9I/PlQkYOuTNbRpKLJlQpSgwSkzFYh+pUj0gtvglnOZLKB6YgnIgRuJ2/IlpL48qw==", "dev": true }, "regexp-util": { @@ -6105,40 +6392,19 @@ } }, "regexp.prototype.flags": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz", - "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz", + "integrity": "sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA==", "dev": true, "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - }, - "dependencies": { - "es-abstract": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", - "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - } + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" } }, "regexpp": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", - "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true }, "release-zalgo": { @@ -6213,22 +6479,6 @@ "tough-cookie": "~2.5.0", "tunnel-agent": "^0.6.0", "uuid": "^3.3.2" - }, - "dependencies": { - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" - } } }, "require-directory": { @@ -6256,19 +6506,18 @@ "dev": true }, "resolve": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", - "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", "dev": true, "requires": { - "is-core-module": "^2.1.0", "path-parse": "^1.0.6" } }, "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, "responselike": { @@ -6294,16 +6543,28 @@ } }, "run-parallel": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.10.tgz", - "integrity": "sha512-zb/1OuZ6flOlH6tQyMPUrE3x3Ulxjlo9WIVXR4yVYi4H9UXQaeIsPbLn2R3O3vQCnDKkAl2qHiuocKKX4Tz/Sw==", - "dev": true + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, + "safe-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz", + "integrity": "sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==", + "dev": true, + "requires": { + "regexp-tree": "~0.1.1" + } + }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -6315,9 +6576,9 @@ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" }, "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" }, "semver-compare": { "version": "1.0.0", @@ -6348,6 +6609,21 @@ "safe-buffer": "^5.0.1" } }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, "side-channel": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", @@ -6396,9 +6672,9 @@ } }, "simple-html-tokenizer": { - "version": "0.5.10", - "resolved": "https://registry.npmjs.org/simple-html-tokenizer/-/simple-html-tokenizer-0.5.10.tgz", - "integrity": "sha512-1DHMUmvUOGuUZ9/+cX/+hOhWhRD5dEw6lodn8WuV+T+cQ31hhBcCu1dcDsNotowi4mMaNhrLyKoS+DtB81HdDA==", + "version": "0.5.11", + "resolved": "https://registry.npmjs.org/simple-html-tokenizer/-/simple-html-tokenizer-0.5.11.tgz", + "integrity": "sha512-C2WEK/Z3HoSFbYq8tI7ni3eOo/NneSPRoPpcM7WdLjFOArFuyXEjAoCdOC3DgMfRyziZQ1hCNR4mrNdWEvD0og==", "dev": true }, "sinon": { @@ -6413,6 +6689,23 @@ "diff": "^4.0.2", "nise": "^4.1.0", "supports-color": "^7.1.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "slash": { @@ -6430,6 +6723,38 @@ "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", "is-fullwidth-code-point": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + } } }, "source-map": { @@ -6498,9 +6823,9 @@ } }, "spdx-license-ids": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz", - "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==", + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz", + "integrity": "sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ==", "dev": true }, "sprintf-js": { @@ -6561,48 +6886,48 @@ "dev": true }, "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dev": true, + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } }, "string.prototype.matchall": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.3.tgz", - "integrity": "sha512-OBxYDA2ifZQ2e13cP82dWFMaCV9CGF8GzmN4fljBVw5O5wep0lu4gacm1OL6MjROoUnB8VbkWRThqkV2YFLNxw==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.5.tgz", + "integrity": "sha512-Z5ZaXO0svs0M2xd/6By3qpeKpLKd9mO4v4q3oMEQrk8Ck4xOD5d5XeBOOjGrmVZZ/AHB1S0CgG4N5r1G9N3E2Q==", "dev": true, "requires": { - "call-bind": "^1.0.0", + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1", - "has-symbols": "^1.0.1", - "internal-slot": "^1.0.2", - "regexp.prototype.flags": "^1.3.0", - "side-channel": "^1.0.3" + "es-abstract": "^1.18.2", + "get-intrinsic": "^1.1.1", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "regexp.prototype.flags": "^1.3.1", + "side-channel": "^1.0.4" } }, "string.prototype.trimend": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz", - "integrity": "sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", "dev": true, "requires": { - "call-bind": "^1.0.0", + "call-bind": "^1.0.2", "define-properties": "^1.1.3" } }, "string.prototype.trimstart": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz", - "integrity": "sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", "dev": true, "requires": { - "call-bind": "^1.0.0", + "call-bind": "^1.0.2", "define-properties": "^1.1.3" } }, @@ -6615,51 +6940,50 @@ } }, "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { - "ansi-regex": "^5.0.0" + "ansi-regex": "^2.0.0" } }, "strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true }, "strip-json-comments": { - "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==", - "dev": true + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" }, "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "requires": { - "has-flag": "^4.0.0" + "has-flag": "^3.0.0" } }, "table": { - "version": "6.0.7", - "resolved": "https://registry.npmjs.org/table/-/table-6.0.7.tgz", - "integrity": "sha512-rxZevLGTUzWna/qBLObOe16kB2RTnnbhciwgPbMMlazz1yZGVEgnZK762xyVdVznhqxrfCeBMmMkgOOaPwjH7g==", + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz", + "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==", "dev": true, "requires": { - "ajv": "^7.0.2", - "lodash": "^4.17.20", + "ajv": "^8.0.1", + "lodash.clonedeep": "^4.5.0", + "lodash.truncate": "^4.4.2", "slice-ansi": "^4.0.0", - "string-width": "^4.2.0" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0" }, "dependencies": { "ajv": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-7.0.3.tgz", - "integrity": "sha512-R50QRlXSxqXcQP5SvKUrw8VZeypvo12i2IX0EeR5PiZ7bEKeHWgzgo264LDadUsCU42lTJVhFikTqJwNeH34gQ==", + "version": "8.6.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.1.tgz", + "integrity": "sha512-42VLtQUOLefAvKFAQIxIZDaThq6om/PrfP0CYk3/vn+y4BMNkKnbli8ON2QCiHov4KkzOSJ/xSoBJdayiiYvVQ==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -6668,11 +6992,43 @@ "uri-js": "^4.2.2" } }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, "json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } } } }, @@ -6688,21 +7044,6 @@ "mkdirp": "^0.5.0", "safe-buffer": "^5.1.2", "yallist": "^3.0.3" - }, - "dependencies": { - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "requires": { - "minimist": "^1.2.5" - } - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - } } }, "tar-fs": { @@ -6716,14 +7057,6 @@ "tar-stream": "^1.1.2" }, "dependencies": { - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "requires": { - "minimist": "^1.2.5" - } - }, "pump": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz", @@ -6797,6 +7130,15 @@ "is-number": "^7.0.0" } }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, "transform-file": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/transform-file/-/transform-file-1.0.1.tgz", @@ -6839,32 +7181,14 @@ } }, "tsconfig-paths": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", - "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.10.1.tgz", + "integrity": "sha512-rETidPDgCpltxF7MjBZlAFPUHv5aHH2MymyPvh+vEyWAED4Eb/WeMbsnD/JDr4OKPOA1TssDHgIcpTN5Kh0p6Q==", "dev": true, "requires": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", + "json5": "^2.2.0", "minimist": "^1.2.0", "strip-bom": "^3.0.0" - }, - "dependencies": { - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - } } }, "tslib": { @@ -6874,17 +7198,17 @@ "dev": true }, "tslog": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/tslog/-/tslog-3.1.2.tgz", - "integrity": "sha512-sKhNPUMjf+POPxcWuGxinjilEjIzPCdehF/zIdp33ttv9ohIBWHMV9gpdGvJjWbZn09a5IqP1dmaYq56IPXZAg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/tslog/-/tslog-3.2.0.tgz", + "integrity": "sha512-xOCghepl5w+wcI4qXI7vJy6c53loF8OoC/EuKz1ktAPMtltEDz00yo1poKuyBYIQaq4ZDYKYFPD9PfqVrFXh0A==", "requires": { "source-map-support": "^0.5.19" } }, "tsutils": { - "version": "3.19.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.19.0.tgz", - "integrity": "sha512-A7BaLUPvcQ1cxVu72YfD+UMI3SQPTDv/w4ol6TOwLyI0hwfG9EC+cYlhdflJTmtYTgZ3KqdPSe/otxU4K3kArg==", + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", "dev": true, "requires": { "tslib": "^1.8.1" @@ -6903,6 +7227,15 @@ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, "type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", @@ -6910,10 +7243,9 @@ "dev": true }, "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.10.0.tgz", + "integrity": "sha512-EUV9jo4sffrwlg8s0zDhP0T2WD3pru5Xi0+HTE3zTUmBaZNhfkite9PdSJwdXLwPVW0jnAHT56pZHIOYckPEiw==" }, "typedarray-to-buffer": { "version": "3.1.5", @@ -6925,15 +7257,15 @@ } }, "typescript": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.4.tgz", - "integrity": "sha512-uauPG7XZn9F/mo+7MrsRjyvbxFpzemRjKEZXS4AK83oP2KKOJPvb+9cO/gmnv8arWZvhnjVOXz7B49m1l0e9Ew==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz", + "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==", "dev": true }, "uglify-js": { - "version": "3.12.4", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.12.4.tgz", - "integrity": "sha512-L5i5jg/SHkEqzN18gQMTWsZk3KelRsfD1wUVNqtq0kzqWQqcJjyL8yc1o8hJgRrWqrAl2mUFbhfznEIoi7zi2A==", + "version": "3.13.10", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.10.tgz", + "integrity": "sha512-57H3ACYFXeo1IaZ1w02sfA71wI60MGco/IQFjOqK+WtKoprh7Go2/yvd2HPtoJILO2Or84ncLccI4xoHMTSbGg==", "dev": true, "optional": true }, @@ -6942,6 +7274,18 @@ "resolved": "https://registry.npmjs.org/ulid/-/ulid-2.3.0.tgz", "integrity": "sha512-keqHubrlpvT6G2wH0OEfSW4mquYRcbe/J8NMmveoQOjUqmo+hXtO+ORCpWhdbZ7k72UtY61BL7haGxW6enBnjw==" }, + "unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + } + }, "unherit": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.3.tgz", @@ -6978,14 +7322,6 @@ "is-plain-obj": "^2.0.0", "trough": "^1.0.0", "vfile": "^4.0.0" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", - "dev": true - } } }, "uniq": { @@ -7042,14 +7378,14 @@ "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==" }, "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" }, "uri-js": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", - "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "requires": { "punycode": "^2.1.0" } @@ -7059,10 +7395,15 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + }, "v8-compile-cache": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz", - "integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", "dev": true }, "validate-npm-package-license": { @@ -7101,14 +7442,6 @@ "is-buffer": "^2.0.0", "unist-util-stringify-position": "^2.0.0", "vfile-message": "^2.0.0" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", - "dev": true - } } }, "vfile-location": { @@ -7138,61 +7471,11 @@ "tslib": "^1.9.3" }, "dependencies": { - "ansi-styles": { - "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==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, "leven": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=", "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } } } }, @@ -7204,6 +7487,19 @@ "isexe": "^2.0.0" } }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", @@ -7216,35 +7512,6 @@ "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", "requires": { "string-width": "^1.0.2 || 2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "requires": { - "ansi-regex": "^3.0.0" - } - } } }, "word-wrap": { @@ -7266,14 +7533,72 @@ "dev": true }, "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "requires": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } } }, "wrappy": { @@ -7299,21 +7624,20 @@ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" }, "y18n": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", - "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true }, "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, "yaml": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz", - "integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==", + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", "dev": true }, "yaml-unist-parser": { @@ -7328,33 +7652,59 @@ } }, "yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "requires": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } } }, "yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true }, "yargs-unparser": { "version": "2.0.0", @@ -7366,20 +7716,6 @@ "decamelize": "^4.0.0", "flat": "^5.0.2", "is-plain-obj": "^2.1.0" - }, - "dependencies": { - "camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", - "dev": true - }, - "decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true - } } }, "yn": { diff --git a/package.json b/package.json index 716151d7..d04868be 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "bugs": { "url": "https://github.com/sosuisen/git-documentdb/issues" }, - "homepage": "https://github.com/sosuisen/git-documentdb#readme", + "homepage": "https://gitddb.com/", "devDependencies": { "@microsoft/api-extractor": "^7.16.0", "@octokit/types": "^6.12.2", diff --git a/src/error.ts b/src/error.ts index a63ebdb8..a391fe15 100644 --- a/src/error.ts +++ b/src/error.ts @@ -230,16 +230,6 @@ export namespace Err { } } - /** - * @public - */ - export class InvalidSSHKeyPathError extends BaseError { - constructor () { - const e = `Invalid SSH key path`; - super(e); - } - } - /** * @public */ diff --git a/src/git_documentdb.ts b/src/git_documentdb.ts index 7a44c6b9..75d79d54 100644 --- a/src/git_documentdb.ts +++ b/src/git_documentdb.ts @@ -35,6 +35,7 @@ import { JsonDoc, NormalizedCommit, OpenOptions, + PluginTypes, PutOptions, PutResult, PutResultJsonDoc, @@ -107,6 +108,22 @@ export function generateDatabaseId () { */ export class GitDocumentDB implements GitDDBInterface, CRUDInterface, CollectionInterface, SyncEventInterface { + static plugin (obj: any) { + const type: PluginTypes = obj.type; + if (type === 'sync') { + Object.keys(obj).forEach(function (id) { + // @ts-ignore + Sync.prototype[id] = obj[id]; + }); + } + else { + Object.keys(obj).forEach(function (id) { + // @ts-ignore + GitDocumentDB.prototype[id] = obj[id]; + }); + } + } + /*********************************************** * Private properties ***********************************************/ diff --git a/src/remote/sync.ts b/src/remote/sync.ts index 51bbebf2..b1ea4dc0 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -1048,4 +1048,22 @@ export class Sync implements SyncInterface { ); return this; } + + /** + * clone + * @internal + */ + clone () {} + + /** + * fetch + * @internal + */ + fetch () {} + + /** + * push + * @internal + */ + push () {} } diff --git a/src/types.ts b/src/types.ts index e938fdc6..80c846c7 100644 --- a/src/types.ts +++ b/src/types.ts @@ -8,6 +8,11 @@ import { TLogLevelName } from 'tslog'; +/** + * Plugin types + */ +export type PluginTypes = 'db' | 'sync'; + /** * Database Options * From 28dce9617df0e2976e25576f6d711997e60210dd Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 13 Jul 2021 01:15:46 +0900 Subject: [PATCH 016/297] fix: correct types --- src/remote/3way_merge.ts | 24 +++++++++---------- .../{clone.test.ts => sync_clone.test.ts} | 0 2 files changed, 12 insertions(+), 12 deletions(-) rename test/remote/{clone.test.ts => sync_clone.test.ts} (100%) diff --git a/src/remote/3way_merge.ts b/src/remote/3way_merge.ts index 7e9fe0cc..17aba383 100644 --- a/src/remote/3way_merge.ts +++ b/src/remote/3way_merge.ts @@ -200,30 +200,30 @@ export async function merge ( const baseType = base === null ? undefined : await base.type(); if (baseType === 'tree') { return { - mode: (await base.mode()).toString(8), + mode: (await base!.mode()).toString(8), path: basename(fullDocPath), - oid: await base.oid(), - type: await base.type(), + oid: await base!.oid(), + type: await base!.type(), }; } const oursType = ours === null ? undefined : await ours.type(); if (oursType === 'tree') { return { - mode: (await ours.mode()).toString(8), + mode: (await ours!.mode()).toString(8), path: basename(fullDocPath), - oid: await ours.oid(), - type: await ours.type(), + oid: await ours!.oid(), + type: await ours!.type(), }; } const theirsType = theirs === null ? undefined : await theirs.type(); if (theirsType === 'tree') { return { - mode: (await theirs.mode()).toString(8), + mode: (await theirs!.mode()).toString(8), path: basename(fullDocPath), - oid: await theirs.oid(), - type: await theirs.type(), + oid: await theirs!.oid(), + type: await theirs!.type(), }; } @@ -295,9 +295,9 @@ export async function threeWayMerge ( sync: SyncInterface, conflictResolutionStrategy: ConflictResolutionStrategies, fullDocPath: string, - base: WalkerEntry, - ours: WalkerEntry, - theirs: WalkerEntry + base: WalkerEntry | null, + ours: WalkerEntry | null, + theirs: WalkerEntry | null ): Promise< [ TreeEntry | undefined, diff --git a/test/remote/clone.test.ts b/test/remote/sync_clone.test.ts similarity index 100% rename from test/remote/clone.test.ts rename to test/remote/sync_clone.test.ts From a02027ee494222da476fc9a40e1b585579b00341 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 13 Jul 2021 01:16:29 +0900 Subject: [PATCH 017/297] fix: implement clone by plugin --- package-lock.json | 10 +++++++ package.json | 1 + src/error.ts | 10 +++++++ src/git_documentdb.ts | 7 +++-- src/main.ts | 1 + src/remote/combine.ts | 7 ++--- src/remote/remote.ts | 2 ++ src/remote/sync.ts | 21 +++------------ src/types.ts | 2 +- test/remote/combine.test.ts | 32 ++++++++++++++++++++++- test/remote/sync_clone.test.ts | 48 +++++++++++++++++++++++++++------- 11 files changed, 107 insertions(+), 34 deletions(-) create mode 100644 src/remote/remote.ts diff --git a/package-lock.json b/package-lock.json index 143e9407..b870fd6f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3499,6 +3499,16 @@ "integrity": "sha512-qc8h1KIQbJpp+241id3GuAtkdyJ+IK+LIVtkiFTRKRrmddDzs3SI9CvP1QYmWBFvm1I/PWRwj//of8bgAc0ltA==", "dev": true }, + "git-documentdb-plugin-remote-nodegit": { + "version": "1.0.0-alpha.3", + "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.0-alpha.3.tgz", + "integrity": "sha512-UjpqbB7HVXZC0kkTsNeOmH/YLvjxcsuz+YUT4rf9vjssJlYx9o4hj6XBzWB9ZBi6KNqRIazjfS87ihXIe89p9A==", + "dev": true, + "requires": { + "@sosuisen/nodegit": "^0.27.3", + "tslog": "^3.2.0" + } + }, "glob": { "version": "7.1.7", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", diff --git a/package.json b/package.json index d04868be..3fc4918f 100644 --- a/package.json +++ b/package.json @@ -61,6 +61,7 @@ "eslint-config-standardize": "^0.7.1", "eslint-plugin-prettierx": "^0.14.0", "expect": "^27.0.2", + "git-documentdb-plugin-remote-nodegit": "^1.0.0-alpha.3", "mocha": "^8.3.2", "nyc": "^15.1.0", "parse-git-config": "^3.0.0", diff --git a/src/error.ts b/src/error.ts index a391fe15..5e3d69a5 100644 --- a/src/error.ts +++ b/src/error.ts @@ -612,4 +612,14 @@ Current value is '${type}'`); super(`Combine database failed: ${mes})`); } } + + /** + * @public + */ + export class InvalidSSHKeyPathError extends BaseError { + constructor () { + const e = `Invalid SSH key path`; + super(e); + } + } } diff --git a/src/git_documentdb.ts b/src/git_documentdb.ts index 75d79d54..789eb18b 100644 --- a/src/git_documentdb.ts +++ b/src/git_documentdb.ts @@ -13,6 +13,7 @@ import fs from 'fs-extra'; import rimraf from 'rimraf'; import { Logger, TLogLevelName } from 'tslog'; import { ulid } from 'ulid'; +import { Remote } from './remote/remote'; import { Err } from './error'; import { Collection } from './collection'; import { Validator } from './validator'; @@ -110,14 +111,16 @@ export class GitDocumentDB implements GitDDBInterface, CRUDInterface, CollectionInterface, SyncEventInterface { static plugin (obj: any) { const type: PluginTypes = obj.type; - if (type === 'sync') { + if (type === 'remote') { Object.keys(obj).forEach(function (id) { + // Set to Remote object // @ts-ignore - Sync.prototype[id] = obj[id]; + Remote[id] = obj[id]; }); } else { Object.keys(obj).forEach(function (id) { + // Set to Instance property // @ts-ignore GitDocumentDB.prototype[id] = obj[id]; }); diff --git a/src/main.ts b/src/main.ts index 733a55cd..9d655e0f 100644 --- a/src/main.ts +++ b/src/main.ts @@ -12,6 +12,7 @@ export * from './git_documentdb'; export * from './types'; export * from './validator'; export * from './remote/clone'; +export * from './remote/remote'; export * from './remote/remote_repository'; export * from './remote/sync'; export * from './const'; diff --git a/src/remote/combine.ts b/src/remote/combine.ts index 5df33284..2e233f9a 100644 --- a/src/remote/combine.ts +++ b/src/remote/combine.ts @@ -8,11 +8,11 @@ */ import path from 'path'; import git from 'isomorphic-git'; -import nodegit from '@sosuisen/nodegit'; +import nodegit, { Repository } from '@sosuisen/nodegit'; import fs from 'fs-extra'; import { ulid } from 'ulid'; import rimraf from 'rimraf'; -import { cloneRepository } from './clone'; +import { Logger } from 'tslog'; import { DocMetadata, DocType, @@ -25,6 +25,7 @@ import { GitDDBInterface } from '../types_gitddb'; import { Err } from '../error'; import { DUPLICATED_FILE_POSTFIX, FILE_REMOVE_TIMEOUT, JSON_EXT } from '../const'; import { getAllMetadata, toSortedJSONString } from '../utils'; +import { Remote } from './remote'; /** * Clone a remote repository and combine the current local working directory with it. @@ -42,7 +43,7 @@ export async function combineDatabaseWithTheirs ( let remoteRepository: nodegit.Repository | undefined; const duplicates: DuplicatedFile[] = []; try { - remoteRepository = await cloneRepository(remoteDir, remoteOptions, gitDDB.logger); + remoteRepository = await Remote.clone(remoteDir, remoteOptions, gitDDB.logger); if (remoteRepository === undefined) { // Remote repository not found. // This will not occur after NoBaseMergeFoundError. diff --git a/src/remote/remote.ts b/src/remote/remote.ts new file mode 100644 index 00000000..3a325478 --- /dev/null +++ b/src/remote/remote.ts @@ -0,0 +1,2 @@ +// eslint-disable-next-line @typescript-eslint/naming-convention +export const Remote: { [key: string]: any } = {}; diff --git a/src/remote/sync.ts b/src/remote/sync.ts index b1ea4dc0..f2b15f37 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -178,6 +178,9 @@ function filterChanges (syncResult: SyncResult, collectionPath: string): SyncRes * @public */ export class Sync implements SyncInterface { + /********************************************** + * Private properties + ***********************************************/ private _gitDDB: GitDDBInterface; private _checkoutOptions: nodegit.CheckoutOptions; private _syncTimer: NodeJS.Timeout | undefined; @@ -1048,22 +1051,4 @@ export class Sync implements SyncInterface { ); return this; } - - /** - * clone - * @internal - */ - clone () {} - - /** - * fetch - * @internal - */ - fetch () {} - - /** - * push - * @internal - */ - push () {} } diff --git a/src/types.ts b/src/types.ts index 80c846c7..b7081f76 100644 --- a/src/types.ts +++ b/src/types.ts @@ -11,7 +11,7 @@ import { TLogLevelName } from 'tslog'; /** * Plugin types */ -export type PluginTypes = 'db' | 'sync'; +export type PluginTypes = 'db' | 'remote'; /** * Database Options diff --git a/test/remote/combine.test.ts b/test/remote/combine.test.ts index 540de8cc..62c0b182 100644 --- a/test/remote/combine.test.ts +++ b/test/remote/combine.test.ts @@ -75,8 +75,11 @@ maybe('', () => { /** * Combine database */ - describe('Combining database', () => { + describe('with NodeGit', () => { it('throws NoMergeBaseFoundError when combineDbStrategy is throw-error in [both] direction', async () => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { combineDbStrategy: 'throw-error', syncDirection: 'both', @@ -99,6 +102,9 @@ maybe('', () => { }); it('commits with valid commit message for combine-head-with-theirs', async () => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { combineDbStrategy: 'combine-head-with-theirs', syncDirection: 'both', @@ -136,6 +142,9 @@ maybe('', () => { }); it('succeeds when combine-head-with-theirs with empty local and empty remote', async () => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { combineDbStrategy: 'combine-head-with-theirs', syncDirection: 'both', @@ -167,6 +176,9 @@ maybe('', () => { }); it('succeeds combine-head-with-theirs with empty local and not empty remote', async () => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { combineDbStrategy: 'combine-head-with-theirs', syncDirection: 'both', @@ -202,6 +214,9 @@ maybe('', () => { }); it('succeeds when combine-head-with-theirs with not empty local and empty remote', async () => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { combineDbStrategy: 'combine-head-with-theirs', syncDirection: 'both', @@ -236,6 +251,9 @@ maybe('', () => { }); it('succeeds when combine-head-with-theirs with deep local and deep remote', async () => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { combineDbStrategy: 'combine-head-with-theirs', syncDirection: 'both', @@ -270,6 +288,9 @@ maybe('', () => { }); it('returns SyncResult with duplicates when combine-head-with-theirs with not empty local and not empty remote', async () => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { combineDbStrategy: 'combine-head-with-theirs', syncDirection: 'both', @@ -338,6 +359,9 @@ maybe('', () => { }); it('returns SyncResult with duplicates when combine-head-with-theirs with deep local and deep remote', async () => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { combineDbStrategy: 'combine-head-with-theirs', syncDirection: 'both', @@ -409,6 +433,9 @@ maybe('', () => { }); it('invokes combine event with duplicates when combine-head-with-theirs with not empty local and not empty remote', async () => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { combineDbStrategy: 'combine-head-with-theirs', syncDirection: 'both', @@ -488,6 +515,9 @@ maybe('', () => { }); it('copies author from local repository', async () => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { combineDbStrategy: 'combine-head-with-theirs', syncDirection: 'both', diff --git a/test/remote/sync_clone.test.ts b/test/remote/sync_clone.test.ts index bbc28f18..18bcad40 100644 --- a/test/remote/sync_clone.test.ts +++ b/test/remote/sync_clone.test.ts @@ -14,11 +14,17 @@ import path from 'path'; import fs from 'fs-extra'; import expect from 'expect'; -import { cloneRepository } from '../../src/remote/clone'; -import { removeRemoteRepositories } from '../remote_utils'; +import { createDatabase, destroyDBs, removeRemoteRepositories } from '../remote_utils'; +import { GitDocumentDB } from '../../src/git_documentdb'; +import { Remote } from '../../src/remote/remote'; -const reposPrefix = 'test_clone___'; -const localDir = `./test/database_clone`; +const reposPrefix = 'test_sync_clone___'; +const localDir = `./test/database_sync_clone`; + +let idCounter = 0; +const serialId = () => { + return `${reposPrefix}${idCounter++}`; +}; beforeEach(function () { // @ts-ignore @@ -40,7 +46,7 @@ const maybe = ? describe : describe.skip; -maybe(' cloneRepository', () => { +maybe(' clone', () => { const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') ? process.env.GITDDB_GITHUB_USER_URL : process.env.GITDDB_GITHUB_USER_URL + '/'; @@ -51,9 +57,33 @@ maybe(' cloneRepository', () => { await removeRemoteRepositories(reposPrefix); }); - it('returns undefined when invalid RemoteOptions', async () => { - // @ts-ignore - await expect(cloneRepository('tmp')).resolves.toBeUndefined(); - await expect(cloneRepository('tmp', { remoteUrl: undefined })).resolves.toBeUndefined(); + describe('using NodeGit', () => { + it('returns undefined when invalid RemoteOptions', async () => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + // @ts-ignore + await expect(Remote.clone('tmp')).resolves.toBeUndefined(); + await expect(Remote.clone('tmp', { remoteUrl: undefined })).resolves.toBeUndefined(); + }); + + it('clones a repository by NodeGit', async () => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId); + const jsonA1 = { _id: '1', name: 'fromA' }; + await dbA.put(jsonA1); + await syncA.tryPush(); + + const dbNameB = serialId(); + const workingDir = localDir + '/' + dbNameB; + await Remote.clone(workingDir, syncA.options); + + const dbB = new GitDocumentDB({ localDir, dbName: dbNameB }); + await dbB.open(); + await expect(dbB.get(jsonA1._id)).resolves.toEqual(jsonA1); + + await destroyDBs([dbA, dbB]); + }); }); }); From 2e1719728bca237b29f19d472b9b4376485920cd Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 13 Jul 2021 08:59:20 +0900 Subject: [PATCH 018/297] fix: change return value of Remote.clone() --- package-lock.json | 6 +++--- package.json | 2 +- src/remote/combine.ts | 13 +++---------- test/remote/sync_clone.test.ts | 4 ++-- 4 files changed, 9 insertions(+), 16 deletions(-) diff --git a/package-lock.json b/package-lock.json index b870fd6f..afff1c8c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3500,9 +3500,9 @@ "dev": true }, "git-documentdb-plugin-remote-nodegit": { - "version": "1.0.0-alpha.3", - "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.0-alpha.3.tgz", - "integrity": "sha512-UjpqbB7HVXZC0kkTsNeOmH/YLvjxcsuz+YUT4rf9vjssJlYx9o4hj6XBzWB9ZBi6KNqRIazjfS87ihXIe89p9A==", + "version": "1.0.0-alpha.5", + "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.0-alpha.5.tgz", + "integrity": "sha512-xotU+FGWtL8hyqXN00vAhDBNfaCWSlEe8RCF4FsR9MCy7NfdlpiriuXZS4rn9T4ErOaSsGirn1TlWFuh4u7ssg==", "dev": true, "requires": { "@sosuisen/nodegit": "^0.27.3", diff --git a/package.json b/package.json index 3fc4918f..241ab064 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "eslint-config-standardize": "^0.7.1", "eslint-plugin-prettierx": "^0.14.0", "expect": "^27.0.2", - "git-documentdb-plugin-remote-nodegit": "^1.0.0-alpha.3", + "git-documentdb-plugin-remote-nodegit": "^1.0.0-alpha.5", "mocha": "^8.3.2", "nyc": "^15.1.0", "parse-git-config": "^3.0.0", diff --git a/src/remote/combine.ts b/src/remote/combine.ts index 2e233f9a..7eb10cfe 100644 --- a/src/remote/combine.ts +++ b/src/remote/combine.ts @@ -30,7 +30,7 @@ import { Remote } from './remote'; /** * Clone a remote repository and combine the current local working directory with it. * - * @remarks Must catch errors + * TODO: Must catch errors */ // eslint-disable-next-line complexity export async function combineDatabaseWithTheirs ( @@ -40,17 +40,10 @@ export async function combineDatabaseWithTheirs ( // Clone repository if remoteURL exists const remoteDir = gitDDB.workingDir + '_' + ulid(Date.now()); const tmpLocalDir = gitDDB.workingDir + '_' + ulid(Date.now()); - let remoteRepository: nodegit.Repository | undefined; + const duplicates: DuplicatedFile[] = []; try { - remoteRepository = await Remote.clone(remoteDir, remoteOptions, gitDDB.logger); - if (remoteRepository === undefined) { - // Remote repository not found. - // This will not occur after NoBaseMergeFoundError. - throw new Err.RemoteRepositoryNotFoundError(remoteOptions.remoteUrl!); - } - - const index = await remoteRepository.refreshIndex(); + await Remote.clone(remoteDir, remoteOptions, gitDDB.logger); const localMetadataList: DocMetadata[] = await getAllMetadata(gitDDB.repository()!); const remoteMetadataList: DocMetadata[] = await getAllMetadata(remoteRepository); diff --git a/test/remote/sync_clone.test.ts b/test/remote/sync_clone.test.ts index 18bcad40..b974f33f 100644 --- a/test/remote/sync_clone.test.ts +++ b/test/remote/sync_clone.test.ts @@ -62,8 +62,8 @@ maybe(' clone', () => { // eslint-disable-next-line @typescript-eslint/no-var-requires GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); // @ts-ignore - await expect(Remote.clone('tmp')).resolves.toBeUndefined(); - await expect(Remote.clone('tmp', { remoteUrl: undefined })).resolves.toBeUndefined(); + await expect(Remote.clone('tmp')).resolves.toBeFalsy(); + await expect(Remote.clone('tmp', { remoteUrl: undefined })).resolves.toBeFalsy(); }); it('clones a repository by NodeGit', async () => { From a1a823e332ac1e46dc19921a2c55a2b847572cd6 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 13 Jul 2021 10:54:05 +0900 Subject: [PATCH 019/297] fix!: remove setRepository() --- src/git_documentdb.ts | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/git_documentdb.ts b/src/git_documentdb.ts index 789eb18b..cdf76777 100644 --- a/src/git_documentdb.ts +++ b/src/git_documentdb.ts @@ -893,18 +893,6 @@ export class GitDocumentDB return this._currentRepository; } - /** - * Set repository - * - * @remarks Be aware that it can corrupt the database. - * @deprecated This will be removed when NodeGit is replaced with isomorphic-git. - * @public - */ - setRepository (repos: nodegit.Repository) { - this._currentRepository = undefined; - this._currentRepository = repos; - } - /*********************************************** * Public method (Implementation of CRUDInterface) ***********************************************/ From 952a34b9a60371220af4ae5b0a6aa704e33bdd65 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 13 Jul 2021 10:54:48 +0900 Subject: [PATCH 020/297] fix: rewrite combine function by isomorphic-git instead of NodeGit --- src/remote/combine.ts | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/src/remote/combine.ts b/src/remote/combine.ts index 7eb10cfe..a6628e07 100644 --- a/src/remote/combine.ts +++ b/src/remote/combine.ts @@ -8,11 +8,9 @@ */ import path from 'path'; import git from 'isomorphic-git'; -import nodegit, { Repository } from '@sosuisen/nodegit'; import fs from 'fs-extra'; import { ulid } from 'ulid'; import rimraf from 'rimraf'; -import { Logger } from 'tslog'; import { DocMetadata, DocType, @@ -45,8 +43,8 @@ export async function combineDatabaseWithTheirs ( try { await Remote.clone(remoteDir, remoteOptions, gitDDB.logger); - const localMetadataList: DocMetadata[] = await getAllMetadata(gitDDB.repository()!); - const remoteMetadataList: DocMetadata[] = await getAllMetadata(remoteRepository); + const localMetadataList: DocMetadata[] = await getAllMetadata(gitDDB.workingDir); + const remoteMetadataList: DocMetadata[] = await getAllMetadata(remoteDir); const remoteNames = remoteMetadataList.map(meta => meta.name); for (let i = 0; i < localMetadataList.length; i++) { @@ -124,8 +122,7 @@ export async function combineDatabaseWithTheirs ( type: docType, }; } - await index.addByPath(duplicatedFileName); - await index.write(); + git.add({ fs, dir: remoteDir, filepath: duplicatedFileName }); duplicates.push({ original, @@ -135,14 +132,11 @@ export async function combineDatabaseWithTheirs ( else { // Copy localFilePath to remoteFilePath if remoteFilePath not exists await fs.copyFile(localFilePath, remoteFilePath); - await index.addByPath(meta.name); - await index.write(); + git.add({ fs, dir: remoteDir, filepath: meta.name }); } } if (localMetadataList.length > 0) { - await index.writeTree(); - const commitMessage = 'combine database head with theirs'; await git.commit({ @@ -157,9 +151,6 @@ export async function combineDatabaseWithTheirs ( gitDDB.repository()!.cleanup(); await fs.rename(gitDDB.workingDir, tmpLocalDir); - if (remoteRepository) remoteRepository.cleanup(); - remoteRepository = undefined; - await fs.rename(remoteDir, gitDDB.workingDir); const userName = await git @@ -213,11 +204,8 @@ export async function combineDatabaseWithTheirs ( resolve(); }); }); - if (remoteRepository) remoteRepository.cleanup(); - remoteRepository = undefined; } - const repos = await nodegit.Repository.open(gitDDB.workingDir); - gitDDB.setRepository(repos!); + await gitDDB.loadDbInfo(); const result: SyncResultCombineDatabase = { From 52537ce0b7f147e89fc926a4b8409200729a4a99 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 13 Jul 2021 10:55:44 +0900 Subject: [PATCH 021/297] fix: remove definition of setRepository --- src/types_gitddb.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/types_gitddb.ts b/src/types_gitddb.ts index 443da0f7..a96bb70f 100644 --- a/src/types_gitddb.ts +++ b/src/types_gitddb.ts @@ -89,6 +89,4 @@ export interface GitDDBInterface { /* deprecate */ repository(): nodegit.Repository | undefined; - /* deprecate */ - setRepository(repos: nodegit.Repository): void; } From 8b0adf103f88aa5ac3f3ffcd8e959dca30cdbe69 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 13 Jul 2021 10:58:10 +0900 Subject: [PATCH 022/297] fix: do not use readLatestBlob because it calls resolveRef every time --- src/crud/find.ts | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/crud/find.ts b/src/crud/find.ts index 775f0d5c..f1fa979e 100644 --- a/src/crud/find.ts +++ b/src/crud/find.ts @@ -7,7 +7,7 @@ */ import fs from 'fs'; -import { readTree, resolveRef, TreeEntry, TreeObject } from 'isomorphic-git'; +import { readBlob, readTree, resolveRef, TreeEntry, TreeObject } from 'isomorphic-git'; import { GIT_DOCUMENTDB_METADATA_DIR, JSON_EXT } from '../const'; import { Err } from '../error'; import { @@ -21,7 +21,7 @@ import { JsonDoc, } from '../types'; import { GitDDBInterface } from '../types_gitddb'; -import { blobToBinary, blobToJsonDoc, blobToText, readLatestBlob } from './blob'; +import { blobToBinary, blobToJsonDoc, blobToText } from './blob'; /** * Implementation of find() @@ -57,7 +57,7 @@ export async function findImpl ( options.prefix ??= ''; options.prefix = collectionPath + options.prefix; - const commitOid = await resolveRef({ fs, dir: gitDDB.workingDir, ref: 'main' }); + const commitOid = await resolveRef({ fs, dir: gitDDB.workingDir, ref: 'HEAD' }); // Normalize prefix and targetDir let prefix = options!.prefix; @@ -147,7 +147,13 @@ export async function findImpl ( continue; } // eslint-disable-next-line no-await-in-loop - const readBlobResult = await readLatestBlob(gitDDB.workingDir, fullDocPath); + const readBlobResult = await readBlob({ + fs, + dir: gitDDB.workingDir, + oid: commitOid, + filepath: fullDocPath, + }).catch(() => undefined); + // Skip if cannot read if (readBlobResult) { const docType: DocType = From 1b6aba7c92a925ac7c1f84cff2cdc0f5197840c1 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 13 Jul 2021 10:59:03 +0900 Subject: [PATCH 023/297] fix: rewrite getAllMetadata by isomorphic-git instead of NodeGit --- src/utils.ts | 159 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 97 insertions(+), 62 deletions(-) diff --git a/src/utils.ts b/src/utils.ts index 2e291a06..809b338e 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -6,10 +6,23 @@ * found in the LICENSE file in the root directory of this source tree. */ -import path from 'path'; -import nodegit from '@sosuisen/nodegit'; -import { ReadCommitResult } from 'isomorphic-git'; -import { DocMetadata, DocType, NormalizedCommit } from './types'; +import fs from 'fs-extra'; +import { + readBlob, + ReadCommitResult, + readTree, + resolveRef, + TreeEntry, + TreeObject, +} from 'isomorphic-git'; +import { + BinaryDocMetadata, + DocMetadata, + DocType, + JsonDocMetadata, + NormalizedCommit, + TextDocMetadata, +} from './types'; import { GIT_DOCUMENTDB_METADATA_DIR, JSON_EXT } from './const'; /** @@ -65,70 +78,92 @@ export function toSortedJSONString (obj: Record) { * @internal */ // eslint-disable-next-line complexity -export async function getAllMetadata (repos: nodegit.Repository) { +export async function getAllMetadata (workingDir: string): Promise { const files: DocMetadata[] = []; - const head = await nodegit.Reference.nameToId(repos, 'HEAD').catch(e => false); - if (head) { - const headCommit = await repos.getCommit(head as nodegit.Oid); - const localTree = await headCommit.getTree(); - const directories: nodegit.Tree[] = []; - directories.push(localTree); - - while (directories.length > 0) { - const dir = directories.shift(); - if (dir === undefined) break; - const entries = dir.entries(); // returns entry by alphabetical order - while (entries.length > 0) { - const entry = entries.shift(); - if (entry?.isDirectory()) { - // eslint-disable-next-line max-depth - if (entry.name() !== GIT_DOCUMENTDB_METADATA_DIR) { - // eslint-disable-next-line no-await-in-loop - const subtree = await entry.getTree(); - directories.push(subtree); - } + const commitOid = await resolveRef({ fs, dir: workingDir, ref: 'HEAD' }); + + if (commitOid === undefined) return []; + + const treeResult = (await readTree({ + fs, + dir: workingDir, + oid: commitOid, + }).catch(() => undefined))!; + + const directories: { path: string; entries: TreeObject }[] = []; // type TreeObject = Array + const targetDir = ''; + if (treeResult) { + directories.push({ path: targetDir, entries: treeResult.tree }); + } + + const docs: DocMetadata[] = []; + while (directories.length > 0) { + const directory = directories.shift(); + if (directory === undefined) break; + + const entries: TreeEntry[] = directory.entries; + + for (const entry of entries) { + const fullDocPath = + directory.path !== '' ? `${directory.path}/${entry.path}` : entry.path; + if (entry.type === 'tree') { + if (fullDocPath !== GIT_DOCUMENTDB_METADATA_DIR) { + // eslint-disable-next-line no-await-in-loop + const { tree } = await readTree({ + fs, + dir: workingDir, + oid: entry.oid, + }); + directories.push({ path: fullDocPath, entries: tree }); } - else { - const entryPath = entry!.path(); - - const docType: DocType = entryPath.endsWith('.json') ? 'json' : 'text'; - // eslint-disable-next-line max-depth - if (docType === 'text') { - // TODO: select binary or text by .gitattribtues - } - - let docMetadata: DocMetadata; - // eslint-disable-next-line max-depth - if (docType === 'json') { - const _id = entryPath.replace(new RegExp(JSON_EXT + '$'), ''); - docMetadata = { - _id, - name: entryPath, - fileOid: entry!.id().tostrS(), - type: 'json', - }; - } - else if (docType === 'text') { - docMetadata = { - name: entryPath, - fileOid: entry!.id().tostrS(), - type: 'text', - }; - } - else if (docType === 'binary') { - docMetadata = { - name: entryPath, - fileOid: entry!.id().tostrS(), - type: 'binary', - }; - } - - files.push(docMetadata!); + } + else { + // eslint-disable-next-line no-await-in-loop + const readBlobResult = await readBlob({ + fs, + dir: workingDir, + oid: commitOid, + filepath: fullDocPath, + }).catch(() => undefined); + + // Skip if cannot read + if (readBlobResult === undefined) continue; + + const docType: DocType = fullDocPath.endsWith('.json') ? 'json' : 'text'; + if (docType === 'text') { + // TODO: select binary or text by .gitattribtues + } + if (docType === 'json') { + const _id = fullDocPath.replace(new RegExp(JSON_EXT + '$'), ''); + const meta: JsonDocMetadata = { + _id, + name: fullDocPath, + fileOid: entry.oid, + type: 'json', + }; + docs.push(meta); + } + else if (docType === 'text') { + const meta: TextDocMetadata = { + name: fullDocPath, + fileOid: entry.oid, + type: 'text', + }; + docs.push(meta); + } + else if (docType === 'binary') { + const meta: BinaryDocMetadata = { + name: fullDocPath, + fileOid: entry.oid, + type: 'binary', + }; + docs.push(meta); } } } } - return files; + + return docs; } /** From 0c7f1fde533ab1fbaa56e5b5aa69943a83c78902 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 13 Jul 2021 14:04:34 +0900 Subject: [PATCH 024/297] fix: extract checkFetch and checkPush to NodeGit plugin --- package-lock.json | 6 +- package.json | 2 +- src/error.ts | 13 +- src/remote/remote_repository.ts | 189 --------- src/remote/sync.ts | 96 +++-- test/remote/remote_repository.test.ts | 534 +------------------------- test/remote/sync.test.ts | 26 +- 7 files changed, 90 insertions(+), 776 deletions(-) diff --git a/package-lock.json b/package-lock.json index afff1c8c..a0f0dc35 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3500,9 +3500,9 @@ "dev": true }, "git-documentdb-plugin-remote-nodegit": { - "version": "1.0.0-alpha.5", - "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.0-alpha.5.tgz", - "integrity": "sha512-xotU+FGWtL8hyqXN00vAhDBNfaCWSlEe8RCF4FsR9MCy7NfdlpiriuXZS4rn9T4ErOaSsGirn1TlWFuh4u7ssg==", + "version": "1.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.0-alpha.6.tgz", + "integrity": "sha512-O0FMOt2gURS0K4S9xmz5SfQM7rpDsc/ejLv5HronndDchhw9Il9GV0w7mhWz09Y2fRaDv1VUEvklNpMwdyZZJA==", "dev": true, "requires": { "@sosuisen/nodegit": "^0.27.3", diff --git a/package.json b/package.json index 241ab064..4d5a9b42 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "eslint-config-standardize": "^0.7.1", "eslint-plugin-prettierx": "^0.14.0", "expect": "^27.0.2", - "git-documentdb-plugin-remote-nodegit": "^1.0.0-alpha.5", + "git-documentdb-plugin-remote-nodegit": "^1.0.0-alpha.6", "mocha": "^8.3.2", "nyc": "^15.1.0", "parse-git-config": "^3.0.0", diff --git a/src/error.ts b/src/error.ts index 5e3d69a5..d3cf5f7c 100644 --- a/src/error.ts +++ b/src/error.ts @@ -551,9 +551,18 @@ Current value is '${type}'`); /** * @public */ - export class RemoteRepositoryConnectError extends BaseError { + export class RemoteCheckPushError extends BaseError { constructor (mes: unknown) { - super(`Error in RemoteRepository#connect(): ${mes}`); + super(`Error in Remote.checkPush(): ${mes}`); + } + } + + /** + * @public + */ + export class RemoteCheckFetchError extends BaseError { + constructor (mes: unknown) { + super(`Error in Remote.checkFetch(): ${mes}`); } } diff --git a/src/remote/remote_repository.ts b/src/remote/remote_repository.ts index 8ac2826a..5907833b 100644 --- a/src/remote/remote_repository.ts +++ b/src/remote/remote_repository.ts @@ -13,11 +13,6 @@ import { RemoteOptions } from '../types'; import { NETWORK_RETRY, NETWORK_RETRY_INTERVAL } from '../const'; import { sleep } from '../utils'; -/** - * GitOrigin - */ -type GitRemoteAction = 'add' | 'change' | 'exist'; - /** * Remote repository class * @@ -195,188 +190,4 @@ export class RemoteRepository { ); } } - - /** - * Get or create Git remote named 'origin' - * - * (git remote add) - * - * @internal - */ - // eslint-disable-next-line complexity - private async _getOrCreateGitRemote ( - repos: nodegit.Repository, - remoteURL: string - ): Promise<[GitRemoteAction, nodegit.Remote]> { - let result: GitRemoteAction; - // Check if remote repository already exists - let remote = await nodegit.Remote.lookup(repos, 'origin').catch(() => {}); - if (remote === undefined) { - // Add remote repository - remote = await nodegit.Remote.create(repos, 'origin', remoteURL); - result = 'add'; - } - else if (remote.url() !== remoteURL) { - nodegit.Remote.setUrl(repos, 'origin', remoteURL); - result = 'change'; - } - else { - result = 'exist'; - } - return [result, remote]; - } - - /** - * Check connection by FETCH - * - * @throws {@link Err.InvalidURLError} - * @throws {@link Err.RemoteRepositoryNotFoundError} - * @throws Error (Other errors from NodeGit.Remote#connect()) - * - * @internal - */ - // eslint-disable-next-line complexity - private async _checkFetch ( - remote: nodegit.Remote, - credentialCallbacks: { [key: string]: any } - ): Promise<'exist'> { - const remoteURL = remote.url(); - const error = String( - await remote - .connect(nodegit.Enums.DIRECTION.FETCH, credentialCallbacks) - .catch(err => err) - ); - await remote.disconnect(); - // if (error !== 'undefined') console.warn('connect fetch error: ' + error); - switch (true) { - case error === 'undefined': - break; - case error.startsWith('Error: unsupported URL protocol'): - case error.startsWith('Error: failed to resolve address'): - case error.startsWith('Error: failed to send request'): - throw new Err.InvalidURLError(remoteURL + ':' + error); - case error.startsWith('Error: unexpected HTTP status code: 4'): // 401, 404 on Ubuntu - case error.startsWith('Error: request failed with status code: 4'): // 401, 404 on Windows - case error.startsWith('Error: Method connect has thrown an error'): - case error.startsWith('Error: ERROR: Repository not found'): - // Remote repository does not exist, or you do not have permission to the private repository - throw new Err.RemoteRepositoryNotFoundError(remoteURL + ':' + error); - case error.startsWith( - 'Error: remote credential provider returned an invalid cred type' - ): // on Ubuntu - case error.startsWith('Failed to retrieve list of SSH authentication methods'): - case error.startsWith('Error: too many redirects or authentication replays'): - throw new Err.FetchPermissionDeniedError(error); - default: - throw new Error(error); - } - return 'exist'; - } - - /** - * Check connection by PUSH - * - * @throws {@link Err.InvalidURLError} - * @throws {@link Err.RemoteRepositoryNotFoundError} - * @throws {@link Err.PushPermissionDeniedError} - * @throws Error (Other errors from NodeGit.Remote#connect()) - * - * @internal - */ - // eslint-disable-next-line complexity - private async _checkPush ( - remote: nodegit.Remote, - credentialCallbacks: { [key: string]: any } - ) { - const remoteURL = remote.url(); - const error = String( - await remote - .connect(nodegit.Enums.DIRECTION.PUSH, credentialCallbacks) - .catch(err => err) - ); - await remote.disconnect(); - // if (error !== 'undefined') console.warn('connect push error: ' + error); - switch (true) { - case error === 'undefined': - break; - case error.startsWith('Error: unsupported URL protocol'): - case error.startsWith('Error: failed to resolve address'): - case error.startsWith('Error: failed to send request'): - throw new Err.InvalidURLError(remoteURL); - case error.startsWith('Error: unexpected HTTP status code: 4'): // 401, 404 on Ubuntu - case error.startsWith('Error: request failed with status code: 4'): // 401, 404 on Windows - case error.startsWith('Error: Method connect has thrown an error'): - case error.startsWith('Error: ERROR: Repository not found'): { - // Remote repository does not exist, or you do not have permission to the private repository - throw new Err.RemoteRepositoryNotFoundError(remoteURL); - } - // Invalid personal access token - // Personal access token is read only - case error.startsWith( - 'Error: remote credential provider returned an invalid cred type' - ): // on Ubuntu - case error.startsWith('Error: too many redirects or authentication replays'): - case error.startsWith('Error: ERROR: Permission to'): { - throw new Err.PushPermissionDeniedError(error); - } - default: - throw new Error(error); - } - return 'ok'; - } - - /** - * Set a remote repository and connect to the remote repository. - * A remote repository will be created if not exists. - * - * @throws {@link Err.UndefinedPersonalAccessTokenError} (from RemoteRepository#create()) - * @throws {@link Err.PersonalAccessTokenForAnotherAccountError} (from RemoteRepository#create()) - * @throws {@link Err.CannotConnectError} (from RemoteRepository#create()) - * @throws {@link Err.AuthenticationTypeNotAllowCreateRepositoryError} (from RemoteRepository#create()) - * @throws {@link Err.FetchConnectionFailedError} - * @throws {@link Err.CannotCreateRemoteRepositoryError} - * @throws {@link Err.PushConnectionFailedError} - * - * @public - */ - async connect ( - repos: nodegit.Repository, - credentialCallbacks: { [key: string]: any }, - onlyFetch?: boolean - ): Promise<[GitRemoteAction, 'exist' | 'create']> { - // Get NodeGit.Remote - const [gitResult, remote] = await this._getOrCreateGitRemote( - repos, - this._options.remoteUrl! - ); - - // Check fetch and push by NodeGit.Remote - const remoteResult: 'exist' | 'create' = await this._checkFetch( - remote, - credentialCallbacks - ).catch(err => { - if ( - err instanceof Err.RemoteRepositoryNotFoundError && - this._options.connection?.type === 'github' - ) { - return 'create'; - } - - throw new Err.FetchConnectionFailedError(err.message); - }); - if (remoteResult === 'create') { - // Try to create repository by octokit - await this.create().catch(err => { - // App may check permission or - throw new Err.CannotCreateRemoteRepositoryError(err.message); - }); - } - - if (!onlyFetch) { - await this._checkPush(remote, credentialCallbacks).catch(err => { - throw new Err.PushConnectionFailedError(err.message); - }); - } - return [gitResult, remoteResult]; - } } diff --git a/src/remote/sync.ts b/src/remote/sync.ts index f2b15f37..d757aa5d 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -10,7 +10,8 @@ * ! Must import both clearInterval and setInterval from 'timers' */ import { clearInterval, setInterval } from 'timers'; -import nodegit from '@sosuisen/nodegit'; +import git from 'isomorphic-git'; +import fs from 'fs-extra'; import { CONSOLE_STYLE, sleep } from '../utils'; import { Err } from '../error'; import { @@ -54,6 +55,7 @@ import { JsonDiff } from './json_diff'; import { JsonPatchOT } from './json_patch_ot'; import { combineDatabaseWithTheirs } from './combine'; import { Validator } from '../validator'; +import { Remote } from './remote'; /** * Implementation of GitDocumentDB#sync(options, get_sync_result) @@ -74,12 +76,8 @@ export async function syncAndGetResultImpl ( this: GitDDBInterface, options: RemoteOptions ): Promise<[Sync, SyncResult]> { - const repos = this.repository(); - if (repos === undefined) { - throw new Err.RepositoryNotOpenError(); - } const sync = new Sync(this, options); - const syncResult = await sync.init(repos); + const syncResult = await sync.init(); return [sync, syncResult]; } /** @@ -101,12 +99,8 @@ export async function syncImpl ( this: GitDDBInterface, options: RemoteOptions ): Promise { - const repos = this.repository(); - if (repos === undefined) { - throw new Err.RepositoryNotOpenError(); - } const sync = new Sync(this, options); - await sync.init(repos); + await sync.init(); return sync; } @@ -182,7 +176,6 @@ export class Sync implements SyncInterface { * Private properties ***********************************************/ private _gitDDB: GitDDBInterface; - private _checkoutOptions: nodegit.CheckoutOptions; private _syncTimer: NodeJS.Timeout | undefined; private _retrySyncCounter = 0; // Decremental count @@ -297,6 +290,7 @@ export class Sync implements SyncInterface { * * @public */ + // eslint-disable-next-line complexity constructor (gitDDB: GitDDBInterface, options?: RemoteOptions) { this._gitDDB = gitDDB; @@ -318,10 +312,6 @@ export class Sync implements SyncInterface { this._options.conflictResolutionStrategy = options.conflictResolutionStrategy; if (this._options.remoteUrl === undefined || this._options.remoteUrl === '') { - /** - * TODO: Check upstream branch of this repository - * Set remoteUrl to the upstream branch and cloneRepository() if exists. - */ throw new Err.UndefinedRemoteURLError(); } @@ -352,11 +342,6 @@ export class Sync implements SyncInterface { this._upstreamBranch = `origin/${this._gitDDB.defaultBranch}`; - this._checkoutOptions = new nodegit.CheckoutOptions(); - // nodegit.Checkout.STRATEGY.USE_OURS: For unmerged files, checkout stage 2 from index - this._checkoutOptions.checkoutStrategy = - nodegit.Checkout.STRATEGY.FORCE | nodegit.Checkout.STRATEGY.USE_OURS; - this._remoteRepository = new RemoteRepository({ remoteUrl: this._options.remoteUrl, connection: this._options.connection, @@ -399,18 +384,34 @@ export class Sync implements SyncInterface { * * @public */ - async init (repos: nodegit.Repository): Promise { + async init (): Promise { const onlyFetch = this._options.syncDirection === 'pull'; - const [gitResult, remoteResult] = await this.remoteRepository - .connect(this._gitDDB.repository()!, this.credentialCallbacks, onlyFetch) - .catch(err => { - throw new Err.RemoteRepositoryConnectError(err.message); + + const remoteResult: 'exist' | 'not_exist' = await Remote.checkFetch( + this._gitDDB.workingDir, + this._options, + this.credentialCallbacks + ).catch((err: Error) => { + throw new Err.RemoteCheckFetchError(err.message); + }); + if (remoteResult === 'not_exist') { + // Try to create repository by octokit + await this.remoteRepository.create().catch(err => { + // App may check permission or + throw new Err.CannotCreateRemoteRepositoryError(err.message); }); - this._gitDDB.logger.debug('git remote: ' + gitResult); - this._gitDDB.logger.debug('remote repository: ' + remoteResult); - if (remoteResult === 'create') { this._upstreamBranch = ''; } + if (!onlyFetch) { + await Remote.checkPush( + this._gitDDB.workingDir, + this._options, + this.credentialCallbacks + ).catch((err: Error) => { + throw new Err.RemoteCheckPushError(err.message); + }); + } + let syncResult: SyncResult = { action: 'nop', }; @@ -422,15 +423,32 @@ export class Sync implements SyncInterface { else if (this.upstreamBranch === '') { this._gitDDB.logger.debug('upstream_branch is empty. tryPush..'); // Empty upstream_branch shows that an empty repository has been created on a remote site. - // _trySync() pushes local commits to the remote branch. + // trySync() pushes local commits to the remote branch. syncResult = await this.tryPush(); // An upstream branch must be set to a local branch after the first push // because refs/remotes/origin/main is not created until the first push. - await nodegit.Branch.setUpstream( - await repos.getBranch(this._gitDDB.defaultBranch), - `origin/${this._gitDDB.defaultBranch}` - ); + await git.setConfig({ + fs, + dir: this._gitDDB.workingDir, + path: `branch.${this._gitDDB.defaultBranch}.remote`, + value: 'origin', + }); + + await git.setConfig({ + fs, + dir: this._gitDDB.workingDir, + path: `branch.${this._gitDDB.defaultBranch}.merge`, + value: `refs/heads/${this._gitDDB.defaultBranch}`, + }); + + await git.setConfig({ + fs, + dir: this._gitDDB.workingDir, + path: `branch.${this._gitDDB.defaultBranch}.remote`, + value: 'origin', + }); + this._upstreamBranch = `origin/${this._gitDDB.defaultBranch}`; } else if (this._options.syncDirection === 'push') { @@ -505,12 +523,10 @@ export class Sync implements SyncInterface { this._options.retry = options.retry; } - if (this._gitDDB.repository() !== undefined) { - this._options.live = true; - this._syncTimer = setInterval(() => { - this.trySync().catch(() => undefined); - }, this._options.interval!); - } + this._options.live = true; + this._syncTimer = setInterval(() => { + this.trySync().catch(() => undefined); + }, this._options.interval!); this.eventHandlers.resume.forEach(listener => { listener.func(); diff --git a/test/remote/remote_repository.test.ts b/test/remote/remote_repository.test.ts index 6370ce48..60de6a6c 100644 --- a/test/remote/remote_repository.test.ts +++ b/test/remote/remote_repository.test.ts @@ -74,7 +74,7 @@ maybe(' RemoteRepository', () => { await removeRemoteRepositories(reposPrefix); }); - describe(': create()', () => { + describe('create()', () => { it('throws InvalidAuthenticationTypeError', () => { const remoteURL = remoteURLBase + serialId(); expect(() => { @@ -249,7 +249,7 @@ maybe(' RemoteRepository', () => { }); }); - describe(': destroy()', () => { + describe('destroy()', () => { it('removes a remote repository on GitHub by personal access token', async () => { const remoteURL = remoteURLBase + serialId(); @@ -309,534 +309,4 @@ maybe(' RemoteRepository', () => { ).rejects.toThrowError(Err.AuthenticationTypeNotAllowCreateRepositoryError); }); }); - - describe(': _getOrCreateGitRemote()', () => { - it('returns "add" when origin is undefined', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbName = monoId(); - const gitDDB = new GitDocumentDB({ - dbName, - localDir, - }); - await gitDDB.open(); - const remoteRepos = new RemoteRepository({ - remoteUrl: remoteURL, - }); - // You can test private members by array access. - // eslint-disable-next-line dot-notation - const [result, remote] = await remoteRepos['_getOrCreateGitRemote']( - gitDDB.repository()!, - remoteURL - ); - expect(result).toBe('add'); - - destroyDBs([gitDDB]); - }); - - it('returns "change" when another origin exists', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbName = monoId(); - const gitDDB = new GitDocumentDB({ - dbName, - localDir, - }); - await gitDDB.open(); - const remoteRepos = new RemoteRepository({ - remoteUrl: remoteURL, - }); - // You can test private members by array access. - // eslint-disable-next-line dot-notation - await remoteRepos['_getOrCreateGitRemote'](gitDDB.repository()!, remoteURL); - - const remoteURL2 = remoteURLBase + serialId(); - // eslint-disable-next-line dot-notation - const [result, remote] = await remoteRepos['_getOrCreateGitRemote']( - gitDDB.repository()!, - remoteURL2 - ); - expect(result).toBe('change'); - - destroyDBs([gitDDB]); - }); - - it('returns "exist" when the same origin exists', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbName = monoId(); - const gitDDB = new GitDocumentDB({ - dbName, - localDir, - }); - await gitDDB.open(); - const remoteRepos = new RemoteRepository({ - remoteUrl: remoteURL, - }); - // You can test private members by array access. - // eslint-disable-next-line dot-notation - await remoteRepos['_getOrCreateGitRemote'](gitDDB.repository()!, remoteURL); - - const remoteURL2 = remoteURLBase + serialId(); - // eslint-disable-next-line dot-notation - const [result, remote] = await remoteRepos['_getOrCreateGitRemote']( - gitDDB.repository()!, - remoteURL - ); - expect(result).toBe('exist'); - - destroyDBs([gitDDB]); - }); - }); - - describe(': _checkFetch()', () => { - it('returns exist', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbName = monoId(); - const gitDDB = new GitDocumentDB({ - dbName, - localDir, - }); - await gitDDB.open(); - const remoteRepos = new RemoteRepository({ - remoteUrl: remoteURL, - }); - // You can test private members by array access. - // eslint-disable-next-line dot-notation - const [result, remote] = await remoteRepos['_getOrCreateGitRemote']( - gitDDB.repository()!, - remoteURL - ); - await createRemoteRepository(remoteURL); - const cred = createCredential({ - remoteUrl: remoteURL, - connection: { - type: 'github', - personalAccessToken: token, - }, - }); - // eslint-disable-next-line dot-notation - await expect(remoteRepos['_checkFetch'](remote, cred)).resolves.toBe('exist'); - - destroyDBs([gitDDB]); - }); - - it('throws InvalidURLError when a url starts with git@', async () => { - const remoteURL = 'git@github.com/xyz/' + serialId(); - const dbName = monoId(); - const gitDDB = new GitDocumentDB({ - dbName, - localDir, - }); - await gitDDB.open(); - const remoteRepos = new RemoteRepository({ - remoteUrl: remoteURL, - }); - // You can test private members by array access. - // eslint-disable-next-line dot-notation - const [result, remote] = await remoteRepos['_getOrCreateGitRemote']( - gitDDB.repository()!, - remoteURL - ); - - const cred = createCredential({ - remoteUrl: remoteURLBase + serialId(), - connection: { - type: 'github', - personalAccessToken: token, - }, - }); - - // eslint-disable-next-line dot-notation - await expect(remoteRepos['_checkFetch'](remote, cred)).rejects.toThrowError( - Err.InvalidURLError - ); - - destroyDBs([gitDDB]); - }); - - it('throws InvalidURLError when a url starts invalid scheme', async () => { - const remoteURL = 'xttp://github.com/xyz/' + serialId(); - const dbName = monoId(); - const gitDDB = new GitDocumentDB({ - dbName, - localDir, - }); - await gitDDB.open(); - const remoteRepos = new RemoteRepository({ - remoteUrl: remoteURL, - }); - // You can test private members by array access. - // eslint-disable-next-line dot-notation - const [result, remote] = await remoteRepos['_getOrCreateGitRemote']( - gitDDB.repository()!, - remoteURL - ); - - const cred = createCredential({ - remoteUrl: remoteURLBase + serialId(), - connection: { - type: 'github', - personalAccessToken: token, - }, - }); - - // eslint-disable-next-line dot-notation - await expect(remoteRepos['_checkFetch'](remote, cred)).rejects.toThrowError( - Err.InvalidURLError - ); - - destroyDBs([gitDDB]); - }); - - it('throws InvalidURLError when a host name is invalid', async () => { - const remoteURL = 'http://github.test/xyz/' + serialId(); - const dbName = monoId(); - const gitDDB = new GitDocumentDB({ - dbName, - localDir, - }); - await gitDDB.open(); - const remoteRepos = new RemoteRepository({ - remoteUrl: remoteURL, - }); - // You can test private members by array access. - // eslint-disable-next-line dot-notation - const [result, remote] = await remoteRepos['_getOrCreateGitRemote']( - gitDDB.repository()!, - remoteURL - ); - - const cred = createCredential({ - remoteUrl: remoteURLBase + serialId(), - connection: { - type: 'github', - personalAccessToken: token, - }, - }); - - // eslint-disable-next-line dot-notation - await expect(remoteRepos['_checkFetch'](remote, cred)).rejects.toThrowError( - Err.InvalidURLError - ); - - destroyDBs([gitDDB]); - }); - - it('throws RepositoryNotFoundError when a remote repository does not exist', async () => { - const remoteURL = 'http://github.com/xyz/' + monoId(); - const dbName = monoId(); - const gitDDB = new GitDocumentDB({ - dbName, - localDir, - }); - await gitDDB.open(); - const remoteRepos = new RemoteRepository({ - remoteUrl: remoteURL, - }); - // You can test private members by array access. - // eslint-disable-next-line dot-notation - const [result, remote] = await remoteRepos['_getOrCreateGitRemote']( - gitDDB.repository()!, - remoteURL - ); - - const cred = createCredential({ - remoteUrl: remoteURL, - connection: { - type: 'github', - personalAccessToken: token, - }, - }); - - // eslint-disable-next-line dot-notation - await expect(remoteRepos['_checkFetch'](remote, cred)).rejects.toThrowError( - Err.RemoteRepositoryNotFoundError - ); - - destroyDBs([gitDDB]); - }); - - it('throws FetchPermissionDeniedError when ssh key pair does not exist', async () => { - const remoteURL = 'http://github.com/xyz/' + monoId(); - const dbName = monoId(); - const gitDDB = new GitDocumentDB({ - dbName, - localDir, - }); - await gitDDB.open(); - const remoteRepos = new RemoteRepository({ - remoteUrl: remoteURL, - }); - // You can test private members by array access. - // eslint-disable-next-line dot-notation - const [result, remote] = await remoteRepos['_getOrCreateGitRemote']( - gitDDB.repository()!, - remoteURL - ); - - const cred = createCredential({ - remoteUrl: remoteURL, - connection: { - type: 'ssh', - privateKeyPath: '/not/exist', - publicKeyPath: '/not/exist', - }, - }); - - // eslint-disable-next-line dot-notation - await expect(remoteRepos['_checkFetch'](remote, cred)).rejects.toThrowError( - Err.FetchPermissionDeniedError - ); - - destroyDBs([gitDDB]); - }); - - it.skip('throws Error when private repository'); - - it.skip('throws FetchPermissionError when invalid ssh key pair exists'); - }); - - describe(': _checkPush()', () => { - it('returns ok', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbName = monoId(); - const gitDDB = new GitDocumentDB({ - dbName, - localDir, - }); - await gitDDB.open(); - const remoteRepos = new RemoteRepository({ - remoteUrl: remoteURL, - }); - // You can test private members by array access. - // eslint-disable-next-line dot-notation - const [result, remote] = await remoteRepos['_getOrCreateGitRemote']( - gitDDB.repository()!, - remoteURL - ); - await createRemoteRepository(remoteURL); - const cred = createCredential({ - remoteUrl: remoteURL, - connection: { - type: 'github', - personalAccessToken: token, - }, - }); - // eslint-disable-next-line dot-notation - await expect(remoteRepos['_checkPush'](remote, cred)).resolves.toBe('ok'); - - destroyDBs([gitDDB]); - }); - - it('throws PushPermissionDeniedError when personalAccessToken is invalid', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbName = monoId(); - const gitDDB = new GitDocumentDB({ - dbName, - localDir, - }); - await gitDDB.open(); - const remoteRepos = new RemoteRepository({ - remoteUrl: remoteURL, - }); - // You can test private members by array access. - // eslint-disable-next-line dot-notation - const [result, remote] = await remoteRepos['_getOrCreateGitRemote']( - gitDDB.repository()!, - remoteURL - ); - await new RemoteRepository({ - remoteUrl: remoteURL, - connection: { - type: 'github', - personalAccessToken: token, - }, - }).create(); - - const cred = createCredential({ - remoteUrl: remoteURL, - connection: { - type: 'github', - personalAccessToken: token + '_invalid', - }, - }); - // eslint-disable-next-line dot-notation - const error = await remoteRepos['_checkPush'](remote, cred).catch(err => err); - if (error instanceof Err.PushPermissionDeniedError) { - // Notice that it sometimes throw Err.RemoteRepositoryNotFoundError - } - else { - expect(error).toBeInstanceOf(Err.RemoteRepositoryNotFoundError); - } - - destroyDBs([gitDDB]); - }); - - it("throws RemoteRepositoryNotFoundError when try to push to others' repository", async () => { - const remoteURL = 'https://github.com/sosuisen/git-documentdb'; - const dbName = monoId(); - const gitDDB = new GitDocumentDB({ - dbName, - localDir, - }); - await gitDDB.open(); - const remoteRepos = new RemoteRepository({ - remoteUrl: remoteURL, - }); - // You can test private members by array access. - // eslint-disable-next-line dot-notation - const [result, remote] = await remoteRepos['_getOrCreateGitRemote']( - gitDDB.repository()!, - remoteURL - ); - const cred = createCredential({ - remoteUrl: remoteURL, - connection: { - type: 'github', - personalAccessToken: token, - }, - }); - // eslint-disable-next-line dot-notation - await expect(remoteRepos['_checkPush'](remote, cred)).rejects.toThrowError( - Err.RemoteRepositoryNotFoundError - ); - - destroyDBs([gitDDB]); - }); - }); - - describe(': connect()', () => { - it(`returns ['add', 'create'] when both local and GitHub repository do not exist`, async () => { - const remoteURL = remoteURLBase + serialId(); - const dbName = monoId(); - const gitDDB = new GitDocumentDB({ - dbName, - localDir, - }); - await gitDDB.open(); - - const remoteOptions: RemoteOptions = { - remoteUrl: remoteURL, - connection: { - type: 'github', - personalAccessToken: token, - }, - }; - // @ts-ignore - const remoteRepos = new RemoteRepository(remoteOptions); - const cred = createCredential(remoteOptions); - const onlyFetch = true; - await expect( - remoteRepos.connect(gitDDB.repository()!, cred, onlyFetch) - ).resolves.toEqual(['add', 'create']); - - destroyDBs([gitDDB]); - }); - - it(`returns ['add', 'exist'] when a local repository does not exist and a GitHub repository exists`, async () => { - const readonlyURL = 'https://github.com/sosuisen/git-documentdb'; - const dbName = monoId(); - const gitDDB = new GitDocumentDB({ - dbName, - localDir, - }); - await gitDDB.open(); - - const remoteOptions: RemoteOptions = { - remoteUrl: readonlyURL, - connection: { - type: 'github', - personalAccessToken: token, - }, - }; - // @ts-ignore - const remoteRepos = new RemoteRepository(remoteOptions); - const cred = createCredential(remoteOptions); - const onlyFetch = true; - await expect( - remoteRepos.connect(gitDDB.repository()!, cred, onlyFetch) - ).resolves.toEqual(['add', 'exist']); - - destroyDBs([gitDDB]); - }); - - it(`throws FetchConnectionFailedError when remote url is invalid`, async () => { - const readonlyURL = 'https://github.test/invalid/host'; - const dbName = monoId(); - const gitDDB = new GitDocumentDB({ - dbName, - localDir, - }); - await gitDDB.open(); - - const remoteOptions: RemoteOptions = { - remoteUrl: readonlyURL, - connection: { - type: 'github', - personalAccessToken: token, - }, - }; - // @ts-ignore - const remoteRepos = new RemoteRepository(remoteOptions); - const cred = createCredential(remoteOptions); - const onlyFetch = true; - await expect( - remoteRepos.connect(gitDDB.repository()!, cred, onlyFetch) - ).rejects.toThrowError(Err.FetchConnectionFailedError); - - destroyDBs([gitDDB]); - }); - - it(`throws CannotCreateRemoteRepositoryError when a personal access token is for another account`, async () => { - const readonlyURL = 'https://github.com/sosuisen/' + serialId(); - const dbName = monoId(); - const gitDDB = new GitDocumentDB({ - dbName, - localDir, - }); - await gitDDB.open(); - - const remoteOptions: RemoteOptions = { - remoteUrl: readonlyURL, - connection: { - type: 'github', - personalAccessToken: token, // It is valid but for another account - }, - }; - // @ts-ignore - const remoteRepos = new RemoteRepository(remoteOptions); - const cred = createCredential(remoteOptions); - const onlyFetch = true; - await expect( - remoteRepos.connect(gitDDB.repository()!, cred, onlyFetch) - ).rejects.toThrowError(Err.CannotCreateRemoteRepositoryError); - - destroyDBs([gitDDB]); - }); - - it(`to a read only repository throws PushConnectionFailedError when onlyFetch is false`, async () => { - const readonlyURL = 'https://github.com/sosuisen/git-documentdb'; - const dbName = monoId(); - const gitDDB = new GitDocumentDB({ - dbName, - localDir, - }); - await gitDDB.open(); - - const remoteOptions: RemoteOptions = { - remoteUrl: readonlyURL, - connection: { - type: 'github', - personalAccessToken: token, - }, - }; - // @ts-ignore - const remoteRepos = new RemoteRepository(remoteOptions); - const cred = createCredential(remoteOptions); - const onlyFetch = false; - await expect( - remoteRepos.connect(gitDDB.repository()!, cred, onlyFetch) - ).rejects.toThrowError(Err.PushConnectionFailedError); - - destroyDBs([gitDDB]); - }); - }); }); diff --git a/test/remote/sync.test.ts b/test/remote/sync.test.ts index 24ab2557..5ad3779f 100644 --- a/test/remote/sync.test.ts +++ b/test/remote/sync.test.ts @@ -376,7 +376,10 @@ maybe(' init()', () => { await removeRemoteRepositories(reposPrefix); }); - it('throws RemoteRepositoryConnectError.', async () => { + it('throws RemoteCheckFetchError.', async () => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + const dbName = serialId(); const remoteURL = 'https://github.com/sosuisen/foobar_test_for_remote_repository_connect_error'; @@ -394,9 +397,7 @@ maybe(' init()', () => { }; const sync = new Sync(gitDDB, options); // - await expect(sync.init(gitDDB.repository()!)).rejects.toThrowError( - Err.RemoteRepositoryConnectError - ); + await expect(sync.init()).rejects.toThrowError(Err.RemoteCheckFetchError); await gitDDB.destroy(); }); }); @@ -412,7 +413,10 @@ maybe(' syncImpl()', () => { await removeRemoteRepositories(reposPrefix); }); - it('throws RepositoryNotOpenError.', async () => { + it('throws RemoteCheckFetchError.', async () => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + const dbName = serialId(); const remoteURL = remoteURLBase + serialId(); const gitDDB: GitDocumentDB = new GitDocumentDB({ @@ -424,11 +428,14 @@ maybe(' syncImpl()', () => { remoteUrl: remoteURL, connection: { type: 'github', personalAccessToken: token }, }) - ).rejects.toThrowError(Err.RepositoryNotOpenError); + ).rejects.toThrowError(Err.RemoteCheckFetchError); await gitDDB.destroy(); }); it('creates a remote repository on GitHub by using personal access token', async () => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + const remoteURL = remoteURLBase + serialId(); const dbNameA = serialId(); @@ -470,6 +477,9 @@ maybe(' tryPush()', () => { }); it('throws PushNotAllowedError.', async () => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + const remoteURL = remoteURLBase + serialId(); const dbName = serialId(); const gitDDB: GitDocumentDB = new GitDocumentDB({ @@ -486,9 +496,7 @@ maybe(' tryPush()', () => { syncDirection: 'pull', }; const sync = new Sync(gitDDB, options); - await await expect(sync.init(gitDDB.repository()!)).rejects.toThrowError( - Err.PushNotAllowedError - ); + await await expect(sync.init()).rejects.toThrowError(Err.PushNotAllowedError); destroyDBs([gitDDB]); }); From 20644d138f4fe60e616669cafc167e62c631e6c0 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 13 Jul 2021 16:37:13 +0900 Subject: [PATCH 025/297] fix!: remove NodeGit.Repository --- src/collection.ts | 25 --- src/crud/delete.ts | 6 - src/crud/find.ts | 5 - src/crud/get.ts | 5 - src/crud/history.ts | 5 - src/crud/put.ts | 5 - src/git_documentdb.ts | 218 +++++++++----------------- src/remote/3way_merge.ts | 10 +- src/remote/authentication.ts | 95 ----------- src/remote/clone.ts | 83 ---------- src/remote/combine.ts | 1 - src/remote/remote_repository.ts | 1 - src/types_gitddb.ts | 4 - src/types_sync.ts | 5 +- test/collection_get.test.ts | 27 ---- test/crud/delete.test.ts | 12 -- test/crud/find.test.ts | 26 --- test/crud/get.test.ts | 14 -- test/crud/history.test.ts | 14 -- test/crud/put.test.ts | 18 --- test/git_documentdb_crud.test.ts | 14 -- test/git_documentdb_open.test.ts | 15 +- test/remote/remote_repository.test.ts | 4 - test/remote/sync_events.test.ts | 3 +- 24 files changed, 75 insertions(+), 540 deletions(-) delete mode 100644 src/remote/authentication.ts delete mode 100644 src/remote/clone.ts diff --git a/src/collection.ts b/src/collection.ts index 287eb4a4..23a14541 100644 --- a/src/collection.ts +++ b/src/collection.ts @@ -188,14 +188,10 @@ export class Collection implements ICollection { * * @param dirPath - dirPath is a relative path from collectionPath. Default is ''. * @returns Array of Collections which does not include ''. - * @throws {@link Err.RepositoryNotOpenError} * * @public */ async getCollections (dirPath = ''): Promise { - if (!this._gitDDB.isOpened) { - throw new Err.RepositoryNotOpenError(); - } dirPath = Validator.normalizeCollectionPath(this.collectionPath + dirPath); dirPath = dirPath.slice(0, -1); @@ -246,7 +242,6 @@ export class Collection implements ICollection { * @throws {@link Err.TaskCancelError} (from putImpl) * * @throws {@link Err.UndefinedDBError} (fromm putWorker) - * @throws {@link Err.RepositoryNotOpenError} (fromm putWorker) * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) * @throws {@link Err.CannotWriteDataError} (from putWorker) * @@ -278,7 +273,6 @@ export class Collection implements ICollection { * @throws {@link Err.TaskCancelError} (from putImpl) * * @throws {@link Err.UndefinedDBError} (fromm putWorker) - * @throws {@link Err.RepositoryNotOpenError} (fromm putWorker) * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) * @throws {@link Err.CannotWriteDataError} (from putWorker) * @@ -390,7 +384,6 @@ export class Collection implements ICollection { * @throws {@link Err.TaskCancelError} (from putImpl) * * @throws {@link Err.UndefinedDBError} (fromm putWorker) - * @throws {@link Err.RepositoryNotOpenError} (fromm putWorker) * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) * @throws {@link Err.CannotWriteDataError} (from putWorker) * @@ -423,7 +416,6 @@ export class Collection implements ICollection { * @throws {@link Err.TaskCancelError} (from putImpl) * * @throws {@link Err.UndefinedDBError} (fromm putWorker) - * @throws {@link Err.RepositoryNotOpenError} (fromm putWorker) * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) * @throws {@link Err.CannotWriteDataError} (from putWorker) * @@ -491,7 +483,6 @@ export class Collection implements ICollection { * @throws {@link Err.TaskCancelError} (from putImpl) * * @throws {@link Err.UndefinedDBError} (fromm putWorker) - * @throws {@link Err.RepositoryNotOpenError} (fromm putWorker) * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) * @throws {@link Err.CannotWriteDataError} (from putWorker) * @@ -522,7 +513,6 @@ export class Collection implements ICollection { * @throws {@link Err.TaskCancelError} (from putImpl) * * @throws {@link Err.UndefinedDBError} (fromm putWorker) - * @throws {@link Err.RepositoryNotOpenError} (fromm putWorker) * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) * @throws {@link Err.CannotWriteDataError} (from putWorker) * @@ -591,7 +581,6 @@ export class Collection implements ICollection { * @throws {@link Err.TaskCancelError} (from putImpl) * * @throws {@link Err.UndefinedDBError} (fromm putWorker) - * @throws {@link Err.RepositoryNotOpenError} (fromm putWorker) * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) * @throws {@link Err.CannotWriteDataError} (from putWorker) * @@ -709,7 +698,6 @@ export class Collection implements ICollection { * @throws {@link Err.TaskCancelError} (from putImpl) * * @throws {@link Err.UndefinedDBError} (fromm putWorker) - * @throws {@link Err.RepositoryNotOpenError} (fromm putWorker) * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) * @throws {@link Err.CannotWriteDataError} (from putWorker) * @@ -752,7 +740,6 @@ export class Collection implements ICollection { * @throws {@link Err.TaskCancelError} (from putImpl) * * @throws {@link Err.UndefinedDBError} (fromm putWorker) - * @throws {@link Err.RepositoryNotOpenError} (fromm putWorker) * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) * @throws {@link Err.CannotWriteDataError} (from putWorker) * @@ -783,7 +770,6 @@ export class Collection implements ICollection { * - JsonDoc may not have _id property when an app other than GitDocumentDB creates it. * * @throws {@link Err.DatabaseClosingError} - * @throws {@link Err.RepositoryNotOpenError} * @throws {@link Err.InvalidJsonObjectError} * * @public @@ -810,7 +796,6 @@ export class Collection implements ICollection { * - getOptions.forceDocType always overwrite return type. * * @throws {@link Err.DatabaseClosingError} - * @throws {@link Err.RepositoryNotOpenError} * @throws {@link Err.InvalidJsonObjectError} * * @public @@ -830,7 +815,6 @@ export class Collection implements ICollection { * - undefined if a specified oid does not exist. * * @throws {@link Err.DatabaseClosingError} - * @throws {@link Err.RepositoryNotOpenError} * @throws {@link Err.InvalidJsonObjectError} * * @public @@ -866,7 +850,6 @@ export class Collection implements ICollection { * ``` * * @throws {@link Err.DatabaseClosingError} - * @throws {@link Err.RepositoryNotOpenError} * @throws {@link Err.InvalidJsonObjectError} * * @public @@ -914,7 +897,6 @@ export class Collection implements ICollection { * ``` * * @throws {@link Err.DatabaseClosingError} - * @throws {@link Err.RepositoryNotOpenError} * @throws {@link Err.InvalidJsonObjectError} * * @public @@ -980,7 +962,6 @@ export class Collection implements ICollection { * ``` * * @throws {@link Err.DatabaseClosingError} - * @throws {@link Err.RepositoryNotOpenError} * @throws {@link Err.InvalidJsonObjectError} * * @public @@ -1018,7 +999,6 @@ export class Collection implements ICollection { * - getOptions.forceDocType always overwrite return type. * * @throws {@link Err.DatabaseClosingError} - * @throws {@link Err.RepositoryNotOpenError} * @throws {@link Err.InvalidJsonObjectError} * * @public @@ -1047,7 +1027,6 @@ export class Collection implements ICollection { * @throws {@link Err.DatabaseClosingError} (from deleteImpl) * @throws {@link Err.TaskCancelError} (from deleteImpl) * - * @throws {@link Err.RepositoryNotOpenError} (from deleteWorker) * @throws {@link Err.UndefinedDBError} (from deleteWorker) * @throws {@link Err.DocumentNotFoundError} (from deleteWorker) * @throws {@link Err.CannotDeleteDataError} (from deleteWorker) @@ -1065,7 +1044,6 @@ export class Collection implements ICollection { * @throws {@link Err.DatabaseClosingError} (from deleteImpl) * @throws {@link Err.TaskCancelError} (from deleteImpl) * - * @throws {@link Err.RepositoryNotOpenError} (from deleteWorker) * @throws {@link Err.UndefinedDBError} (from deleteWorker) * @throws {@link Err.DocumentNotFoundError} (from deleteWorker) * @throws {@link Err.CannotDeleteDataError} (from deleteWorker) @@ -1119,7 +1097,6 @@ export class Collection implements ICollection { * @throws {@link Err.DatabaseClosingError} (from deleteImpl) * @throws {@link Err.TaskCancelError} (from deleteImpl) * - * @throws {@link Err.RepositoryNotOpenError} (from deleteWorker) * @throws {@link Err.UndefinedDBError} (from deleteWorker) * @throws {@link Err.DocumentNotFoundError} (from deleteWorker) * @throws {@link Err.CannotDeleteDataError} (from deleteWorker) @@ -1172,7 +1149,6 @@ export class Collection implements ICollection { * Get all the JSON documents * * @throws {@link Err.DatabaseClosingError} - * @throws {@link Err.RepositoryNotOpenError} * @throws {@link Err.InvalidJsonObjectError} * * @public @@ -1189,7 +1165,6 @@ export class Collection implements ICollection { * Get all the FatDoc data * * @throws {@link Err.DatabaseClosingError} - * @throws {@link Err.RepositoryNotOpenError} * @throws {@link Err.InvalidJsonObjectError} * * @public diff --git a/src/crud/delete.ts b/src/crud/delete.ts index cf8e6259..8528728e 100644 --- a/src/crud/delete.ts +++ b/src/crud/delete.ts @@ -22,7 +22,6 @@ import { normalizeCommit } from '../utils'; * @throws {@link Err.TaskCancelError} * * @throws {@link Err.UndefinedDBError} (from deleteWorker) - * @throws {@link Err.RepositoryNotOpenError} (deleteWorker) * @throws {@link Err.DocumentNotFoundError} (from deleteWorker) * @throws {@link Err.CannotDeleteDataError} (from deleteWorker) * @@ -80,7 +79,6 @@ export function deleteImpl ( * Remove and commit a file * * @throws {@link Err.UndefinedDBError} - * @throws {@link Err.RepositoryNotOpenError} * @throws {@link Err.DocumentNotFoundError} * @throws {@link Err.CannotDeleteDataError} */ @@ -94,10 +92,6 @@ export async function deleteWorker ( throw new Err.UndefinedDBError(); } - if (!gitDDB.isOpened) { - throw new Err.RepositoryNotOpenError(); - } - const fullDocPath = collectionPath + shortName; if (collectionPath === undefined || shortName === undefined || fullDocPath === '') { diff --git a/src/crud/find.ts b/src/crud/find.ts index f1fa979e..9f1004f5 100644 --- a/src/crud/find.ts +++ b/src/crud/find.ts @@ -27,7 +27,6 @@ import { blobToBinary, blobToJsonDoc, blobToText } from './blob'; * Implementation of find() * * @throws {@link Err.DatabaseClosingError} - * @throws {@link Err.RepositoryNotOpenError} * @throws {@link Err.InvalidJsonObjectError} */ // eslint-disable-next-line complexity @@ -42,10 +41,6 @@ export async function findImpl ( return Promise.reject(new Err.DatabaseClosingError()); } - if (!gitDDB.isOpened) { - return Promise.reject(new Err.RepositoryNotOpenError()); - } - options ??= { descending: undefined, recursive: undefined, diff --git a/src/crud/get.ts b/src/crud/get.ts index 48fa2951..50d51eac 100644 --- a/src/crud/get.ts +++ b/src/crud/get.ts @@ -32,7 +32,6 @@ import { readOldBlob } from './history'; * Common implementation of get-like commands * * @throws {@link Err.DatabaseClosingError} - * @throws {@link Err.RepositoryNotOpenError} * @throws {@link Err.InvalidJsonObjectError} */ // eslint-disable-next-line complexity @@ -48,10 +47,6 @@ export async function getImpl ( throw new Err.DatabaseClosingError(); } - if (!gitDDB.isOpened) { - throw new Err.RepositoryNotOpenError(); - } - options ??= { forceDocType: undefined, }; diff --git a/src/crud/history.ts b/src/crud/history.ts index 4b7717d6..d473a611 100644 --- a/src/crud/history.ts +++ b/src/crud/history.ts @@ -18,7 +18,6 @@ import { blobToBinary, blobToJsonDoc, blobToText } from './blob'; * Implementation of getHistory * * @throws {@link Err.DatabaseClosingError} - * @throws {@link Err.RepositoryNotOpenError} * @throws {@link Err.InvalidJsonObjectError} (from blobToJsonDoc) */ // eslint-disable-next-line complexity @@ -34,10 +33,6 @@ export async function getHistoryImpl ( throw new Err.DatabaseClosingError(); } - if (!gitDDB.isOpened) { - throw new Err.RepositoryNotOpenError(); - } - options ??= { forceDocType: undefined, }; diff --git a/src/crud/put.ts b/src/crud/put.ts index 0bb07f7b..63722ee3 100644 --- a/src/crud/put.ts +++ b/src/crud/put.ts @@ -22,7 +22,6 @@ import { Err } from '../error'; * @throws {@link Err.TaskCancelError} * * @throws {@link Err.UndefinedDBError} (from putWorker) - * @throws {@link Err.RepositoryNotOpenError} (from putWorker) * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) * @throws {@link Err.SameIdExistsError} (from putWorker) * @throws {@link Err.DocumentNotFoundError} (from putWorker) @@ -93,7 +92,6 @@ export function putImpl ( * Add and commit a file * * @throws {@link Err.UndefinedDBError} - * @throws {@link Err.RepositoryNotOpenError} * @throws {@link Err.CannotCreateDirectoryError} * @throws {@link Err.SameIdExistsError} * @throws {@link Err.DocumentNotFoundError} @@ -111,9 +109,6 @@ export async function putWorker ( throw new Err.UndefinedDBError(); } - if (!gitDDB.isOpened) { - throw new Err.RepositoryNotOpenError(); - } const fullDocPath = collectionPath + shortName; let fileOid: string; diff --git a/src/git_documentdb.ts b/src/git_documentdb.ts index cdf76777..37967671 100644 --- a/src/git_documentdb.ts +++ b/src/git_documentdb.ts @@ -7,7 +7,6 @@ */ import path from 'path'; -import nodegit from '@sosuisen/nodegit'; import git from 'isomorphic-git'; import fs from 'fs-extra'; import rimraf from 'rimraf'; @@ -68,28 +67,6 @@ import { SyncEventInterface, SyncInterface } from './types_sync'; import { CRUDInterface } from './types_crud_interface'; import { CollectionInterface, ICollection } from './types_collection'; -interface RepositoryInitOptions { - description?: string; - initialHead?: string; - flags?: number; // https://libgit2.org/libgit2/#HEAD/type/git_repository_init_flag_t - mode?: number; // https://libgit2.org/libgit2/#HEAD/type/git_repository_init_mode_t - originUrl?: string; - templatePath?: string; - version?: number; - workdirPath?: string; -} -/* - const repositoryInitOptionFlags = { - GIT_REPOSITORY_INIT_BARE: 1, - GIT_REPOSITORY_INIT_NO_REINIT: 2, - GIT_REPOSITORY_INIT_NO_DOTGIT_DIR: 4, - GIT_REPOSITORY_INIT_MKDIR: 8, - GIT_REPOSITORY_INIT_MKPATH: 16, - GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE: 32, - GIT_REPOSITORY_INIT_RELATIVE_GITLINK: 64, - }; - */ - /** * Get database ID * @@ -99,6 +76,15 @@ export function generateDatabaseId () { return ulid(Date.now()); } +const INITIAL_DATABASE_OPEN_RESULT = { + dbId: '', + creator: '', + version: '', + isNew: false, + isCreatedByGitDDB: true, + isValidVersion: true, +}; + /** * Main class of GitDocumentDB * @@ -130,18 +116,9 @@ export class GitDocumentDB /*********************************************** * Private properties ***********************************************/ - private _currentRepository: nodegit.Repository | undefined; - private _synchronizers: { [url: string]: Sync } = {}; - private _dbOpenResult: DatabaseOpenResult = { - dbId: '', - creator: '', - version: '', - isNew: false, - isCreatedByGitDDB: true, - isValidVersion: true, - }; + private _dbOpenResult: DatabaseOpenResult = { ...INITIAL_DATABASE_OPEN_RESULT }; /*********************************************** * Public properties (readonly) @@ -373,25 +350,30 @@ export class GitDocumentDB ***********************************************/ /** + * @throws {@link Err.CannotCreateDirectoryError} + * + * @throws {@link Err.UndefinedDBError} (from putWorker) + * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) + * @throws {@link Err.SameIdExistsError} (from putWorker) + * @throws {@link Err.DocumentNotFoundError} (from putWorker) + * @throws {@link Err.CannotWriteDataError} (from putWorker) + * @internal */ private async _createRepository () { /** - * Create a repository followed by first commit + * Create directory */ - const options: RepositoryInitOptions = { - initialHead: this.defaultBranch, - }; - this._dbOpenResult.isNew = true; - - this._currentRepository = await nodegit.Repository.initExt( - this._workingDir, - // @ts-ignore - options - ).catch(err => { - return Promise.reject(err); + await fs.ensureDir(this._workingDir).catch((err: Error) => { + throw new Err.CannotCreateDirectoryError(err.message); }); + await git + .init({ fs, dir: this._workingDir, defaultBranch: this.defaultBranch }) + .catch(err => { + return Promise.reject(err); + }); + // First commit const info = { dbId: generateDatabaseId(), @@ -406,6 +388,9 @@ export class GitDocumentDB toSortedJSONString(info), FIRST_COMMIT_MESSAGE ); + + this._dbOpenResult.isNew = true; + this._dbOpenResult = { ...this._dbOpenResult, ...info }; } @@ -426,10 +411,16 @@ export class GitDocumentDB * - GitDocumentDB can also load a Git repository that is created by other apps. It almost works; however, correct behavior is not guaranteed if it does not have a valid '.gitddb/'. * * @throws {@link Err.DatabaseClosingError} - * @throws {@link Err.CannotCreateDirectoryError} - * @throws {@link Err.CannotOpenRepositoryError} * @throws {@link Err.RepositoryNotFoundError} may occurs when openOptions.createIfNotExists is false. * + * @throws {@link Err.CannotCreateDirectoryError} (from _createRepository) + * + * @throws {@link Err.UndefinedDBError} (from putWorker) + * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) + * @throws {@link Err.SameIdExistsError} (from putWorker) + * @throws {@link Err.DocumentNotFoundError} (from putWorker) + * @throws {@link Err.CannotWriteDataError} (from putWorker) + * @public */ async open (openOptions?: OpenOptions): Promise { @@ -447,43 +438,10 @@ export class GitDocumentDB } openOptions.createIfNotExists ??= true; - /** - * Create directory - */ - await fs.ensureDir(this._workingDir).catch((err: Error) => { - throw new Err.CannotCreateDirectoryError(err.message); - }); - - /** - * Reset - */ - this._synchronizers = {}; - this._dbOpenResult = { - dbId: '', - creator: '', - version: '', - isNew: false, - isCreatedByGitDDB: true, - isValidVersion: true, - }; - this.taskQueue.clear(); - - /** - * nodegit.Repository.open() throws an error if the specified repository does not exist. - * open() also throws an error if the path is invalid or not writable, - */ - try { - this._currentRepository = await nodegit.Repository.open(this._workingDir); - } catch (err) { - const gitDir = this._workingDir + '/.git/'; - if (fs.existsSync(gitDir)) { - // Cannot open though .git directory exists. - throw new Err.CannotOpenRepositoryError(this._workingDir); - } + const gitDir = this._workingDir + '/.git/'; + if (!fs.existsSync(gitDir)) { if (openOptions.createIfNotExists) { - await this._createRepository().catch(e => { - throw new Err.CannotCreateRepositoryError(e.message); - }); + await this._createRepository(); } else { throw new Err.RepositoryNotFoundError(gitDir); @@ -520,35 +478,22 @@ export class GitDocumentDB options.timeout ??= 10000; // Wait taskQueue - if (this._currentRepository instanceof nodegit.Repository) { - try { - this._isClosing = true; - if (!options.force) { - const isTimeout = await this.taskQueue.waitCompletion(options.timeout); - if (isTimeout) { - return Promise.reject(new Err.DatabaseCloseTimeoutError()); - } + try { + this._isClosing = true; + if (!options.force) { + const isTimeout = await this.taskQueue.waitCompletion(options.timeout); + if (isTimeout) { + return Promise.reject(new Err.DatabaseCloseTimeoutError()); } - } finally { - this.taskQueue.clear(); - - /** - * The types are wrong. Repository does not have free() method. - * See https://github.com/nodegit/nodegit/issues/1817#issuecomment-776844425 - * https://github.com/nodegit/nodegit/pull/1570 - * - * Use cleanup() instead. - * http://carlosmn.github.io/libgit2/#v0.23.0/group/repository/git_repository__cleanup - */ - // this._currentRepository.free(); + } + } finally { + this.taskQueue.clear(); - this._currentRepository.cleanup(); - this._currentRepository = undefined; + this._synchronizers = {}; - this._synchronizers = {}; + this._dbOpenResult = { ...INITIAL_DATABASE_OPEN_RESULT }; - this._isClosing = false; - } + this._isClosing = false; } } @@ -577,13 +522,12 @@ export class GitDocumentDB } let closeError: Error | undefined; - if (this._currentRepository !== undefined) { - // NOTICE: options.force is true by default. - options.force = options.force ?? true; - await this.close(options).catch(err => { - closeError = err; - }); - } + // NOTICE: options.force is true by default. + options.force = options.force ?? true; + await this.close(options).catch(err => { + closeError = err; + }); + // If the path does not exist, remove() silently does nothing. // https://github.com/jprichardson/node-fs-extra/blob/master/docs/remove.md // await fs.remove(this._workingDir).catch(err => { @@ -616,7 +560,7 @@ export class GitDocumentDB * @public */ get isOpened (): boolean { - return this._currentRepository !== undefined; + return this._dbOpenResult.dbId !== ''; } /** @@ -640,7 +584,6 @@ export class GitDocumentDB * * @param dirPath - Get collections directly under the dirPath. dirPath is a relative path from localDir. Default is ''. * @returns Promise\ - * @throws {@link Err.RepositoryNotOpenError} * * @public */ @@ -832,6 +775,12 @@ export class GitDocumentDB /** * Load DatabaseInfo from .gitddb/info.json * + * @throws {@link Err.UndefinedDBError} (from putWorker) + * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) + * @throws {@link Err.SameIdExistsError} (from putWorker) + * @throws {@link Err.DocumentNotFoundError} (from putWorker) + * @throws {@link Err.CannotWriteDataError} (from putWorker) + * * @internal */ async loadDbInfo () { @@ -883,16 +832,6 @@ export class GitDocumentDB } } - /** - * Get a current repository - * - * @deprecated This will be removed when NodeGit is replaced with isomorphic-git. - * @public - */ - repository (): nodegit.Repository | undefined { - return this._currentRepository; - } - /*********************************************** * Public method (Implementation of CRUDInterface) ***********************************************/ @@ -918,7 +857,6 @@ export class GitDocumentDB * @throws {@link Err.TaskCancelError} (from putImpl) * * @throws {@link Err.UndefinedDBError} (fromm putWorker) - * @throws {@link Err.RepositoryNotOpenError} (fromm putWorker) * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) * @throws {@link Err.CannotWriteDataError} (from putWorker) * @@ -951,7 +889,6 @@ export class GitDocumentDB * @throws {@link Err.TaskCancelError} (from putImpl) * * @throws {@link Err.UndefinedDBError} (fromm putWorker) - * @throws {@link Err.RepositoryNotOpenError} (fromm putWorker) * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) * @throws {@link Err.CannotWriteDataError} (from putWorker) * @@ -996,7 +933,6 @@ export class GitDocumentDB * @throws {@link Err.TaskCancelError} (from putImpl) * * @throws {@link Err.UndefinedDBError} (fromm putWorker) - * @throws {@link Err.RepositoryNotOpenError} (fromm putWorker) * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) * @throws {@link Err.CannotWriteDataError} (from putWorker) * @@ -1031,7 +967,6 @@ export class GitDocumentDB * @throws {@link Err.TaskCancelError} (from putImpl) * * @throws {@link Err.UndefinedDBError} (fromm putWorker) - * @throws {@link Err.RepositoryNotOpenError} (fromm putWorker) * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) * @throws {@link Err.CannotWriteDataError} (from putWorker) * @@ -1078,7 +1013,7 @@ export class GitDocumentDB * @throws {@link Err.TaskCancelError} (from putImpl) * * @throws {@link Err.UndefinedDBError} (fromm putWorker) - * @throws {@link Err.RepositoryNotOpenError} (fromm putWorker) + * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) * @throws {@link Err.CannotWriteDataError} (from putWorker) * @@ -1111,7 +1046,6 @@ export class GitDocumentDB * @throws {@link Err.TaskCancelError} (from putImpl) * * @throws {@link Err.UndefinedDBError} (fromm putWorker) - * @throws {@link Err.RepositoryNotOpenError} (fromm putWorker) * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) * @throws {@link Err.CannotWriteDataError} (from putWorker) * @@ -1159,7 +1093,6 @@ export class GitDocumentDB * @throws {@link Err.TaskCancelError} (from putImpl) * * @throws {@link Err.UndefinedDBError} (fromm putWorker) - * @throws {@link Err.RepositoryNotOpenError} (fromm putWorker) * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) * @throws {@link Err.CannotWriteDataError} (from putWorker) * @@ -1198,7 +1131,6 @@ export class GitDocumentDB * @throws {@link Err.TaskCancelError} (from putImpl) * * @throws {@link Err.UndefinedDBError} (fromm putWorker) - * @throws {@link Err.RepositoryNotOpenError} (fromm putWorker) * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) * @throws {@link Err.CannotWriteDataError} (from putWorker) * @@ -1239,7 +1171,6 @@ export class GitDocumentDB * @throws {@link Err.TaskCancelError} (from putImpl) * * @throws {@link Err.UndefinedDBError} (fromm putWorker) - * @throws {@link Err.RepositoryNotOpenError} (fromm putWorker) * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) * @throws {@link Err.CannotWriteDataError} (from putWorker) * @@ -1268,7 +1199,6 @@ export class GitDocumentDB * - This is an alias of GitDocumentDB#rootCollection.get() * * @throws {@link Err.DatabaseClosingError} - * @throws {@link Err.RepositoryNotOpenError} * @throws {@link Err.InvalidJsonObjectError} * * @public @@ -1294,7 +1224,6 @@ export class GitDocumentDB * - This is an alias of GitDocumentDB#rootCollection.getFatDoc() * * @throws {@link Err.DatabaseClosingError} - * @throws {@link Err.RepositoryNotOpenError} * @throws {@link Err.InvalidJsonObjectError} * * @public @@ -1314,7 +1243,7 @@ export class GitDocumentDB * - This is an alias of GitDocumentDB#rootCollection.getDocByOid() * * @throws {@link Err.DatabaseClosingError} - * @throws {@link Err.RepositoryNotOpenError} + * @throws {@link Err.InvalidJsonObjectError} * * @public @@ -1343,7 +1272,7 @@ export class GitDocumentDB * ``` * * @throws {@link Err.DatabaseClosingError} - * @throws {@link Err.RepositoryNotOpenError} + * @throws {@link Err.InvalidJsonObjectError} * * @public @@ -1382,7 +1311,6 @@ export class GitDocumentDB * ``` * * @throws {@link Err.DatabaseClosingError} - * @throws {@link Err.RepositoryNotOpenError} * @throws {@link Err.InvalidJsonObjectError} * * @public @@ -1451,7 +1379,7 @@ export class GitDocumentDB * ``` * * @throws {@link Err.DatabaseClosingError} - * @throws {@link Err.RepositoryNotOpenError} + * @throws {@link Err.InvalidJsonObjectError} * * @public @@ -1483,7 +1411,6 @@ export class GitDocumentDB * - getOptions.forceDocType always overwrite return type. * * @throws {@link Err.DatabaseClosingError} - * @throws {@link Err.RepositoryNotOpenError} * @throws {@link Err.InvalidJsonObjectError} * * @public @@ -1508,7 +1435,6 @@ export class GitDocumentDB * @throws {@link Err.DatabaseClosingError} (from deleteImpl) * @throws {@link Err.TaskCancelError} (from deleteImpl) * - * @throws {@link Err.RepositoryNotOpenError} (from deleteWorker) * @throws {@link Err.UndefinedDBError} (from deleteWorker) * @throws {@link Err.DocumentNotFoundError} (from deleteWorker) * @throws {@link Err.CannotDeleteDataError} (from deleteWorker) @@ -1529,7 +1455,6 @@ export class GitDocumentDB * @throws {@link Err.DatabaseClosingError} (from deleteImpl) * @throws {@link Err.TaskCancelError} (from deleteImpl) * - * @throws {@link Err.RepositoryNotOpenError} (from deleteWorker) * @throws {@link Err.UndefinedDBError} (from deleteWorker) * @throws {@link Err.DocumentNotFoundError} (from deleteWorker) * @throws {@link Err.CannotDeleteDataError} (from deleteWorker) @@ -1556,7 +1481,6 @@ export class GitDocumentDB * @throws {@link Err.DatabaseClosingError} (from deleteImpl) * @throws {@link Err.TaskCancelError} (from deleteImpl) * - * @throws {@link Err.RepositoryNotOpenError} (from deleteWorker) * @throws {@link Err.UndefinedDBError} (from deleteWorker) * @throws {@link Err.DocumentNotFoundError} (from deleteWorker) * @throws {@link Err.CannotDeleteDataError} (from deleteWorker) @@ -1576,7 +1500,6 @@ export class GitDocumentDB * @param options - The options specify how to get documents. * * @throws {@link Err.DatabaseClosingError} - * @throws {@link Err.RepositoryNotOpenError} * @throws {@link Err.InvalidJsonObjectError} * * @public @@ -1594,7 +1517,6 @@ export class GitDocumentDB * - This is an alias of GitDocumentDB#rootCollection.findFatDoc() * * @throws {@link Err.DatabaseClosingError} - * @throws {@link Err.RepositoryNotOpenError} * @throws {@link Err.InvalidJsonObjectError} * * @public diff --git a/src/remote/3way_merge.ts b/src/remote/3way_merge.ts index 17aba383..c61b65f0 100644 --- a/src/remote/3way_merge.ts +++ b/src/remote/3way_merge.ts @@ -278,7 +278,6 @@ export async function merge ( /** * 3-way merge * - * @throws {@link Err.RepositoryNotOpenError} * @throws {@link Err.InvalidConflictStateError} * * @throws {@link Err.InvalidDocTypeError} @@ -306,11 +305,6 @@ export async function threeWayMerge ( AcceptedConflict | undefined ] > { - const repos = gitDDB.repository(); - if (repos === undefined) { - throw new Err.RepositoryNotOpenError(); - } - const docType: DocType = fullDocPath.endsWith('.json') ? 'json' : 'text'; if (docType === 'text') { // TODO: select binary or text by .gitattribtues @@ -562,7 +556,7 @@ export async function threeWayMerge ( if (baseOid === oursOid) { // A file has been removed from theirs. // console.log(' #case 10 - Accept theirs (delete): ' + fullDocPath); - await fs.remove(nodePath.resolve(repos.workdir(), fullDocPath)).catch(() => { + await fs.remove(nodePath.resolve(gitDDB.workingDir, fullDocPath)).catch(() => { throw new Err.CannotDeleteDataError(); }); await git.remove({ fs, dir: gitDDB.workingDir, filepath: fullDocPath }); @@ -612,7 +606,7 @@ export async function threeWayMerge ( strategy: strategy, operation: 'delete', }; - await fs.remove(nodePath.resolve(repos.workdir(), fullDocPath)).catch(() => { + await fs.remove(nodePath.resolve(gitDDB.workingDir, fullDocPath)).catch(() => { throw new Err.CannotDeleteDataError(); }); await git.remove({ fs, dir: gitDDB.workingDir, filepath: fullDocPath }); diff --git a/src/remote/authentication.ts b/src/remote/authentication.ts deleted file mode 100644 index 5b0338ae..00000000 --- a/src/remote/authentication.ts +++ /dev/null @@ -1,95 +0,0 @@ -/** - * GitDocumentDB - * Copyright (c) Hidekazu Kubota - * - * This source code is licensed under the Mozilla Public License Version 2.0 - * found in the LICENSE file in the root directory of this source tree. - */ - -import nodegit from '@sosuisen/nodegit'; -import { Err } from '../error'; -import { ConnectionSettingsGitHub, ConnectionSettingsSSH, RemoteOptions } from '../types'; - -/** - * Insert credential options for GitHub - * - * @internal - */ -function createCredentialForGitHub (options: RemoteOptions) { - if (!options.remoteUrl!.match(/^https?:\/\//)) { - throw new Err.HttpProtocolRequiredError(options.remoteUrl!); - } - const connection = options.connection as ConnectionSettingsGitHub; - if (options.syncDirection !== 'pull' && !connection.personalAccessToken) { - throw new Err.UndefinedPersonalAccessTokenError(); - } - const urlArray = options.remoteUrl!.replace(/^https?:\/\//, '').split('/'); - // github.com/account_name/repository_name - if (urlArray.length !== 3) { - throw new Err.InvalidRepositoryURLError(options.remoteUrl!); - } - const owner = urlArray[urlArray.length - 2]; - const credentials = () => { - return nodegit.Cred.userpassPlaintextNew(owner, connection.personalAccessToken!); - }; - return credentials; -} - -/** - * Create credential options for SSH - * - * @internal - */ -function createCredentialForSSH (options: RemoteOptions) { - const connection = options.connection as ConnectionSettingsSSH; - if (connection.privateKeyPath === undefined || connection.privateKeyPath === '') { - throw new Err.InvalidSSHKeyPathError(); - } - if (connection.publicKeyPath === undefined || connection.publicKeyPath === '') { - throw new Err.InvalidSSHKeyPathError(); - } - connection.passPhrase ??= ''; - - const credentials = (url: string, userName: string) => { - return nodegit.Cred.sshKeyNew( - userName, - connection.publicKeyPath, - connection.privateKeyPath, - connection.passPhrase! - ); - }; - return credentials; -} - -/** - * Create credential options - * - * @internal - */ -export function createCredential (options: RemoteOptions) { - options.connection ??= { type: 'none' }; - let cred: any; - if (options.connection.type === 'github') { - cred = createCredentialForGitHub(options); - } - else if (options.connection.type === 'ssh') { - cred = createCredentialForSSH(options); - } - else if (options.connection.type === 'none') { - // nop - } - else { - // @ts-ignore - throw new Err.InvalidAuthenticationTypeError(options.connection.type); - } - - const callbacks = { - credentials: cred, - }; - - if (process.platform === 'darwin') { - // @ts-ignore - callbacks.certificateCheck = () => 0; - } - return callbacks; -} diff --git a/src/remote/clone.ts b/src/remote/clone.ts deleted file mode 100644 index 8f6b0dc4..00000000 --- a/src/remote/clone.ts +++ /dev/null @@ -1,83 +0,0 @@ -/** - * GitDocumentDB - * Copyright (c) Hidekazu Kubota - * - * This source code is licensed under the Mozilla Public License Version 2.0 - * found in the LICENSE file in the root directory of this source tree. - */ - -import nodegit from '@sosuisen/nodegit'; -import { Logger } from 'tslog'; -import { Err } from '../error'; -import { sleep } from '../utils'; -import { NETWORK_RETRY, NETWORK_RETRY_INTERVAL, NETWORK_TIMEOUT } from '../const'; -import { RemoteOptions } from '../types'; -import { createCredential } from './authentication'; -import { checkHTTP } from './net'; - -/** - * Clone repository from remote - * - * @throws {@link Err.CannotConnectError} - * - * @internal - */ -export async function cloneRepository ( - workingDir: string, - remoteOptions: RemoteOptions, - logger?: Logger -) { - logger ??= new Logger({ - name: 'clone', - minLevel: 'trace', - displayDateTime: false, - displayFunctionName: false, - displayFilePath: 'hidden', - }); - if ( - remoteOptions !== undefined && - remoteOptions.remoteUrl !== undefined && - remoteOptions.remoteUrl !== '' - ) { - /** - * Retry if network errors. - */ - let result: { - ok: boolean; - code?: number; - error?: Error; - } = { - ok: false, - }; - let retry = 0; - for (; retry < NETWORK_RETRY; retry++) { - // eslint-disable-next-line no-await-in-loop - result = await checkHTTP(remoteOptions.remoteUrl!, NETWORK_TIMEOUT).catch(err => err); - if (result.ok) { - break; - } - else { - logger.debug(`NetworkError in cloning: ${remoteOptions.remoteUrl}, ` + result); - } - // eslint-disable-next-line no-await-in-loop - await sleep(NETWORK_RETRY_INTERVAL); - } - if (!result.ok) { - // Set retry number for code test - throw new Err.CannotConnectError(retry, remoteOptions.remoteUrl, result.toString()); - } - - return await nodegit.Clone.clone(remoteOptions.remoteUrl, workingDir, { - fetchOpts: { - callbacks: createCredential(remoteOptions), - }, - }).catch(err => { - // Errors except CannotConnectError are handled in sync(). - logger!.debug(`Error in cloning: ${remoteOptions.remoteUrl}, ` + err); - // The db will try to create remote repository in sync() if 'undefined' is returned. - return undefined; - }); - } - - return undefined; -} diff --git a/src/remote/combine.ts b/src/remote/combine.ts index a6628e07..f466e67b 100644 --- a/src/remote/combine.ts +++ b/src/remote/combine.ts @@ -148,7 +148,6 @@ export async function combineDatabaseWithTheirs ( }); } - gitDDB.repository()!.cleanup(); await fs.rename(gitDDB.workingDir, tmpLocalDir); await fs.rename(remoteDir, gitDDB.workingDir); diff --git a/src/remote/remote_repository.ts b/src/remote/remote_repository.ts index 5907833b..0c2247ef 100644 --- a/src/remote/remote_repository.ts +++ b/src/remote/remote_repository.ts @@ -6,7 +6,6 @@ * found in the LICENSE file in the root directory of this source tree. */ -import nodegit from '@sosuisen/nodegit'; import { Octokit } from '@octokit/rest'; import { Err } from '../error'; import { RemoteOptions } from '../types'; diff --git a/src/types_gitddb.ts b/src/types_gitddb.ts index a96bb70f..721b2bbc 100644 --- a/src/types_gitddb.ts +++ b/src/types_gitddb.ts @@ -6,7 +6,6 @@ * found in the LICENSE file in the root directory of this source tree. */ -import nodegit from '@sosuisen/nodegit'; import { Logger, TLogLevelName } from 'tslog'; import { TaskQueue } from './task_queue'; import { @@ -86,7 +85,4 @@ export interface GitDDBInterface { loadAppInfo(): { [key: string]: any }; loadDbInfo(): void; - - /* deprecate */ - repository(): nodegit.Repository | undefined; } diff --git a/src/types_sync.ts b/src/types_sync.ts index f4e2d9c5..a6739432 100644 --- a/src/types_sync.ts +++ b/src/types_sync.ts @@ -1,4 +1,3 @@ -import nodegit from '@sosuisen/nodegit'; import { JsonDiff } from './remote/json_diff'; import { RemoteRepository } from './remote/remote_repository'; import { @@ -52,15 +51,13 @@ export interface SyncInterface { error: { collectionPath: string; func: SyncErrorCallback }[]; }; - credentialCallbacks: { [key: string]: any }; - jsonDiff: JsonDiff; jsonPatch: IJsonPatch; /*********************************************** * Public methods ***********************************************/ - init(repos: nodegit.Repository): Promise; + init(): Promise; pause(): void; resume(options?: { interval?: number; retry?: number }): void; diff --git a/test/collection_get.test.ts b/test/collection_get.test.ts index a4531e8f..7054198f 100644 --- a/test/collection_get.test.ts +++ b/test/collection_get.test.ts @@ -59,18 +59,6 @@ describe(' get()', () => { await gitDDB.destroy(); }); - it('throws RepositoryNotOpenError', async () => { - const dbName = monoId(); - const gitDDB: GitDocumentDB = new GitDocumentDB({ - dbName, - localDir, - }); - await gitDDB.open(); - const col = new Collection(gitDDB, 'col01'); - await gitDDB.close(); - await expect(col.get('prof01')).rejects.toThrowError(Err.RepositoryNotOpenError); - }); - it('throws InvalidJsonObjectError', async () => { const dbName = monoId(); const gitDDB: GitDocumentDB = new GitDocumentDB({ @@ -857,21 +845,6 @@ describe(' getFatDocHistory()', () => { await gitDDB.destroy(); }); - it('throws RepositoryNotOpenError', async () => { - const dbName = monoId(); - const gitDDB: GitDocumentDB = new GitDocumentDB({ - dbName, - localDir, - }); - await gitDDB.open(); - const col = new Collection(gitDDB, 'col01'); - await gitDDB.close(); - await expect(col.getFatDocHistory('tmp')).rejects.toThrowError( - Err.RepositoryNotOpenError - ); - await gitDDB.destroy(); - }); - it('throws InvalidJsonObjectError.', async () => { const dbName = monoId(); const gitDDB: GitDocumentDB = new GitDocumentDB({ diff --git a/test/crud/delete.test.ts b/test/crud/delete.test.ts index a8a9c306..be1c744e 100644 --- a/test/crud/delete.test.ts +++ b/test/crud/delete.test.ts @@ -328,18 +328,6 @@ describe('', () => { await expect(deleteWorker(undefined)).rejects.toThrowError(Err.UndefinedDBError); }); - it('throws RepositoryNotOpenError when a repository is not opened.', async () => { - const dbName = monoId(); - const gitDDB: GitDocumentDB = new GitDocumentDB({ - dbName, - localDir, - }); - await expect(deleteWorker(gitDDB, '', 'prof01', '')).rejects.toThrowError( - Err.RepositoryNotOpenError - ); - await gitDDB.destroy(); - }); - it('throws DocumentNotFoundError when collectionPath is undefined.', async () => { const dbName = monoId(); const gitDDB: GitDocumentDB = new GitDocumentDB({ diff --git a/test/crud/find.test.ts b/test/crud/find.test.ts index cf459d41..b5d6d347 100644 --- a/test/crud/find.test.ts +++ b/test/crud/find.test.ts @@ -86,20 +86,6 @@ describe(' find()', () => { await gitDDB.destroy(); }); - it('throws RepositoryNotOpenError', async () => { - const dbName = monoId(); - const gitDDB: GitDocumentDB = new GitDocumentDB({ - dbName, - localDir, - }); - await gitDDB.open(); - await gitDDB.close(); - await expect(findImpl(gitDDB, '', true, false)).rejects.toThrowError( - Err.RepositoryNotOpenError - ); - await gitDDB.destroy(); - }); - it('throws InvalidJsonObjectError', async () => { const dbName = monoId(); const gitDDB: GitDocumentDB = new GitDocumentDB({ @@ -179,10 +165,6 @@ describe(' find()', () => { localDir, }); - await expect(findImpl(gitDDB, '', true, false)).rejects.toThrowError( - Err.RepositoryNotOpenError - ); - await gitDDB.open(); const json_b = { _id: _id_b, name: name_b }; @@ -309,10 +291,6 @@ describe(' find()', () => { localDir, }); - await expect(findImpl(gitDDB, '', true, false)).rejects.toThrowError( - Err.RepositoryNotOpenError - ); - await gitDDB.open(); const json_b = { _id: _id_b, name: name_b }; @@ -561,10 +539,6 @@ describe(' find()', () => { localDir, }); - await expect(findImpl(gitDDB, '', true, false)).rejects.toThrowError( - Err.RepositoryNotOpenError - ); - await gitDDB.open(); const colPath = 'col01/'; diff --git a/test/crud/get.test.ts b/test/crud/get.test.ts index 034801bc..9b9710e4 100644 --- a/test/crud/get.test.ts +++ b/test/crud/get.test.ts @@ -73,20 +73,6 @@ describe(' getImpl()', () => { await gitDDB.destroy(); }); - it('throws RepositoryNotOpenError', async () => { - const dbName = monoId(); - const gitDDB: GitDocumentDB = new GitDocumentDB({ - dbName, - localDir, - }); - await gitDDB.open(); - await gitDDB.close(); - await expect(getImpl(gitDDB, 'tmp', '')).rejects.toThrowError( - Err.RepositoryNotOpenError - ); - await gitDDB.destroy(); - }); - it('throws InvalidJsonObjectError', async () => { const dbName = monoId(); const gitDDB: GitDocumentDB = new GitDocumentDB({ diff --git a/test/crud/history.test.ts b/test/crud/history.test.ts index 22129f04..d30d3b3a 100644 --- a/test/crud/history.test.ts +++ b/test/crud/history.test.ts @@ -425,20 +425,6 @@ describe(' getHistoryImpl', () => { await destroyDBs([gitDDB]); }); - it('throws RepositoryNotOpenError', async () => { - const dbName = monoId(); - const gitDDB: GitDocumentDB = new GitDocumentDB({ - dbName, - localDir, - }); - await gitDDB.open(); - await gitDDB.close(); - await expect( - getHistoryImpl(gitDDB, 'tmp', '', undefined, undefined, true) - ).rejects.toThrowError(Err.RepositoryNotOpenError); - await destroyDBs([gitDDB]); - }); - it('throws InvalidJsonObjectError.', async () => { const dbName = monoId(); const gitDDB: GitDocumentDB = new GitDocumentDB({ diff --git a/test/crud/put.test.ts b/test/crud/put.test.ts index 9fb14315..b0d59ae7 100644 --- a/test/crud/put.test.ts +++ b/test/crud/put.test.ts @@ -505,24 +505,6 @@ describe(' putWorker', () => { await expect(putWorker(undefined)).rejects.toThrowError(Err.UndefinedDBError); }); - it('throws RepositoryNotOpenError when a repository is not opened.', async () => { - const dbName = monoId(); - const gitDDB: GitDocumentDB = new GitDocumentDB({ - dbName, - localDir, - }); - await expect( - putWorker( - gitDDB, - '', - 'prof01' + JSON_EXT, - '{ "_id": "prof01", "name": "Shirase" }', - 'message' - ) - ).rejects.toThrowError(Err.RepositoryNotOpenError); - await gitDDB.destroy(); - }); - it('throws CannotCreateDirectoryError', async () => { const dbName = monoId(); const gitDDB: GitDocumentDB = new GitDocumentDB({ diff --git a/test/git_documentdb_crud.test.ts b/test/git_documentdb_crud.test.ts index cc6343ac..571ad65a 100644 --- a/test/git_documentdb_crud.test.ts +++ b/test/git_documentdb_crud.test.ts @@ -1221,20 +1221,6 @@ describe(' getFatDocHistory()', () => { await gitDDB.destroy(); }); - it('throws RepositoryNotOpenError', async () => { - const dbName = monoId(); - const gitDDB: GitDocumentDB = new GitDocumentDB({ - dbName, - localDir, - }); - await gitDDB.open(); - await gitDDB.close(); - await expect(gitDDB.getFatDocHistory('tmp')).rejects.toThrowError( - Err.RepositoryNotOpenError - ); - await gitDDB.destroy(); - }); - it('throws InvalidJsonObjectError.', async () => { const dbName = monoId(); const gitDDB: GitDocumentDB = new GitDocumentDB({ diff --git a/test/git_documentdb_open.test.ts b/test/git_documentdb_open.test.ts index a9b5ceda..d4358cb0 100644 --- a/test/git_documentdb_open.test.ts +++ b/test/git_documentdb_open.test.ts @@ -107,19 +107,6 @@ describe('', () => { await expect(gitDDB.open()).rejects.toThrowError(Err.CannotCreateDirectoryError); }); - it('throws CannotCreateRepositoryError when tries to create a new repository on a readonly filesystem.', async () => { - const dbName = monoId(); - const stubEnsureDir = sandbox.stub(fs_module, 'ensureDir'); - stubEnsureDir.onFirstCall().resolves().onSecondCall().rejects(); - - const gitDDB: GitDocumentDB = new GitDocumentDB({ - dbName, - localDir, - }); - // You don't have permission - await expect(gitDDB.open()).rejects.toThrowError(Err.CannotCreateRepositoryError); - }); - it('creates a new repository.', async () => { const dbName = monoId(); @@ -191,7 +178,7 @@ describe('', () => { }); // Create empty .git directory await fs.ensureDir(gitDDB.workingDir + '/.git/'); - await expect(gitDDB.open()).rejects.toThrowError(Err.CannotOpenRepositoryError); + await expect(gitDDB.open()).rejects.toThrowError(Err.CannotWriteDataError); }); it('opens an existing repository.', async () => { diff --git a/test/remote/remote_repository.test.ts b/test/remote/remote_repository.test.ts index 60de6a6c..24e47271 100644 --- a/test/remote/remote_repository.test.ts +++ b/test/remote/remote_repository.test.ts @@ -17,18 +17,14 @@ import { Octokit } from '@octokit/rest'; import expect from 'expect'; import fs from 'fs-extra'; import { monotonicFactory } from 'ulid'; -import { createCredential } from '../../src/remote/authentication'; -import { GitDocumentDB } from '../../src/git_documentdb'; import { Err } from '../../src/error'; import { NETWORK_RETRY, NETWORK_RETRY_INTERVAL } from '../../src/const'; import { createRemoteRepository, - destroyDBs, destroyRemoteRepository, removeRemoteRepositories, } from '../remote_utils'; import { RemoteRepository } from '../../src/remote/remote_repository'; -import { RemoteOptions } from '../../src/types'; const ulid = monotonicFactory(); const monoId = () => { diff --git a/test/remote/sync_events.test.ts b/test/remote/sync_events.test.ts index 35a0aa80..87736398 100644 --- a/test/remote/sync_events.test.ts +++ b/test/remote/sync_events.test.ts @@ -967,14 +967,13 @@ maybe(' [event]', () => { }; await dbA.open(); - const repos = dbA.repository(); const sync = new Sync(dbA, options); let resume = false; sync.on('resume', () => { resume = true; }); - const syncResult = await sync.init(repos!); + const syncResult = await sync.init(); console.log(JSON.stringify(syncResult)); expect(resume).toBe(true); From f66d8131f36ce1773e93c91fbc5a46b30195ae7e Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 13 Jul 2021 16:37:32 +0900 Subject: [PATCH 026/297] fix: extract push and fetch to plugin --- src/remote/push_worker.ts | 97 ++------------------------------------- src/remote/sync.ts | 19 +------- src/remote/sync_worker.ts | 44 +++--------------- 3 files changed, 11 insertions(+), 149 deletions(-) diff --git a/src/remote/push_worker.ts b/src/remote/push_worker.ts index bcf10c34..fc4f9328 100644 --- a/src/remote/push_worker.ts +++ b/src/remote/push_worker.ts @@ -6,111 +6,20 @@ * found in the LICENSE file in the root directory of gitDDB source tree. */ -import nodegit from '@sosuisen/nodegit'; import git from 'isomorphic-git'; import fs from 'fs-extra'; -import { CONSOLE_STYLE } from '../utils'; -import { Err } from '../error'; import { GitDDBInterface } from '../types_gitddb'; import { ChangedFile, NormalizedCommit, SyncResultPush, TaskMetadata } from '../types'; import { SyncInterface } from '../types_sync'; -import { calcDistance, getChanges, getCommitLogs } from './worker_utils'; - -/** - * git push - * - * @throws {@link Err.UnfetchedCommitExistsError} (from this and validatePushResult()) - * @throws {@link Err.SyncWorkerFetchError} (from validatePushResult()) - * @throws {@link Err.GitPushError} (from NodeGit.Remote.push()) - */ -async function push (gitDDB: GitDDBInterface, sync: SyncInterface): Promise { - const repos = gitDDB.repository()!; - const remote: nodegit.Remote = await repos.getRemote('origin'); - await remote - .push(['refs/heads/main:refs/heads/main'], { - callbacks: sync.credentialCallbacks, - }) - .catch((err: Error) => { - if ( - err.message.startsWith( - 'cannot push because a reference that you are trying to update on the remote contains commits that are not present locally' - ) - ) { - throw new Err.UnfetchedCommitExistsError(); - } - throw new Err.GitPushError(err.message); - }); - // gitDDB.logger.debug(CONSOLE_STYLE.BgWhite().FgBlack().tag()`sync_worker: May pushed.`); - await validatePushResult(gitDDB, sync); -} - -/** - * NodeGit.Remote.push does not return valid error in race condition, - * so check is needed. - * - * @throws {@link Err.SyncWorkerFetchError} - * @throws {@link Err.UnfetchedCommitExistsError} - */ -async function validatePushResult ( - gitDDB: GitDDBInterface, - sync: SyncInterface -): Promise { - const repos = gitDDB.repository()!; - await repos - .fetch('origin', { - callbacks: sync.credentialCallbacks, - }) - .catch(err => { - throw new Err.SyncWorkerFetchError(err.message); - }); - - const localCommitOid = await git.resolveRef({ - fs, - dir: gitDDB.workingDir, - ref: 'HEAD', - }); - const remoteCommitOid = await git.resolveRef({ - fs, - dir: gitDDB.workingDir, - ref: 'refs/remotes/origin/main', - }); - - const [baseCommitOid] = await git.findMergeBase({ - fs, - dir: gitDDB.workingDir, - oids: [localCommitOid, remoteCommitOid], - }); - - const distance = await calcDistance(baseCommitOid, localCommitOid, remoteCommitOid); - - if (distance.behind === undefined) { - // This will not be occurred. - gitDDB.logger.debug( - CONSOLE_STYLE.bgWhite() - .fgBlack() - .tag()`sync_worker: push failed: cannot get merge base}` - ); - throw new Err.NoMergeBaseFoundError(); - } - else if (distance.behind > 0) { - gitDDB.logger.debug( - CONSOLE_STYLE.bgWhite() - .fgBlack() - .tag()`sync_worker: push failed: ahead ${distance.ahead} behind ${distance.behind}` - ); - - throw new Err.UnfetchedCommitExistsError(); - } -} +import { getChanges, getCommitLogs } from './worker_utils'; +import { Remote } from './remote'; /** * Push and get changes * - * @throws {@link Err.RepositoryNotOpenError} * @throws {@link Err.UnfetchedCommitExistsError} (from push() and validatePushResult()) * @throws {@link Err.SyncWorkerFetchError} (from validatePushResult()) * @throws {@link Err.InvalidJsonObjectError} (from getChanges()) - * @throws Error (Other errors from NodeGit.Remote.push()) */ export async function pushWorker ( gitDDB: GitDDBInterface, @@ -186,7 +95,7 @@ export async function pushWorker ( } // Push - await push(gitDDB, sync); + await Remote.push(gitDDB, sync); let remoteChanges: ChangedFile[] | undefined; if (skipGetChanges) { remoteChanges = undefined; diff --git a/src/remote/sync.ts b/src/remote/sync.ts index d757aa5d..7c9249d0 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -39,7 +39,6 @@ import { SyncInterface } from '../types_sync'; import { GitDDBInterface } from '../types_gitddb'; import { syncWorker } from './sync_worker'; import { pushWorker } from './push_worker'; -import { createCredential } from './authentication'; import { RemoteRepository } from './remote_repository'; import { checkHTTP } from './net'; import { @@ -260,13 +259,6 @@ export class Sync implements SyncInterface { error: [], }; - /** - * Callback for authentication - * - * @public - */ - credentialCallbacks: { [key: string]: any }; - /** * JsonDiff * @@ -338,8 +330,6 @@ export class Sync implements SyncInterface { this.jsonDiff = new JsonDiff(gitDDB.schema.json); this.jsonPatch = new JsonPatchOT(); - this.credentialCallbacks = createCredential(this._options); - this._upstreamBranch = `origin/${this._gitDDB.defaultBranch}`; this._remoteRepository = new RemoteRepository({ @@ -389,8 +379,7 @@ export class Sync implements SyncInterface { const remoteResult: 'exist' | 'not_exist' = await Remote.checkFetch( this._gitDDB.workingDir, - this._options, - this.credentialCallbacks + this._options ).catch((err: Error) => { throw new Err.RemoteCheckFetchError(err.message); }); @@ -403,11 +392,7 @@ export class Sync implements SyncInterface { this._upstreamBranch = ''; } if (!onlyFetch) { - await Remote.checkPush( - this._gitDDB.workingDir, - this._options, - this.credentialCallbacks - ).catch((err: Error) => { + await Remote.checkPush(this._gitDDB.workingDir, this._options).catch((err: Error) => { throw new Err.RemoteCheckPushError(err.message); }); } diff --git a/src/remote/sync_worker.ts b/src/remote/sync_worker.ts index cd1bf60c..15d6c95e 100644 --- a/src/remote/sync_worker.ts +++ b/src/remote/sync_worker.ts @@ -7,15 +7,13 @@ * found in the LICENSE file in the root directory of gitDDB source tree. */ -import nodegit from '@sosuisen/nodegit'; import git from 'isomorphic-git'; import fs from 'fs-extra'; -import { JSON_EXT, SHORT_SHA_LENGTH } from '../const'; -import { CONSOLE_STYLE, normalizeCommit, utf8decode } from '../utils'; +import { SHORT_SHA_LENGTH } from '../const'; +import { normalizeCommit } from '../utils'; import { Err } from '../error'; import { GitDDBInterface } from '../types_gitddb'; import { - AcceptedConflict, NormalizedCommit, SyncResult, SyncResultMergeAndPush, @@ -26,38 +24,13 @@ import { } from '../types'; import { SyncInterface } from '../types_sync'; import { pushWorker } from './push_worker'; -import { - calcDistance, - getAndWriteLocalChanges, - getChanges, - getCommitLogs, - writeBlobToFile, -} from './worker_utils'; -import { merge, threeWayMerge } from './3way_merge'; - -/** - * git fetch - * - * @throws {@link Err.SyncWorkerFetchError} - */ -async function fetch (gitDDB: GitDDBInterface, sync: SyncInterface) { - gitDDB.logger.debug( - CONSOLE_STYLE.bgWhite().fgBlack().tag()`sync_worker: fetch: ${sync.remoteURL}` - ); - await gitDDB - .repository()! - .fetch('origin', { - callbacks: sync.credentialCallbacks, - }) - .catch(err => { - throw new Err.SyncWorkerFetchError(err.message); - }); -} +import { calcDistance, getAndWriteLocalChanges, getCommitLogs } from './worker_utils'; +import { merge } from './3way_merge'; +import { Remote } from './remote'; /** * sync_worker * - * @throws {@link Err.RepositoryNotOpenError} (from this and push_worker()) * @throws {@link Err.SyncWorkerFetchError} (from fetch() and push_worker()) * @throws {@link Err.NoMergeBaseFoundError} * @throws {@link Err.ThreeWayMergeError} @@ -66,7 +39,6 @@ async function fetch (gitDDB: GitDDBInterface, sync: SyncInterface) { * @throws {@link Err.UnfetchedCommitExistsError} (from push_worker()) * @throws {@link Err.InvalidJsonObjectError} (from push_worker()) * @throws {@link Err.GitPushError} (from push_worker()) - * @throws {@link Err.GitMergeBranchError} (from NodeGit.repos.mergeBranches()) * * @internal */ @@ -76,10 +48,6 @@ export async function syncWorker ( sync: SyncInterface, taskMetadata: TaskMetadata ): Promise { - const repos = gitDDB.repository(); - if (repos === undefined) { - throw new Err.RepositoryNotOpenError(); - } sync.eventHandlers.start.forEach(listener => { listener.func( { ...taskMetadata, collectionPath: listener.collectionPath }, @@ -90,7 +58,7 @@ export async function syncWorker ( /** * Fetch */ - await fetch(gitDDB, sync); + await Remote.fetch(gitDDB, sync, gitDDB.logger); /** * Calc distance From 4bd9a3d72fb984d9fb282e4e90d324beb4329808 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 13 Jul 2021 19:16:06 +0900 Subject: [PATCH 027/297] fix: testing trySync --- .vscode/launch.json | 2 +- package-lock.json | 7 ++- package.json | 2 +- src/remote/push_worker.ts | 2 +- src/remote/sync.ts | 9 ++- src/remote/sync_worker.ts | 2 +- src/remote/worker_utils.ts | 1 - test/remote/sync.test.ts | 96 +------------------------------- test/remote/sync_trypush.test.ts | 4 ++ test/remote/sync_trysync.test.ts | 7 ++- test/remote_utils.ts | 66 ++++++++-------------- 11 files changed, 50 insertions(+), 148 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index cfc101bc..31d3ae2b 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,7 +4,7 @@ "type": "pickString", "id": "choice", "description": "select a file", - "options": ["test/remote/3way_merge.test.js"], + "options": ["test/remote/sync_trysync.test.js"], }], "configurations": [ { diff --git a/package-lock.json b/package-lock.json index a0f0dc35..1c1c43cd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3500,12 +3500,13 @@ "dev": true }, "git-documentdb-plugin-remote-nodegit": { - "version": "1.0.0-alpha.6", - "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.0-alpha.6.tgz", - "integrity": "sha512-O0FMOt2gURS0K4S9xmz5SfQM7rpDsc/ejLv5HronndDchhw9Il9GV0w7mhWz09Y2fRaDv1VUEvklNpMwdyZZJA==", + "version": "1.0.0-alpha.8", + "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.0-alpha.8.tgz", + "integrity": "sha512-1YihB9FBfXwxT9UtAvAN1SuXwPd1ZI4Zd/PUGEHJEOmynVB79VFBzXZBBG0pA0VxmxPAMM8gBg6pQavEJoBTJA==", "dev": true, "requires": { "@sosuisen/nodegit": "^0.27.3", + "isomorphic-git": "^1.9.1", "tslog": "^3.2.0" } }, diff --git a/package.json b/package.json index 4d5a9b42..ee7248cd 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "eslint-config-standardize": "^0.7.1", "eslint-plugin-prettierx": "^0.14.0", "expect": "^27.0.2", - "git-documentdb-plugin-remote-nodegit": "^1.0.0-alpha.6", + "git-documentdb-plugin-remote-nodegit": "^1.0.0-alpha.8", "mocha": "^8.3.2", "nyc": "^15.1.0", "parse-git-config": "^3.0.0", diff --git a/src/remote/push_worker.ts b/src/remote/push_worker.ts index fc4f9328..399e7490 100644 --- a/src/remote/push_worker.ts +++ b/src/remote/push_worker.ts @@ -95,7 +95,7 @@ export async function pushWorker ( } // Push - await Remote.push(gitDDB, sync); + await Remote.push(gitDDB.workingDir, sync.options); let remoteChanges: ChangedFile[] | undefined; if (skipGetChanges) { remoteChanges = undefined; diff --git a/src/remote/sync.ts b/src/remote/sync.ts index 7c9249d0..65d4fcdd 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -379,7 +379,8 @@ export class Sync implements SyncInterface { const remoteResult: 'exist' | 'not_exist' = await Remote.checkFetch( this._gitDDB.workingDir, - this._options + this._options, + this._gitDDB.logger ).catch((err: Error) => { throw new Err.RemoteCheckFetchError(err.message); }); @@ -392,7 +393,11 @@ export class Sync implements SyncInterface { this._upstreamBranch = ''; } if (!onlyFetch) { - await Remote.checkPush(this._gitDDB.workingDir, this._options).catch((err: Error) => { + await Remote.checkPush( + this._gitDDB.workingDir, + this._options, + this._gitDDB.logger + ).catch((err: Error) => { throw new Err.RemoteCheckPushError(err.message); }); } diff --git a/src/remote/sync_worker.ts b/src/remote/sync_worker.ts index 15d6c95e..d4c46eac 100644 --- a/src/remote/sync_worker.ts +++ b/src/remote/sync_worker.ts @@ -58,7 +58,7 @@ export async function syncWorker ( /** * Fetch */ - await Remote.fetch(gitDDB, sync, gitDDB.logger); + await Remote.fetch(gitDDB.workingDir, sync.options, gitDDB.logger); /** * Calc distance diff --git a/src/remote/worker_utils.ts b/src/remote/worker_utils.ts index d9ea6510..bcb217c0 100644 --- a/src/remote/worker_utils.ts +++ b/src/remote/worker_utils.ts @@ -22,7 +22,6 @@ import { JsonDoc, NormalizedCommit, } from '../types'; -import { GitDDBInterface } from '../types_gitddb'; import { blobToBinary, blobToJsonDoc, blobToText } from '../crud/blob'; /** diff --git a/test/remote/sync.test.ts b/test/remote/sync.test.ts index 5ad3779f..5e6aa155 100644 --- a/test/remote/sync.test.ts +++ b/test/remote/sync.test.ts @@ -37,6 +37,9 @@ beforeEach(function () { }); before(() => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + fs.removeSync(path.resolve(localDir)); }); @@ -209,87 +212,6 @@ maybe(' Sync#constructor()', () => { await gitDDB.destroy(); }); - it('throws HttpProtocolRequiredError when remoteURL starts with ssh://', async () => { - const dbName = serialId(); - const remoteURL = 'ssh://github.com/'; - const gitDDB: GitDocumentDB = new GitDocumentDB({ - dbName, - localDir, - }); - await gitDDB.open(); - const options: RemoteOptions = { - remoteUrl: remoteURL, - connection: { - type: 'github', - personalAccessToken: 'foobar', - }, - }; - expect(() => new Sync(gitDDB, options)).toThrowError(Err.HttpProtocolRequiredError); - await gitDDB.destroy(); - }); - - it('throws UndefinedPersonalAccessTokenError', async () => { - const dbName = serialId(); - const remoteURL = remoteURLBase + serialId(); - const gitDDB: GitDocumentDB = new GitDocumentDB({ - dbName, - localDir, - }); - await gitDDB.open(); - const options: RemoteOptions = { - remoteUrl: remoteURL, - connection: { - type: 'github', - personalAccessToken: '', - }, - }; - expect(() => new Sync(gitDDB, options)).toThrowError( - Err.UndefinedPersonalAccessTokenError - ); - await gitDDB.destroy(); - }); - - it('does not throw UndefinedPersonalAccessTokenError when syncDirections is "pull" ', async () => { - const dbName = serialId(); - const remoteURL = remoteURLBase + serialId(); - const gitDDB: GitDocumentDB = new GitDocumentDB({ - dbName, - localDir, - }); - await gitDDB.open(); - const options: RemoteOptions = { - remoteUrl: remoteURL, - syncDirection: 'pull', - connection: { - type: 'github', - personalAccessToken: '', - }, - }; - expect(() => new Sync(gitDDB, options)).not.toThrowError( - Err.UndefinedPersonalAccessTokenError - ); - await gitDDB.destroy(); - }); - - it('throws InvalidRepositoryURLError when url does not show a repository.', async () => { - const dbName = serialId(); - const remoteURL = 'https://github.com/'; - const gitDDB: GitDocumentDB = new GitDocumentDB({ - dbName, - localDir, - }); - await gitDDB.open(); - const options: RemoteOptions = { - remoteUrl: remoteURL, - connection: { - type: 'github', - personalAccessToken: 'foobar', - }, - }; - expect(() => new Sync(gitDDB, options)).toThrowError(Err.InvalidRepositoryURLError); - await gitDDB.destroy(); - }); - it('throws IntervalTooSmallError when interval is less than minimumSyncInterval.', async () => { const remoteURL = remoteURLBase + serialId(); const dbName = serialId(); @@ -377,9 +299,6 @@ maybe(' init()', () => { }); it('throws RemoteCheckFetchError.', async () => { - // eslint-disable-next-line @typescript-eslint/no-var-requires - GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); - const dbName = serialId(); const remoteURL = 'https://github.com/sosuisen/foobar_test_for_remote_repository_connect_error'; @@ -414,9 +333,6 @@ maybe(' syncImpl()', () => { }); it('throws RemoteCheckFetchError.', async () => { - // eslint-disable-next-line @typescript-eslint/no-var-requires - GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); - const dbName = serialId(); const remoteURL = remoteURLBase + serialId(); const gitDDB: GitDocumentDB = new GitDocumentDB({ @@ -433,9 +349,6 @@ maybe(' syncImpl()', () => { }); it('creates a remote repository on GitHub by using personal access token', async () => { - // eslint-disable-next-line @typescript-eslint/no-var-requires - GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); - const remoteURL = remoteURLBase + serialId(); const dbNameA = serialId(); @@ -477,9 +390,6 @@ maybe(' tryPush()', () => { }); it('throws PushNotAllowedError.', async () => { - // eslint-disable-next-line @typescript-eslint/no-var-requires - GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); - const remoteURL = remoteURLBase + serialId(); const dbName = serialId(); const gitDDB: GitDocumentDB = new GitDocumentDB({ diff --git a/test/remote/sync_trypush.test.ts b/test/remote/sync_trypush.test.ts index 18b4cfc8..95a68113 100644 --- a/test/remote/sync_trypush.test.ts +++ b/test/remote/sync_trypush.test.ts @@ -28,6 +28,7 @@ import { } from '../remote_utils'; import { SyncResultCancel, SyncResultPush } from '../../src/types'; import { sleep } from '../../src/utils'; +import { GitDocumentDB } from '../../src/git_documentdb'; const reposPrefix = 'test_sync_trypush___'; const localDir = `./test/database_sync_trypush`; @@ -43,6 +44,9 @@ beforeEach(function () { }); before(() => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + fs.removeSync(path.resolve(localDir)); }); diff --git a/test/remote/sync_trysync.test.ts b/test/remote/sync_trysync.test.ts index ab43d9b4..e9ca8d83 100644 --- a/test/remote/sync_trysync.test.ts +++ b/test/remote/sync_trysync.test.ts @@ -18,12 +18,10 @@ import fs from 'fs-extra'; import expect from 'expect'; import { GitDocumentDB } from '../../src/git_documentdb'; import { - FatJsonDoc, SyncResult, SyncResultFastForwardMerge, SyncResultMergeAndPush, SyncResultPush, - SyncResultResolveConflictsAndPush, } from '../../src/types'; import { Err } from '../../src/error'; import { @@ -54,6 +52,9 @@ beforeEach(function () { }); before(() => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + fs.removeSync(path.resolve(localDir)); }); @@ -197,7 +198,7 @@ maybe(': Sync#trySync()', () => { * dbB : * after : jsonA1 */ - it('which includes one local creation when a remote db creates a document', async () => { + it.only('which includes one local creation when a remote db creates a document', async () => { const [dbA, dbB, syncA, syncB] = await createClonedDatabases( remoteURLBase, localDir, diff --git a/test/remote_utils.ts b/test/remote_utils.ts index 6dafbd17..496d6a64 100644 --- a/test/remote_utils.ts +++ b/test/remote_utils.ts @@ -4,7 +4,6 @@ import { Octokit } from '@octokit/rest'; import git from 'isomorphic-git'; import sinon from 'sinon'; import expect from 'expect'; -import nodegit from '@sosuisen/nodegit'; import { ChangedFileDelete, ChangedFileInsert, @@ -17,7 +16,7 @@ import { } from '../src/types'; import { SyncInterface } from '../src/types_sync'; import { GitDocumentDB } from '../src/git_documentdb'; -import { FILE_REMOVE_TIMEOUT, JSON_EXT } from '../src/const'; +import { FILE_REMOVE_TIMEOUT, GIT_DOCUMENTDB_METADATA_DIR, JSON_EXT } from '../src/const'; import { RemoteRepository } from '../src/remote/remote_repository'; const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; @@ -297,6 +296,7 @@ export async function removeRemoteRepositories (reposPrefix: string) { const repo = urlArray[1]; return repo.startsWith(reposPrefix); } + return false; }) ); // console.log(` - Got ${reposArray.length} repositories`); @@ -334,63 +334,45 @@ export const compareWorkingDirAndBlobs = async ( ): Promise => { const files = listFiles(gitDDB, gitDDB.workingDir); - /* - const headCommitOid = await git.resolveRef({ fs, dir: gitDDB.workingDir, ref: 'HEAD' }); - await git.walk({ + const entries: string[] = await git.walk({ fs, dir: gitDDB.workingDir, - trees: [git.TREE({ ref: headCommitOid })], + trees: [git.STAGE()], // @ts-ignore - map: function (fullDocPath, [a]) { - console.log('myres: ' + fullDocPath); - return ''; + // eslint-disable-next-line complexity + map: async function (fullDocPath, [entry]) { + if (fullDocPath.startsWith(GIT_DOCUMENTDB_METADATA_DIR)) return; + if ((await entry?.type()) === 'blob') { + return fullDocPath; + } }, - }); */ + }); - const currentIndex = await gitDDB.repository()?.refreshIndex(); - const entryCount = currentIndex!.entryCount() - 1; // Reduce by 1 due to '.gitddb/info.json' // console.log('# check count: fromFiles: ' + files.length + ', fromIndex: ' + entryCount); - if (files.length !== entryCount) { + if (files.length !== entries.length) { return false; } - /** Basic type (loose or packed) of any Git object. - // https://github.com/libgit2/libgit2/blob/HEAD/include/git2/types.h - typedef enum { - GIT_OBJECT_ANY = -2, // Object can be any of the following - GIT_OBJECT_INVALID = -1, // Object is invalid. - GIT_OBJECT_COMMIT = 1, // A commit object. - GIT_OBJECT_TREE = 2, // A tree (directory listing) object. - GIT_OBJECT_BLOB = 3, // A file revision object. - GIT_OBJECT_TAG = 4, // An annotated tag object. - GIT_OBJECT_OFS_DELTA = 6, // A delta, base is given by an offset. - GIT_OBJECT_REF_DELTA = 7, // A delta, base is given by object id. - } git_object_t; - */ for (const file of files) { // console.log('# check:' + file); - // Type 3 means BLOB - // @ts-ignore - // eslint-disable-next-line no-await-in-loop - const hashFromFile = await nodegit.Odb.hashfile( - gitDDB.workingDir + '/' + file, - 3 - ).catch((err: Error) => console.log(err)); - // console.log(' - fromFile: ' + hashFromFile.tostrS()); - // Does index include blob? - const hashFromIndex = currentIndex?.getByPath(file).id; - // console.log(' - fromIndex: ' + hashFromIndex!.tostrS()); - if (!hashFromIndex?.equal(hashFromFile)) { + if (!entries.includes(file)) { return false; } + + // eslint-disable-next-line no-await-in-loop + const buf = await fs.readFile(gitDDB.workingDir + '/' + file)!; + const data = Uint8Array.from(buf); + // eslint-disable-next-line no-await-in-loop + const { oid } = await git.hashBlob({ object: data }); + // Does blob exist? // eslint-disable-next-line no-await-in-loop - const blob = await gitDDB - .repository() - ?.getBlob(hashFromIndex!) + const readBlobResult = await git + .readBlob({ fs, dir: gitDDB.workingDir, oid }) .catch((err: Error) => console.log(err)); - if (!blob || blob?.rawsize() === 0) { + + if (readBlobResult === undefined) { return false; } // console.log(' - rawSize:' + blob?.rawsize()); From 69b7619c46f84c661491286d25c962dba44dc466 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 14 Jul 2021 03:41:44 +0900 Subject: [PATCH 028/297] fix: replace some errors with Remote.Err --- src/error.ts | 20 -------------------- src/remote/push_worker.ts | 2 +- src/remote/sync.ts | 22 +++++++++++----------- src/remote/sync_worker.ts | 6 +++--- 4 files changed, 15 insertions(+), 35 deletions(-) diff --git a/src/error.ts b/src/error.ts index d3cf5f7c..2656532d 100644 --- a/src/error.ts +++ b/src/error.ts @@ -373,26 +373,6 @@ Current value is '${type}'`); } } - /** - * @public - */ - export class NoMergeBaseFoundError extends BaseError { - constructor () { - super(`No merge base found`); - } - } - - /** - * @public - */ - export class UnfetchedCommitExistsError extends BaseError { - constructor () { - super( - 'Cannot push because a reference that you are trying to update on the remote contains commits that are not present locally.' - ); - } - } - /** * @public */ diff --git a/src/remote/push_worker.ts b/src/remote/push_worker.ts index 399e7490..2a319282 100644 --- a/src/remote/push_worker.ts +++ b/src/remote/push_worker.ts @@ -17,7 +17,7 @@ import { Remote } from './remote'; /** * Push and get changes * - * @throws {@link Err.UnfetchedCommitExistsError} (from push() and validatePushResult()) + * @throws {@link Remote.Err.UnfetchedCommitExistsError} (from push() and validatePushResult()) * @throws {@link Err.SyncWorkerFetchError} (from validatePushResult()) * @throws {@link Err.InvalidJsonObjectError} (from getChanges()) */ diff --git a/src/remote/sync.ts b/src/remote/sync.ts index 65d4fcdd..c6c7714e 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -60,7 +60,7 @@ import { Remote } from './remote'; * Implementation of GitDocumentDB#sync(options, get_sync_result) * * @throws {@link Err.RepositoryNotFoundError} - * @throws {@link Err.UndefinedRemoteURLError} (from Sync#constructor()) + * @throws {@link Remote.Err.UndefinedRemoteURLError} (from Sync#constructor()) * @throws {@link Err.IntervalTooSmallError} (from Sync#constructor()) * * @throws {@link Err.RemoteRepositoryConnectError} (from Sync#init()) @@ -550,7 +550,7 @@ export class Sync implements SyncInterface { * * @throws {@link Err.PushNotAllowedError} (from this and enqueuePushTask) * @throws {@link Err.PushWorkerError} (from this and enqueuePushTask) - * @throws {@link Err.UnfetchedCommitExistsError} (from this and enqueuePushTask) + * @throws {@link Remote.Err.UnfetchedCommitExistsError} (from this and enqueuePushTask) * * @public */ @@ -576,7 +576,7 @@ export class Sync implements SyncInterface { result = resultOrError; } - if (error instanceof Err.UnfetchedCommitExistsError) { + if (error instanceof Remote.Err.UnfetchedCommitExistsError) { if (this._options.syncDirection === 'push') { if (this._options.combineDbStrategy === 'replace-with-ours') { // TODO: Exec replace-with-ours instead of throw error @@ -630,7 +630,7 @@ export class Sync implements SyncInterface { * @throws {@link Err.PushNotAllowedError} (from this and enqueueSyncTask) * @throws {@link Err.SyncWorkerError} (from enqueueSyncTask) * @throws {@link Err.NoMergeBaseFoundError} (from enqueueSyncTask) - * @throws {@link Err.UnfetchedCommitExistsError} (from enqueueSyncTask) + * @throws {@link Remote.Err.UnfetchedCommitExistsError} (from enqueueSyncTask) * * @public */ @@ -663,7 +663,7 @@ export class Sync implements SyncInterface { result = resultOrError; } - if (error instanceof Err.NoMergeBaseFoundError) { + if (error instanceof Remote.Err.NoMergeBaseFoundError) { if (this._options.combineDbStrategy === 'throw-error') { throw error; } @@ -705,7 +705,7 @@ export class Sync implements SyncInterface { if ( // eslint-disable-next-line no-await-in-loop !(await this.canNetworkConnection()) || - error instanceof Err.UnfetchedCommitExistsError + error instanceof Remote.Err.UnfetchedCommitExistsError ) { // Retry for the following reasons: // - Network connection may be improved next time. @@ -735,7 +735,7 @@ export class Sync implements SyncInterface { * Enqueue push task to TaskQueue * * @throws {@link Err.PushWorkerError} - * @throws {@link Err.UnfetchedCommitExistsError} + * @throws {@link Remote.Err.UnfetchedCommitExistsError} * @throws {@link Err.PushNotAllowedError} * * @public @@ -792,7 +792,7 @@ export class Sync implements SyncInterface { }) .catch(err => { // console.log(`Error in push_worker: ${err}`); - if (!(err instanceof Err.UnfetchedCommitExistsError)) { + if (!(err instanceof Remote.Err.UnfetchedCommitExistsError)) { err = new Err.PushWorkerError(err.message); } this.eventHandlers.error.forEach(listener => { @@ -836,7 +836,7 @@ export class Sync implements SyncInterface { * * @throws {@link Err.SyncWorkerError} * @throws {@link Err.NoMergeBaseFoundError} - * @throws {@link Err.UnfetchedCommitExistsError} + * @throws {@link Remote.Err.UnfetchedCommitExistsError} * @throws {@link Err.PushNotAllowedError} * * @public @@ -934,8 +934,8 @@ export class Sync implements SyncInterface { // console.log(`Error in sync_worker: ${err}`); if ( !( - err instanceof Err.NoMergeBaseFoundError || - err instanceof Err.UnfetchedCommitExistsError + err instanceof Remote.Err.NoMergeBaseFoundError || + err instanceof Remote.Err.UnfetchedCommitExistsError ) ) { err = new Err.SyncWorkerError(err.message); diff --git a/src/remote/sync_worker.ts b/src/remote/sync_worker.ts index d4c46eac..77ec49da 100644 --- a/src/remote/sync_worker.ts +++ b/src/remote/sync_worker.ts @@ -11,7 +11,6 @@ import git from 'isomorphic-git'; import fs from 'fs-extra'; import { SHORT_SHA_LENGTH } from '../const'; import { normalizeCommit } from '../utils'; -import { Err } from '../error'; import { GitDDBInterface } from '../types_gitddb'; import { NormalizedCommit, @@ -36,7 +35,7 @@ import { Remote } from './remote'; * @throws {@link Err.ThreeWayMergeError} * @throws {@link Err.CannotDeleteDataError} * @throws {@link Err.InvalidJsonObjectError} (from getChanges()) - * @throws {@link Err.UnfetchedCommitExistsError} (from push_worker()) + * @throws {@link Remote.Err.UnfetchedCommitExistsError} (from push_worker()) * @throws {@link Err.InvalidJsonObjectError} (from push_worker()) * @throws {@link Err.GitPushError} (from push_worker()) * @@ -68,6 +67,7 @@ export async function syncWorker ( dir: gitDDB.workingDir, ref: 'HEAD', }); + const oldRemoteCommitOid = await git.resolveRef({ fs, dir: gitDDB.workingDir, @@ -87,7 +87,7 @@ export async function syncWorker ( // ahead: 1, behind 1 => Merge, may resolve conflict and push: Local has new commits. Remote has pushed new commits. if (distance.ahead === undefined || distance.behind === undefined) { - throw new Err.NoMergeBaseFoundError(); + throw new Remote.Err.NoMergeBaseFoundError(); } else if (distance.ahead === 0 && distance.behind === 0) { return { action: 'nop' }; From db005e619ae6a9f9611689dcab9f0340ac56641b Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 14 Jul 2021 03:42:16 +0900 Subject: [PATCH 029/297] fix: remove unused block --- src/remote/sync.ts | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/remote/sync.ts b/src/remote/sync.ts index c6c7714e..50d5076d 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -432,13 +432,6 @@ export class Sync implements SyncInterface { value: `refs/heads/${this._gitDDB.defaultBranch}`, }); - await git.setConfig({ - fs, - dir: this._gitDDB.workingDir, - path: `branch.${this._gitDDB.defaultBranch}.remote`, - value: 'origin', - }); - this._upstreamBranch = `origin/${this._gitDDB.defaultBranch}`; } else if (this._options.syncDirection === 'push') { From 7a90df48d4add324fb57dd0999c7ff37bd097263 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 14 Jul 2021 03:42:57 +0900 Subject: [PATCH 030/297] fix: do not skip GIT_DOCUMENTDB_METADATA_DIR when get changes --- src/remote/worker_utils.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/remote/worker_utils.ts b/src/remote/worker_utils.ts index bcb217c0..09fd7bb5 100644 --- a/src/remote/worker_utils.ts +++ b/src/remote/worker_utils.ts @@ -155,9 +155,6 @@ export async function getChanges ( if (fullDocPath === '.') { return; } - if (fullDocPath.startsWith(GIT_DOCUMENTDB_METADATA_DIR)) { - return; - } const docType: DocType = fullDocPath.endsWith('.json') ? 'json' : 'text'; if (docType === 'text') { @@ -225,9 +222,6 @@ export async function getAndWriteLocalChanges ( if (fullDocPath === '.') { return; } - if (fullDocPath.startsWith(GIT_DOCUMENTDB_METADATA_DIR)) { - return; - } const docType: DocType = fullDocPath.endsWith('.json') ? 'json' : 'text'; if (docType === 'text') { From 2a704a08fa4c286e21d455a55c40cd43d78794f8 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 14 Jul 2021 03:43:21 +0900 Subject: [PATCH 031/297] fix: remove export --- src/main.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main.ts b/src/main.ts index 9d655e0f..eae5e9d9 100644 --- a/src/main.ts +++ b/src/main.ts @@ -11,7 +11,6 @@ export * from './error'; export * from './git_documentdb'; export * from './types'; export * from './validator'; -export * from './remote/clone'; export * from './remote/remote'; export * from './remote/remote_repository'; export * from './remote/sync'; From 6e26587c5609287dc25ff60e8be1b8887dcce16b Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 14 Jul 2021 03:43:47 +0900 Subject: [PATCH 032/297] fix: add necessary await --- src/remote/combine.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/remote/combine.ts b/src/remote/combine.ts index f466e67b..823f7f54 100644 --- a/src/remote/combine.ts +++ b/src/remote/combine.ts @@ -122,7 +122,7 @@ export async function combineDatabaseWithTheirs ( type: docType, }; } - git.add({ fs, dir: remoteDir, filepath: duplicatedFileName }); + await git.add({ fs, dir: remoteDir, filepath: duplicatedFileName }); duplicates.push({ original, @@ -132,7 +132,7 @@ export async function combineDatabaseWithTheirs ( else { // Copy localFilePath to remoteFilePath if remoteFilePath not exists await fs.copyFile(localFilePath, remoteFilePath); - git.add({ fs, dir: remoteDir, filepath: meta.name }); + await git.add({ fs, dir: remoteDir, filepath: meta.name }); } } From 422bdfd63cec51a20a4b974d462290861f725e18 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 14 Jul 2021 03:44:27 +0900 Subject: [PATCH 033/297] build: bump git-documentdb-plugin-remote-nodegit to v1.0.0-alpha.12 --- package-lock.json | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1c1c43cd..4bebe849 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3500,9 +3500,9 @@ "dev": true }, "git-documentdb-plugin-remote-nodegit": { - "version": "1.0.0-alpha.8", - "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.0-alpha.8.tgz", - "integrity": "sha512-1YihB9FBfXwxT9UtAvAN1SuXwPd1ZI4Zd/PUGEHJEOmynVB79VFBzXZBBG0pA0VxmxPAMM8gBg6pQavEJoBTJA==", + "version": "1.0.0-alpha.12", + "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.0-alpha.12.tgz", + "integrity": "sha512-Je4HCi/l/tWRZTWmkOQ5Qo+nU4xKOpwJi8+IDfJZ/DfOG63svF+N4tH0aGKr+eHYySITbeh1OiYV95ycH0GZFA==", "dev": true, "requires": { "@sosuisen/nodegit": "^0.27.3", diff --git a/package.json b/package.json index ee7248cd..d598a290 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "eslint-config-standardize": "^0.7.1", "eslint-plugin-prettierx": "^0.14.0", "expect": "^27.0.2", - "git-documentdb-plugin-remote-nodegit": "^1.0.0-alpha.8", + "git-documentdb-plugin-remote-nodegit": "^1.0.0-alpha.12", "mocha": "^8.3.2", "nyc": "^15.1.0", "parse-git-config": "^3.0.0", From 5e1903fe836f9e4252451bd0755b5f9d7e6b9cee Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 14 Jul 2021 03:45:09 +0900 Subject: [PATCH 034/297] test: use Remote.Err instead of Err --- test/remote/combine.test.ts | 48 ++++++++++--------------------------- 1 file changed, 12 insertions(+), 36 deletions(-) diff --git a/test/remote/combine.test.ts b/test/remote/combine.test.ts index 62c0b182..e5367111 100644 --- a/test/remote/combine.test.ts +++ b/test/remote/combine.test.ts @@ -19,6 +19,7 @@ import expect from 'expect'; import parse from 'parse-git-config'; import { DuplicatedFile } from '../../src/types'; import { GitDocumentDB } from '../../src/git_documentdb'; +import { Remote } from '../../src/remote/remote'; import { Err } from '../../src/error'; import { compareWorkingDirAndBlobs, @@ -45,6 +46,9 @@ beforeEach(function () { }); before(() => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + fs.removeSync(path.resolve(localDir)); }); @@ -77,9 +81,6 @@ maybe('', () => { */ describe('with NodeGit', () => { it('throws NoMergeBaseFoundError when combineDbStrategy is throw-error in [both] direction', async () => { - // eslint-disable-next-line @typescript-eslint/no-var-requires - GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { combineDbStrategy: 'throw-error', syncDirection: 'both', @@ -93,7 +94,9 @@ maybe('', () => { await dbB.open(); // trySync throws NoMergeBaseFoundError - await expect(dbB.sync(syncA.options)).rejects.toThrowError(Err.NoMergeBaseFoundError); + await expect(dbB.sync(syncA.options)).rejects.toThrowError( + Remote.Err.NoMergeBaseFoundError + ); // await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); // await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); @@ -102,9 +105,6 @@ maybe('', () => { }); it('commits with valid commit message for combine-head-with-theirs', async () => { - // eslint-disable-next-line @typescript-eslint/no-var-requires - GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { combineDbStrategy: 'combine-head-with-theirs', syncDirection: 'both', @@ -123,7 +123,7 @@ maybe('', () => { // Combine with remote db await expect(dbB.sync(syncA.options)).resolves.not.toThrowError( - Err.NoMergeBaseFoundError + Remote.Err.NoMergeBaseFoundError ); const headCommitOid = await git.resolveRef({ @@ -142,9 +142,6 @@ maybe('', () => { }); it('succeeds when combine-head-with-theirs with empty local and empty remote', async () => { - // eslint-disable-next-line @typescript-eslint/no-var-requires - GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { combineDbStrategy: 'combine-head-with-theirs', syncDirection: 'both', @@ -159,7 +156,7 @@ maybe('', () => { // Combine with remote db await expect(dbB.sync(syncA.options)).resolves.not.toThrowError( - Err.NoMergeBaseFoundError + Remote.Err.NoMergeBaseFoundError ); // Put new doc to combined db. @@ -176,9 +173,6 @@ maybe('', () => { }); it('succeeds combine-head-with-theirs with empty local and not empty remote', async () => { - // eslint-disable-next-line @typescript-eslint/no-var-requires - GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { combineDbStrategy: 'combine-head-with-theirs', syncDirection: 'both', @@ -197,7 +191,7 @@ maybe('', () => { // Combine with remote db await expect(dbB.sync(syncA.options)).resolves.not.toThrowError( - Err.NoMergeBaseFoundError + Remote.Err.NoMergeBaseFoundError ); // Put new doc to combined db. @@ -214,9 +208,6 @@ maybe('', () => { }); it('succeeds when combine-head-with-theirs with not empty local and empty remote', async () => { - // eslint-disable-next-line @typescript-eslint/no-var-requires - GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { combineDbStrategy: 'combine-head-with-theirs', syncDirection: 'both', @@ -234,7 +225,7 @@ maybe('', () => { // Combine with remote db await expect(dbB.sync(syncA.options)).resolves.not.toThrowError( - Err.NoMergeBaseFoundError + Remote.Err.NoMergeBaseFoundError ); // Put new doc to combined db. @@ -251,9 +242,6 @@ maybe('', () => { }); it('succeeds when combine-head-with-theirs with deep local and deep remote', async () => { - // eslint-disable-next-line @typescript-eslint/no-var-requires - GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { combineDbStrategy: 'combine-head-with-theirs', syncDirection: 'both', @@ -288,9 +276,6 @@ maybe('', () => { }); it('returns SyncResult with duplicates when combine-head-with-theirs with not empty local and not empty remote', async () => { - // eslint-disable-next-line @typescript-eslint/no-var-requires - GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { combineDbStrategy: 'combine-head-with-theirs', syncDirection: 'both', @@ -359,9 +344,6 @@ maybe('', () => { }); it('returns SyncResult with duplicates when combine-head-with-theirs with deep local and deep remote', async () => { - // eslint-disable-next-line @typescript-eslint/no-var-requires - GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { combineDbStrategy: 'combine-head-with-theirs', syncDirection: 'both', @@ -433,9 +415,6 @@ maybe('', () => { }); it('invokes combine event with duplicates when combine-head-with-theirs with not empty local and not empty remote', async () => { - // eslint-disable-next-line @typescript-eslint/no-var-requires - GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { combineDbStrategy: 'combine-head-with-theirs', syncDirection: 'both', @@ -515,9 +494,6 @@ maybe('', () => { }); it('copies author from local repository', async () => { - // eslint-disable-next-line @typescript-eslint/no-var-requires - GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { combineDbStrategy: 'combine-head-with-theirs', syncDirection: 'both', @@ -538,7 +514,7 @@ maybe('', () => { // Combine with remote db await expect(dbB.sync(syncA.options)).resolves.not.toThrowError( - Err.NoMergeBaseFoundError + Remote.Err.NoMergeBaseFoundError ); const config = parse.sync({ cwd: dbB.workingDir, path: '.git/config' }); From fbb6fce8fa170f96ed0e726ce5dc39d171cac414 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 14 Jul 2021 03:45:54 +0900 Subject: [PATCH 035/297] test: use Remote.Err instead of Err --- test/remote/sync_trysync.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/remote/sync_trysync.test.ts b/test/remote/sync_trysync.test.ts index e9ca8d83..af003031 100644 --- a/test/remote/sync_trysync.test.ts +++ b/test/remote/sync_trysync.test.ts @@ -17,6 +17,7 @@ import git from 'isomorphic-git'; import fs from 'fs-extra'; import expect from 'expect'; import { GitDocumentDB } from '../../src/git_documentdb'; +import { Remote } from '../../src/remote/remote'; import { SyncResult, SyncResultFastForwardMerge, @@ -760,7 +761,7 @@ maybe(': Sync#trySync()', () => { // tryPush throws UnfetchedCommitExistsError await expect(dbB.sync(syncA.options)).rejects.toThrowError( - Err.UnfetchedCommitExistsError + Remote.Err.UnfetchedCommitExistsError ); await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); From 24c9fa8356b2009ea1fbc18ee959b958bec8f844 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 14 Jul 2021 03:46:37 +0900 Subject: [PATCH 036/297] test: remove test for saveAppInfo --- test/remote/sync_trysync.test.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/test/remote/sync_trysync.test.ts b/test/remote/sync_trysync.test.ts index af003031..5ce1d9de 100644 --- a/test/remote/sync_trysync.test.ts +++ b/test/remote/sync_trysync.test.ts @@ -25,6 +25,7 @@ import { SyncResultPush, } from '../../src/types'; import { Err } from '../../src/error'; + import { compareWorkingDirAndBlobs, createClonedDatabases, @@ -789,12 +790,9 @@ maybe(': Sync#trySync()', () => { }; const putResult = await dbA.putFatDoc('.gitddb/info.json', toSortedJSONString(info)); - const appInfo = { ver: 1.0 }; - await dbA.saveAppInfo(appInfo); - await syncA.tryPush(); + await syncB.trySync(); - await expect(dbB.loadAppInfo()).resolves.toEqual(appInfo); const fatDoc = { _id: '.gitddb/info', From 7b23b03cb6c92e43031db58addda6946d692eb06 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 14 Jul 2021 03:46:55 +0900 Subject: [PATCH 037/297] test: testing sync_trysync.test.ts --- test/remote/sync_trysync.test.ts | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/test/remote/sync_trysync.test.ts b/test/remote/sync_trysync.test.ts index 5ce1d9de..8b1b59ee 100644 --- a/test/remote/sync_trysync.test.ts +++ b/test/remote/sync_trysync.test.ts @@ -200,11 +200,13 @@ maybe(': Sync#trySync()', () => { * dbB : * after : jsonA1 */ - it.only('which includes one local creation when a remote db creates a document', async () => { + it('which includes one local creation when a remote db creates a document', async () => { const [dbA, dbB, syncA, syncB] = await createClonedDatabases( remoteURLBase, localDir, - serialId + serialId, + undefined, + 'trace' ); // A puts and pushes const jsonA1 = { _id: '1', name: 'fromA' }; @@ -694,6 +696,7 @@ maybe(': Sync#trySync()', () => { it('skips consecutive sync tasks', async () => { const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId); const results: SyncResult[] = []; + dbA.logLevel = 'trace'; for (let i = 0; i < 3; i++) { // eslint-disable-next-line promise/catch-or-return syncA.trySync().then(result => results.push(result)); @@ -771,9 +774,8 @@ maybe(': Sync#trySync()', () => { await destroyDBs([dbA, dbB]); }); - it('syncs files under .gitddb', async () => { + it.only('syncs files under .gitddb', async () => { const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId); - const dbNameB = serialId(); const dbB: GitDocumentDB = new GitDocumentDB({ dbName: dbNameB, @@ -783,6 +785,9 @@ maybe(': Sync#trySync()', () => { await dbB.open(); const syncB = await dbB.sync(syncA.options); + dbA.logLevel = 'trace'; + dbB.logLevel = 'trace'; + const info = { dbId: 'foo', creator: 'bar', @@ -801,7 +806,9 @@ maybe(': Sync#trySync()', () => { type: 'json', doc: info, }; - await expect(dbB.getFatDoc('.gitddb/info.json')).resolves.toEqual(fatDoc); + const mergedFatDoc = await dbB.getFatDoc('.gitddb/info.json'); + console.log(mergedFatDoc); + expect(mergedFatDoc).toEqual(fatDoc); await destroyDBs([dbA, dbB]); }); From e48bc92a0610052dbccf368177dce9a038489283 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 14 Jul 2021 16:37:41 +0900 Subject: [PATCH 038/297] build: bump git-documentdb-plugin-remote-nodegit to v1.0.0.alpha.14 --- package-lock.json | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4bebe849..5e2c175f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3500,9 +3500,9 @@ "dev": true }, "git-documentdb-plugin-remote-nodegit": { - "version": "1.0.0-alpha.12", - "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.0-alpha.12.tgz", - "integrity": "sha512-Je4HCi/l/tWRZTWmkOQ5Qo+nU4xKOpwJi8+IDfJZ/DfOG63svF+N4tH0aGKr+eHYySITbeh1OiYV95ycH0GZFA==", + "version": "1.0.0-alpha.14", + "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.0-alpha.14.tgz", + "integrity": "sha512-kt5D18cIlqEmF4gCOCh1Bo3NyuMDtbNshp4nDlRDgakBhh9af7dXUQdoYpvzAkeFUFbNK4va7I/O7tn2Q74Zzw==", "dev": true, "requires": { "@sosuisen/nodegit": "^0.27.3", diff --git a/package.json b/package.json index d598a290..a987e86b 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "eslint-config-standardize": "^0.7.1", "eslint-plugin-prettierx": "^0.14.0", "expect": "^27.0.2", - "git-documentdb-plugin-remote-nodegit": "^1.0.0-alpha.12", + "git-documentdb-plugin-remote-nodegit": "^1.0.0-alpha.14", "mocha": "^8.3.2", "nyc": "^15.1.0", "parse-git-config": "^3.0.0", From 8dc9b3629c3cc8459cafee869f8e882702537f8f Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 14 Jul 2021 16:38:26 +0900 Subject: [PATCH 039/297] fix: remote unused block --- src/remote/sync_worker.ts | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/remote/sync_worker.ts b/src/remote/sync_worker.ts index 77ec49da..505f64bb 100644 --- a/src/remote/sync_worker.ts +++ b/src/remote/sync_worker.ts @@ -30,14 +30,14 @@ import { Remote } from './remote'; /** * sync_worker * - * @throws {@link Err.SyncWorkerFetchError} (from fetch() and push_worker()) + * @throws {@link Err.SyncWorkerFetchError} (from fetch() and pushWorker()) * @throws {@link Err.NoMergeBaseFoundError} * @throws {@link Err.ThreeWayMergeError} * @throws {@link Err.CannotDeleteDataError} * @throws {@link Err.InvalidJsonObjectError} (from getChanges()) - * @throws {@link Remote.Err.UnfetchedCommitExistsError} (from push_worker()) - * @throws {@link Err.InvalidJsonObjectError} (from push_worker()) - * @throws {@link Err.GitPushError} (from push_worker()) + * @throws {@link Remote.Err.UnfetchedCommitExistsError} (from pushWorker()) + * @throws {@link Err.InvalidJsonObjectError} (from pushWorker()) + * @throws {@link Err.GitPushError} (from pushWorker()) * * @internal */ @@ -162,13 +162,6 @@ export async function syncWorker ( tree: mergedTreeOid, }); - /* - const localChanges = await getAndWriteLocalChanges( - gitDDB.workingDir, - oldCommitOid, - mergeCommitOid! - ); - */ let localCommits: NormalizedCommit[] | undefined; // Get list of commits which has been added to local From 9b641a8f7d0809feb1a3185eed4adf0dcb413249 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 14 Jul 2021 16:39:01 +0900 Subject: [PATCH 040/297] fix: return undefined when throw error --- src/utils.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/utils.ts b/src/utils.ts index 809b338e..374ff0a3 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -80,7 +80,9 @@ export function toSortedJSONString (obj: Record) { // eslint-disable-next-line complexity export async function getAllMetadata (workingDir: string): Promise { const files: DocMetadata[] = []; - const commitOid = await resolveRef({ fs, dir: workingDir, ref: 'HEAD' }); + const commitOid = await resolveRef({ fs, dir: workingDir, ref: 'HEAD' }).catch( + () => undefined + ); if (commitOid === undefined) return []; From 98c19704b57eee359391b23ed2211315f58c0387 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 14 Jul 2021 16:39:28 +0900 Subject: [PATCH 041/297] fix: show merge cases for debugging --- src/remote/3way_merge.ts | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/remote/3way_merge.ts b/src/remote/3way_merge.ts index c61b65f0..e7116d83 100644 --- a/src/remote/3way_merge.ts +++ b/src/remote/3way_merge.ts @@ -321,7 +321,7 @@ export async function threeWayMerge ( // A new file has been inserted into theirs. // Write it to the working directory. // Write it to the index. - // console.log(' #case 1 - Accept theirs (insert): ' + fullDocPath); + console.log(' #case 1 - Accept theirs (insert): ' + fullDocPath); const theirsData = (await theirs.content())!; const theirsFatDoc = await getFatDocFromData(theirsData, fullDocPath, docType); await writeBlobToFile(gitDDB.workingDir, fullDocPath, theirsData); @@ -345,7 +345,7 @@ export async function threeWayMerge ( // A new file has been inserted into ours. // It has already been created on the working directory. // It has already been added to the index. - // console.log(' #case 2 - Accept ours (insert): ' + fullDocPath); + console.log(' #case 2 - Accept ours (insert): ' + fullDocPath); const oursData = (await ours.content())!; const oursFatDoc = await getFatDocFromData(oursData, fullDocPath, docType); return [ @@ -370,7 +370,7 @@ export async function threeWayMerge ( // The same filenames with exactly the same contents are inserted on both local and remote. // It has already been created on the both working directory. // It has already been added to the both index. - // console.log(' #case 3 - Accept both (insert): ' + fullDocPath); + console.log(' #case 3 - Accept both (insert): ' + fullDocPath); return [ { mode: (await ours.mode()).toString(8), @@ -396,11 +396,11 @@ export async function threeWayMerge ( ); let mode = ''; if (strategy === 'ours' || strategy === 'ours-diff') { - // console.log(' #case 4 - Conflict. Accept ours (insert): ' + fullDocPath); + console.log(' #case 4 - Conflict. Accept ours (insert): ' + fullDocPath); mode = (await ours.mode()).toString(8); } else if (strategy === 'theirs' || strategy === 'theirs-diff') { - // console.log(' #case 5 - Conflict. Accept theirs (insert): ' + fullDocPath); + console.log(' #case 5 - Conflict. Accept theirs (insert): ' + fullDocPath); mode = (await theirs.mode()).toString(8); } @@ -476,7 +476,7 @@ export async function threeWayMerge ( } else if (base && !ours && !theirs) { // The same files have been removed from both local and remote. - // console.log(' #case 6 - Accept both (delete): ' + fullDocPath); + console.log(' #case 6 - Accept both (delete): ' + fullDocPath); return [undefined, undefined, undefined, undefined]; } else if (base && !ours && theirs) { @@ -487,7 +487,7 @@ export async function threeWayMerge ( if (baseOid === theirsOid) { // A file has been removed from ours. - // console.log(' #case 7 - Accept ours (delete): ' + fullDocPath); + console.log(' #case 7 - Accept ours (delete): ' + fullDocPath); return [ undefined, undefined, @@ -504,7 +504,7 @@ export async function threeWayMerge ( const strategy = await getStrategy(conflictResolutionStrategy, undefined, theirsFatDoc); if (strategy === 'ours' || strategy === 'ours-diff') { - // console.log(' #case 8 - Conflict. Accept ours (delete): ' + fullDocPath); + console.log(' #case 8 - Conflict. Accept ours (delete): ' + fullDocPath); const baseData = (await base.content())!; const baseFatDoc = await getFatDocFromData(baseData, fullDocPath, docType); const acceptedConflict: AcceptedConflict = { @@ -523,7 +523,7 @@ export async function threeWayMerge ( ]; } else if (strategy === 'theirs' || strategy === 'theirs-diff') { - // console.log(' #case 9 - Conflict. Accept theirs (update): ' + fullDocPath); + console.log(' #case 9 - Conflict. Accept theirs (update): ' + fullDocPath); const acceptedConflict: AcceptedConflict = { fatDoc: theirsFatDoc, strategy: strategy, @@ -555,7 +555,7 @@ export async function threeWayMerge ( if (baseOid === oursOid) { // A file has been removed from theirs. - // console.log(' #case 10 - Accept theirs (delete): ' + fullDocPath); + console.log(' #case 10 - Accept theirs (delete): ' + fullDocPath); await fs.remove(nodePath.resolve(gitDDB.workingDir, fullDocPath)).catch(() => { throw new Err.CannotDeleteDataError(); }); @@ -576,7 +576,7 @@ export async function threeWayMerge ( const strategy = await getStrategy(conflictResolutionStrategy, oursFatDoc, undefined); if (strategy === 'ours' || strategy === 'ours-diff') { - // console.log(' #case 11 - Conflict. Accept ours (update): ' + fullDocPath); + console.log(' #case 11 - Conflict. Accept ours (update): ' + fullDocPath); const acceptedConflict: AcceptedConflict = { fatDoc: oursFatDoc, strategy: strategy, @@ -598,7 +598,7 @@ export async function threeWayMerge ( ]; } else if (strategy === 'theirs' || strategy === 'theirs-diff') { - // console.log(' #case 12 - Conflict. Accept theirs (delete): ' + fullDocPath); + console.log(' #case 12 - Conflict. Accept theirs (delete): ' + fullDocPath); const baseData = (await base.content())!; const baseFatDoc = await getFatDocFromData(baseData, fullDocPath, docType); const acceptedConflicts: AcceptedConflict = { @@ -628,7 +628,7 @@ export async function threeWayMerge ( if (oursOid === theirsOid) { // The same filenames with exactly the same contents are inserted into both local and remote. - // console.log(' #case 13 - Accept both (update): ' + fullDocPath); + console.log(' #case 13 - Accept both (update): ' + fullDocPath); return [ { // TODO: check whether mode is the same. @@ -643,7 +643,7 @@ export async function threeWayMerge ( ]; } else if (baseOid === oursOid) { - // console.log(' #case 14 - Accept theirs (update): ' + fullDocPath); + console.log(' #case 14 - Accept theirs (update): ' + fullDocPath); const oursData = (await ours.content())!; const oursFatDoc = await getFatDocFromData(oursData, fullDocPath, docType); const theirsData = (await theirs.content())!; @@ -667,7 +667,7 @@ export async function threeWayMerge ( ]; } else if (baseOid === theirsOid) { - // console.log(' #case 15 - Accept ours (update): ' + fullDocPath); + console.log(' #case 15 - Accept ours (update): ' + fullDocPath); const oursData = (await ours.content())!; const oursFatDoc = await getFatDocFromData(oursData, fullDocPath, docType); const theirsData = (await theirs.content())!; @@ -703,7 +703,7 @@ export async function threeWayMerge ( ); if (strategy === 'ours') { - // console.log(' #case 16 - Conflict. Accept ours (update): ' + fullDocPath); + console.log(' #case 16 - Conflict. Accept ours (update): ' + fullDocPath); return [ { mode: (await ours.mode()).toString(8), @@ -725,7 +725,7 @@ export async function threeWayMerge ( ]; } else if (strategy === 'theirs') { - // console.log(' #case 17 - Conflict. Accept theirs (update): ' + fullDocPath); + console.log(' #case 17 - Conflict. Accept theirs (update): ' + fullDocPath); await writeBlobToFile(gitDDB.workingDir, fullDocPath, theirsData); await git.add({ fs, dir: gitDDB.workingDir, filepath: fullDocPath }); @@ -765,11 +765,11 @@ export async function threeWayMerge ( let mode = ''; if (strategy === 'ours-diff') { - // console.log(' #case 16 (diff) - Conflict. Accept ours (update): ' + fullDocPath); + console.log(' #case 16 (diff) - Conflict. Accept ours (update): ' + fullDocPath); mode = (await ours.mode()).toString(8); } else if (strategy === 'theirs-diff') { - // console.log(' #case 17 (diff) - Conflict. Accept theirs (update): ' + fullDocPath); + console.log(' #case 17 (diff) - Conflict. Accept theirs (update): ' + fullDocPath); mode = (await theirs.mode()).toString(8); } From 0a78cb5629dd58974cc12c97ed24aca981f2b94f Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 14 Jul 2021 16:39:44 +0900 Subject: [PATCH 042/297] test: pass sync_trysync --- test/remote/sync_trysync.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/remote/sync_trysync.test.ts b/test/remote/sync_trysync.test.ts index 8b1b59ee..f0e53cb1 100644 --- a/test/remote/sync_trysync.test.ts +++ b/test/remote/sync_trysync.test.ts @@ -696,7 +696,7 @@ maybe(': Sync#trySync()', () => { it('skips consecutive sync tasks', async () => { const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId); const results: SyncResult[] = []; - dbA.logLevel = 'trace'; + for (let i = 0; i < 3; i++) { // eslint-disable-next-line promise/catch-or-return syncA.trySync().then(result => results.push(result)); @@ -774,7 +774,7 @@ maybe(': Sync#trySync()', () => { await destroyDBs([dbA, dbB]); }); - it.only('syncs files under .gitddb', async () => { + it('syncs files under .gitddb', async () => { const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId); const dbNameB = serialId(); const dbB: GitDocumentDB = new GitDocumentDB({ From e4a4e8b5db6214c8358609b68657a8a0c1d6ff26 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 14 Jul 2021 19:07:27 +0900 Subject: [PATCH 043/297] fix: add isSameFatDoc to detect localChange and remoteChange correctly --- src/crud/blob.ts | 15 ++++++++- src/remote/3way_merge.ts | 69 ++++++++++++++++++++++++++-------------- 2 files changed, 59 insertions(+), 25 deletions(-) diff --git a/src/crud/blob.ts b/src/crud/blob.ts index 16f452cf..47dce986 100644 --- a/src/crud/blob.ts +++ b/src/crud/blob.ts @@ -11,7 +11,7 @@ import { readBlob, ReadBlobResult, resolveRef } from 'isomorphic-git'; import { JSON_EXT } from '../const'; import { utf8decode } from '../utils'; import { Err } from '../error'; -import { FatBinaryDoc, FatJsonDoc, FatTextDoc, JsonDoc } from '../types'; +import { FatBinaryDoc, FatDoc, FatJsonDoc, FatTextDoc, JsonDoc } from '../types'; /** * blobToJsonDoc @@ -136,3 +136,16 @@ export async function readLatestBlob ( filepath: fullDocPath, }).catch(() => undefined); } + +/** + * Check if two FatDocs are the same. + */ +export function isSameFatDoc (a: FatDoc, b: FatDoc) { + if (a.type !== b.type) { + return false; + } + if (a.type === 'json') { + return JSON.stringify(a) === JSON.stringify(b); + } + return a === b; +} diff --git a/src/remote/3way_merge.ts b/src/remote/3way_merge.ts index e7116d83..4387380b 100644 --- a/src/remote/3way_merge.ts +++ b/src/remote/3way_merge.ts @@ -18,6 +18,7 @@ import { getFatDocFromData, writeBlobToFile } from './worker_utils'; import { toSortedJSONString, utf8decode } from '../utils'; import { JsonDiff } from './json_diff'; import { SyncInterface } from '../types_sync'; +import { isSameFatDoc } from '../crud/blob'; function getStrategy ( strategy: ConflictResolutionStrategies | undefined, @@ -366,14 +367,18 @@ export async function threeWayMerge ( else if (!base && ours && theirs) { const oursOid = await ours.oid(); const theirsOid = await theirs.oid(); - if (oursOid === theirsOid) { + + const oursMode = (await ours.mode()).toString(8); + const theirsMode = (await theirs.mode()).toString(8); + + if (oursOid === theirsOid && oursMode === theirsMode) { // The same filenames with exactly the same contents are inserted on both local and remote. // It has already been created on the both working directory. // It has already been added to the both index. console.log(' #case 3 - Accept both (insert): ' + fullDocPath); return [ { - mode: (await ours.mode()).toString(8), + mode: oursMode, path: basename(fullDocPath), oid: oursOid, type: 'blob', @@ -389,19 +394,21 @@ export async function threeWayMerge ( const theirsData = (await theirs.content())!; const oursFatDoc = await getFatDocFromData(oursData, fullDocPath, docType); const theirsFatDoc = await getFatDocFromData(theirsData, fullDocPath, docType); + const strategy = await getStrategy( conflictResolutionStrategy, oursFatDoc, theirsFatDoc ); + let mode = ''; if (strategy === 'ours' || strategy === 'ours-diff') { console.log(' #case 4 - Conflict. Accept ours (insert): ' + fullDocPath); - mode = (await ours.mode()).toString(8); + mode = oursMode; } else if (strategy === 'theirs' || strategy === 'theirs-diff') { console.log(' #case 5 - Conflict. Accept theirs (insert): ' + fullDocPath); - mode = (await theirs.mode()).toString(8); + mode = theirsMode; } let resultFatDoc: FatDoc; @@ -444,16 +451,21 @@ export async function threeWayMerge ( resultFatDoc = await getFatDocFromData(data, fullDocPath, docType); await writeBlobToFile(gitDDB.workingDir, fullDocPath, data); await git.add({ fs, dir: gitDDB.workingDir, filepath: fullDocPath }); - localChange = { - operation: 'update', - old: oursFatDoc, - new: resultFatDoc, - }; - remoteChange = { - operation: 'update', - old: theirsFatDoc, - new: resultFatDoc, - }; + + if (!isSameFatDoc(oursFatDoc, resultFatDoc)) { + localChange = { + operation: 'update', + old: oursFatDoc, + new: resultFatDoc, + }; + } + if (!isSameFatDoc(theirsFatDoc, resultFatDoc)) { + remoteChange = { + operation: 'update', + old: theirsFatDoc, + new: resultFatDoc, + }; + } } const acceptedConflict: AcceptedConflict = { @@ -773,23 +785,32 @@ export async function threeWayMerge ( mode = (await theirs.mode()).toString(8); } - return [ - { - mode, - path: basename(fullDocPath), - oid: resultFatDoc.fileOid, - type: 'blob', - }, - { + let localChange: ChangedFile | undefined; + let remoteChange: ChangedFile | undefined; + if (!isSameFatDoc(oursFatDoc, resultFatDoc)) { + localChange = { operation: 'update', old: oursFatDoc, new: resultFatDoc, - }, - { + }; + } + if (!isSameFatDoc(theirsFatDoc, resultFatDoc)) { + remoteChange = { operation: 'update', old: theirsFatDoc, new: resultFatDoc, + }; + } + + return [ + { + mode, + path: basename(fullDocPath), + oid: resultFatDoc.fileOid, + type: 'blob', }, + localChange, + remoteChange, { fatDoc: resultFatDoc, strategy: strategy, From 71a83a3b6bb5811026d6eab47a13480e831c2606 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 14 Jul 2021 19:07:48 +0900 Subject: [PATCH 044/297] fix: remove unused errors --- src/error.ts | 113 +++++---------------------------------------------- 1 file changed, 10 insertions(+), 103 deletions(-) diff --git a/src/error.ts b/src/error.ts index 2656532d..0df6c1dc 100644 --- a/src/error.ts +++ b/src/error.ts @@ -145,6 +145,15 @@ export namespace Err { } } + /** + * @public + */ + export class UndefinedPersonalAccessTokenError extends BaseError { + constructor () { + super(`Personal Access Token of your GitHub account is needed.`); + } + } + /** * @public */ @@ -230,15 +239,6 @@ export namespace Err { } } - /** - * @public - */ - export class InvalidURLError extends BaseError { - constructor (url: unknown) { - super(`Invalid url: ${url}'`); - } - } - /** * @public */ @@ -248,53 +248,6 @@ export namespace Err { } } - /** - * @public - */ - export class RemoteRepositoryNotFoundError extends BaseError { - constructor (url: unknown) { - super( - `Repository does not exist, or you do not have permission to access the repository: ${url}` - ); - } - } - - /** - * @public - */ - export class PushPermissionDeniedError extends BaseError { - constructor (mes: unknown) { - super(`Permission denied to push to the repository: ${mes}`); - } - } - - /** - * @public - */ - export class FetchPermissionDeniedError extends BaseError { - constructor (mes: unknown) { - super(`Permission denied to fetch to the repository: ${mes}`); - } - } - - /** - * @public - */ - export class FetchConnectionFailedError extends BaseError { - constructor (mes: unknown) { - super(`Fetch connection failed: ${mes}`); - } - } - - /** - * @public - */ - export class PushConnectionFailedError extends BaseError { - constructor (mes: unknown) { - super(`Push connection failed: ${mes}`); - } - } - /** * @public */ @@ -328,24 +281,6 @@ Current value is '${type}'`); } } - /** - * @public - */ - export class UndefinedPersonalAccessTokenError extends BaseError { - constructor () { - super(`Personal Access Token of your GitHub account is needed.`); - } - } - - /** - * @public - */ - export class SyncWorkerFetchError extends BaseError { - constructor (mes: string) { - super(`Fetch error in sync worker: ${mes}`); - } - } - /** * @public */ @@ -364,15 +299,6 @@ Current value is '${type}'`); } } - /** - * @public - */ - export class InvalidRepositoryURLError extends BaseError { - constructor (url: unknown) { - super(`Repository URL is invalid: ${url}`); - } - } - /** * @public */ @@ -432,7 +358,7 @@ Current value is '${type}'`); /** * @public */ - export class CannotConnectError extends BaseError { + export class CannotConnectRemoteRepositoryError extends BaseError { constructor (public retry: number, url: string, mes: string) { super(`Cannot connect to ${url}: ${mes}`); } @@ -555,15 +481,6 @@ Current value is '${type}'`); } } - /** - * @public - */ - export class GitPushError extends BaseError { - constructor (mes: string) { - super(`Push error in Git : ${mes}`); - } - } - /** * @public */ @@ -601,14 +518,4 @@ Current value is '${type}'`); super(`Combine database failed: ${mes})`); } } - - /** - * @public - */ - export class InvalidSSHKeyPathError extends BaseError { - constructor () { - const e = `Invalid SSH key path`; - super(e); - } - } } From 88f5ac9eb96b916fb764d827d614a20a28ad1eab Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 14 Jul 2021 19:09:09 +0900 Subject: [PATCH 045/297] fix: rename errors --- src/remote/push_worker.ts | 2 +- src/remote/remote_repository.ts | 16 ++++++++++++---- src/remote/sync_worker.ts | 6 +++--- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/remote/push_worker.ts b/src/remote/push_worker.ts index 2a319282..b342911c 100644 --- a/src/remote/push_worker.ts +++ b/src/remote/push_worker.ts @@ -18,7 +18,7 @@ import { Remote } from './remote'; * Push and get changes * * @throws {@link Remote.Err.UnfetchedCommitExistsError} (from push() and validatePushResult()) - * @throws {@link Err.SyncWorkerFetchError} (from validatePushResult()) + * @throws {@link Remote.Err.GitFetchError} (from validatePushResult()) * @throws {@link Err.InvalidJsonObjectError} (from getChanges()) */ export async function pushWorker ( diff --git a/src/remote/remote_repository.ts b/src/remote/remote_repository.ts index 0c2247ef..6841800c 100644 --- a/src/remote/remote_repository.ts +++ b/src/remote/remote_repository.ts @@ -59,7 +59,7 @@ export class RemoteRepository { * * @throws {@link Err.UndefinedPersonalAccessTokenError} * @throws {@link Err.PersonalAccessTokenForAnotherAccountError} - * @throws {@link Err.CannotConnectError} + * @throws {@link Err.CannotConnectRemoteRepositoryError} * * may include the following errors: * @@ -115,7 +115,11 @@ export class RemoteRepository { await sleep(NETWORK_RETRY_INTERVAL); } if (result instanceof Error) { - throw new Err.CannotConnectError(retry, this._options.remoteUrl!, result.message); + throw new Err.CannotConnectRemoteRepositoryError( + retry, + this._options.remoteUrl!, + result.message + ); } } else { @@ -131,7 +135,7 @@ export class RemoteRepository { * connection.type must be 'github' * * @throws {@link Err.UndefinedPersonalAccessTokenError} - * @throws {@link Err.CannotConnectError} + * @throws {@link Err.CannotConnectRemoteRepositoryError} * * may include the following errors: * @@ -180,7 +184,11 @@ export class RemoteRepository { await sleep(NETWORK_RETRY_INTERVAL); } if (result instanceof Error) { - throw new Err.CannotConnectError(retry, this._options.remoteUrl!, result.message); + throw new Err.CannotConnectRemoteRepositoryError( + retry, + this._options.remoteUrl!, + result.message + ); } } else { diff --git a/src/remote/sync_worker.ts b/src/remote/sync_worker.ts index 505f64bb..501db41d 100644 --- a/src/remote/sync_worker.ts +++ b/src/remote/sync_worker.ts @@ -30,14 +30,14 @@ import { Remote } from './remote'; /** * sync_worker * - * @throws {@link Err.SyncWorkerFetchError} (from fetch() and pushWorker()) - * @throws {@link Err.NoMergeBaseFoundError} + * @throws {@link Remote.Err.GitFetchError} (from fetch() and pushWorker()) + * @throws {@link Remote.Err.NoMergeBaseFoundError} * @throws {@link Err.ThreeWayMergeError} * @throws {@link Err.CannotDeleteDataError} * @throws {@link Err.InvalidJsonObjectError} (from getChanges()) * @throws {@link Remote.Err.UnfetchedCommitExistsError} (from pushWorker()) + * @throws {@link Remote.Err.GitPushError} (from pushWorker()) * @throws {@link Err.InvalidJsonObjectError} (from pushWorker()) - * @throws {@link Err.GitPushError} (from pushWorker()) * * @internal */ From 994459109e4b00ff58fa5837d767644eb992c349 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 14 Jul 2021 19:09:27 +0900 Subject: [PATCH 046/297] fix: correct return type --- src/types_sync.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types_sync.ts b/src/types_sync.ts index a6739432..308d10aa 100644 --- a/src/types_sync.ts +++ b/src/types_sync.ts @@ -71,7 +71,7 @@ export interface SyncInterface { currentRetries(): number; on(event: SyncEvent, callback: SyncCallback, collectionPath?: string): SyncInterface; - off(event: SyncEvent, callback: SyncCallback): void; + off(event: SyncEvent, callback: SyncCallback): SyncInterface; } /** From 2dc41863ff89e1c0a86cadb4ef0a3323aa85941c Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 14 Jul 2021 19:10:03 +0900 Subject: [PATCH 047/297] fix: add isClosed --- src/remote/sync.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/remote/sync.ts b/src/remote/sync.ts index 50d5076d..d731f498 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -177,7 +177,7 @@ export class Sync implements SyncInterface { private _gitDDB: GitDDBInterface; private _syncTimer: NodeJS.Timeout | undefined; private _retrySyncCounter = 0; // Decremental count - + private _isClosed = false; /*********************************************** * Public properties (readonly) ***********************************************/ @@ -375,6 +375,8 @@ export class Sync implements SyncInterface { * @public */ async init (): Promise { + this._isClosed = false; + const onlyFetch = this._options.syncDirection === 'pull'; const remoteResult: 'exist' | 'not_exist' = await Remote.checkFetch( @@ -488,6 +490,7 @@ export class Sync implements SyncInterface { * @public */ resume (options?: { interval?: number; retry?: number }) { + if (this._isClosed) return false; if (this._options.live) return false; options ??= { @@ -524,6 +527,7 @@ export class Sync implements SyncInterface { * @public */ close () { + this._isClosed = true; this.pause(); this.eventHandlers = { change: [], @@ -549,6 +553,7 @@ export class Sync implements SyncInterface { */ // eslint-disable-next-line complexity async tryPush (): Promise { + if (this._isClosed) return { action: 'canceled' }; if (this._options.syncDirection === 'pull') { throw new Err.PushNotAllowedError(this._options.syncDirection); } @@ -629,6 +634,7 @@ export class Sync implements SyncInterface { */ // eslint-disable-next-line complexity async trySync (): Promise { + if (this._isClosed) return { action: 'canceled' }; if (this._options.syncDirection === 'pull') { throw new Err.PushNotAllowedError(this._options.syncDirection); } @@ -984,7 +990,9 @@ export class Sync implements SyncInterface { * @eventProperty * @public */ + // eslint-disable-next-line complexity on (event: SyncEvent, callback: SyncCallback, collectionPath = '') { + if (this._isClosed) return this; collectionPath = Validator.normalizeCollectionPath(collectionPath); if (event === 'change') this.eventHandlers[event].push({ @@ -1042,6 +1050,7 @@ export class Sync implements SyncInterface { * @public */ off (event: SyncEvent, callback: SyncCallback) { + if (this._isClosed) return this; // @ts-ignore this.eventHandlers[event] = this.eventHandlers[event].filter( (listener: { collectionPath: string; func: (res?: any) => void }) => { From 24b4c277389e0c45e12441a82fbbdc41e96ea438 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 14 Jul 2021 19:10:44 +0900 Subject: [PATCH 048/297] test: pass all tests --- package-lock.json | 6 +++--- package.json | 2 +- test/crud/history.test.ts | 3 +++ test/remote/3way_merge.test.ts | 3 +++ test/remote/combine.test.ts | 1 - test/remote/remote_repository.test.ts | 12 +++++------ test/remote/sync_clone.test.ts | 8 +++----- test/remote/sync_events.test.ts | 14 ++++++++----- test/remote/sync_trysync.test.ts | 4 ---- test/task_queue.test.ts | 3 +++ test_intg/3way_merge_ot.test.ts | 3 +++ test_intg/on_sync_event.test.ts | 3 +++ test_intg/sync_lifecycle.test.ts | 29 ++++++++++++++++----------- 13 files changed, 54 insertions(+), 37 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5e2c175f..25ae6e96 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3500,9 +3500,9 @@ "dev": true }, "git-documentdb-plugin-remote-nodegit": { - "version": "1.0.0-alpha.14", - "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.0-alpha.14.tgz", - "integrity": "sha512-kt5D18cIlqEmF4gCOCh1Bo3NyuMDtbNshp4nDlRDgakBhh9af7dXUQdoYpvzAkeFUFbNK4va7I/O7tn2Q74Zzw==", + "version": "1.0.0-alpha.15", + "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.0-alpha.15.tgz", + "integrity": "sha512-3gC/2znX5HNIvTFsQ91DlyUYppsw419kHIntcP8CSUQ9BclJ4ULOkbdBEl8X+etQMQ+vBpd57p/Nc9sI4An/pA==", "dev": true, "requires": { "@sosuisen/nodegit": "^0.27.3", diff --git a/package.json b/package.json index a987e86b..fb1c550e 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "eslint-config-standardize": "^0.7.1", "eslint-plugin-prettierx": "^0.14.0", "expect": "^27.0.2", - "git-documentdb-plugin-remote-nodegit": "^1.0.0-alpha.14", + "git-documentdb-plugin-remote-nodegit": "^1.0.0-alpha.15", "mocha": "^8.3.2", "nyc": "^15.1.0", "parse-git-config": "^3.0.0", diff --git a/test/crud/history.test.ts b/test/crud/history.test.ts index d30d3b3a..319c8aec 100644 --- a/test/crud/history.test.ts +++ b/test/crud/history.test.ts @@ -53,6 +53,9 @@ beforeEach(function () { }); before(() => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + fs.removeSync(path.resolve(localDir)); }); diff --git a/test/remote/3way_merge.test.ts b/test/remote/3way_merge.test.ts index f9d7c292..66e31cfa 100644 --- a/test/remote/3way_merge.test.ts +++ b/test/remote/3way_merge.test.ts @@ -52,6 +52,9 @@ beforeEach(function () { }); before(() => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + fs.removeSync(path.resolve(localDir)); }); diff --git a/test/remote/combine.test.ts b/test/remote/combine.test.ts index e5367111..226f9607 100644 --- a/test/remote/combine.test.ts +++ b/test/remote/combine.test.ts @@ -20,7 +20,6 @@ import parse from 'parse-git-config'; import { DuplicatedFile } from '../../src/types'; import { GitDocumentDB } from '../../src/git_documentdb'; import { Remote } from '../../src/remote/remote'; -import { Err } from '../../src/error'; import { compareWorkingDirAndBlobs, createDatabase, diff --git a/test/remote/remote_repository.test.ts b/test/remote/remote_repository.test.ts index 24e47271..7f398104 100644 --- a/test/remote/remote_repository.test.ts +++ b/test/remote/remote_repository.test.ts @@ -213,7 +213,7 @@ maybe(' RemoteRepository', () => { ).rejects.toThrowError(Err.PersonalAccessTokenForAnotherAccountError); }); - it(`throws CannotConnectError() with ${NETWORK_RETRY} retries`, async () => { + it(`throws CannotConnectRemoteRepositoryError() with ${NETWORK_RETRY} retries`, async () => { const remoteURL = remoteURLBase + serialId(); await createRemoteRepository(remoteURL); @@ -226,9 +226,9 @@ maybe(' RemoteRepository', () => { }) .create() .catch(err => err); - expect(error).toBeInstanceOf(Err.CannotConnectError); + expect(error).toBeInstanceOf(Err.CannotConnectRemoteRepositoryError); // This may be tested by using sinon.spy - expect((error as Err.CannotConnectError).retry).toBe(NETWORK_RETRY); + expect((error as Err.CannotConnectRemoteRepositoryError).retry).toBe(NETWORK_RETRY); }); it('throws AuthenticationTypeNotAllowCreateRepositoryError()', async () => { @@ -276,7 +276,7 @@ maybe(' RemoteRepository', () => { ).rejects.toThrowError(Err.UndefinedPersonalAccessTokenError); }); - it(`throws CannotConnectError() with ${NETWORK_RETRY_INTERVAL} retries`, async () => { + it(`throws CannotConnectRemoteRepositoryError() with ${NETWORK_RETRY_INTERVAL} retries`, async () => { const remoteURL = remoteURLBase + serialId(); const error = await new RemoteRepository({ @@ -288,8 +288,8 @@ maybe(' RemoteRepository', () => { }) .destroy() .catch(err => err); - expect(error).toBeInstanceOf(Err.CannotConnectError); - expect((error as Err.CannotConnectError).retry).toBe(NETWORK_RETRY); + expect(error).toBeInstanceOf(Err.CannotConnectRemoteRepositoryError); + expect((error as Err.CannotConnectRemoteRepositoryError).retry).toBe(NETWORK_RETRY); }); it('throws AuthenticationTypeNotAllowCreateRepositoryError()', async () => { diff --git a/test/remote/sync_clone.test.ts b/test/remote/sync_clone.test.ts index b974f33f..10a21eca 100644 --- a/test/remote/sync_clone.test.ts +++ b/test/remote/sync_clone.test.ts @@ -32,6 +32,9 @@ beforeEach(function () { }); before(() => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + fs.removeSync(path.resolve(localDir)); }); @@ -59,17 +62,12 @@ maybe(' clone', () => { describe('using NodeGit', () => { it('returns undefined when invalid RemoteOptions', async () => { - // eslint-disable-next-line @typescript-eslint/no-var-requires - GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); // @ts-ignore await expect(Remote.clone('tmp')).resolves.toBeFalsy(); await expect(Remote.clone('tmp', { remoteUrl: undefined })).resolves.toBeFalsy(); }); it('clones a repository by NodeGit', async () => { - // eslint-disable-next-line @typescript-eslint/no-var-requires - GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId); const jsonA1 = { _id: '1', name: 'fromA' }; await dbA.put(jsonA1); diff --git a/test/remote/sync_events.test.ts b/test/remote/sync_events.test.ts index 87736398..cdb1af25 100644 --- a/test/remote/sync_events.test.ts +++ b/test/remote/sync_events.test.ts @@ -40,10 +40,11 @@ import { removeRemoteRepositories, } from '../remote_utils'; import { GitDocumentDB } from '../../src/git_documentdb'; +import { Remote } from '../../src/remote/remote'; import { Sync } from '../../src/remote/sync'; import { Err } from '../../src/error'; -import { MINIMUM_SYNC_INTERVAL, NETWORK_RETRY } from '../../src/const'; -import { pushWorker } from '../../src/remote/push_worker'; +import { MINIMUM_SYNC_INTERVAL } from '../../src/const'; + // eslint-disable-next-line @typescript-eslint/no-var-requires const pushWorker_module = require('../../src/remote/push_worker'); @@ -68,6 +69,9 @@ afterEach(function () { }); before(() => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + fs.removeSync(path.resolve(localDir)); }); @@ -226,7 +230,7 @@ maybe(' [event]', () => { await dbB.put({ _id: '2' }); const stubPush = sandbox.stub(pushWorker_module, 'pushWorker'); - stubPush.onFirstCall().rejects(new Err.UnfetchedCommitExistsError()); + stubPush.onFirstCall().rejects(new Remote.Err.UnfetchedCommitExistsError()); const resultsB: SyncResult[] = []; syncB.on('change', (result: SyncResult) => { @@ -307,7 +311,7 @@ maybe(' [event]', () => { await dbB.put({ _id: '2' }); const stubPush = sandbox.stub(pushWorker_module, 'pushWorker'); - stubPush.onFirstCall().rejects(new Err.UnfetchedCommitExistsError()); + stubPush.onFirstCall().rejects(new Remote.Err.UnfetchedCommitExistsError()); const localChangesB: ChangedFile[][] = []; syncB.on('localChange', (changes: ChangedFile[]) => { @@ -388,7 +392,7 @@ maybe(' [event]', () => { await dbB.put({ _id: '2' }); const stubPush = sandbox.stub(pushWorker_module, 'pushWorker'); - stubPush.onFirstCall().rejects(new Err.UnfetchedCommitExistsError()); + stubPush.onFirstCall().rejects(new Remote.Err.UnfetchedCommitExistsError()); let firstChange = true; syncB.on('change', (changes: ChangedFile[]) => { diff --git a/test/remote/sync_trysync.test.ts b/test/remote/sync_trysync.test.ts index f0e53cb1..06717358 100644 --- a/test/remote/sync_trysync.test.ts +++ b/test/remote/sync_trysync.test.ts @@ -24,7 +24,6 @@ import { SyncResultMergeAndPush, SyncResultPush, } from '../../src/types'; -import { Err } from '../../src/error'; import { compareWorkingDirAndBlobs, @@ -785,9 +784,6 @@ maybe(': Sync#trySync()', () => { await dbB.open(); const syncB = await dbB.sync(syncA.options); - dbA.logLevel = 'trace'; - dbB.logLevel = 'trace'; - const info = { dbId: 'foo', creator: 'bar', diff --git a/test/task_queue.test.ts b/test/task_queue.test.ts index 243e6351..caf78b25 100644 --- a/test/task_queue.test.ts +++ b/test/task_queue.test.ts @@ -37,6 +37,9 @@ beforeEach(function () { }); before(() => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + fs.removeSync(path.resolve(localDir)); }); diff --git a/test_intg/3way_merge_ot.test.ts b/test_intg/3way_merge_ot.test.ts index b4887893..0f2bbf37 100644 --- a/test_intg/3way_merge_ot.test.ts +++ b/test_intg/3way_merge_ot.test.ts @@ -49,6 +49,9 @@ beforeEach(function () { }); before(() => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + fs.removeSync(path.resolve(localDir)); }); diff --git a/test_intg/on_sync_event.test.ts b/test_intg/on_sync_event.test.ts index 8ca73e3f..1afd27a3 100644 --- a/test_intg/on_sync_event.test.ts +++ b/test_intg/on_sync_event.test.ts @@ -41,6 +41,9 @@ beforeEach(function () { }); before(() => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + fs.removeSync(path.resolve(localDir)); }); diff --git a/test_intg/sync_lifecycle.test.ts b/test_intg/sync_lifecycle.test.ts index 3c522a7d..45a595dd 100644 --- a/test_intg/sync_lifecycle.test.ts +++ b/test_intg/sync_lifecycle.test.ts @@ -30,6 +30,8 @@ import { import { JSON_EXT, MINIMUM_SYNC_INTERVAL, NETWORK_RETRY } from '../src/const'; import { pushWorker } from '../src/remote/push_worker'; import { syncWorker } from '../src/remote/sync_worker'; +import { Remote } from '../src/remote/remote'; + // eslint-disable-next-line @typescript-eslint/no-var-requires const pushWorker_module = require('../src/remote/push_worker'); // eslint-disable-next-line @typescript-eslint/no-var-requires @@ -56,6 +58,9 @@ afterEach(function () { }); before(() => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + fs.removeSync(path.resolve(localDir)); }); @@ -211,7 +216,7 @@ maybe('intg Sync', () => { await dbB.put(jsonB1); await expect(Promise.all([syncA.tryPush(), syncB.tryPush()])).rejects.toThrowError( - Err.UnfetchedCommitExistsError + Remote.Err.UnfetchedCommitExistsError ); await destroyDBs([dbA, dbB]); @@ -246,7 +251,9 @@ maybe('intg Sync', () => { await dbB.put(jsonB1); await syncA.tryPush(); - await expect(syncB.tryPush()).rejects.toThrowError(Err.UnfetchedCommitExistsError); + await expect(syncB.tryPush()).rejects.toThrowError( + Remote.Err.UnfetchedCommitExistsError + ); await destroyDBs([dbA, dbB]); }); @@ -552,7 +559,7 @@ maybe('intg Sync', () => { const stubPush = sandbox.stub(pushWorker_module, 'pushWorker'); stubPush.rejects(); - await expect(sync.init(dbA.repository()!)).rejects.toThrowError(); + await expect(sync.init()).rejects.toThrowError(); expect(stubPush.callCount).toBe(NETWORK_RETRY + 1); @@ -595,7 +602,7 @@ maybe('intg Sync', () => { taskId: 'myTaskId', }); }); - const syncResult = await sync.init(dbA.repository()!); + const syncResult = await sync.init(); expect(syncResult).toEqual(syncResultPush); expect(stubPush.callCount).toBe(2); @@ -632,9 +639,7 @@ maybe('intg Sync', () => { }); }); - await expect(sync.init(dbA.repository()!)).rejects.toThrowError( - Err.PushWorkerError - ); + await expect(sync.init()).rejects.toThrowError(Err.PushWorkerError); expect(stubPush.callCount).toBe(1); @@ -665,7 +670,7 @@ maybe('intg Sync', () => { stubSync.rejects(); // sync has already been initialized, so will run trySync() - await expect(sync.init(dbA.repository()!)).rejects.toThrowError(); + await expect(sync.init()).rejects.toThrowError(); expect(stubSync.callCount).toBe(NETWORK_RETRY + 1); @@ -713,7 +718,7 @@ maybe('intg Sync', () => { }, }; - await expect(sync.init(dbA.repository()!)).resolves.toEqual(syncResultPush); + await expect(sync.init()).resolves.toEqual(syncResultPush); expect(stubSync.callCount).toBe(2); @@ -809,7 +814,7 @@ maybe('intg Sync', () => { const stubSync = sandbox.stub(syncWorker_module, 'syncWorker'); stubSync.rejects(); - await expect(sync.init(dbA.repository()!)).rejects.toThrowError(); + await expect(sync.init()).rejects.toThrowError(); expect(stubSync.callCount).toBe(1); @@ -840,7 +845,7 @@ maybe('intg Sync', () => { const stubPush = sandbox.stub(pushWorker_module, 'pushWorker'); stubPush.rejects(); - await expect(sync.init(dbA.repository()!)).rejects.toThrowError(); + await expect(sync.init()).rejects.toThrowError(); expect(stubPush.callCount).toBe(1); @@ -875,7 +880,7 @@ maybe('intg Sync', () => { const stubPush = sandbox.stub(pushWorker_module, 'pushWorker'); stubPush.rejects(); - sync.init(dbA.repository()!).catch(() => {}); + sync.init().catch(() => {}); await sleep(retryInterval - 500); expect(stubPush.callCount).toBe(1); From 178a2921e73f317187ccc697256a8ec23190e69a Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 14 Jul 2021 19:23:30 +0900 Subject: [PATCH 049/297] fix: remove console.log for merge cases --- src/remote/3way_merge.ts | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/remote/3way_merge.ts b/src/remote/3way_merge.ts index 4387380b..0663d715 100644 --- a/src/remote/3way_merge.ts +++ b/src/remote/3way_merge.ts @@ -322,7 +322,7 @@ export async function threeWayMerge ( // A new file has been inserted into theirs. // Write it to the working directory. // Write it to the index. - console.log(' #case 1 - Accept theirs (insert): ' + fullDocPath); + // console.log(' #case 1 - Accept theirs (insert): ' + fullDocPath); const theirsData = (await theirs.content())!; const theirsFatDoc = await getFatDocFromData(theirsData, fullDocPath, docType); await writeBlobToFile(gitDDB.workingDir, fullDocPath, theirsData); @@ -346,7 +346,7 @@ export async function threeWayMerge ( // A new file has been inserted into ours. // It has already been created on the working directory. // It has already been added to the index. - console.log(' #case 2 - Accept ours (insert): ' + fullDocPath); + // console.log(' #case 2 - Accept ours (insert): ' + fullDocPath); const oursData = (await ours.content())!; const oursFatDoc = await getFatDocFromData(oursData, fullDocPath, docType); return [ @@ -375,7 +375,7 @@ export async function threeWayMerge ( // The same filenames with exactly the same contents are inserted on both local and remote. // It has already been created on the both working directory. // It has already been added to the both index. - console.log(' #case 3 - Accept both (insert): ' + fullDocPath); + // console.log(' #case 3 - Accept both (insert): ' + fullDocPath); return [ { mode: oursMode, @@ -403,11 +403,11 @@ export async function threeWayMerge ( let mode = ''; if (strategy === 'ours' || strategy === 'ours-diff') { - console.log(' #case 4 - Conflict. Accept ours (insert): ' + fullDocPath); + // console.log(' #case 4 - Conflict. Accept ours (insert): ' + fullDocPath); mode = oursMode; } else if (strategy === 'theirs' || strategy === 'theirs-diff') { - console.log(' #case 5 - Conflict. Accept theirs (insert): ' + fullDocPath); + // console.log(' #case 5 - Conflict. Accept theirs (insert): ' + fullDocPath); mode = theirsMode; } @@ -488,7 +488,7 @@ export async function threeWayMerge ( } else if (base && !ours && !theirs) { // The same files have been removed from both local and remote. - console.log(' #case 6 - Accept both (delete): ' + fullDocPath); + // console.log(' #case 6 - Accept both (delete): ' + fullDocPath); return [undefined, undefined, undefined, undefined]; } else if (base && !ours && theirs) { @@ -499,7 +499,7 @@ export async function threeWayMerge ( if (baseOid === theirsOid) { // A file has been removed from ours. - console.log(' #case 7 - Accept ours (delete): ' + fullDocPath); + // console.log(' #case 7 - Accept ours (delete): ' + fullDocPath); return [ undefined, undefined, @@ -516,7 +516,7 @@ export async function threeWayMerge ( const strategy = await getStrategy(conflictResolutionStrategy, undefined, theirsFatDoc); if (strategy === 'ours' || strategy === 'ours-diff') { - console.log(' #case 8 - Conflict. Accept ours (delete): ' + fullDocPath); + // console.log(' #case 8 - Conflict. Accept ours (delete): ' + fullDocPath); const baseData = (await base.content())!; const baseFatDoc = await getFatDocFromData(baseData, fullDocPath, docType); const acceptedConflict: AcceptedConflict = { @@ -535,7 +535,7 @@ export async function threeWayMerge ( ]; } else if (strategy === 'theirs' || strategy === 'theirs-diff') { - console.log(' #case 9 - Conflict. Accept theirs (update): ' + fullDocPath); + // console.log(' #case 9 - Conflict. Accept theirs (update): ' + fullDocPath); const acceptedConflict: AcceptedConflict = { fatDoc: theirsFatDoc, strategy: strategy, @@ -567,7 +567,7 @@ export async function threeWayMerge ( if (baseOid === oursOid) { // A file has been removed from theirs. - console.log(' #case 10 - Accept theirs (delete): ' + fullDocPath); + // console.log(' #case 10 - Accept theirs (delete): ' + fullDocPath); await fs.remove(nodePath.resolve(gitDDB.workingDir, fullDocPath)).catch(() => { throw new Err.CannotDeleteDataError(); }); @@ -588,7 +588,7 @@ export async function threeWayMerge ( const strategy = await getStrategy(conflictResolutionStrategy, oursFatDoc, undefined); if (strategy === 'ours' || strategy === 'ours-diff') { - console.log(' #case 11 - Conflict. Accept ours (update): ' + fullDocPath); + // console.log(' #case 11 - Conflict. Accept ours (update): ' + fullDocPath); const acceptedConflict: AcceptedConflict = { fatDoc: oursFatDoc, strategy: strategy, @@ -610,7 +610,7 @@ export async function threeWayMerge ( ]; } else if (strategy === 'theirs' || strategy === 'theirs-diff') { - console.log(' #case 12 - Conflict. Accept theirs (delete): ' + fullDocPath); + // console.log(' #case 12 - Conflict. Accept theirs (delete): ' + fullDocPath); const baseData = (await base.content())!; const baseFatDoc = await getFatDocFromData(baseData, fullDocPath, docType); const acceptedConflicts: AcceptedConflict = { @@ -640,7 +640,7 @@ export async function threeWayMerge ( if (oursOid === theirsOid) { // The same filenames with exactly the same contents are inserted into both local and remote. - console.log(' #case 13 - Accept both (update): ' + fullDocPath); + // console.log(' #case 13 - Accept both (update): ' + fullDocPath); return [ { // TODO: check whether mode is the same. @@ -655,7 +655,7 @@ export async function threeWayMerge ( ]; } else if (baseOid === oursOid) { - console.log(' #case 14 - Accept theirs (update): ' + fullDocPath); + // console.log(' #case 14 - Accept theirs (update): ' + fullDocPath); const oursData = (await ours.content())!; const oursFatDoc = await getFatDocFromData(oursData, fullDocPath, docType); const theirsData = (await theirs.content())!; @@ -679,7 +679,7 @@ export async function threeWayMerge ( ]; } else if (baseOid === theirsOid) { - console.log(' #case 15 - Accept ours (update): ' + fullDocPath); + // console.log(' #case 15 - Accept ours (update): ' + fullDocPath); const oursData = (await ours.content())!; const oursFatDoc = await getFatDocFromData(oursData, fullDocPath, docType); const theirsData = (await theirs.content())!; @@ -715,7 +715,7 @@ export async function threeWayMerge ( ); if (strategy === 'ours') { - console.log(' #case 16 - Conflict. Accept ours (update): ' + fullDocPath); + // console.log(' #case 16 - Conflict. Accept ours (update): ' + fullDocPath); return [ { mode: (await ours.mode()).toString(8), @@ -737,7 +737,7 @@ export async function threeWayMerge ( ]; } else if (strategy === 'theirs') { - console.log(' #case 17 - Conflict. Accept theirs (update): ' + fullDocPath); + // console.log(' #case 17 - Conflict. Accept theirs (update): ' + fullDocPath); await writeBlobToFile(gitDDB.workingDir, fullDocPath, theirsData); await git.add({ fs, dir: gitDDB.workingDir, filepath: fullDocPath }); @@ -777,11 +777,11 @@ export async function threeWayMerge ( let mode = ''; if (strategy === 'ours-diff') { - console.log(' #case 16 (diff) - Conflict. Accept ours (update): ' + fullDocPath); + // console.log(' #case 16 (diff) - Conflict. Accept ours (update): ' + fullDocPath); mode = (await ours.mode()).toString(8); } else if (strategy === 'theirs-diff') { - console.log(' #case 17 (diff) - Conflict. Accept theirs (update): ' + fullDocPath); + // console.log(' #case 17 (diff) - Conflict. Accept theirs (update): ' + fullDocPath); mode = (await theirs.mode()).toString(8); } From 230dcbac4c4884eaf45f4ac884ad1b571dec84d5 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 14 Jul 2021 22:57:59 +0900 Subject: [PATCH 050/297] fix: can register multiple RemoteEngines by plugins --- package-lock.json | 6 +-- package.json | 2 +- src/error.ts | 4 +- src/git_documentdb.ts | 15 +++--- src/main.ts | 2 +- src/remote/combine.ts | 8 ++- src/remote/push_worker.ts | 8 +-- src/remote/{remote.ts => remote_engine.ts} | 2 +- src/remote/remote_repository.ts | 1 - src/remote/sync.ts | 58 ++++++++++++---------- src/remote/sync_worker.ts | 14 +++--- src/types.ts | 3 ++ src/types_sync.ts | 1 + test/remote/combine.test.ts | 14 +++--- test/remote/sync_clone.test.ts | 10 ++-- test/remote/sync_events.test.ts | 14 ++++-- test/remote/sync_trypush.test.ts | 48 ++++++++++++++---- test/remote/sync_trysync.test.ts | 4 +- test/remote_utils.ts | 1 - test_intg/sync_lifecycle.test.ts | 6 +-- 20 files changed, 136 insertions(+), 85 deletions(-) rename src/remote/{remote.ts => remote_engine.ts} (53%) diff --git a/package-lock.json b/package-lock.json index 25ae6e96..43918f16 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3500,9 +3500,9 @@ "dev": true }, "git-documentdb-plugin-remote-nodegit": { - "version": "1.0.0-alpha.15", - "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.0-alpha.15.tgz", - "integrity": "sha512-3gC/2znX5HNIvTFsQ91DlyUYppsw419kHIntcP8CSUQ9BclJ4ULOkbdBEl8X+etQMQ+vBpd57p/Nc9sI4An/pA==", + "version": "1.0.0-alpha.16", + "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.0-alpha.16.tgz", + "integrity": "sha512-Ie3EExrKlXwGG14CKTigqjS3uNDJUio798dqTqSCP3qijlTRO9TZAnXNrVmVuJRpglGalM4etC8KBvv4YSoYEA==", "dev": true, "requires": { "@sosuisen/nodegit": "^0.27.3", diff --git a/package.json b/package.json index fb1c550e..e46558f4 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "eslint-config-standardize": "^0.7.1", "eslint-plugin-prettierx": "^0.14.0", "expect": "^27.0.2", - "git-documentdb-plugin-remote-nodegit": "^1.0.0-alpha.15", + "git-documentdb-plugin-remote-nodegit": "^1.0.0-alpha.16", "mocha": "^8.3.2", "nyc": "^15.1.0", "parse-git-config": "^3.0.0", diff --git a/src/error.ts b/src/error.ts index 0df6c1dc..077af10a 100644 --- a/src/error.ts +++ b/src/error.ts @@ -459,7 +459,7 @@ Current value is '${type}'`); */ export class RemoteCheckPushError extends BaseError { constructor (mes: unknown) { - super(`Error in Remote.checkPush(): ${mes}`); + super(`Error in RemoteEngine.checkPush(): ${mes}`); } } @@ -468,7 +468,7 @@ Current value is '${type}'`); */ export class RemoteCheckFetchError extends BaseError { constructor (mes: unknown) { - super(`Error in Remote.checkFetch(): ${mes}`); + super(`Error in RemoteEngine.checkFetch(): ${mes}`); } } diff --git a/src/git_documentdb.ts b/src/git_documentdb.ts index 37967671..d7eae95f 100644 --- a/src/git_documentdb.ts +++ b/src/git_documentdb.ts @@ -12,7 +12,7 @@ import fs from 'fs-extra'; import rimraf from 'rimraf'; import { Logger, TLogLevelName } from 'tslog'; import { ulid } from 'ulid'; -import { Remote } from './remote/remote'; +import { RemoteEngine } from './remote/remote_engine'; import { Err } from './error'; import { Collection } from './collection'; import { Validator } from './validator'; @@ -98,11 +98,14 @@ export class GitDocumentDB static plugin (obj: any) { const type: PluginTypes = obj.type; if (type === 'remote') { - Object.keys(obj).forEach(function (id) { - // Set to Remote object - // @ts-ignore - Remote[id] = obj[id]; - }); + if (obj.name !== undefined) { + RemoteEngine[obj.name] = {}; + Object.keys(obj).forEach(function (id) { + // Set to Remote object + // @ts-ignore + RemoteEngine[obj.name][id] = obj[id]; + }); + } } else { Object.keys(obj).forEach(function (id) { diff --git a/src/main.ts b/src/main.ts index eae5e9d9..ad613d5f 100644 --- a/src/main.ts +++ b/src/main.ts @@ -11,7 +11,7 @@ export * from './error'; export * from './git_documentdb'; export * from './types'; export * from './validator'; -export * from './remote/remote'; +export * from './remote/remote_engine'; export * from './remote/remote_repository'; export * from './remote/sync'; export * from './const'; diff --git a/src/remote/combine.ts b/src/remote/combine.ts index 823f7f54..9c6efd53 100644 --- a/src/remote/combine.ts +++ b/src/remote/combine.ts @@ -23,7 +23,7 @@ import { GitDDBInterface } from '../types_gitddb'; import { Err } from '../error'; import { DUPLICATED_FILE_POSTFIX, FILE_REMOVE_TIMEOUT, JSON_EXT } from '../const'; import { getAllMetadata, toSortedJSONString } from '../utils'; -import { Remote } from './remote'; +import { RemoteEngine } from './remote_engine'; /** * Clone a remote repository and combine the current local working directory with it. @@ -41,7 +41,11 @@ export async function combineDatabaseWithTheirs ( const duplicates: DuplicatedFile[] = []; try { - await Remote.clone(remoteDir, remoteOptions, gitDDB.logger); + await RemoteEngine[remoteOptions.connection!.engine!].clone( + remoteDir, + remoteOptions, + gitDDB.logger + ); const localMetadataList: DocMetadata[] = await getAllMetadata(gitDDB.workingDir); const remoteMetadataList: DocMetadata[] = await getAllMetadata(remoteDir); diff --git a/src/remote/push_worker.ts b/src/remote/push_worker.ts index b342911c..ac9e1c92 100644 --- a/src/remote/push_worker.ts +++ b/src/remote/push_worker.ts @@ -12,13 +12,13 @@ import { GitDDBInterface } from '../types_gitddb'; import { ChangedFile, NormalizedCommit, SyncResultPush, TaskMetadata } from '../types'; import { SyncInterface } from '../types_sync'; import { getChanges, getCommitLogs } from './worker_utils'; -import { Remote } from './remote'; +import { RemoteEngine } from './remote_engine'; /** * Push and get changes * - * @throws {@link Remote.Err.UnfetchedCommitExistsError} (from push() and validatePushResult()) - * @throws {@link Remote.Err.GitFetchError} (from validatePushResult()) + * @throws {@link RemoteEngine.Err.UnfetchedCommitExistsError} (from push() and validatePushResult()) + * @throws {@link RemoteEngine.Err.GitFetchError} (from validatePushResult()) * @throws {@link Err.InvalidJsonObjectError} (from getChanges()) */ export async function pushWorker ( @@ -95,7 +95,7 @@ export async function pushWorker ( } // Push - await Remote.push(gitDDB.workingDir, sync.options); + await RemoteEngine[sync.engine].push(gitDDB.workingDir, sync.options); let remoteChanges: ChangedFile[] | undefined; if (skipGetChanges) { remoteChanges = undefined; diff --git a/src/remote/remote.ts b/src/remote/remote_engine.ts similarity index 53% rename from src/remote/remote.ts rename to src/remote/remote_engine.ts index 3a325478..f53e68a0 100644 --- a/src/remote/remote.ts +++ b/src/remote/remote_engine.ts @@ -1,2 +1,2 @@ // eslint-disable-next-line @typescript-eslint/naming-convention -export const Remote: { [key: string]: any } = {}; +export const RemoteEngine: { [key: string]: any } = {}; diff --git a/src/remote/remote_repository.ts b/src/remote/remote_repository.ts index 6841800c..3df483cd 100644 --- a/src/remote/remote_repository.ts +++ b/src/remote/remote_repository.ts @@ -19,7 +19,6 @@ import { sleep } from '../utils'; */ export class RemoteRepository { private _options: RemoteOptions; - private _octokit: Octokit | undefined; /** diff --git a/src/remote/sync.ts b/src/remote/sync.ts index d731f498..4b5b30ba 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -54,13 +54,13 @@ import { JsonDiff } from './json_diff'; import { JsonPatchOT } from './json_patch_ot'; import { combineDatabaseWithTheirs } from './combine'; import { Validator } from '../validator'; -import { Remote } from './remote'; +import { RemoteEngine } from './remote_engine'; /** * Implementation of GitDocumentDB#sync(options, get_sync_result) * * @throws {@link Err.RepositoryNotFoundError} - * @throws {@link Remote.Err.UndefinedRemoteURLError} (from Sync#constructor()) + * @throws {@link RemoteEngine.Err.UndefinedRemoteURLError} (from Sync#constructor()) * @throws {@link Err.IntervalTooSmallError} (from Sync#constructor()) * * @throws {@link Err.RemoteRepositoryConnectError} (from Sync#init()) @@ -192,6 +192,14 @@ export class Sync implements SyncInterface { return this._options.remoteUrl!; } + /** + * Remote Engine + */ + private _engine = 'iso'; + get engine (): string { + return this._engine; + } + private _remoteRepository: RemoteRepository; /** * Remote repository @@ -336,6 +344,8 @@ export class Sync implements SyncInterface { remoteUrl: this._options.remoteUrl, connection: this._options.connection, }); + + this._engine = this._options.connection?.engine ?? 'iso'; } /*********************************************** @@ -379,13 +389,11 @@ export class Sync implements SyncInterface { const onlyFetch = this._options.syncDirection === 'pull'; - const remoteResult: 'exist' | 'not_exist' = await Remote.checkFetch( - this._gitDDB.workingDir, - this._options, - this._gitDDB.logger - ).catch((err: Error) => { - throw new Err.RemoteCheckFetchError(err.message); - }); + const remoteResult: 'exist' | 'not_exist' = await RemoteEngine[this._engine] + .checkFetch(this._gitDDB.workingDir, this._options, this._gitDDB.logger) + .catch((err: Error) => { + throw new Err.RemoteCheckFetchError(err.message); + }); if (remoteResult === 'not_exist') { // Try to create repository by octokit await this.remoteRepository.create().catch(err => { @@ -395,13 +403,11 @@ export class Sync implements SyncInterface { this._upstreamBranch = ''; } if (!onlyFetch) { - await Remote.checkPush( - this._gitDDB.workingDir, - this._options, - this._gitDDB.logger - ).catch((err: Error) => { - throw new Err.RemoteCheckPushError(err.message); - }); + await RemoteEngine[this._engine] + .checkPush(this._gitDDB.workingDir, this._options, this._gitDDB.logger) + .catch((err: Error) => { + throw new Err.RemoteCheckPushError(err.message); + }); } let syncResult: SyncResult = { @@ -547,7 +553,7 @@ export class Sync implements SyncInterface { * * @throws {@link Err.PushNotAllowedError} (from this and enqueuePushTask) * @throws {@link Err.PushWorkerError} (from this and enqueuePushTask) - * @throws {@link Remote.Err.UnfetchedCommitExistsError} (from this and enqueuePushTask) + * @throws {@link RemoteEngine.Err.UnfetchedCommitExistsError} (from this and enqueuePushTask) * * @public */ @@ -574,7 +580,7 @@ export class Sync implements SyncInterface { result = resultOrError; } - if (error instanceof Remote.Err.UnfetchedCommitExistsError) { + if (error instanceof RemoteEngine[this._engine].Err.UnfetchedCommitExistsError) { if (this._options.syncDirection === 'push') { if (this._options.combineDbStrategy === 'replace-with-ours') { // TODO: Exec replace-with-ours instead of throw error @@ -628,7 +634,7 @@ export class Sync implements SyncInterface { * @throws {@link Err.PushNotAllowedError} (from this and enqueueSyncTask) * @throws {@link Err.SyncWorkerError} (from enqueueSyncTask) * @throws {@link Err.NoMergeBaseFoundError} (from enqueueSyncTask) - * @throws {@link Remote.Err.UnfetchedCommitExistsError} (from enqueueSyncTask) + * @throws {@link RemoteEngine.Err.UnfetchedCommitExistsError} (from enqueueSyncTask) * * @public */ @@ -662,7 +668,7 @@ export class Sync implements SyncInterface { result = resultOrError; } - if (error instanceof Remote.Err.NoMergeBaseFoundError) { + if (error instanceof RemoteEngine[this._engine].Err.NoMergeBaseFoundError) { if (this._options.combineDbStrategy === 'throw-error') { throw error; } @@ -704,7 +710,7 @@ export class Sync implements SyncInterface { if ( // eslint-disable-next-line no-await-in-loop !(await this.canNetworkConnection()) || - error instanceof Remote.Err.UnfetchedCommitExistsError + error instanceof RemoteEngine[this._engine].Err.UnfetchedCommitExistsError ) { // Retry for the following reasons: // - Network connection may be improved next time. @@ -734,7 +740,7 @@ export class Sync implements SyncInterface { * Enqueue push task to TaskQueue * * @throws {@link Err.PushWorkerError} - * @throws {@link Remote.Err.UnfetchedCommitExistsError} + * @throws {@link RemoteEngine.Err.UnfetchedCommitExistsError} * @throws {@link Err.PushNotAllowedError} * * @public @@ -791,7 +797,7 @@ export class Sync implements SyncInterface { }) .catch(err => { // console.log(`Error in push_worker: ${err}`); - if (!(err instanceof Remote.Err.UnfetchedCommitExistsError)) { + if (!(err instanceof RemoteEngine[this._engine].Err.UnfetchedCommitExistsError)) { err = new Err.PushWorkerError(err.message); } this.eventHandlers.error.forEach(listener => { @@ -835,7 +841,7 @@ export class Sync implements SyncInterface { * * @throws {@link Err.SyncWorkerError} * @throws {@link Err.NoMergeBaseFoundError} - * @throws {@link Remote.Err.UnfetchedCommitExistsError} + * @throws {@link RemoteEngine.Err.UnfetchedCommitExistsError} * @throws {@link Err.PushNotAllowedError} * * @public @@ -933,8 +939,8 @@ export class Sync implements SyncInterface { // console.log(`Error in sync_worker: ${err}`); if ( !( - err instanceof Remote.Err.NoMergeBaseFoundError || - err instanceof Remote.Err.UnfetchedCommitExistsError + err instanceof RemoteEngine[this._engine].Err.NoMergeBaseFoundError || + err instanceof RemoteEngine[this._engine].Err.UnfetchedCommitExistsError ) ) { err = new Err.SyncWorkerError(err.message); diff --git a/src/remote/sync_worker.ts b/src/remote/sync_worker.ts index 501db41d..532d2079 100644 --- a/src/remote/sync_worker.ts +++ b/src/remote/sync_worker.ts @@ -25,18 +25,18 @@ import { SyncInterface } from '../types_sync'; import { pushWorker } from './push_worker'; import { calcDistance, getAndWriteLocalChanges, getCommitLogs } from './worker_utils'; import { merge } from './3way_merge'; -import { Remote } from './remote'; +import { RemoteEngine } from './remote_engine'; /** * sync_worker * - * @throws {@link Remote.Err.GitFetchError} (from fetch() and pushWorker()) - * @throws {@link Remote.Err.NoMergeBaseFoundError} + * @throws {@link RemoteEngine.Err.GitFetchError} (from fetch() and pushWorker()) + * @throws {@link RemoteEngine.Err.NoMergeBaseFoundError} * @throws {@link Err.ThreeWayMergeError} * @throws {@link Err.CannotDeleteDataError} * @throws {@link Err.InvalidJsonObjectError} (from getChanges()) - * @throws {@link Remote.Err.UnfetchedCommitExistsError} (from pushWorker()) - * @throws {@link Remote.Err.GitPushError} (from pushWorker()) + * @throws {@link RemoteEngine.Err.UnfetchedCommitExistsError} (from pushWorker()) + * @throws {@link RemoteEngine.Err.GitPushError} (from pushWorker()) * @throws {@link Err.InvalidJsonObjectError} (from pushWorker()) * * @internal @@ -57,7 +57,7 @@ export async function syncWorker ( /** * Fetch */ - await Remote.fetch(gitDDB.workingDir, sync.options, gitDDB.logger); + await RemoteEngine[sync.engine].fetch(gitDDB.workingDir, sync.options, gitDDB.logger); /** * Calc distance @@ -87,7 +87,7 @@ export async function syncWorker ( // ahead: 1, behind 1 => Merge, may resolve conflict and push: Local has new commits. Remote has pushed new commits. if (distance.ahead === undefined || distance.behind === undefined) { - throw new Remote.Err.NoMergeBaseFoundError(); + throw new RemoteEngine[sync.engine].Err.NoMergeBaseFoundError(); } else if (distance.ahead === 0 && distance.behind === 0) { return { action: 'nop' }; diff --git a/src/types.ts b/src/types.ts index b7081f76..4fd80d95 100644 --- a/src/types.ts +++ b/src/types.ts @@ -572,6 +572,7 @@ export type SyncDirection = 'pull' | 'push' | 'both'; */ export type ConnectionSettingsGitHub = { type: 'github'; + engine?: string; personalAccessToken?: string; private?: boolean; }; @@ -583,6 +584,7 @@ export type ConnectionSettingsGitHub = { */ export type ConnectionSettingsSSH = { type: 'ssh'; + engine?: string; privateKeyPath: string; publicKeyPath: string; passPhrase?: string; @@ -595,6 +597,7 @@ export type ConnectionSettingsSSH = { */ export type ConnectionSettingsNone = { type: 'none'; + engine?: string; }; /** diff --git a/src/types_sync.ts b/src/types_sync.ts index 308d10aa..f03da544 100644 --- a/src/types_sync.ts +++ b/src/types_sync.ts @@ -29,6 +29,7 @@ export interface SyncInterface { * Public properties (readonly) ***********************************************/ remoteURL: string; + engine: string; remoteRepository: RemoteRepository; options: RemoteOptions; upstreamBranch: string; diff --git a/test/remote/combine.test.ts b/test/remote/combine.test.ts index 226f9607..7ac2c0a5 100644 --- a/test/remote/combine.test.ts +++ b/test/remote/combine.test.ts @@ -19,7 +19,7 @@ import expect from 'expect'; import parse from 'parse-git-config'; import { DuplicatedFile } from '../../src/types'; import { GitDocumentDB } from '../../src/git_documentdb'; -import { Remote } from '../../src/remote/remote'; +import { RemoteEngine } from '../../src/remote/remote_engine'; import { compareWorkingDirAndBlobs, createDatabase, @@ -94,7 +94,7 @@ maybe('', () => { // trySync throws NoMergeBaseFoundError await expect(dbB.sync(syncA.options)).rejects.toThrowError( - Remote.Err.NoMergeBaseFoundError + RemoteEngine[syncA.engine].Err.NoMergeBaseFoundError ); // await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); @@ -122,7 +122,7 @@ maybe('', () => { // Combine with remote db await expect(dbB.sync(syncA.options)).resolves.not.toThrowError( - Remote.Err.NoMergeBaseFoundError + RemoteEngine[syncA.engine].Err.NoMergeBaseFoundError ); const headCommitOid = await git.resolveRef({ @@ -155,7 +155,7 @@ maybe('', () => { // Combine with remote db await expect(dbB.sync(syncA.options)).resolves.not.toThrowError( - Remote.Err.NoMergeBaseFoundError + RemoteEngine[syncA.engine].Err.NoMergeBaseFoundError ); // Put new doc to combined db. @@ -190,7 +190,7 @@ maybe('', () => { // Combine with remote db await expect(dbB.sync(syncA.options)).resolves.not.toThrowError( - Remote.Err.NoMergeBaseFoundError + RemoteEngine[syncA.engine].Err.NoMergeBaseFoundError ); // Put new doc to combined db. @@ -224,7 +224,7 @@ maybe('', () => { // Combine with remote db await expect(dbB.sync(syncA.options)).resolves.not.toThrowError( - Remote.Err.NoMergeBaseFoundError + RemoteEngine[syncA.engine].Err.NoMergeBaseFoundError ); // Put new doc to combined db. @@ -513,7 +513,7 @@ maybe('', () => { // Combine with remote db await expect(dbB.sync(syncA.options)).resolves.not.toThrowError( - Remote.Err.NoMergeBaseFoundError + RemoteEngine[syncA.engine].Err.NoMergeBaseFoundError ); const config = parse.sync({ cwd: dbB.workingDir, path: '.git/config' }); diff --git a/test/remote/sync_clone.test.ts b/test/remote/sync_clone.test.ts index 10a21eca..7b2a00be 100644 --- a/test/remote/sync_clone.test.ts +++ b/test/remote/sync_clone.test.ts @@ -16,7 +16,7 @@ import fs from 'fs-extra'; import expect from 'expect'; import { createDatabase, destroyDBs, removeRemoteRepositories } from '../remote_utils'; import { GitDocumentDB } from '../../src/git_documentdb'; -import { Remote } from '../../src/remote/remote'; +import { RemoteEngine } from '../../src/remote/remote_engine'; const reposPrefix = 'test_sync_clone___'; const localDir = `./test/database_sync_clone`; @@ -63,8 +63,10 @@ maybe(' clone', () => { describe('using NodeGit', () => { it('returns undefined when invalid RemoteOptions', async () => { // @ts-ignore - await expect(Remote.clone('tmp')).resolves.toBeFalsy(); - await expect(Remote.clone('tmp', { remoteUrl: undefined })).resolves.toBeFalsy(); + await expect(RemoteEngine.nodegit.clone('tmp')).resolves.toBeFalsy(); + await expect( + RemoteEngine.nodegit.clone('tmp', { remoteUrl: undefined }) + ).resolves.toBeFalsy(); }); it('clones a repository by NodeGit', async () => { @@ -75,7 +77,7 @@ maybe(' clone', () => { const dbNameB = serialId(); const workingDir = localDir + '/' + dbNameB; - await Remote.clone(workingDir, syncA.options); + await RemoteEngine[syncA.engine].clone(workingDir, syncA.options); const dbB = new GitDocumentDB({ localDir, dbName: dbNameB }); await dbB.open(); diff --git a/test/remote/sync_events.test.ts b/test/remote/sync_events.test.ts index cdb1af25..2402d835 100644 --- a/test/remote/sync_events.test.ts +++ b/test/remote/sync_events.test.ts @@ -40,7 +40,7 @@ import { removeRemoteRepositories, } from '../remote_utils'; import { GitDocumentDB } from '../../src/git_documentdb'; -import { Remote } from '../../src/remote/remote'; +import { RemoteEngine } from '../../src/remote/remote_engine'; import { Sync } from '../../src/remote/sync'; import { Err } from '../../src/error'; import { MINIMUM_SYNC_INTERVAL } from '../../src/const'; @@ -230,7 +230,9 @@ maybe(' [event]', () => { await dbB.put({ _id: '2' }); const stubPush = sandbox.stub(pushWorker_module, 'pushWorker'); - stubPush.onFirstCall().rejects(new Remote.Err.UnfetchedCommitExistsError()); + stubPush + .onFirstCall() + .rejects(new RemoteEngine[syncB.engine].Err.UnfetchedCommitExistsError()); const resultsB: SyncResult[] = []; syncB.on('change', (result: SyncResult) => { @@ -311,7 +313,9 @@ maybe(' [event]', () => { await dbB.put({ _id: '2' }); const stubPush = sandbox.stub(pushWorker_module, 'pushWorker'); - stubPush.onFirstCall().rejects(new Remote.Err.UnfetchedCommitExistsError()); + stubPush + .onFirstCall() + .rejects(new RemoteEngine[syncB.engine].Err.UnfetchedCommitExistsError()); const localChangesB: ChangedFile[][] = []; syncB.on('localChange', (changes: ChangedFile[]) => { @@ -392,7 +396,9 @@ maybe(' [event]', () => { await dbB.put({ _id: '2' }); const stubPush = sandbox.stub(pushWorker_module, 'pushWorker'); - stubPush.onFirstCall().rejects(new Remote.Err.UnfetchedCommitExistsError()); + stubPush + .onFirstCall() + .rejects(new RemoteEngine[syncB.engine].Err.UnfetchedCommitExistsError()); let firstChange = true; syncB.on('change', (changes: ChangedFile[]) => { diff --git a/test/remote/sync_trypush.test.ts b/test/remote/sync_trypush.test.ts index 95a68113..3a3f083c 100644 --- a/test/remote/sync_trypush.test.ts +++ b/test/remote/sync_trypush.test.ts @@ -26,7 +26,11 @@ import { getWorkingDirDocs, removeRemoteRepositories, } from '../remote_utils'; -import { SyncResultCancel, SyncResultPush } from '../../src/types'; +import { + ConnectionSettingsGitHub, + SyncResultCancel, + SyncResultPush, +} from '../../src/types'; import { sleep } from '../../src/utils'; import { GitDocumentDB } from '../../src/git_documentdb'; @@ -70,6 +74,12 @@ maybe(': Sync#tryPush()', () => { : process.env.GITDDB_GITHUB_USER_URL + '/'; const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; + const connection: ConnectionSettingsGitHub = { + type: 'github', + personalAccessToken: token, + engine: 'nodegit', + }; + before(async () => { await removeRemoteRepositories(reposPrefix); }); @@ -80,7 +90,9 @@ maybe(': Sync#tryPush()', () => { * after : jsonA1 */ it('changes one remote creation when pushes after one put()', async function () { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId); + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, + }); // Put and push const jsonA1 = { _id: '1', name: 'fromA' }; @@ -112,7 +124,9 @@ maybe(': Sync#tryPush()', () => { * after : jsonA1 */ it('does not change remote when pushes after put() the same document again', async function () { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId); + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, + }); const jsonA1 = { _id: '1', name: 'fromA' }; await dbA.put(jsonA1); await syncA.tryPush(); @@ -148,7 +162,9 @@ maybe(': Sync#tryPush()', () => { * after : jsonA1 */ it('changes one remote update when pushes after put() updated document', async function () { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId); + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, + }); const jsonA1 = { _id: '1', name: 'fromA' }; const putResultA1 = await dbA.put(jsonA1); await syncA.tryPush(); @@ -186,7 +202,9 @@ maybe(': Sync#tryPush()', () => { * after : jsonA1 jsonA2 */ it('changes one remote creation when pushes after put() another document', async function () { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId); + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, + }); const jsonA1 = { _id: '1', name: 'fromA' }; await dbA.put(jsonA1); await syncA.tryPush(); @@ -226,7 +244,9 @@ maybe(': Sync#tryPush()', () => { * after2: jsonA1 jsonA2 jsonA3 */ it('changes two remote creations when pushes after put() two documents', async function () { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId); + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, + }); // Two put commands and push const jsonA1 = { _id: '1', name: 'fromA' }; @@ -264,7 +284,9 @@ maybe(': Sync#tryPush()', () => { * after : +jsonA1 jsonA2 */ it('changes one remote creation and one remote update when pushes after put() updated document and another document', async function () { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId); + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, + }); const jsonA1 = { _id: '1', name: 'fromA' }; const putResult1 = await dbA.put(jsonA1); @@ -305,7 +327,9 @@ maybe(': Sync#tryPush()', () => { * after : */ it('changes one remote delete when pushes after one delete()', async function () { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId); + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, + }); const jsonA1 = { _id: '1', name: 'fromA' }; await dbA.put(jsonA1); @@ -344,7 +368,9 @@ maybe(': Sync#tryPush()', () => { * after : */ it('does not change remote when pushes after put() and delete()', async function () { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId); + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, + }); const jsonA1 = { _id: '1', name: 'fromA' }; // Put and delete the same document @@ -373,7 +399,9 @@ maybe(': Sync#tryPush()', () => { }); it('skips consecutive push tasks', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId); + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, + }); const jsonA1 = { _id: '1', name: 'fromA' }; await dbA.put(jsonA1); diff --git a/test/remote/sync_trysync.test.ts b/test/remote/sync_trysync.test.ts index 06717358..f7a996af 100644 --- a/test/remote/sync_trysync.test.ts +++ b/test/remote/sync_trysync.test.ts @@ -17,7 +17,7 @@ import git from 'isomorphic-git'; import fs from 'fs-extra'; import expect from 'expect'; import { GitDocumentDB } from '../../src/git_documentdb'; -import { Remote } from '../../src/remote/remote'; +import { RemoteEngine } from '../../src/remote/remote_engine'; import { SyncResult, SyncResultFastForwardMerge, @@ -764,7 +764,7 @@ maybe(': Sync#trySync()', () => { // tryPush throws UnfetchedCommitExistsError await expect(dbB.sync(syncA.options)).rejects.toThrowError( - Remote.Err.UnfetchedCommitExistsError + RemoteEngine[syncA.engine].Err.UnfetchedCommitExistsError ); await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); diff --git a/test/remote_utils.ts b/test/remote_utils.ts index 496d6a64..2548ff09 100644 --- a/test/remote_utils.ts +++ b/test/remote_utils.ts @@ -191,7 +191,6 @@ export async function createDatabase ( includeCommits: true, }; options.remoteUrl ??= remoteURL; - options.connection ??= { type: 'github', personalAccessToken: token }; options.includeCommits ??= true; await dbA.open(); diff --git a/test_intg/sync_lifecycle.test.ts b/test_intg/sync_lifecycle.test.ts index 45a595dd..c31c1319 100644 --- a/test_intg/sync_lifecycle.test.ts +++ b/test_intg/sync_lifecycle.test.ts @@ -30,7 +30,7 @@ import { import { JSON_EXT, MINIMUM_SYNC_INTERVAL, NETWORK_RETRY } from '../src/const'; import { pushWorker } from '../src/remote/push_worker'; import { syncWorker } from '../src/remote/sync_worker'; -import { Remote } from '../src/remote/remote'; +import { RemoteEngine } from '../src/remote/remote_engine'; // eslint-disable-next-line @typescript-eslint/no-var-requires const pushWorker_module = require('../src/remote/push_worker'); @@ -216,7 +216,7 @@ maybe('intg Sync', () => { await dbB.put(jsonB1); await expect(Promise.all([syncA.tryPush(), syncB.tryPush()])).rejects.toThrowError( - Remote.Err.UnfetchedCommitExistsError + RemoteEngine[syncA.engine].Err.UnfetchedCommitExistsError ); await destroyDBs([dbA, dbB]); @@ -252,7 +252,7 @@ maybe('intg Sync', () => { await syncA.tryPush(); await expect(syncB.tryPush()).rejects.toThrowError( - Remote.Err.UnfetchedCommitExistsError + RemoteEngine[syncB.engine].Err.UnfetchedCommitExistsError ); await destroyDBs([dbA, dbB]); From 730ac84595f0f3c5ad92c97589037299ed0fc7c8 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 14 Jul 2021 23:34:51 +0900 Subject: [PATCH 051/297] fix: retry checkPush --- src/remote/sync.ts | 25 +++++++++++++++---- .../3way_merge.test.ts | 0 test/{remote => remote_base}/combine.test.ts | 0 .../{remote => remote_base}/json_diff.test.ts | 0 .../json_patch_ot.test.ts | 0 test/{remote => remote_base}/net.test.ts | 0 .../remote_repository.test.ts | 0 test/{remote => remote_base}/sync.test.ts | 0 .../sync_clone.test.ts | 0 .../sync_events.test.ts | 0 .../sync_github_noauth.test.ts | 0 .../sync_github_nopat_nooauth_sshkey.test.ts | 0 .../sync_github_nopat_oauth.test.ts | 0 .../sync_trypush.ts} | 0 .../sync_trysync.test.ts | 0 15 files changed, 20 insertions(+), 5 deletions(-) rename test/{remote => remote_base}/3way_merge.test.ts (100%) rename test/{remote => remote_base}/combine.test.ts (100%) rename test/{remote => remote_base}/json_diff.test.ts (100%) rename test/{remote => remote_base}/json_patch_ot.test.ts (100%) rename test/{remote => remote_base}/net.test.ts (100%) rename test/{remote => remote_base}/remote_repository.test.ts (100%) rename test/{remote => remote_base}/sync.test.ts (100%) rename test/{remote => remote_base}/sync_clone.test.ts (100%) rename test/{remote => remote_base}/sync_events.test.ts (100%) rename test/{remote => remote_base}/sync_github_noauth.test.ts (100%) rename test/{remote => remote_base}/sync_github_nopat_nooauth_sshkey.test.ts (100%) rename test/{remote => remote_base}/sync_github_nopat_oauth.test.ts (100%) rename test/{remote/sync_trypush.test.ts => remote_base/sync_trypush.ts} (100%) rename test/{remote => remote_base}/sync_trysync.test.ts (100%) diff --git a/src/remote/sync.ts b/src/remote/sync.ts index 4b5b30ba..e7ccc82e 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -384,6 +384,7 @@ export class Sync implements SyncInterface { * * @public */ + // eslint-disable-next-line complexity async init (): Promise { this._isClosed = false; @@ -403,11 +404,25 @@ export class Sync implements SyncInterface { this._upstreamBranch = ''; } if (!onlyFetch) { - await RemoteEngine[this._engine] - .checkPush(this._gitDDB.workingDir, this._options, this._gitDDB.logger) - .catch((err: Error) => { - throw new Err.RemoteCheckPushError(err.message); - }); + let result; + let retry = 0; + for (; retry < NETWORK_RETRY; retry++) { + // eslint-disable-next-line no-await-in-loop + result = await RemoteEngine[this._engine] + .checkPush(this._gitDDB.workingDir, this._options, this._gitDDB.logger) + .catch((err: Error) => { + return err; + }); + if (!(result instanceof Error)) { + break; + } + console.log('retrying checkPush..'); + // eslint-disable-next-line no-await-in-loop + await sleep(NETWORK_RETRY_INTERVAL); + } + if (result instanceof Error) { + throw new Err.RemoteCheckPushError(result.message); + } } let syncResult: SyncResult = { diff --git a/test/remote/3way_merge.test.ts b/test/remote_base/3way_merge.test.ts similarity index 100% rename from test/remote/3way_merge.test.ts rename to test/remote_base/3way_merge.test.ts diff --git a/test/remote/combine.test.ts b/test/remote_base/combine.test.ts similarity index 100% rename from test/remote/combine.test.ts rename to test/remote_base/combine.test.ts diff --git a/test/remote/json_diff.test.ts b/test/remote_base/json_diff.test.ts similarity index 100% rename from test/remote/json_diff.test.ts rename to test/remote_base/json_diff.test.ts diff --git a/test/remote/json_patch_ot.test.ts b/test/remote_base/json_patch_ot.test.ts similarity index 100% rename from test/remote/json_patch_ot.test.ts rename to test/remote_base/json_patch_ot.test.ts diff --git a/test/remote/net.test.ts b/test/remote_base/net.test.ts similarity index 100% rename from test/remote/net.test.ts rename to test/remote_base/net.test.ts diff --git a/test/remote/remote_repository.test.ts b/test/remote_base/remote_repository.test.ts similarity index 100% rename from test/remote/remote_repository.test.ts rename to test/remote_base/remote_repository.test.ts diff --git a/test/remote/sync.test.ts b/test/remote_base/sync.test.ts similarity index 100% rename from test/remote/sync.test.ts rename to test/remote_base/sync.test.ts diff --git a/test/remote/sync_clone.test.ts b/test/remote_base/sync_clone.test.ts similarity index 100% rename from test/remote/sync_clone.test.ts rename to test/remote_base/sync_clone.test.ts diff --git a/test/remote/sync_events.test.ts b/test/remote_base/sync_events.test.ts similarity index 100% rename from test/remote/sync_events.test.ts rename to test/remote_base/sync_events.test.ts diff --git a/test/remote/sync_github_noauth.test.ts b/test/remote_base/sync_github_noauth.test.ts similarity index 100% rename from test/remote/sync_github_noauth.test.ts rename to test/remote_base/sync_github_noauth.test.ts diff --git a/test/remote/sync_github_nopat_nooauth_sshkey.test.ts b/test/remote_base/sync_github_nopat_nooauth_sshkey.test.ts similarity index 100% rename from test/remote/sync_github_nopat_nooauth_sshkey.test.ts rename to test/remote_base/sync_github_nopat_nooauth_sshkey.test.ts diff --git a/test/remote/sync_github_nopat_oauth.test.ts b/test/remote_base/sync_github_nopat_oauth.test.ts similarity index 100% rename from test/remote/sync_github_nopat_oauth.test.ts rename to test/remote_base/sync_github_nopat_oauth.test.ts diff --git a/test/remote/sync_trypush.test.ts b/test/remote_base/sync_trypush.ts similarity index 100% rename from test/remote/sync_trypush.test.ts rename to test/remote_base/sync_trypush.ts diff --git a/test/remote/sync_trysync.test.ts b/test/remote_base/sync_trysync.test.ts similarity index 100% rename from test/remote/sync_trysync.test.ts rename to test/remote_base/sync_trysync.test.ts From 28330ed2a075128e68df65a169bef4624a96cd1c Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 14 Jul 2021 23:37:04 +0900 Subject: [PATCH 052/297] fix: add individual test for NodeGit RemoteEngine --- test/remote_base/sync_trypush.ts | 64 ++++-------------------- test/remote_nodegit/sync_trypush.test.ts | 64 ++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 53 deletions(-) create mode 100644 test/remote_nodegit/sync_trypush.test.ts diff --git a/test/remote_base/sync_trypush.ts b/test/remote_base/sync_trypush.ts index 3a3f083c..76ee4f8f 100644 --- a/test/remote_base/sync_trypush.ts +++ b/test/remote_base/sync_trypush.ts @@ -12,8 +12,6 @@ * by using GitHub Personal Access Token * These tests create a new repository on GitHub if not exists. */ -import path from 'path'; -import fs from 'fs-extra'; import expect from 'expect'; import { compareWorkingDirAndBlobs, @@ -26,58 +24,18 @@ import { getWorkingDirDocs, removeRemoteRepositories, } from '../remote_utils'; -import { - ConnectionSettingsGitHub, - SyncResultCancel, - SyncResultPush, -} from '../../src/types'; +import { ConnectionSettings, SyncResultCancel, SyncResultPush } from '../../src/types'; import { sleep } from '../../src/utils'; -import { GitDocumentDB } from '../../src/git_documentdb'; - -const reposPrefix = 'test_sync_trypush___'; -const localDir = `./test/database_sync_trypush`; -let idCounter = 0; -const serialId = () => { - return `${reposPrefix}${idCounter++}`; -}; - -beforeEach(function () { - // @ts-ignore - console.log(`... ${this.currentTest.fullTitle()}`); -}); - -before(() => { - // eslint-disable-next-line @typescript-eslint/no-var-requires - GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); - - fs.removeSync(path.resolve(localDir)); -}); - -after(() => { - // It may throw error due to memory leak of getCommitLogs() - // fs.removeSync(path.resolve(localDir)); -}); - -// This test needs environment variables: -// - GITDDB_GITHUB_USER_URL: URL of your GitHub account -// e.g.) https://github.com/foo/ -// - GITDDB_PERSONAL_ACCESS_TOKEN: A personal access token of your GitHub account -const maybe = - process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN - ? describe - : describe.skip; - -maybe(': Sync#tryPush()', () => { - const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') - ? process.env.GITDDB_GITHUB_USER_URL - : process.env.GITDDB_GITHUB_USER_URL + '/'; - const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; - - const connection: ConnectionSettingsGitHub = { - type: 'github', - personalAccessToken: token, - engine: 'nodegit', +export const syncTryPush = ( + connection: ConnectionSettings, + remoteURLBase: string, + reposPrefix: string, + localDir: string +) => () => { + let idCounter = 0; + const serialId = () => { + return `${reposPrefix}${idCounter++}`; }; before(async () => { @@ -427,4 +385,4 @@ maybe(': Sync#tryPush()', () => { await destroyDBs([dbA]); }); -}); +}; diff --git a/test/remote_nodegit/sync_trypush.test.ts b/test/remote_nodegit/sync_trypush.test.ts new file mode 100644 index 00000000..ae5dcdb7 --- /dev/null +++ b/test/remote_nodegit/sync_trypush.test.ts @@ -0,0 +1,64 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +/** + * Test push + * by using GitHub Personal Access Token + * These tests create a new repository on GitHub if not exists. + */ +import path from 'path'; +import fs from 'fs-extra'; +import { syncTryPush } from '../remote_base/sync_trypush'; +import { ConnectionSettingsGitHub } from '../../src/types'; +import { GitDocumentDB } from '../../src/git_documentdb'; + +const reposPrefix = 'test_sync_trypush_nodegit___'; +const localDir = `./test/database_sync_trypush_nodegit`; + +beforeEach(function () { + // @ts-ignore + console.log(`... ${this.currentTest.fullTitle()}`); +}); + +before(() => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + + fs.removeSync(path.resolve(localDir)); +}); + +after(() => { + fs.removeSync(path.resolve(localDir)); +}); + +// This test needs environment variables: +// - GITDDB_GITHUB_USER_URL: URL of your GitHub account +// e.g.) https://github.com/foo/ +// - GITDDB_PERSONAL_ACCESS_TOKEN: A personal access token of your GitHub account +const maybe = + process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN + ? describe + : describe.skip; + +const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') + ? process.env.GITDDB_GITHUB_USER_URL + : process.env.GITDDB_GITHUB_USER_URL + '/'; + +const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; + +const connection: ConnectionSettingsGitHub = { + type: 'github', + personalAccessToken: token, + engine: 'nodegit', +}; + +maybe( + ': Sync#tryPush()', + syncTryPush(connection, remoteURLBase, reposPrefix, localDir) +); From 5391f838d3c429c0d4c7d147f3b3ae03709572b6 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Thu, 15 Jul 2021 03:32:33 +0900 Subject: [PATCH 053/297] docs: add pros and cons --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1ae93d7d..e480205f 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,11 @@ Use GitDocumentDB to ... :dromedary_camel: Travel revisions. -You do not need knowledge of Git to start. However, you make the most of GitDocumentDB if you understand Git. +The throughput in GitDocumentDB is about the same as Git. It's not fast like typical databases. + +However, GitDocumentDB is compatible with Git that enables distributed multi-primary databases with revision history. Besides, it has a fully automated diff, patch, and sync with remote Git repository, automated combining of inconsistent repositories, and accessible CRUD and collection APIs for operating JSON. + +So, GitDocumentDB is helpful for people who develop Git-powered offline-first apps. # API https://gitddb.com/docs/api/git-documentdb.gitdocumentdb From 7dd4e6b54c08552f9071aa3456671173a58a6bc2 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Thu, 15 Jul 2021 11:11:31 +0900 Subject: [PATCH 054/297] docs: update README --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 1ae93d7d..bfdb2f47 100644 --- a/README.md +++ b/README.md @@ -9,19 +9,19 @@ Offline-first DocumentDB that Syncs with Git Use GitDocumentDB to ... -:green_book: Store JSON documents into Git repository. +:nut_and_bolt: Develop offline-first applications using Git. -:art: Manage Git repository by document database API. +:green_book: Manage JSON documents in Git repository by CRUD and collection APIs. -:rocket: Synchronize, diff and patch automatically with a remote repository. +:rocket: Synchronize automatically with a remote repository. -     (No need to resolve conflicts manually.) +     *(No need to resolve conflicts manually!)* -:arrows_counterclockwise: CI/CD through GitHub. +:arrows_counterclockwise: Integrate CI/CD pipelines through GitHub. -:dromedary_camel: Travel revisions. +:dromedary_camel: Get revision history of a document. -You do not need knowledge of Git to start. However, you make the most of GitDocumentDB if you understand Git. +[(More...)](https://gitddb.com/) # API https://gitddb.com/docs/api/git-documentdb.gitdocumentdb From 708503ce995f23f2cc356c1b71db3156de136a36 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Thu, 15 Jul 2021 11:16:10 +0900 Subject: [PATCH 055/297] docs: correct features --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bfdb2f47..9a2e06ab 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Offline-first DocumentDB that Syncs with Git Use GitDocumentDB to ... -:nut_and_bolt: Develop offline-first applications using Git. +:nut_and_bolt: Develop offline-capable applications using Git. :green_book: Manage JSON documents in Git repository by CRUD and collection APIs. From e5012622c3ec038f35eefd4205dba8fe6a85edd5 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Thu, 15 Jul 2021 11:40:53 +0900 Subject: [PATCH 056/297] docs: correct features --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9a2e06ab..ad73173b 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![License: MPL 2.0](https://img.shields.io/github/license/sosuisen/git-documentdb)](LICENSE) [![Coverage Status](https://img.shields.io/coveralls/github/sosuisen/git-documentdb)](https://coveralls.io/github/sosuisen/git-documentdb?branch=main) -Offline-first DocumentDB that Syncs with Git +TypeScript Ready Offline-first Database that Syncs with Git Use GitDocumentDB to ... From 669a8c876bb6ce60808caa68653e199b9277436b Mon Sep 17 00:00:00 2001 From: sosuisen Date: Mon, 26 Jul 2021 16:59:11 +0900 Subject: [PATCH 057/297] fix: replace error.ts with git-documentdb-remote-errors --- package-lock.json | 45 ++++++++++++++++++++++++++++++++----- package.json | 6 +++-- src/remote/remote_engine.ts | 33 ++++++++++++++++++++++++++- src/remote/sync.ts | 21 +++++++++++------ 4 files changed, 90 insertions(+), 15 deletions(-) diff --git a/package-lock.json b/package-lock.json index 43918f16..ce7ac16d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3500,16 +3500,21 @@ "dev": true }, "git-documentdb-plugin-remote-nodegit": { - "version": "1.0.0-alpha.16", - "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.0-alpha.16.tgz", - "integrity": "sha512-Ie3EExrKlXwGG14CKTigqjS3uNDJUio798dqTqSCP3qijlTRO9TZAnXNrVmVuJRpglGalM4etC8KBvv4YSoYEA==", + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.0-beta.2.tgz", + "integrity": "sha512-3V5A6ek1BHy8fUjlkikLNkmR92B8hVxN7d0W5h2Kl0jdwb8i8RUa1g4xOVhGMxXTy4WxNunvtBjYtz+IVn12UA==", "dev": true, "requires": { - "@sosuisen/nodegit": "^0.27.3", - "isomorphic-git": "^1.9.1", + "git-documentdb-remote-errors": "^1.0.2", + "nodegit": "^0.27.0", "tslog": "^3.2.0" } }, + "git-documentdb-remote-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/git-documentdb-remote-errors/-/git-documentdb-remote-errors-1.0.2.tgz", + "integrity": "sha512-sUUM2ncshR5JLcyGRpaWELYLiEVfIIdEEClEVwN52SiPP/kLSq6xnG9Rg5X8v5WIB/geQrH6bCTlvK+vCBdhiQ==" + }, "glob": { "version": "7.1.7", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", @@ -5198,6 +5203,36 @@ "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==", "dev": true }, + "nodegit": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/nodegit/-/nodegit-0.27.0.tgz", + "integrity": "sha512-E9K4gPjWiA0b3Tx5lfWCzG7Cvodi2idl3V5UD2fZrOrHikIfrN7Fc2kWLtMUqqomyoToYJLeIC8IV7xb1CYRLA==", + "dev": true, + "requires": { + "fs-extra": "^7.0.0", + "got": "^10.7.0", + "json5": "^2.1.0", + "lodash": "^4.17.14", + "nan": "^2.14.0", + "node-gyp": "^4.0.0", + "node-pre-gyp": "^0.13.0", + "ramda": "^0.25.0", + "tar-fs": "^1.16.3" + }, + "dependencies": { + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + } + } + }, "nopt": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", diff --git a/package.json b/package.json index e46558f4..e91440f1 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,8 @@ "prepublishOnly": "npm run build && npm test", "api-extractor": "api-extractor run --local --verbose && npx api-documenter markdown -i ./temp -o ./docs-api", "lint": "eslint --fix --ext .ts .", - "crlf": "npx crlf --set=LF docs-api/* etc/* " + "crlf": "npx crlf --set=LF docs-api/* etc/* ", + "remove-remote": "node --experimental-modules --experimental-json-modules remove_remote_repositories.mjs" }, "repository": { "type": "git", @@ -61,7 +62,7 @@ "eslint-config-standardize": "^0.7.1", "eslint-plugin-prettierx": "^0.14.0", "expect": "^27.0.2", - "git-documentdb-plugin-remote-nodegit": "^1.0.0-alpha.16", + "git-documentdb-plugin-remote-nodegit": "^1.0.0-beta.2", "mocha": "^8.3.2", "nyc": "^15.1.0", "parse-git-config": "^3.0.0", @@ -78,6 +79,7 @@ "async-lock": "^1.3.0", "cross-blob": "^2.0.0", "fs-extra": "^9.1.0", + "git-documentdb-remote-errors": "^1.0.2", "isomorphic-git": "^1.8.2", "ot-json1": "^1.0.2", "rimraf": "^3.0.2", diff --git a/src/remote/remote_engine.ts b/src/remote/remote_engine.ts index f53e68a0..2566abd6 100644 --- a/src/remote/remote_engine.ts +++ b/src/remote/remote_engine.ts @@ -1,2 +1,33 @@ +import { Logger } from 'tslog'; +import { RemoteOptions } from '../types'; + // eslint-disable-next-line @typescript-eslint/naming-convention -export const RemoteEngine: { [key: string]: any } = {}; +export const RemoteEngine: { [key: string]: RemoteEngineInterface } = {}; + +export interface RemoteEngineInterface { + checkFetch: ( + workingDir: string, + options: RemoteOptions, + remoteName?: string, + logger?: Logger + ) => Promise; + fetch: ( + workingDir: string, + remoteOptions: RemoteOptions, + remoteName?: string, + logger?: Logger + ) => Promise; + push: ( + workingDir: string, + remoteOptions: RemoteOptions, + remoteName?: string, + localBranch?: string, + remoteBranch?: string, + logger?: Logger + ) => Promise; + clone: ( + workingDir: string, + remoteOptions: RemoteOptions, + logger?: Logger + ) => Promise; +} diff --git a/src/remote/sync.ts b/src/remote/sync.ts index e7ccc82e..58a0b954 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -55,6 +55,7 @@ import { JsonPatchOT } from './json_patch_ot'; import { combineDatabaseWithTheirs } from './combine'; import { Validator } from '../validator'; import { RemoteEngine } from './remote_engine'; +import { } from 'git-documentdb-remote-errors'; /** * Implementation of GitDocumentDB#sync(options, get_sync_result) @@ -390,11 +391,13 @@ export class Sync implements SyncInterface { const onlyFetch = this._options.syncDirection === 'pull'; - const remoteResult: 'exist' | 'not_exist' = await RemoteEngine[this._engine] + const remoteResult: boolean | Error = await RemoteEngine[this._engine] .checkFetch(this._gitDDB.workingDir, this._options, this._gitDDB.logger) .catch((err: Error) => { throw new Err.RemoteCheckFetchError(err.message); }); + + if (remoteResult instanceof CannotConnectError) if (remoteResult === 'not_exist') { // Try to create repository by octokit await this.remoteRepository.create().catch(err => { @@ -694,13 +697,17 @@ export class Sync implements SyncInterface { this._gitDDB, this._options ).catch(err => { - throw new Err.CombineDatabaseError(err.message); + // throw new Err.CombineDatabaseError(err.message); + error = new Err.CombineDatabaseError(err.message); + return undefined; }); - // eslint-disable-next-line no-loop-func - this.eventHandlers.combine.forEach(callback => - callback.func(syncResultCombineDatabase.duplicates) - ); - return syncResultCombineDatabase; + if (syncResultCombineDatabase !== undefined) { + // eslint-disable-next-line no-loop-func + this.eventHandlers.combine.forEach(callback => + callback.func(syncResultCombineDatabase.duplicates) + ); + return syncResultCombineDatabase; + } } } From db8ffed5b6367e68efe02edea0ba2e63ce6f9d05 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Mon, 26 Jul 2021 16:59:39 +0900 Subject: [PATCH 058/297] fix: add remove_remote_repositories script --- .eslintignore | 1 + remove_remote_repositories.mjs | 48 ++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 remove_remote_repositories.mjs diff --git a/.eslintignore b/.eslintignore index 0db7c2a8..d3d57075 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,3 +1,4 @@ examples/ types/sosuisen__nodegit/ dist/ +*.mjs \ No newline at end of file diff --git a/remove_remote_repositories.mjs b/remove_remote_repositories.mjs new file mode 100644 index 00000000..c9470555 --- /dev/null +++ b/remove_remote_repositories.mjs @@ -0,0 +1,48 @@ +import { Octokit } from '@octokit/rest'; + +const reposPrefix = 'test_'; + +const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN; + +const octokit = new Octokit({ + auth: token, +}); + +const len = 0; +const promises = []; + +const removeRemoteRepositories = async () => { + // eslint-disable-next-line no-await-in-loop + const reposArray = await octokit.paginate( + octokit.repos.listForAuthenticatedUser, + { per_page: 100 }, + response => + response.data.filter(repos => { + if (repos) { + const urlArray = repos.full_name.split('/'); + const repo = urlArray[1]; + return repo.startsWith(reposPrefix); + } + return false; + }) + ); + // console.log(` - Got ${reposArray.length} repositories`); + reposArray.forEach(repos => { + const urlArray = repos.full_name.split('/'); + const owner = urlArray[0]; + const repo = urlArray[1]; + promises.push( + octokit.repos.delete({ owner, repo }).catch(err => { + if (err.status !== 404) { + console.debug(err); + } + }) + ); + }); + console.log(` - Start to remove repositories..`); + // eslint-disable-next-line no-await-in-loop + await Promise.all(promises); + console.log(` - Done.`); +}; + +removeRemoteRepositories(); \ No newline at end of file From 164fe54245fd106eab8c89d61630c40e43430aaf Mon Sep 17 00:00:00 2001 From: sosuisen Date: Mon, 26 Jul 2021 19:29:58 +0900 Subject: [PATCH 059/297] fix: add RemoteErr namespace --- src/error.ts | 9 +++++ src/remote/remote_engine.ts | 72 ++++++++++++++++++++++++++++++++++++- src/remote/sync.ts | 48 +++++++------------------ 3 files changed, 93 insertions(+), 36 deletions(-) diff --git a/src/error.ts b/src/error.ts index 077af10a..4df008cc 100644 --- a/src/error.ts +++ b/src/error.ts @@ -518,4 +518,13 @@ Current value is '${type}'`); super(`Combine database failed: ${mes})`); } } + + /** + * @public + */ + export class NoMergeBaseFoundError extends BaseError { + constructor () { + super(`No merge base found`); + } + } } diff --git a/src/remote/remote_engine.ts b/src/remote/remote_engine.ts index 2566abd6..646e06ca 100644 --- a/src/remote/remote_engine.ts +++ b/src/remote/remote_engine.ts @@ -1,7 +1,8 @@ +/* eslint-disable @typescript-eslint/naming-convention */ import { Logger } from 'tslog'; +import * as RemoteErrors from 'git-documentdb-remote-errors'; import { RemoteOptions } from '../types'; -// eslint-disable-next-line @typescript-eslint/naming-convention export const RemoteEngine: { [key: string]: RemoteEngineInterface } = {}; export interface RemoteEngineInterface { @@ -31,3 +32,72 @@ export interface RemoteEngineInterface { logger?: Logger ) => Promise; } + +export namespace RemoteErr { + export class CannotConnectError extends RemoteErrors.CannotConnectError { + constructor (mes: unknown) { + super(mes); + this.name = 'CannotConnectError'; + } + } + export class HTTPError401AuthorizationRequired extends RemoteErrors.HTTPError401AuthorizationRequired { + constructor (mes: unknown) { + super(mes); + this.name = 'HTTPError401AuthorizationRequired'; + } + } + export class HTTPError403Forbidden extends RemoteErrors.HTTPError403Forbidden { + constructor (mes: unknown) { + super(mes); + this.name = 'HTTPError403Forbidden'; + } + } + export class HTTPError404NotFound extends RemoteErrors.HTTPError404NotFound { + constructor (mes: unknown) { + super(mes); + this.name = 'HTTPError404NotFound'; + } + } + export class InvalidAuthenticationTypeError extends RemoteErrors.InvalidAuthenticationTypeError { + constructor (type: unknown) { + super(type); + this.name = 'InvalidAuthenticationTypeError'; + } + } + export class InvalidGitRemoteError extends RemoteErrors.InvalidGitRemoteError { + constructor (mes: unknown) { + super(mes); + this.name = 'InvalidGitRemoteError'; + } + } + export class InvalidRepositoryURLError extends RemoteErrors.InvalidRepositoryURLError { + constructor (url: unknown) { + super(url); + this.name = 'InvalidRepositoryURLError'; + } + } + export class InvalidSSHKeyPathError extends RemoteErrors.InvalidSSHKeyPathError { + constructor () { + super(); + this.name = 'InvalidSSHKeyPathError'; + } + } + export class InvalidURLFormatError extends RemoteErrors.InvalidURLFormatError { + constructor (mes: unknown) { + super(mes); + this.name = 'InvalidURLFormatError'; + } + } + export class NetworkError extends RemoteErrors.NetworkError { + constructor (mes: unknown) { + super(mes); + this.name = 'NetworkError'; + } + } + export class UnfetchedCommitExistsError extends RemoteErrors.UnfetchedCommitExistsError { + constructor () { + super(); + this.name = 'UnfetchedCommitExistsError'; + } + } +} diff --git a/src/remote/sync.ts b/src/remote/sync.ts index 58a0b954..4d496ad9 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -54,8 +54,7 @@ import { JsonDiff } from './json_diff'; import { JsonPatchOT } from './json_patch_ot'; import { combineDatabaseWithTheirs } from './combine'; import { Validator } from '../validator'; -import { RemoteEngine } from './remote_engine'; -import { } from 'git-documentdb-remote-errors'; +import { RemoteEngine, RemoteErr } from './remote_engine'; /** * Implementation of GitDocumentDB#sync(options, get_sync_result) @@ -392,13 +391,13 @@ export class Sync implements SyncInterface { const onlyFetch = this._options.syncDirection === 'pull'; const remoteResult: boolean | Error = await RemoteEngine[this._engine] - .checkFetch(this._gitDDB.workingDir, this._options, this._gitDDB.logger) - .catch((err: Error) => { - throw new Err.RemoteCheckFetchError(err.message); - }); + .checkFetch(this._gitDDB.workingDir, this._options, undefined, this._gitDDB.logger) + .catch(err => err); - if (remoteResult instanceof CannotConnectError) - if (remoteResult === 'not_exist') { + if (typeof remoteResult === 'boolean') { + // nop + } + else if (remoteResult instanceof RemoteErr.CannotConnectError) { // Try to create repository by octokit await this.remoteRepository.create().catch(err => { // App may check permission or @@ -406,27 +405,6 @@ export class Sync implements SyncInterface { }); this._upstreamBranch = ''; } - if (!onlyFetch) { - let result; - let retry = 0; - for (; retry < NETWORK_RETRY; retry++) { - // eslint-disable-next-line no-await-in-loop - result = await RemoteEngine[this._engine] - .checkPush(this._gitDDB.workingDir, this._options, this._gitDDB.logger) - .catch((err: Error) => { - return err; - }); - if (!(result instanceof Error)) { - break; - } - console.log('retrying checkPush..'); - // eslint-disable-next-line no-await-in-loop - await sleep(NETWORK_RETRY_INTERVAL); - } - if (result instanceof Error) { - throw new Err.RemoteCheckPushError(result.message); - } - } let syncResult: SyncResult = { action: 'nop', @@ -598,7 +576,7 @@ export class Sync implements SyncInterface { result = resultOrError; } - if (error instanceof RemoteEngine[this._engine].Err.UnfetchedCommitExistsError) { + if (error instanceof RemoteErr.UnfetchedCommitExistsError) { if (this._options.syncDirection === 'push') { if (this._options.combineDbStrategy === 'replace-with-ours') { // TODO: Exec replace-with-ours instead of throw error @@ -686,7 +664,7 @@ export class Sync implements SyncInterface { result = resultOrError; } - if (error instanceof RemoteEngine[this._engine].Err.NoMergeBaseFoundError) { + if (error instanceof Err.NoMergeBaseFoundError) { if (this._options.combineDbStrategy === 'throw-error') { throw error; } @@ -732,7 +710,7 @@ export class Sync implements SyncInterface { if ( // eslint-disable-next-line no-await-in-loop !(await this.canNetworkConnection()) || - error instanceof RemoteEngine[this._engine].Err.UnfetchedCommitExistsError + error instanceof RemoteErr.UnfetchedCommitExistsError ) { // Retry for the following reasons: // - Network connection may be improved next time. @@ -819,7 +797,7 @@ export class Sync implements SyncInterface { }) .catch(err => { // console.log(`Error in push_worker: ${err}`); - if (!(err instanceof RemoteEngine[this._engine].Err.UnfetchedCommitExistsError)) { + if (!(err instanceof RemoteErr.UnfetchedCommitExistsError)) { err = new Err.PushWorkerError(err.message); } this.eventHandlers.error.forEach(listener => { @@ -961,8 +939,8 @@ export class Sync implements SyncInterface { // console.log(`Error in sync_worker: ${err}`); if ( !( - err instanceof RemoteEngine[this._engine].Err.NoMergeBaseFoundError || - err instanceof RemoteEngine[this._engine].Err.UnfetchedCommitExistsError + err instanceof Err.NoMergeBaseFoundError || + err instanceof RemoteErr.UnfetchedCommitExistsError ) ) { err = new Err.SyncWorkerError(err.message); From c1bc5860437834ba9315f7a5d229b64b1726828c Mon Sep 17 00:00:00 2001 From: sosuisen Date: Mon, 26 Jul 2021 23:01:43 +0900 Subject: [PATCH 060/297] fix: remove InvalidAuthenticationTypeError --- src/error.ts | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/error.ts b/src/error.ts index 077af10a..7a6b967d 100644 --- a/src/error.ts +++ b/src/error.ts @@ -260,16 +260,6 @@ Call removeRemote() before register it again.` } } - /** - * @public - */ - export class InvalidAuthenticationTypeError extends BaseError { - constructor (type: string) { - super(`Authentication type must be one of the following values: 'github', 'ssh'. -Current value is '${type}'`); - } - } - /** * @public */ @@ -518,4 +508,13 @@ Current value is '${type}'`); super(`Combine database failed: ${mes})`); } } + + /** + * @public + */ + export class NoMergeBaseFoundError extends BaseError { + constructor () { + super(`No merge base found`); + } + } } From 31dd70c41ee29aa4fe9008a09eaae270e9171fcf Mon Sep 17 00:00:00 2001 From: sosuisen Date: Mon, 26 Jul 2021 23:02:41 +0900 Subject: [PATCH 061/297] fix: use Err.NoMergebaseFoundError instead of Error in plugin --- src/remote/sync_worker.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/remote/sync_worker.ts b/src/remote/sync_worker.ts index 532d2079..54083adb 100644 --- a/src/remote/sync_worker.ts +++ b/src/remote/sync_worker.ts @@ -26,6 +26,7 @@ import { pushWorker } from './push_worker'; import { calcDistance, getAndWriteLocalChanges, getCommitLogs } from './worker_utils'; import { merge } from './3way_merge'; import { RemoteEngine } from './remote_engine'; +import { Err } from '../error'; /** * sync_worker @@ -87,7 +88,7 @@ export async function syncWorker ( // ahead: 1, behind 1 => Merge, may resolve conflict and push: Local has new commits. Remote has pushed new commits. if (distance.ahead === undefined || distance.behind === undefined) { - throw new RemoteEngine[sync.engine].Err.NoMergeBaseFoundError(); + throw new Err.NoMergeBaseFoundError(); } else if (distance.ahead === 0 && distance.behind === 0) { return { action: 'nop' }; From de482218558820701f9fec5780e0e04d6f66f9ae Mon Sep 17 00:00:00 2001 From: sosuisen Date: Mon, 26 Jul 2021 23:03:59 +0900 Subject: [PATCH 062/297] build: bump git-documentdb-plugin-remote-nodegit to v1.0.0-beta.2 install git-documentdb-remote-errors@1.0.2 --- package-lock.json | 45 ++++++++++++++++++++++++++++++++++++++++----- package.json | 5 +++-- 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 43918f16..ce7ac16d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3500,16 +3500,21 @@ "dev": true }, "git-documentdb-plugin-remote-nodegit": { - "version": "1.0.0-alpha.16", - "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.0-alpha.16.tgz", - "integrity": "sha512-Ie3EExrKlXwGG14CKTigqjS3uNDJUio798dqTqSCP3qijlTRO9TZAnXNrVmVuJRpglGalM4etC8KBvv4YSoYEA==", + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.0-beta.2.tgz", + "integrity": "sha512-3V5A6ek1BHy8fUjlkikLNkmR92B8hVxN7d0W5h2Kl0jdwb8i8RUa1g4xOVhGMxXTy4WxNunvtBjYtz+IVn12UA==", "dev": true, "requires": { - "@sosuisen/nodegit": "^0.27.3", - "isomorphic-git": "^1.9.1", + "git-documentdb-remote-errors": "^1.0.2", + "nodegit": "^0.27.0", "tslog": "^3.2.0" } }, + "git-documentdb-remote-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/git-documentdb-remote-errors/-/git-documentdb-remote-errors-1.0.2.tgz", + "integrity": "sha512-sUUM2ncshR5JLcyGRpaWELYLiEVfIIdEEClEVwN52SiPP/kLSq6xnG9Rg5X8v5WIB/geQrH6bCTlvK+vCBdhiQ==" + }, "glob": { "version": "7.1.7", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", @@ -5198,6 +5203,36 @@ "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==", "dev": true }, + "nodegit": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/nodegit/-/nodegit-0.27.0.tgz", + "integrity": "sha512-E9K4gPjWiA0b3Tx5lfWCzG7Cvodi2idl3V5UD2fZrOrHikIfrN7Fc2kWLtMUqqomyoToYJLeIC8IV7xb1CYRLA==", + "dev": true, + "requires": { + "fs-extra": "^7.0.0", + "got": "^10.7.0", + "json5": "^2.1.0", + "lodash": "^4.17.14", + "nan": "^2.14.0", + "node-gyp": "^4.0.0", + "node-pre-gyp": "^0.13.0", + "ramda": "^0.25.0", + "tar-fs": "^1.16.3" + }, + "dependencies": { + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + } + } + }, "nopt": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", diff --git a/package.json b/package.json index e46558f4..39139dc7 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "@octokit/types": "^6.12.2", "@sosuisen/api-documenter": "^7.13.25", "@types/expect": "^24.3.0", - "@types/fs-extra": "^9.0.6", + "@types/fs-extra": "^9.0.12", "@types/mocha": "^8.2.2", "@types/node": "^14.14.20", "@types/parse-git-config": "^3.0.0", @@ -61,7 +61,7 @@ "eslint-config-standardize": "^0.7.1", "eslint-plugin-prettierx": "^0.14.0", "expect": "^27.0.2", - "git-documentdb-plugin-remote-nodegit": "^1.0.0-alpha.16", + "git-documentdb-plugin-remote-nodegit": "^1.0.0-beta.2", "mocha": "^8.3.2", "nyc": "^15.1.0", "parse-git-config": "^3.0.0", @@ -78,6 +78,7 @@ "async-lock": "^1.3.0", "cross-blob": "^2.0.0", "fs-extra": "^9.1.0", + "git-documentdb-remote-errors": "^1.0.2", "isomorphic-git": "^1.8.2", "ot-json1": "^1.0.2", "rimraf": "^3.0.2", From 6d7a0610967bcc96ff9ab6dd352753caa0b5bfe6 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 27 Jul 2021 10:41:59 +0900 Subject: [PATCH 063/297] fix: add wrappingRemoteEngineError, adding tests for sync --- package-lock.json | 6 +- package.json | 2 +- src/error.ts | 18 - src/git_documentdb.ts | 1 + src/remote/remote_engine.ts | 30 ++ src/remote/remote_repository.ts | 5 - src/remote/sync.ts | 58 ++- src/remote/sync_worker.ts | 7 +- test/remote_base/sync.test.ts | 413 --------------- test/remote_base/sync.ts | 445 ++++++++++++++++ test/remote_base/sync_trypush.ts | 638 ++++++++++++----------- test/remote_nodegit/sync.test.ts | 61 +++ test/remote_nodegit/sync_trypush.test.ts | 7 +- 13 files changed, 911 insertions(+), 780 deletions(-) delete mode 100644 test/remote_base/sync.test.ts create mode 100644 test/remote_base/sync.ts create mode 100644 test/remote_nodegit/sync.test.ts diff --git a/package-lock.json b/package-lock.json index ce7ac16d..b017ad90 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3511,9 +3511,9 @@ } }, "git-documentdb-remote-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/git-documentdb-remote-errors/-/git-documentdb-remote-errors-1.0.2.tgz", - "integrity": "sha512-sUUM2ncshR5JLcyGRpaWELYLiEVfIIdEEClEVwN52SiPP/kLSq6xnG9Rg5X8v5WIB/geQrH6bCTlvK+vCBdhiQ==" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/git-documentdb-remote-errors/-/git-documentdb-remote-errors-1.0.3.tgz", + "integrity": "sha512-14fN8VAQeBC7+Phs6TYB1D5PJDE/dF8dxbigKpsBEqR1FvpAQerSPptxVsQgkU33xwwZBOm7yCwVD2KKmQatOQ==" }, "glob": { "version": "7.1.7", diff --git a/package.json b/package.json index 942afed0..d6bfbdec 100644 --- a/package.json +++ b/package.json @@ -79,7 +79,7 @@ "async-lock": "^1.3.0", "cross-blob": "^2.0.0", "fs-extra": "^9.1.0", - "git-documentdb-remote-errors": "^1.0.2", + "git-documentdb-remote-errors": "^1.0.3", "isomorphic-git": "^1.8.2", "ot-json1": "^1.0.2", "rimraf": "^3.0.2", diff --git a/src/error.ts b/src/error.ts index 7a6b967d..8663f6d8 100644 --- a/src/error.ts +++ b/src/error.ts @@ -444,24 +444,6 @@ Call removeRemote() before register it again.` } } - /** - * @public - */ - export class RemoteCheckPushError extends BaseError { - constructor (mes: unknown) { - super(`Error in RemoteEngine.checkPush(): ${mes}`); - } - } - - /** - * @public - */ - export class RemoteCheckFetchError extends BaseError { - constructor (mes: unknown) { - super(`Error in RemoteEngine.checkFetch(): ${mes}`); - } - } - /** * @public */ diff --git a/src/git_documentdb.ts b/src/git_documentdb.ts index d7eae95f..e8f59232 100644 --- a/src/git_documentdb.ts +++ b/src/git_documentdb.ts @@ -99,6 +99,7 @@ export class GitDocumentDB const type: PluginTypes = obj.type; if (type === 'remote') { if (obj.name !== undefined) { + // @ts-ignore RemoteEngine[obj.name] = {}; Object.keys(obj).forEach(function (id) { // Set to Remote object diff --git a/src/remote/remote_engine.ts b/src/remote/remote_engine.ts index 646e06ca..496886ba 100644 --- a/src/remote/remote_engine.ts +++ b/src/remote/remote_engine.ts @@ -101,3 +101,33 @@ export namespace RemoteErr { } } } + +// eslint-disable-next-line complexity +export function wrappingRemoteEngineError (remoteEngineError: RemoteErrors.BaseError) { + switch (true) { + case remoteEngineError instanceof RemoteErrors.CannotConnectError: + return new RemoteErr.CannotConnectError(remoteEngineError.message); + case remoteEngineError instanceof RemoteErrors.HTTPError401AuthorizationRequired: + return new RemoteErr.HTTPError401AuthorizationRequired(remoteEngineError.message); + case remoteEngineError instanceof RemoteErrors.HTTPError403Forbidden: + return new RemoteErr.HTTPError403Forbidden(remoteEngineError.message); + case remoteEngineError instanceof RemoteErrors.HTTPError404NotFound: + return new RemoteErr.HTTPError404NotFound(remoteEngineError.message); + case remoteEngineError instanceof RemoteErrors.InvalidAuthenticationTypeError: + return new RemoteErr.InvalidAuthenticationTypeError(remoteEngineError.message); + case remoteEngineError instanceof RemoteErrors.InvalidGitRemoteError: + return new RemoteErr.InvalidGitRemoteError(remoteEngineError.message); + case remoteEngineError instanceof RemoteErrors.InvalidRepositoryURLError: + return new RemoteErr.InvalidRepositoryURLError(remoteEngineError.message); + case remoteEngineError instanceof RemoteErrors.InvalidSSHKeyPathError: + return new RemoteErr.InvalidSSHKeyPathError(); + case remoteEngineError instanceof RemoteErrors.InvalidURLFormatError: + return new RemoteErr.InvalidURLFormatError(remoteEngineError.message); + case remoteEngineError instanceof RemoteErrors.NetworkError: + return new RemoteErr.NetworkError(remoteEngineError.message); + case remoteEngineError instanceof RemoteErrors.UnfetchedCommitExistsError: + return new RemoteErr.UnfetchedCommitExistsError(); + default: + return new Error(remoteEngineError.message); + } +} diff --git a/src/remote/remote_repository.ts b/src/remote/remote_repository.ts index 3df483cd..1a35066f 100644 --- a/src/remote/remote_repository.ts +++ b/src/remote/remote_repository.ts @@ -24,8 +24,6 @@ export class RemoteRepository { /** * Constructor * - * @throws {@link Err.InvalidAuthenticationTypeError} - * * @public */ constructor (options: RemoteOptions) { @@ -46,9 +44,6 @@ export class RemoteRepository { else if (this._options.connection.type === 'none') { // nop } - else { - throw new Err.InvalidAuthenticationTypeError(this._options.connection.type); - } } /** diff --git a/src/remote/sync.ts b/src/remote/sync.ts index 4d496ad9..23437a57 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -12,6 +12,7 @@ import { clearInterval, setInterval } from 'timers'; import git from 'isomorphic-git'; import fs from 'fs-extra'; +import * as RemoteEngineError from 'git-documentdb-remote-errors'; import { CONSOLE_STYLE, sleep } from '../utils'; import { Err } from '../error'; import { @@ -54,7 +55,8 @@ import { JsonDiff } from './json_diff'; import { JsonPatchOT } from './json_patch_ot'; import { combineDatabaseWithTheirs } from './combine'; import { Validator } from '../validator'; -import { RemoteEngine, RemoteErr } from './remote_engine'; +import { RemoteEngine, RemoteErr, wrappingRemoteEngineError } from './remote_engine'; +import { NetworkError } from 'git-documentdb-remote-errors'; /** * Implementation of GitDocumentDB#sync(options, get_sync_result) @@ -388,22 +390,46 @@ export class Sync implements SyncInterface { async init (): Promise { this._isClosed = false; - const onlyFetch = this._options.syncDirection === 'pull'; - - const remoteResult: boolean | Error = await RemoteEngine[this._engine] - .checkFetch(this._gitDDB.workingDir, this._options, undefined, this._gitDDB.logger) - .catch(err => err); + for (let i = 0; i < NETWORK_RETRY; i++) { + // eslint-disable-next-line no-await-in-loop + const remoteResult: boolean | Error = await RemoteEngine[this._engine] + .checkFetch(this._gitDDB.workingDir, this._options, undefined, this._gitDDB.logger) + .catch(err => err); - if (typeof remoteResult === 'boolean') { - // nop - } - else if (remoteResult instanceof RemoteErr.CannotConnectError) { - // Try to create repository by octokit - await this.remoteRepository.create().catch(err => { - // App may check permission or - throw new Err.CannotCreateRemoteRepositoryError(err.message); - }); - this._upstreamBranch = ''; + if (typeof remoteResult === 'boolean') { + break; + } + else if ( + remoteResult instanceof RemoteEngineError.InvalidURLFormatError || + remoteResult instanceof RemoteEngineError.InvalidRepositoryURLError || + remoteResult instanceof RemoteEngineError.InvalidSSHKeyPathError || + remoteResult instanceof RemoteEngineError.InvalidAuthenticationTypeError || + remoteResult instanceof RemoteEngineError.HTTPError401AuthorizationRequired + ) { + throw wrappingRemoteEngineError(remoteResult); + } + else if ( + remoteResult instanceof RemoteEngineError.NetworkError || + remoteResult instanceof RemoteEngineError.CannotConnectError + ) { + if (i === NETWORK_RETRY - 1) { + throw wrappingRemoteEngineError(remoteResult); + } + else { + // eslint-disable-next-line no-await-in-loop + await sleep(NETWORK_RETRY_INTERVAL); + continue; + } + } + else if (remoteResult instanceof RemoteErr.HTTPError404NotFound) { + // Try to create repository by octokit + // eslint-disable-next-line no-await-in-loop + await this.remoteRepository.create().catch(err => { + throw new Err.CannotCreateRemoteRepositoryError(err.message); + }); + this._upstreamBranch = ''; + break; + } } let syncResult: SyncResult = { diff --git a/src/remote/sync_worker.ts b/src/remote/sync_worker.ts index 54083adb..0c2b28e7 100644 --- a/src/remote/sync_worker.ts +++ b/src/remote/sync_worker.ts @@ -58,7 +58,12 @@ export async function syncWorker ( /** * Fetch */ - await RemoteEngine[sync.engine].fetch(gitDDB.workingDir, sync.options, gitDDB.logger); + await RemoteEngine[sync.engine].fetch( + gitDDB.workingDir, + sync.options, + undefined, + gitDDB.logger + ); /** * Calc distance diff --git a/test/remote_base/sync.test.ts b/test/remote_base/sync.test.ts deleted file mode 100644 index 5e6aa155..00000000 --- a/test/remote_base/sync.test.ts +++ /dev/null @@ -1,413 +0,0 @@ -/* eslint-disable @typescript-eslint/naming-convention */ -/** - * GitDocumentDB - * Copyright (c) Hidekazu Kubota - * - * This source code is licensed under the Mozilla Public License Version 2.0 - * found in the LICENSE file in the root directory of this source tree. - */ - -/** - * Test constructor - * by using GitHub Personal Access Token - * These tests create a new repository on GitHub if not exists. - */ -import path from 'path'; -import fs from 'fs-extra'; -import { Octokit } from '@octokit/rest'; -import expect from 'expect'; -import { MINIMUM_SYNC_INTERVAL } from '../../src/const'; -import { GitDocumentDB } from '../../src/git_documentdb'; -import { RemoteOptions } from '../../src/types'; -import { Err } from '../../src/error'; -import { Sync, syncImpl } from '../../src/remote/sync'; -import { destroyDBs, removeRemoteRepositories } from '../remote_utils'; - -const reposPrefix = 'test_sync_constructor___'; -const localDir = `./test_intg/database_sync`; - -let idCounter = 0; -const serialId = () => { - return `${reposPrefix}${idCounter++}`; -}; - -beforeEach(function () { - // @ts-ignore - console.log(`... ${this.currentTest.fullTitle()}`); -}); - -before(() => { - // eslint-disable-next-line @typescript-eslint/no-var-requires - GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); - - fs.removeSync(path.resolve(localDir)); -}); - -after(() => { - fs.removeSync(path.resolve(localDir)); -}); - -// GITDDB_GITHUB_USER_URL: URL of your GitHub account -// e.g.) https://github.com/foo/ -const maybe = - process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN - ? describe - : describe.skip; - -maybe(' Sync#constructor()', () => { - const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') - ? process.env.GITDDB_GITHUB_USER_URL - : process.env.GITDDB_GITHUB_USER_URL + '/'; - const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; - - before(async () => { - // Remove remote - await removeRemoteRepositories(reposPrefix); - }); - - // it.only('Run this test with .only to just remove remote repositories.', async () => { await removeRemoteRepositories('test_'); }); - - /** - * Tests for constructor - */ - it('set live to false by default', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbName = serialId(); - const gitDDB: GitDocumentDB = new GitDocumentDB({ - dbName, - localDir, - }); - await gitDDB.open(); - const options: RemoteOptions = { - remoteUrl: remoteURL, - connection: { - type: 'github', - personalAccessToken: token, - }, - }; - const sync = new Sync(gitDDB, options); - expect(sync.options.live).toBe(false); - - destroyDBs([gitDDB]); - }); - - it('set syncDirection to both by default', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbName = serialId(); - const gitDDB: GitDocumentDB = new GitDocumentDB({ - dbName, - localDir, - }); - await gitDDB.open(); - const options: RemoteOptions = { - remoteUrl: remoteURL, - connection: { - type: 'github', - personalAccessToken: token, - }, - }; - const sync = new Sync(gitDDB, options); - expect(sync.options.syncDirection).toBe('both'); - - destroyDBs([gitDDB]); - }); - - it('set combineDbStrategy to combine-head-with-theirs by default', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbName = serialId(); - const gitDDB: GitDocumentDB = new GitDocumentDB({ - dbName, - localDir, - }); - await gitDDB.open(); - const options: RemoteOptions = { - remoteUrl: remoteURL, - connection: { - type: 'github', - personalAccessToken: token, - }, - }; - const sync = new Sync(gitDDB, options); - expect(sync.options.combineDbStrategy).toBe('combine-head-with-theirs'); - - destroyDBs([gitDDB]); - }); - - it('set includeCommits to false by default', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbName = serialId(); - const gitDDB: GitDocumentDB = new GitDocumentDB({ - dbName, - localDir, - }); - await gitDDB.open(); - const options: RemoteOptions = { - remoteUrl: remoteURL, - connection: { - type: 'github', - personalAccessToken: token, - }, - }; - const sync = new Sync(gitDDB, options); - expect(sync.options.includeCommits).toBe(false); - - destroyDBs([gitDDB]); - }); - - it('set conflictResolutionStrategy to ours-diff by default', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbName = serialId(); - const gitDDB: GitDocumentDB = new GitDocumentDB({ - dbName, - localDir, - }); - await gitDDB.open(); - const options: RemoteOptions = { - remoteUrl: remoteURL, - connection: { - type: 'github', - personalAccessToken: token, - }, - }; - const sync = new Sync(gitDDB, options); - expect(sync.options.conflictResolutionStrategy).toBe('ours-diff'); - - destroyDBs([gitDDB]); - }); - - it('accepts remoteURL which ends with .git', async () => { - const remoteURL = remoteURLBase + serialId() + '.git'; - const dbName = serialId(); - const gitDDB: GitDocumentDB = new GitDocumentDB({ - dbName, - localDir, - }); - await gitDDB.open(); - const options: RemoteOptions = { - remoteUrl: remoteURL, - connection: { - type: 'github', - personalAccessToken: token, - }, - }; - expect(() => new Sync(gitDDB, options)).not.toThrowError(); - - destroyDBs([gitDDB]); - }); - - it('throws UndefinedRemoteURLError when remoteURL is undefined.', async () => { - const dbName = serialId(); - const gitDDB: GitDocumentDB = new GitDocumentDB({ - dbName, - localDir, - }); - await gitDDB.open(); - const options: RemoteOptions = { - connection: { - type: 'github', - personalAccessToken: '', - }, - }; - expect(() => new Sync(gitDDB, options)).toThrowError(Err.UndefinedRemoteURLError); - await gitDDB.destroy(); - }); - - it('throws IntervalTooSmallError when interval is less than minimumSyncInterval.', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbName = serialId(); - const gitDDB: GitDocumentDB = new GitDocumentDB({ - dbName, - localDir, - }); - await gitDDB.open(); - const invalid_options: RemoteOptions = { - remoteUrl: remoteURL, - interval: MINIMUM_SYNC_INTERVAL - 1, - connection: { - type: 'github', - personalAccessToken: '', - }, - }; - expect(() => new Sync(gitDDB, invalid_options)).toThrowError(Err.IntervalTooSmallError); - await gitDDB.destroy(); - - await gitDDB.open(); - const valid_options: RemoteOptions = { - remoteUrl: remoteURL, - interval: MINIMUM_SYNC_INTERVAL, - connection: { - type: 'github', - personalAccessToken: token, - }, - }; - expect(() => new Sync(gitDDB, valid_options)).not.toThrowError(); - - await gitDDB.destroy(); - }); - - it('throws SyncIntervalLessThanOrEqualToRetryIntervalError', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbName = serialId(); - const gitDDB: GitDocumentDB = new GitDocumentDB({ - dbName, - localDir, - }); - await gitDDB.open(); - const retryInterval = 5000; - const options: RemoteOptions = { - remoteUrl: remoteURL, - interval: retryInterval - 1, - retryInterval, - connection: { - type: 'github', - personalAccessToken: token, - }, - }; - // less than - expect(() => new Sync(gitDDB, options)).toThrowError( - Err.SyncIntervalLessThanOrEqualToRetryIntervalError - ); - await gitDDB.destroy(); - - // equal to - await gitDDB.open(); - options.interval = retryInterval; - expect(() => new Sync(gitDDB, options)).toThrowError( - Err.SyncIntervalLessThanOrEqualToRetryIntervalError - ); - await gitDDB.destroy(); - - // more than - await gitDDB.open(); - // eslint-disable-next-line require-atomic-updates - options.interval = retryInterval + 1; - expect(() => new Sync(gitDDB, options)).not.toThrowError(); - - await gitDDB.destroy(); - }); -}); - -maybe(' init()', () => { - const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') - ? process.env.GITDDB_GITHUB_USER_URL - : process.env.GITDDB_GITHUB_USER_URL + '/'; - const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; - - before(async () => { - // Remove remote - await removeRemoteRepositories(reposPrefix); - }); - - it('throws RemoteCheckFetchError.', async () => { - const dbName = serialId(); - const remoteURL = - 'https://github.com/sosuisen/foobar_test_for_remote_repository_connect_error'; - const gitDDB: GitDocumentDB = new GitDocumentDB({ - dbName, - localDir, - }); - await gitDDB.open(); - const options: RemoteOptions = { - remoteUrl: remoteURL, - connection: { - type: 'github', - personalAccessToken: 'foo', - }, - }; - const sync = new Sync(gitDDB, options); - // - await expect(sync.init()).rejects.toThrowError(Err.RemoteCheckFetchError); - await gitDDB.destroy(); - }); -}); - -maybe(' syncImpl()', () => { - const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') - ? process.env.GITDDB_GITHUB_USER_URL - : process.env.GITDDB_GITHUB_USER_URL + '/'; - const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; - - before(async () => { - // Remove remote - await removeRemoteRepositories(reposPrefix); - }); - - it('throws RemoteCheckFetchError.', async () => { - const dbName = serialId(); - const remoteURL = remoteURLBase + serialId(); - const gitDDB: GitDocumentDB = new GitDocumentDB({ - dbName, - localDir, - }); - await expect( - syncImpl.call(gitDDB, { - remoteUrl: remoteURL, - connection: { type: 'github', personalAccessToken: token }, - }) - ).rejects.toThrowError(Err.RemoteCheckFetchError); - await gitDDB.destroy(); - }); - - it('creates a remote repository on GitHub by using personal access token', async () => { - const remoteURL = remoteURLBase + serialId(); - - const dbNameA = serialId(); - - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, - }); - const options: RemoteOptions = { - remoteUrl: remoteURL, - connection: { type: 'github', personalAccessToken: token }, - }; - await dbA.open(); - // Check dbInfo - await dbA.sync(options); - - // Check remote - const octokit = new Octokit({ - auth: token, - }); - const urlArray = remoteURL.split('/'); - const owner = urlArray[urlArray.length - 2]; - const repo = urlArray[urlArray.length - 1]; - await expect(octokit.repos.listBranches({ owner, repo })).resolves.not.toThrowError(); - - destroyDBs([dbA]); - }); -}); - -maybe(' tryPush()', () => { - const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') - ? process.env.GITDDB_GITHUB_USER_URL - : process.env.GITDDB_GITHUB_USER_URL + '/'; - const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; - - before(async () => { - // Remove remote - await removeRemoteRepositories(reposPrefix); - }); - - it('throws PushNotAllowedError.', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbName = serialId(); - const gitDDB: GitDocumentDB = new GitDocumentDB({ - dbName, - localDir, - }); - await gitDDB.open(); - const options: RemoteOptions = { - remoteUrl: remoteURL, - connection: { - type: 'github', - personalAccessToken: token, - }, - syncDirection: 'pull', - }; - const sync = new Sync(gitDDB, options); - await await expect(sync.init()).rejects.toThrowError(Err.PushNotAllowedError); - - destroyDBs([gitDDB]); - }); -}); diff --git a/test/remote_base/sync.ts b/test/remote_base/sync.ts new file mode 100644 index 00000000..f0c960fe --- /dev/null +++ b/test/remote_base/sync.ts @@ -0,0 +1,445 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +/** + * Test constructor + * by using GitHub Personal Access Token + * These tests create a new repository on GitHub if not exists. + */ +import { relative } from 'path'; +import { Octokit } from '@octokit/rest'; +import expect from 'expect'; +import sinon from 'sinon'; +import * as RemoteEngineErr from 'git-documentdb-remote-errors'; +import { MINIMUM_SYNC_INTERVAL } from '../../src/const'; +import { GitDocumentDB } from '../../src/git_documentdb'; +import { ConnectionSettings, RemoteOptions } from '../../src/types'; +import { Err } from '../../src/error'; +import { Sync, syncImpl } from '../../src/remote/sync'; +import { destroyDBs, removeRemoteRepositories } from '../remote_utils'; +import { RemoteErr } from '../../src/remote/remote_engine'; +// eslint-disable-next-line @typescript-eslint/no-var-requires +const remote_nodegit_module = require('git-documentdb-plugin-remote-nodegit'); + +export const syncBase = ( + connection: ConnectionSettings, + remoteURLBase: string, + reposPrefix: string, + localDir: string, + token: string +) => () => { + let idCounter = 0; + const serialId = () => { + return `${reposPrefix}${idCounter++}`; + }; + + // Use sandbox to restore stub and spy in parallel mocha tests + let sandbox: sinon.SinonSandbox; + beforeEach(function () { + sandbox = sinon.createSandbox(); + }); + + afterEach(function () { + sandbox.restore(); + }); + + before(async () => { + // Remove remote + await removeRemoteRepositories(reposPrefix); + }); + + /** + * Tests for constructor + */ + describe(' constructor', () => { + it('set live to false by default', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbName = serialId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + }); + await gitDDB.open(); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection, + }; + const sync = new Sync(gitDDB, options); + expect(sync.options.live).toBe(false); + + destroyDBs([gitDDB]); + }); + + it('set syncDirection to both by default', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbName = serialId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + }); + await gitDDB.open(); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection, + }; + const sync = new Sync(gitDDB, options); + expect(sync.options.syncDirection).toBe('both'); + + destroyDBs([gitDDB]); + }); + + it('set combineDbStrategy to combine-head-with-theirs by default', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbName = serialId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + }); + await gitDDB.open(); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection, + }; + const sync = new Sync(gitDDB, options); + expect(sync.options.combineDbStrategy).toBe('combine-head-with-theirs'); + + destroyDBs([gitDDB]); + }); + + it('set includeCommits to false by default', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbName = serialId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + }); + await gitDDB.open(); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection, + }; + const sync = new Sync(gitDDB, options); + expect(sync.options.includeCommits).toBe(false); + + destroyDBs([gitDDB]); + }); + + it('set conflictResolutionStrategy to ours-diff by default', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbName = serialId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + }); + await gitDDB.open(); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection, + }; + const sync = new Sync(gitDDB, options); + expect(sync.options.conflictResolutionStrategy).toBe('ours-diff'); + + destroyDBs([gitDDB]); + }); + + it('accepts remoteURL which ends with .git', async () => { + const remoteURL = remoteURLBase + serialId() + '.git'; + const dbName = serialId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + }); + await gitDDB.open(); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection, + }; + expect(() => new Sync(gitDDB, options)).not.toThrowError(); + + destroyDBs([gitDDB]); + }); + + it('throws UndefinedRemoteURLError when remoteURL is undefined.', async () => { + const dbName = serialId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + }); + await gitDDB.open(); + const options: RemoteOptions = { + connection: { + type: 'github', + personalAccessToken: '', + }, + }; + expect(() => new Sync(gitDDB, options)).toThrowError(Err.UndefinedRemoteURLError); + await gitDDB.destroy(); + }); + + it('throws IntervalTooSmallError when interval is less than minimumSyncInterval.', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbName = serialId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + }); + await gitDDB.open(); + const invalid_options: RemoteOptions = { + remoteUrl: remoteURL, + interval: MINIMUM_SYNC_INTERVAL - 1, + connection: { + type: 'github', + personalAccessToken: '', + }, + }; + expect(() => new Sync(gitDDB, invalid_options)).toThrowError( + Err.IntervalTooSmallError + ); + await gitDDB.destroy(); + + await gitDDB.open(); + const valid_options: RemoteOptions = { + remoteUrl: remoteURL, + interval: MINIMUM_SYNC_INTERVAL, + connection, + }; + expect(() => new Sync(gitDDB, valid_options)).not.toThrowError(); + + await gitDDB.destroy(); + }); + + it('throws SyncIntervalLessThanOrEqualToRetryIntervalError', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbName = serialId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + }); + await gitDDB.open(); + const retryInterval = 5000; + const options: RemoteOptions = { + remoteUrl: remoteURL, + interval: retryInterval - 1, + retryInterval, + connection, + }; + // less than + expect(() => new Sync(gitDDB, options)).toThrowError( + Err.SyncIntervalLessThanOrEqualToRetryIntervalError + ); + await gitDDB.destroy(); + + // equal to + await gitDDB.open(); + options.interval = retryInterval; + expect(() => new Sync(gitDDB, options)).toThrowError( + Err.SyncIntervalLessThanOrEqualToRetryIntervalError + ); + await gitDDB.destroy(); + + // more than + await gitDDB.open(); + // eslint-disable-next-line require-atomic-updates + options.interval = retryInterval + 1; + expect(() => new Sync(gitDDB, options)).not.toThrowError(); + + await gitDDB.destroy(); + }); + }); + + describe.only(' init()', () => { + it('throws RemoteErr.InvalidURLFormatError.', async () => { + const dbName = serialId(); + const remoteURL = remoteURLBase + serialId; + + const stubCheckFetch = sandbox.stub(remote_nodegit_module, 'checkFetch'); + stubCheckFetch.onFirstCall().rejects(new RemoteEngineErr.InvalidURLFormatError('')); + + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + }); + await gitDDB.open(); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection, + }; + const sync = new Sync(gitDDB, options); + await expect(sync.init()).rejects.toThrowError(RemoteErr.InvalidURLFormatError); + await gitDDB.destroy(); + }); + + it('throws RemoteErr.InvalidRepositoryURLError.', async () => { + const dbName = serialId(); + const remoteURL = remoteURLBase + serialId; + + const stubCheckFetch = sandbox.stub(remote_nodegit_module, 'checkFetch'); + stubCheckFetch + .onFirstCall() + .rejects(new RemoteEngineErr.InvalidRepositoryURLError('')); + + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + }); + await gitDDB.open(); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection, + }; + const sync = new Sync(gitDDB, options); + await expect(sync.init()).rejects.toThrowError(RemoteErr.InvalidRepositoryURLError); + await gitDDB.destroy(); + }); + + it('throws RemoteErr.InvalidSSHKeyPathError.', async () => { + const dbName = serialId(); + const remoteURL = remoteURLBase + serialId; + + const stubCheckFetch = sandbox.stub(remote_nodegit_module, 'checkFetch'); + stubCheckFetch.onFirstCall().rejects(new RemoteEngineErr.InvalidSSHKeyPathError()); + + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + }); + await gitDDB.open(); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection, + }; + const sync = new Sync(gitDDB, options); + await expect(sync.init()).rejects.toThrowError(RemoteErr.InvalidSSHKeyPathError); + await gitDDB.destroy(); + }); + + it('throws RemoteErr.InvalidAuthenticationTypeError.', async () => { + const dbName = serialId(); + const remoteURL = remoteURLBase + serialId; + + const stubCheckFetch = sandbox.stub(remote_nodegit_module, 'checkFetch'); + stubCheckFetch + .onFirstCall() + .rejects(new RemoteEngineErr.InvalidAuthenticationTypeError('')); + + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + }); + await gitDDB.open(); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection, + }; + const sync = new Sync(gitDDB, options); + await expect(sync.init()).rejects.toThrowError( + RemoteErr.InvalidAuthenticationTypeError + ); + await gitDDB.destroy(); + }); + + it('throws RemoteErr.HTTPError401AuthorizationRequired.', async () => { + const dbName = serialId(); + const remoteURL = remoteURLBase + serialId; + + const stubCheckFetch = sandbox.stub(remote_nodegit_module, 'checkFetch'); + stubCheckFetch + .onFirstCall() + .rejects(new RemoteEngineErr.HTTPError401AuthorizationRequired('')); + + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + }); + await gitDDB.open(); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection, + }; + const sync = new Sync(gitDDB, options); + await expect(sync.init()).rejects.toThrowError( + RemoteErr.HTTPError401AuthorizationRequired + ); + await gitDDB.destroy(); + }); + }); + + describe(' syncImpl()', () => { + it('throws RemoteCheckFetchError.', async () => { + const dbName = serialId(); + const remoteURL = remoteURLBase + serialId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + }); + await expect( + syncImpl.call(gitDDB, { + remoteUrl: remoteURL, + connection: { type: 'github', personalAccessToken: token }, + }) + ).rejects.toThrowError(RemoteErr.InvalidURLFormatError); + await gitDDB.destroy(); + }); + + it('creates a remote repository on GitHub by using personal access token', async () => { + const remoteURL = remoteURLBase + serialId(); + + const dbNameA = serialId(); + + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection: { type: 'github', personalAccessToken: token }, + }; + await dbA.open(); + // Check dbInfo + await dbA.sync(options); + + // Check remote + const octokit = new Octokit({ + auth: token, + }); + const urlArray = remoteURL.split('/'); + const owner = urlArray[urlArray.length - 2]; + const repo = urlArray[urlArray.length - 1]; + await expect(octokit.repos.listBranches({ owner, repo })).resolves.not.toThrowError(); + + destroyDBs([dbA]); + }); + }); + + describe(' tryPush()', () => { + before(async () => { + // Remove remote + await removeRemoteRepositories(reposPrefix); + }); + + it('throws PushNotAllowedError.', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbName = serialId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + }); + await gitDDB.open(); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection, + syncDirection: 'pull', + }; + const sync = new Sync(gitDDB, options); + // await await expect(sync.init()).rejects.toThrowError(Err.PushNotAllowedError); + + destroyDBs([gitDDB]); + }); + }); +}; diff --git a/test/remote_base/sync_trypush.ts b/test/remote_base/sync_trypush.ts index 76ee4f8f..f6ffb40c 100644 --- a/test/remote_base/sync_trypush.ts +++ b/test/remote_base/sync_trypush.ts @@ -27,7 +27,7 @@ import { import { ConnectionSettings, SyncResultCancel, SyncResultPush } from '../../src/types'; import { sleep } from '../../src/utils'; -export const syncTryPush = ( +export const syncTryPushBase = ( connection: ConnectionSettings, remoteURLBase: string, reposPrefix: string, @@ -42,347 +42,349 @@ export const syncTryPush = ( await removeRemoteRepositories(reposPrefix); }); - /** - * before: - * dbA : +jsonA1 - * after : jsonA1 - */ - it('changes one remote creation when pushes after one put()', async function () { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, + describe(': Sync#tryPush()', () => { + /** + * before: + * dbA : +jsonA1 + * after : jsonA1 + */ + it('changes one remote creation when pushes after one put()', async function () { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, + }); + + // Put and push + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResult = await dbA.put(jsonA1); + const syncResult = await syncA.tryPush(); + expect(syncResult.action).toBe('push'); + if (syncResult.action !== 'push') { + // Check discriminated union + return; + } + expect(syncResult.commits).toMatchObject({ + remote: getCommitInfo([putResult]), + }); + + // One remote creation + expect(syncResult.changes.remote.length).toBe(1); + expect(syncResult.changes.remote).toEqual([getChangedFileInsert(jsonA1, putResult)]); + + expect(getWorkingDirDocs(dbA)).toEqual([jsonA1]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + + await destroyDBs([dbA]); }); - // Put and push - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResult = await dbA.put(jsonA1); - const syncResult = await syncA.tryPush(); - expect(syncResult.action).toBe('push'); - if (syncResult.action !== 'push') { - // Check discriminated union - return; - } - expect(syncResult.commits).toMatchObject({ - remote: getCommitInfo([putResult]), + /** + * before: jsonA1 + * dbA : +jsonA1 + * after : jsonA1 + */ + it('does not change remote when pushes after put() the same document again', async function () { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, + }); + const jsonA1 = { _id: '1', name: 'fromA' }; + await dbA.put(jsonA1); + await syncA.tryPush(); + + // This document is same as the previous document + // while put() creates a new commit. + // (This is valid behavior of put() API.) + const putResult = await dbA.put(jsonA1); + const syncResult = await syncA.tryPush(); + expect(syncResult.action).toBe('push'); + if (syncResult.action !== 'push') { + // Check discriminated union + return; + } + + expect(syncResult.commits).toMatchObject({ + remote: getCommitInfo([putResult]), + }); + + // Does not change remote + expect(syncResult.changes.remote.length).toBe(0); + + expect(getWorkingDirDocs(dbA)).toEqual([jsonA1]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + + await destroyDBs([dbA]); }); - // One remote creation - expect(syncResult.changes.remote.length).toBe(1); - expect(syncResult.changes.remote).toEqual([getChangedFileInsert(jsonA1, putResult)]); - - expect(getWorkingDirDocs(dbA)).toEqual([jsonA1]); - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - - await destroyDBs([dbA]); - }); - - /** - * before: jsonA1 - * dbA : +jsonA1 - * after : jsonA1 - */ - it('does not change remote when pushes after put() the same document again', async function () { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, - }); - const jsonA1 = { _id: '1', name: 'fromA' }; - await dbA.put(jsonA1); - await syncA.tryPush(); - - // This document is same as the previous document - // while put() creates a new commit. - // (This is valid behavior of put() API.) - const putResult = await dbA.put(jsonA1); - const syncResult = await syncA.tryPush(); - expect(syncResult.action).toBe('push'); - if (syncResult.action !== 'push') { - // Check discriminated union - return; - } - - expect(syncResult.commits).toMatchObject({ - remote: getCommitInfo([putResult]), - }); - - // Does not change remote - expect(syncResult.changes.remote.length).toBe(0); - - expect(getWorkingDirDocs(dbA)).toEqual([jsonA1]); - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - - await destroyDBs([dbA]); - }); - - /** - * before: jsonA1 - * dbA : +jsonA1 - * after : jsonA1 - */ - it('changes one remote update when pushes after put() updated document', async function () { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, - }); - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResultA1 = await dbA.put(jsonA1); - await syncA.tryPush(); - - // Put and push an updated document - const jsonA1dash = { _id: '1', name: 'updated' }; - const putResult = await dbA.put(jsonA1dash); - const syncResult = await syncA.tryPush(); - expect(syncResult.action).toBe('push'); - if (syncResult.action !== 'push') { - // Check discriminated union - return; - } - - expect(syncResult.commits).toMatchObject({ - remote: getCommitInfo([putResult]), - }); - - // One remote update - expect(syncResult.changes.remote.length).toBe(1); - expect(syncResult.changes.remote[0]).toMatchObject( - getChangedFileUpdate(jsonA1, putResultA1, jsonA1dash, putResult) - ); - - expect(getWorkingDirDocs(dbA)).toEqual([jsonA1dash]); - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - - await destroyDBs([dbA]); - }); - - /** - * before: jsonA1 - * dbA : +jsonA2 - * after : jsonA1 jsonA2 - */ - it('changes one remote creation when pushes after put() another document', async function () { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, - }); - const jsonA1 = { _id: '1', name: 'fromA' }; - await dbA.put(jsonA1); - await syncA.tryPush(); - - // Put and push another document - const jsonA2 = { _id: '2', name: 'fromA' }; - const putResultA2 = await dbA.put(jsonA2); - const syncResult = await syncA.tryPush(); - expect(syncResult.action).toBe('push'); - if (syncResult.action !== 'push') { - // Check discriminated union - return; - } - - expect(syncResult.commits).toMatchObject({ - remote: getCommitInfo([putResultA2]), - }); - - // One remote creation - expect(syncResult.changes.remote.length).toBe(1); - expect(syncResult.changes.remote[0]).toMatchObject( - getChangedFileInsert(jsonA2, putResultA2) - ); - - expect(getWorkingDirDocs(dbA)).toEqual([jsonA1, jsonA2]); - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - - await destroyDBs([dbA]); - }); - - /** - * before: - * dbA : +jsonA1 +jsonA2 - * after1: jsonA1 jsonA2 - * dbA : +jsonA1 +jsonA3 - * after2: jsonA1 jsonA2 jsonA3 - */ - it('changes two remote creations when pushes after put() two documents', async function () { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, + /** + * before: jsonA1 + * dbA : +jsonA1 + * after : jsonA1 + */ + it('changes one remote update when pushes after put() updated document', async function () { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, + }); + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResultA1 = await dbA.put(jsonA1); + await syncA.tryPush(); + + // Put and push an updated document + const jsonA1dash = { _id: '1', name: 'updated' }; + const putResult = await dbA.put(jsonA1dash); + const syncResult = await syncA.tryPush(); + expect(syncResult.action).toBe('push'); + if (syncResult.action !== 'push') { + // Check discriminated union + return; + } + + expect(syncResult.commits).toMatchObject({ + remote: getCommitInfo([putResult]), + }); + + // One remote update + expect(syncResult.changes.remote.length).toBe(1); + expect(syncResult.changes.remote[0]).toMatchObject( + getChangedFileUpdate(jsonA1, putResultA1, jsonA1dash, putResult) + ); + + expect(getWorkingDirDocs(dbA)).toEqual([jsonA1dash]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + + await destroyDBs([dbA]); }); - // Two put commands and push - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResult1 = await dbA.put(jsonA1); - const jsonA2 = { _id: '2', name: 'fromA' }; - const putResult2 = await dbA.put(jsonA2); - const syncResult = await syncA.tryPush(); - expect(syncResult.action).toBe('push'); - if (syncResult.action !== 'push') { - // Check discriminated union - return; - } - - expect(syncResult.commits).toMatchObject({ - remote: getCommitInfo([putResult1, putResult2]), + /** + * before: jsonA1 + * dbA : +jsonA2 + * after : jsonA1 jsonA2 + */ + it('changes one remote creation when pushes after put() another document', async function () { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, + }); + const jsonA1 = { _id: '1', name: 'fromA' }; + await dbA.put(jsonA1); + await syncA.tryPush(); + + // Put and push another document + const jsonA2 = { _id: '2', name: 'fromA' }; + const putResultA2 = await dbA.put(jsonA2); + const syncResult = await syncA.tryPush(); + expect(syncResult.action).toBe('push'); + if (syncResult.action !== 'push') { + // Check discriminated union + return; + } + + expect(syncResult.commits).toMatchObject({ + remote: getCommitInfo([putResultA2]), + }); + + // One remote creation + expect(syncResult.changes.remote.length).toBe(1); + expect(syncResult.changes.remote[0]).toMatchObject( + getChangedFileInsert(jsonA2, putResultA2) + ); + + expect(getWorkingDirDocs(dbA)).toEqual([jsonA1, jsonA2]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + + await destroyDBs([dbA]); }); - // Two remote creations - expect(syncResult.changes.remote.length).toBe(2); - expect(syncResult.changes.remote).toEqual([ - getChangedFileInsert(jsonA1, putResult1), - getChangedFileInsert(jsonA2, putResult2), - ]); - - expect(getWorkingDirDocs(dbA)).toEqual([jsonA1, jsonA2]); - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - - await destroyDBs([dbA]); - }); - - /** - * before: jsonA1 - * dbA : +jsonA1 jsonA2 - * after : +jsonA1 jsonA2 - */ - it('changes one remote creation and one remote update when pushes after put() updated document and another document', async function () { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, + /** + * before: + * dbA : +jsonA1 +jsonA2 + * after1: jsonA1 jsonA2 + * dbA : +jsonA1 +jsonA3 + * after2: jsonA1 jsonA2 jsonA3 + */ + it('changes two remote creations when pushes after put() two documents', async function () { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, + }); + + // Two put commands and push + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResult1 = await dbA.put(jsonA1); + const jsonA2 = { _id: '2', name: 'fromA' }; + const putResult2 = await dbA.put(jsonA2); + const syncResult = await syncA.tryPush(); + expect(syncResult.action).toBe('push'); + if (syncResult.action !== 'push') { + // Check discriminated union + return; + } + + expect(syncResult.commits).toMatchObject({ + remote: getCommitInfo([putResult1, putResult2]), + }); + + // Two remote creations + expect(syncResult.changes.remote.length).toBe(2); + expect(syncResult.changes.remote).toEqual([ + getChangedFileInsert(jsonA1, putResult1), + getChangedFileInsert(jsonA2, putResult2), + ]); + + expect(getWorkingDirDocs(dbA)).toEqual([jsonA1, jsonA2]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + + await destroyDBs([dbA]); }); - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResult1 = await dbA.put(jsonA1); - await syncA.tryPush(); - - const jsonA1dash = { _id: '1', name: 'updated' }; - const putResult1dash = await dbA.put(jsonA1dash); - const jsonA2 = { _id: '2', name: 'fromA' }; - const putResult2 = await dbA.put(jsonA2); - const syncResult = await syncA.tryPush(); - expect(syncResult.action).toBe('push'); - if (syncResult.action !== 'push') { - // Check discriminated union - return; - } - - expect(syncResult.commits).toMatchObject({ - remote: getCommitInfo([putResult1dash, putResult2]), + /** + * before: jsonA1 + * dbA : +jsonA1 jsonA2 + * after : +jsonA1 jsonA2 + */ + it('changes one remote creation and one remote update when pushes after put() updated document and another document', async function () { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, + }); + + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResult1 = await dbA.put(jsonA1); + await syncA.tryPush(); + + const jsonA1dash = { _id: '1', name: 'updated' }; + const putResult1dash = await dbA.put(jsonA1dash); + const jsonA2 = { _id: '2', name: 'fromA' }; + const putResult2 = await dbA.put(jsonA2); + const syncResult = await syncA.tryPush(); + expect(syncResult.action).toBe('push'); + if (syncResult.action !== 'push') { + // Check discriminated union + return; + } + + expect(syncResult.commits).toMatchObject({ + remote: getCommitInfo([putResult1dash, putResult2]), + }); + + // One remote update and one remote creation + expect(syncResult.changes.remote.length).toBe(2); + expect(syncResult.changes.remote).toEqual([ + getChangedFileUpdate(jsonA1, putResult1, jsonA1dash, putResult1dash), + getChangedFileInsert(jsonA2, putResult2), + ]); + + expect(getWorkingDirDocs(dbA)).toEqual([jsonA1dash, jsonA2]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + + await destroyDBs([dbA]); }); - // One remote update and one remote creation - expect(syncResult.changes.remote.length).toBe(2); - expect(syncResult.changes.remote).toEqual([ - getChangedFileUpdate(jsonA1, putResult1, jsonA1dash, putResult1dash), - getChangedFileInsert(jsonA2, putResult2), - ]); + /** + * before: jsonA1 + * dbA : -jsonA1 + * after : + */ + it('changes one remote delete when pushes after one delete()', async function () { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, + }); - expect(getWorkingDirDocs(dbA)).toEqual([jsonA1dash, jsonA2]); + const jsonA1 = { _id: '1', name: 'fromA' }; + await dbA.put(jsonA1); + await syncA.tryPush(); - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + const deleteResult1 = await dbA.delete(jsonA1); - await destroyDBs([dbA]); - }); + const syncResult1 = await syncA.tryPush(); + expect(syncResult1.action).toBe('push'); + if (syncResult1.action !== 'push') { + // Check discriminated union + return; + } - /** - * before: jsonA1 - * dbA : -jsonA1 - * after : - */ - it('changes one remote delete when pushes after one delete()', async function () { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, - }); + expect(syncResult1.commits).toMatchObject({ + remote: getCommitInfo([deleteResult1]), + }); - const jsonA1 = { _id: '1', name: 'fromA' }; - await dbA.put(jsonA1); - await syncA.tryPush(); + // One remote delete + expect(syncResult1.changes.remote.length).toBe(1); + expect(syncResult1.changes.remote).toEqual([ + getChangedFileDelete(jsonA1, deleteResult1), + ]); - const deleteResult1 = await dbA.delete(jsonA1); + expect(getWorkingDirDocs(dbA)).toEqual([]); - const syncResult1 = await syncA.tryPush(); - expect(syncResult1.action).toBe('push'); - if (syncResult1.action !== 'push') { - // Check discriminated union - return; - } + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - expect(syncResult1.commits).toMatchObject({ - remote: getCommitInfo([deleteResult1]), + await destroyDBs([dbA]); }); - // One remote delete - expect(syncResult1.changes.remote.length).toBe(1); - expect(syncResult1.changes.remote).toEqual([ - getChangedFileDelete(jsonA1, deleteResult1), - ]); - - expect(getWorkingDirDocs(dbA)).toEqual([]); - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - - await destroyDBs([dbA]); - }); - - /** - * before: - * dbA : +jsonA1 - * dbA : -jsonA1 - * after : - */ - it('does not change remote when pushes after put() and delete()', async function () { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, + /** + * before: + * dbA : +jsonA1 + * dbA : -jsonA1 + * after : + */ + it('does not change remote when pushes after put() and delete()', async function () { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, + }); + + const jsonA1 = { _id: '1', name: 'fromA' }; + // Put and delete the same document + const putResult1 = await dbA.put(jsonA1); + const deleteResult1 = await dbA.delete(jsonA1); + + const syncResult1 = await syncA.tryPush(); + expect(syncResult1.action).toBe('push'); + if (syncResult1.action !== 'push') { + // Check discriminated union + return; + } + + expect(syncResult1.commits).toMatchObject({ + remote: getCommitInfo([putResult1, deleteResult1]), + }); + + // Does not change remote + expect(syncResult1.changes.remote.length).toBe(0); + + expect(getWorkingDirDocs(dbA)).toEqual([]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + + await destroyDBs([dbA]); }); - const jsonA1 = { _id: '1', name: 'fromA' }; - // Put and delete the same document - const putResult1 = await dbA.put(jsonA1); - const deleteResult1 = await dbA.delete(jsonA1); - - const syncResult1 = await syncA.tryPush(); - expect(syncResult1.action).toBe('push'); - if (syncResult1.action !== 'push') { - // Check discriminated union - return; - } - - expect(syncResult1.commits).toMatchObject({ - remote: getCommitInfo([putResult1, deleteResult1]), + it('skips consecutive push tasks', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, + }); + + const jsonA1 = { _id: '1', name: 'fromA' }; + await dbA.put(jsonA1); + const results: (SyncResultPush | SyncResultCancel)[] = []; + for (let i = 0; i < 10; i++) { + // eslint-disable-next-line promise/catch-or-return + syncA.tryPush().then(result => results.push(result)); + } + await sleep(5000); + + const syncResultCancel: SyncResultCancel = { + action: 'canceled', + }; + // results will be include 7 or more cancels + let cancelCount = 0; + results.forEach(res => { + if (res.action === 'canceled') cancelCount++; + }); + expect(cancelCount).toBeGreaterThan(6); + + // 3 or less tryPushes will be executed + expect(dbA.taskQueue.currentStatistics().push).toBeLessThanOrEqual(3); + + await destroyDBs([dbA]); }); - - // Does not change remote - expect(syncResult1.changes.remote.length).toBe(0); - - expect(getWorkingDirDocs(dbA)).toEqual([]); - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - - await destroyDBs([dbA]); - }); - - it('skips consecutive push tasks', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, - }); - - const jsonA1 = { _id: '1', name: 'fromA' }; - await dbA.put(jsonA1); - const results: (SyncResultPush | SyncResultCancel)[] = []; - for (let i = 0; i < 10; i++) { - // eslint-disable-next-line promise/catch-or-return - syncA.tryPush().then(result => results.push(result)); - } - await sleep(5000); - - const syncResultCancel: SyncResultCancel = { - action: 'canceled', - }; - // results will be include 7 or more cancels - let cancelCount = 0; - results.forEach(res => { - if (res.action === 'canceled') cancelCount++; - }); - expect(cancelCount).toBeGreaterThan(6); - - // 3 or less tryPushes will be executed - expect(dbA.taskQueue.currentStatistics().push).toBeLessThanOrEqual(3); - - await destroyDBs([dbA]); }); }; diff --git a/test/remote_nodegit/sync.test.ts b/test/remote_nodegit/sync.test.ts new file mode 100644 index 00000000..40c0c92f --- /dev/null +++ b/test/remote_nodegit/sync.test.ts @@ -0,0 +1,61 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +/** + * Test push + * by using GitHub Personal Access Token + * These tests create a new repository on GitHub if not exists. + */ +import path from 'path'; +import fs from 'fs-extra'; +import { ConnectionSettingsGitHub } from '../../src/types'; +import { GitDocumentDB } from '../../src/git_documentdb'; +import { syncBase } from '../remote_base/sync'; + +const reposPrefix = 'test_sync_constructor_nodegit__'; +const localDir = `./test_intg/database_sync_constructor_nodegit`; + +beforeEach(function () { + // @ts-ignore + console.log(`... ${this.currentTest.fullTitle()}`); +}); + +before(() => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + + fs.removeSync(path.resolve(localDir)); +}); + +after(() => { + fs.removeSync(path.resolve(localDir)); +}); + +// This test needs environment variables: +// - GITDDB_GITHUB_USER_URL: URL of your GitHub account +// e.g.) https://github.com/foo/ +// - GITDDB_PERSONAL_ACCESS_TOKEN: A personal access token of your GitHub account +const maybe = + process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN + ? describe + : describe.skip; + +const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') + ? process.env.GITDDB_GITHUB_USER_URL + : process.env.GITDDB_GITHUB_USER_URL + '/'; + +const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; + +const connection: ConnectionSettingsGitHub = { + type: 'github', + personalAccessToken: token, + engine: 'nodegit', +}; + +maybe('NodeGit', syncBase(connection, remoteURLBase, reposPrefix, localDir, token)); diff --git a/test/remote_nodegit/sync_trypush.test.ts b/test/remote_nodegit/sync_trypush.test.ts index ae5dcdb7..aaf00fdb 100644 --- a/test/remote_nodegit/sync_trypush.test.ts +++ b/test/remote_nodegit/sync_trypush.test.ts @@ -14,7 +14,7 @@ */ import path from 'path'; import fs from 'fs-extra'; -import { syncTryPush } from '../remote_base/sync_trypush'; +import { syncTryPushBase } from '../remote_base/sync_trypush'; import { ConnectionSettingsGitHub } from '../../src/types'; import { GitDocumentDB } from '../../src/git_documentdb'; @@ -58,7 +58,4 @@ const connection: ConnectionSettingsGitHub = { engine: 'nodegit', }; -maybe( - ': Sync#tryPush()', - syncTryPush(connection, remoteURLBase, reposPrefix, localDir) -); +maybe('NodeGit', syncTryPushBase(connection, remoteURLBase, reposPrefix, localDir)); From 9bc538cd750debb46109ffd1b818cd90125824a8 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 27 Jul 2021 19:29:41 +0900 Subject: [PATCH 064/297] fix: fix message of RemoteErr --- src/crud/delete.ts | 4 +++ src/crud/find.ts | 4 +++ src/crud/get.ts | 4 +++ src/crud/history.ts | 4 +++ src/crud/put.ts | 4 +++ src/remote/remote_engine.ts | 57 ++++++++++++++++++++----------------- 6 files changed, 51 insertions(+), 26 deletions(-) diff --git a/src/crud/delete.ts b/src/crud/delete.ts index 8528728e..0de8e605 100644 --- a/src/crud/delete.ts +++ b/src/crud/delete.ts @@ -19,6 +19,7 @@ import { normalizeCommit } from '../utils'; * Implementation of delete() * * @throws {@link Err.DatabaseClosingError} + * @throws {@link Err.RepositoryNotOpenError} * @throws {@link Err.TaskCancelError} * * @throws {@link Err.UndefinedDBError} (from deleteWorker) @@ -37,6 +38,9 @@ export function deleteImpl ( if (gitDDB.isClosing) { return Promise.reject(new Err.DatabaseClosingError()); } + if (!gitDDB.isOpened) { + return Promise.reject(new Err.RepositoryNotOpenError()); + } options ??= { commitMessage: undefined, diff --git a/src/crud/find.ts b/src/crud/find.ts index 9f1004f5..5794a64f 100644 --- a/src/crud/find.ts +++ b/src/crud/find.ts @@ -27,6 +27,7 @@ import { blobToBinary, blobToJsonDoc, blobToText } from './blob'; * Implementation of find() * * @throws {@link Err.DatabaseClosingError} + * @throws {@link Err.RepositoryNotOpenError} * @throws {@link Err.InvalidJsonObjectError} */ // eslint-disable-next-line complexity @@ -40,6 +41,9 @@ export async function findImpl ( if (gitDDB.isClosing) { return Promise.reject(new Err.DatabaseClosingError()); } + if (!gitDDB.isOpened) { + return Promise.reject(new Err.RepositoryNotOpenError()); + } options ??= { descending: undefined, diff --git a/src/crud/get.ts b/src/crud/get.ts index 50d51eac..d1dcfddc 100644 --- a/src/crud/get.ts +++ b/src/crud/get.ts @@ -32,6 +32,7 @@ import { readOldBlob } from './history'; * Common implementation of get-like commands * * @throws {@link Err.DatabaseClosingError} + * @throws {@link Err.RepositoryNotOpenError} * @throws {@link Err.InvalidJsonObjectError} */ // eslint-disable-next-line complexity @@ -46,6 +47,9 @@ export async function getImpl ( if (gitDDB.isClosing) { throw new Err.DatabaseClosingError(); } + if (!gitDDB.isOpened) { + return Promise.reject(new Err.RepositoryNotOpenError()); + } options ??= { forceDocType: undefined, diff --git a/src/crud/history.ts b/src/crud/history.ts index d473a611..1945911b 100644 --- a/src/crud/history.ts +++ b/src/crud/history.ts @@ -18,6 +18,7 @@ import { blobToBinary, blobToJsonDoc, blobToText } from './blob'; * Implementation of getHistory * * @throws {@link Err.DatabaseClosingError} + * @throws {@link Err.RepositoryNotOpenError} * @throws {@link Err.InvalidJsonObjectError} (from blobToJsonDoc) */ // eslint-disable-next-line complexity @@ -32,6 +33,9 @@ export async function getHistoryImpl ( if (gitDDB.isClosing) { throw new Err.DatabaseClosingError(); } + if (!gitDDB.isOpened) { + return Promise.reject(new Err.RepositoryNotOpenError()); + } options ??= { forceDocType: undefined, diff --git a/src/crud/put.ts b/src/crud/put.ts index 63722ee3..3c82d52b 100644 --- a/src/crud/put.ts +++ b/src/crud/put.ts @@ -19,6 +19,7 @@ import { Err } from '../error'; * Common implementation of put-like commands. * * @throws {@link Err.DatabaseClosingError} + * @throws {@link Err.RepositoryNotOpenError} * @throws {@link Err.TaskCancelError} * * @throws {@link Err.UndefinedDBError} (from putWorker) @@ -41,6 +42,9 @@ export function putImpl ( if (gitDDB.isClosing) { return Promise.reject(new Err.DatabaseClosingError()); } + if (!gitDDB.isOpened) { + return Promise.reject(new Err.RepositoryNotOpenError()); + } options ??= { commitMessage: undefined, diff --git a/src/remote/remote_engine.ts b/src/remote/remote_engine.ts index 496886ba..aad8cadb 100644 --- a/src/remote/remote_engine.ts +++ b/src/remote/remote_engine.ts @@ -1,3 +1,4 @@ +/* eslint-disable unicorn/custom-error-definition */ /* eslint-disable @typescript-eslint/naming-convention */ import { Logger } from 'tslog'; import * as RemoteErrors from 'git-documentdb-remote-errors'; @@ -29,75 +30,79 @@ export interface RemoteEngineInterface { clone: ( workingDir: string, remoteOptions: RemoteOptions, + remoteName: string, logger?: Logger ) => Promise; } export namespace RemoteErr { + /** + * Copy error message from parent + */ export class CannotConnectError extends RemoteErrors.CannotConnectError { constructor (mes: unknown) { - super(mes); - this.name = 'CannotConnectError'; + super(''); + this.message = mes as string; } } export class HTTPError401AuthorizationRequired extends RemoteErrors.HTTPError401AuthorizationRequired { constructor (mes: unknown) { - super(mes); - this.name = 'HTTPError401AuthorizationRequired'; + super(''); + this.message = mes as string; } } export class HTTPError403Forbidden extends RemoteErrors.HTTPError403Forbidden { constructor (mes: unknown) { - super(mes); - this.name = 'HTTPError403Forbidden'; + super(''); + this.message = mes as string; } } export class HTTPError404NotFound extends RemoteErrors.HTTPError404NotFound { constructor (mes: unknown) { - super(mes); - this.name = 'HTTPError404NotFound'; + super(''); + this.message = mes as string; } } export class InvalidAuthenticationTypeError extends RemoteErrors.InvalidAuthenticationTypeError { - constructor (type: unknown) { - super(type); - this.name = 'InvalidAuthenticationTypeError'; + constructor (mes: unknown) { + super(''); + this.message = mes as string; } } export class InvalidGitRemoteError extends RemoteErrors.InvalidGitRemoteError { constructor (mes: unknown) { - super(mes); - this.name = 'InvalidGitRemoteError'; + super(''); + this.message = mes as string; } } export class InvalidRepositoryURLError extends RemoteErrors.InvalidRepositoryURLError { - constructor (url: unknown) { - super(url); - this.name = 'InvalidRepositoryURLError'; + constructor (mes: unknown) { + super(''); + this.message = mes as string; } } export class InvalidSSHKeyPathError extends RemoteErrors.InvalidSSHKeyPathError { - constructor () { + constructor (mes: unknown) { super(); - this.name = 'InvalidSSHKeyPathError'; + this.message = mes as string; } } export class InvalidURLFormatError extends RemoteErrors.InvalidURLFormatError { constructor (mes: unknown) { - super(mes); - this.name = 'InvalidURLFormatError'; + super(''); + this.message = mes as string; } } export class NetworkError extends RemoteErrors.NetworkError { constructor (mes: unknown) { - super(mes); - this.name = 'NetworkError'; + super(''); + this.message = mes as string; } } export class UnfetchedCommitExistsError extends RemoteErrors.UnfetchedCommitExistsError { - constructor () { + constructor (mes: unknown) { super(); - this.name = 'UnfetchedCommitExistsError'; + this.message = mes as string; } } } @@ -120,13 +125,13 @@ export function wrappingRemoteEngineError (remoteEngineError: RemoteErrors.BaseE case remoteEngineError instanceof RemoteErrors.InvalidRepositoryURLError: return new RemoteErr.InvalidRepositoryURLError(remoteEngineError.message); case remoteEngineError instanceof RemoteErrors.InvalidSSHKeyPathError: - return new RemoteErr.InvalidSSHKeyPathError(); + return new RemoteErr.InvalidSSHKeyPathError(remoteEngineError.message); case remoteEngineError instanceof RemoteErrors.InvalidURLFormatError: return new RemoteErr.InvalidURLFormatError(remoteEngineError.message); case remoteEngineError instanceof RemoteErrors.NetworkError: return new RemoteErr.NetworkError(remoteEngineError.message); case remoteEngineError instanceof RemoteErrors.UnfetchedCommitExistsError: - return new RemoteErr.UnfetchedCommitExistsError(); + return new RemoteErr.UnfetchedCommitExistsError(remoteEngineError.message); default: return new Error(remoteEngineError.message); } From dd744fde8aa8c4c0ac62fcde16c8582192ce468d Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 27 Jul 2021 19:34:49 +0900 Subject: [PATCH 065/297] fix: remove upstreamBranch and add remoteName --- src/remote/sync.ts | 51 +++++++++++++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 16 deletions(-) diff --git a/src/remote/sync.ts b/src/remote/sync.ts index 23437a57..c5f46710 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -56,7 +56,27 @@ import { JsonPatchOT } from './json_patch_ot'; import { combineDatabaseWithTheirs } from './combine'; import { Validator } from '../validator'; import { RemoteEngine, RemoteErr, wrappingRemoteEngineError } from './remote_engine'; -import { NetworkError } from 'git-documentdb-remote-errors'; + +/** + * encodeToRemoteName + * + * @internal + */ +function encodeToRemoteName (remoteURL: string) { + // encodeURIComponent does not encode period. + // Encodes period to %2E for 'path' param of git.setConfig() API. + // Use toLowerCase() because git.setConfig() automatically converts the path to lowercase. + return encodeURIComponent(remoteURL).replace(/\./g, '%2E').toLowerCase(); +} + +/** + * decodeFromRemoteName + * + * @internal + */ +function decodeFromRemoteName (remoteName: string) { + return encodeURIComponent(remoteName); +} /** * Implementation of GitDocumentDB#sync(options, get_sync_result) @@ -227,15 +247,15 @@ export class Sync implements SyncInterface { return newOptions; } - private _upstreamBranch = ''; + private _remoteName = ''; /** - * upstreamBranch + * remoteName * * @readonly * @public */ - get upstreamBranch (): string { - return this._upstreamBranch; + get remoteName (): string { + return this._remoteName; } /*********************************************** @@ -340,13 +360,13 @@ export class Sync implements SyncInterface { this.jsonDiff = new JsonDiff(gitDDB.schema.json); this.jsonPatch = new JsonPatchOT(); - this._upstreamBranch = `origin/${this._gitDDB.defaultBranch}`; - this._remoteRepository = new RemoteRepository({ remoteUrl: this._options.remoteUrl, connection: this._options.connection, }); + this._remoteName = encodeToRemoteName(this.remoteURL); + this._engine = this._options.connection?.engine ?? 'iso'; } @@ -421,13 +441,14 @@ export class Sync implements SyncInterface { continue; } } - else if (remoteResult instanceof RemoteErr.HTTPError404NotFound) { + else if (remoteResult instanceof RemoteEngineError.HTTPError404NotFound) { // Try to create repository by octokit // eslint-disable-next-line no-await-in-loop await this.remoteRepository.create().catch(err => { throw new Err.CannotCreateRemoteRepositoryError(err.message); }); - this._upstreamBranch = ''; + + isNewRemoteRepository = true; break; } } @@ -440,9 +461,8 @@ export class Sync implements SyncInterface { * TODO: Implement case when sync_direction is 'pull'. */ } - else if (this.upstreamBranch === '') { - this._gitDDB.logger.debug('upstream_branch is empty. tryPush..'); - // Empty upstream_branch shows that an empty repository has been created on a remote site. + else if (isNewRemoteRepository) { + this._gitDDB.logger.debug('upstream branch is not set yet. tryPush..'); // trySync() pushes local commits to the remote branch. syncResult = await this.tryPush(); @@ -452,7 +472,7 @@ export class Sync implements SyncInterface { fs, dir: this._gitDDB.workingDir, path: `branch.${this._gitDDB.defaultBranch}.remote`, - value: 'origin', + value: this.remoteName, }); await git.setConfig({ @@ -461,8 +481,6 @@ export class Sync implements SyncInterface { path: `branch.${this._gitDDB.defaultBranch}.merge`, value: `refs/heads/${this._gitDDB.defaultBranch}`, }); - - this._upstreamBranch = `origin/${this._gitDDB.defaultBranch}`; } else if (this._options.syncDirection === 'push') { this._gitDDB.logger.debug('upstream_branch exists. tryPush..'); @@ -699,7 +717,8 @@ export class Sync implements SyncInterface { // eslint-disable-next-line no-await-in-loop const syncResultCombineDatabase = await combineDatabaseWithTheirs( this._gitDDB, - this._options + this._options, + this.remoteName ).catch(err => { // throw new Err.CombineDatabaseError(err.message); error = new Err.CombineDatabaseError(err.message); From afb6fb4fa4543accb53e168a10f1a4dcbd5039db Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 27 Jul 2021 19:35:37 +0900 Subject: [PATCH 066/297] fix: add RepositoryNotOpenError --- src/remote/sync.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/remote/sync.ts b/src/remote/sync.ts index c5f46710..e81bb963 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -104,7 +104,9 @@ export async function syncAndGetResultImpl ( /** * Implementation of GitDocumentDB#sync(options) * - * @throws {@link Err.RepositoryNotFoundError} + * @throws {@link DatabaseClosingError} + * @throws {@link Err.RepositoryNotOpenError} + * * @throws {@link Err.UndefinedRemoteURLError} (from Sync#constructor()) * @throws {@link Err.IntervalTooSmallError} (from Sync#constructor()) * @@ -120,6 +122,13 @@ export async function syncImpl ( this: GitDDBInterface, options: RemoteOptions ): Promise { + if (this.isClosing) { + throw new Err.DatabaseClosingError(); + } + if (!this.isOpened) { + return Promise.reject(new Err.RepositoryNotOpenError()); + } + const sync = new Sync(this, options); await sync.init(); return sync; From d30378d2f038e7c59df5db9917e070588820e994 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 27 Jul 2021 19:36:13 +0900 Subject: [PATCH 067/297] fix: remove unused import --- src/remote/3way_merge.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/remote/3way_merge.ts b/src/remote/3way_merge.ts index 0663d715..5c1518c8 100644 --- a/src/remote/3way_merge.ts +++ b/src/remote/3way_merge.ts @@ -1,7 +1,7 @@ import nodePath, { basename } from 'path'; import git, { TreeEntry, WalkerEntry } from 'isomorphic-git'; import fs from 'fs-extra'; -import { DEFAULT_CONFLICT_RESOLUTION_STRATEGY, JSON_EXT } from '../const'; +import { DEFAULT_CONFLICT_RESOLUTION_STRATEGY } from '../const'; import { Err } from '../error'; import { AcceptedConflict, From 6a7da84dd5bbc82451cada0b35cd4f736936d477 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 27 Jul 2021 19:37:01 +0900 Subject: [PATCH 068/297] fix: align with git-documentdb-plugin-remote-nodegit@1.0.0-beta.4 --- package-lock.json | 8 +- package.json | 2 +- src/remote/combine.ts | 4 +- src/remote/push_worker.ts | 14 ++- src/remote/sync.ts | 43 +++++++-- src/remote/sync_worker.ts | 4 +- src/types_sync.ts | 2 +- test/remote_base/sync.ts | 146 ++++++++++++++++++++++++------- test/remote_nodegit/sync.test.ts | 4 +- 9 files changed, 176 insertions(+), 51 deletions(-) diff --git a/package-lock.json b/package-lock.json index b017ad90..0a3945ca 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3500,12 +3500,12 @@ "dev": true }, "git-documentdb-plugin-remote-nodegit": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.0-beta.2.tgz", - "integrity": "sha512-3V5A6ek1BHy8fUjlkikLNkmR92B8hVxN7d0W5h2Kl0jdwb8i8RUa1g4xOVhGMxXTy4WxNunvtBjYtz+IVn12UA==", + "version": "1.0.0-beta.4", + "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.0-beta.4.tgz", + "integrity": "sha512-SxcktTdPoyjhJTH1CzOxPvMOMLWXyO7S9uxgmA3EG1ZxPt3dsMni0hVyhO2G8zY7nEpeAYXob/Fp2t4GQokKTQ==", "dev": true, "requires": { - "git-documentdb-remote-errors": "^1.0.2", + "git-documentdb-remote-errors": "^1.0.3", "nodegit": "^0.27.0", "tslog": "^3.2.0" } diff --git a/package.json b/package.json index d6bfbdec..07af65d6 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ "eslint-config-standardize": "^0.7.1", "eslint-plugin-prettierx": "^0.14.0", "expect": "^27.0.2", - "git-documentdb-plugin-remote-nodegit": "^1.0.0-beta.2", + "git-documentdb-plugin-remote-nodegit": "^1.0.0-beta.4", "mocha": "^8.3.2", "nyc": "^15.1.0", "parse-git-config": "^3.0.0", diff --git a/src/remote/combine.ts b/src/remote/combine.ts index 9c6efd53..b22aa9b3 100644 --- a/src/remote/combine.ts +++ b/src/remote/combine.ts @@ -33,7 +33,8 @@ import { RemoteEngine } from './remote_engine'; // eslint-disable-next-line complexity export async function combineDatabaseWithTheirs ( gitDDB: GitDDBInterface, - remoteOptions: RemoteOptions + remoteOptions: RemoteOptions, + remoteName: string ): Promise { // Clone repository if remoteURL exists const remoteDir = gitDDB.workingDir + '_' + ulid(Date.now()); @@ -44,6 +45,7 @@ export async function combineDatabaseWithTheirs ( await RemoteEngine[remoteOptions.connection!.engine!].clone( remoteDir, remoteOptions, + remoteName, gitDDB.logger ); diff --git a/src/remote/push_worker.ts b/src/remote/push_worker.ts index ac9e1c92..b448bb60 100644 --- a/src/remote/push_worker.ts +++ b/src/remote/push_worker.ts @@ -66,7 +66,11 @@ export async function pushWorker ( let localCommitOid: string; let remoteCommitOid = await git - .resolveRef({ fs, dir: gitDDB.workingDir, ref: 'refs/remotes/origin/main' }) + .resolveRef({ + fs, + dir: gitDDB.workingDir, + ref: `refs/remotes/${sync.remoteName}/${gitDDB.defaultBranch}`, + }) .catch(() => undefined); if (headCommit.commit.parent.length === 2) { @@ -95,7 +99,13 @@ export async function pushWorker ( } // Push - await RemoteEngine[sync.engine].push(gitDDB.workingDir, sync.options); + await RemoteEngine[sync.engine].push( + gitDDB.workingDir, + sync.options, + sync.remoteName, + gitDDB.defaultBranch, + gitDDB.defaultBranch + ); let remoteChanges: ChangedFile[] | undefined; if (skipGetChanges) { remoteChanges = undefined; diff --git a/src/remote/sync.ts b/src/remote/sync.ts index e81bb963..e5aa62e6 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -408,21 +408,54 @@ export class Sync implements SyncInterface { * @remarks * Call init() once just after creating an instance. * - * @throws {@link Err.RemoteRepositoryConnectError} - * @throws {@link Err.PushWorkerError} - * @throws {@link Err.NoMergeBaseFoundError} - * @throws {@link Err.SyncWorkerError} + * @throws {@link Err.CannotCreateRemoteRepositoryError} + * + * @throws {@link RemoteErr.InvalidURLFormatError} (from checkFetch) + * @throws {@link RemoteErr.InvalidRepositoryURLError} (from checkFetch) + * @throws {@link RemoteErr.InvalidSSHKeyPathError} (from checkFetch) + * @throws {@link RemoteErr.InvalidAuthenticationTypeError} (from checkFetch) + * @throws {@link RemoteErr.HTTPError401AuthorizationRequired} (from checkFetch) + * @throws {@link RemoteErr.NetworkError} (from checkFetch) + * @throws {@link RemoteErr.CannotConnectError} (from checkFetch) + * + * * * @public */ // eslint-disable-next-line complexity async init (): Promise { this._isClosed = false; + let isNewRemoteRepository = false; + + const urlOfRemote = await git.getConfig({ + fs, + dir: this._gitDDB.workingDir, + path: `remote.${this.remoteName}.url`, + }); + if (urlOfRemote !== this.remoteURL) { + await git.setConfig({ + fs, + dir: this._gitDDB.workingDir, + path: `remote.${this.remoteName}.url`, + value: this.remoteURL, + }); + await git.setConfig({ + fs, + dir: this._gitDDB.workingDir, + path: `remote.${this.remoteName}.fetch`, + value: `+refs/heads/*:refs/remotes/${this.remoteName}/*`, + }); + } for (let i = 0; i < NETWORK_RETRY; i++) { // eslint-disable-next-line no-await-in-loop const remoteResult: boolean | Error = await RemoteEngine[this._engine] - .checkFetch(this._gitDDB.workingDir, this._options, undefined, this._gitDDB.logger) + .checkFetch( + this._gitDDB.workingDir, + this._options, + this.remoteName, + this._gitDDB.logger + ) .catch(err => err); if (typeof remoteResult === 'boolean') { diff --git a/src/remote/sync_worker.ts b/src/remote/sync_worker.ts index 0c2b28e7..c25682c8 100644 --- a/src/remote/sync_worker.ts +++ b/src/remote/sync_worker.ts @@ -61,7 +61,7 @@ export async function syncWorker ( await RemoteEngine[sync.engine].fetch( gitDDB.workingDir, sync.options, - undefined, + sync.remoteName, gitDDB.logger ); @@ -77,7 +77,7 @@ export async function syncWorker ( const oldRemoteCommitOid = await git.resolveRef({ fs, dir: gitDDB.workingDir, - ref: 'refs/remotes/origin/' + gitDDB.defaultBranch, + ref: `refs/remotes/${sync.remoteName}/${gitDDB.defaultBranch}`, }); const [baseCommitOid] = await git.findMergeBase({ diff --git a/src/types_sync.ts b/src/types_sync.ts index f03da544..10ef31d6 100644 --- a/src/types_sync.ts +++ b/src/types_sync.ts @@ -32,7 +32,7 @@ export interface SyncInterface { engine: string; remoteRepository: RemoteRepository; options: RemoteOptions; - upstreamBranch: string; + remoteName: string; /*********************************************** * Public properties diff --git a/test/remote_base/sync.ts b/test/remote_base/sync.ts index f0c960fe..da2a27e0 100644 --- a/test/remote_base/sync.ts +++ b/test/remote_base/sync.ts @@ -12,7 +12,7 @@ * by using GitHub Personal Access Token * These tests create a new repository on GitHub if not exists. */ -import { relative } from 'path'; + import { Octokit } from '@octokit/rest'; import expect from 'expect'; import sinon from 'sinon'; @@ -23,7 +23,8 @@ import { ConnectionSettings, RemoteOptions } from '../../src/types'; import { Err } from '../../src/error'; import { Sync, syncImpl } from '../../src/remote/sync'; import { destroyDBs, removeRemoteRepositories } from '../remote_utils'; -import { RemoteErr } from '../../src/remote/remote_engine'; +import { RemoteEngine, RemoteErr } from '../../src/remote/remote_engine'; + // eslint-disable-next-line @typescript-eslint/no-var-requires const remote_nodegit_module = require('git-documentdb-plugin-remote-nodegit'); @@ -253,12 +254,12 @@ export const syncBase = ( }); }); - describe.only(' init()', () => { + describe(' init()', () => { it('throws RemoteErr.InvalidURLFormatError.', async () => { const dbName = serialId(); const remoteURL = remoteURLBase + serialId; - const stubCheckFetch = sandbox.stub(remote_nodegit_module, 'checkFetch'); + const stubCheckFetch = sandbox.stub(RemoteEngine[connection.engine!], 'checkFetch'); stubCheckFetch.onFirstCall().rejects(new RemoteEngineErr.InvalidURLFormatError('')); const gitDDB: GitDocumentDB = new GitDocumentDB({ @@ -277,9 +278,9 @@ export const syncBase = ( it('throws RemoteErr.InvalidRepositoryURLError.', async () => { const dbName = serialId(); - const remoteURL = remoteURLBase + serialId; + const remoteURL = remoteURLBase + serialId(); - const stubCheckFetch = sandbox.stub(remote_nodegit_module, 'checkFetch'); + const stubCheckFetch = sandbox.stub(RemoteEngine[connection.engine!], 'checkFetch'); stubCheckFetch .onFirstCall() .rejects(new RemoteEngineErr.InvalidRepositoryURLError('')); @@ -300,9 +301,9 @@ export const syncBase = ( it('throws RemoteErr.InvalidSSHKeyPathError.', async () => { const dbName = serialId(); - const remoteURL = remoteURLBase + serialId; + const remoteURL = remoteURLBase + serialId(); - const stubCheckFetch = sandbox.stub(remote_nodegit_module, 'checkFetch'); + const stubCheckFetch = sandbox.stub(RemoteEngine[connection.engine!], 'checkFetch'); stubCheckFetch.onFirstCall().rejects(new RemoteEngineErr.InvalidSSHKeyPathError()); const gitDDB: GitDocumentDB = new GitDocumentDB({ @@ -321,9 +322,9 @@ export const syncBase = ( it('throws RemoteErr.InvalidAuthenticationTypeError.', async () => { const dbName = serialId(); - const remoteURL = remoteURLBase + serialId; + const remoteURL = remoteURLBase + serialId(); - const stubCheckFetch = sandbox.stub(remote_nodegit_module, 'checkFetch'); + const stubCheckFetch = sandbox.stub(RemoteEngine[connection.engine!], 'checkFetch'); stubCheckFetch .onFirstCall() .rejects(new RemoteEngineErr.InvalidAuthenticationTypeError('')); @@ -346,9 +347,9 @@ export const syncBase = ( it('throws RemoteErr.HTTPError401AuthorizationRequired.', async () => { const dbName = serialId(); - const remoteURL = remoteURLBase + serialId; + const remoteURL = remoteURLBase + serialId(); - const stubCheckFetch = sandbox.stub(remote_nodegit_module, 'checkFetch'); + const stubCheckFetch = sandbox.stub(RemoteEngine[connection.engine!], 'checkFetch'); stubCheckFetch .onFirstCall() .rejects(new RemoteEngineErr.HTTPError401AuthorizationRequired('')); @@ -368,23 +369,32 @@ export const syncBase = ( ); await gitDDB.destroy(); }); - }); - describe(' syncImpl()', () => { - it('throws RemoteCheckFetchError.', async () => { - const dbName = serialId(); + it('throws CannotCreateRemoteRepositoryError', async () => { const remoteURL = remoteURLBase + serialId(); - const gitDDB: GitDocumentDB = new GitDocumentDB({ - dbName, - localDir, + + const dbNameA = serialId(); + + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, }); - await expect( - syncImpl.call(gitDDB, { - remoteUrl: remoteURL, - connection: { type: 'github', personalAccessToken: token }, - }) - ).rejects.toThrowError(RemoteErr.InvalidURLFormatError); - await gitDDB.destroy(); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection, + }; + await dbA.open(); + + const sync = new Sync(dbA, options); + + const stubReposCreate = sandbox.stub(sync.remoteRepository, 'create'); + stubReposCreate + .onFirstCall() + .rejects(new Err.CannotConnectRemoteRepositoryError(0, '', '')); + + await expect(sync.init()).rejects.toThrowError(Err.CannotCreateRemoteRepositoryError); + + destroyDBs([dbA]); }); it('creates a remote repository on GitHub by using personal access token', async () => { @@ -398,10 +408,9 @@ export const syncBase = ( }); const options: RemoteOptions = { remoteUrl: remoteURL, - connection: { type: 'github', personalAccessToken: token }, + connection, }; await dbA.open(); - // Check dbInfo await dbA.sync(options); // Check remote @@ -415,14 +424,67 @@ export const syncBase = ( destroyDBs([dbA]); }); - }); - describe(' tryPush()', () => { - before(async () => { - // Remove remote - await removeRemoteRepositories(reposPrefix); + it('succeeds after retries when NetworkError', async () => { + const dbName = serialId(); + const remoteURL = remoteURLBase + serialId(); + + const stubCheckFetch = sandbox.stub(RemoteEngine[connection.engine!], 'checkFetch'); + stubCheckFetch.onFirstCall().rejects(new RemoteEngineErr.NetworkError('')); + stubCheckFetch.onSecondCall().rejects(new RemoteEngineErr.HTTPError404NotFound('')); + + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + }); + await gitDDB.open(); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection, + }; + const sync = new Sync(gitDDB, options); + + await expect(sync.init()).resolves.toEqual({ + action: 'push', + changes: { remote: [] }, + }); + + expect(stubCheckFetch.callCount).toBe(2); + + await gitDDB.destroy(); + }); + + it.only('throws after retries when NetworkError', async () => { + const dbName = serialId(); + const remoteURL = remoteURLBase + serialId(); + + const stubCheckFetch = sandbox.stub(RemoteEngine[connection.engine!], 'checkFetch'); + stubCheckFetch.rejects(new RemoteEngineErr.NetworkError('')); + + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + }); + await gitDDB.open(); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection, + }; + const sync = new Sync(gitDDB, options); + + await expect(sync.init()).rejects.toThrowError(RemoteErr.NetworkError); + + expect(stubCheckFetch.callCount).toBe(3); + + await gitDDB.destroy(); }); + it('upstreamBranch'); + + it('tryPush'); + + it('trySync'); + it('throws PushNotAllowedError.', async () => { const remoteURL = remoteURLBase + serialId(); const dbName = serialId(); @@ -442,4 +504,22 @@ export const syncBase = ( destroyDBs([gitDDB]); }); }); + + describe(' syncImpl()', () => { + it('throws RepositoryNotOpenError.', async () => { + const dbName = serialId(); + const remoteURL = remoteURLBase + serialId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + }); + await expect( + syncImpl.call(gitDDB, { + remoteUrl: remoteURL, + connection, + }) + ).rejects.toThrowError(Err.RepositoryNotOpenError); + await gitDDB.destroy(); + }); + }); }; diff --git a/test/remote_nodegit/sync.test.ts b/test/remote_nodegit/sync.test.ts index 40c0c92f..847e840c 100644 --- a/test/remote_nodegit/sync.test.ts +++ b/test/remote_nodegit/sync.test.ts @@ -19,7 +19,7 @@ import { GitDocumentDB } from '../../src/git_documentdb'; import { syncBase } from '../remote_base/sync'; const reposPrefix = 'test_sync_constructor_nodegit__'; -const localDir = `./test_intg/database_sync_constructor_nodegit`; +const localDir = `./test/database_sync_constructor_nodegit`; beforeEach(function () { // @ts-ignore @@ -34,7 +34,7 @@ before(() => { }); after(() => { - fs.removeSync(path.resolve(localDir)); + // fs.removeSync(path.resolve(localDir)); }); // This test needs environment variables: From 59c29acaec28208cdf5d2a25a2133e73f1bd2106 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 28 Jul 2021 01:37:10 +0900 Subject: [PATCH 069/297] fix: use base32 for Git remote name --- package-lock.json | 39 ++++++++++++++++++++++++++++++++++++--- package.json | 3 ++- src/remote/sync.ts | 23 ++++++++++++----------- 3 files changed, 50 insertions(+), 15 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0a3945ca..0a693898 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1004,6 +1004,30 @@ "defer-to-connect": "^2.0.0" } }, + "@tsconfig/node10": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", + "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", + "dev": true + }, + "@tsconfig/node12": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", + "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", + "dev": true + }, + "@tsconfig/node14": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", + "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", + "dev": true + }, + "@tsconfig/node16": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", + "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", + "dev": true + }, "@types/argparse": { "version": "1.0.38", "resolved": "https://registry.npmjs.org/@types/argparse/-/argparse-1.0.38.tgz", @@ -3714,6 +3738,11 @@ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true }, + "hi-base32": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/hi-base32/-/hi-base32-0.5.1.tgz", + "integrity": "sha512-EmBBpvdYh/4XxsnUybsPag6VikPYnN30td+vQk+GI3qpahVEG9+gTkG0aXVxTjBqQ5T6ijbWIu77O+C5WFWsnA==" + }, "hosted-git-info": { "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", @@ -7213,11 +7242,15 @@ "dev": true }, "ts-node": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz", - "integrity": "sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.1.0.tgz", + "integrity": "sha512-6szn3+J9WyG2hE+5W8e0ruZrzyk1uFLYye6IGMBadnOzDh8aP7t8CbFpsfCiEx2+wMixAhjFt7lOZC4+l+WbEA==", "dev": true, "requires": { + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.1", "arg": "^4.1.0", "create-require": "^1.1.0", "diff": "^4.0.1", diff --git a/package.json b/package.json index 07af65d6..214047d2 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ "nyc": "^15.1.0", "parse-git-config": "^3.0.0", "sinon": "^10.0.0", - "ts-node": "^9.1.1", + "ts-node": "^10.1.0", "tsconfig-paths": "^3.9.0", "typescript": "^4.3.4" }, @@ -80,6 +80,7 @@ "cross-blob": "^2.0.0", "fs-extra": "^9.1.0", "git-documentdb-remote-errors": "^1.0.3", + "hi-base32": "^0.5.1", "isomorphic-git": "^1.8.2", "ot-json1": "^1.0.2", "rimraf": "^3.0.2", diff --git a/src/remote/sync.ts b/src/remote/sync.ts index e5aa62e6..2857ffb8 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -13,7 +13,9 @@ import { clearInterval, setInterval } from 'timers'; import git from 'isomorphic-git'; import fs from 'fs-extra'; import * as RemoteEngineError from 'git-documentdb-remote-errors'; -import { CONSOLE_STYLE, sleep } from '../utils'; +import * as base32 from 'hi-base32'; + +import { CONSOLE_STYLE, sleep, utf8decode, utf8encode } from '../utils'; import { Err } from '../error'; import { ChangedFile, @@ -60,22 +62,21 @@ import { RemoteEngine, RemoteErr, wrappingRemoteEngineError } from './remote_eng /** * encodeToRemoteName * - * @internal + * @public */ -function encodeToRemoteName (remoteURL: string) { - // encodeURIComponent does not encode period. - // Encodes period to %2E for 'path' param of git.setConfig() API. - // Use toLowerCase() because git.setConfig() automatically converts the path to lowercase. - return encodeURIComponent(remoteURL).replace(/\./g, '%2E').toLowerCase(); +export function encodeToGitRemoteName (remoteURL: string) { + // - Use toLowerCase() because git.setConfig() automatically converts the path to lowercase. + // - Use base32 because base64 and encodeURL are case sensitive. + return base32.encode(remoteURL).toLowerCase(); } /** * decodeFromRemoteName * - * @internal + * @public */ -function decodeFromRemoteName (remoteName: string) { - return encodeURIComponent(remoteName); +export function decodeFromGitRemoteName (remoteName: string) { + return base32.decode(remoteName.toUpperCase()); } /** @@ -374,7 +375,7 @@ export class Sync implements SyncInterface { connection: this._options.connection, }); - this._remoteName = encodeToRemoteName(this.remoteURL); + this._remoteName = encodeToGitRemoteName(this.remoteURL); this._engine = this._options.connection?.engine ?? 'iso'; } From 699089e528144f484d1340ca303c7d13788a57c0 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 28 Jul 2021 01:39:07 +0900 Subject: [PATCH 070/297] docs: add doc for utf8encode/decode --- src/utils.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/utils.ts b/src/utils.ts index 374ff0a3..476183fc 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -36,9 +36,19 @@ export function sleep (msec: number) { const decoder = new TextDecoder(); // default 'utf-8' or 'utf8' // eslint-disable-next-line @typescript-eslint/naming-convention const encoder = new TextEncoder(); // default 'utf-8' or 'utf8' +/** + * utf8decode + * + * @internal + */ export function utf8decode (uint8array: Uint8Array) { return decoder.decode(uint8array); } +/** + * utf8encode + * + * @internal + */ export function utf8encode (utf8: string) { return encoder.encode(utf8); } From 95d49e139f2ee7b50a9d328e0a9338e70efbf835 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 28 Jul 2021 01:39:27 +0900 Subject: [PATCH 071/297] fix: add origin for empty repository --- src/remote/sync.ts | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/remote/sync.ts b/src/remote/sync.ts index 2857ffb8..8900c000 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -448,6 +448,29 @@ export class Sync implements SyncInterface { }); } + /** + * Set origin if not exist + */ + const originUrl = await git.getConfig({ + fs, + dir: this._gitDDB.workingDir, + path: `remote.origin.url`, + }); + if (originUrl === undefined) { + await git.setConfig({ + fs, + dir: this._gitDDB.workingDir, + path: `remote.origin.url`, + value: this.remoteURL, + }); + await git.setConfig({ + fs, + dir: this._gitDDB.workingDir, + path: `remote.origin.fetch`, + value: `+refs/heads/*:refs/remotes/origin/*`, + }); + } + for (let i = 0; i < NETWORK_RETRY; i++) { // eslint-disable-next-line no-await-in-loop const remoteResult: boolean | Error = await RemoteEngine[this._engine] From feeb0b371e0e1eb064647ca9e4639a092b24698e Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 28 Jul 2021 01:39:43 +0900 Subject: [PATCH 072/297] test: add tests for sync --- test/remote_base/sync.ts | 148 ++++++++++++++++++++++++++++++++++----- 1 file changed, 129 insertions(+), 19 deletions(-) diff --git a/test/remote_base/sync.ts b/test/remote_base/sync.ts index da2a27e0..3869cd4d 100644 --- a/test/remote_base/sync.ts +++ b/test/remote_base/sync.ts @@ -13,7 +13,9 @@ * These tests create a new repository on GitHub if not exists. */ +import fs from 'fs'; import { Octokit } from '@octokit/rest'; +import git from 'isomorphic-git'; import expect from 'expect'; import sinon from 'sinon'; import * as RemoteEngineErr from 'git-documentdb-remote-errors'; @@ -21,8 +23,13 @@ import { MINIMUM_SYNC_INTERVAL } from '../../src/const'; import { GitDocumentDB } from '../../src/git_documentdb'; import { ConnectionSettings, RemoteOptions } from '../../src/types'; import { Err } from '../../src/error'; -import { Sync, syncImpl } from '../../src/remote/sync'; -import { destroyDBs, removeRemoteRepositories } from '../remote_utils'; +import { + decodeFromGitRemoteName, + encodeToGitRemoteName, + Sync, + syncImpl, +} from '../../src/remote/sync'; +import { removeRemoteRepositories } from '../remote_utils'; import { RemoteEngine, RemoteErr } from '../../src/remote/remote_engine'; // eslint-disable-next-line @typescript-eslint/no-var-requires @@ -55,6 +62,12 @@ export const syncBase = ( await removeRemoteRepositories(reposPrefix); }); + it('encode and decode Git remote name', () => { + const remoteURL = 'https://github.com/foo-bar/foo_bar.git'; + const encoded = encodeToGitRemoteName(remoteURL); + expect(decodeFromGitRemoteName(encoded)).toBe(remoteURL); + }); + /** * Tests for constructor */ @@ -74,7 +87,7 @@ export const syncBase = ( const sync = new Sync(gitDDB, options); expect(sync.options.live).toBe(false); - destroyDBs([gitDDB]); + await gitDDB.destroy(); }); it('set syncDirection to both by default', async () => { @@ -92,7 +105,7 @@ export const syncBase = ( const sync = new Sync(gitDDB, options); expect(sync.options.syncDirection).toBe('both'); - destroyDBs([gitDDB]); + await gitDDB.destroy(); }); it('set combineDbStrategy to combine-head-with-theirs by default', async () => { @@ -110,7 +123,7 @@ export const syncBase = ( const sync = new Sync(gitDDB, options); expect(sync.options.combineDbStrategy).toBe('combine-head-with-theirs'); - destroyDBs([gitDDB]); + await gitDDB.destroy(); }); it('set includeCommits to false by default', async () => { @@ -128,7 +141,7 @@ export const syncBase = ( const sync = new Sync(gitDDB, options); expect(sync.options.includeCommits).toBe(false); - destroyDBs([gitDDB]); + await gitDDB.destroy(); }); it('set conflictResolutionStrategy to ours-diff by default', async () => { @@ -146,7 +159,7 @@ export const syncBase = ( const sync = new Sync(gitDDB, options); expect(sync.options.conflictResolutionStrategy).toBe('ours-diff'); - destroyDBs([gitDDB]); + await gitDDB.destroy(); }); it('accepts remoteURL which ends with .git', async () => { @@ -163,7 +176,7 @@ export const syncBase = ( }; expect(() => new Sync(gitDDB, options)).not.toThrowError(); - destroyDBs([gitDDB]); + await gitDDB.destroy(); }); it('throws UndefinedRemoteURLError when remoteURL is undefined.', async () => { @@ -375,7 +388,7 @@ export const syncBase = ( const dbNameA = serialId(); - const dbA: GitDocumentDB = new GitDocumentDB({ + const gitDDB: GitDocumentDB = new GitDocumentDB({ dbName: dbNameA, localDir: localDir, }); @@ -383,9 +396,9 @@ export const syncBase = ( remoteUrl: remoteURL, connection, }; - await dbA.open(); + await gitDDB.open(); - const sync = new Sync(dbA, options); + const sync = new Sync(gitDDB, options); const stubReposCreate = sandbox.stub(sync.remoteRepository, 'create'); stubReposCreate @@ -394,7 +407,7 @@ export const syncBase = ( await expect(sync.init()).rejects.toThrowError(Err.CannotCreateRemoteRepositoryError); - destroyDBs([dbA]); + await gitDDB.destroy(); }); it('creates a remote repository on GitHub by using personal access token', async () => { @@ -402,7 +415,7 @@ export const syncBase = ( const dbNameA = serialId(); - const dbA: GitDocumentDB = new GitDocumentDB({ + const gitDDB: GitDocumentDB = new GitDocumentDB({ dbName: dbNameA, localDir: localDir, }); @@ -410,8 +423,8 @@ export const syncBase = ( remoteUrl: remoteURL, connection, }; - await dbA.open(); - await dbA.sync(options); + await gitDDB.open(); + await gitDDB.sync(options); // Check remote const octokit = new Octokit({ @@ -422,7 +435,7 @@ export const syncBase = ( const repo = urlArray[urlArray.length - 1]; await expect(octokit.repos.listBranches({ owner, repo })).resolves.not.toThrowError(); - destroyDBs([dbA]); + await gitDDB.destroy(); }); it('succeeds after retries when NetworkError', async () => { @@ -454,7 +467,7 @@ export const syncBase = ( await gitDDB.destroy(); }); - it.only('throws after retries when NetworkError', async () => { + it('throws after retries when NetworkError', async () => { const dbName = serialId(); const remoteURL = remoteURLBase + serialId(); @@ -479,7 +492,104 @@ export const syncBase = ( await gitDDB.destroy(); }); - it('upstreamBranch'); + it('sets Git remote in .git/config', async () => { + const remoteURL = remoteURLBase + serialId(); + + const dbNameA = serialId(); + + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection, + }; + await gitDDB.open(); + await gitDDB.sync(options); + + const remoteName = encodeToGitRemoteName(remoteURL); + + const url = await git.getConfig({ + fs, + dir: gitDDB.workingDir, + path: `remote.${remoteName}.url`, + }); + expect(url).toBe(remoteURL); + + const fetch = await git.getConfig({ + fs, + dir: gitDDB.workingDir, + path: `remote.${encodeToGitRemoteName(remoteURL)}.fetch`, + }); + expect(fetch).toBe(`+refs/heads/*:refs/remotes/${remoteName}/*`); + + const originUrl = await git.getConfig({ + fs, + dir: gitDDB.workingDir, + path: `remote.origin.url`, + }); + expect(originUrl).toBe(remoteURL); + + const originFetch = await git.getConfig({ + fs, + dir: gitDDB.workingDir, + path: `remote.origin.fetch`, + }); + expect(originFetch).toBe(`+refs/heads/*:refs/remotes/origin/*`); + + await gitDDB.destroy(); + }); + + it('skip setting origin when it already exists.', async () => { + const remoteURL = remoteURLBase + serialId(); + + const dbNameA = serialId(); + + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection, + }; + await gitDDB.open(); + await gitDDB.sync(options); + + const remoteName = encodeToGitRemoteName(remoteURL); + + // Set origin + await git.setConfig({ + fs, + dir: gitDDB.workingDir, + path: `remote.origin.url`, + value: 'http://example.com/originurl' + }); + + const url = await git.getConfig({ + fs, + dir: gitDDB.workingDir, + path: `remote.${remoteName}.url`, + }); + expect(url).toBe(remoteURL); + + const fetch = await git.getConfig({ + fs, + dir: gitDDB.workingDir, + path: `remote.${encodeToGitRemoteName(remoteURL)}.fetch`, + }); + expect(fetch).toBe(`+refs/heads/*:refs/remotes/${remoteName}/*`); + + const originUrl = await git.getConfig({ + fs, + dir: gitDDB.workingDir, + path: `remote.origin.url`, + }); + expect(originUrl).toBe('http://example.com/originurl'); + + await gitDDB.destroy(); + }); it('tryPush'); @@ -501,7 +611,7 @@ export const syncBase = ( const sync = new Sync(gitDDB, options); // await await expect(sync.init()).rejects.toThrowError(Err.PushNotAllowedError); - destroyDBs([gitDDB]); + await gitDDB.destroy(); }); }); From 0b59ee2f570e3d638c22fc274c32c688b374418d Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 28 Jul 2021 04:47:40 +0900 Subject: [PATCH 073/297] test: adding test for sync --- src/remote/combine.ts | 13 +++++- src/remote/push_worker.ts | 17 +++++++- src/remote/sync.ts | 87 +++++++++++++++++++++++++++++---------- src/remote/sync_worker.ts | 22 +++++++--- test/remote_base/sync.ts | 14 +++++-- 5 files changed, 119 insertions(+), 34 deletions(-) diff --git a/src/remote/combine.ts b/src/remote/combine.ts index b22aa9b3..3732ff9b 100644 --- a/src/remote/combine.ts +++ b/src/remote/combine.ts @@ -27,8 +27,19 @@ import { RemoteEngine } from './remote_engine'; /** * Clone a remote repository and combine the current local working directory with it. - * * TODO: Must catch errors + * + * @throws {@link InvalidURLFormatError} (from clone()) + * @throws {@link NetworkError} (from clone()) + * @throws {@link HTTPError401AuthorizationRequired} (from clone()) + * @throws {@link HTTPError404NotFound} (from clone()) + * @throws {@link CannotConnectError} (from clone()) + * + * @throws {@link HttpProtocolRequiredError} (from clone()) + * @throws {@link InvalidRepositoryURLError} (from clone()) + * @throws {@link InvalidSSHKeyPathError} (from clone()) + * + * @throws {@link InvalidAuthenticationTypeError} (from clone()) */ // eslint-disable-next-line complexity export async function combineDatabaseWithTheirs ( diff --git a/src/remote/push_worker.ts b/src/remote/push_worker.ts index b448bb60..37ae1414 100644 --- a/src/remote/push_worker.ts +++ b/src/remote/push_worker.ts @@ -17,8 +17,21 @@ import { RemoteEngine } from './remote_engine'; /** * Push and get changes * - * @throws {@link RemoteEngine.Err.UnfetchedCommitExistsError} (from push() and validatePushResult()) - * @throws {@link RemoteEngine.Err.GitFetchError} (from validatePushResult()) + * @throws {@link InvalidGitRemoteError} (from push()) + * @throws {@link UnfetchedCommitExistsError} (from push()) + * @throws {@link InvalidURLFormatError} (from push()) + * @throws {@link NetworkError} (from push()) + * @throws {@link HTTPError401AuthorizationRequired} (from push()) + * @throws {@link HTTPError404NotFound} (from push()) + * @throws {@link HTTPError403Forbidden} (from push()) + * @throws {@link CannotConnectError} (from push()) + * @throws {@link UnfetchedCommitExistsError} (from push()) + * @throws {@link CannotConnectError} (from push()) + * @throws {@link HttpProtocolRequiredError} (from push()) + * @throws {@link InvalidRepositoryURLError} (from push()) + * @throws {@link InvalidSSHKeyPathError} (from push()) + * @throws {@link InvalidAuthenticationTypeError} (from push()) + * * @throws {@link Err.InvalidJsonObjectError} (from getChanges()) */ export async function pushWorker ( diff --git a/src/remote/sync.ts b/src/remote/sync.ts index 8900c000..72c57ee5 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -411,15 +411,25 @@ export class Sync implements SyncInterface { * * @throws {@link Err.CannotCreateRemoteRepositoryError} * - * @throws {@link RemoteErr.InvalidURLFormatError} (from checkFetch) - * @throws {@link RemoteErr.InvalidRepositoryURLError} (from checkFetch) - * @throws {@link RemoteErr.InvalidSSHKeyPathError} (from checkFetch) - * @throws {@link RemoteErr.InvalidAuthenticationTypeError} (from checkFetch) - * @throws {@link RemoteErr.HTTPError401AuthorizationRequired} (from checkFetch) - * @throws {@link RemoteErr.NetworkError} (from checkFetch) - * @throws {@link RemoteErr.CannotConnectError} (from checkFetch) + * @throws {@link RemoteErr.InvalidGitRemoteError} (from checkFetch(), trySync(), tryPush()) + * @throws {@link RemoteErr.InvalidURLFormatError} (from checkFetch(), trySync(), tryPush()) + * @throws {@link RemoteErr.NetworkError} (from checkFetch(), trySync(), tryPush()) + * @throws {@link RemoteErr.HTTPError401AuthorizationRequired} (from checkFetch(), trySync(), tryPush()) + * @throws {@link RemoteErr.HTTPError404NotFound} (from checkFetch(), trySync(), tryPush()) + * @throws {@link RemoteErr.CannotConnectError} (from checkFetch(), trySync(), tryPush()) + * @throws {@link RemoteErr.HttpProtocolRequiredError} (from checkFetch(), trySync(), tryPush()) + * @throws {@link RemoteErr.InvalidRepositoryURLError} (from checkFetch(), trySync(), tryPush()) + * @throws {@link RemoteErr.InvalidSSHKeyPathError} (from checkFetch, trySync(), tryPush()) + * @throws {@link RemoteErr.InvalidAuthenticationTypeError} (from checkFetch(), trySync(), tryPush()) * + * @throws {@link RemoteErr.UnfetchedCommitExistsError} (from tryPush()) + * @throws {@link RemoteErr.HTTPError403Forbidden} (from tryPush()) * + * @throws {@link Err.NoMergeBaseFoundError} (from trySync()) + * @throws {@link Err.ThreeWayMergeError} (from trySync()) + * @throws {@link Err.CannotDeleteDataError} (from trySync()) + * + * @throws {@link Err.InvalidJsonObjectError} (from trySync(), tryPush()) * * @public */ @@ -658,9 +668,7 @@ export class Sync implements SyncInterface { * Try to push with retries * * @throws {@link Err.PushNotAllowedError} (from this and enqueuePushTask) - * @throws {@link Err.PushWorkerError} (from this and enqueuePushTask) - * @throws {@link RemoteEngine.Err.UnfetchedCommitExistsError} (from this and enqueuePushTask) - * + * @public */ // eslint-disable-next-line complexity @@ -736,11 +744,29 @@ export class Sync implements SyncInterface { /** * Try to sync with retries + + * @throws {@link Err.PushNotAllowedError} + * @throws {@link Err.CombineDatabaseError} + * + * @throws {@link Err.NoMergeBaseFoundError} (from syncWorker) + * + * @throws {@link RemoteErr.InvalidGitRemoteError} (from syncWorker) + * @throws {@link RemoteErr.InvalidURLFormatError} (from syncWorker) + * @throws {@link RemoteErr.NetworkError} (from syncWorker) + * @throws {@link RemoteErr.HTTPError401AuthorizationRequired} (from syncWorker) + * @throws {@link RemoteErr.HTTPError404NotFound} (from syncWorker) * - * @throws {@link Err.PushNotAllowedError} (from this and enqueueSyncTask) - * @throws {@link Err.SyncWorkerError} (from enqueueSyncTask) - * @throws {@link Err.NoMergeBaseFoundError} (from enqueueSyncTask) - * @throws {@link RemoteEngine.Err.UnfetchedCommitExistsError} (from enqueueSyncTask) + * @throws {@link RemoteErr.CannotConnectError} (from syncWorker) + * @throws {@link RemoteErr.HttpProtocolRequiredError} (from syncWorker) + * @throws {@link RemoteErr.InvalidRepositoryURLError} (from syncWorker) + * @throws {@link RemoteErr.InvalidSSHKeyPathError} (from syncWorker) + * @throws {@link RemoteErr.InvalidAuthenticationTypeError} (from syncWorker) + * + * @throws {@link RemoteErr.HTTPError403Forbidden} (from syncWorker) + * @throws {@link RemoteErr.UnfetchedCommitExistsError} (from syncWorker) + * @throws {@link Err.ThreeWayMergeError} (from syncWorker) + * @throws {@link Err.CannotDeleteDataError} (from syncWorker) + * @throws {@link Err.InvalidJsonObjectError} (from syncWorker) * * @public */ @@ -851,7 +877,7 @@ export class Sync implements SyncInterface { * Enqueue push task to TaskQueue * * @throws {@link Err.PushWorkerError} - * @throws {@link RemoteEngine.Err.UnfetchedCommitExistsError} + * @throws {@link RemoteEErr.UnfetchedCommitExistsError} * @throws {@link Err.PushNotAllowedError} * * @public @@ -950,11 +976,28 @@ export class Sync implements SyncInterface { /** * Enqueue sync task to TaskQueue * - * @throws {@link Err.SyncWorkerError} - * @throws {@link Err.NoMergeBaseFoundError} - * @throws {@link RemoteEngine.Err.UnfetchedCommitExistsError} * @throws {@link Err.PushNotAllowedError} * + * @throws {@link Err.NoMergeBaseFoundError} (from syncWorker) + * + * @throws {@link RemoteErr.InvalidGitRemoteError} (from syncWorker) + * @throws {@link RemoteErr.InvalidURLFormatError} (from syncWorker) + * @throws {@link RemoteErr.NetworkError} (from syncWorker) + * @throws {@link RemoteErr.HTTPError401AuthorizationRequired} (from syncWorker) + * @throws {@link RemoteErr.HTTPError404NotFound} (from syncWorker) + * + * @throws {@link RemoteErr.CannotConnectError} (from syncWorker) + * @throws {@link RemoteErr.HttpProtocolRequiredError} (from syncWorker) + * @throws {@link RemoteErr.InvalidRepositoryURLError} (from syncWorker) + * @throws {@link RemoteErr.InvalidSSHKeyPathError} (from syncWorker) + * @throws {@link RemoteErr.InvalidAuthenticationTypeError} (from syncWorker) + * + * @throws {@link RemoteErr.HTTPError403Forbidden} (from syncWorker) + * @throws {@link RemoteErr.UnfetchedCommitExistsError} (from syncWorker) + * @throws {@link Err.ThreeWayMergeError} (from syncWorker) + * @throws {@link Err.CannotDeleteDataError} (from syncWorker) + * @throws {@link Err.InvalidJsonObjectError} (from syncWorker) + * * @public */ enqueueSyncTask (): Promise { @@ -972,9 +1015,9 @@ export class Sync implements SyncInterface { ) => syncWorker(this._gitDDB, this, taskMetadata) // eslint-disable-next-line complexity - .then(syncResult => { + .then((syncResult: SyncResult) => { this._gitDDB.logger.debug( - CONSOLE_STYLE.bgWhite().fgBlack().tag()`sync_worker: ${JSON.stringify( + CONSOLE_STYLE.bgWhite().fgBlack().tag()`syncWorker: ${JSON.stringify( syncResult )}` ); @@ -1046,8 +1089,8 @@ export class Sync implements SyncInterface { beforeResolve(); resolve(syncResult); }) - .catch(err => { - // console.log(`Error in sync_worker: ${err}`); + .catch((err: Error) => { + // console.log(`Error in syncWorker: ${err}`); if ( !( err instanceof Err.NoMergeBaseFoundError || diff --git a/src/remote/sync_worker.ts b/src/remote/sync_worker.ts index c25682c8..7ebdae55 100644 --- a/src/remote/sync_worker.ts +++ b/src/remote/sync_worker.ts @@ -31,14 +31,26 @@ import { Err } from '../error'; /** * sync_worker * - * @throws {@link RemoteEngine.Err.GitFetchError} (from fetch() and pushWorker()) - * @throws {@link RemoteEngine.Err.NoMergeBaseFoundError} + * @throws {@link RemoteErr.InvalidGitRemoteError} (from fetch(), push()) + * @throws {@link RemoteErr.InvalidURLFormatError} (from fetch(), push(), combineDatabaseWithTheirs()) + * @throws {@link RemoteErr.NetworkError} (from fetch(), push(), combineDatabaseWithTheirs()) + * @throws {@link RemoteErr.HTTPError401AuthorizationRequired} (from fetch(), push(), combineDatabaseWithTheirs()) + * @throws {@link RemoteErr.HTTPError404NotFound} (from fetch(), push(), combineDatabaseWithTheirs()) + * @throws {@link RemoteErr.CannotConnectError} (from fetch()), push(), combineDatabaseWithTheirs()) + * @throws {@link RemoteErr.HttpProtocolRequiredError} (from fetch(), push(), combineDatabaseWithTheirs()) + * @throws {@link RemoteErr.InvalidRepositoryURLError} (from fetch(), push(), combineDatabaseWithTheirs()) + * @throws {@link RemoteErr.InvalidSSHKeyPathError} (from fetch(), push(), combineDatabaseWithTheirs()) + * @throws {@link RemoteErr.InvalidAuthenticationTypeError} (from fetch(), push(), combineDatabaseWithTheirs()) + * + * @throws {@link HTTPError403Forbidden} (from push()) + * @throws {@link UnfetchedCommitExistsError} (from push()) + * + * @throws {@link Err.NoMergeBaseFoundError} * @throws {@link Err.ThreeWayMergeError} * @throws {@link Err.CannotDeleteDataError} + * * @throws {@link Err.InvalidJsonObjectError} (from getChanges()) - * @throws {@link RemoteEngine.Err.UnfetchedCommitExistsError} (from pushWorker()) - * @throws {@link RemoteEngine.Err.GitPushError} (from pushWorker()) - * @throws {@link Err.InvalidJsonObjectError} (from pushWorker()) + * * * @internal */ diff --git a/test/remote_base/sync.ts b/test/remote_base/sync.ts index 3869cd4d..998decfe 100644 --- a/test/remote_base/sync.ts +++ b/test/remote_base/sync.ts @@ -564,7 +564,7 @@ export const syncBase = ( fs, dir: gitDDB.workingDir, path: `remote.origin.url`, - value: 'http://example.com/originurl' + value: 'http://example.com/originurl', }); const url = await git.getConfig({ @@ -591,9 +591,15 @@ export const syncBase = ( await gitDDB.destroy(); }); - it('tryPush'); + it.skip('calls tryPush() after create remote repository'); - it('trySync'); + it.skip('calls tryPush() when remote repository exists'); + + it.skip('calls trySync() when remote repository exists'); + + it.skip('throws error in tryPush()'); + + it.skip('throws error in trySync()'); it('throws PushNotAllowedError.', async () => { const remoteURL = remoteURLBase + serialId(); @@ -609,7 +615,7 @@ export const syncBase = ( syncDirection: 'pull', }; const sync = new Sync(gitDDB, options); - // await await expect(sync.init()).rejects.toThrowError(Err.PushNotAllowedError); + await expect(sync.init()).rejects.toThrowError(Err.PushNotAllowedError); await gitDDB.destroy(); }); From 328a56085fa2590a567e309ecdad6afc18d1bd96 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 28 Jul 2021 13:19:48 +0900 Subject: [PATCH 074/297] fix: use short SHA-1 for remote name --- package-lock.json | 5 --- package.json | 1 - src/remote/sync.ts | 72 +++++++++++++++++++-------------- test/remote_base/sync.ts | 87 +++++++++++++++++++++++++++++++++++----- 4 files changed, 118 insertions(+), 47 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0a693898..1206d6a3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3738,11 +3738,6 @@ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true }, - "hi-base32": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/hi-base32/-/hi-base32-0.5.1.tgz", - "integrity": "sha512-EmBBpvdYh/4XxsnUybsPag6VikPYnN30td+vQk+GI3qpahVEG9+gTkG0aXVxTjBqQ5T6ijbWIu77O+C5WFWsnA==" - }, "hosted-git-info": { "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", diff --git a/package.json b/package.json index 214047d2..d2b5844e 100644 --- a/package.json +++ b/package.json @@ -80,7 +80,6 @@ "cross-blob": "^2.0.0", "fs-extra": "^9.1.0", "git-documentdb-remote-errors": "^1.0.3", - "hi-base32": "^0.5.1", "isomorphic-git": "^1.8.2", "ot-json1": "^1.0.2", "rimraf": "^3.0.2", diff --git a/src/remote/sync.ts b/src/remote/sync.ts index 72c57ee5..067452df 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -10,12 +10,12 @@ * ! Must import both clearInterval and setInterval from 'timers' */ import { clearInterval, setInterval } from 'timers'; +import crypto from 'crypto'; import git from 'isomorphic-git'; import fs from 'fs-extra'; import * as RemoteEngineError from 'git-documentdb-remote-errors'; -import * as base32 from 'hi-base32'; -import { CONSOLE_STYLE, sleep, utf8decode, utf8encode } from '../utils'; +import { CONSOLE_STYLE, sleep } from '../utils'; import { Err } from '../error'; import { ChangedFile, @@ -62,21 +62,43 @@ import { RemoteEngine, RemoteErr, wrappingRemoteEngineError } from './remote_eng /** * encodeToRemoteName * + * @remarks + * Remote name consists of host_name + hash. + * hash is generated from remoteURL. + * Capitalize host name of remoteURL manually when hashes collide because host name is not case sensitive. + * * @public */ export function encodeToGitRemoteName (remoteURL: string) { - // - Use toLowerCase() because git.setConfig() automatically converts the path to lowercase. - // - Use base32 because base64 and encodeURL are case sensitive. - return base32.encode(remoteURL).toLowerCase(); -} + let host: string; + if (/:\/\/.+?@(.+?):/.test(remoteURL)) { + // ssh://user@foo.bar:xxx/path/repos.git + host = RegExp.$1; + } + else if (/:\/\/(.+?):/.test(remoteURL)) { + // http://foo.bar:xxx/path/repos.git + host = RegExp.$1; + } + else if (/:\/\/.+?@(.+?)\//.test(remoteURL)) { + // ssh://user@foo.bar/path/repos.git + host = RegExp.$1; + } + else if (/:\/\/(.+?)\//.test(remoteURL)) { + // http://foo.bar/user/repos.git + host = RegExp.$1; + } + else if (/^.+?@(.+?):/.test(remoteURL)) { + // user@foo.bar:path/repos.git + host = RegExp.$1; + } + else { + throw new RemoteErr.InvalidURLFormatError(`URL format is invalid: ${remoteURL}`); + } -/** - * decodeFromRemoteName - * - * @public - */ -export function decodeFromGitRemoteName (remoteName: string) { - return base32.decode(remoteName.toUpperCase()); + const shortHash = crypto.createHash('sha1').update(remoteURL).digest('hex').substr(0, 7); + + // Use toLowerCase() because git.setConfig() and git.addRemote() automatically converts the path to lowercase. + return host.toLowerCase().replace(/\./g, '_') + '_' + shortHash; } /** @@ -444,17 +466,11 @@ export class Sync implements SyncInterface { path: `remote.${this.remoteName}.url`, }); if (urlOfRemote !== this.remoteURL) { - await git.setConfig({ - fs, - dir: this._gitDDB.workingDir, - path: `remote.${this.remoteName}.url`, - value: this.remoteURL, - }); - await git.setConfig({ + await git.addRemote({ fs, dir: this._gitDDB.workingDir, - path: `remote.${this.remoteName}.fetch`, - value: `+refs/heads/*:refs/remotes/${this.remoteName}/*`, + remote: this.remoteName, + url: this.remoteURL, }); } @@ -467,17 +483,11 @@ export class Sync implements SyncInterface { path: `remote.origin.url`, }); if (originUrl === undefined) { - await git.setConfig({ - fs, - dir: this._gitDDB.workingDir, - path: `remote.origin.url`, - value: this.remoteURL, - }); - await git.setConfig({ + await git.addRemote({ fs, dir: this._gitDDB.workingDir, - path: `remote.origin.fetch`, - value: `+refs/heads/*:refs/remotes/origin/*`, + remote: 'origin', + url: this.remoteURL, }); } diff --git a/test/remote_base/sync.ts b/test/remote_base/sync.ts index 998decfe..44e70a66 100644 --- a/test/remote_base/sync.ts +++ b/test/remote_base/sync.ts @@ -13,22 +13,19 @@ * These tests create a new repository on GitHub if not exists. */ +import crypto from 'crypto'; import fs from 'fs'; import { Octokit } from '@octokit/rest'; import git from 'isomorphic-git'; import expect from 'expect'; import sinon from 'sinon'; import * as RemoteEngineErr from 'git-documentdb-remote-errors'; +import { sleep } from '../../src/utils'; import { MINIMUM_SYNC_INTERVAL } from '../../src/const'; import { GitDocumentDB } from '../../src/git_documentdb'; import { ConnectionSettings, RemoteOptions } from '../../src/types'; import { Err } from '../../src/error'; -import { - decodeFromGitRemoteName, - encodeToGitRemoteName, - Sync, - syncImpl, -} from '../../src/remote/sync'; +import { encodeToGitRemoteName, Sync, syncImpl } from '../../src/remote/sync'; import { removeRemoteRepositories } from '../remote_utils'; import { RemoteEngine, RemoteErr } from '../../src/remote/remote_engine'; @@ -62,10 +59,80 @@ export const syncBase = ( await removeRemoteRepositories(reposPrefix); }); - it('encode and decode Git remote name', () => { - const remoteURL = 'https://github.com/foo-bar/foo_bar.git'; - const encoded = encodeToGitRemoteName(remoteURL); - expect(decodeFromGitRemoteName(encoded)).toBe(remoteURL); + describe('encode Git remote name', () => { + it('always generates the same name', async () => { + const remoteURL = 'ssh://user@github.com:443/foo-bar/baz.git'; + const encoded = encodeToGitRemoteName(remoteURL); + await sleep(1500); + const encoded2 = encodeToGitRemoteName(remoteURL); + expect(encoded).toBe(encoded2); + }); + + it('ssh://user@github.com:443/foo-bar/baz.git', () => { + const remoteURL = 'ssh://user@github.com:443/foo-bar/baz.git'; + const encoded = encodeToGitRemoteName(remoteURL); + const shortHash = crypto + .createHash('sha1') + .update(remoteURL) + .digest('hex') + .substr(0, 7); + expect(encoded).toBe('github_com_' + shortHash); + }); + + it('ssh://user@127.0.0.1:443/foo-bar/baz.git', () => { + const remoteURL = 'ssh://user@127.0.0.1:443/foo-bar/baz.git'; + const encoded = encodeToGitRemoteName(remoteURL); + const shortHash = crypto + .createHash('sha1') + .update(remoteURL) + .digest('hex') + .substr(0, 7); + expect(encoded).toBe('127_0_0_1_' + shortHash); + }); + + it('https://github.com:80/foo-bar/baz.git', () => { + const remoteURL = 'https://github.com:80/foo-bar/baz.git'; + const encoded = encodeToGitRemoteName(remoteURL); + const shortHash = crypto + .createHash('sha1') + .update(remoteURL) + .digest('hex') + .substr(0, 7); + expect(encoded).toBe('github_com_' + shortHash); + }); + + it('ssh://user@github.com/foo-bar/baz.git', () => { + const remoteURL = 'ssh://user@github.com/foo-bar/baz.git'; + const encoded = encodeToGitRemoteName(remoteURL); + const shortHash = crypto + .createHash('sha1') + .update(remoteURL) + .digest('hex') + .substr(0, 7); + expect(encoded).toBe('github_com_' + shortHash); + }); + + it('https://github.com/foo-bar/baz.git', () => { + const remoteURL = 'https://github.com/foo-bar/baz.git'; + const encoded = encodeToGitRemoteName(remoteURL); + const shortHash = crypto + .createHash('sha1') + .update(remoteURL) + .digest('hex') + .substr(0, 7); + expect(encoded).toBe('github_com_' + shortHash); + }); + + it('git@github.com:foo-bar/baz.git', () => { + const remoteURL = 'git@github.com:foo-bar/baz.git'; + const encoded = encodeToGitRemoteName(remoteURL); + const shortHash = crypto + .createHash('sha1') + .update(remoteURL) + .digest('hex') + .substr(0, 7); + expect(encoded).toBe('github_com_' + shortHash); + }); }); /** From 7c5f63f057f458f868c202724b7aa404e5f4f78a Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 28 Jul 2021 13:46:26 +0900 Subject: [PATCH 075/297] fix: add InvalidGitRemoteError for Sync#init() --- src/remote/sync.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/remote/sync.ts b/src/remote/sync.ts index 067452df..737b00fc 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -505,6 +505,10 @@ export class Sync implements SyncInterface { if (typeof remoteResult === 'boolean') { break; } + else if (remoteResult instanceof RemoteEngineError.InvalidGitRemoteError) { + // checkFetch hardly invoke this error because checkFetch is called just after addRemote. + throw wrappingRemoteEngineError(remoteResult); + } else if ( remoteResult instanceof RemoteEngineError.InvalidURLFormatError || remoteResult instanceof RemoteEngineError.InvalidRepositoryURLError || From ab3ac0fe637ce72533d3dd0587ffcf18df7bd729 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 28 Jul 2021 18:37:44 +0900 Subject: [PATCH 076/297] docs: add doc about errors --- src/remote/3way_merge.ts | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/remote/3way_merge.ts b/src/remote/3way_merge.ts index 5c1518c8..5ba53f20 100644 --- a/src/remote/3way_merge.ts +++ b/src/remote/3way_merge.ts @@ -132,8 +132,10 @@ function getMergedBinaryDoc ( } /** + * getMergedDocument + * * @throws {@link Err.InvalidDocTypeError} - * @throws {@link Err.InvalidConflictResolutionStrategyError} + * @throws {@link Err.InvalidConflictResolutionStrategyError} (from getMergedJsonDoc, getMergedTextDoc, getMergedBinaryDoc) */ function getMergedDocument ( jsonDiff: JsonDiff, @@ -175,6 +177,16 @@ function getMergedDocument ( throw new Err.InvalidDocTypeError(docType); } +/** + * merge + * + * @throws {@link Err.InvalidConflictStateError} (from threeWayMerge()) + * @throws {@link Err.CannotDeleteDataError} (from threeWayMerge()) + * @throws {@link Err.InvalidDocTypeError} (from threeWayMerge()) + * @throws {@link Err.InvalidConflictResolutionStrategyError} (from threeWayMerge()) + * @throws {@link Err.CannotCreateDirectoryError} (from threeWayMerge()) + * @throws {@link Err.InvalidJsonObjectError} (from threeWayMerge()) + */ export async function merge ( gitDDB: GitDDBInterface, sync: SyncInterface, @@ -280,11 +292,11 @@ export async function merge ( * 3-way merge * * @throws {@link Err.InvalidConflictStateError} + * @throws {@link Err.CannotDeleteDataError} * - * @throws {@link Err.InvalidDocTypeError} - * @throws {@link Err.InvalidConflictResolutionStrategyError} + * @throws {@link Err.InvalidDocTypeError} (from getMergedDocument()) + * @throws {@link Err.InvalidConflictResolutionStrategyError} (from getMergedDocument()) * - * @throws {@link Err.CannotDeleteDataError} * @throws {@link Err.CannotCreateDirectoryError} (from writeBlobToFile) * @throws {@link Err.InvalidJsonObjectError} (from getFatDocFromData, getFatDocFromReadBlobResult) * From 0e3fd5310db6c7d1af45ccc20b65acf7e021a8d8 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 28 Jul 2021 18:38:41 +0900 Subject: [PATCH 077/297] fix: wrap errors from RemoteEngine --- src/remote/combine.ts | 31 ++++++++++++------------- src/remote/push_worker.ts | 20 +++++++++------- src/remote/sync_worker.ts | 48 ++++++++++++++++++++++----------------- 3 files changed, 54 insertions(+), 45 deletions(-) diff --git a/src/remote/combine.ts b/src/remote/combine.ts index 3732ff9b..e7973619 100644 --- a/src/remote/combine.ts +++ b/src/remote/combine.ts @@ -23,23 +23,23 @@ import { GitDDBInterface } from '../types_gitddb'; import { Err } from '../error'; import { DUPLICATED_FILE_POSTFIX, FILE_REMOVE_TIMEOUT, JSON_EXT } from '../const'; import { getAllMetadata, toSortedJSONString } from '../utils'; -import { RemoteEngine } from './remote_engine'; +import { RemoteEngine, wrappingRemoteEngineError } from './remote_engine'; /** * Clone a remote repository and combine the current local working directory with it. * TODO: Must catch errors * - * @throws {@link InvalidURLFormatError} (from clone()) - * @throws {@link NetworkError} (from clone()) - * @throws {@link HTTPError401AuthorizationRequired} (from clone()) - * @throws {@link HTTPError404NotFound} (from clone()) - * @throws {@link CannotConnectError} (from clone()) + * @throws {@link RemoteErr.InvalidURLFormatError} (from clone()) + * @throws {@link RemoteErr.NetworkError} (from clone()) + * @throws {@link RemoteErr.HTTPError401AuthorizationRequired} (from clone()) + * @throws {@link RemoteErr.HTTPError404NotFound} (from clone()) + * @throws {@link RemoteErr.CannotConnectError} (from clone()) * - * @throws {@link HttpProtocolRequiredError} (from clone()) - * @throws {@link InvalidRepositoryURLError} (from clone()) - * @throws {@link InvalidSSHKeyPathError} (from clone()) + * @throws {@link RemoteErr.HttpProtocolRequiredError} (from clone()) + * @throws {@link RemoteErr.InvalidRepositoryURLError} (from clone()) + * @throws {@link RemoteErr.InvalidSSHKeyPathError} (from clone()) * - * @throws {@link InvalidAuthenticationTypeError} (from clone()) + * @throws {@link RemoteErr.InvalidAuthenticationTypeError} (from clone()) */ // eslint-disable-next-line complexity export async function combineDatabaseWithTheirs ( @@ -53,12 +53,11 @@ export async function combineDatabaseWithTheirs ( const duplicates: DuplicatedFile[] = []; try { - await RemoteEngine[remoteOptions.connection!.engine!].clone( - remoteDir, - remoteOptions, - remoteName, - gitDDB.logger - ); + await RemoteEngine[remoteOptions.connection!.engine!] + .clone(remoteDir, remoteOptions, remoteName, gitDDB.logger) + .catch(err => { + throw wrappingRemoteEngineError(err); + }); const localMetadataList: DocMetadata[] = await getAllMetadata(gitDDB.workingDir); const remoteMetadataList: DocMetadata[] = await getAllMetadata(remoteDir); diff --git a/src/remote/push_worker.ts b/src/remote/push_worker.ts index 37ae1414..5efffa06 100644 --- a/src/remote/push_worker.ts +++ b/src/remote/push_worker.ts @@ -12,7 +12,7 @@ import { GitDDBInterface } from '../types_gitddb'; import { ChangedFile, NormalizedCommit, SyncResultPush, TaskMetadata } from '../types'; import { SyncInterface } from '../types_sync'; import { getChanges, getCommitLogs } from './worker_utils'; -import { RemoteEngine } from './remote_engine'; +import { RemoteEngine, wrappingRemoteEngineError } from './remote_engine'; /** * Push and get changes @@ -112,13 +112,17 @@ export async function pushWorker ( } // Push - await RemoteEngine[sync.engine].push( - gitDDB.workingDir, - sync.options, - sync.remoteName, - gitDDB.defaultBranch, - gitDDB.defaultBranch - ); + await RemoteEngine[sync.engine] + .push( + gitDDB.workingDir, + sync.options, + sync.remoteName, + gitDDB.defaultBranch, + gitDDB.defaultBranch + ) + .catch(err => { + throw wrappingRemoteEngineError(err); + }); let remoteChanges: ChangedFile[] | undefined; if (skipGetChanges) { remoteChanges = undefined; diff --git a/src/remote/sync_worker.ts b/src/remote/sync_worker.ts index 7ebdae55..1f80ff31 100644 --- a/src/remote/sync_worker.ts +++ b/src/remote/sync_worker.ts @@ -25,30 +25,37 @@ import { SyncInterface } from '../types_sync'; import { pushWorker } from './push_worker'; import { calcDistance, getAndWriteLocalChanges, getCommitLogs } from './worker_utils'; import { merge } from './3way_merge'; -import { RemoteEngine } from './remote_engine'; +import { RemoteEngine, wrappingRemoteEngineError } from './remote_engine'; import { Err } from '../error'; /** * sync_worker * - * @throws {@link RemoteErr.InvalidGitRemoteError} (from fetch(), push()) - * @throws {@link RemoteErr.InvalidURLFormatError} (from fetch(), push(), combineDatabaseWithTheirs()) - * @throws {@link RemoteErr.NetworkError} (from fetch(), push(), combineDatabaseWithTheirs()) - * @throws {@link RemoteErr.HTTPError401AuthorizationRequired} (from fetch(), push(), combineDatabaseWithTheirs()) - * @throws {@link RemoteErr.HTTPError404NotFound} (from fetch(), push(), combineDatabaseWithTheirs()) - * @throws {@link RemoteErr.CannotConnectError} (from fetch()), push(), combineDatabaseWithTheirs()) - * @throws {@link RemoteErr.HttpProtocolRequiredError} (from fetch(), push(), combineDatabaseWithTheirs()) - * @throws {@link RemoteErr.InvalidRepositoryURLError} (from fetch(), push(), combineDatabaseWithTheirs()) - * @throws {@link RemoteErr.InvalidSSHKeyPathError} (from fetch(), push(), combineDatabaseWithTheirs()) - * @throws {@link RemoteErr.InvalidAuthenticationTypeError} (from fetch(), push(), combineDatabaseWithTheirs()) - * - * @throws {@link HTTPError403Forbidden} (from push()) - * @throws {@link UnfetchedCommitExistsError} (from push()) - * * @throws {@link Err.NoMergeBaseFoundError} * @throws {@link Err.ThreeWayMergeError} * @throws {@link Err.CannotDeleteDataError} * + * @throws {@link RemoteErr.InvalidGitRemoteError} (from fetch(), pushWorker()) + * @throws {@link RemoteErr.InvalidURLFormatError} (from fetch(), pushWorker()) + * @throws {@link RemoteErr.NetworkError} (from fetch(), pushWorker()) + * @throws {@link RemoteErr.HTTPError401AuthorizationRequired} (from fetch(), pushWorker()) + * @throws {@link RemoteErr.HTTPError404NotFound} (from fetch(), pushWorker()) + * @throws {@link RemoteErr.CannotConnectError} (from fetch()), pushWorker()) + * @throws {@link RemoteErr.HttpProtocolRequiredError} (from fetch(), pushWorker()) + * @throws {@link RemoteErr.InvalidRepositoryURLError} (from fetch(), pushWorker()) + * @throws {@link RemoteErr.InvalidSSHKeyPathError} (from fetch(), pushWorker()) + * @throws {@link RemoteErr.InvalidAuthenticationTypeError} (from fetch(), pushWorker()) + * + * @throws {@link HTTPError403Forbidden} (from pushWorker()) + * @throws {@link UnfetchedCommitExistsError} (from pushWorker()) + * + * @throws {@link Err.InvalidConflictStateError} (from merge()) + * @throws {@link Err.CannotDeleteDataError} (from merge()) + * @throws {@link Err.InvalidDocTypeError} (from merge()) + * @throws {@link Err.InvalidConflictResolutionStrategyError} (from merge()) + * @throws {@link Err.CannotCreateDirectoryError} (from merge()) + * @throws {@link Err.InvalidJsonObjectError} (from merge()) + * @throws {@link Err.InvalidJsonObjectError} (from getChanges()) * * @@ -70,12 +77,11 @@ export async function syncWorker ( /** * Fetch */ - await RemoteEngine[sync.engine].fetch( - gitDDB.workingDir, - sync.options, - sync.remoteName, - gitDDB.logger - ); + await RemoteEngine[sync.engine] + .fetch(gitDDB.workingDir, sync.options, sync.remoteName, gitDDB.logger) + .catch(err => { + throw wrappingRemoteEngineError(err); + }); /** * Calc distance From 2f6eec935934c418e06b3144eb726ef8017fa8f9 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 28 Jul 2021 18:40:07 +0900 Subject: [PATCH 078/297] docs: add doc about errors --- src/remote/worker_utils.ts | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/remote/worker_utils.ts b/src/remote/worker_utils.ts index 09fd7bb5..1430fab8 100644 --- a/src/remote/worker_utils.ts +++ b/src/remote/worker_utils.ts @@ -10,7 +10,7 @@ import nodePath from 'path'; import git, { ReadBlobResult, ReadCommitResult } from 'isomorphic-git'; import fs from 'fs-extra'; import { normalizeCommit, toSortedJSONString, utf8decode } from '../utils'; -import { GIT_DOCUMENTDB_METADATA_DIR, JSON_EXT } from '../const'; +import { JSON_EXT } from '../const'; import { Err } from '../error'; import { ChangedFile, @@ -42,10 +42,12 @@ export async function writeBlobToFile ( await fs.writeFile(filePath, data); } -export /** +/** + * getFatDocFromData + * * @throws {@link Err.InvalidJsonObjectError} */ -async function getFatDocFromData ( +export async function getFatDocFromData ( data: string | Uint8Array, fullDocPath: string, docType: DocType @@ -96,6 +98,11 @@ async function getFatDocFromData ( return fatDoc!; } +/** + * getFatDocFromOid + * + * @throws {@link Err.InvalidJsonObjectError} (from getFatDocFromReadBlobResult) + */ export async function getFatDocFromOid ( workingDir: string, fullDocPath: string, @@ -111,6 +118,8 @@ export async function getFatDocFromOid ( } /** + * getFatDocFromReadBlobResult + * * @throws {@link Err.InvalidJsonObjectError} */ export function getFatDocFromReadBlobResult ( @@ -135,7 +144,7 @@ export function getFatDocFromReadBlobResult ( /** * Get changed files * - * @throws {@link Err.InvalidJsonObjectError} (from getDocument()) + * @throws {@link Err.InvalidJsonObjectError} (from getFatDocFromOid) * * @internal */ @@ -202,7 +211,8 @@ export async function getChanges ( /** * Get and write changed files on local * - * @throws {@link Err.InvalidJsonObjectError} (from getDocument()) + * @throws {@link Err.InvalidJsonObjectError} (from getFatDocFromOid) + * @throws {@link Err.CannotCreateDirectoryError} (from writeBlobToFile) * * @internal */ From dbc1cfc2999c52940b1eed4f4f91796c83076041 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 28 Jul 2021 18:42:51 +0900 Subject: [PATCH 079/297] fix: do not retry checkFetch --- src/remote/sync.ts | 84 +++++++++++++++++++--------------------------- 1 file changed, 35 insertions(+), 49 deletions(-) diff --git a/src/remote/sync.ts b/src/remote/sync.ts index 737b00fc..13dae711 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -112,6 +112,7 @@ export function encodeToGitRemoteName (remoteURL: string) { * @throws {@link Err.PushWorkerError} (from Sync#init()) * @throws {@link Err.SyncWorkerError} (from Sync#init()) * @throws {@link Err.NoMergeBaseFoundError} + * * @throws {@link Err.PushNotAllowedError} (from Sync#init()) * * @internal @@ -491,56 +492,41 @@ export class Sync implements SyncInterface { }); } - for (let i = 0; i < NETWORK_RETRY; i++) { + // eslint-disable-next-line no-await-in-loop + const remoteResult: boolean | Error = await RemoteEngine[this._engine] + .checkFetch( + this._gitDDB.workingDir, + this._options, + this.remoteName, + this._gitDDB.logger + ) + .catch(err => err); + + if (typeof remoteResult === 'boolean') { + // nop + } + else if (remoteResult instanceof RemoteEngineError.InvalidGitRemoteError) { + // checkFetch hardly invoke this error because checkFetch is called just after addRemote. + throw wrappingRemoteEngineError(remoteResult); + } + else if ( + remoteResult instanceof RemoteEngineError.InvalidURLFormatError || + remoteResult instanceof RemoteEngineError.InvalidRepositoryURLError || + remoteResult instanceof RemoteEngineError.InvalidSSHKeyPathError || + remoteResult instanceof RemoteEngineError.InvalidAuthenticationTypeError || + remoteResult instanceof RemoteEngineError.HTTPError401AuthorizationRequired || + remoteResult instanceof RemoteEngineError.NetworkError || + remoteResult instanceof RemoteEngineError.CannotConnectError + ) { + throw wrappingRemoteEngineError(remoteResult); + } + else if (remoteResult instanceof RemoteEngineError.HTTPError404NotFound) { + // Try to create repository by octokit // eslint-disable-next-line no-await-in-loop - const remoteResult: boolean | Error = await RemoteEngine[this._engine] - .checkFetch( - this._gitDDB.workingDir, - this._options, - this.remoteName, - this._gitDDB.logger - ) - .catch(err => err); - - if (typeof remoteResult === 'boolean') { - break; - } - else if (remoteResult instanceof RemoteEngineError.InvalidGitRemoteError) { - // checkFetch hardly invoke this error because checkFetch is called just after addRemote. - throw wrappingRemoteEngineError(remoteResult); - } - else if ( - remoteResult instanceof RemoteEngineError.InvalidURLFormatError || - remoteResult instanceof RemoteEngineError.InvalidRepositoryURLError || - remoteResult instanceof RemoteEngineError.InvalidSSHKeyPathError || - remoteResult instanceof RemoteEngineError.InvalidAuthenticationTypeError || - remoteResult instanceof RemoteEngineError.HTTPError401AuthorizationRequired - ) { - throw wrappingRemoteEngineError(remoteResult); - } - else if ( - remoteResult instanceof RemoteEngineError.NetworkError || - remoteResult instanceof RemoteEngineError.CannotConnectError - ) { - if (i === NETWORK_RETRY - 1) { - throw wrappingRemoteEngineError(remoteResult); - } - else { - // eslint-disable-next-line no-await-in-loop - await sleep(NETWORK_RETRY_INTERVAL); - continue; - } - } - else if (remoteResult instanceof RemoteEngineError.HTTPError404NotFound) { - // Try to create repository by octokit - // eslint-disable-next-line no-await-in-loop - await this.remoteRepository.create().catch(err => { - throw new Err.CannotCreateRemoteRepositoryError(err.message); - }); - - isNewRemoteRepository = true; - break; - } + await this.remoteRepository.create().catch(err => { + throw new Err.CannotCreateRemoteRepositoryError(err.message); + }); + isNewRemoteRepository = true; } let syncResult: SyncResult = { From c38c818f587c2095a9c99d5fa4f38b9be111c14a Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 28 Jul 2021 18:43:51 +0900 Subject: [PATCH 080/297] fix: do not retry tryPush and trySync for network error --- src/remote/sync.ts | 403 ++++++++++++++++++--------------------------- src/types_sync.ts | 2 - 2 files changed, 160 insertions(+), 245 deletions(-) diff --git a/src/remote/sync.ts b/src/remote/sync.ts index 13dae711..0b8abef2 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -665,227 +665,38 @@ export class Sync implements SyncInterface { } /** - * Try to push with retries + * Try to push * - * @throws {@link Err.PushNotAllowedError} (from this and enqueuePushTask) - - * @public - */ - // eslint-disable-next-line complexity - async tryPush (): Promise { - if (this._isClosed) return { action: 'canceled' }; - if (this._options.syncDirection === 'pull') { - throw new Err.PushNotAllowedError(this._options.syncDirection); - } - if (this._retrySyncCounter === 0) { - this._retrySyncCounter = this._options.retry! + 1; - } - - while (this._retrySyncCounter > 0) { - // eslint-disable-next-line no-await-in-loop - const resultOrError = await this.enqueuePushTask().catch((err: Error) => err); - - let error: Error | undefined; - let result: SyncResultPush | SyncResultCancel | undefined; - if (resultOrError instanceof Error) { - error = resultOrError; - } - else { - result = resultOrError; - } - - if (error instanceof RemoteErr.UnfetchedCommitExistsError) { - if (this._options.syncDirection === 'push') { - if (this._options.combineDbStrategy === 'replace-with-ours') { - // TODO: Exec replace-with-ours instead of throw error - } - else { - throw error; - } - } - } - - if (error) { - this._gitDDB.logger.debug('Push failed: ' + error.message); - this._retrySyncCounter--; - if (this._retrySyncCounter === 0) { - throw error; - } - } - - if (result && result.action === 'canceled') { - return result; - } - - if (error === undefined && result !== undefined) { - this._retrySyncCounter = 0; - return result; - } - - // eslint-disable-next-line no-await-in-loop - if (!(await this.canNetworkConnection())) { - // Retry to connect due to network error. - this._gitDDB.logger.debug( - CONSOLE_STYLE.bgRed().tag()`...retryPush: ${this.currentRetries().toString()}` - ); - // eslint-disable-next-line no-await-in-loop - await sleep(this._options.retryInterval!); - } - else { - this._retrySyncCounter = 0; - throw error; - } - } - // This line is reached when cancel() set _retrySyncCounter to 0; - const cancel: SyncResultCancel = { action: 'canceled' }; - this._retrySyncCounter = 0; - return cancel; - } - - /** - * Try to sync with retries - * @throws {@link Err.PushNotAllowedError} - * @throws {@link Err.CombineDatabaseError} - * - * @throws {@link Err.NoMergeBaseFoundError} (from syncWorker) - * - * @throws {@link RemoteErr.InvalidGitRemoteError} (from syncWorker) - * @throws {@link RemoteErr.InvalidURLFormatError} (from syncWorker) - * @throws {@link RemoteErr.NetworkError} (from syncWorker) - * @throws {@link RemoteErr.HTTPError401AuthorizationRequired} (from syncWorker) - * @throws {@link RemoteErr.HTTPError404NotFound} (from syncWorker) * - * @throws {@link RemoteErr.CannotConnectError} (from syncWorker) - * @throws {@link RemoteErr.HttpProtocolRequiredError} (from syncWorker) - * @throws {@link RemoteErr.InvalidRepositoryURLError} (from syncWorker) - * @throws {@link RemoteErr.InvalidSSHKeyPathError} (from syncWorker) - * @throws {@link RemoteErr.InvalidAuthenticationTypeError} (from syncWorker) - * - * @throws {@link RemoteErr.HTTPError403Forbidden} (from syncWorker) - * @throws {@link RemoteErr.UnfetchedCommitExistsError} (from syncWorker) - * @throws {@link Err.ThreeWayMergeError} (from syncWorker) - * @throws {@link Err.CannotDeleteDataError} (from syncWorker) - * @throws {@link Err.InvalidJsonObjectError} (from syncWorker) + * @throws {@link InvalidGitRemoteError} (from pushWorker()) + * @throws {@link UnfetchedCommitExistsError} (from pushWorker()) + * @throws {@link InvalidURLFormatError} (from pushWorker()) + * @throws {@link NetworkError} (from pushWorker()) + * @throws {@link HTTPError401AuthorizationRequired} (from pushWorker()) + * @throws {@link HTTPError404NotFound} (from pushWorker()) + * @throws {@link HTTPError403Forbidden} (from pushWorker()) + * @throws {@link CannotConnectError} (from pushWorker()) + * @throws {@link UnfetchedCommitExistsError} (from pushWorker()) + * @throws {@link CannotConnectError} (from pushWorker()) + * @throws {@link HttpProtocolRequiredError} (from pushWorker()) + * @throws {@link InvalidRepositoryURLError} (from pushWorker()) + * @throws {@link InvalidSSHKeyPathError} (from pushWorker()) + * @throws {@link InvalidAuthenticationTypeError} (from pushWorker()) + * @throws {@link Err.InvalidJsonObjectError} (from pushWorker()) * * @public */ // eslint-disable-next-line complexity - async trySync (): Promise { + async tryPush (): Promise { if (this._isClosed) return { action: 'canceled' }; if (this._options.syncDirection === 'pull') { throw new Err.PushNotAllowedError(this._options.syncDirection); } - if (this._retrySyncCounter === 0) { - this._retrySyncCounter = this._options.retry! + 1; - } - - while (this._retrySyncCounter > 0) { - // eslint-disable-next-line no-await-in-loop - const resultOrError = await this.enqueueSyncTask().catch((err: Error) => err); - let error: Error | undefined; - let result: SyncResult | undefined; - if (resultOrError instanceof Error) { - error = resultOrError; - } - else if ( - resultOrError.action === 'merge and push error' || - resultOrError.action === 'resolve conflicts and push error' - ) { - result = resultOrError; - error = resultOrError.error; - } - else { - result = resultOrError; - } - - if (error instanceof Err.NoMergeBaseFoundError) { - if (this._options.combineDbStrategy === 'throw-error') { - throw error; - } - else if (this._options.combineDbStrategy === 'combine-head-with-theirs') { - // return SyncResultCombineDatabase - // eslint-disable-next-line no-await-in-loop - const syncResultCombineDatabase = await combineDatabaseWithTheirs( - this._gitDDB, - this._options, - this.remoteName - ).catch(err => { - // throw new Err.CombineDatabaseError(err.message); - error = new Err.CombineDatabaseError(err.message); - return undefined; - }); - if (syncResultCombineDatabase !== undefined) { - // eslint-disable-next-line no-loop-func - this.eventHandlers.combine.forEach(callback => - callback.func(syncResultCombineDatabase.duplicates) - ); - return syncResultCombineDatabase; - } - } - } - - if (error) { - this._gitDDB.logger.debug('Sync or push failed: ' + error.message); - this._retrySyncCounter--; - if (this._retrySyncCounter === 0) { - throw error; - } - } - - if (result && result.action === 'canceled') { - return result; - } - - if (error === undefined && result !== undefined) { - // No error - this._retrySyncCounter = 0; - return result; - } - - if ( - // eslint-disable-next-line no-await-in-loop - !(await this.canNetworkConnection()) || - error instanceof RemoteErr.UnfetchedCommitExistsError - ) { - // Retry for the following reasons: - // - Network connection may be improved next time. - // - Problem will be resolved by sync again. - // - 'push' action throws UnfetchedCommitExistsError - // - push_worker in 'merge and push' action throws UnfetchedCommitExistsError - // - push_worker in 'resolve conflicts and push' action throws UnfetchedCommitExistsError - this._gitDDB.logger.debug( - CONSOLE_STYLE.bgRed().tag()`...retrySync: ${this.currentRetries().toString()}` - ); - // eslint-disable-next-line no-await-in-loop - await sleep(this._options.retryInterval!); - } - else { - // Throw error - this._retrySyncCounter = 0; - throw error; - } - } - // This line is reached when cancel() set _retrySyncCounter to 0; - const cancel: SyncResultCancel = { action: 'canceled' }; - this._retrySyncCounter = 0; - return cancel; - } - - /** - * Enqueue push task to TaskQueue - * - * @throws {@link Err.PushWorkerError} - * @throws {@link RemoteEErr.UnfetchedCommitExistsError} - * @throws {@link Err.PushNotAllowedError} - * - * @public - */ - enqueuePushTask (): Promise { - if (this._options.syncDirection === 'pull') { - throw new Err.PushNotAllowedError(this._options.syncDirection); - } + /** + * Enqueue pushWorker + */ const taskId = this._gitDDB.taskQueue.newTaskId(); const callback = ( resolve: (value: SyncResultPush | SyncResultCancel) => void, @@ -934,9 +745,6 @@ export class Sync implements SyncInterface { }) .catch(err => { // console.log(`Error in push_worker: ${err}`); - if (!(err instanceof RemoteErr.UnfetchedCommitExistsError)) { - err = new Err.PushWorkerError(err.message); - } this.eventHandlers.error.forEach(listener => { listener.func(err, { ...taskMetadata, @@ -965,45 +773,163 @@ export class Sync implements SyncInterface { }; }; - return new Promise( + const resultOrError = await new Promise( (resolve: (value: SyncResultPush | SyncResultCancel) => void, reject) => { this._gitDDB.taskQueue.pushToTaskQueue(task(resolve, reject)); // this._gitDDB.taskQueue.unshiftSyncTaskToTaskQueue(task(resolve, reject)); } - ); + ).catch((err: Error) => err); + + if (resultOrError instanceof Error) { + if (resultOrError instanceof RemoteErr.UnfetchedCommitExistsError) { + if (this._options.syncDirection === 'push') { + if (this._options.combineDbStrategy === 'replace-with-ours') { + // TODO: Exec replace-with-ours instead of throw error + } + } + } + // Fatal error. Don't retry. + this.pause(); + throw resultOrError; + } + + return resultOrError; } /** - * Enqueue sync task to TaskQueue + * Try to sync with retries * * @throws {@link Err.PushNotAllowedError} + * @throws {@link Err.CombineDatabaseError} * - * @throws {@link Err.NoMergeBaseFoundError} (from syncWorker) - * - * @throws {@link RemoteErr.InvalidGitRemoteError} (from syncWorker) - * @throws {@link RemoteErr.InvalidURLFormatError} (from syncWorker) - * @throws {@link RemoteErr.NetworkError} (from syncWorker) - * @throws {@link RemoteErr.HTTPError401AuthorizationRequired} (from syncWorker) - * @throws {@link RemoteErr.HTTPError404NotFound} (from syncWorker) - * - * @throws {@link RemoteErr.CannotConnectError} (from syncWorker) - * @throws {@link RemoteErr.HttpProtocolRequiredError} (from syncWorker) - * @throws {@link RemoteErr.InvalidRepositoryURLError} (from syncWorker) - * @throws {@link RemoteErr.InvalidSSHKeyPathError} (from syncWorker) - * @throws {@link RemoteErr.InvalidAuthenticationTypeError} (from syncWorker) + * @throws {@link Err.NoMergeBaseFoundError} (from syncWorker()) + * @throws {@link RemoteErr.InvalidGitRemoteError} (from syncWorker()) + * @throws {@link RemoteErr.InvalidURLFormatError} (from syncWorker()) + * @throws {@link RemoteErr.NetworkError} (from syncWorker()) + * @throws {@link RemoteErr.HTTPError401AuthorizationRequired} (from syncWorker()) + * @throws {@link RemoteErr.HTTPError404NotFound} (from syncWorker()) + * @throws {@link RemoteErr.CannotConnectError} (from syncWorker()) + * @throws {@link RemoteErr.HttpProtocolRequiredError} (from syncWorker()) + * @throws {@link RemoteErr.InvalidRepositoryURLError} (from syncWorker()) + * @throws {@link RemoteErr.InvalidSSHKeyPathError} (from syncWorker()) + * @throws {@link RemoteErr.InvalidAuthenticationTypeError} (from syncWorker()) + * @throws {@link RemoteErr.HTTPError403Forbidden} (from syncWorker()) + * @throws {@link RemoteErr.UnfetchedCommitExistsError} (from syncWorker()) + * @throws {@link Err.InvalidConflictStateError} (from syncWorker()) + * @throws {@link Err.CannotDeleteDataError} (from syncWorker()) + * @throws {@link Err.InvalidDocTypeError} (from syncWorker()) + * @throws {@link Err.InvalidConflictResolutionStrategyError} (from syncWorker()) + * @throws {@link Err.CannotCreateDirectoryError} (from syncWorker()) + * @throws {@link Err.InvalidJsonObjectError} (from syncWorker()) * - * @throws {@link RemoteErr.HTTPError403Forbidden} (from syncWorker) - * @throws {@link RemoteErr.UnfetchedCommitExistsError} (from syncWorker) - * @throws {@link Err.ThreeWayMergeError} (from syncWorker) - * @throws {@link Err.CannotDeleteDataError} (from syncWorker) - * @throws {@link Err.InvalidJsonObjectError} (from syncWorker) + * @throws {@link InvalidURLFormatError} (from combineDatabaseWithTheirs()) + * @throws {@link NetworkError} (from combineDatabaseWithTheirs()) + * @throws {@link HTTPError401AuthorizationRequired} (from combineDatabaseWithTheirs()) + * @throws {@link HTTPError404NotFound} (from combineDatabaseWithTheirs()) + * @throws {@link CannotConnectError} (from combineDatabaseWithTheirs()) + * @throws {@link HttpProtocolRequiredError} (from combineDatabaseWithTheirs()) + * @throws {@link InvalidRepositoryURLError} (from combineDatabaseWithTheirs()) + * @throws {@link InvalidSSHKeyPathError} (from combineDatabaseWithTheirs()) + * @throws {@link InvalidAuthenticationTypeError} (from combineDatabaseWithTheirs()) * * @public */ - enqueueSyncTask (): Promise { + // eslint-disable-next-line complexity + async trySync (): Promise { + if (this._isClosed) return { action: 'canceled' }; if (this._options.syncDirection === 'pull') { throw new Err.PushNotAllowedError(this._options.syncDirection); } + if (this._retrySyncCounter === 0) { + this._retrySyncCounter = this._options.retry! + 1; + } + + while (this._retrySyncCounter > 0) { + // eslint-disable-next-line no-await-in-loop + const resultOrError = await this.enqueueSyncTask().catch((err: Error) => err); + + let error: Error | undefined; + let result: SyncResult | undefined; + if (resultOrError instanceof Error) { + error = resultOrError; + } + else if ( + resultOrError.action === 'merge and push error' || + resultOrError.action === 'resolve conflicts and push error' + ) { + result = resultOrError; + error = resultOrError.error; + } + else { + result = resultOrError; + } + + if (error instanceof Err.NoMergeBaseFoundError) { + if (this._options.combineDbStrategy === 'throw-error') { + // nop + } + else if (this._options.combineDbStrategy === 'combine-head-with-theirs') { + // return SyncResultCombineDatabase + // eslint-disable-next-line no-await-in-loop + const syncResultCombineDatabase = await combineDatabaseWithTheirs( + this._gitDDB, + this._options, + this.remoteName + ).catch(err => { + if (err) + // throw new Err.CombineDatabaseError(err.message); + error = new Err.CombineDatabaseError(err.message); + return undefined; + }); + if (syncResultCombineDatabase !== undefined) { + // eslint-disable-next-line no-loop-func + this.eventHandlers.combine.forEach(callback => + callback.func(syncResultCombineDatabase.duplicates) + ); + return syncResultCombineDatabase; + } + } + } + + if (error !== undefined) { + this._gitDDB.logger.debug('trySync failed: ' + error.message); + if (error instanceof RemoteErr.UnfetchedCommitExistsError) { + this._retrySyncCounter--; + if (this._retrySyncCounter === 0) { + this.pause(); + throw error; + } + this._gitDDB.logger.debug( + CONSOLE_STYLE.bgRed().tag()`...retrySync: ${this.currentRetries().toString()}` + ); + // eslint-disable-next-line no-await-in-loop + await sleep(this._options.retryInterval!); + } + else { + // Throw error + this._retrySyncCounter = 0; + this.pause(); + throw error; + } + } + else if (result !== undefined) { + // No error + this._retrySyncCounter = 0; + return result; + } + } + // This line is reached when cancel() set _retrySyncCounter to 0; + const cancel: SyncResultCancel = { action: 'canceled' }; + this._retrySyncCounter = 0; + return cancel; + } + + /** + * Enqueue sync task to TaskQueue + * + * @public + */ + enqueueSyncTask (): Promise { const taskId = this._gitDDB.taskQueue.newTaskId(); const callback = ( resolve: (value: SyncResult) => void, @@ -1091,14 +1017,6 @@ export class Sync implements SyncInterface { }) .catch((err: Error) => { // console.log(`Error in syncWorker: ${err}`); - if ( - !( - err instanceof Err.NoMergeBaseFoundError || - err instanceof RemoteErr.UnfetchedCommitExistsError - ) - ) { - err = new Err.SyncWorkerError(err.message); - } this.eventHandlers.error.forEach(listener => { listener.func(err, { ...taskMetadata, @@ -1129,7 +1047,6 @@ export class Sync implements SyncInterface { return new Promise((resolve: (value: SyncResult) => void, reject) => { this._gitDDB.taskQueue.pushToTaskQueue(task(resolve, reject)); - // this._gitDDB.taskQueue.unshiftSyncTaskToTaskQueue(task(resolve, reject)); }); } diff --git a/src/types_sync.ts b/src/types_sync.ts index 10ef31d6..f64c2bb6 100644 --- a/src/types_sync.ts +++ b/src/types_sync.ts @@ -66,8 +66,6 @@ export interface SyncInterface { tryPush(): Promise; trySync(): Promise; - enqueuePushTask(): Promise; - enqueueSyncTask(): Promise; currentRetries(): number; From a3b5a10024b5351f4094a4f006e08242369e1a49 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Thu, 29 Jul 2021 19:35:15 +0900 Subject: [PATCH 081/297] docs: adding structual exceptions --- docs-api/git-documentdb.collection.delete.md | 2 - .../git-documentdb.collection.delete_1.md | 2 - .../git-documentdb.collection.deletefatdoc.md | 2 - docs-api/git-documentdb.collection.find.md | 2 - .../git-documentdb.collection.findfatdoc.md | 2 - docs-api/git-documentdb.collection.get.md | 2 - ...it-documentdb.collection.getcollections.md | 4 - .../git-documentdb.collection.getdocbyoid.md | 2 - .../git-documentdb.collection.getfatdoc.md | 2 - ...-documentdb.collection.getfatdochistory.md | 2 - ...umentdb.collection.getfatdocoldrevision.md | 2 - .../git-documentdb.collection.gethistory.md | 2 - ...it-documentdb.collection.getoldrevision.md | 2 - docs-api/git-documentdb.collection.insert.md | 22 +- .../git-documentdb.collection.insert_1.md | 22 +- .../git-documentdb.collection.insertfatdoc.md | 22 +- docs-api/git-documentdb.collection.put.md | 20 +- docs-api/git-documentdb.collection.put_1.md | 20 +- .../git-documentdb.collection.putfatdoc.md | 20 +- docs-api/git-documentdb.collection.update.md | 20 +- .../git-documentdb.collection.update_1.md | 20 +- .../git-documentdb.collection.updatefatdoc.md | 20 +- ...git-documentdb.connectionsettingsgithub.md | 1 + .../git-documentdb.connectionsettingsnone.md | 1 + .../git-documentdb.connectionsettingsssh.md | 1 + .../git-documentdb.encodetogitremotename.md | 32 ++ ...db.err.cannotconnecterror._constructor_.md | 26 -- .../git-documentdb.err.cannotconnecterror.md | 32 -- ...documentdb.err.cannotconnecterror.retry.md | 15 - ...nectremoterepositoryerror._constructor_.md | 26 ++ ....err.cannotconnectremoterepositoryerror.md | 32 ++ ...annotconnectremoterepositoryerror.retry.md | 15 + ...etchconnectionfailederror._constructor_.md | 24 -- ...cumentdb.err.fetchconnectionfailederror.md | 26 -- ...etchpermissiondeniederror._constructor_.md | 24 -- ...cumentdb.err.fetchpermissiondeniederror.md | 26 -- ...cumentdb.err.gitpusherror._constructor_.md | 24 -- docs-api/git-documentdb.err.gitpusherror.md | 26 -- ...idauthenticationtypeerror._constructor_.md | 24 -- ...ntdb.err.invalidauthenticationtypeerror.md | 26 -- ...ctresolutionstrategyerror._constructor_.md | 17 + ....invalidconflictresolutionstrategyerror.md | 26 ++ ...invalidrepositoryurlerror._constructor_.md | 24 -- ...ocumentdb.err.invalidrepositoryurlerror.md | 26 -- ...rr.invalidsshkeypatherror._constructor_.md | 17 - ...t-documentdb.err.invalidsshkeypatherror.md | 26 -- ...entdb.err.invalidurlerror._constructor_.md | 24 -- .../git-documentdb.err.invalidurlerror.md | 26 -- docs-api/git-documentdb.err.md | 16 +- ...pushconnectionfailederror._constructor_.md | 24 -- ...ocumentdb.err.pushconnectionfailederror.md | 26 -- ...pushpermissiondeniederror._constructor_.md | 24 -- ...ocumentdb.err.pushpermissiondeniederror.md | 26 -- ...oterepositoryconnecterror._constructor_.md | 24 -- ...mentdb.err.remoterepositoryconnecterror.md | 26 -- ...terepositorynotfounderror._constructor_.md | 24 -- ...entdb.err.remoterepositorynotfounderror.md | 26 -- ....err.syncworkerfetcherror._constructor_.md | 24 -- ...git-documentdb.err.syncworkerfetcherror.md | 26 -- ...nfetchedcommitexistserror._constructor_.md | 17 - ...cumentdb.err.unfetchedcommitexistserror.md | 26 -- docs-api/git-documentdb.gitddbinterface.md | 2 - ...t-documentdb.gitddbinterface.repository.md | 19 -- ...ocumentdb.gitddbinterface.setrepository.md | 26 -- .../git-documentdb.gitdocumentdb.delete.md | 2 - .../git-documentdb.gitdocumentdb.delete_1.md | 2 - ...t-documentdb.gitdocumentdb.deletefatdoc.md | 2 - docs-api/git-documentdb.gitdocumentdb.find.md | 2 - ...git-documentdb.gitdocumentdb.findfatdoc.md | 2 - docs-api/git-documentdb.gitdocumentdb.get.md | 2 - ...documentdb.gitdocumentdb.getcollections.md | 4 - ...it-documentdb.gitdocumentdb.getdocbyoid.md | 2 - .../git-documentdb.gitdocumentdb.getfatdoc.md | 2 - ...cumentdb.gitdocumentdb.getfatdochistory.md | 2 - ...ntdb.gitdocumentdb.getfatdocoldrevision.md | 2 - ...git-documentdb.gitdocumentdb.gethistory.md | 2 - ...documentdb.gitdocumentdb.getoldrevision.md | 2 - .../git-documentdb.gitdocumentdb.insert.md | 22 +- .../git-documentdb.gitdocumentdb.insert_1.md | 22 +- ...t-documentdb.gitdocumentdb.insertfatdoc.md | 22 +- docs-api/git-documentdb.gitdocumentdb.md | 3 +- docs-api/git-documentdb.gitdocumentdb.open.md | 16 +- .../git-documentdb.gitdocumentdb.plugin.md | 26 ++ docs-api/git-documentdb.gitdocumentdb.put.md | 20 +- .../git-documentdb.gitdocumentdb.put_1.md | 20 +- .../git-documentdb.gitdocumentdb.putfatdoc.md | 20 +- ...git-documentdb.gitdocumentdb.repository.md | 26 -- ...-documentdb.gitdocumentdb.setrepository.md | 37 --- docs-api/git-documentdb.gitdocumentdb.sync.md | 47 ++- .../git-documentdb.gitdocumentdb.sync_1.md | 47 ++- .../git-documentdb.gitdocumentdb.update.md | 20 +- .../git-documentdb.gitdocumentdb.update_1.md | 20 +- ...t-documentdb.gitdocumentdb.updatefatdoc.md | 22 +- docs-api/git-documentdb.md | 11 + docs-api/git-documentdb.plugintypes.md | 17 + docs-api/git-documentdb.remoteengine.md | 17 + ...mentdb.remoteengineinterface.checkfetch.md | 15 + ...-documentdb.remoteengineinterface.clone.md | 15 + ...-documentdb.remoteengineinterface.fetch.md | 15 + .../git-documentdb.remoteengineinterface.md | 25 ++ ...t-documentdb.remoteengineinterface.push.md | 15 + ...oteerr.cannotconnecterror._constructor_.md | 24 ++ ...documentdb.remoteerr.cannotconnecterror.md | 27 ++ ...r401authorizationrequired._constructor_.md | 24 ++ ...teerr.httperror401authorizationrequired.md | 25 ++ ...err.httperror403forbidden._constructor_.md | 24 ++ ...umentdb.remoteerr.httperror403forbidden.md | 25 ++ ...eerr.httperror404notfound._constructor_.md | 24 ++ ...cumentdb.remoteerr.httperror404notfound.md | 25 ++ ...idauthenticationtypeerror._constructor_.md | 24 ++ ...emoteerr.invalidauthenticationtypeerror.md | 25 ++ ...err.invalidgitremoteerror._constructor_.md | 24 ++ ...umentdb.remoteerr.invalidgitremoteerror.md | 25 ++ ...invalidrepositoryurlerror._constructor_.md | 24 ++ ...tdb.remoteerr.invalidrepositoryurlerror.md | 25 ++ ...rr.invalidsshkeypatherror._constructor_.md | 24 ++ ...mentdb.remoteerr.invalidsshkeypatherror.md | 25 ++ ...err.invalidurlformaterror._constructor_.md | 24 ++ ...umentdb.remoteerr.invalidurlformaterror.md | 25 ++ docs-api/git-documentdb.remoteerr.md | 32 ++ ...db.remoteerr.networkerror._constructor_.md | 24 ++ .../git-documentdb.remoteerr.networkerror.md | 25 ++ ...nfetchedcommitexistserror._constructor_.md | 24 ++ ...db.remoteerr.unfetchedcommitexistserror.md | 25 ++ ...cumentdb.remoterepository._constructor_.md | 4 - ...git-documentdb.remoterepository.connect.md | 48 --- .../git-documentdb.remoterepository.create.md | 2 +- ...git-documentdb.remoterepository.destroy.md | 2 +- docs-api/git-documentdb.remoterepository.md | 1 - docs-api/git-documentdb.sync._constructor_.md | 1 - ...git-documentdb.sync.credentialcallbacks.md | 19 -- docs-api/git-documentdb.sync.engine.md | 15 + .../git-documentdb.sync.enqueuepushtask.md | 29 -- .../git-documentdb.sync.enqueuesynctask.md | 10 - docs-api/git-documentdb.sync.init.md | 45 ++- docs-api/git-documentdb.sync.md | 9 +- docs-api/git-documentdb.sync.remotename.md | 17 + docs-api/git-documentdb.sync.trypush.md | 34 +- docs-api/git-documentdb.sync.trysync.md | 60 +++- .../git-documentdb.sync.upstreambranch.md | 17 - ...entdb.syncinterface.credentialcallbacks.md | 17 - .../git-documentdb.syncinterface.engine.md | 15 + ...ocumentdb.syncinterface.enqueuepushtask.md | 19 -- ...ocumentdb.syncinterface.enqueuesynctask.md | 19 -- docs-api/git-documentdb.syncinterface.init.md | 9 +- docs-api/git-documentdb.syncinterface.md | 8 +- docs-api/git-documentdb.syncinterface.off.md | 4 +- ...git-documentdb.syncinterface.remotename.md | 15 + ...documentdb.syncinterface.upstreambranch.md | 15 - ...it-documentdb.wrappingremoteengineerror.md | 26 ++ etc/git-documentdb.api.md | 194 ++++++------ package-lock.json | 12 +- package.json | 4 +- src/collection.ts | 187 ++++++----- src/git_documentdb.ts | 297 +++++++++++------- src/remote/net.ts | 138 -------- src/remote/sync.ts | 82 ++--- test/remote_base/net.test.ts | 23 -- test/remote_base/sync.ts | 3 - test/remote_nodegit/sync.test.ts | 5 - 160 files changed, 1851 insertions(+), 1812 deletions(-) create mode 100644 docs-api/git-documentdb.encodetogitremotename.md delete mode 100644 docs-api/git-documentdb.err.cannotconnecterror._constructor_.md delete mode 100644 docs-api/git-documentdb.err.cannotconnecterror.md delete mode 100644 docs-api/git-documentdb.err.cannotconnecterror.retry.md create mode 100644 docs-api/git-documentdb.err.cannotconnectremoterepositoryerror._constructor_.md create mode 100644 docs-api/git-documentdb.err.cannotconnectremoterepositoryerror.md create mode 100644 docs-api/git-documentdb.err.cannotconnectremoterepositoryerror.retry.md delete mode 100644 docs-api/git-documentdb.err.fetchconnectionfailederror._constructor_.md delete mode 100644 docs-api/git-documentdb.err.fetchconnectionfailederror.md delete mode 100644 docs-api/git-documentdb.err.fetchpermissiondeniederror._constructor_.md delete mode 100644 docs-api/git-documentdb.err.fetchpermissiondeniederror.md delete mode 100644 docs-api/git-documentdb.err.gitpusherror._constructor_.md delete mode 100644 docs-api/git-documentdb.err.gitpusherror.md delete mode 100644 docs-api/git-documentdb.err.invalidauthenticationtypeerror._constructor_.md delete mode 100644 docs-api/git-documentdb.err.invalidauthenticationtypeerror.md create mode 100644 docs-api/git-documentdb.err.invalidconflictresolutionstrategyerror._constructor_.md create mode 100644 docs-api/git-documentdb.err.invalidconflictresolutionstrategyerror.md delete mode 100644 docs-api/git-documentdb.err.invalidrepositoryurlerror._constructor_.md delete mode 100644 docs-api/git-documentdb.err.invalidrepositoryurlerror.md delete mode 100644 docs-api/git-documentdb.err.invalidsshkeypatherror._constructor_.md delete mode 100644 docs-api/git-documentdb.err.invalidsshkeypatherror.md delete mode 100644 docs-api/git-documentdb.err.invalidurlerror._constructor_.md delete mode 100644 docs-api/git-documentdb.err.invalidurlerror.md delete mode 100644 docs-api/git-documentdb.err.pushconnectionfailederror._constructor_.md delete mode 100644 docs-api/git-documentdb.err.pushconnectionfailederror.md delete mode 100644 docs-api/git-documentdb.err.pushpermissiondeniederror._constructor_.md delete mode 100644 docs-api/git-documentdb.err.pushpermissiondeniederror.md delete mode 100644 docs-api/git-documentdb.err.remoterepositoryconnecterror._constructor_.md delete mode 100644 docs-api/git-documentdb.err.remoterepositoryconnecterror.md delete mode 100644 docs-api/git-documentdb.err.remoterepositorynotfounderror._constructor_.md delete mode 100644 docs-api/git-documentdb.err.remoterepositorynotfounderror.md delete mode 100644 docs-api/git-documentdb.err.syncworkerfetcherror._constructor_.md delete mode 100644 docs-api/git-documentdb.err.syncworkerfetcherror.md delete mode 100644 docs-api/git-documentdb.err.unfetchedcommitexistserror._constructor_.md delete mode 100644 docs-api/git-documentdb.err.unfetchedcommitexistserror.md delete mode 100644 docs-api/git-documentdb.gitddbinterface.repository.md delete mode 100644 docs-api/git-documentdb.gitddbinterface.setrepository.md create mode 100644 docs-api/git-documentdb.gitdocumentdb.plugin.md delete mode 100644 docs-api/git-documentdb.gitdocumentdb.repository.md delete mode 100644 docs-api/git-documentdb.gitdocumentdb.setrepository.md create mode 100644 docs-api/git-documentdb.plugintypes.md create mode 100644 docs-api/git-documentdb.remoteengine.md create mode 100644 docs-api/git-documentdb.remoteengineinterface.checkfetch.md create mode 100644 docs-api/git-documentdb.remoteengineinterface.clone.md create mode 100644 docs-api/git-documentdb.remoteengineinterface.fetch.md create mode 100644 docs-api/git-documentdb.remoteengineinterface.md create mode 100644 docs-api/git-documentdb.remoteengineinterface.push.md create mode 100644 docs-api/git-documentdb.remoteerr.cannotconnecterror._constructor_.md create mode 100644 docs-api/git-documentdb.remoteerr.cannotconnecterror.md create mode 100644 docs-api/git-documentdb.remoteerr.httperror401authorizationrequired._constructor_.md create mode 100644 docs-api/git-documentdb.remoteerr.httperror401authorizationrequired.md create mode 100644 docs-api/git-documentdb.remoteerr.httperror403forbidden._constructor_.md create mode 100644 docs-api/git-documentdb.remoteerr.httperror403forbidden.md create mode 100644 docs-api/git-documentdb.remoteerr.httperror404notfound._constructor_.md create mode 100644 docs-api/git-documentdb.remoteerr.httperror404notfound.md create mode 100644 docs-api/git-documentdb.remoteerr.invalidauthenticationtypeerror._constructor_.md create mode 100644 docs-api/git-documentdb.remoteerr.invalidauthenticationtypeerror.md create mode 100644 docs-api/git-documentdb.remoteerr.invalidgitremoteerror._constructor_.md create mode 100644 docs-api/git-documentdb.remoteerr.invalidgitremoteerror.md create mode 100644 docs-api/git-documentdb.remoteerr.invalidrepositoryurlerror._constructor_.md create mode 100644 docs-api/git-documentdb.remoteerr.invalidrepositoryurlerror.md create mode 100644 docs-api/git-documentdb.remoteerr.invalidsshkeypatherror._constructor_.md create mode 100644 docs-api/git-documentdb.remoteerr.invalidsshkeypatherror.md create mode 100644 docs-api/git-documentdb.remoteerr.invalidurlformaterror._constructor_.md create mode 100644 docs-api/git-documentdb.remoteerr.invalidurlformaterror.md create mode 100644 docs-api/git-documentdb.remoteerr.md create mode 100644 docs-api/git-documentdb.remoteerr.networkerror._constructor_.md create mode 100644 docs-api/git-documentdb.remoteerr.networkerror.md create mode 100644 docs-api/git-documentdb.remoteerr.unfetchedcommitexistserror._constructor_.md create mode 100644 docs-api/git-documentdb.remoteerr.unfetchedcommitexistserror.md delete mode 100644 docs-api/git-documentdb.remoterepository.connect.md delete mode 100644 docs-api/git-documentdb.sync.credentialcallbacks.md create mode 100644 docs-api/git-documentdb.sync.engine.md delete mode 100644 docs-api/git-documentdb.sync.enqueuepushtask.md create mode 100644 docs-api/git-documentdb.sync.remotename.md delete mode 100644 docs-api/git-documentdb.sync.upstreambranch.md delete mode 100644 docs-api/git-documentdb.syncinterface.credentialcallbacks.md create mode 100644 docs-api/git-documentdb.syncinterface.engine.md delete mode 100644 docs-api/git-documentdb.syncinterface.enqueuepushtask.md delete mode 100644 docs-api/git-documentdb.syncinterface.enqueuesynctask.md create mode 100644 docs-api/git-documentdb.syncinterface.remotename.md delete mode 100644 docs-api/git-documentdb.syncinterface.upstreambranch.md create mode 100644 docs-api/git-documentdb.wrappingremoteengineerror.md delete mode 100644 src/remote/net.ts delete mode 100644 test/remote_base/net.test.ts diff --git a/docs-api/git-documentdb.collection.delete.md b/docs-api/git-documentdb.collection.delete.md index d559ff75..cfff337b 100644 --- a/docs-api/git-documentdb.collection.delete.md +++ b/docs-api/git-documentdb.collection.delete.md @@ -35,8 +35,6 @@ Promise<[DeleteResultJsonDoc](./git-documentdb.deleteresultjsondoc.md) > [Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) (from deleteImpl) -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) (from deleteWorker) - [Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) (from deleteWorker) [Err.DocumentNotFoundError](./git-documentdb.err.documentnotfounderror.md) (from deleteWorker) diff --git a/docs-api/git-documentdb.collection.delete_1.md b/docs-api/git-documentdb.collection.delete_1.md index 928db32e..57b5d1f5 100644 --- a/docs-api/git-documentdb.collection.delete_1.md +++ b/docs-api/git-documentdb.collection.delete_1.md @@ -35,8 +35,6 @@ Promise<[DeleteResultJsonDoc](./git-documentdb.deleteresultjsondoc.md) > [Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) (from deleteImpl) -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) (from deleteWorker) - [Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) (from deleteWorker) [Err.DocumentNotFoundError](./git-documentdb.err.documentnotfounderror.md) (from deleteWorker) diff --git a/docs-api/git-documentdb.collection.deletefatdoc.md b/docs-api/git-documentdb.collection.deletefatdoc.md index adeed87d..b508cb72 100644 --- a/docs-api/git-documentdb.collection.deletefatdoc.md +++ b/docs-api/git-documentdb.collection.deletefatdoc.md @@ -35,8 +35,6 @@ Promise<[DeleteResult](./git-documentdb.deleteresult.md) > [Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) (from deleteImpl) -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) (from deleteWorker) - [Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) (from deleteWorker) [Err.DocumentNotFoundError](./git-documentdb.err.documentnotfounderror.md) (from deleteWorker) diff --git a/docs-api/git-documentdb.collection.find.md b/docs-api/git-documentdb.collection.find.md index 48355f29..0307f4ea 100644 --- a/docs-api/git-documentdb.collection.find.md +++ b/docs-api/git-documentdb.collection.find.md @@ -30,7 +30,5 @@ Promise<[JsonDoc](./git-documentdb.jsondoc.md) \[\]> [Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) - [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) diff --git a/docs-api/git-documentdb.collection.findfatdoc.md b/docs-api/git-documentdb.collection.findfatdoc.md index ba8608a8..fc42edd4 100644 --- a/docs-api/git-documentdb.collection.findfatdoc.md +++ b/docs-api/git-documentdb.collection.findfatdoc.md @@ -30,7 +30,5 @@ Promise<[FatDoc](./git-documentdb.fatdoc.md) \[\]> [Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) - [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) diff --git a/docs-api/git-documentdb.collection.get.md b/docs-api/git-documentdb.collection.get.md index 68d75fba..776709d8 100644 --- a/docs-api/git-documentdb.collection.get.md +++ b/docs-api/git-documentdb.collection.get.md @@ -34,7 +34,5 @@ Promise<[JsonDoc](./git-documentdb.jsondoc.md) \| undefined> [Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) - [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) diff --git a/docs-api/git-documentdb.collection.getcollections.md b/docs-api/git-documentdb.collection.getcollections.md index b9cb6691..aeef665d 100644 --- a/docs-api/git-documentdb.collection.getcollections.md +++ b/docs-api/git-documentdb.collection.getcollections.md @@ -28,7 +28,3 @@ Promise<[ICollection](./git-documentdb.icollection.md) \[\]> Array of Collections which does not include ''. -## Exceptions - -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) - diff --git a/docs-api/git-documentdb.collection.getdocbyoid.md b/docs-api/git-documentdb.collection.getdocbyoid.md index b0207805..73b1655b 100644 --- a/docs-api/git-documentdb.collection.getdocbyoid.md +++ b/docs-api/git-documentdb.collection.getdocbyoid.md @@ -35,7 +35,5 @@ Promise<[Doc](./git-documentdb.doc.md) \| undefined> [Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) - [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) diff --git a/docs-api/git-documentdb.collection.getfatdoc.md b/docs-api/git-documentdb.collection.getfatdoc.md index 9a8617d9..e1cb4800 100644 --- a/docs-api/git-documentdb.collection.getfatdoc.md +++ b/docs-api/git-documentdb.collection.getfatdoc.md @@ -39,7 +39,5 @@ Promise<[FatDoc](./git-documentdb.fatdoc.md) \| undefined> [Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) - [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) diff --git a/docs-api/git-documentdb.collection.getfatdochistory.md b/docs-api/git-documentdb.collection.getfatdochistory.md index a08e6c51..9577eca6 100644 --- a/docs-api/git-documentdb.collection.getfatdochistory.md +++ b/docs-api/git-documentdb.collection.getfatdochistory.md @@ -44,7 +44,5 @@ See [GitDocumentDB.getHistory()](./git-documentdb.gitdocumentdb.gethistory.md) f [Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) - [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) diff --git a/docs-api/git-documentdb.collection.getfatdocoldrevision.md b/docs-api/git-documentdb.collection.getfatdocoldrevision.md index bb1d4591..c5a85861 100644 --- a/docs-api/git-documentdb.collection.getfatdocoldrevision.md +++ b/docs-api/git-documentdb.collection.getfatdocoldrevision.md @@ -52,7 +52,5 @@ collection.getFatDocOldRevision(shortName, 2); // returns a FatDoc two revisions [Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) - [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) diff --git a/docs-api/git-documentdb.collection.gethistory.md b/docs-api/git-documentdb.collection.gethistory.md index 2adc901f..e296419e 100644 --- a/docs-api/git-documentdb.collection.gethistory.md +++ b/docs-api/git-documentdb.collection.gethistory.md @@ -69,7 +69,5 @@ Thus, a history is not [undefined, undefined, file_v2, undefined, file_v2, file_ [Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) - [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) diff --git a/docs-api/git-documentdb.collection.getoldrevision.md b/docs-api/git-documentdb.collection.getoldrevision.md index bf9ac218..b16f19d3 100644 --- a/docs-api/git-documentdb.collection.getoldrevision.md +++ b/docs-api/git-documentdb.collection.getoldrevision.md @@ -45,7 +45,5 @@ collection.getOldRevision(_shortId, 2); // returns a document two revisions olde [Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) - [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) diff --git a/docs-api/git-documentdb.collection.insert.md b/docs-api/git-documentdb.collection.insert.md index b5cf3fc2..28632e21 100644 --- a/docs-api/git-documentdb.collection.insert.md +++ b/docs-api/git-documentdb.collection.insert.md @@ -39,21 +39,25 @@ Promise<[PutResultJsonDoc](./git-documentdb.putresultjsondoc.md) > [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) -[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) (from validateDocument, validateId) +\# from validateDocument, validateId -[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) (from validateDocument, validateId) +[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) -[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) (fromm putImpl) +[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) -[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) (from putImpl) +\# from putImpl -[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) (fromm putWorker) +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) (fromm putWorker) +[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) -[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) (from putWorker) +\# from putWorker -[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) (from putWorker) +[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) -[Err.SameIdExistsError](./git-documentdb.err.sameidexistserror.md) (from putWorker) +[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) + +[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) + +[Err.SameIdExistsError](./git-documentdb.err.sameidexistserror.md) diff --git a/docs-api/git-documentdb.collection.insert_1.md b/docs-api/git-documentdb.collection.insert_1.md index 2b0dcec9..9da0d169 100644 --- a/docs-api/git-documentdb.collection.insert_1.md +++ b/docs-api/git-documentdb.collection.insert_1.md @@ -42,21 +42,25 @@ Promise<[PutResultJsonDoc](./git-documentdb.putresultjsondoc.md) > [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) -[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) (from validateDocument, validateId) +\# from validateDocument, validateId -[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) (from validateDocument, validateId) +[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) -[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) (fromm putImpl) +[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) -[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) (from putImpl) +\# from putImpl -[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) (fromm putWorker) +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) (fromm putWorker) +[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) -[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) (from putWorker) +\# from putWorker -[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) (from putWorker) +[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) -[Err.SameIdExistsError](./git-documentdb.err.sameidexistserror.md) (from putWorker) +[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) + +[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) + +[Err.SameIdExistsError](./git-documentdb.err.sameidexistserror.md) diff --git a/docs-api/git-documentdb.collection.insertfatdoc.md b/docs-api/git-documentdb.collection.insertfatdoc.md index e8746cd4..bf03ed22 100644 --- a/docs-api/git-documentdb.collection.insertfatdoc.md +++ b/docs-api/git-documentdb.collection.insertfatdoc.md @@ -42,21 +42,25 @@ Promise<[PutResult](./git-documentdb.putresult.md) > [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) -[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) (from validateDocument, validateId) +\# from validateDocument, validateId -[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) (from validateDocument, validateId) +[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) -[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) (fromm putImpl) +[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) -[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) (from putImpl) +\# fromm putImpl -[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) (fromm putWorker) +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) (fromm putWorker) +[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) -[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) (from putWorker) +\# from putWorker -[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) (from putWorker) +[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) -[Err.SameIdExistsError](./git-documentdb.err.sameidexistserror.md) (from putWorker) +[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) + +[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) + +[Err.SameIdExistsError](./git-documentdb.err.sameidexistserror.md) diff --git a/docs-api/git-documentdb.collection.put.md b/docs-api/git-documentdb.collection.put.md index 088a30c3..85064a67 100644 --- a/docs-api/git-documentdb.collection.put.md +++ b/docs-api/git-documentdb.collection.put.md @@ -37,19 +37,23 @@ Promise<[PutResultJsonDoc](./git-documentdb.putresultjsondoc.md) > [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) -[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) (from validateDocument, validateId) +\# from validateDocument, validateId -[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) (from validateDocument, validateId) +[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) -[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) (fromm putImpl) +[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) -[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) (from putImpl) +\# from putImpl -[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) (fromm putWorker) +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) (fromm putWorker) +[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) -[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) (from putWorker) +\# from putWorker -[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) (from putWorker) +[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) + +[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) + +[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) diff --git a/docs-api/git-documentdb.collection.put_1.md b/docs-api/git-documentdb.collection.put_1.md index cdb1ccdd..1500efc2 100644 --- a/docs-api/git-documentdb.collection.put_1.md +++ b/docs-api/git-documentdb.collection.put_1.md @@ -42,21 +42,23 @@ Promise<[PutResultJsonDoc](./git-documentdb.putresultjsondoc.md) > [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) -[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) (from validateDocument, validateId) +\# from validateDocument, validateId -[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) (from validateDocument, validateId) +[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) -[Err.InvalidCollectionPathCharacterError](./git-documentdb.err.invalidcollectionpathcharactererror.md) (from validateDocument, validateId) +[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) -[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) (fromm putImpl) +\# from putImpl -[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) (from putImpl) +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) (fromm putWorker) +[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) (fromm putWorker) +\# from putWorker -[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) (from putWorker) +[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) -[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) (from putWorker) +[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) + +[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) diff --git a/docs-api/git-documentdb.collection.putfatdoc.md b/docs-api/git-documentdb.collection.putfatdoc.md index db7fe58e..a8ff41dd 100644 --- a/docs-api/git-documentdb.collection.putfatdoc.md +++ b/docs-api/git-documentdb.collection.putfatdoc.md @@ -44,19 +44,23 @@ Promise<[PutResult](./git-documentdb.putresult.md) > [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) -[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) (from validateDocument, validateId) +\# from validateDocument, validateId -[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) (from validateDocument, validateId) +[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) -[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) (fromm putImpl) +[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) -[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) (from putImpl) +\# from putImpl -[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) (fromm putWorker) +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) (fromm putWorker) +[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) -[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) (from putWorker) +\# from putWorker -[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) (from putWorker) +[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) + +[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) + +[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) diff --git a/docs-api/git-documentdb.collection.update.md b/docs-api/git-documentdb.collection.update.md index cf2a0c31..2a376db1 100644 --- a/docs-api/git-documentdb.collection.update.md +++ b/docs-api/git-documentdb.collection.update.md @@ -41,21 +41,25 @@ Promise<[PutResultJsonDoc](./git-documentdb.putresultjsondoc.md) > [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) -[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) (from validateDocument, validateId) +\# from validateDocument, validateId -[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) (from validateDocument, validateId) +[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) -[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) (fromm putImpl) +[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) -[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) (from putImpl) +\# from putImpl -[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) (fromm putWorker) +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) (fromm putWorker) +[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) -[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) (from putWorker) +\# from putWorker -[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) (from putWorker) +[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) + +[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) + +[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) [Err.DocumentNotFoundError](./git-documentdb.err.documentnotfounderror.md) diff --git a/docs-api/git-documentdb.collection.update_1.md b/docs-api/git-documentdb.collection.update_1.md index 9020cd03..71965279 100644 --- a/docs-api/git-documentdb.collection.update_1.md +++ b/docs-api/git-documentdb.collection.update_1.md @@ -40,21 +40,25 @@ Promise<[PutResultJsonDoc](./git-documentdb.putresultjsondoc.md) > [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) -[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) (from validateDocument, validateId) +\# from validateDocument, validateId -[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) (from validateDocument, validateId) +[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) -[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) (fromm putImpl) +[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) -[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) (from putImpl) +\# from putImpl -[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) (fromm putWorker) +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) (fromm putWorker) +[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) -[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) (from putWorker) +\# from putWorker -[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) (from putWorker) +[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) + +[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) + +[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) [Err.DocumentNotFoundError](./git-documentdb.err.documentnotfounderror.md) diff --git a/docs-api/git-documentdb.collection.updatefatdoc.md b/docs-api/git-documentdb.collection.updatefatdoc.md index 8171e1ce..66f9300a 100644 --- a/docs-api/git-documentdb.collection.updatefatdoc.md +++ b/docs-api/git-documentdb.collection.updatefatdoc.md @@ -42,21 +42,25 @@ Promise<[PutResult](./git-documentdb.putresult.md) > [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) -[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) (from validateDocument, validateId) +\# from validateDocument, validateId -[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) (from validateDocument, validateId) +[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) -[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) (fromm putImpl) +[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) -[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) (from putImpl) +\# fromm putImpl -[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) (fromm putWorker) +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) (fromm putWorker) +[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) -[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) (from putWorker) +\# from putWorker -[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) (from putWorker) +[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) + +[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) + +[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) [Err.DocumentNotFoundError](./git-documentdb.err.documentnotfounderror.md) diff --git a/docs-api/git-documentdb.connectionsettingsgithub.md b/docs-api/git-documentdb.connectionsettingsgithub.md index 40ccf327..77ae60ec 100644 --- a/docs-api/git-documentdb.connectionsettingsgithub.md +++ b/docs-api/git-documentdb.connectionsettingsgithub.md @@ -15,6 +15,7 @@ Connection settings for GitHub ```typescript export declare type ConnectionSettingsGitHub = { type: 'github'; + engine?: string; personalAccessToken?: string; private?: boolean; }; diff --git a/docs-api/git-documentdb.connectionsettingsnone.md b/docs-api/git-documentdb.connectionsettingsnone.md index f5855a8f..13071f30 100644 --- a/docs-api/git-documentdb.connectionsettingsnone.md +++ b/docs-api/git-documentdb.connectionsettingsnone.md @@ -15,5 +15,6 @@ Connection settings do not exist. ```typescript export declare type ConnectionSettingsNone = { type: 'none'; + engine?: string; }; ``` diff --git a/docs-api/git-documentdb.connectionsettingsssh.md b/docs-api/git-documentdb.connectionsettingsssh.md index 55b11e4c..40e7a54d 100644 --- a/docs-api/git-documentdb.connectionsettingsssh.md +++ b/docs-api/git-documentdb.connectionsettingsssh.md @@ -15,6 +15,7 @@ Connection settings for SSH ```typescript export declare type ConnectionSettingsSSH = { type: 'ssh'; + engine?: string; privateKeyPath: string; publicKeyPath: string; passPhrase?: string; diff --git a/docs-api/git-documentdb.encodetogitremotename.md b/docs-api/git-documentdb.encodetogitremotename.md new file mode 100644 index 00000000..96c57a7b --- /dev/null +++ b/docs-api/git-documentdb.encodetogitremotename.md @@ -0,0 +1,32 @@ +--- +sidebar_label: encodeToGitRemoteName() function +title: encodeToGitRemoteName() function +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [encodeToGitRemoteName](./git-documentdb.encodetogitremotename.md) + +## encodeToGitRemoteName() function + +encodeToRemoteName + +Signature: + +```typescript +export declare function encodeToGitRemoteName(remoteURL: string): string; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| remoteURL | string | | + +Returns: + +string + +## Remarks + +Remote name consists of host\_name + hash. hash is generated from remoteURL. Capitalize host name of remoteURL manually when hashes collide because host name is not case sensitive. + diff --git a/docs-api/git-documentdb.err.cannotconnecterror._constructor_.md b/docs-api/git-documentdb.err.cannotconnecterror._constructor_.md deleted file mode 100644 index aac35d67..00000000 --- a/docs-api/git-documentdb.err.cannotconnecterror._constructor_.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -sidebar_label: (constructor) -title: Err.CannotConnectError.(constructor) -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [Err](./git-documentdb.err.md) > [CannotConnectError](./git-documentdb.err.cannotconnecterror.md) > [(constructor)](./git-documentdb.err.cannotconnecterror._constructor_.md) - -## Err.CannotConnectError.(constructor) - -Constructs a new instance of the `CannotConnectError` class - -Signature: - -```typescript -constructor(retry: number, url: string, mes: string); -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| retry | number | | -| url | string | | -| mes | string | | - diff --git a/docs-api/git-documentdb.err.cannotconnecterror.md b/docs-api/git-documentdb.err.cannotconnecterror.md deleted file mode 100644 index 4b03228c..00000000 --- a/docs-api/git-documentdb.err.cannotconnecterror.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -sidebar_label: CannotConnectError -title: Err.CannotConnectError class -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [Err](./git-documentdb.err.md) > [CannotConnectError](./git-documentdb.err.cannotconnecterror.md) - -## Err.CannotConnectError class - - -Signature: - -```typescript -export class CannotConnectError extends BaseError -``` -Extends: - -BaseError - -## Constructors - -| Constructor | Modifiers | Description | -| --- | --- | --- | -| [(constructor)(retry, url, mes)](./git-documentdb.err.cannotconnecterror._constructor_.md) | | Constructs a new instance of the CannotConnectError class | - -## Properties - -| Property | Modifiers | Type | Description | -| --- | --- | --- | --- | -| [retry](./git-documentdb.err.cannotconnecterror.retry.md) | | number | | - diff --git a/docs-api/git-documentdb.err.cannotconnecterror.retry.md b/docs-api/git-documentdb.err.cannotconnecterror.retry.md deleted file mode 100644 index c6355d77..00000000 --- a/docs-api/git-documentdb.err.cannotconnecterror.retry.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -sidebar_label: retry -title: Err.CannotConnectError.retry property -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [Err](./git-documentdb.err.md) > [CannotConnectError](./git-documentdb.err.cannotconnecterror.md) > [retry](./git-documentdb.err.cannotconnecterror.retry.md) - -## Err.CannotConnectError.retry property - -Signature: - -```typescript -retry: number; -``` diff --git a/docs-api/git-documentdb.err.cannotconnectremoterepositoryerror._constructor_.md b/docs-api/git-documentdb.err.cannotconnectremoterepositoryerror._constructor_.md new file mode 100644 index 00000000..bf4dde09 --- /dev/null +++ b/docs-api/git-documentdb.err.cannotconnectremoterepositoryerror._constructor_.md @@ -0,0 +1,26 @@ +--- +sidebar_label: (constructor) +title: Err.CannotConnectRemoteRepositoryError.(constructor) +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [Err](./git-documentdb.err.md) > [CannotConnectRemoteRepositoryError](./git-documentdb.err.cannotconnectremoterepositoryerror.md) > [(constructor)](./git-documentdb.err.cannotconnectremoterepositoryerror._constructor_.md) + +## Err.CannotConnectRemoteRepositoryError.(constructor) + +Constructs a new instance of the `CannotConnectRemoteRepositoryError` class + +Signature: + +```typescript +constructor(retry: number, url: string, mes: string); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| retry | number | | +| url | string | | +| mes | string | | + diff --git a/docs-api/git-documentdb.err.cannotconnectremoterepositoryerror.md b/docs-api/git-documentdb.err.cannotconnectremoterepositoryerror.md new file mode 100644 index 00000000..ec9cc040 --- /dev/null +++ b/docs-api/git-documentdb.err.cannotconnectremoterepositoryerror.md @@ -0,0 +1,32 @@ +--- +sidebar_label: CannotConnectRemoteRepositoryError +title: Err.CannotConnectRemoteRepositoryError class +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [Err](./git-documentdb.err.md) > [CannotConnectRemoteRepositoryError](./git-documentdb.err.cannotconnectremoterepositoryerror.md) + +## Err.CannotConnectRemoteRepositoryError class + + +Signature: + +```typescript +export class CannotConnectRemoteRepositoryError extends BaseError +``` +Extends: + +BaseError + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(retry, url, mes)](./git-documentdb.err.cannotconnectremoterepositoryerror._constructor_.md) | | Constructs a new instance of the CannotConnectRemoteRepositoryError class | + +## Properties + +| Property | Modifiers | Type | Description | +| --- | --- | --- | --- | +| [retry](./git-documentdb.err.cannotconnectremoterepositoryerror.retry.md) | | number | | + diff --git a/docs-api/git-documentdb.err.cannotconnectremoterepositoryerror.retry.md b/docs-api/git-documentdb.err.cannotconnectremoterepositoryerror.retry.md new file mode 100644 index 00000000..dfea0ce5 --- /dev/null +++ b/docs-api/git-documentdb.err.cannotconnectremoterepositoryerror.retry.md @@ -0,0 +1,15 @@ +--- +sidebar_label: retry +title: Err.CannotConnectRemoteRepositoryError.retry property +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [Err](./git-documentdb.err.md) > [CannotConnectRemoteRepositoryError](./git-documentdb.err.cannotconnectremoterepositoryerror.md) > [retry](./git-documentdb.err.cannotconnectremoterepositoryerror.retry.md) + +## Err.CannotConnectRemoteRepositoryError.retry property + +Signature: + +```typescript +retry: number; +``` diff --git a/docs-api/git-documentdb.err.fetchconnectionfailederror._constructor_.md b/docs-api/git-documentdb.err.fetchconnectionfailederror._constructor_.md deleted file mode 100644 index c8885d6c..00000000 --- a/docs-api/git-documentdb.err.fetchconnectionfailederror._constructor_.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -sidebar_label: (constructor) -title: Err.FetchConnectionFailedError.(constructor) -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [Err](./git-documentdb.err.md) > [FetchConnectionFailedError](./git-documentdb.err.fetchconnectionfailederror.md) > [(constructor)](./git-documentdb.err.fetchconnectionfailederror._constructor_.md) - -## Err.FetchConnectionFailedError.(constructor) - -Constructs a new instance of the `FetchConnectionFailedError` class - -Signature: - -```typescript -constructor(mes: unknown); -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| mes | unknown | | - diff --git a/docs-api/git-documentdb.err.fetchconnectionfailederror.md b/docs-api/git-documentdb.err.fetchconnectionfailederror.md deleted file mode 100644 index 78372aef..00000000 --- a/docs-api/git-documentdb.err.fetchconnectionfailederror.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -sidebar_label: FetchConnectionFailedError -title: Err.FetchConnectionFailedError class -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [Err](./git-documentdb.err.md) > [FetchConnectionFailedError](./git-documentdb.err.fetchconnectionfailederror.md) - -## Err.FetchConnectionFailedError class - - -Signature: - -```typescript -export class FetchConnectionFailedError extends BaseError -``` -Extends: - -BaseError - -## Constructors - -| Constructor | Modifiers | Description | -| --- | --- | --- | -| [(constructor)(mes)](./git-documentdb.err.fetchconnectionfailederror._constructor_.md) | | Constructs a new instance of the FetchConnectionFailedError class | - diff --git a/docs-api/git-documentdb.err.fetchpermissiondeniederror._constructor_.md b/docs-api/git-documentdb.err.fetchpermissiondeniederror._constructor_.md deleted file mode 100644 index dd484292..00000000 --- a/docs-api/git-documentdb.err.fetchpermissiondeniederror._constructor_.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -sidebar_label: (constructor) -title: Err.FetchPermissionDeniedError.(constructor) -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [Err](./git-documentdb.err.md) > [FetchPermissionDeniedError](./git-documentdb.err.fetchpermissiondeniederror.md) > [(constructor)](./git-documentdb.err.fetchpermissiondeniederror._constructor_.md) - -## Err.FetchPermissionDeniedError.(constructor) - -Constructs a new instance of the `FetchPermissionDeniedError` class - -Signature: - -```typescript -constructor(mes: unknown); -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| mes | unknown | | - diff --git a/docs-api/git-documentdb.err.fetchpermissiondeniederror.md b/docs-api/git-documentdb.err.fetchpermissiondeniederror.md deleted file mode 100644 index 4a529771..00000000 --- a/docs-api/git-documentdb.err.fetchpermissiondeniederror.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -sidebar_label: FetchPermissionDeniedError -title: Err.FetchPermissionDeniedError class -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [Err](./git-documentdb.err.md) > [FetchPermissionDeniedError](./git-documentdb.err.fetchpermissiondeniederror.md) - -## Err.FetchPermissionDeniedError class - - -Signature: - -```typescript -export class FetchPermissionDeniedError extends BaseError -``` -Extends: - -BaseError - -## Constructors - -| Constructor | Modifiers | Description | -| --- | --- | --- | -| [(constructor)(mes)](./git-documentdb.err.fetchpermissiondeniederror._constructor_.md) | | Constructs a new instance of the FetchPermissionDeniedError class | - diff --git a/docs-api/git-documentdb.err.gitpusherror._constructor_.md b/docs-api/git-documentdb.err.gitpusherror._constructor_.md deleted file mode 100644 index 56859ce6..00000000 --- a/docs-api/git-documentdb.err.gitpusherror._constructor_.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -sidebar_label: (constructor) -title: Err.GitPushError.(constructor) -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [Err](./git-documentdb.err.md) > [GitPushError](./git-documentdb.err.gitpusherror.md) > [(constructor)](./git-documentdb.err.gitpusherror._constructor_.md) - -## Err.GitPushError.(constructor) - -Constructs a new instance of the `GitPushError` class - -Signature: - -```typescript -constructor(mes: string); -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| mes | string | | - diff --git a/docs-api/git-documentdb.err.gitpusherror.md b/docs-api/git-documentdb.err.gitpusherror.md deleted file mode 100644 index 7c948c5a..00000000 --- a/docs-api/git-documentdb.err.gitpusherror.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -sidebar_label: GitPushError -title: Err.GitPushError class -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [Err](./git-documentdb.err.md) > [GitPushError](./git-documentdb.err.gitpusherror.md) - -## Err.GitPushError class - - -Signature: - -```typescript -export class GitPushError extends BaseError -``` -Extends: - -BaseError - -## Constructors - -| Constructor | Modifiers | Description | -| --- | --- | --- | -| [(constructor)(mes)](./git-documentdb.err.gitpusherror._constructor_.md) | | Constructs a new instance of the GitPushError class | - diff --git a/docs-api/git-documentdb.err.invalidauthenticationtypeerror._constructor_.md b/docs-api/git-documentdb.err.invalidauthenticationtypeerror._constructor_.md deleted file mode 100644 index 855416fc..00000000 --- a/docs-api/git-documentdb.err.invalidauthenticationtypeerror._constructor_.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -sidebar_label: (constructor) -title: Err.InvalidAuthenticationTypeError.(constructor) -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [Err](./git-documentdb.err.md) > [InvalidAuthenticationTypeError](./git-documentdb.err.invalidauthenticationtypeerror.md) > [(constructor)](./git-documentdb.err.invalidauthenticationtypeerror._constructor_.md) - -## Err.InvalidAuthenticationTypeError.(constructor) - -Constructs a new instance of the `InvalidAuthenticationTypeError` class - -Signature: - -```typescript -constructor(type: string); -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| type | string | | - diff --git a/docs-api/git-documentdb.err.invalidauthenticationtypeerror.md b/docs-api/git-documentdb.err.invalidauthenticationtypeerror.md deleted file mode 100644 index e074c4e6..00000000 --- a/docs-api/git-documentdb.err.invalidauthenticationtypeerror.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -sidebar_label: InvalidAuthenticationTypeError -title: Err.InvalidAuthenticationTypeError class -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [Err](./git-documentdb.err.md) > [InvalidAuthenticationTypeError](./git-documentdb.err.invalidauthenticationtypeerror.md) - -## Err.InvalidAuthenticationTypeError class - - -Signature: - -```typescript -export class InvalidAuthenticationTypeError extends BaseError -``` -Extends: - -BaseError - -## Constructors - -| Constructor | Modifiers | Description | -| --- | --- | --- | -| [(constructor)(type)](./git-documentdb.err.invalidauthenticationtypeerror._constructor_.md) | | Constructs a new instance of the InvalidAuthenticationTypeError class | - diff --git a/docs-api/git-documentdb.err.invalidconflictresolutionstrategyerror._constructor_.md b/docs-api/git-documentdb.err.invalidconflictresolutionstrategyerror._constructor_.md new file mode 100644 index 00000000..05d08ca5 --- /dev/null +++ b/docs-api/git-documentdb.err.invalidconflictresolutionstrategyerror._constructor_.md @@ -0,0 +1,17 @@ +--- +sidebar_label: (constructor) +title: Err.InvalidConflictResolutionStrategyError.(constructor) +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [Err](./git-documentdb.err.md) > [InvalidConflictResolutionStrategyError](./git-documentdb.err.invalidconflictresolutionstrategyerror.md) > [(constructor)](./git-documentdb.err.invalidconflictresolutionstrategyerror._constructor_.md) + +## Err.InvalidConflictResolutionStrategyError.(constructor) + +Constructs a new instance of the `InvalidConflictResolutionStrategyError` class + +Signature: + +```typescript +constructor(); +``` diff --git a/docs-api/git-documentdb.err.invalidconflictresolutionstrategyerror.md b/docs-api/git-documentdb.err.invalidconflictresolutionstrategyerror.md new file mode 100644 index 00000000..63e2e706 --- /dev/null +++ b/docs-api/git-documentdb.err.invalidconflictresolutionstrategyerror.md @@ -0,0 +1,26 @@ +--- +sidebar_label: InvalidConflictResolutionStrategyError +title: Err.InvalidConflictResolutionStrategyError class +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [Err](./git-documentdb.err.md) > [InvalidConflictResolutionStrategyError](./git-documentdb.err.invalidconflictresolutionstrategyerror.md) + +## Err.InvalidConflictResolutionStrategyError class + + +Signature: + +```typescript +export class InvalidConflictResolutionStrategyError extends BaseError +``` +Extends: + +BaseError + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)()](./git-documentdb.err.invalidconflictresolutionstrategyerror._constructor_.md) | | Constructs a new instance of the InvalidConflictResolutionStrategyError class | + diff --git a/docs-api/git-documentdb.err.invalidrepositoryurlerror._constructor_.md b/docs-api/git-documentdb.err.invalidrepositoryurlerror._constructor_.md deleted file mode 100644 index 45381d50..00000000 --- a/docs-api/git-documentdb.err.invalidrepositoryurlerror._constructor_.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -sidebar_label: (constructor) -title: Err.InvalidRepositoryURLError.(constructor) -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [Err](./git-documentdb.err.md) > [InvalidRepositoryURLError](./git-documentdb.err.invalidrepositoryurlerror.md) > [(constructor)](./git-documentdb.err.invalidrepositoryurlerror._constructor_.md) - -## Err.InvalidRepositoryURLError.(constructor) - -Constructs a new instance of the `InvalidRepositoryURLError` class - -Signature: - -```typescript -constructor(url: unknown); -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| url | unknown | | - diff --git a/docs-api/git-documentdb.err.invalidrepositoryurlerror.md b/docs-api/git-documentdb.err.invalidrepositoryurlerror.md deleted file mode 100644 index 67b3e7d4..00000000 --- a/docs-api/git-documentdb.err.invalidrepositoryurlerror.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -sidebar_label: InvalidRepositoryURLError -title: Err.InvalidRepositoryURLError class -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [Err](./git-documentdb.err.md) > [InvalidRepositoryURLError](./git-documentdb.err.invalidrepositoryurlerror.md) - -## Err.InvalidRepositoryURLError class - - -Signature: - -```typescript -export class InvalidRepositoryURLError extends BaseError -``` -Extends: - -BaseError - -## Constructors - -| Constructor | Modifiers | Description | -| --- | --- | --- | -| [(constructor)(url)](./git-documentdb.err.invalidrepositoryurlerror._constructor_.md) | | Constructs a new instance of the InvalidRepositoryURLError class | - diff --git a/docs-api/git-documentdb.err.invalidsshkeypatherror._constructor_.md b/docs-api/git-documentdb.err.invalidsshkeypatherror._constructor_.md deleted file mode 100644 index 0824a8fa..00000000 --- a/docs-api/git-documentdb.err.invalidsshkeypatherror._constructor_.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -sidebar_label: (constructor) -title: Err.InvalidSSHKeyPathError.(constructor) -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [Err](./git-documentdb.err.md) > [InvalidSSHKeyPathError](./git-documentdb.err.invalidsshkeypatherror.md) > [(constructor)](./git-documentdb.err.invalidsshkeypatherror._constructor_.md) - -## Err.InvalidSSHKeyPathError.(constructor) - -Constructs a new instance of the `InvalidSSHKeyPathError` class - -Signature: - -```typescript -constructor(); -``` diff --git a/docs-api/git-documentdb.err.invalidsshkeypatherror.md b/docs-api/git-documentdb.err.invalidsshkeypatherror.md deleted file mode 100644 index c25c5488..00000000 --- a/docs-api/git-documentdb.err.invalidsshkeypatherror.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -sidebar_label: InvalidSSHKeyPathError -title: Err.InvalidSSHKeyPathError class -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [Err](./git-documentdb.err.md) > [InvalidSSHKeyPathError](./git-documentdb.err.invalidsshkeypatherror.md) - -## Err.InvalidSSHKeyPathError class - - -Signature: - -```typescript -export class InvalidSSHKeyPathError extends BaseError -``` -Extends: - -BaseError - -## Constructors - -| Constructor | Modifiers | Description | -| --- | --- | --- | -| [(constructor)()](./git-documentdb.err.invalidsshkeypatherror._constructor_.md) | | Constructs a new instance of the InvalidSSHKeyPathError class | - diff --git a/docs-api/git-documentdb.err.invalidurlerror._constructor_.md b/docs-api/git-documentdb.err.invalidurlerror._constructor_.md deleted file mode 100644 index 8f1a9be3..00000000 --- a/docs-api/git-documentdb.err.invalidurlerror._constructor_.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -sidebar_label: (constructor) -title: Err.InvalidURLError.(constructor) -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [Err](./git-documentdb.err.md) > [InvalidURLError](./git-documentdb.err.invalidurlerror.md) > [(constructor)](./git-documentdb.err.invalidurlerror._constructor_.md) - -## Err.InvalidURLError.(constructor) - -Constructs a new instance of the `InvalidURLError` class - -Signature: - -```typescript -constructor(url: unknown); -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| url | unknown | | - diff --git a/docs-api/git-documentdb.err.invalidurlerror.md b/docs-api/git-documentdb.err.invalidurlerror.md deleted file mode 100644 index b5ee3519..00000000 --- a/docs-api/git-documentdb.err.invalidurlerror.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -sidebar_label: InvalidURLError -title: Err.InvalidURLError class -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [Err](./git-documentdb.err.md) > [InvalidURLError](./git-documentdb.err.invalidurlerror.md) - -## Err.InvalidURLError class - - -Signature: - -```typescript -export class InvalidURLError extends BaseError -``` -Extends: - -BaseError - -## Constructors - -| Constructor | Modifiers | Description | -| --- | --- | --- | -| [(constructor)(url)](./git-documentdb.err.invalidurlerror._constructor_.md) | | Constructs a new instance of the InvalidURLError class | - diff --git a/docs-api/git-documentdb.err.md b/docs-api/git-documentdb.err.md index 5ae41261..5bc5fed6 100644 --- a/docs-api/git-documentdb.err.md +++ b/docs-api/git-documentdb.err.md @@ -22,7 +22,7 @@ export declare namespace Err | --- | --- | | [AuthenticationTypeNotAllowCreateRepositoryError](./git-documentdb.err.authenticationtypenotallowcreaterepositoryerror.md) | | | [BaseError](./git-documentdb.err.baseerror.md) | BaseError | -| [CannotConnectError](./git-documentdb.err.cannotconnecterror.md) | | +| [CannotConnectRemoteRepositoryError](./git-documentdb.err.cannotconnectremoterepositoryerror.md) | | | [CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) | | | [CannotCreateRemoteRepositoryError](./git-documentdb.err.cannotcreateremoterepositoryerror.md) | | | [CannotCreateRepositoryError](./git-documentdb.err.cannotcreaterepositoryerror.md) | | @@ -34,17 +34,14 @@ export declare namespace Err | [DatabaseCloseTimeoutError](./git-documentdb.err.databaseclosetimeouterror.md) | | | [DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) | | | [DocumentNotFoundError](./git-documentdb.err.documentnotfounderror.md) | | -| [FetchConnectionFailedError](./git-documentdb.err.fetchconnectionfailederror.md) | | -| [FetchPermissionDeniedError](./git-documentdb.err.fetchpermissiondeniederror.md) | | | [FileRemoveTimeoutError](./git-documentdb.err.fileremovetimeouterror.md) | | | [GitMergeBranchError](./git-documentdb.err.gitmergebrancherror.md) | | -| [GitPushError](./git-documentdb.err.gitpusherror.md) | | | [HTTPNetworkError](./git-documentdb.err.httpnetworkerror.md) | | | [HttpProtocolRequiredError](./git-documentdb.err.httpprotocolrequirederror.md) | | | [IntervalTooSmallError](./git-documentdb.err.intervaltoosmallerror.md) | | -| [InvalidAuthenticationTypeError](./git-documentdb.err.invalidauthenticationtypeerror.md) | | | [InvalidCollectionPathCharacterError](./git-documentdb.err.invalidcollectionpathcharactererror.md) | | | [InvalidCollectionPathLengthError](./git-documentdb.err.invalidcollectionpathlengtherror.md) | | +| [InvalidConflictResolutionStrategyError](./git-documentdb.err.invalidconflictresolutionstrategyerror.md) | | | [InvalidConflictStateError](./git-documentdb.err.invalidconflictstateerror.md) | | | [InvalidDbNameCharacterError](./git-documentdb.err.invaliddbnamecharactererror.md) | | | [InvalidDocTypeError](./git-documentdb.err.invaliddoctypeerror.md) | | @@ -53,19 +50,12 @@ export declare namespace Err | [InvalidJsonFileExtensionError](./git-documentdb.err.invalidjsonfileextensionerror.md) | | | [InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) | | | [InvalidLocalDirCharacterError](./git-documentdb.err.invalidlocaldircharactererror.md) | | -| [InvalidRepositoryURLError](./git-documentdb.err.invalidrepositoryurlerror.md) | | -| [InvalidSSHKeyPathError](./git-documentdb.err.invalidsshkeypatherror.md) | | -| [InvalidURLError](./git-documentdb.err.invalidurlerror.md) | | | [InvalidWorkingDirectoryPathLengthError](./git-documentdb.err.invalidworkingdirectorypathlengtherror.md) | | | [NoMergeBaseFoundError](./git-documentdb.err.nomergebasefounderror.md) | | | [PersonalAccessTokenForAnotherAccountError](./git-documentdb.err.personalaccesstokenforanotheraccounterror.md) | | -| [PushConnectionFailedError](./git-documentdb.err.pushconnectionfailederror.md) | | | [PushNotAllowedError](./git-documentdb.err.pushnotallowederror.md) | | -| [PushPermissionDeniedError](./git-documentdb.err.pushpermissiondeniederror.md) | | | [PushWorkerError](./git-documentdb.err.pushworkererror.md) | | | [RemoteAlreadyRegisteredError](./git-documentdb.err.remotealreadyregisterederror.md) | | -| [RemoteRepositoryConnectError](./git-documentdb.err.remoterepositoryconnecterror.md) | | -| [RemoteRepositoryNotFoundError](./git-documentdb.err.remoterepositorynotfounderror.md) | | | [RepositoryNotFoundError](./git-documentdb.err.repositorynotfounderror.md) | | | [RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) | | | [RequestTimeoutError](./git-documentdb.err.requesttimeouterror.md) | | @@ -73,7 +63,6 @@ export declare namespace Err | [SocketTimeoutError](./git-documentdb.err.sockettimeouterror.md) | | | [SyncIntervalLessThanOrEqualToRetryIntervalError](./git-documentdb.err.syncintervallessthanorequaltoretryintervalerror.md) | | | [SyncWorkerError](./git-documentdb.err.syncworkererror.md) | | -| [SyncWorkerFetchError](./git-documentdb.err.syncworkerfetcherror.md) | | | [TaskCancelError](./git-documentdb.err.taskcancelerror.md) | | | [ThreeWayMergeError](./git-documentdb.err.threewaymergeerror.md) | | | [UndefinedDatabaseNameError](./git-documentdb.err.undefineddatabasenameerror.md) | | @@ -82,5 +71,4 @@ export declare namespace Err | [UndefinedPersonalAccessTokenError](./git-documentdb.err.undefinedpersonalaccesstokenerror.md) | | | [UndefinedRemoteURLError](./git-documentdb.err.undefinedremoteurlerror.md) | | | [UndefinedSyncError](./git-documentdb.err.undefinedsyncerror.md) | | -| [UnfetchedCommitExistsError](./git-documentdb.err.unfetchedcommitexistserror.md) | | diff --git a/docs-api/git-documentdb.err.pushconnectionfailederror._constructor_.md b/docs-api/git-documentdb.err.pushconnectionfailederror._constructor_.md deleted file mode 100644 index a4ea2a52..00000000 --- a/docs-api/git-documentdb.err.pushconnectionfailederror._constructor_.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -sidebar_label: (constructor) -title: Err.PushConnectionFailedError.(constructor) -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [Err](./git-documentdb.err.md) > [PushConnectionFailedError](./git-documentdb.err.pushconnectionfailederror.md) > [(constructor)](./git-documentdb.err.pushconnectionfailederror._constructor_.md) - -## Err.PushConnectionFailedError.(constructor) - -Constructs a new instance of the `PushConnectionFailedError` class - -Signature: - -```typescript -constructor(mes: unknown); -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| mes | unknown | | - diff --git a/docs-api/git-documentdb.err.pushconnectionfailederror.md b/docs-api/git-documentdb.err.pushconnectionfailederror.md deleted file mode 100644 index af63945d..00000000 --- a/docs-api/git-documentdb.err.pushconnectionfailederror.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -sidebar_label: PushConnectionFailedError -title: Err.PushConnectionFailedError class -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [Err](./git-documentdb.err.md) > [PushConnectionFailedError](./git-documentdb.err.pushconnectionfailederror.md) - -## Err.PushConnectionFailedError class - - -Signature: - -```typescript -export class PushConnectionFailedError extends BaseError -``` -Extends: - -BaseError - -## Constructors - -| Constructor | Modifiers | Description | -| --- | --- | --- | -| [(constructor)(mes)](./git-documentdb.err.pushconnectionfailederror._constructor_.md) | | Constructs a new instance of the PushConnectionFailedError class | - diff --git a/docs-api/git-documentdb.err.pushpermissiondeniederror._constructor_.md b/docs-api/git-documentdb.err.pushpermissiondeniederror._constructor_.md deleted file mode 100644 index 7dfb4ed6..00000000 --- a/docs-api/git-documentdb.err.pushpermissiondeniederror._constructor_.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -sidebar_label: (constructor) -title: Err.PushPermissionDeniedError.(constructor) -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [Err](./git-documentdb.err.md) > [PushPermissionDeniedError](./git-documentdb.err.pushpermissiondeniederror.md) > [(constructor)](./git-documentdb.err.pushpermissiondeniederror._constructor_.md) - -## Err.PushPermissionDeniedError.(constructor) - -Constructs a new instance of the `PushPermissionDeniedError` class - -Signature: - -```typescript -constructor(mes: unknown); -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| mes | unknown | | - diff --git a/docs-api/git-documentdb.err.pushpermissiondeniederror.md b/docs-api/git-documentdb.err.pushpermissiondeniederror.md deleted file mode 100644 index e6d7775f..00000000 --- a/docs-api/git-documentdb.err.pushpermissiondeniederror.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -sidebar_label: PushPermissionDeniedError -title: Err.PushPermissionDeniedError class -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [Err](./git-documentdb.err.md) > [PushPermissionDeniedError](./git-documentdb.err.pushpermissiondeniederror.md) - -## Err.PushPermissionDeniedError class - - -Signature: - -```typescript -export class PushPermissionDeniedError extends BaseError -``` -Extends: - -BaseError - -## Constructors - -| Constructor | Modifiers | Description | -| --- | --- | --- | -| [(constructor)(mes)](./git-documentdb.err.pushpermissiondeniederror._constructor_.md) | | Constructs a new instance of the PushPermissionDeniedError class | - diff --git a/docs-api/git-documentdb.err.remoterepositoryconnecterror._constructor_.md b/docs-api/git-documentdb.err.remoterepositoryconnecterror._constructor_.md deleted file mode 100644 index e274fe74..00000000 --- a/docs-api/git-documentdb.err.remoterepositoryconnecterror._constructor_.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -sidebar_label: (constructor) -title: Err.RemoteRepositoryConnectError.(constructor) -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [Err](./git-documentdb.err.md) > [RemoteRepositoryConnectError](./git-documentdb.err.remoterepositoryconnecterror.md) > [(constructor)](./git-documentdb.err.remoterepositoryconnecterror._constructor_.md) - -## Err.RemoteRepositoryConnectError.(constructor) - -Constructs a new instance of the `RemoteRepositoryConnectError` class - -Signature: - -```typescript -constructor(mes: unknown); -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| mes | unknown | | - diff --git a/docs-api/git-documentdb.err.remoterepositoryconnecterror.md b/docs-api/git-documentdb.err.remoterepositoryconnecterror.md deleted file mode 100644 index 5c1c6f1c..00000000 --- a/docs-api/git-documentdb.err.remoterepositoryconnecterror.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -sidebar_label: RemoteRepositoryConnectError -title: Err.RemoteRepositoryConnectError class -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [Err](./git-documentdb.err.md) > [RemoteRepositoryConnectError](./git-documentdb.err.remoterepositoryconnecterror.md) - -## Err.RemoteRepositoryConnectError class - - -Signature: - -```typescript -export class RemoteRepositoryConnectError extends BaseError -``` -Extends: - -BaseError - -## Constructors - -| Constructor | Modifiers | Description | -| --- | --- | --- | -| [(constructor)(mes)](./git-documentdb.err.remoterepositoryconnecterror._constructor_.md) | | Constructs a new instance of the RemoteRepositoryConnectError class | - diff --git a/docs-api/git-documentdb.err.remoterepositorynotfounderror._constructor_.md b/docs-api/git-documentdb.err.remoterepositorynotfounderror._constructor_.md deleted file mode 100644 index 98ebc277..00000000 --- a/docs-api/git-documentdb.err.remoterepositorynotfounderror._constructor_.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -sidebar_label: (constructor) -title: Err.RemoteRepositoryNotFoundError.(constructor) -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [Err](./git-documentdb.err.md) > [RemoteRepositoryNotFoundError](./git-documentdb.err.remoterepositorynotfounderror.md) > [(constructor)](./git-documentdb.err.remoterepositorynotfounderror._constructor_.md) - -## Err.RemoteRepositoryNotFoundError.(constructor) - -Constructs a new instance of the `RemoteRepositoryNotFoundError` class - -Signature: - -```typescript -constructor(url: unknown); -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| url | unknown | | - diff --git a/docs-api/git-documentdb.err.remoterepositorynotfounderror.md b/docs-api/git-documentdb.err.remoterepositorynotfounderror.md deleted file mode 100644 index 644d7b6e..00000000 --- a/docs-api/git-documentdb.err.remoterepositorynotfounderror.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -sidebar_label: RemoteRepositoryNotFoundError -title: Err.RemoteRepositoryNotFoundError class -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [Err](./git-documentdb.err.md) > [RemoteRepositoryNotFoundError](./git-documentdb.err.remoterepositorynotfounderror.md) - -## Err.RemoteRepositoryNotFoundError class - - -Signature: - -```typescript -export class RemoteRepositoryNotFoundError extends BaseError -``` -Extends: - -BaseError - -## Constructors - -| Constructor | Modifiers | Description | -| --- | --- | --- | -| [(constructor)(url)](./git-documentdb.err.remoterepositorynotfounderror._constructor_.md) | | Constructs a new instance of the RemoteRepositoryNotFoundError class | - diff --git a/docs-api/git-documentdb.err.syncworkerfetcherror._constructor_.md b/docs-api/git-documentdb.err.syncworkerfetcherror._constructor_.md deleted file mode 100644 index afa2d5e5..00000000 --- a/docs-api/git-documentdb.err.syncworkerfetcherror._constructor_.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -sidebar_label: (constructor) -title: Err.SyncWorkerFetchError.(constructor) -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [Err](./git-documentdb.err.md) > [SyncWorkerFetchError](./git-documentdb.err.syncworkerfetcherror.md) > [(constructor)](./git-documentdb.err.syncworkerfetcherror._constructor_.md) - -## Err.SyncWorkerFetchError.(constructor) - -Constructs a new instance of the `SyncWorkerFetchError` class - -Signature: - -```typescript -constructor(mes: string); -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| mes | string | | - diff --git a/docs-api/git-documentdb.err.syncworkerfetcherror.md b/docs-api/git-documentdb.err.syncworkerfetcherror.md deleted file mode 100644 index 73ef83b9..00000000 --- a/docs-api/git-documentdb.err.syncworkerfetcherror.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -sidebar_label: SyncWorkerFetchError -title: Err.SyncWorkerFetchError class -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [Err](./git-documentdb.err.md) > [SyncWorkerFetchError](./git-documentdb.err.syncworkerfetcherror.md) - -## Err.SyncWorkerFetchError class - - -Signature: - -```typescript -export class SyncWorkerFetchError extends BaseError -``` -Extends: - -BaseError - -## Constructors - -| Constructor | Modifiers | Description | -| --- | --- | --- | -| [(constructor)(mes)](./git-documentdb.err.syncworkerfetcherror._constructor_.md) | | Constructs a new instance of the SyncWorkerFetchError class | - diff --git a/docs-api/git-documentdb.err.unfetchedcommitexistserror._constructor_.md b/docs-api/git-documentdb.err.unfetchedcommitexistserror._constructor_.md deleted file mode 100644 index 8c0d3879..00000000 --- a/docs-api/git-documentdb.err.unfetchedcommitexistserror._constructor_.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -sidebar_label: (constructor) -title: Err.UnfetchedCommitExistsError.(constructor) -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [Err](./git-documentdb.err.md) > [UnfetchedCommitExistsError](./git-documentdb.err.unfetchedcommitexistserror.md) > [(constructor)](./git-documentdb.err.unfetchedcommitexistserror._constructor_.md) - -## Err.UnfetchedCommitExistsError.(constructor) - -Constructs a new instance of the `UnfetchedCommitExistsError` class - -Signature: - -```typescript -constructor(); -``` diff --git a/docs-api/git-documentdb.err.unfetchedcommitexistserror.md b/docs-api/git-documentdb.err.unfetchedcommitexistserror.md deleted file mode 100644 index e14b9756..00000000 --- a/docs-api/git-documentdb.err.unfetchedcommitexistserror.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -sidebar_label: UnfetchedCommitExistsError -title: Err.UnfetchedCommitExistsError class -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [Err](./git-documentdb.err.md) > [UnfetchedCommitExistsError](./git-documentdb.err.unfetchedcommitexistserror.md) - -## Err.UnfetchedCommitExistsError class - - -Signature: - -```typescript -export class UnfetchedCommitExistsError extends BaseError -``` -Extends: - -BaseError - -## Constructors - -| Constructor | Modifiers | Description | -| --- | --- | --- | -| [(constructor)()](./git-documentdb.err.unfetchedcommitexistserror._constructor_.md) | | Constructs a new instance of the UnfetchedCommitExistsError class | - diff --git a/docs-api/git-documentdb.gitddbinterface.md b/docs-api/git-documentdb.gitddbinterface.md index 3aeeb090..19d5c8bc 100644 --- a/docs-api/git-documentdb.gitddbinterface.md +++ b/docs-api/git-documentdb.gitddbinterface.md @@ -50,10 +50,8 @@ export interface GitDDBInterface | [loadDbInfo()](./git-documentdb.gitddbinterface.loaddbinfo.md) | | | [open(options)](./git-documentdb.gitddbinterface.open.md) | \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* Public methods \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* | | [removeSync(remoteURL)](./git-documentdb.gitddbinterface.removesync.md) | | -| [repository()](./git-documentdb.gitddbinterface.repository.md) | | | [saveAppInfo(info)](./git-documentdb.gitddbinterface.saveappinfo.md) | | | [saveAuthor()](./git-documentdb.gitddbinterface.saveauthor.md) | | -| [setRepository(repos)](./git-documentdb.gitddbinterface.setrepository.md) | | | [sync(options, getSyncResult)](./git-documentdb.gitddbinterface.sync.md) | | | [sync(options)](./git-documentdb.gitddbinterface.sync_1.md) | | diff --git a/docs-api/git-documentdb.gitddbinterface.repository.md b/docs-api/git-documentdb.gitddbinterface.repository.md deleted file mode 100644 index 19f775da..00000000 --- a/docs-api/git-documentdb.gitddbinterface.repository.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -sidebar_label: repository() -title: GitDDBInterface.repository() method -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [GitDDBInterface](./git-documentdb.gitddbinterface.md) > [repository](./git-documentdb.gitddbinterface.repository.md) - -## GitDDBInterface.repository() method - -Signature: - -```typescript -repository(): nodegit.Repository | undefined; -``` -Returns: - -nodegit.Repository \| undefined - diff --git a/docs-api/git-documentdb.gitddbinterface.setrepository.md b/docs-api/git-documentdb.gitddbinterface.setrepository.md deleted file mode 100644 index 368c6bb4..00000000 --- a/docs-api/git-documentdb.gitddbinterface.setrepository.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -sidebar_label: setRepository() -title: GitDDBInterface.setRepository() method -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [GitDDBInterface](./git-documentdb.gitddbinterface.md) > [setRepository](./git-documentdb.gitddbinterface.setrepository.md) - -## GitDDBInterface.setRepository() method - -Signature: - -```typescript -setRepository(repos: nodegit.Repository): void; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| repos | nodegit.Repository | | - -Returns: - -void - diff --git a/docs-api/git-documentdb.gitdocumentdb.delete.md b/docs-api/git-documentdb.gitdocumentdb.delete.md index 09dbb3d0..38d37b06 100644 --- a/docs-api/git-documentdb.gitdocumentdb.delete.md +++ b/docs-api/git-documentdb.gitdocumentdb.delete.md @@ -39,8 +39,6 @@ Promise<[DeleteResultJsonDoc](./git-documentdb.deleteresultjsondoc.md) > [Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) (from deleteImpl) -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) (from deleteWorker) - [Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) (from deleteWorker) [Err.DocumentNotFoundError](./git-documentdb.err.documentnotfounderror.md) (from deleteWorker) diff --git a/docs-api/git-documentdb.gitdocumentdb.delete_1.md b/docs-api/git-documentdb.gitdocumentdb.delete_1.md index 3cdd40be..1344f28f 100644 --- a/docs-api/git-documentdb.gitdocumentdb.delete_1.md +++ b/docs-api/git-documentdb.gitdocumentdb.delete_1.md @@ -39,8 +39,6 @@ Promise<[DeleteResultJsonDoc](./git-documentdb.deleteresultjsondoc.md) > [Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) (from deleteImpl) -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) (from deleteWorker) - [Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) (from deleteWorker) [Err.DocumentNotFoundError](./git-documentdb.err.documentnotfounderror.md) (from deleteWorker) diff --git a/docs-api/git-documentdb.gitdocumentdb.deletefatdoc.md b/docs-api/git-documentdb.gitdocumentdb.deletefatdoc.md index 924416c1..9a424bb5 100644 --- a/docs-api/git-documentdb.gitdocumentdb.deletefatdoc.md +++ b/docs-api/git-documentdb.gitdocumentdb.deletefatdoc.md @@ -39,8 +39,6 @@ Promise<[DeleteResult](./git-documentdb.deleteresult.md) > [Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) (from deleteImpl) -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) (from deleteWorker) - [Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) (from deleteWorker) [Err.DocumentNotFoundError](./git-documentdb.err.documentnotfounderror.md) (from deleteWorker) diff --git a/docs-api/git-documentdb.gitdocumentdb.find.md b/docs-api/git-documentdb.gitdocumentdb.find.md index 6ce8f483..5b862c9b 100644 --- a/docs-api/git-documentdb.gitdocumentdb.find.md +++ b/docs-api/git-documentdb.gitdocumentdb.find.md @@ -34,7 +34,5 @@ Promise<[JsonDoc](./git-documentdb.jsondoc.md) \[\]> [Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) - [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) diff --git a/docs-api/git-documentdb.gitdocumentdb.findfatdoc.md b/docs-api/git-documentdb.gitdocumentdb.findfatdoc.md index 6ac58693..6cf1d573 100644 --- a/docs-api/git-documentdb.gitdocumentdb.findfatdoc.md +++ b/docs-api/git-documentdb.gitdocumentdb.findfatdoc.md @@ -34,7 +34,5 @@ Promise<[FatDoc](./git-documentdb.fatdoc.md) \[\]> [Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) - [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) diff --git a/docs-api/git-documentdb.gitdocumentdb.get.md b/docs-api/git-documentdb.gitdocumentdb.get.md index 2b1b926a..371789c4 100644 --- a/docs-api/git-documentdb.gitdocumentdb.get.md +++ b/docs-api/git-documentdb.gitdocumentdb.get.md @@ -36,7 +36,5 @@ Promise<[JsonDoc](./git-documentdb.jsondoc.md) \| undefined> [Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) - [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) diff --git a/docs-api/git-documentdb.gitdocumentdb.getcollections.md b/docs-api/git-documentdb.gitdocumentdb.getcollections.md index 88e21b75..378ec93b 100644 --- a/docs-api/git-documentdb.gitdocumentdb.getcollections.md +++ b/docs-api/git-documentdb.gitdocumentdb.getcollections.md @@ -28,7 +28,3 @@ Promise<[ICollection](./git-documentdb.icollection.md) \[\]> Promise < Collection\[\] > -## Exceptions - -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) - diff --git a/docs-api/git-documentdb.gitdocumentdb.getdocbyoid.md b/docs-api/git-documentdb.gitdocumentdb.getdocbyoid.md index 0af3fa15..039cc5d5 100644 --- a/docs-api/git-documentdb.gitdocumentdb.getdocbyoid.md +++ b/docs-api/git-documentdb.gitdocumentdb.getdocbyoid.md @@ -37,7 +37,5 @@ Promise<[Doc](./git-documentdb.doc.md) \| undefined> [Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) - [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) diff --git a/docs-api/git-documentdb.gitdocumentdb.getfatdoc.md b/docs-api/git-documentdb.gitdocumentdb.getfatdoc.md index 1998be6c..905256c1 100644 --- a/docs-api/git-documentdb.gitdocumentdb.getfatdoc.md +++ b/docs-api/git-documentdb.gitdocumentdb.getfatdoc.md @@ -41,7 +41,5 @@ Promise<[FatDoc](./git-documentdb.fatdoc.md) \| undefined> [Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) - [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) diff --git a/docs-api/git-documentdb.gitdocumentdb.getfatdochistory.md b/docs-api/git-documentdb.gitdocumentdb.getfatdochistory.md index 564d391f..bb58bd08 100644 --- a/docs-api/git-documentdb.gitdocumentdb.getfatdochistory.md +++ b/docs-api/git-documentdb.gitdocumentdb.getfatdochistory.md @@ -46,7 +46,5 @@ Array of FatDoc or undefined. - undefined if a specified data does not exist or [Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) - [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) diff --git a/docs-api/git-documentdb.gitdocumentdb.getfatdocoldrevision.md b/docs-api/git-documentdb.gitdocumentdb.getfatdocoldrevision.md index d008dbc9..f80dde18 100644 --- a/docs-api/git-documentdb.gitdocumentdb.getfatdocoldrevision.md +++ b/docs-api/git-documentdb.gitdocumentdb.getfatdocoldrevision.md @@ -54,7 +54,5 @@ db.getFatDocOldRevision(name, 2); // returns a FatDoc two revisions older than t [Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) - [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) diff --git a/docs-api/git-documentdb.gitdocumentdb.gethistory.md b/docs-api/git-documentdb.gitdocumentdb.gethistory.md index 25c90777..954334c0 100644 --- a/docs-api/git-documentdb.gitdocumentdb.gethistory.md +++ b/docs-api/git-documentdb.gitdocumentdb.gethistory.md @@ -77,7 +77,5 @@ Thus, a history is not [undefined, undefined, file_v2, undefined, file_v2, file_ [Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) - [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) diff --git a/docs-api/git-documentdb.gitdocumentdb.getoldrevision.md b/docs-api/git-documentdb.gitdocumentdb.getoldrevision.md index fc95e0af..4ea99cb2 100644 --- a/docs-api/git-documentdb.gitdocumentdb.getoldrevision.md +++ b/docs-api/git-documentdb.gitdocumentdb.getoldrevision.md @@ -47,7 +47,5 @@ db.getOldRevision(_id, 2); // returns a document two revisions older than the la [Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) - [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) diff --git a/docs-api/git-documentdb.gitdocumentdb.insert.md b/docs-api/git-documentdb.gitdocumentdb.insert.md index 6207b30e..4ddb333c 100644 --- a/docs-api/git-documentdb.gitdocumentdb.insert.md +++ b/docs-api/git-documentdb.gitdocumentdb.insert.md @@ -41,21 +41,25 @@ Promise<[PutResultJsonDoc](./git-documentdb.putresultjsondoc.md) > [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) -[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) (from validateDocument, validateId) +\# from validateDocument, validateId -[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) (from validateDocument, validateId) +[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) -[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) (fromm putImpl) +[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) -[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) (from putImpl) +\# from putImpl -[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) (fromm putWorker) +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) (fromm putWorker) +[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) -[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) (from putWorker) +\# from putWorker -[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) (from putWorker) +[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) -[Err.SameIdExistsError](./git-documentdb.err.sameidexistserror.md) (from putWorker) +[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) + +[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) + +[Err.SameIdExistsError](./git-documentdb.err.sameidexistserror.md) diff --git a/docs-api/git-documentdb.gitdocumentdb.insert_1.md b/docs-api/git-documentdb.gitdocumentdb.insert_1.md index 00421a62..94ec5a80 100644 --- a/docs-api/git-documentdb.gitdocumentdb.insert_1.md +++ b/docs-api/git-documentdb.gitdocumentdb.insert_1.md @@ -44,21 +44,25 @@ Promise<[PutResultJsonDoc](./git-documentdb.putresultjsondoc.md) > [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) -[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) (from validateDocument, validateId) +\# from validateDocument, validateId -[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) (from validateDocument, validateId) +[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) -[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) (fromm putImpl) +[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) -[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) (from putImpl) +\# from putImpl -[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) (fromm putWorker) +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) (fromm putWorker) +[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) -[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) (from putWorker) +\# from putWorker -[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) (from putWorker) +[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) -[Err.SameIdExistsError](./git-documentdb.err.sameidexistserror.md) (from putWorker) +[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) + +[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) + +[Err.SameIdExistsError](./git-documentdb.err.sameidexistserror.md) diff --git a/docs-api/git-documentdb.gitdocumentdb.insertfatdoc.md b/docs-api/git-documentdb.gitdocumentdb.insertfatdoc.md index 1931bcd2..8dffc00e 100644 --- a/docs-api/git-documentdb.gitdocumentdb.insertfatdoc.md +++ b/docs-api/git-documentdb.gitdocumentdb.insertfatdoc.md @@ -44,21 +44,25 @@ Promise<[PutResult](./git-documentdb.putresult.md) > [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) -[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) (from validateDocument, validateId) +\# from validateDocument, validateId -[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) (from validateDocument, validateId) +[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) -[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) (fromm putImpl) +[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) -[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) (from putImpl) +\# from putImpl -[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) (fromm putWorker) +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) (fromm putWorker) +[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) -[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) (from putWorker) +\# from putWorker -[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) (from putWorker) +[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) -[Err.SameIdExistsError](./git-documentdb.err.sameidexistserror.md) (from putWorker) +[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) + +[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) + +[Err.SameIdExistsError](./git-documentdb.err.sameidexistserror.md) diff --git a/docs-api/git-documentdb.gitdocumentdb.md b/docs-api/git-documentdb.gitdocumentdb.md index 7f371183..f793a91d 100644 --- a/docs-api/git-documentdb.gitdocumentdb.md +++ b/docs-api/git-documentdb.gitdocumentdb.md @@ -82,14 +82,13 @@ Call open() before using DB. | [onSyncEvent(remoteURL, event, callback)](./git-documentdb.gitdocumentdb.onsyncevent.md) | | Add SyncEvent handler | | [onSyncEvent(sync, event, callback)](./git-documentdb.gitdocumentdb.onsyncevent_1.md) | | Add SyncEvent handler | | [open(openOptions)](./git-documentdb.gitdocumentdb.open.md) | | Open or create a Git repository | +| [plugin(obj)](./git-documentdb.gitdocumentdb.plugin.md) | static | | | [put(jsonDoc, options)](./git-documentdb.gitdocumentdb.put.md) | | Insert a JSON document if not exists. Otherwise, update it. | | [put(\_id, jsonDoc, options)](./git-documentdb.gitdocumentdb.put_1.md) | | Insert a JSON document if not exists. Otherwise, update it. | | [putFatDoc(name, doc, options)](./git-documentdb.gitdocumentdb.putfatdoc.md) | | Insert data if not exists. Otherwise, update it. | | [removeSync(remoteURL)](./git-documentdb.gitdocumentdb.removesync.md) | | Stop and unregister remote synchronization | -| [repository()](./git-documentdb.gitdocumentdb.repository.md) | | Get a current repository | | [saveAppInfo(info)](./git-documentdb.gitdocumentdb.saveappinfo.md) | | Save app-specific info into .gitddb/app.json | | [saveAuthor()](./git-documentdb.gitdocumentdb.saveauthor.md) | | Save current author to .git/config | -| [setRepository(repos)](./git-documentdb.gitdocumentdb.setrepository.md) | | Set repository | | [sync(options)](./git-documentdb.gitdocumentdb.sync.md) | | Synchronize with a remote repository | | [sync(options, getSyncResult)](./git-documentdb.gitdocumentdb.sync_1.md) | | Synchronize with a remote repository | | [update(jsonDoc, options)](./git-documentdb.gitdocumentdb.update.md) | | Update a JSON document | diff --git a/docs-api/git-documentdb.gitdocumentdb.open.md b/docs-api/git-documentdb.gitdocumentdb.open.md index 56c49c51..851c4338 100644 --- a/docs-api/git-documentdb.gitdocumentdb.open.md +++ b/docs-api/git-documentdb.gitdocumentdb.open.md @@ -40,9 +40,21 @@ Promise<[DatabaseOpenResult](./git-documentdb.databaseopenresult.md) > [Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) +[Err.RepositoryNotFoundError](./git-documentdb.err.repositorynotfounderror.md) may occurs when openOptions.createIfNotExists is false. + +\# from \_createRepository + [Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) -[Err.CannotOpenRepositoryError](./git-documentdb.err.cannotopenrepositoryerror.md) +\# from putWorker -[Err.RepositoryNotFoundError](./git-documentdb.err.repositorynotfounderror.md) may occurs when openOptions.createIfNotExists is false. +[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) + +[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) + +[Err.SameIdExistsError](./git-documentdb.err.sameidexistserror.md) + +[Err.DocumentNotFoundError](./git-documentdb.err.documentnotfounderror.md) + +[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) diff --git a/docs-api/git-documentdb.gitdocumentdb.plugin.md b/docs-api/git-documentdb.gitdocumentdb.plugin.md new file mode 100644 index 00000000..670a3c8e --- /dev/null +++ b/docs-api/git-documentdb.gitdocumentdb.plugin.md @@ -0,0 +1,26 @@ +--- +sidebar_label: plugin() +title: GitDocumentDB.plugin() method +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [GitDocumentDB](./git-documentdb.gitdocumentdb.md) > [plugin](./git-documentdb.gitdocumentdb.plugin.md) + +## GitDocumentDB.plugin() method + +Signature: + +```typescript +static plugin(obj: any): void; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| obj | any | | + +Returns: + +void + diff --git a/docs-api/git-documentdb.gitdocumentdb.put.md b/docs-api/git-documentdb.gitdocumentdb.put.md index 9bfb13de..7f83e0f9 100644 --- a/docs-api/git-documentdb.gitdocumentdb.put.md +++ b/docs-api/git-documentdb.gitdocumentdb.put.md @@ -39,19 +39,23 @@ Promise<[PutResultJsonDoc](./git-documentdb.putresultjsondoc.md) > [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) -[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) (from validateDocument, validateId) +\# from validateDocument, validateId -[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) (from validateDocument, validateId) +[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) -[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) (fromm putImpl) +[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) -[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) (from putImpl) +\# from putImpl -[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) (fromm putWorker) +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) (fromm putWorker) +[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) -[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) (from putWorker) +\# from putWorker -[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) (from putWorker) +[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) + +[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) + +[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) diff --git a/docs-api/git-documentdb.gitdocumentdb.put_1.md b/docs-api/git-documentdb.gitdocumentdb.put_1.md index e03491cb..369c4ec8 100644 --- a/docs-api/git-documentdb.gitdocumentdb.put_1.md +++ b/docs-api/git-documentdb.gitdocumentdb.put_1.md @@ -44,19 +44,23 @@ Promise<[PutResultJsonDoc](./git-documentdb.putresultjsondoc.md) > [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) -[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) (from validateDocument, validateId) +\# from validateDocument, validateId -[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) (from validateDocument, validateId) +[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) -[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) (fromm putImpl) +[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) -[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) (from putImpl) +\# from putImpl -[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) (fromm putWorker) +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) (fromm putWorker) +[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) -[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) (from putWorker) +\# from putWorker -[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) (from putWorker) +[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) + +[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) + +[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) diff --git a/docs-api/git-documentdb.gitdocumentdb.putfatdoc.md b/docs-api/git-documentdb.gitdocumentdb.putfatdoc.md index 6350705e..bc0f8dea 100644 --- a/docs-api/git-documentdb.gitdocumentdb.putfatdoc.md +++ b/docs-api/git-documentdb.gitdocumentdb.putfatdoc.md @@ -46,19 +46,23 @@ Promise<[PutResult](./git-documentdb.putresult.md) > [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) -[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) (from validateDocument, validateId) +\# from validateDocument, validateId -[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) (from validateDocument, validateId) +[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) -[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) (fromm putImpl) +[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) -[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) (from putImpl) +\# from putImpl -[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) (fromm putWorker) +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) (fromm putWorker) +[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) -[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) (from putWorker) +\# from putWorker -[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) (from putWorker) +[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) + +[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) + +[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) diff --git a/docs-api/git-documentdb.gitdocumentdb.repository.md b/docs-api/git-documentdb.gitdocumentdb.repository.md deleted file mode 100644 index d5f97e98..00000000 --- a/docs-api/git-documentdb.gitdocumentdb.repository.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -sidebar_label: repository() -title: GitDocumentDB.repository() method -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [GitDocumentDB](./git-documentdb.gitdocumentdb.md) > [repository](./git-documentdb.gitdocumentdb.repository.md) - -## GitDocumentDB.repository() method - -> Warning: This API is now obsolete. -> -> This will be removed when NodeGit is replaced with isomorphic-git. -> - -Get a current repository - -Signature: - -```typescript -repository(): nodegit.Repository | undefined; -``` -Returns: - -nodegit.Repository \| undefined - diff --git a/docs-api/git-documentdb.gitdocumentdb.setrepository.md b/docs-api/git-documentdb.gitdocumentdb.setrepository.md deleted file mode 100644 index d1029b0d..00000000 --- a/docs-api/git-documentdb.gitdocumentdb.setrepository.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -sidebar_label: setRepository() -title: GitDocumentDB.setRepository() method -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [GitDocumentDB](./git-documentdb.gitdocumentdb.md) > [setRepository](./git-documentdb.gitdocumentdb.setrepository.md) - -## GitDocumentDB.setRepository() method - -> Warning: This API is now obsolete. -> -> This will be removed when NodeGit is replaced with isomorphic-git. -> - -Set repository - -Signature: - -```typescript -setRepository(repos: nodegit.Repository): void; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| repos | nodegit.Repository | | - -Returns: - -void - -## Remarks - -Be aware that it can corrupt the database. - diff --git a/docs-api/git-documentdb.gitdocumentdb.sync.md b/docs-api/git-documentdb.gitdocumentdb.sync.md index 7d129d59..0003f74e 100644 --- a/docs-api/git-documentdb.gitdocumentdb.sync.md +++ b/docs-api/git-documentdb.gitdocumentdb.sync.md @@ -32,15 +32,50 @@ Register and synchronize with a remote repository. Do not register the same remo ## Exceptions -[Err.UndefinedRemoteURLError](./git-documentdb.err.undefinedremoteurlerror.md) (from Sync\#constructor()) +[Err.RemoteAlreadyRegisteredError](./git-documentdb.err.remotealreadyregisterederror.md) -[Err.IntervalTooSmallError](./git-documentdb.err.intervaltoosmallerror.md) (from Sync\#constructor()) +\# from Sync\#syncAndGetResultImpl -[Err.RepositoryNotFoundError](./git-documentdb.err.repositorynotfounderror.md) (from Sync\#syncImpl()) +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.RemoteRepositoryConnectError](./git-documentdb.err.remoterepositoryconnecterror.md) (from Sync\#init()) +[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) -[Err.PushWorkerError](./git-documentdb.err.pushworkererror.md) (from Sync\#init()) +[Err.UndefinedRemoteURLError](./git-documentdb.err.undefinedremoteurlerror.md) -[Err.SyncWorkerError](./git-documentdb.err.syncworkererror.md) (from Sync\#init()) +[Err.IntervalTooSmallError](./git-documentdb.err.intervaltoosmallerror.md) + +[Err.SyncIntervalLessThanOrEqualToRetryIntervalError](./git-documentdb.err.syncintervallessthanorequaltoretryintervalerror.md) + +[Err.CannotCreateRemoteRepositoryError](./git-documentdb.err.cannotcreateremoterepositoryerror.md) + +[RemoteErr.InvalidGitRemoteError](./git-documentdb.remoteerr.invalidgitremoteerror.md) + +[RemoteErr.InvalidURLFormatError](./git-documentdb.remoteerr.invalidurlformaterror.md) + +[RemoteErr.NetworkError](./git-documentdb.remoteerr.networkerror.md) + +[RemoteErr.HTTPError401AuthorizationRequired](./git-documentdb.remoteerr.httperror401authorizationrequired.md) + +[RemoteErr.HTTPError404NotFound](./git-documentdb.remoteerr.httperror404notfound.md) + +[RemoteErr.CannotConnectError](./git-documentdb.remoteerr.cannotconnecterror.md) + + +[RemoteErr.InvalidRepositoryURLError](./git-documentdb.remoteerr.invalidrepositoryurlerror.md) + +[RemoteErr.InvalidSSHKeyPathError](./git-documentdb.remoteerr.invalidsshkeypatherror.md) + +[RemoteErr.InvalidAuthenticationTypeError](./git-documentdb.remoteerr.invalidauthenticationtypeerror.md) + +[RemoteErr.UnfetchedCommitExistsError](./git-documentdb.remoteerr.unfetchedcommitexistserror.md) + +[RemoteErr.HTTPError403Forbidden](./git-documentdb.remoteerr.httperror403forbidden.md) + +[Err.NoMergeBaseFoundError](./git-documentdb.err.nomergebasefounderror.md) + +[Err.ThreeWayMergeError](./git-documentdb.err.threewaymergeerror.md) + +[Err.CannotDeleteDataError](./git-documentdb.err.cannotdeletedataerror.md) + +[Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) diff --git a/docs-api/git-documentdb.gitdocumentdb.sync_1.md b/docs-api/git-documentdb.gitdocumentdb.sync_1.md index 7b32a73f..f24f2c6b 100644 --- a/docs-api/git-documentdb.gitdocumentdb.sync_1.md +++ b/docs-api/git-documentdb.gitdocumentdb.sync_1.md @@ -33,15 +33,50 @@ Register and synchronize with a remote repository. Do not register the same remo ## Exceptions -[Err.UndefinedRemoteURLError](./git-documentdb.err.undefinedremoteurlerror.md) (from Sync\#constructor()) +[Err.RemoteAlreadyRegisteredError](./git-documentdb.err.remotealreadyregisterederror.md) -[Err.IntervalTooSmallError](./git-documentdb.err.intervaltoosmallerror.md) (from Sync\#constructor()) +\# from Sync\#syncAndGetResultImpl -[Err.RepositoryNotFoundError](./git-documentdb.err.repositorynotfounderror.md) (from Sync\#syncAndGetResultImpl()) +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.RemoteRepositoryConnectError](./git-documentdb.err.remoterepositoryconnecterror.md) (from Sync\#init()) +[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) -[Err.PushWorkerError](./git-documentdb.err.pushworkererror.md) (from Sync\#init()) +[Err.UndefinedRemoteURLError](./git-documentdb.err.undefinedremoteurlerror.md) -[Err.SyncWorkerError](./git-documentdb.err.syncworkererror.md) (from Sync\#init()) +[Err.IntervalTooSmallError](./git-documentdb.err.intervaltoosmallerror.md) + +[Err.SyncIntervalLessThanOrEqualToRetryIntervalError](./git-documentdb.err.syncintervallessthanorequaltoretryintervalerror.md) + +[Err.CannotCreateRemoteRepositoryError](./git-documentdb.err.cannotcreateremoterepositoryerror.md) + +[RemoteErr.InvalidGitRemoteError](./git-documentdb.remoteerr.invalidgitremoteerror.md) + +[RemoteErr.InvalidURLFormatError](./git-documentdb.remoteerr.invalidurlformaterror.md) + +[RemoteErr.NetworkError](./git-documentdb.remoteerr.networkerror.md) + +[RemoteErr.HTTPError401AuthorizationRequired](./git-documentdb.remoteerr.httperror401authorizationrequired.md) + +[RemoteErr.HTTPError404NotFound](./git-documentdb.remoteerr.httperror404notfound.md) + +[RemoteErr.CannotConnectError](./git-documentdb.remoteerr.cannotconnecterror.md) + + +[RemoteErr.InvalidRepositoryURLError](./git-documentdb.remoteerr.invalidrepositoryurlerror.md) + +[RemoteErr.InvalidSSHKeyPathError](./git-documentdb.remoteerr.invalidsshkeypatherror.md) + +[RemoteErr.InvalidAuthenticationTypeError](./git-documentdb.remoteerr.invalidauthenticationtypeerror.md) + +[RemoteErr.UnfetchedCommitExistsError](./git-documentdb.remoteerr.unfetchedcommitexistserror.md) + +[RemoteErr.HTTPError403Forbidden](./git-documentdb.remoteerr.httperror403forbidden.md) + +[Err.NoMergeBaseFoundError](./git-documentdb.err.nomergebasefounderror.md) + +[Err.ThreeWayMergeError](./git-documentdb.err.threewaymergeerror.md) + +[Err.CannotDeleteDataError](./git-documentdb.err.cannotdeletedataerror.md) + +[Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) diff --git a/docs-api/git-documentdb.gitdocumentdb.update.md b/docs-api/git-documentdb.gitdocumentdb.update.md index d3aaf992..2bcdaaeb 100644 --- a/docs-api/git-documentdb.gitdocumentdb.update.md +++ b/docs-api/git-documentdb.gitdocumentdb.update.md @@ -41,21 +41,25 @@ Promise<[PutResultJsonDoc](./git-documentdb.putresultjsondoc.md) > [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) -[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) (from validateDocument, validateId) +\# from validateDocument, validateId -[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) (from validateDocument, validateId) +[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) -[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) (fromm putImpl) +[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) -[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) (from putImpl) +\# from putImpl -[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) (fromm putWorker) +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) (fromm putWorker) +[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) -[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) (from putWorker) +\# from putWorker -[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) (from putWorker) +[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) + +[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) + +[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) [Err.DocumentNotFoundError](./git-documentdb.err.documentnotfounderror.md) diff --git a/docs-api/git-documentdb.gitdocumentdb.update_1.md b/docs-api/git-documentdb.gitdocumentdb.update_1.md index 7080efac..37bb9ea7 100644 --- a/docs-api/git-documentdb.gitdocumentdb.update_1.md +++ b/docs-api/git-documentdb.gitdocumentdb.update_1.md @@ -42,21 +42,25 @@ Promise<[PutResultJsonDoc](./git-documentdb.putresultjsondoc.md) > [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) -[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) (from validateDocument, validateId) +\# from validateDocument, validateId -[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) (from validateDocument, validateId) +[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) -[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) (fromm putImpl) +[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) -[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) (from putImpl) +\# from putImpl -[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) (fromm putWorker) +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) (fromm putWorker) +[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) -[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) (from putWorker) +\# from putWorker -[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) (from putWorker) +[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) + +[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) + +[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) [Err.DocumentNotFoundError](./git-documentdb.err.documentnotfounderror.md) diff --git a/docs-api/git-documentdb.gitdocumentdb.updatefatdoc.md b/docs-api/git-documentdb.gitdocumentdb.updatefatdoc.md index 12ab595a..9d81a818 100644 --- a/docs-api/git-documentdb.gitdocumentdb.updatefatdoc.md +++ b/docs-api/git-documentdb.gitdocumentdb.updatefatdoc.md @@ -42,23 +42,29 @@ Promise<[PutResult](./git-documentdb.putresult.md) > ## Exceptions +\# from this method + [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) -[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) (from validateDocument, validateId) +\# from validateDocument, validateId + +[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) + +[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) -[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) (from validateDocument, validateId) +\# fromm putImpl -[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) (fromm putImpl) +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) (from putImpl) +[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) -[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) (fromm putWorker) +\# from putWorker -[Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) (fromm putWorker) +[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) -[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) (from putWorker) +[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) -[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) (from putWorker) +[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) [Err.DocumentNotFoundError](./git-documentdb.err.documentnotfounderror.md) diff --git a/docs-api/git-documentdb.md b/docs-api/git-documentdb.md index 50595f9c..53fd95f1 100644 --- a/docs-api/git-documentdb.md +++ b/docs-api/git-documentdb.md @@ -21,6 +21,13 @@ Offline-first Database that Syncs with Git | [TaskQueue](./git-documentdb.taskqueue.md) | TaskQueue | | [Validator](./git-documentdb.validator.md) | Validator Class | +## Functions + +| Function | Description | +| --- | --- | +| [encodeToGitRemoteName(remoteURL)](./git-documentdb.encodetogitremotename.md) | encodeToRemoteName | +| [wrappingRemoteEngineError(remoteEngineError)](./git-documentdb.wrappingremoteengineerror.md) | | + ## Interfaces | Interface | Description | @@ -28,6 +35,7 @@ Offline-first Database that Syncs with Git | [CollectionInterface](./git-documentdb.collectioninterface.md) | Interface for Collection | | [CRUDInterface](./git-documentdb.crudinterface.md) | Interface for GitDocumentDB CRUD | | [GitDDBInterface](./git-documentdb.gitddbinterface.md) | Interface of GitDocumentDB body | +| [RemoteEngineInterface](./git-documentdb.remoteengineinterface.md) | | | [SyncEventInterface](./git-documentdb.synceventinterface.md) | Interface for SyncEvent | | [SyncInterface](./git-documentdb.syncinterface.md) | Interface of Sync | @@ -36,6 +44,7 @@ Offline-first Database that Syncs with Git | Namespace | Description | | --- | --- | | [Err](./git-documentdb.err.md) | Namespace for errors | +| [RemoteErr](./git-documentdb.remoteerr.md) | | ## Variables @@ -61,6 +70,7 @@ Offline-first Database that Syncs with Git | [NETWORK\_RETRY](./git-documentdb.network_retry.md) | | | [NETWORK\_TIMEOUT](./git-documentdb.network_timeout.md) | | | [PUT\_APP\_INFO\_MESSAGE](./git-documentdb.put_app_info_message.md) | | +| [RemoteEngine](./git-documentdb.remoteengine.md) | | | [SET\_DATABASE\_ID\_MESSAGE](./git-documentdb.set_database_id_message.md) | | | [SHORT\_SHA\_LENGTH](./git-documentdb.short_sha_length.md) | | @@ -110,6 +120,7 @@ Offline-first Database that Syncs with Git | [JsonDocMetadata](./git-documentdb.jsondocmetadata.md) | Metadata for JsonDoc | | [NormalizedCommit](./git-documentdb.normalizedcommit.md) | Normalized Commit | | [OpenOptions](./git-documentdb.openoptions.md) | Database open options | +| [PluginTypes](./git-documentdb.plugintypes.md) | Plugin types | | [PutOptions](./git-documentdb.putoptions.md) | Options for put APIs (put, update, insert, putFatDoc, updateFatDoc, and insertFatDoc) | | [PutResult](./git-documentdb.putresult.md) | Result of put APIs (put, update, insert, putFatDoc, updateFatDoc, and insertFatDoc) | | [PutResultBinary](./git-documentdb.putresultbinary.md) | | diff --git a/docs-api/git-documentdb.plugintypes.md b/docs-api/git-documentdb.plugintypes.md new file mode 100644 index 00000000..f93689fd --- /dev/null +++ b/docs-api/git-documentdb.plugintypes.md @@ -0,0 +1,17 @@ +--- +sidebar_label: PluginTypes type +title: PluginTypes type +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [PluginTypes](./git-documentdb.plugintypes.md) + +## PluginTypes type + +Plugin types + +Signature: + +```typescript +export declare type PluginTypes = 'db' | 'remote'; +``` diff --git a/docs-api/git-documentdb.remoteengine.md b/docs-api/git-documentdb.remoteengine.md new file mode 100644 index 00000000..c1645c36 --- /dev/null +++ b/docs-api/git-documentdb.remoteengine.md @@ -0,0 +1,17 @@ +--- +sidebar_label: RemoteEngine variable +title: RemoteEngine variable +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [RemoteEngine](./git-documentdb.remoteengine.md) + +## RemoteEngine variable + +Signature: + +```typescript +RemoteEngine: { + [key: string]: RemoteEngineInterface; +} +``` diff --git a/docs-api/git-documentdb.remoteengineinterface.checkfetch.md b/docs-api/git-documentdb.remoteengineinterface.checkfetch.md new file mode 100644 index 00000000..103e0b5b --- /dev/null +++ b/docs-api/git-documentdb.remoteengineinterface.checkfetch.md @@ -0,0 +1,15 @@ +--- +sidebar_label: checkFetch +title: RemoteEngineInterface.checkFetch property +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [RemoteEngineInterface](./git-documentdb.remoteengineinterface.md) > [checkFetch](./git-documentdb.remoteengineinterface.checkfetch.md) + +## RemoteEngineInterface.checkFetch property + +Signature: + +```typescript +checkFetch: (workingDir: string, options: RemoteOptions, remoteName?: string, logger?: Logger) => Promise; +``` diff --git a/docs-api/git-documentdb.remoteengineinterface.clone.md b/docs-api/git-documentdb.remoteengineinterface.clone.md new file mode 100644 index 00000000..cc9b78a5 --- /dev/null +++ b/docs-api/git-documentdb.remoteengineinterface.clone.md @@ -0,0 +1,15 @@ +--- +sidebar_label: clone +title: RemoteEngineInterface.clone property +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [RemoteEngineInterface](./git-documentdb.remoteengineinterface.md) > [clone](./git-documentdb.remoteengineinterface.clone.md) + +## RemoteEngineInterface.clone property + +Signature: + +```typescript +clone: (workingDir: string, remoteOptions: RemoteOptions, remoteName: string, logger?: Logger) => Promise; +``` diff --git a/docs-api/git-documentdb.remoteengineinterface.fetch.md b/docs-api/git-documentdb.remoteengineinterface.fetch.md new file mode 100644 index 00000000..2f509b04 --- /dev/null +++ b/docs-api/git-documentdb.remoteengineinterface.fetch.md @@ -0,0 +1,15 @@ +--- +sidebar_label: fetch +title: RemoteEngineInterface.fetch property +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [RemoteEngineInterface](./git-documentdb.remoteengineinterface.md) > [fetch](./git-documentdb.remoteengineinterface.fetch.md) + +## RemoteEngineInterface.fetch property + +Signature: + +```typescript +fetch: (workingDir: string, remoteOptions: RemoteOptions, remoteName?: string, logger?: Logger) => Promise; +``` diff --git a/docs-api/git-documentdb.remoteengineinterface.md b/docs-api/git-documentdb.remoteengineinterface.md new file mode 100644 index 00000000..6e9a33c7 --- /dev/null +++ b/docs-api/git-documentdb.remoteengineinterface.md @@ -0,0 +1,25 @@ +--- +sidebar_label: RemoteEngineInterface interface +title: RemoteEngineInterface interface +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [RemoteEngineInterface](./git-documentdb.remoteengineinterface.md) + +## RemoteEngineInterface interface + +Signature: + +```typescript +export interface RemoteEngineInterface +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [checkFetch](./git-documentdb.remoteengineinterface.checkfetch.md) | (workingDir: string, options: [RemoteOptions](./git-documentdb.remoteoptions.md) , remoteName?: string, logger?: Logger) => Promise<boolean> | | +| [clone](./git-documentdb.remoteengineinterface.clone.md) | (workingDir: string, remoteOptions: [RemoteOptions](./git-documentdb.remoteoptions.md) , remoteName: string, logger?: Logger) => Promise<void> | | +| [fetch](./git-documentdb.remoteengineinterface.fetch.md) | (workingDir: string, remoteOptions: [RemoteOptions](./git-documentdb.remoteoptions.md) , remoteName?: string, logger?: Logger) => Promise<void> | | +| [push](./git-documentdb.remoteengineinterface.push.md) | (workingDir: string, remoteOptions: [RemoteOptions](./git-documentdb.remoteoptions.md) , remoteName?: string, localBranch?: string, remoteBranch?: string, logger?: Logger) => Promise<void> | | + diff --git a/docs-api/git-documentdb.remoteengineinterface.push.md b/docs-api/git-documentdb.remoteengineinterface.push.md new file mode 100644 index 00000000..bc73ed48 --- /dev/null +++ b/docs-api/git-documentdb.remoteengineinterface.push.md @@ -0,0 +1,15 @@ +--- +sidebar_label: push +title: RemoteEngineInterface.push property +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [RemoteEngineInterface](./git-documentdb.remoteengineinterface.md) > [push](./git-documentdb.remoteengineinterface.push.md) + +## RemoteEngineInterface.push property + +Signature: + +```typescript +push: (workingDir: string, remoteOptions: RemoteOptions, remoteName?: string, localBranch?: string, remoteBranch?: string, logger?: Logger) => Promise; +``` diff --git a/docs-api/git-documentdb.remoteerr.cannotconnecterror._constructor_.md b/docs-api/git-documentdb.remoteerr.cannotconnecterror._constructor_.md new file mode 100644 index 00000000..64b5618d --- /dev/null +++ b/docs-api/git-documentdb.remoteerr.cannotconnecterror._constructor_.md @@ -0,0 +1,24 @@ +--- +sidebar_label: (constructor) +title: RemoteErr.CannotConnectError.(constructor) +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [RemoteErr](./git-documentdb.remoteerr.md) > [CannotConnectError](./git-documentdb.remoteerr.cannotconnecterror.md) > [(constructor)](./git-documentdb.remoteerr.cannotconnecterror._constructor_.md) + +## RemoteErr.CannotConnectError.(constructor) + +Constructs a new instance of the `CannotConnectError` class + +Signature: + +```typescript +constructor(mes: unknown); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| mes | unknown | | + diff --git a/docs-api/git-documentdb.remoteerr.cannotconnecterror.md b/docs-api/git-documentdb.remoteerr.cannotconnecterror.md new file mode 100644 index 00000000..1ca70754 --- /dev/null +++ b/docs-api/git-documentdb.remoteerr.cannotconnecterror.md @@ -0,0 +1,27 @@ +--- +sidebar_label: CannotConnectError +title: RemoteErr.CannotConnectError class +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [RemoteErr](./git-documentdb.remoteerr.md) > [CannotConnectError](./git-documentdb.remoteerr.cannotconnecterror.md) + +## RemoteErr.CannotConnectError class + +Copy error message from parent + +Signature: + +```typescript +class CannotConnectError extends RemoteErrors.CannotConnectError +``` +Extends: + +RemoteErrors.CannotConnectError + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(mes)](./git-documentdb.remoteerr.cannotconnecterror._constructor_.md) | | Constructs a new instance of the CannotConnectError class | + diff --git a/docs-api/git-documentdb.remoteerr.httperror401authorizationrequired._constructor_.md b/docs-api/git-documentdb.remoteerr.httperror401authorizationrequired._constructor_.md new file mode 100644 index 00000000..6ad8e9e2 --- /dev/null +++ b/docs-api/git-documentdb.remoteerr.httperror401authorizationrequired._constructor_.md @@ -0,0 +1,24 @@ +--- +sidebar_label: (constructor) +title: RemoteErr.HTTPError401AuthorizationRequired.(constructor) +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [RemoteErr](./git-documentdb.remoteerr.md) > [HTTPError401AuthorizationRequired](./git-documentdb.remoteerr.httperror401authorizationrequired.md) > [(constructor)](./git-documentdb.remoteerr.httperror401authorizationrequired._constructor_.md) + +## RemoteErr.HTTPError401AuthorizationRequired.(constructor) + +Constructs a new instance of the `HTTPError401AuthorizationRequired` class + +Signature: + +```typescript +constructor(mes: unknown); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| mes | unknown | | + diff --git a/docs-api/git-documentdb.remoteerr.httperror401authorizationrequired.md b/docs-api/git-documentdb.remoteerr.httperror401authorizationrequired.md new file mode 100644 index 00000000..96a225b1 --- /dev/null +++ b/docs-api/git-documentdb.remoteerr.httperror401authorizationrequired.md @@ -0,0 +1,25 @@ +--- +sidebar_label: HTTPError401AuthorizationRequired +title: RemoteErr.HTTPError401AuthorizationRequired class +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [RemoteErr](./git-documentdb.remoteerr.md) > [HTTPError401AuthorizationRequired](./git-documentdb.remoteerr.httperror401authorizationrequired.md) + +## RemoteErr.HTTPError401AuthorizationRequired class + +Signature: + +```typescript +class HTTPError401AuthorizationRequired extends RemoteErrors.HTTPError401AuthorizationRequired +``` +Extends: + +RemoteErrors.HTTPError401AuthorizationRequired + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(mes)](./git-documentdb.remoteerr.httperror401authorizationrequired._constructor_.md) | | Constructs a new instance of the HTTPError401AuthorizationRequired class | + diff --git a/docs-api/git-documentdb.remoteerr.httperror403forbidden._constructor_.md b/docs-api/git-documentdb.remoteerr.httperror403forbidden._constructor_.md new file mode 100644 index 00000000..9ada4440 --- /dev/null +++ b/docs-api/git-documentdb.remoteerr.httperror403forbidden._constructor_.md @@ -0,0 +1,24 @@ +--- +sidebar_label: (constructor) +title: RemoteErr.HTTPError403Forbidden.(constructor) +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [RemoteErr](./git-documentdb.remoteerr.md) > [HTTPError403Forbidden](./git-documentdb.remoteerr.httperror403forbidden.md) > [(constructor)](./git-documentdb.remoteerr.httperror403forbidden._constructor_.md) + +## RemoteErr.HTTPError403Forbidden.(constructor) + +Constructs a new instance of the `HTTPError403Forbidden` class + +Signature: + +```typescript +constructor(mes: unknown); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| mes | unknown | | + diff --git a/docs-api/git-documentdb.remoteerr.httperror403forbidden.md b/docs-api/git-documentdb.remoteerr.httperror403forbidden.md new file mode 100644 index 00000000..a3bebaf7 --- /dev/null +++ b/docs-api/git-documentdb.remoteerr.httperror403forbidden.md @@ -0,0 +1,25 @@ +--- +sidebar_label: HTTPError403Forbidden +title: RemoteErr.HTTPError403Forbidden class +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [RemoteErr](./git-documentdb.remoteerr.md) > [HTTPError403Forbidden](./git-documentdb.remoteerr.httperror403forbidden.md) + +## RemoteErr.HTTPError403Forbidden class + +Signature: + +```typescript +class HTTPError403Forbidden extends RemoteErrors.HTTPError403Forbidden +``` +Extends: + +RemoteErrors.HTTPError403Forbidden + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(mes)](./git-documentdb.remoteerr.httperror403forbidden._constructor_.md) | | Constructs a new instance of the HTTPError403Forbidden class | + diff --git a/docs-api/git-documentdb.remoteerr.httperror404notfound._constructor_.md b/docs-api/git-documentdb.remoteerr.httperror404notfound._constructor_.md new file mode 100644 index 00000000..e552baf6 --- /dev/null +++ b/docs-api/git-documentdb.remoteerr.httperror404notfound._constructor_.md @@ -0,0 +1,24 @@ +--- +sidebar_label: (constructor) +title: RemoteErr.HTTPError404NotFound.(constructor) +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [RemoteErr](./git-documentdb.remoteerr.md) > [HTTPError404NotFound](./git-documentdb.remoteerr.httperror404notfound.md) > [(constructor)](./git-documentdb.remoteerr.httperror404notfound._constructor_.md) + +## RemoteErr.HTTPError404NotFound.(constructor) + +Constructs a new instance of the `HTTPError404NotFound` class + +Signature: + +```typescript +constructor(mes: unknown); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| mes | unknown | | + diff --git a/docs-api/git-documentdb.remoteerr.httperror404notfound.md b/docs-api/git-documentdb.remoteerr.httperror404notfound.md new file mode 100644 index 00000000..37ef08cc --- /dev/null +++ b/docs-api/git-documentdb.remoteerr.httperror404notfound.md @@ -0,0 +1,25 @@ +--- +sidebar_label: HTTPError404NotFound +title: RemoteErr.HTTPError404NotFound class +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [RemoteErr](./git-documentdb.remoteerr.md) > [HTTPError404NotFound](./git-documentdb.remoteerr.httperror404notfound.md) + +## RemoteErr.HTTPError404NotFound class + +Signature: + +```typescript +class HTTPError404NotFound extends RemoteErrors.HTTPError404NotFound +``` +Extends: + +RemoteErrors.HTTPError404NotFound + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(mes)](./git-documentdb.remoteerr.httperror404notfound._constructor_.md) | | Constructs a new instance of the HTTPError404NotFound class | + diff --git a/docs-api/git-documentdb.remoteerr.invalidauthenticationtypeerror._constructor_.md b/docs-api/git-documentdb.remoteerr.invalidauthenticationtypeerror._constructor_.md new file mode 100644 index 00000000..5a0c1d7a --- /dev/null +++ b/docs-api/git-documentdb.remoteerr.invalidauthenticationtypeerror._constructor_.md @@ -0,0 +1,24 @@ +--- +sidebar_label: (constructor) +title: RemoteErr.InvalidAuthenticationTypeError.(constructor) +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [RemoteErr](./git-documentdb.remoteerr.md) > [InvalidAuthenticationTypeError](./git-documentdb.remoteerr.invalidauthenticationtypeerror.md) > [(constructor)](./git-documentdb.remoteerr.invalidauthenticationtypeerror._constructor_.md) + +## RemoteErr.InvalidAuthenticationTypeError.(constructor) + +Constructs a new instance of the `InvalidAuthenticationTypeError` class + +Signature: + +```typescript +constructor(mes: unknown); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| mes | unknown | | + diff --git a/docs-api/git-documentdb.remoteerr.invalidauthenticationtypeerror.md b/docs-api/git-documentdb.remoteerr.invalidauthenticationtypeerror.md new file mode 100644 index 00000000..3e5f1694 --- /dev/null +++ b/docs-api/git-documentdb.remoteerr.invalidauthenticationtypeerror.md @@ -0,0 +1,25 @@ +--- +sidebar_label: InvalidAuthenticationTypeError +title: RemoteErr.InvalidAuthenticationTypeError class +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [RemoteErr](./git-documentdb.remoteerr.md) > [InvalidAuthenticationTypeError](./git-documentdb.remoteerr.invalidauthenticationtypeerror.md) + +## RemoteErr.InvalidAuthenticationTypeError class + +Signature: + +```typescript +class InvalidAuthenticationTypeError extends RemoteErrors.InvalidAuthenticationTypeError +``` +Extends: + +RemoteErrors.InvalidAuthenticationTypeError + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(mes)](./git-documentdb.remoteerr.invalidauthenticationtypeerror._constructor_.md) | | Constructs a new instance of the InvalidAuthenticationTypeError class | + diff --git a/docs-api/git-documentdb.remoteerr.invalidgitremoteerror._constructor_.md b/docs-api/git-documentdb.remoteerr.invalidgitremoteerror._constructor_.md new file mode 100644 index 00000000..c64af94d --- /dev/null +++ b/docs-api/git-documentdb.remoteerr.invalidgitremoteerror._constructor_.md @@ -0,0 +1,24 @@ +--- +sidebar_label: (constructor) +title: RemoteErr.InvalidGitRemoteError.(constructor) +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [RemoteErr](./git-documentdb.remoteerr.md) > [InvalidGitRemoteError](./git-documentdb.remoteerr.invalidgitremoteerror.md) > [(constructor)](./git-documentdb.remoteerr.invalidgitremoteerror._constructor_.md) + +## RemoteErr.InvalidGitRemoteError.(constructor) + +Constructs a new instance of the `InvalidGitRemoteError` class + +Signature: + +```typescript +constructor(mes: unknown); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| mes | unknown | | + diff --git a/docs-api/git-documentdb.remoteerr.invalidgitremoteerror.md b/docs-api/git-documentdb.remoteerr.invalidgitremoteerror.md new file mode 100644 index 00000000..c065bde7 --- /dev/null +++ b/docs-api/git-documentdb.remoteerr.invalidgitremoteerror.md @@ -0,0 +1,25 @@ +--- +sidebar_label: InvalidGitRemoteError +title: RemoteErr.InvalidGitRemoteError class +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [RemoteErr](./git-documentdb.remoteerr.md) > [InvalidGitRemoteError](./git-documentdb.remoteerr.invalidgitremoteerror.md) + +## RemoteErr.InvalidGitRemoteError class + +Signature: + +```typescript +class InvalidGitRemoteError extends RemoteErrors.InvalidGitRemoteError +``` +Extends: + +RemoteErrors.InvalidGitRemoteError + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(mes)](./git-documentdb.remoteerr.invalidgitremoteerror._constructor_.md) | | Constructs a new instance of the InvalidGitRemoteError class | + diff --git a/docs-api/git-documentdb.remoteerr.invalidrepositoryurlerror._constructor_.md b/docs-api/git-documentdb.remoteerr.invalidrepositoryurlerror._constructor_.md new file mode 100644 index 00000000..91973c60 --- /dev/null +++ b/docs-api/git-documentdb.remoteerr.invalidrepositoryurlerror._constructor_.md @@ -0,0 +1,24 @@ +--- +sidebar_label: (constructor) +title: RemoteErr.InvalidRepositoryURLError.(constructor) +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [RemoteErr](./git-documentdb.remoteerr.md) > [InvalidRepositoryURLError](./git-documentdb.remoteerr.invalidrepositoryurlerror.md) > [(constructor)](./git-documentdb.remoteerr.invalidrepositoryurlerror._constructor_.md) + +## RemoteErr.InvalidRepositoryURLError.(constructor) + +Constructs a new instance of the `InvalidRepositoryURLError` class + +Signature: + +```typescript +constructor(mes: unknown); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| mes | unknown | | + diff --git a/docs-api/git-documentdb.remoteerr.invalidrepositoryurlerror.md b/docs-api/git-documentdb.remoteerr.invalidrepositoryurlerror.md new file mode 100644 index 00000000..5a60f330 --- /dev/null +++ b/docs-api/git-documentdb.remoteerr.invalidrepositoryurlerror.md @@ -0,0 +1,25 @@ +--- +sidebar_label: InvalidRepositoryURLError +title: RemoteErr.InvalidRepositoryURLError class +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [RemoteErr](./git-documentdb.remoteerr.md) > [InvalidRepositoryURLError](./git-documentdb.remoteerr.invalidrepositoryurlerror.md) + +## RemoteErr.InvalidRepositoryURLError class + +Signature: + +```typescript +class InvalidRepositoryURLError extends RemoteErrors.InvalidRepositoryURLError +``` +Extends: + +RemoteErrors.InvalidRepositoryURLError + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(mes)](./git-documentdb.remoteerr.invalidrepositoryurlerror._constructor_.md) | | Constructs a new instance of the InvalidRepositoryURLError class | + diff --git a/docs-api/git-documentdb.remoteerr.invalidsshkeypatherror._constructor_.md b/docs-api/git-documentdb.remoteerr.invalidsshkeypatherror._constructor_.md new file mode 100644 index 00000000..d2acbe2b --- /dev/null +++ b/docs-api/git-documentdb.remoteerr.invalidsshkeypatherror._constructor_.md @@ -0,0 +1,24 @@ +--- +sidebar_label: (constructor) +title: RemoteErr.InvalidSSHKeyPathError.(constructor) +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [RemoteErr](./git-documentdb.remoteerr.md) > [InvalidSSHKeyPathError](./git-documentdb.remoteerr.invalidsshkeypatherror.md) > [(constructor)](./git-documentdb.remoteerr.invalidsshkeypatherror._constructor_.md) + +## RemoteErr.InvalidSSHKeyPathError.(constructor) + +Constructs a new instance of the `InvalidSSHKeyPathError` class + +Signature: + +```typescript +constructor(mes: unknown); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| mes | unknown | | + diff --git a/docs-api/git-documentdb.remoteerr.invalidsshkeypatherror.md b/docs-api/git-documentdb.remoteerr.invalidsshkeypatherror.md new file mode 100644 index 00000000..5b07c375 --- /dev/null +++ b/docs-api/git-documentdb.remoteerr.invalidsshkeypatherror.md @@ -0,0 +1,25 @@ +--- +sidebar_label: InvalidSSHKeyPathError +title: RemoteErr.InvalidSSHKeyPathError class +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [RemoteErr](./git-documentdb.remoteerr.md) > [InvalidSSHKeyPathError](./git-documentdb.remoteerr.invalidsshkeypatherror.md) + +## RemoteErr.InvalidSSHKeyPathError class + +Signature: + +```typescript +class InvalidSSHKeyPathError extends RemoteErrors.InvalidSSHKeyPathError +``` +Extends: + +RemoteErrors.InvalidSSHKeyPathError + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(mes)](./git-documentdb.remoteerr.invalidsshkeypatherror._constructor_.md) | | Constructs a new instance of the InvalidSSHKeyPathError class | + diff --git a/docs-api/git-documentdb.remoteerr.invalidurlformaterror._constructor_.md b/docs-api/git-documentdb.remoteerr.invalidurlformaterror._constructor_.md new file mode 100644 index 00000000..40884b5a --- /dev/null +++ b/docs-api/git-documentdb.remoteerr.invalidurlformaterror._constructor_.md @@ -0,0 +1,24 @@ +--- +sidebar_label: (constructor) +title: RemoteErr.InvalidURLFormatError.(constructor) +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [RemoteErr](./git-documentdb.remoteerr.md) > [InvalidURLFormatError](./git-documentdb.remoteerr.invalidurlformaterror.md) > [(constructor)](./git-documentdb.remoteerr.invalidurlformaterror._constructor_.md) + +## RemoteErr.InvalidURLFormatError.(constructor) + +Constructs a new instance of the `InvalidURLFormatError` class + +Signature: + +```typescript +constructor(mes: unknown); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| mes | unknown | | + diff --git a/docs-api/git-documentdb.remoteerr.invalidurlformaterror.md b/docs-api/git-documentdb.remoteerr.invalidurlformaterror.md new file mode 100644 index 00000000..fee837d2 --- /dev/null +++ b/docs-api/git-documentdb.remoteerr.invalidurlformaterror.md @@ -0,0 +1,25 @@ +--- +sidebar_label: InvalidURLFormatError +title: RemoteErr.InvalidURLFormatError class +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [RemoteErr](./git-documentdb.remoteerr.md) > [InvalidURLFormatError](./git-documentdb.remoteerr.invalidurlformaterror.md) + +## RemoteErr.InvalidURLFormatError class + +Signature: + +```typescript +class InvalidURLFormatError extends RemoteErrors.InvalidURLFormatError +``` +Extends: + +RemoteErrors.InvalidURLFormatError + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(mes)](./git-documentdb.remoteerr.invalidurlformaterror._constructor_.md) | | Constructs a new instance of the InvalidURLFormatError class | + diff --git a/docs-api/git-documentdb.remoteerr.md b/docs-api/git-documentdb.remoteerr.md new file mode 100644 index 00000000..54550e46 --- /dev/null +++ b/docs-api/git-documentdb.remoteerr.md @@ -0,0 +1,32 @@ +--- +sidebar_label: RemoteErr namespace +title: RemoteErr namespace +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [RemoteErr](./git-documentdb.remoteerr.md) + +## RemoteErr namespace + +Signature: + +```typescript +export declare namespace RemoteErr +``` + +## Classes + +| Class | Description | +| --- | --- | +| [CannotConnectError](./git-documentdb.remoteerr.cannotconnecterror.md) | Copy error message from parent | +| [HTTPError401AuthorizationRequired](./git-documentdb.remoteerr.httperror401authorizationrequired.md) | | +| [HTTPError403Forbidden](./git-documentdb.remoteerr.httperror403forbidden.md) | | +| [HTTPError404NotFound](./git-documentdb.remoteerr.httperror404notfound.md) | | +| [InvalidAuthenticationTypeError](./git-documentdb.remoteerr.invalidauthenticationtypeerror.md) | | +| [InvalidGitRemoteError](./git-documentdb.remoteerr.invalidgitremoteerror.md) | | +| [InvalidRepositoryURLError](./git-documentdb.remoteerr.invalidrepositoryurlerror.md) | | +| [InvalidSSHKeyPathError](./git-documentdb.remoteerr.invalidsshkeypatherror.md) | | +| [InvalidURLFormatError](./git-documentdb.remoteerr.invalidurlformaterror.md) | | +| [NetworkError](./git-documentdb.remoteerr.networkerror.md) | | +| [UnfetchedCommitExistsError](./git-documentdb.remoteerr.unfetchedcommitexistserror.md) | | + diff --git a/docs-api/git-documentdb.remoteerr.networkerror._constructor_.md b/docs-api/git-documentdb.remoteerr.networkerror._constructor_.md new file mode 100644 index 00000000..657aa689 --- /dev/null +++ b/docs-api/git-documentdb.remoteerr.networkerror._constructor_.md @@ -0,0 +1,24 @@ +--- +sidebar_label: (constructor) +title: RemoteErr.NetworkError.(constructor) +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [RemoteErr](./git-documentdb.remoteerr.md) > [NetworkError](./git-documentdb.remoteerr.networkerror.md) > [(constructor)](./git-documentdb.remoteerr.networkerror._constructor_.md) + +## RemoteErr.NetworkError.(constructor) + +Constructs a new instance of the `NetworkError` class + +Signature: + +```typescript +constructor(mes: unknown); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| mes | unknown | | + diff --git a/docs-api/git-documentdb.remoteerr.networkerror.md b/docs-api/git-documentdb.remoteerr.networkerror.md new file mode 100644 index 00000000..b27c9186 --- /dev/null +++ b/docs-api/git-documentdb.remoteerr.networkerror.md @@ -0,0 +1,25 @@ +--- +sidebar_label: NetworkError +title: RemoteErr.NetworkError class +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [RemoteErr](./git-documentdb.remoteerr.md) > [NetworkError](./git-documentdb.remoteerr.networkerror.md) + +## RemoteErr.NetworkError class + +Signature: + +```typescript +class NetworkError extends RemoteErrors.NetworkError +``` +Extends: + +RemoteErrors.NetworkError + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(mes)](./git-documentdb.remoteerr.networkerror._constructor_.md) | | Constructs a new instance of the NetworkError class | + diff --git a/docs-api/git-documentdb.remoteerr.unfetchedcommitexistserror._constructor_.md b/docs-api/git-documentdb.remoteerr.unfetchedcommitexistserror._constructor_.md new file mode 100644 index 00000000..c8abc816 --- /dev/null +++ b/docs-api/git-documentdb.remoteerr.unfetchedcommitexistserror._constructor_.md @@ -0,0 +1,24 @@ +--- +sidebar_label: (constructor) +title: RemoteErr.UnfetchedCommitExistsError.(constructor) +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [RemoteErr](./git-documentdb.remoteerr.md) > [UnfetchedCommitExistsError](./git-documentdb.remoteerr.unfetchedcommitexistserror.md) > [(constructor)](./git-documentdb.remoteerr.unfetchedcommitexistserror._constructor_.md) + +## RemoteErr.UnfetchedCommitExistsError.(constructor) + +Constructs a new instance of the `UnfetchedCommitExistsError` class + +Signature: + +```typescript +constructor(mes: unknown); +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| mes | unknown | | + diff --git a/docs-api/git-documentdb.remoteerr.unfetchedcommitexistserror.md b/docs-api/git-documentdb.remoteerr.unfetchedcommitexistserror.md new file mode 100644 index 00000000..fe878eac --- /dev/null +++ b/docs-api/git-documentdb.remoteerr.unfetchedcommitexistserror.md @@ -0,0 +1,25 @@ +--- +sidebar_label: UnfetchedCommitExistsError +title: RemoteErr.UnfetchedCommitExistsError class +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [RemoteErr](./git-documentdb.remoteerr.md) > [UnfetchedCommitExistsError](./git-documentdb.remoteerr.unfetchedcommitexistserror.md) + +## RemoteErr.UnfetchedCommitExistsError class + +Signature: + +```typescript +class UnfetchedCommitExistsError extends RemoteErrors.UnfetchedCommitExistsError +``` +Extends: + +RemoteErrors.UnfetchedCommitExistsError + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(mes)](./git-documentdb.remoteerr.unfetchedcommitexistserror._constructor_.md) | | Constructs a new instance of the UnfetchedCommitExistsError class | + diff --git a/docs-api/git-documentdb.remoterepository._constructor_.md b/docs-api/git-documentdb.remoterepository._constructor_.md index 7074125b..0f040a7b 100644 --- a/docs-api/git-documentdb.remoterepository._constructor_.md +++ b/docs-api/git-documentdb.remoterepository._constructor_.md @@ -22,7 +22,3 @@ constructor(options: RemoteOptions); | --- | --- | --- | | options | [RemoteOptions](./git-documentdb.remoteoptions.md) | | -## Exceptions - -[Err.InvalidAuthenticationTypeError](./git-documentdb.err.invalidauthenticationtypeerror.md) - diff --git a/docs-api/git-documentdb.remoterepository.connect.md b/docs-api/git-documentdb.remoterepository.connect.md deleted file mode 100644 index 1a1426ab..00000000 --- a/docs-api/git-documentdb.remoterepository.connect.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -sidebar_label: connect() -title: RemoteRepository.connect() method -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [RemoteRepository](./git-documentdb.remoterepository.md) > [connect](./git-documentdb.remoterepository.connect.md) - -## RemoteRepository.connect() method - -Set a remote repository and connect to the remote repository. A remote repository will be created if not exists. - -Signature: - -```typescript -connect(repos: nodegit.Repository, credentialCallbacks: { - [key: string]: any; - }, onlyFetch?: boolean): Promise<[GitRemoteAction, 'exist' | 'create']>; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| repos | nodegit.Repository | | -| credentialCallbacks | { \[key: string\]: any; } | | -| onlyFetch | boolean | | - -Returns: - -Promise<\[GitRemoteAction, 'exist' \| 'create'\]> - -## Exceptions - -[Err.UndefinedPersonalAccessTokenError](./git-documentdb.err.undefinedpersonalaccesstokenerror.md) (from RemoteRepository\#create()) - -[Err.PersonalAccessTokenForAnotherAccountError](./git-documentdb.err.personalaccesstokenforanotheraccounterror.md) (from RemoteRepository\#create()) - -[Err.CannotConnectError](./git-documentdb.err.cannotconnecterror.md) (from RemoteRepository\#create()) - -[Err.AuthenticationTypeNotAllowCreateRepositoryError](./git-documentdb.err.authenticationtypenotallowcreaterepositoryerror.md) (from RemoteRepository\#create()) - -[Err.FetchConnectionFailedError](./git-documentdb.err.fetchconnectionfailederror.md) - -[Err.CannotCreateRemoteRepositoryError](./git-documentdb.err.cannotcreateremoterepositoryerror.md) - -[Err.PushConnectionFailedError](./git-documentdb.err.pushconnectionfailederror.md) - diff --git a/docs-api/git-documentdb.remoterepository.create.md b/docs-api/git-documentdb.remoterepository.create.md index 09b32b57..6e38d19d 100644 --- a/docs-api/git-documentdb.remoterepository.create.md +++ b/docs-api/git-documentdb.remoterepository.create.md @@ -29,7 +29,7 @@ connection.type must be 'github' [Err.PersonalAccessTokenForAnotherAccountError](./git-documentdb.err.personalaccesstokenforanotheraccounterror.md) -[Err.CannotConnectError](./git-documentdb.err.cannotconnecterror.md) +[Err.CannotConnectRemoteRepositoryError](./git-documentdb.err.cannotconnectremoterepositoryerror.md) may include the following errors: diff --git a/docs-api/git-documentdb.remoterepository.destroy.md b/docs-api/git-documentdb.remoterepository.destroy.md index a058f5cf..070679a2 100644 --- a/docs-api/git-documentdb.remoterepository.destroy.md +++ b/docs-api/git-documentdb.remoterepository.destroy.md @@ -27,7 +27,7 @@ connection.type must be 'github' [Err.UndefinedPersonalAccessTokenError](./git-documentdb.err.undefinedpersonalaccesstokenerror.md) -[Err.CannotConnectError](./git-documentdb.err.cannotconnecterror.md) +[Err.CannotConnectRemoteRepositoryError](./git-documentdb.err.cannotconnectremoterepositoryerror.md) may include the following errors: diff --git a/docs-api/git-documentdb.remoterepository.md b/docs-api/git-documentdb.remoterepository.md index ebc1d9fb..934d6b26 100644 --- a/docs-api/git-documentdb.remoterepository.md +++ b/docs-api/git-documentdb.remoterepository.md @@ -26,7 +26,6 @@ export declare class RemoteRepository | Method | Modifiers | Description | | --- | --- | --- | -| [connect(repos, credentialCallbacks, onlyFetch)](./git-documentdb.remoterepository.connect.md) | | Set a remote repository and connect to the remote repository. A remote repository will be created if not exists. | | [create()](./git-documentdb.remoterepository.create.md) | | Create a repository on a remote site | | [destroy()](./git-documentdb.remoterepository.destroy.md) | | Delete a repository on a remote site | diff --git a/docs-api/git-documentdb.sync._constructor_.md b/docs-api/git-documentdb.sync._constructor_.md index 0c22366f..8d9abfd1 100644 --- a/docs-api/git-documentdb.sync._constructor_.md +++ b/docs-api/git-documentdb.sync._constructor_.md @@ -29,5 +29,4 @@ constructor(gitDDB: GitDDBInterface, options?: RemoteOptions); [Err.IntervalTooSmallError](./git-documentdb.err.intervaltoosmallerror.md) -[Err.InvalidAuthenticationTypeError](./git-documentdb.err.invalidauthenticationtypeerror.md) diff --git a/docs-api/git-documentdb.sync.credentialcallbacks.md b/docs-api/git-documentdb.sync.credentialcallbacks.md deleted file mode 100644 index 52d04f21..00000000 --- a/docs-api/git-documentdb.sync.credentialcallbacks.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -sidebar_label: credentialCallbacks -title: Sync.credentialCallbacks property -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [Sync](./git-documentdb.sync.md) > [credentialCallbacks](./git-documentdb.sync.credentialcallbacks.md) - -## Sync.credentialCallbacks property - -Callback for authentication - -Signature: - -```typescript -credentialCallbacks: { - [key: string]: any; - }; -``` diff --git a/docs-api/git-documentdb.sync.engine.md b/docs-api/git-documentdb.sync.engine.md new file mode 100644 index 00000000..9704041c --- /dev/null +++ b/docs-api/git-documentdb.sync.engine.md @@ -0,0 +1,15 @@ +--- +sidebar_label: engine +title: Sync.engine property +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [Sync](./git-documentdb.sync.md) > [engine](./git-documentdb.sync.engine.md) + +## Sync.engine property + +Signature: + +```typescript +get engine(): string; +``` diff --git a/docs-api/git-documentdb.sync.enqueuepushtask.md b/docs-api/git-documentdb.sync.enqueuepushtask.md deleted file mode 100644 index f4077756..00000000 --- a/docs-api/git-documentdb.sync.enqueuepushtask.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -sidebar_label: enqueuePushTask() -title: Sync.enqueuePushTask() method -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [Sync](./git-documentdb.sync.md) > [enqueuePushTask](./git-documentdb.sync.enqueuepushtask.md) - -## Sync.enqueuePushTask() method - -Enqueue push task to TaskQueue - -Signature: - -```typescript -enqueuePushTask(): Promise; -``` -Returns: - -Promise<[SyncResultPush](./git-documentdb.syncresultpush.md) \| [SyncResultCancel](./git-documentdb.syncresultcancel.md) > - -## Exceptions - -[Err.PushWorkerError](./git-documentdb.err.pushworkererror.md) - -[Err.UnfetchedCommitExistsError](./git-documentdb.err.unfetchedcommitexistserror.md) - -[Err.PushNotAllowedError](./git-documentdb.err.pushnotallowederror.md) - diff --git a/docs-api/git-documentdb.sync.enqueuesynctask.md b/docs-api/git-documentdb.sync.enqueuesynctask.md index 55f83511..df43fcfb 100644 --- a/docs-api/git-documentdb.sync.enqueuesynctask.md +++ b/docs-api/git-documentdb.sync.enqueuesynctask.md @@ -19,13 +19,3 @@ enqueueSyncTask(): Promise; Promise<[SyncResult](./git-documentdb.syncresult.md) > -## Exceptions - -[Err.SyncWorkerError](./git-documentdb.err.syncworkererror.md) - -[Err.NoMergeBaseFoundError](./git-documentdb.err.nomergebasefounderror.md) - -[Err.UnfetchedCommitExistsError](./git-documentdb.err.unfetchedcommitexistserror.md) - -[Err.PushNotAllowedError](./git-documentdb.err.pushnotallowederror.md) - diff --git a/docs-api/git-documentdb.sync.init.md b/docs-api/git-documentdb.sync.init.md index 04bfc429..67feabb4 100644 --- a/docs-api/git-documentdb.sync.init.md +++ b/docs-api/git-documentdb.sync.init.md @@ -8,20 +8,13 @@ hide_title: true ## Sync.init() method -Create remote connection +Initialize remote connection Signature: ```typescript -init(repos: nodegit.Repository): Promise; +init(): Promise; ``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| repos | nodegit.Repository | | - Returns: Promise<[SyncResult](./git-documentdb.syncresult.md) > @@ -32,11 +25,37 @@ Call init() once just after creating an instance. ## Exceptions -[Err.RemoteRepositoryConnectError](./git-documentdb.err.remoterepositoryconnecterror.md) +[Err.CannotCreateRemoteRepositoryError](./git-documentdb.err.cannotcreateremoterepositoryerror.md) + +[RemoteErr.InvalidGitRemoteError](./git-documentdb.remoteerr.invalidgitremoteerror.md) (from checkFetch(), trySync(), tryPush()) + +[RemoteErr.InvalidURLFormatError](./git-documentdb.remoteerr.invalidurlformaterror.md) (from checkFetch(), trySync(), tryPush()) + +[RemoteErr.NetworkError](./git-documentdb.remoteerr.networkerror.md) (from checkFetch(), trySync(), tryPush()) + +[RemoteErr.HTTPError401AuthorizationRequired](./git-documentdb.remoteerr.httperror401authorizationrequired.md) (from checkFetch(), trySync(), tryPush()) + +[RemoteErr.HTTPError404NotFound](./git-documentdb.remoteerr.httperror404notfound.md) (from checkFetch(), trySync(), tryPush()) + +[RemoteErr.CannotConnectError](./git-documentdb.remoteerr.cannotconnecterror.md) (from checkFetch(), trySync(), tryPush()) + + (from checkFetch(), trySync(), tryPush()) + +[RemoteErr.InvalidRepositoryURLError](./git-documentdb.remoteerr.invalidrepositoryurlerror.md) (from checkFetch(), trySync(), tryPush()) + +[RemoteErr.InvalidSSHKeyPathError](./git-documentdb.remoteerr.invalidsshkeypatherror.md) (from checkFetch, trySync(), tryPush()) + +[RemoteErr.InvalidAuthenticationTypeError](./git-documentdb.remoteerr.invalidauthenticationtypeerror.md) (from checkFetch(), trySync(), tryPush()) + +[RemoteErr.UnfetchedCommitExistsError](./git-documentdb.remoteerr.unfetchedcommitexistserror.md) (from tryPush()) + +[RemoteErr.HTTPError403Forbidden](./git-documentdb.remoteerr.httperror403forbidden.md) (from tryPush()) + +[Err.NoMergeBaseFoundError](./git-documentdb.err.nomergebasefounderror.md) (from trySync()) -[Err.PushWorkerError](./git-documentdb.err.pushworkererror.md) +[Err.ThreeWayMergeError](./git-documentdb.err.threewaymergeerror.md) (from trySync()) -[Err.NoMergeBaseFoundError](./git-documentdb.err.nomergebasefounderror.md) +[Err.CannotDeleteDataError](./git-documentdb.err.cannotdeletedataerror.md) (from trySync()) -[Err.SyncWorkerError](./git-documentdb.err.syncworkererror.md) +[Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) (from trySync(), tryPush()) diff --git a/docs-api/git-documentdb.sync.md b/docs-api/git-documentdb.sync.md index e481353c..ebc7b31b 100644 --- a/docs-api/git-documentdb.sync.md +++ b/docs-api/git-documentdb.sync.md @@ -29,13 +29,13 @@ export declare class Sync implements SyncInterface | Property | Modifiers | Type | Description | | --- | --- | --- | --- | -| [credentialCallbacks](./git-documentdb.sync.credentialcallbacks.md) | | { \[key: string\]: any; } | Callback for authentication | +| [engine](./git-documentdb.sync.engine.md) | | string | | | [jsonDiff](./git-documentdb.sync.jsondiff.md) | | JsonDiff | JsonDiff | | [jsonPatch](./git-documentdb.sync.jsonpatch.md) | | JsonPatchOT | JsonPatch | | [options](./git-documentdb.sync.options.md) | | Required<[RemoteOptions](./git-documentdb.remoteoptions.md) > | Get a clone of remote options | +| [remoteName](./git-documentdb.sync.remotename.md) | | string | remoteName | | [remoteRepository](./git-documentdb.sync.remoterepository.md) | | [RemoteRepository](./git-documentdb.remoterepository.md) | Remote repository | | [remoteURL](./git-documentdb.sync.remoteurl.md) | | string | remoteURL | -| [upstreamBranch](./git-documentdb.sync.upstreambranch.md) | | string | upstreamBranch | ## Methods @@ -43,13 +43,12 @@ export declare class Sync implements SyncInterface | --- | --- | --- | | [close()](./git-documentdb.sync.close.md) | | Stop and clear remote connection | | [currentRetries()](./git-documentdb.sync.currentretries.md) | | Return current retry count (incremental) | -| [enqueuePushTask()](./git-documentdb.sync.enqueuepushtask.md) | | Enqueue push task to TaskQueue | | [enqueueSyncTask()](./git-documentdb.sync.enqueuesynctask.md) | | Enqueue sync task to TaskQueue | -| [init(repos)](./git-documentdb.sync.init.md) | | Create remote connection | +| [init()](./git-documentdb.sync.init.md) | | Initialize remote connection | | [off(event, callback)](./git-documentdb.sync.off.md) | | Remove SyncEvent handler | | [on(event, callback, collectionPath)](./git-documentdb.sync.on.md) | | Add SyncEvent handler | | [pause()](./git-documentdb.sync.pause.md) | | Pause synchronization | | [resume(options)](./git-documentdb.sync.resume.md) | | Resume synchronization | -| [tryPush()](./git-documentdb.sync.trypush.md) | | Try to push with retries | +| [tryPush()](./git-documentdb.sync.trypush.md) | | Try to push | | [trySync()](./git-documentdb.sync.trysync.md) | | Try to sync with retries | diff --git a/docs-api/git-documentdb.sync.remotename.md b/docs-api/git-documentdb.sync.remotename.md new file mode 100644 index 00000000..925fa157 --- /dev/null +++ b/docs-api/git-documentdb.sync.remotename.md @@ -0,0 +1,17 @@ +--- +sidebar_label: remoteName +title: Sync.remoteName property +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [Sync](./git-documentdb.sync.md) > [remoteName](./git-documentdb.sync.remotename.md) + +## Sync.remoteName property + +remoteName + +Signature: + +```typescript +get remoteName(): string; +``` diff --git a/docs-api/git-documentdb.sync.trypush.md b/docs-api/git-documentdb.sync.trypush.md index 6f6f3fd4..4786faae 100644 --- a/docs-api/git-documentdb.sync.trypush.md +++ b/docs-api/git-documentdb.sync.trypush.md @@ -8,7 +8,7 @@ hide_title: true ## Sync.tryPush() method -Try to push with retries +Try to push Signature: @@ -21,9 +21,35 @@ Promise<[SyncResultPush](./git-documentdb.syncresultpush.md) \| [SyncResultCa ## Exceptions -[Err.PushNotAllowedError](./git-documentdb.err.pushnotallowederror.md) (from this and enqueuePushTask) +[Err.PushNotAllowedError](./git-documentdb.err.pushnotallowederror.md) -[Err.PushWorkerError](./git-documentdb.err.pushworkererror.md) (from this and enqueuePushTask) + (from pushWorker()) -[Err.UnfetchedCommitExistsError](./git-documentdb.err.unfetchedcommitexistserror.md) (from this and enqueuePushTask) + (from pushWorker()) + + (from pushWorker()) + + (from pushWorker()) + + (from pushWorker()) + + (from pushWorker()) + + (from pushWorker()) + + (from pushWorker()) + + (from pushWorker()) + + (from pushWorker()) + + (from pushWorker()) + + (from pushWorker()) + + (from pushWorker()) + + (from pushWorker()) + +[Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) (from pushWorker()) diff --git a/docs-api/git-documentdb.sync.trysync.md b/docs-api/git-documentdb.sync.trysync.md index 7c1be9ad..4698b3bb 100644 --- a/docs-api/git-documentdb.sync.trysync.md +++ b/docs-api/git-documentdb.sync.trysync.md @@ -21,11 +21,63 @@ Promise<[SyncResult](./git-documentdb.syncresult.md) > ## Exceptions -[Err.PushNotAllowedError](./git-documentdb.err.pushnotallowederror.md) (from this and enqueueSyncTask) +[Err.PushNotAllowedError](./git-documentdb.err.pushnotallowederror.md) -[Err.SyncWorkerError](./git-documentdb.err.syncworkererror.md) (from enqueueSyncTask) +[Err.CombineDatabaseError](./git-documentdb.err.combinedatabaseerror.md) -[Err.NoMergeBaseFoundError](./git-documentdb.err.nomergebasefounderror.md) (from enqueueSyncTask) +[Err.NoMergeBaseFoundError](./git-documentdb.err.nomergebasefounderror.md) (from syncWorker()) -[Err.UnfetchedCommitExistsError](./git-documentdb.err.unfetchedcommitexistserror.md) (from enqueueSyncTask) +[RemoteErr.InvalidGitRemoteError](./git-documentdb.remoteerr.invalidgitremoteerror.md) (from syncWorker()) + +[RemoteErr.InvalidURLFormatError](./git-documentdb.remoteerr.invalidurlformaterror.md) (from syncWorker()) + +[RemoteErr.NetworkError](./git-documentdb.remoteerr.networkerror.md) (from syncWorker()) + +[RemoteErr.HTTPError401AuthorizationRequired](./git-documentdb.remoteerr.httperror401authorizationrequired.md) (from syncWorker()) + +[RemoteErr.HTTPError404NotFound](./git-documentdb.remoteerr.httperror404notfound.md) (from syncWorker()) + +[RemoteErr.CannotConnectError](./git-documentdb.remoteerr.cannotconnecterror.md) (from syncWorker()) + + (from syncWorker()) + +[RemoteErr.InvalidRepositoryURLError](./git-documentdb.remoteerr.invalidrepositoryurlerror.md) (from syncWorker()) + +[RemoteErr.InvalidSSHKeyPathError](./git-documentdb.remoteerr.invalidsshkeypatherror.md) (from syncWorker()) + +[RemoteErr.InvalidAuthenticationTypeError](./git-documentdb.remoteerr.invalidauthenticationtypeerror.md) (from syncWorker()) + +[RemoteErr.HTTPError403Forbidden](./git-documentdb.remoteerr.httperror403forbidden.md) (from syncWorker()) + +[RemoteErr.UnfetchedCommitExistsError](./git-documentdb.remoteerr.unfetchedcommitexistserror.md) (from syncWorker()) + +[Err.InvalidConflictStateError](./git-documentdb.err.invalidconflictstateerror.md) (from syncWorker()) + +[Err.CannotDeleteDataError](./git-documentdb.err.cannotdeletedataerror.md) (from syncWorker()) + +[Err.InvalidDocTypeError](./git-documentdb.err.invaliddoctypeerror.md) (from syncWorker()) + +[Err.InvalidConflictResolutionStrategyError](./git-documentdb.err.invalidconflictresolutionstrategyerror.md) (from syncWorker()) + +[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) (from syncWorker()) + +[Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) (from syncWorker()) + + (from combineDatabaseWithTheirs()) + + (from combineDatabaseWithTheirs()) + + (from combineDatabaseWithTheirs()) + + (from combineDatabaseWithTheirs()) + + (from combineDatabaseWithTheirs()) + + (from combineDatabaseWithTheirs()) + + (from combineDatabaseWithTheirs()) + + (from combineDatabaseWithTheirs()) + + (from combineDatabaseWithTheirs()) diff --git a/docs-api/git-documentdb.sync.upstreambranch.md b/docs-api/git-documentdb.sync.upstreambranch.md deleted file mode 100644 index 1649fe36..00000000 --- a/docs-api/git-documentdb.sync.upstreambranch.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -sidebar_label: upstreamBranch -title: Sync.upstreamBranch property -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [Sync](./git-documentdb.sync.md) > [upstreamBranch](./git-documentdb.sync.upstreambranch.md) - -## Sync.upstreamBranch property - -upstreamBranch - -Signature: - -```typescript -get upstreamBranch(): string; -``` diff --git a/docs-api/git-documentdb.syncinterface.credentialcallbacks.md b/docs-api/git-documentdb.syncinterface.credentialcallbacks.md deleted file mode 100644 index 97c8df78..00000000 --- a/docs-api/git-documentdb.syncinterface.credentialcallbacks.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -sidebar_label: credentialCallbacks -title: SyncInterface.credentialCallbacks property -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [SyncInterface](./git-documentdb.syncinterface.md) > [credentialCallbacks](./git-documentdb.syncinterface.credentialcallbacks.md) - -## SyncInterface.credentialCallbacks property - -Signature: - -```typescript -credentialCallbacks: { - [key: string]: any; - }; -``` diff --git a/docs-api/git-documentdb.syncinterface.engine.md b/docs-api/git-documentdb.syncinterface.engine.md new file mode 100644 index 00000000..45571012 --- /dev/null +++ b/docs-api/git-documentdb.syncinterface.engine.md @@ -0,0 +1,15 @@ +--- +sidebar_label: engine +title: SyncInterface.engine property +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [SyncInterface](./git-documentdb.syncinterface.md) > [engine](./git-documentdb.syncinterface.engine.md) + +## SyncInterface.engine property + +Signature: + +```typescript +engine: string; +``` diff --git a/docs-api/git-documentdb.syncinterface.enqueuepushtask.md b/docs-api/git-documentdb.syncinterface.enqueuepushtask.md deleted file mode 100644 index d1ea72a8..00000000 --- a/docs-api/git-documentdb.syncinterface.enqueuepushtask.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -sidebar_label: enqueuePushTask() -title: SyncInterface.enqueuePushTask() method -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [SyncInterface](./git-documentdb.syncinterface.md) > [enqueuePushTask](./git-documentdb.syncinterface.enqueuepushtask.md) - -## SyncInterface.enqueuePushTask() method - -Signature: - -```typescript -enqueuePushTask(): Promise; -``` -Returns: - -Promise<[SyncResultPush](./git-documentdb.syncresultpush.md) \| [SyncResultCancel](./git-documentdb.syncresultcancel.md) > - diff --git a/docs-api/git-documentdb.syncinterface.enqueuesynctask.md b/docs-api/git-documentdb.syncinterface.enqueuesynctask.md deleted file mode 100644 index 061279fb..00000000 --- a/docs-api/git-documentdb.syncinterface.enqueuesynctask.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -sidebar_label: enqueueSyncTask() -title: SyncInterface.enqueueSyncTask() method -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [SyncInterface](./git-documentdb.syncinterface.md) > [enqueueSyncTask](./git-documentdb.syncinterface.enqueuesynctask.md) - -## SyncInterface.enqueueSyncTask() method - -Signature: - -```typescript -enqueueSyncTask(): Promise; -``` -Returns: - -Promise<[SyncResult](./git-documentdb.syncresult.md) > - diff --git a/docs-api/git-documentdb.syncinterface.init.md b/docs-api/git-documentdb.syncinterface.init.md index 50c0c1b6..89eb179e 100644 --- a/docs-api/git-documentdb.syncinterface.init.md +++ b/docs-api/git-documentdb.syncinterface.init.md @@ -13,15 +13,8 @@ hide_title: true Signature: ```typescript -init(repos: nodegit.Repository): Promise; +init(): Promise; ``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| repos | nodegit.Repository | | - Returns: Promise<[SyncResult](./git-documentdb.syncresult.md) > diff --git a/docs-api/git-documentdb.syncinterface.md b/docs-api/git-documentdb.syncinterface.md index 247c55bb..e11fe670 100644 --- a/docs-api/git-documentdb.syncinterface.md +++ b/docs-api/git-documentdb.syncinterface.md @@ -20,13 +20,13 @@ export interface SyncInterface | Property | Type | Description | | --- | --- | --- | -| [credentialCallbacks](./git-documentdb.syncinterface.credentialcallbacks.md) | { \[key: string\]: any; } | | +| [engine](./git-documentdb.syncinterface.engine.md) | string | | | [jsonDiff](./git-documentdb.syncinterface.jsondiff.md) | JsonDiff | | | [jsonPatch](./git-documentdb.syncinterface.jsonpatch.md) | IJsonPatch | | | [options](./git-documentdb.syncinterface.options.md) | [RemoteOptions](./git-documentdb.remoteoptions.md) | | +| [remoteName](./git-documentdb.syncinterface.remotename.md) | string | | | [remoteRepository](./git-documentdb.syncinterface.remoterepository.md) | [RemoteRepository](./git-documentdb.remoterepository.md) | | | [remoteURL](./git-documentdb.syncinterface.remoteurl.md) | string | \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* Public properties (readonly) \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* | -| [upstreamBranch](./git-documentdb.syncinterface.upstreambranch.md) | string | | ## Methods @@ -34,9 +34,7 @@ export interface SyncInterface | --- | --- | | [close()](./git-documentdb.syncinterface.close.md) | | | [currentRetries()](./git-documentdb.syncinterface.currentretries.md) | | -| [enqueuePushTask()](./git-documentdb.syncinterface.enqueuepushtask.md) | | -| [enqueueSyncTask()](./git-documentdb.syncinterface.enqueuesynctask.md) | | -| [init(repos)](./git-documentdb.syncinterface.init.md) | \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* Public methods \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* | +| [init()](./git-documentdb.syncinterface.init.md) | \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* Public methods \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* | | [off(event, callback)](./git-documentdb.syncinterface.off.md) | | | [on(event, callback, collectionPath)](./git-documentdb.syncinterface.on.md) | | | [pause()](./git-documentdb.syncinterface.pause.md) | | diff --git a/docs-api/git-documentdb.syncinterface.off.md b/docs-api/git-documentdb.syncinterface.off.md index ab9388a2..41f8487f 100644 --- a/docs-api/git-documentdb.syncinterface.off.md +++ b/docs-api/git-documentdb.syncinterface.off.md @@ -11,7 +11,7 @@ hide_title: true Signature: ```typescript -off(event: SyncEvent, callback: SyncCallback): void; +off(event: SyncEvent, callback: SyncCallback): SyncInterface; ``` ## Parameters @@ -23,5 +23,5 @@ off(event: SyncEvent, callback: SyncCallback): void; Returns: -void +[SyncInterface](./git-documentdb.syncinterface.md) diff --git a/docs-api/git-documentdb.syncinterface.remotename.md b/docs-api/git-documentdb.syncinterface.remotename.md new file mode 100644 index 00000000..be112f60 --- /dev/null +++ b/docs-api/git-documentdb.syncinterface.remotename.md @@ -0,0 +1,15 @@ +--- +sidebar_label: remoteName +title: SyncInterface.remoteName property +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [SyncInterface](./git-documentdb.syncinterface.md) > [remoteName](./git-documentdb.syncinterface.remotename.md) + +## SyncInterface.remoteName property + +Signature: + +```typescript +remoteName: string; +``` diff --git a/docs-api/git-documentdb.syncinterface.upstreambranch.md b/docs-api/git-documentdb.syncinterface.upstreambranch.md deleted file mode 100644 index cab3081e..00000000 --- a/docs-api/git-documentdb.syncinterface.upstreambranch.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -sidebar_label: upstreamBranch -title: SyncInterface.upstreamBranch property -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [SyncInterface](./git-documentdb.syncinterface.md) > [upstreamBranch](./git-documentdb.syncinterface.upstreambranch.md) - -## SyncInterface.upstreamBranch property - -Signature: - -```typescript -upstreamBranch: string; -``` diff --git a/docs-api/git-documentdb.wrappingremoteengineerror.md b/docs-api/git-documentdb.wrappingremoteengineerror.md new file mode 100644 index 00000000..ebae7031 --- /dev/null +++ b/docs-api/git-documentdb.wrappingremoteengineerror.md @@ -0,0 +1,26 @@ +--- +sidebar_label: wrappingRemoteEngineError() function +title: wrappingRemoteEngineError() function +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [wrappingRemoteEngineError](./git-documentdb.wrappingremoteengineerror.md) + +## wrappingRemoteEngineError() function + +Signature: + +```typescript +export declare function wrappingRemoteEngineError(remoteEngineError: RemoteErrors.BaseError): Error; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| remoteEngineError | RemoteErrors.BaseError | | + +Returns: + +Error + diff --git a/etc/git-documentdb.api.md b/etc/git-documentdb.api.md index eada2f36..efc76fe0 100644 --- a/etc/git-documentdb.api.md +++ b/etc/git-documentdb.api.md @@ -6,7 +6,7 @@ import { JSONOp } from 'ot-json1'; import { Logger } from 'tslog'; -import nodegit from '@sosuisen/nodegit'; +import * as RemoteErrors from 'git-documentdb-remote-errors'; import { TLogLevelName } from 'tslog'; // @public @@ -45,11 +45,6 @@ export type ChangedFileUpdate = { new: FatDoc; }; -// Warning: (ae-internal-missing-underscore) The name "cloneRepository" should be prefixed with an underscore because the declaration is marked as @internal -// -// @internal -export function cloneRepository(workingDir: string, remoteOptions: RemoteOptions, logger?: Logger): Promise; - // @public export class Collection implements ICollection { constructor(gitDDB: GitDDBInterface, collectionPathFromParent?: CollectionPath, parent?: ICollection, options?: CollectionOptions); @@ -133,6 +128,7 @@ export type ConnectionSettings = ConnectionSettingsNone | ConnectionSettingsGitH // @public export type ConnectionSettingsGitHub = { type: 'github'; + engine?: string; personalAccessToken?: string; private?: boolean; }; @@ -140,11 +136,13 @@ export type ConnectionSettingsGitHub = { // @public export type ConnectionSettingsNone = { type: 'none'; + engine?: string; }; // @public export type ConnectionSettingsSSH = { type: 'ssh'; + engine?: string; privateKeyPath: string; publicKeyPath: string; passPhrase?: string; @@ -306,6 +304,9 @@ export type DuplicatedFile = { duplicate: DocMetadata; }; +// @public +export function encodeToGitRemoteName(remoteURL: string): string; + // @public export namespace Err { // (undocumented) @@ -316,7 +317,7 @@ export namespace Err { constructor(e: string); } // (undocumented) - export class CannotConnectError extends BaseError { + export class CannotConnectRemoteRepositoryError extends BaseError { constructor(retry: number, url: string, mes: string); // (undocumented) retry: number; @@ -366,14 +367,6 @@ export namespace Err { constructor(e?: unknown); } // (undocumented) - export class FetchConnectionFailedError extends BaseError { - constructor(mes: unknown); - } - // (undocumented) - export class FetchPermissionDeniedError extends BaseError { - constructor(mes: unknown); - } - // (undocumented) export class FileRemoveTimeoutError extends BaseError { constructor(); } @@ -382,10 +375,6 @@ export namespace Err { constructor(mes: string); } // (undocumented) - export class GitPushError extends BaseError { - constructor(mes: string); - } - // (undocumented) export class HTTPNetworkError extends BaseError { constructor(mes: unknown); } @@ -398,10 +387,6 @@ export namespace Err { constructor(min: unknown, current: unknown); } // (undocumented) - export class InvalidAuthenticationTypeError extends BaseError { - constructor(type: string); - } - // (undocumented) export class InvalidCollectionPathCharacterError extends BaseError { constructor(name: unknown); } @@ -410,6 +395,10 @@ export namespace Err { constructor(collectionPath: unknown, minLength: unknown, maxLength: unknown); } // (undocumented) + export class InvalidConflictResolutionStrategyError extends BaseError { + constructor(); + } + // (undocumented) export class InvalidConflictStateError extends BaseError { constructor(mes: unknown); } @@ -442,18 +431,6 @@ export namespace Err { constructor(name: unknown); } // (undocumented) - export class InvalidRepositoryURLError extends BaseError { - constructor(url: unknown); - } - // (undocumented) - export class InvalidSSHKeyPathError extends BaseError { - constructor(); - } - // (undocumented) - export class InvalidURLError extends BaseError { - constructor(url: unknown); - } - // (undocumented) export class InvalidWorkingDirectoryPathLengthError extends BaseError { constructor(path: unknown, minLength: unknown, maxLength: unknown); } @@ -466,18 +443,10 @@ export namespace Err { constructor(); } // (undocumented) - export class PushConnectionFailedError extends BaseError { - constructor(mes: unknown); - } - // (undocumented) export class PushNotAllowedError extends BaseError { constructor(direction: unknown); } // (undocumented) - export class PushPermissionDeniedError extends BaseError { - constructor(mes: unknown); - } - // (undocumented) export class PushWorkerError extends BaseError { constructor(mes: unknown); } @@ -486,14 +455,6 @@ export namespace Err { constructor(url: unknown); } // (undocumented) - export class RemoteRepositoryConnectError extends BaseError { - constructor(mes: unknown); - } - // (undocumented) - export class RemoteRepositoryNotFoundError extends BaseError { - constructor(url: unknown); - } - // (undocumented) export class RepositoryNotFoundError extends BaseError { constructor(path: unknown); } @@ -522,10 +483,6 @@ export namespace Err { constructor(mes: unknown); } // (undocumented) - export class SyncWorkerFetchError extends BaseError { - constructor(mes: string); - } - // (undocumented) export class TaskCancelError extends BaseError { constructor(taskId: unknown); } @@ -557,11 +514,7 @@ export namespace Err { export class UndefinedSyncError extends BaseError { constructor(e?: unknown); } - // (undocumented) - export class UnfetchedCommitExistsError extends BaseError { - constructor(); - } - {}; + {}; } // @public @@ -674,8 +627,6 @@ export interface GitDDBInterface { // (undocumented) removeSync(remoteURL: string): void; // (undocumented) - repository(): nodegit.Repository | undefined; - // (undocumented) rootCollection: ICollection; // (undocumented) saveAppInfo(info: { @@ -686,8 +637,6 @@ export interface GitDDBInterface { // (undocumented) schema: Schema; // (undocumented) - setRepository(repos: nodegit.Repository): void; - // (undocumented) sync(options: RemoteOptions, getSyncResult: boolean): Promise<[SyncInterface, SyncResult]>; // (undocumented) sync(options: RemoteOptions): Promise; @@ -756,20 +705,18 @@ export class GitDocumentDB implements GitDDBInterface, CRUDInterface, Collection // @eventProperty onSyncEvent(sync: SyncInterface, event: SyncEvent, callback: SyncCallback): SyncInterface; open(openOptions?: OpenOptions): Promise; + // (undocumented) + static plugin(obj: any): void; put(jsonDoc: JsonDoc, options?: PutOptions): Promise; put(_id: string | undefined | null, jsonDoc: JsonDoc, options?: PutOptions): Promise; putFatDoc(name: string | undefined | null, doc: JsonDoc | Uint8Array | string, options?: PutOptions): Promise; removeSync(remoteURL: string): void; - // @deprecated - repository(): nodegit.Repository | undefined; get rootCollection(): ICollection; saveAppInfo(info: { [key: string]: any; }): Promise; saveAuthor(): Promise; get schema(): Schema; - // @deprecated - setRepository(repos: nodegit.Repository): void; sync(options: RemoteOptions): Promise; sync(options: RemoteOptions, getSyncResult: boolean): Promise<[Sync, SyncResult]>; get taskQueue(): TaskQueue; @@ -778,7 +725,7 @@ export class GitDocumentDB implements GitDDBInterface, CRUDInterface, Collection updateFatDoc(name: string | undefined | null, doc: JsonDoc | string | Uint8Array, options?: PutOptions): Promise; get validator(): Validator; get workingDir(): string; - } +} // @public export type HistoryFilter = { @@ -879,6 +826,9 @@ export type OpenOptions = { createIfNotExists?: boolean; }; +// @public +export type PluginTypes = 'db' | 'remote'; + // @public (undocumented) export const PUT_APP_INFO_MESSAGE = "put appinfo"; @@ -918,6 +868,70 @@ export type PutResultText = { type: 'text'; }; +// @public (undocumented) +export const RemoteEngine: { + [key: string]: RemoteEngineInterface; +}; + +// @public (undocumented) +export interface RemoteEngineInterface { + // (undocumented) + checkFetch: (workingDir: string, options: RemoteOptions, remoteName?: string, logger?: Logger) => Promise; + // (undocumented) + clone: (workingDir: string, remoteOptions: RemoteOptions, remoteName: string, logger?: Logger) => Promise; + // (undocumented) + fetch: (workingDir: string, remoteOptions: RemoteOptions, remoteName?: string, logger?: Logger) => Promise; + // (undocumented) + push: (workingDir: string, remoteOptions: RemoteOptions, remoteName?: string, localBranch?: string, remoteBranch?: string, logger?: Logger) => Promise; +} + +// @public (undocumented) +export namespace RemoteErr { + export class CannotConnectError extends RemoteErrors.CannotConnectError { + constructor(mes: unknown); + } + // (undocumented) + export class HTTPError401AuthorizationRequired extends RemoteErrors.HTTPError401AuthorizationRequired { + constructor(mes: unknown); + } + // (undocumented) + export class HTTPError403Forbidden extends RemoteErrors.HTTPError403Forbidden { + constructor(mes: unknown); + } + // (undocumented) + export class HTTPError404NotFound extends RemoteErrors.HTTPError404NotFound { + constructor(mes: unknown); + } + // (undocumented) + export class InvalidAuthenticationTypeError extends RemoteErrors.InvalidAuthenticationTypeError { + constructor(mes: unknown); + } + // (undocumented) + export class InvalidGitRemoteError extends RemoteErrors.InvalidGitRemoteError { + constructor(mes: unknown); + } + // (undocumented) + export class InvalidRepositoryURLError extends RemoteErrors.InvalidRepositoryURLError { + constructor(mes: unknown); + } + // (undocumented) + export class InvalidSSHKeyPathError extends RemoteErrors.InvalidSSHKeyPathError { + constructor(mes: unknown); + } + // (undocumented) + export class InvalidURLFormatError extends RemoteErrors.InvalidURLFormatError { + constructor(mes: unknown); + } + // (undocumented) + export class NetworkError extends RemoteErrors.NetworkError { + constructor(mes: unknown); + } + // (undocumented) + export class UnfetchedCommitExistsError extends RemoteErrors.UnfetchedCommitExistsError { + constructor(mes: unknown); + } +} + // @public export type RemoteOptions = { remoteUrl?: string; @@ -935,13 +949,9 @@ export type RemoteOptions = { // @public export class RemoteRepository { constructor(options: RemoteOptions); - // Warning: (ae-forgotten-export) The symbol "GitRemoteAction" needs to be exported by the entry point main.d.ts - connect(repos: nodegit.Repository, credentialCallbacks: { - [key: string]: any; - }, onlyFetch?: boolean): Promise<[GitRemoteAction, 'exist' | 'create']>; create(): Promise; destroy(): Promise; - } +} // @public export type Schema = { @@ -957,14 +967,10 @@ export const SHORT_SHA_LENGTH = 7; // @public export class Sync implements SyncInterface { constructor(gitDDB: GitDDBInterface, options?: RemoteOptions); - // @internal - canNetworkConnection(): Promise; close(): void; - credentialCallbacks: { - [key: string]: any; - }; currentRetries(): number; - enqueuePushTask(): Promise; + // (undocumented) + get engine(): string; enqueueSyncTask(): Promise; // @internal eventHandlers: { @@ -1005,7 +1011,7 @@ export class Sync implements SyncInterface { func: SyncErrorCallback; }[]; }; - init(repos: nodegit.Repository): Promise; + init(): Promise; // Warning: (ae-forgotten-export) The symbol "JsonDiff" needs to be exported by the entry point main.d.ts jsonDiff: JsonDiff; // Warning: (ae-forgotten-export) The symbol "JsonPatchOT" needs to be exported by the entry point main.d.ts @@ -1016,6 +1022,7 @@ export class Sync implements SyncInterface { on(event: SyncEvent, callback: SyncCallback, collectionPath?: string): this; get options(): Required; pause(): boolean; + get remoteName(): string; get remoteRepository(): RemoteRepository; get remoteURL(): string; resume(options?: { @@ -1024,8 +1031,7 @@ export class Sync implements SyncInterface { }): boolean; tryPush(): Promise; trySync(): Promise; - get upstreamBranch(): string; - } +} // Warning: (ae-internal-missing-underscore) The name "syncAndGetResultImpl" should be prefixed with an underscore because the declaration is marked as @internal // @@ -1079,15 +1085,9 @@ export interface SyncInterface { // (undocumented) close(): void; // (undocumented) - credentialCallbacks: { - [key: string]: any; - }; - // (undocumented) currentRetries(): number; // (undocumented) - enqueuePushTask(): Promise; - // (undocumented) - enqueueSyncTask(): Promise; + engine: string; // @internal (undocumented) eventHandlers: { change: { @@ -1127,7 +1127,7 @@ export interface SyncInterface { func: SyncErrorCallback; }[]; }; - init(repos: nodegit.Repository): Promise; + init(): Promise; // (undocumented) jsonDiff: JsonDiff; // Warning: (ae-incompatible-release-tags) The symbol "jsonPatch" is marked as @public, but its signature references "IJsonPatch" which is marked as @internal @@ -1135,7 +1135,7 @@ export interface SyncInterface { // (undocumented) jsonPatch: IJsonPatch; // (undocumented) - off(event: SyncEvent, callback: SyncCallback): void; + off(event: SyncEvent, callback: SyncCallback): SyncInterface; // (undocumented) on(event: SyncEvent, callback: SyncCallback, collectionPath?: string): SyncInterface; // (undocumented) @@ -1143,6 +1143,8 @@ export interface SyncInterface { // (undocumented) pause(): void; // (undocumented) + remoteName: string; + // (undocumented) remoteRepository: RemoteRepository; remoteURL: string; // (undocumented) @@ -1154,8 +1156,6 @@ export interface SyncInterface { tryPush(): Promise; // (undocumented) trySync(): Promise; - // (undocumented) - upstreamBranch: string; } // @public @@ -1348,10 +1348,12 @@ export class Validator { validateDocument(doc: JsonDoc): void; validateId(_id: string): void; validateLocalDir(localDir: string): void; - } +} + +// @public (undocumented) +export function wrappingRemoteEngineError(remoteEngineError: RemoteErrors.BaseError): Error; // @public export type WriteOperation = 'insert' | 'update' | 'delete' | 'insert-merge' | 'update-merge'; - ``` diff --git a/package-lock.json b/package-lock.json index 1206d6a3..0aaf3422 100644 --- a/package-lock.json +++ b/package-lock.json @@ -945,9 +945,9 @@ "dev": true }, "@sosuisen/api-documenter": { - "version": "7.13.25", - "resolved": "https://registry.npmjs.org/@sosuisen/api-documenter/-/api-documenter-7.13.25.tgz", - "integrity": "sha512-/BW6yDpP9DJGUtD/KD42DQR+Od7Gje1gAnrpwotwpEGhqCzAPyzZiV5z/1eegZfWbnmvtrPSbsCAtVkAhXmLZA==", + "version": "7.13.27", + "resolved": "https://registry.npmjs.org/@sosuisen/api-documenter/-/api-documenter-7.13.27.tgz", + "integrity": "sha512-Y3uEwBRSbxEvlLXRD/YcaRhsVNVWMDRLE/EOVDAUzPYy5FrdXiNK0GZNdmxrjCe2E58W/bGKUTZnw9sOI2YOZg==", "dev": true, "requires": { "@microsoft/api-extractor-model": "^7.13.3", @@ -3524,9 +3524,9 @@ "dev": true }, "git-documentdb-plugin-remote-nodegit": { - "version": "1.0.0-beta.4", - "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.0-beta.4.tgz", - "integrity": "sha512-SxcktTdPoyjhJTH1CzOxPvMOMLWXyO7S9uxgmA3EG1ZxPt3dsMni0hVyhO2G8zY7nEpeAYXob/Fp2t4GQokKTQ==", + "version": "1.0.0-beta.5", + "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.0-beta.5.tgz", + "integrity": "sha512-Lmodd7K6q4WwYMGe/C/TbxhrbLvjxNwi3xk4rv0VQsOCcBsevw7c97E4OpqNx5JNLZXltXnLBkxAQpVR9ewq6w==", "dev": true, "requires": { "git-documentdb-remote-errors": "^1.0.3", diff --git a/package.json b/package.json index d2b5844e..d7d9f076 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "devDependencies": { "@microsoft/api-extractor": "^7.16.0", "@octokit/types": "^6.12.2", - "@sosuisen/api-documenter": "^7.13.25", + "@sosuisen/api-documenter": "^7.13.27", "@types/expect": "^24.3.0", "@types/fs-extra": "^9.0.12", "@types/mocha": "^8.2.2", @@ -62,7 +62,7 @@ "eslint-config-standardize": "^0.7.1", "eslint-plugin-prettierx": "^0.14.0", "expect": "^27.0.2", - "git-documentdb-plugin-remote-nodegit": "^1.0.0-beta.4", + "git-documentdb-plugin-remote-nodegit": "^1.0.0-beta.5", "mocha": "^8.3.2", "nyc": "^15.1.0", "parse-git-config": "^3.0.0", diff --git a/src/collection.ts b/src/collection.ts index 23a14541..6850d04a 100644 --- a/src/collection.ts +++ b/src/collection.ts @@ -235,16 +235,18 @@ export class Collection implements ICollection { * * @throws {@link Err.InvalidJsonObjectError} * - * @throws {@link Err.InvalidIdCharacterError} (from validateDocument, validateId) - * @throws {@link Err.InvalidIdLengthError} (from validateDocument, validateId) + * @throws # from validateDocument, validateId + * @throws {@link Err.InvalidIdCharacterError} + * @throws {@link Err.InvalidIdLengthError} * - * @throws {@link Err.DatabaseClosingError} (fromm putImpl) - * @throws {@link Err.TaskCancelError} (from putImpl) - * - * @throws {@link Err.UndefinedDBError} (fromm putWorker) - * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) - * @throws {@link Err.CannotWriteDataError} (from putWorker) + * @throws # from putImpl + * @throws {@link Err.DatabaseClosingError} + * @throws {@link Err.TaskCancelError} * + * @throws # from putWorker + * @throws {@link Err.UndefinedDBError} + * @throws {@link Err.CannotCreateDirectoryError} + * @throws {@link Err.CannotWriteDataError} * @public */ put (jsonDoc: JsonDoc, options?: PutOptions): Promise; @@ -265,16 +267,18 @@ export class Collection implements ICollection { * * @throws {@link Err.InvalidJsonObjectError} * - * @throws {@link Err.InvalidIdCharacterError} (from validateDocument, validateId) - * @throws {@link Err.InvalidIdLengthError} (from validateDocument, validateId) - * @throws {@link Err.InvalidCollectionPathCharacterError} (from validateDocument, validateId) + * @throws # from validateDocument, validateId + * @throws {@link Err.InvalidIdCharacterError} + * @throws {@link Err.InvalidIdLengthError} * - * @throws {@link Err.DatabaseClosingError} (fromm putImpl) - * @throws {@link Err.TaskCancelError} (from putImpl) + * @throws # from putImpl + * @throws {@link Err.DatabaseClosingError} + * @throws {@link Err.TaskCancelError} * - * @throws {@link Err.UndefinedDBError} (fromm putWorker) - * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) - * @throws {@link Err.CannotWriteDataError} (from putWorker) + * @throws # from putWorker + * @throws {@link Err.UndefinedDBError} + * @throws {@link Err.CannotCreateDirectoryError} + * @throws {@link Err.CannotWriteDataError} * * @public */ @@ -377,17 +381,20 @@ export class Collection implements ICollection { * * @throws {@link Err.InvalidJsonObjectError} * - * @throws {@link Err.InvalidIdCharacterError} (from validateDocument, validateId) - * @throws {@link Err.InvalidIdLengthError} (from validateDocument, validateId) + * @throws # from validateDocument, validateId + * @throws {@link Err.InvalidIdCharacterError} + * @throws {@link Err.InvalidIdLengthError} * - * @throws {@link Err.DatabaseClosingError} (fromm putImpl) - * @throws {@link Err.TaskCancelError} (from putImpl) + * @throws # from putImpl + * @throws {@link Err.DatabaseClosingError} + * @throws {@link Err.TaskCancelError} * - * @throws {@link Err.UndefinedDBError} (fromm putWorker) - * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) - * @throws {@link Err.CannotWriteDataError} (from putWorker) + * @throws # from putWorker + * @throws {@link Err.UndefinedDBError} + * @throws {@link Err.CannotCreateDirectoryError} + * @throws {@link Err.CannotWriteDataError} * - * @throws {@link Err.SameIdExistsError} (from putWorker) + * @throws {@link Err.SameIdExistsError} * * @public */ @@ -409,17 +416,20 @@ export class Collection implements ICollection { * * @throws {@link Err.InvalidJsonObjectError} * - * @throws {@link Err.InvalidIdCharacterError} (from validateDocument, validateId) - * @throws {@link Err.InvalidIdLengthError} (from validateDocument, validateId) + * @throws # from validateDocument, validateId + * @throws {@link Err.InvalidIdCharacterError} + * @throws {@link Err.InvalidIdLengthError} * - * @throws {@link Err.DatabaseClosingError} (fromm putImpl) - * @throws {@link Err.TaskCancelError} (from putImpl) + * @throws # from putImpl + * @throws {@link Err.DatabaseClosingError} + * @throws {@link Err.TaskCancelError} * - * @throws {@link Err.UndefinedDBError} (fromm putWorker) - * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) - * @throws {@link Err.CannotWriteDataError} (from putWorker) + * @throws # from putWorker + * @throws {@link Err.UndefinedDBError} + * @throws {@link Err.CannotCreateDirectoryError} + * @throws {@link Err.CannotWriteDataError} * - * @throws {@link Err.SameIdExistsError} (from putWorker) + * @throws {@link Err.SameIdExistsError} * * @public */ @@ -476,15 +486,18 @@ export class Collection implements ICollection { * * @throws {@link Err.InvalidJsonObjectError} * - * @throws {@link Err.InvalidIdCharacterError} (from validateDocument, validateId) - * @throws {@link Err.InvalidIdLengthError} (from validateDocument, validateId) + * @throws # from validateDocument, validateId + * @throws {@link Err.InvalidIdCharacterError} + * @throws {@link Err.InvalidIdLengthError} * - * @throws {@link Err.DatabaseClosingError} (fromm putImpl) - * @throws {@link Err.TaskCancelError} (from putImpl) + * @throws # from putImpl + * @throws {@link Err.DatabaseClosingError} + * @throws {@link Err.TaskCancelError} * - * @throws {@link Err.UndefinedDBError} (fromm putWorker) - * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) - * @throws {@link Err.CannotWriteDataError} (from putWorker) + * @throws # from putWorker + * @throws {@link Err.UndefinedDBError} + * @throws {@link Err.CannotCreateDirectoryError} + * @throws {@link Err.CannotWriteDataError} * * @throws {@link Err.DocumentNotFoundError} * @@ -506,15 +519,18 @@ export class Collection implements ICollection { * * @throws {@link Err.InvalidJsonObjectError} * - * @throws {@link Err.InvalidIdCharacterError} (from validateDocument, validateId) - * @throws {@link Err.InvalidIdLengthError} (from validateDocument, validateId) + * @throws # from validateDocument, validateId + * @throws {@link Err.InvalidIdCharacterError} + * @throws {@link Err.InvalidIdLengthError} * - * @throws {@link Err.DatabaseClosingError} (fromm putImpl) - * @throws {@link Err.TaskCancelError} (from putImpl) + * @throws # from putImpl + * @throws {@link Err.DatabaseClosingError} + * @throws {@link Err.TaskCancelError} * - * @throws {@link Err.UndefinedDBError} (fromm putWorker) - * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) - * @throws {@link Err.CannotWriteDataError} (from putWorker) + * @throws # from putWorker + * @throws {@link Err.UndefinedDBError} + * @throws {@link Err.CannotCreateDirectoryError} + * @throws {@link Err.CannotWriteDataError} * * @throws {@link Err.DocumentNotFoundError} * @@ -574,15 +590,18 @@ export class Collection implements ICollection { * @throws {@link Err.InvalidJsonFileExtensionError} * @throws {@link Err.InvalidJsonObjectError} * - * @throws {@link Err.InvalidIdCharacterError} (from validateDocument, validateId) - * @throws {@link Err.InvalidIdLengthError} (from validateDocument, validateId) + * @throws # from validateDocument, validateId + * @throws {@link Err.InvalidIdCharacterError} + * @throws {@link Err.InvalidIdLengthError} * - * @throws {@link Err.DatabaseClosingError} (fromm putImpl) - * @throws {@link Err.TaskCancelError} (from putImpl) + * @throws # from putImpl + * @throws {@link Err.DatabaseClosingError} + * @throws {@link Err.TaskCancelError} * - * @throws {@link Err.UndefinedDBError} (fromm putWorker) - * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) - * @throws {@link Err.CannotWriteDataError} (from putWorker) + * @throws # from putWorker + * @throws {@link Err.UndefinedDBError} + * @throws {@link Err.CannotCreateDirectoryError} + * @throws {@link Err.CannotWriteDataError} * * @public */ @@ -691,17 +710,20 @@ export class Collection implements ICollection { * * @throws {@link Err.InvalidJsonObjectError} * - * @throws {@link Err.InvalidIdCharacterError} (from validateDocument, validateId) - * @throws {@link Err.InvalidIdLengthError} (from validateDocument, validateId) + * @throws # from validateDocument, validateId + * @throws {@link Err.InvalidIdCharacterError} + * @throws {@link Err.InvalidIdLengthError} * - * @throws {@link Err.DatabaseClosingError} (fromm putImpl) - * @throws {@link Err.TaskCancelError} (from putImpl) + * @throws # fromm putImpl + * @throws {@link Err.DatabaseClosingError} + * @throws {@link Err.TaskCancelError} * - * @throws {@link Err.UndefinedDBError} (fromm putWorker) - * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) - * @throws {@link Err.CannotWriteDataError} (from putWorker) + * @throws # from putWorker + * @throws {@link Err.UndefinedDBError} + * @throws {@link Err.CannotCreateDirectoryError} + * @throws {@link Err.CannotWriteDataError} * - * @throws {@link Err.SameIdExistsError} (from putWorker) + * @throws {@link Err.SameIdExistsError} * * @public */ @@ -733,15 +755,18 @@ export class Collection implements ICollection { * * @throws {@link Err.InvalidJsonObjectError} * - * @throws {@link Err.InvalidIdCharacterError} (from validateDocument, validateId) - * @throws {@link Err.InvalidIdLengthError} (from validateDocument, validateId) + * @throws # from validateDocument, validateId + * @throws {@link Err.InvalidIdCharacterError} + * @throws {@link Err.InvalidIdLengthError} * - * @throws {@link Err.DatabaseClosingError} (fromm putImpl) - * @throws {@link Err.TaskCancelError} (from putImpl) + * @throws # fromm putImpl + * @throws {@link Err.DatabaseClosingError} + * @throws {@link Err.TaskCancelError} * - * @throws {@link Err.UndefinedDBError} (fromm putWorker) - * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) - * @throws {@link Err.CannotWriteDataError} (from putWorker) + * @throws # from putWorker + * @throws {@link Err.UndefinedDBError} + * @throws {@link Err.CannotCreateDirectoryError} + * @throws {@link Err.CannotWriteDataError} * * @throws {@link Err.DocumentNotFoundError} * @@ -1024,12 +1049,15 @@ export class Collection implements ICollection { * @param shortId - shortId is a file path whose collectionPath and .json extension is omitted. * * @throws {@link Err.UndefinedDocumentIdError} - * @throws {@link Err.DatabaseClosingError} (from deleteImpl) - * @throws {@link Err.TaskCancelError} (from deleteImpl) * - * @throws {@link Err.UndefinedDBError} (from deleteWorker) - * @throws {@link Err.DocumentNotFoundError} (from deleteWorker) - * @throws {@link Err.CannotDeleteDataError} (from deleteWorker) + * @throws from deleteImpl + * @throws {@link Err.DatabaseClosingError} + * @throws {@link Err.TaskCancelError} + * + * @throws from deleteWorker + * @throws {@link Err.UndefinedDBError} + * @throws {@link Err.DocumentNotFoundError} + * @throws {@link Err.CannotDeleteDataError} * * @public */ @@ -1041,12 +1069,15 @@ export class Collection implements ICollection { * @param jsonDoc - JsonDoc whose _id is shortId. Only the _id property is referenced. shortId is a file path whose collectionPath and .json extension are omitted. * * @throws {@link Err.UndefinedDocumentIdError} - * @throws {@link Err.DatabaseClosingError} (from deleteImpl) - * @throws {@link Err.TaskCancelError} (from deleteImpl) * - * @throws {@link Err.UndefinedDBError} (from deleteWorker) - * @throws {@link Err.DocumentNotFoundError} (from deleteWorker) - * @throws {@link Err.CannotDeleteDataError} (from deleteWorker) + * @throws from deleteImpl + * @throws {@link Err.DatabaseClosingError} + * @throws {@link Err.TaskCancelError} + * + * @throws from deleteWorker + * @throws {@link Err.UndefinedDBError} + * @throws {@link Err.DocumentNotFoundError} + * @throws {@link Err.CannotDeleteDataError} * * @public */ diff --git a/src/git_documentdb.ts b/src/git_documentdb.ts index e8f59232..4b20a328 100644 --- a/src/git_documentdb.ts +++ b/src/git_documentdb.ts @@ -354,13 +354,16 @@ export class GitDocumentDB ***********************************************/ /** + * Create local repository + * * @throws {@link Err.CannotCreateDirectoryError} * - * @throws {@link Err.UndefinedDBError} (from putWorker) - * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) - * @throws {@link Err.SameIdExistsError} (from putWorker) - * @throws {@link Err.DocumentNotFoundError} (from putWorker) - * @throws {@link Err.CannotWriteDataError} (from putWorker) + * @throws # from putWorker + * @throws {@link Err.UndefinedDBError} + * @throws {@link Err.CannotCreateDirectoryError} + * @throws {@link Err.SameIdExistsError} + * @throws {@link Err.DocumentNotFoundError} + * @throws {@link Err.CannotWriteDataError} * @internal */ @@ -417,13 +420,15 @@ export class GitDocumentDB * @throws {@link Err.DatabaseClosingError} * @throws {@link Err.RepositoryNotFoundError} may occurs when openOptions.createIfNotExists is false. * - * @throws {@link Err.CannotCreateDirectoryError} (from _createRepository) + * @throws # from _createRepository + * @throws {@link Err.CannotCreateDirectoryError} * - * @throws {@link Err.UndefinedDBError} (from putWorker) - * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) - * @throws {@link Err.SameIdExistsError} (from putWorker) - * @throws {@link Err.DocumentNotFoundError} (from putWorker) - * @throws {@link Err.CannotWriteDataError} (from putWorker) + * @throws # from putWorker + * @throws {@link Err.UndefinedDBError} + * @throws {@link Err.CannotCreateDirectoryError} + * @throws {@link Err.SameIdExistsError} + * @throws {@link Err.DocumentNotFoundError} + * @throws {@link Err.CannotWriteDataError} * @public */ @@ -465,6 +470,7 @@ export class GitDocumentDB * - Queued operations are executed before the database is closed unless it times out. * * @param options - The options specify how to close database. + * * @throws {@link Err.DatabaseClosingError} * @throws {@link Err.DatabaseCloseTimeoutError} * @@ -514,6 +520,7 @@ export class GitDocumentDB * - destroy() does not remove localDir (which is specified in constructor). * * @param options - The options specify how to close database. + * * @throws {@link Err.DatabaseClosingError} * @throws {@link Err.DatabaseCloseTimeoutError} * @throws {@link Err.FileRemoveTimeoutError} @@ -626,13 +633,31 @@ export class GitDocumentDB /** * Synchronize with a remote repository * - * @throws {@link Err.UndefinedRemoteURLError} (from Sync#constructor()) - * @throws {@link Err.IntervalTooSmallError} (from Sync#constructor()) + * @throws {@link Err.RemoteAlreadyRegisteredError} * - * @throws {@link Err.RepositoryNotFoundError} (from Sync#syncImpl()) - * @throws {@link Err.RemoteRepositoryConnectError} (from Sync#init()) - * @throws {@link Err.PushWorkerError} (from Sync#init()) - * @throws {@link Err.SyncWorkerError} (from Sync#init()) + * @throws # from Sync#syncAndGetResultImpl + * @throws {@link Err.DatabaseClosingError} + * @throws {@link Err.RepositoryNotOpenError} + * @throws {@link Err.UndefinedRemoteURLError} + * @throws {@link Err.IntervalTooSmallError} + * @throws {@link Err.SyncIntervalLessThanOrEqualToRetryIntervalError} + * @throws {@link Err.CannotCreateRemoteRepositoryError} + * @throws {@link RemoteErr.InvalidGitRemoteError} + * @throws {@link RemoteErr.InvalidURLFormatError} + * @throws {@link RemoteErr.NetworkError} + * @throws {@link RemoteErr.HTTPError401AuthorizationRequired} + * @throws {@link RemoteErr.HTTPError404NotFound} + * @throws {@link RemoteErr.CannotConnectError} + * @throws {@link RemoteErr.HttpProtocolRequiredError} + * @throws {@link RemoteErr.InvalidRepositoryURLError} + * @throws {@link RemoteErr.InvalidSSHKeyPathError} + * @throws {@link RemoteErr.InvalidAuthenticationTypeError} + * @throws {@link RemoteErr.UnfetchedCommitExistsError} + * @throws {@link RemoteErr.HTTPError403Forbidden} + * @throws {@link Err.NoMergeBaseFoundError} + * @throws {@link Err.ThreeWayMergeError} + * @throws {@link Err.CannotDeleteDataError} + * @throws {@link Err.InvalidJsonObjectError} * * @remarks * Register and synchronize with a remote repository. Do not register the same remote repository again. Call unregisterRemote() before register it again. @@ -643,17 +668,35 @@ export class GitDocumentDB /** * Synchronize with a remote repository * - * @throws {@link Err.UndefinedRemoteURLError} (from Sync#constructor()) - * @throws {@link Err.IntervalTooSmallError} (from Sync#constructor()) - * - * @throws {@link Err.RepositoryNotFoundError} (from Sync#syncAndGetResultImpl()) - * @throws {@link Err.RemoteRepositoryConnectError} (from Sync#init()) - * @throws {@link Err.PushWorkerError} (from Sync#init()) - * @throws {@link Err.SyncWorkerError} (from Sync#init()) - * * @remarks * Register and synchronize with a remote repository. Do not register the same remote repository again. Call unregisterRemote() before register it again. * + * @throws {@link Err.RemoteAlreadyRegisteredError} + * + * @throws # from Sync#syncAndGetResultImpl + * @throws {@link Err.DatabaseClosingError} + * @throws {@link Err.RepositoryNotOpenError} + * @throws {@link Err.UndefinedRemoteURLError} + * @throws {@link Err.IntervalTooSmallError} + * @throws {@link Err.SyncIntervalLessThanOrEqualToRetryIntervalError} + * @throws {@link Err.CannotCreateRemoteRepositoryError} + * @throws {@link RemoteErr.InvalidGitRemoteError} + * @throws {@link RemoteErr.InvalidURLFormatError} + * @throws {@link RemoteErr.NetworkError} + * @throws {@link RemoteErr.HTTPError401AuthorizationRequired} + * @throws {@link RemoteErr.HTTPError404NotFound} + * @throws {@link RemoteErr.CannotConnectError} + * @throws {@link RemoteErr.HttpProtocolRequiredError} + * @throws {@link RemoteErr.InvalidRepositoryURLError} + * @throws {@link RemoteErr.InvalidSSHKeyPathError} + * @throws {@link RemoteErr.InvalidAuthenticationTypeError} + * @throws {@link RemoteErr.UnfetchedCommitExistsError} + * @throws {@link RemoteErr.HTTPError403Forbidden} + * @throws {@link Err.NoMergeBaseFoundError} + * @throws {@link Err.ThreeWayMergeError} + * @throws {@link Err.CannotDeleteDataError} + * @throws {@link Err.InvalidJsonObjectError} + * @public */ async sync (options: RemoteOptions, getSyncResult: boolean): Promise<[Sync, SyncResult]>; @@ -779,11 +822,12 @@ export class GitDocumentDB /** * Load DatabaseInfo from .gitddb/info.json * - * @throws {@link Err.UndefinedDBError} (from putWorker) - * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) - * @throws {@link Err.SameIdExistsError} (from putWorker) - * @throws {@link Err.DocumentNotFoundError} (from putWorker) - * @throws {@link Err.CannotWriteDataError} (from putWorker) + * @throws # from putWorker + * @throws {@link Err.UndefinedDBError} + * @throws {@link Err.CannotCreateDirectoryError} + * @throws {@link Err.SameIdExistsError} + * @throws {@link Err.DocumentNotFoundError} + * @throws {@link Err.CannotWriteDataError} * * @internal */ @@ -854,15 +898,18 @@ export class GitDocumentDB * * @throws {@link Err.InvalidJsonObjectError} * - * @throws {@link Err.InvalidIdCharacterError} (from validateDocument, validateId) - * @throws {@link Err.InvalidIdLengthError} (from validateDocument, validateId) + * @throws # from validateDocument, validateId + * @throws {@link Err.InvalidIdCharacterError} + * @throws {@link Err.InvalidIdLengthError} * - * @throws {@link Err.DatabaseClosingError} (fromm putImpl) - * @throws {@link Err.TaskCancelError} (from putImpl) + * @throws # from putImpl + * @throws {@link Err.DatabaseClosingError} + * @throws {@link Err.TaskCancelError} * - * @throws {@link Err.UndefinedDBError} (fromm putWorker) - * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) - * @throws {@link Err.CannotWriteDataError} (from putWorker) + * @throws # from putWorker + * @throws {@link Err.UndefinedDBError} + * @throws {@link Err.CannotCreateDirectoryError} + * @throws {@link Err.CannotWriteDataError} * * @public */ @@ -886,15 +933,18 @@ export class GitDocumentDB * * @throws {@link Err.InvalidJsonObjectError} * - * @throws {@link Err.InvalidIdCharacterError} (from validateDocument, validateId) - * @throws {@link Err.InvalidIdLengthError} (from validateDocument, validateId) + * @throws # from validateDocument, validateId + * @throws {@link Err.InvalidIdCharacterError} + * @throws {@link Err.InvalidIdLengthError} * - * @throws {@link Err.DatabaseClosingError} (fromm putImpl) - * @throws {@link Err.TaskCancelError} (from putImpl) + * @throws # from putImpl + * @throws {@link Err.DatabaseClosingError} + * @throws {@link Err.TaskCancelError} * - * @throws {@link Err.UndefinedDBError} (fromm putWorker) - * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) - * @throws {@link Err.CannotWriteDataError} (from putWorker) + * @throws # from putWorker + * @throws {@link Err.UndefinedDBError} + * @throws {@link Err.CannotCreateDirectoryError} + * @throws {@link Err.CannotWriteDataError} * * @public */ @@ -930,17 +980,20 @@ export class GitDocumentDB * * @throws {@link Err.InvalidJsonObjectError} * - * @throws {@link Err.InvalidIdCharacterError} (from validateDocument, validateId) - * @throws {@link Err.InvalidIdLengthError} (from validateDocument, validateId) + * @throws # from validateDocument, validateId + * @throws {@link Err.InvalidIdCharacterError} + * @throws {@link Err.InvalidIdLengthError} * - * @throws {@link Err.DatabaseClosingError} (fromm putImpl) - * @throws {@link Err.TaskCancelError} (from putImpl) + * @throws # from putImpl + * @throws {@link Err.DatabaseClosingError} + * @throws {@link Err.TaskCancelError} * - * @throws {@link Err.UndefinedDBError} (fromm putWorker) - * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) - * @throws {@link Err.CannotWriteDataError} (from putWorker) + * @throws # from putWorker + * @throws {@link Err.UndefinedDBError} + * @throws {@link Err.CannotCreateDirectoryError} + * @throws {@link Err.CannotWriteDataError} * - * @throws {@link Err.SameIdExistsError} (from putWorker) + * @throws {@link Err.SameIdExistsError} * * @public */ @@ -964,17 +1017,20 @@ export class GitDocumentDB * * @throws {@link Err.InvalidJsonObjectError} * - * @throws {@link Err.InvalidIdCharacterError} (from validateDocument, validateId) - * @throws {@link Err.InvalidIdLengthError} (from validateDocument, validateId) + * @throws # from validateDocument, validateId + * @throws {@link Err.InvalidIdCharacterError} + * @throws {@link Err.InvalidIdLengthError} * - * @throws {@link Err.DatabaseClosingError} (fromm putImpl) - * @throws {@link Err.TaskCancelError} (from putImpl) + * @throws # from putImpl + * @throws {@link Err.DatabaseClosingError} + * @throws {@link Err.TaskCancelError} * - * @throws {@link Err.UndefinedDBError} (fromm putWorker) - * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) - * @throws {@link Err.CannotWriteDataError} (from putWorker) + * @throws # from putWorker + * @throws {@link Err.UndefinedDBError} + * @throws {@link Err.CannotCreateDirectoryError} + * @throws {@link Err.CannotWriteDataError} * - * @throws {@link Err.SameIdExistsError} (from putWorker) + * @throws {@link Err.SameIdExistsError} * * @public */ @@ -1010,16 +1066,18 @@ export class GitDocumentDB * * @throws {@link Err.InvalidJsonObjectError} * - * @throws {@link Err.InvalidIdCharacterError} (from validateDocument, validateId) - * @throws {@link Err.InvalidIdLengthError} (from validateDocument, validateId) + * @throws # from validateDocument, validateId + * @throws {@link Err.InvalidIdCharacterError} + * @throws {@link Err.InvalidIdLengthError} * - * @throws {@link Err.DatabaseClosingError} (fromm putImpl) - * @throws {@link Err.TaskCancelError} (from putImpl) + * @throws # from putImpl + * @throws {@link Err.DatabaseClosingError} + * @throws {@link Err.TaskCancelError} * - * @throws {@link Err.UndefinedDBError} (fromm putWorker) - - * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) - * @throws {@link Err.CannotWriteDataError} (from putWorker) + * @throws # from putWorker + * @throws {@link Err.UndefinedDBError} + * @throws {@link Err.CannotCreateDirectoryError} + * @throws {@link Err.CannotWriteDataError} * * @throws {@link Err.DocumentNotFoundError} * @@ -1043,15 +1101,18 @@ export class GitDocumentDB * * @throws {@link Err.InvalidJsonObjectError} * - * @throws {@link Err.InvalidIdCharacterError} (from validateDocument, validateId) - * @throws {@link Err.InvalidIdLengthError} (from validateDocument, validateId) + * @throws # from validateDocument, validateId + * @throws {@link Err.InvalidIdCharacterError} + * @throws {@link Err.InvalidIdLengthError} * - * @throws {@link Err.DatabaseClosingError} (fromm putImpl) - * @throws {@link Err.TaskCancelError} (from putImpl) + * @throws # from putImpl + * @throws {@link Err.DatabaseClosingError} + * @throws {@link Err.TaskCancelError} * - * @throws {@link Err.UndefinedDBError} (fromm putWorker) - * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) - * @throws {@link Err.CannotWriteDataError} (from putWorker) + * @throws # from putWorker + * @throws {@link Err.UndefinedDBError} + * @throws {@link Err.CannotCreateDirectoryError} + * @throws {@link Err.CannotWriteDataError} * * @throws {@link Err.DocumentNotFoundError} * @@ -1090,15 +1151,18 @@ export class GitDocumentDB * @throws {@link Err.InvalidJsonFileExtensionError} * @throws {@link Err.InvalidJsonObjectError} * - * @throws {@link Err.InvalidIdCharacterError} (from validateDocument, validateId) - * @throws {@link Err.InvalidIdLengthError} (from validateDocument, validateId) + * @throws # from validateDocument, validateId + * @throws {@link Err.InvalidIdCharacterError} + * @throws {@link Err.InvalidIdLengthError} * - * @throws {@link Err.DatabaseClosingError} (fromm putImpl) - * @throws {@link Err.TaskCancelError} (from putImpl) + * @throws # from putImpl + * @throws {@link Err.DatabaseClosingError} + * @throws {@link Err.TaskCancelError} * - * @throws {@link Err.UndefinedDBError} (fromm putWorker) - * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) - * @throws {@link Err.CannotWriteDataError} (from putWorker) + * @throws # from putWorker + * @throws {@link Err.UndefinedDBError} + * @throws {@link Err.CannotCreateDirectoryError} + * @throws {@link Err.CannotWriteDataError} * * @public */ @@ -1128,17 +1192,20 @@ export class GitDocumentDB * * @throws {@link Err.InvalidJsonObjectError} * - * @throws {@link Err.InvalidIdCharacterError} (from validateDocument, validateId) - * @throws {@link Err.InvalidIdLengthError} (from validateDocument, validateId) + * @throws # from validateDocument, validateId + * @throws {@link Err.InvalidIdCharacterError} + * @throws {@link Err.InvalidIdLengthError} * - * @throws {@link Err.DatabaseClosingError} (fromm putImpl) - * @throws {@link Err.TaskCancelError} (from putImpl) + * @throws # from putImpl + * @throws {@link Err.DatabaseClosingError} + * @throws {@link Err.TaskCancelError} * - * @throws {@link Err.UndefinedDBError} (fromm putWorker) - * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) - * @throws {@link Err.CannotWriteDataError} (from putWorker) + * @throws # from putWorker + * @throws {@link Err.UndefinedDBError} + * @throws {@link Err.CannotCreateDirectoryError} + * @throws {@link Err.CannotWriteDataError} * - * @throws {@link Err.SameIdExistsError} (from putWorker) + * @throws {@link Err.SameIdExistsError} * * @public */ @@ -1168,15 +1235,18 @@ export class GitDocumentDB * * @throws {@link Err.InvalidJsonObjectError} * - * @throws {@link Err.InvalidIdCharacterError} (from validateDocument, validateId) - * @throws {@link Err.InvalidIdLengthError} (from validateDocument, validateId) + * @throws # from validateDocument, validateId + * @throws {@link Err.InvalidIdCharacterError} + * @throws {@link Err.InvalidIdLengthError} * - * @throws {@link Err.DatabaseClosingError} (fromm putImpl) - * @throws {@link Err.TaskCancelError} (from putImpl) + * @throws # fromm putImpl + * @throws {@link Err.DatabaseClosingError} + * @throws {@link Err.TaskCancelError} * - * @throws {@link Err.UndefinedDBError} (fromm putWorker) - * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) - * @throws {@link Err.CannotWriteDataError} (from putWorker) + * @throws # from putWorker + * @throws {@link Err.UndefinedDBError} + * @throws {@link Err.CannotCreateDirectoryError} + * @throws {@link Err.CannotWriteDataError} * * @throws {@link Err.DocumentNotFoundError} * @@ -1247,7 +1317,6 @@ export class GitDocumentDB * - This is an alias of GitDocumentDB#rootCollection.getDocByOid() * * @throws {@link Err.DatabaseClosingError} - * @throws {@link Err.InvalidJsonObjectError} * * @public @@ -1276,7 +1345,6 @@ export class GitDocumentDB * ``` * * @throws {@link Err.DatabaseClosingError} - * @throws {@link Err.InvalidJsonObjectError} * * @public @@ -1383,7 +1451,6 @@ export class GitDocumentDB * ``` * * @throws {@link Err.DatabaseClosingError} - * @throws {@link Err.InvalidJsonObjectError} * * @public @@ -1435,13 +1502,16 @@ export class GitDocumentDB * @remarks * - This is an alias of GitDocumentDB#rootCollection.delete() * - * @throws {@link Err.UndefinedDocumentIdError} (from Collection#delete) - * @throws {@link Err.DatabaseClosingError} (from deleteImpl) - * @throws {@link Err.TaskCancelError} (from deleteImpl) + * @throws {@link Err.UndefinedDocumentIdError} * - * @throws {@link Err.UndefinedDBError} (from deleteWorker) - * @throws {@link Err.DocumentNotFoundError} (from deleteWorker) - * @throws {@link Err.CannotDeleteDataError} (from deleteWorker) + * @throws from deleteImpl + * @throws {@link Err.DatabaseClosingError} + * @throws {@link Err.TaskCancelError} + * + * @throws from deleteWorker + * @throws {@link Err.UndefinedDBError} + * @throws {@link Err.DocumentNotFoundError} + * @throws {@link Err.CannotDeleteDataError} * * @public */ @@ -1455,13 +1525,16 @@ export class GitDocumentDB * @remarks * - This is an alias of GitDocumentDB#rootCollection.delete() * - * @throws {@link Err.UndefinedDocumentIdError} (from Collection#delete) - * @throws {@link Err.DatabaseClosingError} (from deleteImpl) - * @throws {@link Err.TaskCancelError} (from deleteImpl) + * @throws {@link Err.UndefinedDocumentIdError} * - * @throws {@link Err.UndefinedDBError} (from deleteWorker) - * @throws {@link Err.DocumentNotFoundError} (from deleteWorker) - * @throws {@link Err.CannotDeleteDataError} (from deleteWorker) + * @throws from deleteImpl + * @throws {@link Err.DatabaseClosingError} + * @throws {@link Err.TaskCancelError} + * + * @throws from deleteWorker + * @throws {@link Err.UndefinedDBError} + * @throws {@link Err.DocumentNotFoundError} + * @throws {@link Err.CannotDeleteDataError} * * @public */ diff --git a/src/remote/net.ts b/src/remote/net.ts deleted file mode 100644 index bb8047b4..00000000 --- a/src/remote/net.ts +++ /dev/null @@ -1,138 +0,0 @@ -/** - * GitDocumentDB - * Copyright (c) Hidekazu Kubota - * - * This source code is licensed under the Mozilla Public License Version 2.0 - * found in the LICENSE file in the root directory of this source tree. - */ - -import { Socket } from 'net'; -import http from 'http'; -import https from 'https'; -import { Err } from '../error'; - -/** - * Ping to host - */ -/* -export const ping = ( - port: number, - address: string, - timeout: number -): Promise<{ ok: boolean; error?: Error }> => { - return new Promise(resolve => { - // Create a new tcp socket - const socket = new Socket(); - // Connect to the given host - socket.connect(port, address, () => { - socket.destroy(); - // Resolve with the latency of this attempt - resolve({ ok: true }); - }); - // Make sure we catch any errors thrown by the socket - socket.on('error', error => { - socket.destroy(); - resolve({ ok: false, error }); - }); - - socket.setTimeout(timeout, () => { - socket.destroy(); - resolve({ ok: false, error: new Error('Request timeout') }); - }); - }); -}; -*/ - -/** - * Check HTTP connection - * @remarks - * requestTimeout and socketTimeout must be greater than 0. - * Timeout is not set if timeout is less than 0. - * - * @throws {@link Err.HttpProtocolRequiredError} - * @throws {@link Err.HTTPNetworkError} - * @throws {@link Err.RequestTimeoutError} - * @throws {@link Err.SocketTimeoutError} - * - * @internal - */ -export function checkHTTP ( - url: string, - requestTimeout: number, - socketTimeout?: number -): Promise<{ ok: boolean; code?: number }> { - // timeout must be greater than 0 - socketTimeout ??= requestTimeout; - if (requestTimeout === 0) { - requestTimeout = 1; - } - if (socketTimeout === 0) { - socketTimeout = 1; - } - return new Promise((resolve, reject) => { - // Send GET - let request: ( - // eslint-disable-next-line node/no-unsupported-features/node-builtins - options: string | https.RequestOptions | URL, - callback?: ((res: http.IncomingMessage) => void) | undefined - ) => http.ClientRequest; - if (url.startsWith('http:')) { - request = http.request; - } - else if (url.startsWith('https:')) { - request = https.request; - } - else { - reject(new Err.HttpProtocolRequiredError(url)); - } - - let socket: Socket; - const req = request!(url, res => { - req.removeAllListeners(); - if (socket) { - socket.removeAllListeners(); - } - req.destroy(); - resolve({ ok: true, code: res.statusCode }); - }); - req.on('error', error => { - // network error - req.removeAllListeners(); - if (socket) { - socket.removeAllListeners(); - } - req.destroy(); - reject(new Err.HTTPNetworkError(error.message)); - }); - - if (requestTimeout > 0) { - req.setTimeout(requestTimeout, () => { - req.removeAllListeners(); - if (socket) { - socket.removeAllListeners(); - } - req.destroy(); - console.log(' - request timeout error: ' + requestTimeout); - reject(new Err.RequestTimeoutError(url)); - }); - } - - if (socketTimeout! > 0) { - req.on('socket', function (mySocket: Socket) { - socket = mySocket; - socket.setTimeout(socketTimeout!); - socket.on('timeout', () => { - req.removeAllListeners(); - if (socket) { - socket.removeAllListeners(); - } - req.destroy(); - console.log(' - socket timeout error: ' + socketTimeout); - reject(new Err.SocketTimeoutError(url)); - }); - }); - } - - req.end(); - }); -} diff --git a/src/remote/sync.ts b/src/remote/sync.ts index 0b8abef2..176d7c8e 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -43,7 +43,6 @@ import { GitDDBInterface } from '../types_gitddb'; import { syncWorker } from './sync_worker'; import { pushWorker } from './push_worker'; import { RemoteRepository } from './remote_repository'; -import { checkHTTP } from './net'; import { DEFAULT_COMBINE_DB_STRATEGY, DEFAULT_CONFLICT_RESOLUTION_STRATEGY, @@ -51,7 +50,6 @@ import { MINIMUM_SYNC_INTERVAL, NETWORK_RETRY, NETWORK_RETRY_INTERVAL, - NETWORK_TIMEOUT, } from '../const'; import { JsonDiff } from './json_diff'; import { JsonPatchOT } from './json_patch_ot'; @@ -104,16 +102,30 @@ export function encodeToGitRemoteName (remoteURL: string) { /** * Implementation of GitDocumentDB#sync(options, get_sync_result) * - * @throws {@link Err.RepositoryNotFoundError} - * @throws {@link RemoteEngine.Err.UndefinedRemoteURLError} (from Sync#constructor()) - * @throws {@link Err.IntervalTooSmallError} (from Sync#constructor()) + * @throws {@link Err.DatabaseClosingError} + * @throws {@link Err.RepositoryNotOpenError} * - * @throws {@link Err.RemoteRepositoryConnectError} (from Sync#init()) - * @throws {@link Err.PushWorkerError} (from Sync#init()) - * @throws {@link Err.SyncWorkerError} (from Sync#init()) - * @throws {@link Err.NoMergeBaseFoundError} + * @throws {@link Err.UndefinedRemoteURLError} (from constructor) + * @throws {@link Err.IntervalTooSmallError} (from constructor) + * @throws {@link Err.SyncIntervalLessThanOrEqualToRetryIntervalError} (from sync#constructor) * - * @throws {@link Err.PushNotAllowedError} (from Sync#init()) + * @throws {@link Err.CannotCreateRemoteRepositoryError} (from init) + * @throws {@link RemoteErr.InvalidGitRemoteError} (from init) + * @throws {@link RemoteErr.InvalidURLFormatError} (from init) + * @throws {@link RemoteErr.NetworkError} (from init) + * @throws {@link RemoteErr.HTTPError401AuthorizationRequired} (from init) + * @throws {@link RemoteErr.HTTPError404NotFound} (from init) + * @throws {@link RemoteErr.CannotConnectError} (from init) + * @throws {@link RemoteErr.HttpProtocolRequiredError} (from init) + * @throws {@link RemoteErr.InvalidRepositoryURLError} (from init) + * @throws {@link RemoteErr.InvalidSSHKeyPathError} (from init) + * @throws {@link RemoteErr.InvalidAuthenticationTypeError} (from inti) + * @throws {@link RemoteErr.UnfetchedCommitExistsError} (from init) + * @throws {@link RemoteErr.HTTPError403Forbidden} (from init) + * @throws {@link Err.NoMergeBaseFoundError} (from init) + * @throws {@link Err.ThreeWayMergeError} (from init) + * @throws {@link Err.CannotDeleteDataError} (from init) + * @throws {@link Err.InvalidJsonObjectError} (from init) * * @internal */ @@ -121,6 +133,13 @@ export async function syncAndGetResultImpl ( this: GitDDBInterface, options: RemoteOptions ): Promise<[Sync, SyncResult]> { + if (this.isClosing) { + throw new Err.DatabaseClosingError(); + } + if (!this.isOpened) { + return Promise.reject(new Err.RepositoryNotOpenError()); + } + const sync = new Sync(this, options); const syncResult = await sync.init(); return [sync, syncResult]; @@ -128,33 +147,13 @@ export async function syncAndGetResultImpl ( /** * Implementation of GitDocumentDB#sync(options) * - * @throws {@link DatabaseClosingError} - * @throws {@link Err.RepositoryNotOpenError} - * - * @throws {@link Err.UndefinedRemoteURLError} (from Sync#constructor()) - * @throws {@link Err.IntervalTooSmallError} (from Sync#constructor()) - * - * @throws {@link Err.RemoteRepositoryConnectError} (from Sync#init()) - * @throws {@link Err.PushWorkerError} (from Sync#init()) - * @throws {@link Err.SyncWorkerError} (from Sync#init()) - * @throws {@link Err.NoMergeBaseFoundError} - * @throws {@link Err.PushNotAllowedError} (from Sync#init()) - * * @internal */ export async function syncImpl ( this: GitDDBInterface, options: RemoteOptions ): Promise { - if (this.isClosing) { - throw new Err.DatabaseClosingError(); - } - if (!this.isOpened) { - return Promise.reject(new Err.RepositoryNotOpenError()); - } - - const sync = new Sync(this, options); - await sync.init(); + const [sync, syncResult] = await syncAndGetResultImpl.call(this, options); return sync; } @@ -403,31 +402,12 @@ export class Sync implements SyncInterface { this._engine = this._options.connection?.engine ?? 'iso'; } - /*********************************************** - * Private properties - ***********************************************/ - - /** - * Check network connection - * - * @internal - */ - async canNetworkConnection (): Promise { - const okOrNetworkError = await checkHTTP( - this._options.remoteUrl!, - NETWORK_TIMEOUT - ).catch(() => { - return { ok: false }; - }); - return okOrNetworkError.ok; - } - /*********************************************** * Public properties ***********************************************/ /** - * Create remote connection + * Initialize remote connection * * @remarks * Call init() once just after creating an instance. diff --git a/test/remote_base/net.test.ts b/test/remote_base/net.test.ts deleted file mode 100644 index 8a7706b7..00000000 --- a/test/remote_base/net.test.ts +++ /dev/null @@ -1,23 +0,0 @@ -import expect from 'expect'; -import { Err } from '../../src/error'; -import { checkHTTP } from '../../src/remote/net'; - -describe(' checkHTTP', () => { - it('checks HTTPS connection', async () => { - await expect(checkHTTP('xyz', 3000)).rejects.toThrowError( - Err.HttpProtocolRequiredError - ); - const httpUrl = 'http://xyz.invalid/xyz/http_repos'; - await expect(checkHTTP(httpUrl, 3000)).rejects.toThrowError(Err.HTTPNetworkError); - const httpsUrl = 'https://xyz.invalid/xyz/http_repos'; - await expect(checkHTTP(httpsUrl, 3000)).rejects.toThrowError(Err.HTTPNetworkError); - - const validUrl = 'https://github.com/'; - await expect(checkHTTP(validUrl, 0)).rejects.toThrowError(Err.RequestTimeoutError); - await expect(checkHTTP(validUrl, -1, 0)).rejects.toThrowError(Err.SocketTimeoutError); - await expect(checkHTTP(validUrl, 10000)).resolves.toMatchObject({ - ok: true, - code: 200, - }); - }); -}); diff --git a/test/remote_base/sync.ts b/test/remote_base/sync.ts index 44e70a66..f6dc3866 100644 --- a/test/remote_base/sync.ts +++ b/test/remote_base/sync.ts @@ -29,9 +29,6 @@ import { encodeToGitRemoteName, Sync, syncImpl } from '../../src/remote/sync'; import { removeRemoteRepositories } from '../remote_utils'; import { RemoteEngine, RemoteErr } from '../../src/remote/remote_engine'; -// eslint-disable-next-line @typescript-eslint/no-var-requires -const remote_nodegit_module = require('git-documentdb-plugin-remote-nodegit'); - export const syncBase = ( connection: ConnectionSettings, remoteURLBase: string, diff --git a/test/remote_nodegit/sync.test.ts b/test/remote_nodegit/sync.test.ts index 847e840c..2e2097df 100644 --- a/test/remote_nodegit/sync.test.ts +++ b/test/remote_nodegit/sync.test.ts @@ -7,11 +7,6 @@ * found in the LICENSE file in the root directory of this source tree. */ -/** - * Test push - * by using GitHub Personal Access Token - * These tests create a new repository on GitHub if not exists. - */ import path from 'path'; import fs from 'fs-extra'; import { ConnectionSettingsGitHub } from '../../src/types'; From 8e35c78df0798acfac208a718397691c3d1ff94a Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 30 Jul 2021 00:24:53 +0900 Subject: [PATCH 082/297] docs: align Exceptions with new rules --- docs-api/git-documentdb.collection.delete.md | 12 +- .../git-documentdb.collection.delete_1.md | 12 +- .../git-documentdb.collection.deletefatdoc.md | 12 +- docs-api/git-documentdb.collection.insert.md | 22 +- .../git-documentdb.collection.insert_1.md | 22 +- .../git-documentdb.collection.insertfatdoc.md | 22 +- docs-api/git-documentdb.collection.put.md | 20 +- docs-api/git-documentdb.collection.put_1.md | 20 +- .../git-documentdb.collection.putfatdoc.md | 20 +- docs-api/git-documentdb.collection.update.md | 22 +- .../git-documentdb.collection.update_1.md | 22 +- .../git-documentdb.collection.updatefatdoc.md | 22 +- .../git-documentdb.encodetogitremotename.md | 10 +- .../git-documentdb.gitdocumentdb.delete.md | 14 +- .../git-documentdb.gitdocumentdb.delete_1.md | 14 +- ...t-documentdb.gitdocumentdb.deletefatdoc.md | 12 +- .../git-documentdb.gitdocumentdb.insert.md | 22 +- .../git-documentdb.gitdocumentdb.insert_1.md | 22 +- ...t-documentdb.gitdocumentdb.insertfatdoc.md | 22 +- docs-api/git-documentdb.gitdocumentdb.open.md | 16 +- docs-api/git-documentdb.gitdocumentdb.put.md | 20 +- .../git-documentdb.gitdocumentdb.put_1.md | 20 +- .../git-documentdb.gitdocumentdb.putfatdoc.md | 20 +- docs-api/git-documentdb.gitdocumentdb.sync.md | 41 +-- .../git-documentdb.gitdocumentdb.sync_1.md | 41 +-- .../git-documentdb.gitdocumentdb.update.md | 22 +- .../git-documentdb.gitdocumentdb.update_1.md | 22 +- ...t-documentdb.gitdocumentdb.updatefatdoc.md | 24 +- docs-api/git-documentdb.md | 8 +- docs-api/git-documentdb.remoteengine.md | 2 + .../git-documentdb.remoteengineinterface.md | 2 + docs-api/git-documentdb.remoteerr.md | 2 + docs-api/git-documentdb.sync._constructor_.md | 1 + docs-api/git-documentdb.sync.init.md | 32 +- docs-api/git-documentdb.sync.trypush.md | 34 +- docs-api/git-documentdb.sync.trysync.md | 56 ++-- ...it-documentdb.wrappingremoteengineerror.md | 2 + etc/git-documentdb.api.md | 8 +- src/collection.ts | 212 ++++++------ src/git_documentdb.ts | 304 ++++++++---------- src/remote/3way_merge.ts | 36 ++- src/remote/combine.ts | 2 + src/remote/push_worker.ts | 34 +- src/remote/remote_engine.ts | 20 ++ src/remote/sync.ts | 175 +++++----- src/remote/sync_worker.ts | 46 +-- 46 files changed, 743 insertions(+), 803 deletions(-) diff --git a/docs-api/git-documentdb.collection.delete.md b/docs-api/git-documentdb.collection.delete.md index cfff337b..f84c16d6 100644 --- a/docs-api/git-documentdb.collection.delete.md +++ b/docs-api/git-documentdb.collection.delete.md @@ -31,13 +31,15 @@ Promise<[DeleteResultJsonDoc](./git-documentdb.deleteresultjsondoc.md) > [Err.UndefinedDocumentIdError](./git-documentdb.err.undefineddocumentiderror.md) -[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) (from deleteImpl) +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) (from deleteImpl) +[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) -[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) (from deleteWorker) +\# Errors from deleteWorker -[Err.DocumentNotFoundError](./git-documentdb.err.documentnotfounderror.md) (from deleteWorker) +- [Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) -[Err.CannotDeleteDataError](./git-documentdb.err.cannotdeletedataerror.md) (from deleteWorker) +- [Err.DocumentNotFoundError](./git-documentdb.err.documentnotfounderror.md) + +- [Err.CannotDeleteDataError](./git-documentdb.err.cannotdeletedataerror.md) diff --git a/docs-api/git-documentdb.collection.delete_1.md b/docs-api/git-documentdb.collection.delete_1.md index 57b5d1f5..15450298 100644 --- a/docs-api/git-documentdb.collection.delete_1.md +++ b/docs-api/git-documentdb.collection.delete_1.md @@ -31,13 +31,15 @@ Promise<[DeleteResultJsonDoc](./git-documentdb.deleteresultjsondoc.md) > [Err.UndefinedDocumentIdError](./git-documentdb.err.undefineddocumentiderror.md) -[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) (from deleteImpl) +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) (from deleteImpl) +[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) -[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) (from deleteWorker) +\# Errors from deleteWorker -[Err.DocumentNotFoundError](./git-documentdb.err.documentnotfounderror.md) (from deleteWorker) +- [Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) -[Err.CannotDeleteDataError](./git-documentdb.err.cannotdeletedataerror.md) (from deleteWorker) +- [Err.DocumentNotFoundError](./git-documentdb.err.documentnotfounderror.md) + +- [Err.CannotDeleteDataError](./git-documentdb.err.cannotdeletedataerror.md) diff --git a/docs-api/git-documentdb.collection.deletefatdoc.md b/docs-api/git-documentdb.collection.deletefatdoc.md index b508cb72..6b62605b 100644 --- a/docs-api/git-documentdb.collection.deletefatdoc.md +++ b/docs-api/git-documentdb.collection.deletefatdoc.md @@ -31,13 +31,15 @@ Promise<[DeleteResult](./git-documentdb.deleteresult.md) > [Err.UndefinedDocumentIdError](./git-documentdb.err.undefineddocumentiderror.md) -[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) (from deleteImpl) +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) (from deleteImpl) +[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) -[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) (from deleteWorker) +\# Errors from deleteWorker -[Err.DocumentNotFoundError](./git-documentdb.err.documentnotfounderror.md) (from deleteWorker) +- [Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) -[Err.CannotDeleteDataError](./git-documentdb.err.cannotdeletedataerror.md) (from deleteWorker) +- [Err.DocumentNotFoundError](./git-documentdb.err.documentnotfounderror.md) + +- [Err.CannotDeleteDataError](./git-documentdb.err.cannotdeletedataerror.md) diff --git a/docs-api/git-documentdb.collection.insert.md b/docs-api/git-documentdb.collection.insert.md index 28632e21..187278b9 100644 --- a/docs-api/git-documentdb.collection.insert.md +++ b/docs-api/git-documentdb.collection.insert.md @@ -39,25 +39,23 @@ Promise<[PutResultJsonDoc](./git-documentdb.putresultjsondoc.md) > [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) -\# from validateDocument, validateId +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) +[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) -[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) +\# Errors from validateDocument, validateId -\# from putImpl +- [Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) -[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) - -[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) +- [Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) -\# from putWorker +\# Errors from putWorker -[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) +- [Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) -[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) +- [Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) -[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) +- [Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) -[Err.SameIdExistsError](./git-documentdb.err.sameidexistserror.md) +- [Err.SameIdExistsError](./git-documentdb.err.sameidexistserror.md) diff --git a/docs-api/git-documentdb.collection.insert_1.md b/docs-api/git-documentdb.collection.insert_1.md index 9da0d169..6f34871b 100644 --- a/docs-api/git-documentdb.collection.insert_1.md +++ b/docs-api/git-documentdb.collection.insert_1.md @@ -42,25 +42,23 @@ Promise<[PutResultJsonDoc](./git-documentdb.putresultjsondoc.md) > [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) -\# from validateDocument, validateId +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) +[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) -[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) +\# Errors from validateDocument, validateId -\# from putImpl +- [Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) -[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) - -[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) +- [Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) -\# from putWorker +\# Errors from putWorker -[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) +- [Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) -[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) +- [Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) -[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) +- [Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) -[Err.SameIdExistsError](./git-documentdb.err.sameidexistserror.md) +- [Err.SameIdExistsError](./git-documentdb.err.sameidexistserror.md) diff --git a/docs-api/git-documentdb.collection.insertfatdoc.md b/docs-api/git-documentdb.collection.insertfatdoc.md index bf03ed22..4de863b1 100644 --- a/docs-api/git-documentdb.collection.insertfatdoc.md +++ b/docs-api/git-documentdb.collection.insertfatdoc.md @@ -42,25 +42,23 @@ Promise<[PutResult](./git-documentdb.putresult.md) > [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) -\# from validateDocument, validateId +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) +[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) -[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) +\# Errors from validateDocument, validateId -\# fromm putImpl +- [Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) -[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) - -[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) +- [Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) -\# from putWorker +\# Errors from putWorker -[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) +- [Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) -[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) +- [Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) -[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) +- [Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) -[Err.SameIdExistsError](./git-documentdb.err.sameidexistserror.md) +- [Err.SameIdExistsError](./git-documentdb.err.sameidexistserror.md) diff --git a/docs-api/git-documentdb.collection.put.md b/docs-api/git-documentdb.collection.put.md index 85064a67..3849ca9f 100644 --- a/docs-api/git-documentdb.collection.put.md +++ b/docs-api/git-documentdb.collection.put.md @@ -37,23 +37,21 @@ Promise<[PutResultJsonDoc](./git-documentdb.putresultjsondoc.md) > [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) -\# from validateDocument, validateId +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) +[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) -[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) +\# Errors from validateDocument, validateId -\# from putImpl +- [Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) -[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) - -[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) +- [Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) -\# from putWorker +\# Errors from putWorker -[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) +- [Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) -[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) +- [Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) -[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) +- [Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) diff --git a/docs-api/git-documentdb.collection.put_1.md b/docs-api/git-documentdb.collection.put_1.md index 1500efc2..c3418e62 100644 --- a/docs-api/git-documentdb.collection.put_1.md +++ b/docs-api/git-documentdb.collection.put_1.md @@ -42,23 +42,21 @@ Promise<[PutResultJsonDoc](./git-documentdb.putresultjsondoc.md) > [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) -\# from validateDocument, validateId +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) +[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) -[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) +\# Errors from validateDocument, validateId -\# from putImpl +- [Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) -[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) - -[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) +- [Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) -\# from putWorker +\# Errors from putWorker -[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) +- [Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) -[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) +- [Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) -[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) +- [Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) diff --git a/docs-api/git-documentdb.collection.putfatdoc.md b/docs-api/git-documentdb.collection.putfatdoc.md index a8ff41dd..ff93ccdf 100644 --- a/docs-api/git-documentdb.collection.putfatdoc.md +++ b/docs-api/git-documentdb.collection.putfatdoc.md @@ -44,23 +44,21 @@ Promise<[PutResult](./git-documentdb.putresult.md) > [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) -\# from validateDocument, validateId +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) +[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) -[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) +\# Errors from validateDocument, validateId -\# from putImpl +- [Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) -[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) - -[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) +- [Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) -\# from putWorker +\# Errors from putWorker -[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) +- [Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) -[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) +- [Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) -[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) +- [Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) diff --git a/docs-api/git-documentdb.collection.update.md b/docs-api/git-documentdb.collection.update.md index 2a376db1..08137051 100644 --- a/docs-api/git-documentdb.collection.update.md +++ b/docs-api/git-documentdb.collection.update.md @@ -41,25 +41,23 @@ Promise<[PutResultJsonDoc](./git-documentdb.putresultjsondoc.md) > [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) -\# from validateDocument, validateId +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) +[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) -[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) +\# Errors from validateDocument, validateId -\# from putImpl +- [Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) -[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) - -[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) +- [Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) -\# from putWorker +\# Errors from putWorker -[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) +- [Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) -[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) +- [Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) -[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) +- [Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) -[Err.DocumentNotFoundError](./git-documentdb.err.documentnotfounderror.md) +- [Err.DocumentNotFoundError](./git-documentdb.err.documentnotfounderror.md) diff --git a/docs-api/git-documentdb.collection.update_1.md b/docs-api/git-documentdb.collection.update_1.md index 71965279..8cd6ca43 100644 --- a/docs-api/git-documentdb.collection.update_1.md +++ b/docs-api/git-documentdb.collection.update_1.md @@ -40,25 +40,23 @@ Promise<[PutResultJsonDoc](./git-documentdb.putresultjsondoc.md) > [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) -\# from validateDocument, validateId +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) +[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) -[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) +\# Errors from validateDocument, validateId -\# from putImpl +- [Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) -[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) - -[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) +- [Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) -\# from putWorker +\# Errors from putWorker -[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) +- [Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) -[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) +- [Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) -[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) +- [Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) -[Err.DocumentNotFoundError](./git-documentdb.err.documentnotfounderror.md) +- [Err.DocumentNotFoundError](./git-documentdb.err.documentnotfounderror.md) diff --git a/docs-api/git-documentdb.collection.updatefatdoc.md b/docs-api/git-documentdb.collection.updatefatdoc.md index 66f9300a..a7928d88 100644 --- a/docs-api/git-documentdb.collection.updatefatdoc.md +++ b/docs-api/git-documentdb.collection.updatefatdoc.md @@ -42,25 +42,23 @@ Promise<[PutResult](./git-documentdb.putresult.md) > [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) -\# from validateDocument, validateId +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) +[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) -[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) +\# Errors from validateDocument, validateId -\# fromm putImpl +- [Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) -[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) - -[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) +- [Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) -\# from putWorker +\# Errors from putWorker -[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) +- [Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) -[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) +- [Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) -[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) +- [Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) -[Err.DocumentNotFoundError](./git-documentdb.err.documentnotfounderror.md) +- [Err.DocumentNotFoundError](./git-documentdb.err.documentnotfounderror.md) diff --git a/docs-api/git-documentdb.encodetogitremotename.md b/docs-api/git-documentdb.encodetogitremotename.md index 96c57a7b..b999c5c8 100644 --- a/docs-api/git-documentdb.encodetogitremotename.md +++ b/docs-api/git-documentdb.encodetogitremotename.md @@ -28,5 +28,13 @@ string ## Remarks -Remote name consists of host\_name + hash. hash is generated from remoteURL. Capitalize host name of remoteURL manually when hashes collide because host name is not case sensitive. +The first default name of Git remote is "origin". + +GitDocumentDB adds an alias of "origin", whose name is generated automatically by this function. The second and subsequent remotes are also named in the same way. + +A remote name consists of \[remote address\]\_\[hash\]. Periods are replaced with underscores. e.g.) github\_com\_a0b1c23 It is human-readable. + +\[remote address\] is \[hostname + domain name\] or \[ip address\]. \[hash\] is calculated from remoteURL. + +\[hash\] is the first seven characters of SHA-1 so that it may collide. Capitalize one of the remote addresses when hashes collide because a hostname and a domain name are not case sensitive. diff --git a/docs-api/git-documentdb.gitdocumentdb.delete.md b/docs-api/git-documentdb.gitdocumentdb.delete.md index 38d37b06..1b9bc9f5 100644 --- a/docs-api/git-documentdb.gitdocumentdb.delete.md +++ b/docs-api/git-documentdb.gitdocumentdb.delete.md @@ -33,15 +33,17 @@ Promise<[DeleteResultJsonDoc](./git-documentdb.deleteresultjsondoc.md) > ## Exceptions -[Err.UndefinedDocumentIdError](./git-documentdb.err.undefineddocumentiderror.md) (from Collection\#delete) +[Err.UndefinedDocumentIdError](./git-documentdb.err.undefineddocumentiderror.md) -[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) (from deleteImpl) +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) (from deleteImpl) +[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) -[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) (from deleteWorker) +\# Errors from deleteWorker -[Err.DocumentNotFoundError](./git-documentdb.err.documentnotfounderror.md) (from deleteWorker) +- [Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) -[Err.CannotDeleteDataError](./git-documentdb.err.cannotdeletedataerror.md) (from deleteWorker) +- [Err.DocumentNotFoundError](./git-documentdb.err.documentnotfounderror.md) + +- [Err.CannotDeleteDataError](./git-documentdb.err.cannotdeletedataerror.md) diff --git a/docs-api/git-documentdb.gitdocumentdb.delete_1.md b/docs-api/git-documentdb.gitdocumentdb.delete_1.md index 1344f28f..a0b24568 100644 --- a/docs-api/git-documentdb.gitdocumentdb.delete_1.md +++ b/docs-api/git-documentdb.gitdocumentdb.delete_1.md @@ -33,15 +33,17 @@ Promise<[DeleteResultJsonDoc](./git-documentdb.deleteresultjsondoc.md) > ## Exceptions -[Err.UndefinedDocumentIdError](./git-documentdb.err.undefineddocumentiderror.md) (from Collection\#delete) +[Err.UndefinedDocumentIdError](./git-documentdb.err.undefineddocumentiderror.md) -[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) (from deleteImpl) +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) (from deleteImpl) +[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) -[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) (from deleteWorker) +\# Errors from deleteWorker -[Err.DocumentNotFoundError](./git-documentdb.err.documentnotfounderror.md) (from deleteWorker) +- [Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) -[Err.CannotDeleteDataError](./git-documentdb.err.cannotdeletedataerror.md) (from deleteWorker) +- [Err.DocumentNotFoundError](./git-documentdb.err.documentnotfounderror.md) + +- [Err.CannotDeleteDataError](./git-documentdb.err.cannotdeletedataerror.md) diff --git a/docs-api/git-documentdb.gitdocumentdb.deletefatdoc.md b/docs-api/git-documentdb.gitdocumentdb.deletefatdoc.md index 9a424bb5..45bc75d7 100644 --- a/docs-api/git-documentdb.gitdocumentdb.deletefatdoc.md +++ b/docs-api/git-documentdb.gitdocumentdb.deletefatdoc.md @@ -35,13 +35,15 @@ Promise<[DeleteResult](./git-documentdb.deleteresult.md) > [Err.UndefinedDocumentIdError](./git-documentdb.err.undefineddocumentiderror.md) -[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) (from deleteImpl) +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) (from deleteImpl) +[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) -[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) (from deleteWorker) +\# Errors from deleteWorker -[Err.DocumentNotFoundError](./git-documentdb.err.documentnotfounderror.md) (from deleteWorker) +- [Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) -[Err.CannotDeleteDataError](./git-documentdb.err.cannotdeletedataerror.md) (from deleteWorker) +- [Err.DocumentNotFoundError](./git-documentdb.err.documentnotfounderror.md) + +- [Err.CannotDeleteDataError](./git-documentdb.err.cannotdeletedataerror.md) diff --git a/docs-api/git-documentdb.gitdocumentdb.insert.md b/docs-api/git-documentdb.gitdocumentdb.insert.md index 4ddb333c..9c0ffad6 100644 --- a/docs-api/git-documentdb.gitdocumentdb.insert.md +++ b/docs-api/git-documentdb.gitdocumentdb.insert.md @@ -41,25 +41,23 @@ Promise<[PutResultJsonDoc](./git-documentdb.putresultjsondoc.md) > [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) -\# from validateDocument, validateId +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) +[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) -[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) +\# Errors from validateDocument, validateId -\# from putImpl +- [Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) -[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) - -[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) +- [Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) -\# from putWorker +\# Errors from putWorker -[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) +- [Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) -[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) +- [Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) -[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) +- [Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) -[Err.SameIdExistsError](./git-documentdb.err.sameidexistserror.md) +- [Err.SameIdExistsError](./git-documentdb.err.sameidexistserror.md) diff --git a/docs-api/git-documentdb.gitdocumentdb.insert_1.md b/docs-api/git-documentdb.gitdocumentdb.insert_1.md index 94ec5a80..6d804fa0 100644 --- a/docs-api/git-documentdb.gitdocumentdb.insert_1.md +++ b/docs-api/git-documentdb.gitdocumentdb.insert_1.md @@ -44,25 +44,23 @@ Promise<[PutResultJsonDoc](./git-documentdb.putresultjsondoc.md) > [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) -\# from validateDocument, validateId +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) +[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) -[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) +\# Errors from validateDocument, validateId -\# from putImpl +- [Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) -[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) - -[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) +- [Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) -\# from putWorker +\# Errors from putWorker -[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) +- [Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) -[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) +- [Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) -[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) +- [Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) -[Err.SameIdExistsError](./git-documentdb.err.sameidexistserror.md) +- [Err.SameIdExistsError](./git-documentdb.err.sameidexistserror.md) diff --git a/docs-api/git-documentdb.gitdocumentdb.insertfatdoc.md b/docs-api/git-documentdb.gitdocumentdb.insertfatdoc.md index 8dffc00e..cc89fa14 100644 --- a/docs-api/git-documentdb.gitdocumentdb.insertfatdoc.md +++ b/docs-api/git-documentdb.gitdocumentdb.insertfatdoc.md @@ -44,25 +44,23 @@ Promise<[PutResult](./git-documentdb.putresult.md) > [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) -\# from validateDocument, validateId +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) +[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) -[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) +\# Errors from validateDocument, validateId -\# from putImpl +- [Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) -[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) - -[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) +- [Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) -\# from putWorker +\# Errors from putWorker -[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) +- [Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) -[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) +- [Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) -[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) +- [Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) -[Err.SameIdExistsError](./git-documentdb.err.sameidexistserror.md) +- [Err.SameIdExistsError](./git-documentdb.err.sameidexistserror.md) diff --git a/docs-api/git-documentdb.gitdocumentdb.open.md b/docs-api/git-documentdb.gitdocumentdb.open.md index 851c4338..3db12691 100644 --- a/docs-api/git-documentdb.gitdocumentdb.open.md +++ b/docs-api/git-documentdb.gitdocumentdb.open.md @@ -42,19 +42,19 @@ Promise<[DatabaseOpenResult](./git-documentdb.databaseopenresult.md) > [Err.RepositoryNotFoundError](./git-documentdb.err.repositorynotfounderror.md) may occurs when openOptions.createIfNotExists is false. -\# from \_createRepository +\# Errors from \_createRepository -[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) +- [Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) -\# from putWorker +\# Errors from putWorker -[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) +- [Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) -[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) +- [Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) -[Err.SameIdExistsError](./git-documentdb.err.sameidexistserror.md) +- [Err.SameIdExistsError](./git-documentdb.err.sameidexistserror.md) -[Err.DocumentNotFoundError](./git-documentdb.err.documentnotfounderror.md) +- [Err.DocumentNotFoundError](./git-documentdb.err.documentnotfounderror.md) -[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) +- [Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) diff --git a/docs-api/git-documentdb.gitdocumentdb.put.md b/docs-api/git-documentdb.gitdocumentdb.put.md index 7f83e0f9..0d517f3a 100644 --- a/docs-api/git-documentdb.gitdocumentdb.put.md +++ b/docs-api/git-documentdb.gitdocumentdb.put.md @@ -39,23 +39,21 @@ Promise<[PutResultJsonDoc](./git-documentdb.putresultjsondoc.md) > [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) -\# from validateDocument, validateId +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) +[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) -[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) +\# Errors from validateDocument, validateId -\# from putImpl +- [Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) -[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) - -[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) +- [Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) -\# from putWorker +\# Errors from putWorker -[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) +- [Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) -[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) +- [Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) -[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) +- [Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) diff --git a/docs-api/git-documentdb.gitdocumentdb.put_1.md b/docs-api/git-documentdb.gitdocumentdb.put_1.md index 369c4ec8..7d7e561d 100644 --- a/docs-api/git-documentdb.gitdocumentdb.put_1.md +++ b/docs-api/git-documentdb.gitdocumentdb.put_1.md @@ -44,23 +44,21 @@ Promise<[PutResultJsonDoc](./git-documentdb.putresultjsondoc.md) > [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) -\# from validateDocument, validateId +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) +[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) -[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) +\# Errors from validateDocument, validateId -\# from putImpl +- [Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) -[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) - -[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) +- [Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) -\# from putWorker +\# Errors from putWorker -[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) +- [Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) -[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) +- [Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) -[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) +- [Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) diff --git a/docs-api/git-documentdb.gitdocumentdb.putfatdoc.md b/docs-api/git-documentdb.gitdocumentdb.putfatdoc.md index bc0f8dea..1f4d9f8d 100644 --- a/docs-api/git-documentdb.gitdocumentdb.putfatdoc.md +++ b/docs-api/git-documentdb.gitdocumentdb.putfatdoc.md @@ -46,23 +46,21 @@ Promise<[PutResult](./git-documentdb.putresult.md) > [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) -\# from validateDocument, validateId +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) +[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) -[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) +\# Errors from validateDocument, validateId -\# from putImpl +- [Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) -[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) - -[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) +- [Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) -\# from putWorker +\# Errors from putWorker -[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) +- [Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) -[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) +- [Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) -[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) +- [Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) diff --git a/docs-api/git-documentdb.gitdocumentdb.sync.md b/docs-api/git-documentdb.gitdocumentdb.sync.md index 0003f74e..586cc03d 100644 --- a/docs-api/git-documentdb.gitdocumentdb.sync.md +++ b/docs-api/git-documentdb.gitdocumentdb.sync.md @@ -34,48 +34,11 @@ Register and synchronize with a remote repository. Do not register the same remo [Err.RemoteAlreadyRegisteredError](./git-documentdb.err.remotealreadyregisterederror.md) -\# from Sync\#syncAndGetResultImpl - [Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) [Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) -[Err.UndefinedRemoteURLError](./git-documentdb.err.undefinedremoteurlerror.md) - -[Err.IntervalTooSmallError](./git-documentdb.err.intervaltoosmallerror.md) - -[Err.SyncIntervalLessThanOrEqualToRetryIntervalError](./git-documentdb.err.syncintervallessthanorequaltoretryintervalerror.md) - -[Err.CannotCreateRemoteRepositoryError](./git-documentdb.err.cannotcreateremoterepositoryerror.md) - -[RemoteErr.InvalidGitRemoteError](./git-documentdb.remoteerr.invalidgitremoteerror.md) - -[RemoteErr.InvalidURLFormatError](./git-documentdb.remoteerr.invalidurlformaterror.md) - -[RemoteErr.NetworkError](./git-documentdb.remoteerr.networkerror.md) - -[RemoteErr.HTTPError401AuthorizationRequired](./git-documentdb.remoteerr.httperror401authorizationrequired.md) - -[RemoteErr.HTTPError404NotFound](./git-documentdb.remoteerr.httperror404notfound.md) - -[RemoteErr.CannotConnectError](./git-documentdb.remoteerr.cannotconnecterror.md) - - -[RemoteErr.InvalidRepositoryURLError](./git-documentdb.remoteerr.invalidrepositoryurlerror.md) - -[RemoteErr.InvalidSSHKeyPathError](./git-documentdb.remoteerr.invalidsshkeypatherror.md) - -[RemoteErr.InvalidAuthenticationTypeError](./git-documentdb.remoteerr.invalidauthenticationtypeerror.md) - -[RemoteErr.UnfetchedCommitExistsError](./git-documentdb.remoteerr.unfetchedcommitexistserror.md) - -[RemoteErr.HTTPError403Forbidden](./git-documentdb.remoteerr.httperror403forbidden.md) - -[Err.NoMergeBaseFoundError](./git-documentdb.err.nomergebasefounderror.md) - -[Err.ThreeWayMergeError](./git-documentdb.err.threewaymergeerror.md) - -[Err.CannotDeleteDataError](./git-documentdb.err.cannotdeletedataerror.md) +Errors from constructor of [Sync](./git-documentdb.sync.md) class. -[Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) +Errors from [Sync.init()](./git-documentdb.sync.init.md) diff --git a/docs-api/git-documentdb.gitdocumentdb.sync_1.md b/docs-api/git-documentdb.gitdocumentdb.sync_1.md index f24f2c6b..4ca1cce1 100644 --- a/docs-api/git-documentdb.gitdocumentdb.sync_1.md +++ b/docs-api/git-documentdb.gitdocumentdb.sync_1.md @@ -35,48 +35,11 @@ Register and synchronize with a remote repository. Do not register the same remo [Err.RemoteAlreadyRegisteredError](./git-documentdb.err.remotealreadyregisterederror.md) -\# from Sync\#syncAndGetResultImpl - [Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) [Err.RepositoryNotOpenError](./git-documentdb.err.repositorynotopenerror.md) -[Err.UndefinedRemoteURLError](./git-documentdb.err.undefinedremoteurlerror.md) - -[Err.IntervalTooSmallError](./git-documentdb.err.intervaltoosmallerror.md) - -[Err.SyncIntervalLessThanOrEqualToRetryIntervalError](./git-documentdb.err.syncintervallessthanorequaltoretryintervalerror.md) - -[Err.CannotCreateRemoteRepositoryError](./git-documentdb.err.cannotcreateremoterepositoryerror.md) - -[RemoteErr.InvalidGitRemoteError](./git-documentdb.remoteerr.invalidgitremoteerror.md) - -[RemoteErr.InvalidURLFormatError](./git-documentdb.remoteerr.invalidurlformaterror.md) - -[RemoteErr.NetworkError](./git-documentdb.remoteerr.networkerror.md) - -[RemoteErr.HTTPError401AuthorizationRequired](./git-documentdb.remoteerr.httperror401authorizationrequired.md) - -[RemoteErr.HTTPError404NotFound](./git-documentdb.remoteerr.httperror404notfound.md) - -[RemoteErr.CannotConnectError](./git-documentdb.remoteerr.cannotconnecterror.md) - - -[RemoteErr.InvalidRepositoryURLError](./git-documentdb.remoteerr.invalidrepositoryurlerror.md) - -[RemoteErr.InvalidSSHKeyPathError](./git-documentdb.remoteerr.invalidsshkeypatherror.md) - -[RemoteErr.InvalidAuthenticationTypeError](./git-documentdb.remoteerr.invalidauthenticationtypeerror.md) - -[RemoteErr.UnfetchedCommitExistsError](./git-documentdb.remoteerr.unfetchedcommitexistserror.md) - -[RemoteErr.HTTPError403Forbidden](./git-documentdb.remoteerr.httperror403forbidden.md) - -[Err.NoMergeBaseFoundError](./git-documentdb.err.nomergebasefounderror.md) - -[Err.ThreeWayMergeError](./git-documentdb.err.threewaymergeerror.md) - -[Err.CannotDeleteDataError](./git-documentdb.err.cannotdeletedataerror.md) +Errors from constructor of [Sync](./git-documentdb.sync.md) class. -[Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) +Errors from [Sync.init()](./git-documentdb.sync.init.md) diff --git a/docs-api/git-documentdb.gitdocumentdb.update.md b/docs-api/git-documentdb.gitdocumentdb.update.md index 2bcdaaeb..020bdf3e 100644 --- a/docs-api/git-documentdb.gitdocumentdb.update.md +++ b/docs-api/git-documentdb.gitdocumentdb.update.md @@ -41,25 +41,23 @@ Promise<[PutResultJsonDoc](./git-documentdb.putresultjsondoc.md) > [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) -\# from validateDocument, validateId +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) +[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) -[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) +\# Errors from validateDocument, validateId -\# from putImpl +- [Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) -[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) - -[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) +- [Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) -\# from putWorker +\# Errors from putWorker -[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) +- [Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) -[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) +- [Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) -[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) +- [Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) -[Err.DocumentNotFoundError](./git-documentdb.err.documentnotfounderror.md) +- [Err.DocumentNotFoundError](./git-documentdb.err.documentnotfounderror.md) diff --git a/docs-api/git-documentdb.gitdocumentdb.update_1.md b/docs-api/git-documentdb.gitdocumentdb.update_1.md index 37bb9ea7..9a064314 100644 --- a/docs-api/git-documentdb.gitdocumentdb.update_1.md +++ b/docs-api/git-documentdb.gitdocumentdb.update_1.md @@ -42,25 +42,23 @@ Promise<[PutResultJsonDoc](./git-documentdb.putresultjsondoc.md) > [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) -\# from validateDocument, validateId +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) +[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) -[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) +\# Errors from validateDocument, validateId -\# from putImpl +- [Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) -[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) - -[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) +- [Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) -\# from putWorker +\# Errors from putWorker -[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) +- [Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) -[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) +- [Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) -[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) +- [Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) -[Err.DocumentNotFoundError](./git-documentdb.err.documentnotfounderror.md) +- [Err.DocumentNotFoundError](./git-documentdb.err.documentnotfounderror.md) diff --git a/docs-api/git-documentdb.gitdocumentdb.updatefatdoc.md b/docs-api/git-documentdb.gitdocumentdb.updatefatdoc.md index 9d81a818..bbc305d9 100644 --- a/docs-api/git-documentdb.gitdocumentdb.updatefatdoc.md +++ b/docs-api/git-documentdb.gitdocumentdb.updatefatdoc.md @@ -42,29 +42,25 @@ Promise<[PutResult](./git-documentdb.putresult.md) > ## Exceptions -\# from this method - [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) -\# from validateDocument, validateId - -[Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) +[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) -[Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) +[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) -\# fromm putImpl +\# Errors from validateDocument, validateId -[Err.DatabaseClosingError](./git-documentdb.err.databaseclosingerror.md) +- [Err.InvalidIdCharacterError](./git-documentdb.err.invalididcharactererror.md) -[Err.TaskCancelError](./git-documentdb.err.taskcancelerror.md) +- [Err.InvalidIdLengthError](./git-documentdb.err.invalididlengtherror.md) -\# from putWorker +\# Errors from putWorker -[Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) +- [Err.UndefinedDBError](./git-documentdb.err.undefineddberror.md) -[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) +- [Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) -[Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) +- [Err.CannotWriteDataError](./git-documentdb.err.cannotwritedataerror.md) -[Err.DocumentNotFoundError](./git-documentdb.err.documentnotfounderror.md) +- [Err.DocumentNotFoundError](./git-documentdb.err.documentnotfounderror.md) diff --git a/docs-api/git-documentdb.md b/docs-api/git-documentdb.md index 53fd95f1..6b38731a 100644 --- a/docs-api/git-documentdb.md +++ b/docs-api/git-documentdb.md @@ -26,7 +26,7 @@ Offline-first Database that Syncs with Git | Function | Description | | --- | --- | | [encodeToGitRemoteName(remoteURL)](./git-documentdb.encodetogitremotename.md) | encodeToRemoteName | -| [wrappingRemoteEngineError(remoteEngineError)](./git-documentdb.wrappingremoteengineerror.md) | | +| [wrappingRemoteEngineError(remoteEngineError)](./git-documentdb.wrappingremoteengineerror.md) | wrappingRemoteEngineError | ## Interfaces @@ -35,7 +35,7 @@ Offline-first Database that Syncs with Git | [CollectionInterface](./git-documentdb.collectioninterface.md) | Interface for Collection | | [CRUDInterface](./git-documentdb.crudinterface.md) | Interface for GitDocumentDB CRUD | | [GitDDBInterface](./git-documentdb.gitddbinterface.md) | Interface of GitDocumentDB body | -| [RemoteEngineInterface](./git-documentdb.remoteengineinterface.md) | | +| [RemoteEngineInterface](./git-documentdb.remoteengineinterface.md) | RemoteEngineInterface | | [SyncEventInterface](./git-documentdb.synceventinterface.md) | Interface for SyncEvent | | [SyncInterface](./git-documentdb.syncinterface.md) | Interface of Sync | @@ -44,7 +44,7 @@ Offline-first Database that Syncs with Git | Namespace | Description | | --- | --- | | [Err](./git-documentdb.err.md) | Namespace for errors | -| [RemoteErr](./git-documentdb.remoteerr.md) | | +| [RemoteErr](./git-documentdb.remoteerr.md) | RemoteError | ## Variables @@ -70,7 +70,7 @@ Offline-first Database that Syncs with Git | [NETWORK\_RETRY](./git-documentdb.network_retry.md) | | | [NETWORK\_TIMEOUT](./git-documentdb.network_timeout.md) | | | [PUT\_APP\_INFO\_MESSAGE](./git-documentdb.put_app_info_message.md) | | -| [RemoteEngine](./git-documentdb.remoteengine.md) | | +| [RemoteEngine](./git-documentdb.remoteengine.md) | RemoteEngine | | [SET\_DATABASE\_ID\_MESSAGE](./git-documentdb.set_database_id_message.md) | | | [SHORT\_SHA\_LENGTH](./git-documentdb.short_sha_length.md) | | diff --git a/docs-api/git-documentdb.remoteengine.md b/docs-api/git-documentdb.remoteengine.md index c1645c36..30f6b209 100644 --- a/docs-api/git-documentdb.remoteengine.md +++ b/docs-api/git-documentdb.remoteengine.md @@ -8,6 +8,8 @@ hide_title: true ## RemoteEngine variable +RemoteEngine + Signature: ```typescript diff --git a/docs-api/git-documentdb.remoteengineinterface.md b/docs-api/git-documentdb.remoteengineinterface.md index 6e9a33c7..a8279a07 100644 --- a/docs-api/git-documentdb.remoteengineinterface.md +++ b/docs-api/git-documentdb.remoteengineinterface.md @@ -8,6 +8,8 @@ hide_title: true ## RemoteEngineInterface interface +RemoteEngineInterface + Signature: ```typescript diff --git a/docs-api/git-documentdb.remoteerr.md b/docs-api/git-documentdb.remoteerr.md index 54550e46..0720a6e6 100644 --- a/docs-api/git-documentdb.remoteerr.md +++ b/docs-api/git-documentdb.remoteerr.md @@ -8,6 +8,8 @@ hide_title: true ## RemoteErr namespace +RemoteError + Signature: ```typescript diff --git a/docs-api/git-documentdb.sync._constructor_.md b/docs-api/git-documentdb.sync._constructor_.md index 8d9abfd1..8625492c 100644 --- a/docs-api/git-documentdb.sync._constructor_.md +++ b/docs-api/git-documentdb.sync._constructor_.md @@ -29,4 +29,5 @@ constructor(gitDDB: GitDDBInterface, options?: RemoteOptions); [Err.IntervalTooSmallError](./git-documentdb.err.intervaltoosmallerror.md) +[Err.SyncIntervalLessThanOrEqualToRetryIntervalError](./git-documentdb.err.syncintervallessthanorequaltoretryintervalerror.md) diff --git a/docs-api/git-documentdb.sync.init.md b/docs-api/git-documentdb.sync.init.md index 67feabb4..07e78d3e 100644 --- a/docs-api/git-documentdb.sync.init.md +++ b/docs-api/git-documentdb.sync.init.md @@ -27,35 +27,29 @@ Call init() once just after creating an instance. [Err.CannotCreateRemoteRepositoryError](./git-documentdb.err.cannotcreateremoterepositoryerror.md) -[RemoteErr.InvalidGitRemoteError](./git-documentdb.remoteerr.invalidgitremoteerror.md) (from checkFetch(), trySync(), tryPush()) +\# Errors from RemoteEngine\[engineName\].checkFetch -[RemoteErr.InvalidURLFormatError](./git-documentdb.remoteerr.invalidurlformaterror.md) (from checkFetch(), trySync(), tryPush()) +- [RemoteErr.InvalidGitRemoteError](./git-documentdb.remoteerr.invalidgitremoteerror.md) -[RemoteErr.NetworkError](./git-documentdb.remoteerr.networkerror.md) (from checkFetch(), trySync(), tryPush()) +- [RemoteErr.InvalidURLFormatError](./git-documentdb.remoteerr.invalidurlformaterror.md) -[RemoteErr.HTTPError401AuthorizationRequired](./git-documentdb.remoteerr.httperror401authorizationrequired.md) (from checkFetch(), trySync(), tryPush()) +- [RemoteErr.NetworkError](./git-documentdb.remoteerr.networkerror.md) -[RemoteErr.HTTPError404NotFound](./git-documentdb.remoteerr.httperror404notfound.md) (from checkFetch(), trySync(), tryPush()) +- [RemoteErr.HTTPError401AuthorizationRequired](./git-documentdb.remoteerr.httperror401authorizationrequired.md) -[RemoteErr.CannotConnectError](./git-documentdb.remoteerr.cannotconnecterror.md) (from checkFetch(), trySync(), tryPush()) +- [RemoteErr.HTTPError404NotFound](./git-documentdb.remoteerr.httperror404notfound.md) - (from checkFetch(), trySync(), tryPush()) +- [RemoteErr.CannotConnectError](./git-documentdb.remoteerr.cannotconnecterror.md) -[RemoteErr.InvalidRepositoryURLError](./git-documentdb.remoteerr.invalidrepositoryurlerror.md) (from checkFetch(), trySync(), tryPush()) +- [RemoteErr.InvalidURLFormatError](./git-documentdb.remoteerr.invalidurlformaterror.md) -[RemoteErr.InvalidSSHKeyPathError](./git-documentdb.remoteerr.invalidsshkeypatherror.md) (from checkFetch, trySync(), tryPush()) +- [RemoteErr.InvalidRepositoryURLError](./git-documentdb.remoteerr.invalidrepositoryurlerror.md) -[RemoteErr.InvalidAuthenticationTypeError](./git-documentdb.remoteerr.invalidauthenticationtypeerror.md) (from checkFetch(), trySync(), tryPush()) +- [RemoteErr.InvalidSSHKeyPathError](./git-documentdb.remoteerr.invalidsshkeypatherror.md) -[RemoteErr.UnfetchedCommitExistsError](./git-documentdb.remoteerr.unfetchedcommitexistserror.md) (from tryPush()) +- [RemoteErr.InvalidAuthenticationTypeError](./git-documentdb.remoteerr.invalidauthenticationtypeerror.md) -[RemoteErr.HTTPError403Forbidden](./git-documentdb.remoteerr.httperror403forbidden.md) (from tryPush()) +Errors from [Sync.trySync()](./git-documentdb.sync.trysync.md) -[Err.NoMergeBaseFoundError](./git-documentdb.err.nomergebasefounderror.md) (from trySync()) - -[Err.ThreeWayMergeError](./git-documentdb.err.threewaymergeerror.md) (from trySync()) - -[Err.CannotDeleteDataError](./git-documentdb.err.cannotdeletedataerror.md) (from trySync()) - -[Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) (from trySync(), tryPush()) +Errors from [Sync.tryPush()](./git-documentdb.sync.trypush.md) diff --git a/docs-api/git-documentdb.sync.trypush.md b/docs-api/git-documentdb.sync.trypush.md index 4786faae..79cd7bc7 100644 --- a/docs-api/git-documentdb.sync.trypush.md +++ b/docs-api/git-documentdb.sync.trypush.md @@ -23,33 +23,37 @@ Promise<[SyncResultPush](./git-documentdb.syncresultpush.md) \| [SyncResultCa [Err.PushNotAllowedError](./git-documentdb.err.pushnotallowederror.md) - (from pushWorker()) +\# Errors from push - (from pushWorker()) +- [RemoteErr.InvalidGitRemoteError](./git-documentdb.remoteerr.invalidgitremoteerror.md) - (from pushWorker()) +- [RemoteErr.UnfetchedCommitExistsError](./git-documentdb.remoteerr.unfetchedcommitexistserror.md) - (from pushWorker()) +- [RemoteErr.InvalidURLFormatError](./git-documentdb.remoteerr.invalidurlformaterror.md) - (from pushWorker()) +- [RemoteErr.NetworkError](./git-documentdb.remoteerr.networkerror.md) - (from pushWorker()) +- [RemoteErr.HTTPError401AuthorizationRequired](./git-documentdb.remoteerr.httperror401authorizationrequired.md) - (from pushWorker()) +- [RemoteErr.HTTPError404NotFound](./git-documentdb.remoteerr.httperror404notfound.md) - (from pushWorker()) +- [RemoteErr.HTTPError403Forbidden](./git-documentdb.remoteerr.httperror403forbidden.md) - (from pushWorker()) +- [RemoteErr.CannotConnectError](./git-documentdb.remoteerr.cannotconnecterror.md) - (from pushWorker()) +- [RemoteErr.UnfetchedCommitExistsError](./git-documentdb.remoteerr.unfetchedcommitexistserror.md) - (from pushWorker()) +- [RemoteErr.CannotConnectError](./git-documentdb.remoteerr.cannotconnecterror.md) - (from pushWorker()) +- [RemoteErr.InvalidURLFormatError](./git-documentdb.remoteerr.invalidurlformaterror.md) - (from pushWorker()) +- [RemoteErr.InvalidRepositoryURLError](./git-documentdb.remoteerr.invalidrepositoryurlerror.md) - (from pushWorker()) +- [RemoteErr.InvalidSSHKeyPathError](./git-documentdb.remoteerr.invalidsshkeypatherror.md) -[Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) (from pushWorker()) +- [RemoteErr.InvalidAuthenticationTypeError](./git-documentdb.remoteerr.invalidauthenticationtypeerror.md) + +\# Errors from getChanges + +- [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) diff --git a/docs-api/git-documentdb.sync.trysync.md b/docs-api/git-documentdb.sync.trysync.md index 4698b3bb..1388fa75 100644 --- a/docs-api/git-documentdb.sync.trysync.md +++ b/docs-api/git-documentdb.sync.trysync.md @@ -25,59 +25,57 @@ Promise<[SyncResult](./git-documentdb.syncresult.md) > [Err.CombineDatabaseError](./git-documentdb.err.combinedatabaseerror.md) -[Err.NoMergeBaseFoundError](./git-documentdb.err.nomergebasefounderror.md) (from syncWorker()) +\# Errors from syncWorker -[RemoteErr.InvalidGitRemoteError](./git-documentdb.remoteerr.invalidgitremoteerror.md) (from syncWorker()) +- [Err.NoMergeBaseFoundError](./git-documentdb.err.nomergebasefounderror.md) -[RemoteErr.InvalidURLFormatError](./git-documentdb.remoteerr.invalidurlformaterror.md) (from syncWorker()) +- [Err.ThreeWayMergeError](./git-documentdb.err.threewaymergeerror.md) -[RemoteErr.NetworkError](./git-documentdb.remoteerr.networkerror.md) (from syncWorker()) +- [Err.CannotDeleteDataError](./git-documentdb.err.cannotdeletedataerror.md) -[RemoteErr.HTTPError401AuthorizationRequired](./git-documentdb.remoteerr.httperror401authorizationrequired.md) (from syncWorker()) +\# Errors from fetch, pushWorker -[RemoteErr.HTTPError404NotFound](./git-documentdb.remoteerr.httperror404notfound.md) (from syncWorker()) +- [RemoteErr.InvalidGitRemoteError](./git-documentdb.remoteerr.invalidgitremoteerror.md) -[RemoteErr.CannotConnectError](./git-documentdb.remoteerr.cannotconnecterror.md) (from syncWorker()) +- [RemoteErr.InvalidURLFormatError](./git-documentdb.remoteerr.invalidurlformaterror.md) - (from syncWorker()) +- [RemoteErr.NetworkError](./git-documentdb.remoteerr.networkerror.md) -[RemoteErr.InvalidRepositoryURLError](./git-documentdb.remoteerr.invalidrepositoryurlerror.md) (from syncWorker()) +- [RemoteErr.HTTPError401AuthorizationRequired](./git-documentdb.remoteerr.httperror401authorizationrequired.md) -[RemoteErr.InvalidSSHKeyPathError](./git-documentdb.remoteerr.invalidsshkeypatherror.md) (from syncWorker()) +- [RemoteErr.HTTPError404NotFound](./git-documentdb.remoteerr.httperror404notfound.md) -[RemoteErr.InvalidAuthenticationTypeError](./git-documentdb.remoteerr.invalidauthenticationtypeerror.md) (from syncWorker()) +- [RemoteErr.CannotConnectError](./git-documentdb.remoteerr.cannotconnecterror.md) -[RemoteErr.HTTPError403Forbidden](./git-documentdb.remoteerr.httperror403forbidden.md) (from syncWorker()) +- [RemoteErr.InvalidURLFormatError](./git-documentdb.remoteerr.invalidurlformaterror.md) -[RemoteErr.UnfetchedCommitExistsError](./git-documentdb.remoteerr.unfetchedcommitexistserror.md) (from syncWorker()) +- [RemoteErr.InvalidRepositoryURLError](./git-documentdb.remoteerr.invalidrepositoryurlerror.md) -[Err.InvalidConflictStateError](./git-documentdb.err.invalidconflictstateerror.md) (from syncWorker()) +- [RemoteErr.InvalidSSHKeyPathError](./git-documentdb.remoteerr.invalidsshkeypatherror.md) -[Err.CannotDeleteDataError](./git-documentdb.err.cannotdeletedataerror.md) (from syncWorker()) +- [RemoteErr.InvalidAuthenticationTypeError](./git-documentdb.remoteerr.invalidauthenticationtypeerror.md) -[Err.InvalidDocTypeError](./git-documentdb.err.invaliddoctypeerror.md) (from syncWorker()) +\# Errors from pushWorker -[Err.InvalidConflictResolutionStrategyError](./git-documentdb.err.invalidconflictresolutionstrategyerror.md) (from syncWorker()) +- [RemoteErr.HTTPError403Forbidden](./git-documentdb.remoteerr.httperror403forbidden.md) -[Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) (from syncWorker()) +- [RemoteErr.UnfetchedCommitExistsError](./git-documentdb.remoteerr.unfetchedcommitexistserror.md) -[Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) (from syncWorker()) +\# Errors from merge - (from combineDatabaseWithTheirs()) +- [Err.InvalidConflictStateError](./git-documentdb.err.invalidconflictstateerror.md) - (from combineDatabaseWithTheirs()) +- [Err.CannotDeleteDataError](./git-documentdb.err.cannotdeletedataerror.md) - (from combineDatabaseWithTheirs()) +- [Err.InvalidDocTypeError](./git-documentdb.err.invaliddoctypeerror.md) - (from combineDatabaseWithTheirs()) +- [Err.InvalidConflictResolutionStrategyError](./git-documentdb.err.invalidconflictresolutionstrategyerror.md) - (from combineDatabaseWithTheirs()) +- [Err.CannotCreateDirectoryError](./git-documentdb.err.cannotcreatedirectoryerror.md) - (from combineDatabaseWithTheirs()) +- [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) - (from combineDatabaseWithTheirs()) +\# Errors from getChanges - (from combineDatabaseWithTheirs()) - - (from combineDatabaseWithTheirs()) +- [Err.InvalidJsonObjectError](./git-documentdb.err.invalidjsonobjecterror.md) diff --git a/docs-api/git-documentdb.wrappingremoteengineerror.md b/docs-api/git-documentdb.wrappingremoteengineerror.md index ebae7031..a7bcc66e 100644 --- a/docs-api/git-documentdb.wrappingremoteengineerror.md +++ b/docs-api/git-documentdb.wrappingremoteengineerror.md @@ -8,6 +8,8 @@ hide_title: true ## wrappingRemoteEngineError() function +wrappingRemoteEngineError + Signature: ```typescript diff --git a/etc/git-documentdb.api.md b/etc/git-documentdb.api.md index efc76fe0..d9e06d4a 100644 --- a/etc/git-documentdb.api.md +++ b/etc/git-documentdb.api.md @@ -868,12 +868,12 @@ export type PutResultText = { type: 'text'; }; -// @public (undocumented) +// @public export const RemoteEngine: { [key: string]: RemoteEngineInterface; }; -// @public (undocumented) +// @public export interface RemoteEngineInterface { // (undocumented) checkFetch: (workingDir: string, options: RemoteOptions, remoteName?: string, logger?: Logger) => Promise; @@ -885,7 +885,7 @@ export interface RemoteEngineInterface { push: (workingDir: string, remoteOptions: RemoteOptions, remoteName?: string, localBranch?: string, remoteBranch?: string, logger?: Logger) => Promise; } -// @public (undocumented) +// @public export namespace RemoteErr { export class CannotConnectError extends RemoteErrors.CannotConnectError { constructor(mes: unknown); @@ -1350,7 +1350,7 @@ export class Validator { validateLocalDir(localDir: string): void; } -// @public (undocumented) +// @public export function wrappingRemoteEngineError(remoteEngineError: RemoteErrors.BaseError): Error; // @public diff --git a/src/collection.ts b/src/collection.ts index 6850d04a..b73416af 100644 --- a/src/collection.ts +++ b/src/collection.ts @@ -109,6 +109,7 @@ export class Collection implements ICollection { * * @remarks * Child collection inherits Parent's CollectionOptions. + * * @public */ get parent (): ICollection | undefined { @@ -120,6 +121,7 @@ export class Collection implements ICollection { * * @param collectionPathFromParent - A relative collectionPath from a parent collection. * @param parent - A parent collection of this collection. + * * @throws {@link Err.InvalidCollectionPathCharacterError} * @throws {@link Err.InvalidCollectionPathLengthError} * @@ -235,18 +237,19 @@ export class Collection implements ICollection { * * @throws {@link Err.InvalidJsonObjectError} * - * @throws # from validateDocument, validateId - * @throws {@link Err.InvalidIdCharacterError} - * @throws {@link Err.InvalidIdLengthError} - * - * @throws # from putImpl + * @privateRemarks # Errors from putImpl * @throws {@link Err.DatabaseClosingError} * @throws {@link Err.TaskCancelError} * - * @throws # from putWorker - * @throws {@link Err.UndefinedDBError} - * @throws {@link Err.CannotCreateDirectoryError} - * @throws {@link Err.CannotWriteDataError} + * @throws # Errors from validateDocument, validateId + * @throws - {@link Err.InvalidIdCharacterError} + * @throws - {@link Err.InvalidIdLengthError} + * + * @throws # Errors from putWorker + * @throws - {@link Err.UndefinedDBError} + * @throws - {@link Err.CannotCreateDirectoryError} + * @throws - {@link Err.CannotWriteDataError} + * * @public */ put (jsonDoc: JsonDoc, options?: PutOptions): Promise; @@ -267,18 +270,18 @@ export class Collection implements ICollection { * * @throws {@link Err.InvalidJsonObjectError} * - * @throws # from validateDocument, validateId - * @throws {@link Err.InvalidIdCharacterError} - * @throws {@link Err.InvalidIdLengthError} - * - * @throws # from putImpl + * @privateRemarks # Errors from putImpl * @throws {@link Err.DatabaseClosingError} * @throws {@link Err.TaskCancelError} * - * @throws # from putWorker - * @throws {@link Err.UndefinedDBError} - * @throws {@link Err.CannotCreateDirectoryError} - * @throws {@link Err.CannotWriteDataError} + * @throws # Errors from validateDocument, validateId + * @throws - {@link Err.InvalidIdCharacterError} + * @throws - {@link Err.InvalidIdLengthError} + * + * @throws # Errors from putWorker + * @throws - {@link Err.UndefinedDBError} + * @throws - {@link Err.CannotCreateDirectoryError} + * @throws - {@link Err.CannotWriteDataError} * * @public */ @@ -379,22 +382,24 @@ export class Collection implements ICollection { * * @param jsonDoc - See {@link JsonDoc} for restriction. * - * @throws {@link Err.InvalidJsonObjectError} + * @param jsonDoc - See {@link JsonDoc} for restriction. * - * @throws # from validateDocument, validateId - * @throws {@link Err.InvalidIdCharacterError} - * @throws {@link Err.InvalidIdLengthError} + * @throws {@link Err.InvalidJsonObjectError} * - * @throws # from putImpl + * @privateRemarks # Errors from putImpl * @throws {@link Err.DatabaseClosingError} * @throws {@link Err.TaskCancelError} * - * @throws # from putWorker - * @throws {@link Err.UndefinedDBError} - * @throws {@link Err.CannotCreateDirectoryError} - * @throws {@link Err.CannotWriteDataError} + * @throws # Errors from validateDocument, validateId + * @throws - {@link Err.InvalidIdCharacterError} + * @throws - {@link Err.InvalidIdLengthError} * - * @throws {@link Err.SameIdExistsError} + * @throws # Errors from putWorker + * @throws - {@link Err.UndefinedDBError} + * @throws - {@link Err.CannotCreateDirectoryError} + * @throws - {@link Err.CannotWriteDataError} + * + * @throws - {@link Err.SameIdExistsError} * * @public */ @@ -416,20 +421,20 @@ export class Collection implements ICollection { * * @throws {@link Err.InvalidJsonObjectError} * - * @throws # from validateDocument, validateId - * @throws {@link Err.InvalidIdCharacterError} - * @throws {@link Err.InvalidIdLengthError} - * - * @throws # from putImpl + * @privateRemarks # Errors from putImpl * @throws {@link Err.DatabaseClosingError} * @throws {@link Err.TaskCancelError} * - * @throws # from putWorker - * @throws {@link Err.UndefinedDBError} - * @throws {@link Err.CannotCreateDirectoryError} - * @throws {@link Err.CannotWriteDataError} + * @throws # Errors from validateDocument, validateId + * @throws - {@link Err.InvalidIdCharacterError} + * @throws - {@link Err.InvalidIdLengthError} + * + * @throws # Errors from putWorker + * @throws - {@link Err.UndefinedDBError} + * @throws - {@link Err.CannotCreateDirectoryError} + * @throws - {@link Err.CannotWriteDataError} * - * @throws {@link Err.SameIdExistsError} + * @throws - {@link Err.SameIdExistsError} * * @public */ @@ -486,20 +491,20 @@ export class Collection implements ICollection { * * @throws {@link Err.InvalidJsonObjectError} * - * @throws # from validateDocument, validateId - * @throws {@link Err.InvalidIdCharacterError} - * @throws {@link Err.InvalidIdLengthError} - * - * @throws # from putImpl + * @privateRemarks # Errors from putImpl * @throws {@link Err.DatabaseClosingError} * @throws {@link Err.TaskCancelError} * - * @throws # from putWorker - * @throws {@link Err.UndefinedDBError} - * @throws {@link Err.CannotCreateDirectoryError} - * @throws {@link Err.CannotWriteDataError} + * @throws # Errors from validateDocument, validateId + * @throws - {@link Err.InvalidIdCharacterError} + * @throws - {@link Err.InvalidIdLengthError} + * + * @throws # Errors from putWorker + * @throws - {@link Err.UndefinedDBError} + * @throws - {@link Err.CannotCreateDirectoryError} + * @throws - {@link Err.CannotWriteDataError} * - * @throws {@link Err.DocumentNotFoundError} + * @throws - {@link Err.DocumentNotFoundError} * * @public */ @@ -519,20 +524,20 @@ export class Collection implements ICollection { * * @throws {@link Err.InvalidJsonObjectError} * - * @throws # from validateDocument, validateId - * @throws {@link Err.InvalidIdCharacterError} - * @throws {@link Err.InvalidIdLengthError} - * - * @throws # from putImpl + * @privateRemarks # Errors from putImpl * @throws {@link Err.DatabaseClosingError} * @throws {@link Err.TaskCancelError} * - * @throws # from putWorker - * @throws {@link Err.UndefinedDBError} - * @throws {@link Err.CannotCreateDirectoryError} - * @throws {@link Err.CannotWriteDataError} + * @throws # Errors from validateDocument, validateId + * @throws - {@link Err.InvalidIdCharacterError} + * @throws - {@link Err.InvalidIdLengthError} + * + * @throws # Errors from putWorker + * @throws - {@link Err.UndefinedDBError} + * @throws - {@link Err.CannotCreateDirectoryError} + * @throws - {@link Err.CannotWriteDataError} * - * @throws {@link Err.DocumentNotFoundError} + * @throws - {@link Err.DocumentNotFoundError} * * @public */ @@ -590,18 +595,18 @@ export class Collection implements ICollection { * @throws {@link Err.InvalidJsonFileExtensionError} * @throws {@link Err.InvalidJsonObjectError} * - * @throws # from validateDocument, validateId - * @throws {@link Err.InvalidIdCharacterError} - * @throws {@link Err.InvalidIdLengthError} - * - * @throws # from putImpl + * @privateRemarks # Errors from putImpl * @throws {@link Err.DatabaseClosingError} * @throws {@link Err.TaskCancelError} * - * @throws # from putWorker - * @throws {@link Err.UndefinedDBError} - * @throws {@link Err.CannotCreateDirectoryError} - * @throws {@link Err.CannotWriteDataError} + * @throws # Errors from validateDocument, validateId + * @throws - {@link Err.InvalidIdCharacterError} + * @throws - {@link Err.InvalidIdLengthError} + * + * @throws # Errors from putWorker + * @throws - {@link Err.UndefinedDBError} + * @throws - {@link Err.CannotCreateDirectoryError} + * @throws - {@link Err.CannotWriteDataError} * * @public */ @@ -710,20 +715,20 @@ export class Collection implements ICollection { * * @throws {@link Err.InvalidJsonObjectError} * - * @throws # from validateDocument, validateId - * @throws {@link Err.InvalidIdCharacterError} - * @throws {@link Err.InvalidIdLengthError} - * - * @throws # fromm putImpl + * @privateRemarks # Errors from putImpl * @throws {@link Err.DatabaseClosingError} * @throws {@link Err.TaskCancelError} * - * @throws # from putWorker - * @throws {@link Err.UndefinedDBError} - * @throws {@link Err.CannotCreateDirectoryError} - * @throws {@link Err.CannotWriteDataError} + * @throws # Errors from validateDocument, validateId + * @throws - {@link Err.InvalidIdCharacterError} + * @throws - {@link Err.InvalidIdLengthError} * - * @throws {@link Err.SameIdExistsError} + * @throws # Errors from putWorker + * @throws - {@link Err.UndefinedDBError} + * @throws - {@link Err.CannotCreateDirectoryError} + * @throws - {@link Err.CannotWriteDataError} + * + * @throws - {@link Err.SameIdExistsError} * * @public */ @@ -755,20 +760,20 @@ export class Collection implements ICollection { * * @throws {@link Err.InvalidJsonObjectError} * - * @throws # from validateDocument, validateId - * @throws {@link Err.InvalidIdCharacterError} - * @throws {@link Err.InvalidIdLengthError} - * - * @throws # fromm putImpl + * @privateRemarks # Errors from putImpl * @throws {@link Err.DatabaseClosingError} * @throws {@link Err.TaskCancelError} * - * @throws # from putWorker - * @throws {@link Err.UndefinedDBError} - * @throws {@link Err.CannotCreateDirectoryError} - * @throws {@link Err.CannotWriteDataError} + * @throws # Errors from validateDocument, validateId + * @throws - {@link Err.InvalidIdCharacterError} + * @throws - {@link Err.InvalidIdLengthError} + * + * @throws # Errors from putWorker + * @throws - {@link Err.UndefinedDBError} + * @throws - {@link Err.CannotCreateDirectoryError} + * @throws - {@link Err.CannotWriteDataError} * - * @throws {@link Err.DocumentNotFoundError} + * @throws - {@link Err.DocumentNotFoundError} * * @public */ @@ -1050,14 +1055,14 @@ export class Collection implements ICollection { * * @throws {@link Err.UndefinedDocumentIdError} * - * @throws from deleteImpl + * @privateRemarks # Errors from deleteImpl * @throws {@link Err.DatabaseClosingError} * @throws {@link Err.TaskCancelError} * - * @throws from deleteWorker - * @throws {@link Err.UndefinedDBError} - * @throws {@link Err.DocumentNotFoundError} - * @throws {@link Err.CannotDeleteDataError} + * @throws # Errors from deleteWorker + * @throws - {@link Err.UndefinedDBError} + * @throws - {@link Err.DocumentNotFoundError} + * @throws - {@link Err.CannotDeleteDataError} * * @public */ @@ -1070,14 +1075,14 @@ export class Collection implements ICollection { * * @throws {@link Err.UndefinedDocumentIdError} * - * @throws from deleteImpl + * @privateRemarks # Errors from deleteImpl * @throws {@link Err.DatabaseClosingError} * @throws {@link Err.TaskCancelError} * - * @throws from deleteWorker - * @throws {@link Err.UndefinedDBError} - * @throws {@link Err.DocumentNotFoundError} - * @throws {@link Err.CannotDeleteDataError} + * @throws # Errors from deleteWorker + * @throws - {@link Err.UndefinedDBError} + * @throws - {@link Err.DocumentNotFoundError} + * @throws - {@link Err.CannotDeleteDataError} * * @public */ @@ -1125,12 +1130,15 @@ export class Collection implements ICollection { * @param shortName - shortName is a file path whose collectionPath is omitted. * * @throws {@link Err.UndefinedDocumentIdError} - * @throws {@link Err.DatabaseClosingError} (from deleteImpl) - * @throws {@link Err.TaskCancelError} (from deleteImpl) * - * @throws {@link Err.UndefinedDBError} (from deleteWorker) - * @throws {@link Err.DocumentNotFoundError} (from deleteWorker) - * @throws {@link Err.CannotDeleteDataError} (from deleteWorker) + * @privateRemarks # Errors from deleteImpl + * @throws {@link Err.DatabaseClosingError} + * @throws {@link Err.TaskCancelError} + * + * @throws # Errors from deleteWorker + * @throws - {@link Err.UndefinedDBError} + * @throws - {@link Err.DocumentNotFoundError} + * @throws - {@link Err.CannotDeleteDataError} * * @public */ diff --git a/src/git_documentdb.ts b/src/git_documentdb.ts index 4b20a328..0e2efc73 100644 --- a/src/git_documentdb.ts +++ b/src/git_documentdb.ts @@ -359,11 +359,11 @@ export class GitDocumentDB * @throws {@link Err.CannotCreateDirectoryError} * * @throws # from putWorker - * @throws {@link Err.UndefinedDBError} - * @throws {@link Err.CannotCreateDirectoryError} - * @throws {@link Err.SameIdExistsError} - * @throws {@link Err.DocumentNotFoundError} - * @throws {@link Err.CannotWriteDataError} + * @throws - {@link Err.UndefinedDBError} + * @throws - {@link Err.CannotCreateDirectoryError} + * @throws - {@link Err.SameIdExistsError} + * @throws - {@link Err.DocumentNotFoundError} + * @throws - {@link Err.CannotWriteDataError} * @internal */ @@ -420,16 +420,16 @@ export class GitDocumentDB * @throws {@link Err.DatabaseClosingError} * @throws {@link Err.RepositoryNotFoundError} may occurs when openOptions.createIfNotExists is false. * - * @throws # from _createRepository - * @throws {@link Err.CannotCreateDirectoryError} + * @throws # Errors from _createRepository + * @throws - {@link Err.CannotCreateDirectoryError} + * + * @throws # Errors from putWorker + * @throws - {@link Err.UndefinedDBError} + * @throws - {@link Err.CannotCreateDirectoryError} + * @throws - {@link Err.SameIdExistsError} + * @throws - {@link Err.DocumentNotFoundError} + * @throws - {@link Err.CannotWriteDataError} * - * @throws # from putWorker - * @throws {@link Err.UndefinedDBError} - * @throws {@link Err.CannotCreateDirectoryError} - * @throws {@link Err.SameIdExistsError} - * @throws {@link Err.DocumentNotFoundError} - * @throws {@link Err.CannotWriteDataError} - * @public */ async open (openOptions?: OpenOptions): Promise { @@ -633,34 +633,17 @@ export class GitDocumentDB /** * Synchronize with a remote repository * + * @remarks + * Register and synchronize with a remote repository. Do not register the same remote repository again. Call unregisterRemote() before register it again. + * * @throws {@link Err.RemoteAlreadyRegisteredError} * - * @throws # from Sync#syncAndGetResultImpl + * @privateRemarks # from Sync#syncAndGetResultImpl * @throws {@link Err.DatabaseClosingError} * @throws {@link Err.RepositoryNotOpenError} - * @throws {@link Err.UndefinedRemoteURLError} - * @throws {@link Err.IntervalTooSmallError} - * @throws {@link Err.SyncIntervalLessThanOrEqualToRetryIntervalError} - * @throws {@link Err.CannotCreateRemoteRepositoryError} - * @throws {@link RemoteErr.InvalidGitRemoteError} - * @throws {@link RemoteErr.InvalidURLFormatError} - * @throws {@link RemoteErr.NetworkError} - * @throws {@link RemoteErr.HTTPError401AuthorizationRequired} - * @throws {@link RemoteErr.HTTPError404NotFound} - * @throws {@link RemoteErr.CannotConnectError} - * @throws {@link RemoteErr.HttpProtocolRequiredError} - * @throws {@link RemoteErr.InvalidRepositoryURLError} - * @throws {@link RemoteErr.InvalidSSHKeyPathError} - * @throws {@link RemoteErr.InvalidAuthenticationTypeError} - * @throws {@link RemoteErr.UnfetchedCommitExistsError} - * @throws {@link RemoteErr.HTTPError403Forbidden} - * @throws {@link Err.NoMergeBaseFoundError} - * @throws {@link Err.ThreeWayMergeError} - * @throws {@link Err.CannotDeleteDataError} - * @throws {@link Err.InvalidJsonObjectError} * - * @remarks - * Register and synchronize with a remote repository. Do not register the same remote repository again. Call unregisterRemote() before register it again. + * @throws Errors from constructor of {@link Sync} class. + * @throws Errors from {@link Sync.init} * * @public */ @@ -673,30 +656,14 @@ export class GitDocumentDB * * @throws {@link Err.RemoteAlreadyRegisteredError} * - * @throws # from Sync#syncAndGetResultImpl + * @privateRemarks # from Sync#syncAndGetResultImpl * @throws {@link Err.DatabaseClosingError} * @throws {@link Err.RepositoryNotOpenError} - * @throws {@link Err.UndefinedRemoteURLError} - * @throws {@link Err.IntervalTooSmallError} - * @throws {@link Err.SyncIntervalLessThanOrEqualToRetryIntervalError} - * @throws {@link Err.CannotCreateRemoteRepositoryError} - * @throws {@link RemoteErr.InvalidGitRemoteError} - * @throws {@link RemoteErr.InvalidURLFormatError} - * @throws {@link RemoteErr.NetworkError} - * @throws {@link RemoteErr.HTTPError401AuthorizationRequired} - * @throws {@link RemoteErr.HTTPError404NotFound} - * @throws {@link RemoteErr.CannotConnectError} - * @throws {@link RemoteErr.HttpProtocolRequiredError} - * @throws {@link RemoteErr.InvalidRepositoryURLError} - * @throws {@link RemoteErr.InvalidSSHKeyPathError} - * @throws {@link RemoteErr.InvalidAuthenticationTypeError} - * @throws {@link RemoteErr.UnfetchedCommitExistsError} - * @throws {@link RemoteErr.HTTPError403Forbidden} - * @throws {@link Err.NoMergeBaseFoundError} - * @throws {@link Err.ThreeWayMergeError} - * @throws {@link Err.CannotDeleteDataError} - * @throws {@link Err.InvalidJsonObjectError} - + * + * @throws Errors from constructor of {@link Sync} class. + * @throws Errors from {@link Sync.init} + * + * * @public */ async sync (options: RemoteOptions, getSyncResult: boolean): Promise<[Sync, SyncResult]>; @@ -822,12 +789,12 @@ export class GitDocumentDB /** * Load DatabaseInfo from .gitddb/info.json * - * @throws # from putWorker - * @throws {@link Err.UndefinedDBError} - * @throws {@link Err.CannotCreateDirectoryError} - * @throws {@link Err.SameIdExistsError} - * @throws {@link Err.DocumentNotFoundError} - * @throws {@link Err.CannotWriteDataError} + * @throws # Errors from putWorker + * @throws - {@link Err.UndefinedDBError} + * @throws - {@link Err.CannotCreateDirectoryError} + * @throws - {@link Err.SameIdExistsError} + * @throws - {@link Err.DocumentNotFoundError} + * @throws - {@link Err.CannotWriteDataError} * * @internal */ @@ -898,18 +865,18 @@ export class GitDocumentDB * * @throws {@link Err.InvalidJsonObjectError} * - * @throws # from validateDocument, validateId - * @throws {@link Err.InvalidIdCharacterError} - * @throws {@link Err.InvalidIdLengthError} - * - * @throws # from putImpl + * @privateRemarks # Errors from putImpl * @throws {@link Err.DatabaseClosingError} * @throws {@link Err.TaskCancelError} * - * @throws # from putWorker - * @throws {@link Err.UndefinedDBError} - * @throws {@link Err.CannotCreateDirectoryError} - * @throws {@link Err.CannotWriteDataError} + * @throws # Errors from validateDocument, validateId + * @throws - {@link Err.InvalidIdCharacterError} + * @throws - {@link Err.InvalidIdLengthError} + * + * @throws # Errors from putWorker + * @throws - {@link Err.UndefinedDBError} + * @throws - {@link Err.CannotCreateDirectoryError} + * @throws - {@link Err.CannotWriteDataError} * * @public */ @@ -933,18 +900,18 @@ export class GitDocumentDB * * @throws {@link Err.InvalidJsonObjectError} * - * @throws # from validateDocument, validateId - * @throws {@link Err.InvalidIdCharacterError} - * @throws {@link Err.InvalidIdLengthError} - * - * @throws # from putImpl + * @privateRemarks # Errors from putImpl * @throws {@link Err.DatabaseClosingError} * @throws {@link Err.TaskCancelError} * - * @throws # from putWorker - * @throws {@link Err.UndefinedDBError} - * @throws {@link Err.CannotCreateDirectoryError} - * @throws {@link Err.CannotWriteDataError} + * @throws # Errors from validateDocument, validateId + * @throws - {@link Err.InvalidIdCharacterError} + * @throws - {@link Err.InvalidIdLengthError} + * + * @throws # Errors from putWorker + * @throws - {@link Err.UndefinedDBError} + * @throws - {@link Err.CannotCreateDirectoryError} + * @throws - {@link Err.CannotWriteDataError} * * @public */ @@ -980,20 +947,20 @@ export class GitDocumentDB * * @throws {@link Err.InvalidJsonObjectError} * - * @throws # from validateDocument, validateId - * @throws {@link Err.InvalidIdCharacterError} - * @throws {@link Err.InvalidIdLengthError} - * - * @throws # from putImpl + * @privateRemarks # Errors from putImpl * @throws {@link Err.DatabaseClosingError} * @throws {@link Err.TaskCancelError} * - * @throws # from putWorker - * @throws {@link Err.UndefinedDBError} - * @throws {@link Err.CannotCreateDirectoryError} - * @throws {@link Err.CannotWriteDataError} + * @throws # Errors from validateDocument, validateId + * @throws - {@link Err.InvalidIdCharacterError} + * @throws - {@link Err.InvalidIdLengthError} + * + * @throws # Errors from putWorker + * @throws - {@link Err.UndefinedDBError} + * @throws - {@link Err.CannotCreateDirectoryError} + * @throws - {@link Err.CannotWriteDataError} * - * @throws {@link Err.SameIdExistsError} + * @throws - {@link Err.SameIdExistsError} * * @public */ @@ -1017,20 +984,20 @@ export class GitDocumentDB * * @throws {@link Err.InvalidJsonObjectError} * - * @throws # from validateDocument, validateId - * @throws {@link Err.InvalidIdCharacterError} - * @throws {@link Err.InvalidIdLengthError} - * - * @throws # from putImpl + * @privateRemarks # Errors from putImpl * @throws {@link Err.DatabaseClosingError} * @throws {@link Err.TaskCancelError} * - * @throws # from putWorker - * @throws {@link Err.UndefinedDBError} - * @throws {@link Err.CannotCreateDirectoryError} - * @throws {@link Err.CannotWriteDataError} + * @throws # Errors from validateDocument, validateId + * @throws - {@link Err.InvalidIdCharacterError} + * @throws - {@link Err.InvalidIdLengthError} + * + * @throws # Errors from putWorker + * @throws - {@link Err.UndefinedDBError} + * @throws - {@link Err.CannotCreateDirectoryError} + * @throws - {@link Err.CannotWriteDataError} * - * @throws {@link Err.SameIdExistsError} + * @throws - {@link Err.SameIdExistsError} * * @public */ @@ -1066,20 +1033,20 @@ export class GitDocumentDB * * @throws {@link Err.InvalidJsonObjectError} * - * @throws # from validateDocument, validateId - * @throws {@link Err.InvalidIdCharacterError} - * @throws {@link Err.InvalidIdLengthError} - * - * @throws # from putImpl + * @privateRemarks # Errors from putImpl * @throws {@link Err.DatabaseClosingError} * @throws {@link Err.TaskCancelError} * - * @throws # from putWorker - * @throws {@link Err.UndefinedDBError} - * @throws {@link Err.CannotCreateDirectoryError} - * @throws {@link Err.CannotWriteDataError} + * @throws # Errors from validateDocument, validateId + * @throws - {@link Err.InvalidIdCharacterError} + * @throws - {@link Err.InvalidIdLengthError} + * + * @throws # Errors from putWorker + * @throws - {@link Err.UndefinedDBError} + * @throws - {@link Err.CannotCreateDirectoryError} + * @throws - {@link Err.CannotWriteDataError} * - * @throws {@link Err.DocumentNotFoundError} + * @throws - {@link Err.DocumentNotFoundError} * * @public */ @@ -1101,20 +1068,20 @@ export class GitDocumentDB * * @throws {@link Err.InvalidJsonObjectError} * - * @throws # from validateDocument, validateId - * @throws {@link Err.InvalidIdCharacterError} - * @throws {@link Err.InvalidIdLengthError} - * - * @throws # from putImpl + * @privateRemarks # Errors from putImpl * @throws {@link Err.DatabaseClosingError} * @throws {@link Err.TaskCancelError} * - * @throws # from putWorker - * @throws {@link Err.UndefinedDBError} - * @throws {@link Err.CannotCreateDirectoryError} - * @throws {@link Err.CannotWriteDataError} + * @throws # Errors from validateDocument, validateId + * @throws - {@link Err.InvalidIdCharacterError} + * @throws - {@link Err.InvalidIdLengthError} + * + * @throws # Errors from putWorker + * @throws - {@link Err.UndefinedDBError} + * @throws - {@link Err.CannotCreateDirectoryError} + * @throws - {@link Err.CannotWriteDataError} * - * @throws {@link Err.DocumentNotFoundError} + * @throws - {@link Err.DocumentNotFoundError} * * @public */ @@ -1151,18 +1118,18 @@ export class GitDocumentDB * @throws {@link Err.InvalidJsonFileExtensionError} * @throws {@link Err.InvalidJsonObjectError} * - * @throws # from validateDocument, validateId - * @throws {@link Err.InvalidIdCharacterError} - * @throws {@link Err.InvalidIdLengthError} - * - * @throws # from putImpl + * @privateRemarks # Errors from putImpl * @throws {@link Err.DatabaseClosingError} * @throws {@link Err.TaskCancelError} * - * @throws # from putWorker - * @throws {@link Err.UndefinedDBError} - * @throws {@link Err.CannotCreateDirectoryError} - * @throws {@link Err.CannotWriteDataError} + * @throws # Errors from validateDocument, validateId + * @throws - {@link Err.InvalidIdCharacterError} + * @throws - {@link Err.InvalidIdLengthError} + * + * @throws # Errors from putWorker + * @throws - {@link Err.UndefinedDBError} + * @throws - {@link Err.CannotCreateDirectoryError} + * @throws - {@link Err.CannotWriteDataError} * * @public */ @@ -1192,20 +1159,20 @@ export class GitDocumentDB * * @throws {@link Err.InvalidJsonObjectError} * - * @throws # from validateDocument, validateId - * @throws {@link Err.InvalidIdCharacterError} - * @throws {@link Err.InvalidIdLengthError} - * - * @throws # from putImpl + * @privateRemarks # Errors from putImpl * @throws {@link Err.DatabaseClosingError} * @throws {@link Err.TaskCancelError} * - * @throws # from putWorker - * @throws {@link Err.UndefinedDBError} - * @throws {@link Err.CannotCreateDirectoryError} - * @throws {@link Err.CannotWriteDataError} + * @throws # Errors from validateDocument, validateId + * @throws - {@link Err.InvalidIdCharacterError} + * @throws - {@link Err.InvalidIdLengthError} + * + * @throws # Errors from putWorker + * @throws - {@link Err.UndefinedDBError} + * @throws - {@link Err.CannotCreateDirectoryError} + * @throws - {@link Err.CannotWriteDataError} * - * @throws {@link Err.SameIdExistsError} + * @throws - {@link Err.SameIdExistsError} * * @public */ @@ -1235,20 +1202,20 @@ export class GitDocumentDB * * @throws {@link Err.InvalidJsonObjectError} * - * @throws # from validateDocument, validateId - * @throws {@link Err.InvalidIdCharacterError} - * @throws {@link Err.InvalidIdLengthError} - * - * @throws # fromm putImpl + * @privateRemarks # Errors from putImpl * @throws {@link Err.DatabaseClosingError} * @throws {@link Err.TaskCancelError} * - * @throws # from putWorker - * @throws {@link Err.UndefinedDBError} - * @throws {@link Err.CannotCreateDirectoryError} - * @throws {@link Err.CannotWriteDataError} + * @throws # Errors from validateDocument, validateId + * @throws - {@link Err.InvalidIdCharacterError} + * @throws - {@link Err.InvalidIdLengthError} + * + * @throws # Errors from putWorker + * @throws - {@link Err.UndefinedDBError} + * @throws - {@link Err.CannotCreateDirectoryError} + * @throws - {@link Err.CannotWriteDataError} * - * @throws {@link Err.DocumentNotFoundError} + * @throws - {@link Err.DocumentNotFoundError} * * @public */ @@ -1504,14 +1471,14 @@ export class GitDocumentDB * * @throws {@link Err.UndefinedDocumentIdError} * - * @throws from deleteImpl + * @privateRemarks # Errors from deleteImpl * @throws {@link Err.DatabaseClosingError} * @throws {@link Err.TaskCancelError} * - * @throws from deleteWorker - * @throws {@link Err.UndefinedDBError} - * @throws {@link Err.DocumentNotFoundError} - * @throws {@link Err.CannotDeleteDataError} + * @throws # Errors from deleteWorker + * @throws - {@link Err.UndefinedDBError} + * @throws - {@link Err.DocumentNotFoundError} + * @throws - {@link Err.CannotDeleteDataError} * * @public */ @@ -1527,14 +1494,14 @@ export class GitDocumentDB * * @throws {@link Err.UndefinedDocumentIdError} * - * @throws from deleteImpl + * @privateRemarks # Errors from deleteImpl * @throws {@link Err.DatabaseClosingError} * @throws {@link Err.TaskCancelError} * - * @throws from deleteWorker - * @throws {@link Err.UndefinedDBError} - * @throws {@link Err.DocumentNotFoundError} - * @throws {@link Err.CannotDeleteDataError} + * @throws # Errors from deleteWorker + * @throws - {@link Err.UndefinedDBError} + * @throws - {@link Err.DocumentNotFoundError} + * @throws - {@link Err.CannotDeleteDataError} * * @public */ @@ -1555,12 +1522,15 @@ export class GitDocumentDB * - This is an alias of GitDocumentDB#rootCollection.deleteFatDoc() * * @throws {@link Err.UndefinedDocumentIdError} - * @throws {@link Err.DatabaseClosingError} (from deleteImpl) - * @throws {@link Err.TaskCancelError} (from deleteImpl) * - * @throws {@link Err.UndefinedDBError} (from deleteWorker) - * @throws {@link Err.DocumentNotFoundError} (from deleteWorker) - * @throws {@link Err.CannotDeleteDataError} (from deleteWorker) + * @privateRemarks # Errors from deleteImpl + * @throws {@link Err.DatabaseClosingError} + * @throws {@link Err.TaskCancelError} + * + * @throws # Errors from deleteWorker + * @throws - {@link Err.UndefinedDBError} + * @throws - {@link Err.DocumentNotFoundError} + * @throws - {@link Err.CannotDeleteDataError} * * @public */ diff --git a/src/remote/3way_merge.ts b/src/remote/3way_merge.ts index 5ba53f20..ee9e353d 100644 --- a/src/remote/3way_merge.ts +++ b/src/remote/3way_merge.ts @@ -20,6 +20,9 @@ import { JsonDiff } from './json_diff'; import { SyncInterface } from '../types_sync'; import { isSameFatDoc } from '../crud/blob'; +/** + * @internal + */ function getStrategy ( strategy: ConflictResolutionStrategies | undefined, oursDoc?: FatDoc, @@ -46,6 +49,8 @@ function getStrategy ( /** * @throws {@link Err.InvalidConflictResolutionStrategyError} + * + * @internal */ function getMergedJsonDoc ( jsonDiff: JsonDiff, @@ -88,6 +93,8 @@ function getMergedJsonDoc ( /** * @throws {@link Err.InvalidConflictResolutionStrategyError} + * + * @internal */ function getMergedTextDoc ( strategy: ConflictResolutionStrategyLabels, @@ -115,6 +122,8 @@ function getMergedTextDoc ( /** * @throws {@link Err.InvalidConflictResolutionStrategyError} + * + * @internal */ function getMergedBinaryDoc ( strategy: ConflictResolutionStrategyLabels, @@ -135,7 +144,11 @@ function getMergedBinaryDoc ( * getMergedDocument * * @throws {@link Err.InvalidDocTypeError} - * @throws {@link Err.InvalidConflictResolutionStrategyError} (from getMergedJsonDoc, getMergedTextDoc, getMergedBinaryDoc) + * + * @throws # Errors from getMergedJsonDoc, getMergedTextDoc, getMergedBinaryDoc + * @throws - {@link Err.InvalidConflictResolutionStrategyError} + * + * @internal */ function getMergedDocument ( jsonDiff: JsonDiff, @@ -180,12 +193,9 @@ function getMergedDocument ( /** * merge * - * @throws {@link Err.InvalidConflictStateError} (from threeWayMerge()) - * @throws {@link Err.CannotDeleteDataError} (from threeWayMerge()) - * @throws {@link Err.InvalidDocTypeError} (from threeWayMerge()) - * @throws {@link Err.InvalidConflictResolutionStrategyError} (from threeWayMerge()) - * @throws {@link Err.CannotCreateDirectoryError} (from threeWayMerge()) - * @throws {@link Err.InvalidJsonObjectError} (from threeWayMerge()) + * @throws Errors from {@link threeWayMerge} + * + * @internal */ export async function merge ( gitDDB: GitDDBInterface, @@ -294,11 +304,15 @@ export async function merge ( * @throws {@link Err.InvalidConflictStateError} * @throws {@link Err.CannotDeleteDataError} * - * @throws {@link Err.InvalidDocTypeError} (from getMergedDocument()) - * @throws {@link Err.InvalidConflictResolutionStrategyError} (from getMergedDocument()) + * @throws # Errors from getMergedDocument + * @throws - {@link Err.InvalidDocTypeError} + * @throws - {@link Err.InvalidConflictResolutionStrategyError} + * + * @throws # Errors from writeBlobToFile + * @throws - {@link Err.CannotCreateDirectoryError} * - * @throws {@link Err.CannotCreateDirectoryError} (from writeBlobToFile) - * @throws {@link Err.InvalidJsonObjectError} (from getFatDocFromData, getFatDocFromReadBlobResult) + * @throws # Errors from getFatDocFromData, getFatDocFromReadBlobResult + * @throws - {@link Err.InvalidJsonObjectError} * */ // eslint-disable-next-line complexity diff --git a/src/remote/combine.ts b/src/remote/combine.ts index e7973619..a1b7c4c2 100644 --- a/src/remote/combine.ts +++ b/src/remote/combine.ts @@ -40,6 +40,8 @@ import { RemoteEngine, wrappingRemoteEngineError } from './remote_engine'; * @throws {@link RemoteErr.InvalidSSHKeyPathError} (from clone()) * * @throws {@link RemoteErr.InvalidAuthenticationTypeError} (from clone()) + * + * @public */ // eslint-disable-next-line complexity export async function combineDatabaseWithTheirs ( diff --git a/src/remote/push_worker.ts b/src/remote/push_worker.ts index 5efffa06..2bef978d 100644 --- a/src/remote/push_worker.ts +++ b/src/remote/push_worker.ts @@ -17,22 +17,26 @@ import { RemoteEngine, wrappingRemoteEngineError } from './remote_engine'; /** * Push and get changes * - * @throws {@link InvalidGitRemoteError} (from push()) - * @throws {@link UnfetchedCommitExistsError} (from push()) - * @throws {@link InvalidURLFormatError} (from push()) - * @throws {@link NetworkError} (from push()) - * @throws {@link HTTPError401AuthorizationRequired} (from push()) - * @throws {@link HTTPError404NotFound} (from push()) - * @throws {@link HTTPError403Forbidden} (from push()) - * @throws {@link CannotConnectError} (from push()) - * @throws {@link UnfetchedCommitExistsError} (from push()) - * @throws {@link CannotConnectError} (from push()) - * @throws {@link HttpProtocolRequiredError} (from push()) - * @throws {@link InvalidRepositoryURLError} (from push()) - * @throws {@link InvalidSSHKeyPathError} (from push()) - * @throws {@link InvalidAuthenticationTypeError} (from push()) + * @throws # Errors from push + * @throws - {@link InvalidGitRemoteError} + * @throws - {@link UnfetchedCommitExistsError} + * @throws - {@link InvalidURLFormatError} + * @throws - {@link NetworkError} + * @throws - {@link HTTPError401AuthorizationRequired} + * @throws - {@link HTTPError404NotFound} + * @throws - {@link HTTPError403Forbidden} + * @throws - {@link CannotConnectError} + * @throws - {@link UnfetchedCommitExistsError} + * @throws - {@link CannotConnectError} + * @throws - {@link HttpProtocolRequiredError} + * @throws - {@link InvalidRepositoryURLError} + * @throws - {@link InvalidSSHKeyPathError} + * @throws - {@link InvalidAuthenticationTypeError} * - * @throws {@link Err.InvalidJsonObjectError} (from getChanges()) + * @throws # Errors from getChanges + * @throws - {@link Err.InvalidJsonObjectError} + * + * @internal */ export async function pushWorker ( gitDDB: GitDDBInterface, diff --git a/src/remote/remote_engine.ts b/src/remote/remote_engine.ts index aad8cadb..80633e3f 100644 --- a/src/remote/remote_engine.ts +++ b/src/remote/remote_engine.ts @@ -4,8 +4,18 @@ import { Logger } from 'tslog'; import * as RemoteErrors from 'git-documentdb-remote-errors'; import { RemoteOptions } from '../types'; +/** + * RemoteEngine + * + * @public + */ export const RemoteEngine: { [key: string]: RemoteEngineInterface } = {}; +/** + * RemoteEngineInterface + * + * @public + */ export interface RemoteEngineInterface { checkFetch: ( workingDir: string, @@ -35,6 +45,11 @@ export interface RemoteEngineInterface { ) => Promise; } +/** + * RemoteError + * + * @public + */ export namespace RemoteErr { /** * Copy error message from parent @@ -107,6 +122,11 @@ export namespace RemoteErr { } } +/** + * wrappingRemoteEngineError + * + * @public + */ // eslint-disable-next-line complexity export function wrappingRemoteEngineError (remoteEngineError: RemoteErrors.BaseError) { switch (true) { diff --git a/src/remote/sync.ts b/src/remote/sync.ts index 176d7c8e..2a93db6c 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -61,9 +61,23 @@ import { RemoteEngine, RemoteErr, wrappingRemoteEngineError } from './remote_eng * encodeToRemoteName * * @remarks - * Remote name consists of host_name + hash. - * hash is generated from remoteURL. - * Capitalize host name of remoteURL manually when hashes collide because host name is not case sensitive. + * The first default name of Git remote is "origin". + * + * GitDocumentDB adds an alias of "origin", + * whose name is generated automatically by this function. + * The second and subsequent remotes are also named in the same way. + * + * A remote name consists of [remote address]_[hash]. + * Periods are replaced with underscores. + * e.g.) github_com_a0b1c23 + * It is human-readable. + * + * [remote address] is [hostname + domain name] or [ip address]. + * [hash] is calculated from remoteURL. + * + * [hash] is the first seven characters of SHA-1 so that it may collide. + * Capitalize one of the remote addresses when hashes collide + * because a hostname and a domain name are not case sensitive. * * @public */ @@ -105,27 +119,8 @@ export function encodeToGitRemoteName (remoteURL: string) { * @throws {@link Err.DatabaseClosingError} * @throws {@link Err.RepositoryNotOpenError} * - * @throws {@link Err.UndefinedRemoteURLError} (from constructor) - * @throws {@link Err.IntervalTooSmallError} (from constructor) - * @throws {@link Err.SyncIntervalLessThanOrEqualToRetryIntervalError} (from sync#constructor) - * - * @throws {@link Err.CannotCreateRemoteRepositoryError} (from init) - * @throws {@link RemoteErr.InvalidGitRemoteError} (from init) - * @throws {@link RemoteErr.InvalidURLFormatError} (from init) - * @throws {@link RemoteErr.NetworkError} (from init) - * @throws {@link RemoteErr.HTTPError401AuthorizationRequired} (from init) - * @throws {@link RemoteErr.HTTPError404NotFound} (from init) - * @throws {@link RemoteErr.CannotConnectError} (from init) - * @throws {@link RemoteErr.HttpProtocolRequiredError} (from init) - * @throws {@link RemoteErr.InvalidRepositoryURLError} (from init) - * @throws {@link RemoteErr.InvalidSSHKeyPathError} (from init) - * @throws {@link RemoteErr.InvalidAuthenticationTypeError} (from inti) - * @throws {@link RemoteErr.UnfetchedCommitExistsError} (from init) - * @throws {@link RemoteErr.HTTPError403Forbidden} (from init) - * @throws {@link Err.NoMergeBaseFoundError} (from init) - * @throws {@link Err.ThreeWayMergeError} (from init) - * @throws {@link Err.CannotDeleteDataError} (from init) - * @throws {@link Err.InvalidJsonObjectError} (from init) + * @throws # Errors from constructor of {@link Sync} class. + * @throws # Errors from {@link Sync.init} * * @internal */ @@ -147,6 +142,12 @@ export async function syncAndGetResultImpl ( /** * Implementation of GitDocumentDB#sync(options) * + * @throws {@link Err.DatabaseClosingError} + * @throws {@link Err.RepositoryNotOpenError} + * + * @throws # Errors from constructor of {@link Sync} class. + * @throws # Errors from {@link Sync.init} + * * @internal */ export async function syncImpl ( @@ -158,6 +159,8 @@ export async function syncImpl ( } /** + * Filter file changes by collectionPath + * * @internal */ function filterChanges (syncResult: SyncResult, collectionPath: string): SyncResult { @@ -340,7 +343,7 @@ export class Sync implements SyncInterface { * * @throws {@link Err.UndefinedRemoteURLError} * @throws {@link Err.IntervalTooSmallError} - * @throws {@link Err.InvalidAuthenticationTypeError} + * @throws {@link Err.SyncIntervalLessThanOrEqualToRetryIntervalError} * * @public */ @@ -414,25 +417,20 @@ export class Sync implements SyncInterface { * * @throws {@link Err.CannotCreateRemoteRepositoryError} * - * @throws {@link RemoteErr.InvalidGitRemoteError} (from checkFetch(), trySync(), tryPush()) - * @throws {@link RemoteErr.InvalidURLFormatError} (from checkFetch(), trySync(), tryPush()) - * @throws {@link RemoteErr.NetworkError} (from checkFetch(), trySync(), tryPush()) - * @throws {@link RemoteErr.HTTPError401AuthorizationRequired} (from checkFetch(), trySync(), tryPush()) - * @throws {@link RemoteErr.HTTPError404NotFound} (from checkFetch(), trySync(), tryPush()) - * @throws {@link RemoteErr.CannotConnectError} (from checkFetch(), trySync(), tryPush()) - * @throws {@link RemoteErr.HttpProtocolRequiredError} (from checkFetch(), trySync(), tryPush()) - * @throws {@link RemoteErr.InvalidRepositoryURLError} (from checkFetch(), trySync(), tryPush()) - * @throws {@link RemoteErr.InvalidSSHKeyPathError} (from checkFetch, trySync(), tryPush()) - * @throws {@link RemoteErr.InvalidAuthenticationTypeError} (from checkFetch(), trySync(), tryPush()) - * - * @throws {@link RemoteErr.UnfetchedCommitExistsError} (from tryPush()) - * @throws {@link RemoteErr.HTTPError403Forbidden} (from tryPush()) - * - * @throws {@link Err.NoMergeBaseFoundError} (from trySync()) - * @throws {@link Err.ThreeWayMergeError} (from trySync()) - * @throws {@link Err.CannotDeleteDataError} (from trySync()) + * @throws # Errors from RemoteEngine[engineName].checkFetch + * @throws - {@link RemoteErr.InvalidGitRemoteError} + * @throws - {@link RemoteErr.InvalidURLFormatError} + * @throws - {@link RemoteErr.NetworkError} + * @throws - {@link RemoteErr.HTTPError401AuthorizationRequired} + * @throws - {@link RemoteErr.HTTPError404NotFound} + * @throws - {@link RemoteErr.CannotConnectError} + * @throws - {@link RemoteErr.InvalidURLFormatError} + * @throws - {@link RemoteErr.InvalidRepositoryURLError} + * @throws - {@link RemoteErr.InvalidSSHKeyPathError} + * @throws - {@link RemoteErr.InvalidAuthenticationTypeError} * - * @throws {@link Err.InvalidJsonObjectError} (from trySync(), tryPush()) + * @throws Errors from {@link Sync.trySync} + * @throws Errors from {@link Sync.tryPush} * * @public */ @@ -649,21 +647,24 @@ export class Sync implements SyncInterface { * * @throws {@link Err.PushNotAllowedError} * - * @throws {@link InvalidGitRemoteError} (from pushWorker()) - * @throws {@link UnfetchedCommitExistsError} (from pushWorker()) - * @throws {@link InvalidURLFormatError} (from pushWorker()) - * @throws {@link NetworkError} (from pushWorker()) - * @throws {@link HTTPError401AuthorizationRequired} (from pushWorker()) - * @throws {@link HTTPError404NotFound} (from pushWorker()) - * @throws {@link HTTPError403Forbidden} (from pushWorker()) - * @throws {@link CannotConnectError} (from pushWorker()) - * @throws {@link UnfetchedCommitExistsError} (from pushWorker()) - * @throws {@link CannotConnectError} (from pushWorker()) - * @throws {@link HttpProtocolRequiredError} (from pushWorker()) - * @throws {@link InvalidRepositoryURLError} (from pushWorker()) - * @throws {@link InvalidSSHKeyPathError} (from pushWorker()) - * @throws {@link InvalidAuthenticationTypeError} (from pushWorker()) - * @throws {@link Err.InvalidJsonObjectError} (from pushWorker()) + * @throws # Errors from push + * @throws - {@link RemoteErr.InvalidGitRemoteError} + * @throws - {@link RemoteErr.UnfetchedCommitExistsError} + * @throws - {@link RemoteErr.InvalidURLFormatError} + * @throws - {@link RemoteErr.NetworkError} + * @throws - {@link RemoteErr.HTTPError401AuthorizationRequired} + * @throws - {@link RemoteErr.HTTPError404NotFound} + * @throws - {@link RemoteErr.HTTPError403Forbidden} + * @throws - {@link RemoteErr.CannotConnectError} + * @throws - {@link RemoteErr.UnfetchedCommitExistsError} + * @throws - {@link RemoteErr.CannotConnectError} + * @throws - {@link RemoteErr.InvalidURLFormatError} + * @throws - {@link RemoteErr.InvalidRepositoryURLError} + * @throws - {@link RemoteErr.InvalidSSHKeyPathError} + * @throws - {@link RemoteErr.InvalidAuthenticationTypeError} + * + * @throws # Errors from getChanges + * @throws - {@link Err.InvalidJsonObjectError} * * @public */ @@ -782,35 +783,37 @@ export class Sync implements SyncInterface { * @throws {@link Err.PushNotAllowedError} * @throws {@link Err.CombineDatabaseError} * - * @throws {@link Err.NoMergeBaseFoundError} (from syncWorker()) - * @throws {@link RemoteErr.InvalidGitRemoteError} (from syncWorker()) - * @throws {@link RemoteErr.InvalidURLFormatError} (from syncWorker()) - * @throws {@link RemoteErr.NetworkError} (from syncWorker()) - * @throws {@link RemoteErr.HTTPError401AuthorizationRequired} (from syncWorker()) - * @throws {@link RemoteErr.HTTPError404NotFound} (from syncWorker()) - * @throws {@link RemoteErr.CannotConnectError} (from syncWorker()) - * @throws {@link RemoteErr.HttpProtocolRequiredError} (from syncWorker()) - * @throws {@link RemoteErr.InvalidRepositoryURLError} (from syncWorker()) - * @throws {@link RemoteErr.InvalidSSHKeyPathError} (from syncWorker()) - * @throws {@link RemoteErr.InvalidAuthenticationTypeError} (from syncWorker()) - * @throws {@link RemoteErr.HTTPError403Forbidden} (from syncWorker()) - * @throws {@link RemoteErr.UnfetchedCommitExistsError} (from syncWorker()) - * @throws {@link Err.InvalidConflictStateError} (from syncWorker()) - * @throws {@link Err.CannotDeleteDataError} (from syncWorker()) - * @throws {@link Err.InvalidDocTypeError} (from syncWorker()) - * @throws {@link Err.InvalidConflictResolutionStrategyError} (from syncWorker()) - * @throws {@link Err.CannotCreateDirectoryError} (from syncWorker()) - * @throws {@link Err.InvalidJsonObjectError} (from syncWorker()) + * @throws # Errors from syncWorker + * @throws - {@link Err.NoMergeBaseFoundError} + * @throws - {@link Err.ThreeWayMergeError} + * @throws - {@link Err.CannotDeleteDataError} + * + * @throws # Errors from fetch, pushWorker + * @throws - {@link RemoteErr.InvalidGitRemoteError} + * @throws - {@link RemoteErr.InvalidURLFormatError} + * @throws - {@link RemoteErr.NetworkError} + * @throws - {@link RemoteErr.HTTPError401AuthorizationRequired} + * @throws - {@link RemoteErr.HTTPError404NotFound} + * @throws - {@link RemoteErr.CannotConnectError} + * @throws - {@link RemoteErr.InvalidURLFormatError} + * @throws - {@link RemoteErr.InvalidRepositoryURLError} + * @throws - {@link RemoteErr.InvalidSSHKeyPathError} + * @throws - {@link RemoteErr.InvalidAuthenticationTypeError} + * + * @throws # Errors from pushWorker + * @throws - {@link RemoteErr.HTTPError403Forbidden} + * @throws - {@link RemoteErr.UnfetchedCommitExistsError} + * + * @throws # Errors from merge + * @throws - {@link Err.InvalidConflictStateError} + * @throws - {@link Err.CannotDeleteDataError} + * @throws - {@link Err.InvalidDocTypeError} + * @throws - {@link Err.InvalidConflictResolutionStrategyError} + * @throws - {@link Err.CannotCreateDirectoryError} + * @throws - {@link Err.InvalidJsonObjectError} * - * @throws {@link InvalidURLFormatError} (from combineDatabaseWithTheirs()) - * @throws {@link NetworkError} (from combineDatabaseWithTheirs()) - * @throws {@link HTTPError401AuthorizationRequired} (from combineDatabaseWithTheirs()) - * @throws {@link HTTPError404NotFound} (from combineDatabaseWithTheirs()) - * @throws {@link CannotConnectError} (from combineDatabaseWithTheirs()) - * @throws {@link HttpProtocolRequiredError} (from combineDatabaseWithTheirs()) - * @throws {@link InvalidRepositoryURLError} (from combineDatabaseWithTheirs()) - * @throws {@link InvalidSSHKeyPathError} (from combineDatabaseWithTheirs()) - * @throws {@link InvalidAuthenticationTypeError} (from combineDatabaseWithTheirs()) + * @throws # Errors from getChanges + * @throws - {@link Err.InvalidJsonObjectError} * * @public */ diff --git a/src/remote/sync_worker.ts b/src/remote/sync_worker.ts index 1f80ff31..be477f99 100644 --- a/src/remote/sync_worker.ts +++ b/src/remote/sync_worker.ts @@ -35,29 +35,35 @@ import { Err } from '../error'; * @throws {@link Err.ThreeWayMergeError} * @throws {@link Err.CannotDeleteDataError} * - * @throws {@link RemoteErr.InvalidGitRemoteError} (from fetch(), pushWorker()) - * @throws {@link RemoteErr.InvalidURLFormatError} (from fetch(), pushWorker()) - * @throws {@link RemoteErr.NetworkError} (from fetch(), pushWorker()) - * @throws {@link RemoteErr.HTTPError401AuthorizationRequired} (from fetch(), pushWorker()) - * @throws {@link RemoteErr.HTTPError404NotFound} (from fetch(), pushWorker()) - * @throws {@link RemoteErr.CannotConnectError} (from fetch()), pushWorker()) - * @throws {@link RemoteErr.HttpProtocolRequiredError} (from fetch(), pushWorker()) - * @throws {@link RemoteErr.InvalidRepositoryURLError} (from fetch(), pushWorker()) - * @throws {@link RemoteErr.InvalidSSHKeyPathError} (from fetch(), pushWorker()) - * @throws {@link RemoteErr.InvalidAuthenticationTypeError} (from fetch(), pushWorker()) + * @throws # Errors from fetch, pushWorker + * @throws - {@link RemoteErr.InvalidGitRemoteError} + * @throws - {@link RemoteErr.InvalidURLFormatError} + * @throws - {@link RemoteErr.NetworkError} + * @throws - {@link RemoteErr.HTTPError401AuthorizationRequired} + * @throws - {@link RemoteErr.HTTPError404NotFound} + * @throws - {@link RemoteErr.CannotConnectError} + * @throws - {@link RemoteErr.HttpProtocolRequiredError} + * @throws - {@link RemoteErr.InvalidRepositoryURLError} + * @throws - {@link RemoteErr.InvalidSSHKeyPathError} + * @throws - {@link RemoteErr.InvalidAuthenticationTypeError} * - * @throws {@link HTTPError403Forbidden} (from pushWorker()) - * @throws {@link UnfetchedCommitExistsError} (from pushWorker()) + * @throws # Errors from pushWorker + * @throws - {@link RemoteErr.HTTPError403Forbidden} + * @throws - {@link RemoteErr.UnfetchedCommitExistsError} * - * @throws {@link Err.InvalidConflictStateError} (from merge()) - * @throws {@link Err.CannotDeleteDataError} (from merge()) - * @throws {@link Err.InvalidDocTypeError} (from merge()) - * @throws {@link Err.InvalidConflictResolutionStrategyError} (from merge()) - * @throws {@link Err.CannotCreateDirectoryError} (from merge()) - * @throws {@link Err.InvalidJsonObjectError} (from merge()) - - * @throws {@link Err.InvalidJsonObjectError} (from getChanges()) + * @throws # Errors from merge + * @throws - {@link Err.InvalidConflictStateError} + * @throws - {@link Err.CannotDeleteDataError} + * @throws ## Errors from getMergedDocument + * @throws - {@link Err.InvalidDocTypeError} + * @throws - {@link Err.InvalidConflictResolutionStrategyError} + * @throws ## Errors from writeBlobToFile + * @throws - {@link Err.CannotCreateDirectoryError} + * @throws ## Errors from getFatDocFromData, getFatDocFromReadBlobResult + * @throws - {@link Err.InvalidJsonObjectError} * + * @throws # Errors from getChanges + * @throws - {@link Err.InvalidJsonObjectError} * * @internal */ From 2d2eb1fe2855db3824ea7f415247b3bfae0ba7e3 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 30 Jul 2021 10:20:57 +0900 Subject: [PATCH 083/297] docs: fix exceptions --- src/crud/delete.ts | 7 ++++--- src/crud/history.ts | 4 +++- src/crud/put.ts | 11 ++++++----- src/remote/combine.ts | 21 ++++++++++++--------- 4 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/crud/delete.ts b/src/crud/delete.ts index 0de8e605..441b8337 100644 --- a/src/crud/delete.ts +++ b/src/crud/delete.ts @@ -22,9 +22,10 @@ import { normalizeCommit } from '../utils'; * @throws {@link Err.RepositoryNotOpenError} * @throws {@link Err.TaskCancelError} * - * @throws {@link Err.UndefinedDBError} (from deleteWorker) - * @throws {@link Err.DocumentNotFoundError} (from deleteWorker) - * @throws {@link Err.CannotDeleteDataError} (from deleteWorker) + * @throws # Errors from deleteWorker + * @throws - {@link Err.UndefinedDBError} + * @throws - {@link Err.DocumentNotFoundError} + * @throws - {@link Err.CannotDeleteDataError} * * @internal */ diff --git a/src/crud/history.ts b/src/crud/history.ts index 1945911b..ecce7487 100644 --- a/src/crud/history.ts +++ b/src/crud/history.ts @@ -19,7 +19,9 @@ import { blobToBinary, blobToJsonDoc, blobToText } from './blob'; * * @throws {@link Err.DatabaseClosingError} * @throws {@link Err.RepositoryNotOpenError} - * @throws {@link Err.InvalidJsonObjectError} (from blobToJsonDoc) + * + * @throws # Errors from blobToJsonDoc + * @throws {@link Err.InvalidJsonObjectError} */ // eslint-disable-next-line complexity export async function getHistoryImpl ( diff --git a/src/crud/put.ts b/src/crud/put.ts index 3c82d52b..a085e910 100644 --- a/src/crud/put.ts +++ b/src/crud/put.ts @@ -22,11 +22,12 @@ import { Err } from '../error'; * @throws {@link Err.RepositoryNotOpenError} * @throws {@link Err.TaskCancelError} * - * @throws {@link Err.UndefinedDBError} (from putWorker) - * @throws {@link Err.CannotCreateDirectoryError} (from putWorker) - * @throws {@link Err.SameIdExistsError} (from putWorker) - * @throws {@link Err.DocumentNotFoundError} (from putWorker) - * @throws {@link Err.CannotWriteDataError} (from putWorker) + * @throws # Errors from putWorker + * @throws {@link Err.UndefinedDBError} + * @throws {@link Err.CannotCreateDirectoryError} + * @throws {@link Err.SameIdExistsError} + * @throws {@link Err.DocumentNotFoundError} + * @throws {@link Err.CannotWriteDataError} * * @internal */ diff --git a/src/remote/combine.ts b/src/remote/combine.ts index a1b7c4c2..de79143b 100644 --- a/src/remote/combine.ts +++ b/src/remote/combine.ts @@ -29,17 +29,20 @@ import { RemoteEngine, wrappingRemoteEngineError } from './remote_engine'; * Clone a remote repository and combine the current local working directory with it. * TODO: Must catch errors * - * @throws {@link RemoteErr.InvalidURLFormatError} (from clone()) - * @throws {@link RemoteErr.NetworkError} (from clone()) - * @throws {@link RemoteErr.HTTPError401AuthorizationRequired} (from clone()) - * @throws {@link RemoteErr.HTTPError404NotFound} (from clone()) - * @throws {@link RemoteErr.CannotConnectError} (from clone()) + * @throws {@link Err.FileRemoveTimeoutError} * - * @throws {@link RemoteErr.HttpProtocolRequiredError} (from clone()) - * @throws {@link RemoteErr.InvalidRepositoryURLError} (from clone()) - * @throws {@link RemoteErr.InvalidSSHKeyPathError} (from clone()) + * @throws # Errors from RemoteEngine[engineName].clone + * @throws - {@link RemoteErr.InvalidURLFormatError} + * @throws - {@link RemoteErr.NetworkError} + * @throws - {@link RemoteErr.HTTPError401AuthorizationRequired} + * @throws - {@link RemoteErr.HTTPError404NotFound} + * @throws - {@link RemoteErr.CannotConnectError} * - * @throws {@link RemoteErr.InvalidAuthenticationTypeError} (from clone()) + * @throws - {@link RemoteErr.HttpProtocolRequiredError} + * @throws - {@link RemoteErr.InvalidRepositoryURLError} + * @throws - {@link RemoteErr.InvalidSSHKeyPathError} + * + * @throws - {@link RemoteErr.InvalidAuthenticationTypeError} * * @public */ From 9a5ec79b291709283c359dbfe40b5c6c131b9ecb Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 30 Jul 2021 10:35:14 +0900 Subject: [PATCH 084/297] test: add InvalidURLFormatErrro from encodeToGitRemoteName --- src/remote/sync.ts | 5 +++++ test/remote_base/sync.ts | 21 ++++++++++++++------- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/remote/sync.ts b/src/remote/sync.ts index 2a93db6c..58ce901e 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -79,6 +79,8 @@ import { RemoteEngine, RemoteErr, wrappingRemoteEngineError } from './remote_eng * Capitalize one of the remote addresses when hashes collide * because a hostname and a domain name are not case sensitive. * + * @throws {@link RemoteErr.InvalidURLFormatError} + * * @public */ export function encodeToGitRemoteName (remoteURL: string) { @@ -345,6 +347,9 @@ export class Sync implements SyncInterface { * @throws {@link Err.IntervalTooSmallError} * @throws {@link Err.SyncIntervalLessThanOrEqualToRetryIntervalError} * + * @throws # Errors from encodeToGitRemoteName + * @throws - {@link RemoteErr.InvalidURLFormatError} + * * @public */ // eslint-disable-next-line complexity diff --git a/test/remote_base/sync.ts b/test/remote_base/sync.ts index f6dc3866..5c3fd26d 100644 --- a/test/remote_base/sync.ts +++ b/test/remote_base/sync.ts @@ -56,7 +56,7 @@ export const syncBase = ( await removeRemoteRepositories(reposPrefix); }); - describe('encode Git remote name', () => { + describe.only('encodeToGitRemoteName', () => { it('always generates the same name', async () => { const remoteURL = 'ssh://user@github.com:443/foo-bar/baz.git'; const encoded = encodeToGitRemoteName(remoteURL); @@ -65,7 +65,7 @@ export const syncBase = ( expect(encoded).toBe(encoded2); }); - it('ssh://user@github.com:443/foo-bar/baz.git', () => { + it('encodes ssh://user@github.com:443/foo-bar/baz.git', () => { const remoteURL = 'ssh://user@github.com:443/foo-bar/baz.git'; const encoded = encodeToGitRemoteName(remoteURL); const shortHash = crypto @@ -76,7 +76,7 @@ export const syncBase = ( expect(encoded).toBe('github_com_' + shortHash); }); - it('ssh://user@127.0.0.1:443/foo-bar/baz.git', () => { + it('encodes ssh://user@127.0.0.1:443/foo-bar/baz.git', () => { const remoteURL = 'ssh://user@127.0.0.1:443/foo-bar/baz.git'; const encoded = encodeToGitRemoteName(remoteURL); const shortHash = crypto @@ -87,7 +87,7 @@ export const syncBase = ( expect(encoded).toBe('127_0_0_1_' + shortHash); }); - it('https://github.com:80/foo-bar/baz.git', () => { + it('encodes https://github.com:80/foo-bar/baz.git', () => { const remoteURL = 'https://github.com:80/foo-bar/baz.git'; const encoded = encodeToGitRemoteName(remoteURL); const shortHash = crypto @@ -98,7 +98,7 @@ export const syncBase = ( expect(encoded).toBe('github_com_' + shortHash); }); - it('ssh://user@github.com/foo-bar/baz.git', () => { + it('encodes ssh://user@github.com/foo-bar/baz.git', () => { const remoteURL = 'ssh://user@github.com/foo-bar/baz.git'; const encoded = encodeToGitRemoteName(remoteURL); const shortHash = crypto @@ -109,7 +109,7 @@ export const syncBase = ( expect(encoded).toBe('github_com_' + shortHash); }); - it('https://github.com/foo-bar/baz.git', () => { + it('encodes https://github.com/foo-bar/baz.git', () => { const remoteURL = 'https://github.com/foo-bar/baz.git'; const encoded = encodeToGitRemoteName(remoteURL); const shortHash = crypto @@ -120,7 +120,7 @@ export const syncBase = ( expect(encoded).toBe('github_com_' + shortHash); }); - it('git@github.com:foo-bar/baz.git', () => { + it('encodes git@github.com:foo-bar/baz.git', () => { const remoteURL = 'git@github.com:foo-bar/baz.git'; const encoded = encodeToGitRemoteName(remoteURL); const shortHash = crypto @@ -130,6 +130,13 @@ export const syncBase = ( .substr(0, 7); expect(encoded).toBe('github_com_' + shortHash); }); + + it('throws InvalidURLFormatError', () => { + const remoteURL = 'foo.bar'; + expect(() => { + encodeToGitRemoteName(remoteURL); + }).toThrowError(RemoteErr.InvalidURLFormatError); + }); }); /** From 792f18be6b6a9a0155028e041c0e7d44ff7674b3 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 30 Jul 2021 10:35:30 +0900 Subject: [PATCH 085/297] docs: add new lines --- src/remote/remote_repository.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/remote/remote_repository.ts b/src/remote/remote_repository.ts index 1a35066f..9c9f804b 100644 --- a/src/remote/remote_repository.ts +++ b/src/remote/remote_repository.ts @@ -48,6 +48,7 @@ export class RemoteRepository { /** * Create a repository on a remote site + * * @remarks * connection.type must be 'github' * @@ -125,6 +126,7 @@ export class RemoteRepository { /** * Delete a repository on a remote site + * * @remarks * connection.type must be 'github' * From f4e5fd39d120351b64d1d2faf0f2915b10d5ac10 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 30 Jul 2021 12:17:04 +0900 Subject: [PATCH 086/297] fix: fix walker for first commit --- src/remote/push_worker.ts | 6 ++++-- src/remote/worker_utils.ts | 12 ++++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/remote/push_worker.ts b/src/remote/push_worker.ts index 2bef978d..673fee7c 100644 --- a/src/remote/push_worker.ts +++ b/src/remote/push_worker.ts @@ -98,14 +98,16 @@ export async function pushWorker ( localCommitOid = headCommitOid; } - let baseCommitOid: string; + let baseCommitOid: string | undefined; if (remoteCommitOid === undefined) { // This is the first push in this repository. // Get the first commit. const logs = await git.log({ fs, dir: gitDDB.workingDir }); baseCommitOid = logs[logs.length - 1].oid; - remoteCommitOid = baseCommitOid; + if (baseCommitOid === localCommitOid) { + baseCommitOid = undefined; + } } else { [baseCommitOid] = await git.findMergeBase({ diff --git a/src/remote/worker_utils.ts b/src/remote/worker_utils.ts index 1430fab8..f071a8a7 100644 --- a/src/remote/worker_utils.ts +++ b/src/remote/worker_utils.ts @@ -150,7 +150,7 @@ export function getFatDocFromReadBlobResult ( */ export async function getChanges ( workingDir: string, - oldCommitOid: string, + oldCommitOid: string | undefined, newCommitOid: string ) { return await git.walk({ @@ -164,6 +164,14 @@ export async function getChanges ( if (fullDocPath === '.') { return; } + if (oldCommitOid === undefined) { + // Must set null explicitly. + a = null; + } + console.log(oldCommitOid + ',' + newCommitOid); + console.log(fullDocPath); + console.log(a); + console.log(b); const docType: DocType = fullDocPath.endsWith('.json') ? 'json' : 'text'; if (docType === 'text') { @@ -321,7 +329,7 @@ export async function getAndWriteLocalChanges ( export async function getCommitLogs ( workingDir: string, walkFromCommitOid: string, - walkToCommitOid: string, + walkToCommitOid?: string, walkToCommitOid2?: string ): Promise { // Return partial logs. From f376ac71586f056c6523f8f4993119fa49eb472b Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 30 Jul 2021 12:17:49 +0900 Subject: [PATCH 087/297] fix: do not use get when isOpened is false --- src/git_documentdb.ts | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/git_documentdb.ts b/src/git_documentdb.ts index 0e2efc73..c54e5391 100644 --- a/src/git_documentdb.ts +++ b/src/git_documentdb.ts @@ -66,6 +66,7 @@ import { normalizeCommit, toSortedJSONString } from './utils'; import { SyncEventInterface, SyncInterface } from './types_sync'; import { CRUDInterface } from './types_crud_interface'; import { CollectionInterface, ICollection } from './types_collection'; +import { blobToJsonDoc, readLatestBlob } from './crud/blob'; /** * Get database ID @@ -799,9 +800,16 @@ export class GitDocumentDB * @internal */ async loadDbInfo () { - let info = (await this.get(GIT_DOCUMENTDB_INFO_ID).catch( - () => undefined - )) as DatabaseInfo; + let info: DatabaseInfo; + + // Don't use get() because isOpened is false. + const readBlobResult = await readLatestBlob( + this.workingDir, + GIT_DOCUMENTDB_INFO_ID + JSON_EXT + ).catch(() => undefined); + if (readBlobResult !== undefined) { + info = blobToJsonDoc(GIT_DOCUMENTDB_INFO_ID, readBlobResult, false) as DatabaseInfo; + } info ??= { dbId: '', From aa178654be64a1007c1d0399329e754a05fe0f86 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 30 Jul 2021 12:22:21 +0900 Subject: [PATCH 088/297] fix: use const instead of let --- src/remote/push_worker.ts | 2 +- src/remote/worker_utils.ts | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/remote/push_worker.ts b/src/remote/push_worker.ts index 673fee7c..a64cd251 100644 --- a/src/remote/push_worker.ts +++ b/src/remote/push_worker.ts @@ -82,7 +82,7 @@ export async function pushWorker ( let localCommitOid: string; - let remoteCommitOid = await git + const remoteCommitOid = await git .resolveRef({ fs, dir: gitDDB.workingDir, diff --git a/src/remote/worker_utils.ts b/src/remote/worker_utils.ts index f071a8a7..46a20486 100644 --- a/src/remote/worker_utils.ts +++ b/src/remote/worker_utils.ts @@ -168,10 +168,6 @@ export async function getChanges ( // Must set null explicitly. a = null; } - console.log(oldCommitOid + ',' + newCommitOid); - console.log(fullDocPath); - console.log(a); - console.log(b); const docType: DocType = fullDocPath.endsWith('.json') ? 'json' : 'text'; if (docType === 'text') { From 618a36ef4ff3f1b16ec8f5e6044a62f53a93720c Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 30 Jul 2021 12:45:25 +0900 Subject: [PATCH 089/297] test: pass sync.test in remote_nodegit --- .vscode/launch.json | 2 +- test/remote_base/sync.ts | 204 ++++++++++++++++++++++--------- test/remote_nodegit/sync.test.ts | 2 +- 3 files changed, 145 insertions(+), 63 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 31d3ae2b..c98ed1f4 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,7 +4,7 @@ "type": "pickString", "id": "choice", "description": "select a file", - "options": ["test/remote/sync_trysync.test.js"], + "options": ["test/remote_nodegit/sync.test.js"], }], "configurations": [ { diff --git a/test/remote_base/sync.ts b/test/remote_base/sync.ts index 5c3fd26d..163cbdb1 100644 --- a/test/remote_base/sync.ts +++ b/test/remote_base/sync.ts @@ -26,7 +26,11 @@ import { GitDocumentDB } from '../../src/git_documentdb'; import { ConnectionSettings, RemoteOptions } from '../../src/types'; import { Err } from '../../src/error'; import { encodeToGitRemoteName, Sync, syncImpl } from '../../src/remote/sync'; -import { removeRemoteRepositories } from '../remote_utils'; +import { + createClonedDatabases, + destroyDBs, + removeRemoteRepositories, +} from '../remote_utils'; import { RemoteEngine, RemoteErr } from '../../src/remote/remote_engine'; export const syncBase = ( @@ -56,7 +60,7 @@ export const syncBase = ( await removeRemoteRepositories(reposPrefix); }); - describe.only('encodeToGitRemoteName', () => { + describe('encodeToGitRemoteName', () => { it('always generates the same name', async () => { const remoteURL = 'ssh://user@github.com:443/foo-bar/baz.git'; const encoded = encodeToGitRemoteName(remoteURL); @@ -454,6 +458,29 @@ export const syncBase = ( await gitDDB.destroy(); }); + it('throws NetworkError', async () => { + const dbName = serialId(); + const remoteURL = remoteURLBase + serialId(); + + const stubCheckFetch = sandbox.stub(RemoteEngine[connection.engine!], 'checkFetch'); + stubCheckFetch.rejects(new RemoteEngineErr.NetworkError('')); + + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + }); + await gitDDB.open(); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection, + }; + const sync = new Sync(gitDDB, options); + + await expect(sync.init()).rejects.toThrowError(RemoteErr.NetworkError); + + await gitDDB.destroy(); + }); + it('throws CannotCreateRemoteRepositoryError', async () => { const remoteURL = remoteURLBase + serialId(); @@ -509,60 +536,6 @@ export const syncBase = ( await gitDDB.destroy(); }); - it('succeeds after retries when NetworkError', async () => { - const dbName = serialId(); - const remoteURL = remoteURLBase + serialId(); - - const stubCheckFetch = sandbox.stub(RemoteEngine[connection.engine!], 'checkFetch'); - stubCheckFetch.onFirstCall().rejects(new RemoteEngineErr.NetworkError('')); - stubCheckFetch.onSecondCall().rejects(new RemoteEngineErr.HTTPError404NotFound('')); - - const gitDDB: GitDocumentDB = new GitDocumentDB({ - dbName, - localDir, - }); - await gitDDB.open(); - const options: RemoteOptions = { - remoteUrl: remoteURL, - connection, - }; - const sync = new Sync(gitDDB, options); - - await expect(sync.init()).resolves.toEqual({ - action: 'push', - changes: { remote: [] }, - }); - - expect(stubCheckFetch.callCount).toBe(2); - - await gitDDB.destroy(); - }); - - it('throws after retries when NetworkError', async () => { - const dbName = serialId(); - const remoteURL = remoteURLBase + serialId(); - - const stubCheckFetch = sandbox.stub(RemoteEngine[connection.engine!], 'checkFetch'); - stubCheckFetch.rejects(new RemoteEngineErr.NetworkError('')); - - const gitDDB: GitDocumentDB = new GitDocumentDB({ - dbName, - localDir, - }); - await gitDDB.open(); - const options: RemoteOptions = { - remoteUrl: remoteURL, - connection, - }; - const sync = new Sync(gitDDB, options); - - await expect(sync.init()).rejects.toThrowError(RemoteErr.NetworkError); - - expect(stubCheckFetch.callCount).toBe(3); - - await gitDDB.destroy(); - }); - it('sets Git remote in .git/config', async () => { const remoteURL = remoteURLBase + serialId(); @@ -662,15 +635,124 @@ export const syncBase = ( await gitDDB.destroy(); }); - it.skip('calls tryPush() after create remote repository'); + it('calls tryPush() after create remote repository', async () => { + const remoteURL = remoteURLBase + serialId(); + + const dbNameA = serialId(); + + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection, + }; + await gitDDB.open(); + const [sync, syncResult] = await gitDDB.sync(options, true); - it.skip('calls tryPush() when remote repository exists'); + expect(syncResult).toMatchObject({ + action: 'push', + changes: { + remote: [ + { + new: { + _id: '.gitddb/info', + doc: { + creator: 'GitDocumentDB', + // dbId: '01FBTPJSX4AE871NA0QN3ZEQVF', + version: '1.0', + }, + // fileOid: 'e6d3f788687080d0fd1aa23cbc4f270f5a3f98d0', + name: '.gitddb/info.json', + type: 'json', + }, + operation: 'insert', + }, + ], + }, + }); - it.skip('calls trySync() when remote repository exists'); + await expect( + git.getConfig({ + fs, + dir: gitDDB.workingDir, + path: `branch.${gitDDB.defaultBranch}.remote`, + }) + ).resolves.toBe(sync.remoteName); - it.skip('throws error in tryPush()'); + await expect( + git.getConfig({ + fs, + dir: gitDDB.workingDir, + path: `branch.${gitDDB.defaultBranch}.merge`, + }) + ).resolves.toBe(`refs/heads/${gitDDB.defaultBranch}`); - it.skip('throws error in trySync()'); + await gitDDB.destroy(); + }); + + it('calls tryPush() when remote repository exists', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir, + }); + await dbA.open(); + const optionA: RemoteOptions = { + remoteUrl: remoteURL, + syncDirection: 'push', + connection, + }; + await dbA.sync(optionA); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir, + }); + // Clone dbA + await dbB.open(); + const syncB = await dbB.sync({ + remoteUrl: remoteURL, + connection, + }); + await dbB.put({ name: 'fromB' }); + await syncB.tryPush(); + + await dbA.close(); + await dbA.open(); + await expect(dbA.sync(optionA, true)).rejects.toThrowError( + RemoteErr.UnfetchedCommitExistsError + ); + + await destroyDBs([dbA, dbB]); + }); + + it('calls trySync() when remote repository exists', async () => { + const [dbA, dbB, syncA, syncB] = await createClonedDatabases( + remoteURLBase, + localDir, + serialId, + { + syncDirection: 'both', + connection, + } + ); + await dbB.put({ name: 'fromB' }); + await syncB.tryPush(); + + await dbA.close(); + await dbA.open(); + const [sync, syncResult] = await dbA.sync(syncB.options, true); + + expect(syncResult).toMatchObject({ + action: 'fast-forward merge', + }); + + await destroyDBs([dbA, dbB]); + }); it('throws PushNotAllowedError.', async () => { const remoteURL = remoteURLBase + serialId(); diff --git a/test/remote_nodegit/sync.test.ts b/test/remote_nodegit/sync.test.ts index 2e2097df..b3a4bfa9 100644 --- a/test/remote_nodegit/sync.test.ts +++ b/test/remote_nodegit/sync.test.ts @@ -29,7 +29,7 @@ before(() => { }); after(() => { - // fs.removeSync(path.resolve(localDir)); + fs.removeSync(path.resolve(localDir)); }); // This test needs environment variables: From bd47445e19dead45918dcee5dc73f964de0ebdf3 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 30 Jul 2021 12:54:30 +0900 Subject: [PATCH 090/297] fix: fix error for invalid .gitddb/info.json --- src/git_documentdb.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/git_documentdb.ts b/src/git_documentdb.ts index c54e5391..45d651f9 100644 --- a/src/git_documentdb.ts +++ b/src/git_documentdb.ts @@ -800,7 +800,7 @@ export class GitDocumentDB * @internal */ async loadDbInfo () { - let info: DatabaseInfo; + let info: DatabaseInfo | undefined; // Don't use get() because isOpened is false. const readBlobResult = await readLatestBlob( @@ -808,7 +808,9 @@ export class GitDocumentDB GIT_DOCUMENTDB_INFO_ID + JSON_EXT ).catch(() => undefined); if (readBlobResult !== undefined) { - info = blobToJsonDoc(GIT_DOCUMENTDB_INFO_ID, readBlobResult, false) as DatabaseInfo; + try { + info = blobToJsonDoc(GIT_DOCUMENTDB_INFO_ID, readBlobResult, false) as DatabaseInfo; + } catch (e) {} } info ??= { From 6b716ad4ed9280bb3cfd8a3a93f4c7436f99bbf7 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 30 Jul 2021 12:55:09 +0900 Subject: [PATCH 091/297] test: move network test for history under test/remote_base/ --- test/crud/history.test.ts | 145 ------------------------------------ test/remote_base/history.ts | 144 +++++++++++++++++++++++++++++++++++ 2 files changed, 144 insertions(+), 145 deletions(-) create mode 100644 test/remote_base/history.ts diff --git a/test/crud/history.test.ts b/test/crud/history.test.ts index 319c8aec..fcd07333 100644 --- a/test/crud/history.test.ts +++ b/test/crud/history.test.ts @@ -76,151 +76,6 @@ const maybe = ? describe : describe.skip; -maybe(' getHistoryImpl', () => { - const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') - ? process.env.GITDDB_GITHUB_USER_URL - : process.env.GITDDB_GITHUB_USER_URL + '/'; - const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; - - before(async () => { - await removeRemoteRepositories(reposPrefix); - }); - - it('gets all revisions sorted by date from merged commit', async () => { - const [dbA, dbB, syncA, syncB] = await createClonedDatabases( - remoteURLBase, - localDir, - serialId, - { - conflictResolutionStrategy: 'ours', - } - ); - - const _id = 'prof'; - const shortName = _id + JSON_EXT; - const jsonA1 = { _id, name: 'A-1' }; - const jsonA2 = { _id, name: 'A-2' }; - const jsonA3 = { _id, name: 'A-3' }; - const jsonB1 = { _id, name: 'B-1' }; - const jsonB2 = { _id, name: 'B-2' }; - const putResultA1 = await dbA.put(jsonA1); - await sleep(1500); - const putResultB1 = await dbB.put(jsonB1); - await sleep(1500); - const putResultA2 = await dbA.put(jsonA2); - await sleep(1500); - const putResultB2 = await dbB.put(jsonB2); - await sleep(1500); - const putResultA3 = await dbA.put(jsonA3); - await sleep(1500); - - await syncA.trySync(); - await syncB.trySync(); // Resolve conflict. jsonB2 wins. - - // Get - const history = await getHistoryImpl(dbB, shortName, '', undefined, undefined, true); - - expect(history[0]).toEqual({ - _id, - name: shortName, - fileOid: expect.stringMatching(/^[\da-z]{40}$/), - type: 'json', - doc: jsonB2, - }); - expect(history[1]).toEqual({ - _id, - name: shortName, - fileOid: expect.stringMatching(/^[\da-z]{40}$/), - type: 'json', - doc: jsonA3, - }); - expect(history[2]).toEqual({ - _id, - name: shortName, - fileOid: expect.stringMatching(/^[\da-z]{40}$/), - type: 'json', - doc: jsonB2, - }); - expect(history[3]).toEqual({ - _id, - name: shortName, - fileOid: expect.stringMatching(/^[\da-z]{40}$/), - type: 'json', - doc: jsonA2, - }); - expect(history[4]).toEqual({ - _id, - name: shortName, - fileOid: expect.stringMatching(/^[\da-z]{40}$/), - type: 'json', - doc: jsonB1, - }); - expect(history[5]).toEqual({ - _id, - name: shortName, - fileOid: expect.stringMatching(/^[\da-z]{40}$/), - type: 'json', - doc: jsonA1, - }); - - await destroyDBs([dbA, dbB]); - }); -}); - -maybe(' readOldBlob()', () => { - const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') - ? process.env.GITDDB_GITHUB_USER_URL - : process.env.GITDDB_GITHUB_USER_URL + '/'; - const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; - - before(async () => { - await removeRemoteRepositories(reposPrefix); - }); - - it('skips a merge commit', async () => { - const [dbA, dbB, syncA, syncB] = await createClonedDatabases( - remoteURLBase, - localDir, - serialId, - { - conflictResolutionStrategy: 'ours', - } - ); - dbA.author = { - name: 'authorA', - email: 'authorEmailA', - }; - dbB.author = { - name: 'authorB', - email: 'authorEmailB', - }; - - const jsonA1 = { _id: 'A1', name: 'A1' }; - const jsonA1internal = { _id: 'A1', name: 'A1' }; - const jsonB1 = { _id: 'B1', name: 'B1' }; - const putResultA1 = await dbA.put(jsonA1); - await sleep(1500); - await dbB.put(jsonB1); - await sleep(1500); - - await syncA.trySync(); - await syncB.trySync(); // dbB commits 'merge' - - await expect( - readOldBlob(dbB.workingDir, 'A1.json', 0, { filter: [{ author: dbB.author }] }) - ).resolves.toBeUndefined(); // merge commit is skipped, so jsonA1 does not exist. - - await expect( - readOldBlob(dbB.workingDir, 'A1.json', 0, { filter: [{ author: dbA.author }] }) - ).resolves.toEqual({ - oid: putResultA1.fileOid, - blob: utf8encode(toSortedJSONString(jsonA1internal)), - }); - - await destroyDBs([dbA, dbB]); - }); -}); - describe(' getHistoryImpl', () => { it('gets all revisions', async () => { const dbName = monoId(); diff --git a/test/remote_base/history.ts b/test/remote_base/history.ts new file mode 100644 index 00000000..f528a12d --- /dev/null +++ b/test/remote_base/history.ts @@ -0,0 +1,144 @@ +maybe(' getHistoryImpl', () => { + const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') + ? process.env.GITDDB_GITHUB_USER_URL + : process.env.GITDDB_GITHUB_USER_URL + '/'; + const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; + + before(async () => { + await removeRemoteRepositories(reposPrefix); + }); + + it('gets all revisions sorted by date from merged commit', async () => { + const [dbA, dbB, syncA, syncB] = await createClonedDatabases( + remoteURLBase, + localDir, + serialId, + { + conflictResolutionStrategy: 'ours', + } + ); + + const _id = 'prof'; + const shortName = _id + JSON_EXT; + const jsonA1 = { _id, name: 'A-1' }; + const jsonA2 = { _id, name: 'A-2' }; + const jsonA3 = { _id, name: 'A-3' }; + const jsonB1 = { _id, name: 'B-1' }; + const jsonB2 = { _id, name: 'B-2' }; + const putResultA1 = await dbA.put(jsonA1); + await sleep(1500); + const putResultB1 = await dbB.put(jsonB1); + await sleep(1500); + const putResultA2 = await dbA.put(jsonA2); + await sleep(1500); + const putResultB2 = await dbB.put(jsonB2); + await sleep(1500); + const putResultA3 = await dbA.put(jsonA3); + await sleep(1500); + + await syncA.trySync(); + await syncB.trySync(); // Resolve conflict. jsonB2 wins. + + // Get + const history = await getHistoryImpl(dbB, shortName, '', undefined, undefined, true); + + expect(history[0]).toEqual({ + _id, + name: shortName, + fileOid: expect.stringMatching(/^[\da-z]{40}$/), + type: 'json', + doc: jsonB2, + }); + expect(history[1]).toEqual({ + _id, + name: shortName, + fileOid: expect.stringMatching(/^[\da-z]{40}$/), + type: 'json', + doc: jsonA3, + }); + expect(history[2]).toEqual({ + _id, + name: shortName, + fileOid: expect.stringMatching(/^[\da-z]{40}$/), + type: 'json', + doc: jsonB2, + }); + expect(history[3]).toEqual({ + _id, + name: shortName, + fileOid: expect.stringMatching(/^[\da-z]{40}$/), + type: 'json', + doc: jsonA2, + }); + expect(history[4]).toEqual({ + _id, + name: shortName, + fileOid: expect.stringMatching(/^[\da-z]{40}$/), + type: 'json', + doc: jsonB1, + }); + expect(history[5]).toEqual({ + _id, + name: shortName, + fileOid: expect.stringMatching(/^[\da-z]{40}$/), + type: 'json', + doc: jsonA1, + }); + + await destroyDBs([dbA, dbB]); + }); +}); + +maybe(' readOldBlob()', () => { + const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') + ? process.env.GITDDB_GITHUB_USER_URL + : process.env.GITDDB_GITHUB_USER_URL + '/'; + const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; + + before(async () => { + await removeRemoteRepositories(reposPrefix); + }); + + it('skips a merge commit', async () => { + const [dbA, dbB, syncA, syncB] = await createClonedDatabases( + remoteURLBase, + localDir, + serialId, + { + conflictResolutionStrategy: 'ours', + } + ); + dbA.author = { + name: 'authorA', + email: 'authorEmailA', + }; + dbB.author = { + name: 'authorB', + email: 'authorEmailB', + }; + + const jsonA1 = { _id: 'A1', name: 'A1' }; + const jsonA1internal = { _id: 'A1', name: 'A1' }; + const jsonB1 = { _id: 'B1', name: 'B1' }; + const putResultA1 = await dbA.put(jsonA1); + await sleep(1500); + await dbB.put(jsonB1); + await sleep(1500); + + await syncA.trySync(); + await syncB.trySync(); // dbB commits 'merge' + + await expect( + readOldBlob(dbB.workingDir, 'A1.json', 0, { filter: [{ author: dbB.author }] }) + ).resolves.toBeUndefined(); // merge commit is skipped, so jsonA1 does not exist. + + await expect( + readOldBlob(dbB.workingDir, 'A1.json', 0, { filter: [{ author: dbA.author }] }) + ).resolves.toEqual({ + oid: putResultA1.fileOid, + blob: utf8encode(toSortedJSONString(jsonA1internal)), + }); + + await destroyDBs([dbA, dbB]); + }); +}); \ No newline at end of file From 18850c8483106428a9f09b50652a4910e181fb33 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 30 Jul 2021 12:58:41 +0900 Subject: [PATCH 092/297] test: move network test for task_queue under test/remote_base/ --- test/remote_base/task_queue.ts | 66 +++++++++++++++++++++++++++++++++ test/task_queue.test.ts | 67 ---------------------------------- 2 files changed, 66 insertions(+), 67 deletions(-) create mode 100644 test/remote_base/task_queue.ts diff --git a/test/remote_base/task_queue.ts b/test/remote_base/task_queue.ts new file mode 100644 index 00000000..42d17797 --- /dev/null +++ b/test/remote_base/task_queue.ts @@ -0,0 +1,66 @@ +const maybe = + process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN + ? describe + : describe.skip; + +maybe(' remote', () => { + const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') + ? process.env.GITDDB_GITHUB_USER_URL + : process.env.GITDDB_GITHUB_USER_URL + '/'; + const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; + + before(async () => { + await removeRemoteRepositories(reposPrefix); + }); + + it('increments statistics: push', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId); + + // The first push in open() + expect(dbA.taskQueue.currentStatistics().push).toBe(1); + + const jsonA1 = { _id: '1', name: 'fromA' }; + await dbA.put(jsonA1); + await syncA.tryPush(); + expect(dbA.taskQueue.currentStatistics().push).toBe(2); + + await destroyDBs([dbA]); + }); + + it('increments statistics: sync', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId); + + expect(dbA.taskQueue.currentStatistics().sync).toBe(0); + + await syncA.trySync(); + expect(dbA.taskQueue.currentStatistics().sync).toBe(1); + + await destroyDBs([dbA]); + }); + + it('clear() statistics', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId); + + await syncA.trySync(); + expect(dbA.taskQueue.currentStatistics()).toEqual({ + put: 0, + insert: 0, + update: 0, + delete: 0, + push: 1, + sync: 1, + cancel: 0, + }); + dbA.taskQueue.clear(); + expect(dbA.taskQueue.currentStatistics()).toEqual({ + put: 0, + insert: 0, + update: 0, + delete: 0, + push: 0, + sync: 0, + cancel: 0, + }); + await destroyDBs([dbA]); + }); +}); diff --git a/test/task_queue.test.ts b/test/task_queue.test.ts index caf78b25..b32463ca 100644 --- a/test/task_queue.test.ts +++ b/test/task_queue.test.ts @@ -432,70 +432,3 @@ describe('', () => { await gitDDB.destroy(); }); }); - -const maybe = - process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN - ? describe - : describe.skip; - -maybe(' remote', () => { - const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') - ? process.env.GITDDB_GITHUB_USER_URL - : process.env.GITDDB_GITHUB_USER_URL + '/'; - const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; - - before(async () => { - await removeRemoteRepositories(reposPrefix); - }); - - it('increments statistics: push', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId); - - // The first push in open() - expect(dbA.taskQueue.currentStatistics().push).toBe(1); - - const jsonA1 = { _id: '1', name: 'fromA' }; - await dbA.put(jsonA1); - await syncA.tryPush(); - expect(dbA.taskQueue.currentStatistics().push).toBe(2); - - await destroyDBs([dbA]); - }); - - it('increments statistics: sync', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId); - - expect(dbA.taskQueue.currentStatistics().sync).toBe(0); - - await syncA.trySync(); - expect(dbA.taskQueue.currentStatistics().sync).toBe(1); - - await destroyDBs([dbA]); - }); - - it('clear() statistics', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId); - - await syncA.trySync(); - expect(dbA.taskQueue.currentStatistics()).toEqual({ - put: 0, - insert: 0, - update: 0, - delete: 0, - push: 1, - sync: 1, - cancel: 0, - }); - dbA.taskQueue.clear(); - expect(dbA.taskQueue.currentStatistics()).toEqual({ - put: 0, - insert: 0, - update: 0, - delete: 0, - push: 0, - sync: 0, - cancel: 0, - }); - await destroyDBs([dbA]); - }); -}); From f5851086db0cccfd666adadbfbc56a926f795677 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 30 Jul 2021 14:48:08 +0900 Subject: [PATCH 093/297] test: add test for error in sync_trypush --- test/remote_base/sync_trypush.ts | 67 ++++++++++++++++++++++++++------ 1 file changed, 55 insertions(+), 12 deletions(-) diff --git a/test/remote_base/sync_trypush.ts b/test/remote_base/sync_trypush.ts index f6ffb40c..0618c2aa 100644 --- a/test/remote_base/sync_trypush.ts +++ b/test/remote_base/sync_trypush.ts @@ -13,6 +13,7 @@ * These tests create a new repository on GitHub if not exists. */ import expect from 'expect'; +import sinon from 'sinon'; import { compareWorkingDirAndBlobs, createDatabase, @@ -26,6 +27,7 @@ import { } from '../remote_utils'; import { ConnectionSettings, SyncResultCancel, SyncResultPush } from '../../src/types'; import { sleep } from '../../src/utils'; +import { RemoteEngine, RemoteErr } from '../../src/remote/remote_engine'; export const syncTryPushBase = ( connection: ConnectionSettings, @@ -38,6 +40,16 @@ export const syncTryPushBase = ( return `${reposPrefix}${idCounter++}`; }; + // Use sandbox to restore stub and spy in parallel mocha tests + let sandbox: sinon.SinonSandbox; + beforeEach(function () { + sandbox = sinon.createSandbox(); + }); + + afterEach(function () { + sandbox.restore(); + }); + before(async () => { await removeRemoteRepositories(reposPrefix); }); @@ -48,7 +60,7 @@ export const syncTryPushBase = ( * dbA : +jsonA1 * after : jsonA1 */ - it('changes one remote creation when pushes after one put()', async function () { + it('changes one remote insertion when pushes after one put()', async function () { const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { connection, }); @@ -60,7 +72,7 @@ export const syncTryPushBase = ( expect(syncResult.action).toBe('push'); if (syncResult.action !== 'push') { // Check discriminated union - return; + throw new Error('invalid result'); } expect(syncResult.commits).toMatchObject({ remote: getCommitInfo([putResult]), @@ -98,7 +110,7 @@ export const syncTryPushBase = ( expect(syncResult.action).toBe('push'); if (syncResult.action !== 'push') { // Check discriminated union - return; + throw new Error('invalid result'); } expect(syncResult.commits).toMatchObject({ @@ -135,7 +147,7 @@ export const syncTryPushBase = ( expect(syncResult.action).toBe('push'); if (syncResult.action !== 'push') { // Check discriminated union - return; + throw new Error('invalid result'); } expect(syncResult.commits).toMatchObject({ @@ -160,7 +172,7 @@ export const syncTryPushBase = ( * dbA : +jsonA2 * after : jsonA1 jsonA2 */ - it('changes one remote creation when pushes after put() another document', async function () { + it('changes one remote insertion when pushes after put() another document', async function () { const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { connection, }); @@ -175,7 +187,7 @@ export const syncTryPushBase = ( expect(syncResult.action).toBe('push'); if (syncResult.action !== 'push') { // Check discriminated union - return; + throw new Error('invalid result'); } expect(syncResult.commits).toMatchObject({ @@ -202,7 +214,7 @@ export const syncTryPushBase = ( * dbA : +jsonA1 +jsonA3 * after2: jsonA1 jsonA2 jsonA3 */ - it('changes two remote creations when pushes after put() two documents', async function () { + it('changes two remote insertions when pushes after put() two documents', async function () { const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { connection, }); @@ -216,7 +228,7 @@ export const syncTryPushBase = ( expect(syncResult.action).toBe('push'); if (syncResult.action !== 'push') { // Check discriminated union - return; + throw new Error('invalid result'); } expect(syncResult.commits).toMatchObject({ @@ -242,7 +254,7 @@ export const syncTryPushBase = ( * dbA : +jsonA1 jsonA2 * after : +jsonA1 jsonA2 */ - it('changes one remote creation and one remote update when pushes after put() updated document and another document', async function () { + it('changes one remote insertion and one remote update when pushes after put() updated document and another document', async function () { const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { connection, }); @@ -259,7 +271,7 @@ export const syncTryPushBase = ( expect(syncResult.action).toBe('push'); if (syncResult.action !== 'push') { // Check discriminated union - return; + throw new Error('invalid result'); } expect(syncResult.commits).toMatchObject({ @@ -300,7 +312,7 @@ export const syncTryPushBase = ( expect(syncResult1.action).toBe('push'); if (syncResult1.action !== 'push') { // Check discriminated union - return; + throw new Error('invalid result'); } expect(syncResult1.commits).toMatchObject({ @@ -340,7 +352,7 @@ export const syncTryPushBase = ( expect(syncResult1.action).toBe('push'); if (syncResult1.action !== 'push') { // Check discriminated union - return; + throw new Error('invalid result'); } expect(syncResult1.commits).toMatchObject({ @@ -386,5 +398,36 @@ export const syncTryPushBase = ( await destroyDBs([dbA]); }); + + it('pauses live sync after error', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, + live: true, + interval: 3000, + }); + expect(syncA.options.live).toBeTruthy(); + + dbA.put({ name: 'fromA' }); + + let error: Error | undefined; + syncA.on('error', (err: Error) => { + error = err; + }); + const stubPush = sandbox.stub(RemoteEngine[syncA.engine], 'push'); + stubPush.onFirstCall().throwsException(new RemoteErr.NetworkError('foo')); + + for (let i = 0; i < 10; i++) { + // eslint-disable-next-line no-await-in-loop + await sleep(1000); + if (error instanceof Error) { + break; + } + } + + expect(error).toBeInstanceOf(RemoteErr.NetworkError); + expect(syncA.options.live).toBeFalsy(); + + await destroyDBs([dbA]); + }); }); }; From 9418b0e15ba4b3870a2735767da084a5fae9c5e3 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 30 Jul 2021 16:17:33 +0900 Subject: [PATCH 094/297] test: add sync tests from sync_lifecycle --- test/remote_base/sync.ts | 31 + test/remote_base/sync_live.ts | 307 +++++ .../{sync_trysync.test.ts => sync_trysync.ts} | 0 test_intg/sync_lifecycle.test.ts | 1008 ----------------- 4 files changed, 338 insertions(+), 1008 deletions(-) create mode 100644 test/remote_base/sync_live.ts rename test/remote_base/{sync_trysync.test.ts => sync_trysync.ts} (100%) delete mode 100644 test_intg/sync_lifecycle.test.ts diff --git a/test/remote_base/sync.ts b/test/remote_base/sync.ts index 163cbdb1..87027275 100644 --- a/test/remote_base/sync.ts +++ b/test/remote_base/sync.ts @@ -772,6 +772,37 @@ export const syncBase = ( await gitDDB.destroy(); }); + + it('After dbA created remote repository, dbB clones it.', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); + + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + + await dbA.open(); + const jsonA1 = { _id: '1', name: 'fromA' }; + await dbA.put(jsonA1); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection, + }; + await dbA.sync(options); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir: localDir, + }); + await dbB.open(); + await dbB.sync(options); + + await expect(dbB.get(jsonA1._id)).resolves.toMatchObject(jsonA1); + + await destroyDBs([dbA, dbB]); + }); }); describe(' syncImpl()', () => { diff --git a/test/remote_base/sync_live.ts b/test/remote_base/sync_live.ts new file mode 100644 index 00000000..43a90ff3 --- /dev/null +++ b/test/remote_base/sync_live.ts @@ -0,0 +1,307 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +/** + * Test lifecycle of synchronization (open, sync, tryPush, trySync) + * by using GitHub Personal Access Token + * These tests create a new repository on GitHub if not exists. + */ +import path from 'path'; +import fs from 'fs-extra'; +import expect from 'expect'; +import sinon from 'sinon'; +import { Sync } from '../src/remote/sync'; +import { GitDocumentDB } from '../src/git_documentdb'; +import { RemoteOptions, SyncResultPush } from '../src/types'; +import { Err } from '../src/error'; +import { sleep } from '../src/utils'; +import { + destroyDBs, + getChangedFileInsert, + getChangedFileUpdate, + removeRemoteRepositories, +} from '../test/remote_utils'; +import { JSON_EXT, MINIMUM_SYNC_INTERVAL, NETWORK_RETRY } from '../src/const'; +import { pushWorker } from '../src/remote/push_worker'; +import { syncWorker } from '../src/remote/sync_worker'; +import { RemoteEngine } from '../src/remote/remote_engine'; + +// eslint-disable-next-line @typescript-eslint/no-var-requires +const pushWorker_module = require('../src/remote/push_worker'); +// eslint-disable-next-line @typescript-eslint/no-var-requires +const syncWorker_module = require('../src/remote/sync_worker'); + +const reposPrefix = 'test_sync_lifecycle___'; +const localDir = `./test_intg/database_sync_lifecycle`; + +let idCounter = 0; +const serialId = () => { + return `${reposPrefix}${idCounter++}`; +}; + +// Use sandbox to restore stub and spy in parallel mocha tests +let sandbox: sinon.SinonSandbox; +beforeEach(function () { + // @ts-ignore + console.log(`... ${this.currentTest.fullTitle()}`); + sandbox = sinon.createSandbox(); +}); + +afterEach(function () { + sandbox.restore(); +}); + +before(() => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + + fs.removeSync(path.resolve(localDir)); +}); + +after(() => { + // It may throw error due to memory leak with UnfetchedCommitExistsError + // fs.removeSync(path.resolve(localDir)); +}); + +// GITDDB_GITHUB_USER_URL: URL of your GitHub account +// e.g.) https://github.com/foo/ +const maybe = + process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN + ? describe + : describe.skip; + +// Test live +maybe(' Sync', () => { + const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') + ? process.env.GITDDB_GITHUB_USER_URL + : process.env.GITDDB_GITHUB_USER_URL + '/'; + const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; + + before(async () => { + await removeRemoteRepositories(reposPrefix); + }); + + /** + * Repetitive Sync (live) + */ + describe('Repetitive Sync (live)', () => { + it('starts and pushes after interval when called from open() with live option.', async () => { + const remoteURL = remoteURLBase + serialId(); + + const dbNameA = serialId(); + + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + const interval = MINIMUM_SYNC_INTERVAL; + const options: RemoteOptions = { + remoteUrl: remoteURL, + live: true, + syncDirection: 'both', + interval, + connection: { type: 'github', personalAccessToken: token }, + }; + await dbA.open(); + const syncA = await dbA.sync(options); + + const jsonA1 = { _id: '1', name: 'fromA' }; + await dbA.put(jsonA1); + + expect(syncA.options.live).toBeTruthy(); + expect(syncA.options.interval).toBe(interval); + + // Wait live sync() + while (dbA.taskQueue.currentStatistics().sync === 0) { + // eslint-disable-next-line no-await-in-loop + await sleep(500); + } + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir: localDir, + }); + await dbB.open(); + await dbB.sync(options); + await expect(dbB.get(jsonA1._id)).resolves.toMatchObject(jsonA1); + + await destroyDBs([dbA, dbB]); + }); + + it('stops by pause()', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); + + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + const interval = MINIMUM_SYNC_INTERVAL; + const options: RemoteOptions = { + remoteUrl: remoteURL, + live: true, + syncDirection: 'both', + interval, + connection: { type: 'github', personalAccessToken: token }, + }; + await dbA.open(); + const syncA = await dbA.sync(options); + + expect(syncA.options.live).toBeTruthy(); + const count = dbA.taskQueue.currentStatistics().sync; + syncA.pause(); + await sleep(interval * 2); + expect(syncA.options.live).toBeFalsy(); + expect(dbA.taskQueue.currentStatistics().sync).toBe(count); + + await destroyDBs([dbA]); + }); + + it('pause() and resume()', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); + + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + const interval = MINIMUM_SYNC_INTERVAL; + const options: RemoteOptions = { + remoteUrl: remoteURL, + live: true, + syncDirection: 'both', + interval, + connection: { type: 'github', personalAccessToken: token }, + }; + await dbA.open(); + const syncA = await dbA.sync(options); + + expect(syncA.options.live).toBeTruthy(); + const count = dbA.taskQueue.currentStatistics().sync; + expect(syncA.pause()).toBeTruthy(); + expect(syncA.pause()).toBeFalsy(); // ignored + + await sleep(interval * 2); + expect(syncA.options.live).toBeFalsy(); + expect(dbA.taskQueue.currentStatistics().sync).toBe(count); + + expect(syncA.resume()).toBeTruthy(); + expect(syncA.resume()).toBeFalsy(); // ignored + await sleep(interval * 2); + expect(syncA.options.live).toBeTruthy(); + expect(dbA.taskQueue.currentStatistics().sync).toBeGreaterThan(count); + + await destroyDBs([dbA]); + }); + + it('stops by gitDDB.close()', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); + + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + const interval = MINIMUM_SYNC_INTERVAL; + const options: RemoteOptions = { + remoteUrl: remoteURL, + live: true, + syncDirection: 'both', + interval, + connection: { type: 'github', personalAccessToken: token }, + }; + await dbA.open(); + const syncA = await dbA.sync(options); + + expect(syncA.options.live).toBeTruthy(); + const count = dbA.taskQueue.currentStatistics().sync; + await dbA.close(); + + syncA.resume(); // resume() must be ignored after close(); + + await sleep(interval * 2); + expect(syncA.options.live).toBeFalsy(); + expect(dbA.taskQueue.currentStatistics().sync).toBe(count); + + await destroyDBs([dbA]); + }); + + it('changes interval when resume() is called with new interval.', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); + + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + const interval = MINIMUM_SYNC_INTERVAL; + const options: RemoteOptions = { + remoteUrl: remoteURL, + live: true, + syncDirection: 'both', + interval, + connection: { type: 'github', personalAccessToken: token }, + }; + await dbA.open(); + const syncA = await dbA.sync(options); + + expect(syncA.options.interval).toBe(interval); + + const jsonA1 = { _id: '1', name: 'fromA' }; + await dbA.put(jsonA1); + // Wait live sync() + while (dbA.taskQueue.currentStatistics().sync === 0) { + // eslint-disable-next-line no-await-in-loop + await sleep(500); + } + syncA.pause(); + + const jsonA2 = { _id: '2', name: 'fromA' }; + await dbA.put(jsonA2); + + const currentCount = dbA.taskQueue.currentStatistics().sync; + // Change interval + syncA.resume({ + interval: interval * 3, + }); + expect(syncA.options.interval).toBe(interval * 3); + await sleep(interval); + // Check count before next sync() + expect(dbA.taskQueue.currentStatistics().sync).toBe(currentCount); + + await destroyDBs([dbA]); + }); + + it('repeats trySync() automatically.', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); + + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + const interval = MINIMUM_SYNC_INTERVAL; + const options: RemoteOptions = { + remoteUrl: remoteURL, + live: true, + syncDirection: 'both', + interval, + connection: { type: 'github', personalAccessToken: token }, + }; + await dbA.open(); + const syncA = await dbA.sync(options); + + await sleep(interval * 5); + expect(dbA.taskQueue.currentStatistics().sync).toBeGreaterThanOrEqual(3); + + await destroyDBs([dbA]); + }); + }); +}); diff --git a/test/remote_base/sync_trysync.test.ts b/test/remote_base/sync_trysync.ts similarity index 100% rename from test/remote_base/sync_trysync.test.ts rename to test/remote_base/sync_trysync.ts diff --git a/test_intg/sync_lifecycle.test.ts b/test_intg/sync_lifecycle.test.ts deleted file mode 100644 index c31c1319..00000000 --- a/test_intg/sync_lifecycle.test.ts +++ /dev/null @@ -1,1008 +0,0 @@ -/* eslint-disable @typescript-eslint/naming-convention */ -/** - * GitDocumentDB - * Copyright (c) Hidekazu Kubota - * - * This source code is licensed under the Mozilla Public License Version 2.0 - * found in the LICENSE file in the root directory of this source tree. - */ - -/** - * Test lifecycle of synchronization (open, sync, tryPush, trySync) - * by using GitHub Personal Access Token - * These tests create a new repository on GitHub if not exists. - */ -import path from 'path'; -import fs from 'fs-extra'; -import expect from 'expect'; -import sinon from 'sinon'; -import { Sync } from '../src/remote/sync'; -import { GitDocumentDB } from '../src/git_documentdb'; -import { RemoteOptions, SyncResultPush } from '../src/types'; -import { Err } from '../src/error'; -import { sleep } from '../src/utils'; -import { - destroyDBs, - getChangedFileInsert, - getChangedFileUpdate, - removeRemoteRepositories, -} from '../test/remote_utils'; -import { JSON_EXT, MINIMUM_SYNC_INTERVAL, NETWORK_RETRY } from '../src/const'; -import { pushWorker } from '../src/remote/push_worker'; -import { syncWorker } from '../src/remote/sync_worker'; -import { RemoteEngine } from '../src/remote/remote_engine'; - -// eslint-disable-next-line @typescript-eslint/no-var-requires -const pushWorker_module = require('../src/remote/push_worker'); -// eslint-disable-next-line @typescript-eslint/no-var-requires -const syncWorker_module = require('../src/remote/sync_worker'); - -const reposPrefix = 'test_sync_lifecycle___'; -const localDir = `./test_intg/database_sync_lifecycle`; - -let idCounter = 0; -const serialId = () => { - return `${reposPrefix}${idCounter++}`; -}; - -// Use sandbox to restore stub and spy in parallel mocha tests -let sandbox: sinon.SinonSandbox; -beforeEach(function () { - // @ts-ignore - console.log(`... ${this.currentTest.fullTitle()}`); - sandbox = sinon.createSandbox(); -}); - -afterEach(function () { - sandbox.restore(); -}); - -before(() => { - // eslint-disable-next-line @typescript-eslint/no-var-requires - GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); - - fs.removeSync(path.resolve(localDir)); -}); - -after(() => { - // It may throw error due to memory leak with UnfetchedCommitExistsError - // fs.removeSync(path.resolve(localDir)); -}); - -// GITDDB_GITHUB_USER_URL: URL of your GitHub account -// e.g.) https://github.com/foo/ -const maybe = - process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN - ? describe - : describe.skip; - -// Test lifecycle of Sync (open, sync, tryPush, trySync) -maybe('intg Sync', () => { - const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') - ? process.env.GITDDB_GITHUB_USER_URL - : process.env.GITDDB_GITHUB_USER_URL + '/'; - const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; - - before(async () => { - await removeRemoteRepositories(reposPrefix); - }); - - /** - * Initialize synchronization by open() with remoteURL - * Initialize means creating local and remote repositories by using a remoteUrl - */ - describe('initialized by open():', () => { - it('getSync() returns an instance of Sync.', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbNameA = serialId(); - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, - }); - const options: RemoteOptions = { - remoteUrl: remoteURL, - connection: { type: 'github', personalAccessToken: token }, - }; - await dbA.open(); - const syncA = await dbA.sync(options); - expect(syncA.remoteURL).toBe(remoteURL); - destroyDBs([dbA]); - }); - - it('unregisterRemote() removes an instance of Sync.', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbNameA = serialId(); - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, - }); - const options: RemoteOptions = { - remoteUrl: remoteURL, - connection: { type: 'github', personalAccessToken: token }, - }; - await dbA.open(); - await dbA.sync(options); - dbA.removeSync(remoteURL); - expect(dbA.getSync(remoteURL)).toBeUndefined(); - destroyDBs([dbA]); - }); - - it.skip('getRemoteURLs() returns sync', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbNameA = serialId(); - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, - logLevel: 'trace', - }); - const options: RemoteOptions = { - remoteUrl: remoteURL, - connection: { type: 'github', personalAccessToken: token }, - }; - await dbA.open(); - await dbA.sync(options); - const remoteURL2 = remoteURLBase + serialId(); - const options2: RemoteOptions = { - remoteUrl: remoteURL2, - connection: { type: 'github', personalAccessToken: token }, - }; - await dbA.sync(options2); - expect(dbA.getRemoteURLs()).toEqual([remoteURL, remoteURL2]); - destroyDBs([dbA]); - }); - - /** - * Basics: A is empty, creates remote, puts data; B is empty, clones the remote - */ - describe('After dbA created remote repository, dbB clones it.', () => { - it('dbA and dbB have the same document.', async () => { - const remoteURL = remoteURLBase + serialId(); - - const dbNameA = serialId(); - - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, - }); - const options: RemoteOptions = { - remoteUrl: remoteURL, - connection: { type: 'github', personalAccessToken: token }, - }; - await dbA.open(); - const syncA = await dbA.sync(options); - const jsonA1 = { _id: '1', name: 'fromA' }; - await dbA.put(jsonA1); - await syncA.tryPush(); - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir: localDir, - }); - await dbB.open(); - await dbB.sync(options); - - await expect(dbB.get(jsonA1._id)).resolves.toMatchObject(jsonA1); - - await destroyDBs([dbA, dbB]); - }); - - it('Race condition of two tryPush() calls throws UnfetchedCommitExistsError.', async () => { - const remoteURL = remoteURLBase + serialId(); - - const dbNameA = serialId(); - - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, - }); - const options: RemoteOptions = { - remoteUrl: remoteURL, - connection: { type: 'github', personalAccessToken: token }, - }; - await dbA.open(); - const syncA = await dbA.sync(options); - const jsonA1 = { _id: '1', name: 'fromA' }; - await dbA.put(jsonA1); - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir: localDir, - }); - await dbB.open(); - const syncB = await dbB.sync(options); - const jsonB1 = { _id: '1', name: 'fromB' }; - await dbB.put(jsonB1); - - await expect(Promise.all([syncA.tryPush(), syncB.tryPush()])).rejects.toThrowError( - RemoteEngine[syncA.engine].Err.UnfetchedCommitExistsError - ); - - await destroyDBs([dbA, dbB]); - }); - - it('Ordered condition of two tryPush() calls throws UnfetchedCommitExistsError.', async () => { - const remoteURL = remoteURLBase + serialId(); - - const dbNameA = serialId(); - - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, - }); - const options: RemoteOptions = { - remoteUrl: remoteURL, - connection: { type: 'github', personalAccessToken: token }, - }; - await dbA.open(); - const syncA = await dbA.sync(options); - const jsonA1 = { _id: '1', name: 'fromA' }; - await dbA.put(jsonA1); - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir: localDir, - }); - await dbB.open(); - const syncB = await dbB.sync(options); - const jsonB1 = { _id: '1', name: 'fromB' }; - await dbB.put(jsonB1); - - await syncA.tryPush(); - await expect(syncB.tryPush()).rejects.toThrowError( - RemoteEngine[syncB.engine].Err.UnfetchedCommitExistsError - ); - - await destroyDBs([dbA, dbB]); - }); - - it('Updating the same document results [resolve conflict and push] action.', async () => { - const remoteURL = remoteURLBase + serialId(); - - const dbNameA = serialId(); - - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, - }); - const options: RemoteOptions = { - remoteUrl: remoteURL, - connection: { type: 'github', personalAccessToken: token }, - }; - await dbA.open(); - const syncA = await dbA.sync(options); - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir: localDir, - }); - await dbB.open(); - const syncB = await dbB.sync(options); - - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResultA1 = await dbA.put(jsonA1); - await syncA.tryPush(); - - // The same id - const jsonB1 = { _id: '1', name: 'fromB' }; - const putResultB1 = await dbB.put(jsonB1); - - await expect(syncB.trySync()).resolves.toMatchObject({ - action: 'resolve conflicts and push', - changes: { - local: [], - remote: [getChangedFileUpdate(jsonA1, putResultA1, jsonB1, putResultB1)], - }, - conflicts: [ - { - fatDoc: { - _id: jsonB1._id, - name: jsonB1._id + JSON_EXT, - fileOid: putResultB1.fileOid, - type: 'json', - doc: jsonB1, - }, - operation: 'insert-merge', - strategy: 'ours-diff', - }, - ], - }); - - await destroyDBs([dbA, dbB]); - }); - }); - - /** - * Repetitive Sync (live) - */ - describe('Repetitive Sync (live)', () => { - it('starts and pushes after interval when called from open() with live option.', async () => { - const remoteURL = remoteURLBase + serialId(); - - const dbNameA = serialId(); - - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, - }); - const interval = MINIMUM_SYNC_INTERVAL; - const options: RemoteOptions = { - remoteUrl: remoteURL, - live: true, - syncDirection: 'both', - interval, - connection: { type: 'github', personalAccessToken: token }, - }; - await dbA.open(); - const syncA = await dbA.sync(options); - - const jsonA1 = { _id: '1', name: 'fromA' }; - await dbA.put(jsonA1); - - expect(syncA.options.live).toBeTruthy(); - expect(syncA.options.interval).toBe(interval); - - // Wait live sync() - while (dbA.taskQueue.currentStatistics().sync === 0) { - // eslint-disable-next-line no-await-in-loop - await sleep(500); - } - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir: localDir, - }); - await dbB.open(); - await dbB.sync(options); - await expect(dbB.get(jsonA1._id)).resolves.toMatchObject(jsonA1); - - await destroyDBs([dbA, dbB]); - }); - - it('stops by pause()', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbNameA = serialId(); - - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, - }); - const interval = MINIMUM_SYNC_INTERVAL; - const options: RemoteOptions = { - remoteUrl: remoteURL, - live: true, - syncDirection: 'both', - interval, - connection: { type: 'github', personalAccessToken: token }, - }; - await dbA.open(); - const syncA = await dbA.sync(options); - - expect(syncA.options.live).toBeTruthy(); - const count = dbA.taskQueue.currentStatistics().sync; - syncA.pause(); - await sleep(interval * 2); - expect(syncA.options.live).toBeFalsy(); - expect(dbA.taskQueue.currentStatistics().sync).toBe(count); - - await destroyDBs([dbA]); - }); - - it('pause() and resume()', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbNameA = serialId(); - - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, - }); - const interval = MINIMUM_SYNC_INTERVAL; - const options: RemoteOptions = { - remoteUrl: remoteURL, - live: true, - syncDirection: 'both', - interval, - connection: { type: 'github', personalAccessToken: token }, - }; - await dbA.open(); - const syncA = await dbA.sync(options); - - expect(syncA.options.live).toBeTruthy(); - const count = dbA.taskQueue.currentStatistics().sync; - expect(syncA.pause()).toBeTruthy(); - expect(syncA.pause()).toBeFalsy(); // ignored - - await sleep(interval * 2); - expect(syncA.options.live).toBeFalsy(); - expect(dbA.taskQueue.currentStatistics().sync).toBe(count); - - expect(syncA.resume()).toBeTruthy(); - expect(syncA.resume()).toBeFalsy(); // ignored - await sleep(interval * 2); - expect(syncA.options.live).toBeTruthy(); - expect(dbA.taskQueue.currentStatistics().sync).toBeGreaterThan(count); - - await destroyDBs([dbA]); - }); - - it('stops by gitDDB.close()', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbNameA = serialId(); - - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, - }); - const interval = MINIMUM_SYNC_INTERVAL; - const options: RemoteOptions = { - remoteUrl: remoteURL, - live: true, - syncDirection: 'both', - interval, - connection: { type: 'github', personalAccessToken: token }, - }; - await dbA.open(); - const syncA = await dbA.sync(options); - - expect(syncA.options.live).toBeTruthy(); - const count = dbA.taskQueue.currentStatistics().sync; - await dbA.close(); - - syncA.resume(); // resume() must be ignored after close(); - - await sleep(interval * 2); - expect(syncA.options.live).toBeFalsy(); - expect(dbA.taskQueue.currentStatistics().sync).toBe(count); - - await destroyDBs([dbA]); - }); - - it('changes interval when resume() is called with new interval.', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbNameA = serialId(); - - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, - }); - const interval = MINIMUM_SYNC_INTERVAL; - const options: RemoteOptions = { - remoteUrl: remoteURL, - live: true, - syncDirection: 'both', - interval, - connection: { type: 'github', personalAccessToken: token }, - }; - await dbA.open(); - const syncA = await dbA.sync(options); - - expect(syncA.options.interval).toBe(interval); - - const jsonA1 = { _id: '1', name: 'fromA' }; - await dbA.put(jsonA1); - // Wait live sync() - while (dbA.taskQueue.currentStatistics().sync === 0) { - // eslint-disable-next-line no-await-in-loop - await sleep(500); - } - syncA.pause(); - - const jsonA2 = { _id: '2', name: 'fromA' }; - await dbA.put(jsonA2); - - const currentCount = dbA.taskQueue.currentStatistics().sync; - // Change interval - syncA.resume({ - interval: interval * 3, - }); - expect(syncA.options.interval).toBe(interval * 3); - await sleep(interval); - // Check count before next sync() - expect(dbA.taskQueue.currentStatistics().sync).toBe(currentCount); - - await destroyDBs([dbA]); - }); - - it('repeats trySync() automatically.', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbNameA = serialId(); - - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, - }); - const interval = MINIMUM_SYNC_INTERVAL; - const options: RemoteOptions = { - remoteUrl: remoteURL, - live: true, - syncDirection: 'both', - interval, - connection: { type: 'github', personalAccessToken: token }, - }; - await dbA.open(); - const syncA = await dbA.sync(options); - - await sleep(interval * 5); - expect(dbA.taskQueue.currentStatistics().sync).toBeGreaterThanOrEqual(3); - - await destroyDBs([dbA]); - }); - }); - - /** - * Retry sync - */ - describe('Failed sync', () => { - it('retries tryPush() in init() after connection errors, and fails.', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbNameA = serialId(); - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, - }); - await dbA.open(); - - const options: RemoteOptions = { - remoteUrl: remoteURL, - syncDirection: 'push', - connection: { type: 'github', personalAccessToken: token }, - }; - - const sync = new Sync(dbA, options); - const stubNet = sandbox.stub(sync, 'canNetworkConnection'); - stubNet.resolves(false); - - const stubPush = sandbox.stub(pushWorker_module, 'pushWorker'); - stubPush.rejects(); - - await expect(sync.init()).rejects.toThrowError(); - - expect(stubPush.callCount).toBe(NETWORK_RETRY + 1); - - await destroyDBs([dbA]); - }); - - it('retries tryPush() in init() after connection errors, and succeeds.', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbNameA = serialId(); - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, - }); - await dbA.open(); - - const options: RemoteOptions = { - remoteUrl: remoteURL, - syncDirection: 'push', - connection: { type: 'github', personalAccessToken: token }, - }; - - const sync = new Sync(dbA, options); - const stubNet = sandbox.stub(sync, 'canNetworkConnection'); - stubNet.resolves(false); - - const stubPush = sandbox.stub(pushWorker_module, 'pushWorker'); - stubPush.onFirstCall().rejects(); - const syncResultPush: SyncResultPush = { - action: 'push', - changes: { - remote: [], - }, - }; - - // Call pushWorker which is not spied by Sinon - stubPush.onSecondCall().callsFake(async () => { - stubPush.restore(); - return await pushWorker(dbA, sync, { - label: 'sync', - taskId: 'myTaskId', - }); - }); - const syncResult = await sync.init(); - expect(syncResult).toEqual(syncResultPush); - - expect(stubPush.callCount).toBe(2); - - await destroyDBs([dbA]); - }); - - it('does not retry tryPush() in init() after error except connection errors and resolvable errors.', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbNameA = serialId(); - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, - }); - await dbA.open(); - - const options: RemoteOptions = { - remoteUrl: remoteURL, - syncDirection: 'push', - connection: { type: 'github', personalAccessToken: token }, - }; - - const sync = new Sync(dbA, options); - - const stubPush = sandbox.stub(pushWorker_module, 'pushWorker'); - stubPush.rejects(); - - // Call pushWorker which is not spied by Sinon - stubPush.onSecondCall().callsFake(async () => { - stubPush.restore(); - return await pushWorker(dbA, sync, { - label: 'sync', - taskId: 'myTaskId', - }); - }); - - await expect(sync.init()).rejects.toThrowError(Err.PushWorkerError); - - expect(stubPush.callCount).toBe(1); - - await destroyDBs([dbA]); - }); - - it('retries trySync() in init() after connection errors, and fails.', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbNameA = serialId(); - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, - }); - await dbA.open(); - - const options: RemoteOptions = { - remoteUrl: remoteURL, - syncDirection: 'both', - connection: { type: 'github', personalAccessToken: token }, - }; - - const sync = await dbA.sync(options); - - const stubNet = sandbox.stub(sync, 'canNetworkConnection'); - stubNet.resolves(false); - - const stubSync = sandbox.stub(syncWorker_module, 'syncWorker'); - stubSync.rejects(); - - // sync has already been initialized, so will run trySync() - await expect(sync.init()).rejects.toThrowError(); - - expect(stubSync.callCount).toBe(NETWORK_RETRY + 1); - - await destroyDBs([dbA]); - }); - - it('retries trySync() in init() after connection errors, and succeeds.', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbNameA = serialId(); - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, - }); - await dbA.open(); - - const options: RemoteOptions = { - remoteUrl: remoteURL, - syncDirection: 'both', - connection: { type: 'github', personalAccessToken: token }, - }; - - const sync = await dbA.sync(options); - - const stubNet = sandbox.stub(sync, 'canNetworkConnection'); - stubNet.resolves(false); - - const stubSync = sandbox.stub(syncWorker_module, 'syncWorker'); - stubSync.onFirstCall().rejects(); - - // Call pushWorker which is not spied by Sinon - stubSync.onSecondCall().callsFake(async () => { - stubSync.restore(); - return await syncWorker(dbA, sync, { - label: 'sync', - taskId: 'myTaskId', - }); - }); - - const jsonA1 = { _id: '1', name: 'profile01' }; - const putResult = await dbA.put(jsonA1); - const syncResultPush: SyncResultPush = { - action: 'push', - changes: { - remote: [getChangedFileInsert(jsonA1, putResult)], - }, - }; - - await expect(sync.init()).resolves.toEqual(syncResultPush); - - expect(stubSync.callCount).toBe(2); - - await destroyDBs([dbA]); - }); - - it('retries trySync() in init() after resolvable errors, and succeeds.', async () => { - /** - * After race condition of trySync() throws Error, - * db retries trySync() and resolves the problems automatically. - */ - const remoteURL = remoteURLBase + serialId(); - - const dbNameA = serialId(); - - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, - }); - // Set retry interval to 0ms - const options: RemoteOptions = { - remoteUrl: remoteURL, - connection: { type: 'github', personalAccessToken: token }, - retryInterval: 0, - }; - await dbA.open(); - const syncA = await dbA.sync(options); - const jsonA1 = { _id: '1', name: 'fromA' }; - await dbA.put(jsonA1); - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir: localDir, - }); - await dbB.open(); - const syncB = await dbB.sync(options); - const jsonB1 = { _id: '2', name: 'fromB' }; - await dbB.put(jsonB1); - - let errorOnA = false; - let errorOnB = false; - syncA.on('error', () => { - errorOnA = true; - }); - syncB.on('error', () => { - errorOnB = true; - }); - - const spySync = sandbox.spy(syncWorker_module, 'syncWorker'); - - // Either dbA or dbB will get UnfetchedCommitExistsError - // and retry automatically. - const [resultA, resultB] = await Promise.all([syncA.trySync(), syncB.trySync()]); - - const nextResultA = await syncA.trySync(); - const nextResultB = await syncB.trySync(); - - if (errorOnA) { - expect(resultA.action).toBe('merge and push'); - expect(nextResultA.action).toBe('nop'); - expect(resultB.action).toBe('push'); - expect(nextResultB.action).toBe('fast-forward merge'); - } - else { - expect(resultA.action).toBe('push'); - expect(nextResultA.action).toBe('fast-forward merge'); - expect(resultB.action).toBe('merge and push'); - expect(nextResultB.action).toBe('nop'); - } - expect(spySync.callCount).toBe(5); - - await destroyDBs([dbA, dbB]); - }); - - it('does not retry trySync() in init() after error except connection errors and resolvable errors', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbNameA = serialId(); - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, - }); - await dbA.open(); - - const options: RemoteOptions = { - remoteUrl: remoteURL, - syncDirection: 'both', - connection: { type: 'github', personalAccessToken: token }, - }; - - const sync = await dbA.sync(options); - - const stubSync = sandbox.stub(syncWorker_module, 'syncWorker'); - stubSync.rejects(); - - await expect(sync.init()).rejects.toThrowError(); - - expect(stubSync.callCount).toBe(1); - - await destroyDBs([dbA]); - }); - - it('does not occur when retry option is 0', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbNameA = serialId(); - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, - }); - await dbA.open(); - - const options: RemoteOptions = { - remoteUrl: remoteURL, - syncDirection: 'push', - retryInterval: 0, - retry: 0, - connection: { type: 'github', personalAccessToken: token }, - }; - - const sync = new Sync(dbA, options); - const stubNet = sandbox.stub(sync, 'canNetworkConnection'); - stubNet.resolves(false); - - const stubPush = sandbox.stub(pushWorker_module, 'pushWorker'); - stubPush.rejects(); - - await expect(sync.init()).rejects.toThrowError(); - - expect(stubPush.callCount).toBe(1); - - await destroyDBs([dbA]); - }); - - it('retries every retry interval', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbNameA = serialId(); - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, - }); - await dbA.open(); - - const interval = 100000; - const retryInterval = 5000; - - const options: RemoteOptions = { - remoteUrl: remoteURL, - syncDirection: 'push', - interval, - retryInterval, - retry: 2, - connection: { type: 'github', personalAccessToken: token }, - }; - - const sync = new Sync(dbA, options); - const stubNet = sandbox.stub(sync, 'canNetworkConnection'); - stubNet.resolves(false); - - const stubPush = sandbox.stub(pushWorker_module, 'pushWorker'); - stubPush.rejects(); - - sync.init().catch(() => {}); - - await sleep(retryInterval - 500); - expect(stubPush.callCount).toBe(1); - await sleep(retryInterval); - expect(stubPush.callCount).toBe(2); - await sleep(retryInterval); - expect(stubPush.callCount).toBe(3); - await sleep(retryInterval); - - await destroyDBs([dbA]); - }); - }); - }); - - /** - * Initialize synchronization by sync() with remoteURL - * Initialize means creating local and remote repositories by using a remoteUrl - */ - describe('initialized by sync():', () => { - it('throws RemoteAlreadyRegisteredError when sync() the same url twice.', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbNameA = serialId(); - - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, - }); - - await dbA.open(); - - const options: RemoteOptions = { - remoteUrl: remoteURL, - connection: { type: 'github', personalAccessToken: token }, - }; - const syncA = await dbA.sync(options); - await expect(dbA.sync(options)).rejects.toThrowError( - Err.RemoteAlreadyRegisteredError - ); - dbA.destroy(); - }); - - it('After dbA#sync() created remote repository, dbB#open() clones it.', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbNameA = serialId(); - - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, - }); - - await dbA.open(); - const options: RemoteOptions = { - remoteUrl: remoteURL, - syncDirection: 'both', - connection: { type: 'github', personalAccessToken: token }, - }; - const jsonA1 = { _id: '1', name: 'fromA' }; - await dbA.put(jsonA1); - - const syncA = await dbA.sync(options); - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir: localDir, - }); - await dbB.open(); - await dbB.sync(options); - await expect(dbB.get(jsonA1._id)).resolves.toMatchObject(jsonA1); - - await destroyDBs([dbA, dbB]); - }); - - it('After dbA#sync() created remote repository, dbB#open() clones it, close(), open() again with no remote, following sync().', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbNameA = serialId(); - - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, - }); - - await dbA.open(); - const options: RemoteOptions = { - remoteUrl: remoteURL, - live: true, - interval: MINIMUM_SYNC_INTERVAL, - syncDirection: 'both', - connection: { type: 'github', personalAccessToken: token }, - }; - const jsonA1 = { _id: '1', name: 'fromA' }; - await dbA.put(jsonA1); - - const syncA = await dbA.sync(options); - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir: localDir, - }); - await dbB.open(); - await dbB.sync(options); - await dbB.close(); - - await dbB.open(); - const jsonB1 = { _id: '1', name: 'fromB' }; - await dbB.put(jsonB1); - - await dbB.sync(options); - await expect(dbB.get(jsonB1._id)).resolves.toMatchObject(jsonB1); - - // Wait next sync() - const count = dbA.taskQueue.currentStatistics().sync; - while (dbA.taskQueue.currentStatistics().sync === count) { - // eslint-disable-next-line no-await-in-loop - await sleep(500); - } - await expect(dbA.get(jsonA1._id)).resolves.toMatchObject(jsonB1); - - await destroyDBs([dbA, dbB]); - }); - }); - - it.skip('Multiple Sync object'); -}); From f8c31fa3be162dbc4f9c384f9d2b466bc8b94b10 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 30 Jul 2021 16:32:40 +0900 Subject: [PATCH 095/297] test: add sync_trypush tests from sync_lifesycle --- test/remote_base/sync_trypush.ts | 82 +++++++++++++++++++++++- test/remote_nodegit/sync_trypush.test.ts | 2 +- 2 files changed, 81 insertions(+), 3 deletions(-) diff --git a/test/remote_base/sync_trypush.ts b/test/remote_base/sync_trypush.ts index 0618c2aa..b94d0764 100644 --- a/test/remote_base/sync_trypush.ts +++ b/test/remote_base/sync_trypush.ts @@ -14,6 +14,7 @@ */ import expect from 'expect'; import sinon from 'sinon'; +import { GitDocumentDB } from '../../src/git_documentdb'; import { compareWorkingDirAndBlobs, createDatabase, @@ -25,7 +26,12 @@ import { getWorkingDirDocs, removeRemoteRepositories, } from '../remote_utils'; -import { ConnectionSettings, SyncResultCancel, SyncResultPush } from '../../src/types'; +import { + ConnectionSettings, + RemoteOptions, + SyncResultCancel, + SyncResultPush, +} from '../../src/types'; import { sleep } from '../../src/utils'; import { RemoteEngine, RemoteErr } from '../../src/remote/remote_engine'; @@ -399,11 +405,12 @@ export const syncTryPushBase = ( await destroyDBs([dbA]); }); - it('pauses live sync after error', async () => { + it('pauses live push after error', async () => { const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { connection, live: true, interval: 3000, + syncDirection: 'push', }); expect(syncA.options.live).toBeTruthy(); @@ -429,5 +436,76 @@ export const syncTryPushBase = ( await destroyDBs([dbA]); }); + + it('Race condition of two tryPush() calls throws UnfetchedCommitExistsError.', async () => { + const remoteURL = remoteURLBase + serialId(); + + const dbNameA = serialId(); + + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection, + }; + await dbA.open(); + const syncA = await dbA.sync(options); + const jsonA1 = { _id: '1', name: 'fromA' }; + await dbA.put(jsonA1); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir: localDir, + }); + await dbB.open(); + const syncB = await dbB.sync(options); + const jsonB1 = { _id: '1', name: 'fromB' }; + await dbB.put(jsonB1); + + await expect(Promise.all([syncA.tryPush(), syncB.tryPush()])).rejects.toThrowError( + RemoteErr.UnfetchedCommitExistsError + ); + + await destroyDBs([dbA, dbB]); + }); + + it('Ordered condition of two tryPush() calls throws UnfetchedCommitExistsError.', async () => { + const remoteURL = remoteURLBase + serialId(); + + const dbNameA = serialId(); + + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection, + }; + await dbA.open(); + const syncA = await dbA.sync(options); + const jsonA1 = { _id: '1', name: 'fromA' }; + await dbA.put(jsonA1); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir: localDir, + }); + await dbB.open(); + const syncB = await dbB.sync(options); + const jsonB1 = { _id: '1', name: 'fromB' }; + await dbB.put(jsonB1); + + await syncA.tryPush(); + await expect(syncB.tryPush()).rejects.toThrowError( + RemoteErr.UnfetchedCommitExistsError + ); + + await destroyDBs([dbA, dbB]); + }); }); }; diff --git a/test/remote_nodegit/sync_trypush.test.ts b/test/remote_nodegit/sync_trypush.test.ts index aaf00fdb..a83287ab 100644 --- a/test/remote_nodegit/sync_trypush.test.ts +++ b/test/remote_nodegit/sync_trypush.test.ts @@ -8,7 +8,7 @@ */ /** - * Test push + * Test tryPush * by using GitHub Personal Access Token * These tests create a new repository on GitHub if not exists. */ From 390a1b854ac864eb16c07bf8a8bb3f27f7484c96 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 30 Jul 2021 16:33:27 +0900 Subject: [PATCH 096/297] test: add git_documentdb remote test from sync_lifecycle --- test/remote_base/git_documentdb.ts | 89 ++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 test/remote_base/git_documentdb.ts diff --git a/test/remote_base/git_documentdb.ts b/test/remote_base/git_documentdb.ts new file mode 100644 index 00000000..29d6ae67 --- /dev/null +++ b/test/remote_base/git_documentdb.ts @@ -0,0 +1,89 @@ +/** + * Initialize synchronization by open() with remoteURL + * Initialize means creating local and remote repositories by using a remoteUrl + */ + describe('is initialized from GitDocumentDB():', () => { + it('sync() returns an instance of Sync.', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection: { type: 'github', personalAccessToken: token }, + }; + await dbA.open(); + const syncA = await dbA.sync(options); + expect(syncA.remoteURL).toBe(remoteURL); + destroyDBs([dbA]); + }); + + it('unregisterRemote() removes an instance of Sync.', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection: { type: 'github', personalAccessToken: token }, + }; + await dbA.open(); + await dbA.sync(options); + dbA.removeSync(remoteURL); + expect(dbA.getSync(remoteURL)).toBeUndefined(); + destroyDBs([dbA]); + }); + + it('throws RemoteAlreadyRegisteredError when sync() the same url twice.', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); + + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + + await dbA.open(); + + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection: { type: 'github', personalAccessToken: token }, + }; + const syncA = await dbA.sync(options); + await expect(dbA.sync(options)).rejects.toThrowError( + Err.RemoteAlreadyRegisteredError + ); + dbA.destroy(); + }); + + + it.skip('getRemoteURLs() returns sync', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + logLevel: 'trace', + }); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection: { type: 'github', personalAccessToken: token }, + }; + await dbA.open(); + await dbA.sync(options); + const remoteURL2 = remoteURLBase + serialId(); + const options2: RemoteOptions = { + remoteUrl: remoteURL2, + connection: { type: 'github', personalAccessToken: token }, + }; + await dbA.sync(options2); + expect(dbA.getRemoteURLs()).toEqual([remoteURL, remoteURL2]); + destroyDBs([dbA]); + }); + + it.skip('Multiple Sync object'); +}); From dff40c6f5a80628e129f7f773b2ca7ad177ad719 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 30 Jul 2021 18:28:04 +0900 Subject: [PATCH 097/297] test: pass sync_trysync in remote_nodegit --- test/remote_base/sync_trysync.ts | 1552 +++++++++++++--------- test/remote_nodegit/sync_trysync.test.ts | 61 + 2 files changed, 953 insertions(+), 660 deletions(-) create mode 100644 test/remote_nodegit/sync_trysync.test.ts diff --git a/test/remote_base/sync_trysync.ts b/test/remote_base/sync_trysync.ts index f7a996af..2da5326e 100644 --- a/test/remote_base/sync_trysync.ts +++ b/test/remote_base/sync_trysync.ts @@ -12,13 +12,15 @@ * by using GitHub Personal Access Token * These tests create a new repository on GitHub if not exists. */ -import path from 'path'; import git from 'isomorphic-git'; import fs from 'fs-extra'; import expect from 'expect'; +import sinon from 'sinon'; import { GitDocumentDB } from '../../src/git_documentdb'; -import { RemoteEngine } from '../../src/remote/remote_engine'; +import { RemoteEngine, RemoteErr } from '../../src/remote/remote_engine'; import { + ConnectionSettings, + RemoteOptions, SyncResult, SyncResultFastForwardMerge, SyncResultMergeAndPush, @@ -38,498 +40,791 @@ import { removeRemoteRepositories, } from '../remote_utils'; import { sleep, toSortedJSONString } from '../../src/utils'; +import { JSON_EXT } from '../../src/const'; + +// eslint-disable-next-line @typescript-eslint/no-var-requires +const pushWorker_module = require('../../src/remote/push_worker'); + +export const syncTrySyncBase = ( + connection: ConnectionSettings, + remoteURLBase: string, + reposPrefix: string, + localDir: string +) => () => { + let idCounter = 0; + const serialId = () => { + return `${reposPrefix}${idCounter++}`; + }; + + // Use sandbox to restore stub and spy in parallel mocha tests + let sandbox: sinon.SinonSandbox; + beforeEach(function () { + sandbox = sinon.createSandbox(); + }); -const reposPrefix = 'test_sync_trysync___'; -const localDir = `./test/database_sync_trysync`; - -let idCounter = 0; -const serialId = () => { - return `${reposPrefix}${idCounter++}`; -}; - -beforeEach(function () { - // @ts-ignore - console.log(`... ${this.currentTest.fullTitle()}`); -}); - -before(() => { - // eslint-disable-next-line @typescript-eslint/no-var-requires - GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); - - fs.removeSync(path.resolve(localDir)); -}); - -after(() => { - // It may throw error due to memory leak of getCommitLogs() - // fs.removeSync(path.resolve(localDir)); -}); - -// This test needs environment variables: -// - GITDDB_GITHUB_USER_URL: URL of your GitHub account -// e.g.) https://github.com/foo/ -// - GITDDB_PERSONAL_ACCESS_TOKEN: A personal access token of your GitHub account -const maybe = - process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN - ? describe - : describe.skip; - -maybe(': Sync#trySync()', () => { - const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') - ? process.env.GITDDB_GITHUB_USER_URL - : process.env.GITDDB_GITHUB_USER_URL + '/'; - const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; + afterEach(function () { + sandbox.restore(); + }); before(async () => { await removeRemoteRepositories(reposPrefix); }); - /** - * before: - * dbA : - * after : - */ - it('returns SyncResultNop when no commit', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId); - - const syncResult1 = (await syncA.trySync()) as SyncResultPush; - - expect(syncResult1.action).toBe('nop'); - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - - await destroyDBs([dbA]); - }); - - describe('returns SyncResultPush', () => { + describe(': Sync#trySync()', () => { /** * before: - * dbA : jsonA1 - * after : jsonA1 - */ - it('which includes one remote creation when a local db creates a document', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId); - - // A puts and pushes - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResultA1 = await dbA.put(jsonA1); - const syncResult1 = (await syncA.trySync()) as SyncResultPush; - - expect(syncResult1.action).toBe('push'); - expect(syncResult1.commits!.remote.length).toBe(1); - expect(syncResult1.commits!.remote[0].oid).toBe(putResultA1.commit.oid); - expect(syncResult1.changes.remote.length).toBe(1); - expect(syncResult1.changes.remote).toEqual([ - getChangedFileInsert(jsonA1, putResultA1), - ]); - - expect(getWorkingDirDocs(dbA)).toEqual([jsonA1]); - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - - await destroyDBs([dbA]); - }); - - /** - * before: jsonA1 - * dbA : -jsonA1 + * dbA : * after : */ - it('which includes one remote delete when a local db deletes a document', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId); - - // A puts and pushes - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResultA1 = await dbA.put(jsonA1); - await syncA.tryPush(); + it('returns SyncResultNop when no commit', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, + }); - const deleteResultA1 = await dbA.delete(jsonA1); const syncResult1 = (await syncA.trySync()) as SyncResultPush; - expect(syncResult1.action).toBe('push'); - expect(syncResult1.commits!.remote.length).toBe(1); - expect(syncResult1.commits!.remote[0].oid).toBe(deleteResultA1.commit.oid); - expect(syncResult1.changes.remote.length).toBe(1); - expect(syncResult1.changes.remote).toEqual([ - getChangedFileDelete(jsonA1, deleteResultA1), - ]); - - expect(getWorkingDirDocs(dbA)).toEqual([]); + expect(syncResult1.action).toBe('nop'); await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); await destroyDBs([dbA]); }); - /** - * before: jsonA1 - * dbA : +jsonA1 - * after : jsonA1 - */ - it('which includes one remote update when a local db a document', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId); - // A puts and pushes - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResultA1 = await dbA.put(jsonA1); - await syncA.tryPush(); + describe('returns SyncResultPush', () => { + /** + * before: + * dbA : jsonA1 + * after : jsonA1 + */ + it('which includes one remote creation when a local db creates a document', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, + }); + + // A puts and pushes + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResultA1 = await dbA.put(jsonA1); + const syncResult1 = (await syncA.trySync()) as SyncResultPush; + + expect(syncResult1.action).toBe('push'); + expect(syncResult1.commits!.remote.length).toBe(1); + expect(syncResult1.commits!.remote[0].oid).toBe(putResultA1.commit.oid); + expect(syncResult1.changes.remote.length).toBe(1); + expect(syncResult1.changes.remote).toEqual([ + getChangedFileInsert(jsonA1, putResultA1), + ]); - const jsonA1dash = { _id: '1', name: 'updated' }; - const putResultA1dash = await dbA.put(jsonA1dash); - const syncResult1 = (await syncA.trySync()) as SyncResultPush; + expect(getWorkingDirDocs(dbA)).toEqual([jsonA1]); - expect(syncResult1.action).toBe('push'); - expect(syncResult1.commits!.remote.length).toBe(1); - expect(syncResult1.commits!.remote[0].oid).toBe(putResultA1dash.commit.oid); - expect(syncResult1.changes.remote.length).toBe(1); - expect(syncResult1.changes.remote).toEqual([ - getChangedFileUpdate(jsonA1, putResultA1, jsonA1dash, putResultA1dash), - ]); + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - expect(getWorkingDirDocs(dbA)).toEqual([jsonA1dash]); + await destroyDBs([dbA]); + }); - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + /** + * before: jsonA1 + * dbA : -jsonA1 + * after : + */ + it('which includes one remote delete when a local db deletes a document', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, + }); + + // A puts and pushes + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResultA1 = await dbA.put(jsonA1); + await syncA.tryPush(); + + const deleteResultA1 = await dbA.delete(jsonA1); + const syncResult1 = (await syncA.trySync()) as SyncResultPush; + + expect(syncResult1.action).toBe('push'); + expect(syncResult1.commits!.remote.length).toBe(1); + expect(syncResult1.commits!.remote[0].oid).toBe(deleteResultA1.commit.oid); + expect(syncResult1.changes.remote.length).toBe(1); + expect(syncResult1.changes.remote).toEqual([ + getChangedFileDelete(jsonA1, deleteResultA1), + ]); + + expect(getWorkingDirDocs(dbA)).toEqual([]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + + await destroyDBs([dbA]); + }); - await destroyDBs([dbA]); + /** + * before: jsonA1 + * dbA : +jsonA1 + * after : jsonA1 + */ + it('which includes one remote update when a local db a document', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, + }); + // A puts and pushes + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResultA1 = await dbA.put(jsonA1); + await syncA.tryPush(); + + const jsonA1dash = { _id: '1', name: 'updated' }; + const putResultA1dash = await dbA.put(jsonA1dash); + const syncResult1 = (await syncA.trySync()) as SyncResultPush; + + expect(syncResult1.action).toBe('push'); + expect(syncResult1.commits!.remote.length).toBe(1); + expect(syncResult1.commits!.remote[0].oid).toBe(putResultA1dash.commit.oid); + expect(syncResult1.changes.remote.length).toBe(1); + expect(syncResult1.changes.remote).toEqual([ + getChangedFileUpdate(jsonA1, putResultA1, jsonA1dash, putResultA1dash), + ]); + + expect(getWorkingDirDocs(dbA)).toEqual([jsonA1dash]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + + await destroyDBs([dbA]); + }); }); - }); - describe('returns SyncResultFastForwardMerge', () => { - /** - * before: - * dbA : jsonA1 - * dbB : - * after : jsonA1 - */ - it('which includes one local creation when a remote db creates a document', async () => { - const [dbA, dbB, syncA, syncB] = await createClonedDatabases( - remoteURLBase, - localDir, - serialId, - undefined, - 'trace' - ); - // A puts and pushes - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResult1 = await dbA.put(jsonA1); - - await syncA.tryPush(); + describe('returns SyncResultFastForwardMerge', () => { + /** + * before: + * dbA : jsonA1 + * dbB : + * after : jsonA1 + */ + it('which includes one local creation when a remote db creates a document', async () => { + const [dbA, dbB, syncA, syncB] = await createClonedDatabases( + remoteURLBase, + localDir, + serialId, + { connection } + ); + // A puts and pushes + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResult1 = await dbA.put(jsonA1); + + await syncA.tryPush(); + + // B syncs + const syncResult1 = (await syncB.trySync()) as SyncResultFastForwardMerge; + expect(syncResult1.action).toBe('fast-forward merge'); + expect(syncResult1.commits!.local.length).toBe(1); + expect(syncResult1.commits!.local[0].oid).toBe(putResult1.commit.oid); + expect(syncResult1.changes.local.length).toBe(1); + expect(syncResult1.changes.local).toEqual([ + getChangedFileInsert(jsonA1, putResult1), + ]); - // B syncs - const syncResult1 = (await syncB.trySync()) as SyncResultFastForwardMerge; - expect(syncResult1.action).toBe('fast-forward merge'); - expect(syncResult1.commits!.local.length).toBe(1); - expect(syncResult1.commits!.local[0].oid).toBe(putResult1.commit.oid); - expect(syncResult1.changes.local.length).toBe(1); - expect(syncResult1.changes.local).toEqual([getChangedFileInsert(jsonA1, putResult1)]); + expect(getWorkingDirDocs(dbB)).toEqual([jsonA1]); - expect(getWorkingDirDocs(dbB)).toEqual([jsonA1]); + // Sync dbA + const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; + expect(getWorkingDirDocs(dbA)).toEqual([jsonA1]); - // Sync dbA - const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; - expect(getWorkingDirDocs(dbA)).toEqual([jsonA1]); + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + await destroyDBs([dbA, dbB]); + }); - await destroyDBs([dbA, dbB]); + /** + * before: + * dbA : jsonA1 jsonA2 + * dbB : + * after : jsonA1 jsonA2 + */ + it('which includes two local creations when a remote db creates two documents', async () => { + const [dbA, dbB, syncA, syncB] = await createClonedDatabases( + remoteURLBase, + localDir, + serialId, + { + connection, + } + ); + + // A puts and pushes + const jsonA1 = { _id: '1', name: 'fromA' }; + const jsonA2 = { _id: '2', name: 'fromA' }; + const putResult1 = await dbA.put(jsonA1); + const putResult2 = await dbA.put(jsonA2); + await syncA.tryPush(); + + // B syncs + const syncResult1 = (await syncB.trySync()) as SyncResultFastForwardMerge; + expect(syncResult1.action).toBe('fast-forward merge'); + expect(syncResult1.commits!.local.length).toBe(2); + expect(syncResult1.commits!.local[0].oid).toBe(putResult1.commit.oid); + expect(syncResult1.commits!.local[1].oid).toBe(putResult2.commit.oid); + expect(syncResult1.changes.local.length).toBe(2); + expect(syncResult1.changes.local).toEqual( + expect.arrayContaining([ + getChangedFileInsert(jsonA1, putResult1), + getChangedFileInsert(jsonA2, putResult2), + ]) + ); + + expect(getWorkingDirDocs(dbB)).toEqual([jsonA1, jsonA2]); + + // Sync dbA + const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; + expect(getWorkingDirDocs(dbA)).toEqual([jsonA1, jsonA2]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + + // Check HEAD + const headCommitA = await git.resolveRef({ + fs, + dir: dbA.workingDir, + ref: 'HEAD', + }); + expect(headCommitA).toBe(putResult2.commit.oid); + + const headCommitB = await git.resolveRef({ + fs, + dir: dbB.workingDir, + ref: 'HEAD', + }); + expect(headCommitB).toBe(putResult2.commit.oid); + + // Check defaultBranch + const mainBranchA = await git.resolveRef({ + fs, + dir: dbA.workingDir, + ref: 'refs/heads/main', + }); + expect(mainBranchA).toBe(putResult2.commit.oid); + + const mainBranchB = await git.resolveRef({ + fs, + dir: dbB.workingDir, + ref: 'refs/heads/main', + }); + expect(mainBranchB).toBe(putResult2.commit.oid); + + await destroyDBs([dbA, dbB]); + }); }); - /** - * before: - * dbA : jsonA1 jsonA2 - * dbB : - * after : jsonA1 jsonA2 - */ - it('which includes two local creations when a remote db creates two documents', async () => { - const [dbA, dbB, syncA, syncB] = await createClonedDatabases( - remoteURLBase, - localDir, - serialId - ); - - // A puts and pushes - const jsonA1 = { _id: '1', name: 'fromA' }; - const jsonA2 = { _id: '2', name: 'fromA' }; - const putResult1 = await dbA.put(jsonA1); - const putResult2 = await dbA.put(jsonA2); - await syncA.tryPush(); + describe('returns SyncResultMergeAndPush', () => { + /** + * before: + * dbA : jsonA1 + * dbB : jsonB2 + * after : jsonA1 jsonB2 + */ + it('which includes local and remote creations when a remote db creates a document and a local db creates another document', async () => { + const [dbA, dbB, syncA, syncB] = await createClonedDatabases( + remoteURLBase, + localDir, + serialId, + { connection } + ); + // A puts and pushes + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResultA1 = await dbA.put(jsonA1); + await syncA.tryPush(); + + // B syncs + const jsonB2 = { _id: '2', name: 'fromB' }; + const putResultB2 = await dbB.put(jsonB2); + + // Sync dbB + const syncResult1 = (await syncB.trySync()) as SyncResultMergeAndPush; + expect(syncResult1.action).toBe('merge and push'); + + expect(syncResult1.commits!.local.length).toBe(2); // put commit and merge commit + expect(syncResult1.commits!.remote.length).toBe(2); // put commit and merge commit + expect(syncResult1.commits!.local[0].oid).toBe(putResultA1.commit.oid); + expect(syncResult1.commits!.local[1].message).toBe('merge'); + expect(syncResult1.commits!.remote[0].oid).toBe(putResultB2.commit.oid); + expect(syncResult1.commits!.remote[1].message).toBe('merge'); + + expect(syncResult1.changes.local).toEqual([ + getChangedFileInsert(jsonA1, putResultA1), + ]); - // B syncs - const syncResult1 = (await syncB.trySync()) as SyncResultFastForwardMerge; - expect(syncResult1.action).toBe('fast-forward merge'); - expect(syncResult1.commits!.local.length).toBe(2); - expect(syncResult1.commits!.local[0].oid).toBe(putResult1.commit.oid); - expect(syncResult1.commits!.local[1].oid).toBe(putResult2.commit.oid); - expect(syncResult1.changes.local.length).toBe(2); - expect(syncResult1.changes.local).toEqual( - expect.arrayContaining([ - getChangedFileInsert(jsonA1, putResult1), - getChangedFileInsert(jsonA2, putResult2), - ]) - ); + expect(syncResult1.changes.remote).toEqual([ + getChangedFileInsert(jsonB2, putResultB2), + ]); - expect(getWorkingDirDocs(dbB)).toEqual([jsonA1, jsonA2]); + expect(getWorkingDirDocs(dbB)).toEqual([jsonA1, jsonB2]); - // Sync dbA - const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; - expect(getWorkingDirDocs(dbA)).toEqual([jsonA1, jsonA2]); + // Sync dbA + const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; + expect(getWorkingDirDocs(dbA)).toEqual([jsonA1, jsonB2]); - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); - // Check HEAD - const headCommitA = await git.resolveRef({ - fs, - dir: dbA.workingDir, - ref: 'HEAD', + await destroyDBs([dbA, dbB]); }); - expect(headCommitA).toBe(putResult2.commit.oid); - const headCommitB = await git.resolveRef({ - fs, - dir: dbB.workingDir, - ref: 'HEAD', + /** + * before: + * dbA : jsonA1 jsonA2 + * dbB : jsonB3 jsonB4 + * after : jsonA1 jsonA2 jsonB3 jsonB4 + */ + it('which includes two local creations and two remote creations when a remote db creates two documents and a local db creates two different documents', async () => { + const [dbA, dbB, syncA, syncB] = await createClonedDatabases( + remoteURLBase, + localDir, + serialId, + { connection } + ); + + // A puts and pushes + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResultA1 = await dbA.put(jsonA1); + const jsonA2 = { _id: '2', name: 'fromA' }; + const putResultA2 = await dbA.put(jsonA2); + await syncA.tryPush(); + + // B syncs + const jsonB3 = { _id: '3', name: 'fromB' }; + const putResultB3 = await dbB.put(jsonB3); + const jsonB4 = { _id: '4', name: 'fromB' }; + const putResultB4 = await dbB.put(jsonB4); + + const syncResult1 = (await syncB.trySync()) as SyncResultMergeAndPush; + expect(syncResult1.action).toBe('merge and push'); + expect(syncResult1.commits).toMatchObject({ + local: getCommitInfo([putResultA1, putResultA2, 'merge']), + remote: getCommitInfo([putResultB3, putResultB4, 'merge']), + }); + + expect(syncResult1.changes.local.length).toBe(2); + expect(syncResult1.changes.local).toEqual( + expect.arrayContaining([ + getChangedFileInsert(jsonA1, putResultA1), + getChangedFileInsert(jsonA2, putResultA2), + ]) + ); + + expect(syncResult1.changes.remote.length).toBe(2); + expect(syncResult1.changes.remote).toEqual( + expect.arrayContaining([ + getChangedFileInsert(jsonB3, putResultB3), + getChangedFileInsert(jsonB4, putResultB4), + ]) + ); + + expect(getWorkingDirDocs(dbB)).toEqual([jsonA1, jsonA2, jsonB3, jsonB4]); + + // Sync dbA + const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; + expect(getWorkingDirDocs(dbA)).toEqual([jsonA1, jsonA2, jsonB3, jsonB4]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + + await destroyDBs([dbA, dbB]); }); - expect(headCommitB).toBe(putResult2.commit.oid); - // Check defaultBranch - const mainBranchA = await git.resolveRef({ - fs, - dir: dbA.workingDir, - ref: 'refs/heads/main', + /** + * before: + * dbA : jsonA1 + * dbB : jsonA1 + * after : jsonA1 + */ + it('which does not include changes after a remote db creates a document and a local db creates exactly the same document', async () => { + const [dbA, dbB, syncA, syncB] = await createClonedDatabases( + remoteURLBase, + localDir, + serialId, + { connection } + ); + + // A puts and pushes + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResultA1 = await dbA.put(jsonA1); + await syncA.tryPush(); + + // B puts the same file with exactly the same contents + const putResultB1 = await dbB.put(jsonA1); + + const syncResult1 = (await syncB.trySync()) as SyncResultMergeAndPush; + expect(syncResult1.action).toBe('merge and push'); + + expect(syncResult1.commits).toMatchObject({ + local: getCommitInfo([putResultA1, 'merge']), + remote: getCommitInfo([putResultB1, 'merge']), + }); + + expect(syncResult1.changes.local.length).toBe(0); + expect(syncResult1.changes.remote.length).toBe(0); + + expect(getWorkingDirDocs(dbA)).toEqual([jsonA1]); + expect(getWorkingDirDocs(dbB)).toEqual([jsonA1]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + + await destroyDBs([dbA, dbB]); }); - expect(mainBranchA).toBe(putResult2.commit.oid); - const mainBranchB = await git.resolveRef({ - fs, - dir: dbB.workingDir, - ref: 'refs/heads/main', + /** + * before: jsonA1 + * dbA : +jsonA1 + * dbB : +jsonA1 + * after : jsonA1 + */ + it('which does not include changes after a remote db updates a document and a local db updates exactly the same update', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, + }); + + // A puts and pushes + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResultA1 = await dbA.put(jsonA1); + await syncA.tryPush(); + + // Clone + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir, + }); + // Clone dbA + await dbB.open(); + const syncB = await dbB.sync(syncA.options); + + // A updates and pushes + const jsonA1dash = { _id: '1', name: 'updated' }; + const putResultA1dash = await dbA.put(jsonA1dash); + await syncA.tryPush(); + + // B updates the same file with exactly the same contents + const putResultB1dash = await dbB.put(jsonA1dash); + + const syncResult1 = (await syncB.trySync()) as SyncResultMergeAndPush; + expect(syncResult1.action).toBe('merge and push'); + + expect(syncResult1.commits).toMatchObject({ + local: getCommitInfo([putResultA1dash, 'merge']), + remote: getCommitInfo([putResultB1dash, 'merge']), + }); + + expect(syncResult1.changes.local.length).toBe(0); + expect(syncResult1.changes.remote.length).toBe(0); + + expect(getWorkingDirDocs(dbA)).toEqual([jsonA1dash]); + expect(getWorkingDirDocs(dbB)).toEqual([jsonA1dash]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + + await destroyDBs([dbA, dbB]); }); - expect(mainBranchB).toBe(putResult2.commit.oid); - await destroyDBs([dbA, dbB]); - }); - }); - - describe('returns SyncResultMergeAndPush', () => { - /** - * before: - * dbA : jsonA1 - * dbB : jsonB2 - * after : jsonA1 jsonB2 - */ - it('which includes local and remote creations when a remote db creates a document and a local db creates another document', async () => { - const [dbA, dbB, syncA, syncB] = await createClonedDatabases( - remoteURLBase, - localDir, - serialId - ); - // A puts and pushes - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResultA1 = await dbA.put(jsonA1); - await syncA.tryPush(); - - // B syncs - const jsonB2 = { _id: '2', name: 'fromB' }; - const putResultB2 = await dbB.put(jsonB2); - - // Sync dbB - const syncResult1 = (await syncB.trySync()) as SyncResultMergeAndPush; - expect(syncResult1.action).toBe('merge and push'); + /** + * before: jsonA1 + * dbA : jsonA2 + * dbB : -jsonA1 + * after : jsonA2 + */ + it('which include a local create and a remote delete when a remote db creates a document and a local db deletes another document', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, + }); + // A puts and pushes + const jsonA1 = { _id: '1', name: 'fromA' }; + await dbA.put(jsonA1); + await syncA.tryPush(); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir, + }); + // Clone dbA + await dbB.open(); + const syncB = await dbB.sync(syncA.options); + + // A puts and pushes + const jsonA2 = { _id: '2', name: 'fromA' }; + const putResultA2 = await dbA.put(jsonA2); + await syncA.tryPush(); + + // B deletes and syncs + const deleteResultB1 = await dbB.delete(jsonA1); + + const syncResult1 = (await syncB.trySync()) as SyncResultMergeAndPush; + expect(syncResult1.action).toBe('merge and push'); + + expect(syncResult1.commits).toMatchObject({ + local: getCommitInfo([putResultA2, 'merge']), + remote: getCommitInfo([deleteResultB1, 'merge']), + }); + + expect(syncResult1.changes.local.length).toBe(1); + expect(syncResult1.changes.local).toEqual([ + getChangedFileInsert(jsonA2, putResultA2), + ]); - expect(syncResult1.commits!.local.length).toBe(2); // put commit and merge commit - expect(syncResult1.commits!.remote.length).toBe(2); // put commit and merge commit - expect(syncResult1.commits!.local[0].oid).toBe(putResultA1.commit.oid); - expect(syncResult1.commits!.local[1].message).toBe('merge'); - expect(syncResult1.commits!.remote[0].oid).toBe(putResultB2.commit.oid); - expect(syncResult1.commits!.remote[1].message).toBe('merge'); + expect(syncResult1.changes.remote.length).toBe(1); + expect(syncResult1.changes.remote).toEqual([ + getChangedFileDelete(jsonA1, deleteResultB1), + ]); - expect(syncResult1.changes.local).toEqual([ - getChangedFileInsert(jsonA1, putResultA1), - ]); + expect(getWorkingDirDocs(dbB)).toEqual([jsonA2]); - expect(syncResult1.changes.remote).toEqual([ - getChangedFileInsert(jsonB2, putResultB2), - ]); + // Sync dbA + const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; + expect(getWorkingDirDocs(dbA)).toEqual([jsonA2]); - expect(getWorkingDirDocs(dbB)).toEqual([jsonA1, jsonB2]); + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); - // Sync dbA - const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; - expect(getWorkingDirDocs(dbA)).toEqual([jsonA1, jsonB2]); + await destroyDBs([dbA, dbB]); + }); - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + /** + * before: jsonA1 + * dbA : -jsonA1 + * dbB : jsonB2 + * after : jsonB2 + */ + it('which include a remote create and a local delete when a remote db deletes a document and a local db creates another document', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, + }); + + // A puts and pushes + const jsonA1 = { _id: '1', name: 'fromA' }; + await dbA.put(jsonA1); + await syncA.tryPush(); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir, + }); + + // Clone dbA + await dbB.open(); + const syncB = await dbB.sync(syncA.options); + + // A deletes and pushes + const deleteResultA1 = await dbA.delete(jsonA1); + await syncA.tryPush(); + + // B put another file and syncs + const jsonB2 = { _id: '2', name: 'fromB' }; + const putResultB2 = await dbB.put(jsonB2); + + const syncResult1 = (await syncB.trySync()) as SyncResultMergeAndPush; + expect(syncResult1.action).toBe('merge and push'); + + expect(syncResult1.commits).toMatchObject({ + local: getCommitInfo([deleteResultA1, 'merge']), + remote: getCommitInfo([putResultB2, 'merge']), + }); + + expect(syncResult1.changes.local.length).toBe(1); + expect(syncResult1.changes.local).toEqual([ + getChangedFileDelete(jsonA1, deleteResultA1), + ]); + + expect(syncResult1.changes.remote.length).toBe(1); + expect(syncResult1.changes.remote).toEqual([ + getChangedFileInsert(jsonB2, putResultB2), + ]); + + expect(getWorkingDirDocs(dbB)).toEqual([jsonB2]); + + // Sync dbA + const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; + expect(getWorkingDirDocs(dbA)).toEqual([jsonB2]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + + await destroyDBs([dbA, dbB]); + }); - await destroyDBs([dbA, dbB]); + /** + * before: jsonA1 + * dbA : -jsonA1 + * dbB : -jsonA1 + * after : + */ + it('which does not include changes when a remote db deletes a document and a local db deletes the same document', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, + }); + // A puts and pushes + const jsonA1 = { _id: '1', name: 'fromA' }; + await dbA.put(jsonA1); + await syncA.tryPush(); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir, + }); + // Clone dbA + await dbB.open(); + const syncB = await dbB.sync(syncA.options); + + // A deletes and pushes + const deleteResultA1 = await dbA.delete(jsonA1); + await syncA.tryPush(); + + // B deletes the same file and syncs + const deleteResultB1 = await dbB.delete(jsonA1); + + const syncResult1 = (await syncB.trySync()) as SyncResultMergeAndPush; + expect(syncResult1.action).toBe('merge and push'); + + expect(syncResult1.commits).toMatchObject({ + local: getCommitInfo([deleteResultA1, 'merge']), + remote: getCommitInfo([deleteResultB1, 'merge']), + }); + + expect(syncResult1.changes.local.length).toBe(0); // Must no be 1 but 0, because diff is empty. + expect(syncResult1.changes.remote.length).toBe(0); // Must no be 1 but 0, because diff is empty. + + expect(getWorkingDirDocs(dbB)).toEqual([]); + + // Sync dbA + const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; + expect(getWorkingDirDocs(dbA)).toEqual([]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + + await destroyDBs([dbA, dbB]); + }); }); - /** - * before: - * dbA : jsonA1 jsonA2 - * dbB : jsonB3 jsonB4 - * after : jsonA1 jsonA2 jsonB3 jsonB4 - */ - it('which includes two local creations and two remote creations when a remote db creates two documents and a local db creates two different documents', async () => { - const [dbA, dbB, syncA, syncB] = await createClonedDatabases( - remoteURLBase, - localDir, - serialId - ); - - // A puts and pushes - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResultA1 = await dbA.put(jsonA1); - const jsonA2 = { _id: '2', name: 'fromA' }; - const putResultA2 = await dbA.put(jsonA2); - await syncA.tryPush(); - - // B syncs - const jsonB3 = { _id: '3', name: 'fromB' }; - const putResultB3 = await dbB.put(jsonB3); - const jsonB4 = { _id: '4', name: 'fromB' }; - const putResultB4 = await dbB.put(jsonB4); - - const syncResult1 = (await syncB.trySync()) as SyncResultMergeAndPush; - expect(syncResult1.action).toBe('merge and push'); - expect(syncResult1.commits).toMatchObject({ - local: getCommitInfo([putResultA1, putResultA2, 'merge']), - remote: getCommitInfo([putResultB3, putResultB4, 'merge']), + describe('returns SyncResolveConflictAndPush', () => { + it('when two databases put the same _id document', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection, + }; + await dbA.open(); + const syncA = await dbA.sync(options); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir: localDir, + }); + await dbB.open(); + const syncB = await dbB.sync(options); + + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResultA1 = await dbA.put(jsonA1); + await syncA.tryPush(); + + // The same id + const jsonB1 = { _id: '1', name: 'fromB' }; + const putResultB1 = await dbB.put(jsonB1); + + await expect(syncB.trySync()).resolves.toMatchObject({ + action: 'resolve conflicts and push', + changes: { + local: [], + remote: [getChangedFileUpdate(jsonA1, putResultA1, jsonB1, putResultB1)], + }, + conflicts: [ + { + fatDoc: { + _id: jsonB1._id, + name: jsonB1._id + JSON_EXT, + fileOid: putResultB1.fileOid, + type: 'json', + doc: jsonB1, + }, + operation: 'insert-merge', + strategy: 'ours-diff', + }, + ], + }); + + await destroyDBs([dbA, dbB]); }); - - expect(syncResult1.changes.local.length).toBe(2); - expect(syncResult1.changes.local).toEqual( - expect.arrayContaining([ - getChangedFileInsert(jsonA1, putResultA1), - getChangedFileInsert(jsonA2, putResultA2), - ]) - ); - - expect(syncResult1.changes.remote.length).toBe(2); - expect(syncResult1.changes.remote).toEqual( - expect.arrayContaining([ - getChangedFileInsert(jsonB3, putResultB3), - getChangedFileInsert(jsonB4, putResultB4), - ]) - ); - - expect(getWorkingDirDocs(dbB)).toEqual([jsonA1, jsonA2, jsonB3, jsonB4]); - - // Sync dbA - const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; - expect(getWorkingDirDocs(dbA)).toEqual([jsonA1, jsonA2, jsonB3, jsonB4]); - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); - - await destroyDBs([dbA, dbB]); }); - /** - * before: - * dbA : jsonA1 - * dbB : jsonA1 - * after : jsonA1 - */ - it('which does not include changes after a remote db creates a document and a local db creates exactly the same document', async () => { - const [dbA, dbB, syncA, syncB] = await createClonedDatabases( - remoteURLBase, - localDir, - serialId - ); - - // A puts and pushes - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResultA1 = await dbA.put(jsonA1); - await syncA.tryPush(); - - // B puts the same file with exactly the same contents - const putResultB1 = await dbB.put(jsonA1); - - const syncResult1 = (await syncB.trySync()) as SyncResultMergeAndPush; - expect(syncResult1.action).toBe('merge and push'); - - expect(syncResult1.commits).toMatchObject({ - local: getCommitInfo([putResultA1, 'merge']), - remote: getCommitInfo([putResultB1, 'merge']), + it('skips consecutive sync tasks', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, }); + const results: SyncResult[] = []; + + for (let i = 0; i < 3; i++) { + // eslint-disable-next-line promise/catch-or-return + syncA.trySync().then(result => results.push(result)); + } + await sleep(5000); + + // results will be include 9 cancels + let cancelCount = 0; + results.forEach(res => { + if (res.action === 'canceled') cancelCount++; + }); + // Check results + expect(cancelCount).toBeGreaterThanOrEqual(1); - expect(syncResult1.changes.local.length).toBe(0); - expect(syncResult1.changes.remote.length).toBe(0); - - expect(getWorkingDirDocs(dbA)).toEqual([jsonA1]); - expect(getWorkingDirDocs(dbB)).toEqual([jsonA1]); + // Check statistics + expect(dbA.taskQueue.currentStatistics().cancel).toBeGreaterThanOrEqual(1); - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + // Only one trySync() will be executed + expect(dbA.taskQueue.currentStatistics().sync).toBeGreaterThanOrEqual(1); - await destroyDBs([dbA, dbB]); + await destroyDBs([dbA]); }); - /** - * before: jsonA1 - * dbA : +jsonA1 - * dbB : +jsonA1 - * after : jsonA1 - */ - it('which does not include changes after a remote db updates a document and a local db updates exactly the same update', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId); - - // A puts and pushes - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResultA1 = await dbA.put(jsonA1); - await syncA.tryPush(); - - // Clone - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir, + it('skips consecutive sync tasks after crud tasks', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, }); - // Clone dbA - await dbB.open(); - const syncB = await dbB.sync(syncA.options); - - // A updates and pushes - const jsonA1dash = { _id: '1', name: 'updated' }; - const putResultA1dash = await dbA.put(jsonA1dash); - await syncA.tryPush(); - // B updates the same file with exactly the same contents - const putResultB1dash = await dbB.put(jsonA1dash); - - const syncResult1 = (await syncB.trySync()) as SyncResultMergeAndPush; - expect(syncResult1.action).toBe('merge and push'); - - expect(syncResult1.commits).toMatchObject({ - local: getCommitInfo([putResultA1dash, 'merge']), - remote: getCommitInfo([putResultB1dash, 'merge']), + const jsonA1 = { _id: '1', name: 'fromA' }; + for (let i = 0; i < 10; i++) { + dbA.put(jsonA1); + } + const results: SyncResult[] = []; + for (let i = 0; i < 3; i++) { + // eslint-disable-next-line promise/catch-or-return + syncA.trySync().then(result => results.push(result)); + } + await sleep(10000); + + // results will be include 9 cancels + let cancelCount = 0; + results.forEach(res => { + if (res.action === 'canceled') cancelCount++; }); + // Check results + expect(cancelCount).toBeGreaterThanOrEqual(1); - expect(syncResult1.changes.local.length).toBe(0); - expect(syncResult1.changes.remote.length).toBe(0); + // Check statistics + expect(dbA.taskQueue.currentStatistics().cancel).toBeGreaterThanOrEqual(1); - expect(getWorkingDirDocs(dbA)).toEqual([jsonA1dash]); - expect(getWorkingDirDocs(dbB)).toEqual([jsonA1dash]); + // Only one trySync() will be executed + expect(dbA.taskQueue.currentStatistics().sync).toBeGreaterThanOrEqual(1); - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); - - await destroyDBs([dbA, dbB]); + await destroyDBs([dbA]); }); - /** - * before: jsonA1 - * dbA : jsonA2 - * dbB : -jsonA1 - * after : jsonA2 - */ - it('which include a local create and a remote delete when a remote db creates a document and a local db deletes another document', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId); - // A puts and pushes - const jsonA1 = { _id: '1', name: 'fromA' }; - await dbA.put(jsonA1); - await syncA.tryPush(); - + it('syncs files under .gitddb', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, + }); const dbNameB = serialId(); const dbB: GitDocumentDB = new GitDocumentDB({ dbName: dbNameB, @@ -539,273 +834,210 @@ maybe(': Sync#trySync()', () => { await dbB.open(); const syncB = await dbB.sync(syncA.options); - // A puts and pushes - const jsonA2 = { _id: '2', name: 'fromA' }; - const putResultA2 = await dbA.put(jsonA2); - await syncA.tryPush(); - - // B deletes and syncs - const deleteResultB1 = await dbB.delete(jsonA1); + const info = { + dbId: 'foo', + creator: 'bar', + version: 'baz', + }; + const putResult = await dbA.putFatDoc('.gitddb/info.json', toSortedJSONString(info)); - const syncResult1 = (await syncB.trySync()) as SyncResultMergeAndPush; - expect(syncResult1.action).toBe('merge and push'); - - expect(syncResult1.commits).toMatchObject({ - local: getCommitInfo([putResultA2, 'merge']), - remote: getCommitInfo([deleteResultB1, 'merge']), - }); - - expect(syncResult1.changes.local.length).toBe(1); - expect(syncResult1.changes.local).toEqual([ - getChangedFileInsert(jsonA2, putResultA2), - ]); + await syncA.tryPush(); - expect(syncResult1.changes.remote.length).toBe(1); - expect(syncResult1.changes.remote).toEqual([ - getChangedFileDelete(jsonA1, deleteResultB1), - ]); + await syncB.trySync(); - expect(getWorkingDirDocs(dbB)).toEqual([jsonA2]); + const fatDoc = { + _id: '.gitddb/info', + name: '.gitddb/info.json', + fileOid: putResult.fileOid, + type: 'json', + doc: info, + }; + const mergedFatDoc = await dbB.getFatDoc('.gitddb/info.json'); - // Sync dbA - const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; - expect(getWorkingDirDocs(dbA)).toEqual([jsonA2]); - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + expect(mergedFatDoc).toEqual(fatDoc); await destroyDBs([dbA, dbB]); }); - /** - * before: jsonA1 - * dbA : -jsonA1 - * dbB : jsonB2 - * after : jsonB2 - */ - it('which include a remote create and a local delete when a remote db deletes a document and a local db creates another document', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId); - - // A puts and pushes - const jsonA1 = { _id: '1', name: 'fromA' }; - await dbA.put(jsonA1); - await syncA.tryPush(); - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir, + it('pauses live sync after error', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, + live: true, + interval: 3000, }); + expect(syncA.options.live).toBeTruthy(); - // Clone dbA - await dbB.open(); - const syncB = await dbB.sync(syncA.options); - - // A deletes and pushes - const deleteResultA1 = await dbA.delete(jsonA1); - await syncA.tryPush(); - - // B put another file and syncs - const jsonB2 = { _id: '2', name: 'fromB' }; - const putResultB2 = await dbB.put(jsonB2); + dbA.put({ name: 'fromA' }); - const syncResult1 = (await syncB.trySync()) as SyncResultMergeAndPush; - expect(syncResult1.action).toBe('merge and push'); - - expect(syncResult1.commits).toMatchObject({ - local: getCommitInfo([deleteResultA1, 'merge']), - remote: getCommitInfo([putResultB2, 'merge']), + let error: Error | undefined; + syncA.on('error', (err: Error) => { + error = err; }); + const stubPush = sandbox.stub(RemoteEngine[syncA.engine], 'push'); + stubPush.onFirstCall().throwsException(new RemoteErr.NetworkError('foo')); - expect(syncResult1.changes.local.length).toBe(1); - expect(syncResult1.changes.local).toEqual([ - getChangedFileDelete(jsonA1, deleteResultA1), - ]); - - expect(syncResult1.changes.remote.length).toBe(1); - expect(syncResult1.changes.remote).toEqual([ - getChangedFileInsert(jsonB2, putResultB2), - ]); - - expect(getWorkingDirDocs(dbB)).toEqual([jsonB2]); + for (let i = 0; i < 10; i++) { + // eslint-disable-next-line no-await-in-loop + await sleep(1000); + if (error instanceof Error) { + break; + } + } - // Sync dbA - const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; - expect(getWorkingDirDocs(dbA)).toEqual([jsonB2]); + expect(error).toBeInstanceOf(RemoteErr.NetworkError); + expect(syncA.options.live).toBeFalsy(); - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); - - await destroyDBs([dbA, dbB]); + await destroyDBs([dbA]); }); /** - * before: jsonA1 - * dbA : -jsonA1 - * dbB : -jsonA1 - * after : + * Retry sync */ - it('which does not include changes when a remote db deletes a document and a local db deletes the same document', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId); - // A puts and pushes - const jsonA1 = { _id: '1', name: 'fromA' }; - await dbA.put(jsonA1); - await syncA.tryPush(); - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir, - }); - // Clone dbA - await dbB.open(); - const syncB = await dbB.sync(syncA.options); - - // A deletes and pushes - const deleteResultA1 = await dbA.delete(jsonA1); - await syncA.tryPush(); - - // B deletes the same file and syncs - const deleteResultB1 = await dbB.delete(jsonA1); - - const syncResult1 = (await syncB.trySync()) as SyncResultMergeAndPush; - expect(syncResult1.action).toBe('merge and push'); - - expect(syncResult1.commits).toMatchObject({ - local: getCommitInfo([deleteResultA1, 'merge']), - remote: getCommitInfo([deleteResultB1, 'merge']), + describe('Retry trySync', () => { + it('does not retry when retry option is 0 after UnfetchedCommitExistsError', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + await dbA.open(); + + const options: RemoteOptions = { + remoteUrl: remoteURL, + syncDirection: 'push', + retryInterval: 0, + retry: 0, + connection, + }; + + const sync = await dbA.sync(options); + await dbA.put({ name: 'fromA' }); + + const stubPush = sandbox.stub(pushWorker_module, 'pushWorker'); + stubPush.rejects(new RemoteErr.UnfetchedCommitExistsError('')); + + await expect(sync.trySync()).rejects.toThrowError( + RemoteErr.UnfetchedCommitExistsError + ); + + expect(stubPush.callCount).toBe(1); + + await destroyDBs([dbA]); }); - expect(syncResult1.changes.local.length).toBe(0); // Must no be 1 but 0, because diff is empty. - expect(syncResult1.changes.remote.length).toBe(0); // Must no be 1 but 0, because diff is empty. - - expect(getWorkingDirDocs(dbB)).toEqual([]); - - // Sync dbA - const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; - expect(getWorkingDirDocs(dbA)).toEqual([]); - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); - - await destroyDBs([dbA, dbB]); - }); - }); - - it('skips consecutive sync tasks', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId); - const results: SyncResult[] = []; + it('retries every retry interval and fails after UnfetchedCommitExistsError', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + await dbA.open(); - for (let i = 0; i < 3; i++) { - // eslint-disable-next-line promise/catch-or-return - syncA.trySync().then(result => results.push(result)); - } - await sleep(5000); + const interval = 100000; + const retryInterval = 5000; - // results will be include 9 cancels - let cancelCount = 0; - results.forEach(res => { - if (res.action === 'canceled') cancelCount++; - }); - // Check results - expect(cancelCount).toBeGreaterThanOrEqual(1); + const options: RemoteOptions = { + remoteUrl: remoteURL, + syncDirection: 'push', + interval, + retryInterval, + retry: 2, + connection, + }; - // Check statistics - expect(dbA.taskQueue.currentStatistics().cancel).toBeGreaterThanOrEqual(1); + const sync = await dbA.sync(options); + await dbA.put({ name: 'fromA' }); - // Only one trySync() will be executed - expect(dbA.taskQueue.currentStatistics().sync).toBeGreaterThanOrEqual(1); + const stubPush = sandbox.stub(pushWorker_module, 'pushWorker'); + stubPush.rejects(new RemoteErr.UnfetchedCommitExistsError('')); - await destroyDBs([dbA]); - }); - - it('skips consecutive sync tasks after crud tasks', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId); - - const jsonA1 = { _id: '1', name: 'fromA' }; - for (let i = 0; i < 10; i++) { - dbA.put(jsonA1); - } - const results: SyncResult[] = []; - for (let i = 0; i < 3; i++) { - // eslint-disable-next-line promise/catch-or-return - syncA.trySync().then(result => results.push(result)); - } - await sleep(10000); - - // results will be include 9 cancels - let cancelCount = 0; - results.forEach(res => { - if (res.action === 'canceled') cancelCount++; - }); - // Check results - expect(cancelCount).toBeGreaterThanOrEqual(1); + await expect(sync.trySync()).rejects.toThrowError( + RemoteErr.UnfetchedCommitExistsError + ); - // Check statistics - expect(dbA.taskQueue.currentStatistics().cancel).toBeGreaterThanOrEqual(1); + expect(stubPush.callCount).toBe(3); - // Only one trySync() will be executed - expect(dbA.taskQueue.currentStatistics().sync).toBeGreaterThanOrEqual(1); - - await destroyDBs([dbA]); - }); - - it('throws UnfetchedCommitExistError for [push] direction', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - syncDirection: 'push', - }); - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir, - }); - await dbB.open(); - - // tryPush throws UnfetchedCommitExistsError - await expect(dbB.sync(syncA.options)).rejects.toThrowError( - RemoteEngine[syncA.engine].Err.UnfetchedCommitExistsError - ); - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + await destroyDBs([dbA]); + }); - await destroyDBs([dbA, dbB]); - }); + it('retries every retry interval and succeeds after UnfetchedCommitExistsError', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + await dbA.open(); + + const interval = 100000; + const retryInterval = 5000; + + const options: RemoteOptions = { + remoteUrl: remoteURL, + syncDirection: 'push', + interval, + retryInterval, + retry: 2, + connection, + }; + + const sync = await dbA.sync(options); + await dbA.put({ name: 'fromA' }); + + const stubPush = sandbox.stub(pushWorker_module, 'pushWorker'); + stubPush + .onFirstCall() + .throwsException(new RemoteErr.UnfetchedCommitExistsError('')); + stubPush + .onSecondCall() + .throwsException(new RemoteErr.UnfetchedCommitExistsError('')); + stubPush + .onThirdCall() + .returns(Promise.resolve({ action: 'push', changes: { remote: [] } })); + + await expect(sync.trySync()).resolves.not.toThrowError(); + + expect(stubPush.callCount).toBe(3); + + await destroyDBs([dbA]); + }); - it('syncs files under .gitddb', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId); - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir, + it('Race condition of two trySync() calls does not throw UnfetchedCommitExistsError.', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); + + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection, + }; + await dbA.open(); + const syncA = await dbA.sync(options); + const jsonA1 = { _id: '1', name: 'fromA' }; + await dbA.put(jsonA1); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir: localDir, + }); + await dbB.open(); + const syncB = await dbB.sync(options); + const jsonB1 = { _id: '1', name: 'fromB' }; + await dbB.put(jsonB1); + + // It will retry due to RemoteErr.UnfetchedCommitExistsError + await expect( + Promise.all([syncA.trySync(), syncB.trySync()]) + ).resolves.not.toThrowError(); + + await destroyDBs([dbA, dbB]); + }); }); - // Clone dbA - await dbB.open(); - const syncB = await dbB.sync(syncA.options); - - const info = { - dbId: 'foo', - creator: 'bar', - version: 'baz', - }; - const putResult = await dbA.putFatDoc('.gitddb/info.json', toSortedJSONString(info)); - - await syncA.tryPush(); - - await syncB.trySync(); - - const fatDoc = { - _id: '.gitddb/info', - name: '.gitddb/info.json', - fileOid: putResult.fileOid, - type: 'json', - doc: info, - }; - const mergedFatDoc = await dbB.getFatDoc('.gitddb/info.json'); - console.log(mergedFatDoc); - expect(mergedFatDoc).toEqual(fatDoc); - - await destroyDBs([dbA, dbB]); }); -}); +}; diff --git a/test/remote_nodegit/sync_trysync.test.ts b/test/remote_nodegit/sync_trysync.test.ts new file mode 100644 index 00000000..ebe9ae2a --- /dev/null +++ b/test/remote_nodegit/sync_trysync.test.ts @@ -0,0 +1,61 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +/** + * Test trySync + * by using GitHub Personal Access Token + * These tests create a new repository on GitHub if not exists. + */ +import path from 'path'; +import fs from 'fs-extra'; +import { syncTrySyncBase } from '../remote_base/sync_trysync'; +import { ConnectionSettingsGitHub } from '../../src/types'; +import { GitDocumentDB } from '../../src/git_documentdb'; + +const reposPrefix = 'test_sync_trysync_nodegit___'; +const localDir = `./test/database_sync_trysync_nodegit`; + +beforeEach(function () { + // @ts-ignore + console.log(`... ${this.currentTest.fullTitle()}`); +}); + +before(() => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + + fs.removeSync(path.resolve(localDir)); +}); + +after(() => { + fs.removeSync(path.resolve(localDir)); +}); + +// This test needs environment variables: +// - GITDDB_GITHUB_USER_URL: URL of your GitHub account +// e.g.) https://github.com/foo/ +// - GITDDB_PERSONAL_ACCESS_TOKEN: A personal access token of your GitHub account +const maybe = + process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN + ? describe + : describe.skip; + +const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') + ? process.env.GITDDB_GITHUB_USER_URL + : process.env.GITDDB_GITHUB_USER_URL + '/'; + +const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; + +const connection: ConnectionSettingsGitHub = { + type: 'github', + personalAccessToken: token, + engine: 'nodegit', +}; + +maybe('NodeGit', syncTrySyncBase(connection, remoteURLBase, reposPrefix, localDir)); From 1606a9bf9439f53ad455245c86f2cb3831c3f591 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 30 Jul 2021 18:28:41 +0900 Subject: [PATCH 098/297] fix: add live tryPush --- src/remote/sync.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/remote/sync.ts b/src/remote/sync.ts index 58ce901e..37393fb5 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -556,7 +556,12 @@ export class Sync implements SyncInterface { listener.func(); }); this._syncTimer = setInterval(() => { - this.trySync().catch(() => undefined); + if (this._options.syncDirection === 'push') { + this.tryPush().catch(() => undefined); + } + else if (this._options.syncDirection === 'both') { + this.trySync().catch(() => undefined); + } }, this._options.interval!); } } @@ -616,7 +621,12 @@ export class Sync implements SyncInterface { this._options.live = true; this._syncTimer = setInterval(() => { - this.trySync().catch(() => undefined); + if (this._options.syncDirection === 'push') { + this.tryPush().catch(() => undefined); + } + else if (this._options.syncDirection === 'both') { + this.trySync().catch(() => undefined); + } }, this._options.interval!); this.eventHandlers.resume.forEach(listener => { From aa81b5f950efbb11086ea17b67c8320c51c7d3ba Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 30 Jul 2021 19:06:10 +0900 Subject: [PATCH 099/297] fix: add 3way_merge test in remote_nodegit --- test/remote_base/3way_merge.test.ts | 1736 ----------------------- test/remote_base/3way_merge.ts | 1747 ++++++++++++++++++++++++ test/remote_nodegit/3way_merge.test.ts | 61 + 3 files changed, 1808 insertions(+), 1736 deletions(-) delete mode 100644 test/remote_base/3way_merge.test.ts create mode 100644 test/remote_base/3way_merge.ts create mode 100644 test/remote_nodegit/3way_merge.test.ts diff --git a/test/remote_base/3way_merge.test.ts b/test/remote_base/3way_merge.test.ts deleted file mode 100644 index 66e31cfa..00000000 --- a/test/remote_base/3way_merge.test.ts +++ /dev/null @@ -1,1736 +0,0 @@ -/* eslint-disable @typescript-eslint/naming-convention */ -/** - * GitDocumentDB - * Copyright (c) Hidekazu Kubota - * - * This source code is licensed under the Mozilla Public License Version 2.0 - * found in the LICENSE file in the root directory of this source tree. - */ - -/** - * Test 3-way merge - * by using GitHub Personal Access Token - * These tests create a new repository on GitHub if not exists. - */ -import path from 'path'; -import fs from 'fs-extra'; -import expect from 'expect'; -import { Err } from '../../src/error'; -import { threeWayMerge } from '../../src/remote/3way_merge'; -import { GitDocumentDB } from '../../src/git_documentdb'; -import { - FatDoc, - JsonDoc, - SyncResultMergeAndPush, - SyncResultResolveConflictsAndPush, -} from '../../src/types'; -import { - compareWorkingDirAndBlobs, - createClonedDatabases, - createDatabase, - destroyDBs, - getChangedFileDelete, - getChangedFileInsert, - getChangedFileUpdate, - getCommitInfo, - getWorkingDirDocs, - removeRemoteRepositories, -} from '../remote_utils'; -import { JSON_EXT } from '../../src/const'; - -const reposPrefix = 'test_3way_merge___'; -const localDir = `./test/database_3way_merge`; - -let idCounter = 0; -const serialId = () => { - return `${reposPrefix}${idCounter++}`; -}; - -beforeEach(function () { - // @ts-ignore - console.log(`... ${this.currentTest.fullTitle()}`); -}); - -before(() => { - // eslint-disable-next-line @typescript-eslint/no-var-requires - GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); - - fs.removeSync(path.resolve(localDir)); -}); - -after(() => { - // It may throw error due to memory leak of getCommitLogs() - // fs.removeSync(path.resolve(localDir)); -}); - -// This test needs environment variables: -// - GITDDB_GITHUB_USER_URL: URL of your GitHub account -// e.g.) https://github.com/foo/ -// - GITDDB_PERSONAL_ACCESS_TOKEN: A personal access token of your GitHub account -const maybe = - process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN - ? describe - : describe.skip; - -maybe('', () => { - const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') - ? process.env.GITDDB_GITHUB_USER_URL - : process.env.GITDDB_GITHUB_USER_URL + '/'; - const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; - - before(async () => { - await removeRemoteRepositories(reposPrefix); - }); - - it('throws InvalidConflictsStateError', async () => { - const [dbA, dbB, syncA, syncB] = await createClonedDatabases( - remoteURLBase, - localDir, - serialId, - { - conflictResolutionStrategy: 'ours', - } - ); - - await expect( - // @ts-ignore - threeWayMerge(dbA, syncA, 'ours-diff', 'foo', undefined, undefined, undefined) - ).rejects.toThrowError(Err.InvalidConflictStateError); - }); - - /** - * before: - * dbA : jsonA1 jsonA2 - * dbB : jsonB1 jsonB3 - * after : jsonB1 jsonA2 jsonB3 - * - * 3-way merge: - * jsonB1: 4 - Conflict. Accept ours (insert) - * jsonA2: 1 - Accept theirs (insert) - * jsonB3: 2 - Accept ours (insert) - */ - it('resolves case 1 - Accept theirs (insert), case 2 - Accept ours (insert), case 4 - Conflict. Accept ours (insert)', async () => { - const [dbA, dbB, syncA, syncB] = await createClonedDatabases( - remoteURLBase, - localDir, - serialId, - { - conflictResolutionStrategy: 'ours', - } - ); - - // A puts and pushes - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResultA1 = await dbA.put(jsonA1); - const jsonA2 = { _id: '2', name: 'fromA' }; - const putResultA2 = await dbA.put(jsonA2); - await syncA.tryPush(); - - // B puts the same file - const jsonB1 = { _id: '1', name: 'fromB' }; - const putResultB1 = await dbB.put(jsonB1); - - // B puts a new file - const jsonB3 = { _id: '3', name: 'fromB' }; - const putResultB3 = await dbB.put(jsonB3); - - // It will occur conflict on id 1.json. - const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; - expect(syncResult1.action).toBe('resolve conflicts and push'); - expect(syncResult1.commits).toMatchObject({ - local: getCommitInfo([ - putResultA1, - putResultA2, - `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, - ]), - remote: getCommitInfo([ - putResultB1, - putResultB3, - `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, - ]), - }); - expect(syncResult1.changes.local.length).toBe(1); - expect(syncResult1.changes.local).toEqual([getChangedFileInsert(jsonA2, putResultA2)]); - - expect(syncResult1.changes.remote.length).toBe(2); - expect(syncResult1.changes.remote).toEqual( - expect.arrayContaining([ - getChangedFileInsert(jsonB3, putResultB3), - getChangedFileUpdate(jsonA1, putResultA1, jsonB1, putResultB1), - ]) - ); - - expect(syncResult1.conflicts.length).toEqual(1); - expect(syncResult1.conflicts).toEqual([ - { - fatDoc: { - _id: '1', - name: '1.json', - fileOid: putResultB1.fileOid, - type: 'json', - doc: jsonB1, - }, - strategy: 'ours', - operation: 'insert', - }, - ]); - // Conflict occurs on 1.json - - expect(getWorkingDirDocs(dbB)).toEqual([jsonB1, jsonA2, jsonB3]); - // Sync dbA - await syncA.trySync(); - expect(getWorkingDirDocs(dbA)).toEqual([jsonB1, jsonA2, jsonB3]); - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); - - await destroyDBs([dbA, dbB]); - }); - - /** - * before: - * dbA : jsonA1 jsonA2 - * dbB : jsonB1 jsonA2 - * after : jsonB1 jsonA2 - * - * 3-way merge: - * jsonB1: 4 - Conflict. Accept ours (insert) - * jsonA2: 3 - Accept both (insert) - */ - it('resolves case 3 - Accept both (insert), case 4 - Conflict. Accept ours (insert)', async () => { - const [dbA, dbB, syncA, syncB] = await createClonedDatabases( - remoteURLBase, - localDir, - serialId, - { - conflictResolutionStrategy: 'ours', - } - ); - - // A puts and pushes - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResultA1 = await dbA.put(jsonA1); - const jsonA2 = { _id: '2', name: 'fromA' }; - const putResultA2 = await dbA.put(jsonA2); - await syncA.tryPush(); - - // B puts the same file - const jsonB1 = { _id: '1', name: 'fromB' }; - const putResultB1 = await dbB.put(jsonB1); - - // B puts the same file with the same contents - const putResultB2 = await dbB.put(jsonA2); - - // It will occur conflict on id 1.json. - const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; - expect(syncResult1.action).toBe('resolve conflicts and push'); - expect(syncResult1.commits).toMatchObject({ - local: getCommitInfo([ - putResultA1, - putResultA2, - `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, - ]), - remote: getCommitInfo([ - putResultB1, - putResultB2, - `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, - ]), - }); - expect(syncResult1.changes.local.length).toBe(0); - - expect(syncResult1.changes.remote.length).toBe(1); - expect(syncResult1.changes.remote).toEqual([ - getChangedFileUpdate(jsonA1, putResultA1, jsonB1, putResultB1), - ]); - - expect(syncResult1.conflicts.length).toEqual(1); - expect(syncResult1.conflicts).toEqual([ - { - fatDoc: { - _id: '1', - name: '1.json', - fileOid: putResultB1.fileOid, - type: 'json', - doc: jsonB1, - }, - strategy: 'ours', - operation: 'insert', - }, - ]); - // Conflict occurs on 1.json - - expect(getWorkingDirDocs(dbB)).toEqual([jsonB1, jsonA2]); - // Sync dbA - const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; - expect(getWorkingDirDocs(dbA)).toEqual([jsonB1, jsonA2]); - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); - - await destroyDBs([dbA, dbB]); - }); - - /** - * before: - * dbA : jsonA1 - * dbB : jsonB1 - * after : jsonA1 - * - * 3-way merge: - * jsonA1: 5 - Conflict. Accept theirs (insert) - */ - it('resolves case 5 - Conflict. Accept theirs (insert)', async () => { - const [dbA, dbB, syncA, syncB] = await createClonedDatabases( - remoteURLBase, - localDir, - serialId, - { - conflictResolutionStrategy: 'theirs', - } - ); - - // A puts and pushes - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResultA1 = await dbA.put(jsonA1); - await syncA.tryPush(); - - // B puts the same file - const jsonB1 = { _id: '1', name: 'fromB' }; - const putResultB1 = await dbB.put(jsonB1); - - // It will occur conflict on id 1.json. - const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; - expect(syncResult1.action).toBe('resolve conflicts and push'); - expect(syncResult1.commits).toMatchObject({ - local: getCommitInfo([ - putResultA1, - `resolve: 1${JSON_EXT}(insert,${putResultA1.fileOid.substr(0, 7)},theirs)`, - ]), - remote: getCommitInfo([ - putResultB1, - `resolve: 1${JSON_EXT}(insert,${putResultA1.fileOid.substr(0, 7)},theirs)`, - ]), - }); - expect(syncResult1.changes.local.length).toBe(1); - expect(syncResult1.changes.local).toEqual([ - getChangedFileUpdate(jsonB1, putResultB1, jsonA1, putResultA1), - ]); - - expect(syncResult1.changes.remote.length).toBe(0); - - expect(syncResult1.conflicts.length).toEqual(1); - expect(syncResult1.conflicts).toEqual([ - { - fatDoc: { - _id: '1', - name: '1.json', - fileOid: putResultA1.fileOid, - type: 'json', - doc: jsonA1, - }, - strategy: 'theirs', - operation: 'insert', - }, - ]); - expect(getWorkingDirDocs(dbA)).toEqual([jsonA1]); - expect(getWorkingDirDocs(dbB)).toEqual([jsonA1]); - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); - - await destroyDBs([dbA, dbB]); - }); - - /** - * before: jsonA2 - * dbA : jsonA1 -jsonA2 - * dbB : jsonB1 -jsonA2 - * after : jsonB1 - * - * '-' means delete - * - * 3-way merge: - * jsonB1: 4 - Conflict. Accept ours (insert) - * jsonA2: 6 - Accept both (delete) - */ - it('resolves case 6 - Accept both (delete), case 4 - Conflict. Accept ours (insert)', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - conflictResolutionStrategy: 'ours', - }); - // A puts and pushes - const jsonA2 = { _id: '2', name: 'fromA' }; - await dbA.put(jsonA2); - await syncA.tryPush(); - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir, - }); - // Clone dbA - await dbB.open(); - const syncB = await dbB.sync(syncA.options); - - // A puts, deletes, and pushes - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResultA1 = await dbA.put(jsonA1); - - const deleteResultA2 = await dbA.delete(jsonA2); - await syncA.tryPush(); - - // B puts the same file - const jsonB1 = { _id: '1', name: 'fromB' }; - const putResultB1 = await dbB.put(jsonB1); - - // B deletes the same file - const deleteResultB2 = await dbB.delete(jsonA2); - - // It will occur conflict on id 1.json. - const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; - expect(syncResult1.action).toBe('resolve conflicts and push'); - expect(syncResult1.commits).toMatchObject({ - local: getCommitInfo([ - putResultA1, - deleteResultA2, - `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, - ]), - remote: getCommitInfo([ - putResultB1, - deleteResultB2, - `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, - ]), - }); - expect(syncResult1.changes.local.length).toBe(0); - - expect(syncResult1.changes.remote.length).toBe(1); - expect(syncResult1.changes.remote).toEqual([ - getChangedFileUpdate(jsonA1, putResultA1, jsonB1, putResultB1), - ]); - - expect(syncResult1.conflicts.length).toEqual(1); - expect(syncResult1.conflicts).toEqual([ - { - fatDoc: { - _id: '1', - name: '1.json', - fileOid: putResultB1.fileOid, - type: 'json', - doc: jsonB1, - }, - strategy: 'ours', - operation: 'insert', - }, - ]); - // Conflict occurs on 1.json - - expect(getWorkingDirDocs(dbB)).toEqual([jsonB1]); - // Sync dbA - const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; - expect(getWorkingDirDocs(dbA)).toEqual([jsonB1]); - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); - - await destroyDBs([dbA, dbB]); - }); - - /** - * before: jsonA2 - * dbA : jsonA1 - * dbB : jsonB1 -jsonA2 - * after : jsonB1 - * - * 3-way merge: - * jsonB1: 4 - Conflict. Accept ours (insert) - * jsonA2: 7 - Accept ours (delete) - */ - it('resolves case 7 - Accept ours (delete), case 4 - Conflict. Accept ours (insert)', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - conflictResolutionStrategy: 'ours', - }); - // A puts and pushes - const jsonA2 = { _id: '2', name: 'fromA' }; - await dbA.put(jsonA2); - await syncA.tryPush(); - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir, - }); - // Clone dbA - await dbB.open(); - const syncB = await dbB.sync(syncA.options); - - // A puts and pushes - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResultA1 = await dbA.put(jsonA1); - await syncA.tryPush(); - - // B puts the same file - const jsonB1 = { _id: '1', name: 'fromB' }; - const putResultB1 = await dbB.put(jsonB1); - - // B deletes the same file - const deleteResultB2 = await dbB.delete(jsonA2); - - // It will occur conflict on id 1.json. - const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; - expect(syncResult1.action).toBe('resolve conflicts and push'); - expect(syncResult1.commits).toMatchObject({ - local: getCommitInfo([ - putResultA1, - `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, - ]), - remote: getCommitInfo([ - putResultB1, - deleteResultB2, - `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, - ]), - }); - expect(syncResult1.changes.local.length).toBe(0); - - expect(syncResult1.changes.remote.length).toBe(2); - expect(syncResult1.changes.remote).toEqual( - expect.arrayContaining([ - getChangedFileUpdate(jsonA1, putResultA1, jsonB1, putResultB1), - getChangedFileDelete(jsonA2, deleteResultB2), - ]) - ); - - expect(syncResult1.conflicts.length).toEqual(1); - expect(syncResult1.conflicts).toEqual([ - { - fatDoc: { - _id: '1', - name: '1.json', - fileOid: putResultB1.fileOid, - type: 'json', - doc: jsonB1, - }, - strategy: 'ours', - operation: 'insert', - }, - ]); - // Conflict occurs on 1.json - - expect(getWorkingDirDocs(dbB)).toEqual([jsonB1]); - // Sync dbA - const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; - expect(getWorkingDirDocs(dbA)).toEqual([jsonB1]); - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); - - await destroyDBs([dbA, dbB]); - }); - - /** - * before: jsonA1 - * dbA : +jsonA1 - * dbB : -jsonA1 - * result: - * - * '+' means update - * - * 3-way merge: - * jsonA1: 8 - Conflict. Accept ours (delete) - */ - it('resolves case 8 - Conflict. Accept ours (delete)', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - conflictResolutionStrategy: 'ours', - }); - // A puts and pushes - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResultA1 = await dbA.put(jsonA1); - await syncA.tryPush(); - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir, - }); - // Clone dbA - await dbB.open(); - const syncB = await dbB.sync(syncA.options); - - // A updates and pushes - const jsonA1dash = { _id: '1', name: 'updated' }; - const putResultA1dash = await dbA.put(jsonA1dash); - await syncA.tryPush(); - - // B deletes and syncs - const deleteResultB1 = await dbB.delete(jsonA1); - - const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; - expect(syncResult1.action).toBe('resolve conflicts and push'); - expect(syncResult1.commits).toMatchObject({ - local: getCommitInfo([ - putResultA1dash, - `resolve: 1${JSON_EXT}(delete,${deleteResultB1.fileOid.substr(0, 7)},ours)`, - ]), - remote: getCommitInfo([ - deleteResultB1, - `resolve: 1${JSON_EXT}(delete,${deleteResultB1.fileOid.substr(0, 7)},ours)`, - ]), - }); - expect(syncResult1.changes.local.length).toBe(0); - - expect(syncResult1.changes.remote.length).toBe(1); - expect(syncResult1.changes.remote).toEqual([ - getChangedFileDelete(jsonA1dash, putResultA1dash), - ]); - - expect(syncResult1.conflicts.length).toEqual(1); - expect(syncResult1.conflicts).toEqual([ - { - fatDoc: { - _id: '1', - name: '1.json', - fileOid: deleteResultB1.fileOid, - type: 'json', - doc: jsonA1, - }, - strategy: 'ours', - operation: 'delete', - }, - ]); - // Conflict occurs on 1.json - - expect(getWorkingDirDocs(dbB)).toEqual([]); - - // Sync dbA - const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; - expect(getWorkingDirDocs(dbA)).toEqual([]); - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); - - await destroyDBs([dbA, dbB]); - }); - - /** - * before: jsonA1 - * dbA : +jsonA1 - * dbB : -jsonA1 - * result: jsonA1 - * - * '+' means update - * - * 3-way merge: - * jsonA1: 9 - Conflict. Accept theirs (update) - */ - it('resolves case 9 - Conflict. Accept ours (delete)', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - conflictResolutionStrategy: 'theirs', - }); - // A puts and pushes - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResultA1 = await dbA.put(jsonA1); - await syncA.tryPush(); - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir, - }); - // Clone dbA - await dbB.open(); - const syncB = await dbB.sync(syncA.options); - - // A updates and pushes - const jsonA1dash = { _id: '1', name: 'updated' }; - const putResultA1dash = await dbA.put(jsonA1dash); - await syncA.tryPush(); - - // B deletes and syncs - const deleteResultB1 = await dbB.delete(jsonA1); - - const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; - expect(syncResult1.action).toBe('resolve conflicts and push'); - expect(syncResult1.commits).toMatchObject({ - local: getCommitInfo([ - putResultA1dash, - `resolve: 1${JSON_EXT}(update,${putResultA1dash.fileOid.substr(0, 7)},theirs)`, - ]), - remote: getCommitInfo([ - deleteResultB1, - `resolve: 1${JSON_EXT}(update,${putResultA1dash.fileOid.substr(0, 7)},theirs)`, - ]), - }); - - expect(syncResult1.changes.local.length).toBe(1); - expect(syncResult1.changes.local).toEqual([ - getChangedFileInsert(jsonA1dash, putResultA1dash), - ]); - - expect(syncResult1.changes.remote.length).toBe(0); - - expect(syncResult1.conflicts.length).toEqual(1); - expect(syncResult1.conflicts).toEqual([ - { - fatDoc: { - _id: '1', - name: '1.json', - fileOid: putResultA1dash.fileOid, - type: 'json', - doc: jsonA1dash, - }, - strategy: 'theirs', - operation: 'update', - }, - ]); - // Conflict occurs on 1.json - - expect(getWorkingDirDocs(dbA)).toEqual([jsonA1dash]); - expect(getWorkingDirDocs(dbB)).toEqual([jsonA1dash]); - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); - - await destroyDBs([dbA, dbB]); - }); - - /** - * before: jsonA2 - * dbA : jsonA1 -jsonA2 - * dbB : jsonB1 - * after : jsonB1 - * - * 3-way merge: - * jsonB1: 4 - Conflict. Accept ours (insert) - * jsonA2:10 - Accept theirs (delete) - */ - it('resolves case 10 - Accept theirs (delete), case 4 - Conflict. Accept ours (insert)', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - conflictResolutionStrategy: 'ours', - }); - // A puts and pushes - const jsonA2 = { _id: '2', name: 'fromA' }; - await dbA.put(jsonA2); - await syncA.tryPush(); - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir, - }); - // Clone dbA - await dbB.open(); - const syncB = await dbB.sync(syncA.options); - - // A puts, deletes, and pushes - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResultA1 = await dbA.put(jsonA1); - const deleteResultA2 = await dbA.delete(jsonA2); - await syncA.tryPush(); - - // B puts the same file - const jsonB1 = { _id: '1', name: 'fromB' }; - const putResultB1 = await dbB.put(jsonB1); - - // It will occur conflict on id 1.json. - const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; - expect(syncResult1.action).toBe('resolve conflicts and push'); - expect(syncResult1.commits).toMatchObject({ - local: getCommitInfo([ - putResultA1, - deleteResultA2, - `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, - ]), - remote: getCommitInfo([ - putResultB1, - `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, - ]), - }); - expect(syncResult1.changes.local.length).toBe(1); - expect(syncResult1.changes.local).toEqual([ - getChangedFileDelete(jsonA2, deleteResultA2), - ]); - - expect(syncResult1.changes.remote.length).toBe(1); - expect(syncResult1.changes.remote).toEqual([ - getChangedFileUpdate(jsonA1, putResultA1, jsonB1, putResultB1), - ]); - - expect(syncResult1.conflicts.length).toEqual(1); - expect(syncResult1.conflicts).toEqual([ - { - fatDoc: { - _id: '1', - name: '1.json', - fileOid: putResultB1.fileOid, - type: 'json', - doc: jsonB1, - }, - strategy: 'ours', - operation: 'insert', - }, - ]); - // Conflict occurs on 1.json - - expect(getWorkingDirDocs(dbB)).toEqual([jsonB1]); - // Sync dbA - const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; - expect(getWorkingDirDocs(dbA)).toEqual([jsonB1]); - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); - - await destroyDBs([dbA, dbB]); - }); - - /** - * before: jsonA1 - * dbA : -jsonA1 jsonA2 - * dbB : jsonB1 - * result: jsonB1 jsonA2 - * - * 3-way merge: - * jsonB1: 11 - Conflict. Accept ours (update) - * jsonA2: 1 - Accept theirs (insert) - */ - it('resolves case 11 - Conflict. Accept ours (update), case 1 - Accept theirs (insert), ', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - conflictResolutionStrategy: 'ours', - }); - // A puts and pushes - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResultA1 = await dbA.put(jsonA1); - await syncA.tryPush(); - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir, - }); - // Clone dbA - await dbB.open(); - const syncB = await dbB.sync(syncA.options); - - // A deletes the old file and puts a new file - const deleteResultA1 = await dbA.delete(jsonA1); - const jsonA2 = { _id: '2', name: 'fromA' }; - const putResultA2 = await dbA.put(jsonA2); - await syncA.tryPush(); - - // B updates the old file and syncs - const jsonB1 = { _id: '1', name: 'fromB' }; - const putResultB1 = await dbB.put(jsonB1); - - const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; - expect(syncResult1.action).toBe('resolve conflicts and push'); - expect(syncResult1.commits).toMatchObject({ - local: getCommitInfo([ - deleteResultA1, - putResultA2, - `resolve: 1${JSON_EXT}(update,${putResultB1.fileOid.substr(0, 7)},ours)`, - ]), - remote: getCommitInfo([ - putResultB1, - `resolve: 1${JSON_EXT}(update,${putResultB1.fileOid.substr(0, 7)},ours)`, - ]), - }); - expect(syncResult1.changes.local.length).toBe(1); - expect(syncResult1.changes.local).toEqual([getChangedFileInsert(jsonA2, putResultA2)]); - - expect(syncResult1.changes.remote.length).toBe(1); - expect(syncResult1.changes.remote).toEqual([getChangedFileInsert(jsonB1, putResultB1)]); - - expect(syncResult1.conflicts.length).toEqual(1); - expect(syncResult1.conflicts).toEqual([ - { - fatDoc: { - _id: '1', - name: '1.json', - fileOid: putResultB1.fileOid, - type: 'json', - doc: jsonB1, - }, - strategy: 'ours', - operation: 'update', - }, - ]); - // Conflict occurs on 1.json - - expect(getWorkingDirDocs(dbB)).toEqual([jsonB1, jsonA2]); - - // Sync dbA - const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; - expect(getWorkingDirDocs(dbA)).toEqual([jsonB1, jsonA2]); - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); - - await destroyDBs([dbA, dbB]); - }); - - /** - * before: jsonA1 - * dbA : -jsonA1 jsonA2 - * dbB : jsonB1 - * result: jsonA2 - * - * 3-way merge: - * jsonA1: 11 - Conflict. Accept theirs (delete) - * jsonA2: 1 - Accept theirs (insert) - */ - it('resolves case 12 - accept theirs (delete), case 1 - Accept theirs (insert)', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - conflictResolutionStrategy: 'ours', - }); - // A puts and pushes - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResultA1 = await dbA.put(jsonA1); - await syncA.tryPush(); - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir, - }); - // Clone dbA - await dbB.open(); - const syncB = await dbB.sync({ - ...syncA.options, - conflictResolutionStrategy: 'theirs', - }); - - // A deletes the old file and puts a new file - const deleteResultA1 = await dbA.delete(jsonA1); - const jsonA2 = { _id: '2', name: 'fromA' }; - const putResultA2 = await dbA.put(jsonA2); - await syncA.tryPush(); - - // B updates the old file and syncs - const jsonB1 = { _id: '1', name: 'fromB' }; - const putResultB1 = await dbB.put(jsonB1); - - const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; - expect(syncResult1.action).toBe('resolve conflicts and push'); - expect(syncResult1.commits).toMatchObject({ - local: getCommitInfo([ - deleteResultA1, - putResultA2, - `resolve: 1${JSON_EXT}(delete,${deleteResultA1.fileOid.substr(0, 7)},theirs)`, - ]), - remote: getCommitInfo([ - putResultB1, - `resolve: 1${JSON_EXT}(delete,${deleteResultA1.fileOid.substr(0, 7)},theirs)`, - ]), - }); - expect(syncResult1.changes.local.length).toBe(2); - expect(syncResult1.changes.local).toEqual( - expect.arrayContaining([ - getChangedFileDelete(jsonB1, putResultB1), - getChangedFileInsert(jsonA2, putResultA2), - ]) - ); - - expect(syncResult1.changes.remote.length).toBe(0); - - expect(syncResult1.conflicts.length).toEqual(1); - expect(syncResult1.conflicts).toEqual([ - { - fatDoc: { - _id: '1', - name: '1.json', - fileOid: deleteResultA1.fileOid, - type: 'json', - doc: jsonA1, - }, - strategy: 'theirs', - operation: 'delete', - }, - ]); - // Conflict occurs on 1.json - expect(getWorkingDirDocs(dbA)).toEqual([jsonA2]); - expect(getWorkingDirDocs(dbB)).toEqual([jsonA2]); - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); - - await destroyDBs([dbA, dbB]); - }); - - /** - * before: jsonA2 - * dbA : jsonA1 +jsonA2 - * dbB : jsonB1 +jsonA2 - * after : jsonB1 +jsonA2 - * - * 3-way merge: - * jsonB1: 4 - Conflict. Accept ours (insert) - * jsonA2:13 - Accept both (update) - */ - it('resolves case 13 - Accept both (update), case 4 - Conflict. Accept ours (insert)', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - conflictResolutionStrategy: 'ours', - }); - // A puts and pushes - const jsonA2 = { _id: '2', name: 'fromA' }; - const putResultA2 = await dbA.put(jsonA2); - await syncA.tryPush(); - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir, - }); - // Clone dbA - await dbB.open(); - const syncB = await dbB.sync(syncA.options); - - // A puts and pushes - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResultA1 = await dbA.put(jsonA1); - const jsonA2dash = { _id: '2', name: 'updated' }; - const putResultA2dash = await dbA.put(jsonA2dash); - await syncA.tryPush(); - - // B puts the same file - const jsonB1 = { _id: '1', name: 'fromB' }; - const putResultB1 = await dbB.put(jsonB1); - - // B puts the same file with the same contents - const putResultB2 = await dbB.put(jsonA2dash); - - // It will occur conflict on id 1.json. - const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; - expect(syncResult1.action).toBe('resolve conflicts and push'); - expect(syncResult1.commits).toMatchObject({ - local: getCommitInfo([ - putResultA1, - putResultA2dash, - `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, - ]), - remote: getCommitInfo([ - putResultB1, - putResultB2, - `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, - ]), - }); - expect(syncResult1.changes.local.length).toBe(0); - - expect(syncResult1.changes.remote.length).toBe(1); - expect(syncResult1.changes.remote).toEqual([ - getChangedFileUpdate(jsonA1, putResultA1, jsonB1, putResultB1), - ]); - - expect(syncResult1.conflicts.length).toEqual(1); - expect(syncResult1.conflicts).toEqual([ - { - fatDoc: { - _id: '1', - name: '1.json', - fileOid: putResultB1.fileOid, - type: 'json', - doc: jsonB1, - }, - strategy: 'ours', - operation: 'insert', - }, - ]); - // Conflict occurs on 1.json - - expect(getWorkingDirDocs(dbB)).toEqual([jsonB1, jsonA2dash]); - // Sync dbA - const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; - expect(getWorkingDirDocs(dbA)).toEqual([jsonB1, jsonA2dash]); - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); - - await destroyDBs([dbA, dbB]); - }); - - // case 14 - /** - * before: jsonA2 - * dbA : jsonA1 +jsonA2 - * dbB : jsonB1 jsonA2 - * after : jsonB1 +jsonA2 - * - * 3-way merge: - * jsonB1: 4 - Conflict. Accept ours (insert) - * jsonA2:14 - Accept theirs (update) - */ - it('resolves case 14 - Accept theirs (update), case 4 - Conflict. Accept ours (insert)', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - conflictResolutionStrategy: 'ours', - }); - // A puts and pushes - const jsonA2 = { _id: '2', name: 'fromA' }; - const putResultA2 = await dbA.put(jsonA2); - await syncA.tryPush(); - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir, - }); - // Clone dbA - await dbB.open(); - const syncB = await dbB.sync(syncA.options); - - // A puts and pushes - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResultA1 = await dbA.put(jsonA1); - const jsonA2dash = { _id: '2', name: 'updated' }; - const putResultA2dash = await dbA.put(jsonA2dash); - await syncA.tryPush(); - - // B puts the same file - const jsonB1 = { _id: '1', name: 'fromB' }; - const putResultB1 = await dbB.put(jsonB1); - - // B puts the same file with the previous contents - const putResultB2 = await dbB.put(jsonA2); - - // It will occur conflict on id 1.json. - const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; - expect(syncResult1.action).toBe('resolve conflicts and push'); - expect(syncResult1.commits).toMatchObject({ - local: getCommitInfo([ - putResultA1, - putResultA2dash, - `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, - ]), - remote: getCommitInfo([ - putResultB1, - putResultB2, - `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, - ]), - }); - expect(syncResult1.changes.local.length).toBe(1); - expect(syncResult1.changes.local).toEqual([ - getChangedFileUpdate(jsonA2, putResultB2, jsonA2dash, putResultA2dash), - ]); - - expect(syncResult1.changes.remote.length).toBe(1); - expect(syncResult1.changes.remote).toEqual([ - getChangedFileUpdate(jsonA1, putResultA1, jsonB1, putResultB1), - ]); - - expect(syncResult1.conflicts.length).toEqual(1); - expect(syncResult1.conflicts).toEqual([ - { - fatDoc: { - _id: '1', - name: '1.json', - fileOid: putResultB1.fileOid, - type: 'json', - doc: jsonB1, - }, - strategy: 'ours', - operation: 'insert', - }, - ]); - // Conflict occurs on 1.json - - expect(getWorkingDirDocs(dbB)).toEqual([jsonB1, jsonA2dash]); - // Sync dbA - const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; - expect(getWorkingDirDocs(dbA)).toEqual([jsonB1, jsonA2dash]); - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); - - await destroyDBs([dbA, dbB]); - }); - - /** - * before: jsonA2 - * dbA : jsonA1 jsonA2 - * dbB : jsonB1 jsonB2 - * after : jsonB1 jsonB2 - * - * 3-way merge: - * jsonB1: 4 - Conflict. Accept ours (insert) - * jsonA2:15 - Accept ours (update) - */ - it('resolves case 15 - Accept ours (update), case 4 - Conflict. Accept ours (insert)', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - conflictResolutionStrategy: 'ours', - }); - // A puts and pushes - const jsonA2 = { _id: '2', name: 'fromA' }; - const putResultA2 = await dbA.put(jsonA2); - await syncA.tryPush(); - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir, - }); - // Clone dbA - await dbB.open(); - const syncB = await dbB.sync(syncA.options); - - // A puts - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResultA1 = await dbA.put(jsonA1); - // A puts the previous file and pushes - const putResultA2dash = await dbA.put(jsonA2); - await syncA.tryPush(); - - // B puts the same file - const jsonB1 = { _id: '1', name: 'fromB' }; - const putResultB1 = await dbB.put(jsonB1); - - // B puts - const jsonB2 = { _id: '2', name: 'fromB' }; - const putResultB2 = await dbB.put(jsonB2); - - // It will occur conflict on id 1.json. - const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; - expect(syncResult1.action).toBe('resolve conflicts and push'); - expect(syncResult1.commits).toMatchObject({ - local: getCommitInfo([ - putResultA1, - putResultA2dash, - `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, - ]), - remote: getCommitInfo([ - putResultB1, - putResultB2, - `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, - ]), - }); - expect(syncResult1.changes.local.length).toBe(0); - - expect(syncResult1.changes.remote.length).toBe(2); - expect(syncResult1.changes.remote).toEqual([ - getChangedFileUpdate(jsonA1, putResultA1, jsonB1, putResultB1), - getChangedFileUpdate(jsonA2, putResultA2dash, jsonB2, putResultB2), - ]); - - expect(syncResult1.conflicts.length).toEqual(1); - expect(syncResult1.conflicts).toEqual([ - { - fatDoc: { - _id: '1', - name: '1.json', - fileOid: putResultB1.fileOid, - type: 'json', - doc: jsonB1, - }, - strategy: 'ours', - operation: 'insert', - }, - ]); - // Conflict occurs on 1.json - - expect(getWorkingDirDocs(dbB)).toEqual([jsonB1, jsonB2]); - // Sync dbA - const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; - expect(getWorkingDirDocs(dbA)).toEqual([jsonB1, jsonB2]); - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); - - await destroyDBs([dbA, dbB]); - }); - - /** - * before: jsonA1 - * dbA : +jsonA1 - * dbB : jsonB1 - * after : jsonB1 - * - * 3-way merge: - * jsonB1:16 - Conflict. Accept ours (update) - */ - it('resolves case 16 - Conflict. Accept ours (update)', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - conflictResolutionStrategy: 'ours', - }); - // A puts and pushes - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResultA1 = await dbA.put(jsonA1); - await syncA.tryPush(); - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir, - }); - // Clone dbA - await dbB.open(); - const syncB = await dbB.sync(syncA.options); - - // A puts and pushes - const jsonA1dash = { _id: '1', name: 'updated' }; - const putResultA1dash = await dbA.put(jsonA1dash); - await syncA.tryPush(); - - // B puts - const jsonB1 = { _id: '1', name: 'fromB' }; - const putResultB1 = await dbB.put(jsonB1); - - // It will occur conflict on id 1.json. - const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; - expect(syncResult1.action).toBe('resolve conflicts and push'); - expect(syncResult1.commits).toMatchObject({ - local: getCommitInfo([ - putResultA1dash, - `resolve: 1${JSON_EXT}(update,${putResultB1.fileOid.substr(0, 7)},ours)`, - ]), - remote: getCommitInfo([ - putResultB1, - `resolve: 1${JSON_EXT}(update,${putResultB1.fileOid.substr(0, 7)},ours)`, - ]), - }); - expect(syncResult1.changes.local.length).toBe(0); - - expect(syncResult1.changes.remote.length).toBe(1); - expect(syncResult1.changes.remote).toEqual([ - getChangedFileUpdate(jsonA1dash, putResultA1dash, jsonB1, putResultB1), - ]); - - expect(syncResult1.conflicts.length).toEqual(1); - expect(syncResult1.conflicts).toEqual([ - { - fatDoc: { - _id: '1', - name: '1.json', - fileOid: putResultB1.fileOid, - type: 'json', - doc: jsonB1, - }, - strategy: 'ours', - operation: 'update', - }, - ]); - // Conflict occurs on 1.json - - expect(getWorkingDirDocs(dbB)).toEqual([jsonB1]); - // Sync dbA - const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; - expect(getWorkingDirDocs(dbA)).toEqual([jsonB1]); - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); - - await destroyDBs([dbA, dbB]); - }); - - /** - * before: jsonA1 - * dbA : +jsonA1 - * dbB : jsonB1 - * after : +jsonA1 - * - * 3-way merge: - * jsonA1:17 - Conflict. Accept theirs (update) - */ - it('resolves case 17 - Conflict. Accept theirs (update)', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - conflictResolutionStrategy: 'theirs', - }); - // A puts and pushes - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResultA1 = await dbA.put(jsonA1); - await syncA.tryPush(); - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir, - }); - // Clone dbA - await dbB.open(); - const syncB = await dbB.sync({ - ...syncA.options, - conflictResolutionStrategy: 'theirs', - }); - - // A puts and pushes - const jsonA1dash = { _id: '1', name: 'updated' }; - const putResultA1dash = await dbA.put(jsonA1dash); - await syncA.tryPush(); - - // B puts - const jsonB1 = { _id: '1', name: 'fromB' }; - const putResultB1 = await dbB.put(jsonB1); - - // It will occur conflict on id 1.json. - const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; - expect(syncResult1.action).toBe('resolve conflicts and push'); - expect(syncResult1.commits).toMatchObject({ - local: getCommitInfo([ - putResultA1dash, - `resolve: 1${JSON_EXT}(update,${putResultA1dash.fileOid.substr(0, 7)},theirs)`, - ]), - remote: getCommitInfo([ - putResultB1, - `resolve: 1${JSON_EXT}(update,${putResultA1dash.fileOid.substr(0, 7)},theirs)`, - ]), - }); - expect(syncResult1.changes.local.length).toBe(1); - expect(syncResult1.changes.local).toEqual([ - getChangedFileUpdate(jsonB1, putResultB1, jsonA1dash, putResultA1dash), - ]); - - expect(syncResult1.changes.remote.length).toBe(0); - - expect(syncResult1.conflicts.length).toEqual(1); - expect(syncResult1.conflicts).toEqual([ - { - fatDoc: { - _id: '1', - name: '1.json', - fileOid: putResultA1dash.fileOid, - type: 'json', - doc: jsonA1dash, - }, - strategy: 'theirs', - operation: 'update', - }, - ]); - // Conflict occurs on 1.json - - expect(getWorkingDirDocs(dbA)).toEqual([jsonA1dash]); - expect(getWorkingDirDocs(dbB)).toEqual([jsonA1dash]); - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); - - await destroyDBs([dbA, dbB]); - }); - - /** - * before: jsonA1 jsonA2 jsonA3 - * dbA : +jsonA1 -jsonA2 +jsonA3 - * dbB : -jsonA1 +jsonB2 +jsonB3 - * result: jsonB2 jsonB3 - * - * 3-way merge: - * jsonA1: 8 - Conflict. Accept ours (delete) - * jsonB2: 4 - Conflict. Accept ours (insert) - * jsonB3:11 - Conflict. Accept ours (update) - */ - it('resolves many conflicts', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - conflictResolutionStrategy: 'ours', - }); - // A puts and pushes - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResultA1 = await dbA.put(jsonA1); - const jsonA2 = { _id: '2', name: 'fromA' }; - const putResultA2 = await dbA.put(jsonA2); - const jsonA3 = { _id: '3', name: 'fromA' }; - const putResultA3 = await dbA.put(jsonA3); - await syncA.tryPush(); - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir, - }); - // Clone dbA - await dbB.open(); - const syncB = await dbB.sync(syncA.options); - - // A updates, deletes, updates, and pushes - - // change commit order for test - // 3 -> 1 -> 2 - const jsonA3dash = { _id: '3', name: 'updated' }; - const putResultA3dash = await dbA.put(jsonA3dash); - - const jsonA1dash = { _id: '1', name: 'updated' }; - const putResultA1dash = await dbA.put(jsonA1dash); - - const deleteResultA2 = await dbA.delete(jsonA2); - - await syncA.tryPush(); - - // B deletes, updates, updates, and syncs - - // change commit order for test - // 3 -> 1 -> 2 - const jsonB3 = { _id: '3', name: 'fromB' }; - const putResultB3 = await dbB.put(jsonB3); - - const deleteResultB1 = await dbB.delete(jsonA1); - - const jsonB2 = { _id: '2', name: 'fromB' }; - const putResultB2 = await dbB.put(jsonB2); - - const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; - expect(syncResult1.action).toBe('resolve conflicts and push'); - expect(syncResult1.commits).toMatchObject({ - local: getCommitInfo([ - putResultA3dash, - putResultA1dash, - deleteResultA2, - `resolve: 1${JSON_EXT}(delete,${deleteResultB1.fileOid.substr( - 0, - 7 - )},ours), 2${JSON_EXT}(update,${putResultB2.fileOid.substr( - 0, - 7 - )},ours), 3${JSON_EXT}(update,${putResultB3.fileOid.substr(0, 7)},ours)`, - ]), - remote: getCommitInfo([ - putResultB3, - deleteResultB1, - putResultB2, - `resolve: 1${JSON_EXT}(delete,${deleteResultB1.fileOid.substr( - 0, - 7 - )},ours), 2${JSON_EXT}(update,${putResultB2.fileOid.substr( - 0, - 7 - )},ours), 3${JSON_EXT}(update,${putResultB3.fileOid.substr(0, 7)},ours)`, - ]), - }); - expect(syncResult1.changes.local.length).toBe(0); - - expect(syncResult1.changes.remote.length).toBe(3); - expect(syncResult1.changes.remote).toEqual( - expect.arrayContaining([ - getChangedFileDelete(jsonA1dash, putResultA1dash), - getChangedFileInsert(jsonB2, putResultB2), - getChangedFileUpdate(jsonA3dash, putResultA3dash, jsonB3, putResultB3), - ]) - ); - - expect(syncResult1.conflicts).toEqual( - expect.arrayContaining([ - { - fatDoc: { - _id: '1', - name: '1.json', - fileOid: deleteResultB1.fileOid, - type: 'json', - doc: jsonA1, - }, - strategy: 'ours', - operation: 'delete', - }, - { - fatDoc: { - _id: '2', - name: '2.json', - fileOid: putResultB2.fileOid, - type: 'json', - doc: jsonB2, - }, - strategy: 'ours', - operation: 'update', - }, - { - fatDoc: { - _id: '3', - name: '3.json', - fileOid: putResultB3.fileOid, - type: 'json', - doc: jsonB3, - }, - strategy: 'ours', - operation: 'update', - }, - ]) - ); - // Conflict occurs on 1.json - - expect(getWorkingDirDocs(dbB)).toEqual([jsonB2, jsonB3]); - - // Sync dbA - const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; - expect(getWorkingDirDocs(dbA)).toEqual([jsonB2, jsonB3]); - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); - - await destroyDBs([dbA, dbB]); - }); - - /** - * before: jsonA1 - * dbA : +jsonA1 - * dbB : jsonB1 - * after : jsonB1 - * - * 3-way merge: - * jsonB1:16 - Conflict. Accept ours (update) - */ - it('resolves case 16 by user strategy function.', async () => { - const userStrategyByDate = (ours?: FatDoc, theirs?: FatDoc) => { - if (ours === undefined || theirs === undefined) { - throw new Error('Undefined document'); - } - if ((ours.doc as JsonDoc).date > (theirs.doc as JsonDoc).date) { - return 'ours'; - } - return 'theirs'; - }; - - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - conflictResolutionStrategy: userStrategyByDate, - }); - // A puts and pushes - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResultA1 = await dbA.put(jsonA1); - await syncA.tryPush(); - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir, - }); - // Clone dbA - await dbB.open(); - const syncB = await dbB.sync(syncA.options); - - // A puts and pushes - const jsonA1dash = { _id: '1', name: 'updated', date: '2021/05/16' }; - const putResultA1dash = await dbA.put(jsonA1dash); - await syncA.tryPush(); - - // B puts - const jsonB1 = { _id: '1', name: 'fromB', date: '2021/06/16' }; - const putResultB1 = await dbB.put(jsonB1); - - // It will occur conflict on id 1.json. - const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; - expect(syncResult1.action).toBe('resolve conflicts and push'); - expect(syncResult1.commits).toMatchObject({ - local: getCommitInfo([ - putResultA1dash, - `resolve: 1${JSON_EXT}(update,${putResultB1.fileOid.substr(0, 7)},ours)`, - ]), - remote: getCommitInfo([ - putResultB1, - `resolve: 1${JSON_EXT}(update,${putResultB1.fileOid.substr(0, 7)},ours)`, - ]), - }); - expect(syncResult1.changes.local.length).toBe(0); - - expect(syncResult1.changes.remote.length).toBe(1); - expect(syncResult1.changes.remote).toEqual([ - getChangedFileUpdate(jsonA1dash, putResultA1dash, jsonB1, putResultB1), - ]); - - expect(syncResult1.conflicts.length).toEqual(1); - expect(syncResult1.conflicts).toEqual([ - { - fatDoc: { - _id: '1', - name: '1.json', - fileOid: putResultB1.fileOid, - type: 'json', - doc: jsonB1, - }, - strategy: 'ours', - operation: 'update', - }, - ]); - // Conflict occurs on 1.json - - expect(getWorkingDirDocs(dbB)).toEqual([jsonB1]); - // Sync dbA - const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; - expect(getWorkingDirDocs(dbA)).toEqual([jsonB1]); - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); - - await destroyDBs([dbA, dbB]); - }); - - /** - * before: jsonA1 - * dbA : +jsonA1 - * dbB : jsonB1 - * after : +jsonA1 - * - * 3-way merge: - * jsonA1:17 - Conflict. Accept theirs (update) - */ - it('resolves case 17 by user strategy function.', async () => { - const userStrategyByDate = (ours?: FatDoc, theirs?: FatDoc) => { - if (ours === undefined || theirs === undefined) { - throw new Error('Undefined document'); - } - if ((ours.doc as JsonDoc).date > (theirs.doc as JsonDoc).date) { - return 'ours'; - } - return 'theirs'; - }; - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - conflictResolutionStrategy: userStrategyByDate, - }); - // A puts and pushes - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResultA1 = await dbA.put(jsonA1); - await syncA.tryPush(); - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir, - }); - // Clone dbA - await dbB.open(); - const syncB = await dbB.sync({ - ...syncA.options, - conflictResolutionStrategy: 'theirs', - }); - - // A puts and pushes - const jsonA1dash = { _id: '1', name: 'updated', date: '2021/06/16' }; - const putResultA1dash = await dbA.put(jsonA1dash); - await syncA.tryPush(); - - // B puts - const jsonB1 = { _id: '1', name: 'fromB', date: '2021/05/16' }; - const putResultB1 = await dbB.put(jsonB1); - - // It will occur conflict on id 1.json. - const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; - expect(syncResult1.action).toBe('resolve conflicts and push'); - expect(syncResult1.commits).toMatchObject({ - local: getCommitInfo([ - putResultA1dash, - `resolve: 1${JSON_EXT}(update,${putResultA1dash.fileOid.substr(0, 7)},theirs)`, - ]), - remote: getCommitInfo([ - putResultB1, - `resolve: 1${JSON_EXT}(update,${putResultA1dash.fileOid.substr(0, 7)},theirs)`, - ]), - }); - expect(syncResult1.changes.local.length).toBe(1); - expect(syncResult1.changes.local).toEqual([ - getChangedFileUpdate(jsonB1, putResultB1, jsonA1dash, putResultA1dash), - ]); - - expect(syncResult1.changes.remote.length).toBe(0); - - expect(syncResult1.conflicts.length).toEqual(1); - expect(syncResult1.conflicts).toEqual([ - { - fatDoc: { - _id: '1', - name: '1.json', - fileOid: putResultA1dash.fileOid, - type: 'json', - doc: jsonA1dash, - }, - strategy: 'theirs', - operation: 'update', - }, - ]); - // Conflict occurs on 1.json - - expect(getWorkingDirDocs(dbA)).toEqual([jsonA1dash]); - expect(getWorkingDirDocs(dbB)).toEqual([jsonA1dash]); - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); - - await destroyDBs([dbA, dbB]); - }); -}); diff --git a/test/remote_base/3way_merge.ts b/test/remote_base/3way_merge.ts new file mode 100644 index 00000000..46795281 --- /dev/null +++ b/test/remote_base/3way_merge.ts @@ -0,0 +1,1747 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +/** + * Test 3-way merge + * by using GitHub Personal Access Token + * These tests create a new repository on GitHub if not exists. + */ +import expect from 'expect'; +import sinon from 'sinon'; +import { Err } from '../../src/error'; +import { threeWayMerge } from '../../src/remote/3way_merge'; +import { GitDocumentDB } from '../../src/git_documentdb'; +import { + ConnectionSettings, + FatDoc, + JsonDoc, + SyncResultMergeAndPush, + SyncResultResolveConflictsAndPush, +} from '../../src/types'; +import { + compareWorkingDirAndBlobs, + createClonedDatabases, + createDatabase, + destroyDBs, + getChangedFileDelete, + getChangedFileInsert, + getChangedFileUpdate, + getCommitInfo, + getWorkingDirDocs, + removeRemoteRepositories, +} from '../remote_utils'; +import { JSON_EXT } from '../../src/const'; + +// eslint-disable-next-line @typescript-eslint/no-var-requires +const pushWorker_module = require('../../src/remote/push_worker'); + +export const syncThreeWayMergeBase = ( + connection: ConnectionSettings, + remoteURLBase: string, + reposPrefix: string, + localDir: string +) => () => { + let idCounter = 0; + const serialId = () => { + return `${reposPrefix}${idCounter++}`; + }; + + // Use sandbox to restore stub and spy in parallel mocha tests + let sandbox: sinon.SinonSandbox; + beforeEach(function () { + sandbox = sinon.createSandbox(); + }); + + afterEach(function () { + sandbox.restore(); + }); + + before(async () => { + await removeRemoteRepositories(reposPrefix); + }); + + describe('', () => { + it('throws InvalidConflictsStateError', async () => { + const [dbA, dbB, syncA, syncB] = await createClonedDatabases( + remoteURLBase, + localDir, + serialId, + { + conflictResolutionStrategy: 'ours', + connection, + } + ); + + await expect( + // @ts-ignore + threeWayMerge(dbA, syncA, 'ours-diff', 'foo', undefined, undefined, undefined) + ).rejects.toThrowError(Err.InvalidConflictStateError); + }); + + /** + * before: + * dbA : jsonA1 jsonA2 + * dbB : jsonB1 jsonB3 + * after : jsonB1 jsonA2 jsonB3 + * + * 3-way merge: + * jsonB1: 4 - Conflict. Accept ours (insert) + * jsonA2: 1 - Accept theirs (insert) + * jsonB3: 2 - Accept ours (insert) + */ + it('resolves case 1 - Accept theirs (insert), case 2 - Accept ours (insert), case 4 - Conflict. Accept ours (insert)', async () => { + const [dbA, dbB, syncA, syncB] = await createClonedDatabases( + remoteURLBase, + localDir, + serialId, + { + conflictResolutionStrategy: 'ours', + connection, + } + ); + + // A puts and pushes + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResultA1 = await dbA.put(jsonA1); + const jsonA2 = { _id: '2', name: 'fromA' }; + const putResultA2 = await dbA.put(jsonA2); + await syncA.tryPush(); + + // B puts the same file + const jsonB1 = { _id: '1', name: 'fromB' }; + const putResultB1 = await dbB.put(jsonB1); + + // B puts a new file + const jsonB3 = { _id: '3', name: 'fromB' }; + const putResultB3 = await dbB.put(jsonB3); + + // It will occur conflict on id 1.json. + const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; + expect(syncResult1.action).toBe('resolve conflicts and push'); + expect(syncResult1.commits).toMatchObject({ + local: getCommitInfo([ + putResultA1, + putResultA2, + `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + ]), + remote: getCommitInfo([ + putResultB1, + putResultB3, + `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + ]), + }); + expect(syncResult1.changes.local.length).toBe(1); + expect(syncResult1.changes.local).toEqual([ + getChangedFileInsert(jsonA2, putResultA2), + ]); + + expect(syncResult1.changes.remote.length).toBe(2); + expect(syncResult1.changes.remote).toEqual( + expect.arrayContaining([ + getChangedFileInsert(jsonB3, putResultB3), + getChangedFileUpdate(jsonA1, putResultA1, jsonB1, putResultB1), + ]) + ); + + expect(syncResult1.conflicts.length).toEqual(1); + expect(syncResult1.conflicts).toEqual([ + { + fatDoc: { + _id: '1', + name: '1.json', + fileOid: putResultB1.fileOid, + type: 'json', + doc: jsonB1, + }, + strategy: 'ours', + operation: 'insert', + }, + ]); + // Conflict occurs on 1.json + + expect(getWorkingDirDocs(dbB)).toEqual([jsonB1, jsonA2, jsonB3]); + // Sync dbA + await syncA.trySync(); + expect(getWorkingDirDocs(dbA)).toEqual([jsonB1, jsonA2, jsonB3]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + + await destroyDBs([dbA, dbB]); + }); + + /** + * before: + * dbA : jsonA1 jsonA2 + * dbB : jsonB1 jsonA2 + * after : jsonB1 jsonA2 + * + * 3-way merge: + * jsonB1: 4 - Conflict. Accept ours (insert) + * jsonA2: 3 - Accept both (insert) + */ + it('resolves case 3 - Accept both (insert), case 4 - Conflict. Accept ours (insert)', async () => { + const [dbA, dbB, syncA, syncB] = await createClonedDatabases( + remoteURLBase, + localDir, + serialId, + { + conflictResolutionStrategy: 'ours', + connection, + } + ); + + // A puts and pushes + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResultA1 = await dbA.put(jsonA1); + const jsonA2 = { _id: '2', name: 'fromA' }; + const putResultA2 = await dbA.put(jsonA2); + await syncA.tryPush(); + + // B puts the same file + const jsonB1 = { _id: '1', name: 'fromB' }; + const putResultB1 = await dbB.put(jsonB1); + + // B puts the same file with the same contents + const putResultB2 = await dbB.put(jsonA2); + + // It will occur conflict on id 1.json. + const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; + expect(syncResult1.action).toBe('resolve conflicts and push'); + expect(syncResult1.commits).toMatchObject({ + local: getCommitInfo([ + putResultA1, + putResultA2, + `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + ]), + remote: getCommitInfo([ + putResultB1, + putResultB2, + `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + ]), + }); + expect(syncResult1.changes.local.length).toBe(0); + + expect(syncResult1.changes.remote.length).toBe(1); + expect(syncResult1.changes.remote).toEqual([ + getChangedFileUpdate(jsonA1, putResultA1, jsonB1, putResultB1), + ]); + + expect(syncResult1.conflicts.length).toEqual(1); + expect(syncResult1.conflicts).toEqual([ + { + fatDoc: { + _id: '1', + name: '1.json', + fileOid: putResultB1.fileOid, + type: 'json', + doc: jsonB1, + }, + strategy: 'ours', + operation: 'insert', + }, + ]); + // Conflict occurs on 1.json + + expect(getWorkingDirDocs(dbB)).toEqual([jsonB1, jsonA2]); + // Sync dbA + const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; + expect(getWorkingDirDocs(dbA)).toEqual([jsonB1, jsonA2]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + + await destroyDBs([dbA, dbB]); + }); + + /** + * before: + * dbA : jsonA1 + * dbB : jsonB1 + * after : jsonA1 + * + * 3-way merge: + * jsonA1: 5 - Conflict. Accept theirs (insert) + */ + it('resolves case 5 - Conflict. Accept theirs (insert)', async () => { + const [dbA, dbB, syncA, syncB] = await createClonedDatabases( + remoteURLBase, + localDir, + serialId, + { + conflictResolutionStrategy: 'theirs', + connection, + } + ); + + // A puts and pushes + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResultA1 = await dbA.put(jsonA1); + await syncA.tryPush(); + + // B puts the same file + const jsonB1 = { _id: '1', name: 'fromB' }; + const putResultB1 = await dbB.put(jsonB1); + + // It will occur conflict on id 1.json. + const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; + expect(syncResult1.action).toBe('resolve conflicts and push'); + expect(syncResult1.commits).toMatchObject({ + local: getCommitInfo([ + putResultA1, + `resolve: 1${JSON_EXT}(insert,${putResultA1.fileOid.substr(0, 7)},theirs)`, + ]), + remote: getCommitInfo([ + putResultB1, + `resolve: 1${JSON_EXT}(insert,${putResultA1.fileOid.substr(0, 7)},theirs)`, + ]), + }); + expect(syncResult1.changes.local.length).toBe(1); + expect(syncResult1.changes.local).toEqual([ + getChangedFileUpdate(jsonB1, putResultB1, jsonA1, putResultA1), + ]); + + expect(syncResult1.changes.remote.length).toBe(0); + + expect(syncResult1.conflicts.length).toEqual(1); + expect(syncResult1.conflicts).toEqual([ + { + fatDoc: { + _id: '1', + name: '1.json', + fileOid: putResultA1.fileOid, + type: 'json', + doc: jsonA1, + }, + strategy: 'theirs', + operation: 'insert', + }, + ]); + expect(getWorkingDirDocs(dbA)).toEqual([jsonA1]); + expect(getWorkingDirDocs(dbB)).toEqual([jsonA1]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + + await destroyDBs([dbA, dbB]); + }); + + /** + * before: jsonA2 + * dbA : jsonA1 -jsonA2 + * dbB : jsonB1 -jsonA2 + * after : jsonB1 + * + * '-' means delete + * + * 3-way merge: + * jsonB1: 4 - Conflict. Accept ours (insert) + * jsonA2: 6 - Accept both (delete) + */ + it('resolves case 6 - Accept both (delete), case 4 - Conflict. Accept ours (insert)', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + conflictResolutionStrategy: 'ours', + connection, + }); + // A puts and pushes + const jsonA2 = { _id: '2', name: 'fromA' }; + await dbA.put(jsonA2); + await syncA.tryPush(); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir, + }); + // Clone dbA + await dbB.open(); + const syncB = await dbB.sync(syncA.options); + + // A puts, deletes, and pushes + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResultA1 = await dbA.put(jsonA1); + + const deleteResultA2 = await dbA.delete(jsonA2); + await syncA.tryPush(); + + // B puts the same file + const jsonB1 = { _id: '1', name: 'fromB' }; + const putResultB1 = await dbB.put(jsonB1); + + // B deletes the same file + const deleteResultB2 = await dbB.delete(jsonA2); + + // It will occur conflict on id 1.json. + const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; + expect(syncResult1.action).toBe('resolve conflicts and push'); + expect(syncResult1.commits).toMatchObject({ + local: getCommitInfo([ + putResultA1, + deleteResultA2, + `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + ]), + remote: getCommitInfo([ + putResultB1, + deleteResultB2, + `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + ]), + }); + expect(syncResult1.changes.local.length).toBe(0); + + expect(syncResult1.changes.remote.length).toBe(1); + expect(syncResult1.changes.remote).toEqual([ + getChangedFileUpdate(jsonA1, putResultA1, jsonB1, putResultB1), + ]); + + expect(syncResult1.conflicts.length).toEqual(1); + expect(syncResult1.conflicts).toEqual([ + { + fatDoc: { + _id: '1', + name: '1.json', + fileOid: putResultB1.fileOid, + type: 'json', + doc: jsonB1, + }, + strategy: 'ours', + operation: 'insert', + }, + ]); + // Conflict occurs on 1.json + + expect(getWorkingDirDocs(dbB)).toEqual([jsonB1]); + // Sync dbA + const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; + expect(getWorkingDirDocs(dbA)).toEqual([jsonB1]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + + await destroyDBs([dbA, dbB]); + }); + + /** + * before: jsonA2 + * dbA : jsonA1 + * dbB : jsonB1 -jsonA2 + * after : jsonB1 + * + * 3-way merge: + * jsonB1: 4 - Conflict. Accept ours (insert) + * jsonA2: 7 - Accept ours (delete) + */ + it('resolves case 7 - Accept ours (delete), case 4 - Conflict. Accept ours (insert)', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + conflictResolutionStrategy: 'ours', + connection, + }); + // A puts and pushes + const jsonA2 = { _id: '2', name: 'fromA' }; + await dbA.put(jsonA2); + await syncA.tryPush(); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir, + }); + // Clone dbA + await dbB.open(); + const syncB = await dbB.sync(syncA.options); + + // A puts and pushes + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResultA1 = await dbA.put(jsonA1); + await syncA.tryPush(); + + // B puts the same file + const jsonB1 = { _id: '1', name: 'fromB' }; + const putResultB1 = await dbB.put(jsonB1); + + // B deletes the same file + const deleteResultB2 = await dbB.delete(jsonA2); + + // It will occur conflict on id 1.json. + const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; + expect(syncResult1.action).toBe('resolve conflicts and push'); + expect(syncResult1.commits).toMatchObject({ + local: getCommitInfo([ + putResultA1, + `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + ]), + remote: getCommitInfo([ + putResultB1, + deleteResultB2, + `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + ]), + }); + expect(syncResult1.changes.local.length).toBe(0); + + expect(syncResult1.changes.remote.length).toBe(2); + expect(syncResult1.changes.remote).toEqual( + expect.arrayContaining([ + getChangedFileUpdate(jsonA1, putResultA1, jsonB1, putResultB1), + getChangedFileDelete(jsonA2, deleteResultB2), + ]) + ); + + expect(syncResult1.conflicts.length).toEqual(1); + expect(syncResult1.conflicts).toEqual([ + { + fatDoc: { + _id: '1', + name: '1.json', + fileOid: putResultB1.fileOid, + type: 'json', + doc: jsonB1, + }, + strategy: 'ours', + operation: 'insert', + }, + ]); + // Conflict occurs on 1.json + + expect(getWorkingDirDocs(dbB)).toEqual([jsonB1]); + // Sync dbA + const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; + expect(getWorkingDirDocs(dbA)).toEqual([jsonB1]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + + await destroyDBs([dbA, dbB]); + }); + + /** + * before: jsonA1 + * dbA : +jsonA1 + * dbB : -jsonA1 + * result: + * + * '+' means update + * + * 3-way merge: + * jsonA1: 8 - Conflict. Accept ours (delete) + */ + it('resolves case 8 - Conflict. Accept ours (delete)', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + conflictResolutionStrategy: 'ours', + connection, + }); + // A puts and pushes + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResultA1 = await dbA.put(jsonA1); + await syncA.tryPush(); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir, + }); + // Clone dbA + await dbB.open(); + const syncB = await dbB.sync(syncA.options); + + // A updates and pushes + const jsonA1dash = { _id: '1', name: 'updated' }; + const putResultA1dash = await dbA.put(jsonA1dash); + await syncA.tryPush(); + + // B deletes and syncs + const deleteResultB1 = await dbB.delete(jsonA1); + + const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; + expect(syncResult1.action).toBe('resolve conflicts and push'); + expect(syncResult1.commits).toMatchObject({ + local: getCommitInfo([ + putResultA1dash, + `resolve: 1${JSON_EXT}(delete,${deleteResultB1.fileOid.substr(0, 7)},ours)`, + ]), + remote: getCommitInfo([ + deleteResultB1, + `resolve: 1${JSON_EXT}(delete,${deleteResultB1.fileOid.substr(0, 7)},ours)`, + ]), + }); + expect(syncResult1.changes.local.length).toBe(0); + + expect(syncResult1.changes.remote.length).toBe(1); + expect(syncResult1.changes.remote).toEqual([ + getChangedFileDelete(jsonA1dash, putResultA1dash), + ]); + + expect(syncResult1.conflicts.length).toEqual(1); + expect(syncResult1.conflicts).toEqual([ + { + fatDoc: { + _id: '1', + name: '1.json', + fileOid: deleteResultB1.fileOid, + type: 'json', + doc: jsonA1, + }, + strategy: 'ours', + operation: 'delete', + }, + ]); + // Conflict occurs on 1.json + + expect(getWorkingDirDocs(dbB)).toEqual([]); + + // Sync dbA + const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; + expect(getWorkingDirDocs(dbA)).toEqual([]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + + await destroyDBs([dbA, dbB]); + }); + + /** + * before: jsonA1 + * dbA : +jsonA1 + * dbB : -jsonA1 + * result: jsonA1 + * + * '+' means update + * + * 3-way merge: + * jsonA1: 9 - Conflict. Accept theirs (update) + */ + it('resolves case 9 - Conflict. Accept ours (delete)', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + conflictResolutionStrategy: 'theirs', + connection, + }); + // A puts and pushes + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResultA1 = await dbA.put(jsonA1); + await syncA.tryPush(); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir, + }); + // Clone dbA + await dbB.open(); + const syncB = await dbB.sync(syncA.options); + + // A updates and pushes + const jsonA1dash = { _id: '1', name: 'updated' }; + const putResultA1dash = await dbA.put(jsonA1dash); + await syncA.tryPush(); + + // B deletes and syncs + const deleteResultB1 = await dbB.delete(jsonA1); + + const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; + expect(syncResult1.action).toBe('resolve conflicts and push'); + expect(syncResult1.commits).toMatchObject({ + local: getCommitInfo([ + putResultA1dash, + `resolve: 1${JSON_EXT}(update,${putResultA1dash.fileOid.substr(0, 7)},theirs)`, + ]), + remote: getCommitInfo([ + deleteResultB1, + `resolve: 1${JSON_EXT}(update,${putResultA1dash.fileOid.substr(0, 7)},theirs)`, + ]), + }); + + expect(syncResult1.changes.local.length).toBe(1); + expect(syncResult1.changes.local).toEqual([ + getChangedFileInsert(jsonA1dash, putResultA1dash), + ]); + + expect(syncResult1.changes.remote.length).toBe(0); + + expect(syncResult1.conflicts.length).toEqual(1); + expect(syncResult1.conflicts).toEqual([ + { + fatDoc: { + _id: '1', + name: '1.json', + fileOid: putResultA1dash.fileOid, + type: 'json', + doc: jsonA1dash, + }, + strategy: 'theirs', + operation: 'update', + }, + ]); + // Conflict occurs on 1.json + + expect(getWorkingDirDocs(dbA)).toEqual([jsonA1dash]); + expect(getWorkingDirDocs(dbB)).toEqual([jsonA1dash]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + + await destroyDBs([dbA, dbB]); + }); + + /** + * before: jsonA2 + * dbA : jsonA1 -jsonA2 + * dbB : jsonB1 + * after : jsonB1 + * + * 3-way merge: + * jsonB1: 4 - Conflict. Accept ours (insert) + * jsonA2:10 - Accept theirs (delete) + */ + it('resolves case 10 - Accept theirs (delete), case 4 - Conflict. Accept ours (insert)', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + conflictResolutionStrategy: 'ours', + connection, + }); + // A puts and pushes + const jsonA2 = { _id: '2', name: 'fromA' }; + await dbA.put(jsonA2); + await syncA.tryPush(); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir, + }); + // Clone dbA + await dbB.open(); + const syncB = await dbB.sync(syncA.options); + + // A puts, deletes, and pushes + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResultA1 = await dbA.put(jsonA1); + const deleteResultA2 = await dbA.delete(jsonA2); + await syncA.tryPush(); + + // B puts the same file + const jsonB1 = { _id: '1', name: 'fromB' }; + const putResultB1 = await dbB.put(jsonB1); + + // It will occur conflict on id 1.json. + const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; + expect(syncResult1.action).toBe('resolve conflicts and push'); + expect(syncResult1.commits).toMatchObject({ + local: getCommitInfo([ + putResultA1, + deleteResultA2, + `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + ]), + remote: getCommitInfo([ + putResultB1, + `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + ]), + }); + expect(syncResult1.changes.local.length).toBe(1); + expect(syncResult1.changes.local).toEqual([ + getChangedFileDelete(jsonA2, deleteResultA2), + ]); + + expect(syncResult1.changes.remote.length).toBe(1); + expect(syncResult1.changes.remote).toEqual([ + getChangedFileUpdate(jsonA1, putResultA1, jsonB1, putResultB1), + ]); + + expect(syncResult1.conflicts.length).toEqual(1); + expect(syncResult1.conflicts).toEqual([ + { + fatDoc: { + _id: '1', + name: '1.json', + fileOid: putResultB1.fileOid, + type: 'json', + doc: jsonB1, + }, + strategy: 'ours', + operation: 'insert', + }, + ]); + // Conflict occurs on 1.json + + expect(getWorkingDirDocs(dbB)).toEqual([jsonB1]); + // Sync dbA + const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; + expect(getWorkingDirDocs(dbA)).toEqual([jsonB1]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + + await destroyDBs([dbA, dbB]); + }); + + /** + * before: jsonA1 + * dbA : -jsonA1 jsonA2 + * dbB : jsonB1 + * result: jsonB1 jsonA2 + * + * 3-way merge: + * jsonB1: 11 - Conflict. Accept ours (update) + * jsonA2: 1 - Accept theirs (insert) + */ + it('resolves case 11 - Conflict. Accept ours (update), case 1 - Accept theirs (insert), ', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + conflictResolutionStrategy: 'ours', + connection, + }); + // A puts and pushes + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResultA1 = await dbA.put(jsonA1); + await syncA.tryPush(); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir, + }); + // Clone dbA + await dbB.open(); + const syncB = await dbB.sync(syncA.options); + + // A deletes the old file and puts a new file + const deleteResultA1 = await dbA.delete(jsonA1); + const jsonA2 = { _id: '2', name: 'fromA' }; + const putResultA2 = await dbA.put(jsonA2); + await syncA.tryPush(); + + // B updates the old file and syncs + const jsonB1 = { _id: '1', name: 'fromB' }; + const putResultB1 = await dbB.put(jsonB1); + + const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; + expect(syncResult1.action).toBe('resolve conflicts and push'); + expect(syncResult1.commits).toMatchObject({ + local: getCommitInfo([ + deleteResultA1, + putResultA2, + `resolve: 1${JSON_EXT}(update,${putResultB1.fileOid.substr(0, 7)},ours)`, + ]), + remote: getCommitInfo([ + putResultB1, + `resolve: 1${JSON_EXT}(update,${putResultB1.fileOid.substr(0, 7)},ours)`, + ]), + }); + expect(syncResult1.changes.local.length).toBe(1); + expect(syncResult1.changes.local).toEqual([ + getChangedFileInsert(jsonA2, putResultA2), + ]); + + expect(syncResult1.changes.remote.length).toBe(1); + expect(syncResult1.changes.remote).toEqual([ + getChangedFileInsert(jsonB1, putResultB1), + ]); + + expect(syncResult1.conflicts.length).toEqual(1); + expect(syncResult1.conflicts).toEqual([ + { + fatDoc: { + _id: '1', + name: '1.json', + fileOid: putResultB1.fileOid, + type: 'json', + doc: jsonB1, + }, + strategy: 'ours', + operation: 'update', + }, + ]); + // Conflict occurs on 1.json + + expect(getWorkingDirDocs(dbB)).toEqual([jsonB1, jsonA2]); + + // Sync dbA + const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; + expect(getWorkingDirDocs(dbA)).toEqual([jsonB1, jsonA2]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + + await destroyDBs([dbA, dbB]); + }); + + /** + * before: jsonA1 + * dbA : -jsonA1 jsonA2 + * dbB : jsonB1 + * result: jsonA2 + * + * 3-way merge: + * jsonA1: 11 - Conflict. Accept theirs (delete) + * jsonA2: 1 - Accept theirs (insert) + */ + it('resolves case 12 - accept theirs (delete), case 1 - Accept theirs (insert)', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + conflictResolutionStrategy: 'ours', + connection, + }); + // A puts and pushes + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResultA1 = await dbA.put(jsonA1); + await syncA.tryPush(); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir, + }); + // Clone dbA + await dbB.open(); + const syncB = await dbB.sync({ + ...syncA.options, + conflictResolutionStrategy: 'theirs', + }); + + // A deletes the old file and puts a new file + const deleteResultA1 = await dbA.delete(jsonA1); + const jsonA2 = { _id: '2', name: 'fromA' }; + const putResultA2 = await dbA.put(jsonA2); + await syncA.tryPush(); + + // B updates the old file and syncs + const jsonB1 = { _id: '1', name: 'fromB' }; + const putResultB1 = await dbB.put(jsonB1); + + const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; + expect(syncResult1.action).toBe('resolve conflicts and push'); + expect(syncResult1.commits).toMatchObject({ + local: getCommitInfo([ + deleteResultA1, + putResultA2, + `resolve: 1${JSON_EXT}(delete,${deleteResultA1.fileOid.substr(0, 7)},theirs)`, + ]), + remote: getCommitInfo([ + putResultB1, + `resolve: 1${JSON_EXT}(delete,${deleteResultA1.fileOid.substr(0, 7)},theirs)`, + ]), + }); + expect(syncResult1.changes.local.length).toBe(2); + expect(syncResult1.changes.local).toEqual( + expect.arrayContaining([ + getChangedFileDelete(jsonB1, putResultB1), + getChangedFileInsert(jsonA2, putResultA2), + ]) + ); + + expect(syncResult1.changes.remote.length).toBe(0); + + expect(syncResult1.conflicts.length).toEqual(1); + expect(syncResult1.conflicts).toEqual([ + { + fatDoc: { + _id: '1', + name: '1.json', + fileOid: deleteResultA1.fileOid, + type: 'json', + doc: jsonA1, + }, + strategy: 'theirs', + operation: 'delete', + }, + ]); + // Conflict occurs on 1.json + expect(getWorkingDirDocs(dbA)).toEqual([jsonA2]); + expect(getWorkingDirDocs(dbB)).toEqual([jsonA2]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + + await destroyDBs([dbA, dbB]); + }); + + /** + * before: jsonA2 + * dbA : jsonA1 +jsonA2 + * dbB : jsonB1 +jsonA2 + * after : jsonB1 +jsonA2 + * + * 3-way merge: + * jsonB1: 4 - Conflict. Accept ours (insert) + * jsonA2:13 - Accept both (update) + */ + it('resolves case 13 - Accept both (update), case 4 - Conflict. Accept ours (insert)', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + conflictResolutionStrategy: 'ours', + connection, + }); + // A puts and pushes + const jsonA2 = { _id: '2', name: 'fromA' }; + const putResultA2 = await dbA.put(jsonA2); + await syncA.tryPush(); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir, + }); + // Clone dbA + await dbB.open(); + const syncB = await dbB.sync(syncA.options); + + // A puts and pushes + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResultA1 = await dbA.put(jsonA1); + const jsonA2dash = { _id: '2', name: 'updated' }; + const putResultA2dash = await dbA.put(jsonA2dash); + await syncA.tryPush(); + + // B puts the same file + const jsonB1 = { _id: '1', name: 'fromB' }; + const putResultB1 = await dbB.put(jsonB1); + + // B puts the same file with the same contents + const putResultB2 = await dbB.put(jsonA2dash); + + // It will occur conflict on id 1.json. + const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; + expect(syncResult1.action).toBe('resolve conflicts and push'); + expect(syncResult1.commits).toMatchObject({ + local: getCommitInfo([ + putResultA1, + putResultA2dash, + `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + ]), + remote: getCommitInfo([ + putResultB1, + putResultB2, + `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + ]), + }); + expect(syncResult1.changes.local.length).toBe(0); + + expect(syncResult1.changes.remote.length).toBe(1); + expect(syncResult1.changes.remote).toEqual([ + getChangedFileUpdate(jsonA1, putResultA1, jsonB1, putResultB1), + ]); + + expect(syncResult1.conflicts.length).toEqual(1); + expect(syncResult1.conflicts).toEqual([ + { + fatDoc: { + _id: '1', + name: '1.json', + fileOid: putResultB1.fileOid, + type: 'json', + doc: jsonB1, + }, + strategy: 'ours', + operation: 'insert', + }, + ]); + // Conflict occurs on 1.json + + expect(getWorkingDirDocs(dbB)).toEqual([jsonB1, jsonA2dash]); + // Sync dbA + const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; + expect(getWorkingDirDocs(dbA)).toEqual([jsonB1, jsonA2dash]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + + await destroyDBs([dbA, dbB]); + }); + + // case 14 + /** + * before: jsonA2 + * dbA : jsonA1 +jsonA2 + * dbB : jsonB1 jsonA2 + * after : jsonB1 +jsonA2 + * + * 3-way merge: + * jsonB1: 4 - Conflict. Accept ours (insert) + * jsonA2:14 - Accept theirs (update) + */ + it('resolves case 14 - Accept theirs (update), case 4 - Conflict. Accept ours (insert)', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + conflictResolutionStrategy: 'ours', + connection, + }); + // A puts and pushes + const jsonA2 = { _id: '2', name: 'fromA' }; + const putResultA2 = await dbA.put(jsonA2); + await syncA.tryPush(); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir, + }); + // Clone dbA + await dbB.open(); + const syncB = await dbB.sync(syncA.options); + + // A puts and pushes + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResultA1 = await dbA.put(jsonA1); + const jsonA2dash = { _id: '2', name: 'updated' }; + const putResultA2dash = await dbA.put(jsonA2dash); + await syncA.tryPush(); + + // B puts the same file + const jsonB1 = { _id: '1', name: 'fromB' }; + const putResultB1 = await dbB.put(jsonB1); + + // B puts the same file with the previous contents + const putResultB2 = await dbB.put(jsonA2); + + // It will occur conflict on id 1.json. + const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; + expect(syncResult1.action).toBe('resolve conflicts and push'); + expect(syncResult1.commits).toMatchObject({ + local: getCommitInfo([ + putResultA1, + putResultA2dash, + `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + ]), + remote: getCommitInfo([ + putResultB1, + putResultB2, + `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + ]), + }); + expect(syncResult1.changes.local.length).toBe(1); + expect(syncResult1.changes.local).toEqual([ + getChangedFileUpdate(jsonA2, putResultB2, jsonA2dash, putResultA2dash), + ]); + + expect(syncResult1.changes.remote.length).toBe(1); + expect(syncResult1.changes.remote).toEqual([ + getChangedFileUpdate(jsonA1, putResultA1, jsonB1, putResultB1), + ]); + + expect(syncResult1.conflicts.length).toEqual(1); + expect(syncResult1.conflicts).toEqual([ + { + fatDoc: { + _id: '1', + name: '1.json', + fileOid: putResultB1.fileOid, + type: 'json', + doc: jsonB1, + }, + strategy: 'ours', + operation: 'insert', + }, + ]); + // Conflict occurs on 1.json + + expect(getWorkingDirDocs(dbB)).toEqual([jsonB1, jsonA2dash]); + // Sync dbA + const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; + expect(getWorkingDirDocs(dbA)).toEqual([jsonB1, jsonA2dash]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + + await destroyDBs([dbA, dbB]); + }); + + /** + * before: jsonA2 + * dbA : jsonA1 jsonA2 + * dbB : jsonB1 jsonB2 + * after : jsonB1 jsonB2 + * + * 3-way merge: + * jsonB1: 4 - Conflict. Accept ours (insert) + * jsonA2:15 - Accept ours (update) + */ + it('resolves case 15 - Accept ours (update), case 4 - Conflict. Accept ours (insert)', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + conflictResolutionStrategy: 'ours', + connection, + }); + // A puts and pushes + const jsonA2 = { _id: '2', name: 'fromA' }; + const putResultA2 = await dbA.put(jsonA2); + await syncA.tryPush(); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir, + }); + // Clone dbA + await dbB.open(); + const syncB = await dbB.sync(syncA.options); + + // A puts + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResultA1 = await dbA.put(jsonA1); + // A puts the previous file and pushes + const putResultA2dash = await dbA.put(jsonA2); + await syncA.tryPush(); + + // B puts the same file + const jsonB1 = { _id: '1', name: 'fromB' }; + const putResultB1 = await dbB.put(jsonB1); + + // B puts + const jsonB2 = { _id: '2', name: 'fromB' }; + const putResultB2 = await dbB.put(jsonB2); + + // It will occur conflict on id 1.json. + const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; + expect(syncResult1.action).toBe('resolve conflicts and push'); + expect(syncResult1.commits).toMatchObject({ + local: getCommitInfo([ + putResultA1, + putResultA2dash, + `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + ]), + remote: getCommitInfo([ + putResultB1, + putResultB2, + `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + ]), + }); + expect(syncResult1.changes.local.length).toBe(0); + + expect(syncResult1.changes.remote.length).toBe(2); + expect(syncResult1.changes.remote).toEqual([ + getChangedFileUpdate(jsonA1, putResultA1, jsonB1, putResultB1), + getChangedFileUpdate(jsonA2, putResultA2dash, jsonB2, putResultB2), + ]); + + expect(syncResult1.conflicts.length).toEqual(1); + expect(syncResult1.conflicts).toEqual([ + { + fatDoc: { + _id: '1', + name: '1.json', + fileOid: putResultB1.fileOid, + type: 'json', + doc: jsonB1, + }, + strategy: 'ours', + operation: 'insert', + }, + ]); + // Conflict occurs on 1.json + + expect(getWorkingDirDocs(dbB)).toEqual([jsonB1, jsonB2]); + // Sync dbA + const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; + expect(getWorkingDirDocs(dbA)).toEqual([jsonB1, jsonB2]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + + await destroyDBs([dbA, dbB]); + }); + + /** + * before: jsonA1 + * dbA : +jsonA1 + * dbB : jsonB1 + * after : jsonB1 + * + * 3-way merge: + * jsonB1:16 - Conflict. Accept ours (update) + */ + it('resolves case 16 - Conflict. Accept ours (update)', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + conflictResolutionStrategy: 'ours', + connection, + }); + // A puts and pushes + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResultA1 = await dbA.put(jsonA1); + await syncA.tryPush(); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir, + }); + // Clone dbA + await dbB.open(); + const syncB = await dbB.sync(syncA.options); + + // A puts and pushes + const jsonA1dash = { _id: '1', name: 'updated' }; + const putResultA1dash = await dbA.put(jsonA1dash); + await syncA.tryPush(); + + // B puts + const jsonB1 = { _id: '1', name: 'fromB' }; + const putResultB1 = await dbB.put(jsonB1); + + // It will occur conflict on id 1.json. + const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; + expect(syncResult1.action).toBe('resolve conflicts and push'); + expect(syncResult1.commits).toMatchObject({ + local: getCommitInfo([ + putResultA1dash, + `resolve: 1${JSON_EXT}(update,${putResultB1.fileOid.substr(0, 7)},ours)`, + ]), + remote: getCommitInfo([ + putResultB1, + `resolve: 1${JSON_EXT}(update,${putResultB1.fileOid.substr(0, 7)},ours)`, + ]), + }); + expect(syncResult1.changes.local.length).toBe(0); + + expect(syncResult1.changes.remote.length).toBe(1); + expect(syncResult1.changes.remote).toEqual([ + getChangedFileUpdate(jsonA1dash, putResultA1dash, jsonB1, putResultB1), + ]); + + expect(syncResult1.conflicts.length).toEqual(1); + expect(syncResult1.conflicts).toEqual([ + { + fatDoc: { + _id: '1', + name: '1.json', + fileOid: putResultB1.fileOid, + type: 'json', + doc: jsonB1, + }, + strategy: 'ours', + operation: 'update', + }, + ]); + // Conflict occurs on 1.json + + expect(getWorkingDirDocs(dbB)).toEqual([jsonB1]); + // Sync dbA + const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; + expect(getWorkingDirDocs(dbA)).toEqual([jsonB1]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + + await destroyDBs([dbA, dbB]); + }); + + /** + * before: jsonA1 + * dbA : +jsonA1 + * dbB : jsonB1 + * after : +jsonA1 + * + * 3-way merge: + * jsonA1:17 - Conflict. Accept theirs (update) + */ + it('resolves case 17 - Conflict. Accept theirs (update)', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + conflictResolutionStrategy: 'theirs', + connection, + }); + // A puts and pushes + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResultA1 = await dbA.put(jsonA1); + await syncA.tryPush(); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir, + }); + // Clone dbA + await dbB.open(); + const syncB = await dbB.sync({ + ...syncA.options, + conflictResolutionStrategy: 'theirs', + }); + + // A puts and pushes + const jsonA1dash = { _id: '1', name: 'updated' }; + const putResultA1dash = await dbA.put(jsonA1dash); + await syncA.tryPush(); + + // B puts + const jsonB1 = { _id: '1', name: 'fromB' }; + const putResultB1 = await dbB.put(jsonB1); + + // It will occur conflict on id 1.json. + const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; + expect(syncResult1.action).toBe('resolve conflicts and push'); + expect(syncResult1.commits).toMatchObject({ + local: getCommitInfo([ + putResultA1dash, + `resolve: 1${JSON_EXT}(update,${putResultA1dash.fileOid.substr(0, 7)},theirs)`, + ]), + remote: getCommitInfo([ + putResultB1, + `resolve: 1${JSON_EXT}(update,${putResultA1dash.fileOid.substr(0, 7)},theirs)`, + ]), + }); + expect(syncResult1.changes.local.length).toBe(1); + expect(syncResult1.changes.local).toEqual([ + getChangedFileUpdate(jsonB1, putResultB1, jsonA1dash, putResultA1dash), + ]); + + expect(syncResult1.changes.remote.length).toBe(0); + + expect(syncResult1.conflicts.length).toEqual(1); + expect(syncResult1.conflicts).toEqual([ + { + fatDoc: { + _id: '1', + name: '1.json', + fileOid: putResultA1dash.fileOid, + type: 'json', + doc: jsonA1dash, + }, + strategy: 'theirs', + operation: 'update', + }, + ]); + // Conflict occurs on 1.json + + expect(getWorkingDirDocs(dbA)).toEqual([jsonA1dash]); + expect(getWorkingDirDocs(dbB)).toEqual([jsonA1dash]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + + await destroyDBs([dbA, dbB]); + }); + + /** + * before: jsonA1 jsonA2 jsonA3 + * dbA : +jsonA1 -jsonA2 +jsonA3 + * dbB : -jsonA1 +jsonB2 +jsonB3 + * result: jsonB2 jsonB3 + * + * 3-way merge: + * jsonA1: 8 - Conflict. Accept ours (delete) + * jsonB2: 4 - Conflict. Accept ours (insert) + * jsonB3:11 - Conflict. Accept ours (update) + */ + it('resolves many conflicts', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + conflictResolutionStrategy: 'ours', + connection, + }); + // A puts and pushes + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResultA1 = await dbA.put(jsonA1); + const jsonA2 = { _id: '2', name: 'fromA' }; + const putResultA2 = await dbA.put(jsonA2); + const jsonA3 = { _id: '3', name: 'fromA' }; + const putResultA3 = await dbA.put(jsonA3); + await syncA.tryPush(); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir, + }); + // Clone dbA + await dbB.open(); + const syncB = await dbB.sync(syncA.options); + + // A updates, deletes, updates, and pushes + + // change commit order for test + // 3 -> 1 -> 2 + const jsonA3dash = { _id: '3', name: 'updated' }; + const putResultA3dash = await dbA.put(jsonA3dash); + + const jsonA1dash = { _id: '1', name: 'updated' }; + const putResultA1dash = await dbA.put(jsonA1dash); + + const deleteResultA2 = await dbA.delete(jsonA2); + + await syncA.tryPush(); + + // B deletes, updates, updates, and syncs + + // change commit order for test + // 3 -> 1 -> 2 + const jsonB3 = { _id: '3', name: 'fromB' }; + const putResultB3 = await dbB.put(jsonB3); + + const deleteResultB1 = await dbB.delete(jsonA1); + + const jsonB2 = { _id: '2', name: 'fromB' }; + const putResultB2 = await dbB.put(jsonB2); + + const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; + expect(syncResult1.action).toBe('resolve conflicts and push'); + expect(syncResult1.commits).toMatchObject({ + local: getCommitInfo([ + putResultA3dash, + putResultA1dash, + deleteResultA2, + `resolve: 1${JSON_EXT}(delete,${deleteResultB1.fileOid.substr( + 0, + 7 + )},ours), 2${JSON_EXT}(update,${putResultB2.fileOid.substr( + 0, + 7 + )},ours), 3${JSON_EXT}(update,${putResultB3.fileOid.substr(0, 7)},ours)`, + ]), + remote: getCommitInfo([ + putResultB3, + deleteResultB1, + putResultB2, + `resolve: 1${JSON_EXT}(delete,${deleteResultB1.fileOid.substr( + 0, + 7 + )},ours), 2${JSON_EXT}(update,${putResultB2.fileOid.substr( + 0, + 7 + )},ours), 3${JSON_EXT}(update,${putResultB3.fileOid.substr(0, 7)},ours)`, + ]), + }); + expect(syncResult1.changes.local.length).toBe(0); + + expect(syncResult1.changes.remote.length).toBe(3); + expect(syncResult1.changes.remote).toEqual( + expect.arrayContaining([ + getChangedFileDelete(jsonA1dash, putResultA1dash), + getChangedFileInsert(jsonB2, putResultB2), + getChangedFileUpdate(jsonA3dash, putResultA3dash, jsonB3, putResultB3), + ]) + ); + + expect(syncResult1.conflicts).toEqual( + expect.arrayContaining([ + { + fatDoc: { + _id: '1', + name: '1.json', + fileOid: deleteResultB1.fileOid, + type: 'json', + doc: jsonA1, + }, + strategy: 'ours', + operation: 'delete', + }, + { + fatDoc: { + _id: '2', + name: '2.json', + fileOid: putResultB2.fileOid, + type: 'json', + doc: jsonB2, + }, + strategy: 'ours', + operation: 'update', + }, + { + fatDoc: { + _id: '3', + name: '3.json', + fileOid: putResultB3.fileOid, + type: 'json', + doc: jsonB3, + }, + strategy: 'ours', + operation: 'update', + }, + ]) + ); + // Conflict occurs on 1.json + + expect(getWorkingDirDocs(dbB)).toEqual([jsonB2, jsonB3]); + + // Sync dbA + const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; + expect(getWorkingDirDocs(dbA)).toEqual([jsonB2, jsonB3]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + + await destroyDBs([dbA, dbB]); + }); + + /** + * before: jsonA1 + * dbA : +jsonA1 + * dbB : jsonB1 + * after : jsonB1 + * + * 3-way merge: + * jsonB1:16 - Conflict. Accept ours (update) + */ + it('resolves case 16 by user strategy function.', async () => { + const userStrategyByDate = (ours?: FatDoc, theirs?: FatDoc) => { + if (ours === undefined || theirs === undefined) { + throw new Error('Undefined document'); + } + if ((ours.doc as JsonDoc).date > (theirs.doc as JsonDoc).date) { + return 'ours'; + } + return 'theirs'; + }; + + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + conflictResolutionStrategy: userStrategyByDate, + connection, + }); + // A puts and pushes + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResultA1 = await dbA.put(jsonA1); + await syncA.tryPush(); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir, + }); + // Clone dbA + await dbB.open(); + const syncB = await dbB.sync(syncA.options); + + // A puts and pushes + const jsonA1dash = { _id: '1', name: 'updated', date: '2021/05/16' }; + const putResultA1dash = await dbA.put(jsonA1dash); + await syncA.tryPush(); + + // B puts + const jsonB1 = { _id: '1', name: 'fromB', date: '2021/06/16' }; + const putResultB1 = await dbB.put(jsonB1); + + // It will occur conflict on id 1.json. + const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; + expect(syncResult1.action).toBe('resolve conflicts and push'); + expect(syncResult1.commits).toMatchObject({ + local: getCommitInfo([ + putResultA1dash, + `resolve: 1${JSON_EXT}(update,${putResultB1.fileOid.substr(0, 7)},ours)`, + ]), + remote: getCommitInfo([ + putResultB1, + `resolve: 1${JSON_EXT}(update,${putResultB1.fileOid.substr(0, 7)},ours)`, + ]), + }); + expect(syncResult1.changes.local.length).toBe(0); + + expect(syncResult1.changes.remote.length).toBe(1); + expect(syncResult1.changes.remote).toEqual([ + getChangedFileUpdate(jsonA1dash, putResultA1dash, jsonB1, putResultB1), + ]); + + expect(syncResult1.conflicts.length).toEqual(1); + expect(syncResult1.conflicts).toEqual([ + { + fatDoc: { + _id: '1', + name: '1.json', + fileOid: putResultB1.fileOid, + type: 'json', + doc: jsonB1, + }, + strategy: 'ours', + operation: 'update', + }, + ]); + // Conflict occurs on 1.json + + expect(getWorkingDirDocs(dbB)).toEqual([jsonB1]); + // Sync dbA + const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; + expect(getWorkingDirDocs(dbA)).toEqual([jsonB1]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + + await destroyDBs([dbA, dbB]); + }); + + /** + * before: jsonA1 + * dbA : +jsonA1 + * dbB : jsonB1 + * after : +jsonA1 + * + * 3-way merge: + * jsonA1:17 - Conflict. Accept theirs (update) + */ + it('resolves case 17 by user strategy function.', async () => { + const userStrategyByDate = (ours?: FatDoc, theirs?: FatDoc) => { + if (ours === undefined || theirs === undefined) { + throw new Error('Undefined document'); + } + if ((ours.doc as JsonDoc).date > (theirs.doc as JsonDoc).date) { + return 'ours'; + } + return 'theirs'; + }; + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + conflictResolutionStrategy: userStrategyByDate, + connection, + }); + // A puts and pushes + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResultA1 = await dbA.put(jsonA1); + await syncA.tryPush(); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir, + }); + // Clone dbA + await dbB.open(); + const syncB = await dbB.sync({ + ...syncA.options, + conflictResolutionStrategy: 'theirs', + }); + + // A puts and pushes + const jsonA1dash = { _id: '1', name: 'updated', date: '2021/06/16' }; + const putResultA1dash = await dbA.put(jsonA1dash); + await syncA.tryPush(); + + // B puts + const jsonB1 = { _id: '1', name: 'fromB', date: '2021/05/16' }; + const putResultB1 = await dbB.put(jsonB1); + + // It will occur conflict on id 1.json. + const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; + expect(syncResult1.action).toBe('resolve conflicts and push'); + expect(syncResult1.commits).toMatchObject({ + local: getCommitInfo([ + putResultA1dash, + `resolve: 1${JSON_EXT}(update,${putResultA1dash.fileOid.substr(0, 7)},theirs)`, + ]), + remote: getCommitInfo([ + putResultB1, + `resolve: 1${JSON_EXT}(update,${putResultA1dash.fileOid.substr(0, 7)},theirs)`, + ]), + }); + expect(syncResult1.changes.local.length).toBe(1); + expect(syncResult1.changes.local).toEqual([ + getChangedFileUpdate(jsonB1, putResultB1, jsonA1dash, putResultA1dash), + ]); + + expect(syncResult1.changes.remote.length).toBe(0); + + expect(syncResult1.conflicts.length).toEqual(1); + expect(syncResult1.conflicts).toEqual([ + { + fatDoc: { + _id: '1', + name: '1.json', + fileOid: putResultA1dash.fileOid, + type: 'json', + doc: jsonA1dash, + }, + strategy: 'theirs', + operation: 'update', + }, + ]); + // Conflict occurs on 1.json + + expect(getWorkingDirDocs(dbA)).toEqual([jsonA1dash]); + expect(getWorkingDirDocs(dbB)).toEqual([jsonA1dash]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + + await destroyDBs([dbA, dbB]); + }); + }); +}; diff --git a/test/remote_nodegit/3way_merge.test.ts b/test/remote_nodegit/3way_merge.test.ts new file mode 100644 index 00000000..41554ee8 --- /dev/null +++ b/test/remote_nodegit/3way_merge.test.ts @@ -0,0 +1,61 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +/** + * Test tryPush + * by using GitHub Personal Access Token + * These tests create a new repository on GitHub if not exists. + */ +import path from 'path'; +import fs from 'fs-extra'; +import { syncThreeWayMergeBase } from '../remote_base/3way_merge'; +import { ConnectionSettingsGitHub } from '../../src/types'; +import { GitDocumentDB } from '../../src/git_documentdb'; + +const reposPrefix = 'test_3way_merge_nodegit__'; +const localDir = `./test/database_3way_merge_nodegit`; + +beforeEach(function () { + // @ts-ignore + console.log(`... ${this.currentTest.fullTitle()}`); +}); + +before(() => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + + fs.removeSync(path.resolve(localDir)); +}); + +after(() => { + fs.removeSync(path.resolve(localDir)); +}); + +// This test needs environment variables: +// - GITDDB_GITHUB_USER_URL: URL of your GitHub account +// e.g.) https://github.com/foo/ +// - GITDDB_PERSONAL_ACCESS_TOKEN: A personal access token of your GitHub account +const maybe = + process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN + ? describe + : describe.skip; + +const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') + ? process.env.GITDDB_GITHUB_USER_URL + : process.env.GITDDB_GITHUB_USER_URL + '/'; + +const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; + +const connection: ConnectionSettingsGitHub = { + type: 'github', + personalAccessToken: token, + engine: 'nodegit', +}; + +maybe('NodeGit', syncThreeWayMergeBase(connection, remoteURLBase, reposPrefix, localDir)); From f4e81f096e459a62c9cef3039d9ad683d470218e Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 30 Jul 2021 19:06:37 +0900 Subject: [PATCH 100/297] fix: add logger for push() --- src/remote/push_worker.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/remote/push_worker.ts b/src/remote/push_worker.ts index a64cd251..f3c99556 100644 --- a/src/remote/push_worker.ts +++ b/src/remote/push_worker.ts @@ -124,7 +124,8 @@ export async function pushWorker ( sync.options, sync.remoteName, gitDDB.defaultBranch, - gitDDB.defaultBranch + gitDDB.defaultBranch, + gitDDB.logger ) .catch(err => { throw wrappingRemoteEngineError(err); From c57768ca22fda7dd1f48a46cb24ca8160d672f6b Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 30 Jul 2021 19:07:59 +0900 Subject: [PATCH 101/297] fix: add retry to resolve 404 not found after create remote repositroy --- src/remote/sync.ts | 21 +++++++++++- test/remote_base/sync.ts | 74 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 93 insertions(+), 2 deletions(-) diff --git a/src/remote/sync.ts b/src/remote/sync.ts index 37393fb5..5697755c 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -523,7 +523,26 @@ export class Sync implements SyncInterface { else if (isNewRemoteRepository) { this._gitDDB.logger.debug('upstream branch is not set yet. tryPush..'); // trySync() pushes local commits to the remote branch. - syncResult = await this.tryPush(); + + // Remote repository may not be created yet due to internal delay of GitHub. + // Retry if not exist. + for (let i = 0; i < this._options.retry! + 1; i++) { + // eslint-disable-next-line no-await-in-loop + const syncResultOrError = await this.tryPush().catch(err => err); + if (syncResultOrError instanceof Error) { + if (syncResultOrError instanceof RemoteErr.HTTPError404NotFound) { + // eslint-disable-next-line no-await-in-loop + await sleep(this._options.retryInterval!); + if (i === this._options.retry!) { + throw syncResultOrError; + } + continue; + } + throw syncResultOrError; + } + syncResult = syncResultOrError; + break; + } // An upstream branch must be set to a local branch after the first push // because refs/remotes/origin/main is not created until the first push. diff --git a/test/remote_base/sync.ts b/test/remote_base/sync.ts index 87027275..b7253a54 100644 --- a/test/remote_base/sync.ts +++ b/test/remote_base/sync.ts @@ -25,7 +25,7 @@ import { MINIMUM_SYNC_INTERVAL } from '../../src/const'; import { GitDocumentDB } from '../../src/git_documentdb'; import { ConnectionSettings, RemoteOptions } from '../../src/types'; import { Err } from '../../src/error'; -import { encodeToGitRemoteName, Sync, syncImpl } from '../../src/remote/sync'; +import { encodeToGitRemoteName, Sync, syncAndGetResultImpl, syncImpl } from '../../src/remote/sync'; import { createClonedDatabases, destroyDBs, @@ -692,6 +692,78 @@ export const syncBase = ( await gitDDB.destroy(); }); + it('retries tryPush() for 404 not found after create remote repository', async () => { + const remoteURL = remoteURLBase + serialId(); + + const dbNameA = serialId(); + + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection, + }; + await gitDDB.open(); + + const sync = new Sync(gitDDB, options); + + const stubTryPush = sandbox.stub(sync, 'tryPush'); + stubTryPush.onCall(0).rejects(new RemoteErr.HTTPError404NotFound('')); + stubTryPush.onCall(1).rejects(new RemoteErr.HTTPError404NotFound('')); + stubTryPush.onCall(2).rejects(new RemoteErr.HTTPError404NotFound('')); + // @ts-ignore + stubTryPush.onCall(3).resolves({ action: 'push' }); + + const stubConfig = sandbox.stub(git, 'setConfig'); + stubConfig.returns(Promise.resolve()); + + const syncResult = await sync.init(); + + expect(syncResult).toMatchObject({ + action: 'push', + }); + + expect(stubTryPush.callCount).toBe(4); + + await gitDDB.destroy(); + }); + + it('retries tryPush() for 404 not found and throws after create remote repository', async () => { + const remoteURL = remoteURLBase + serialId(); + + const dbNameA = serialId(); + + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection, + }; + await gitDDB.open(); + + const sync = new Sync(gitDDB, options); + + const stubTryPush = sandbox.stub(sync, 'tryPush'); + stubTryPush.onCall(0).rejects(new RemoteErr.HTTPError404NotFound('')); + stubTryPush.onCall(1).rejects(new RemoteErr.HTTPError404NotFound('')); + stubTryPush.onCall(2).rejects(new RemoteErr.HTTPError404NotFound('')); + // @ts-ignore + stubTryPush.onCall(3).rejects(new RemoteErr.HTTPError404NotFound('')); + + const stubConfig = sandbox.stub(git, 'setConfig'); + stubConfig.returns(Promise.resolve()); + + await expect(sync.init()).rejects.toThrowError(RemoteErr.HTTPError404NotFound); + + expect(stubTryPush.callCount).toBe(4); + + await gitDDB.destroy(); + }); + it('calls tryPush() when remote repository exists', async () => { const remoteURL = remoteURLBase + serialId(); const dbNameA = serialId(); From 2d167bf48017e65f31be3fc5eb05f93deadae436 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 30 Jul 2021 19:30:02 +0900 Subject: [PATCH 102/297] fix: remote unused import --- test/remote_base/sync.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/remote_base/sync.ts b/test/remote_base/sync.ts index b7253a54..231c473d 100644 --- a/test/remote_base/sync.ts +++ b/test/remote_base/sync.ts @@ -25,7 +25,7 @@ import { MINIMUM_SYNC_INTERVAL } from '../../src/const'; import { GitDocumentDB } from '../../src/git_documentdb'; import { ConnectionSettings, RemoteOptions } from '../../src/types'; import { Err } from '../../src/error'; -import { encodeToGitRemoteName, Sync, syncAndGetResultImpl, syncImpl } from '../../src/remote/sync'; +import { encodeToGitRemoteName, Sync, syncImpl } from '../../src/remote/sync'; import { createClonedDatabases, destroyDBs, From 7dbae63a66e798ada5c6de19da35169a574c087e Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 30 Jul 2021 23:39:41 +0900 Subject: [PATCH 103/297] test: add combine test in remote_nodegit --- test/remote_base/3way_merge.ts | 3 - test/remote_base/combine.test.ts | 525 ---------------------------- test/remote_base/combine.ts | 519 +++++++++++++++++++++++++++ test/remote_nodegit/combine.test.ts | 61 ++++ 4 files changed, 580 insertions(+), 528 deletions(-) delete mode 100644 test/remote_base/combine.test.ts create mode 100644 test/remote_base/combine.ts create mode 100644 test/remote_nodegit/combine.test.ts diff --git a/test/remote_base/3way_merge.ts b/test/remote_base/3way_merge.ts index 46795281..2bb3fdbe 100644 --- a/test/remote_base/3way_merge.ts +++ b/test/remote_base/3way_merge.ts @@ -38,9 +38,6 @@ import { } from '../remote_utils'; import { JSON_EXT } from '../../src/const'; -// eslint-disable-next-line @typescript-eslint/no-var-requires -const pushWorker_module = require('../../src/remote/push_worker'); - export const syncThreeWayMergeBase = ( connection: ConnectionSettings, remoteURLBase: string, diff --git a/test/remote_base/combine.test.ts b/test/remote_base/combine.test.ts deleted file mode 100644 index 7ac2c0a5..00000000 --- a/test/remote_base/combine.test.ts +++ /dev/null @@ -1,525 +0,0 @@ -/* eslint-disable @typescript-eslint/naming-convention */ -/** - * GitDocumentDB - * Copyright (c) Hidekazu Kubota - * - * This source code is licensed under the Mozilla Public License Version 2.0 - * found in the LICENSE file in the root directory of this source tree. - */ - -/** - * Test sync - * by using GitHub Personal Access Token - * These tests create a new repository on GitHub if not exists. - */ -import path from 'path'; -import fs from 'fs-extra'; -import git from 'isomorphic-git'; -import expect from 'expect'; -import parse from 'parse-git-config'; -import { DuplicatedFile } from '../../src/types'; -import { GitDocumentDB } from '../../src/git_documentdb'; -import { RemoteEngine } from '../../src/remote/remote_engine'; -import { - compareWorkingDirAndBlobs, - createDatabase, - destroyDBs, - destroyRemoteRepository, - getWorkingDirDocs, - removeRemoteRepositories, -} from '../remote_utils'; -import { sleep } from '../../src/utils'; -import { JSON_EXT } from '../../src/const'; - -const reposPrefix = 'test_combine___'; -const localDir = `./test/database_combine`; - -let idCounter = 0; -const serialId = () => { - return `${reposPrefix}${idCounter++}`; -}; - -beforeEach(function () { - // @ts-ignore - console.log(`... ${this.currentTest.fullTitle()}`); -}); - -before(() => { - // eslint-disable-next-line @typescript-eslint/no-var-requires - GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); - - fs.removeSync(path.resolve(localDir)); -}); - -after(() => { - // It may throw error due to memory leak of getCommitLogs() - // fs.removeSync(path.resolve(localDir)); -}); - -// This test needs environment variables: -// - GITDDB_GITHUB_USER_URL: URL of your GitHub account -// e.g.) https://github.com/foo/ -// - GITDDB_PERSONAL_ACCESS_TOKEN: A personal access token of your GitHub account -const maybe = - process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN - ? describe - : describe.skip; - -maybe('', () => { - const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') - ? process.env.GITDDB_GITHUB_USER_URL - : process.env.GITDDB_GITHUB_USER_URL + '/'; - const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; - - before(async () => { - await removeRemoteRepositories(reposPrefix); - }); - - /** - * Combine database - */ - describe('with NodeGit', () => { - it('throws NoMergeBaseFoundError when combineDbStrategy is throw-error in [both] direction', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - combineDbStrategy: 'throw-error', - syncDirection: 'both', - }); - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir, - }); - await dbB.open(); - - // trySync throws NoMergeBaseFoundError - await expect(dbB.sync(syncA.options)).rejects.toThrowError( - RemoteEngine[syncA.engine].Err.NoMergeBaseFoundError - ); - - // await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - // await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); - - await destroyDBs([dbA, dbB]); - }); - - it('commits with valid commit message for combine-head-with-theirs', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - combineDbStrategy: 'combine-head-with-theirs', - syncDirection: 'both', - }); - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir, - }); - await dbB.open(); - - // Need local commit to combine dbs with commit message. - const jsonB1 = { _id: '1', name: 'fromB' }; - await dbB.put(jsonB1); - - // Combine with remote db - await expect(dbB.sync(syncA.options)).resolves.not.toThrowError( - RemoteEngine[syncA.engine].Err.NoMergeBaseFoundError - ); - - const headCommitOid = await git.resolveRef({ - fs, - dir: dbB.workingDir, - ref: 'HEAD', - }); - const headCommit = await git.readCommit({ - fs, - dir: dbB.workingDir, - oid: headCommitOid, - }); - expect(headCommit.commit.message).toEqual(`combine database head with theirs\n`); - - await destroyDBs([dbA, dbB]); - }); - - it('succeeds when combine-head-with-theirs with empty local and empty remote', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - combineDbStrategy: 'combine-head-with-theirs', - syncDirection: 'both', - }); - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir, - }); - await dbB.open(); - - // Combine with remote db - await expect(dbB.sync(syncA.options)).resolves.not.toThrowError( - RemoteEngine[syncA.engine].Err.NoMergeBaseFoundError - ); - - // Put new doc to combined db. - const jsonB2 = { _id: '2', name: 'fromB' }; - await dbB.put(jsonB2); - - expect(getWorkingDirDocs(dbA)).toEqual([]); - expect(getWorkingDirDocs(dbB)).toEqual([jsonB2]); - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); - - await destroyDBs([dbA, dbB]); - }); - - it('succeeds combine-head-with-theirs with empty local and not empty remote', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - combineDbStrategy: 'combine-head-with-theirs', - syncDirection: 'both', - }); - - const jsonA1 = { _id: '1', name: 'fromA' }; - await dbA.put(jsonA1); - await syncA.trySync(); - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir, - }); - await dbB.open(); - - // Combine with remote db - await expect(dbB.sync(syncA.options)).resolves.not.toThrowError( - RemoteEngine[syncA.engine].Err.NoMergeBaseFoundError - ); - - // Put new doc to combined db. - const jsonB2 = { _id: '2', name: 'fromB' }; - await dbB.put(jsonB2); - - expect(getWorkingDirDocs(dbA)).toEqual([jsonA1]); - expect(getWorkingDirDocs(dbB)).toEqual([jsonA1, jsonB2]); - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); - - await destroyDBs([dbA, dbB]); - }); - - it('succeeds when combine-head-with-theirs with not empty local and empty remote', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - combineDbStrategy: 'combine-head-with-theirs', - syncDirection: 'both', - }); - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir, - }); - await dbB.open(); - - const jsonB1 = { _id: '1', name: 'fromB' }; - await dbB.put(jsonB1); - - // Combine with remote db - await expect(dbB.sync(syncA.options)).resolves.not.toThrowError( - RemoteEngine[syncA.engine].Err.NoMergeBaseFoundError - ); - - // Put new doc to combined db. - const jsonB2 = { _id: '2', name: 'fromB' }; - await dbB.put(jsonB2); - - expect(getWorkingDirDocs(dbA)).toEqual([]); - expect(getWorkingDirDocs(dbB)).toEqual([jsonB1, jsonB2]); - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); - - await destroyDBs([dbA, dbB]); - }); - - it('succeeds when combine-head-with-theirs with deep local and deep remote', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - combineDbStrategy: 'combine-head-with-theirs', - syncDirection: 'both', - }); - const jsonA1 = { _id: 'deep/one', name: 'fromA' }; - await dbA.put(jsonA1); - await syncA.trySync(); - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir, - }); - await dbB.open(); - - const jsonB2 = { - _id: 'item/box01F76SNGYBWA5PBAYR0GNNT3Y4/item01F76SP8HNANY5QAXZ53DEHXBJ', - name: 'fromB', - }; - await dbB.put(jsonB2); - - // Combine with remote db - await dbB.sync(syncA.options); - - expect(getWorkingDirDocs(dbA)).toEqual([jsonA1]); - expect(getWorkingDirDocs(dbB)).toEqual([jsonA1, jsonB2]); - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); - - await destroyDBs([dbA, dbB]); - }); - - it('returns SyncResult with duplicates when combine-head-with-theirs with not empty local and not empty remote', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - combineDbStrategy: 'combine-head-with-theirs', - syncDirection: 'both', - }); - const dbIdA = dbA.dbId; - - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResultA1 = await dbA.put(jsonA1); - await syncA.trySync(); - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir, - }); - await dbB.open(); - - const dbIdB = dbB.dbId; - expect(dbIdB).not.toBe(dbIdA); - - const jsonB1 = { _id: '1', name: 'fromB' }; - await dbB.put(jsonB1); - - const jsonB2 = { _id: '2', name: 'fromB' }; - await dbB.put(jsonB2); - - // Combine with remote db - const [sync, syncResult] = await dbB.sync(syncA.options, true); - - expect(dbB.dbId).toBe(dbIdA); - - // Put new doc to combined db. - const jsonB3 = { _id: '3', name: 'fromB' }; - await dbB.put(jsonB3); - - expect(getWorkingDirDocs(dbA)).toEqual([jsonA1]); - // jsonB1 is duplicated with postfix due to combine-head-with-theirs strategy - jsonB1._id = jsonB1._id + '-from-' + dbIdB; - const duplicatedB1 = await dbB.getFatDoc(jsonB1._id + JSON_EXT); - - expect(syncResult).toEqual({ - action: 'combine database', - duplicates: [ - { - original: { - _id: jsonA1._id, - name: jsonA1._id + JSON_EXT, - fileOid: putResultA1.fileOid, - type: 'json', - }, - duplicate: { - _id: jsonB1._id, - name: jsonB1._id + JSON_EXT, - fileOid: duplicatedB1?.fileOid, - type: 'json', - }, - }, - ], - }); - expect(getWorkingDirDocs(dbB)).toEqual([jsonB1, jsonA1, jsonB2, jsonB3]); - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); - - await destroyDBs([dbA, dbB]); - }); - - it('returns SyncResult with duplicates when combine-head-with-theirs with deep local and deep remote', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - combineDbStrategy: 'combine-head-with-theirs', - syncDirection: 'both', - }); - const dbIdA = dbA.dbId; - - const jsonA1 = { _id: 'deep/one', name: 'fromA' }; - const putResultA1 = await dbA.put(jsonA1); - await syncA.trySync(); - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir, - }); - await dbB.open(); - - const dbIdB = dbB.dbId; - expect(dbIdB).not.toBe(dbIdA); - - const jsonB1 = { _id: 'deep/one', name: 'fromB' }; - await dbB.put(jsonB1); - - const jsonB2 = { _id: '2', name: 'fromB' }; - await dbB.put(jsonB2); - - // Combine with remote db - const [sync, syncResult] = await dbB.sync(syncA.options, true); - - expect(dbB.dbId).toBe(dbIdA); - - // Put new doc to combined db. - const jsonB3 = { _id: '3', name: 'fromB' }; - await dbB.put(jsonB3); - - expect(getWorkingDirDocs(dbA)).toEqual([jsonA1]); - // jsonB1 is duplicated with postfix due to combine-head-with-theirs strategy - jsonB1._id = jsonB1._id + '-from-' + dbIdB; - const duplicatedB1 = await dbB.getFatDoc(jsonB1._id + JSON_EXT); - - expect(syncResult).toEqual({ - action: 'combine database', - duplicates: [ - { - original: { - _id: jsonA1._id, - name: jsonA1._id + JSON_EXT, - fileOid: putResultA1.fileOid, - type: 'json', - }, - duplicate: { - _id: jsonB1._id, - name: jsonB1._id + JSON_EXT, - fileOid: duplicatedB1?.fileOid, - type: 'json', - }, - }, - ], - }); - expect(getWorkingDirDocs(dbB)).toEqual([jsonB2, jsonB3, jsonB1, jsonA1]); - - const rawJSON = fs.readJSONSync(dbB.workingDir + '/deep/one.json'); - rawJSON._id = 'one'; // not 'deep/one' - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); - - await destroyDBs([dbA, dbB]); - }); - - it('invokes combine event with duplicates when combine-head-with-theirs with not empty local and not empty remote', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - combineDbStrategy: 'combine-head-with-theirs', - syncDirection: 'both', - }); - let duplicatedFiles: DuplicatedFile[] = []; - syncA.on('combine', (duplicates: DuplicatedFile[]) => { - duplicatedFiles = [...duplicates]; - }); - - const dbIdA = dbA.dbId; - - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResultA1 = await dbA.put(jsonA1); - - // Delete remote repository - await destroyRemoteRepository(syncA.remoteURL); - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir, - }); - await dbB.open(); - - const dbIdB = dbB.dbId; - - const jsonB1 = { _id: '1', name: 'fromB' }; - const putResultB1 = await dbB.put(jsonB1); - - const jsonB2 = { _id: '2', name: 'fromB' }; - await dbB.put(jsonB2); - - // Create and push to new remote repository - const syncB = await dbB.sync(syncA.options); - // Combine database on A - await syncA.trySync().catch(async () => { - await dbA.destroy(); - }); - - jsonA1._id = jsonA1._id + '-from-' + dbIdA; - const duplicatedA1 = await dbA.getFatDoc(jsonA1._id + JSON_EXT); - - expect(getWorkingDirDocs(dbA)).toEqual([jsonA1, jsonB1, jsonB2]); - // jsonA1 is duplicated with postfix due to combine-head-with-theirs strategy - - while (duplicatedFiles.length === 0) { - // eslint-disable-next-line no-await-in-loop - await sleep(3000); - } - expect(duplicatedFiles).toEqual([ - { - original: { - _id: jsonB1._id, - name: jsonB1._id + JSON_EXT, - fileOid: putResultB1.fileOid, - type: 'json', - }, - duplicate: { - _id: jsonA1._id, - name: jsonA1._id + JSON_EXT, - fileOid: duplicatedA1?.fileOid, - type: 'json', - }, - }, - ]); - - // Push combined db - await syncA.trySync(); - // Pull combined db - await syncB.trySync(); - expect(getWorkingDirDocs(dbB)).toEqual([jsonA1, jsonB1, jsonB2]); - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); - - await destroyDBs([dbA, dbB]); - }); - - it('copies author from local repository', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - combineDbStrategy: 'combine-head-with-theirs', - syncDirection: 'both', - }); - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir, - }); - await dbB.open(); - const author = { - name: 'foo', - email: 'bar@localhost', - }; - dbB.author = author; - await dbB.saveAuthor(); - - // Combine with remote db - await expect(dbB.sync(syncA.options)).resolves.not.toThrowError( - RemoteEngine[syncA.engine].Err.NoMergeBaseFoundError - ); - - const config = parse.sync({ cwd: dbB.workingDir, path: '.git/config' }); - expect(config.user).toEqual(author); - - await destroyDBs([dbA, dbB]); - }); - }); -}); diff --git a/test/remote_base/combine.ts b/test/remote_base/combine.ts new file mode 100644 index 00000000..2fb71111 --- /dev/null +++ b/test/remote_base/combine.ts @@ -0,0 +1,519 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +/** + * Test combine databases + * by using GitHub Personal Access Token + * These tests create a new repository on GitHub if not exists. + */ + +import fs from 'fs-extra'; +import git from 'isomorphic-git'; +import expect from 'expect'; +import parse from 'parse-git-config'; +import sinon from 'sinon'; +import { Err } from '../../src/error'; +import { ConnectionSettings, DuplicatedFile } from '../../src/types'; +import { GitDocumentDB } from '../../src/git_documentdb'; +import { + compareWorkingDirAndBlobs, + createDatabase, + destroyDBs, + destroyRemoteRepository, + getWorkingDirDocs, + removeRemoteRepositories, +} from '../remote_utils'; +import { sleep } from '../../src/utils'; +import { JSON_EXT } from '../../src/const'; + +export const syncCombine = ( + connection: ConnectionSettings, + remoteURLBase: string, + reposPrefix: string, + localDir: string +) => () => { + let idCounter = 0; + const serialId = () => { + return `${reposPrefix}${idCounter++}`; + }; + + // Use sandbox to restore stub and spy in parallel mocha tests + let sandbox: sinon.SinonSandbox; + beforeEach(function () { + sandbox = sinon.createSandbox(); + }); + + afterEach(function () { + sandbox.restore(); + }); + + before(async () => { + await removeRemoteRepositories(reposPrefix); + }); + + describe('', () => { + /** + * Combine database + */ + describe('with NodeGit', () => { + it('throws NoMergeBaseFoundError when combineDbStrategy is throw-error in [both] direction', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + combineDbStrategy: 'throw-error', + syncDirection: 'both', + connection, + }); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir, + }); + await dbB.open(); + + // trySync throws NoMergeBaseFoundError + await expect(dbB.sync(syncA.options)).rejects.toThrowError( + Err.NoMergeBaseFoundError + ); + + // await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + // await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + + await destroyDBs([dbA, dbB]); + }); + + it('commits with valid commit message for combine-head-with-theirs', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + combineDbStrategy: 'combine-head-with-theirs', + syncDirection: 'both', + connection, + }); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir, + }); + await dbB.open(); + + // Need local commit to combine dbs with commit message. + const jsonB1 = { _id: '1', name: 'fromB' }; + await dbB.put(jsonB1); + + // Combine with remote db + await expect(dbB.sync(syncA.options)).resolves.not.toThrowError( + Err.NoMergeBaseFoundError + ); + + const headCommitOid = await git.resolveRef({ + fs, + dir: dbB.workingDir, + ref: 'HEAD', + }); + const headCommit = await git.readCommit({ + fs, + dir: dbB.workingDir, + oid: headCommitOid, + }); + expect(headCommit.commit.message).toEqual(`combine database head with theirs\n`); + + await destroyDBs([dbA, dbB]); + }); + + it('succeeds when combine-head-with-theirs with empty local and empty remote', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + combineDbStrategy: 'combine-head-with-theirs', + syncDirection: 'both', + connection, + }); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir, + }); + await dbB.open(); + + // Combine with remote db + await expect(dbB.sync(syncA.options)).resolves.not.toThrowError( + Err.NoMergeBaseFoundError + ); + + // Put new doc to combined db. + const jsonB2 = { _id: '2', name: 'fromB' }; + await dbB.put(jsonB2); + + expect(getWorkingDirDocs(dbA)).toEqual([]); + expect(getWorkingDirDocs(dbB)).toEqual([jsonB2]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + + await destroyDBs([dbA, dbB]); + }); + + it('succeeds combine-head-with-theirs with empty local and not empty remote', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + combineDbStrategy: 'combine-head-with-theirs', + syncDirection: 'both', + connection, + }); + + const jsonA1 = { _id: '1', name: 'fromA' }; + await dbA.put(jsonA1); + await syncA.trySync(); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir, + }); + await dbB.open(); + + // Combine with remote db + await expect(dbB.sync(syncA.options)).resolves.not.toThrowError( + Err.NoMergeBaseFoundError + ); + + // Put new doc to combined db. + const jsonB2 = { _id: '2', name: 'fromB' }; + await dbB.put(jsonB2); + + expect(getWorkingDirDocs(dbA)).toEqual([jsonA1]); + expect(getWorkingDirDocs(dbB)).toEqual([jsonA1, jsonB2]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + + await destroyDBs([dbA, dbB]); + }); + + it('succeeds when combine-head-with-theirs with not empty local and empty remote', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + combineDbStrategy: 'combine-head-with-theirs', + syncDirection: 'both', + connection, + }); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir, + }); + await dbB.open(); + + const jsonB1 = { _id: '1', name: 'fromB' }; + await dbB.put(jsonB1); + + // Combine with remote db + await expect(dbB.sync(syncA.options)).resolves.not.toThrowError( + Err.NoMergeBaseFoundError + ); + + // Put new doc to combined db. + const jsonB2 = { _id: '2', name: 'fromB' }; + await dbB.put(jsonB2); + + expect(getWorkingDirDocs(dbA)).toEqual([]); + expect(getWorkingDirDocs(dbB)).toEqual([jsonB1, jsonB2]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + + await destroyDBs([dbA, dbB]); + }); + + it('succeeds when combine-head-with-theirs with deep local and deep remote', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + combineDbStrategy: 'combine-head-with-theirs', + syncDirection: 'both', + connection, + }); + const jsonA1 = { _id: 'deep/one', name: 'fromA' }; + await dbA.put(jsonA1); + await syncA.trySync(); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir, + }); + await dbB.open(); + + const jsonB2 = { + _id: 'item/box01F76SNGYBWA5PBAYR0GNNT3Y4/item01F76SP8HNANY5QAXZ53DEHXBJ', + name: 'fromB', + }; + await dbB.put(jsonB2); + + // Combine with remote db + await dbB.sync(syncA.options); + + expect(getWorkingDirDocs(dbA)).toEqual([jsonA1]); + expect(getWorkingDirDocs(dbB)).toEqual([jsonA1, jsonB2]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + + await destroyDBs([dbA, dbB]); + }); + + it('returns SyncResult with duplicates when combine-head-with-theirs with not empty local and not empty remote', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + combineDbStrategy: 'combine-head-with-theirs', + syncDirection: 'both', + connection, + }); + const dbIdA = dbA.dbId; + + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResultA1 = await dbA.put(jsonA1); + await syncA.trySync(); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir, + }); + await dbB.open(); + + const dbIdB = dbB.dbId; + expect(dbIdB).not.toBe(dbIdA); + + const jsonB1 = { _id: '1', name: 'fromB' }; + await dbB.put(jsonB1); + + const jsonB2 = { _id: '2', name: 'fromB' }; + await dbB.put(jsonB2); + + // Combine with remote db + const [sync, syncResult] = await dbB.sync(syncA.options, true); + + expect(dbB.dbId).toBe(dbIdA); + + // Put new doc to combined db. + const jsonB3 = { _id: '3', name: 'fromB' }; + await dbB.put(jsonB3); + + expect(getWorkingDirDocs(dbA)).toEqual([jsonA1]); + // jsonB1 is duplicated with postfix due to combine-head-with-theirs strategy + jsonB1._id = jsonB1._id + '-from-' + dbIdB; + const duplicatedB1 = await dbB.getFatDoc(jsonB1._id + JSON_EXT); + + expect(syncResult).toEqual({ + action: 'combine database', + duplicates: [ + { + original: { + _id: jsonA1._id, + name: jsonA1._id + JSON_EXT, + fileOid: putResultA1.fileOid, + type: 'json', + }, + duplicate: { + _id: jsonB1._id, + name: jsonB1._id + JSON_EXT, + fileOid: duplicatedB1?.fileOid, + type: 'json', + }, + }, + ], + }); + expect(getWorkingDirDocs(dbB)).toEqual([jsonB1, jsonA1, jsonB2, jsonB3]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + + await destroyDBs([dbA, dbB]); + }); + + it('returns SyncResult with duplicates when combine-head-with-theirs with deep local and deep remote', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + combineDbStrategy: 'combine-head-with-theirs', + syncDirection: 'both', + connection, + }); + const dbIdA = dbA.dbId; + + const jsonA1 = { _id: 'deep/one', name: 'fromA' }; + const putResultA1 = await dbA.put(jsonA1); + await syncA.trySync(); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir, + }); + await dbB.open(); + + const dbIdB = dbB.dbId; + expect(dbIdB).not.toBe(dbIdA); + + const jsonB1 = { _id: 'deep/one', name: 'fromB' }; + await dbB.put(jsonB1); + + const jsonB2 = { _id: '2', name: 'fromB' }; + await dbB.put(jsonB2); + + // Combine with remote db + const [sync, syncResult] = await dbB.sync(syncA.options, true); + + expect(dbB.dbId).toBe(dbIdA); + + // Put new doc to combined db. + const jsonB3 = { _id: '3', name: 'fromB' }; + await dbB.put(jsonB3); + + expect(getWorkingDirDocs(dbA)).toEqual([jsonA1]); + // jsonB1 is duplicated with postfix due to combine-head-with-theirs strategy + jsonB1._id = jsonB1._id + '-from-' + dbIdB; + const duplicatedB1 = await dbB.getFatDoc(jsonB1._id + JSON_EXT); + + expect(syncResult).toEqual({ + action: 'combine database', + duplicates: [ + { + original: { + _id: jsonA1._id, + name: jsonA1._id + JSON_EXT, + fileOid: putResultA1.fileOid, + type: 'json', + }, + duplicate: { + _id: jsonB1._id, + name: jsonB1._id + JSON_EXT, + fileOid: duplicatedB1?.fileOid, + type: 'json', + }, + }, + ], + }); + expect(getWorkingDirDocs(dbB)).toEqual([jsonB2, jsonB3, jsonB1, jsonA1]); + + const rawJSON = fs.readJSONSync(dbB.workingDir + '/deep/one.json'); + rawJSON._id = 'one'; // not 'deep/one' + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + + await destroyDBs([dbA, dbB]); + }); + + it('invokes combine event with duplicates when combine-head-with-theirs with not empty local and not empty remote', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + combineDbStrategy: 'combine-head-with-theirs', + syncDirection: 'both', + connection, + }); + let duplicatedFiles: DuplicatedFile[] = []; + syncA.on('combine', (duplicates: DuplicatedFile[]) => { + duplicatedFiles = [...duplicates]; + }); + + const dbIdA = dbA.dbId; + + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResultA1 = await dbA.put(jsonA1); + + // Delete remote repository + await destroyRemoteRepository(syncA.remoteURL); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir, + }); + await dbB.open(); + + const dbIdB = dbB.dbId; + + const jsonB1 = { _id: '1', name: 'fromB' }; + const putResultB1 = await dbB.put(jsonB1); + + const jsonB2 = { _id: '2', name: 'fromB' }; + await dbB.put(jsonB2); + + // Create and push to new remote repository + const syncB = await dbB.sync(syncA.options); + // Combine database on A + await syncA.trySync().catch(async () => { + await dbA.destroy(); + }); + + jsonA1._id = jsonA1._id + '-from-' + dbIdA; + const duplicatedA1 = await dbA.getFatDoc(jsonA1._id + JSON_EXT); + + expect(getWorkingDirDocs(dbA)).toEqual([jsonA1, jsonB1, jsonB2]); + // jsonA1 is duplicated with postfix due to combine-head-with-theirs strategy + + while (duplicatedFiles.length === 0) { + // eslint-disable-next-line no-await-in-loop + await sleep(3000); + } + expect(duplicatedFiles).toEqual([ + { + original: { + _id: jsonB1._id, + name: jsonB1._id + JSON_EXT, + fileOid: putResultB1.fileOid, + type: 'json', + }, + duplicate: { + _id: jsonA1._id, + name: jsonA1._id + JSON_EXT, + fileOid: duplicatedA1?.fileOid, + type: 'json', + }, + }, + ]); + + // Push combined db + await syncA.trySync(); + // Pull combined db + await syncB.trySync(); + expect(getWorkingDirDocs(dbB)).toEqual([jsonA1, jsonB1, jsonB2]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + + await destroyDBs([dbA, dbB]); + }); + + it('copies author from local repository', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + combineDbStrategy: 'combine-head-with-theirs', + syncDirection: 'both', + connection, + }); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir, + }); + await dbB.open(); + const author = { + name: 'foo', + email: 'bar@localhost', + }; + dbB.author = author; + await dbB.saveAuthor(); + + // Combine with remote db + await expect(dbB.sync(syncA.options)).resolves.not.toThrowError( + Err.NoMergeBaseFoundError + ); + + const config = parse.sync({ cwd: dbB.workingDir, path: '.git/config' }); + expect(config.user).toEqual(author); + + await destroyDBs([dbA, dbB]); + }); + }); + }); +}; diff --git a/test/remote_nodegit/combine.test.ts b/test/remote_nodegit/combine.test.ts new file mode 100644 index 00000000..a72f19f4 --- /dev/null +++ b/test/remote_nodegit/combine.test.ts @@ -0,0 +1,61 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +/** + * Test combine databases + * by using GitHub Personal Access Token + * These tests create a new repository on GitHub if not exists. + */ +import path from 'path'; +import fs from 'fs-extra'; +import { syncCombine } from '../remote_base/combine'; +import { ConnectionSettingsGitHub } from '../../src/types'; +import { GitDocumentDB } from '../../src/git_documentdb'; + +const reposPrefix = 'test_combine_nodegit__'; +const localDir = `./test/database_combine_nodegit`; + +beforeEach(function () { + // @ts-ignore + console.log(`... ${this.currentTest.fullTitle()}`); +}); + +before(() => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + + fs.removeSync(path.resolve(localDir)); +}); + +after(() => { + fs.removeSync(path.resolve(localDir)); +}); + +// This test needs environment variables: +// - GITDDB_GITHUB_USER_URL: URL of your GitHub account +// e.g.) https://github.com/foo/ +// - GITDDB_PERSONAL_ACCESS_TOKEN: A personal access token of your GitHub account +const maybe = + process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN + ? describe + : describe.skip; + +const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') + ? process.env.GITDDB_GITHUB_USER_URL + : process.env.GITDDB_GITHUB_USER_URL + '/'; + +const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; + +const connection: ConnectionSettingsGitHub = { + type: 'github', + personalAccessToken: token, + engine: 'nodegit', +}; + +maybe('NodeGit', syncCombine(connection, remoteURLBase, reposPrefix, localDir)); From b221dde15907a4337848760104e9e5e728d7f89d Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 30 Jul 2021 23:51:13 +0900 Subject: [PATCH 104/297] test: rename test files --- test/remote_base/{git_documentdb.ts => network_git_documentdb.ts} | 0 test/remote_base/{history.ts => network_history.ts} | 0 test/remote_base/{task_queue.ts => network_task_queue.ts} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename test/remote_base/{git_documentdb.ts => network_git_documentdb.ts} (100%) rename test/remote_base/{history.ts => network_history.ts} (100%) rename test/remote_base/{task_queue.ts => network_task_queue.ts} (100%) diff --git a/test/remote_base/git_documentdb.ts b/test/remote_base/network_git_documentdb.ts similarity index 100% rename from test/remote_base/git_documentdb.ts rename to test/remote_base/network_git_documentdb.ts diff --git a/test/remote_base/history.ts b/test/remote_base/network_history.ts similarity index 100% rename from test/remote_base/history.ts rename to test/remote_base/network_history.ts diff --git a/test/remote_base/task_queue.ts b/test/remote_base/network_task_queue.ts similarity index 100% rename from test/remote_base/task_queue.ts rename to test/remote_base/network_task_queue.ts From 59feefd8b0ebb3f6e3b59525a316c12f80c8d40b Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 30 Jul 2021 23:52:04 +0900 Subject: [PATCH 105/297] test: add network test for GitDocumentDB class in remote_nodegit --- test/remote_base/network_git_documentdb.ts | 195 +++++++++++------- test/remote_base/sync.ts | 2 + .../network_git_documentdb.test.ts | 61 ++++++ 3 files changed, 183 insertions(+), 75 deletions(-) create mode 100644 test/remote_nodegit/network_git_documentdb.test.ts diff --git a/test/remote_base/network_git_documentdb.ts b/test/remote_base/network_git_documentdb.ts index 29d6ae67..b7e844b4 100644 --- a/test/remote_base/network_git_documentdb.ts +++ b/test/remote_base/network_git_documentdb.ts @@ -1,89 +1,134 @@ +/* eslint-disable @typescript-eslint/naming-convention */ /** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +/** + * Network test for GitDocumentDB class + * by using GitHub Personal Access Token + * These tests create a new repository on GitHub if not exists. + */ + +import sinon from 'sinon'; +import expect from 'expect'; +import { ConnectionSettings, RemoteOptions } from '../../src/types'; +import { destroyDBs, removeRemoteRepositories } from '../remote_utils'; +import { GitDocumentDB } from '../../src/git_documentdb'; +import { Err } from '../../src/error'; + +export const networkGitDocumentDB = ( + connection: ConnectionSettings, + remoteURLBase: string, + reposPrefix: string, + localDir: string +) => () => { + let idCounter = 0; + const serialId = () => { + return `${reposPrefix}${idCounter++}`; + }; + + // Use sandbox to restore stub and spy in parallel mocha tests + let sandbox: sinon.SinonSandbox; + beforeEach(function () { + sandbox = sinon.createSandbox(); + }); + + afterEach(function () { + sandbox.restore(); + }); + + before(async () => { + await removeRemoteRepositories(reposPrefix); + }); + + /** * Initialize synchronization by open() with remoteURL * Initialize means creating local and remote repositories by using a remoteUrl */ - describe('is initialized from GitDocumentDB():', () => { - it('sync() returns an instance of Sync.', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbNameA = serialId(); - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, + describe('is initialized from GitDocumentDB():', () => { + it('sync() returns an instance of Sync.', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection, + }; + await dbA.open(); + const syncA = await dbA.sync(options); + expect(syncA.remoteURL).toBe(remoteURL); + await destroyDBs([dbA]); }); - const options: RemoteOptions = { - remoteUrl: remoteURL, - connection: { type: 'github', personalAccessToken: token }, - }; - await dbA.open(); - const syncA = await dbA.sync(options); - expect(syncA.remoteURL).toBe(remoteURL); - destroyDBs([dbA]); - }); - it('unregisterRemote() removes an instance of Sync.', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbNameA = serialId(); - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, + it('unregisterRemote() removes an instance of Sync.', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection, + }; + await dbA.open(); + await dbA.sync(options); + dbA.removeSync(remoteURL); + expect(dbA.getSync(remoteURL)).toBeUndefined(); + await destroyDBs([dbA]); }); - const options: RemoteOptions = { - remoteUrl: remoteURL, - connection: { type: 'github', personalAccessToken: token }, - }; - await dbA.open(); - await dbA.sync(options); - dbA.removeSync(remoteURL); - expect(dbA.getSync(remoteURL)).toBeUndefined(); - destroyDBs([dbA]); - }); - it('throws RemoteAlreadyRegisteredError when sync() the same url twice.', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbNameA = serialId(); + it('throws RemoteAlreadyRegisteredError when sync() the same url twice.', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, - }); + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); - await dbA.open(); - - const options: RemoteOptions = { - remoteUrl: remoteURL, - connection: { type: 'github', personalAccessToken: token }, - }; - const syncA = await dbA.sync(options); - await expect(dbA.sync(options)).rejects.toThrowError( - Err.RemoteAlreadyRegisteredError - ); - dbA.destroy(); - }); + await dbA.open(); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection, + }; + const syncA = await dbA.sync(options); + await expect(dbA.sync(options)).rejects.toThrowError( + Err.RemoteAlreadyRegisteredError + ); + await dbA.destroy(); + }); - it.skip('getRemoteURLs() returns sync', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbNameA = serialId(); - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, - logLevel: 'trace', + it('getRemoteURLs() returns sync', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + logLevel: 'trace', + }); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection, + }; + await dbA.open(); + await dbA.sync(options); + const remoteURL2 = remoteURLBase + serialId(); + const options2: RemoteOptions = { + remoteUrl: remoteURL2, + connection, + }; + await dbA.sync(options2); + expect(dbA.getRemoteURLs()).toEqual([remoteURL, remoteURL2]); + await destroyDBs([dbA]); }); - const options: RemoteOptions = { - remoteUrl: remoteURL, - connection: { type: 'github', personalAccessToken: token }, - }; - await dbA.open(); - await dbA.sync(options); - const remoteURL2 = remoteURLBase + serialId(); - const options2: RemoteOptions = { - remoteUrl: remoteURL2, - connection: { type: 'github', personalAccessToken: token }, - }; - await dbA.sync(options2); - expect(dbA.getRemoteURLs()).toEqual([remoteURL, remoteURL2]); - destroyDBs([dbA]); }); - - it.skip('Multiple Sync object'); -}); +}; diff --git a/test/remote_base/sync.ts b/test/remote_base/sync.ts index 231c473d..4b0c26c7 100644 --- a/test/remote_base/sync.ts +++ b/test/remote_base/sync.ts @@ -894,4 +894,6 @@ export const syncBase = ( await gitDDB.destroy(); }); }); + + it.skip('Multiple Sync object'); }; diff --git a/test/remote_nodegit/network_git_documentdb.test.ts b/test/remote_nodegit/network_git_documentdb.test.ts new file mode 100644 index 00000000..647340d6 --- /dev/null +++ b/test/remote_nodegit/network_git_documentdb.test.ts @@ -0,0 +1,61 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +/** + * Network test for GitDocumentDB class + * by using GitHub Personal Access Token + * These tests create a new repository on GitHub if not exists. + */ +import path from 'path'; +import fs from 'fs-extra'; +import { networkGitDocumentDB } from '../remote_base/network_git_documentdb'; +import { ConnectionSettingsGitHub } from '../../src/types'; +import { GitDocumentDB } from '../../src/git_documentdb'; + +const reposPrefix = 'test_network_git_documentdb_nodegit__'; +const localDir = `./test/database_network_git_documentdb_nodegit`; + +beforeEach(function () { + // @ts-ignore + console.log(`... ${this.currentTest.fullTitle()}`); +}); + +before(() => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + + fs.removeSync(path.resolve(localDir)); +}); + +after(() => { + fs.removeSync(path.resolve(localDir)); +}); + +// This test needs environment variables: +// - GITDDB_GITHUB_USER_URL: URL of your GitHub account +// e.g.) https://github.com/foo/ +// - GITDDB_PERSONAL_ACCESS_TOKEN: A personal access token of your GitHub account +const maybe = + process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN + ? describe + : describe.skip; + +const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') + ? process.env.GITDDB_GITHUB_USER_URL + : process.env.GITDDB_GITHUB_USER_URL + '/'; + +const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; + +const connection: ConnectionSettingsGitHub = { + type: 'github', + personalAccessToken: token, + engine: 'nodegit', +}; + +maybe('NodeGit', networkGitDocumentDB(connection, remoteURLBase, reposPrefix, localDir)); From d533346d851212f36b8f5404ba11c7813fb8c659 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sat, 31 Jul 2021 01:32:04 +0900 Subject: [PATCH 106/297] test: move offline tests from remote_base to remote_offline --- test/{remote_base => remote_offline}/json_diff.test.ts | 7 +++++++ test/{remote_base => remote_offline}/json_patch_ot.test.ts | 0 2 files changed, 7 insertions(+) rename test/{remote_base => remote_offline}/json_diff.test.ts (98%) rename test/{remote_base => remote_offline}/json_patch_ot.test.ts (100%) diff --git a/test/remote_base/json_diff.test.ts b/test/remote_offline/json_diff.test.ts similarity index 98% rename from test/remote_base/json_diff.test.ts rename to test/remote_offline/json_diff.test.ts index 2ac387b1..adc2aa6f 100644 --- a/test/remote_base/json_diff.test.ts +++ b/test/remote_offline/json_diff.test.ts @@ -1,4 +1,11 @@ /* eslint-disable @typescript-eslint/naming-convention */ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ import expect from 'expect'; import { JsonDiff } from '../../src/remote/json_diff'; diff --git a/test/remote_base/json_patch_ot.test.ts b/test/remote_offline/json_patch_ot.test.ts similarity index 100% rename from test/remote_base/json_patch_ot.test.ts rename to test/remote_offline/json_patch_ot.test.ts From fd9829792b78b68b026e7ce37081637e1138ec00 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sat, 31 Jul 2021 01:47:15 +0900 Subject: [PATCH 107/297] test: add network test for history and TaskQueue in remote_nodegit --- test/remote_base/network_git_documentdb.ts | 2 +- test/remote_base/network_history.ts | 291 ++++++++++-------- test/remote_base/network_task_queue.ts | 134 +++++--- test/remote_base/sync.ts | 2 +- test/remote_nodegit/network_history.test.ts | 61 ++++ .../remote_nodegit/network_task_queue.test.ts | 61 ++++ 6 files changed, 368 insertions(+), 183 deletions(-) create mode 100644 test/remote_nodegit/network_history.test.ts create mode 100644 test/remote_nodegit/network_task_queue.test.ts diff --git a/test/remote_base/network_git_documentdb.ts b/test/remote_base/network_git_documentdb.ts index b7e844b4..f576d8ed 100644 --- a/test/remote_base/network_git_documentdb.ts +++ b/test/remote_base/network_git_documentdb.ts @@ -49,7 +49,7 @@ export const networkGitDocumentDB = ( * Initialize synchronization by open() with remoteURL * Initialize means creating local and remote repositories by using a remoteUrl */ - describe('is initialized from GitDocumentDB():', () => { + describe(' Sync is initialized from GitDocumentDB():', () => { it('sync() returns an instance of Sync.', async () => { const remoteURL = remoteURLBase + serialId(); const dbNameA = serialId(); diff --git a/test/remote_base/network_history.ts b/test/remote_base/network_history.ts index f528a12d..20950d33 100644 --- a/test/remote_base/network_history.ts +++ b/test/remote_base/network_history.ts @@ -1,144 +1,171 @@ -maybe(' getHistoryImpl', () => { - const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') - ? process.env.GITDDB_GITHUB_USER_URL - : process.env.GITDDB_GITHUB_USER_URL + '/'; - const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; +/* eslint-disable @typescript-eslint/naming-convention */ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +/** + * Network test for history + * by using GitHub Personal Access Token + * These tests create a new repository on GitHub if not exists. + */ + +import expect from 'expect'; +import sinon from 'sinon'; +import { ConnectionSettings } from '../../src/types'; +import { + createClonedDatabases, + destroyDBs, + removeRemoteRepositories, +} from '../remote_utils'; +import { sleep, toSortedJSONString, utf8encode } from '../../src/utils'; +import { JSON_EXT } from '../../src/const'; +import { getHistoryImpl, readOldBlob } from '../../src/crud/history'; + +export const networkHistory = ( + connection: ConnectionSettings, + remoteURLBase: string, + reposPrefix: string, + localDir: string +) => () => { + let idCounter = 0; + const serialId = () => { + return `${reposPrefix}${idCounter++}`; + }; before(async () => { await removeRemoteRepositories(reposPrefix); }); - it('gets all revisions sorted by date from merged commit', async () => { - const [dbA, dbB, syncA, syncB] = await createClonedDatabases( - remoteURLBase, - localDir, - serialId, - { - conflictResolutionStrategy: 'ours', - } - ); - - const _id = 'prof'; - const shortName = _id + JSON_EXT; - const jsonA1 = { _id, name: 'A-1' }; - const jsonA2 = { _id, name: 'A-2' }; - const jsonA3 = { _id, name: 'A-3' }; - const jsonB1 = { _id, name: 'B-1' }; - const jsonB2 = { _id, name: 'B-2' }; - const putResultA1 = await dbA.put(jsonA1); - await sleep(1500); - const putResultB1 = await dbB.put(jsonB1); - await sleep(1500); - const putResultA2 = await dbA.put(jsonA2); - await sleep(1500); - const putResultB2 = await dbB.put(jsonB2); - await sleep(1500); - const putResultA3 = await dbA.put(jsonA3); - await sleep(1500); - - await syncA.trySync(); - await syncB.trySync(); // Resolve conflict. jsonB2 wins. - - // Get - const history = await getHistoryImpl(dbB, shortName, '', undefined, undefined, true); - - expect(history[0]).toEqual({ - _id, - name: shortName, - fileOid: expect.stringMatching(/^[\da-z]{40}$/), - type: 'json', - doc: jsonB2, - }); - expect(history[1]).toEqual({ - _id, - name: shortName, - fileOid: expect.stringMatching(/^[\da-z]{40}$/), - type: 'json', - doc: jsonA3, - }); - expect(history[2]).toEqual({ - _id, - name: shortName, - fileOid: expect.stringMatching(/^[\da-z]{40}$/), - type: 'json', - doc: jsonB2, - }); - expect(history[3]).toEqual({ - _id, - name: shortName, - fileOid: expect.stringMatching(/^[\da-z]{40}$/), - type: 'json', - doc: jsonA2, - }); - expect(history[4]).toEqual({ - _id, - name: shortName, - fileOid: expect.stringMatching(/^[\da-z]{40}$/), - type: 'json', - doc: jsonB1, - }); - expect(history[5]).toEqual({ - _id, - name: shortName, - fileOid: expect.stringMatching(/^[\da-z]{40}$/), - type: 'json', - doc: jsonA1, - }); + describe(' getHistoryImpl', () => { + it('gets all revisions sorted by date from merged commit', async () => { + const [dbA, dbB, syncA, syncB] = await createClonedDatabases( + remoteURLBase, + localDir, + serialId, + { + conflictResolutionStrategy: 'ours', + connection, + } + ); - await destroyDBs([dbA, dbB]); - }); -}); + const _id = 'prof'; + const shortName = _id + JSON_EXT; + const jsonA1 = { _id, name: 'A-1' }; + const jsonA2 = { _id, name: 'A-2' }; + const jsonA3 = { _id, name: 'A-3' }; + const jsonB1 = { _id, name: 'B-1' }; + const jsonB2 = { _id, name: 'B-2' }; + const putResultA1 = await dbA.put(jsonA1); + await sleep(1500); + const putResultB1 = await dbB.put(jsonB1); + await sleep(1500); + const putResultA2 = await dbA.put(jsonA2); + await sleep(1500); + const putResultB2 = await dbB.put(jsonB2); + await sleep(1500); + const putResultA3 = await dbA.put(jsonA3); + await sleep(1500); -maybe(' readOldBlob()', () => { - const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') - ? process.env.GITDDB_GITHUB_USER_URL - : process.env.GITDDB_GITHUB_USER_URL + '/'; - const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; + await syncA.trySync(); + await syncB.trySync(); // Resolve conflict. jsonB2 wins. - before(async () => { - await removeRemoteRepositories(reposPrefix); - }); + // Get + const history = await getHistoryImpl(dbB, shortName, '', undefined, undefined, true); + + expect(history[0]).toEqual({ + _id, + name: shortName, + fileOid: expect.stringMatching(/^[\da-z]{40}$/), + type: 'json', + doc: jsonB2, + }); + expect(history[1]).toEqual({ + _id, + name: shortName, + fileOid: expect.stringMatching(/^[\da-z]{40}$/), + type: 'json', + doc: jsonA3, + }); + expect(history[2]).toEqual({ + _id, + name: shortName, + fileOid: expect.stringMatching(/^[\da-z]{40}$/), + type: 'json', + doc: jsonB2, + }); + expect(history[3]).toEqual({ + _id, + name: shortName, + fileOid: expect.stringMatching(/^[\da-z]{40}$/), + type: 'json', + doc: jsonA2, + }); + expect(history[4]).toEqual({ + _id, + name: shortName, + fileOid: expect.stringMatching(/^[\da-z]{40}$/), + type: 'json', + doc: jsonB1, + }); + expect(history[5]).toEqual({ + _id, + name: shortName, + fileOid: expect.stringMatching(/^[\da-z]{40}$/), + type: 'json', + doc: jsonA1, + }); - it('skips a merge commit', async () => { - const [dbA, dbB, syncA, syncB] = await createClonedDatabases( - remoteURLBase, - localDir, - serialId, - { - conflictResolutionStrategy: 'ours', - } - ); - dbA.author = { - name: 'authorA', - email: 'authorEmailA', - }; - dbB.author = { - name: 'authorB', - email: 'authorEmailB', - }; - - const jsonA1 = { _id: 'A1', name: 'A1' }; - const jsonA1internal = { _id: 'A1', name: 'A1' }; - const jsonB1 = { _id: 'B1', name: 'B1' }; - const putResultA1 = await dbA.put(jsonA1); - await sleep(1500); - await dbB.put(jsonB1); - await sleep(1500); - - await syncA.trySync(); - await syncB.trySync(); // dbB commits 'merge' - - await expect( - readOldBlob(dbB.workingDir, 'A1.json', 0, { filter: [{ author: dbB.author }] }) - ).resolves.toBeUndefined(); // merge commit is skipped, so jsonA1 does not exist. - - await expect( - readOldBlob(dbB.workingDir, 'A1.json', 0, { filter: [{ author: dbA.author }] }) - ).resolves.toEqual({ - oid: putResultA1.fileOid, - blob: utf8encode(toSortedJSONString(jsonA1internal)), + await destroyDBs([dbA, dbB]); }); + }); + + describe(' readOldBlob()', () => { + it('skips a merge commit', async () => { + const [dbA, dbB, syncA, syncB] = await createClonedDatabases( + remoteURLBase, + localDir, + serialId, + { + conflictResolutionStrategy: 'ours', + connection, + } + ); + dbA.author = { + name: 'authorA', + email: 'authorEmailA', + }; + dbB.author = { + name: 'authorB', + email: 'authorEmailB', + }; - await destroyDBs([dbA, dbB]); + const jsonA1 = { _id: 'A1', name: 'A1' }; + const jsonA1internal = { _id: 'A1', name: 'A1' }; + const jsonB1 = { _id: 'B1', name: 'B1' }; + const putResultA1 = await dbA.put(jsonA1); + await sleep(1500); + await dbB.put(jsonB1); + await sleep(1500); + + await syncA.trySync(); + await syncB.trySync(); // dbB commits 'merge' + + await expect( + readOldBlob(dbB.workingDir, 'A1.json', 0, { filter: [{ author: dbB.author }] }) + ).resolves.toBeUndefined(); // merge commit is skipped, so jsonA1 does not exist. + + await expect( + readOldBlob(dbB.workingDir, 'A1.json', 0, { filter: [{ author: dbA.author }] }) + ).resolves.toEqual({ + oid: putResultA1.fileOid, + blob: utf8encode(toSortedJSONString(jsonA1internal)), + }); + + await destroyDBs([dbA, dbB]); + }); }); -}); \ No newline at end of file +}; diff --git a/test/remote_base/network_task_queue.ts b/test/remote_base/network_task_queue.ts index 42d17797..036d70a5 100644 --- a/test/remote_base/network_task_queue.ts +++ b/test/remote_base/network_task_queue.ts @@ -1,66 +1,102 @@ -const maybe = - process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN - ? describe - : describe.skip; +/* eslint-disable @typescript-eslint/naming-convention */ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ -maybe(' remote', () => { - const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') - ? process.env.GITDDB_GITHUB_USER_URL - : process.env.GITDDB_GITHUB_USER_URL + '/'; - const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; +/** + * Network test for TaskQueue + * by using GitHub Personal Access Token + * These tests create a new repository on GitHub if not exists. + */ + +import expect from 'expect'; +import sinon from 'sinon'; +import { ConnectionSettings } from '../../src/types'; +import { + createClonedDatabases, + createDatabase, + destroyDBs, + removeRemoteRepositories, +} from '../remote_utils'; +import { sleep, toSortedJSONString, utf8encode } from '../../src/utils'; +import { JSON_EXT } from '../../src/const'; +import { getHistoryImpl, readOldBlob } from '../../src/crud/history'; + +export const networkHistory = ( + connection: ConnectionSettings, + remoteURLBase: string, + reposPrefix: string, + localDir: string +) => () => { + let idCounter = 0; + const serialId = () => { + return `${reposPrefix}${idCounter++}`; + }; before(async () => { await removeRemoteRepositories(reposPrefix); }); - it('increments statistics: push', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId); + describe(' remote', () => { + it('increments statistics: push', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, + }); - // The first push in open() - expect(dbA.taskQueue.currentStatistics().push).toBe(1); + // The first push in open() + expect(dbA.taskQueue.currentStatistics().push).toBe(1); - const jsonA1 = { _id: '1', name: 'fromA' }; - await dbA.put(jsonA1); - await syncA.tryPush(); - expect(dbA.taskQueue.currentStatistics().push).toBe(2); + const jsonA1 = { _id: '1', name: 'fromA' }; + await dbA.put(jsonA1); + await syncA.tryPush(); + expect(dbA.taskQueue.currentStatistics().push).toBe(2); - await destroyDBs([dbA]); - }); + await destroyDBs([dbA]); + }); - it('increments statistics: sync', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId); + it('increments statistics: sync', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, + }); - expect(dbA.taskQueue.currentStatistics().sync).toBe(0); + expect(dbA.taskQueue.currentStatistics().sync).toBe(0); - await syncA.trySync(); - expect(dbA.taskQueue.currentStatistics().sync).toBe(1); + await syncA.trySync(); + expect(dbA.taskQueue.currentStatistics().sync).toBe(1); - await destroyDBs([dbA]); - }); + await destroyDBs([dbA]); + }); - it('clear() statistics', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId); + it('clear() statistics', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, + }); - await syncA.trySync(); - expect(dbA.taskQueue.currentStatistics()).toEqual({ - put: 0, - insert: 0, - update: 0, - delete: 0, - push: 1, - sync: 1, - cancel: 0, - }); - dbA.taskQueue.clear(); - expect(dbA.taskQueue.currentStatistics()).toEqual({ - put: 0, - insert: 0, - update: 0, - delete: 0, - push: 0, - sync: 0, - cancel: 0, + await syncA.trySync(); + expect(dbA.taskQueue.currentStatistics()).toEqual({ + put: 0, + insert: 0, + update: 0, + delete: 0, + push: 1, + sync: 1, + cancel: 0, + }); + dbA.taskQueue.clear(); + expect(dbA.taskQueue.currentStatistics()).toEqual({ + put: 0, + insert: 0, + update: 0, + delete: 0, + push: 0, + sync: 0, + cancel: 0, + }); + await destroyDBs([dbA]); }); - await destroyDBs([dbA]); }); -}); +}; diff --git a/test/remote_base/sync.ts b/test/remote_base/sync.ts index 4b0c26c7..07098cf9 100644 --- a/test/remote_base/sync.ts +++ b/test/remote_base/sync.ts @@ -60,7 +60,7 @@ export const syncBase = ( await removeRemoteRepositories(reposPrefix); }); - describe('encodeToGitRemoteName', () => { + describe(' encodeToGitRemoteName', () => { it('always generates the same name', async () => { const remoteURL = 'ssh://user@github.com:443/foo-bar/baz.git'; const encoded = encodeToGitRemoteName(remoteURL); diff --git a/test/remote_nodegit/network_history.test.ts b/test/remote_nodegit/network_history.test.ts new file mode 100644 index 00000000..83db5d77 --- /dev/null +++ b/test/remote_nodegit/network_history.test.ts @@ -0,0 +1,61 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +/** + * Network test for history + * by using GitHub Personal Access Token + * These tests create a new repository on GitHub if not exists. + */ +import path from 'path'; +import fs from 'fs-extra'; +import { ConnectionSettingsGitHub } from '../../src/types'; +import { GitDocumentDB } from '../../src/git_documentdb'; +import { networkHistory } from '../remote_base/network_history'; + +const reposPrefix = 'test_network_history_nodegit__'; +const localDir = `./test/database_network_history_nodegit`; + +beforeEach(function () { + // @ts-ignore + console.log(`... ${this.currentTest.fullTitle()}`); +}); + +before(() => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + + fs.removeSync(path.resolve(localDir)); +}); + +after(() => { + fs.removeSync(path.resolve(localDir)); +}); + +// This test needs environment variables: +// - GITDDB_GITHUB_USER_URL: URL of your GitHub account +// e.g.) https://github.com/foo/ +// - GITDDB_PERSONAL_ACCESS_TOKEN: A personal access token of your GitHub account +const maybe = + process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN + ? describe + : describe.skip; + +const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') + ? process.env.GITDDB_GITHUB_USER_URL + : process.env.GITDDB_GITHUB_USER_URL + '/'; + +const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; + +const connection: ConnectionSettingsGitHub = { + type: 'github', + personalAccessToken: token, + engine: 'nodegit', +}; + +maybe('NodeGit', networkHistory(connection, remoteURLBase, reposPrefix, localDir)); diff --git a/test/remote_nodegit/network_task_queue.test.ts b/test/remote_nodegit/network_task_queue.test.ts new file mode 100644 index 00000000..fda1b3c9 --- /dev/null +++ b/test/remote_nodegit/network_task_queue.test.ts @@ -0,0 +1,61 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +/** + * Network test for TaskQueue + * by using GitHub Personal Access Token + * These tests create a new repository on GitHub if not exists. + */ +import path from 'path'; +import fs from 'fs-extra'; +import { ConnectionSettingsGitHub } from '../../src/types'; +import { GitDocumentDB } from '../../src/git_documentdb'; +import { networkHistory } from '../remote_base/network_history'; + +const reposPrefix = 'test_network_task_queue_nodegit__'; +const localDir = `./test/database_network_task_queue_nodegit`; + +beforeEach(function () { + // @ts-ignore + console.log(`... ${this.currentTest.fullTitle()}`); +}); + +before(() => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + + fs.removeSync(path.resolve(localDir)); +}); + +after(() => { + fs.removeSync(path.resolve(localDir)); +}); + +// This test needs environment variables: +// - GITDDB_GITHUB_USER_URL: URL of your GitHub account +// e.g.) https://github.com/foo/ +// - GITDDB_PERSONAL_ACCESS_TOKEN: A personal access token of your GitHub account +const maybe = + process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN + ? describe + : describe.skip; + +const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') + ? process.env.GITDDB_GITHUB_USER_URL + : process.env.GITDDB_GITHUB_USER_URL + '/'; + +const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; + +const connection: ConnectionSettingsGitHub = { + type: 'github', + personalAccessToken: token, + engine: 'nodegit', +}; + +maybe('NodeGit', networkHistory(connection, remoteURLBase, reposPrefix, localDir)); From 40fe4810553a167318ccc3f523a79cbecb0079ec Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sat, 31 Jul 2021 02:15:41 +0900 Subject: [PATCH 108/297] fix: move test for RemoteRepository to test/remote_repository directory --- .../remote_repository.test.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) rename test/{remote_base => remote_repository}/remote_repository.test.ts (98%) diff --git a/test/remote_base/remote_repository.test.ts b/test/remote_repository/remote_repository.test.ts similarity index 98% rename from test/remote_base/remote_repository.test.ts rename to test/remote_repository/remote_repository.test.ts index 7f398104..b5051ef3 100644 --- a/test/remote_base/remote_repository.test.ts +++ b/test/remote_repository/remote_repository.test.ts @@ -26,11 +26,6 @@ import { } from '../remote_utils'; import { RemoteRepository } from '../../src/remote/remote_repository'; -const ulid = monotonicFactory(); -const monoId = () => { - return ulid(Date.now()); -}; - const reposPrefix = 'test_remote_repository___'; const localDir = `./test/database_remote_repository`; @@ -59,7 +54,7 @@ const maybe = ? describe : describe.skip; -maybe(' RemoteRepository', () => { +maybe(' RemoteRepository', () => { const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') ? process.env.GITDDB_GITHUB_USER_URL : process.env.GITDDB_GITHUB_USER_URL + '/'; From 5fb81e3c5e8a5559bd2e2f6e7fce3af46f1c49e7 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sat, 31 Jul 2021 02:21:33 +0900 Subject: [PATCH 109/297] fix: add trailing [Base] to function names in remote_base --- test/remote_base/3way_merge.ts | 11 ----------- test/remote_base/combine.ts | 13 +------------ test/remote_base/network_git_documentdb.ts | 13 +------------ test/remote_base/network_history.ts | 3 +-- test/remote_base/network_task_queue.ts | 13 ++----------- test/remote_nodegit/combine.test.ts | 4 ++-- test/remote_nodegit/network_git_documentdb.test.ts | 7 +++++-- test/remote_nodegit/network_history.test.ts | 4 ++-- test/remote_nodegit/network_task_queue.test.ts | 4 ++-- 9 files changed, 16 insertions(+), 56 deletions(-) diff --git a/test/remote_base/3way_merge.ts b/test/remote_base/3way_merge.ts index 2bb3fdbe..158bd74e 100644 --- a/test/remote_base/3way_merge.ts +++ b/test/remote_base/3way_merge.ts @@ -13,7 +13,6 @@ * These tests create a new repository on GitHub if not exists. */ import expect from 'expect'; -import sinon from 'sinon'; import { Err } from '../../src/error'; import { threeWayMerge } from '../../src/remote/3way_merge'; import { GitDocumentDB } from '../../src/git_documentdb'; @@ -49,16 +48,6 @@ export const syncThreeWayMergeBase = ( return `${reposPrefix}${idCounter++}`; }; - // Use sandbox to restore stub and spy in parallel mocha tests - let sandbox: sinon.SinonSandbox; - beforeEach(function () { - sandbox = sinon.createSandbox(); - }); - - afterEach(function () { - sandbox.restore(); - }); - before(async () => { await removeRemoteRepositories(reposPrefix); }); diff --git a/test/remote_base/combine.ts b/test/remote_base/combine.ts index 2fb71111..dd9477bc 100644 --- a/test/remote_base/combine.ts +++ b/test/remote_base/combine.ts @@ -17,7 +17,6 @@ import fs from 'fs-extra'; import git from 'isomorphic-git'; import expect from 'expect'; import parse from 'parse-git-config'; -import sinon from 'sinon'; import { Err } from '../../src/error'; import { ConnectionSettings, DuplicatedFile } from '../../src/types'; import { GitDocumentDB } from '../../src/git_documentdb'; @@ -32,7 +31,7 @@ import { import { sleep } from '../../src/utils'; import { JSON_EXT } from '../../src/const'; -export const syncCombine = ( +export const syncCombineBase = ( connection: ConnectionSettings, remoteURLBase: string, reposPrefix: string, @@ -43,16 +42,6 @@ export const syncCombine = ( return `${reposPrefix}${idCounter++}`; }; - // Use sandbox to restore stub and spy in parallel mocha tests - let sandbox: sinon.SinonSandbox; - beforeEach(function () { - sandbox = sinon.createSandbox(); - }); - - afterEach(function () { - sandbox.restore(); - }); - before(async () => { await removeRemoteRepositories(reposPrefix); }); diff --git a/test/remote_base/network_git_documentdb.ts b/test/remote_base/network_git_documentdb.ts index f576d8ed..e801e096 100644 --- a/test/remote_base/network_git_documentdb.ts +++ b/test/remote_base/network_git_documentdb.ts @@ -13,14 +13,13 @@ * These tests create a new repository on GitHub if not exists. */ -import sinon from 'sinon'; import expect from 'expect'; import { ConnectionSettings, RemoteOptions } from '../../src/types'; import { destroyDBs, removeRemoteRepositories } from '../remote_utils'; import { GitDocumentDB } from '../../src/git_documentdb'; import { Err } from '../../src/error'; -export const networkGitDocumentDB = ( +export const networkGitDocumentDBBase = ( connection: ConnectionSettings, remoteURLBase: string, reposPrefix: string, @@ -31,16 +30,6 @@ export const networkGitDocumentDB = ( return `${reposPrefix}${idCounter++}`; }; - // Use sandbox to restore stub and spy in parallel mocha tests - let sandbox: sinon.SinonSandbox; - beforeEach(function () { - sandbox = sinon.createSandbox(); - }); - - afterEach(function () { - sandbox.restore(); - }); - before(async () => { await removeRemoteRepositories(reposPrefix); }); diff --git a/test/remote_base/network_history.ts b/test/remote_base/network_history.ts index 20950d33..17aca601 100644 --- a/test/remote_base/network_history.ts +++ b/test/remote_base/network_history.ts @@ -14,7 +14,6 @@ */ import expect from 'expect'; -import sinon from 'sinon'; import { ConnectionSettings } from '../../src/types'; import { createClonedDatabases, @@ -25,7 +24,7 @@ import { sleep, toSortedJSONString, utf8encode } from '../../src/utils'; import { JSON_EXT } from '../../src/const'; import { getHistoryImpl, readOldBlob } from '../../src/crud/history'; -export const networkHistory = ( +export const networkHistoryBase = ( connection: ConnectionSettings, remoteURLBase: string, reposPrefix: string, diff --git a/test/remote_base/network_task_queue.ts b/test/remote_base/network_task_queue.ts index 036d70a5..fae716f9 100644 --- a/test/remote_base/network_task_queue.ts +++ b/test/remote_base/network_task_queue.ts @@ -14,19 +14,10 @@ */ import expect from 'expect'; -import sinon from 'sinon'; import { ConnectionSettings } from '../../src/types'; -import { - createClonedDatabases, - createDatabase, - destroyDBs, - removeRemoteRepositories, -} from '../remote_utils'; -import { sleep, toSortedJSONString, utf8encode } from '../../src/utils'; -import { JSON_EXT } from '../../src/const'; -import { getHistoryImpl, readOldBlob } from '../../src/crud/history'; +import { createDatabase, destroyDBs, removeRemoteRepositories } from '../remote_utils'; -export const networkHistory = ( +export const networkTaskQueueBase = ( connection: ConnectionSettings, remoteURLBase: string, reposPrefix: string, diff --git a/test/remote_nodegit/combine.test.ts b/test/remote_nodegit/combine.test.ts index a72f19f4..194be53e 100644 --- a/test/remote_nodegit/combine.test.ts +++ b/test/remote_nodegit/combine.test.ts @@ -14,7 +14,7 @@ */ import path from 'path'; import fs from 'fs-extra'; -import { syncCombine } from '../remote_base/combine'; +import { syncCombineBase } from '../remote_base/combine'; import { ConnectionSettingsGitHub } from '../../src/types'; import { GitDocumentDB } from '../../src/git_documentdb'; @@ -58,4 +58,4 @@ const connection: ConnectionSettingsGitHub = { engine: 'nodegit', }; -maybe('NodeGit', syncCombine(connection, remoteURLBase, reposPrefix, localDir)); +maybe('NodeGit', syncCombineBase(connection, remoteURLBase, reposPrefix, localDir)); diff --git a/test/remote_nodegit/network_git_documentdb.test.ts b/test/remote_nodegit/network_git_documentdb.test.ts index 647340d6..2135b6b5 100644 --- a/test/remote_nodegit/network_git_documentdb.test.ts +++ b/test/remote_nodegit/network_git_documentdb.test.ts @@ -14,7 +14,7 @@ */ import path from 'path'; import fs from 'fs-extra'; -import { networkGitDocumentDB } from '../remote_base/network_git_documentdb'; +import { networkGitDocumentDBBase } from '../remote_base/network_git_documentdb'; import { ConnectionSettingsGitHub } from '../../src/types'; import { GitDocumentDB } from '../../src/git_documentdb'; @@ -58,4 +58,7 @@ const connection: ConnectionSettingsGitHub = { engine: 'nodegit', }; -maybe('NodeGit', networkGitDocumentDB(connection, remoteURLBase, reposPrefix, localDir)); +maybe( + 'NodeGit', + networkGitDocumentDBBase(connection, remoteURLBase, reposPrefix, localDir) +); diff --git a/test/remote_nodegit/network_history.test.ts b/test/remote_nodegit/network_history.test.ts index 83db5d77..e2b6a3cc 100644 --- a/test/remote_nodegit/network_history.test.ts +++ b/test/remote_nodegit/network_history.test.ts @@ -16,7 +16,7 @@ import path from 'path'; import fs from 'fs-extra'; import { ConnectionSettingsGitHub } from '../../src/types'; import { GitDocumentDB } from '../../src/git_documentdb'; -import { networkHistory } from '../remote_base/network_history'; +import { networkHistoryBase } from '../remote_base/network_history'; const reposPrefix = 'test_network_history_nodegit__'; const localDir = `./test/database_network_history_nodegit`; @@ -58,4 +58,4 @@ const connection: ConnectionSettingsGitHub = { engine: 'nodegit', }; -maybe('NodeGit', networkHistory(connection, remoteURLBase, reposPrefix, localDir)); +maybe('NodeGit', networkHistoryBase(connection, remoteURLBase, reposPrefix, localDir)); diff --git a/test/remote_nodegit/network_task_queue.test.ts b/test/remote_nodegit/network_task_queue.test.ts index fda1b3c9..b0863e8d 100644 --- a/test/remote_nodegit/network_task_queue.test.ts +++ b/test/remote_nodegit/network_task_queue.test.ts @@ -16,7 +16,7 @@ import path from 'path'; import fs from 'fs-extra'; import { ConnectionSettingsGitHub } from '../../src/types'; import { GitDocumentDB } from '../../src/git_documentdb'; -import { networkHistory } from '../remote_base/network_history'; +import { networkTaskQueueBase } from '../remote_base/network_task_queue'; const reposPrefix = 'test_network_task_queue_nodegit__'; const localDir = `./test/database_network_task_queue_nodegit`; @@ -58,4 +58,4 @@ const connection: ConnectionSettingsGitHub = { engine: 'nodegit', }; -maybe('NodeGit', networkHistory(connection, remoteURLBase, reposPrefix, localDir)); +maybe('NodeGit', networkTaskQueueBase(connection, remoteURLBase, reposPrefix, localDir)); From 8b65f678ae2124ca1ab908780beeb07c0dcc239c Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sat, 31 Jul 2021 03:12:31 +0900 Subject: [PATCH 110/297] test: add sync_clone test in remote_nodegit --- test/remote_base/sync_clone.test.ts | 89 -------------------------- test/remote_base/sync_clone.ts | 62 ++++++++++++++++++ test/remote_nodegit/sync_clone.test.ts | 61 ++++++++++++++++++ 3 files changed, 123 insertions(+), 89 deletions(-) delete mode 100644 test/remote_base/sync_clone.test.ts create mode 100644 test/remote_base/sync_clone.ts create mode 100644 test/remote_nodegit/sync_clone.test.ts diff --git a/test/remote_base/sync_clone.test.ts b/test/remote_base/sync_clone.test.ts deleted file mode 100644 index 7b2a00be..00000000 --- a/test/remote_base/sync_clone.test.ts +++ /dev/null @@ -1,89 +0,0 @@ -/* eslint-disable @typescript-eslint/naming-convention */ -/** - * GitDocumentDB - * Copyright (c) Hidekazu Kubota - * - * This source code is licensed under the Mozilla Public License Version 2.0 - * found in the LICENSE file in the root directory of this source tree. - */ - -/** - * Test clone - * by using GitHub Personal Access Token - */ -import path from 'path'; -import fs from 'fs-extra'; -import expect from 'expect'; -import { createDatabase, destroyDBs, removeRemoteRepositories } from '../remote_utils'; -import { GitDocumentDB } from '../../src/git_documentdb'; -import { RemoteEngine } from '../../src/remote/remote_engine'; - -const reposPrefix = 'test_sync_clone___'; -const localDir = `./test/database_sync_clone`; - -let idCounter = 0; -const serialId = () => { - return `${reposPrefix}${idCounter++}`; -}; - -beforeEach(function () { - // @ts-ignore - console.log(`... ${this.currentTest.fullTitle()}`); -}); - -before(() => { - // eslint-disable-next-line @typescript-eslint/no-var-requires - GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); - - fs.removeSync(path.resolve(localDir)); -}); - -after(() => { - fs.removeSync(path.resolve(localDir)); -}); - -// GITDDB_GITHUB_USER_URL: URL of your GitHub account -// e.g.) https://github.com/foo/ -const maybe = - process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN - ? describe - : describe.skip; - -maybe(' clone', () => { - const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') - ? process.env.GITDDB_GITHUB_USER_URL - : process.env.GITDDB_GITHUB_USER_URL + '/'; - const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; - - before(async () => { - // Remove remote - await removeRemoteRepositories(reposPrefix); - }); - - describe('using NodeGit', () => { - it('returns undefined when invalid RemoteOptions', async () => { - // @ts-ignore - await expect(RemoteEngine.nodegit.clone('tmp')).resolves.toBeFalsy(); - await expect( - RemoteEngine.nodegit.clone('tmp', { remoteUrl: undefined }) - ).resolves.toBeFalsy(); - }); - - it('clones a repository by NodeGit', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId); - const jsonA1 = { _id: '1', name: 'fromA' }; - await dbA.put(jsonA1); - await syncA.tryPush(); - - const dbNameB = serialId(); - const workingDir = localDir + '/' + dbNameB; - await RemoteEngine[syncA.engine].clone(workingDir, syncA.options); - - const dbB = new GitDocumentDB({ localDir, dbName: dbNameB }); - await dbB.open(); - await expect(dbB.get(jsonA1._id)).resolves.toEqual(jsonA1); - - await destroyDBs([dbA, dbB]); - }); - }); -}); diff --git a/test/remote_base/sync_clone.ts b/test/remote_base/sync_clone.ts new file mode 100644 index 00000000..39cd0c09 --- /dev/null +++ b/test/remote_base/sync_clone.ts @@ -0,0 +1,62 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +/** + * Test clone + * by using GitHub Personal Access Token + */ +import path from 'path'; +import fs from 'fs-extra'; +import expect from 'expect'; +import { createDatabase, destroyDBs, removeRemoteRepositories } from '../remote_utils'; +import { GitDocumentDB } from '../../src/git_documentdb'; +import { RemoteEngine } from '../../src/remote/remote_engine'; +import { ConnectionSettings } from '../../src/types'; + +export const syncCloneBase = ( + connection: ConnectionSettings, + remoteURLBase: string, + reposPrefix: string, + localDir: string +) => () => { + let idCounter = 0; + const serialId = () => { + return `${reposPrefix}${idCounter++}`; + }; + + before(async () => { + await removeRemoteRepositories(reposPrefix); + }); + + describe(' clone', () => { + it('clones a repository', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, + }); + const jsonA1 = { _id: '1', name: 'fromA' }; + await dbA.put(jsonA1); + await syncA.tryPush(); + + const dbNameB = serialId(); + const workingDir = localDir + '/' + dbNameB; + await RemoteEngine[syncA.engine].clone( + workingDir, + syncA.options, + 'origin', + dbA.logger + ); + + const dbB = new GitDocumentDB({ localDir, dbName: dbNameB }); + await dbB.open(); + await expect(dbB.get(jsonA1._id)).resolves.toEqual(jsonA1); + + await destroyDBs([dbA, dbB]); + }); + }); +}; diff --git a/test/remote_nodegit/sync_clone.test.ts b/test/remote_nodegit/sync_clone.test.ts new file mode 100644 index 00000000..790e052e --- /dev/null +++ b/test/remote_nodegit/sync_clone.test.ts @@ -0,0 +1,61 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +/** + * Test tryPush + * by using GitHub Personal Access Token + * These tests create a new repository on GitHub if not exists. + */ +import path from 'path'; +import fs from 'fs-extra'; +import { syncCloneBase } from '../remote_base/sync_clone'; +import { ConnectionSettingsGitHub } from '../../src/types'; +import { GitDocumentDB } from '../../src/git_documentdb'; + +const reposPrefix = 'test_sync_clone_nodegit___'; +const localDir = `./test/database_sync_clone_nodegit`; + +beforeEach(function () { + // @ts-ignore + console.log(`... ${this.currentTest.fullTitle()}`); +}); + +before(() => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + + fs.removeSync(path.resolve(localDir)); +}); + +after(() => { + fs.removeSync(path.resolve(localDir)); +}); + +// This test needs environment variables: +// - GITDDB_GITHUB_USER_URL: URL of your GitHub account +// e.g.) https://github.com/foo/ +// - GITDDB_PERSONAL_ACCESS_TOKEN: A personal access token of your GitHub account +const maybe = + process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN + ? describe + : describe.skip; + +const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') + ? process.env.GITDDB_GITHUB_USER_URL + : process.env.GITDDB_GITHUB_USER_URL + '/'; + +const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; + +const connection: ConnectionSettingsGitHub = { + type: 'github', + personalAccessToken: token, + engine: 'nodegit', +}; + +maybe('NodeGit', syncCloneBase(connection, remoteURLBase, reposPrefix, localDir)); From 7912db88be0d75ff8aae27b37b2195c760ffe61e Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sat, 31 Jul 2021 15:59:28 +0900 Subject: [PATCH 111/297] test: add test for sync_events and sync_live in remote_nodegit --- test/remote_base/sync_events.test.ts | 1194 ---------------------- test/remote_base/sync_events.ts | 1204 +++++++++++++++++++++++ test/remote_base/sync_live.ts | 498 +++++----- test/remote_nodegit/sync_events.test.ts | 61 ++ test/remote_nodegit/sync_live.test.ts | 61 ++ 5 files changed, 1550 insertions(+), 1468 deletions(-) delete mode 100644 test/remote_base/sync_events.test.ts create mode 100644 test/remote_base/sync_events.ts create mode 100644 test/remote_nodegit/sync_events.test.ts create mode 100644 test/remote_nodegit/sync_live.test.ts diff --git a/test/remote_base/sync_events.test.ts b/test/remote_base/sync_events.test.ts deleted file mode 100644 index 2402d835..00000000 --- a/test/remote_base/sync_events.test.ts +++ /dev/null @@ -1,1194 +0,0 @@ -/* eslint-disable @typescript-eslint/naming-convention */ -/** - * GitDocumentDB - * Copyright (c) Hidekazu Kubota - * - * This source code is licensed under the Mozilla Public License Version 2.0 - * found in the LICENSE file in the root directory of this source tree. - */ - -/** - * Test synchronization events - * by using GitHub Personal Access Token - * These tests create a new repository on GitHub if not exists. - */ -import path from 'path'; -import fs from 'fs-extra'; -import expect from 'expect'; -import sinon from 'sinon'; -import { - ChangedFile, - RemoteOptions, - SyncResult, - SyncResultFastForwardMerge, - SyncResultMergeAndPush, - SyncResultPush, - TaskMetadata, -} from '../../src/types'; -import { sleep } from '../../src/utils'; -import { - compareWorkingDirAndBlobs, - createClonedDatabases, - createDatabase, - destroyDBs, - destroyRemoteRepository, - getChangedFileDelete, - getChangedFileInsert, - getChangedFileUpdate, - getCommitInfo, - getWorkingDirDocs, - removeRemoteRepositories, -} from '../remote_utils'; -import { GitDocumentDB } from '../../src/git_documentdb'; -import { RemoteEngine } from '../../src/remote/remote_engine'; -import { Sync } from '../../src/remote/sync'; -import { Err } from '../../src/error'; -import { MINIMUM_SYNC_INTERVAL } from '../../src/const'; - -// eslint-disable-next-line @typescript-eslint/no-var-requires -const pushWorker_module = require('../../src/remote/push_worker'); - -const reposPrefix = 'test_sync_events___'; -const localDir = `./test/database_sync_events`; - -let idCounter = 0; -const serialId = () => { - return `${reposPrefix}${idCounter++}`; -}; - -// Use sandbox to restore stub and spy in parallel mocha tests -let sandbox: sinon.SinonSandbox; -beforeEach(function () { - // @ts-ignore - console.log(`... ${this.currentTest.fullTitle()}`); - sandbox = sinon.createSandbox(); -}); - -afterEach(function () { - sandbox.restore(); -}); - -before(() => { - // eslint-disable-next-line @typescript-eslint/no-var-requires - GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); - - fs.removeSync(path.resolve(localDir)); -}); - -after(() => { - // It may throw error due to memory leak of getCommitLogs() - // fs.removeSync(path.resolve(localDir)); -}); - -// GITDDB_GITHUB_USER_URL: URL of your GitHub account -// e.g.) https://github.com/foo/ -const maybe = - process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN - ? describe - : describe.skip; - -maybe(' [event]', () => { - const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') - ? process.env.GITDDB_GITHUB_USER_URL - : process.env.GITDDB_GITHUB_USER_URL + '/'; - const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; - - before(async () => { - await removeRemoteRepositories(reposPrefix); - }); - - /** - * Events - */ - describe('change', () => { - it('occurs once', async () => { - const [dbA, dbB, syncA, syncB] = await createClonedDatabases( - remoteURLBase, - localDir, - serialId - ); - - // A puts and pushes - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResult1 = await dbA.put(jsonA1); - await syncA.tryPush(); - - // B syncs - let result: SyncResultFastForwardMerge | undefined; - let changeTaskId = ''; - syncB.on('change', (syncResult: SyncResult, taskMetadata: TaskMetadata) => { - result = syncResult as SyncResultFastForwardMerge; - changeTaskId = taskMetadata.taskId; - }); - let complete = false; - let endTaskId = ''; - syncB.on('complete', (taskMetadata: TaskMetadata) => { - complete = true; - endTaskId = taskMetadata.taskId; - }); - await syncB.trySync(); - - // eslint-disable-next-line no-unmodified-loop-condition - while (!complete) { - // eslint-disable-next-line no-await-in-loop - await sleep(1000); - } - - expect(result!.action).toBe('fast-forward merge'); - - expect(result!.commits).toMatchObject({ - local: getCommitInfo([putResult1]), - }); - - expect(result!.changes.local).toEqual([getChangedFileInsert(jsonA1, putResult1)]); - - expect(changeTaskId).toBe(endTaskId); - - await destroyDBs([dbA, dbB]); - }); - - it('is propagated between local and remote sites', async () => { - const [dbA, dbB, syncA, syncB] = await createClonedDatabases( - remoteURLBase, - localDir, - serialId - ); - - // A puts and pushes - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResultA1 = await dbA.put(jsonA1); - await syncA.trySync(); - - // B puts and pushes - const jsonB1 = { _id: '1', name: 'fromB' }; - const putResultB1 = await dbB.put(jsonB1); - - let resultA: SyncResultFastForwardMerge | undefined; - let completeA = false; - syncA.on('change', (syncResult: SyncResult) => { - resultA = syncResult as SyncResultFastForwardMerge; - console.log('A: ' + resultA.action); - if (resultA.action === 'fast-forward merge') { - completeA = true; - } - }); - - let resultB: SyncResultFastForwardMerge | undefined; - syncB.on('change', (syncResult: SyncResult) => { - resultB = syncResult as SyncResultFastForwardMerge; - console.log('B: ' + resultB.action); - }); - let completeB = false; - syncB.on('complete', () => { - completeB = true; - }); - - syncA.resume({ ...syncA.options, interval: 3000 }); - syncB.resume({ ...syncA.options, interval: 3000 }); - - // eslint-disable-next-line no-unmodified-loop-condition - while (!completeA || !completeB) { - // eslint-disable-next-line no-await-in-loop - await sleep(1000); - } - - expect(resultA!.action).toBe('fast-forward merge'); - - expect(resultA!.changes.local).toEqual([ - getChangedFileUpdate(jsonA1, putResultA1, jsonB1, putResultB1), - ]); - - expect(resultB!.action).toBe('resolve conflicts and push'); - - expect(resultB!.changes.local).toEqual([]); - - expect(getWorkingDirDocs(dbA)).toEqual([jsonB1]); - expect(getWorkingDirDocs(dbB)).toEqual([jsonB1]); - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); - - await destroyDBs([dbA, dbB]); - }); - - /** - * before: jsonA1 jsonA2 - * dbA : -jsonA1 -jsonA2 - * dbB : jsonB3 - * after : jsonB3 - */ - it('occurs with every retry', async () => { - const [dbA, dbB, syncA, syncB] = await createClonedDatabases( - remoteURLBase, - localDir, - serialId - ); - - await dbA.put({ _id: '1' }); - await syncA.tryPush(); - - await dbB.put({ _id: '2' }); - - const stubPush = sandbox.stub(pushWorker_module, 'pushWorker'); - stubPush - .onFirstCall() - .rejects(new RemoteEngine[syncB.engine].Err.UnfetchedCommitExistsError()); - - const resultsB: SyncResult[] = []; - syncB.on('change', (result: SyncResult) => { - if (resultsB.length === 0) { - // Restore stub after first change event. - stubPush.restore(); - } - // console.log('B: ' + JSON.stringify(result)); - resultsB.push(result); - }); - await syncB.trySync(); - - await sleep(syncA.options.retryInterval! + 5000); - expect(resultsB.length).toBe(2); - expect(resultsB[0].action).toBe('merge and push error'); - expect(resultsB[1].action).toBe('push'); - - await destroyDBs([dbA, dbB]); - }); - - it('is followed by localChange', async () => { - const [dbA, dbB, syncA, syncB] = await createClonedDatabases( - remoteURLBase, - localDir, - serialId - ); - - // A puts and pushes - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResult1 = await dbA.put(jsonA1); - await syncA.tryPush(); - - // B syncs - let changes: ChangedFile[] = []; - let changeTaskId = ''; - syncB.on('localChange', (localChanges: ChangedFile[], taskMetadata: TaskMetadata) => { - changes = localChanges; - changeTaskId = taskMetadata.taskId; - }); - let complete = false; - let endTaskId = ''; - syncB.on('complete', (taskMetadata: TaskMetadata) => { - complete = true; - endTaskId = taskMetadata.taskId; - }); - await syncB.trySync(); - - // eslint-disable-next-line no-unmodified-loop-condition - while (!complete) { - // eslint-disable-next-line no-await-in-loop - await sleep(1000); - } - - expect(changes.length).toBe(1); - expect(changes).toEqual([getChangedFileInsert(jsonA1, putResult1)]); - - expect(changeTaskId).toBe(endTaskId); - - await destroyDBs([dbA, dbB]); - }); - - /** - * before: jsonA1 jsonA2 - * dbA : -jsonA1 -jsonA2 - * dbB : jsonB3 - * after : jsonB3 - */ - it('occurs localChanges when SyncResultMergeAndPushError', async () => { - const [dbA, dbB, syncA, syncB] = await createClonedDatabases( - remoteURLBase, - localDir, - serialId - ); - - await dbA.put({ _id: '1' }); - await syncA.tryPush(); - - await dbB.put({ _id: '2' }); - - const stubPush = sandbox.stub(pushWorker_module, 'pushWorker'); - stubPush - .onFirstCall() - .rejects(new RemoteEngine[syncB.engine].Err.UnfetchedCommitExistsError()); - - const localChangesB: ChangedFile[][] = []; - syncB.on('localChange', (changes: ChangedFile[]) => { - if (localChangesB.length === 0) { - // Restore stub after first change event. - stubPush.restore(); - } - localChangesB.push(changes); - }); - - await syncB.trySync(); - - await sleep(syncB.options.retryInterval! + 5000); - expect(localChangesB.length).toBe(1); - - await syncB.trySync(); - }); - - it('is followed by remoteChange', async () => { - const [dbA, dbB, syncA, syncB] = await createClonedDatabases( - remoteURLBase, - localDir, - serialId - ); - - let changes: ChangedFile[] = []; - let changeTaskId = ''; - syncB.on( - 'remoteChange', - (remoteChanges: ChangedFile[], taskMetadata: TaskMetadata) => { - changes = remoteChanges; - changeTaskId = taskMetadata.taskId; - } - ); - let complete = false; - let endTaskId = ''; - syncB.on('complete', (taskMetadata: TaskMetadata) => { - complete = true; - endTaskId = taskMetadata.taskId; - }); - - // B puts and syncs - const jsonB1 = { _id: '1', name: 'fromB' }; - const putResult1 = await dbB.put(jsonB1); - await syncB.trySync(); - - // eslint-disable-next-line no-unmodified-loop-condition - while (!complete) { - // eslint-disable-next-line no-await-in-loop - await sleep(1000); - } - - expect(changes.length).toBe(1); - - expect(changes).toEqual([getChangedFileInsert(jsonB1, putResult1)]); - - expect(changeTaskId).toBe(endTaskId); - - await destroyDBs([dbA, dbB]); - }); - - /** - * before: jsonA1 jsonA2 - * dbA : -jsonA1 -jsonA2 - * dbB : jsonB3 - * after : jsonB3 - */ - it('occurs remoteChanges after SyncResultMergeAndPushError', async () => { - const [dbA, dbB, syncA, syncB] = await createClonedDatabases( - remoteURLBase, - localDir, - serialId - ); - - await dbA.put({ _id: '1' }); - await syncA.tryPush(); - - await dbB.put({ _id: '2' }); - - const stubPush = sandbox.stub(pushWorker_module, 'pushWorker'); - stubPush - .onFirstCall() - .rejects(new RemoteEngine[syncB.engine].Err.UnfetchedCommitExistsError()); - - let firstChange = true; - syncB.on('change', (changes: ChangedFile[]) => { - if (firstChange) { - firstChange = false; - // Restore stub after first change event. - stubPush.restore(); - } - }); - const remoteChangesB: ChangedFile[][] = []; - syncB.on('remoteChange', (changes: ChangedFile[]) => { - remoteChangesB.push(changes); - }); - - await syncB.trySync(); - - await sleep(syncB.options.retryInterval! + 5000); - expect(remoteChangesB.length).toBe(1); - - await syncB.trySync(); - }); - }); - - describe('filtered by collectionPath', () => { - it('occurs change and localChange events', async () => { - const [dbA, dbB, syncA, syncB] = await createClonedDatabases( - remoteURLBase, - localDir, - serialId - ); - - // A puts and pushes - const col01 = dbA.collection('col01'); - const col02 = dbA.collection('col02'); - const jsonA1 = { _id: '1', name: 'fromA' }; - const jsonA2 = { _id: '2', name: 'fromA' }; - const putResult1 = await col01.put(jsonA1); - const putResult2 = await col02.put(jsonA2); - - const jsonA1dash = { _id: 'col01/1', name: 'fromA' }; - const putResult1dash = { ...putResult1, _id: 'col01/1' }; - const jsonA2dash = { _id: 'col02/2', name: 'fromA' }; - const putResult2dash = { ...putResult2, _id: 'col02/2' }; - - await syncA.tryPush(); - - // B syncs - let col01Result: SyncResultFastForwardMerge | undefined; - let col01ChangeTaskId: string | undefined; - syncB.on( - 'change', - (syncResult: SyncResult, taskMetadata: TaskMetadata) => { - col01Result = syncResult as SyncResultFastForwardMerge; - col01ChangeTaskId = taskMetadata.taskId; - }, - 'col01' - ); - - let changedFiles: ChangedFile[]; - syncB.on( - 'localChange', - (files: ChangedFile[], taskMetadata: TaskMetadata) => { - changedFiles = files; - }, - 'col02' - ); - - let rootResult: SyncResultFastForwardMerge | undefined; - let rootChangeTaskId: string | undefined; - syncB.on( - 'change', - (syncResult: SyncResult, taskMetadata: TaskMetadata) => { - rootResult = syncResult as SyncResultFastForwardMerge; - rootChangeTaskId = taskMetadata.taskId; - }, - '' - ); - - let complete = false; - let endTaskId = ''; - let completeCollectionPath: string | undefined; - syncB.on('complete', (taskMetadata: TaskMetadata) => { - complete = true; - endTaskId = taskMetadata.taskId; - completeCollectionPath = taskMetadata.collectionPath; - }); - await syncB.trySync(); - - // eslint-disable-next-line no-unmodified-loop-condition - while (!complete) { - // eslint-disable-next-line no-await-in-loop - await sleep(1000); - } - - expect(col01Result?.action).toBe('fast-forward merge'); - expect(rootResult?.action).toBe('fast-forward merge'); - - expect(col01Result?.commits).toMatchObject({ - local: getCommitInfo([putResult1, putResult2]), - }); - expect(rootResult?.commits).toMatchObject({ - local: getCommitInfo([putResult1, putResult2]), - }); - - expect(col01Result?.changes.local).toEqual([ - getChangedFileInsert(jsonA1, putResult1), - ]); - expect(changedFiles!).toEqual([getChangedFileInsert(jsonA2, putResult2)]); - - expect(rootResult?.changes.local).toEqual([ - getChangedFileInsert(jsonA1dash, putResult1dash), - getChangedFileInsert(jsonA2dash, putResult2dash), - ]); - - expect(col01ChangeTaskId).toBe(endTaskId); - expect(rootChangeTaskId).toBe(endTaskId); - - expect(completeCollectionPath).toBe(''); - - await destroyDBs([dbA, dbB]); - }); - - it('occurs change events with update and delete', async () => { - const [dbA, dbB, syncA, syncB] = await createClonedDatabases( - remoteURLBase, - localDir, - serialId - ); - - // A puts and pushes - const col01 = dbA.collection('col01'); - const col02 = dbA.collection('col02'); - const jsonA1 = { _id: '1', name: 'fromA' }; - const jsonA2 = { _id: '2', name: 'fromA' }; - const putResult1 = await col01.put(jsonA1); - await col02.put(jsonA2); - await syncA.trySync(); - const jsonA1updated = { _id: '1', name: 'updated' }; - const putResult1updated = await col01.put(jsonA1updated); - const deleteResult2 = await col02.delete(jsonA2); - - let col01Result: SyncResultPush | undefined; - let col01ChangeTaskId: string | undefined; - syncA.on( - 'change', - (syncResult: SyncResult, taskMetadata: TaskMetadata) => { - col01Result = syncResult as SyncResultPush; - col01ChangeTaskId = taskMetadata.taskId; - }, - 'col01' - ); - - let changedFiles: ChangedFile[]; - syncA.on( - 'remoteChange', - (files: ChangedFile[], taskMetadata: TaskMetadata) => { - changedFiles = files; - }, - 'col02' - ); - - let complete = false; - syncA.on('complete', (taskMetadata: TaskMetadata) => { - complete = true; - }); - await syncA.tryPush(); - - // eslint-disable-next-line no-unmodified-loop-condition - while (!complete) { - // eslint-disable-next-line no-await-in-loop - await sleep(1000); - } - - expect(col01Result?.action).toBe('push'); - - expect(col01Result?.commits).toMatchObject({ - remote: getCommitInfo([putResult1updated, deleteResult2]), - }); - - expect(col01Result?.changes.remote).toEqual([ - getChangedFileUpdate(jsonA1, putResult1, jsonA1updated, putResult1updated), - ]); - expect(changedFiles!).toEqual([getChangedFileDelete(jsonA2, deleteResult2)]); - - await destroyDBs([dbA, dbB]); - }); - - it('occurs change and remoteChange events by trySync', async () => { - const [dbA, dbB, syncA, syncB] = await createClonedDatabases( - remoteURLBase, - localDir, - serialId - ); - - // A puts and pushes - const col01 = dbA.collection('col01'); - const col02 = dbA.collection('col02'); - const jsonA1 = { _id: '1', name: 'fromA' }; - const jsonA2 = { _id: '2', name: 'fromA' }; - const putResult1 = await col01.put(jsonA1); - const putResult2 = await col02.put(jsonA2); - - const jsonA1dash = { _id: 'col01/1', name: 'fromA' }; - const putResult1dash = { ...putResult1, _id: 'col01/1' }; - const jsonA2dash = { _id: 'col02/2', name: 'fromA' }; - const putResult2dash = { ...putResult2, _id: 'col02/2' }; - - let col01Result: SyncResultPush | undefined; - let col01ChangeTaskId: string | undefined; - syncA.on( - 'change', - (syncResult: SyncResult, taskMetadata: TaskMetadata) => { - col01Result = syncResult as SyncResultPush; - col01ChangeTaskId = taskMetadata.taskId; - }, - 'col01' - ); - - let changedFiles: ChangedFile[]; - syncA.on( - 'remoteChange', - (files: ChangedFile[], taskMetadata: TaskMetadata) => { - changedFiles = files; - }, - 'col02' - ); - - let rootResult: SyncResultPush | undefined; - let rootChangeTaskId: string | undefined; - syncA.on( - 'change', - (syncResult: SyncResult, taskMetadata: TaskMetadata) => { - rootResult = syncResult as SyncResultPush; - rootChangeTaskId = taskMetadata.taskId; - }, - '' - ); - - let complete = false; - let endTaskId = ''; - let completeCollectionPath: string | undefined; - syncA.on('complete', (taskMetadata: TaskMetadata) => { - complete = true; - endTaskId = taskMetadata.taskId; - completeCollectionPath = taskMetadata.collectionPath; - }); - await syncA.trySync(); - - // eslint-disable-next-line no-unmodified-loop-condition - while (!complete) { - // eslint-disable-next-line no-await-in-loop - await sleep(1000); - } - - expect(col01Result?.action).toBe('push'); - expect(rootResult?.action).toBe('push'); - - expect(col01Result?.commits).toMatchObject({ - remote: getCommitInfo([putResult1, putResult2]), - }); - expect(rootResult?.commits).toMatchObject({ - remote: getCommitInfo([putResult1, putResult2]), - }); - - expect(col01Result?.changes.remote).toEqual([ - getChangedFileInsert(jsonA1, putResult1), - ]); - expect(changedFiles!).toEqual([getChangedFileInsert(jsonA2, putResult2)]); - - expect(rootResult?.changes.remote).toEqual([ - getChangedFileInsert(jsonA1dash, putResult1dash), - getChangedFileInsert(jsonA2dash, putResult2dash), - ]); - - expect(col01ChangeTaskId).toBe(endTaskId); - expect(rootChangeTaskId).toBe(endTaskId); - - expect(completeCollectionPath).toBe(''); - - await destroyDBs([dbA, dbB]); - }); - - it('occurs change and remoteChange events by tryPush', async () => { - const [dbA, dbB, syncA, syncB] = await createClonedDatabases( - remoteURLBase, - localDir, - serialId - ); - - // A puts and pushes - const col01 = dbA.collection('col01'); - const col02 = dbA.collection('col02'); - const jsonA1 = { _id: '1', name: 'fromA' }; - const jsonA2 = { _id: '2', name: 'fromA' }; - const putResult1 = await col01.put(jsonA1); - const putResult2 = await col02.put(jsonA2); - - const jsonA1dash = { _id: 'col01/1', name: 'fromA' }; - const putResult1dash = { ...putResult1, _id: 'col01/1' }; - const jsonA2dash = { _id: 'col02/2', name: 'fromA' }; - const putResult2dash = { ...putResult2, _id: 'col02/2' }; - - let col01Result: SyncResultPush | undefined; - let col01ChangeTaskId: string | undefined; - syncA.on( - 'change', - (syncResult: SyncResult, taskMetadata: TaskMetadata) => { - col01Result = syncResult as SyncResultPush; - col01ChangeTaskId = taskMetadata.taskId; - }, - 'col01' - ); - - let changedFiles: ChangedFile[]; - syncA.on( - 'remoteChange', - (files: ChangedFile[], taskMetadata: TaskMetadata) => { - changedFiles = files; - }, - 'col02' - ); - - let rootResult: SyncResultPush | undefined; - let rootChangeTaskId: string | undefined; - syncA.on( - 'change', - (syncResult: SyncResult, taskMetadata: TaskMetadata) => { - rootResult = syncResult as SyncResultPush; - rootChangeTaskId = taskMetadata.taskId; - }, - '' - ); - - let complete = false; - let endTaskId = ''; - let completeCollectionPath: string | undefined; - syncA.on('complete', (taskMetadata: TaskMetadata) => { - complete = true; - endTaskId = taskMetadata.taskId; - completeCollectionPath = taskMetadata.collectionPath; - }); - await syncA.tryPush(); - - // eslint-disable-next-line no-unmodified-loop-condition - while (!complete) { - // eslint-disable-next-line no-await-in-loop - await sleep(1000); - } - - expect(col01Result?.action).toBe('push'); - expect(rootResult?.action).toBe('push'); - - expect(col01Result?.commits).toMatchObject({ - remote: getCommitInfo([putResult1, putResult2]), - }); - expect(rootResult?.commits).toMatchObject({ - remote: getCommitInfo([putResult1, putResult2]), - }); - - expect(col01Result?.changes.remote).toEqual([ - getChangedFileInsert(jsonA1, putResult1), - ]); - expect(changedFiles!).toEqual([getChangedFileInsert(jsonA2, putResult2)]); - - expect(rootResult?.changes.remote).toEqual([ - getChangedFileInsert(jsonA1dash, putResult1dash), - getChangedFileInsert(jsonA2dash, putResult2dash), - ]); - - expect(col01ChangeTaskId).toBe(endTaskId); - expect(rootChangeTaskId).toBe(endTaskId); - - expect(completeCollectionPath).toBe(''); - - await destroyDBs([dbA, dbB]); - }); - - it('occurs change, localChange, and remoteChange events by merge and push', async () => { - const [dbA, dbB, syncA, syncB] = await createClonedDatabases( - remoteURLBase, - localDir, - serialId - ); - - // A puts and pushes - const col01 = dbA.collection('col01'); - const col02 = dbA.collection('col02'); - const jsonA1 = { _id: '1', name: 'fromA' }; - const jsonA2 = { _id: '2', name: 'fromA' }; - const putResult1 = await col01.put(jsonA1); - const putResult2 = await col02.put(jsonA2); - - const jsonA1dash = { _id: 'col01/1', name: 'fromA' }; - const putResult1dash = { ...putResult1, _id: 'col01/1' }; - const jsonA2dash = { _id: 'col02/2', name: 'fromA' }; - const putResult2dash = { ...putResult2, _id: 'col02/2' }; - - const jsonB3 = { _id: '3', name: 'fromB' }; - const putResult3 = await dbB.collection('col01').put(jsonB3); - const jsonB3dash = { _id: 'col01/3', name: 'fromB' }; - const putResult3dash = { ...putResult3, _id: 'col01/3' }; - await syncB.trySync(); - - let col01Result: SyncResultMergeAndPush | undefined; - let col01ChangeTaskId: string | undefined; - syncA.on( - 'change', - (syncResult: SyncResult, taskMetadata: TaskMetadata) => { - col01Result = syncResult as SyncResultMergeAndPush; - col01ChangeTaskId = taskMetadata.taskId; - }, - 'col01' - ); - - let localChangedFiles: ChangedFile[]; - syncA.on( - 'localChange', - (files: ChangedFile[], taskMetadata: TaskMetadata) => { - localChangedFiles = files; - }, - 'col01' - ); - - let remoteChangedFiles: ChangedFile[]; - syncA.on( - 'remoteChange', - (files: ChangedFile[], taskMetadata: TaskMetadata) => { - remoteChangedFiles = files; - }, - 'col02' - ); - - let rootResult: SyncResultMergeAndPush | undefined; - let rootChangeTaskId: string | undefined; - syncA.on( - 'change', - (syncResult: SyncResult, taskMetadata: TaskMetadata) => { - rootResult = syncResult as SyncResultMergeAndPush; - rootChangeTaskId = taskMetadata.taskId; - }, - '' - ); - - let complete = false; - let endTaskId = ''; - let completeCollectionPath: string | undefined; - syncA.on( - 'complete', - (taskMetadata: TaskMetadata) => { - complete = true; - endTaskId = taskMetadata.taskId; - completeCollectionPath = taskMetadata.collectionPath; - }, - 'col01' - ); - await syncA.trySync(); - - // eslint-disable-next-line no-unmodified-loop-condition - while (!complete) { - // eslint-disable-next-line no-await-in-loop - await sleep(1000); - } - - expect(col01Result?.action).toBe('merge and push'); - expect(rootResult?.action).toBe('merge and push'); - - expect(col01Result?.commits).toMatchObject({ - remote: getCommitInfo([putResult1, putResult2, 'merge']), - local: getCommitInfo([putResult3, 'merge']), - }); - expect(rootResult?.commits).toMatchObject({ - remote: getCommitInfo([putResult1, putResult2, 'merge']), - local: getCommitInfo([putResult3, 'merge']), - }); - - expect(col01Result?.changes.remote).toEqual([ - getChangedFileInsert(jsonA1, putResult1), - ]); - expect(col01Result?.changes.local).toEqual([ - getChangedFileInsert(jsonB3, putResult3), - ]); - expect(localChangedFiles!).toEqual([getChangedFileInsert(jsonB3, putResult3)]); - expect(remoteChangedFiles!).toEqual([getChangedFileInsert(jsonA2, putResult2)]); - - expect(rootResult?.changes.remote).toEqual([ - getChangedFileInsert(jsonA1dash, putResult1dash), - getChangedFileInsert(jsonA2dash, putResult2dash), - ]); - expect(rootResult?.changes.local).toEqual([ - getChangedFileInsert(jsonB3dash, putResult3dash), - ]); - - expect(col01ChangeTaskId).toBe(endTaskId); - expect(rootChangeTaskId).toBe(endTaskId); - - expect(completeCollectionPath).toBe('col01/'); - - await destroyDBs([dbA, dbB]); - }); - }); - - it('pause and resume', async () => { - const [dbA, dbB, syncA, syncB] = await createClonedDatabases( - remoteURLBase, - localDir, - serialId, - { - connection: { type: 'github', personalAccessToken: token }, - includeCommits: true, - live: true, - interval: 3000, - } - ); - - let resume = false; - syncB.on('resume', () => { - resume = true; - }); - let pause = false; - syncB.on('pause', () => { - pause = true; - }); - let complete = false; - syncB.on('complete', () => { - complete = true; - }); - - // Check first complete event - - let sleepTime = 0; - // eslint-disable-next-line no-unmodified-loop-condition - while (!complete) { - // eslint-disable-next-line no-await-in-loop - await sleep(1000); - sleepTime += 1000; - } - - syncB.pause(); - expect(pause).toBe(true); - expect(resume).toBe(false); - expect(syncB.options.live).toBe(false); - - // Check second complete event - complete = false; // reset - // fast forward timer - await sleep(sleepTime + 1000); - - expect(complete).toBe(false); // complete will not happen because synchronization is paused. - - syncB.resume(); - expect(resume).toBe(true); - expect(syncB.options.live).toBe(true); - - // Check third complete event - complete = false; // reset - // fast forward timer - await sleep(sleepTime + 1000); - - expect(complete).toBe(true); - - await destroyDBs([dbA, dbB]); - }); - - it('active at initialization', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbNameA = serialId(); - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir, - }); - const options: RemoteOptions = { - remoteUrl: remoteURL, - connection: { type: 'github', personalAccessToken: token }, - includeCommits: true, - live: true, - }; - await dbA.open(); - - const sync = new Sync(dbA, options); - let resume = false; - sync.on('resume', () => { - resume = true; - }); - - const syncResult = await sync.init(); - console.log(JSON.stringify(syncResult)); - expect(resume).toBe(true); - - sync.close(); - - await destroyDBs([dbA]); - }); - - it('starts once', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection: { type: 'github', personalAccessToken: token }, - includeCommits: true, - live: true, - interval: 3000, - }); - - let start = false; - syncA.on('start', () => { - start = true; - }); - - expect(start).toBe(false); - - let sleepTime = 0; - // eslint-disable-next-line no-unmodified-loop-condition - while (!start) { - // eslint-disable-next-line no-await-in-loop - await sleep(1000); - sleepTime += 1000; - } - - expect(start).toBe(true); - expect(sleepTime).toBeLessThan(5000); - - await destroyDBs([dbA]); - }); - - it('starts repeatedly', async () => { - const interval = MINIMUM_SYNC_INTERVAL; - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection: { type: 'github', personalAccessToken: token }, - includeCommits: true, - live: true, - interval, - }); - - let counter = 0; - syncA.on('start', () => { - counter++; - }); - - await sleep(interval * 5); - - expect(counter).toBeGreaterThanOrEqual(3); - - await destroyDBs([dbA]); - }); - - it('starts event returns taskMetaData and current retries', async () => { - const interval = MINIMUM_SYNC_INTERVAL; - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection: { type: 'github', personalAccessToken: token }, - includeCommits: true, - live: true, - interval, - }); - - let counter = 0; - let taskId = ''; - let currentRetries = -1; - syncA.on('start', (taskMetadata: TaskMetadata, _currentRetries: number) => { - counter++; - taskId = taskMetadata.taskId; - currentRetries = _currentRetries; - }); - - await sleep(interval * 5); - - expect(counter).toBeGreaterThanOrEqual(3); - expect(taskId).not.toBe(''); - expect(currentRetries).toBe(0); - - await destroyDBs([dbA]); - }); - - it('completes once', async () => { - const interval = MINIMUM_SYNC_INTERVAL; - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection: { type: 'github', personalAccessToken: token }, - includeCommits: true, - live: true, - interval, - }); - - let startTaskId = ''; - syncA.on('start', (taskMetadata: TaskMetadata) => { - startTaskId = taskMetadata.taskId; - }); - - let complete = false; - let endTaskId = ''; - syncA.on('complete', (taskMetadata: TaskMetadata) => { - complete = true; - endTaskId = taskMetadata.taskId; - }); - - expect(complete).toBe(false); - - let sleepTime = 0; - // eslint-disable-next-line no-unmodified-loop-condition - while (!complete) { - // eslint-disable-next-line no-await-in-loop - await sleep(1000); - sleepTime += 1000; - } - - expect(complete).toBe(true); - expect(startTaskId).toBe(endTaskId); - expect(sleepTime).toBeLessThan(interval * 2); - - await destroyDBs([dbA]); - }); - - it('completes repeatedly', async () => { - const interval = MINIMUM_SYNC_INTERVAL; - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection: { type: 'github', personalAccessToken: token }, - includeCommits: true, - live: true, - interval, - }); - - let counter = 0; - syncA.on('complete', () => { - counter++; - }); - - await sleep(interval * 5); - - expect(counter).toBeGreaterThanOrEqual(3); - - await destroyDBs([dbA]); - }); - - it('error', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId); - await dbA.put({ _id: '1', name: 'fromA' }); - await syncA.trySync(); - - await destroyRemoteRepository(syncA.remoteURL); - // Create different repository with the same repository name. - const [dbB, syncB] = await createDatabase(remoteURLBase, localDir, serialId); - await dbB.put({ _id: '1', name: 'fromB' }); - await syncB.trySync(); - - let startTaskId = ''; - syncA.on('start', (taskMetadata: TaskMetadata) => { - startTaskId = taskMetadata.taskId; - }); - - let error = false; - let errorTaskId = ''; - syncA.on('error', (e: Error, taskMetadata: TaskMetadata) => { - error = true; - errorTaskId = taskMetadata.taskId; - }); - await expect(syncA.trySync()).rejects.toThrowError(Err.SyncWorkerError); - - expect(error).toBe(true); - expect(startTaskId).toBe(errorTaskId); - - error = false; - await expect(syncA.tryPush()).rejects.toThrowError(); // request failed with status code: 404 - - expect(error).toBe(true); - - await destroyDBs([dbA, dbB]); - }); - - it('on and off', async () => { - const interval = MINIMUM_SYNC_INTERVAL; - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection: { type: 'github', personalAccessToken: token }, - includeCommits: true, - live: true, - interval, - }); - - let counter = 0; - const increment = () => { - counter++; - }; - syncA.on('start', increment); - - await sleep(interval * 3); - - expect(counter).toBeGreaterThanOrEqual(1); - expect(counter).toBeLessThanOrEqual(3); - - syncA.off('start', increment); - - await sleep(interval * 3); - - expect(counter).toBeLessThanOrEqual(3); - - await destroyDBs([dbA]); - }); -}); diff --git a/test/remote_base/sync_events.ts b/test/remote_base/sync_events.ts new file mode 100644 index 00000000..cb7cfbf9 --- /dev/null +++ b/test/remote_base/sync_events.ts @@ -0,0 +1,1204 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +/** + * Test synchronization events + * by using GitHub Personal Access Token + * These tests create a new repository on GitHub if not exists. + */ +import expect from 'expect'; +import sinon from 'sinon'; +import { + ChangedFile, + ConnectionSettings, + RemoteOptions, + SyncResult, + SyncResultFastForwardMerge, + SyncResultMergeAndPush, + SyncResultPush, + TaskMetadata, +} from '../../src/types'; +import { sleep } from '../../src/utils'; +import { + compareWorkingDirAndBlobs, + createClonedDatabases, + createDatabase, + destroyDBs, + destroyRemoteRepository, + getChangedFileDelete, + getChangedFileInsert, + getChangedFileUpdate, + getCommitInfo, + getWorkingDirDocs, + removeRemoteRepositories, +} from '../remote_utils'; +import { GitDocumentDB } from '../../src/git_documentdb'; +import { RemoteEngine, RemoteErr } from '../../src/remote/remote_engine'; +import { Sync } from '../../src/remote/sync'; +import { Err } from '../../src/error'; +import { MINIMUM_SYNC_INTERVAL } from '../../src/const'; + +// eslint-disable-next-line @typescript-eslint/no-var-requires +const pushWorker_module = require('../../src/remote/push_worker'); + +export const syncEventsBase = ( + connection: ConnectionSettings, + remoteURLBase: string, + reposPrefix: string, + localDir: string +) => () => { + let idCounter = 0; + const serialId = () => { + return `${reposPrefix}${idCounter++}`; + }; + + // Use sandbox to restore stub and spy in parallel mocha tests + let sandbox: sinon.SinonSandbox; + beforeEach(function () { + sandbox = sinon.createSandbox(); + }); + + afterEach(function () { + sandbox.restore(); + }); + + before(async () => { + await removeRemoteRepositories(reposPrefix); + }); + + describe(' [event]', () => { + /** + * Events + */ + describe('change', () => { + it('occurs once', async () => { + const [dbA, dbB, syncA, syncB] = await createClonedDatabases( + remoteURLBase, + localDir, + serialId, + { connection } + ); + + // A puts and pushes + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResult1 = await dbA.put(jsonA1); + await syncA.tryPush(); + + // B syncs + let result: SyncResultFastForwardMerge | undefined; + let changeTaskId = ''; + syncB.on('change', (syncResult: SyncResult, taskMetadata: TaskMetadata) => { + result = syncResult as SyncResultFastForwardMerge; + changeTaskId = taskMetadata.taskId; + }); + let complete = false; + let endTaskId = ''; + syncB.on('complete', (taskMetadata: TaskMetadata) => { + complete = true; + endTaskId = taskMetadata.taskId; + }); + await syncB.trySync(); + + // eslint-disable-next-line no-unmodified-loop-condition + while (!complete) { + // eslint-disable-next-line no-await-in-loop + await sleep(1000); + } + + expect(result!.action).toBe('fast-forward merge'); + + expect(result!.commits).toMatchObject({ + local: getCommitInfo([putResult1]), + }); + + expect(result!.changes.local).toEqual([getChangedFileInsert(jsonA1, putResult1)]); + + expect(changeTaskId).toBe(endTaskId); + + await destroyDBs([dbA, dbB]); + }); + + it('is propagated between local and remote sites', async () => { + const [dbA, dbB, syncA, syncB] = await createClonedDatabases( + remoteURLBase, + localDir, + serialId, + { connection } + ); + + // A puts and pushes + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResultA1 = await dbA.put(jsonA1); + await syncA.trySync(); + + // B puts and pushes + const jsonB1 = { _id: '1', name: 'fromB' }; + const putResultB1 = await dbB.put(jsonB1); + + let resultA: SyncResultFastForwardMerge | undefined; + let completeA = false; + syncA.on('change', (syncResult: SyncResult) => { + resultA = syncResult as SyncResultFastForwardMerge; + console.log('A: ' + resultA.action); + if (resultA.action === 'fast-forward merge') { + completeA = true; + } + }); + + let resultB: SyncResultFastForwardMerge | undefined; + syncB.on('change', (syncResult: SyncResult) => { + resultB = syncResult as SyncResultFastForwardMerge; + console.log('B: ' + resultB.action); + }); + let completeB = false; + syncB.on('complete', () => { + completeB = true; + }); + + syncA.resume({ ...syncA.options, interval: 3000 }); + syncB.resume({ ...syncA.options, interval: 3000 }); + + // eslint-disable-next-line no-unmodified-loop-condition + while (!completeA || !completeB) { + // eslint-disable-next-line no-await-in-loop + await sleep(1000); + } + + expect(resultA!.action).toBe('fast-forward merge'); + + expect(resultA!.changes.local).toEqual([ + getChangedFileUpdate(jsonA1, putResultA1, jsonB1, putResultB1), + ]); + + expect(resultB!.action).toBe('resolve conflicts and push'); + + expect(resultB!.changes.local).toEqual([]); + + expect(getWorkingDirDocs(dbA)).toEqual([jsonB1]); + expect(getWorkingDirDocs(dbB)).toEqual([jsonB1]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + + await destroyDBs([dbA, dbB]); + }); + + /** + * before: jsonA1 jsonA2 + * dbA : -jsonA1 -jsonA2 + * dbB : jsonB3 + * after : jsonB3 + */ + it('occurs with every retry', async () => { + const [dbA, dbB, syncA, syncB] = await createClonedDatabases( + remoteURLBase, + localDir, + serialId, + { + connection, + } + ); + + await dbA.put({ _id: '1' }); + await syncA.tryPush(); + + await dbB.put({ _id: '2' }); + + const stubPush = sandbox.stub(pushWorker_module, 'pushWorker'); + stubPush.onFirstCall().rejects(new RemoteErr.UnfetchedCommitExistsError('')); + + const resultsB: SyncResult[] = []; + syncB.on('change', (result: SyncResult) => { + if (resultsB.length === 0) { + // Restore stub after first change event. + stubPush.restore(); + } + // console.log('B: ' + JSON.stringify(result)); + resultsB.push(result); + }); + await syncB.trySync(); + + await sleep(syncA.options.retryInterval! + 5000); + expect(resultsB.length).toBe(2); + expect(resultsB[0].action).toBe('merge and push error'); + expect(resultsB[1].action).toBe('push'); + + await destroyDBs([dbA, dbB]); + }); + + it('is followed by localChange', async () => { + const [dbA, dbB, syncA, syncB] = await createClonedDatabases( + remoteURLBase, + localDir, + serialId, + { + connection, + } + ); + + // A puts and pushes + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResult1 = await dbA.put(jsonA1); + await syncA.tryPush(); + + // B syncs + let changes: ChangedFile[] = []; + let changeTaskId = ''; + syncB.on( + 'localChange', + (localChanges: ChangedFile[], taskMetadata: TaskMetadata) => { + changes = localChanges; + changeTaskId = taskMetadata.taskId; + } + ); + let complete = false; + let endTaskId = ''; + syncB.on('complete', (taskMetadata: TaskMetadata) => { + complete = true; + endTaskId = taskMetadata.taskId; + }); + await syncB.trySync(); + + // eslint-disable-next-line no-unmodified-loop-condition + while (!complete) { + // eslint-disable-next-line no-await-in-loop + await sleep(1000); + } + + expect(changes.length).toBe(1); + expect(changes).toEqual([getChangedFileInsert(jsonA1, putResult1)]); + + expect(changeTaskId).toBe(endTaskId); + + await destroyDBs([dbA, dbB]); + }); + + /** + * before: jsonA1 jsonA2 + * dbA : -jsonA1 -jsonA2 + * dbB : jsonB3 + * after : jsonB3 + */ + it('occurs localChanges when SyncResultMergeAndPushError', async () => { + const [dbA, dbB, syncA, syncB] = await createClonedDatabases( + remoteURLBase, + localDir, + serialId, + { + connection, + } + ); + + await dbA.put({ _id: '1' }); + await syncA.tryPush(); + + await dbB.put({ _id: '2' }); + + const stubPush = sandbox.stub(pushWorker_module, 'pushWorker'); + stubPush.onFirstCall().rejects(new RemoteErr.UnfetchedCommitExistsError('')); + + const localChangesB: ChangedFile[][] = []; + syncB.on('localChange', (changes: ChangedFile[]) => { + if (localChangesB.length === 0) { + // Restore stub after first change event. + stubPush.restore(); + } + localChangesB.push(changes); + }); + + await syncB.trySync(); + + await sleep(syncB.options.retryInterval! + 5000); + expect(localChangesB.length).toBe(1); + + await syncB.trySync(); + }); + + it('is followed by remoteChange', async () => { + const [dbA, dbB, syncA, syncB] = await createClonedDatabases( + remoteURLBase, + localDir, + serialId, + { + connection, + } + ); + + let changes: ChangedFile[] = []; + let changeTaskId = ''; + syncB.on( + 'remoteChange', + (remoteChanges: ChangedFile[], taskMetadata: TaskMetadata) => { + changes = remoteChanges; + changeTaskId = taskMetadata.taskId; + } + ); + let complete = false; + let endTaskId = ''; + syncB.on('complete', (taskMetadata: TaskMetadata) => { + complete = true; + endTaskId = taskMetadata.taskId; + }); + + // B puts and syncs + const jsonB1 = { _id: '1', name: 'fromB' }; + const putResult1 = await dbB.put(jsonB1); + await syncB.trySync(); + + // eslint-disable-next-line no-unmodified-loop-condition + while (!complete) { + // eslint-disable-next-line no-await-in-loop + await sleep(1000); + } + + expect(changes.length).toBe(1); + + expect(changes).toEqual([getChangedFileInsert(jsonB1, putResult1)]); + + expect(changeTaskId).toBe(endTaskId); + + await destroyDBs([dbA, dbB]); + }); + + /** + * before: jsonA1 jsonA2 + * dbA : -jsonA1 -jsonA2 + * dbB : jsonB3 + * after : jsonB3 + */ + it('occurs remoteChanges after SyncResultMergeAndPushError', async () => { + const [dbA, dbB, syncA, syncB] = await createClonedDatabases( + remoteURLBase, + localDir, + serialId, + { + connection, + } + ); + + await dbA.put({ _id: '1' }); + await syncA.tryPush(); + + await dbB.put({ _id: '2' }); + + const stubPush = sandbox.stub(pushWorker_module, 'pushWorker'); + stubPush.onFirstCall().rejects(new RemoteErr.UnfetchedCommitExistsError('')); + + let firstChange = true; + syncB.on('change', (changes: ChangedFile[]) => { + if (firstChange) { + firstChange = false; + // Restore stub after first change event. + stubPush.restore(); + } + }); + const remoteChangesB: ChangedFile[][] = []; + syncB.on('remoteChange', (changes: ChangedFile[]) => { + remoteChangesB.push(changes); + }); + + await syncB.trySync(); + + await sleep(syncB.options.retryInterval! + 5000); + expect(remoteChangesB.length).toBe(1); + + await syncB.trySync(); + }); + }); + + describe('filtered by collectionPath', () => { + it('occurs change and localChange events', async () => { + const [dbA, dbB, syncA, syncB] = await createClonedDatabases( + remoteURLBase, + localDir, + serialId, + { + connection, + } + ); + + // A puts and pushes + const col01 = dbA.collection('col01'); + const col02 = dbA.collection('col02'); + const jsonA1 = { _id: '1', name: 'fromA' }; + const jsonA2 = { _id: '2', name: 'fromA' }; + const putResult1 = await col01.put(jsonA1); + const putResult2 = await col02.put(jsonA2); + + const jsonA1dash = { _id: 'col01/1', name: 'fromA' }; + const putResult1dash = { ...putResult1, _id: 'col01/1' }; + const jsonA2dash = { _id: 'col02/2', name: 'fromA' }; + const putResult2dash = { ...putResult2, _id: 'col02/2' }; + + await syncA.tryPush(); + + // B syncs + let col01Result: SyncResultFastForwardMerge | undefined; + let col01ChangeTaskId: string | undefined; + syncB.on( + 'change', + (syncResult: SyncResult, taskMetadata: TaskMetadata) => { + col01Result = syncResult as SyncResultFastForwardMerge; + col01ChangeTaskId = taskMetadata.taskId; + }, + 'col01' + ); + + let changedFiles: ChangedFile[]; + syncB.on( + 'localChange', + (files: ChangedFile[], taskMetadata: TaskMetadata) => { + changedFiles = files; + }, + 'col02' + ); + + let rootResult: SyncResultFastForwardMerge | undefined; + let rootChangeTaskId: string | undefined; + syncB.on( + 'change', + (syncResult: SyncResult, taskMetadata: TaskMetadata) => { + rootResult = syncResult as SyncResultFastForwardMerge; + rootChangeTaskId = taskMetadata.taskId; + }, + '' + ); + + let complete = false; + let endTaskId = ''; + let completeCollectionPath: string | undefined; + syncB.on('complete', (taskMetadata: TaskMetadata) => { + complete = true; + endTaskId = taskMetadata.taskId; + completeCollectionPath = taskMetadata.collectionPath; + }); + await syncB.trySync(); + + // eslint-disable-next-line no-unmodified-loop-condition + while (!complete) { + // eslint-disable-next-line no-await-in-loop + await sleep(1000); + } + + expect(col01Result?.action).toBe('fast-forward merge'); + expect(rootResult?.action).toBe('fast-forward merge'); + + expect(col01Result?.commits).toMatchObject({ + local: getCommitInfo([putResult1, putResult2]), + }); + expect(rootResult?.commits).toMatchObject({ + local: getCommitInfo([putResult1, putResult2]), + }); + + expect(col01Result?.changes.local).toEqual([ + getChangedFileInsert(jsonA1, putResult1), + ]); + expect(changedFiles!).toEqual([getChangedFileInsert(jsonA2, putResult2)]); + + expect(rootResult?.changes.local).toEqual([ + getChangedFileInsert(jsonA1dash, putResult1dash), + getChangedFileInsert(jsonA2dash, putResult2dash), + ]); + + expect(col01ChangeTaskId).toBe(endTaskId); + expect(rootChangeTaskId).toBe(endTaskId); + + expect(completeCollectionPath).toBe(''); + + await destroyDBs([dbA, dbB]); + }); + + it('occurs change events with update and delete', async () => { + const [dbA, dbB, syncA, syncB] = await createClonedDatabases( + remoteURLBase, + localDir, + serialId, + { + connection, + } + ); + + // A puts and pushes + const col01 = dbA.collection('col01'); + const col02 = dbA.collection('col02'); + const jsonA1 = { _id: '1', name: 'fromA' }; + const jsonA2 = { _id: '2', name: 'fromA' }; + const putResult1 = await col01.put(jsonA1); + await col02.put(jsonA2); + await syncA.trySync(); + const jsonA1updated = { _id: '1', name: 'updated' }; + const putResult1updated = await col01.put(jsonA1updated); + const deleteResult2 = await col02.delete(jsonA2); + + let col01Result: SyncResultPush | undefined; + let col01ChangeTaskId: string | undefined; + syncA.on( + 'change', + (syncResult: SyncResult, taskMetadata: TaskMetadata) => { + col01Result = syncResult as SyncResultPush; + col01ChangeTaskId = taskMetadata.taskId; + }, + 'col01' + ); + + let changedFiles: ChangedFile[]; + syncA.on( + 'remoteChange', + (files: ChangedFile[], taskMetadata: TaskMetadata) => { + changedFiles = files; + }, + 'col02' + ); + + let complete = false; + syncA.on('complete', (taskMetadata: TaskMetadata) => { + complete = true; + }); + await syncA.tryPush(); + + // eslint-disable-next-line no-unmodified-loop-condition + while (!complete) { + // eslint-disable-next-line no-await-in-loop + await sleep(1000); + } + + expect(col01Result?.action).toBe('push'); + + expect(col01Result?.commits).toMatchObject({ + remote: getCommitInfo([putResult1updated, deleteResult2]), + }); + + expect(col01Result?.changes.remote).toEqual([ + getChangedFileUpdate(jsonA1, putResult1, jsonA1updated, putResult1updated), + ]); + expect(changedFiles!).toEqual([getChangedFileDelete(jsonA2, deleteResult2)]); + + await destroyDBs([dbA, dbB]); + }); + + it('occurs change and remoteChange events by trySync', async () => { + const [dbA, dbB, syncA, syncB] = await createClonedDatabases( + remoteURLBase, + localDir, + serialId, + { + connection, + } + ); + + // A puts and pushes + const col01 = dbA.collection('col01'); + const col02 = dbA.collection('col02'); + const jsonA1 = { _id: '1', name: 'fromA' }; + const jsonA2 = { _id: '2', name: 'fromA' }; + const putResult1 = await col01.put(jsonA1); + const putResult2 = await col02.put(jsonA2); + + const jsonA1dash = { _id: 'col01/1', name: 'fromA' }; + const putResult1dash = { ...putResult1, _id: 'col01/1' }; + const jsonA2dash = { _id: 'col02/2', name: 'fromA' }; + const putResult2dash = { ...putResult2, _id: 'col02/2' }; + + let col01Result: SyncResultPush | undefined; + let col01ChangeTaskId: string | undefined; + syncA.on( + 'change', + (syncResult: SyncResult, taskMetadata: TaskMetadata) => { + col01Result = syncResult as SyncResultPush; + col01ChangeTaskId = taskMetadata.taskId; + }, + 'col01' + ); + + let changedFiles: ChangedFile[]; + syncA.on( + 'remoteChange', + (files: ChangedFile[], taskMetadata: TaskMetadata) => { + changedFiles = files; + }, + 'col02' + ); + + let rootResult: SyncResultPush | undefined; + let rootChangeTaskId: string | undefined; + syncA.on( + 'change', + (syncResult: SyncResult, taskMetadata: TaskMetadata) => { + rootResult = syncResult as SyncResultPush; + rootChangeTaskId = taskMetadata.taskId; + }, + '' + ); + + let complete = false; + let endTaskId = ''; + let completeCollectionPath: string | undefined; + syncA.on('complete', (taskMetadata: TaskMetadata) => { + complete = true; + endTaskId = taskMetadata.taskId; + completeCollectionPath = taskMetadata.collectionPath; + }); + await syncA.trySync(); + + // eslint-disable-next-line no-unmodified-loop-condition + while (!complete) { + // eslint-disable-next-line no-await-in-loop + await sleep(1000); + } + + expect(col01Result?.action).toBe('push'); + expect(rootResult?.action).toBe('push'); + + expect(col01Result?.commits).toMatchObject({ + remote: getCommitInfo([putResult1, putResult2]), + }); + expect(rootResult?.commits).toMatchObject({ + remote: getCommitInfo([putResult1, putResult2]), + }); + + expect(col01Result?.changes.remote).toEqual([ + getChangedFileInsert(jsonA1, putResult1), + ]); + expect(changedFiles!).toEqual([getChangedFileInsert(jsonA2, putResult2)]); + + expect(rootResult?.changes.remote).toEqual([ + getChangedFileInsert(jsonA1dash, putResult1dash), + getChangedFileInsert(jsonA2dash, putResult2dash), + ]); + + expect(col01ChangeTaskId).toBe(endTaskId); + expect(rootChangeTaskId).toBe(endTaskId); + + expect(completeCollectionPath).toBe(''); + + await destroyDBs([dbA, dbB]); + }); + + it('occurs change and remoteChange events by tryPush', async () => { + const [dbA, dbB, syncA, syncB] = await createClonedDatabases( + remoteURLBase, + localDir, + serialId, + { + connection, + } + ); + + // A puts and pushes + const col01 = dbA.collection('col01'); + const col02 = dbA.collection('col02'); + const jsonA1 = { _id: '1', name: 'fromA' }; + const jsonA2 = { _id: '2', name: 'fromA' }; + const putResult1 = await col01.put(jsonA1); + const putResult2 = await col02.put(jsonA2); + + const jsonA1dash = { _id: 'col01/1', name: 'fromA' }; + const putResult1dash = { ...putResult1, _id: 'col01/1' }; + const jsonA2dash = { _id: 'col02/2', name: 'fromA' }; + const putResult2dash = { ...putResult2, _id: 'col02/2' }; + + let col01Result: SyncResultPush | undefined; + let col01ChangeTaskId: string | undefined; + syncA.on( + 'change', + (syncResult: SyncResult, taskMetadata: TaskMetadata) => { + col01Result = syncResult as SyncResultPush; + col01ChangeTaskId = taskMetadata.taskId; + }, + 'col01' + ); + + let changedFiles: ChangedFile[]; + syncA.on( + 'remoteChange', + (files: ChangedFile[], taskMetadata: TaskMetadata) => { + changedFiles = files; + }, + 'col02' + ); + + let rootResult: SyncResultPush | undefined; + let rootChangeTaskId: string | undefined; + syncA.on( + 'change', + (syncResult: SyncResult, taskMetadata: TaskMetadata) => { + rootResult = syncResult as SyncResultPush; + rootChangeTaskId = taskMetadata.taskId; + }, + '' + ); + + let complete = false; + let endTaskId = ''; + let completeCollectionPath: string | undefined; + syncA.on('complete', (taskMetadata: TaskMetadata) => { + complete = true; + endTaskId = taskMetadata.taskId; + completeCollectionPath = taskMetadata.collectionPath; + }); + await syncA.tryPush(); + + // eslint-disable-next-line no-unmodified-loop-condition + while (!complete) { + // eslint-disable-next-line no-await-in-loop + await sleep(1000); + } + + expect(col01Result?.action).toBe('push'); + expect(rootResult?.action).toBe('push'); + + expect(col01Result?.commits).toMatchObject({ + remote: getCommitInfo([putResult1, putResult2]), + }); + expect(rootResult?.commits).toMatchObject({ + remote: getCommitInfo([putResult1, putResult2]), + }); + + expect(col01Result?.changes.remote).toEqual([ + getChangedFileInsert(jsonA1, putResult1), + ]); + expect(changedFiles!).toEqual([getChangedFileInsert(jsonA2, putResult2)]); + + expect(rootResult?.changes.remote).toEqual([ + getChangedFileInsert(jsonA1dash, putResult1dash), + getChangedFileInsert(jsonA2dash, putResult2dash), + ]); + + expect(col01ChangeTaskId).toBe(endTaskId); + expect(rootChangeTaskId).toBe(endTaskId); + + expect(completeCollectionPath).toBe(''); + + await destroyDBs([dbA, dbB]); + }); + + it('occurs change, localChange, and remoteChange events by merge and push', async () => { + const [dbA, dbB, syncA, syncB] = await createClonedDatabases( + remoteURLBase, + localDir, + serialId, + { + connection, + } + ); + + // A puts and pushes + const col01 = dbA.collection('col01'); + const col02 = dbA.collection('col02'); + const jsonA1 = { _id: '1', name: 'fromA' }; + const jsonA2 = { _id: '2', name: 'fromA' }; + const putResult1 = await col01.put(jsonA1); + const putResult2 = await col02.put(jsonA2); + + const jsonA1dash = { _id: 'col01/1', name: 'fromA' }; + const putResult1dash = { ...putResult1, _id: 'col01/1' }; + const jsonA2dash = { _id: 'col02/2', name: 'fromA' }; + const putResult2dash = { ...putResult2, _id: 'col02/2' }; + + const jsonB3 = { _id: '3', name: 'fromB' }; + const putResult3 = await dbB.collection('col01').put(jsonB3); + const jsonB3dash = { _id: 'col01/3', name: 'fromB' }; + const putResult3dash = { ...putResult3, _id: 'col01/3' }; + await syncB.trySync(); + + let col01Result: SyncResultMergeAndPush | undefined; + let col01ChangeTaskId: string | undefined; + syncA.on( + 'change', + (syncResult: SyncResult, taskMetadata: TaskMetadata) => { + col01Result = syncResult as SyncResultMergeAndPush; + col01ChangeTaskId = taskMetadata.taskId; + }, + 'col01' + ); + + let localChangedFiles: ChangedFile[]; + syncA.on( + 'localChange', + (files: ChangedFile[], taskMetadata: TaskMetadata) => { + localChangedFiles = files; + }, + 'col01' + ); + + let remoteChangedFiles: ChangedFile[]; + syncA.on( + 'remoteChange', + (files: ChangedFile[], taskMetadata: TaskMetadata) => { + remoteChangedFiles = files; + }, + 'col02' + ); + + let rootResult: SyncResultMergeAndPush | undefined; + let rootChangeTaskId: string | undefined; + syncA.on( + 'change', + (syncResult: SyncResult, taskMetadata: TaskMetadata) => { + rootResult = syncResult as SyncResultMergeAndPush; + rootChangeTaskId = taskMetadata.taskId; + }, + '' + ); + + let complete = false; + let endTaskId = ''; + let completeCollectionPath: string | undefined; + syncA.on( + 'complete', + (taskMetadata: TaskMetadata) => { + complete = true; + endTaskId = taskMetadata.taskId; + completeCollectionPath = taskMetadata.collectionPath; + }, + 'col01' + ); + await syncA.trySync(); + + // eslint-disable-next-line no-unmodified-loop-condition + while (!complete) { + // eslint-disable-next-line no-await-in-loop + await sleep(1000); + } + + expect(col01Result?.action).toBe('merge and push'); + expect(rootResult?.action).toBe('merge and push'); + + expect(col01Result?.commits).toMatchObject({ + remote: getCommitInfo([putResult1, putResult2, 'merge']), + local: getCommitInfo([putResult3, 'merge']), + }); + expect(rootResult?.commits).toMatchObject({ + remote: getCommitInfo([putResult1, putResult2, 'merge']), + local: getCommitInfo([putResult3, 'merge']), + }); + + expect(col01Result?.changes.remote).toEqual([ + getChangedFileInsert(jsonA1, putResult1), + ]); + expect(col01Result?.changes.local).toEqual([ + getChangedFileInsert(jsonB3, putResult3), + ]); + expect(localChangedFiles!).toEqual([getChangedFileInsert(jsonB3, putResult3)]); + expect(remoteChangedFiles!).toEqual([getChangedFileInsert(jsonA2, putResult2)]); + + expect(rootResult?.changes.remote).toEqual([ + getChangedFileInsert(jsonA1dash, putResult1dash), + getChangedFileInsert(jsonA2dash, putResult2dash), + ]); + expect(rootResult?.changes.local).toEqual([ + getChangedFileInsert(jsonB3dash, putResult3dash), + ]); + + expect(col01ChangeTaskId).toBe(endTaskId); + expect(rootChangeTaskId).toBe(endTaskId); + + expect(completeCollectionPath).toBe('col01/'); + + await destroyDBs([dbA, dbB]); + }); + }); + + it('pause and resume', async () => { + const [dbA, dbB, syncA, syncB] = await createClonedDatabases( + remoteURLBase, + localDir, + serialId, + { + connection, + includeCommits: true, + live: true, + interval: 3000, + } + ); + + let resume = false; + syncB.on('resume', () => { + resume = true; + }); + let pause = false; + syncB.on('pause', () => { + pause = true; + }); + let complete = false; + syncB.on('complete', () => { + complete = true; + }); + + // Check first complete event + + let sleepTime = 0; + // eslint-disable-next-line no-unmodified-loop-condition + while (!complete) { + // eslint-disable-next-line no-await-in-loop + await sleep(1000); + sleepTime += 1000; + } + + syncB.pause(); + expect(pause).toBe(true); + expect(resume).toBe(false); + expect(syncB.options.live).toBe(false); + + // Check second complete event + complete = false; // reset + // fast forward timer + await sleep(sleepTime + 1000); + + expect(complete).toBe(false); // complete will not happen because synchronization is paused. + + syncB.resume(); + expect(resume).toBe(true); + expect(syncB.options.live).toBe(true); + + // Check third complete event + complete = false; // reset + // fast forward timer + await sleep(sleepTime + 1000); + + expect(complete).toBe(true); + + await destroyDBs([dbA, dbB]); + }); + + it('active at initialization', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir, + }); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection, + includeCommits: true, + live: true, + }; + await dbA.open(); + + const sync = new Sync(dbA, options); + let resume = false; + sync.on('resume', () => { + resume = true; + }); + + const syncResult = await sync.init(); + console.log(JSON.stringify(syncResult)); + expect(resume).toBe(true); + + sync.close(); + + await destroyDBs([dbA]); + }); + + it('starts once', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, + includeCommits: true, + live: true, + interval: 3000, + }); + + let start = false; + syncA.on('start', () => { + start = true; + }); + + expect(start).toBe(false); + + let sleepTime = 0; + // eslint-disable-next-line no-unmodified-loop-condition + while (!start) { + // eslint-disable-next-line no-await-in-loop + await sleep(1000); + sleepTime += 1000; + } + + expect(start).toBe(true); + expect(sleepTime).toBeLessThan(5000); + + await destroyDBs([dbA]); + }); + + it('starts repeatedly', async () => { + const interval = MINIMUM_SYNC_INTERVAL; + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, + includeCommits: true, + live: true, + interval, + }); + + let counter = 0; + syncA.on('start', () => { + counter++; + }); + + await sleep(interval * 5); + + expect(counter).toBeGreaterThanOrEqual(3); + + await destroyDBs([dbA]); + }); + + it('starts event returns taskMetaData and current retries', async () => { + const interval = MINIMUM_SYNC_INTERVAL; + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, + includeCommits: true, + live: true, + interval, + }); + + let counter = 0; + let taskId = ''; + let currentRetries = -1; + syncA.on('start', (taskMetadata: TaskMetadata, _currentRetries: number) => { + counter++; + taskId = taskMetadata.taskId; + currentRetries = _currentRetries; + }); + + await sleep(interval * 5); + + expect(counter).toBeGreaterThanOrEqual(3); + expect(taskId).not.toBe(''); + expect(currentRetries).toBe(0); + + await destroyDBs([dbA]); + }); + + it('completes once', async () => { + const interval = MINIMUM_SYNC_INTERVAL; + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, + includeCommits: true, + live: true, + interval, + }); + + let startTaskId = ''; + syncA.on('start', (taskMetadata: TaskMetadata) => { + startTaskId = taskMetadata.taskId; + }); + + let complete = false; + let endTaskId = ''; + syncA.on('complete', (taskMetadata: TaskMetadata) => { + complete = true; + endTaskId = taskMetadata.taskId; + }); + + expect(complete).toBe(false); + + let sleepTime = 0; + // eslint-disable-next-line no-unmodified-loop-condition + while (!complete) { + // eslint-disable-next-line no-await-in-loop + await sleep(1000); + sleepTime += 1000; + } + + expect(complete).toBe(true); + expect(startTaskId).toBe(endTaskId); + expect(sleepTime).toBeLessThan(interval * 2); + + await destroyDBs([dbA]); + }); + + it('completes repeatedly', async () => { + const interval = MINIMUM_SYNC_INTERVAL; + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, + includeCommits: true, + live: true, + interval, + }); + + let counter = 0; + syncA.on('complete', () => { + counter++; + }); + + await sleep(interval * 5); + + expect(counter).toBeGreaterThanOrEqual(3); + + await destroyDBs([dbA]); + }); + + it('error', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, + }); + await dbA.put({ _id: '1', name: 'fromA' }); + await syncA.trySync(); + + await destroyRemoteRepository(syncA.remoteURL); + // Create different repository with the same repository name. + const [dbB, syncB] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, + }); + await dbB.put({ _id: '1', name: 'fromB' }); + await syncB.trySync(); + + let startTaskId = ''; + syncA.on('start', (taskMetadata: TaskMetadata) => { + startTaskId = taskMetadata.taskId; + }); + + let error = false; + let errorTaskId = ''; + syncA.on('error', (e: Error, taskMetadata: TaskMetadata) => { + error = true; + errorTaskId = taskMetadata.taskId; + }); + await expect(syncA.trySync()).rejects.toThrowError(RemoteErr.HTTPError404NotFound); + + expect(error).toBe(true); + expect(startTaskId).toBe(errorTaskId); + + error = false; + await expect(syncA.tryPush()).rejects.toThrowError(); // request failed with status code: 404 + + expect(error).toBe(true); + + await destroyDBs([dbA, dbB]); + }); + + it('on and off', async () => { + const interval = MINIMUM_SYNC_INTERVAL; + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, + includeCommits: true, + live: true, + interval, + }); + + let counter = 0; + const increment = () => { + counter++; + }; + syncA.on('start', increment); + + await sleep(interval * 3); + + expect(counter).toBeGreaterThanOrEqual(1); + expect(counter).toBeLessThanOrEqual(3); + + syncA.off('start', increment); + + await sleep(interval * 3); + + expect(counter).toBeLessThanOrEqual(3); + + await destroyDBs([dbA]); + }); + }); +}; diff --git a/test/remote_base/sync_live.ts b/test/remote_base/sync_live.ts index 43a90ff3..8674de92 100644 --- a/test/remote_base/sync_live.ts +++ b/test/remote_base/sync_live.ts @@ -12,296 +12,246 @@ * by using GitHub Personal Access Token * These tests create a new repository on GitHub if not exists. */ -import path from 'path'; -import fs from 'fs-extra'; import expect from 'expect'; -import sinon from 'sinon'; -import { Sync } from '../src/remote/sync'; -import { GitDocumentDB } from '../src/git_documentdb'; -import { RemoteOptions, SyncResultPush } from '../src/types'; -import { Err } from '../src/error'; -import { sleep } from '../src/utils'; -import { - destroyDBs, - getChangedFileInsert, - getChangedFileUpdate, - removeRemoteRepositories, -} from '../test/remote_utils'; -import { JSON_EXT, MINIMUM_SYNC_INTERVAL, NETWORK_RETRY } from '../src/const'; -import { pushWorker } from '../src/remote/push_worker'; -import { syncWorker } from '../src/remote/sync_worker'; -import { RemoteEngine } from '../src/remote/remote_engine'; - -// eslint-disable-next-line @typescript-eslint/no-var-requires -const pushWorker_module = require('../src/remote/push_worker'); -// eslint-disable-next-line @typescript-eslint/no-var-requires -const syncWorker_module = require('../src/remote/sync_worker'); - -const reposPrefix = 'test_sync_lifecycle___'; -const localDir = `./test_intg/database_sync_lifecycle`; - -let idCounter = 0; -const serialId = () => { - return `${reposPrefix}${idCounter++}`; -}; - -// Use sandbox to restore stub and spy in parallel mocha tests -let sandbox: sinon.SinonSandbox; -beforeEach(function () { - // @ts-ignore - console.log(`... ${this.currentTest.fullTitle()}`); - sandbox = sinon.createSandbox(); -}); - -afterEach(function () { - sandbox.restore(); -}); - -before(() => { - // eslint-disable-next-line @typescript-eslint/no-var-requires - GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); - - fs.removeSync(path.resolve(localDir)); -}); - -after(() => { - // It may throw error due to memory leak with UnfetchedCommitExistsError - // fs.removeSync(path.resolve(localDir)); -}); - -// GITDDB_GITHUB_USER_URL: URL of your GitHub account -// e.g.) https://github.com/foo/ -const maybe = - process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN - ? describe - : describe.skip; - -// Test live -maybe(' Sync', () => { - const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') - ? process.env.GITDDB_GITHUB_USER_URL - : process.env.GITDDB_GITHUB_USER_URL + '/'; - const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; +import { GitDocumentDB } from '../../src/git_documentdb'; +import { ConnectionSettings, RemoteOptions } from '../../src/types'; +import { sleep } from '../../src/utils'; +import { destroyDBs, removeRemoteRepositories } from '../remote_utils'; +import { MINIMUM_SYNC_INTERVAL } from '../../src/const'; + +export const syncLiveBase = ( + connection: ConnectionSettings, + remoteURLBase: string, + reposPrefix: string, + localDir: string +) => () => { + let idCounter = 0; + const serialId = () => { + return `${reposPrefix}${idCounter++}`; + }; before(async () => { await removeRemoteRepositories(reposPrefix); }); - /** - * Repetitive Sync (live) - */ - describe('Repetitive Sync (live)', () => { - it('starts and pushes after interval when called from open() with live option.', async () => { - const remoteURL = remoteURLBase + serialId(); - - const dbNameA = serialId(); - - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, - }); - const interval = MINIMUM_SYNC_INTERVAL; - const options: RemoteOptions = { - remoteUrl: remoteURL, - live: true, - syncDirection: 'both', - interval, - connection: { type: 'github', personalAccessToken: token }, - }; - await dbA.open(); - const syncA = await dbA.sync(options); - - const jsonA1 = { _id: '1', name: 'fromA' }; - await dbA.put(jsonA1); - - expect(syncA.options.live).toBeTruthy(); - expect(syncA.options.interval).toBe(interval); - - // Wait live sync() - while (dbA.taskQueue.currentStatistics().sync === 0) { - // eslint-disable-next-line no-await-in-loop - await sleep(500); - } - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir: localDir, + // Test live + describe(' Sync', () => { + /** + * Repetitive Sync (live) + */ + describe('Repetitive Sync (live)', () => { + it('starts and pushes after interval when called from open() with live option.', async () => { + const remoteURL = remoteURLBase + serialId(); + + const dbNameA = serialId(); + + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + const interval = MINIMUM_SYNC_INTERVAL; + const options: RemoteOptions = { + remoteUrl: remoteURL, + live: true, + syncDirection: 'both', + interval, + connection, + }; + await dbA.open(); + const syncA = await dbA.sync(options); + + const jsonA1 = { _id: '1', name: 'fromA' }; + await dbA.put(jsonA1); + + expect(syncA.options.live).toBeTruthy(); + expect(syncA.options.interval).toBe(interval); + + // Wait live sync() + while (dbA.taskQueue.currentStatistics().sync === 0) { + // eslint-disable-next-line no-await-in-loop + await sleep(500); + } + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir: localDir, + }); + await dbB.open(); + await dbB.sync(options); + await expect(dbB.get(jsonA1._id)).resolves.toMatchObject(jsonA1); + + await destroyDBs([dbA, dbB]); }); - await dbB.open(); - await dbB.sync(options); - await expect(dbB.get(jsonA1._id)).resolves.toMatchObject(jsonA1); - await destroyDBs([dbA, dbB]); - }); - - it('stops by pause()', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbNameA = serialId(); - - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, + it('stops by pause()', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); + + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + const interval = MINIMUM_SYNC_INTERVAL; + const options: RemoteOptions = { + remoteUrl: remoteURL, + live: true, + syncDirection: 'both', + interval, + connection, + }; + await dbA.open(); + const syncA = await dbA.sync(options); + + expect(syncA.options.live).toBeTruthy(); + const count = dbA.taskQueue.currentStatistics().sync; + syncA.pause(); + await sleep(interval * 2); + expect(syncA.options.live).toBeFalsy(); + expect(dbA.taskQueue.currentStatistics().sync).toBe(count); + + await destroyDBs([dbA]); }); - const interval = MINIMUM_SYNC_INTERVAL; - const options: RemoteOptions = { - remoteUrl: remoteURL, - live: true, - syncDirection: 'both', - interval, - connection: { type: 'github', personalAccessToken: token }, - }; - await dbA.open(); - const syncA = await dbA.sync(options); - - expect(syncA.options.live).toBeTruthy(); - const count = dbA.taskQueue.currentStatistics().sync; - syncA.pause(); - await sleep(interval * 2); - expect(syncA.options.live).toBeFalsy(); - expect(dbA.taskQueue.currentStatistics().sync).toBe(count); - - await destroyDBs([dbA]); - }); - - it('pause() and resume()', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbNameA = serialId(); - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, + it('pause() and resume()', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); + + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + const interval = MINIMUM_SYNC_INTERVAL; + const options: RemoteOptions = { + remoteUrl: remoteURL, + live: true, + syncDirection: 'both', + interval, + connection, + }; + await dbA.open(); + const syncA = await dbA.sync(options); + + expect(syncA.options.live).toBeTruthy(); + const count = dbA.taskQueue.currentStatistics().sync; + expect(syncA.pause()).toBeTruthy(); + expect(syncA.pause()).toBeFalsy(); // ignored + + await sleep(interval * 2); + expect(syncA.options.live).toBeFalsy(); + expect(dbA.taskQueue.currentStatistics().sync).toBe(count); + + expect(syncA.resume()).toBeTruthy(); + expect(syncA.resume()).toBeFalsy(); // ignored + await sleep(interval * 2); + expect(syncA.options.live).toBeTruthy(); + expect(dbA.taskQueue.currentStatistics().sync).toBeGreaterThan(count); + + await destroyDBs([dbA]); }); - const interval = MINIMUM_SYNC_INTERVAL; - const options: RemoteOptions = { - remoteUrl: remoteURL, - live: true, - syncDirection: 'both', - interval, - connection: { type: 'github', personalAccessToken: token }, - }; - await dbA.open(); - const syncA = await dbA.sync(options); - - expect(syncA.options.live).toBeTruthy(); - const count = dbA.taskQueue.currentStatistics().sync; - expect(syncA.pause()).toBeTruthy(); - expect(syncA.pause()).toBeFalsy(); // ignored - - await sleep(interval * 2); - expect(syncA.options.live).toBeFalsy(); - expect(dbA.taskQueue.currentStatistics().sync).toBe(count); - - expect(syncA.resume()).toBeTruthy(); - expect(syncA.resume()).toBeFalsy(); // ignored - await sleep(interval * 2); - expect(syncA.options.live).toBeTruthy(); - expect(dbA.taskQueue.currentStatistics().sync).toBeGreaterThan(count); - - await destroyDBs([dbA]); - }); - - it('stops by gitDDB.close()', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbNameA = serialId(); - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, + it('stops by gitDDB.close()', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); + + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + const interval = MINIMUM_SYNC_INTERVAL; + const options: RemoteOptions = { + remoteUrl: remoteURL, + live: true, + syncDirection: 'both', + interval, + connection, + }; + await dbA.open(); + const syncA = await dbA.sync(options); + + expect(syncA.options.live).toBeTruthy(); + const count = dbA.taskQueue.currentStatistics().sync; + await dbA.close(); + + syncA.resume(); // resume() must be ignored after close(); + + await sleep(interval * 2); + expect(syncA.options.live).toBeFalsy(); + expect(dbA.taskQueue.currentStatistics().sync).toBe(count); + + await destroyDBs([dbA]); }); - const interval = MINIMUM_SYNC_INTERVAL; - const options: RemoteOptions = { - remoteUrl: remoteURL, - live: true, - syncDirection: 'both', - interval, - connection: { type: 'github', personalAccessToken: token }, - }; - await dbA.open(); - const syncA = await dbA.sync(options); - - expect(syncA.options.live).toBeTruthy(); - const count = dbA.taskQueue.currentStatistics().sync; - await dbA.close(); - - syncA.resume(); // resume() must be ignored after close(); - - await sleep(interval * 2); - expect(syncA.options.live).toBeFalsy(); - expect(dbA.taskQueue.currentStatistics().sync).toBe(count); - - await destroyDBs([dbA]); - }); - it('changes interval when resume() is called with new interval.', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbNameA = serialId(); - - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, - }); - const interval = MINIMUM_SYNC_INTERVAL; - const options: RemoteOptions = { - remoteUrl: remoteURL, - live: true, - syncDirection: 'both', - interval, - connection: { type: 'github', personalAccessToken: token }, - }; - await dbA.open(); - const syncA = await dbA.sync(options); - - expect(syncA.options.interval).toBe(interval); - - const jsonA1 = { _id: '1', name: 'fromA' }; - await dbA.put(jsonA1); - // Wait live sync() - while (dbA.taskQueue.currentStatistics().sync === 0) { - // eslint-disable-next-line no-await-in-loop - await sleep(500); - } - syncA.pause(); - - const jsonA2 = { _id: '2', name: 'fromA' }; - await dbA.put(jsonA2); - - const currentCount = dbA.taskQueue.currentStatistics().sync; - // Change interval - syncA.resume({ - interval: interval * 3, + it('changes interval when resume() is called with new interval.', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); + + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + const interval = MINIMUM_SYNC_INTERVAL; + const options: RemoteOptions = { + remoteUrl: remoteURL, + live: true, + syncDirection: 'both', + interval, + connection, + }; + await dbA.open(); + const syncA = await dbA.sync(options); + + expect(syncA.options.interval).toBe(interval); + + const jsonA1 = { _id: '1', name: 'fromA' }; + await dbA.put(jsonA1); + // Wait live sync() + while (dbA.taskQueue.currentStatistics().sync === 0) { + // eslint-disable-next-line no-await-in-loop + await sleep(500); + } + syncA.pause(); + + const jsonA2 = { _id: '2', name: 'fromA' }; + await dbA.put(jsonA2); + + const currentCount = dbA.taskQueue.currentStatistics().sync; + // Change interval + syncA.resume({ + interval: interval * 3, + }); + expect(syncA.options.interval).toBe(interval * 3); + await sleep(interval); + // Check count before next sync() + expect(dbA.taskQueue.currentStatistics().sync).toBe(currentCount); + + await destroyDBs([dbA]); }); - expect(syncA.options.interval).toBe(interval * 3); - await sleep(interval); - // Check count before next sync() - expect(dbA.taskQueue.currentStatistics().sync).toBe(currentCount); - await destroyDBs([dbA]); - }); - - it('repeats trySync() automatically.', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbNameA = serialId(); - - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, + it('repeats trySync() automatically.', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); + + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + const interval = MINIMUM_SYNC_INTERVAL; + const options: RemoteOptions = { + remoteUrl: remoteURL, + live: true, + syncDirection: 'both', + interval, + connection, + }; + await dbA.open(); + const syncA = await dbA.sync(options); + + await sleep(interval * 5); + expect(dbA.taskQueue.currentStatistics().sync).toBeGreaterThanOrEqual(3); + + await destroyDBs([dbA]); }); - const interval = MINIMUM_SYNC_INTERVAL; - const options: RemoteOptions = { - remoteUrl: remoteURL, - live: true, - syncDirection: 'both', - interval, - connection: { type: 'github', personalAccessToken: token }, - }; - await dbA.open(); - const syncA = await dbA.sync(options); - - await sleep(interval * 5); - expect(dbA.taskQueue.currentStatistics().sync).toBeGreaterThanOrEqual(3); - - await destroyDBs([dbA]); }); }); -}); +}; diff --git a/test/remote_nodegit/sync_events.test.ts b/test/remote_nodegit/sync_events.test.ts new file mode 100644 index 00000000..cb641722 --- /dev/null +++ b/test/remote_nodegit/sync_events.test.ts @@ -0,0 +1,61 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +/** + * Test Sync Events + * by using GitHub Personal Access Token + * These tests create a new repository on GitHub if not exists. + */ +import path from 'path'; +import fs from 'fs-extra'; +import { syncEventsBase } from '../remote_base/sync_events'; +import { ConnectionSettingsGitHub } from '../../src/types'; +import { GitDocumentDB } from '../../src/git_documentdb'; + +const reposPrefix = 'test_sync_events_nodegit___'; +const localDir = `./test/database_sync_events_nodegit`; + +beforeEach(function () { + // @ts-ignore + console.log(`... ${this.currentTest.fullTitle()}`); +}); + +before(() => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + + fs.removeSync(path.resolve(localDir)); +}); + +after(() => { + fs.removeSync(path.resolve(localDir)); +}); + +// This test needs environment variables: +// - GITDDB_GITHUB_USER_URL: URL of your GitHub account +// e.g.) https://github.com/foo/ +// - GITDDB_PERSONAL_ACCESS_TOKEN: A personal access token of your GitHub account +const maybe = + process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN + ? describe + : describe.skip; + +const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') + ? process.env.GITDDB_GITHUB_USER_URL + : process.env.GITDDB_GITHUB_USER_URL + '/'; + +const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; + +const connection: ConnectionSettingsGitHub = { + type: 'github', + personalAccessToken: token, + engine: 'nodegit', +}; + +maybe('NodeGit', syncEventsBase(connection, remoteURLBase, reposPrefix, localDir)); diff --git a/test/remote_nodegit/sync_live.test.ts b/test/remote_nodegit/sync_live.test.ts new file mode 100644 index 00000000..1dfc52d8 --- /dev/null +++ b/test/remote_nodegit/sync_live.test.ts @@ -0,0 +1,61 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +/** + * Test Sync live + * by using GitHub Personal Access Token + * These tests create a new repository on GitHub if not exists. + */ +import path from 'path'; +import fs from 'fs-extra'; +import { syncLiveBase } from '../remote_base/sync_live'; +import { ConnectionSettingsGitHub } from '../../src/types'; +import { GitDocumentDB } from '../../src/git_documentdb'; + +const reposPrefix = 'test_sync_live_nodegit___'; +const localDir = `./test/database_sync_live_nodegit`; + +beforeEach(function () { + // @ts-ignore + console.log(`... ${this.currentTest.fullTitle()}`); +}); + +before(() => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + + fs.removeSync(path.resolve(localDir)); +}); + +after(() => { + fs.removeSync(path.resolve(localDir)); +}); + +// This test needs environment variables: +// - GITDDB_GITHUB_USER_URL: URL of your GitHub account +// e.g.) https://github.com/foo/ +// - GITDDB_PERSONAL_ACCESS_TOKEN: A personal access token of your GitHub account +const maybe = + process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN + ? describe + : describe.skip; + +const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') + ? process.env.GITDDB_GITHUB_USER_URL + : process.env.GITDDB_GITHUB_USER_URL + '/'; + +const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; + +const connection: ConnectionSettingsGitHub = { + type: 'github', + personalAccessToken: token, + engine: 'nodegit', +}; + +maybe('NodeGit', syncLiveBase(connection, remoteURLBase, reposPrefix, localDir)); From 87a25946352db026d9a14d74f4b1a818b0932ea8 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sat, 31 Jul 2021 16:19:26 +0900 Subject: [PATCH 112/297] test: add test for 3way_merge_ot in remote_nodegit --- test/remote_base/3way_merge_ot.ts | 746 +++++++++++++++++ .../remote_base/on_sync_event.ts | 0 test/remote_nodegit/3way_merge_ot.test.ts | 61 ++ test_intg/3way_merge_ot.test.ts | 755 ------------------ test_intg/README.md | 1 - test_intg/tsconfig.json | 6 - 6 files changed, 807 insertions(+), 762 deletions(-) create mode 100644 test/remote_base/3way_merge_ot.ts rename test_intg/on_sync_event.test.ts => test/remote_base/on_sync_event.ts (100%) create mode 100644 test/remote_nodegit/3way_merge_ot.test.ts delete mode 100644 test_intg/3way_merge_ot.test.ts delete mode 100644 test_intg/README.md delete mode 100644 test_intg/tsconfig.json diff --git a/test/remote_base/3way_merge_ot.ts b/test/remote_base/3way_merge_ot.ts new file mode 100644 index 00000000..c1597464 --- /dev/null +++ b/test/remote_base/3way_merge_ot.ts @@ -0,0 +1,746 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +/** + * Test Operational Transformation in 3-way merge + * by using GitHub Personal Access Token + * These tests create a new repository on GitHub if not exists. + */ +import expect from 'expect'; +import { GitDocumentDB } from '../../src/git_documentdb'; +import { + ConnectionSettings, + Schema, + SyncResultMergeAndPush, + SyncResultResolveConflictsAndPush, +} from '../../src/types'; +import { + compareWorkingDirAndBlobs, + createClonedDatabases, + createDatabase, + destroyDBs, + getChangedFileDelete, + getChangedFileInsert, + getChangedFileUpdateBySHA, + getCommitInfo, + getWorkingDirDocs, + removeRemoteRepositories, +} from '../remote_utils'; + +import { JSON_EXT } from '../../src/const'; + +export const threeWayMergeOtBase = ( + connection: ConnectionSettings, + remoteURLBase: string, + reposPrefix: string, + localDir: string +) => () => { + let idCounter = 0; + const serialId = () => { + return `${reposPrefix}${idCounter++}`; + }; + + before(async () => { + await removeRemoteRepositories(reposPrefix); + }); + + describe('', () => { + /** + * before: + * dbA : jsonA1 jsonA2 + * dbB : jsonB1 jsonB3 + * after : mergedJson jsonA2 jsonB3 + * + * 3-way merge: + * mergedJson: 4 - Conflict. Accept ours (insert-merge) + * jsonA2: 1 - Accept theirs (insert) + * jsonB3: 2 - Accept ours (insert) + */ + it('resolves case 1 - Accept theirs (insert), case 2 - Accept ours (insert), case 4 - Conflict. Accept ours (insert-merge)', async () => { + const [dbA, dbB, syncA, syncB] = await createClonedDatabases( + remoteURLBase, + localDir, + serialId, + { + conflictResolutionStrategy: 'ours-diff', + connection, + } + ); + + // A puts and pushes + const jsonA1 = { _id: '1', name: 'fromA', a: 'fromA' }; + const putResultA1 = await dbA.put(jsonA1); + const jsonA2 = { _id: '2', name: 'fromA' }; + const putResultA2 = await dbA.put(jsonA2); + await syncA.tryPush(); + + // B puts the same file + const jsonB1 = { _id: '1', name: 'fromB', b: 'fromB' }; + const putResultB1 = await dbB.put(jsonB1); + + const mergedJson = { _id: '1', name: 'fromB', a: 'fromA', b: 'fromB' }; + + // B puts a new file + const jsonB3 = { _id: '3', name: 'fromB' }; + const putResultB3 = await dbB.put(jsonB3); + + // It will occur conflict on id 1.json. + const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; + + const mergedDoc = await dbB.getFatDoc('1.json'); + + expect(syncResult1.action).toBe('resolve conflicts and push'); + expect(syncResult1.commits).toMatchObject({ + local: getCommitInfo([ + putResultA1, + putResultA2, + `resolve: 1${JSON_EXT}(insert-merge,${mergedDoc!.fileOid.substr( + 0, + 7 + )},ours-diff)`, + ]), + remote: getCommitInfo([ + putResultB1, + putResultB3, + `resolve: 1${JSON_EXT}(insert-merge,${mergedDoc!.fileOid.substr( + 0, + 7 + )},ours-diff)`, + ]), + }); + expect(syncResult1.changes.local.length).toBe(2); + expect(syncResult1.changes.local).toEqual( + expect.arrayContaining([ + getChangedFileUpdateBySHA( + jsonB1, + putResultB1.fileOid, + mergedJson, + mergedDoc!.fileOid + ), + getChangedFileInsert(jsonA2, putResultA2), + ]) + ); + + expect(syncResult1.changes.remote.length).toBe(2); + expect(syncResult1.changes.remote).toEqual( + expect.arrayContaining([ + getChangedFileUpdateBySHA( + jsonA1, + putResultA1.fileOid, + mergedJson, + mergedDoc!.fileOid + ), + getChangedFileInsert(jsonB3, putResultB3), + ]) + ); + + expect(syncResult1.conflicts.length).toEqual(1); + expect(syncResult1.conflicts).toEqual([ + { + fatDoc: mergedDoc, + strategy: 'ours-diff', + operation: 'insert-merge', + }, + ]); + // Conflict occurs on 1.json + + expect(getWorkingDirDocs(dbB)).toEqual([mergedJson, jsonA2, jsonB3]); + // Sync dbA + const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; + expect(getWorkingDirDocs(dbA)).toEqual([mergedJson, jsonA2, jsonB3]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + + await destroyDBs([dbA, dbB]); + }); + + /** + * before: + * dbA : jsonA1 + * dbB : jsonB1 + * after : jsonA1 + * + * 3-way merge: + * jsonA1: 5 - Conflict. Accept theirs (insert) + */ + it('resolves case 5 - Conflict. Accept theirs (insert)', async () => { + const [dbA, dbB, syncA, syncB] = await createClonedDatabases( + remoteURLBase, + localDir, + serialId, + { + conflictResolutionStrategy: 'theirs-diff', + connection, + } + ); + + // A puts and pushes + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResultA1 = await dbA.put(jsonA1); + await syncA.tryPush(); + + // B puts the same file + const jsonB1 = { _id: '1', name: 'fromB' }; + const putResultB1 = await dbB.put(jsonB1); + + const mergedJson = { _id: '1', name: 'fromA' }; + + // It will occur conflict on id 1.json. + const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; + + const mergedDoc = await dbB.getFatDoc('1.json'); + + expect(syncResult1.action).toBe('resolve conflicts and push'); + expect(syncResult1.commits).toMatchObject({ + local: getCommitInfo([ + putResultA1, + `resolve: 1${JSON_EXT}(insert-merge,${mergedDoc!.fileOid.substr( + 0, + 7 + )},theirs-diff)`, + ]), + remote: getCommitInfo([ + putResultB1, + `resolve: 1${JSON_EXT}(insert-merge,${mergedDoc!.fileOid.substr( + 0, + 7 + )},theirs-diff)`, + ]), + }); + expect(syncResult1.changes.local.length).toBe(1); + expect(syncResult1.changes.local).toEqual([ + getChangedFileUpdateBySHA( + jsonB1, + putResultB1!.fileOid, + mergedJson, + mergedDoc!.fileOid + ), + ]); + + expect(syncResult1.changes.remote.length).toBe(0); + + expect(syncResult1.conflicts.length).toEqual(1); + expect(syncResult1.conflicts).toEqual([ + { + fatDoc: mergedDoc, + strategy: 'theirs-diff', + operation: 'insert-merge', + }, + ]); + expect(getWorkingDirDocs(dbA)).toEqual([jsonA1]); + expect(getWorkingDirDocs(dbB)).toEqual([jsonA1]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + + await destroyDBs([dbA, dbB]); + }); + + /** + * before: jsonA1 + * dbA : +jsonA1 + * dbB : -jsonA1 + * result: + * + * '+' means update + * + * 3-way merge: + * jsonA1: 8 - Conflict. Accept ours (delete) + */ + it('resolves case 8 - Conflict. Accept ours (delete)', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + conflictResolutionStrategy: 'ours-diff', + connection, + }); + // A puts and pushes + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResultA1 = await dbA.put(jsonA1); + await syncA.tryPush(); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir: localDir, + }); + // Clone dbA + await dbB.open(); + const syncB = await dbB.sync(syncA.options); + + // A updates and pushes + const jsonA1dash = { _id: '1', name: 'updated' }; + const putResultA1dash = await dbA.put(jsonA1dash); + await syncA.tryPush(); + + // B removes and syncs + const deleteResultB1 = await dbB.delete(jsonA1); + + const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; + expect(syncResult1.action).toBe('resolve conflicts and push'); + expect(syncResult1.commits).toMatchObject({ + local: getCommitInfo([ + putResultA1dash, + `resolve: 1${JSON_EXT}(delete,${deleteResultB1.fileOid.substr(0, 7)},ours-diff)`, + ]), + remote: getCommitInfo([ + deleteResultB1, + `resolve: 1${JSON_EXT}(delete,${deleteResultB1.fileOid.substr(0, 7)},ours-diff)`, + ]), + }); + expect(syncResult1.changes.local.length).toBe(0); + + expect(syncResult1.changes.remote.length).toBe(1); + expect(syncResult1.changes.remote).toEqual([ + getChangedFileDelete(jsonA1dash, putResultA1dash), + ]); + + expect(syncResult1.conflicts.length).toEqual(1); + expect(syncResult1.conflicts).toEqual([ + { + fatDoc: { + _id: '1', + name: '1.json', + fileOid: deleteResultB1.fileOid, + type: 'json', + doc: jsonA1, + }, + strategy: 'ours-diff', + operation: 'delete', + }, + ]); + // Conflict occurs on 1.json + + expect(getWorkingDirDocs(dbB)).toEqual([]); + + // Sync dbA + const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; + expect(getWorkingDirDocs(dbA)).toEqual([]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + + await destroyDBs([dbA, dbB]); + }); + + /** + * before: jsonA1 + * dbA : -jsonA1 jsonA2 + * dbB : jsonB1 + * result: jsonB1 jsonA2 + * + * 3-way merge: + * jsonB1: 11 - Conflict. Accept ours (update) + * jsonA2: 1 - Accept theirs (insert) + */ + it('resolves case 11 - Conflict. Accept ours (update), case 1 - Accept theirs (insert), ', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + conflictResolutionStrategy: 'ours-diff', + connection, + }); + // A puts and pushes + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResultA1 = await dbA.put(jsonA1); + await syncA.tryPush(); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir: localDir, + }); + // Clone dbA + await dbB.open(); + const syncB = await dbB.sync(syncA.options); + + // A removes the old file and puts a new file + const deleteResultA1 = await dbA.delete(jsonA1); + const jsonA2 = { _id: '2', name: 'fromA' }; + const putResultA2 = await dbA.put(jsonA2); + await syncA.tryPush(); + + // B updates the old file and syncs + const jsonB1 = { _id: '1', name: 'fromB' }; + const putResultB1 = await dbB.put(jsonB1); + + const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; + expect(syncResult1.action).toBe('resolve conflicts and push'); + expect(syncResult1.commits).toMatchObject({ + local: getCommitInfo([ + deleteResultA1, + putResultA2, + `resolve: 1${JSON_EXT}(update,${putResultB1.fileOid.substr(0, 7)},ours-diff)`, + ]), + remote: getCommitInfo([ + putResultB1, + `resolve: 1${JSON_EXT}(update,${putResultB1.fileOid.substr(0, 7)},ours-diff)`, + ]), + }); + expect(syncResult1.changes.local.length).toBe(1); + expect(syncResult1.changes.local).toEqual([ + getChangedFileInsert(jsonA2, putResultA2), + ]); + + expect(syncResult1.changes.remote.length).toBe(1); + expect(syncResult1.changes.remote).toEqual([ + getChangedFileInsert(jsonB1, putResultB1), + ]); + + expect(syncResult1.conflicts.length).toEqual(1); + expect(syncResult1.conflicts).toEqual([ + { + fatDoc: { + _id: '1', + name: '1.json', + fileOid: putResultB1.fileOid, + type: 'json', + doc: jsonB1, + }, + strategy: 'ours-diff', + operation: 'update', + }, + ]); + // Conflict occurs on 1.json + + expect(getWorkingDirDocs(dbB)).toEqual([jsonB1, jsonA2]); + + // Sync dbA + const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; + expect(getWorkingDirDocs(dbA)).toEqual([jsonB1, jsonA2]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + + await destroyDBs([dbA, dbB]); + }); + + /** + * before: jsonA1 + * dbA : +jsonA1 + * dbB : jsonB1 + * after : mergedJson + * + * 3-way merge: + * mergedJson:17 - Conflict. Accept theirs (update-merge) + */ + it('resolves case 17 - Conflict. Accept theirs (update-merge)', async () => { + const schema: Schema = { + json: { plainTextProperties: { name: true } }, + }; + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + { + conflictResolutionStrategy: 'theirs-diff', + connection, + }, + schema + ); + // A puts and pushes + const jsonA1 = { _id: '1', name: 'Hello, world!' }; + const putResultA1 = await dbA.put(jsonA1); + await syncA.tryPush(); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir: localDir, + schema, + }); + // Clone dbA + await dbB.open(); + const syncB = await dbB.sync({ + ...syncA.options, + conflictResolutionStrategy: 'theirs-diff', + }); + + // A puts and pushes + const jsonA1dash = { _id: '1', name: 'Hello' }; + const putResultA1dash = await dbA.put(jsonA1dash); + await syncA.tryPush(); + + // B puts + const jsonB1 = { _id: '1', name: 'Hello, world! Hello, Nara!' }; + const putResultB1 = await dbB.put(jsonB1); + + const mergedJson = { _id: '1', name: 'Hello Hello, Nara!' }; + + // It will occur conflict on id 1.json. + const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; + + const mergedDoc = await dbB.getFatDoc('1.json'); + + expect(syncResult1.action).toBe('resolve conflicts and push'); + expect(syncResult1.commits).toMatchObject({ + local: getCommitInfo([ + putResultA1dash, + `resolve: 1${JSON_EXT}(update-merge,${mergedDoc!.fileOid.substr( + 0, + 7 + )},theirs-diff)`, + ]), + remote: getCommitInfo([ + putResultB1, + `resolve: 1${JSON_EXT}(update-merge,${mergedDoc!.fileOid.substr( + 0, + 7 + )},theirs-diff)`, + ]), + }); + expect(syncResult1.changes.local.length).toBe(1); + expect(syncResult1.changes.local).toEqual([ + getChangedFileUpdateBySHA( + jsonB1, + putResultB1.fileOid, + mergedJson, + mergedDoc!.fileOid + ), + ]); + + expect(syncResult1.changes.remote.length).toBe(1); + expect(syncResult1.changes.remote).toEqual([ + getChangedFileUpdateBySHA( + jsonA1dash, + putResultA1dash.fileOid, + mergedJson, + mergedDoc!.fileOid + ), + ]); + + expect(syncResult1.conflicts.length).toEqual(1); + expect(syncResult1.conflicts).toEqual([ + { + fatDoc: mergedDoc, + strategy: 'theirs-diff', + operation: 'update-merge', + }, + ]); + // Conflict occurs on 1.json + + expect(getWorkingDirDocs(dbB)).toEqual([mergedJson]); + // Sync dbA + const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; + expect(getWorkingDirDocs(dbA)).toEqual([mergedJson]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + + await destroyDBs([dbA, dbB]); + }); + + describe('plaintext-OT Type', () => { + /** + * before: jsonA1 + * dbA : +jsonA1 + * dbB : jsonB1 + * after : mergedJson + * + * 3-way merge: + * mergedJson:17 - Conflict. Accept theirs (update-merge) + */ + it('add text', async () => { + const schema: Schema = { + json: { plainTextProperties: { name: true } }, + }; + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + { + conflictResolutionStrategy: 'ours-diff', + connection, + }, + schema + ); + + // A puts and pushes + const jsonA1 = { _id: '1', name: 'Nara and Kyoto' }; + const putResultA1 = await dbA.put(jsonA1); + await syncA.tryPush(); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir: localDir, + schema, + }); + // Clone dbA + await dbB.open(); + const syncB = await dbB.sync({ + ...syncA.options, + conflictResolutionStrategy: 'ours-diff', + }); + + // A puts and pushes + const jsonA1dash = { _id: '1', name: 'Hello, Nara and Kyoto' }; + const putResultA1dash = await dbA.put(jsonA1dash); + await syncA.tryPush(); + + // B puts + const jsonB1 = { _id: '1', name: 'Nara and Kyoto and Osaka' }; + const putResultB1 = await dbB.put(jsonB1); + + const mergedJson = { _id: '1', name: 'Hello, Nara and Kyoto and Osaka' }; + + // It will occur conflict on id 1.json. + const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; + + const mergedDoc = await dbB.getFatDoc('1.json'); + + expect(syncResult1.changes.local).toEqual([ + getChangedFileUpdateBySHA( + jsonB1, + putResultB1.fileOid, + mergedJson, + mergedDoc!.fileOid + ), + ]); + await destroyDBs([dbA, dbB]); + }); + + /** + * before: jsonA1 + * dbA : +jsonA1 + * dbB : jsonB1 + * after : mergedJson + * + * 3-way merge: + * mergedJson:17 - Conflict. Accept theirs (update-merge) + */ + it('move text', async () => { + const schema: Schema = { + json: { plainTextProperties: { name: true } }, + }; + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + { + conflictResolutionStrategy: 'ours-diff', + connection, + }, + schema + ); + + // A puts and pushes + const jsonA1 = { _id: '1', name: 'Nara Osaka Kyoto Nagoya' }; + const putResultA1 = await dbA.put(jsonA1); + await syncA.tryPush(); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir: localDir, + schema, + }); + // Clone dbA + await dbB.open(); + const syncB = await dbB.sync({ + ...syncA.options, + conflictResolutionStrategy: 'ours-diff', + }); + + // A puts and pushes + const jsonA1dash = { _id: '1', name: 'Osaka Kyoto Nara Nagoya' }; + const putResultA1dash = await dbA.put(jsonA1dash); + await syncA.tryPush(); + + // B puts + const jsonB1 = { _id: '1', name: 'Kyoto Nara Osaka Nagoya' }; + const putResultB1 = await dbB.put(jsonB1); + + const mergedJson = { _id: '1', name: 'Kyoto Osaka Nara Nagoya' }; + + // It will occur conflict on id 1.json. + const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; + + const mergedDoc = await dbB.getFatDoc('1.json'); + + expect(syncResult1.changes.local).toEqual([ + getChangedFileUpdateBySHA( + jsonB1, + putResultB1.fileOid, + mergedJson, + mergedDoc!.fileOid + ), + ]); + await destroyDBs([dbA, dbB]); + }); + + /** + * before: jsonA1 + * dbA : +jsonA1 + * dbB : jsonB1 + * after : mergedJson + * + * 3-way merge: + * mergedJson:17 - Conflict. Accept theirs (update-merge) + */ + it('bad result', async () => { + const schema: Schema = { + json: { plainTextProperties: { name: true } }, + }; + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + { + conflictResolutionStrategy: 'ours-diff', + connection, + }, + schema + ); + + // A puts and pushes + const jsonA1 = { _id: '1', name: 'Nara Kyoto' }; + const putResultA1 = await dbA.put(jsonA1); + await syncA.tryPush(); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir: localDir, + schema, + }); + // Clone dbA + await dbB.open(); + const syncB = await dbB.sync({ + ...syncA.options, + conflictResolutionStrategy: 'ours-diff', + }); + + // A puts and pushes + const jsonA1dash = { _id: '1', name: 'Nara Kamo' }; + const putResultA1dash = await dbA.put(jsonA1dash); + await syncA.tryPush(); + + // B puts + const jsonB1 = { _id: '1', name: 'Kyoto Nara' }; + const putResultB1 = await dbB.put(jsonB1); + + // ! Bad result. Best result is 'Kyoto Nara Kamo' + const mergedJson = { _id: '1', name: 'Kyoto ama' }; + + // It will occur conflict on id 1.json. + const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; + + const mergedDoc = await dbB.getFatDoc('1.json'); + + expect(syncResult1.changes.local).toEqual([ + getChangedFileUpdateBySHA( + jsonB1, + putResultB1.fileOid, + mergedJson, + mergedDoc!.fileOid + ), + ]); + await destroyDBs([dbA, dbB]); + }); + }); + }); +}; diff --git a/test_intg/on_sync_event.test.ts b/test/remote_base/on_sync_event.ts similarity index 100% rename from test_intg/on_sync_event.test.ts rename to test/remote_base/on_sync_event.ts diff --git a/test/remote_nodegit/3way_merge_ot.test.ts b/test/remote_nodegit/3way_merge_ot.test.ts new file mode 100644 index 00000000..ff9c6adb --- /dev/null +++ b/test/remote_nodegit/3way_merge_ot.test.ts @@ -0,0 +1,61 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +/** + * Test trySync + * by using GitHub Personal Access Token + * These tests create a new repository on GitHub if not exists. + */ +import path from 'path'; +import fs from 'fs-extra'; +import { ConnectionSettingsGitHub } from '../../src/types'; +import { GitDocumentDB } from '../../src/git_documentdb'; +import { threeWayMergeOtBase } from '../remote_base/3way_merge_ot'; + +const reposPrefix = 'test_3way_merge_ot_nodegit__'; +const localDir = `./test/database_3way_merge_ot_nodegit`; + +beforeEach(function () { + // @ts-ignore + console.log(`... ${this.currentTest.fullTitle()}`); +}); + +before(() => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + + fs.removeSync(path.resolve(localDir)); +}); + +after(() => { + fs.removeSync(path.resolve(localDir)); +}); + +// This test needs environment variables: +// - GITDDB_GITHUB_USER_URL: URL of your GitHub account +// e.g.) https://github.com/foo/ +// - GITDDB_PERSONAL_ACCESS_TOKEN: A personal access token of your GitHub account +const maybe = + process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN + ? describe + : describe.skip; + +const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') + ? process.env.GITDDB_GITHUB_USER_URL + : process.env.GITDDB_GITHUB_USER_URL + '/'; + +const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; + +const connection: ConnectionSettingsGitHub = { + type: 'github', + personalAccessToken: token, + engine: 'nodegit', +}; + +maybe('NodeGit', threeWayMergeOtBase(connection, remoteURLBase, reposPrefix, localDir)); diff --git a/test_intg/3way_merge_ot.test.ts b/test_intg/3way_merge_ot.test.ts deleted file mode 100644 index 0f2bbf37..00000000 --- a/test_intg/3way_merge_ot.test.ts +++ /dev/null @@ -1,755 +0,0 @@ -/* eslint-disable @typescript-eslint/naming-convention */ -/** - * GitDocumentDB - * Copyright (c) Hidekazu Kubota - * - * This source code is licensed under the Mozilla Public License Version 2.0 - * found in the LICENSE file in the root directory of this source tree. - */ - -/** - * Test Operational Transformation in 3-way merge - * by using GitHub Personal Access Token - * These tests create a new repository on GitHub if not exists. - */ -import path from 'path'; -import fs from 'fs-extra'; -import expect from 'expect'; -import { GitDocumentDB } from '../src/git_documentdb'; -import { - Schema, - SyncResultMergeAndPush, - SyncResultResolveConflictsAndPush, -} from '../src/types'; -import { - compareWorkingDirAndBlobs, - createClonedDatabases, - createDatabase, - destroyDBs, - getChangedFileDelete, - getChangedFileInsert, - getChangedFileUpdateBySHA, - getCommitInfo, - getWorkingDirDocs, - removeRemoteRepositories, -} from '../test/remote_utils'; -import { JSON_EXT } from '../src/const'; - -const reposPrefix = 'test_3way_merge_ot___'; -const localDir = `./test_intg/database_3way_merge_ot`; - -let idCounter = 0; -const serialId = () => { - return `${reposPrefix}${idCounter++}`; -}; - -beforeEach(function () { - // @ts-ignore - console.log(`... ${this.currentTest.fullTitle()}`); -}); - -before(() => { - // eslint-disable-next-line @typescript-eslint/no-var-requires - GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); - - fs.removeSync(path.resolve(localDir)); -}); - -after(() => { - // It may throw error due to memory leak of getCommitLogs() - // fs.removeSync(path.resolve(localDir)); -}); - -// This test needs environment variables: -// - GITDDB_GITHUB_USER_URL: URL of your GitHub account -// e.g.) https://github.com/foo/ -// - GITDDB_personalAccessToken: A personal access token of your GitHub account -const maybe = - process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN - ? describe - : describe.skip; - -maybe('intg: <3way_merge_ot>', () => { - const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') - ? process.env.GITDDB_GITHUB_USER_URL - : process.env.GITDDB_GITHUB_USER_URL + '/'; - const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; - - before(async () => { - await removeRemoteRepositories(reposPrefix); - }); - - /** - * before: - * dbA : jsonA1 jsonA2 - * dbB : jsonB1 jsonB3 - * after : mergedJson jsonA2 jsonB3 - * - * 3-way merge: - * mergedJson: 4 - Conflict. Accept ours (insert-merge) - * jsonA2: 1 - Accept theirs (insert) - * jsonB3: 2 - Accept ours (insert) - */ - it('resolves case 1 - Accept theirs (insert), case 2 - Accept ours (insert), case 4 - Conflict. Accept ours (insert-merge)', async () => { - const [dbA, dbB, syncA, syncB] = await createClonedDatabases( - remoteURLBase, - localDir, - serialId, - { - conflictResolutionStrategy: 'ours-diff', - } - ); - - // A puts and pushes - const jsonA1 = { _id: '1', name: 'fromA', a: 'fromA' }; - const putResultA1 = await dbA.put(jsonA1); - const jsonA2 = { _id: '2', name: 'fromA' }; - const putResultA2 = await dbA.put(jsonA2); - await syncA.tryPush(); - - // B puts the same file - const jsonB1 = { _id: '1', name: 'fromB', b: 'fromB' }; - const putResultB1 = await dbB.put(jsonB1); - - const mergedJson = { _id: '1', name: 'fromB', a: 'fromA', b: 'fromB' }; - - // B puts a new file - const jsonB3 = { _id: '3', name: 'fromB' }; - const putResultB3 = await dbB.put(jsonB3); - - // It will occur conflict on id 1.json. - const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; - - const mergedDoc = await dbB.getFatDoc('1.json'); - - expect(syncResult1.action).toBe('resolve conflicts and push'); - expect(syncResult1.commits).toMatchObject({ - local: getCommitInfo([ - putResultA1, - putResultA2, - `resolve: 1${JSON_EXT}(insert-merge,${mergedDoc!.fileOid.substr(0, 7)},ours-diff)`, - ]), - remote: getCommitInfo([ - putResultB1, - putResultB3, - `resolve: 1${JSON_EXT}(insert-merge,${mergedDoc!.fileOid.substr(0, 7)},ours-diff)`, - ]), - }); - expect(syncResult1.changes.local.length).toBe(2); - expect(syncResult1.changes.local).toEqual( - expect.arrayContaining([ - getChangedFileUpdateBySHA( - jsonB1, - putResultB1.fileOid, - mergedJson, - mergedDoc!.fileOid - ), - getChangedFileInsert(jsonA2, putResultA2), - ]) - ); - - expect(syncResult1.changes.remote.length).toBe(2); - expect(syncResult1.changes.remote).toEqual( - expect.arrayContaining([ - getChangedFileUpdateBySHA( - jsonA1, - putResultA1.fileOid, - mergedJson, - mergedDoc!.fileOid - ), - getChangedFileInsert(jsonB3, putResultB3), - ]) - ); - - expect(syncResult1.conflicts.length).toEqual(1); - expect(syncResult1.conflicts).toEqual([ - { - fatDoc: mergedDoc, - strategy: 'ours-diff', - operation: 'insert-merge', - }, - ]); - // Conflict occurs on 1.json - - expect(getWorkingDirDocs(dbB)).toEqual([mergedJson, jsonA2, jsonB3]); - // Sync dbA - const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; - expect(getWorkingDirDocs(dbA)).toEqual([mergedJson, jsonA2, jsonB3]); - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); - - await destroyDBs([dbA, dbB]); - }); - - /** - * before: - * dbA : jsonA1 - * dbB : jsonB1 - * after : jsonA1 - * - * 3-way merge: - * jsonA1: 5 - Conflict. Accept theirs (insert) - */ - it('resolves case 5 - Conflict. Accept theirs (insert)', async () => { - const [dbA, dbB, syncA, syncB] = await createClonedDatabases( - remoteURLBase, - localDir, - serialId, - { - conflictResolutionStrategy: 'theirs-diff', - } - ); - - // A puts and pushes - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResultA1 = await dbA.put(jsonA1); - await syncA.tryPush(); - - // B puts the same file - const jsonB1 = { _id: '1', name: 'fromB' }; - const putResultB1 = await dbB.put(jsonB1); - - const mergedJson = { _id: '1', name: 'fromA' }; - - // It will occur conflict on id 1.json. - const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; - - const mergedDoc = await dbB.getFatDoc('1.json'); - - expect(syncResult1.action).toBe('resolve conflicts and push'); - expect(syncResult1.commits).toMatchObject({ - local: getCommitInfo([ - putResultA1, - `resolve: 1${JSON_EXT}(insert-merge,${mergedDoc!.fileOid.substr( - 0, - 7 - )},theirs-diff)`, - ]), - remote: getCommitInfo([ - putResultB1, - `resolve: 1${JSON_EXT}(insert-merge,${mergedDoc!.fileOid.substr( - 0, - 7 - )},theirs-diff)`, - ]), - }); - expect(syncResult1.changes.local.length).toBe(1); - expect(syncResult1.changes.local).toEqual([ - getChangedFileUpdateBySHA( - jsonB1, - putResultB1!.fileOid, - mergedJson, - mergedDoc!.fileOid - ), - ]); - - expect(syncResult1.changes.remote.length).toBe(0); - - expect(syncResult1.conflicts.length).toEqual(1); - expect(syncResult1.conflicts).toEqual([ - { - fatDoc: mergedDoc, - strategy: 'theirs-diff', - operation: 'insert-merge', - }, - ]); - expect(getWorkingDirDocs(dbA)).toEqual([jsonA1]); - expect(getWorkingDirDocs(dbB)).toEqual([jsonA1]); - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); - - await destroyDBs([dbA, dbB]); - }); - - /** - * before: jsonA1 - * dbA : +jsonA1 - * dbB : -jsonA1 - * result: - * - * '+' means update - * - * 3-way merge: - * jsonA1: 8 - Conflict. Accept ours (delete) - */ - it('resolves case 8 - Conflict. Accept ours (delete)', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - conflictResolutionStrategy: 'ours-diff', - }); - // A puts and pushes - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResultA1 = await dbA.put(jsonA1); - await syncA.tryPush(); - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir: localDir, - }); - // Clone dbA - await dbB.open(); - const syncB = await dbB.sync(syncA.options); - - // A updates and pushes - const jsonA1dash = { _id: '1', name: 'updated' }; - const putResultA1dash = await dbA.put(jsonA1dash); - await syncA.tryPush(); - - // B removes and syncs - const deleteResultB1 = await dbB.delete(jsonA1); - - const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; - expect(syncResult1.action).toBe('resolve conflicts and push'); - expect(syncResult1.commits).toMatchObject({ - local: getCommitInfo([ - putResultA1dash, - `resolve: 1${JSON_EXT}(delete,${deleteResultB1.fileOid.substr(0, 7)},ours-diff)`, - ]), - remote: getCommitInfo([ - deleteResultB1, - `resolve: 1${JSON_EXT}(delete,${deleteResultB1.fileOid.substr(0, 7)},ours-diff)`, - ]), - }); - expect(syncResult1.changes.local.length).toBe(0); - - expect(syncResult1.changes.remote.length).toBe(1); - expect(syncResult1.changes.remote).toEqual([ - getChangedFileDelete(jsonA1dash, putResultA1dash), - ]); - - expect(syncResult1.conflicts.length).toEqual(1); - expect(syncResult1.conflicts).toEqual([ - { - fatDoc: { - _id: '1', - name: '1.json', - fileOid: deleteResultB1.fileOid, - type: 'json', - doc: jsonA1, - }, - strategy: 'ours-diff', - operation: 'delete', - }, - ]); - // Conflict occurs on 1.json - - expect(getWorkingDirDocs(dbB)).toEqual([]); - - // Sync dbA - const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; - expect(getWorkingDirDocs(dbA)).toEqual([]); - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); - - await destroyDBs([dbA, dbB]); - }); - - /** - * before: jsonA1 - * dbA : -jsonA1 jsonA2 - * dbB : jsonB1 - * result: jsonB1 jsonA2 - * - * 3-way merge: - * jsonB1: 11 - Conflict. Accept ours (update) - * jsonA2: 1 - Accept theirs (insert) - */ - it('resolves case 11 - Conflict. Accept ours (update), case 1 - Accept theirs (insert), ', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - conflictResolutionStrategy: 'ours-diff', - }); - // A puts and pushes - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResultA1 = await dbA.put(jsonA1); - await syncA.tryPush(); - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir: localDir, - }); - // Clone dbA - await dbB.open(); - const syncB = await dbB.sync(syncA.options); - - // A removes the old file and puts a new file - const deleteResultA1 = await dbA.delete(jsonA1); - const jsonA2 = { _id: '2', name: 'fromA' }; - const putResultA2 = await dbA.put(jsonA2); - await syncA.tryPush(); - - // B updates the old file and syncs - const jsonB1 = { _id: '1', name: 'fromB' }; - const putResultB1 = await dbB.put(jsonB1); - - const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; - expect(syncResult1.action).toBe('resolve conflicts and push'); - expect(syncResult1.commits).toMatchObject({ - local: getCommitInfo([ - deleteResultA1, - putResultA2, - `resolve: 1${JSON_EXT}(update,${putResultB1.fileOid.substr(0, 7)},ours-diff)`, - ]), - remote: getCommitInfo([ - putResultB1, - `resolve: 1${JSON_EXT}(update,${putResultB1.fileOid.substr(0, 7)},ours-diff)`, - ]), - }); - expect(syncResult1.changes.local.length).toBe(1); - expect(syncResult1.changes.local).toEqual([getChangedFileInsert(jsonA2, putResultA2)]); - - expect(syncResult1.changes.remote.length).toBe(1); - expect(syncResult1.changes.remote).toEqual([getChangedFileInsert(jsonB1, putResultB1)]); - - expect(syncResult1.conflicts.length).toEqual(1); - expect(syncResult1.conflicts).toEqual([ - { - fatDoc: { - _id: '1', - name: '1.json', - fileOid: putResultB1.fileOid, - type: 'json', - doc: jsonB1, - }, - strategy: 'ours-diff', - operation: 'update', - }, - ]); - // Conflict occurs on 1.json - - expect(getWorkingDirDocs(dbB)).toEqual([jsonB1, jsonA2]); - - // Sync dbA - const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; - expect(getWorkingDirDocs(dbA)).toEqual([jsonB1, jsonA2]); - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); - - await destroyDBs([dbA, dbB]); - }); - - /** - * before: jsonA1 - * dbA : +jsonA1 - * dbB : jsonB1 - * after : mergedJson - * - * 3-way merge: - * mergedJson:17 - Conflict. Accept theirs (update-merge) - */ - it('resolves case 17 - Conflict. Accept theirs (update-merge)', async () => { - const schema: Schema = { - json: { plainTextProperties: { name: true } }, - }; - const [dbA, syncA] = await createDatabase( - remoteURLBase, - localDir, - serialId, - { - conflictResolutionStrategy: 'theirs-diff', - }, - schema - ); - // A puts and pushes - const jsonA1 = { _id: '1', name: 'Hello, world!' }; - const putResultA1 = await dbA.put(jsonA1); - await syncA.tryPush(); - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir: localDir, - schema, - }); - // Clone dbA - await dbB.open(); - const syncB = await dbB.sync({ - ...syncA.options, - conflictResolutionStrategy: 'theirs-diff', - }); - - // A puts and pushes - const jsonA1dash = { _id: '1', name: 'Hello' }; - const putResultA1dash = await dbA.put(jsonA1dash); - await syncA.tryPush(); - - // B puts - const jsonB1 = { _id: '1', name: 'Hello, world! Hello, Nara!' }; - const putResultB1 = await dbB.put(jsonB1); - - const mergedJson = { _id: '1', name: 'Hello Hello, Nara!' }; - - // It will occur conflict on id 1.json. - const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; - - const mergedDoc = await dbB.getFatDoc('1.json'); - - expect(syncResult1.action).toBe('resolve conflicts and push'); - expect(syncResult1.commits).toMatchObject({ - local: getCommitInfo([ - putResultA1dash, - `resolve: 1${JSON_EXT}(update-merge,${mergedDoc!.fileOid.substr( - 0, - 7 - )},theirs-diff)`, - ]), - remote: getCommitInfo([ - putResultB1, - `resolve: 1${JSON_EXT}(update-merge,${mergedDoc!.fileOid.substr( - 0, - 7 - )},theirs-diff)`, - ]), - }); - expect(syncResult1.changes.local.length).toBe(1); - expect(syncResult1.changes.local).toEqual([ - getChangedFileUpdateBySHA( - jsonB1, - putResultB1.fileOid, - mergedJson, - mergedDoc!.fileOid - ), - ]); - - expect(syncResult1.changes.remote.length).toBe(1); - expect(syncResult1.changes.remote).toEqual([ - getChangedFileUpdateBySHA( - jsonA1dash, - putResultA1dash.fileOid, - mergedJson, - mergedDoc!.fileOid - ), - ]); - - expect(syncResult1.conflicts.length).toEqual(1); - expect(syncResult1.conflicts).toEqual([ - { - fatDoc: mergedDoc, - strategy: 'theirs-diff', - operation: 'update-merge', - }, - ]); - // Conflict occurs on 1.json - - expect(getWorkingDirDocs(dbB)).toEqual([mergedJson]); - // Sync dbA - const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; - expect(getWorkingDirDocs(dbA)).toEqual([mergedJson]); - - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); - await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); - - await destroyDBs([dbA, dbB]); - }); - - describe('plaintext-OT Type', () => { - /** - * before: jsonA1 - * dbA : +jsonA1 - * dbB : jsonB1 - * after : mergedJson - * - * 3-way merge: - * mergedJson:17 - Conflict. Accept theirs (update-merge) - */ - it('add text', async () => { - const schema: Schema = { - json: { plainTextProperties: { name: true } }, - }; - const [dbA, syncA] = await createDatabase( - remoteURLBase, - localDir, - serialId, - { - conflictResolutionStrategy: 'ours-diff', - }, - schema - ); - - // A puts and pushes - const jsonA1 = { _id: '1', name: 'Nara and Kyoto' }; - const putResultA1 = await dbA.put(jsonA1); - await syncA.tryPush(); - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir: localDir, - schema, - }); - // Clone dbA - await dbB.open(); - const syncB = await dbB.sync({ - ...syncA.options, - conflictResolutionStrategy: 'ours-diff', - }); - - // A puts and pushes - const jsonA1dash = { _id: '1', name: 'Hello, Nara and Kyoto' }; - const putResultA1dash = await dbA.put(jsonA1dash); - await syncA.tryPush(); - - // B puts - const jsonB1 = { _id: '1', name: 'Nara and Kyoto and Osaka' }; - const putResultB1 = await dbB.put(jsonB1); - - const mergedJson = { _id: '1', name: 'Hello, Nara and Kyoto and Osaka' }; - - // It will occur conflict on id 1.json. - const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; - - const mergedDoc = await dbB.getFatDoc('1.json'); - - expect(syncResult1.changes.local).toEqual([ - getChangedFileUpdateBySHA( - jsonB1, - putResultB1.fileOid, - mergedJson, - mergedDoc!.fileOid - ), - ]); - await destroyDBs([dbA, dbB]); - }); - - /** - * before: jsonA1 - * dbA : +jsonA1 - * dbB : jsonB1 - * after : mergedJson - * - * 3-way merge: - * mergedJson:17 - Conflict. Accept theirs (update-merge) - */ - it('move text', async () => { - const schema: Schema = { - json: { plainTextProperties: { name: true } }, - }; - const [dbA, syncA] = await createDatabase( - remoteURLBase, - localDir, - serialId, - { - conflictResolutionStrategy: 'ours-diff', - }, - schema - ); - - // A puts and pushes - const jsonA1 = { _id: '1', name: 'Nara Osaka Kyoto Nagoya' }; - const putResultA1 = await dbA.put(jsonA1); - await syncA.tryPush(); - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir: localDir, - schema, - }); - // Clone dbA - await dbB.open(); - const syncB = await dbB.sync({ - ...syncA.options, - conflictResolutionStrategy: 'ours-diff', - }); - - // A puts and pushes - const jsonA1dash = { _id: '1', name: 'Osaka Kyoto Nara Nagoya' }; - const putResultA1dash = await dbA.put(jsonA1dash); - await syncA.tryPush(); - - // B puts - const jsonB1 = { _id: '1', name: 'Kyoto Nara Osaka Nagoya' }; - const putResultB1 = await dbB.put(jsonB1); - - const mergedJson = { _id: '1', name: 'Kyoto Osaka Nara Nagoya' }; - - // It will occur conflict on id 1.json. - const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; - - const mergedDoc = await dbB.getFatDoc('1.json'); - - expect(syncResult1.changes.local).toEqual([ - getChangedFileUpdateBySHA( - jsonB1, - putResultB1.fileOid, - mergedJson, - mergedDoc!.fileOid - ), - ]); - await destroyDBs([dbA, dbB]); - }); - - /** - * before: jsonA1 - * dbA : +jsonA1 - * dbB : jsonB1 - * after : mergedJson - * - * 3-way merge: - * mergedJson:17 - Conflict. Accept theirs (update-merge) - */ - it('bad result', async () => { - const schema: Schema = { - json: { plainTextProperties: { name: true } }, - }; - const [dbA, syncA] = await createDatabase( - remoteURLBase, - localDir, - serialId, - { - conflictResolutionStrategy: 'ours-diff', - }, - schema - ); - - // A puts and pushes - const jsonA1 = { _id: '1', name: 'Nara Kyoto' }; - const putResultA1 = await dbA.put(jsonA1); - await syncA.tryPush(); - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir: localDir, - schema, - }); - // Clone dbA - await dbB.open(); - const syncB = await dbB.sync({ - ...syncA.options, - conflictResolutionStrategy: 'ours-diff', - }); - - // A puts and pushes - const jsonA1dash = { _id: '1', name: 'Nara Kamo' }; - const putResultA1dash = await dbA.put(jsonA1dash); - await syncA.tryPush(); - - // B puts - const jsonB1 = { _id: '1', name: 'Kyoto Nara' }; - const putResultB1 = await dbB.put(jsonB1); - - // ! Bad result. Best result is 'Kyoto Nara Kamo' - const mergedJson = { _id: '1', name: 'Kyoto ama' }; - - // It will occur conflict on id 1.json. - const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; - - const mergedDoc = await dbB.getFatDoc('1.json'); - - expect(syncResult1.changes.local).toEqual([ - getChangedFileUpdateBySHA( - jsonB1, - putResultB1.fileOid, - mergedJson, - mergedDoc!.fileOid - ), - ]); - await destroyDBs([dbA, dbB]); - }); - }); -}); diff --git a/test_intg/README.md b/test_intg/README.md deleted file mode 100644 index daf6f6b7..00000000 --- a/test_intg/README.md +++ /dev/null @@ -1 +0,0 @@ -# Integration Test \ No newline at end of file diff --git a/test_intg/tsconfig.json b/test_intg/tsconfig.json deleted file mode 100644 index 607d44fc..00000000 --- a/test_intg/tsconfig.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "extends": "../tsconfig-base", - "include": [ - "**/*", - ], -} \ No newline at end of file From bfb9445c923eafedd0270a581b43da58db0c1afd Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sat, 31 Jul 2021 16:19:39 +0900 Subject: [PATCH 113/297] test: remote test_intg --- .npmignore | 1 - package.json | 10 +- test/remote_base/on_sync_event.ts | 695 +++++++++++----------- test/remote_nodegit/on_sync_event.test.ts | 61 ++ tsconfig.eslint.json | 1 - 5 files changed, 409 insertions(+), 359 deletions(-) create mode 100644 test/remote_nodegit/on_sync_event.test.ts diff --git a/.npmignore b/.npmignore index 9f3284e7..4585b884 100644 --- a/.npmignore +++ b/.npmignore @@ -33,7 +33,6 @@ node_modules/ # test coverage/ test/ -test_intg/ dist/test/ .nyc_output/ diff --git a/package.json b/package.json index d7d9f076..fc8e8d68 100644 --- a/package.json +++ b/package.json @@ -12,11 +12,11 @@ "doc": "npm run build && npm run api-extractor && npm run crlf", "mocha": "rm -rf test/database* && npx cross-env TS_NODE_FILES=true TS_NODE_PROJECT=tsconfig.mocha.json mocha", "mocha-unit": "rm -rf test/database* && npx cross-env TS_NODE_FILES=true TS_NODE_PROJECT=tsconfig.mocha.json mocha --retries 0 --no-parallel", - "compile-tests": "tsc --project test/tsconfig.json && tsc --project test_intg/tsconfig.json", - "rm-test-db": "rm -rf test/database* test_intg/database*", - "test": "npm run rm-test-db && npx nyc npm run mocha \"test/**/*.test.ts\" \"test_intg/**/*.test.ts\" && npm run rm-test-db", - "test-noretry": "npm run rm-test-db && npx nyc npm run mocha-noretry \"test/**/*.test.ts\" \"test_intg/**/*.test.ts\" && npm run rm-test-db", - "test-serial": "npm run rm-test-db && npx nyc npm run mocha-serial \"test/**/*.test.ts\" \"test_intg/**/*.test.ts\" && npm run rm-test-db", + "compile-tests": "tsc --project test/tsconfig.json", + "rm-test-db": "rm -rf test/database*", + "test": "npm run rm-test-db && npx nyc npm run mocha \"test/**/*.test.ts\" && npm run rm-test-db", + "test-noretry": "npm run rm-test-db && npx nyc npm run mocha-noretry \"test/**/*.test.ts\" && npm run rm-test-db", + "test-serial": "npm run rm-test-db && npx nyc npm run mocha-serial \"test/**/*.test.ts\" && npm run rm-test-db", "upload-coverage": "npx coveralls < coverage/lcov.info", "prepare": "", "prepublishOnly": "npm run build && npm test", diff --git a/test/remote_base/on_sync_event.ts b/test/remote_base/on_sync_event.ts index 1afd27a3..580d597d 100644 --- a/test/remote_base/on_sync_event.ts +++ b/test/remote_base/on_sync_event.ts @@ -12,414 +12,405 @@ * by using GitHub Personal Access Token * These tests create a new repository on GitHub if not exists. */ -import path from 'path'; -import fs from 'fs-extra'; import expect from 'expect'; -import { Err } from '../src/error'; -import { SyncResult, SyncResultFastForwardMerge, TaskMetadata } from '../src/types'; +import { Err } from '../../src/error'; +import { + ConnectionSettings, + SyncResult, + SyncResultFastForwardMerge, + TaskMetadata, +} from '../../src/types'; import { createClonedDatabases, destroyDBs, getChangedFileInsert, getCommitInfo, removeRemoteRepositories, -} from '../test/remote_utils'; -import { sleep } from '../src/utils'; -import { GitDocumentDB } from '../src/git_documentdb'; - -const reposPrefix = 'test_on_sync_event___'; -const localDir = `./test_intg/database_on_sync_event`; - -let idCounter = 0; -const serialId = () => { - return `${reposPrefix}${idCounter++}`; -}; - -beforeEach(function () { - // @ts-ignore - console.log(`... ${this.currentTest.fullTitle()}`); -}); - -before(() => { - // eslint-disable-next-line @typescript-eslint/no-var-requires - GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); - - fs.removeSync(path.resolve(localDir)); -}); - -after(() => { - // It may throw error due to memory leak of getCommitLogs() - // fs.removeSync(path.resolve(localDir)); -}); - -// This test needs environment variables: -// - GITDDB_GITHUB_USER_URL: URL of your GitHub account -// e.g.) https://github.com/foo/ -// - GITDDB_personalAccessToken: A personal access token of your GitHub account -const maybe = - process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN - ? describe - : describe.skip; - -maybe('intg: ', () => { - const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') - ? process.env.GITDDB_GITHUB_USER_URL - : process.env.GITDDB_GITHUB_USER_URL + '/'; - const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; +} from '../remote_utils'; +import { sleep } from '../../src/utils'; +import { GitDocumentDB } from '../../src/git_documentdb'; + +export const onSyncEventBase = ( + connection: ConnectionSettings, + remoteURLBase: string, + reposPrefix: string, + localDir: string +) => () => { + let idCounter = 0; + const serialId = () => { + return `${reposPrefix}${idCounter++}`; + }; before(async () => { await removeRemoteRepositories(reposPrefix); }); - describe('onSyncEvent', () => { - it('with remoteURL', async () => { - const [dbA, dbB, syncA, syncB] = await createClonedDatabases( - remoteURLBase, - localDir, - serialId - ); - - // A puts and pushes - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResult1 = await dbA.put(jsonA1); - await syncA.tryPush(); - - // B syncs - let result: SyncResultFastForwardMerge | undefined; - let changeTaskId = ''; - - dbB.onSyncEvent( - syncB.remoteURL, - 'change', - (syncResult: SyncResult, taskMetadata: TaskMetadata) => { - result = syncResult as SyncResultFastForwardMerge; - changeTaskId = taskMetadata.taskId; + describe(' GitDocumentDB', () => { + describe('onSyncEvent', () => { + it('with remoteURL', async () => { + const [dbA, dbB, syncA, syncB] = await createClonedDatabases( + remoteURLBase, + localDir, + serialId, + { + connection, + } + ); + + // A puts and pushes + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResult1 = await dbA.put(jsonA1); + await syncA.tryPush(); + + // B syncs + let result: SyncResultFastForwardMerge | undefined; + let changeTaskId = ''; + + dbB.onSyncEvent( + syncB.remoteURL, + 'change', + (syncResult: SyncResult, taskMetadata: TaskMetadata) => { + result = syncResult as SyncResultFastForwardMerge; + changeTaskId = taskMetadata.taskId; + } + ); + let complete = false; + let endTaskId = ''; + dbB.onSyncEvent(syncB.remoteURL, 'complete', (taskMetadata: TaskMetadata) => { + complete = true; + endTaskId = taskMetadata.taskId; + }); + await syncB.trySync(); + + // eslint-disable-next-line no-unmodified-loop-condition + while (!complete) { + // eslint-disable-next-line no-await-in-loop + await sleep(1000); } - ); - let complete = false; - let endTaskId = ''; - dbB.onSyncEvent(syncB.remoteURL, 'complete', (taskMetadata: TaskMetadata) => { - complete = true; - endTaskId = taskMetadata.taskId; - }); - await syncB.trySync(); - // eslint-disable-next-line no-unmodified-loop-condition - while (!complete) { - // eslint-disable-next-line no-await-in-loop - await sleep(1000); - } + expect(result!.action).toBe('fast-forward merge'); - expect(result!.action).toBe('fast-forward merge'); + expect(result!.commits).toMatchObject({ + local: getCommitInfo([putResult1]), + }); - expect(result!.commits).toMatchObject({ - local: getCommitInfo([putResult1]), - }); - - expect(result!.changes.local).toEqual([getChangedFileInsert(jsonA1, putResult1)]); - - expect(changeTaskId).toBe(endTaskId); + expect(result!.changes.local).toEqual([getChangedFileInsert(jsonA1, putResult1)]); - await destroyDBs([dbA, dbB]); - }); + expect(changeTaskId).toBe(endTaskId); - it('with remoteURL throws UndefinedSyncError', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbNameA = serialId(); - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, + await destroyDBs([dbA, dbB]); }); - await dbA.open(); - - expect(() => { - dbA.onSyncEvent('https://test.example.com', 'change', () => {}); - }).toThrowError(Err.UndefinedSyncError); - }); - it('with sync', async () => { - const [dbA, dbB, syncA, syncB] = await createClonedDatabases( - remoteURLBase, - localDir, - serialId - ); - - // A puts and pushes - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResult1 = await dbA.put(jsonA1); - await syncA.tryPush(); - - // B syncs - let result: SyncResultFastForwardMerge | undefined; - let changeTaskId = ''; - - dbB.onSyncEvent( - syncB, - 'change', - (syncResult: SyncResult, taskMetadata: TaskMetadata) => { - result = syncResult as SyncResultFastForwardMerge; - changeTaskId = taskMetadata.taskId; - } - ); - let complete = false; - let endTaskId = ''; - dbB.onSyncEvent(syncB, 'complete', (taskMetadata: TaskMetadata) => { - complete = true; - endTaskId = taskMetadata.taskId; + it('with remoteURL throws UndefinedSyncError', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + await dbA.open(); + + expect(() => { + dbA.onSyncEvent('https://test.example.com', 'change', () => {}); + }).toThrowError(Err.UndefinedSyncError); }); - await syncB.trySync(); - - // eslint-disable-next-line no-unmodified-loop-condition - while (!complete) { - // eslint-disable-next-line no-await-in-loop - await sleep(1000); - } - - expect(result!.action).toBe('fast-forward merge'); - expect(result!.commits).toMatchObject({ - local: getCommitInfo([putResult1]), - }); + it('with sync', async () => { + const [dbA, dbB, syncA, syncB] = await createClonedDatabases( + remoteURLBase, + localDir, + serialId, + { + connection, + } + ); + + // A puts and pushes + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResult1 = await dbA.put(jsonA1); + await syncA.tryPush(); + + // B syncs + let result: SyncResultFastForwardMerge | undefined; + let changeTaskId = ''; + + dbB.onSyncEvent( + syncB, + 'change', + (syncResult: SyncResult, taskMetadata: TaskMetadata) => { + result = syncResult as SyncResultFastForwardMerge; + changeTaskId = taskMetadata.taskId; + } + ); + let complete = false; + let endTaskId = ''; + dbB.onSyncEvent(syncB, 'complete', (taskMetadata: TaskMetadata) => { + complete = true; + endTaskId = taskMetadata.taskId; + }); + await syncB.trySync(); + + // eslint-disable-next-line no-unmodified-loop-condition + while (!complete) { + // eslint-disable-next-line no-await-in-loop + await sleep(1000); + } - expect(result!.changes.local).toEqual([getChangedFileInsert(jsonA1, putResult1)]); + expect(result!.action).toBe('fast-forward merge'); - expect(changeTaskId).toBe(endTaskId); + expect(result!.commits).toMatchObject({ + local: getCommitInfo([putResult1]), + }); - await destroyDBs([dbA, dbB]); - }); - }); + expect(result!.changes.local).toEqual([getChangedFileInsert(jsonA1, putResult1)]); - describe('offSyncEvent', () => { - it('with remoteURL', async () => { - const [dbA, dbB, syncA, syncB] = await createClonedDatabases( - remoteURLBase, - localDir, - serialId - ); - - const callback = (syncResult: SyncResult, taskMetadata: TaskMetadata) => {}; - dbB.onSyncEvent(syncB.remoteURL, 'change', callback); - expect(syncB.eventHandlers.change.length).toBe(1); - dbB.offSyncEvent(syncB.remoteURL, 'change', callback); - expect(syncB.eventHandlers.change.length).toBe(0); - - await destroyDBs([dbA, dbB]); - }); + expect(changeTaskId).toBe(endTaskId); - it('with remoteURL throws UndefinedSyncError', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbNameA = serialId(); - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, + await destroyDBs([dbA, dbB]); }); - await dbA.open(); - - expect(() => { - dbA.offSyncEvent('https://test.example.com', 'change', () => {}); - }).toThrowError(Err.UndefinedSyncError); }); - it('with sync', async () => { - const [dbA, dbB, syncA, syncB] = await createClonedDatabases( - remoteURLBase, - localDir, - serialId - ); + describe('offSyncEvent', () => { + it('with remoteURL', async () => { + const [dbA, dbB, syncA, syncB] = await createClonedDatabases( + remoteURLBase, + localDir, + serialId, + { + connection, + } + ); + + const callback = (syncResult: SyncResult, taskMetadata: TaskMetadata) => {}; + dbB.onSyncEvent(syncB.remoteURL, 'change', callback); + expect(syncB.eventHandlers.change.length).toBe(1); + dbB.offSyncEvent(syncB.remoteURL, 'change', callback); + expect(syncB.eventHandlers.change.length).toBe(0); + + await destroyDBs([dbA, dbB]); + }); - const callback = (syncResult: SyncResult, taskMetadata: TaskMetadata) => {}; - dbB.onSyncEvent(syncB, 'change', callback); - expect(syncB.eventHandlers.change.length).toBe(1); - dbB.offSyncEvent(syncB, 'change', callback); - expect(syncB.eventHandlers.change.length).toBe(0); + it('with remoteURL throws UndefinedSyncError', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + await dbA.open(); + + expect(() => { + dbA.offSyncEvent('https://test.example.com', 'change', () => {}); + }).toThrowError(Err.UndefinedSyncError); + }); - await destroyDBs([dbA, dbB]); + it('with sync', async () => { + const [dbA, dbB, syncA, syncB] = await createClonedDatabases( + remoteURLBase, + localDir, + serialId, + { + connection, + } + ); + + const callback = (syncResult: SyncResult, taskMetadata: TaskMetadata) => {}; + dbB.onSyncEvent(syncB, 'change', callback); + expect(syncB.eventHandlers.change.length).toBe(1); + dbB.offSyncEvent(syncB, 'change', callback); + expect(syncB.eventHandlers.change.length).toBe(0); + + await destroyDBs([dbA, dbB]); + }); }); }); -}); -maybe('intg: ', () => { - const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') - ? process.env.GITDDB_GITHUB_USER_URL - : process.env.GITDDB_GITHUB_USER_URL + '/'; - const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; - - before(async () => { - await removeRemoteRepositories(reposPrefix); - }); - - describe('onSyncEvent', () => { - it('with remoteURL', async () => { - const [dbA, dbB, syncA, syncB] = await createClonedDatabases( - remoteURLBase, - localDir, - serialId - ); - const colA = dbA.collection('col'); - const colB = dbB.collection('col'); - - // A puts and pushes - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResult1 = await colA.put(jsonA1); - await syncA.tryPush(); - - // B syncs - let result: SyncResultFastForwardMerge | undefined; - let changeTaskId = ''; - - colB.onSyncEvent( - syncB.remoteURL, - 'change', - (syncResult: SyncResult, taskMetadata: TaskMetadata) => { - result = syncResult as SyncResultFastForwardMerge; - changeTaskId = taskMetadata.taskId; + describe(' Collection', () => { + describe('onSyncEvent', () => { + it('with remoteURL', async () => { + const [dbA, dbB, syncA, syncB] = await createClonedDatabases( + remoteURLBase, + localDir, + serialId, + { + connection, + } + ); + const colA = dbA.collection('col'); + const colB = dbB.collection('col'); + + // A puts and pushes + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResult1 = await colA.put(jsonA1); + await syncA.tryPush(); + + // B syncs + let result: SyncResultFastForwardMerge | undefined; + let changeTaskId = ''; + + colB.onSyncEvent( + syncB.remoteURL, + 'change', + (syncResult: SyncResult, taskMetadata: TaskMetadata) => { + result = syncResult as SyncResultFastForwardMerge; + changeTaskId = taskMetadata.taskId; + } + ); + let complete = false; + let endTaskId = ''; + colB.onSyncEvent(syncB.remoteURL, 'complete', (taskMetadata: TaskMetadata) => { + complete = true; + endTaskId = taskMetadata.taskId; + }); + await syncB.trySync(); + + // eslint-disable-next-line no-unmodified-loop-condition + while (!complete) { + // eslint-disable-next-line no-await-in-loop + await sleep(1000); } - ); - let complete = false; - let endTaskId = ''; - colB.onSyncEvent(syncB.remoteURL, 'complete', (taskMetadata: TaskMetadata) => { - complete = true; - endTaskId = taskMetadata.taskId; - }); - await syncB.trySync(); - // eslint-disable-next-line no-unmodified-loop-condition - while (!complete) { - // eslint-disable-next-line no-await-in-loop - await sleep(1000); - } + expect(result!.action).toBe('fast-forward merge'); - expect(result!.action).toBe('fast-forward merge'); + expect(result!.commits).toMatchObject({ + local: getCommitInfo([putResult1]), + }); - expect(result!.commits).toMatchObject({ - local: getCommitInfo([putResult1]), - }); - - expect(result!.changes.local).toEqual([getChangedFileInsert(jsonA1, putResult1)]); - - expect(changeTaskId).toBe(endTaskId); + expect(result!.changes.local).toEqual([getChangedFileInsert(jsonA1, putResult1)]); - await destroyDBs([dbA, dbB]); - }); + expect(changeTaskId).toBe(endTaskId); - it('with remoteURL throws UndefinedSyncError', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbNameA = serialId(); - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, + await destroyDBs([dbA, dbB]); }); - await dbA.open(); - const colA = dbA.collection('col'); - expect(() => { - colA.onSyncEvent('https://test.example.com', 'change', () => {}); - }).toThrowError(Err.UndefinedSyncError); - }); - it('with sync', async () => { - const [dbA, dbB, syncA, syncB] = await createClonedDatabases( - remoteURLBase, - localDir, - serialId - ); - - const colA = dbA.collection('col'); - const colB = dbB.collection('col'); - - // A puts and pushes - const jsonA1 = { _id: '1', name: 'fromA' }; - const putResult1 = await colA.put(jsonA1); - await syncA.tryPush(); - - // B syncs - let result: SyncResultFastForwardMerge | undefined; - let changeTaskId = ''; - - colB.onSyncEvent( - syncB, - 'change', - (syncResult: SyncResult, taskMetadata: TaskMetadata) => { - result = syncResult as SyncResultFastForwardMerge; - changeTaskId = taskMetadata.taskId; - } - ); - let complete = false; - let endTaskId = ''; - colB.onSyncEvent(syncB, 'complete', (taskMetadata: TaskMetadata) => { - complete = true; - endTaskId = taskMetadata.taskId; + it('with remoteURL throws UndefinedSyncError', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + await dbA.open(); + const colA = dbA.collection('col'); + expect(() => { + colA.onSyncEvent('https://test.example.com', 'change', () => {}); + }).toThrowError(Err.UndefinedSyncError); }); - await syncB.trySync(); - // eslint-disable-next-line no-unmodified-loop-condition - while (!complete) { - // eslint-disable-next-line no-await-in-loop - await sleep(1000); - } - - expect(result!.action).toBe('fast-forward merge'); + it('with sync', async () => { + const [dbA, dbB, syncA, syncB] = await createClonedDatabases( + remoteURLBase, + localDir, + serialId, + { + connection, + } + ); + + const colA = dbA.collection('col'); + const colB = dbB.collection('col'); + + // A puts and pushes + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResult1 = await colA.put(jsonA1); + await syncA.tryPush(); + + // B syncs + let result: SyncResultFastForwardMerge | undefined; + let changeTaskId = ''; + + colB.onSyncEvent( + syncB, + 'change', + (syncResult: SyncResult, taskMetadata: TaskMetadata) => { + result = syncResult as SyncResultFastForwardMerge; + changeTaskId = taskMetadata.taskId; + } + ); + let complete = false; + let endTaskId = ''; + colB.onSyncEvent(syncB, 'complete', (taskMetadata: TaskMetadata) => { + complete = true; + endTaskId = taskMetadata.taskId; + }); + await syncB.trySync(); + + // eslint-disable-next-line no-unmodified-loop-condition + while (!complete) { + // eslint-disable-next-line no-await-in-loop + await sleep(1000); + } - expect(result!.commits).toMatchObject({ - local: getCommitInfo([putResult1]), - }); + expect(result!.action).toBe('fast-forward merge'); - expect(result!.changes.local).toEqual([getChangedFileInsert(jsonA1, putResult1)]); + expect(result!.commits).toMatchObject({ + local: getCommitInfo([putResult1]), + }); - expect(changeTaskId).toBe(endTaskId); + expect(result!.changes.local).toEqual([getChangedFileInsert(jsonA1, putResult1)]); - await destroyDBs([dbA, dbB]); - }); - }); + expect(changeTaskId).toBe(endTaskId); - describe('offSyncEvent', () => { - it('with remoteURL', async () => { - const [dbA, dbB, syncA, syncB] = await createClonedDatabases( - remoteURLBase, - localDir, - serialId - ); - - const colB = dbB.collection('col'); - const callback = (syncResult: SyncResult, taskMetadata: TaskMetadata) => {}; - colB.onSyncEvent(syncB.remoteURL, 'change', callback); - expect(syncB.eventHandlers.change.length).toBe(1); - colB.offSyncEvent(syncB.remoteURL, 'change', callback); - expect(syncB.eventHandlers.change.length).toBe(0); - - await destroyDBs([dbA, dbB]); + await destroyDBs([dbA, dbB]); + }); }); - it('with remoteURL throws UndefinedSyncError', async () => { - const dbNameA = serialId(); - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, + describe('offSyncEvent', () => { + it('with remoteURL', async () => { + const [dbA, dbB, syncA, syncB] = await createClonedDatabases( + remoteURLBase, + localDir, + serialId, + { + connection, + } + ); + + const colB = dbB.collection('col'); + const callback = (syncResult: SyncResult, taskMetadata: TaskMetadata) => {}; + colB.onSyncEvent(syncB.remoteURL, 'change', callback); + expect(syncB.eventHandlers.change.length).toBe(1); + colB.offSyncEvent(syncB.remoteURL, 'change', callback); + expect(syncB.eventHandlers.change.length).toBe(0); + + await destroyDBs([dbA, dbB]); }); - await dbA.open(); - const colA = dbA.collection('col'); + it('with remoteURL throws UndefinedSyncError', async () => { + const dbNameA = serialId(); + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + await dbA.open(); - expect(() => { - colA.offSyncEvent('https://test.example.com', 'change', () => {}); - }).toThrowError(Err.UndefinedSyncError); - }); - - it('with sync', async () => { - const [dbA, dbB, syncA, syncB] = await createClonedDatabases( - remoteURLBase, - localDir, - serialId - ); - - const colB = dbB.collection('col'); + const colA = dbA.collection('col'); - const callback = (syncResult: SyncResult, taskMetadata: TaskMetadata) => {}; - colB.onSyncEvent(syncB, 'change', callback); - expect(syncB.eventHandlers.change.length).toBe(1); - colB.offSyncEvent(syncB, 'change', callback); - expect(syncB.eventHandlers.change.length).toBe(0); + expect(() => { + colA.offSyncEvent('https://test.example.com', 'change', () => {}); + }).toThrowError(Err.UndefinedSyncError); + }); - await destroyDBs([dbA, dbB]); + it('with sync', async () => { + const [dbA, dbB, syncA, syncB] = await createClonedDatabases( + remoteURLBase, + localDir, + serialId, + { + connection, + } + ); + + const colB = dbB.collection('col'); + + const callback = (syncResult: SyncResult, taskMetadata: TaskMetadata) => {}; + colB.onSyncEvent(syncB, 'change', callback); + expect(syncB.eventHandlers.change.length).toBe(1); + colB.offSyncEvent(syncB, 'change', callback); + expect(syncB.eventHandlers.change.length).toBe(0); + + await destroyDBs([dbA, dbB]); + }); }); }); -}); +}; diff --git a/test/remote_nodegit/on_sync_event.test.ts b/test/remote_nodegit/on_sync_event.test.ts new file mode 100644 index 00000000..e4083ee6 --- /dev/null +++ b/test/remote_nodegit/on_sync_event.test.ts @@ -0,0 +1,61 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +/** + * Test trySync + * by using GitHub Personal Access Token + * These tests create a new repository on GitHub if not exists. + */ +import path from 'path'; +import fs from 'fs-extra'; +import { onSyncEventBase } from '../remote_base/on_sync_event'; +import { ConnectionSettingsGitHub } from '../../src/types'; +import { GitDocumentDB } from '../../src/git_documentdb'; + +const reposPrefix = 'test_on_sync_event_nodegit__'; +const localDir = `./test/database_on_sync_event_nodegit`; + +beforeEach(function () { + // @ts-ignore + console.log(`... ${this.currentTest.fullTitle()}`); +}); + +before(() => { + // eslint-disable-next-line @typescript-eslint/no-var-requires + GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + + fs.removeSync(path.resolve(localDir)); +}); + +after(() => { + fs.removeSync(path.resolve(localDir)); +}); + +// This test needs environment variables: +// - GITDDB_GITHUB_USER_URL: URL of your GitHub account +// e.g.) https://github.com/foo/ +// - GITDDB_PERSONAL_ACCESS_TOKEN: A personal access token of your GitHub account +const maybe = + process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN + ? describe + : describe.skip; + +const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') + ? process.env.GITDDB_GITHUB_USER_URL + : process.env.GITDDB_GITHUB_USER_URL + '/'; + +const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; + +const connection: ConnectionSettingsGitHub = { + type: 'github', + personalAccessToken: token, + engine: 'nodegit', +}; + +maybe('NodeGit', onSyncEventBase(connection, remoteURLBase, reposPrefix, localDir)); diff --git a/tsconfig.eslint.json b/tsconfig.eslint.json index a13bec62..6f757a15 100644 --- a/tsconfig.eslint.json +++ b/tsconfig.eslint.json @@ -3,7 +3,6 @@ "include": [ "src/**/*", "test/**/*", - "test_intg/**/*", "webpack.*" ], } \ No newline at end of file From 147d70de72f97717d1bebee1a743c0364b2d9869 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sun, 1 Aug 2021 00:58:08 +0900 Subject: [PATCH 114/297] fix: add plugin for isomorphic-git --- src/plugin/remote-isomorphic-git.ts | 520 ++++++++++++++++++++++++++++ 1 file changed, 520 insertions(+) create mode 100644 src/plugin/remote-isomorphic-git.ts diff --git a/src/plugin/remote-isomorphic-git.ts b/src/plugin/remote-isomorphic-git.ts new file mode 100644 index 00000000..7432c880 --- /dev/null +++ b/src/plugin/remote-isomorphic-git.ts @@ -0,0 +1,520 @@ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +import fs from 'fs'; +import git from 'isomorphic-git'; +import { Logger } from 'tslog'; +import { + CannotConnectError, + HTTPError401AuthorizationRequired, + HTTPError403Forbidden, + HTTPError404NotFound, + InvalidGitRemoteError, + InvalidRepositoryURLError, + InvalidURLFormatError, + NetworkError, + UnfetchedCommitExistsError, +} from 'git-documentdb-remote-errors'; +import httpClient from 'isomorphic-git/http/node'; +import { ConnectionSettingsGitHub, RemoteOptions } from '../types'; +import { NETWORK_RETRY, NETWORK_RETRY_INTERVAL } from '../const'; +import { sleep } from '../utils'; + +/** + * @public + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +export const type = 'remote'; + +/** + * @public + */ +// eslint-disable-next-line @typescript-eslint/naming-convention +export const name = 'isomorphic-git'; + +/** + * Insert credential options for GitHub + * + * @throws {@link InvalidURLFormatError} + * @throws {@link InvalidRepositoryURLError} + * + * @internal + */ +function createCredentialForGitHub (options: RemoteOptions) { + if (!options.remoteUrl!.match(/^https?:\/\//)) { + throw new InvalidURLFormatError('http protocol required in createCredentialForGitHub'); + } + const connection = options.connection as ConnectionSettingsGitHub; + if (!connection.personalAccessToken) { + return undefined; + } + const urlArray = options.remoteUrl!.replace(/^https?:\/\//, '').split('/'); + // github.com/account_name/repository_name + if (urlArray.length !== 3) { + throw new InvalidRepositoryURLError(options.remoteUrl!); + } + + const credentials = + connection.personalAccessToken !== undefined + ? () => ({ username: connection.personalAccessToken }) + : undefined; + + return credentials; +} + +/** + * Create credential options + * + * @throws {@link InvalidAuthenticationTypeError} + * + * @throws # Error from createCredentialForGitHub + * @throws - {@link InvalidURLFormatError} + * @throws - {@link InvalidRepositoryURLError} + * + * @internal + */ +export function createCredentialCallback (options: RemoteOptions) { + options.connection ??= { type: 'none' }; + if (options.connection.type === 'github') { + return createCredentialForGitHub(options); + } + else if (options.connection.type === 'none') { + return undefined; + } + // @ts-ignore + throw new InvalidAuthenticationTypeError(options.connection.type); +} + +/** + * Clone + * + * @throws {@link InvalidURLFormatError} + * @throws {@link NetworkError} + * @throws {@link HTTPError401AuthorizationRequired} + * @throws {@link HTTPError404NotFound} + * @throws {@link CannotConnectError} + * + * @throws # Errors from createCredentialForGitHub + * @throws {@link HttpProtocolRequiredError} + * @throws {@link InvalidRepositoryURLError} + * + * @throws # Errors from createCredential + * @throws {@link InvalidAuthenticationTypeError} + * + * @internal + */ +// eslint-disable-next-line complexity +export async function clone ( + workingDir: string, + remoteOptions: RemoteOptions, + remoteName?: string, + logger?: Logger +): Promise { + logger ??= new Logger({ + name: 'plugin-nodegit', + minLevel: 'trace', + displayDateTime: false, + displayFunctionName: false, + displayFilePath: 'hidden', + }); + logger.debug(`remote-isomorphic-git: clone: ${remoteOptions.remoteUrl}`); + + remoteName ??= 'origin'; + + remoteOptions.retry ??= NETWORK_RETRY; + remoteOptions.retryInterval ??= NETWORK_RETRY_INTERVAL; + + const cloneOption: any = { + fs, + dir: workingDir, + http: httpClient, + url: remoteOptions.remoteUrl!, + }; + const cred = createCredentialCallback(remoteOptions); + if (cred) { + cloneOption.onAuth = cred; + } + for (let i = 0; i < remoteOptions.retry! + 1; i++) { + // eslint-disable-next-line no-await-in-loop + const res = await git.clone(cloneOption).catch(err => err); + + let error = ''; + if (res instanceof Error) { + error = res.message; + } + else { + break; + } + + // if (error !== 'undefined') console.warn('connect fetch error: ' + error); + switch (true) { + case error.startsWith('UrlParseError:'): + case error.startsWith('Error: getaddrinfo ENOTFOUND'): + throw new InvalidURLFormatError(error); + + case error.startsWith('Error: connect EACCES'): + // isomorphic-git throws this when network is limited. + if (i >= remoteOptions.retry!) { + throw new NetworkError(error); + } + break; + + case error.startsWith('HttpError: HTTP Error: 401 Authorization Required'): + throw new HTTPError401AuthorizationRequired(error); + + case error.startsWith('HttpError: HTTP Error: 404 Not Found'): + throw new HTTPError404NotFound(error); + + default: + if (i >= remoteOptions.retry!) { + throw new CannotConnectError(error); + } + } + // eslint-disable-next-line no-await-in-loop + await sleep(remoteOptions.retryInterval!); + } + + // Rewrite remote + + // default is 'origin' + if (remoteName !== 'origin') { + // Add remote + await git.setConfig({ + fs, + dir: workingDir, + path: `remote.${remoteName}.url`, + value: remoteOptions.remoteUrl!, + }); + await git.setConfig({ + fs, + dir: workingDir, + path: `remote.${remoteName}.fetch`, + value: `+refs/heads/*:refs/remotes/${remoteName}/*`, + }); + } +} + +/** + * Check connection by FETCH + * + * @throws {@link InvalidGitRemoteError} + * @throws {@link InvalidURLFormatError} + * @throws {@link NetworkError} + * @throws {@link HTTPError401AuthorizationRequired} + * @throws {@link HTTPError404NotFound} + * @throws {@link CannotConnectError} + * + * @throws # Errors from createCredentialForGitHub + * @throws {@link HttpProtocolRequiredError} + * @throws {@link InvalidRepositoryURLError} + * + * @throws # Errors from createCredential + * @throws {@link InvalidAuthenticationTypeError} + * + * @internal + */ +// eslint-disable-next-line complexity +export async function checkFetch ( + workingDir: string, + remoteOptions: RemoteOptions, + remoteName?: string, + logger?: Logger +): Promise { + logger ??= new Logger({ + name: 'plugin-nodegit', + minLevel: 'trace', + displayDateTime: false, + displayFunctionName: false, + displayFilePath: 'hidden', + }); + remoteName ??= 'origin'; + + const urlOfRemote = await git.getConfig({ + fs, + dir: workingDir, + path: `remote.${remoteName}.url`, + }); + if (urlOfRemote === undefined) { + throw new InvalidGitRemoteError(`remote '${remoteName}' does not exist`); + } + + remoteOptions.retry ??= NETWORK_RETRY; + remoteOptions.retryInterval ??= NETWORK_RETRY_INTERVAL; + + const checkOption: any = { + http: httpClient, + url: remoteOptions.remoteUrl!, + }; + const cred = createCredentialCallback(remoteOptions); + if (cred) { + checkOption.onAuth = cred; + } + + for (let i = 0; i < remoteOptions.retry! + 1; i++) { + const res = git.getRemoteInfo2(checkOption).catch(err => err); + + let error = ''; + if (res instanceof Error) { + error = res.message; + } + else { + break; + } + + // if (error !== 'undefined') console.warn('connect fetch error: ' + error); + switch (true) { + case error.startsWith('UrlParseError:'): + case error.startsWith('Error: getaddrinfo ENOTFOUND'): + throw new InvalidURLFormatError(error); + + case error.startsWith('Error: connect EACCES'): + // isomorphic-git throws this when network is limited. + if (i >= remoteOptions.retry!) { + throw new NetworkError(error); + } + break; + + case error.startsWith('HttpError: HTTP Error: 401 Authorization Required'): + throw new HTTPError401AuthorizationRequired(error); + + case error.startsWith('HttpError: HTTP Error: 404 Not Found'): + throw new HTTPError404NotFound(error); + + default: + if (i >= remoteOptions.retry!) { + throw new CannotConnectError(error); + } + } + // eslint-disable-next-line no-await-in-loop + await sleep(remoteOptions.retryInterval!); + } + + return true; +} + +/** + * git fetch + * + * @throws {@link InvalidGitRemoteError} + * @throws {@link InvalidURLFormatError} + * @throws {@link NetworkError} + * @throws {@link HTTPError401AuthorizationRequired} + * @throws {@link HTTPError404NotFound} + * @throws {@link CannotConnectError} + * + * @throws # Errors from createCredentialForGitHub + * @throws {@link HttpProtocolRequiredError} + * @throws {@link InvalidRepositoryURLError} + * + * @throws # Errors from createCredential + * @throws {@link InvalidAuthenticationTypeError} + * + * @internal + */ +// eslint-disable-next-line complexity +export async function fetch ( + workingDir: string, + remoteOptions: RemoteOptions, + remoteName?: string, + logger?: Logger +): Promise { + logger ??= new Logger({ + name: 'plugin-nodegit', + minLevel: 'trace', + displayDateTime: false, + displayFunctionName: false, + displayFilePath: 'hidden', + }); + logger.debug(`remote-isomorphic-git: fetch: ${remoteOptions.remoteUrl}`); + + remoteName ??= 'origin'; + + const urlOfRemote = await git.getConfig({ + fs, + dir: workingDir, + path: `remote.${remoteName}.url`, + }); + if (urlOfRemote === undefined) { + throw new InvalidGitRemoteError(`remote '${remoteName}' does not exist`); + } + + remoteOptions.retry ??= NETWORK_RETRY; + remoteOptions.retryInterval ??= NETWORK_RETRY_INTERVAL; + + const fetchOption: any = { + http: httpClient, + url: remoteOptions.remoteUrl!, + }; + const cred = createCredentialCallback(remoteOptions); + if (cred) { + fetchOption.onAuth = cred; + } + + for (let i = 0; i < remoteOptions.retry! + 1; i++) { + // eslint-disable-next-line no-await-in-loop + const res = git.getRemoteInfo2(fetchOption).catch(err => err); + + let error = ''; + if (res instanceof Error) { + error = res.message; + } + else { + break; + } + + // if (error !== 'undefined') console.warn('connect fetch error: ' + error); + switch (true) { + case error.startsWith('NoRefspecError'): + throw new InvalidGitRemoteError(error); + + case error.startsWith('UrlParseError:'): + case error.startsWith('Error: getaddrinfo ENOTFOUND'): + throw new InvalidURLFormatError(error); + + case error.startsWith('Error: connect EACCES'): + // isomorphic-git throws this when network is limited. + if (i >= remoteOptions.retry!) { + throw new NetworkError(error); + } + break; + + case error.startsWith('HttpError: HTTP Error: 401 Authorization Required'): + throw new HTTPError401AuthorizationRequired(error); + + case error.startsWith('HttpError: HTTP Error: 404 Not Found'): + throw new HTTPError404NotFound(error); + + default: + if (i >= remoteOptions.retry!) { + throw new CannotConnectError(error); + } + } + // eslint-disable-next-line no-await-in-loop + await sleep(remoteOptions.retryInterval!); + } +} + +/** + * git push + * + * @throws {@link InvalidGitRemoteError} + * @throws {@link UnfetchedCommitExistsError} + * @throws {@link InvalidURLFormatError} + * @throws {@link NetworkError} + * @throws {@link HTTPError401AuthorizationRequired} + * @throws {@link HTTPError404NotFound} + * @throws {@link HTTPError403Forbidden} + * @throws {@link CannotConnectError} + * + * @throws # Errors from createCredentialForGitHub + * @throws - {@link InvalidURLFormatError} + * @throws - {@link InvalidRepositoryURLError} + * + * @throws # Errors from createCredential + * @throws - {@link InvalidAuthenticationTypeError} + * + * @internal + */ +// eslint-disable-next-line complexity +export async function push ( + workingDir: string, + remoteOptions: RemoteOptions, + remoteName?: string, + localBranchName?: string, + remoteBranchName?: string, + logger?: Logger +): Promise { + logger ??= new Logger({ + name: 'plugin-nodegit', + minLevel: 'trace', + displayDateTime: false, + displayFunctionName: false, + displayFilePath: 'hidden', + }); + logger.debug(`remote-isomorphic-git: push: ${remoteOptions.remoteUrl}`); + + remoteName ??= 'origin'; + localBranchName ??= 'main'; + remoteBranchName ??= 'main'; + + const urlOfRemote = await git.getConfig({ + fs, + dir: workingDir, + path: `remote.${remoteName}.url`, + }); + if (urlOfRemote === undefined) { + throw new InvalidGitRemoteError(`remote '${remoteName}' does not exist`); + } + + const localBranch = 'refs/heads/' + localBranchName; + const remoteBranch = 'refs/heads/' + remoteBranchName; + + remoteOptions.retry ??= NETWORK_RETRY; + remoteOptions.retryInterval ??= NETWORK_RETRY_INTERVAL; + + const pushOption: any = { + http: httpClient, + url: remoteOptions.remoteUrl!, + ref: localBranch, + remoteRef: remoteBranch, + }; + const cred = createCredentialCallback(remoteOptions); + if (cred) { + pushOption.onAuth = cred; + } + + for (let i = 0; i < remoteOptions.retry! + 1; i++) { + // eslint-disable-next-line no-await-in-loop + const res = await git.push(pushOption).catch(err => err); + + let error = ''; + if (res instanceof Error) { + error = res.message; + } + else { + break; + } + + // console.warn('connect push error: ' + error); + switch (true) { + // NoRefspecError does not invoke because push does not need Remote when url is specified. + // case error.startsWith('NoRefspecError'): + // throw new InvalidGitRemoteError(error); + + case error.startsWith('PushRejectedError:'): + throw new UnfetchedCommitExistsError(); + + case error.startsWith('UrlParseError:'): + case error.startsWith('Error: getaddrinfo ENOTFOUND'): + throw new InvalidURLFormatError(error); + + case error.startsWith('Error: connect EACCES'): + // isomorphic-git throws this when network is limited. + if (i >= remoteOptions.retry!) { + throw new NetworkError(error); + } + break; + + case error.startsWith('HttpError: HTTP Error: 401 Authorization Required'): + throw new HTTPError401AuthorizationRequired(error); + + case error.startsWith('HttpError: HTTP Error: 404 Not Found'): + throw new HTTPError404NotFound(error); + + case error.startsWith('HttpError: HTTP Error: 403 Forbidden'): + throw new HTTPError403Forbidden(error); + + default: + if (i >= remoteOptions.retry!) { + throw new CannotConnectError(error); + } + } + // eslint-disable-next-line no-await-in-loop + await sleep(remoteOptions.retryInterval!); + } +} From 56e8bd6d3c637835ce2ae595ded29c1ae82b3bc3 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sun, 1 Aug 2021 22:16:11 +0900 Subject: [PATCH 115/297] fix: add tests for checkFetch in plugin/remote-isomorphic-git --- src/plugin/remote-isomorphic-git.ts | 31 +- test/plugin/checkfetch.test.ts | 442 ++++++++++++++ test/plugin/clone.test.ts | 547 +++++++++++++++++ test/plugin/fetch.test.ts | 634 ++++++++++++++++++++ test/plugin/push.test.ts | 874 ++++++++++++++++++++++++++++ test/remote_utils.ts | 19 + 6 files changed, 2534 insertions(+), 13 deletions(-) create mode 100644 test/plugin/checkfetch.test.ts create mode 100644 test/plugin/clone.test.ts create mode 100644 test/plugin/fetch.test.ts create mode 100644 test/plugin/push.test.ts diff --git a/src/plugin/remote-isomorphic-git.ts b/src/plugin/remote-isomorphic-git.ts index 7432c880..b63d955d 100644 --- a/src/plugin/remote-isomorphic-git.ts +++ b/src/plugin/remote-isomorphic-git.ts @@ -14,6 +14,7 @@ import { HTTPError401AuthorizationRequired, HTTPError403Forbidden, HTTPError404NotFound, + InvalidAuthenticationTypeError, InvalidGitRemoteError, InvalidRepositoryURLError, InvalidURLFormatError, @@ -100,11 +101,11 @@ export function createCredentialCallback (options: RemoteOptions) { * @throws {@link CannotConnectError} * * @throws # Errors from createCredentialForGitHub - * @throws {@link HttpProtocolRequiredError} - * @throws {@link InvalidRepositoryURLError} + * @throws - {@link HttpProtocolRequiredError} + * @throws - {@link InvalidRepositoryURLError} * * @throws # Errors from createCredential - * @throws {@link InvalidAuthenticationTypeError} + * @throws - {@link InvalidAuthenticationTypeError} * * @internal */ @@ -158,6 +159,7 @@ export async function clone ( throw new InvalidURLFormatError(error); case error.startsWith('Error: connect EACCES'): + case error.startsWith('Error: connect ECONNREFUSED'): // isomorphic-git throws this when network is limited. if (i >= remoteOptions.retry!) { throw new NetworkError(error); @@ -210,11 +212,11 @@ export async function clone ( * @throws {@link CannotConnectError} * * @throws # Errors from createCredentialForGitHub - * @throws {@link HttpProtocolRequiredError} - * @throws {@link InvalidRepositoryURLError} + * @throws - {@link HttpProtocolRequiredError} + * @throws - {@link InvalidRepositoryURLError} * * @throws # Errors from createCredential - * @throws {@link InvalidAuthenticationTypeError} + * @throws - {@link InvalidAuthenticationTypeError} * * @internal */ @@ -256,23 +258,24 @@ export async function checkFetch ( } for (let i = 0; i < remoteOptions.retry! + 1; i++) { - const res = git.getRemoteInfo2(checkOption).catch(err => err); + // eslint-disable-next-line no-await-in-loop + const res = await git.getRemoteInfo2(checkOption).catch(err => err); let error = ''; if (res instanceof Error) { - error = res.message; + error = res.toString(); } else { break; } - // if (error !== 'undefined') console.warn('connect fetch error: ' + error); switch (true) { case error.startsWith('UrlParseError:'): case error.startsWith('Error: getaddrinfo ENOTFOUND'): throw new InvalidURLFormatError(error); case error.startsWith('Error: connect EACCES'): + case error.startsWith('Error: connect ECONNREFUSED'): // isomorphic-git throws this when network is limited. if (i >= remoteOptions.retry!) { throw new NetworkError(error); @@ -308,11 +311,11 @@ export async function checkFetch ( * @throws {@link CannotConnectError} * * @throws # Errors from createCredentialForGitHub - * @throws {@link HttpProtocolRequiredError} - * @throws {@link InvalidRepositoryURLError} + * @throws - {@link HttpProtocolRequiredError} + * @throws - {@link InvalidRepositoryURLError} * * @throws # Errors from createCredential - * @throws {@link InvalidAuthenticationTypeError} + * @throws - {@link InvalidAuthenticationTypeError} * * @internal */ @@ -357,7 +360,7 @@ export async function fetch ( for (let i = 0; i < remoteOptions.retry! + 1; i++) { // eslint-disable-next-line no-await-in-loop - const res = git.getRemoteInfo2(fetchOption).catch(err => err); + const res = await git.fetch(fetchOption).catch(err => err); let error = ''; if (res instanceof Error) { @@ -377,6 +380,7 @@ export async function fetch ( throw new InvalidURLFormatError(error); case error.startsWith('Error: connect EACCES'): + case error.startsWith('Error: connect ECONNREFUSED'): // isomorphic-git throws this when network is limited. if (i >= remoteOptions.retry!) { throw new NetworkError(error); @@ -494,6 +498,7 @@ export async function push ( throw new InvalidURLFormatError(error); case error.startsWith('Error: connect EACCES'): + case error.startsWith('Error: connect ECONNREFUSED'): // isomorphic-git throws this when network is limited. if (i >= remoteOptions.retry!) { throw new NetworkError(error); diff --git a/test/plugin/checkfetch.test.ts b/test/plugin/checkfetch.test.ts new file mode 100644 index 00000000..1e25d10f --- /dev/null +++ b/test/plugin/checkfetch.test.ts @@ -0,0 +1,442 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +import path from 'path'; +import fs from 'fs-extra'; +import expect from 'expect'; +import git from 'isomorphic-git'; +import { + HTTPError401AuthorizationRequired, + HTTPError404NotFound, + InvalidAuthenticationTypeError, + InvalidGitRemoteError, + InvalidRepositoryURLError, + InvalidURLFormatError, + NetworkError, +} from 'git-documentdb-remote-errors'; +import sinon from 'sinon'; +import { GitDocumentDB } from '../../src/git_documentdb'; +import { checkFetch } from '../../src/plugin/remote-isomorphic-git'; +import { createGitRemote, destroyDBs, removeRemoteRepositories } from '../remote_utils'; + +const reposPrefix = 'test_remote_isomorphic_git_check_fetch___'; +const localDir = `./test/database_check_fetch`; + +let idCounter = 0; +const serialId = () => { + return `${reposPrefix}${idCounter++}`; +}; + +// Use sandbox to restore stub and spy in parallel mocha tests +let sandbox: sinon.SinonSandbox; +beforeEach(function () { + sandbox = sinon.createSandbox(); + // @ts-ignore + console.log(`... ${this.currentTest.fullTitle()}`); +}); + +afterEach(function () { + sandbox.restore(); +}); + +before(() => { + fs.removeSync(path.resolve(localDir)); +}); + +after(() => { + fs.removeSync(path.resolve(localDir)); +}); + +/** + * Prerequisites + * + * Environment variables: + * GITDDB_GITHUB_USER_URL: URL of your GitHub account + * e.g.) https://github.com/foo/ + * GITDDB_PERSONAL_ACCESS_TOKEN: The personal access token of your GitHub account + * GitHub repositories: + * remoteURLBase + 'test-private.git' must be a private repository. + */ +const userHome = process.env[process.platform === 'win32' ? 'USERPROFILE' : 'HOME'] ?? ''; + +const maybe = + process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN + ? describe + : describe.skip; + +maybe(' checkFetch', () => { + const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') + ? process.env.GITDDB_GITHUB_USER_URL + : process.env.GITDDB_GITHUB_USER_URL + '/'; + const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; + + before(async () => { + // Remove remote + await removeRemoteRepositories(reposPrefix); + }); + + describe('returns true', () => { + it('when connect to public repository with no personal access token', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = remoteURLBase + 'test-public.git'; + await createGitRemote(dbA.workingDir, remoteUrl); + const res = await checkFetch(dbA.workingDir, { + remoteUrl, + connection: { type: 'github' }, + }).catch(error => error); + expect(res).not.toBeInstanceOf(Error); + + await destroyDBs([dbA]); + }); + + it('when connect to public repository with valid personal access token', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = remoteURLBase + 'test-public.git'; + await createGitRemote(dbA.workingDir, remoteUrl); + const res = await checkFetch(dbA.workingDir, { + remoteUrl, + connection: { type: 'github', personalAccessToken: token }, + }).catch(error => error); + expect(res).not.toBeInstanceOf(Error); + + await destroyDBs([dbA]); + }); + + it('when connect to private repository with valid personal access token', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = remoteURLBase + 'test-private.git'; + await createGitRemote(dbA.workingDir, remoteUrl); + const res = await checkFetch(dbA.workingDir, { + remoteUrl, + connection: { type: 'github', personalAccessToken: token }, + }).catch(error => error); + expect(res).not.toBeInstanceOf(Error); + + await destroyDBs([dbA]); + }); + + it('after retries', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = remoteURLBase + 'test-private.git'; + await createGitRemote(dbA.workingDir, remoteUrl); + + const stubRemote = sandbox.stub(git, 'getRemoteInfo2'); + stubRemote.onCall(0).rejects(new Error('connect EACCES')); + stubRemote.onCall(1).rejects(new Error('connect EACCES')); + stubRemote.onCall(2).rejects(new Error('connect EACCES')); + stubRemote.onCall(3).resolves(undefined); + + const res = await checkFetch(dbA.workingDir, { + remoteUrl, + connection: { type: 'github', personalAccessToken: token }, + }).catch(error => error); + expect(res).not.toBeInstanceOf(Error); + + expect(stubRemote.callCount).toBe(4); + + await destroyDBs([dbA]); + }); + }); + + it('throws NetworkError after retries', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = remoteURLBase + 'test-private.git'; + await createGitRemote(dbA.workingDir, remoteUrl); + + const stubRemote = sandbox.stub(git, 'getRemoteInfo2'); + stubRemote.rejects(new Error('connect EACCES')); + + const res = await checkFetch(dbA.workingDir, { + remoteUrl, + connection: { type: 'github', personalAccessToken: token }, + }).catch(error => error); + expect(res).toBeInstanceOf(NetworkError); + + expect(stubRemote.callCount).toBe(4); + + await destroyDBs([dbA]); + }); + + it('throws InvalidGitRemoteError', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + const remoteUrl = 'foo-bar'; + + const err = await checkFetch(dbA.workingDir, { remoteUrl }).catch(error => error); + expect(err).toBeInstanceOf(InvalidGitRemoteError); + + await destroyDBs([dbA]); + }); + + it('throws InvalidURLFormat by checkFetch when http protocol is missing', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + const remoteUrl = 'foo-bar'; + await createGitRemote(dbA.workingDir, remoteUrl); + const err = await checkFetch(dbA.workingDir, { remoteUrl }).catch(error => error); + + expect(err).toBeInstanceOf(InvalidURLFormatError); + expect(err.message).toMatch(/^URL format is invalid: UrlParseError:/); + + await destroyDBs([dbA]); + }); + + it('throws InvalidURLFormatError by checkFetch when URL is malformed', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + const remoteUrl = 'https://foo.example.com:xxxx'; + await createGitRemote(dbA.workingDir, remoteUrl); + const err = await checkFetch(dbA.workingDir, { remoteUrl }).catch(error => error); + expect(err).toBeInstanceOf(InvalidURLFormatError); + expect(err.message).toMatch(/^URL format is invalid: Error: getaddrinfo ENOTFOUND/); + + await destroyDBs([dbA]); + }); + + it('throws InvalidURLFormatError by checkFetch when HTTP host is invalid', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = 'https://foo.bar.example.com/gitddb-plugin/sync-test-invalid.git'; + await createGitRemote(dbA.workingDir, remoteUrl); + const err = await checkFetch(dbA.workingDir, { remoteUrl }).catch(error => error); + expect(err).toBeInstanceOf(InvalidURLFormatError); + expect(err.message).toMatch(/^URL format is invalid: Error: getaddrinfo ENOTFOUND/); + + await destroyDBs([dbA]); + }); + + describe('throws NetworkError', () => { + it('when IP address is invalid', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = 'https://127.0.0.1/gitddb-plugin/sync-test-invalid.git'; + await createGitRemote(dbA.workingDir, remoteUrl); + const err = await checkFetch(dbA.workingDir, { + remoteUrl, + connection: { + type: 'github', + }, + }).catch(error => error); + expect(err).toBeInstanceOf(NetworkError); + expect(err.message).toMatch(/^Network error: Error: connect ECONNREFUSED/); + + await destroyDBs([dbA]); + }); + }); + + describe('throws HttpError401AuthorizationRequired', () => { + it('when personal access token does not exist', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = remoteURLBase + 'test-private.git'; + await createGitRemote(dbA.workingDir, remoteUrl); + const err = await checkFetch(dbA.workingDir, { + remoteUrl, + connection: { type: 'github' }, + }).catch(error => error); + + expect(err).toBeInstanceOf(HTTPError401AuthorizationRequired); + expect(err.message).toMatch(/^HTTP Error: 401 Authorization required/); + + await destroyDBs([dbA]); + }); + + it('when connection setting not found', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = remoteURLBase + 'test-private.git'; + + // eslint-disable-next-line no-await-in-loop + await createGitRemote(dbA.workingDir, remoteUrl); + // eslint-disable-next-line no-await-in-loop + const err = await checkFetch(dbA.workingDir, { remoteUrl }).catch(error => error); + + expect(err).toBeInstanceOf(HTTPError401AuthorizationRequired); + expect(err.message).toMatch(/^HTTP Error: 401 Authorization required/); + + await destroyDBs([dbA]); + }); + + it('when invalid personal access token', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = remoteURLBase + 'test-private.git'; + await createGitRemote(dbA.workingDir, remoteUrl); + const err = await checkFetch(dbA.workingDir, { + remoteUrl, + connection: { type: 'github', personalAccessToken: 'foo-bar' }, + }).catch(error => error); + + expect(err).toBeInstanceOf(HTTPError401AuthorizationRequired); + expect(err.message).toMatch(/^HTTP Error: 401 Authorization required/); + + await destroyDBs([dbA]); + }); + }); + + describe('throws HttpError404NotFound', () => { + it('when valid auth and repository does not exist', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = remoteURLBase + 'sync-test-invalid.git'; + await createGitRemote(dbA.workingDir, remoteUrl); + const err = await checkFetch(dbA.workingDir, { + remoteUrl, + connection: { type: 'github', personalAccessToken: token }, + }).catch(error => error); + expect(err).toBeInstanceOf(HTTPError404NotFound); + expect(err.message).toMatch(/^HTTP Error: 404 Not Found/); + + await destroyDBs([dbA]); + }); + }); + + it('throws InvalidURLFormatError by createCredentialForGitHub', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + const remoteUrl = 'foo-bar'; + await createGitRemote(dbA.workingDir, remoteUrl); + const err = await checkFetch(dbA.workingDir, { + remoteUrl, + connection: { type: 'github', personalAccessToken: token }, + }).catch(error => error); + expect(err).toBeInstanceOf(InvalidURLFormatError); + expect(err.message).toMatch( + /^URL format is invalid: http protocol required in createCredentialForGitHub/ + ); + + await destroyDBs([dbA]); + }); + + it('throws InvalidRepositoryURLError', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = remoteURLBase + 'foo/bar/test.git'; + await createGitRemote(dbA.workingDir, remoteUrl); + await expect( + checkFetch(dbA.workingDir, { + remoteUrl, + connection: { type: 'github', personalAccessToken: token }, + }) + ).rejects.toThrowError(InvalidRepositoryURLError); + + await destroyDBs([dbA]); + }); + + it('throws InvalidAuthenticationTypeError', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = remoteURLBase + 'test-private.git'; + await createGitRemote(dbA.workingDir, remoteUrl); + await expect( + // @ts-ignore + checkFetch(dbA.workingDir, { remoteUrl, connection: { type: 'foo' } }) + ).rejects.toThrowError(InvalidAuthenticationTypeError); + + await destroyDBs([dbA]); + }); + + it('throws InvalidAuthenticationTypeError with SSH', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = 'git@foo.example.com:bar/sync-test.git'; + await createGitRemote(dbA.workingDir, remoteUrl); + await expect( + checkFetch(dbA.workingDir, { + remoteUrl, + connection: { + type: 'ssh', + publicKeyPath: path.resolve(userHome, '.ssh/invalid-test.pub'), + privateKeyPath: path.resolve(userHome, '.ssh/invalid-test'), + passPhrase: '', + }, + }) + ).rejects.toThrowError(InvalidAuthenticationTypeError); + + await destroyDBs([dbA]); + }); + + describe('throws CannotConnectError', () => { + // NetworkError is thrown when network is not connected. + // CannotConnectError will be thrown when other unexpected cases. + }); +}); diff --git a/test/plugin/clone.test.ts b/test/plugin/clone.test.ts new file mode 100644 index 00000000..13797dad --- /dev/null +++ b/test/plugin/clone.test.ts @@ -0,0 +1,547 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +import path from 'path'; +import fs from 'fs-extra'; +import expect from 'expect'; +import { + HTTPError401AuthorizationRequired, + HTTPError404NotFound, + InvalidAuthenticationTypeError, + InvalidRepositoryURLError, + InvalidSSHKeyPathError, + InvalidURLFormatError, + NetworkError, +} from 'git-documentdb-remote-errors'; +import git from 'isomorphic-git'; +import sinon from 'sinon'; +import { GitDocumentDB } from '../../src/git_documentdb'; +import { clone } from '../../src/plugin/remote-isomorphic-git'; +import { destroyDBs, removeRemoteRepositories } from '../remote_utils'; + +const reposPrefix = 'test_remote_isomorphic_git_clone___'; +const localDir = `./test/database_clone`; + +let idCounter = 0; +const serialId = () => { + return `${reposPrefix}${idCounter++}`; +}; + +// Use sandbox to restore stub and spy in parallel mocha tests +let sandbox: sinon.SinonSandbox; +beforeEach(function () { + sandbox = sinon.createSandbox(); + // @ts-ignore + console.log(`... ${this.currentTest.fullTitle()}`); +}); + +afterEach(function () { + sandbox.restore(); +}); + +before(() => { + fs.removeSync(path.resolve(localDir)); +}); + +after(() => { + fs.removeSync(path.resolve(localDir)); +}); + +/** + * Prerequisites + * + * Environment variables: + * GITDDB_GITHUB_USER_URL: URL of your GitHub account + * e.g.) https://github.com/foo/ + * GITDDB_PERSONAL_ACCESS_TOKEN: The personal access token of your GitHub account + * GitHub repositories: + * remoteURLBase + 'test-private.git' must be a private repository. + */ +const userHome = process.env[process.platform === 'win32' ? 'USERPROFILE' : 'HOME'] ?? ''; + +const maybe = + process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN + ? describe + : describe.skip; + +maybe(' clone', () => { + const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') + ? process.env.GITDDB_GITHUB_USER_URL + : process.env.GITDDB_GITHUB_USER_URL + '/'; + const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; + + before(async () => { + // Remove remote + await removeRemoteRepositories(reposPrefix); + }); + + describe('succeeds', () => { + it('when connect to public repository with no personal access token', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + const remoteUrl = remoteURLBase + 'test-public.git'; + fs.ensureDirSync(dbA.workingDir); + const res = await clone(dbA.workingDir, { + remoteUrl, + connection: { type: 'github' }, + }).catch(error => error); + expect(res).toBeUndefined(); + + await destroyDBs([dbA]); + }); + + it('when connect to public repository with valid personal access token', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + const remoteUrl = remoteURLBase + 'test-public.git'; + fs.ensureDirSync(dbA.workingDir); + const res = await clone(dbA.workingDir, { + remoteUrl, + connection: { type: 'github', personalAccessToken: token }, + }).catch(error => error); + expect(res).toBeUndefined(); + + await destroyDBs([dbA]); + }); + + it('when connect to private repository with valid personal access token', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + const remoteUrl = remoteURLBase + 'test-private.git'; + fs.ensureDirSync(dbA.workingDir); + const res = await clone(dbA.workingDir, { + remoteUrl, + connection: { type: 'github', personalAccessToken: token }, + }).catch(error => error); + expect(res).toBeUndefined(); + + await destroyDBs([dbA]); + }); + + it('set another remote name', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + const remoteUrl = remoteURLBase + 'test-public.git'; + fs.ensureDirSync(dbA.workingDir); + const res = await clone( + dbA.workingDir, + { + remoteUrl, + connection: { type: 'github' }, + }, + 'another' + ).catch(error => error); + expect(res).toBeUndefined(); + + const url = await git.getConfig({ + fs, + dir: dbA.workingDir, + path: 'remote.another.url', + }); + expect(url).toBe(remoteUrl); + + const fetch = await git.getConfig({ + fs, + dir: dbA.workingDir, + path: 'remote.another.fetch', + }); + expect(fetch).toBe(`+refs/heads/*:refs/remotes/another/*`); + + await destroyDBs([dbA]); + }); + + it('after retries', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + const remoteUrl = remoteURLBase + 'test-public.git'; + fs.ensureDirSync(dbA.workingDir); + + const cloneStub = sandbox.stub(nodegit.Clone, 'clone'); + cloneStub.onCall(0).rejects(new Error('failed to send request')); + cloneStub.onCall(1).rejects(new Error('failed to send request')); + cloneStub.onCall(2).rejects(new Error('failed to send request')); + cloneStub.onCall(3).resolves(undefined); + + const res = await clone(dbA.workingDir, { + remoteUrl, + connection: { type: 'github' }, + }).catch(error => error); + expect(res).toBeUndefined(); + + expect(cloneStub.callCount).toBe(4); + + await destroyDBs([dbA]); + }); + }); + + it('throws NetworkError after retries', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + const remoteUrl = remoteURLBase + 'test-public.git'; + fs.ensureDirSync(dbA.workingDir); + + const cloneStub = sandbox.stub(nodegit.Clone, 'clone'); + cloneStub.rejects(new Error('failed to send request')); + + const res = await clone(dbA.workingDir, { + remoteUrl, + connection: { type: 'github' }, + }).catch(error => error); + expect(res).toBeInstanceOf(NetworkError); + + expect(cloneStub.callCount).toBe(4); + + await destroyDBs([dbA]); + }); + + it('throws InvalidURLFormat by clone when http protocol is missing', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + const remoteUrl = 'foo-bar'; + fs.ensureDirSync(dbA.workingDir); + const err = await clone(dbA.workingDir, { remoteUrl }).catch(error => error); + await dbA.open(); + + expect(err).toBeInstanceOf(InvalidURLFormatError); + expect(err.message).toMatch(/^URL format is invalid: unsupported URL protocol/); + + await destroyDBs([dbA]); + }); + + it('throws InvalidURLFormatError by clone when URL is malformed', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + const remoteUrl = 'https://foo.example.com:xxxx'; + fs.ensureDirSync(dbA.workingDir); + const err = await clone(dbA.workingDir, { remoteUrl }).catch(error => error); + expect(err).toBeInstanceOf(InvalidURLFormatError); + expect(err.message).toMatch(/^URL format is invalid: malformed URL/); + + await destroyDBs([dbA]); + }); + + describe('throws NetworkError', () => { + it('when HTTP host is invalid', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + const remoteUrl = 'https://foo.bar.example.com/gitddb-plugin/sync-test-invalid.git'; + fs.ensureDirSync(dbA.workingDir); + const err = await clone(dbA.workingDir, { remoteUrl }).catch(error => error); + expect(err).toBeInstanceOf(NetworkError); + expect(err.message).toMatch(/^Network error: failed to send request/); + + await destroyDBs([dbA]); + }); + + it('when IP address is invalid', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + const remoteUrl = 'https://foo.bar.example.com/gitddb-plugin/sync-test-invalid.git'; + fs.ensureDirSync(dbA.workingDir); + const err = await clone(dbA.workingDir, { remoteUrl }).catch(error => error); + expect(err).toBeInstanceOf(NetworkError); + expect(err.message).toMatch(/^Network error: failed to send request/); + + await destroyDBs([dbA]); + }); + + it('when SSH host is invalid', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + const remoteUrl = 'git@foo.example.com:bar/sync-test.git'; + fs.ensureDirSync(dbA.workingDir); + const err = await clone(dbA.workingDir, { + remoteUrl, + connection: { + type: 'ssh', + publicKeyPath: path.resolve(userHome, '.ssh/invalid-test.pub'), + privateKeyPath: path.resolve(userHome, '.ssh/invalid-test'), + passPhrase: '', + }, + }).catch(error => error); + + expect(err).toBeInstanceOf(NetworkError); + expect(err.message).toMatch(/^Network error: failed to resolve address/); + + await destroyDBs([dbA]); + }); + }); + + describe('throws HttpError401AuthorizationRequired', () => { + it('when personal access token does not exist', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + const remoteUrl = remoteURLBase + 'test-private.git'; + fs.ensureDirSync(dbA.workingDir); + const err = await clone(dbA.workingDir, { + remoteUrl, + connection: { type: 'github' }, + }).catch(error => error); + + expect(err).toBeInstanceOf(HTTPError401AuthorizationRequired); + expect(err.message).toMatch( + /^HTTP Error: 401 Authorization required: request failed with status code: 401/ + ); + + await destroyDBs([dbA]); + }); + + it('when connection setting not found', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + const remoteUrl = remoteURLBase + 'test-private.git'; + fs.ensureDirSync(dbA.workingDir); + let err; + for (let i = 0; i < 3; i++) { + // eslint-disable-next-line no-await-in-loop + err = await clone(dbA.workingDir, { remoteUrl }).catch(error => error); + if ( + !err.message.startsWith( + 'HTTP Error: 401 Authorization required: too many redirects or authentication replays' + ) + ) { + break; + } + } + expect(err).toBeInstanceOf(HTTPError401AuthorizationRequired); + if (process.platform === 'win32') { + expect(err.message).toMatch( + /^HTTP Error: 401 Authorization required: request failed with status code: 401/ + ); + } + else { + expect(err.message).toMatch( + /^HTTP Error: 401 Authorization required: unexpected HTTP status code: 401/ + ); + } + + await destroyDBs([dbA]); + }); + + it.skip('when XXXX?', async () => { + // TODO: This will invoke on ubuntu + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + const remoteUrl = remoteURLBase + 'test-private.git'; + fs.ensureDirSync(dbA.workingDir); + const err = await clone(dbA.workingDir, { remoteUrl }).catch(error => error); + expect(err).toBeInstanceOf(HTTPError401AuthorizationRequired); + expect(err.message).toMatch( + /^HTTP Error: 401 Authorization required: remote credential provider returned an invalid cred type/ + ); + + await destroyDBs([dbA]); + }); + + it.skip('when invalid SSH key format', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + // TODO: set SSH url for test + const remoteUrl = 'git@github.com:xxxxxxxxxxxxxxxxxx/sync-test.git'; + fs.ensureDirSync(dbA.workingDir); + const err = await clone(dbA.workingDir, { + remoteUrl, + connection: { + type: 'ssh', + publicKeyPath: path.resolve(userHome, '.ssh/invalid-test.pub'), + privateKeyPath: path.resolve(userHome, '.ssh/invalid-test'), + passPhrase: '', + }, + }).catch(error => error); + + expect(err).toBeInstanceOf(HTTPError401AuthorizationRequired); + // TODO: How to invoke this error + expect(err.message).toMatch( + /^HTTP Error: 401 Authorization required: Failed to retrieve list of SSH authentication methods/ + ); + + await destroyDBs([dbA]); + }); + + it('when invalid personal access token', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + const remoteUrl = remoteURLBase + 'test-private.git'; + fs.ensureDirSync(dbA.workingDir); + const err = await clone(dbA.workingDir, { + remoteUrl, + connection: { type: 'github', personalAccessToken: 'foo-bar' }, + }).catch(error => error); + + expect(err).toBeInstanceOf(HTTPError401AuthorizationRequired); + expect(err.message).toMatch( + /^HTTP Error: 401 Authorization required: too many redirects or authentication replays/ + ); + + await destroyDBs([dbA]); + }); + + it('when invalid pair of url and SSH auth', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + const remoteUrl = remoteURLBase + 'test-private.git'; + fs.ensureDirSync(dbA.workingDir); + const err = await clone(dbA.workingDir, { + remoteUrl, + connection: { + type: 'ssh', + publicKeyPath: path.resolve(userHome, '.ssh/invalid-test.pub'), + privateKeyPath: path.resolve(userHome, '.ssh/invalid-test'), + passPhrase: '', + }, + }).catch(error => error); + + expect(err).toBeInstanceOf(HTTPError401AuthorizationRequired); + expect(err.message).toMatch( + /^HTTP Error: 401 Authorization required: too many redirects or authentication replays/ + ); + + await destroyDBs([dbA]); + }); + }); + + describe('throws HttpError404NotFound', () => { + it('when valid auth and repository does not exist', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + const remoteUrl = remoteURLBase + 'sync-test-invalid.git'; + fs.ensureDirSync(dbA.workingDir); + const err = await clone(dbA.workingDir, { + remoteUrl, + connection: { type: 'github', personalAccessToken: token }, + }).catch(error => error); + expect(err).toBeInstanceOf(HTTPError404NotFound); + if (process.platform === 'win32') { + expect(err.message).toMatch( + /^HTTP Error: 404 Not Found: request failed with status code: 404/ + ); + } + else { + expect(err.message).toMatch( + /^HTTP Error: 404 Not Found: unexpected HTTP status code: 404/ + ); + } + + await destroyDBs([dbA]); + }); + }); + + describe.skip('throws CannotFetchError', () => { + // Other cases + }); + + it('throws InvalidURLFormatError by createCredentialForGitHub', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + const remoteUrl = 'foo-bar'; + fs.ensureDirSync(dbA.workingDir); + const err = await clone(dbA.workingDir, { + remoteUrl, + connection: { type: 'github', personalAccessToken: token }, + }).catch(error => error); + expect(err).toBeInstanceOf(InvalidURLFormatError); + expect(err.message).toMatch( + /^URL format is invalid: http protocol required in createCredentialForGitHub/ + ); + + await destroyDBs([dbA]); + }); + + it('throws InvalidRepositoryURLError', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + const remoteUrl = remoteURLBase + 'foo/bar/test.git'; + fs.ensureDirSync(dbA.workingDir); + await expect( + clone(dbA.workingDir, { + remoteUrl, + connection: { type: 'github', personalAccessToken: token }, + }) + ).rejects.toThrowError(InvalidRepositoryURLError); + + await destroyDBs([dbA]); + }); + + it('throws InvalidSSHKeyPathError', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + const remoteUrl = 'git@github.com:xxxxxxxxxxxxxxxxxx/sync-test.git'; + fs.ensureDirSync(dbA.workingDir); + await expect( + clone(dbA.workingDir, { + remoteUrl, + connection: { + type: 'ssh', + publicKeyPath: path.resolve(userHome, 'foo'), + privateKeyPath: path.resolve(userHome, 'bar'), + passPhrase: '', + }, + }) + ).rejects.toThrowError(InvalidSSHKeyPathError); + + await destroyDBs([dbA]); + }); + + it('throws InvalidAuthenticationTypeError', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + const remoteUrl = remoteURLBase + 'test-private.git'; + fs.ensureDirSync(dbA.workingDir); + await expect( + // @ts-ignore + clone(dbA.workingDir, { remoteUrl, connection: { type: 'foo' } }) + ).rejects.toThrowError(InvalidAuthenticationTypeError); + + await destroyDBs([dbA]); + }); +}); diff --git a/test/plugin/fetch.test.ts b/test/plugin/fetch.test.ts new file mode 100644 index 00000000..70d7b018 --- /dev/null +++ b/test/plugin/fetch.test.ts @@ -0,0 +1,634 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +import path from 'path'; +import fs from 'fs-extra'; +import expect from 'expect'; +import { + HTTPError401AuthorizationRequired, + HTTPError404NotFound, + InvalidAuthenticationTypeError, + InvalidGitRemoteError, + InvalidRepositoryURLError, + InvalidSSHKeyPathError, + InvalidURLFormatError, + NetworkError, +} from 'git-documentdb-remote-errors'; +import sinon from 'sinon'; +import { GitDocumentDB } from '../../src/git_documentdb'; +import { fetch } from '../../src/plugin/remote-isomorphic-git'; +import { createGitRemote, destroyDBs, removeRemoteRepositories } from '../remote_utils'; + +const reposPrefix = 'test_remote_isomorphic_git_fetch___'; +const localDir = `./test/database_fetch`; + +let idCounter = 0; +const serialId = () => { + return `${reposPrefix}${idCounter++}`; +}; + +// Use sandbox to restore stub and spy in parallel mocha tests +let sandbox: sinon.SinonSandbox; +beforeEach(function () { + sandbox = sinon.createSandbox(); + // @ts-ignore + console.log(`... ${this.currentTest.fullTitle()}`); +}); + +afterEach(function () { + sandbox.restore(); +}); + +before(() => { + fs.removeSync(path.resolve(localDir)); +}); + +after(() => { + fs.removeSync(path.resolve(localDir)); +}); + +/** + * Prerequisites + * + * Environment variables: + * GITDDB_GITHUB_USER_URL: URL of your GitHub account + * e.g.) https://github.com/foo/ + * GITDDB_PERSONAL_ACCESS_TOKEN: The personal access token of your GitHub account + * GitHub repositories: + * remoteURLBase + 'test-private.git' must be a private repository. + */ +const userHome = process.env[process.platform === 'win32' ? 'USERPROFILE' : 'HOME'] ?? ''; + +const maybe = + process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN + ? describe + : describe.skip; + +maybe(' fetch', () => { + const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') + ? process.env.GITDDB_GITHUB_USER_URL + : process.env.GITDDB_GITHUB_USER_URL + '/'; + const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; + + before(async () => { + // Remove remote + await removeRemoteRepositories(reposPrefix).catch(err => console.log(err)); + }); + + it('throws InvalidGitRemoteError', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = 'foo-bar'; + const err = await fetch(dbA.workingDir, { remoteUrl }).catch(error => error); + + expect(err).toBeInstanceOf(InvalidGitRemoteError); + expect(err.message).toMatch(/^Invalid Git remote: remote 'origin' does not exist/); + + await destroyDBs([dbA]); + }); + + describe('succeeds', () => { + it('when connect to public repository with no personal access token', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = remoteURLBase + 'test-public.git'; + await createGitRemote(dbA.workingDir, remoteUrl); + const res = await fetch(dbA.workingDir, { + remoteUrl, + connection: { type: 'github' }, + }).catch(error => error); + expect(res).toBeUndefined(); + + await destroyDBs([dbA]); + }); + + it('when connect to public repository with valid personal access token', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = remoteURLBase + 'test-public.git'; + + await createGitRemote(dbA.workingDir, remoteUrl); + const res = await fetch(dbA.workingDir, { + remoteUrl, + connection: { type: 'github', personalAccessToken: token }, + }).catch(error => error); + expect(res).toBeUndefined(); + + await destroyDBs([dbA]); + }); + + it('when connect to private repository with valid personal access token', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = remoteURLBase + 'test-private.git'; + await createGitRemote(dbA.workingDir, remoteUrl); + + const res = await fetch(dbA.workingDir, { + remoteUrl, + connection: { type: 'github', personalAccessToken: token }, + }).catch(error => error); + expect(res).toBeUndefined(); + + await destroyDBs([dbA]); + }); + + it('after retrying push()', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = remoteURLBase + 'test-private.git'; + await createGitRemote(dbA.workingDir, remoteUrl); + + let counter = 0; + const stubOpen = sandbox.stub(nodegit.Repository, 'open'); + // Create fake Repository.open() that returns fake Remote by calling getRemote() + stubOpen.callsFake(async function (dir) { + const repos = await stubOpen.wrappedMethod(dir); // Call original nodegit.Repository.open(); + // @ts-ignore + repos.getRemote = () => { + return Promise.resolve({ + fetch: () => { + if (counter < 3) { + counter++; + return Promise.reject(new Error('failed to send request')); + } + counter++; + return Promise.resolve(undefined); + }, + disconnect: () => {}, + }); + }; + return repos; + }); + + const res = await fetch(dbA.workingDir, { + remoteUrl, + connection: { type: 'github', personalAccessToken: token }, + }).catch(error => error); + expect(res).toBeUndefined(); + + expect(counter).toBe(4); + + await destroyDBs([dbA]); + }); + }); + + it('throws NetworkError after retrying push()', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = remoteURLBase + 'test-private.git'; + await createGitRemote(dbA.workingDir, remoteUrl); + + let counter = 0; + const stubOpen = sandbox.stub(nodegit.Repository, 'open'); + // Create fake Repository.open() that returns fake Remote by calling getRemote() + stubOpen.callsFake(async function (dir) { + const repos = await stubOpen.wrappedMethod(dir); // Call original nodegit.Repository.open(); + // @ts-ignore + repos.getRemote = () => { + return Promise.resolve({ + fetch: () => { + counter++; + return Promise.reject(new Error('failed to send request')); + }, + disconnect: () => {}, + }); + }; + return repos; + }); + + const res = await fetch(dbA.workingDir, { + remoteUrl, + connection: { type: 'github', personalAccessToken: token }, + }).catch(error => error); + expect(res).toBeInstanceOf(NetworkError); + + expect(counter).toBe(4); + + await destroyDBs([dbA]); + }); + + it('throws InvalidURLFormat by fetch when http protocol is missing', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = 'foo-bar'; + await createGitRemote(dbA.workingDir, remoteUrl); + + const err = await fetch(dbA.workingDir, { remoteUrl }).catch(error => error); + + expect(err).toBeInstanceOf(InvalidURLFormatError); + expect(err.message).toMatch(/^URL format is invalid: unsupported URL protocol/); + + await destroyDBs([dbA]); + }); + + it('throws InvalidURLFormatError by fetch when URL is malformed', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = 'https://foo.example.com:xxxx'; + await createGitRemote(dbA.workingDir, remoteUrl); + + const err = await fetch(dbA.workingDir, { remoteUrl }).catch(error => error); + expect(err).toBeInstanceOf(InvalidURLFormatError); + expect(err.message).toMatch(/^URL format is invalid: malformed URL/); + + await destroyDBs([dbA]); + }); + + describe('throws NetworkError', () => { + it('when HTTP host is invalid', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = 'https://foo.bar.example.com/gitddb-plugin/sync-test-invalid.git'; + + await createGitRemote(dbA.workingDir, remoteUrl); + + const err = await fetch(dbA.workingDir, { remoteUrl }).catch(error => error); + expect(err).toBeInstanceOf(NetworkError); + expect(err.message).toMatch(/^Network error: failed to send request/); + + await destroyDBs([dbA]); + }); + + it('when IP address is invalid', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = 'https://127.0.0.1/gitddb-plugin/sync-test-invalid.git'; + await createGitRemote(dbA.workingDir, remoteUrl); + + const err = await fetch(dbA.workingDir, { + remoteUrl, + connection: { + type: 'github', + }, + }).catch(error => error); + + expect(err).toBeInstanceOf(NetworkError); + expect(err.message).toMatch(/^Network error: failed to send request/); + + await destroyDBs([dbA]); + }); + + it('when SSH host is invalid', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = 'git@foo.example.com:bar/sync-test.git'; + await createGitRemote(dbA.workingDir, remoteUrl); + + const err = await fetch(dbA.workingDir, { + remoteUrl, + connection: { + type: 'ssh', + publicKeyPath: path.resolve(userHome, '.ssh/invalid-test.pub'), + privateKeyPath: path.resolve(userHome, '.ssh/invalid-test'), + passPhrase: '', + }, + }).catch(error => error); + + expect(err).toBeInstanceOf(NetworkError); + expect(err.message).toMatch(/^Network error: failed to resolve address/); + + await destroyDBs([dbA]); + }); + }); + + describe('throws HttpError401AuthorizationRequired', () => { + it('when personal access token does not exist', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = remoteURLBase + 'test-private.git'; + + await createGitRemote(dbA.workingDir, remoteUrl); + + const err = await fetch(dbA.workingDir, { + remoteUrl, + connection: { type: 'github' }, + }).catch(error => error); + + expect(err).toBeInstanceOf(HTTPError401AuthorizationRequired); + expect(err.message).toMatch( + /^HTTP Error: 401 Authorization required: request failed with status code: 401/ + ); + + await destroyDBs([dbA]); + }); + + it('when connection setting not found', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = remoteURLBase + 'test-private.git'; + await createGitRemote(dbA.workingDir, remoteUrl); + + let err; + for (let i = 0; i < 3; i++) { + // eslint-disable-next-line no-await-in-loop + err = await fetch(dbA.workingDir, { remoteUrl }).catch(error => error); + if ( + !err.message.startsWith( + 'HTTP Error: 401 Authorization required: too many redirects or authentication replays' + ) + ) { + break; + } + } + expect(err).toBeInstanceOf(HTTPError401AuthorizationRequired); + if (process.platform === 'win32') { + expect(err.message).toMatch( + /^HTTP Error: 401 Authorization required: request failed with status code: 401/ + ); + } + else { + expect(err.message).toMatch( + /^HTTP Error: 401 Authorization required: unexpected HTTP status code: 401/ + ); + } + + await destroyDBs([dbA]); + }); + + it.skip('when XXXX?', async () => { + // TODO: This will invoke on ubuntu + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = remoteURLBase + 'test-private.git'; + + await createGitRemote(dbA.workingDir, remoteUrl); + + const err = await fetch(dbA.workingDir, { remoteUrl }).catch(error => error); + expect(err).toBeInstanceOf(HTTPError401AuthorizationRequired); + expect(err.message).toMatch( + /^HTTP Error: 401 Authorization required: remote credential provider returned an invalid cred type/ + ); + + await destroyDBs([dbA]); + }); + + it.skip('when invalid SSH key format', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + // TODO: set SSH url for test + const remoteUrl = 'git@github.com:xxxxxxxxxxxxxxxxxx/sync-test.git'; + + await createGitRemote(dbA.workingDir, remoteUrl); + + const err = await fetch(dbA.workingDir, { + remoteUrl, + connection: { + type: 'ssh', + publicKeyPath: path.resolve(userHome, '.ssh/invalid-test.pub'), + privateKeyPath: path.resolve(userHome, '.ssh/invalid-test'), + passPhrase: '', + }, + }).catch(error => error); + + expect(err).toBeInstanceOf(HTTPError401AuthorizationRequired); + // TODO: How to invoke this error + expect(err.message).toMatch( + /^HTTP Error: 401 Authorization required: Failed to retrieve list of SSH authentication methods/ + ); + + await destroyDBs([dbA]); + }); + + it('when invalid personal access token', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = remoteURLBase + 'test-private.git'; + await createGitRemote(dbA.workingDir, remoteUrl); + + const err = await fetch(dbA.workingDir, { + remoteUrl, + connection: { type: 'github', personalAccessToken: 'foo-bar' }, + }).catch(error => error); + + expect(err).toBeInstanceOf(HTTPError401AuthorizationRequired); + expect(err.message).toMatch( + /^HTTP Error: 401 Authorization required: too many redirects or authentication replays/ + ); + + await destroyDBs([dbA]); + }); + + it('when invalid pair of url and SSH auth', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = remoteURLBase + 'test-private.git'; + await createGitRemote(dbA.workingDir, remoteUrl); + + const err = await fetch(dbA.workingDir, { + remoteUrl, + connection: { + type: 'ssh', + publicKeyPath: path.resolve(userHome, '.ssh/invalid-test.pub'), + privateKeyPath: path.resolve(userHome, '.ssh/invalid-test'), + passPhrase: '', + }, + }).catch(error => error); + + expect(err).toBeInstanceOf(HTTPError401AuthorizationRequired); + expect(err.message).toMatch( + /^HTTP Error: 401 Authorization required: too many redirects or authentication replays/ + ); + + await destroyDBs([dbA]); + }); + }); + + describe('throws HttpError404NotFound', () => { + it('when valid auth and repository does not exist', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = remoteURLBase + 'sync-test-invalid.git'; + await createGitRemote(dbA.workingDir, remoteUrl); + + const err = await fetch(dbA.workingDir, { + remoteUrl, + connection: { type: 'github', personalAccessToken: token }, + }).catch(error => error); + expect(err).toBeInstanceOf(HTTPError404NotFound); + if (process.platform === 'win32') { + expect(err.message).toMatch( + /^HTTP Error: 404 Not Found: request failed with status code: 404/ + ); + } + else { + expect(err.message).toMatch( + /^HTTP Error: 404 Not Found: unexpected HTTP status code: 404/ + ); + } + + await destroyDBs([dbA]); + }); + }); + + describe.skip('throws CannotFetchError', () => { + // Other cases + }); + + it('throws InvalidURLFormatError by createCredentialForGitHub', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = 'foo-bar'; + await createGitRemote(dbA.workingDir, remoteUrl); + + const err = await fetch(dbA.workingDir, { + remoteUrl, + connection: { type: 'github', personalAccessToken: token }, + }).catch(error => error); + expect(err).toBeInstanceOf(InvalidURLFormatError); + expect(err.message).toMatch( + /^URL format is invalid: http protocol required in createCredentialForGitHub/ + ); + + await destroyDBs([dbA]); + }); + + it('throws InvalidRepositoryURLError', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = remoteURLBase + 'foo/bar/test.git'; + await createGitRemote(dbA.workingDir, remoteUrl); + + await expect( + fetch(dbA.workingDir, { + remoteUrl, + connection: { type: 'github', personalAccessToken: token }, + }) + ).rejects.toThrowError(InvalidRepositoryURLError); + + await destroyDBs([dbA]); + }); + + it('throws InvalidSSHKeyPathError', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = 'git@github.com:xxxxxxxxxxxxxxxxxx/sync-test.git'; + await createGitRemote(dbA.workingDir, remoteUrl); + + await expect( + fetch(dbA.workingDir, { + remoteUrl, + connection: { + type: 'ssh', + publicKeyPath: path.resolve(userHome, 'foo'), + privateKeyPath: path.resolve(userHome, 'bar'), + passPhrase: '', + }, + }) + ).rejects.toThrowError(InvalidSSHKeyPathError); + + await destroyDBs([dbA]); + }); + + it('throws InvalidAuthenticationTypeError', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = remoteURLBase + 'test-private.git'; + await createGitRemote(dbA.workingDir, remoteUrl); + + await expect( + // @ts-ignore + fetch(dbA.workingDir, { remoteUrl, connection: { type: 'foo' } }) + ).rejects.toThrowError(InvalidAuthenticationTypeError); + + await destroyDBs([dbA]); + }); + + describe('throws CannotConnectError', () => { + // NetworkError is thrown when network is not connected. + // CannotConnectError will be thrown when other unexpected cases. + }); +}); diff --git a/test/plugin/push.test.ts b/test/plugin/push.test.ts new file mode 100644 index 00000000..95154c2a --- /dev/null +++ b/test/plugin/push.test.ts @@ -0,0 +1,874 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +import path from 'path'; +import git from 'isomorphic-git'; +import fs from 'fs-extra'; +import expect from 'expect'; +import { + CannotConnectError, + HTTPError401AuthorizationRequired, + HTTPError403Forbidden, + HTTPError404NotFound, + InvalidAuthenticationTypeError, + InvalidGitRemoteError, + InvalidRepositoryURLError, + InvalidSSHKeyPathError, + InvalidURLFormatError, + NetworkError, + UnfetchedCommitExistsError, +} from 'git-documentdb-remote-errors'; +import sinon from 'sinon'; +import { GitDocumentDB } from '../../src/git_documentdb'; +import { RemoteOptions } from '../../src/types'; +import { clone, push } from '../../src/plugin/remote-isomorphic-git'; +import { + createClonedDatabases, + createGitRemote, + createRemoteRepository, + destroyDBs, + removeRemoteRepositories, +} from '../remote_utils'; + +const reposPrefix = 'test_remote_isomorphic_git_push___'; +const localDir = `./test/database_push`; + +let idCounter = 0; +const serialId = () => { + return `${reposPrefix}${idCounter++}`; +}; + +// Use sandbox to restore stub and spy in parallel mocha tests +let sandbox: sinon.SinonSandbox; +beforeEach(function () { + sandbox = sinon.createSandbox(); + // @ts-ignore + console.log(`... ${this.currentTest.fullTitle()}`); +}); + +afterEach(function () { + sandbox.restore(); +}); + +before(() => { + fs.removeSync(path.resolve(localDir)); +}); + +after(() => { + // fs.removeSync(path.resolve(localDir)); +}); + +/** + * Prerequisites + * + * Environment variables: + * GITDDB_GITHUB_USER_URL: URL of your GitHub account + * e.g.) https://github.com/foo/ + * GITDDB_PERSONAL_ACCESS_TOKEN: The personal access token of your GitHub account + * GitHub repositories: + * remoteURLBase + 'test-private.git' must be a private repository. + */ +const userHome = process.env[process.platform === 'win32' ? 'USERPROFILE' : 'HOME'] ?? ''; + +const maybe = + process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN + ? describe + : describe.skip; + +maybe(' push', () => { + const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') + ? process.env.GITDDB_GITHUB_USER_URL + : process.env.GITDDB_GITHUB_USER_URL + '/'; + const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; + + before(async () => { + // Remove remote + await removeRemoteRepositories(reposPrefix).catch(err => console.log(err)); + }); + + it('throws InvalidGitRemoteError', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = 'foo-bar'; + + const err = await push(dbA.workingDir, { remoteUrl }, undefined, undefined).catch( + error => error + ); + + expect(err).toBeInstanceOf(InvalidGitRemoteError); + expect(err.message).toMatch(/^Invalid Git remote: remote 'origin' does not exist/); + + await destroyDBs([dbA]); + }); + + describe('succeeds', () => { + it('when connect to empty repository with valid personal access token', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + const remoteUrl = remoteURLBase + serialId(); + await dbA.open(); + await createRemoteRepository(remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl); + const res = await push(dbA.workingDir, { + remoteUrl, + connection: { type: 'github', personalAccessToken: token }, + }).catch(error => error); + + expect(res).toBeUndefined(); + + await destroyDBs([dbA]); + }); + + it('when connect to cloned repository with valid personal access token', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + const remoteUrl = remoteURLBase + 'test-public.git'; + fs.ensureDirSync(dbA.workingDir); + await clone(dbA.workingDir, { + remoteUrl: remoteUrl, + connection: { type: 'github', personalAccessToken: token }, + }); + await dbA.open(); + // await createGitRemote(dbA.workingDir, remoteUrl); // Not need because cloned repository. + + const res = await push(dbA.workingDir, { + remoteUrl, + connection: { type: 'github', personalAccessToken: token }, + }).catch(error => error); + + expect(res).toBeUndefined(); + + await destroyDBs([dbA]); + }); + + it('when connect to private repository with valid personal access token', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + + const remoteUrl = remoteURLBase + 'test-private.git'; + fs.ensureDirSync(dbA.workingDir); + await clone(dbA.workingDir, { + remoteUrl: remoteUrl, + connection: { type: 'github', personalAccessToken: token }, + }); + await dbA.open(); + await createGitRemote(dbA.workingDir, remoteUrl); + + const res = await push(dbA.workingDir, { + remoteUrl, + connection: { type: 'github', personalAccessToken: token }, + }).catch(error => error); + expect(res).toBeUndefined(); + + await destroyDBs([dbA]); + }); + + it('after retrying push()', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + const remoteUrl = remoteURLBase + serialId(); + await dbA.open(); + await createRemoteRepository(remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl); + + let pushCounter = 0; + const stubOpen = sandbox.stub(nodegit.Repository, 'open'); + // Create fake Repository.open() that returns fake Remote by calling getRemote() + stubOpen.callsFake(async function (dir) { + const repos = await stubOpen.wrappedMethod(dir); // Call original nodegit.Repository.open(); + // @ts-ignore + repos.getRemote = () => { + return Promise.resolve({ + push: () => { + if (pushCounter < 3) { + pushCounter++; + return Promise.reject(new Error('failed to send request')); + } + pushCounter++; + return Promise.resolve(1); + }, + fetch: () => { + return Promise.resolve(undefined); + }, + disconnect: () => {}, + }); + }; + return repos; + }); + + sandbox.stub(git, 'resolveRef').resolves(undefined); + sandbox.stub(git, 'findMergeBase').resolves([undefined]); + + const res = await push(dbA.workingDir, { + remoteUrl, + connection: { type: 'github', personalAccessToken: token }, + }).catch((error: Error) => error); + + expect(res).toBeUndefined(); + + expect(pushCounter).toBe(4); + + await destroyDBs([dbA]); + }); + + it('after retrying validatePushResult()', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + const remoteUrl = remoteURLBase + serialId(); + await dbA.open(); + await createRemoteRepository(remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl); + + let pushValidateCounter = 0; + const stubOpen = sandbox.stub(nodegit.Repository, 'open'); + // Create fake Repository.open() that returns fake Remote by calling getRemote() + stubOpen.callsFake(async function (dir) { + const repos = await stubOpen.wrappedMethod(dir); // Call original nodegit.Repository.open(); + // @ts-ignore + repos.getRemote = () => { + return Promise.resolve({ + push: () => { + return Promise.resolve(1); + }, + fetch: () => { + if (pushValidateCounter < 3) { + pushValidateCounter++; + return Promise.reject(new Error('foo')); + } + pushValidateCounter++; + return Promise.resolve(undefined); + }, + disconnect: () => {}, + }); + }; + return repos; + }); + + sandbox.stub(git, 'resolveRef').resolves(undefined); + sandbox.stub(git, 'findMergeBase').resolves([undefined]); + + const res = await push(dbA.workingDir, { + remoteUrl, + connection: { type: 'github', personalAccessToken: token }, + }).catch((error: Error) => error); + + expect(res).toBeUndefined(); + + expect(pushValidateCounter).toBe(4); + + await destroyDBs([dbA]); + }); + }); + + it('throws NetworkError after retrying push()', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + const remoteUrl = remoteURLBase + serialId(); + await dbA.open(); + await createRemoteRepository(remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl); + + let pushCounter = 0; + const stubOpen = sandbox.stub(nodegit.Repository, 'open'); + // Create fake Repository.open() that returns fake Remote by calling getRemote() + stubOpen.callsFake(async function (dir) { + const repos = await stubOpen.wrappedMethod(dir); // Call original nodegit.Repository.open(); + // @ts-ignore + repos.getRemote = () => { + return Promise.resolve({ + push: () => { + pushCounter++; + return Promise.reject(new Error('failed to send request')); + }, + fetch: () => { + return Promise.resolve(undefined); + }, + disconnect: () => {}, + }); + }; + return repos; + }); + + sandbox.stub(git, 'resolveRef').resolves(undefined); + sandbox.stub(git, 'findMergeBase').resolves([undefined]); + + const res = await push(dbA.workingDir, { + remoteUrl, + connection: { type: 'github', personalAccessToken: token }, + }).catch((error: Error) => error); + + expect(res).toBeInstanceOf(NetworkError); + + expect(pushCounter).toBe(4); + + await destroyDBs([dbA]); + }); + + it('throws CannotConnectError after retrying validatePushResult()', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + const remoteUrl = remoteURLBase + serialId(); + await dbA.open(); + await createRemoteRepository(remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl); + + let pushValidateCounter = 0; + const stubOpen = sandbox.stub(nodegit.Repository, 'open'); + // Create fake Repository.open() that returns fake Remote by calling getRemote() + stubOpen.callsFake(async function (dir) { + const repos = await stubOpen.wrappedMethod(dir); // Call original nodegit.Repository.open(); + // @ts-ignore + repos.getRemote = () => { + return Promise.resolve({ + push: () => { + return Promise.resolve(1); + }, + fetch: () => { + pushValidateCounter++; + return Promise.reject(new Error('foo')); + }, + disconnect: () => {}, + }); + }; + return repos; + }); + + sandbox.stub(git, 'resolveRef').resolves(undefined); + sandbox.stub(git, 'findMergeBase').resolves([undefined]); + + const res = await push(dbA.workingDir, { + remoteUrl, + connection: { type: 'github', personalAccessToken: token }, + }).catch((error: Error) => error); + + expect(res).toBeInstanceOf(CannotConnectError); + + expect(pushValidateCounter).toBe(4); + + await destroyDBs([dbA]); + }); + + it('throws InvalidURLFormat by push when http protocol is missing', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = 'foo-bar'; + await createGitRemote(dbA.workingDir, remoteUrl); + + const err = await push(dbA.workingDir, { + remoteUrl, + connection: { type: 'none' }, + }).catch(error => error); + + expect(err).toBeInstanceOf(InvalidURLFormatError); + expect(err.message).toMatch(/^URL format is invalid: unsupported URL protocol/); + + await destroyDBs([dbA]); + }); + + it('throws InvalidURLFormatError by push when URL is malformed', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = 'https://foo.example.com:xxxx'; + await createGitRemote(dbA.workingDir, remoteUrl); + + const err = await push(dbA.workingDir, { + remoteUrl, + connection: { type: 'none' }, + }).catch(error => error); + + expect(err).toBeInstanceOf(InvalidURLFormatError); + expect(err.message).toMatch(/^URL format is invalid: malformed URL/); + + await destroyDBs([dbA]); + }); + + describe('throws NetworkError', () => { + it('when HTTP host is invalid', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = 'https://foo.bar.example.com/gitddb-plugin/sync-test-invalid.git'; + await createGitRemote(dbA.workingDir, remoteUrl); + + const err = await push(dbA.workingDir, { + remoteUrl, + connection: { type: 'none' }, + }).catch(error => error); + + expect(err).toBeInstanceOf(NetworkError); + expect(err.message).toMatch(/^Network error: failed to send request/); + + await destroyDBs([dbA]); + }); + + it('when IP address is invalid', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = 'https://127.0.0.1/gitddb-plugin/sync-test-invalid.git'; + await createGitRemote(dbA.workingDir, remoteUrl); + + const err = await push(dbA.workingDir, { + remoteUrl, + connection: { + type: 'github', + }, + }).catch(error => error); + + expect(err).toBeInstanceOf(NetworkError); + expect(err.message).toMatch(/^Network error: failed to send request/); + + await destroyDBs([dbA]); + }); + + it('when SSH host is invalid', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = 'git@foo.example.com:bar/sync-test.git'; + await createGitRemote(dbA.workingDir, remoteUrl); + + const err = await push(dbA.workingDir, { + remoteUrl, + connection: { + type: 'ssh', + publicKeyPath: path.resolve(userHome, '.ssh/invalid-test.pub'), + privateKeyPath: path.resolve(userHome, '.ssh/invalid-test'), + passPhrase: '', + }, + }).catch(error => error); + + expect(err).toBeInstanceOf(NetworkError); + expect(err.message).toMatch(/^Network error: failed to resolve address/); + + await destroyDBs([dbA]); + }); + }); + + describe('throws HttpError401AuthorizationRequired', () => { + it('when personal access token does not exist', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = remoteURLBase + 'test-public.git'; + await createGitRemote(dbA.workingDir, remoteUrl); + + const err = await push(dbA.workingDir, { + remoteUrl, + connection: { type: 'github' }, + }).catch(error => error); + + expect(err).toBeInstanceOf(HTTPError401AuthorizationRequired); + expect(err.message).toMatch( + /^HTTP Error: 401 Authorization required: request failed with status code: 401/ + ); + + await destroyDBs([dbA]); + }); + + it('when connection setting not found', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = remoteURLBase + 'test-public.git'; + await createGitRemote(dbA.workingDir, remoteUrl); + + let err; + for (let i = 0; i < 3; i++) { + // eslint-disable-next-line no-await-in-loop + err = await push(dbA.workingDir, { remoteUrl }).catch(error => error); + if ( + !err.message.startsWith( + 'HTTP Error: 401 Authorization required: too many redirects or authentication replays' + ) + ) { + break; + } + } + expect(err).toBeInstanceOf(HTTPError401AuthorizationRequired); + if (process.platform === 'win32') { + expect(err.message).toMatch( + /^HTTP Error: 401 Authorization required: request failed with status code: 401/ + ); + } + else { + expect(err.message).toMatch( + /^HTTP Error: 401 Authorization required: unexpected HTTP status code: 401/ + ); + } + + await destroyDBs([dbA]); + }); + + it.skip('when XXXX?', async () => { + // TODO: This will invoke on ubuntu + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = remoteURLBase + 'test-private.git'; + await createGitRemote(dbA.workingDir, remoteUrl); + + const err = await push(dbA.workingDir, { remoteUrl }).catch(error => error); + expect(err).toBeInstanceOf(HTTPError401AuthorizationRequired); + expect(err.message).toMatch( + /^HTTP Error: 401 Authorization required: remote credential provider returned an invalid cred type/ + ); + + await destroyDBs([dbA]); + }); + + it.skip('when invalid SSH key format', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + // TODO: set SSH url for test + const remoteUrl = 'git@github.com:xxxxxxxxxxxxxxxxxx/sync-test.git'; + await createGitRemote(dbA.workingDir, remoteUrl); + + const err = await push(dbA.workingDir, { + remoteUrl, + connection: { + type: 'ssh', + publicKeyPath: path.resolve(userHome, '.ssh/invalid-test.pub'), + privateKeyPath: path.resolve(userHome, '.ssh/invalid-test'), + passPhrase: '', + }, + }).catch(error => error); + + expect(err).toBeInstanceOf(HTTPError401AuthorizationRequired); + // TODO: How to invoke this error + expect(err.message).toMatch( + /^HTTP Error: 401 Authorization required: Failed to retrieve list of SSH authentication methods/ + ); + + await destroyDBs([dbA]); + }); + + it('when invalid personal access token', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = remoteURLBase + 'test-private.git'; + await createGitRemote(dbA.workingDir, remoteUrl); + + const err = await push(dbA.workingDir, { + remoteUrl, + connection: { type: 'github', personalAccessToken: 'foo-bar' }, + }).catch(error => error); + + expect(err).toBeInstanceOf(HTTPError401AuthorizationRequired); + expect(err.message).toMatch( + /^HTTP Error: 401 Authorization required: too many redirects or authentication replays/ + ); + + await destroyDBs([dbA]); + }); + + it('when invalid pair of url and SSH auth', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = remoteURLBase + 'test-private.git'; + await createGitRemote(dbA.workingDir, remoteUrl); + + const err = await push(dbA.workingDir, { + remoteUrl, + connection: { + type: 'ssh', + publicKeyPath: path.resolve(userHome, '.ssh/invalid-test.pub'), + privateKeyPath: path.resolve(userHome, '.ssh/invalid-test'), + passPhrase: '', + }, + }).catch(error => error); + + expect(err).toBeInstanceOf(HTTPError401AuthorizationRequired); + expect(err.message).toMatch( + /^HTTP Error: 401 Authorization required: too many redirects or authentication replays/ + ); + + await destroyDBs([dbA]); + }); + }); + + describe('throws HttpError404NotFound', () => { + it('when valid auth and repository does not exist', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = remoteURLBase + 'sync-test-invalid.git'; + await createGitRemote(dbA.workingDir, remoteUrl); + + const err = await push(dbA.workingDir, { + remoteUrl, + connection: { type: 'github', personalAccessToken: token }, + }).catch(error => error); + expect(err).toBeInstanceOf(HTTPError404NotFound); + if (process.platform === 'win32') { + expect(err.message).toMatch( + /^HTTP Error: 404 Not Found: request failed with status code: 404/ + ); + } + else { + expect(err.message).toMatch( + /^HTTP Error: 404 Not Found: unexpected HTTP status code: 404/ + ); + } + + await destroyDBs([dbA]); + }); + }); + + describe.skip('throws CannotPushError', () => { + // Other cases + }); + + it('throws InvalidURLFormatError by createCredentialForGitHub', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = 'foo-bar'; + await createGitRemote(dbA.workingDir, remoteUrl); + + const err = await push(dbA.workingDir, { + remoteUrl, + connection: { type: 'github', personalAccessToken: token }, + }).catch(error => error); + expect(err).toBeInstanceOf(InvalidURLFormatError); + expect(err.message).toMatch( + /^URL format is invalid: http protocol required in createCredentialForGitHub/ + ); + + await destroyDBs([dbA]); + }); + + it('throws InvalidRepositoryURLError', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = remoteURLBase + 'foo/bar/test.git'; + await createGitRemote(dbA.workingDir, remoteUrl); + + await expect( + push(dbA.workingDir, { + remoteUrl, + connection: { type: 'github', personalAccessToken: token }, + }) + ).rejects.toThrowError(InvalidRepositoryURLError); + + await destroyDBs([dbA]); + }); + + it('throws InvalidSSHKeyPathError', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = 'git@github.com:xxxxxxxxxxxxxxxxxx/sync-test.git'; + await createGitRemote(dbA.workingDir, remoteUrl); + + await expect( + push(dbA.workingDir, { + remoteUrl, + connection: { + type: 'ssh', + publicKeyPath: path.resolve(userHome, 'foo'), + privateKeyPath: path.resolve(userHome, 'bar'), + passPhrase: '', + }, + }) + ).rejects.toThrowError(InvalidSSHKeyPathError); + + await destroyDBs([dbA]); + }); + + it('throws InvalidAuthenticationTypeError', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = remoteURLBase + 'test-private.git'; + await createGitRemote(dbA.workingDir, remoteUrl); + + await expect( + // @ts-ignore + push(dbA.workingDir, { remoteUrl, connection: { type: 'foo' } }) + ).rejects.toThrowError(InvalidAuthenticationTypeError); + + await destroyDBs([dbA]); + }); + + describe('throws HttpError403Forbidden', () => { + it('when access repository of another account with your account', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + // const remoteUrl = privateRepositoryOfAnotherUser; + const remoteUrl = 'https://github.com/sosuisen/git-documentdb.git'; + await createGitRemote(dbA.workingDir, remoteUrl); + + const err = await push(dbA.workingDir, { + remoteUrl, + connection: { type: 'github', personalAccessToken: token }, + }).catch(error => error); + expect(err).toBeInstanceOf(HTTPError403Forbidden); + + if (process.platform === 'win32') { + expect(err.message).toMatch( + /^HTTP Error: 403 Forbidden: request failed with status code: 403/ + ); + } + else { + expect(err.message).toMatch( + /^HTTP Error: 403 Forbidden: unexpected HTTP status code: 403/ + ); + } + + await destroyDBs([dbA]); + }); + }); + + describe('throws UnfetchedCommitExistsError', () => { + it('when unfetched commit exists', async () => { + const [dbA, dbB, syncA, syncB] = await createClonedDatabases( + remoteURLBase, + localDir, + serialId + ); + + await dbB.put({ name: 'foo' }); + await syncB.tryPush(); + + const err = await push(dbA.workingDir, { + remoteUrl: syncA.remoteURL, + connection: { type: 'github', personalAccessToken: token }, + }).catch(error => error); + expect(err).toBeInstanceOf(UnfetchedCommitExistsError); + + await destroyDBs([dbA, dbB]); + }); + + it('Race condition of two push() calls throws UnfetchedCommitExistsError in validatePushResult', async () => { + const remoteURL = remoteURLBase + serialId(); + + const dbNameA = serialId(); + + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection: { type: 'github', personalAccessToken: token }, + }; + await dbA.open(); + const syncA = await dbA.sync(options); + const jsonA1 = { _id: '1', name: 'fromA' }; + await dbA.put(jsonA1); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir: localDir, + }); + await dbB.open(); + const syncB = await dbB.sync(options); + const jsonB1 = { _id: '1', name: 'fromB' }; + await dbB.put(jsonB1); + + await expect( + Promise.all([ + push(dbA.workingDir, { + remoteUrl: syncA.remoteURL, + connection: { type: 'github', personalAccessToken: token }, + }), + push(dbB.workingDir, { + remoteUrl: syncB.remoteURL, + connection: { type: 'github', personalAccessToken: token }, + }), + ]) + ).rejects.toThrowError(UnfetchedCommitExistsError); + + await destroyDBs([dbA, dbB]); + }); + }); + + describe('throws CannotConnectError', () => { + // NetworkError is thrown when network is not connected. + // CannotConnectError will be thrown when other unexpected cases. + }); +}); diff --git a/test/remote_utils.ts b/test/remote_utils.ts index 2548ff09..fd8a235e 100644 --- a/test/remote_utils.ts +++ b/test/remote_utils.ts @@ -402,3 +402,22 @@ export const destroyDBs = async (DBs: GitDocumentDB[]) => { await clock.tickAsync(FILE_REMOVE_TIMEOUT); clock.restore(); }; + +export async function createGitRemote ( + localDir: string, + remoteUrl: string, + remoteName = 'origin' +) { + await git.setConfig({ + fs, + dir: localDir, + path: `remote.${remoteName}.url`, + value: remoteUrl, + }); + await git.setConfig({ + fs, + dir: localDir, + path: `remote.${remoteName}.fetch`, + value: `+refs/heads/*:refs/remotes/${remoteName}/*`, + }); +} From 2923a0eef47e517f97a2f9b0c078de424c5b5bc8 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Mon, 2 Aug 2021 01:53:36 +0900 Subject: [PATCH 116/297] test: add test for fetch and checkFetch in remote-isomorphic-git --- test/plugin/checkfetch.test.ts | 2 - test/plugin/fetch.test.ts | 296 +++++++-------------------------- 2 files changed, 61 insertions(+), 237 deletions(-) diff --git a/test/plugin/checkfetch.test.ts b/test/plugin/checkfetch.test.ts index 1e25d10f..e4bd1d1c 100644 --- a/test/plugin/checkfetch.test.ts +++ b/test/plugin/checkfetch.test.ts @@ -302,9 +302,7 @@ maybe(' checkFetch', () => { const remoteUrl = remoteURLBase + 'test-private.git'; - // eslint-disable-next-line no-await-in-loop await createGitRemote(dbA.workingDir, remoteUrl); - // eslint-disable-next-line no-await-in-loop const err = await checkFetch(dbA.workingDir, { remoteUrl }).catch(error => error); expect(err).toBeInstanceOf(HTTPError401AuthorizationRequired); diff --git a/test/plugin/fetch.test.ts b/test/plugin/fetch.test.ts index 70d7b018..0d85edc5 100644 --- a/test/plugin/fetch.test.ts +++ b/test/plugin/fetch.test.ts @@ -10,6 +10,7 @@ import path from 'path'; import fs from 'fs-extra'; import expect from 'expect'; +import git from 'isomorphic-git'; import { HTTPError401AuthorizationRequired, HTTPError404NotFound, @@ -81,22 +82,6 @@ maybe(' fetch', () => { await removeRemoteRepositories(reposPrefix).catch(err => console.log(err)); }); - it('throws InvalidGitRemoteError', async () => { - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: serialId(), - localDir, - }); - await dbA.open(); - - const remoteUrl = 'foo-bar'; - const err = await fetch(dbA.workingDir, { remoteUrl }).catch(error => error); - - expect(err).toBeInstanceOf(InvalidGitRemoteError); - expect(err.message).toMatch(/^Invalid Git remote: remote 'origin' does not exist/); - - await destroyDBs([dbA]); - }); - describe('succeeds', () => { it('when connect to public repository with no personal access token', async () => { const dbA: GitDocumentDB = new GitDocumentDB({ @@ -164,27 +149,11 @@ maybe(' fetch', () => { const remoteUrl = remoteURLBase + 'test-private.git'; await createGitRemote(dbA.workingDir, remoteUrl); - let counter = 0; - const stubOpen = sandbox.stub(nodegit.Repository, 'open'); - // Create fake Repository.open() that returns fake Remote by calling getRemote() - stubOpen.callsFake(async function (dir) { - const repos = await stubOpen.wrappedMethod(dir); // Call original nodegit.Repository.open(); - // @ts-ignore - repos.getRemote = () => { - return Promise.resolve({ - fetch: () => { - if (counter < 3) { - counter++; - return Promise.reject(new Error('failed to send request')); - } - counter++; - return Promise.resolve(undefined); - }, - disconnect: () => {}, - }); - }; - return repos; - }); + const stubFetch = sandbox.stub(git, 'fetch'); + stubFetch.onCall(0).rejects(new Error('connect EACCES')); + stubFetch.onCall(1).rejects(new Error('connect EACCES')); + stubFetch.onCall(2).rejects(new Error('connect EACCES')); + stubFetch.onCall(3).resolves(undefined); const res = await fetch(dbA.workingDir, { remoteUrl, @@ -192,7 +161,7 @@ maybe(' fetch', () => { }).catch(error => error); expect(res).toBeUndefined(); - expect(counter).toBe(4); + expect(stubFetch.callCount).toBe(4); await destroyDBs([dbA]); }); @@ -208,23 +177,8 @@ maybe(' fetch', () => { const remoteUrl = remoteURLBase + 'test-private.git'; await createGitRemote(dbA.workingDir, remoteUrl); - let counter = 0; - const stubOpen = sandbox.stub(nodegit.Repository, 'open'); - // Create fake Repository.open() that returns fake Remote by calling getRemote() - stubOpen.callsFake(async function (dir) { - const repos = await stubOpen.wrappedMethod(dir); // Call original nodegit.Repository.open(); - // @ts-ignore - repos.getRemote = () => { - return Promise.resolve({ - fetch: () => { - counter++; - return Promise.reject(new Error('failed to send request')); - }, - disconnect: () => {}, - }); - }; - return repos; - }); + const stubFetch = sandbox.stub(git, 'fetch'); + stubFetch.rejects(new Error('connect EACCES')); const res = await fetch(dbA.workingDir, { remoteUrl, @@ -232,7 +186,22 @@ maybe(' fetch', () => { }).catch(error => error); expect(res).toBeInstanceOf(NetworkError); - expect(counter).toBe(4); + expect(stubFetch.callCount).toBe(4); + + await destroyDBs([dbA]); + }); + + it('throws InvalidGitRemoteError', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = 'foo-bar'; + const err = await fetch(dbA.workingDir, { remoteUrl }).catch(error => error); + + expect(err).toBeInstanceOf(InvalidGitRemoteError); await destroyDBs([dbA]); }); @@ -250,7 +219,7 @@ maybe(' fetch', () => { const err = await fetch(dbA.workingDir, { remoteUrl }).catch(error => error); expect(err).toBeInstanceOf(InvalidURLFormatError); - expect(err.message).toMatch(/^URL format is invalid: unsupported URL protocol/); + expect(err.message).toMatch(/^URL format is invalid: UrlParseError:/); await destroyDBs([dbA]); }); @@ -267,30 +236,28 @@ maybe(' fetch', () => { const err = await fetch(dbA.workingDir, { remoteUrl }).catch(error => error); expect(err).toBeInstanceOf(InvalidURLFormatError); - expect(err.message).toMatch(/^URL format is invalid: malformed URL/); + expect(err.message).toMatch(/^URL format is invalid: Error: getaddrinfo ENOTFOUND/); await destroyDBs([dbA]); }); - describe('throws NetworkError', () => { - it('when HTTP host is invalid', async () => { - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: serialId(), - localDir, - }); - await dbA.open(); - - const remoteUrl = 'https://foo.bar.example.com/gitddb-plugin/sync-test-invalid.git'; - - await createGitRemote(dbA.workingDir, remoteUrl); + it('throws InvalidURLFormatError by checkFetch when HTTP host is invalid', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); - const err = await fetch(dbA.workingDir, { remoteUrl }).catch(error => error); - expect(err).toBeInstanceOf(NetworkError); - expect(err.message).toMatch(/^Network error: failed to send request/); + const remoteUrl = 'https://foo.bar.example.com/gitddb-plugin/sync-test-invalid.git'; + await createGitRemote(dbA.workingDir, remoteUrl); + const err = await fetch(dbA.workingDir, { remoteUrl }).catch(error => error); + expect(err).toBeInstanceOf(InvalidURLFormatError); + expect(err.message).toMatch(/^URL format is invalid: Error: getaddrinfo ENOTFOUND/); - await destroyDBs([dbA]); - }); + await destroyDBs([dbA]); + }); + describe('throws NetworkError', () => { it('when IP address is invalid', async () => { const dbA: GitDocumentDB = new GitDocumentDB({ dbName: serialId(), @@ -309,33 +276,7 @@ maybe(' fetch', () => { }).catch(error => error); expect(err).toBeInstanceOf(NetworkError); - expect(err.message).toMatch(/^Network error: failed to send request/); - - await destroyDBs([dbA]); - }); - - it('when SSH host is invalid', async () => { - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: serialId(), - localDir, - }); - await dbA.open(); - - const remoteUrl = 'git@foo.example.com:bar/sync-test.git'; - await createGitRemote(dbA.workingDir, remoteUrl); - - const err = await fetch(dbA.workingDir, { - remoteUrl, - connection: { - type: 'ssh', - publicKeyPath: path.resolve(userHome, '.ssh/invalid-test.pub'), - privateKeyPath: path.resolve(userHome, '.ssh/invalid-test'), - passPhrase: '', - }, - }).catch(error => error); - - expect(err).toBeInstanceOf(NetworkError); - expect(err.message).toMatch(/^Network error: failed to resolve address/); + expect(err.message).toMatch(/^Network error: Error: connect ECONNREFUSED/); await destroyDBs([dbA]); }); @@ -359,9 +300,7 @@ maybe(' fetch', () => { }).catch(error => error); expect(err).toBeInstanceOf(HTTPError401AuthorizationRequired); - expect(err.message).toMatch( - /^HTTP Error: 401 Authorization required: request failed with status code: 401/ - ); + expect(err.message).toMatch(/^HTTP Error: 401 Authorization required/); await destroyDBs([dbA]); }); @@ -376,81 +315,10 @@ maybe(' fetch', () => { const remoteUrl = remoteURLBase + 'test-private.git'; await createGitRemote(dbA.workingDir, remoteUrl); - let err; - for (let i = 0; i < 3; i++) { - // eslint-disable-next-line no-await-in-loop - err = await fetch(dbA.workingDir, { remoteUrl }).catch(error => error); - if ( - !err.message.startsWith( - 'HTTP Error: 401 Authorization required: too many redirects or authentication replays' - ) - ) { - break; - } - } - expect(err).toBeInstanceOf(HTTPError401AuthorizationRequired); - if (process.platform === 'win32') { - expect(err.message).toMatch( - /^HTTP Error: 401 Authorization required: request failed with status code: 401/ - ); - } - else { - expect(err.message).toMatch( - /^HTTP Error: 401 Authorization required: unexpected HTTP status code: 401/ - ); - } - - await destroyDBs([dbA]); - }); - - it.skip('when XXXX?', async () => { - // TODO: This will invoke on ubuntu - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: serialId(), - localDir, - }); - await dbA.open(); - - const remoteUrl = remoteURLBase + 'test-private.git'; - - await createGitRemote(dbA.workingDir, remoteUrl); - const err = await fetch(dbA.workingDir, { remoteUrl }).catch(error => error); - expect(err).toBeInstanceOf(HTTPError401AuthorizationRequired); - expect(err.message).toMatch( - /^HTTP Error: 401 Authorization required: remote credential provider returned an invalid cred type/ - ); - - await destroyDBs([dbA]); - }); - - it.skip('when invalid SSH key format', async () => { - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: serialId(), - localDir, - }); - await dbA.open(); - - // TODO: set SSH url for test - const remoteUrl = 'git@github.com:xxxxxxxxxxxxxxxxxx/sync-test.git'; - - await createGitRemote(dbA.workingDir, remoteUrl); - - const err = await fetch(dbA.workingDir, { - remoteUrl, - connection: { - type: 'ssh', - publicKeyPath: path.resolve(userHome, '.ssh/invalid-test.pub'), - privateKeyPath: path.resolve(userHome, '.ssh/invalid-test'), - passPhrase: '', - }, - }).catch(error => error); expect(err).toBeInstanceOf(HTTPError401AuthorizationRequired); - // TODO: How to invoke this error - expect(err.message).toMatch( - /^HTTP Error: 401 Authorization required: Failed to retrieve list of SSH authentication methods/ - ); + expect(err.message).toMatch(/^HTTP Error: 401 Authorization required/); await destroyDBs([dbA]); }); @@ -471,37 +339,7 @@ maybe(' fetch', () => { }).catch(error => error); expect(err).toBeInstanceOf(HTTPError401AuthorizationRequired); - expect(err.message).toMatch( - /^HTTP Error: 401 Authorization required: too many redirects or authentication replays/ - ); - - await destroyDBs([dbA]); - }); - - it('when invalid pair of url and SSH auth', async () => { - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: serialId(), - localDir, - }); - await dbA.open(); - - const remoteUrl = remoteURLBase + 'test-private.git'; - await createGitRemote(dbA.workingDir, remoteUrl); - - const err = await fetch(dbA.workingDir, { - remoteUrl, - connection: { - type: 'ssh', - publicKeyPath: path.resolve(userHome, '.ssh/invalid-test.pub'), - privateKeyPath: path.resolve(userHome, '.ssh/invalid-test'), - passPhrase: '', - }, - }).catch(error => error); - - expect(err).toBeInstanceOf(HTTPError401AuthorizationRequired); - expect(err.message).toMatch( - /^HTTP Error: 401 Authorization required: too many redirects or authentication replays/ - ); + expect(err.message).toMatch(/^HTTP Error: 401 Authorization required/); await destroyDBs([dbA]); }); @@ -523,25 +361,12 @@ maybe(' fetch', () => { connection: { type: 'github', personalAccessToken: token }, }).catch(error => error); expect(err).toBeInstanceOf(HTTPError404NotFound); - if (process.platform === 'win32') { - expect(err.message).toMatch( - /^HTTP Error: 404 Not Found: request failed with status code: 404/ - ); - } - else { - expect(err.message).toMatch( - /^HTTP Error: 404 Not Found: unexpected HTTP status code: 404/ - ); - } + expect(err.message).toMatch(/^HTTP Error: 404 Not Found/); await destroyDBs([dbA]); }); }); - describe.skip('throws CannotFetchError', () => { - // Other cases - }); - it('throws InvalidURLFormatError by createCredentialForGitHub', async () => { const dbA: GitDocumentDB = new GitDocumentDB({ dbName: serialId(), @@ -584,32 +409,25 @@ maybe(' fetch', () => { await destroyDBs([dbA]); }); - it('throws InvalidSSHKeyPathError', async () => { + it('throws InvalidAuthenticationTypeError', async () => { const dbA: GitDocumentDB = new GitDocumentDB({ dbName: serialId(), localDir, }); await dbA.open(); - const remoteUrl = 'git@github.com:xxxxxxxxxxxxxxxxxx/sync-test.git'; + const remoteUrl = remoteURLBase + 'test-private.git'; await createGitRemote(dbA.workingDir, remoteUrl); await expect( - fetch(dbA.workingDir, { - remoteUrl, - connection: { - type: 'ssh', - publicKeyPath: path.resolve(userHome, 'foo'), - privateKeyPath: path.resolve(userHome, 'bar'), - passPhrase: '', - }, - }) - ).rejects.toThrowError(InvalidSSHKeyPathError); + // @ts-ignore + fetch(dbA.workingDir, { remoteUrl, connection: { type: 'foo' } }) + ).rejects.toThrowError(InvalidAuthenticationTypeError); await destroyDBs([dbA]); }); - it('throws InvalidAuthenticationTypeError', async () => { + it('throws InvalidAuthenticationTypeError with SSH', async () => { const dbA: GitDocumentDB = new GitDocumentDB({ dbName: serialId(), localDir, @@ -621,7 +439,15 @@ maybe(' fetch', () => { await expect( // @ts-ignore - fetch(dbA.workingDir, { remoteUrl, connection: { type: 'foo' } }) + fetch(dbA.workingDir, { + remoteUrl, + connection: { + type: 'ssh', + publicKeyPath: path.resolve(userHome, '.ssh/invalid-test.pub'), + privateKeyPath: path.resolve(userHome, '.ssh/invalid-test'), + passPhrase: '', + }, + }) ).rejects.toThrowError(InvalidAuthenticationTypeError); await destroyDBs([dbA]); From 403bf82058e54f5f245fb4ae68eadfd713ffc6bc Mon Sep 17 00:00:00 2001 From: sosuisen Date: Mon, 2 Aug 2021 06:25:44 +0900 Subject: [PATCH 117/297] test: add test for remote-isomorphic-git --- test/plugin/clone.test.ts | 217 +++++--------------- test/plugin/fetch.test.ts | 19 +- test/plugin/push.test.ts | 414 +++++++------------------------------- test/remote_utils.ts | 3 - 4 files changed, 144 insertions(+), 509 deletions(-) diff --git a/test/plugin/clone.test.ts b/test/plugin/clone.test.ts index 13797dad..734fed54 100644 --- a/test/plugin/clone.test.ts +++ b/test/plugin/clone.test.ts @@ -172,10 +172,10 @@ maybe(' clone', () => { const remoteUrl = remoteURLBase + 'test-public.git'; fs.ensureDirSync(dbA.workingDir); - const cloneStub = sandbox.stub(nodegit.Clone, 'clone'); - cloneStub.onCall(0).rejects(new Error('failed to send request')); - cloneStub.onCall(1).rejects(new Error('failed to send request')); - cloneStub.onCall(2).rejects(new Error('failed to send request')); + const cloneStub = sandbox.stub(git, 'clone'); + cloneStub.onCall(0).rejects(new Error('connect EACCES')); + cloneStub.onCall(1).rejects(new Error('connect EACCES')); + cloneStub.onCall(2).rejects(new Error('connect EACCES')); cloneStub.onCall(3).resolves(undefined); const res = await clone(dbA.workingDir, { @@ -198,8 +198,8 @@ maybe(' clone', () => { const remoteUrl = remoteURLBase + 'test-public.git'; fs.ensureDirSync(dbA.workingDir); - const cloneStub = sandbox.stub(nodegit.Clone, 'clone'); - cloneStub.rejects(new Error('failed to send request')); + const cloneStub = sandbox.stub(git, 'clone'); + cloneStub.rejects(new Error('connect EACCES')); const res = await clone(dbA.workingDir, { remoteUrl, @@ -223,7 +223,7 @@ maybe(' clone', () => { await dbA.open(); expect(err).toBeInstanceOf(InvalidURLFormatError); - expect(err.message).toMatch(/^URL format is invalid: unsupported URL protocol/); + expect(err.message).toMatch(/^URL format is invalid: UrlParseError:/); await destroyDBs([dbA]); }); @@ -237,59 +237,36 @@ maybe(' clone', () => { fs.ensureDirSync(dbA.workingDir); const err = await clone(dbA.workingDir, { remoteUrl }).catch(error => error); expect(err).toBeInstanceOf(InvalidURLFormatError); - expect(err.message).toMatch(/^URL format is invalid: malformed URL/); + expect(err.message).toMatch(/^URL format is invalid: Error: getaddrinfo ENOTFOUND/); await destroyDBs([dbA]); }); - describe('throws NetworkError', () => { - it('when HTTP host is invalid', async () => { - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: serialId(), - localDir, - }); - const remoteUrl = 'https://foo.bar.example.com/gitddb-plugin/sync-test-invalid.git'; - fs.ensureDirSync(dbA.workingDir); - const err = await clone(dbA.workingDir, { remoteUrl }).catch(error => error); - expect(err).toBeInstanceOf(NetworkError); - expect(err.message).toMatch(/^Network error: failed to send request/); - - await destroyDBs([dbA]); + it('throws InvalidURLFormatError by checkFetch when HTTP host is invalid', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, }); + const remoteUrl = 'https://foo.bar.example.com/gitddb-plugin/sync-test-invalid.git'; + fs.ensureDirSync(dbA.workingDir); + const err = await clone(dbA.workingDir, { remoteUrl }).catch(error => error); + expect(err).toBeInstanceOf(InvalidURLFormatError); + expect(err.message).toMatch(/^URL format is invalid: Error: getaddrinfo ENOTFOUND/); + + await destroyDBs([dbA]); + }); + describe('throws NetworkError', () => { it('when IP address is invalid', async () => { const dbA: GitDocumentDB = new GitDocumentDB({ dbName: serialId(), localDir, }); - const remoteUrl = 'https://foo.bar.example.com/gitddb-plugin/sync-test-invalid.git'; + const remoteUrl = 'https://127.0.0.1/gitddb-plugin/sync-test-invalid.git'; fs.ensureDirSync(dbA.workingDir); const err = await clone(dbA.workingDir, { remoteUrl }).catch(error => error); expect(err).toBeInstanceOf(NetworkError); - expect(err.message).toMatch(/^Network error: failed to send request/); - - await destroyDBs([dbA]); - }); - - it('when SSH host is invalid', async () => { - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: serialId(), - localDir, - }); - const remoteUrl = 'git@foo.example.com:bar/sync-test.git'; - fs.ensureDirSync(dbA.workingDir); - const err = await clone(dbA.workingDir, { - remoteUrl, - connection: { - type: 'ssh', - publicKeyPath: path.resolve(userHome, '.ssh/invalid-test.pub'), - privateKeyPath: path.resolve(userHome, '.ssh/invalid-test'), - passPhrase: '', - }, - }).catch(error => error); - - expect(err).toBeInstanceOf(NetworkError); - expect(err.message).toMatch(/^Network error: failed to resolve address/); + expect(err.message).toMatch(/^Network error: Error: connect ECONNREFUSED/); await destroyDBs([dbA]); }); @@ -309,49 +286,12 @@ maybe(' clone', () => { }).catch(error => error); expect(err).toBeInstanceOf(HTTPError401AuthorizationRequired); - expect(err.message).toMatch( - /^HTTP Error: 401 Authorization required: request failed with status code: 401/ - ); + expect(err.message).toMatch(/^HTTP Error: 401 Authorization required/); await destroyDBs([dbA]); }); it('when connection setting not found', async () => { - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: serialId(), - localDir, - }); - const remoteUrl = remoteURLBase + 'test-private.git'; - fs.ensureDirSync(dbA.workingDir); - let err; - for (let i = 0; i < 3; i++) { - // eslint-disable-next-line no-await-in-loop - err = await clone(dbA.workingDir, { remoteUrl }).catch(error => error); - if ( - !err.message.startsWith( - 'HTTP Error: 401 Authorization required: too many redirects or authentication replays' - ) - ) { - break; - } - } - expect(err).toBeInstanceOf(HTTPError401AuthorizationRequired); - if (process.platform === 'win32') { - expect(err.message).toMatch( - /^HTTP Error: 401 Authorization required: request failed with status code: 401/ - ); - } - else { - expect(err.message).toMatch( - /^HTTP Error: 401 Authorization required: unexpected HTTP status code: 401/ - ); - } - - await destroyDBs([dbA]); - }); - - it.skip('when XXXX?', async () => { - // TODO: This will invoke on ubuntu const dbA: GitDocumentDB = new GitDocumentDB({ dbName: serialId(), localDir, @@ -360,36 +300,7 @@ maybe(' clone', () => { fs.ensureDirSync(dbA.workingDir); const err = await clone(dbA.workingDir, { remoteUrl }).catch(error => error); expect(err).toBeInstanceOf(HTTPError401AuthorizationRequired); - expect(err.message).toMatch( - /^HTTP Error: 401 Authorization required: remote credential provider returned an invalid cred type/ - ); - - await destroyDBs([dbA]); - }); - - it.skip('when invalid SSH key format', async () => { - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: serialId(), - localDir, - }); - // TODO: set SSH url for test - const remoteUrl = 'git@github.com:xxxxxxxxxxxxxxxxxx/sync-test.git'; - fs.ensureDirSync(dbA.workingDir); - const err = await clone(dbA.workingDir, { - remoteUrl, - connection: { - type: 'ssh', - publicKeyPath: path.resolve(userHome, '.ssh/invalid-test.pub'), - privateKeyPath: path.resolve(userHome, '.ssh/invalid-test'), - passPhrase: '', - }, - }).catch(error => error); - - expect(err).toBeInstanceOf(HTTPError401AuthorizationRequired); - // TODO: How to invoke this error - expect(err.message).toMatch( - /^HTTP Error: 401 Authorization required: Failed to retrieve list of SSH authentication methods/ - ); + expect(err.message).toMatch(/^HTTP Error: 401 Authorization required/); await destroyDBs([dbA]); }); @@ -407,34 +318,7 @@ maybe(' clone', () => { }).catch(error => error); expect(err).toBeInstanceOf(HTTPError401AuthorizationRequired); - expect(err.message).toMatch( - /^HTTP Error: 401 Authorization required: too many redirects or authentication replays/ - ); - - await destroyDBs([dbA]); - }); - - it('when invalid pair of url and SSH auth', async () => { - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: serialId(), - localDir, - }); - const remoteUrl = remoteURLBase + 'test-private.git'; - fs.ensureDirSync(dbA.workingDir); - const err = await clone(dbA.workingDir, { - remoteUrl, - connection: { - type: 'ssh', - publicKeyPath: path.resolve(userHome, '.ssh/invalid-test.pub'), - privateKeyPath: path.resolve(userHome, '.ssh/invalid-test'), - passPhrase: '', - }, - }).catch(error => error); - - expect(err).toBeInstanceOf(HTTPError401AuthorizationRequired); - expect(err.message).toMatch( - /^HTTP Error: 401 Authorization required: too many redirects or authentication replays/ - ); + expect(err.message).toMatch(/^HTTP Error: 401 Authorization required/); await destroyDBs([dbA]); }); @@ -453,16 +337,7 @@ maybe(' clone', () => { connection: { type: 'github', personalAccessToken: token }, }).catch(error => error); expect(err).toBeInstanceOf(HTTPError404NotFound); - if (process.platform === 'win32') { - expect(err.message).toMatch( - /^HTTP Error: 404 Not Found: request failed with status code: 404/ - ); - } - else { - expect(err.message).toMatch( - /^HTTP Error: 404 Not Found: unexpected HTTP status code: 404/ - ); - } + expect(err.message).toMatch(/^HTTP Error: 404 Not Found/); await destroyDBs([dbA]); }); @@ -508,40 +383,48 @@ maybe(' clone', () => { await destroyDBs([dbA]); }); - it('throws InvalidSSHKeyPathError', async () => { + it('throws InvalidAuthenticationTypeError', async () => { const dbA: GitDocumentDB = new GitDocumentDB({ dbName: serialId(), localDir, }); - const remoteUrl = 'git@github.com:xxxxxxxxxxxxxxxxxx/sync-test.git'; + const remoteUrl = remoteURLBase + 'test-private.git'; fs.ensureDirSync(dbA.workingDir); await expect( - clone(dbA.workingDir, { - remoteUrl, - connection: { - type: 'ssh', - publicKeyPath: path.resolve(userHome, 'foo'), - privateKeyPath: path.resolve(userHome, 'bar'), - passPhrase: '', - }, - }) - ).rejects.toThrowError(InvalidSSHKeyPathError); + // @ts-ignore + clone(dbA.workingDir, { remoteUrl, connection: { type: 'foo' } }) + ).rejects.toThrowError(InvalidAuthenticationTypeError); await destroyDBs([dbA]); }); - it('throws InvalidAuthenticationTypeError', async () => { + it('throws InvalidAuthenticationTypeError with SSH', async () => { const dbA: GitDocumentDB = new GitDocumentDB({ dbName: serialId(), localDir, }); - const remoteUrl = remoteURLBase + 'test-private.git'; + await dbA.open(); + + const remoteUrl = 'git@foo.example.com:bar/sync-test.git'; fs.ensureDirSync(dbA.workingDir); await expect( // @ts-ignore - clone(dbA.workingDir, { remoteUrl, connection: { type: 'foo' } }) + clone(dbA.workingDir, { + remoteUrl, + connection: { + type: 'ssh', + publicKeyPath: path.resolve(userHome, '.ssh/invalid-test.pub'), + privateKeyPath: path.resolve(userHome, '.ssh/invalid-test'), + passPhrase: '', + }, + }) ).rejects.toThrowError(InvalidAuthenticationTypeError); await destroyDBs([dbA]); }); + + describe('throws CannotConnectError', () => { + // NetworkError is thrown when network is not connected. + // CannotConnectError will be thrown when other unexpected cases. + }); }); diff --git a/test/plugin/fetch.test.ts b/test/plugin/fetch.test.ts index 0d85edc5..c5da10cf 100644 --- a/test/plugin/fetch.test.ts +++ b/test/plugin/fetch.test.ts @@ -17,7 +17,6 @@ import { InvalidAuthenticationTypeError, InvalidGitRemoteError, InvalidRepositoryURLError, - InvalidSSHKeyPathError, InvalidURLFormatError, NetworkError, } from 'git-documentdb-remote-errors'; @@ -206,6 +205,24 @@ maybe(' fetch', () => { await destroyDBs([dbA]); }); + it('throws InvalidGitRemoteError by NoRefspecError', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const stubPush = sandbox.stub(git, 'fetch'); + stubPush.rejects(new Error('NoRefspecError')); + + const remoteUrl = 'foo-bar'; + const err = await fetch(dbA.workingDir, { remoteUrl }).catch(error => error); + + expect(err).toBeInstanceOf(InvalidGitRemoteError); + + await destroyDBs([dbA]); + }); + it('throws InvalidURLFormat by fetch when http protocol is missing', async () => { const dbA: GitDocumentDB = new GitDocumentDB({ dbName: serialId(), diff --git a/test/plugin/push.test.ts b/test/plugin/push.test.ts index 95154c2a..64e06276 100644 --- a/test/plugin/push.test.ts +++ b/test/plugin/push.test.ts @@ -106,7 +106,6 @@ maybe(' push', () => { ); expect(err).toBeInstanceOf(InvalidGitRemoteError); - expect(err.message).toMatch(/^Invalid Git remote: remote 'origin' does not exist/); await destroyDBs([dbA]); }); @@ -119,6 +118,8 @@ maybe(' push', () => { }); const remoteUrl = remoteURLBase + serialId(); await dbA.open(); + await dbA.put({ name: 'fromA' }); + await createRemoteRepository(remoteUrl); await createGitRemote(dbA.workingDir, remoteUrl); const res = await push(dbA.workingDir, { @@ -143,6 +144,7 @@ maybe(' push', () => { connection: { type: 'github', personalAccessToken: token }, }); await dbA.open(); + await dbA.put({ name: 'fromA' }); // await createGitRemote(dbA.workingDir, remoteUrl); // Not need because cloned repository. const res = await push(dbA.workingDir, { @@ -168,6 +170,7 @@ maybe(' push', () => { connection: { type: 'github', personalAccessToken: token }, }); await dbA.open(); + await dbA.put({ name: 'fromA' }); await createGitRemote(dbA.workingDir, remoteUrl); const res = await push(dbA.workingDir, { @@ -186,36 +189,15 @@ maybe(' push', () => { }); const remoteUrl = remoteURLBase + serialId(); await dbA.open(); + await dbA.put({ name: 'fromA' }); await createRemoteRepository(remoteUrl); await createGitRemote(dbA.workingDir, remoteUrl); - let pushCounter = 0; - const stubOpen = sandbox.stub(nodegit.Repository, 'open'); - // Create fake Repository.open() that returns fake Remote by calling getRemote() - stubOpen.callsFake(async function (dir) { - const repos = await stubOpen.wrappedMethod(dir); // Call original nodegit.Repository.open(); - // @ts-ignore - repos.getRemote = () => { - return Promise.resolve({ - push: () => { - if (pushCounter < 3) { - pushCounter++; - return Promise.reject(new Error('failed to send request')); - } - pushCounter++; - return Promise.resolve(1); - }, - fetch: () => { - return Promise.resolve(undefined); - }, - disconnect: () => {}, - }); - }; - return repos; - }); - - sandbox.stub(git, 'resolveRef').resolves(undefined); - sandbox.stub(git, 'findMergeBase').resolves([undefined]); + const stubPush = sandbox.stub(git, 'push'); + stubPush.onCall(0).rejects(new Error('connect EACCES')); + stubPush.onCall(1).rejects(new Error('connect EACCES')); + stubPush.onCall(2).rejects(new Error('connect EACCES')); + stubPush.onCall(3).resolves(undefined); const res = await push(dbA.workingDir, { remoteUrl, @@ -224,57 +206,7 @@ maybe(' push', () => { expect(res).toBeUndefined(); - expect(pushCounter).toBe(4); - - await destroyDBs([dbA]); - }); - - it('after retrying validatePushResult()', async () => { - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: serialId(), - localDir, - }); - const remoteUrl = remoteURLBase + serialId(); - await dbA.open(); - await createRemoteRepository(remoteUrl); - await createGitRemote(dbA.workingDir, remoteUrl); - - let pushValidateCounter = 0; - const stubOpen = sandbox.stub(nodegit.Repository, 'open'); - // Create fake Repository.open() that returns fake Remote by calling getRemote() - stubOpen.callsFake(async function (dir) { - const repos = await stubOpen.wrappedMethod(dir); // Call original nodegit.Repository.open(); - // @ts-ignore - repos.getRemote = () => { - return Promise.resolve({ - push: () => { - return Promise.resolve(1); - }, - fetch: () => { - if (pushValidateCounter < 3) { - pushValidateCounter++; - return Promise.reject(new Error('foo')); - } - pushValidateCounter++; - return Promise.resolve(undefined); - }, - disconnect: () => {}, - }); - }; - return repos; - }); - - sandbox.stub(git, 'resolveRef').resolves(undefined); - sandbox.stub(git, 'findMergeBase').resolves([undefined]); - - const res = await push(dbA.workingDir, { - remoteUrl, - connection: { type: 'github', personalAccessToken: token }, - }).catch((error: Error) => error); - - expect(res).toBeUndefined(); - - expect(pushValidateCounter).toBe(4); + expect(stubPush.callCount).toBe(4); await destroyDBs([dbA]); }); @@ -287,32 +219,12 @@ maybe(' push', () => { }); const remoteUrl = remoteURLBase + serialId(); await dbA.open(); + await dbA.put({ name: 'fromA' }); await createRemoteRepository(remoteUrl); await createGitRemote(dbA.workingDir, remoteUrl); - let pushCounter = 0; - const stubOpen = sandbox.stub(nodegit.Repository, 'open'); - // Create fake Repository.open() that returns fake Remote by calling getRemote() - stubOpen.callsFake(async function (dir) { - const repos = await stubOpen.wrappedMethod(dir); // Call original nodegit.Repository.open(); - // @ts-ignore - repos.getRemote = () => { - return Promise.resolve({ - push: () => { - pushCounter++; - return Promise.reject(new Error('failed to send request')); - }, - fetch: () => { - return Promise.resolve(undefined); - }, - disconnect: () => {}, - }); - }; - return repos; - }); - - sandbox.stub(git, 'resolveRef').resolves(undefined); - sandbox.stub(git, 'findMergeBase').resolves([undefined]); + const stubPush = sandbox.stub(git, 'push'); + stubPush.rejects(new Error('connect EACCES')); const res = await push(dbA.workingDir, { remoteUrl, @@ -321,65 +233,41 @@ maybe(' push', () => { expect(res).toBeInstanceOf(NetworkError); - expect(pushCounter).toBe(4); + expect(stubPush.callCount).toBe(4); await destroyDBs([dbA]); }); - it('throws CannotConnectError after retrying validatePushResult()', async () => { + it('throws InvalidURLFormat by push when http protocol is missing', async () => { const dbA: GitDocumentDB = new GitDocumentDB({ dbName: serialId(), localDir, }); - const remoteUrl = remoteURLBase + serialId(); await dbA.open(); - await createRemoteRepository(remoteUrl); - await createGitRemote(dbA.workingDir, remoteUrl); - - let pushValidateCounter = 0; - const stubOpen = sandbox.stub(nodegit.Repository, 'open'); - // Create fake Repository.open() that returns fake Remote by calling getRemote() - stubOpen.callsFake(async function (dir) { - const repos = await stubOpen.wrappedMethod(dir); // Call original nodegit.Repository.open(); - // @ts-ignore - repos.getRemote = () => { - return Promise.resolve({ - push: () => { - return Promise.resolve(1); - }, - fetch: () => { - pushValidateCounter++; - return Promise.reject(new Error('foo')); - }, - disconnect: () => {}, - }); - }; - return repos; - }); - sandbox.stub(git, 'resolveRef').resolves(undefined); - sandbox.stub(git, 'findMergeBase').resolves([undefined]); + const remoteUrl = 'foo-bar'; + await createGitRemote(dbA.workingDir, remoteUrl); - const res = await push(dbA.workingDir, { + // type is 'none' + const err = await push(dbA.workingDir, { remoteUrl, - connection: { type: 'github', personalAccessToken: token }, - }).catch((error: Error) => error); - - expect(res).toBeInstanceOf(CannotConnectError); + connection: { type: 'none' }, + }).catch(error => error); - expect(pushValidateCounter).toBe(4); + expect(err).toBeInstanceOf(InvalidURLFormatError); + expect(err.message).toMatch(/^URL format is invalid: UrlParseError:/); await destroyDBs([dbA]); }); - it('throws InvalidURLFormat by push when http protocol is missing', async () => { + it('throws InvalidURLFormatError by push when URL is malformed', async () => { const dbA: GitDocumentDB = new GitDocumentDB({ dbName: serialId(), localDir, }); await dbA.open(); - const remoteUrl = 'foo-bar'; + const remoteUrl = 'https://foo.example.com:xxxx'; await createGitRemote(dbA.workingDir, remoteUrl); const err = await push(dbA.workingDir, { @@ -388,19 +276,19 @@ maybe(' push', () => { }).catch(error => error); expect(err).toBeInstanceOf(InvalidURLFormatError); - expect(err.message).toMatch(/^URL format is invalid: unsupported URL protocol/); + expect(err.message).toMatch(/^URL format is invalid: Error: getaddrinfo ENOTFOUND/); await destroyDBs([dbA]); }); - it('throws InvalidURLFormatError by push when URL is malformed', async () => { + it('throws InvalidURLFormatError by checkFetch when HTTP host is invalid', async () => { const dbA: GitDocumentDB = new GitDocumentDB({ dbName: serialId(), localDir, }); await dbA.open(); - const remoteUrl = 'https://foo.example.com:xxxx'; + const remoteUrl = 'https://foo.bar.example.com/gitddb-plugin/sync-test-invalid.git'; await createGitRemote(dbA.workingDir, remoteUrl); const err = await push(dbA.workingDir, { @@ -409,33 +297,12 @@ maybe(' push', () => { }).catch(error => error); expect(err).toBeInstanceOf(InvalidURLFormatError); - expect(err.message).toMatch(/^URL format is invalid: malformed URL/); + expect(err.message).toMatch(/^URL format is invalid: Error: getaddrinfo ENOTFOUND/); await destroyDBs([dbA]); }); describe('throws NetworkError', () => { - it('when HTTP host is invalid', async () => { - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: serialId(), - localDir, - }); - await dbA.open(); - - const remoteUrl = 'https://foo.bar.example.com/gitddb-plugin/sync-test-invalid.git'; - await createGitRemote(dbA.workingDir, remoteUrl); - - const err = await push(dbA.workingDir, { - remoteUrl, - connection: { type: 'none' }, - }).catch(error => error); - - expect(err).toBeInstanceOf(NetworkError); - expect(err.message).toMatch(/^Network error: failed to send request/); - - await destroyDBs([dbA]); - }); - it('when IP address is invalid', async () => { const dbA: GitDocumentDB = new GitDocumentDB({ dbName: serialId(), @@ -454,33 +321,7 @@ maybe(' push', () => { }).catch(error => error); expect(err).toBeInstanceOf(NetworkError); - expect(err.message).toMatch(/^Network error: failed to send request/); - - await destroyDBs([dbA]); - }); - - it('when SSH host is invalid', async () => { - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: serialId(), - localDir, - }); - await dbA.open(); - - const remoteUrl = 'git@foo.example.com:bar/sync-test.git'; - await createGitRemote(dbA.workingDir, remoteUrl); - - const err = await push(dbA.workingDir, { - remoteUrl, - connection: { - type: 'ssh', - publicKeyPath: path.resolve(userHome, '.ssh/invalid-test.pub'), - privateKeyPath: path.resolve(userHome, '.ssh/invalid-test'), - passPhrase: '', - }, - }).catch(error => error); - - expect(err).toBeInstanceOf(NetworkError); - expect(err.message).toMatch(/^Network error: failed to resolve address/); + expect(err.message).toMatch(/^Network error: Error: connect ECONNREFUSED/); await destroyDBs([dbA]); }); @@ -503,9 +344,7 @@ maybe(' push', () => { }).catch(error => error); expect(err).toBeInstanceOf(HTTPError401AuthorizationRequired); - expect(err.message).toMatch( - /^HTTP Error: 401 Authorization required: request failed with status code: 401/ - ); + expect(err.message).toMatch(/^HTTP Error: 401 Authorization required/); await destroyDBs([dbA]); }); @@ -520,79 +359,10 @@ maybe(' push', () => { const remoteUrl = remoteURLBase + 'test-public.git'; await createGitRemote(dbA.workingDir, remoteUrl); - let err; - for (let i = 0; i < 3; i++) { - // eslint-disable-next-line no-await-in-loop - err = await push(dbA.workingDir, { remoteUrl }).catch(error => error); - if ( - !err.message.startsWith( - 'HTTP Error: 401 Authorization required: too many redirects or authentication replays' - ) - ) { - break; - } - } - expect(err).toBeInstanceOf(HTTPError401AuthorizationRequired); - if (process.platform === 'win32') { - expect(err.message).toMatch( - /^HTTP Error: 401 Authorization required: request failed with status code: 401/ - ); - } - else { - expect(err.message).toMatch( - /^HTTP Error: 401 Authorization required: unexpected HTTP status code: 401/ - ); - } - - await destroyDBs([dbA]); - }); - - it.skip('when XXXX?', async () => { - // TODO: This will invoke on ubuntu - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: serialId(), - localDir, - }); - await dbA.open(); - - const remoteUrl = remoteURLBase + 'test-private.git'; - await createGitRemote(dbA.workingDir, remoteUrl); - const err = await push(dbA.workingDir, { remoteUrl }).catch(error => error); - expect(err).toBeInstanceOf(HTTPError401AuthorizationRequired); - expect(err.message).toMatch( - /^HTTP Error: 401 Authorization required: remote credential provider returned an invalid cred type/ - ); - - await destroyDBs([dbA]); - }); - - it.skip('when invalid SSH key format', async () => { - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: serialId(), - localDir, - }); - await dbA.open(); - - // TODO: set SSH url for test - const remoteUrl = 'git@github.com:xxxxxxxxxxxxxxxxxx/sync-test.git'; - await createGitRemote(dbA.workingDir, remoteUrl); - - const err = await push(dbA.workingDir, { - remoteUrl, - connection: { - type: 'ssh', - publicKeyPath: path.resolve(userHome, '.ssh/invalid-test.pub'), - privateKeyPath: path.resolve(userHome, '.ssh/invalid-test'), - passPhrase: '', - }, - }).catch(error => error); expect(err).toBeInstanceOf(HTTPError401AuthorizationRequired); - // TODO: How to invoke this error - expect(err.message).toMatch( - /^HTTP Error: 401 Authorization required: Failed to retrieve list of SSH authentication methods/ - ); + expect(err.message).toMatch(/^HTTP Error: 401 Authorization required/); await destroyDBs([dbA]); }); @@ -613,37 +383,7 @@ maybe(' push', () => { }).catch(error => error); expect(err).toBeInstanceOf(HTTPError401AuthorizationRequired); - expect(err.message).toMatch( - /^HTTP Error: 401 Authorization required: too many redirects or authentication replays/ - ); - - await destroyDBs([dbA]); - }); - - it('when invalid pair of url and SSH auth', async () => { - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: serialId(), - localDir, - }); - await dbA.open(); - - const remoteUrl = remoteURLBase + 'test-private.git'; - await createGitRemote(dbA.workingDir, remoteUrl); - - const err = await push(dbA.workingDir, { - remoteUrl, - connection: { - type: 'ssh', - publicKeyPath: path.resolve(userHome, '.ssh/invalid-test.pub'), - privateKeyPath: path.resolve(userHome, '.ssh/invalid-test'), - passPhrase: '', - }, - }).catch(error => error); - - expect(err).toBeInstanceOf(HTTPError401AuthorizationRequired); - expect(err.message).toMatch( - /^HTTP Error: 401 Authorization required: too many redirects or authentication replays/ - ); + expect(err.message).toMatch(/^HTTP Error: 401 Authorization required/); await destroyDBs([dbA]); }); @@ -665,25 +405,12 @@ maybe(' push', () => { connection: { type: 'github', personalAccessToken: token }, }).catch(error => error); expect(err).toBeInstanceOf(HTTPError404NotFound); - if (process.platform === 'win32') { - expect(err.message).toMatch( - /^HTTP Error: 404 Not Found: request failed with status code: 404/ - ); - } - else { - expect(err.message).toMatch( - /^HTTP Error: 404 Not Found: unexpected HTTP status code: 404/ - ); - } + expect(err.message).toMatch(/^HTTP Error: 404 Not Found/); await destroyDBs([dbA]); }); }); - describe.skip('throws CannotPushError', () => { - // Other cases - }); - it('throws InvalidURLFormatError by createCredentialForGitHub', async () => { const dbA: GitDocumentDB = new GitDocumentDB({ dbName: serialId(), @@ -726,32 +453,25 @@ maybe(' push', () => { await destroyDBs([dbA]); }); - it('throws InvalidSSHKeyPathError', async () => { + it('throws InvalidAuthenticationTypeError', async () => { const dbA: GitDocumentDB = new GitDocumentDB({ dbName: serialId(), localDir, }); await dbA.open(); - const remoteUrl = 'git@github.com:xxxxxxxxxxxxxxxxxx/sync-test.git'; + const remoteUrl = remoteURLBase + 'test-private.git'; await createGitRemote(dbA.workingDir, remoteUrl); await expect( - push(dbA.workingDir, { - remoteUrl, - connection: { - type: 'ssh', - publicKeyPath: path.resolve(userHome, 'foo'), - privateKeyPath: path.resolve(userHome, 'bar'), - passPhrase: '', - }, - }) - ).rejects.toThrowError(InvalidSSHKeyPathError); + // @ts-ignore + push(dbA.workingDir, { remoteUrl, connection: { type: 'foo' } }) + ).rejects.toThrowError(InvalidAuthenticationTypeError); await destroyDBs([dbA]); }); - it('throws InvalidAuthenticationTypeError', async () => { + it('throws InvalidAuthenticationTypeError with SSH', async () => { const dbA: GitDocumentDB = new GitDocumentDB({ dbName: serialId(), localDir, @@ -763,7 +483,15 @@ maybe(' push', () => { await expect( // @ts-ignore - push(dbA.workingDir, { remoteUrl, connection: { type: 'foo' } }) + push(dbA.workingDir, { + remoteUrl, + connection: { + type: 'ssh', + publicKeyPath: path.resolve(userHome, '.ssh/invalid-test.pub'), + privateKeyPath: path.resolve(userHome, '.ssh/invalid-test'), + passPhrase: '', + }, + }) ).rejects.toThrowError(InvalidAuthenticationTypeError); await destroyDBs([dbA]); @@ -786,17 +514,7 @@ maybe(' push', () => { connection: { type: 'github', personalAccessToken: token }, }).catch(error => error); expect(err).toBeInstanceOf(HTTPError403Forbidden); - - if (process.platform === 'win32') { - expect(err.message).toMatch( - /^HTTP Error: 403 Forbidden: request failed with status code: 403/ - ); - } - else { - expect(err.message).toMatch( - /^HTTP Error: 403 Forbidden: unexpected HTTP status code: 403/ - ); - } + expect(err.message).toMatch(/^HTTP Error: 403 Forbidden/); await destroyDBs([dbA]); }); @@ -804,12 +522,20 @@ maybe(' push', () => { describe('throws UnfetchedCommitExistsError', () => { it('when unfetched commit exists', async () => { + console.log('#start'); const [dbA, dbB, syncA, syncB] = await createClonedDatabases( remoteURLBase, localDir, - serialId + serialId, + { + connection: { + type: 'github', + personalAccessToken: token, + engine: 'isomorphic-git', + }, + } ); - + console.log('#end'); await dbB.put({ name: 'foo' }); await syncB.tryPush(); @@ -833,7 +559,11 @@ maybe(' push', () => { }); const options: RemoteOptions = { remoteUrl: remoteURL, - connection: { type: 'github', personalAccessToken: token }, + connection: { + type: 'github', + personalAccessToken: token, + engine: 'isomorphic-git', + }, }; await dbA.open(); const syncA = await dbA.sync(options); @@ -854,11 +584,19 @@ maybe(' push', () => { Promise.all([ push(dbA.workingDir, { remoteUrl: syncA.remoteURL, - connection: { type: 'github', personalAccessToken: token }, + connection: { + type: 'github', + personalAccessToken: token, + engine: 'isomorphic-git', + }, }), push(dbB.workingDir, { remoteUrl: syncB.remoteURL, - connection: { type: 'github', personalAccessToken: token }, + connection: { + type: 'github', + personalAccessToken: token, + engine: 'isomorphic-git', + }, }), ]) ).rejects.toThrowError(UnfetchedCommitExistsError); diff --git a/test/remote_utils.ts b/test/remote_utils.ts index fd8a235e..965eccc2 100644 --- a/test/remote_utils.ts +++ b/test/remote_utils.ts @@ -224,10 +224,8 @@ export async function createClonedDatabases ( options.remoteUrl ??= remoteURL; options.connection ??= { type: 'github', personalAccessToken: token }; options.includeCommits ??= true; - await dbA.open(); await dbA.sync(options); - const dbNameB = serialId(); const dbB: GitDocumentDB = new GitDocumentDB({ dbName: dbNameB, @@ -237,7 +235,6 @@ export async function createClonedDatabases ( // Clone dbA await dbB.open(); await dbB.sync(options); - const remoteA = dbA.getSync(remoteURL); const remoteB = dbB.getSync(remoteURL); From f51f0b5dd492ceacbfc8e9f18cbeb0c45300dded Mon Sep 17 00:00:00 2001 From: sosuisen Date: Mon, 2 Aug 2021 06:26:22 +0900 Subject: [PATCH 118/297] fix: set remote-isomorphic-git as default RemoteEngine --- src/git_documentdb.ts | 11 +++++++ src/plugin/remote-isomorphic-git.ts | 19 ++++++----- src/remote/sync.ts | 49 +++++++++++++++++++++++------ 3 files changed, 63 insertions(+), 16 deletions(-) diff --git a/src/git_documentdb.ts b/src/git_documentdb.ts index 45d651f9..c09f4288 100644 --- a/src/git_documentdb.ts +++ b/src/git_documentdb.ts @@ -68,6 +68,8 @@ import { CRUDInterface } from './types_crud_interface'; import { CollectionInterface, ICollection } from './types_collection'; import { blobToJsonDoc, readLatestBlob } from './crud/blob'; +import * as remote_isomorphic_git from './plugin/remote-isomorphic-git'; + /** * Get database ID * @@ -348,6 +350,15 @@ export class GitDocumentDB namePrefix: options?.namePrefix ?? '', }; this._rootCollection = new Collection(this, '', undefined, collectionOptions); + + // @ts-ignore + RemoteEngine[remote_isomorphic_git.name] = {}; + Object.keys(remote_isomorphic_git).forEach(function (id) { + // Set to Remote object + // @ts-ignore + // eslint-disable-next-line import/namespace + RemoteEngine[remote_isomorphic_git.name][id] = remote_isomorphic_git[id]; + }); } /*********************************************** diff --git a/src/plugin/remote-isomorphic-git.ts b/src/plugin/remote-isomorphic-git.ts index b63d955d..21df7954 100644 --- a/src/plugin/remote-isomorphic-git.ts +++ b/src/plugin/remote-isomorphic-git.ts @@ -146,7 +146,7 @@ export async function clone ( let error = ''; if (res instanceof Error) { - error = res.message; + error = res.toString(); } else { break; @@ -350,6 +350,8 @@ export async function fetch ( remoteOptions.retryInterval ??= NETWORK_RETRY_INTERVAL; const fetchOption: any = { + fs, + dir: workingDir, http: httpClient, url: remoteOptions.remoteUrl!, }; @@ -364,7 +366,7 @@ export async function fetch ( let error = ''; if (res instanceof Error) { - error = res.message; + error = res.toString(); } else { break; @@ -455,17 +457,20 @@ export async function push ( throw new InvalidGitRemoteError(`remote '${remoteName}' does not exist`); } - const localBranch = 'refs/heads/' + localBranchName; - const remoteBranch = 'refs/heads/' + remoteBranchName; + // const localBranch = 'refs/heads/' + localBranchName; + // const remoteBranch = 'refs/heads/' + remoteBranchName; remoteOptions.retry ??= NETWORK_RETRY; remoteOptions.retryInterval ??= NETWORK_RETRY_INTERVAL; const pushOption: any = { + fs, + dir: workingDir, http: httpClient, url: remoteOptions.remoteUrl!, - ref: localBranch, - remoteRef: remoteBranch, + remote: remoteName, + ref: localBranchName, + remoteRef: remoteBranchName, }; const cred = createCredentialCallback(remoteOptions); if (cred) { @@ -478,7 +483,7 @@ export async function push ( let error = ''; if (res instanceof Error) { - error = res.message; + error = res.toString(); } else { break; diff --git a/src/remote/sync.ts b/src/remote/sync.ts index 5697755c..7b767779 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -14,6 +14,7 @@ import crypto from 'crypto'; import git from 'isomorphic-git'; import fs from 'fs-extra'; import * as RemoteEngineError from 'git-documentdb-remote-errors'; +import { name as default_engine_name } from '../plugin/remote-isomorphic-git'; import { CONSOLE_STYLE, sleep } from '../utils'; import { Err } from '../error'; @@ -254,7 +255,7 @@ export class Sync implements SyncInterface { /** * Remote Engine */ - private _engine = 'iso'; + private _engine = default_engine_name; get engine (): string { return this._engine; } @@ -407,7 +408,7 @@ export class Sync implements SyncInterface { this._remoteName = encodeToGitRemoteName(this.remoteURL); - this._engine = this._options.connection?.engine ?? 'iso'; + this._engine = this._options.connection?.engine ?? default_engine_name; } /*********************************************** @@ -560,13 +561,43 @@ export class Sync implements SyncInterface { value: `refs/heads/${this._gitDDB.defaultBranch}`, }); } - else if (this._options.syncDirection === 'push') { - this._gitDDB.logger.debug('upstream_branch exists. tryPush..'); - syncResult = await this.tryPush(); - } - else if (this._options.syncDirection === 'both') { - this._gitDDB.logger.debug('upstream_branch exists. trySync..'); - syncResult = await this.trySync(); + else { + const branchRemote = await git.getConfig({ + fs, + dir: this._gitDDB.workingDir, + path: `branch.${this._gitDDB.defaultBranch}.remote`, + }); + if (branchRemote === undefined) { + await git.setConfig({ + fs, + dir: this._gitDDB.workingDir, + path: `branch.${this._gitDDB.defaultBranch}.remote`, + value: this.remoteName, + }); + } + + const branchMerge = await git.getConfig({ + fs, + dir: this._gitDDB.workingDir, + path: `branch.${this._gitDDB.defaultBranch}.merge`, + }); + if (branchMerge === undefined) { + await git.setConfig({ + fs, + dir: this._gitDDB.workingDir, + path: `branch.${this._gitDDB.defaultBranch}.merge`, + value: `refs/heads/${this._gitDDB.defaultBranch}`, + }); + } + + if (this._options.syncDirection === 'push') { + this._gitDDB.logger.debug('upstream_branch exists. tryPush..'); + syncResult = await this.tryPush(); + } + else if (this._options.syncDirection === 'both') { + this._gitDDB.logger.debug('upstream_branch exists. trySync..'); + syncResult = await this.trySync(); + } } if (this._options.live) { From 7e35a9358a9ea30a54cb9a37cbfaa03c7cc370c7 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Mon, 2 Aug 2021 14:55:32 +0900 Subject: [PATCH 119/297] fix: add Remote origin after clone --- src/plugin/remote-isomorphic-git.ts | 24 +++++++++++------------- test/plugin/clone.test.ts | 20 +++++++++++++++++++- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/src/plugin/remote-isomorphic-git.ts b/src/plugin/remote-isomorphic-git.ts index 21df7954..90c13de0 100644 --- a/src/plugin/remote-isomorphic-git.ts +++ b/src/plugin/remote-isomorphic-git.ts @@ -181,24 +181,22 @@ export async function clone ( await sleep(remoteOptions.retryInterval!); } - // Rewrite remote - - // default is 'origin' + // Add remote + // (default is 'origin') if (remoteName !== 'origin') { - // Add remote - await git.setConfig({ + await git.addRemote({ fs, dir: workingDir, - path: `remote.${remoteName}.url`, - value: remoteOptions.remoteUrl!, - }); - await git.setConfig({ - fs, - dir: workingDir, - path: `remote.${remoteName}.fetch`, - value: `+refs/heads/*:refs/remotes/${remoteName}/*`, + remote: 'origin', + url: remoteOptions.remoteUrl!, }); } + await git.addRemote({ + fs, + dir: workingDir, + remote: remoteName, + url: remoteOptions.remoteUrl!, + }); } /** diff --git a/test/plugin/clone.test.ts b/test/plugin/clone.test.ts index 734fed54..2ff67a52 100644 --- a/test/plugin/clone.test.ts +++ b/test/plugin/clone.test.ts @@ -130,7 +130,7 @@ maybe(' clone', () => { await destroyDBs([dbA]); }); - it('set another remote name', async () => { + it('set default and another remote name', async () => { const dbA: GitDocumentDB = new GitDocumentDB({ dbName: serialId(), localDir, @@ -147,6 +147,20 @@ maybe(' clone', () => { ).catch(error => error); expect(res).toBeUndefined(); + const urlDefault = await git.getConfig({ + fs, + dir: dbA.workingDir, + path: 'remote.origin.url', + }); + expect(urlDefault).toBe(remoteUrl); + + const fetchDefault = await git.getConfig({ + fs, + dir: dbA.workingDir, + path: 'remote.origin.fetch', + }); + expect(fetchDefault).toBe(`+refs/heads/*:refs/remotes/origin/*`); + const url = await git.getConfig({ fs, dir: dbA.workingDir, @@ -178,6 +192,10 @@ maybe(' clone', () => { cloneStub.onCall(2).rejects(new Error('connect EACCES')); cloneStub.onCall(3).resolves(undefined); + // Skip addRemote because repository is empty + const remoteStub = sandbox.stub(git, 'addRemote'); + remoteStub.resolves(); + const res = await clone(dbA.workingDir, { remoteUrl, connection: { type: 'github' }, From 41e406efdd1f8bfa6f90d4d93e20cf2ad0045673 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Mon, 2 Aug 2021 18:20:17 +0900 Subject: [PATCH 120/297] fix: remove --no-parallel from mocha-unit --- package-lock.json | 6 +++--- package.json | 6 ++---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0aaf3422..45b221bf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3524,9 +3524,9 @@ "dev": true }, "git-documentdb-plugin-remote-nodegit": { - "version": "1.0.0-beta.5", - "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.0-beta.5.tgz", - "integrity": "sha512-Lmodd7K6q4WwYMGe/C/TbxhrbLvjxNwi3xk4rv0VQsOCcBsevw7c97E4OpqNx5JNLZXltXnLBkxAQpVR9ewq6w==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.0.tgz", + "integrity": "sha512-fZLcid1l2aMZ1aGHJC3/H0tDY3wrpK1R2YjuHGODlRsxJmupFUa/+63P+4qUepHc+HcmuHP3n8ucbxamlGQThQ==", "dev": true, "requires": { "git-documentdb-remote-errors": "^1.0.3", diff --git a/package.json b/package.json index fc8e8d68..2e114355 100644 --- a/package.json +++ b/package.json @@ -11,12 +11,10 @@ "build": "rm -rf dist/* && npm run lint && tsc --project src/tsconfig.json", "doc": "npm run build && npm run api-extractor && npm run crlf", "mocha": "rm -rf test/database* && npx cross-env TS_NODE_FILES=true TS_NODE_PROJECT=tsconfig.mocha.json mocha", - "mocha-unit": "rm -rf test/database* && npx cross-env TS_NODE_FILES=true TS_NODE_PROJECT=tsconfig.mocha.json mocha --retries 0 --no-parallel", + "mocha-unit": "rm -rf test/database* && npx cross-env TS_NODE_FILES=true TS_NODE_PROJECT=tsconfig.mocha.json mocha --retries 0", "compile-tests": "tsc --project test/tsconfig.json", "rm-test-db": "rm -rf test/database*", "test": "npm run rm-test-db && npx nyc npm run mocha \"test/**/*.test.ts\" && npm run rm-test-db", - "test-noretry": "npm run rm-test-db && npx nyc npm run mocha-noretry \"test/**/*.test.ts\" && npm run rm-test-db", - "test-serial": "npm run rm-test-db && npx nyc npm run mocha-serial \"test/**/*.test.ts\" && npm run rm-test-db", "upload-coverage": "npx coveralls < coverage/lcov.info", "prepare": "", "prepublishOnly": "npm run build && npm test", @@ -62,7 +60,7 @@ "eslint-config-standardize": "^0.7.1", "eslint-plugin-prettierx": "^0.14.0", "expect": "^27.0.2", - "git-documentdb-plugin-remote-nodegit": "^1.0.0-beta.5", + "git-documentdb-plugin-remote-nodegit": "^1.0.0", "mocha": "^8.3.2", "nyc": "^15.1.0", "parse-git-config": "^3.0.0", From 2a6606a9e11d88d5280a3720eaf17610e1b19960 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Mon, 2 Aug 2021 18:25:59 +0900 Subject: [PATCH 121/297] test: fix location of stub --- test/remote_base/sync.ts | 48 ++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/test/remote_base/sync.ts b/test/remote_base/sync.ts index 07098cf9..ec2a2673 100644 --- a/test/remote_base/sync.ts +++ b/test/remote_base/sync.ts @@ -347,9 +347,6 @@ export const syncBase = ( const dbName = serialId(); const remoteURL = remoteURLBase + serialId; - const stubCheckFetch = sandbox.stub(RemoteEngine[connection.engine!], 'checkFetch'); - stubCheckFetch.onFirstCall().rejects(new RemoteEngineErr.InvalidURLFormatError('')); - const gitDDB: GitDocumentDB = new GitDocumentDB({ dbName, localDir, @@ -359,6 +356,9 @@ export const syncBase = ( remoteUrl: remoteURL, connection, }; + const stubCheckFetch = sandbox.stub(RemoteEngine[connection.engine!], 'checkFetch'); + stubCheckFetch.onFirstCall().rejects(new RemoteEngineErr.InvalidURLFormatError('')); + const sync = new Sync(gitDDB, options); await expect(sync.init()).rejects.toThrowError(RemoteErr.InvalidURLFormatError); await gitDDB.destroy(); @@ -368,11 +368,6 @@ export const syncBase = ( const dbName = serialId(); const remoteURL = remoteURLBase + serialId(); - const stubCheckFetch = sandbox.stub(RemoteEngine[connection.engine!], 'checkFetch'); - stubCheckFetch - .onFirstCall() - .rejects(new RemoteEngineErr.InvalidRepositoryURLError('')); - const gitDDB: GitDocumentDB = new GitDocumentDB({ dbName, localDir, @@ -382,6 +377,11 @@ export const syncBase = ( remoteUrl: remoteURL, connection, }; + const stubCheckFetch = sandbox.stub(RemoteEngine[connection.engine!], 'checkFetch'); + stubCheckFetch + .onFirstCall() + .rejects(new RemoteEngineErr.InvalidRepositoryURLError('')); + const sync = new Sync(gitDDB, options); await expect(sync.init()).rejects.toThrowError(RemoteErr.InvalidRepositoryURLError); await gitDDB.destroy(); @@ -391,9 +391,6 @@ export const syncBase = ( const dbName = serialId(); const remoteURL = remoteURLBase + serialId(); - const stubCheckFetch = sandbox.stub(RemoteEngine[connection.engine!], 'checkFetch'); - stubCheckFetch.onFirstCall().rejects(new RemoteEngineErr.InvalidSSHKeyPathError()); - const gitDDB: GitDocumentDB = new GitDocumentDB({ dbName, localDir, @@ -403,6 +400,9 @@ export const syncBase = ( remoteUrl: remoteURL, connection, }; + const stubCheckFetch = sandbox.stub(RemoteEngine[connection.engine!], 'checkFetch'); + stubCheckFetch.onFirstCall().rejects(new RemoteEngineErr.InvalidSSHKeyPathError()); + const sync = new Sync(gitDDB, options); await expect(sync.init()).rejects.toThrowError(RemoteErr.InvalidSSHKeyPathError); await gitDDB.destroy(); @@ -412,11 +412,6 @@ export const syncBase = ( const dbName = serialId(); const remoteURL = remoteURLBase + serialId(); - const stubCheckFetch = sandbox.stub(RemoteEngine[connection.engine!], 'checkFetch'); - stubCheckFetch - .onFirstCall() - .rejects(new RemoteEngineErr.InvalidAuthenticationTypeError('')); - const gitDDB: GitDocumentDB = new GitDocumentDB({ dbName, localDir, @@ -426,6 +421,11 @@ export const syncBase = ( remoteUrl: remoteURL, connection, }; + const stubCheckFetch = sandbox.stub(RemoteEngine[connection.engine!], 'checkFetch'); + stubCheckFetch + .onFirstCall() + .rejects(new RemoteEngineErr.InvalidAuthenticationTypeError('')); + const sync = new Sync(gitDDB, options); await expect(sync.init()).rejects.toThrowError( RemoteErr.InvalidAuthenticationTypeError @@ -437,11 +437,6 @@ export const syncBase = ( const dbName = serialId(); const remoteURL = remoteURLBase + serialId(); - const stubCheckFetch = sandbox.stub(RemoteEngine[connection.engine!], 'checkFetch'); - stubCheckFetch - .onFirstCall() - .rejects(new RemoteEngineErr.HTTPError401AuthorizationRequired('')); - const gitDDB: GitDocumentDB = new GitDocumentDB({ dbName, localDir, @@ -451,6 +446,11 @@ export const syncBase = ( remoteUrl: remoteURL, connection, }; + const stubCheckFetch = sandbox.stub(RemoteEngine[connection.engine!], 'checkFetch'); + stubCheckFetch + .onFirstCall() + .rejects(new RemoteEngineErr.HTTPError401AuthorizationRequired('')); + const sync = new Sync(gitDDB, options); await expect(sync.init()).rejects.toThrowError( RemoteErr.HTTPError401AuthorizationRequired @@ -462,9 +462,6 @@ export const syncBase = ( const dbName = serialId(); const remoteURL = remoteURLBase + serialId(); - const stubCheckFetch = sandbox.stub(RemoteEngine[connection.engine!], 'checkFetch'); - stubCheckFetch.rejects(new RemoteEngineErr.NetworkError('')); - const gitDDB: GitDocumentDB = new GitDocumentDB({ dbName, localDir, @@ -474,6 +471,9 @@ export const syncBase = ( remoteUrl: remoteURL, connection, }; + const stubCheckFetch = sandbox.stub(RemoteEngine[connection.engine!], 'checkFetch'); + stubCheckFetch.rejects(new RemoteEngineErr.NetworkError('')); + const sync = new Sync(gitDDB, options); await expect(sync.init()).rejects.toThrowError(RemoteErr.NetworkError); From cc1a119f64f65bfac550f93f2fefc044b961d352 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Mon, 2 Aug 2021 18:26:39 +0900 Subject: [PATCH 122/297] fix: set engine to RemoteOption.connection.engine if undefined --- src/remote/sync.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/remote/sync.ts b/src/remote/sync.ts index 7b767779..130595c9 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -401,6 +401,9 @@ export class Sync implements SyncInterface { this.jsonDiff = new JsonDiff(gitDDB.schema.json); this.jsonPatch = new JsonPatchOT(); + this._options.connection ??= { type: 'none' }; + this._options.connection.engine ??= default_engine_name; + this._remoteRepository = new RemoteRepository({ remoteUrl: this._options.remoteUrl, connection: this._options.connection, @@ -408,7 +411,7 @@ export class Sync implements SyncInterface { this._remoteName = encodeToGitRemoteName(this.remoteURL); - this._engine = this._options.connection?.engine ?? default_engine_name; + this._engine = this._options.connection.engine; } /*********************************************** From c8b680788be25d8f6789b63ab2536eb39bea20a2 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Mon, 2 Aug 2021 18:27:05 +0900 Subject: [PATCH 123/297] fix: add Remote branch after clone() --- src/remote/combine.ts | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/remote/combine.ts b/src/remote/combine.ts index de79143b..4f39e8cc 100644 --- a/src/remote/combine.ts +++ b/src/remote/combine.ts @@ -63,6 +63,32 @@ export async function combineDatabaseWithTheirs ( .catch(err => { throw wrappingRemoteEngineError(err); }); + // Add refs to remote branch + const remoteCommitOid = await git.resolveRef({ + fs, + dir: remoteDir, + ref: `refs/remotes/origin/${gitDDB.defaultBranch}`, + }); + await git.writeRef({ + fs, + dir: remoteDir, + ref: `refs/remotes/${remoteName}/${gitDDB.defaultBranch}`, + value: remoteCommitOid, + force: true, + }); + // Overwrite upstream branch + await git.setConfig({ + fs, + dir: remoteDir, + path: `branch.${gitDDB.defaultBranch}.remote`, + value: remoteName, + }); + await git.setConfig({ + fs, + dir: remoteDir, + path: `branch.${gitDDB.defaultBranch}.merge`, + value: `refs/heads/${gitDDB.defaultBranch}`, + }); const localMetadataList: DocMetadata[] = await getAllMetadata(gitDDB.workingDir); const remoteMetadataList: DocMetadata[] = await getAllMetadata(remoteDir); From 02f58fcefeaadc25654572d8f04635a56111e782 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Mon, 2 Aug 2021 18:27:24 +0900 Subject: [PATCH 124/297] test: add tests for remote_isomorphic_git --- test/remote_isomorphic_git/3way_merge.test.ts | 59 +++++++++++++++++++ .../3way_merge_ot.test.ts | 59 +++++++++++++++++++ test/remote_isomorphic_git/combine.test.ts | 56 ++++++++++++++++++ .../network_git_documentdb.test.ts | 59 +++++++++++++++++++ .../network_history.test.ts | 59 +++++++++++++++++++ .../network_task_queue.test.ts | 59 +++++++++++++++++++ .../on_sync_event.test.ts | 56 ++++++++++++++++++ test/remote_isomorphic_git/sync.test.ts | 52 ++++++++++++++++ test/remote_isomorphic_git/sync_clone.test.ts | 56 ++++++++++++++++++ .../remote_isomorphic_git/sync_events.test.ts | 56 ++++++++++++++++++ test/remote_isomorphic_git/sync_live.test.ts | 56 ++++++++++++++++++ .../sync_trypush.test.ts | 56 ++++++++++++++++++ .../sync_trysync.test.ts | 56 ++++++++++++++++++ 13 files changed, 739 insertions(+) create mode 100644 test/remote_isomorphic_git/3way_merge.test.ts create mode 100644 test/remote_isomorphic_git/3way_merge_ot.test.ts create mode 100644 test/remote_isomorphic_git/combine.test.ts create mode 100644 test/remote_isomorphic_git/network_git_documentdb.test.ts create mode 100644 test/remote_isomorphic_git/network_history.test.ts create mode 100644 test/remote_isomorphic_git/network_task_queue.test.ts create mode 100644 test/remote_isomorphic_git/on_sync_event.test.ts create mode 100644 test/remote_isomorphic_git/sync.test.ts create mode 100644 test/remote_isomorphic_git/sync_clone.test.ts create mode 100644 test/remote_isomorphic_git/sync_events.test.ts create mode 100644 test/remote_isomorphic_git/sync_live.test.ts create mode 100644 test/remote_isomorphic_git/sync_trypush.test.ts create mode 100644 test/remote_isomorphic_git/sync_trysync.test.ts diff --git a/test/remote_isomorphic_git/3way_merge.test.ts b/test/remote_isomorphic_git/3way_merge.test.ts new file mode 100644 index 00000000..698c0c9b --- /dev/null +++ b/test/remote_isomorphic_git/3way_merge.test.ts @@ -0,0 +1,59 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +/** + * Test tryPush + * by using GitHub Personal Access Token + * These tests create a new repository on GitHub if not exists. + */ +import path from 'path'; +import fs from 'fs-extra'; +import { syncThreeWayMergeBase } from '../remote_base/3way_merge'; +import { ConnectionSettingsGitHub } from '../../src/types'; + +const reposPrefix = 'test_3way_merge_isomorphic_git__'; +const localDir = `./test/database_3way_merge_isomorphic_git`; + +beforeEach(function () { + // @ts-ignore + console.log(`... ${this.currentTest.fullTitle()}`); +}); + +before(() => { + fs.removeSync(path.resolve(localDir)); +}); + +after(() => { + fs.removeSync(path.resolve(localDir)); +}); + +// This test needs environment variables: +// - GITDDB_GITHUB_USER_URL: URL of your GitHub account +// e.g.) https://github.com/foo/ +// - GITDDB_PERSONAL_ACCESS_TOKEN: A personal access token of your GitHub account +const maybe = + process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN + ? describe + : describe.skip; + +const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') + ? process.env.GITDDB_GITHUB_USER_URL + : process.env.GITDDB_GITHUB_USER_URL + '/'; + +const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; + +const connection: ConnectionSettingsGitHub = { + type: 'github', + personalAccessToken: token, +}; + +maybe( + 'isomorphic-git', + syncThreeWayMergeBase(connection, remoteURLBase, reposPrefix, localDir) +); diff --git a/test/remote_isomorphic_git/3way_merge_ot.test.ts b/test/remote_isomorphic_git/3way_merge_ot.test.ts new file mode 100644 index 00000000..75340ee7 --- /dev/null +++ b/test/remote_isomorphic_git/3way_merge_ot.test.ts @@ -0,0 +1,59 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +/** + * Test trySync + * by using GitHub Personal Access Token + * These tests create a new repository on GitHub if not exists. + */ +import path from 'path'; +import fs from 'fs-extra'; +import { ConnectionSettingsGitHub } from '../../src/types'; +import { threeWayMergeOtBase } from '../remote_base/3way_merge_ot'; + +const reposPrefix = 'test_3way_merge_ot_isomorphic_git__'; +const localDir = `./test/database_3way_merge_ot_isomorphic_git`; + +beforeEach(function () { + // @ts-ignore + console.log(`... ${this.currentTest.fullTitle()}`); +}); + +before(() => { + fs.removeSync(path.resolve(localDir)); +}); + +after(() => { + fs.removeSync(path.resolve(localDir)); +}); + +// This test needs environment variables: +// - GITDDB_GITHUB_USER_URL: URL of your GitHub account +// e.g.) https://github.com/foo/ +// - GITDDB_PERSONAL_ACCESS_TOKEN: A personal access token of your GitHub account +const maybe = + process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN + ? describe + : describe.skip; + +const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') + ? process.env.GITDDB_GITHUB_USER_URL + : process.env.GITDDB_GITHUB_USER_URL + '/'; + +const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; + +const connection: ConnectionSettingsGitHub = { + type: 'github', + personalAccessToken: token, +}; + +maybe( + 'isomorphic-git', + threeWayMergeOtBase(connection, remoteURLBase, reposPrefix, localDir) +); diff --git a/test/remote_isomorphic_git/combine.test.ts b/test/remote_isomorphic_git/combine.test.ts new file mode 100644 index 00000000..6c520f78 --- /dev/null +++ b/test/remote_isomorphic_git/combine.test.ts @@ -0,0 +1,56 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +/** + * Test combine databases + * by using GitHub Personal Access Token + * These tests create a new repository on GitHub if not exists. + */ +import path from 'path'; +import fs from 'fs-extra'; +import { syncCombineBase } from '../remote_base/combine'; +import { ConnectionSettingsGitHub } from '../../src/types'; + +const reposPrefix = 'test_combine_isomorphic_git__'; +const localDir = `./test/database_combine_isomorphic_git`; + +beforeEach(function () { + // @ts-ignore + console.log(`... ${this.currentTest.fullTitle()}`); +}); + +before(() => { + fs.removeSync(path.resolve(localDir)); +}); + +after(() => { + fs.removeSync(path.resolve(localDir)); +}); + +// This test needs environment variables: +// - GITDDB_GITHUB_USER_URL: URL of your GitHub account +// e.g.) https://github.com/foo/ +// - GITDDB_PERSONAL_ACCESS_TOKEN: A personal access token of your GitHub account +const maybe = + process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN + ? describe + : describe.skip; + +const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') + ? process.env.GITDDB_GITHUB_USER_URL + : process.env.GITDDB_GITHUB_USER_URL + '/'; + +const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; + +const connection: ConnectionSettingsGitHub = { + type: 'github', + personalAccessToken: token, +}; + +maybe('isomorphic-git', syncCombineBase(connection, remoteURLBase, reposPrefix, localDir)); diff --git a/test/remote_isomorphic_git/network_git_documentdb.test.ts b/test/remote_isomorphic_git/network_git_documentdb.test.ts new file mode 100644 index 00000000..26c8d164 --- /dev/null +++ b/test/remote_isomorphic_git/network_git_documentdb.test.ts @@ -0,0 +1,59 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +/** + * Network test for GitDocumentDB class + * by using GitHub Personal Access Token + * These tests create a new repository on GitHub if not exists. + */ +import path from 'path'; +import fs from 'fs-extra'; +import { networkGitDocumentDBBase } from '../remote_base/network_git_documentdb'; +import { ConnectionSettingsGitHub } from '../../src/types'; + +const reposPrefix = 'test_network_git_documentdb_isomorphic_git__'; +const localDir = `./test/database_network_git_documentdb_isomorphic_git`; + +beforeEach(function () { + // @ts-ignore + console.log(`... ${this.currentTest.fullTitle()}`); +}); + +before(() => { + fs.removeSync(path.resolve(localDir)); +}); + +after(() => { + fs.removeSync(path.resolve(localDir)); +}); + +// This test needs environment variables: +// - GITDDB_GITHUB_USER_URL: URL of your GitHub account +// e.g.) https://github.com/foo/ +// - GITDDB_PERSONAL_ACCESS_TOKEN: A personal access token of your GitHub account +const maybe = + process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN + ? describe + : describe.skip; + +const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') + ? process.env.GITDDB_GITHUB_USER_URL + : process.env.GITDDB_GITHUB_USER_URL + '/'; + +const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; + +const connection: ConnectionSettingsGitHub = { + type: 'github', + personalAccessToken: token, +}; + +maybe( + 'isomorphic-git', + networkGitDocumentDBBase(connection, remoteURLBase, reposPrefix, localDir) +); diff --git a/test/remote_isomorphic_git/network_history.test.ts b/test/remote_isomorphic_git/network_history.test.ts new file mode 100644 index 00000000..dbf3e244 --- /dev/null +++ b/test/remote_isomorphic_git/network_history.test.ts @@ -0,0 +1,59 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +/** + * Network test for history + * by using GitHub Personal Access Token + * These tests create a new repository on GitHub if not exists. + */ +import path from 'path'; +import fs from 'fs-extra'; +import { ConnectionSettingsGitHub } from '../../src/types'; +import { networkHistoryBase } from '../remote_base/network_history'; + +const reposPrefix = 'test_network_history_isomorphic_git__'; +const localDir = `./test/database_network_history_isomorphic_git`; + +beforeEach(function () { + // @ts-ignore + console.log(`... ${this.currentTest.fullTitle()}`); +}); + +before(() => { + fs.removeSync(path.resolve(localDir)); +}); + +after(() => { + fs.removeSync(path.resolve(localDir)); +}); + +// This test needs environment variables: +// - GITDDB_GITHUB_USER_URL: URL of your GitHub account +// e.g.) https://github.com/foo/ +// - GITDDB_PERSONAL_ACCESS_TOKEN: A personal access token of your GitHub account +const maybe = + process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN + ? describe + : describe.skip; + +const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') + ? process.env.GITDDB_GITHUB_USER_URL + : process.env.GITDDB_GITHUB_USER_URL + '/'; + +const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; + +const connection: ConnectionSettingsGitHub = { + type: 'github', + personalAccessToken: token, +}; + +maybe( + 'isomorphic-git', + networkHistoryBase(connection, remoteURLBase, reposPrefix, localDir) +); diff --git a/test/remote_isomorphic_git/network_task_queue.test.ts b/test/remote_isomorphic_git/network_task_queue.test.ts new file mode 100644 index 00000000..333c985e --- /dev/null +++ b/test/remote_isomorphic_git/network_task_queue.test.ts @@ -0,0 +1,59 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +/** + * Network test for TaskQueue + * by using GitHub Personal Access Token + * These tests create a new repository on GitHub if not exists. + */ +import path from 'path'; +import fs from 'fs-extra'; +import { ConnectionSettingsGitHub } from '../../src/types'; +import { networkTaskQueueBase } from '../remote_base/network_task_queue'; + +const reposPrefix = 'test_network_task_queue_isomorphic_git__'; +const localDir = `./test/database_network_task_queue_isomorphic_git`; + +beforeEach(function () { + // @ts-ignore + console.log(`... ${this.currentTest.fullTitle()}`); +}); + +before(() => { + fs.removeSync(path.resolve(localDir)); +}); + +after(() => { + fs.removeSync(path.resolve(localDir)); +}); + +// This test needs environment variables: +// - GITDDB_GITHUB_USER_URL: URL of your GitHub account +// e.g.) https://github.com/foo/ +// - GITDDB_PERSONAL_ACCESS_TOKEN: A personal access token of your GitHub account +const maybe = + process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN + ? describe + : describe.skip; + +const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') + ? process.env.GITDDB_GITHUB_USER_URL + : process.env.GITDDB_GITHUB_USER_URL + '/'; + +const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; + +const connection: ConnectionSettingsGitHub = { + type: 'github', + personalAccessToken: token, +}; + +maybe( + 'isomorphic-git', + networkTaskQueueBase(connection, remoteURLBase, reposPrefix, localDir) +); diff --git a/test/remote_isomorphic_git/on_sync_event.test.ts b/test/remote_isomorphic_git/on_sync_event.test.ts new file mode 100644 index 00000000..7c0d7434 --- /dev/null +++ b/test/remote_isomorphic_git/on_sync_event.test.ts @@ -0,0 +1,56 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +/** + * Test trySync + * by using GitHub Personal Access Token + * These tests create a new repository on GitHub if not exists. + */ +import path from 'path'; +import fs from 'fs-extra'; +import { onSyncEventBase } from '../remote_base/on_sync_event'; +import { ConnectionSettingsGitHub } from '../../src/types'; + +const reposPrefix = 'test_on_sync_event_isomorphic_git__'; +const localDir = `./test/database_on_sync_event_isomorphic_git`; + +beforeEach(function () { + // @ts-ignore + console.log(`... ${this.currentTest.fullTitle()}`); +}); + +before(() => { + fs.removeSync(path.resolve(localDir)); +}); + +after(() => { + fs.removeSync(path.resolve(localDir)); +}); + +// This test needs environment variables: +// - GITDDB_GITHUB_USER_URL: URL of your GitHub account +// e.g.) https://github.com/foo/ +// - GITDDB_PERSONAL_ACCESS_TOKEN: A personal access token of your GitHub account +const maybe = + process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN + ? describe + : describe.skip; + +const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') + ? process.env.GITDDB_GITHUB_USER_URL + : process.env.GITDDB_GITHUB_USER_URL + '/'; + +const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; + +const connection: ConnectionSettingsGitHub = { + type: 'github', + personalAccessToken: token, +}; + +maybe('isomorphic-git', onSyncEventBase(connection, remoteURLBase, reposPrefix, localDir)); diff --git a/test/remote_isomorphic_git/sync.test.ts b/test/remote_isomorphic_git/sync.test.ts new file mode 100644 index 00000000..71f15233 --- /dev/null +++ b/test/remote_isomorphic_git/sync.test.ts @@ -0,0 +1,52 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +import path from 'path'; +import fs from 'fs-extra'; +import { ConnectionSettingsGitHub } from '../../src/types'; +import { syncBase } from '../remote_base/sync'; + +const reposPrefix = 'test_sync_constructor_isomorphic_git__'; +const localDir = `./test/database_sync_constructor_isomorphic_git`; + +beforeEach(function () { + // @ts-ignore + console.log(`... ${this.currentTest.fullTitle()}`); +}); + +before(() => { + fs.removeSync(path.resolve(localDir)); +}); + +after(() => { + fs.removeSync(path.resolve(localDir)); +}); + +// This test needs environment variables: +// - GITDDB_GITHUB_USER_URL: URL of your GitHub account +// e.g.) https://github.com/foo/ +// - GITDDB_PERSONAL_ACCESS_TOKEN: A personal access token of your GitHub account +const maybe = + process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN + ? describe + : describe.skip; + +const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') + ? process.env.GITDDB_GITHUB_USER_URL + : process.env.GITDDB_GITHUB_USER_URL + '/'; + +const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; + +const connection: ConnectionSettingsGitHub = { + type: 'github', + personalAccessToken: token, + engine: 'isomorphic-git', +}; + +maybe('isomorphic-git', syncBase(connection, remoteURLBase, reposPrefix, localDir, token)); diff --git a/test/remote_isomorphic_git/sync_clone.test.ts b/test/remote_isomorphic_git/sync_clone.test.ts new file mode 100644 index 00000000..8c38024b --- /dev/null +++ b/test/remote_isomorphic_git/sync_clone.test.ts @@ -0,0 +1,56 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +/** + * Test tryPush + * by using GitHub Personal Access Token + * These tests create a new repository on GitHub if not exists. + */ +import path from 'path'; +import fs from 'fs-extra'; +import { syncCloneBase } from '../remote_base/sync_clone'; +import { ConnectionSettingsGitHub } from '../../src/types'; + +const reposPrefix = 'test_sync_clone_isomorphic_git___'; +const localDir = `./test/database_sync_clone_isomorphic_git`; + +beforeEach(function () { + // @ts-ignore + console.log(`... ${this.currentTest.fullTitle()}`); +}); + +before(() => { + fs.removeSync(path.resolve(localDir)); +}); + +after(() => { + fs.removeSync(path.resolve(localDir)); +}); + +// This test needs environment variables: +// - GITDDB_GITHUB_USER_URL: URL of your GitHub account +// e.g.) https://github.com/foo/ +// - GITDDB_PERSONAL_ACCESS_TOKEN: A personal access token of your GitHub account +const maybe = + process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN + ? describe + : describe.skip; + +const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') + ? process.env.GITDDB_GITHUB_USER_URL + : process.env.GITDDB_GITHUB_USER_URL + '/'; + +const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; + +const connection: ConnectionSettingsGitHub = { + type: 'github', + personalAccessToken: token, +}; + +maybe('isomorphic-git', syncCloneBase(connection, remoteURLBase, reposPrefix, localDir)); diff --git a/test/remote_isomorphic_git/sync_events.test.ts b/test/remote_isomorphic_git/sync_events.test.ts new file mode 100644 index 00000000..57b4b8b2 --- /dev/null +++ b/test/remote_isomorphic_git/sync_events.test.ts @@ -0,0 +1,56 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +/** + * Test Sync Events + * by using GitHub Personal Access Token + * These tests create a new repository on GitHub if not exists. + */ +import path from 'path'; +import fs from 'fs-extra'; +import { syncEventsBase } from '../remote_base/sync_events'; +import { ConnectionSettingsGitHub } from '../../src/types'; + +const reposPrefix = 'test_sync_events_isomorphic_git___'; +const localDir = `./test/database_sync_events_isomorphic_git`; + +beforeEach(function () { + // @ts-ignore + console.log(`... ${this.currentTest.fullTitle()}`); +}); + +before(() => { + fs.removeSync(path.resolve(localDir)); +}); + +after(() => { + fs.removeSync(path.resolve(localDir)); +}); + +// This test needs environment variables: +// - GITDDB_GITHUB_USER_URL: URL of your GitHub account +// e.g.) https://github.com/foo/ +// - GITDDB_PERSONAL_ACCESS_TOKEN: A personal access token of your GitHub account +const maybe = + process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN + ? describe + : describe.skip; + +const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') + ? process.env.GITDDB_GITHUB_USER_URL + : process.env.GITDDB_GITHUB_USER_URL + '/'; + +const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; + +const connection: ConnectionSettingsGitHub = { + type: 'github', + personalAccessToken: token, +}; + +maybe('isomorphic-git', syncEventsBase(connection, remoteURLBase, reposPrefix, localDir)); diff --git a/test/remote_isomorphic_git/sync_live.test.ts b/test/remote_isomorphic_git/sync_live.test.ts new file mode 100644 index 00000000..b274864f --- /dev/null +++ b/test/remote_isomorphic_git/sync_live.test.ts @@ -0,0 +1,56 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +/** + * Test Sync live + * by using GitHub Personal Access Token + * These tests create a new repository on GitHub if not exists. + */ +import path from 'path'; +import fs from 'fs-extra'; +import { syncLiveBase } from '../remote_base/sync_live'; +import { ConnectionSettingsGitHub } from '../../src/types'; + +const reposPrefix = 'test_sync_live_isomorphic_git___'; +const localDir = `./test/database_sync_live_isomorphic_git`; + +beforeEach(function () { + // @ts-ignore + console.log(`... ${this.currentTest.fullTitle()}`); +}); + +before(() => { + fs.removeSync(path.resolve(localDir)); +}); + +after(() => { + fs.removeSync(path.resolve(localDir)); +}); + +// This test needs environment variables: +// - GITDDB_GITHUB_USER_URL: URL of your GitHub account +// e.g.) https://github.com/foo/ +// - GITDDB_PERSONAL_ACCESS_TOKEN: A personal access token of your GitHub account +const maybe = + process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN + ? describe + : describe.skip; + +const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') + ? process.env.GITDDB_GITHUB_USER_URL + : process.env.GITDDB_GITHUB_USER_URL + '/'; + +const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; + +const connection: ConnectionSettingsGitHub = { + type: 'github', + personalAccessToken: token, +}; + +maybe('isomorphic-git', syncLiveBase(connection, remoteURLBase, reposPrefix, localDir)); diff --git a/test/remote_isomorphic_git/sync_trypush.test.ts b/test/remote_isomorphic_git/sync_trypush.test.ts new file mode 100644 index 00000000..c6465286 --- /dev/null +++ b/test/remote_isomorphic_git/sync_trypush.test.ts @@ -0,0 +1,56 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +/** + * Test tryPush + * by using GitHub Personal Access Token + * These tests create a new repository on GitHub if not exists. + */ +import path from 'path'; +import fs from 'fs-extra'; +import { syncTryPushBase } from '../remote_base/sync_trypush'; +import { ConnectionSettingsGitHub } from '../../src/types'; + +const reposPrefix = 'test_sync_trypush_isomorphic-git___'; +const localDir = `./test/database_sync_trypush_isomorphic-git`; + +beforeEach(function () { + // @ts-ignore + console.log(`... ${this.currentTest.fullTitle()}`); +}); + +before(() => { + fs.removeSync(path.resolve(localDir)); +}); + +after(() => { + fs.removeSync(path.resolve(localDir)); +}); + +// This test needs environment variables: +// - GITDDB_GITHUB_USER_URL: URL of your GitHub account +// e.g.) https://github.com/foo/ +// - GITDDB_PERSONAL_ACCESS_TOKEN: A personal access token of your GitHub account +const maybe = + process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN + ? describe + : describe.skip; + +const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') + ? process.env.GITDDB_GITHUB_USER_URL + : process.env.GITDDB_GITHUB_USER_URL + '/'; + +const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; + +const connection: ConnectionSettingsGitHub = { + type: 'github', + personalAccessToken: token, +}; + +maybe('isomorphic-git', syncTryPushBase(connection, remoteURLBase, reposPrefix, localDir)); diff --git a/test/remote_isomorphic_git/sync_trysync.test.ts b/test/remote_isomorphic_git/sync_trysync.test.ts new file mode 100644 index 00000000..b8a20805 --- /dev/null +++ b/test/remote_isomorphic_git/sync_trysync.test.ts @@ -0,0 +1,56 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +/** + * Test trySync + * by using GitHub Personal Access Token + * These tests create a new repository on GitHub if not exists. + */ +import path from 'path'; +import fs from 'fs-extra'; +import { syncTrySyncBase } from '../remote_base/sync_trysync'; +import { ConnectionSettingsGitHub } from '../../src/types'; + +const reposPrefix = 'test_sync_trysync_isomorphic_git___'; +const localDir = `./test/database_sync_trysync_isomorphic_git`; + +beforeEach(function () { + // @ts-ignore + console.log(`... ${this.currentTest.fullTitle()}`); +}); + +before(() => { + fs.removeSync(path.resolve(localDir)); +}); + +after(() => { + fs.removeSync(path.resolve(localDir)); +}); + +// This test needs environment variables: +// - GITDDB_GITHUB_USER_URL: URL of your GitHub account +// e.g.) https://github.com/foo/ +// - GITDDB_PERSONAL_ACCESS_TOKEN: A personal access token of your GitHub account +const maybe = + process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN + ? describe + : describe.skip; + +const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') + ? process.env.GITDDB_GITHUB_USER_URL + : process.env.GITDDB_GITHUB_USER_URL + '/'; + +const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; + +const connection: ConnectionSettingsGitHub = { + type: 'github', + personalAccessToken: token, +}; + +maybe('isomorphic-git', syncTrySyncBase(connection, remoteURLBase, reposPrefix, localDir)); From 858c342de19171d474576aaba848d9c0c088493c Mon Sep 17 00:00:00 2001 From: sosuisen Date: Mon, 2 Aug 2021 18:45:34 +0900 Subject: [PATCH 125/297] test: remote unused network settings --- test/crud/history.test.ts | 12 ------------ test/task_queue.test.ts | 3 --- 2 files changed, 15 deletions(-) diff --git a/test/crud/history.test.ts b/test/crud/history.test.ts index fcd07333..3044a5ec 100644 --- a/test/crud/history.test.ts +++ b/test/crud/history.test.ts @@ -53,9 +53,6 @@ beforeEach(function () { }); before(() => { - // eslint-disable-next-line @typescript-eslint/no-var-requires - GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); - fs.removeSync(path.resolve(localDir)); }); @@ -67,15 +64,6 @@ after(() => { fs.removeSync(path.resolve(localDir)); }); -// This test needs environment variables: -// - GITDDB_GITHUB_USER_URL: URL of your GitHub account -// e.g.) https://github.com/foo/ -// - GITDDB_PERSONAL_ACCESS_TOKEN: A personal access token of your GitHub account -const maybe = - process.env.GITDDB_GITHUB_USER_URL && process.env.GITDDB_PERSONAL_ACCESS_TOKEN - ? describe - : describe.skip; - describe(' getHistoryImpl', () => { it('gets all revisions', async () => { const dbName = monoId(); diff --git a/test/task_queue.test.ts b/test/task_queue.test.ts index b32463ca..52a35416 100644 --- a/test/task_queue.test.ts +++ b/test/task_queue.test.ts @@ -37,9 +37,6 @@ beforeEach(function () { }); before(() => { - // eslint-disable-next-line @typescript-eslint/no-var-requires - GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); - fs.removeSync(path.resolve(localDir)); }); From 7014af498c0d10c7c820ba637564718b361869f5 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Mon, 2 Aug 2021 18:45:50 +0900 Subject: [PATCH 126/297] test: rename test names --- test/plugin/checkfetch.test.ts | 2 +- test/plugin/clone.test.ts | 2 +- test/plugin/fetch.test.ts | 2 +- test/plugin/push.test.ts | 3 +-- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/test/plugin/checkfetch.test.ts b/test/plugin/checkfetch.test.ts index e4bd1d1c..b9931fbd 100644 --- a/test/plugin/checkfetch.test.ts +++ b/test/plugin/checkfetch.test.ts @@ -70,7 +70,7 @@ const maybe = ? describe : describe.skip; -maybe(' checkFetch', () => { +maybe(' checkFetch', () => { const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') ? process.env.GITDDB_GITHUB_USER_URL : process.env.GITDDB_GITHUB_USER_URL + '/'; diff --git a/test/plugin/clone.test.ts b/test/plugin/clone.test.ts index 2ff67a52..ac46027a 100644 --- a/test/plugin/clone.test.ts +++ b/test/plugin/clone.test.ts @@ -70,7 +70,7 @@ const maybe = ? describe : describe.skip; -maybe(' clone', () => { +maybe(' clone', () => { const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') ? process.env.GITDDB_GITHUB_USER_URL : process.env.GITDDB_GITHUB_USER_URL + '/'; diff --git a/test/plugin/fetch.test.ts b/test/plugin/fetch.test.ts index c5da10cf..d8a23353 100644 --- a/test/plugin/fetch.test.ts +++ b/test/plugin/fetch.test.ts @@ -70,7 +70,7 @@ const maybe = ? describe : describe.skip; -maybe(' fetch', () => { +maybe(' fetch', () => { const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') ? process.env.GITDDB_GITHUB_USER_URL : process.env.GITDDB_GITHUB_USER_URL + '/'; diff --git a/test/plugin/push.test.ts b/test/plugin/push.test.ts index 64e06276..84dfdc8d 100644 --- a/test/plugin/push.test.ts +++ b/test/plugin/push.test.ts @@ -19,7 +19,6 @@ import { InvalidAuthenticationTypeError, InvalidGitRemoteError, InvalidRepositoryURLError, - InvalidSSHKeyPathError, InvalidURLFormatError, NetworkError, UnfetchedCommitExistsError, @@ -81,7 +80,7 @@ const maybe = ? describe : describe.skip; -maybe(' push', () => { +maybe(' push', () => { const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') ? process.env.GITDDB_GITHUB_USER_URL : process.env.GITDDB_GITHUB_USER_URL + '/'; From 79f0eef9f4b2a83eef474c102ae7947cccfdab14 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Mon, 2 Aug 2021 19:08:52 +0900 Subject: [PATCH 127/297] fix: remote nodegit from project --- .eslintignore | 1 - package-lock.json | 334 ++++++++++++------ package.json | 1 - tsconfig-base.json | 4 - types/sosuisen__nodegit/LICENSE | 21 -- types/sosuisen__nodegit/README.md | 16 - types/sosuisen__nodegit/annotated-commit.d.ts | 19 - types/sosuisen__nodegit/apply-options.d.ts | 8 - types/sosuisen__nodegit/apply.d.ts | 22 -- types/sosuisen__nodegit/attr.d.ts | 38 -- types/sosuisen__nodegit/blame-hunk.d.ts | 13 - types/sosuisen__nodegit/blame-options.d.ts | 12 - types/sosuisen__nodegit/blame.d.ts | 44 --- types/sosuisen__nodegit/blob.d.ts | 40 --- types/sosuisen__nodegit/branch.d.ts | 25 -- types/sosuisen__nodegit/buf.d.ts | 13 - types/sosuisen__nodegit/cert-host-key.d.ts | 8 - types/sosuisen__nodegit/cert-x509.d.ts | 7 - types/sosuisen__nodegit/cert.d.ts | 17 - types/sosuisen__nodegit/checkout-options.d.ts | 27 -- types/sosuisen__nodegit/checkout.d.ts | 61 ---- .../cherry-pick-options.d.ts | 9 - types/sosuisen__nodegit/cherry-pick.d.ts | 16 - types/sosuisen__nodegit/clone-options.d.ts | 13 - types/sosuisen__nodegit/clone.d.ts | 20 -- types/sosuisen__nodegit/commit.d.ts | 124 ------- types/sosuisen__nodegit/config.d.ts | 52 --- types/sosuisen__nodegit/convenient-hunk.d.ts | 37 -- types/sosuisen__nodegit/convenient-patch.d.ts | 73 ---- .../cred-user-pass-payload.d.ts | 4 - types/sosuisen__nodegit/cred-username.d.ts | 6 - types/sosuisen__nodegit/cred.d.ts | 24 -- types/sosuisen__nodegit/cvar-map.d.ts | 5 - .../describe-format-options.d.ts | 7 - types/sosuisen__nodegit/describe-options.d.ts | 9 - types/sosuisen__nodegit/diff-binary-file.d.ts | 8 - types/sosuisen__nodegit/diff-binary.d.ts | 15 - types/sosuisen__nodegit/diff-delta.d.ts | 10 - types/sosuisen__nodegit/diff-file.d.ts | 24 -- types/sosuisen__nodegit/diff-line.d.ts | 20 -- types/sosuisen__nodegit/diff-options.d.ts | 18 - types/sosuisen__nodegit/diff-perf-data.d.ts | 5 - types/sosuisen__nodegit/diff-stats.d.ts | 25 -- types/sosuisen__nodegit/diff.d.ts | 172 --------- types/sosuisen__nodegit/enums.d.ts | 41 --- types/sosuisen__nodegit/error.d.ts | 68 ---- types/sosuisen__nodegit/fetch-options.d.ts | 13 - types/sosuisen__nodegit/fetch.d.ts | 13 - types/sosuisen__nodegit/filter.d.ts | 35 -- types/sosuisen__nodegit/git-err.d.ts | 8 - types/sosuisen__nodegit/graph.d.ts | 7 - types/sosuisen__nodegit/hash-sig.d.ts | 17 - types/sosuisen__nodegit/ignore.d.ts | 7 - types/sosuisen__nodegit/index-entry.d.ts | 21 -- types/sosuisen__nodegit/index.d.ts | 116 ------ types/sosuisen__nodegit/index_.d.ts | 59 ---- types/sosuisen__nodegit/indexer.d.ts | 9 - types/sosuisen__nodegit/lib-git2.d.ts | 25 -- types/sosuisen__nodegit/merge-file-input.d.ts | 7 - .../sosuisen__nodegit/merge-file-options.d.ts | 9 - .../sosuisen__nodegit/merge-file-result.d.ts | 7 - types/sosuisen__nodegit/merge-options.d.ts | 11 - types/sosuisen__nodegit/merge.d.ts | 59 ---- types/sosuisen__nodegit/note.d.ts | 19 - types/sosuisen__nodegit/object.d.ts | 37 -- types/sosuisen__nodegit/odb-expand-id.d.ts | 8 - types/sosuisen__nodegit/odb-object.d.ts | 11 - types/sosuisen__nodegit/odb.d.ts | 23 -- types/sosuisen__nodegit/oid-array.d.ts | 7 - types/sosuisen__nodegit/oid.d.ts | 11 - types/sosuisen__nodegit/open-ssl.d.ts | 3 - types/sosuisen__nodegit/pack-builder.d.ts | 25 -- types/sosuisen__nodegit/package.json | 79 ----- types/sosuisen__nodegit/path-spec.d.ts | 34 -- types/sosuisen__nodegit/proxy-options.d.ts | 9 - types/sosuisen__nodegit/proxy.d.ts | 5 - types/sosuisen__nodegit/push-options.d.ts | 12 - types/sosuisen__nodegit/push-update.d.ts | 8 - types/sosuisen__nodegit/push.d.ts | 6 - types/sosuisen__nodegit/rebase-operation.d.ts | 18 - types/sosuisen__nodegit/rebase.d.ts | 29 -- types/sosuisen__nodegit/ref-db.d.ts | 9 - types/sosuisen__nodegit/ref-log.d.ts | 24 -- types/sosuisen__nodegit/ref-spec.d.ts | 8 - types/sosuisen__nodegit/reference.d.ts | 60 ---- types/sosuisen__nodegit/remote-callbacks.d.ts | 8 - types/sosuisen__nodegit/remote.d.ts | 72 ---- types/sosuisen__nodegit/repository.d.ts | 249 ------------- types/sosuisen__nodegit/reset.d.ts | 31 -- types/sosuisen__nodegit/rev-parse.d.ts | 16 - types/sosuisen__nodegit/rev-walk.d.ts | 47 --- types/sosuisen__nodegit/revert.d.ts | 21 -- types/sosuisen__nodegit/signature.d.ts | 17 - types/sosuisen__nodegit/stash.d.ts | 46 --- types/sosuisen__nodegit/status-entry.d.ts | 7 - .../status-file-options.d.ts | 8 - types/sosuisen__nodegit/status-file.d.ts | 20 -- types/sosuisen__nodegit/status-list.d.ts | 12 - types/sosuisen__nodegit/status-options.d.ts | 9 - types/sosuisen__nodegit/status.d.ts | 56 --- types/sosuisen__nodegit/str-array.d.ts | 7 - .../submodule-update-options.d.ts | 10 - types/sosuisen__nodegit/submodule.d.ts | 87 ----- types/sosuisen__nodegit/tag.d.ts | 34 -- types/sosuisen__nodegit/time.d.ts | 4 - .../sosuisen__nodegit/transfer-progress.d.ts | 9 - types/sosuisen__nodegit/transport.d.ts | 16 - types/sosuisen__nodegit/tree-builder.d.ts | 15 - types/sosuisen__nodegit/tree-entry.d.ts | 48 --- types/sosuisen__nodegit/tree-update.d.ts | 8 - types/sosuisen__nodegit/tree.d.ts | 80 ----- types/sosuisen__nodegit/wrapper.d.ts | 3 - 112 files changed, 227 insertions(+), 3117 deletions(-) delete mode 100644 types/sosuisen__nodegit/LICENSE delete mode 100644 types/sosuisen__nodegit/README.md delete mode 100644 types/sosuisen__nodegit/annotated-commit.d.ts delete mode 100644 types/sosuisen__nodegit/apply-options.d.ts delete mode 100644 types/sosuisen__nodegit/apply.d.ts delete mode 100644 types/sosuisen__nodegit/attr.d.ts delete mode 100644 types/sosuisen__nodegit/blame-hunk.d.ts delete mode 100644 types/sosuisen__nodegit/blame-options.d.ts delete mode 100644 types/sosuisen__nodegit/blame.d.ts delete mode 100644 types/sosuisen__nodegit/blob.d.ts delete mode 100644 types/sosuisen__nodegit/branch.d.ts delete mode 100644 types/sosuisen__nodegit/buf.d.ts delete mode 100644 types/sosuisen__nodegit/cert-host-key.d.ts delete mode 100644 types/sosuisen__nodegit/cert-x509.d.ts delete mode 100644 types/sosuisen__nodegit/cert.d.ts delete mode 100644 types/sosuisen__nodegit/checkout-options.d.ts delete mode 100644 types/sosuisen__nodegit/checkout.d.ts delete mode 100644 types/sosuisen__nodegit/cherry-pick-options.d.ts delete mode 100644 types/sosuisen__nodegit/cherry-pick.d.ts delete mode 100644 types/sosuisen__nodegit/clone-options.d.ts delete mode 100644 types/sosuisen__nodegit/clone.d.ts delete mode 100644 types/sosuisen__nodegit/commit.d.ts delete mode 100644 types/sosuisen__nodegit/config.d.ts delete mode 100644 types/sosuisen__nodegit/convenient-hunk.d.ts delete mode 100644 types/sosuisen__nodegit/convenient-patch.d.ts delete mode 100644 types/sosuisen__nodegit/cred-user-pass-payload.d.ts delete mode 100644 types/sosuisen__nodegit/cred-username.d.ts delete mode 100644 types/sosuisen__nodegit/cred.d.ts delete mode 100644 types/sosuisen__nodegit/cvar-map.d.ts delete mode 100644 types/sosuisen__nodegit/describe-format-options.d.ts delete mode 100644 types/sosuisen__nodegit/describe-options.d.ts delete mode 100644 types/sosuisen__nodegit/diff-binary-file.d.ts delete mode 100644 types/sosuisen__nodegit/diff-binary.d.ts delete mode 100644 types/sosuisen__nodegit/diff-delta.d.ts delete mode 100644 types/sosuisen__nodegit/diff-file.d.ts delete mode 100644 types/sosuisen__nodegit/diff-line.d.ts delete mode 100644 types/sosuisen__nodegit/diff-options.d.ts delete mode 100644 types/sosuisen__nodegit/diff-perf-data.d.ts delete mode 100644 types/sosuisen__nodegit/diff-stats.d.ts delete mode 100644 types/sosuisen__nodegit/diff.d.ts delete mode 100644 types/sosuisen__nodegit/enums.d.ts delete mode 100644 types/sosuisen__nodegit/error.d.ts delete mode 100644 types/sosuisen__nodegit/fetch-options.d.ts delete mode 100644 types/sosuisen__nodegit/fetch.d.ts delete mode 100644 types/sosuisen__nodegit/filter.d.ts delete mode 100644 types/sosuisen__nodegit/git-err.d.ts delete mode 100644 types/sosuisen__nodegit/graph.d.ts delete mode 100644 types/sosuisen__nodegit/hash-sig.d.ts delete mode 100644 types/sosuisen__nodegit/ignore.d.ts delete mode 100644 types/sosuisen__nodegit/index-entry.d.ts delete mode 100644 types/sosuisen__nodegit/index.d.ts delete mode 100644 types/sosuisen__nodegit/index_.d.ts delete mode 100644 types/sosuisen__nodegit/indexer.d.ts delete mode 100644 types/sosuisen__nodegit/lib-git2.d.ts delete mode 100644 types/sosuisen__nodegit/merge-file-input.d.ts delete mode 100644 types/sosuisen__nodegit/merge-file-options.d.ts delete mode 100644 types/sosuisen__nodegit/merge-file-result.d.ts delete mode 100644 types/sosuisen__nodegit/merge-options.d.ts delete mode 100644 types/sosuisen__nodegit/merge.d.ts delete mode 100644 types/sosuisen__nodegit/note.d.ts delete mode 100644 types/sosuisen__nodegit/object.d.ts delete mode 100644 types/sosuisen__nodegit/odb-expand-id.d.ts delete mode 100644 types/sosuisen__nodegit/odb-object.d.ts delete mode 100644 types/sosuisen__nodegit/odb.d.ts delete mode 100644 types/sosuisen__nodegit/oid-array.d.ts delete mode 100644 types/sosuisen__nodegit/oid.d.ts delete mode 100644 types/sosuisen__nodegit/open-ssl.d.ts delete mode 100644 types/sosuisen__nodegit/pack-builder.d.ts delete mode 100644 types/sosuisen__nodegit/package.json delete mode 100644 types/sosuisen__nodegit/path-spec.d.ts delete mode 100644 types/sosuisen__nodegit/proxy-options.d.ts delete mode 100644 types/sosuisen__nodegit/proxy.d.ts delete mode 100644 types/sosuisen__nodegit/push-options.d.ts delete mode 100644 types/sosuisen__nodegit/push-update.d.ts delete mode 100644 types/sosuisen__nodegit/push.d.ts delete mode 100644 types/sosuisen__nodegit/rebase-operation.d.ts delete mode 100644 types/sosuisen__nodegit/rebase.d.ts delete mode 100644 types/sosuisen__nodegit/ref-db.d.ts delete mode 100644 types/sosuisen__nodegit/ref-log.d.ts delete mode 100644 types/sosuisen__nodegit/ref-spec.d.ts delete mode 100644 types/sosuisen__nodegit/reference.d.ts delete mode 100644 types/sosuisen__nodegit/remote-callbacks.d.ts delete mode 100644 types/sosuisen__nodegit/remote.d.ts delete mode 100644 types/sosuisen__nodegit/repository.d.ts delete mode 100644 types/sosuisen__nodegit/reset.d.ts delete mode 100644 types/sosuisen__nodegit/rev-parse.d.ts delete mode 100644 types/sosuisen__nodegit/rev-walk.d.ts delete mode 100644 types/sosuisen__nodegit/revert.d.ts delete mode 100644 types/sosuisen__nodegit/signature.d.ts delete mode 100644 types/sosuisen__nodegit/stash.d.ts delete mode 100644 types/sosuisen__nodegit/status-entry.d.ts delete mode 100644 types/sosuisen__nodegit/status-file-options.d.ts delete mode 100644 types/sosuisen__nodegit/status-file.d.ts delete mode 100644 types/sosuisen__nodegit/status-list.d.ts delete mode 100644 types/sosuisen__nodegit/status-options.d.ts delete mode 100644 types/sosuisen__nodegit/status.d.ts delete mode 100644 types/sosuisen__nodegit/str-array.d.ts delete mode 100644 types/sosuisen__nodegit/submodule-update-options.d.ts delete mode 100644 types/sosuisen__nodegit/submodule.d.ts delete mode 100644 types/sosuisen__nodegit/tag.d.ts delete mode 100644 types/sosuisen__nodegit/time.d.ts delete mode 100644 types/sosuisen__nodegit/transfer-progress.d.ts delete mode 100644 types/sosuisen__nodegit/transport.d.ts delete mode 100644 types/sosuisen__nodegit/tree-builder.d.ts delete mode 100644 types/sosuisen__nodegit/tree-entry.d.ts delete mode 100644 types/sosuisen__nodegit/tree-update.d.ts delete mode 100644 types/sosuisen__nodegit/tree.d.ts delete mode 100644 types/sosuisen__nodegit/wrapper.d.ts diff --git a/.eslintignore b/.eslintignore index d3d57075..ed812816 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,4 +1,3 @@ examples/ -types/sosuisen__nodegit/ dist/ *.mjs \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 45b221bf..a7850f4d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -907,7 +907,8 @@ "@sindresorhus/is": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-2.1.1.tgz", - "integrity": "sha512-/aPsuoj/1Dw/kzhkgz+ES6TxG0zfTMGLwuK2ZG00k/iJzYHTLCE8mVU8EPqEOp/lmxPoq1C1C9RYToRKb2KEfg==" + "integrity": "sha512-/aPsuoj/1Dw/kzhkgz+ES6TxG0zfTMGLwuK2ZG00k/iJzYHTLCE8mVU8EPqEOp/lmxPoq1C1C9RYToRKb2KEfg==", + "dev": true }, "@sinonjs/commons": { "version": "1.8.3", @@ -968,38 +969,11 @@ "diff-match-patch": "^1.0.0" } }, - "@sosuisen/nodegit": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@sosuisen/nodegit/-/nodegit-0.27.3.tgz", - "integrity": "sha512-0/SSdtXK+grdpbhJP116MtkyHWA1yJ+Tnnzsj5OEPj/bC5s9Losc52p8WKiDn1uKeJcN5F5Zg+VOx4vkBKD4dg==", - "requires": { - "fs-extra": "^7.0.0", - "got": "^10.7.0", - "json5": "^2.1.0", - "lodash": "^4.17.14", - "nan": "^2.14.0", - "node-gyp": "^4.0.0", - "node-pre-gyp": "^0.13.0", - "ramda": "^0.25.0", - "tar-fs": "^1.16.3" - }, - "dependencies": { - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, "@szmarczak/http-timer": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.5.tgz", "integrity": "sha512-PyRA9sm1Yayuj5OIoJ1hGt2YISX45w9WcFbh6ddT0Z/0yaFxOtGLInr4jUfU1EAFVs0Yfyfev4RNwBlUaHdlDQ==", + "dev": true, "requires": { "defer-to-connect": "^2.0.0" } @@ -1043,6 +1017,7 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", + "dev": true, "requires": { "@types/http-cache-semantics": "*", "@types/keyv": "*", @@ -1053,7 +1028,8 @@ "@types/node": { "version": "16.3.1", "resolved": "https://registry.npmjs.org/@types/node/-/node-16.3.1.tgz", - "integrity": "sha512-N87VuQi7HEeRJkhzovao/JviiqKjDKMVKxKMfUvSKw+MbkbW8R0nA3fi/MQhhlxV2fQ+2ReM+/Nt4efdrJx3zA==" + "integrity": "sha512-N87VuQi7HEeRJkhzovao/JviiqKjDKMVKxKMfUvSKw+MbkbW8R0nA3fi/MQhhlxV2fQ+2ReM+/Nt4efdrJx3zA==", + "dev": true } } }, @@ -1088,7 +1064,8 @@ "@types/http-cache-semantics": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", - "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==" + "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==", + "dev": true }, "@types/istanbul-lib-coverage": { "version": "2.0.3", @@ -1124,6 +1101,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.2.tgz", "integrity": "sha512-/FvAK2p4jQOaJ6CGDHJTqZcUtbZe820qIeTg7o0Shg7drB4JHeL+V/dhSaly7NXx6u8eSee+r7coT+yuJEvDLg==", + "dev": true, "requires": { "@types/node": "*" }, @@ -1131,7 +1109,8 @@ "@types/node": { "version": "16.3.1", "resolved": "https://registry.npmjs.org/@types/node/-/node-16.3.1.tgz", - "integrity": "sha512-N87VuQi7HEeRJkhzovao/JviiqKjDKMVKxKMfUvSKw+MbkbW8R0nA3fi/MQhhlxV2fQ+2ReM+/Nt4efdrJx3zA==" + "integrity": "sha512-N87VuQi7HEeRJkhzovao/JviiqKjDKMVKxKMfUvSKw+MbkbW8R0nA3fi/MQhhlxV2fQ+2ReM+/Nt4efdrJx3zA==", + "dev": true } } }, @@ -1175,6 +1154,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", + "dev": true, "requires": { "@types/node": "*" }, @@ -1182,7 +1162,8 @@ "@types/node": { "version": "16.3.1", "resolved": "https://registry.npmjs.org/@types/node/-/node-16.3.1.tgz", - "integrity": "sha512-N87VuQi7HEeRJkhzovao/JviiqKjDKMVKxKMfUvSKw+MbkbW8R0nA3fi/MQhhlxV2fQ+2ReM+/Nt4efdrJx3zA==" + "integrity": "sha512-N87VuQi7HEeRJkhzovao/JviiqKjDKMVKxKMfUvSKw+MbkbW8R0nA3fi/MQhhlxV2fQ+2ReM+/Nt4efdrJx3zA==", + "dev": true } } }, @@ -1398,7 +1379,8 @@ "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true }, "acorn": { "version": "7.4.1", @@ -1426,6 +1408,7 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, "requires": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -1461,7 +1444,8 @@ "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true }, "ansi-styles": { "version": "3.2.1", @@ -1493,7 +1477,8 @@ "aproba": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true }, "archy": { "version": "1.0.0", @@ -1505,6 +1490,7 @@ "version": "1.1.5", "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "dev": true, "requires": { "delegates": "^1.0.0", "readable-stream": "^2.0.6" @@ -1571,6 +1557,7 @@ "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, "requires": { "safer-buffer": "~2.1.0" } @@ -1578,7 +1565,8 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true }, "astral-regex": { "version": "2.0.0", @@ -1594,7 +1582,8 @@ "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true }, "at-least-node": { "version": "1.0.0", @@ -1604,12 +1593,14 @@ "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true }, "aws4": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", + "dev": true }, "bail": { "version": "1.0.5", @@ -1626,6 +1617,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, "requires": { "tweetnacl": "^0.14.3" } @@ -1645,6 +1637,7 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==", + "dev": true, "requires": { "readable-stream": "^2.3.5", "safe-buffer": "^5.1.1" @@ -1696,6 +1689,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "dev": true, "requires": { "buffer-alloc-unsafe": "^1.1.0", "buffer-fill": "^1.0.0" @@ -1704,12 +1698,14 @@ "buffer-alloc-unsafe": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", - "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", + "dev": true }, "buffer-fill": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", - "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=" + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=", + "dev": true }, "buffer-from": { "version": "1.1.1", @@ -1720,6 +1716,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-2.0.1.tgz", "integrity": "sha512-EMMbsiOTcdngM/K6gV/OxF2x0t07+vMOWxZNSCRQMjO2MY2nhZQ6OYhOOpyQrbhqsgtvKGI7hcq6xjnA92USjg==", + "dev": true, "requires": { "@types/keyv": "^3.1.1", "keyv": "^4.0.0" @@ -1729,6 +1726,7 @@ "version": "7.0.2", "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", + "dev": true, "requires": { "clone-response": "^1.0.2", "get-stream": "^5.1.0", @@ -1782,7 +1780,8 @@ "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true }, "chalk": { "version": "2.4.2", @@ -1831,7 +1830,8 @@ "chownr": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true }, "ci-info": { "version": "2.0.0", @@ -1929,6 +1929,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dev": true, "requires": { "mimic-response": "^1.0.0" }, @@ -1936,14 +1937,16 @@ "mimic-response": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true } } }, "code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true }, "collapse-white-space": { "version": "1.0.6", @@ -1980,6 +1983,7 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, "requires": { "delayed-stream": "~1.0.0" } @@ -2010,7 +2014,8 @@ "console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "dev": true }, "contains-path": { "version": "0.1.0", @@ -2030,7 +2035,8 @@ "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true }, "cosmiconfig": { "version": "7.0.0", @@ -2141,6 +2147,7 @@ "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, "requires": { "assert-plus": "^1.0.0" } @@ -2155,6 +2162,7 @@ "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, "requires": { "ms": "^2.1.1" } @@ -2169,6 +2177,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-5.0.0.tgz", "integrity": "sha512-TLZWWybuxWgoW7Lykv+gq9xvzOsUjQ9tF09Tj6NSTYGMTCHNXzrPnD6Hi+TgZq19PyTAGH4Ll/NIM/eTGglnMw==", + "dev": true, "requires": { "mimic-response": "^2.0.0" } @@ -2182,7 +2191,8 @@ "deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true }, "deep-is": { "version": "0.1.3", @@ -2216,7 +2226,8 @@ "defer-to-connect": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==" + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "dev": true }, "define-properties": { "version": "1.1.3", @@ -2230,12 +2241,14 @@ "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true }, "delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "dev": true }, "deprecation": { "version": "2.3.1", @@ -2245,7 +2258,8 @@ "detect-libc": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", + "dev": true }, "detect-newline": { "version": "3.1.0", @@ -2296,12 +2310,14 @@ "duplexer3": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, "requires": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" @@ -2365,6 +2381,7 @@ "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, "requires": { "once": "^1.4.0" } @@ -3162,17 +3179,20 @@ "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true }, "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true }, "fast-diff": { "version": "1.2.0", @@ -3196,7 +3216,8 @@ "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true }, "fast-levenshtein": { "version": "2.0.6", @@ -3369,12 +3390,14 @@ "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true }, "form-data": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.6", @@ -3390,7 +3413,8 @@ "fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true }, "fs-extra": { "version": "9.1.0", @@ -3423,6 +3447,7 @@ "version": "1.2.7", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "dev": true, "requires": { "minipass": "^2.6.0" } @@ -3455,6 +3480,7 @@ "version": "2.7.4", "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "dev": true, "requires": { "aproba": "^1.0.3", "console-control-strings": "^1.0.0", @@ -3505,6 +3531,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, "requires": { "pump": "^3.0.0" } @@ -3513,6 +3540,7 @@ "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, "requires": { "assert-plus": "^1.0.0" } @@ -3621,6 +3649,7 @@ "version": "10.7.0", "resolved": "https://registry.npmjs.org/got/-/got-10.7.0.tgz", "integrity": "sha512-aWTDeNw9g+XqEZNcTjMMZSy7B7yE9toWOFYip7ofFTLleJhvZwUxxTxkTpKvF+p1SAA4VHmuEy7PiHTHyq8tJg==", + "dev": true, "requires": { "@sindresorhus/is": "^2.0.0", "@szmarczak/http-timer": "^4.0.0", @@ -3672,12 +3701,14 @@ "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true }, "har-validator": { "version": "5.1.5", "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "dev": true, "requires": { "ajv": "^6.12.3", "har-schema": "^2.0.0" @@ -3712,7 +3743,8 @@ "has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "dev": true }, "hasha": { "version": "5.2.2", @@ -3771,12 +3803,14 @@ "http-cache-semantics": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "dev": true }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, "requires": { "assert-plus": "^1.0.0", "jsprim": "^1.2.2", @@ -3787,6 +3821,7 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, "requires": { "safer-buffer": ">= 2.1.2 < 3" } @@ -3800,6 +3835,7 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.4.tgz", "integrity": "sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ==", + "dev": true, "requires": { "minimatch": "^3.0.4" } @@ -3861,7 +3897,8 @@ "ini": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true }, "internal-slot": { "version": "1.0.3", @@ -3963,6 +4000,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, "requires": { "number-is-nan": "^1.0.0" } @@ -4045,7 +4083,8 @@ "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true }, "is-whitespace-character": { "version": "1.0.4", @@ -4068,12 +4107,14 @@ "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true }, "isomorphic-git": { "version": "1.9.1", @@ -4108,7 +4149,8 @@ "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true }, "istanbul-lib-coverage": { "version": "3.0.0", @@ -4466,7 +4508,8 @@ "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true }, "jsesc": { "version": "2.5.2", @@ -4477,7 +4520,8 @@ "json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true }, "json-parse-even-better-errors": { "version": "2.3.1", @@ -4488,12 +4532,14 @@ "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true }, "json-stable-stringify": { "version": "1.0.1", @@ -4513,12 +4559,14 @@ "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true }, "json5": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, "requires": { "minimist": "^1.2.5" } @@ -4527,6 +4575,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, "requires": { "graceful-fs": "^4.1.6" } @@ -4541,6 +4590,7 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, "requires": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", @@ -4568,6 +4618,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.3.tgz", "integrity": "sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA==", + "dev": true, "requires": { "json-buffer": "3.0.1" } @@ -4639,7 +4690,8 @@ "lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true }, "lodash.clonedeep": { "version": "4.5.0", @@ -4761,7 +4813,8 @@ "lowercase-keys": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true }, "lru-cache": { "version": "6.0.0", @@ -4847,12 +4900,14 @@ "mime-db": { "version": "1.48.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz", - "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==" + "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==", + "dev": true }, "mime-types": { "version": "2.1.31", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz", "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==", + "dev": true, "requires": { "mime-db": "1.48.0" } @@ -4893,6 +4948,7 @@ "version": "2.9.0", "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dev": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -4902,6 +4958,7 @@ "version": "1.3.3", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "dev": true, "requires": { "minipass": "^2.9.0" } @@ -4910,6 +4967,7 @@ "version": "0.5.5", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, "requires": { "minimist": "^1.2.5" } @@ -5083,7 +5141,8 @@ "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true }, "multimap": { "version": "1.1.0", @@ -5100,7 +5159,8 @@ "nan": { "version": "2.14.2", "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", - "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==" + "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==", + "dev": true }, "nanoid": { "version": "3.1.20", @@ -5118,6 +5178,7 @@ "version": "2.8.0", "resolved": "https://registry.npmjs.org/needle/-/needle-2.8.0.tgz", "integrity": "sha512-ZTq6WYkN/3782H1393me3utVYdq2XyqNUFBsprEE3VMAT0+hP/cItpnITpqsY6ep2yeFE4Tqtqwc74VqUlUYtw==", + "dev": true, "requires": { "debug": "^3.2.6", "iconv-lite": "^0.4.4", @@ -5152,6 +5213,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-4.0.0.tgz", "integrity": "sha512-2XiryJ8sICNo6ej8d0idXDEMKfVfFK7kekGCtJAuelGsYHQxhj13KTf95swTCN2dZ/4lTfZ84Fu31jqJEEgjWA==", + "dev": true, "requires": { "glob": "^7.0.3", "graceful-fs": "^4.1.2", @@ -5170,6 +5232,7 @@ "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, "requires": { "glob": "^7.1.3" } @@ -5180,6 +5243,7 @@ "version": "0.13.0", "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.13.0.tgz", "integrity": "sha512-Md1D3xnEne8b/HGVQkZZwV27WUi1ZRuZBij24TNaZwUPU3ZAFtvT6xxJGaUVillfmMKnn5oD1HoGsp2Ftik7SQ==", + "dev": true, "requires": { "detect-libc": "^1.0.2", "mkdirp": "^0.5.1", @@ -5197,6 +5261,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", + "dev": true, "requires": { "abbrev": "1", "osenv": "^0.1.4" @@ -5206,6 +5271,7 @@ "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, "requires": { "glob": "^7.1.3" } @@ -5261,6 +5327,7 @@ "version": "3.0.6", "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "dev": true, "requires": { "abbrev": "1" } @@ -5286,12 +5353,14 @@ "normalize-url": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==" + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "dev": true }, "npm-bundled": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.2.tgz", "integrity": "sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ==", + "dev": true, "requires": { "npm-normalize-package-bin": "^1.0.1" } @@ -5299,12 +5368,14 @@ "npm-normalize-package-bin": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", - "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==" + "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==", + "dev": true }, "npm-packlist": { "version": "1.4.8", "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", + "dev": true, "requires": { "ignore-walk": "^3.0.1", "npm-bundled": "^1.0.1", @@ -5315,6 +5386,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "dev": true, "requires": { "are-we-there-yet": "~1.1.2", "console-control-strings": "~1.1.0", @@ -5325,7 +5397,8 @@ "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true }, "nyc": { "version": "15.1.0", @@ -5547,12 +5620,14 @@ "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true }, "object-inspect": { "version": "1.10.3", @@ -5637,17 +5712,20 @@ "os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true }, "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true }, "osenv": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "dev": true, "requires": { "os-homedir": "^1.0.0", "os-tmpdir": "^1.0.0" @@ -5679,7 +5757,8 @@ "p-cancelable": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", - "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==" + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "dev": true }, "p-defer": { "version": "1.0.0", @@ -5691,6 +5770,7 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz", "integrity": "sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==", + "dev": true, "requires": { "p-timeout": "^3.1.0" } @@ -5698,7 +5778,8 @@ "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true }, "p-limit": { "version": "1.3.0", @@ -5731,6 +5812,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "dev": true, "requires": { "p-finally": "^1.0.0" } @@ -5849,7 +5931,8 @@ "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true }, "picomatch": { "version": "2.3.0", @@ -6282,7 +6365,8 @@ "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true }, "process-on-spawn": { "version": "1.0.0", @@ -6327,12 +6411,14 @@ "psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true }, "pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -6341,12 +6427,14 @@ "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true }, "qs": { "version": "6.5.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true }, "queue-microtask": { "version": "1.2.3", @@ -6357,7 +6445,8 @@ "ramda": { "version": "0.25.0", "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.25.0.tgz", - "integrity": "sha512-GXpfrYVPwx3K7RQ6aYT8KPS8XViSXUVJT1ONhoKPE9VAleW42YE+U+8VEyGWt41EnEQW7gwecYJriTI0pKoecQ==" + "integrity": "sha512-GXpfrYVPwx3K7RQ6aYT8KPS8XViSXUVJT1ONhoKPE9VAleW42YE+U+8VEyGWt41EnEQW7gwecYJriTI0pKoecQ==", + "dev": true }, "randombytes": { "version": "2.1.0", @@ -6372,6 +6461,7 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, "requires": { "deep-extend": "^0.6.0", "ini": "~1.3.0", @@ -6427,6 +6517,7 @@ "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -6528,6 +6619,7 @@ "version": "2.88.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "dev": true, "requires": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", @@ -6594,6 +6686,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz", "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==", + "dev": true, "requires": { "lowercase-keys": "^2.0.0" } @@ -6638,17 +6731,20 @@ "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true }, "sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true }, "semver": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", - "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", + "dev": true }, "semver-compare": { "version": "1.0.0", @@ -6668,7 +6764,8 @@ "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true }, "sha.js": { "version": "2.4.11", @@ -6714,7 +6811,8 @@ "signal-exit": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true }, "simple-concat": { "version": "1.0.1", @@ -6914,6 +7012,7 @@ "version": "1.16.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, "requires": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", @@ -6959,6 +7058,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -7013,6 +7113,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, "requires": { "ansi-regex": "^2.0.0" } @@ -7026,7 +7127,8 @@ "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true }, "supports-color": { "version": "5.5.0", @@ -7106,6 +7208,7 @@ "version": "4.4.13", "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", + "dev": true, "requires": { "chownr": "^1.1.1", "fs-minipass": "^1.2.5", @@ -7120,6 +7223,7 @@ "version": "1.16.3", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.3.tgz", "integrity": "sha512-NvCeXpYx7OsmOh8zIOP/ebG55zZmxLE0etfWRbWok+q2Qo8x/vOR/IJT1taADXPe+jsiu9axDb3X4B+iIgNlKw==", + "dev": true, "requires": { "chownr": "^1.0.1", "mkdirp": "^0.5.1", @@ -7131,6 +7235,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz", "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==", + "dev": true, "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -7142,6 +7247,7 @@ "version": "1.6.2", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", + "dev": true, "requires": { "bl": "^1.0.0", "buffer-alloc": "^1.2.0", @@ -7178,7 +7284,8 @@ "to-buffer": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", - "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==" + "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==", + "dev": true }, "to-fast-properties": { "version": "2.0.0", @@ -7189,7 +7296,8 @@ "to-readable-stream": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-2.1.0.tgz", - "integrity": "sha512-o3Qa6DGg1CEXshSdvWNX2sN4QHqg03SPq7U6jPXRahlQdl5dK8oXjkU/2/sGrnOZKeGV1zLSO8qPwyKklPPE7w==" + "integrity": "sha512-o3Qa6DGg1CEXshSdvWNX2sN4QHqg03SPq7U6jPXRahlQdl5dK8oXjkU/2/sGrnOZKeGV1zLSO8qPwyKklPPE7w==", + "dev": true }, "to-regex-range": { "version": "5.0.1", @@ -7204,6 +7312,7 @@ "version": "2.5.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, "requires": { "psl": "^1.1.28", "punycode": "^2.1.1" @@ -7292,6 +7401,7 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, "requires": { "safe-buffer": "^5.0.1" } @@ -7299,7 +7409,8 @@ "tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true }, "type-check": { "version": "0.4.0", @@ -7319,7 +7430,8 @@ "type-fest": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.10.0.tgz", - "integrity": "sha512-EUV9jo4sffrwlg8s0zDhP0T2WD3pru5Xi0+HTE3zTUmBaZNhfkite9PdSJwdXLwPVW0jnAHT56pZHIOYckPEiw==" + "integrity": "sha512-EUV9jo4sffrwlg8s0zDhP0T2WD3pru5Xi0+HTE3zTUmBaZNhfkite9PdSJwdXLwPVW0jnAHT56pZHIOYckPEiw==", + "dev": true }, "typedarray-to-buffer": { "version": "3.1.5", @@ -7454,12 +7566,14 @@ "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true }, "uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, "requires": { "punycode": "^2.1.0" } @@ -7472,7 +7586,8 @@ "uuid": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true }, "v8-compile-cache": { "version": "2.3.0", @@ -7500,6 +7615,7 @@ "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, "requires": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", @@ -7557,6 +7673,7 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, "requires": { "isexe": "^2.0.0" } @@ -7584,6 +7701,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, "requires": { "string-width": "^1.0.2 || 2" } @@ -7695,7 +7813,8 @@ "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true }, "y18n": { "version": "5.0.8", @@ -7706,7 +7825,8 @@ "yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true }, "yaml": { "version": "1.10.2", diff --git a/package.json b/package.json index 2e114355..1b545d12 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,6 @@ "dependencies": { "@octokit/rest": "^18.3.5", "@sosuisen/jsondiffpatch": "^0.4.7", - "@sosuisen/nodegit": "^0.27.3", "@types/async-lock": "^1.1.2", "async-lock": "^1.3.0", "cross-blob": "^2.0.0", diff --git a/tsconfig-base.json b/tsconfig-base.json index e12b55c0..79091dd7 100644 --- a/tsconfig-base.json +++ b/tsconfig-base.json @@ -15,15 +15,11 @@ "baseUrl": ".", "outDir": "dist", "paths": { - "@sosuisen/nodegit": [ - "types/sosuisen__nodegit" - ], "*": [ "node_modules/*" ], }, "typeRoots": [ - "types", "node_modules/@types" ], }, diff --git a/types/sosuisen__nodegit/LICENSE b/types/sosuisen__nodegit/LICENSE deleted file mode 100644 index 9e841e7a..00000000 --- a/types/sosuisen__nodegit/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ - MIT License - - Copyright (c) Microsoft Corporation. - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE diff --git a/types/sosuisen__nodegit/README.md b/types/sosuisen__nodegit/README.md deleted file mode 100644 index 7bf35d48..00000000 --- a/types/sosuisen__nodegit/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# Installation -> `npm install --save @types/nodegit` - -# Summary -This package contains type definitions for nodegit (https://github.com/nodegit/nodegit). - -# Details -Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/nodegit. - -### Additional Details - * Last updated: Mon, 26 Oct 2020 20:58:07 GMT - * Dependencies: [@types/node](https://npmjs.com/package/@types/node) - * Global values: none - -# Credits -These definitions were written by [Dolan Miu](https://github.com/dolanmiu), [Tobias Nießen](https://github.com/tniessen), [Pierre Vigier](https://github.com/pvigier), [Jibril Saffi](https://github.com/IGI-111), [Benjamin Schuster-Boeckler](https://github.com/DaGaMs), and [Julien Chaumond](https://github.com/julien-c). diff --git a/types/sosuisen__nodegit/annotated-commit.d.ts b/types/sosuisen__nodegit/annotated-commit.d.ts deleted file mode 100644 index c6d910b5..00000000 --- a/types/sosuisen__nodegit/annotated-commit.d.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Repository } from './repository'; -import { Oid } from './oid'; -import { Reference } from './reference'; - -export class AnnotatedCommit { - /** - * @param repo - repository that contains the given commit - * @param branchName - name of the (remote) branch - * @param remoteUrl - url of the remote - * @param id - the commit object id of the remote branch - */ - static fromFetchhead(repo: Repository, branchName: string, remoteUrl: string, id: Oid): Promise; - static fromRef(repo: Repository, ref: Reference): Promise; - static fromRevspec(repo: Repository, revspec: string): Promise; - static lookup(repo: Repository, id: Oid): Promise; - - free(): void; - id(): Oid; -} diff --git a/types/sosuisen__nodegit/apply-options.d.ts b/types/sosuisen__nodegit/apply-options.d.ts deleted file mode 100644 index 730722cb..00000000 --- a/types/sosuisen__nodegit/apply-options.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { ConvenientHunk } from './convenient-hunk'; -import { DiffDelta } from './diff-delta'; - -export class ApplyOptions { - deltaCb?: (delta: DiffDelta, payload: any) => number; - hunkCb?: (hunk: ConvenientHunk, payload: any) => number; - version?: number; -} diff --git a/types/sosuisen__nodegit/apply.d.ts b/types/sosuisen__nodegit/apply.d.ts deleted file mode 100644 index 8b94a4ee..00000000 --- a/types/sosuisen__nodegit/apply.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { ApplyOptions } from './apply-options'; -import { Diff } from './diff'; -import { Index } from './index_'; -import { Repository } from './repository'; -import { Tree } from './tree'; - -export namespace Apply { - const enum FLAGS { - CHECK = 1 - } - - const enum LOCATION { - WORKDIR = 0, - INDEX = 1, - BOTH = 2 - } -} - -export class Apply { - static apply(repo: Repository, diff: Diff, location: Apply.LOCATION, options: ApplyOptions): Promise; - static toTree(repo: Repository, preimage: Tree, diff: Diff, options: ApplyOptions): Promise; -} diff --git a/types/sosuisen__nodegit/attr.d.ts b/types/sosuisen__nodegit/attr.d.ts deleted file mode 100644 index a9c51ae8..00000000 --- a/types/sosuisen__nodegit/attr.d.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { Repository } from './repository'; - -export namespace Attr { - const enum STATES { - UNSPECIFIED_T = 0, - TRUE_T = 1, - FALSE_T = 2, - VALUE_T = 3 - } -} - -export class Attr { - static addMacro(repo: Repository, name: string, values: string): number; - static cacheFlush(repo: Repository): void; - /** - * @param repo - The repository containing the path. - * @param flags - A combination of GIT_ATTR_CHECK... flags. - * @param path - The path to check for attributes. Relative paths are interpreted relative to the repo root. - * The file does not have to exist, but if it does not, then it will be treated as a plain file (not a directory). - * @param name - The name of the attribute to look up. - * @returns - Output of the value of the attribute. Use the GIT_ATTR_... - */ - static get(repo: Repository, flags: number, path: string, name: string): Promise; - /** - * @param repo - The repository containing the path. - * @param flags - A combination of GIT_ATTR_CHECK... flags. - * @param path - The path to check for attributes. Relative paths are interpreted relative to the repo root. - * The file does not have to exist, but if it does not, then it will be treated as a plain file (not a directory). - * @param numAttr - The number of attributes being looked up - * @param names - An array of num_attr strings containing attribute names. - */ - static getMany(repo: Repository, flags: number, path: string, numAttr: number, names: string): any[]; - /** - * @param attr - The attribute - * @returns - the value type for the attribute - */ - static value(attr: string): number; -} diff --git a/types/sosuisen__nodegit/blame-hunk.d.ts b/types/sosuisen__nodegit/blame-hunk.d.ts deleted file mode 100644 index 385c0603..00000000 --- a/types/sosuisen__nodegit/blame-hunk.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { Oid } from './oid'; -import { Signature } from './signature'; - -export class BlameHunk { - linesInHunk(): number; - finalCommitId(): Oid; - finalStartLineNumber(): number; - finalSignature(): Signature; - origCommitId(): Oid; - origPath(): string; - origStartLineNumber(): number; - origSignature(): Signature; -} diff --git a/types/sosuisen__nodegit/blame-options.d.ts b/types/sosuisen__nodegit/blame-options.d.ts deleted file mode 100644 index 1fdc6f62..00000000 --- a/types/sosuisen__nodegit/blame-options.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Oid } from './oid'; - -export class BlameOptions { - version?: number; - flags?: number; - minMatchCharacters?: number; - newestCommit?: Oid; - oldestCommit?: Oid; - minLine?: number; - maxLine?: number; - [key: string]: any; -} diff --git a/types/sosuisen__nodegit/blame.d.ts b/types/sosuisen__nodegit/blame.d.ts deleted file mode 100644 index fd1289f5..00000000 --- a/types/sosuisen__nodegit/blame.d.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { Repository } from './repository'; -import { BlameOptions } from './blame-options'; -import { BlameHunk } from './blame-hunk'; - -export namespace Blame { - const enum FLAG { - NORMAL = 0, - TRACK_COPIES_SAME_FILE = 1, - TRACK_COPIES_SAME_COMMIT_MOVES = 2, - TRACK_COPIES_SAME_COMMIT_COPIES = 4, - TRACK_COPIES_ANY_COMMIT_COPIES = 8, - FIRST_PARENT = 16 - } -} - -export class Blame { - /** - * Retrieve the blame of a file - * - * @param repo - Repository that contains the file - * @param path - to the file to get the blame of - * @param [options] - Options for the blame - */ - static file(repo: Repository, path: string, options?: BlameOptions): Promise; - /** - * @param opts - The git_blame_options struct to initialize - * @param version - Version of struct; pass GIT_BLAME_OPTIONS_VERSION - */ - static initOptions(opts: BlameOptions, version: number): number; - - buffer(buffer: string, bufferLen: number): Promise; - - free(): void; - /** - * @returns - the hunk at the given index, or NULL on error - */ - getHunkByIndex(index: number): BlameHunk; - /** - * @returns - the hunk that contains the given line, or NULL on error - */ - getHunkByLine(lineNo: number): BlameHunk; - - getHunkCount(): number; -} diff --git a/types/sosuisen__nodegit/blob.d.ts b/types/sosuisen__nodegit/blob.d.ts deleted file mode 100644 index 1b8b09e3..00000000 --- a/types/sosuisen__nodegit/blob.d.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { WriteStream } from 'fs'; -import { Wrapper } from "./wrapper"; -import { Repository } from './repository'; -import { Oid } from './oid'; - -export class Blob { - /** - * @param repo - repository where to blob will be written - * @param buffer - data to be written into the blob - * @param len - length of the data - * @returns - return the id of the written blob - */ - static createFromBuffer(repo: Repository, buffer: Buffer, len: number): Promise; - /** - * @param repo - repository where the blob will be written. this repository can be bare or not - * @param path - file from which the blob will be created - */ - static createFromDisk(repo: Repository, path: string): Promise; - static createFromStream(repo: Repository, hintPath: string): Promise; - /** - * @param repo - repository where the blob will be written. this repository cannot be bare - * @param relativePath - file from which the blob will be created, relative to the repository's working dir - * @returns - 0 or an error code - */ - static createFromWorkdir(repo: Repository, relativePath: string): Promise; - static filteredContent(blob: Blob, as_path: string, check_for_binary_data: number): Promise; - static lookup(repo: Repository, id: string | Oid | Blob): Promise; - static lookupPrefix(repo: Repository, id: Oid, len: number): Promise; - - free(): void; - id(): Oid; - isBinary(): number; - owner(): Repository; - rawcontent(): Wrapper; - rawsize(): number; - content(): Buffer; - toString(): string; - filemode(): number; - dup(): Promise; -} diff --git a/types/sosuisen__nodegit/branch.d.ts b/types/sosuisen__nodegit/branch.d.ts deleted file mode 100644 index 71dc35b0..00000000 --- a/types/sosuisen__nodegit/branch.d.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Repository } from './repository'; -import { Reference } from './reference'; -import { Commit } from './commit'; -import { AnnotatedCommit } from './annotated-commit'; - -export namespace Branch { - const enum BRANCH { - LOCAL = 1, - REMOTE = 2, - ALL = 3 - } -} - -export class Branch { - static create(repo: Repository, branchName: string, target: Commit, force: number): Promise; - static createFromAnnotated(repository: Repository, branchName: string, commit: AnnotatedCommit, force: number): Reference; - static delete(branch: Reference): number; - static isHead(branch: Reference): number; - static iteratorNew(repo: Repository, listFlags: number): Promise; - static lookup(repo: Repository, branchName: string, branchType: Branch.BRANCH): Promise; - static move(branch: Reference, newBranchName: string, force: number): Promise; - static name(ref: Reference): Promise; - static setUpstream(branch: Reference, upstreamName: string): Promise; - static upstream(branch: Reference): Promise; -} diff --git a/types/sosuisen__nodegit/buf.d.ts b/types/sosuisen__nodegit/buf.d.ts deleted file mode 100644 index 5aefac72..00000000 --- a/types/sosuisen__nodegit/buf.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -/// - -export class Buf { - containsNul(): number; - - free(): void; - grow(targetSize: number): Promise; - isBinary(): number; - set(data: Buffer, datalen: number): Promise; - ptr: string; - asize: number; - size: number; -} diff --git a/types/sosuisen__nodegit/cert-host-key.d.ts b/types/sosuisen__nodegit/cert-host-key.d.ts deleted file mode 100644 index 9932f666..00000000 --- a/types/sosuisen__nodegit/cert-host-key.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Cert } from './cert'; - -export class CertHostkey { - parent: Cert; - type: Cert.TYPE; - hashMd5: string; - hashSha1: string; -} diff --git a/types/sosuisen__nodegit/cert-x509.d.ts b/types/sosuisen__nodegit/cert-x509.d.ts deleted file mode 100644 index 44f6d5a7..00000000 --- a/types/sosuisen__nodegit/cert-x509.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Cert } from './cert'; - -export class CertX509 { - data: Buffer; - len: number; - parent: Cert; -} diff --git a/types/sosuisen__nodegit/cert.d.ts b/types/sosuisen__nodegit/cert.d.ts deleted file mode 100644 index fde86569..00000000 --- a/types/sosuisen__nodegit/cert.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -export namespace Cert { - const enum TYPE { - NONE = 0, - X509 = 1, - HOSTKEY_LIBSSH2 = 2, - STRARRAY = 3 - } - - const enum SSH { - MD5 = 1, - SHA1 = 2 - } -} - -export class Cert { - certType: Cert.TYPE; -} diff --git a/types/sosuisen__nodegit/checkout-options.d.ts b/types/sosuisen__nodegit/checkout-options.d.ts deleted file mode 100644 index 6971f59f..00000000 --- a/types/sosuisen__nodegit/checkout-options.d.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { Strarray } from './str-array'; -import { Tree } from './tree'; -import { Index } from './index'; - -export class CheckoutOptions { - version?: number; - checkoutStrategy?: number; - disableFilters?: number; - dirMode?: number; - fileMode?: number; - fileOpenFlags?: number; - notifyFlags?: number; - notifyCb?: any; - notifyPayload?: undefined; - progressCb?: any; - progressPayload?: undefined; - paths?: Strarray | string | string[]; - baseline?: Tree; - baselineIndex?: Index; - targetDirectory?: string; - ancestorLabel?: string; - ourLabel?: string; - theirLabel?: string; - perfdataCb?: any; - perfdataPayload?: undefined; - [key: string]: any; -} diff --git a/types/sosuisen__nodegit/checkout.d.ts b/types/sosuisen__nodegit/checkout.d.ts deleted file mode 100644 index c29dd2d2..00000000 --- a/types/sosuisen__nodegit/checkout.d.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { Repository } from './repository'; -import { CheckoutOptions } from './checkout-options'; -import { Reference } from './reference'; -import { Oid } from './oid'; -import { Tree } from './tree'; -import { Commit } from './commit'; -import { Index } from './index'; - -export namespace Checkout { - const enum NOTIFY { - NONE = 0, - CONFLICT = 1, - DIRTY = 2, - UPDATED = 4, - UNTRACKED = 8, - IGNORED = 16, - ALL = 65535 - } - - const enum STRATEGY { - NONE = 0, - SAFE = 1, - FORCE = 2, - RECREATE_MISSING = 4, - ALLOW_CONFLICTS = 16, - REMOVE_UNTRACKED = 32, - REMOVE_IGNORED = 64, - UPDATE_ONLY = 128, - DONT_UPDATE_INDEX = 256, - NO_REFRESH = 512, - SKIP_UNMERGED = 1024, - USE_OURS = 2048, - USE_THEIRS = 4096, - DISABLE_PATHSPEC_MATCH = 8192, - SKIP_LOCKED_DIRECTORIES = 262144, - DONT_OVERWRITE_IGNORED = 524288, - CONFLICT_STYLE_MERGE = 1048576, - CONFLICT_STYLE_DIFF3 = 2097152, - DONT_REMOVE_EXISTING = 4194304, - DONT_WRITE_INDEX = 8388608, - UPDATE_SUBMODULES = 65536, - UPDATE_SUBMODULES_IF_CHANGED = 131072 - } -} - -export class Checkout { - /** - * Patch head checkout to automatically coerce objects. - */ - static head(repo: Repository, options?: CheckoutOptions): Promise; - /** - * Patch index checkout to automatically coerce objects. - */ - static index(repo: Repository, The: Index, options?: CheckoutOptions): Promise; - - static initOptions(opts: CheckoutOptions, version: number): number; - /** - * Patch tree checkout to automatically coerce objects. - */ - static tree(repo: Repository, treeish: Oid | Tree | Commit | Reference, options?: CheckoutOptions): Promise; -} diff --git a/types/sosuisen__nodegit/cherry-pick-options.d.ts b/types/sosuisen__nodegit/cherry-pick-options.d.ts deleted file mode 100644 index cde3c0a3..00000000 --- a/types/sosuisen__nodegit/cherry-pick-options.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { MergeOptions } from './merge-options'; -import { CheckoutOptions } from './checkout-options'; - -export interface CherrypickOptions { - version?: number; - mainline?: number; - mergeOpts?: MergeOptions; - checkoutOpts?: CheckoutOptions; -} diff --git a/types/sosuisen__nodegit/cherry-pick.d.ts b/types/sosuisen__nodegit/cherry-pick.d.ts deleted file mode 100644 index 168de79e..00000000 --- a/types/sosuisen__nodegit/cherry-pick.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Repository } from './repository'; -import { Commit } from './commit'; -import { MergeOptions } from './merge-options'; -import { CherrypickOptions } from './cherry-pick-options'; - -export class Cherrypick { - /** - * Cherrypick a commit and, changing the index and working directory - */ - static cherrypick(repo: Repository, commit: Commit, options?: CherrypickOptions): Promise; - /** - * Cherrypicks the given commit against "our" commit, producing an index that reflects the result of the cherrypick. The index is not backed by a repo. - */ - static commit(repo: Repository, cherrypickCommit: Commit, ourCommit: Commit, mainline: number, mergeOptions?: MergeOptions): Promise; - static initOptions(opts: CherrypickOptions, version: number): number; -} diff --git a/types/sosuisen__nodegit/clone-options.d.ts b/types/sosuisen__nodegit/clone-options.d.ts deleted file mode 100644 index 8535b28c..00000000 --- a/types/sosuisen__nodegit/clone-options.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { CheckoutOptions } from './checkout-options'; -import { FetchOptions } from './fetch-options'; - -export class CloneOptions { - version?: number; - checkoutOpts?: CheckoutOptions; - fetchOpts?: FetchOptions; - bare?: number; - local?: number; - checkoutBranch?: string; - repositoryCbPayload?: any; - remoteCbPayload?: any; -} diff --git a/types/sosuisen__nodegit/clone.d.ts b/types/sosuisen__nodegit/clone.d.ts deleted file mode 100644 index 15933d41..00000000 --- a/types/sosuisen__nodegit/clone.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Repository } from './repository'; -import { CloneOptions } from './clone-options'; - -export namespace Clone { - const enum LOCAL { - AUTO = 0, - LOCAL = 1, - NO_LOCAL = 2, - NO_LINKS = 3 - } -} - -export class Clone { - /** - * Patch repository cloning to automatically coerce objects. - */ - static clone(url: string, localPath: string, options?: CloneOptions): Promise; - - static initOptions(opts: CloneOptions, version: number): number; -} diff --git a/types/sosuisen__nodegit/commit.d.ts b/types/sosuisen__nodegit/commit.d.ts deleted file mode 100644 index 8152eb8a..00000000 --- a/types/sosuisen__nodegit/commit.d.ts +++ /dev/null @@ -1,124 +0,0 @@ -import { EventEmitter } from 'events'; - -import { Repository } from './repository'; -import { Signature } from './signature'; -import { Oid } from './oid'; -import { Buf } from './buf'; -import { Object } from './object'; -import { Tree } from './tree'; -import { TreeEntry } from './tree-entry'; -import { Diff } from './diff'; - -export interface HistoryEventEmitter extends EventEmitter { - start(): void; -} - -export class Commit { - static create(repo: Repository, updateRef: string, author: Signature, committer: Signature, messageEncoding: string, message: string, tree: Tree, parentCount: number, parents: any[]): Oid; - static createV(id: Oid, repo: Repository, updateRef: string, author: Signature, committer: Signature, messageEncoding: string, message: string, tree: Tree, parentCount: number): number; - /** - * Retrieves the commit pointed to by the oid - * - * - */ - static lookup(repo: Repository, id: string | Oid | Commit): Promise; - static lookupPrefix(repo: Repository, id: Oid, len: number): Promise; - static createWithSignature(repo: Repository, commitContent: string, signature: string, signatureField: string): Promise; - - amend(updateRef: string, author: Signature, committer: Signature, messageEncoding: string, message: string, tree: Tree | Oid): Promise; - author(): Signature; - committer(): Signature; - - free(): void; - headerField(field: string): Promise; - id(): Oid; - message(): string; - messageEncoding(): string; - messageRaw(): string; - nthGenAncestor(n: number): Promise; - owner(): Repository; - parent(n: number): Promise; - parentId(n: number): Oid; - parentcount(): number; - rawHeader(): string; - summary(): string; - time(): number; - timeOffset(): number; - tree(treeOut: Tree): number; - treeId(): Oid; - /** - * Retrieve the SHA. - * - * - */ - sha(): string; - /** - * Retrieve the commit time as a unix timestamp. - * - * - */ - timeMs(): number; - /** - * Retrieve the commit time as a Date object. - * - * - */ - date(): Date; - /** - * Get the tree associated with this commit. - * - * - */ - getTree(): Promise; - /** - * Retrieve the entry represented by path for this commit. Path must be relative to repository root. - * - * - */ - getEntry(path: string): Promise; - /** - * Walk the history from this commit backwards. - * An EventEmitter is returned that will emit a "commit" event for each commit in the history, and one "end" - * event when the walk is completed. Don't forget to call start() on the returned EventEmitter. - * - * - */ - history(): HistoryEventEmitter; - /** - * Retrieve the commit's parents as commit objects. - * - * - */ - getParents(limit: number, callback?: Function): Promise; - /** - * Retrieve the commit's parent shas. - * - * - */ - parents(): Oid[]; - /** - * Generate an array of diff trees showing changes between this commit and its parent(s). - * - * - */ - getDiff(callback?: Function): Promise; - /** - * Generate an array of diff trees showing changes between this commit and its parent(s). - * - * - */ - getDiffWithOptions(options: Object, callback?: Function): Promise; - /** - * The sha of this commit - * - * - */ - toString(): string; - dup(): Promise; - /** - * consists of a summary - * - * - */ - body(): string; -} diff --git a/types/sosuisen__nodegit/config.d.ts b/types/sosuisen__nodegit/config.d.ts deleted file mode 100644 index 0f707efe..00000000 --- a/types/sosuisen__nodegit/config.d.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { Buf } from './buf'; - -export namespace Config { - const enum LEVEL { - SYSTEM = 1, - XDG = 2, - GLOBAL = 3, - LOCAL = 4, - APP = 5, - HIGHEST_LEVEL = -1 - } - - const enum MAP { - FALSE = 0, - TRUE = 1, - INT32 = 2, - STRING = 3, - } -} - -export class ConfigEntry { - // the documentation says those are variables, - // but in reality they are functions - level(): number; - name(): number; - value(): string; -} - -export class Config { - static findGlobal(): Promise; // the docs says it's a buff but it's actually a string - static findProgramdata(): Promise; - static findSystem(): Promise; - static findXdg(): Promise; - static openDefault(): Promise; - static openOndisk(path: string): Promise; - - deleteEntry(name: string): number; - deleteMultivar(name: string, regexp: string): number; - getBool(name: string): Promise; - getEntry(name: string): Promise; - getInt32(name: string): Promise; - getInt64(name: string): Promise; - getPath(name: string): Promise; // the docs says Buf but it's actually a string - getStringBuf(name: string): Promise; - lock(transaction: any): number; - setBool(name: string, value: number): Promise; - setInt32(name: string, value: number): Promise; - setInt64(name: string, value: number): number; - setMultivar(name: string, regexp: string, value: string): Promise; - setString(name: string, value: string): Promise; - snapshot(): Promise; -} diff --git a/types/sosuisen__nodegit/convenient-hunk.d.ts b/types/sosuisen__nodegit/convenient-hunk.d.ts deleted file mode 100644 index a844fd4e..00000000 --- a/types/sosuisen__nodegit/convenient-hunk.d.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { DiffLine } from './diff-line'; - -export class ConvenientHunk { - /** - * Diff header string that represents the context of this hunk - * of the diff. Something like `@@ -169,14 +167,12 @@ ...` - */ - header(): string; - /** - * The length of the header - */ - headerLen(): number; - /** - * The lines in this hunk - */ - lines(): Promise; - /** - * The number of new lines in the hunk - */ - newLines(): number; - /** - * The starting offset of the first new line in the file - */ - newStart(): number; - /** - * The number of old lines in the hunk - */ - oldLines(): number; - /** - * The starting offset of the first old line in the file - */ - oldStart(): number; - /** - * Number of lines in this hunk - */ - size(): number; -} diff --git a/types/sosuisen__nodegit/convenient-patch.d.ts b/types/sosuisen__nodegit/convenient-patch.d.ts deleted file mode 100644 index 05fa0def..00000000 --- a/types/sosuisen__nodegit/convenient-patch.d.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { ConvenientHunk } from './convenient-hunk'; -import { DiffFile } from './diff-file'; - -export class ConvenientPatch { - /** - * Old attributes of the file - */ - oldFile(): DiffFile; - /** - * New attributes of the file - */ - newFile(): DiffFile; - /** - * The number of hunks in this patch - */ - size(): number; - /** - * The hunks in this patch - */ - hunks(): Promise; - /** - * The status of this patch (unmodified, added, deleted) - */ - status(): number; - /** - * The line statistics of this patch (#contexts, #added, #deleted) - */ - lineStats(): any; - /** - * Is this an unmodified patch? - */ - isUnmodified(): boolean; - /** - * Is this an added patch? - */ - isAdded(): boolean; - /** - * Is this a deleted patch? - */ - isDeleted(): boolean; - /** - * Is this an modified patch - */ - isModified(): boolean; - /** - * Is this a renamed patch? - */ - isRenamed(): boolean; - /** - * Is this a copied patch? - */ - isCopied(): boolean; - /** - * Is this an ignored patch? - */ - isIgnored(): boolean; - /** - * Is this an untracked patch? - */ - isUntracked(): boolean; - /** - * Is this a type change? - */ - isTypeChange(): boolean; - /** - * Is this an undreadable patch? - */ - isUnreadable(): boolean; - /** - * Is this a conflicted patch? - */ - isConflicted(): boolean; -} diff --git a/types/sosuisen__nodegit/cred-user-pass-payload.d.ts b/types/sosuisen__nodegit/cred-user-pass-payload.d.ts deleted file mode 100644 index 95beeb9f..00000000 --- a/types/sosuisen__nodegit/cred-user-pass-payload.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -export class CredUserpassPayload { - username: string; - password: string; -} diff --git a/types/sosuisen__nodegit/cred-username.d.ts b/types/sosuisen__nodegit/cred-username.d.ts deleted file mode 100644 index d7b619eb..00000000 --- a/types/sosuisen__nodegit/cred-username.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { Cred } from './cred'; - -export class CredUsername { - parent: Cred; - username: string; -} diff --git a/types/sosuisen__nodegit/cred.d.ts b/types/sosuisen__nodegit/cred.d.ts deleted file mode 100644 index 160f62f9..00000000 --- a/types/sosuisen__nodegit/cred.d.ts +++ /dev/null @@ -1,24 +0,0 @@ -export namespace Cred { - const enum TYPE { - USERPASS_PLAINTEXT = 1, - SSH_KEY = 2, - SSH_CUSTOM = 4, - DEFAULT = 8, - SSH_INTERACTIVE = 16, - USERNAME = 32, - SSH_MEMORY = 64 - } -} - -export class Cred { - static defaultNew(): Cred; - static sshKeyFromAgent(username: string): Cred; - static sshKeyMemoryNew(username: string, publicKey: string, privateKey: string, passphrase: string): Promise; - static sshKeyNew(username: string, publicKey: string, privateKey: string, passphrase: string): Cred; - static usernameNew(username: string): Promise; - static userpassPlaintextNew(username: string, password: string): Cred; - - hasUsername(): number; - - free(): void; -} diff --git a/types/sosuisen__nodegit/cvar-map.d.ts b/types/sosuisen__nodegit/cvar-map.d.ts deleted file mode 100644 index f7c4b227..00000000 --- a/types/sosuisen__nodegit/cvar-map.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -export class CvarMap { - cvarType: number; - strMatch: string; - mapValue: number; -} diff --git a/types/sosuisen__nodegit/describe-format-options.d.ts b/types/sosuisen__nodegit/describe-format-options.d.ts deleted file mode 100644 index b4213f0d..00000000 --- a/types/sosuisen__nodegit/describe-format-options.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -export class DescribeFormatOptions { - version?: number; - abbreviatedSize?: number; - alwaysUseLongFormat?: number; - dirtySuffix?: string; - [key: string]: any; -} diff --git a/types/sosuisen__nodegit/describe-options.d.ts b/types/sosuisen__nodegit/describe-options.d.ts deleted file mode 100644 index 2934006a..00000000 --- a/types/sosuisen__nodegit/describe-options.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -export class DescribeOptions { - version?: number; - maxCandidatesTags?: number; - describeStrategy?: number; - pattern?: string; - onlyFollowFirstParent?: number; - showCommitOidAsFallback?: number; - [key: string]: any; -} diff --git a/types/sosuisen__nodegit/diff-binary-file.d.ts b/types/sosuisen__nodegit/diff-binary-file.d.ts deleted file mode 100644 index 362e1a63..00000000 --- a/types/sosuisen__nodegit/diff-binary-file.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Object } from './object'; - -export class DiffBinaryFile { - type: Object.TYPE; - data: string; - datalen: number; - inflatedlen: number; -} diff --git a/types/sosuisen__nodegit/diff-binary.d.ts b/types/sosuisen__nodegit/diff-binary.d.ts deleted file mode 100644 index d5f7c6fd..00000000 --- a/types/sosuisen__nodegit/diff-binary.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { DiffBinaryFile } from './diff-binary-file'; - -export namespace DiffBinary { - const enum DIFF_BINARY { - NONE = 0, - LITERAL = 1, - DELTA = 2 - } -} - -export class DiffBinary { - oldFile: DiffBinaryFile; - newFile: DiffBinaryFile; - containsData: DiffBinary.DIFF_BINARY; -} diff --git a/types/sosuisen__nodegit/diff-delta.d.ts b/types/sosuisen__nodegit/diff-delta.d.ts deleted file mode 100644 index 2afda666..00000000 --- a/types/sosuisen__nodegit/diff-delta.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { DiffFile } from './diff-file'; - -export class DiffDelta { - status: () => number; - flags: () => number; - similarity: () => number; - nfiles: () => number; - oldFile: () => DiffFile; - newFile: () => DiffFile; -} diff --git a/types/sosuisen__nodegit/diff-file.d.ts b/types/sosuisen__nodegit/diff-file.d.ts deleted file mode 100644 index 9f418ccd..00000000 --- a/types/sosuisen__nodegit/diff-file.d.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Oid } from './oid'; - -export class DiffFile { - /** - * Returns the file's flags - */ - flags(): number; - /** - * Returns the file's Oid - */ - id(): Oid; - /** - * Returns the file's mode - */ - mode(): number; - /** - * Returns the file's path - */ - path(): string; - /** - * Returns the file's size - */ - size(): number; -} diff --git a/types/sosuisen__nodegit/diff-line.d.ts b/types/sosuisen__nodegit/diff-line.d.ts deleted file mode 100644 index 7d1c0713..00000000 --- a/types/sosuisen__nodegit/diff-line.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -export class DiffLine { - /** - * The relevant line - * - * - */ - content(): string; - /** - * The non utf8 translated text - * - * - */ - rawContent(): string; - origin(): number; - oldLineno(): number; - newLineno(): number; - numLines(): number; - contentLen(): number; - contentOffset(): number; -} diff --git a/types/sosuisen__nodegit/diff-options.d.ts b/types/sosuisen__nodegit/diff-options.d.ts deleted file mode 100644 index 3925f5c7..00000000 --- a/types/sosuisen__nodegit/diff-options.d.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Strarray } from './str-array'; - -export interface DiffOptions { - version?: number; - flags?: number; - ignoreSubmodules?: number; - pathspec?: Strarray | string | string[]; - notifyCb?: Function; - contextLines?: number; - interhunkLines?: number; - idAbbrev?: number; - maxSize?: number; - oldPrefix?: string; - newPrefix?: string; - payload?: any; - progressCb?: any; - [key: string]: any; -} diff --git a/types/sosuisen__nodegit/diff-perf-data.d.ts b/types/sosuisen__nodegit/diff-perf-data.d.ts deleted file mode 100644 index 5dfca096..00000000 --- a/types/sosuisen__nodegit/diff-perf-data.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -export class DiffPerfdata { - version: number; - statCalls: number; - oidCalculations: number; -} diff --git a/types/sosuisen__nodegit/diff-stats.d.ts b/types/sosuisen__nodegit/diff-stats.d.ts deleted file mode 100644 index 01a5a3c8..00000000 --- a/types/sosuisen__nodegit/diff-stats.d.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Buf } from './buf'; - -export class DiffStats { - /** - * @returns - total number of deletions in the diff - */ - deletions(): Number; - - /** - * @returns - total number of files changed in the diff - */ - filesChanged(): Number; - - /** - * @returns - total number of insertions in the diff - */ - insertions(): Number; - - /** - * @param format - Formatting option. - * @param width - Target width for output (only affects GIT_DIFF_STATS_FULL) - * @returns - buffer to store the formatted diff statistics in. - */ - toBuf(format: Number, width: Number): Promise; -} diff --git a/types/sosuisen__nodegit/diff.d.ts b/types/sosuisen__nodegit/diff.d.ts deleted file mode 100644 index e62f59d4..00000000 --- a/types/sosuisen__nodegit/diff.d.ts +++ /dev/null @@ -1,172 +0,0 @@ -import { Blob } from './blob'; -import { Repository } from './repository'; -import { Tree } from './tree'; -import { Strarray } from './str-array'; -import { Index } from './index_'; -import { DiffDelta } from './diff-delta'; -import { DiffPerfdata } from './diff-perf-data'; -import { DiffOptions } from './diff-options'; -import { Buf } from './buf'; -import { ConvenientPatch } from './convenient-patch'; -import { DiffStats } from './diff-stats'; - -export interface DiffFindOptions { - version?: number; - flags?: number; - renameThreshold?: number; - renameFromRewriteThreshold?: number; - copyThreshold?: number; - breakRewriteThreshold?: number; - renameLimit?: number; -} - -export namespace Diff { - const enum DELTA { - UNMODIFIED = 0, - ADDED = 1, - DELETED = 2, - MODIFIED = 3, - RENAMED = 4, - COPIED = 5, - IGNORED = 6, - UNTRACKED = 7, - TYPECHANGE = 8, - UNREADABLE = 9, - CONFLICTED = 10, - } - - const enum FIND { - BY_CONFIG = 0, - RENAMES = 1, - RENAMES_FROM_REWRITES = 2, - COPIES = 4, - COPIES_FROM_UNMODIFIED = 8, - REWRITES = 16, - BREAK_REWRITES = 32, - AND_BREAK_REWRITES = 48, - FOR_UNTRACKED = 64, - ALL = 255, - IGNORE_LEADING_WHITESPACE = 0, - IGNORE_WHITESPACE = 4096, - DONT_IGNORE_WHITESPACE = 8192, - EXACT_MATCH_ONLY = 16384, - BREAK_REWRITES_FOR_RENAMES_ONLY = 32768, - REMOVE_UNMODIFIED = 65536, - } - - const enum FLAG { - BINARY = 1, - NOT_BINARY = 2, - VALID_ID = 4, - EXISTS = 8, - } - - const enum FORMAT { - PATCH = 1, - PATCH_HEADER = 2, - RAW = 3, - NAME_ONLY = 4, - NAME_STATUS = 5, - } - - const enum FORMAT_EMAIL_FLAGS { - FORMAT_EMAIL_NONE = 0, - FORMAT_EMAIL_EXCLUDE_SUBJECT_PATCH_MARKER = 1, - } - - const enum LINE { - CONTEXT = 32, - ADDITION = 43, - DELETION = 45, - CONTEXT_EOFNL = 61, - ADD_EOFNL = 62, - DEL_EOFNL = 60, - FILE_HDR = 70, - HUNK_HDR = 72, - BINARY = 66, - } - - const enum OPTION { - NORMAL = 0, - REVERSE = 1, - INCLUDE_IGNORED = 2, - RECURSE_IGNORED_DIRS = 4, - INCLUDE_UNTRACKED = 8, - RECURSE_UNTRACKED_DIRS = 16, - INCLUDE_UNMODIFIED = 32, - INCLUDE_TYPECHANGE = 64, - INCLUDE_TYPECHANGE_TREES = 128, - IGNORE_FILEMODE = 256, - IGNORE_SUBMODULES = 512, - IGNORE_CASE = 1024, - INCLUDE_CASECHANGE = 2048, - DISABLE_PATHSPEC_MATCH = 4096, - SKIP_BINARY_CHECK = 8192, - ENABLE_FAST_UNTRACKED_DIRS = 16384, - UPDATE_INDEX = 32768, - INCLUDE_UNREADABLE = 65536, - INCLUDE_UNREADABLE_AS_UNTRACKED = 131072, - FORCE_TEXT = 1048576, - FORCE_BINARY = 2097152, - IGNORE_WHITESPACE = 4194304, - IGNORE_WHITESPACE_CHANGE = 8388608, - IGNORE_WHITESPACE_EOL = 16777216, - SHOW_UNTRACKED_CONTENT = 33554432, - SHOW_UNMODIFIED = 67108864, - PATIENCE = 268435456, - MINIMAL = 536870912, - SHOW_BINARY = 1073741824, - } - - const enum STATS_FORMAT { - STATS_NONE = 0, - STATS_FULL = 1, - STATS_SHORT = 2, - STATS_NUMBER = 4, - STATS_INCLUDE_SUMMARY = 8, - } -} - -export class Diff { - /** - * Directly run a diff between a blob and a buffer. - * - * - */ - static blobToBuffer( - oldBlob?: Blob, - oldAsPath?: string, - buffer?: string, - bufferAsPath?: string, - opts?: DiffOptions, - fileCb?: Function, - binaryCb?: Function, - hunkCb?: Function, - lineCb?: Function, - ): Promise; - static fromBuffer(content: string, contentLen: number): Promise; - static indexToWorkdir(repo: Repository, index?: Index, opts?: DiffOptions): Promise; - static indexToIndex(repo: Repository, oldIndex: Index, newIndex: Index, opts?: DiffOptions): Promise; - static treeToIndex(repo: Repository, oldTree?: Tree, index?: Index, opts?: DiffOptions): Promise; - static treeToTree(repo: Repository, oldTree?: Tree, new_tree?: Tree, opts?: DiffOptions): Promise; - static treeToWorkdir(repo: Repository, oldTree?: Tree, opts?: DiffOptions): Promise; - static treeToWorkdirWithIndex(repo: Repository, oldTree?: Tree, opts?: DiffOptions): Promise; - - findSimilar(options?: DiffFindOptions): Promise; - getDelta(idx: number): DiffDelta; - getPerfdata(): Promise; - numDeltas(): number; - /** - * Retrieve patches in this difflist - * - * - */ - patches(): Promise; - merge(from: Diff): Promise; - toBuf(format: Diff.FORMAT): Promise; - - /** - * @returns - Structure containg the diff statistics. - */ - getStats(): Promise; -} diff --git a/types/sosuisen__nodegit/enums.d.ts b/types/sosuisen__nodegit/enums.d.ts deleted file mode 100644 index 4fb44850..00000000 --- a/types/sosuisen__nodegit/enums.d.ts +++ /dev/null @@ -1,41 +0,0 @@ -export namespace Enums { - const enum CVAR { - FALSE = 0, - TRUE = 1, - INT32 = 2, - string = 3 - } - - const enum DIRECTION { - FETCH = 0, - PUSH = 1 - } - - const enum FEATURE { - THREADS = 1, - HTTPS = 2, - SSH = 4 - } - - const enum IDXENTRY_EXTENDED_FLAG { - IDXENTRY_INTENT_TO_ADD = 8192, - IDXENTRY_SKIP_WORKTREE = 16384, - IDXENTRY_EXTENDED2 = 32768, - S = 24576, - IDXENTRY_UPDATE = 1, - IDXENTRY_REMOVE = 2, - IDXENTRY_UPTODATE = 4, - IDXENTRY_ADDED = 8, - IDXENTRY_HASHED = 16, - IDXENTRY_UNHASHED = 32, - IDXENTRY_WT_REMOVE = 64, - IDXENTRY_CONFLICTED = 128, - IDXENTRY_UNPACKED = 256, - IDXENTRY_NEW_SKIP_WORKTREE = 512 - } - - const enum INDXENTRY_FLAG { - IDXENTRY_EXTENDED = 16384, - IDXENTRY_VALID = 32768 - } -} diff --git a/types/sosuisen__nodegit/error.d.ts b/types/sosuisen__nodegit/error.d.ts deleted file mode 100644 index c259749e..00000000 --- a/types/sosuisen__nodegit/error.d.ts +++ /dev/null @@ -1,68 +0,0 @@ -export namespace Error { - const enum ERROR { - GITERR_NONE = 0, - GITERR_NOMEMORY = 1, - GITERR_OS = 2, - GITERR_INVALID = 3, - GITERR_REFERENCE = 4, - GITERR_ZLIB = 5, - GITERR_REPOSITORY = 6, - GITERR_CONFIG = 7, - GITERR_REGEX = 8, - GITERR_ODB = 9, - GITERR_INDEX = 10, - GITERR_OBJECT = 11, - GITERR_NET = 12, - GITERR_TAG = 13, - GITERR_TREE = 14, - GITERR_INDEXER = 15, - GITERR_SSL = 16, - GITERR_SUBMODULE = 17, - GITERR_THREAD = 18, - GITERR_STASH = 19, - GITERR_CHECKOUT = 20, - GITERR_FETCHHEAD = 21, - GITERR_MERGE = 22, - GITERR_SSH = 23, - GITERR_FILTER = 24, - GITERR_REVERT = 25, - GITERR_CALLBACK = 26, - GITERR_CHERRYPICK = 27, - GITERR_DESCRIBE = 28, - GITERR_REBASE = 29, - GITERR_FILESYSTEM = 30 - } - - const enum CODE { - OK = 0, - ERROR = -1, - ENOTFOUND = -3, - EEXISTS = -4, - EAMBIGUOUS = -5, - EBUFS = -6, - EUSER = -7, - EBAREREPO = -8, - EUNBORNBRANCH = -9, - EUNMERGED = -10, - ENONFASTFORWARD = -11, - EINVALIDSPEC = -12, - ECONFLICT = -13, - ELOCKED = -14, - EMODIFIED = -15, - EAUTH = -16, - ECERTIFICATE = -17, - EAPPLIED = -18, - EPEEL = -19, - EEOF = -20, - EINVALID = -21, - EUNCOMMITTED = -22, - EDIRECTORY = -23, - PASSTHROUGH = -30, - ITEROVER = -31 - } -} - -export class Error { - message: string; - klass: number; -} diff --git a/types/sosuisen__nodegit/fetch-options.d.ts b/types/sosuisen__nodegit/fetch-options.d.ts deleted file mode 100644 index 4a418b67..00000000 --- a/types/sosuisen__nodegit/fetch-options.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { RemoteCallbacks } from './remote-callbacks'; -import { Strarray } from './str-array'; - -export class FetchOptions { - version?: number; - callbacks?: RemoteCallbacks; - prune?: number; - updateFetchhead?: number; - downloadTags?: number; - customHeaders?: Strarray | string | string[]; - proxyOpts?: any; - [key: string]: any; -} diff --git a/types/sosuisen__nodegit/fetch.d.ts b/types/sosuisen__nodegit/fetch.d.ts deleted file mode 100644 index db098058..00000000 --- a/types/sosuisen__nodegit/fetch.d.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { FetchOptions } from './fetch-options'; - -export namespace Fetch { - const enum PRUNE { - GIT_FETCH_PRUNE_UNSPECIFIED = 0, - GIT_FETCH_PRUNE = 1, - GIT_FETCH_NO_PRUNE = 2 - } -} - -export class Fetch { - static initOptions(opts: FetchOptions, version: number): number; -} diff --git a/types/sosuisen__nodegit/filter.d.ts b/types/sosuisen__nodegit/filter.d.ts deleted file mode 100644 index 066a5118..00000000 --- a/types/sosuisen__nodegit/filter.d.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { WriteStream } from 'fs'; - -import { Repository } from './repository'; -import { Blob } from './blob'; -import { Buf } from './buf'; - -export namespace Filter { - const enum FLAG { - DEFAULT = 0, - ALLOW_UNSAFE = 1 - } - - const enum MODE { - TO_WORKTREE = 0, - SMUDGE = 0, - TO_ODB = 1, - CLEAN = 1 - } -} - -export class Filter { - static listContains(filters: any, name: string): number; - static listLength(fl: any): number; - static listNew(repo: Repository, mode: number, options: number): Promise; - static listStreamBlob(filters: any, blob: Blob, target: WriteStream): number; - static listStreamData(filters: any, data: Buf, target: WriteStream): number; - static listStreamFile(filters: any, repo: Repository, path: string, target: WriteStream): number; - static unregister(name: string): number; - - lookup(name: string): Filter; - register(name: string, priority: number): number; - version: number; - attributes: string; - stream: Function; -} diff --git a/types/sosuisen__nodegit/git-err.d.ts b/types/sosuisen__nodegit/git-err.d.ts deleted file mode 100644 index 1ba84342..00000000 --- a/types/sosuisen__nodegit/git-err.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Error } from './error'; - -export class Giterr { - static errClear(): void; - static errLast(): Error; - static errSetOom(): void; - static errSetString(errorClass: number, string: string): void; -} diff --git a/types/sosuisen__nodegit/graph.d.ts b/types/sosuisen__nodegit/graph.d.ts deleted file mode 100644 index d16d7b5d..00000000 --- a/types/sosuisen__nodegit/graph.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Repository } from './repository'; -import { Oid } from './oid'; - -export class Graph { - static aheadBehind(repo: Repository, local: Oid, upstream: Oid): Promise; - static descendantOf(repo: Repository, commit: Oid, ancestor: Oid): Promise; -} diff --git a/types/sosuisen__nodegit/hash-sig.d.ts b/types/sosuisen__nodegit/hash-sig.d.ts deleted file mode 100644 index 229d26d7..00000000 --- a/types/sosuisen__nodegit/hash-sig.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -export namespace Hashsig { - const enum OPTION { - NORMAL = 0, - IGNORE_WHITESPACE = 1, - SMART_WHITESPACE = 2, - ALLOW_SMALL_FILES = 4 - } -} - -export class Hashsig { - static create(buf: string, buflen: number, opts: number): Promise; - static createFromFile(path: string, opts: number): Promise; - - compare(b: Hashsig): number; - - free(): void; -} diff --git a/types/sosuisen__nodegit/ignore.d.ts b/types/sosuisen__nodegit/ignore.d.ts deleted file mode 100644 index c38d84d1..00000000 --- a/types/sosuisen__nodegit/ignore.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Repository } from './repository'; - -export class Ignore { - static addRule(repo: Repository, rules: string): number; - static clearInternalRules(repo: Repository): number; - static pathIsIgnored(repo: Repository, path: string): Promise; -} diff --git a/types/sosuisen__nodegit/index-entry.d.ts b/types/sosuisen__nodegit/index-entry.d.ts deleted file mode 100644 index 978cf24b..00000000 --- a/types/sosuisen__nodegit/index-entry.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Oid } from './oid'; - -export interface IndexTime { - seconds(): number; - nanoseconds(): number; -} - -export class IndexEntry { - ctime: IndexTime; - mtime: IndexTime; - dev: number; - ino: number; - mode: number; - uid: number; - gid: number; - fileSize: number; - id: Oid; - flags: number; - flagsExtended: number; - path: string; -} diff --git a/types/sosuisen__nodegit/index.d.ts b/types/sosuisen__nodegit/index.d.ts deleted file mode 100644 index ac621d64..00000000 --- a/types/sosuisen__nodegit/index.d.ts +++ /dev/null @@ -1,116 +0,0 @@ -// Type definitions for nodegit 0.26 -// Project: https://github.com/nodegit/nodegit, http://nodegit.org -// Definitions by: Dolan Miu , -// Tobias Nießen , -// Pierre Vigier -// Jibril Saffi -// Benjamin Schuster-Boeckler -// Julien Chaumond -// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped - -export { AnnotatedCommit } from './annotated-commit'; -export { Apply } from './apply'; -export { ApplyOptions } from './apply-options'; -export { Attr } from './attr'; -export { BlameHunk } from './blame-hunk'; -export { BlameOptions } from './blame-options'; -export { Blame } from './blame'; -export { Blob } from './blob'; -export { Branch } from './branch'; -export { Buf } from './buf'; -export { CertHostkey } from './cert-host-key'; -export { CertX509 } from './cert-x509'; -export { Cert } from './cert'; -export { CheckoutOptions } from './checkout-options'; -export { Checkout } from './checkout'; -export { CherrypickOptions } from './cherry-pick-options'; -export { Cherrypick } from './cherry-pick'; -export { CloneOptions } from './clone-options'; -export { Clone } from './clone'; -export { Commit } from './commit'; -export { Config } from './config'; -export { ConvenientHunk } from './convenient-hunk'; -export { ConvenientPatch } from './convenient-patch'; -export { CredUserpassPayload } from './cred-user-pass-payload'; -export { CredUsername } from './cred-username'; -export { Cred } from './cred'; -export { CvarMap } from './cvar-map'; -export { DescribeFormatOptions } from './describe-format-options'; -export { DescribeOptions } from './describe-options'; -export { DiffBinaryFile } from './diff-binary-file'; -export { DiffBinary } from './diff-binary'; -export { DiffDelta } from './diff-delta'; -export { DiffFile } from './diff-file'; -export { DiffLine } from './diff-line'; -export { DiffOptions } from './diff-options'; -export { DiffPerfdata } from './diff-perf-data'; -export { DiffStats } from './diff-stats'; -export { Diff, DiffFindOptions } from './diff'; -export { Enums } from './enums'; -export { Error } from './error'; -export { FetchOptions } from './fetch-options'; -export { Fetch } from './fetch'; -export { Filter } from './filter'; -export { Giterr } from './git-err'; -export { Graph } from './graph'; -export { Hashsig } from './hash-sig'; -export { Index } from './index_'; -export { IndexEntry } from './index-entry'; -export { Ignore } from './ignore'; -export { Indexer } from './indexer'; -export { Libgit2 } from './lib-git2'; -export { MergeFileInput } from './merge-file-input'; -export { MergeFileOptions } from './merge-file-options'; -export { MergeFileResult } from './merge-file-result'; -export { MergeOptions } from './merge-options'; -export { Merge } from './merge'; -export { Note } from './note'; -export { Object } from './object'; -export { OdbExpandId } from './odb-expand-id'; -export { OdbObject } from './odb-object'; -export { Odb } from './odb'; -export { Oidarray } from './oid-array'; -export { Oid } from './oid'; -export { Openssl } from './open-ssl'; -export { Packbuilder } from './pack-builder'; -export { Pathspec } from './path-spec'; -export { ProxyOptions } from './proxy-options'; -export { Proxy } from './proxy'; -export { PushOptions } from './push-options'; -export { PushUpdate } from './push-update'; -export { Push } from './push'; -export { RebaseOperation } from './rebase-operation'; -export { Rebase, RebaseOptions } from './rebase'; -export { Refdb } from './ref-db'; -export { Reflog, ReflogEntry } from './ref-log'; -export { Refspec } from './ref-spec'; -export { Reference } from './reference'; -export { RemoteCallbacks } from './remote-callbacks'; -export { Remote } from './remote'; -export { Repository, RepositoryInitOptions } from './repository'; -export { Reset } from './reset'; -export { Revparse } from './rev-parse'; -export { Revwalk } from './rev-walk'; -export { Revert } from './revert'; -export { Signature } from './signature'; -export { Stash } from './stash'; -export { StatusEntry } from './status-entry'; -export { StatusFileOptions } from './status-file-options'; -export { StatusFile } from './status-file'; -export { StatusList } from './status-list'; -export { StatusOptions } from './status-options'; -export { Status } from './status'; -export { Strarray } from './str-array'; -export { SubmoduleUpdateOptions } from './submodule-update-options'; -export { Submodule } from './submodule'; -export { Tag } from './tag'; -export { Time } from './time'; -export { TransferProgress } from './transfer-progress'; -export { Transport } from './transport'; -export { Treebuilder } from './tree-builder'; -export { TreeEntry } from './tree-entry'; -export { TreeUpdate } from './tree-update'; -export { Tree } from './tree'; -export const version: string; -declare const _: typeof Promise; -export { _ as Promise }; diff --git a/types/sosuisen__nodegit/index_.d.ts b/types/sosuisen__nodegit/index_.d.ts deleted file mode 100644 index 4d4a8206..00000000 --- a/types/sosuisen__nodegit/index_.d.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { Oid } from './oid'; -import { IndexEntry } from './index-entry'; -import { Repository } from './repository'; -import { Tree } from './tree'; -import { Strarray } from './str-array'; - -export namespace Index { - const enum ADD_OPTION { - ADD_DEFAULT = 0, - ADD_FORCE = 1, - ADD_DISABLE_PATHSPEC_MATCH = 2, - ADD_CHECK_PATHSPEC = 4 - } - - const enum CAP { - IGNORE_CASE = 1, - NO_FILEMODE = 2, - NO_SYMLINKS = 4, - FROM_OWNER = -1 - } -} - -export class Index { - static entryIsConflict(entry: IndexEntry): boolean; - static entryStage(entry: IndexEntry): number; - static open(indexPath: string): Promise; - - add(sourceEntry: IndexEntry): number; - addAll(pathspec?: Strarray | string | string[], flags?: number, callback?: Function): Promise; - addByPath(path: string): Promise; - caps(): number; - checksum(): Oid; - clear(): number; - conflictAdd(ancestorEntry: IndexEntry, ourEntry: IndexEntry, theirEntry: IndexEntry): number; - conflictCleanup(): number; - conflictGet(path: string): Promise; - conflictRemove(path: string): number; - entryCount(): number; - getByIndex(n: number): IndexEntry; - getByPath(path: string, stage?: number): IndexEntry; - hasConflicts(): boolean; - owner(): Repository; - path(): string; - read(force: number): number; - readTree(tree: Tree): number; - remove(path: string, stage: number): number; - removeAll(pathspec: Strarray | string | string[], callback?: Function): Promise; - removeByPath(path: string): Promise; - removeDirectory(dir: string, stage: number): number; - setCaps(caps: number): number; - updateAll(pathspec: Strarray | string | string[], callback?: Function): Promise; - write(): Promise; - writeTree(): Promise; - writeTreeTo(repo: Repository): Promise; - entries(): IndexEntry[]; - findPrefix(atPos: number, prefix: string): number; - setVersion(version: number): number; - version(): number; -} diff --git a/types/sosuisen__nodegit/indexer.d.ts b/types/sosuisen__nodegit/indexer.d.ts deleted file mode 100644 index d4d3210b..00000000 --- a/types/sosuisen__nodegit/indexer.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { TransferProgress } from './transfer-progress'; -import { Oid } from './oid'; - -export class Indexer { - commit(stats: TransferProgress): number; - - free(): void; - hash(): Oid; -} diff --git a/types/sosuisen__nodegit/lib-git2.d.ts b/types/sosuisen__nodegit/lib-git2.d.ts deleted file mode 100644 index be5a5d18..00000000 --- a/types/sosuisen__nodegit/lib-git2.d.ts +++ /dev/null @@ -1,25 +0,0 @@ -export namespace Libgit2 { - const enum OPT { - GET_MWINDOW_SIZE = 0, - SET_MWINDOW_SIZE = 1, - GET_MWINDOW_MAPPED_LIMIT = 2, - SET_MWINDOW_MAPPED_LIMIT = 3, - GET_SEARCH_PATH = 4, - SET_SEARCH_PATH = 5, - SET_CACHE_OBJECT_LIMIT = 6, - SET_CACHE_MAX_SIZE = 7, - ENABLE_CACHING = 8, - GET_CACHED_MEMORY = 9, - GET_TEMPLATE_PATH = 10, - SET_TEMPLATE_PATH = 11, - SET_SSL_CERT_LOCATIONS = 12 - } -} - -export class Libgit2 { - static features(): number; - static init(): number; - static opts(option: number): number; - static shutdown(): number; - static version(major: number, minor: number, rev: number): void; -} diff --git a/types/sosuisen__nodegit/merge-file-input.d.ts b/types/sosuisen__nodegit/merge-file-input.d.ts deleted file mode 100644 index f49bd446..00000000 --- a/types/sosuisen__nodegit/merge-file-input.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -export interface MergeFileInput { - version: number; - ptr: string; - size: number; - path: string; - mode: number; -} diff --git a/types/sosuisen__nodegit/merge-file-options.d.ts b/types/sosuisen__nodegit/merge-file-options.d.ts deleted file mode 100644 index 861abaf9..00000000 --- a/types/sosuisen__nodegit/merge-file-options.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -export interface MergeFileOptions { - version?: number; - ancestorLabel?: string; - ourLabel?: string; - theirLabel?: string; - favor?: number; - flags?: number; - [key: string]: any; -} diff --git a/types/sosuisen__nodegit/merge-file-result.d.ts b/types/sosuisen__nodegit/merge-file-result.d.ts deleted file mode 100644 index e6f2efcc..00000000 --- a/types/sosuisen__nodegit/merge-file-result.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -export class MergeFileResult { - automergeable: number; - path: string; - mode: number; - ptr: string; - len: number; -} diff --git a/types/sosuisen__nodegit/merge-options.d.ts b/types/sosuisen__nodegit/merge-options.d.ts deleted file mode 100644 index 51494220..00000000 --- a/types/sosuisen__nodegit/merge-options.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -export class MergeOptions { - version?: number; - renameThreshold?: number; - targetLimit?: number; - fileFavor?: number; - fileFlags?: number; - defaultDriver?: string; - flags?: number; - recursionLimit?: number; - [key: string]: any; -} diff --git a/types/sosuisen__nodegit/merge.d.ts b/types/sosuisen__nodegit/merge.d.ts deleted file mode 100644 index 4233b725..00000000 --- a/types/sosuisen__nodegit/merge.d.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { Repository } from './repository'; -import { Oid } from './oid'; -import { Tree } from './tree'; -import { Commit } from './commit'; -import { Index } from './index'; -import { AnnotatedCommit } from './annotated-commit'; -import { CheckoutOptions } from './checkout-options'; -import { Oidarray } from './oid-array'; -import { MergeOptions } from './merge-options'; -import { MergeFileInput } from './merge-file-input'; - -export namespace Merge { - const enum ANALYSIS { - NONE = 0, - NORMAL = 1, - UP_TO_DATE = 2, - FASTFORWARD = 4, - UNBORN = 8 - } - - const enum FILE_FAVOR { - NORMAL = 0, - OURS = 1, - THEIRS = 2, - UNION = 3 - } - - const enum FILE_FLAGS { - FILE_DEFAULT = 0, - FILE_STYLE_MERGE = 1, - FILE_STYLE_DIFF3 = 2, - FILE_SIMPLIFY_ALNUM = 4, - FILE_IGNORE_WHITESPACE = 8, - FILE_IGNORE_WHITESPACE_CHANGE = 16, - FILE_IGNORE_WHITESPACE_EOL = 32, - FILE_DIFF_PATIENCE = 64, - FILE_DIFF_MINIMAL = 128 - } - - const enum PREFERENCE { - NONE = 0, - NO_FASTFORWARD = 1, - FASTFORWARD_ONLY = 2 - } - - const enum TREE_FLAG { - TREE_FIND_RENAMES = 1 - } -} - -export class Merge { - static merge(repo: Repository, theirHead: AnnotatedCommit, mergeOpts?: MergeOptions, checkoutOpts?: CheckoutOptions): any; - static base(repo: Repository, one: Oid, two: Oid): Promise; - static bases(repo: Repository, one: Oid, two: Oid): Promise; - static commits(repo: Repository, ourCommit: Commit, theirCommit: Commit, options?: MergeOptions): any; - static fileInitInput(opts: MergeFileInput, version: number): number; - static initOptions(opts: MergeOptions, version: number): number; - static trees(repo: Repository, ancestorTree: Tree, ourTree: Tree, theirTree: Tree, opts?: MergeOptions): Promise; -} diff --git a/types/sosuisen__nodegit/note.d.ts b/types/sosuisen__nodegit/note.d.ts deleted file mode 100644 index b2c196c3..00000000 --- a/types/sosuisen__nodegit/note.d.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Repository } from './repository'; -import { Signature } from './signature'; -import { Oid } from './oid'; - -export class Note { - static create(repo: Repository, notesRef: string, author: Signature, committer: Signature, oid: Oid, note: string, force: number): Promise; - static foreach(repo: Repository, notesRef: string, noteCb: Function, payload: any): Promise; - static iteratorNew(repo: Repository, notesRef: string): Promise; - static next(noteId: Oid, annotatedId: Oid, it: any): number; - static read(repo: Repository, notesRef: string, oid: Oid): Promise; - static remove(repo: Repository, notesRef: string, author: Signature, committer: Signature, oid: Oid): Promise; - - author(): Signature; - committer(): Signature; - - free(): void; - id(): Oid; - message(): string; -} diff --git a/types/sosuisen__nodegit/object.d.ts b/types/sosuisen__nodegit/object.d.ts deleted file mode 100644 index be7e879b..00000000 --- a/types/sosuisen__nodegit/object.d.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { Oid } from './oid'; -import { Repository } from './repository'; -import { Buf } from './buf'; - -export class Object { - static size(type: Object.TYPE): number; - static lookup(repo: Repository, id: Oid, type: Object.TYPE): Promise; - static lookupPrefix(repo: Repository, id: Oid, len: number, type: Object.TYPE): Promise; - static string2Type(str: string): Object.TYPE; - static type2String(type: Object.TYPE): string; - static typeisloose(type: Object.TYPE): number; - - dup(): Promise; - - free(): void; - id(): Oid; - lookupByPath(path: string, type: Object.TYPE): Promise; - owner(): Repository; - peel(targetType: number): Promise; - shortId(): Promise; - type(): number; -} - -export namespace Object { - const enum TYPE { - ANY = -2, - BAD = -1, - EXT1 = 0, - COMMIT = 1, - TREE = 2, - BLOB = 3, - TAG = 4, - EXT2 = 5, - OFS_DELTA = 6, - REF_DELTA = 7 - } -} diff --git a/types/sosuisen__nodegit/odb-expand-id.d.ts b/types/sosuisen__nodegit/odb-expand-id.d.ts deleted file mode 100644 index 5576fbad..00000000 --- a/types/sosuisen__nodegit/odb-expand-id.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Oid } from './oid'; -import { Object } from './object'; - -export class OdbExpandId { - id: Oid; - length: number; - type: Object.TYPE; -} diff --git a/types/sosuisen__nodegit/odb-object.d.ts b/types/sosuisen__nodegit/odb-object.d.ts deleted file mode 100644 index 9685f282..00000000 --- a/types/sosuisen__nodegit/odb-object.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Oid } from './oid'; - -export class OdbObject { - data(): Buffer; - dup(): Promise; - - free(): void; - id(): Oid; - size(): number; - type(): number; -} diff --git a/types/sosuisen__nodegit/odb.d.ts b/types/sosuisen__nodegit/odb.d.ts deleted file mode 100644 index e5348d08..00000000 --- a/types/sosuisen__nodegit/odb.d.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Oid } from './oid'; -import { OdbObject } from './odb-object'; -import { OdbExpandId } from './odb-expand-id'; -import { Object } from './object'; - -export namespace Odb { - const enum STREAM { - RDONLY = 2, - WRONLY = 4, - RW = 6 - } -} - -export class Odb { - static open(objectsDir: string): Promise; - - addDiskAlternate(path: string): number; - - free(): void; - read(id: Oid): Promise; - write(data: Buffer, len: number, type: Object.TYPE): Promise; - expandIds(ids: OdbExpandId, count: number): number; -} diff --git a/types/sosuisen__nodegit/oid-array.d.ts b/types/sosuisen__nodegit/oid-array.d.ts deleted file mode 100644 index 7a96f24a..00000000 --- a/types/sosuisen__nodegit/oid-array.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Oid } from './oid'; - -export class Oidarray { - free(): void; - ids: Oid; - count: number; -} diff --git a/types/sosuisen__nodegit/oid.d.ts b/types/sosuisen__nodegit/oid.d.ts deleted file mode 100644 index 2aa65905..00000000 --- a/types/sosuisen__nodegit/oid.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -export class Oid { - static fromString(str: string): Oid; - cmp(b: Oid): number; - cpy(): Oid; - equal(b: Oid): number; - iszero(): number; - ncmp(b: Oid, len: number): number; - strcmp(str: string): number; - streq(str: string): number; - tostrS(): string; -} diff --git a/types/sosuisen__nodegit/open-ssl.d.ts b/types/sosuisen__nodegit/open-ssl.d.ts deleted file mode 100644 index f8370260..00000000 --- a/types/sosuisen__nodegit/open-ssl.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -export class Openssl { - static setLocking(): number; -} diff --git a/types/sosuisen__nodegit/pack-builder.d.ts b/types/sosuisen__nodegit/pack-builder.d.ts deleted file mode 100644 index ed0fa0a2..00000000 --- a/types/sosuisen__nodegit/pack-builder.d.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { Repository } from './repository'; -import { Oid } from './oid'; -import { Revwalk } from './rev-walk'; - -export namespace Packbuilder { - const enum STAGE { - ADDING_OBJECTS = 0, - DELTAFICATION = 1 - } -} - -export class Packbuilder { - static create(repo: Repository): Packbuilder; - - free(): void; - hash(): Oid; - insert(id: Oid, name: string): number; - insertCommit(id: Oid): number; - insertRecur(id: Oid, name: string): number; - insertTree(id: Oid): number; - insertWalk(walk: Revwalk): number; - objectCount(): number; - setThreads(n: number): number; - written(): number; -} diff --git a/types/sosuisen__nodegit/package.json b/types/sosuisen__nodegit/package.json deleted file mode 100644 index 1daf887a..00000000 --- a/types/sosuisen__nodegit/package.json +++ /dev/null @@ -1,79 +0,0 @@ -{ - "_args": [ - [ - "@types/nodegit@0.26.12", - "I:\\working_src\\git-documentdb" - ] - ], - "_development": true, - "_from": "@types/nodegit@0.26.12", - "_id": "@types/nodegit@0.26.12", - "_inBundle": false, - "_integrity": "sha512-4YpeTImFZNJ1cve4lEueHFVS8rAs8XpZqlmx+Bm9bMc+XMiCrcwaUf6peN7pod7Rl3esVlGP1zdBB7Z12eMVAA==", - "_location": "/@types/nodegit", - "_phantomChildren": {}, - "_requested": { - "type": "version", - "registry": true, - "raw": "@types/nodegit@0.26.12", - "name": "@types/nodegit", - "escapedName": "@types%2fnodegit", - "scope": "@types", - "rawSpec": "0.26.12", - "saveSpec": null, - "fetchSpec": "0.26.12" - }, - "_requiredBy": [ - "#DEV:/" - ], - "_resolved": "https://registry.npmjs.org/@types/nodegit/-/nodegit-0.26.12.tgz", - "_spec": "0.26.12", - "_where": "I:\\working_src\\git-documentdb", - "bugs": { - "url": "https://github.com/DefinitelyTyped/DefinitelyTyped/issues" - }, - "contributors": [ - { - "name": "Dolan Miu", - "url": "https://github.com/dolanmiu" - }, - { - "name": "Tobias Nießen", - "url": "https://github.com/tniessen" - }, - { - "name": "Pierre Vigier", - "url": "https://github.com/pvigier" - }, - { - "name": "Jibril Saffi", - "url": "https://github.com/IGI-111" - }, - { - "name": "Benjamin Schuster-Boeckler", - "url": "https://github.com/DaGaMs" - }, - { - "name": "Julien Chaumond", - "url": "https://github.com/julien-c" - } - ], - "dependencies": { - "@types/node": "*" - }, - "description": "TypeScript definitions for nodegit", - "homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped#readme", - "license": "MIT", - "main": "", - "name": "@types/nodegit", - "repository": { - "type": "git", - "url": "git+https://github.com/DefinitelyTyped/DefinitelyTyped.git", - "directory": "types/nodegit" - }, - "scripts": {}, - "typeScriptVersion": "3.2", - "types": "index.d.ts", - "typesPublisherContentHash": "18ca2b36bafcdb66a752360fe388e3fe585bac07d9e3e835a0ec2cf4f49f92ae", - "version": "0.26.12" -} diff --git a/types/sosuisen__nodegit/path-spec.d.ts b/types/sosuisen__nodegit/path-spec.d.ts deleted file mode 100644 index 31b58f01..00000000 --- a/types/sosuisen__nodegit/path-spec.d.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { DiffDelta } from './diff-delta'; -import { Tree } from './tree'; -import { Diff } from './diff'; -import { Repository } from './repository'; -import { Index } from './index'; -import { Strarray } from './str-array'; - -export namespace Pathspec { - const enum FLAG { - DEFAULT = 0, - IGNORE_CASE = 1, - USE_CASE = 2, - NO_GLOB = 4, - NO_MATCH_ERROR = 8, - FIND_FAILURES = 16, - FAILURES_ONLY = 32 - } -} - -export class Pathspec { - static matchListDiffEntry(m: any, pos: number): DiffDelta; - static matchListEntry(m: any, pos: number): string; - static matchListEntrycount(m: any): number; - static matchListFailedEntry(m: any, pos: number): string; - static matchListFailedEntrycount(m: any): number; - static create(pathspec: Strarray | string | string[]): Pathspec; - - free(): void; - matchDiff(diff: Diff, flags: number): Promise; - matchIndex(index: Index, flags: number): Promise; - matchTree(tree: Tree, flags: number): Promise; - matchWorkdir(repo: Repository, flags: number): Promise; - matchesPath(flags: number, path: string): number; -} diff --git a/types/sosuisen__nodegit/proxy-options.d.ts b/types/sosuisen__nodegit/proxy-options.d.ts deleted file mode 100644 index 88f73483..00000000 --- a/types/sosuisen__nodegit/proxy-options.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -export class ProxyOptions { - certificateCheck?: Function; - credentials?: Function; - payload?: any; - type?: number; - url?: string; - version?: number; - [key: string]: any; -} diff --git a/types/sosuisen__nodegit/proxy.d.ts b/types/sosuisen__nodegit/proxy.d.ts deleted file mode 100644 index 8b4806a2..00000000 --- a/types/sosuisen__nodegit/proxy.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { ProxyOptions } from './proxy-options'; - -export class Proxy { - static initOptions(opts: ProxyOptions, version: number): number; -} diff --git a/types/sosuisen__nodegit/push-options.d.ts b/types/sosuisen__nodegit/push-options.d.ts deleted file mode 100644 index 5f7625db..00000000 --- a/types/sosuisen__nodegit/push-options.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { RemoteCallbacks } from './remote-callbacks'; -import { Strarray } from './str-array'; -import { ProxyOptions } from './proxy-options'; - -export interface PushOptions { - version?: number; - pbParallelism?: number; - callbacks?: RemoteCallbacks; - customHeaders?: Strarray | string | string[]; - proxyOpts?: ProxyOptions; - [key: string]: any; -} diff --git a/types/sosuisen__nodegit/push-update.d.ts b/types/sosuisen__nodegit/push-update.d.ts deleted file mode 100644 index 50f46726..00000000 --- a/types/sosuisen__nodegit/push-update.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Oid } from './oid'; - -export class PushUpdate { - srcRefname: string; - dstRefname: string; - src: Oid; - dst: Oid; -} diff --git a/types/sosuisen__nodegit/push.d.ts b/types/sosuisen__nodegit/push.d.ts deleted file mode 100644 index 26d8f07b..00000000 --- a/types/sosuisen__nodegit/push.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { RemoteCallbacks } from './remote-callbacks'; -import { PushOptions } from './push-options'; - -export class Push { - static initOptions(opts: PushOptions, version: number): number; -} diff --git a/types/sosuisen__nodegit/rebase-operation.d.ts b/types/sosuisen__nodegit/rebase-operation.d.ts deleted file mode 100644 index 7144ebe6..00000000 --- a/types/sosuisen__nodegit/rebase-operation.d.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Oid } from './oid'; - -export namespace RebaseOperation { - const enum REBASE_OPERATION { - PICK = 0, - REWORD = 1, - EDIT = 2, - SQUASH = 3, - FIXUP = 4, - EXEC = 5 - } -} - -export class RebaseOperation { - type: number; - id: Oid; - exec: string; -} diff --git a/types/sosuisen__nodegit/rebase.d.ts b/types/sosuisen__nodegit/rebase.d.ts deleted file mode 100644 index be0b5d2c..00000000 --- a/types/sosuisen__nodegit/rebase.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { CheckoutOptions } from './checkout-options'; -import { AnnotatedCommit } from './annotated-commit'; -import { Repository } from './repository'; -import { Signature } from './signature'; -import { Oid } from './oid'; -import { RebaseOperation } from './rebase-operation'; -import { Index } from './index'; - -export interface RebaseOptions { - version: number; - quiet: number; - rewriteNotesRef: string; - checkoutOptions: CheckoutOptions; -} - -export class Rebase { - static init(repo: Repository, branch: AnnotatedCommit, upstream: AnnotatedCommit, onto: AnnotatedCommit, opts?: RebaseOptions): Promise; - static initOptions(opts: RebaseOptions, version: number): number; - static open(repo: Repository, opts?: RebaseOptions): Promise; - - abort(): number; - commit(author: Signature, committer: Signature, messageEncoding: string, message: string): Oid; - finish(signature: Signature): number; - inmemoryIndex(index: Index): number; - next(): Promise; - operationByIndex(idx: number): RebaseOperation; - operationCurrent(): number; - operationEntrycount(): number; -} diff --git a/types/sosuisen__nodegit/ref-db.d.ts b/types/sosuisen__nodegit/ref-db.d.ts deleted file mode 100644 index 6a5701ff..00000000 --- a/types/sosuisen__nodegit/ref-db.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Repository } from './repository'; - -export class Refdb { - static open(repo: Repository): Promise; - - compress(): number; - - free(): void; -} diff --git a/types/sosuisen__nodegit/ref-log.d.ts b/types/sosuisen__nodegit/ref-log.d.ts deleted file mode 100644 index ac43de7e..00000000 --- a/types/sosuisen__nodegit/ref-log.d.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Repository } from './repository'; -import { Oid } from './oid'; -import { Signature } from './signature'; - -export class Reflog { - static delete(repo: Repository, name: string): number; - static read(repo: Repository, name: string): Promise; - static rename(repo: Repository, oldName: string, name: string): number; - - append(id: Oid, committer: Signature, msg: string): number; - drop(idx: number, rewritePreviousEntry: number): number; - entryByIndex(idx: number): ReflogEntry; - entrycount(): number; - - free(): void; - write(): number; -} - -export class ReflogEntry { - committer(): Signature; - idNew(): Oid; - idOld(): Oid; - message(): string; -} diff --git a/types/sosuisen__nodegit/ref-spec.d.ts b/types/sosuisen__nodegit/ref-spec.d.ts deleted file mode 100644 index bf40f21a..00000000 --- a/types/sosuisen__nodegit/ref-spec.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -export class Refspec { - direction(): number; - dst(): string; - dstMatches(refname: string): number; - force(): number; - src(): string; - srcMatches(refname: string): number; -} diff --git a/types/sosuisen__nodegit/reference.d.ts b/types/sosuisen__nodegit/reference.d.ts deleted file mode 100644 index cc6cb90e..00000000 --- a/types/sosuisen__nodegit/reference.d.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { Repository } from './repository'; -import { Oid } from './oid'; -import { Object } from './object'; - -export namespace Reference { - const enum TYPE { - INVALID = 0, - OID = 1, - SYMBOLIC = 2, - LISTALL = 3 - } - - const enum NORMALIZE { - REF_FORMAT_NORMAL = 0, - REF_FORMAT_ALLOW_ONELEVEL = 1, - REF_FORMAT_REFSPEC_PATTERN = 2, - REF_FORMAT_REFSPEC_SHORTHAND = 4 - } -} - -export class Reference { - static create(repo: Repository, name: string, id: Oid, force: number, logMessage: string): Promise; - static createMatching(repo: Repository, name: string, id: Oid, force: number, currentId: Oid, logMessage: string): Promise; - static dwim(repo: Repository, id: string | Reference, callback?: Function): Promise; - static ensureLog(repo: Repository, refname: string): number; - static hasLog(repo: Repository, refname: string): number; - static isValidName(refname: string): number; - static list(repo: Repository): Promise; - static lookup(repo: Repository, id: string | Reference, callback?: Function): Promise; - static nameToId(repo: Repository, name: string): Promise; - static normalizeName(bufferOut: string, bufferSize: number, name: string, flags: number): number; - static remove(repo: Repository, name: string): number; - static symbolicCreate(repo: Repository, name: string, target: string, force: number, logMessage: string): Promise; - static symbolicCreateMatching(repo: Repository, name: string, target: string, force: number, currentValue: string, logMessage: string): Promise; - - cmp(ref2: Reference): number; - delete(): number; - isBranch(): number; - isNote(): number; - isRemote(): number; - isTag(): number; - name(): string; - owner(): Repository; - peel(type: Object.TYPE): Promise; - rename(newName: string, force: number, logMessage: string): Promise; - resolve(): Promise; - setTarget(id: Oid, logMessage: string): Promise; - shorthand(): string; - symbolicSetTarget(target: string, logMessage: string): Promise; - symbolicTarget(): string; - target(): Oid; - targetPeel(): Oid; - type(): number; - isValid(): boolean; - isConcrete(): boolean; - isSymbolic(): boolean; - toString(): string; - isHead(): boolean; - dup(): Promise; -} diff --git a/types/sosuisen__nodegit/remote-callbacks.d.ts b/types/sosuisen__nodegit/remote-callbacks.d.ts deleted file mode 100644 index ca244e5c..00000000 --- a/types/sosuisen__nodegit/remote-callbacks.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -export class RemoteCallbacks { - version?: number; - credentials?: Function; - certificateCheck?: Function; - transferProgress?: Function; - transport?: Function; - payload?: undefined; -} diff --git a/types/sosuisen__nodegit/remote.d.ts b/types/sosuisen__nodegit/remote.d.ts deleted file mode 100644 index a8525645..00000000 --- a/types/sosuisen__nodegit/remote.d.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { Repository } from './repository'; -import { RemoteCallbacks } from './remote-callbacks'; -import { Strarray } from './str-array'; -import { FetchOptions } from './fetch-options'; -import { Buf } from './buf'; -import { Enums } from './enums'; -import { TransferProgress } from './transfer-progress'; -import { PushOptions } from './push-options'; -import { Refspec } from './ref-spec'; - -export namespace Remote { - const enum AUTOTAG_OPTION { - DOWNLOAD_TAGS_UNSPECIFIED = 0, - DOWNLOAD_TAGS_AUTO = 1, - DOWNLOAD_TAGS_NONE = 2, - DOWNLOAD_TAGS_ALL = 3 - } - - const enum COMPLETION_TYPE { - COMPLETION_DOWNLOAD = 0, - COMPLETION_INDEXING = 1, - COMPLETION_ERROR = 2 - } -} - -export class Remote { - static addFetch(repo: Repository, remote: string, refspec: string): number; - static addPush(repo: Repository, remote: string, refspec: string): number; - static create(repo: Repository, name: string, url: string): Promise; - static createAnonymous(repo: Repository, url: string): Promise; - static createDetached(url: string): Promise; - static createWithFetchspec(repo: Repository, name: string, url: string, fetch: string): Promise; - static delete(repo: Repository, name: string): Promise; - static initCallbacks(opts: RemoteCallbacks, version: number): number; - static isValidName(remoteName: string): boolean; - static list(repo: Repository): Promise; - static lookup(repo: Repository, name: string | Remote, callback?: Function): Promise; - static setAutotag(repo: Repository, remote: string, value: number): number; - static setPushurl(repo: Repository, remote: string, url: string): number; - static setUrl(repo: Repository, remote: string, url: string): number; - - autotag(): number; - connect(direction: Enums.DIRECTION, callbacks: RemoteCallbacks, callback?: Function): Promise; - connected(): number; - defaultBranch(): Promise; - disconnect(): Promise; - download(refSpecs: any[], opts?: FetchOptions, callback?: Function): Promise; - dup(): Promise; - fetch(refSpecs: any[], opts: FetchOptions, message: string, callback?: Function): Promise; - - free(): void; - getFetchRefspecs(): Promise; - getPushRefspecs(): Promise; - getRefspec(n: number): Refspec; - name(): string; - owner(): Repository; - prune(callbacks: RemoteCallbacks): number; - pruneRefs(): number; - push(refSpecs: any[], options?: PushOptions, callback?: Function): Promise; - pushurl(): string; - refspecCount(): number; - stats(): TransferProgress; - - stop(): void; - updateTips(callbacks: RemoteCallbacks, updateFetchhead: number, downloadTags: number, reflogMessage: string): number; - upload(refspecs: Strarray | string | string[], opts?: PushOptions): number; - url(): string; - /** - * Lists advertised references from a remote. You must connect to the remote before using referenceList. - */ - referenceList(): Promise; -} diff --git a/types/sosuisen__nodegit/repository.d.ts b/types/sosuisen__nodegit/repository.d.ts deleted file mode 100644 index 31ce4df6..00000000 --- a/types/sosuisen__nodegit/repository.d.ts +++ /dev/null @@ -1,249 +0,0 @@ -import { Oid } from './oid'; -import { Buf } from './buf'; -import { Reference } from './reference'; -import { Odb } from './odb'; -import { Object } from './object'; -import { Index } from './index_'; -import { Commit } from './commit'; -import { Blob } from './blob'; -import { Tree } from './tree'; -import { Signature } from './signature'; -import { AnnotatedCommit } from './annotated-commit'; -import { FetchOptions } from './fetch-options'; -import { CheckoutOptions } from './checkout-options'; -import { Remote } from './remote'; -import { Tag } from './tag'; -import { Config } from './config'; -import { Merge } from './merge'; -import { MergeOptions } from './merge-options'; -import { Refdb } from './ref-db'; -import { Revwalk } from './rev-walk'; -import { StatusFile } from './status-file'; -import { StatusOptions } from './status-options'; -import { DiffLine } from './diff-line'; -import { Treebuilder } from './tree-builder'; - -export interface RepositoryInitOptions { - description: string; - flags: number; - initialHead: string; - mode: number; - originUrl: string; - templatePath: string; - version: number; - workdirPath: string; -} - -export class Repository { - /** - * Creates a branch with the passed in name pointing to the commit - */ - static discover(startPath: string, acrossFs: number, ceilingDirs: string): Promise; - static init(path: string, isBare: number): Promise; - static initExt(repoPath: string, options?: RepositoryInitOptions): Promise; - static open(path: string): Promise; - static openBare(barePath: string): Promise; - static openExt(path: string, flags?: number, ceilingDirs?: string): Promise; - static wrapOdb(odb: Odb): Promise; - - cleanup(): void; - commondir(): string; - config(): Promise; - configSnapshot(): Promise; - detachHead(): number; - fetchheadForeach(callback?: Function): Promise; - - free(): void; - getNamespace(): string; - head(): Promise; - headDetached(): number; - headUnborn(): number; - index(): Promise; - isBare(): number; - isEmpty(): number; - isShallow(): number; - mergeheadForeach(callback?: Function): Promise; - messageRemove(): number; - odb(): Promise; - path(): string; - refdb(): Promise; - setHead(refname: string): Promise; - setHeadDetached(commitish: Oid): number; - setHeadDetachedFromAnnotated(commitish: AnnotatedCommit): number; - setIdent(name: string, email: string): number; - setNamespace(nmspace: string): number; - setWorkdir(workdir: string, updateGitLink: number): number; - state(): number; - stateCleanup(): number; - workdir(): string; - /** - * Creates a branch with the passed in name pointing to the commit - */ - createBranch(name: string, commit: Commit | string | Oid, force?: boolean): Promise; - /** - * Look up a refs's commit. - */ - getReferenceCommit(name: string | Reference): Promise; - /** - * Look up a branch. Alias for getReference - */ - getBranch(name: string | Reference): Promise; - /** - * Look up a branch's most recent commit. Alias to getReferenceCommit - */ - getBranchCommit(name: string | Reference): Promise; - /** - * Gets the branch that HEAD currently points to Is an alias to head() - */ - getCurrentBranch(): Promise; - /** - * Lookup the reference with the given name. - */ - getReference(name: string | Reference): Promise; - /** - * Lookup references for a repository. - */ - getReferences(): Promise; - /** - * Lookup reference names for a repository. - */ - getReferenceNames(type: Reference.TYPE): Promise; - getCommit(string: string | Commit| Oid): Promise; - /** - * Retrieve the blob represented by the oid. - */ - getBlob(string: string | Oid): Promise; - /** - * Retrieve the tree represented by the oid. - */ - getTree(string: string | Oid): Promise; - createTag(string: string | Oid, name: string, message: string): Promise; - /** - * Creates a new lightweight tag - */ - createLightweightTag(string: string | Oid, name: string): Promise; - /** - * Retrieve the tag represented by the oid. - */ - getTag(string: string | Oid): Promise; - /** - * Retrieve the tag represented by the tag name. - */ - getTagByName(Short: string): Promise; - /** - * Deletes a tag from a repository by the tag name. - */ - deleteTagByName(Short: string): Promise; - /** - * Instantiate a new revision walker for browsing the Repository"s history. See also Commit.prototype.history() - */ - createRevWalk(): Revwalk; - /** - * Retrieve the master branch commit. - */ - getMasterCommit(): Promise; - /** - * Retrieve the commit that HEAD is currently pointing to - */ - getHeadCommit(): Promise; - createCommit(updateRef: string, author: Signature, committer: Signature, message: string, Tree: Tree | Oid | string, parents: Array, callback?: Function): Promise; - /** - * Creates a new commit on HEAD from the list of passed in files - */ - createCommitOnHead(filesToAdd: string[], author: Signature, committer: Signature, message: string): Promise; - /** - * Create a blob from a buffer - */ - createBlobFromBuffer(buffer: Buffer): Promise; - treeBuilder(tree: Tree): Promise; - /** - * Gets the default signature for the default user and now timestamp - */ - defaultSignature(): Signature; - /** - * Lists out the remotes in the given repository. - */ - getRemotes(callback?: Function): Promise; - /** - * Gets a remote from the repo - */ - getRemote(remote: string | Remote, callback?: Function): Promise; - /** - * Fetches from a remote - */ - fetch(remote: string | Remote, fetchOptions?: FetchOptions): Promise; - /** - * Fetches from all remotes. This is done in series due to deadlocking issues with fetching from many remotes that can happen. - */ - fetchAll(fetchOptions?: FetchOptions, callback?: Function): Promise; - mergeBranches(to: string | Reference, from: string | Reference, signature?: Signature, mergePreference?: Merge.PREFERENCE, mergeOptions?: MergeOptions): Promise; - /** - * Rebases a branch onto another branch - */ - rebaseBranches(branch: string, upstream: string, onto: string, signature: Signature, beforeNextFn: Function): Promise; - continueRebase(signature: Signature, beforeNextFn: Function): Promise; - /** - * Get the status of a repo to it's working directory - */ - getStatus(opts?: StatusOptions): Promise; - /** - * Get extended statuses of a repo to it's working directory. Status entries have status, headToIndex delta, and indexToWorkdir deltas - */ - getStatusExt(opts?: StatusOptions): Promise; - /** - * Get the names of the submodules in the repository. - */ - getSubmoduleNames(): Promise; - /** - * This will set the HEAD to point to the reference and then attempt to update the index and working tree to match the content of the latest commit on that reference - */ - checkoutRef(reference: Reference, opts?: CheckoutOptions): Promise; - /** - * This will set the HEAD to point to the local branch and then attempt to update the index and working tree to match the content of the latest commit on that branch - */ - checkoutBranch(branch: string | Reference, opts?: CheckoutOptions): Promise; - /** - * Stages or unstages line selection of a specified file - */ - stageFilemode(filePath: string | string[], stageNew: boolean): Promise; - /** - * Stages or unstages line selection of a specified file - */ - stageLines(filePath: string, newLines: DiffLine[], isStaged: boolean): Promise; - /** - * Returns true if the repository is in the default NONE state. - */ - isDefaultState(): boolean; - /** - * Returns true if the repository is in the APPLY_MAILBOX or APPLY_MAILBOX_OR_REBASE state. - */ - isApplyingMailbox(): boolean; - /** - * Returns true if the repository is in the BISECT state. - */ - isBisecting(): boolean; - /** - * Returns true if the repository is in the CHERRYPICK state. - */ - isCherrypicking(): boolean; - /** - * Returns true if the repository is in the MERGE state. - */ - isMerging(): boolean; - /** - * Returns true if the repository is in the REBASE, REBASE_INTERACTIVE, or REBASE_MERGE state. - */ - isRebasing(): boolean; - /** - * Returns true if the repository is in the REVERT state. - */ - isReverting(): boolean; - /** - * Discard line selection of a specified file. Assumes selected lines are unstaged. - */ - discardLines(filePath: string, selectedLines: DiffLine[]): Promise; - /** - * Grabs a fresh copy of the index from the repository. Invalidates all previously grabbed indexes - */ - refreshIndex(): Promise; -} diff --git a/types/sosuisen__nodegit/reset.d.ts b/types/sosuisen__nodegit/reset.d.ts deleted file mode 100644 index ca7ff41e..00000000 --- a/types/sosuisen__nodegit/reset.d.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { AnnotatedCommit } from './annotated-commit'; -import { Repository } from './repository'; -import { Strarray } from './str-array'; -import { CheckoutOptions } from './checkout-options'; -import { Commit } from './commit'; -import { Tag } from './tag'; - -export namespace Reset { - const enum TYPE { - SOFT = 1, - MIXED = 2, - HARD = 3 - } -} - -export class Reset { - /** - * Look up a refs's commit. - */ - static reset(repo: Repository, target: Commit | Tag, resetType: number, checkoutOpts: CheckoutOptions): Promise; - /** - * Look up a refs's commit. - */ - static default(repo: Repository, target: Commit | Tag, pathspecs: Strarray | string | string[]): Promise; - /** - * Sets the current head to the specified commit oid and optionally resets the index and working tree to match. - * This behaves like reset but takes an annotated commit, which lets you specify which extended sha syntax string was specified by a user, allowing for more exact reflog messages. - * See the documentation for reset. - */ - static fromAnnotated(repo: Repository, commit: AnnotatedCommit, resetType: number, checkoutOpts: CheckoutOptions): number; -} diff --git a/types/sosuisen__nodegit/rev-parse.d.ts b/types/sosuisen__nodegit/rev-parse.d.ts deleted file mode 100644 index c878b791..00000000 --- a/types/sosuisen__nodegit/rev-parse.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Object } from './object'; -import { Repository } from './repository'; -import { Reference } from './reference'; - -export namespace Revparse { - const enum MODE { - SINGLE = 1, - RANGE = 2, - MERGE_BASE = 4 - } -} - -export class Revparse { - static ext(objectOut: Object, referenceOut: Reference, repo: Repository, spec: string): number; - static single(repo: Repository, spec: string): Promise; -} diff --git a/types/sosuisen__nodegit/rev-walk.d.ts b/types/sosuisen__nodegit/rev-walk.d.ts deleted file mode 100644 index 38975315..00000000 --- a/types/sosuisen__nodegit/rev-walk.d.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { Repository } from './repository'; -import { Oid } from './oid'; -import { Commit } from './commit'; - -export namespace Revwalk { - const enum SORT { - NONE = 0, - TOPOLOGICAL = 1, - TIME = 2, - REVERSE = 4 - } -} - -export class Revwalk { - static create(repo: Repository): Revwalk; - - hide(commitId: Oid): number; - hideGlob(glob: string): number; - hideHead(): number; - hideRef(refname: string): number; - next(): Promise; - push(id: Oid): number; - pushGlob(glob: string): number; - pushHead(): number; - pushRange(range: string): number; - pushRef(refname: string): number; - repository(): Repository; - - reset(): void; - - simplifyFirstParent(): void; - /** - * Set the sort order for the revwalk. This function takes variable arguments like revwalk.sorting(NodeGit.RevWalk.Topological, NodeGit.RevWalk.Reverse). - */ - sorting(...sort: number[]): void; - fastWalk(maxCount: number): Promise; - fileHistoryWalk(filePath: string, maxCount: number): Promise; - /** - * Walk the history from the given oid. The callback is invoked for each commit; When the walk is over, the callback is invoked with (null, null). - */ - walk(oid: Oid, callback?: Function): Commit; - /** - * Walk the history grabbing commits until the checkFn called with the current commit returns false. - */ - getCommitsUntil(checkFn: Function): Promise; - getCommits(count: number): Promise; -} diff --git a/types/sosuisen__nodegit/revert.d.ts b/types/sosuisen__nodegit/revert.d.ts deleted file mode 100644 index df804cbb..00000000 --- a/types/sosuisen__nodegit/revert.d.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { MergeOptions } from './merge-options'; -import { CheckoutOptions } from './checkout-options'; -import { Repository } from './repository'; -import { Commit } from './commit'; -import { Index } from './index'; - -export interface RevertOptions { - version?: number; - mainline?: number; - mergeOpts?: MergeOptions; - checkoutOpts?: CheckoutOptions; - [key: string]: any; -} - -export class Revert { - static revert(repo: Repository, commit: Commit, givenOpts?: RevertOptions): Promise; - /** - * Reverts the given commit against the given "our" commit, producing an index that reflects the result of the revert. - */ - static commit(repo: Repository, revertCommit: Commit, ourCommit: Commit, mainline: number, mergeOptions?: MergeOptions): Promise; -} diff --git a/types/sosuisen__nodegit/signature.d.ts b/types/sosuisen__nodegit/signature.d.ts deleted file mode 100644 index 93e76fd6..00000000 --- a/types/sosuisen__nodegit/signature.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Repository } from './repository'; -import { Time } from './time'; - -export class Signature { - static default(repo: Repository): Signature; - static create(name: string, email: string, time: number, offset: number): Signature; - static now(name: string, email: string): Signature; - static fromBuffer(buf: string): Promise; - - dup(): Promise; - - free(): void; - toString(): string; - name(): string; - email(): string; - when(): Time; -} diff --git a/types/sosuisen__nodegit/stash.d.ts b/types/sosuisen__nodegit/stash.d.ts deleted file mode 100644 index 68d61d0e..00000000 --- a/types/sosuisen__nodegit/stash.d.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { Repository } from './repository'; -import { Signature } from './signature'; -import { Oid } from './oid'; -import { CheckoutOptions } from './checkout-options'; - -export namespace Stash { - const enum APPLY_FLAGS { - APPLY_DEFAULT = 0, - APPLY_REINSTATE_INDEX = 1 - } - - const enum APPLY_PROGRESS { - NONE = 0, - LOADING_STASH = 1, - ANALYZE_INDEX = 2, - ANALYZE_MODIFIED = 3, - ANALYZE_UNTRACKED = 4, - CHECKOUT_UNTRACKED = 5, - CHECKOUT_MODIFIED = 6, - DONE = 7 - } - - const enum FLAGS { - DEFAULT = 0, - KEEP_INDEX = 1, - INCLUDE_UNTRACKED = 2, - INCLUDE_IGNORED = 4 - } -} - -export interface StashApplyOptions { - version?: number; - flags?: number; - checkoutOptions?: CheckoutOptions; - progressCb?: Function; - progressPayload?: any; -} - -export class Stash { - static apply(repo: Repository, index: number, options?: StashApplyOptions): Promise; - static applyInitOptions(opts: StashApplyOptions, version: number): number; - static drop(repo: Repository, index: number): Promise; - static foreach(repo: Repository, callback?: Function): Promise; - static pop(repo: Repository, index: number, options?: StashApplyOptions): Promise; - static save(repo: Repository, stasher: Signature, message: string, flags: number): Promise; -} diff --git a/types/sosuisen__nodegit/status-entry.d.ts b/types/sosuisen__nodegit/status-entry.d.ts deleted file mode 100644 index 59de1a97..00000000 --- a/types/sosuisen__nodegit/status-entry.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { DiffDelta } from './diff-delta'; - -export class StatusEntry { - status(): number; - headToIndex(): DiffDelta; - indexToWorkdir(): DiffDelta; -} diff --git a/types/sosuisen__nodegit/status-file-options.d.ts b/types/sosuisen__nodegit/status-file-options.d.ts deleted file mode 100644 index e3852cf0..00000000 --- a/types/sosuisen__nodegit/status-file-options.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { StatusEntry } from './status-entry'; - -export interface StatusFileOptions { - path?: string; - status?: number; - entry?: StatusEntry; - [key: string]: any; -} diff --git a/types/sosuisen__nodegit/status-file.d.ts b/types/sosuisen__nodegit/status-file.d.ts deleted file mode 100644 index b34a0f23..00000000 --- a/types/sosuisen__nodegit/status-file.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { DiffDelta } from './diff-delta'; -import { StatusFileOptions } from './status-file-options'; - -export class StatusFile { - constructor(args: StatusFileOptions); - headToIndex(): DiffDelta; - indexToWorkdir(): DiffDelta; - inIndex(): boolean; - inWorkingTree(): boolean; - isConflicted(): boolean; - isDeleted(): boolean; - isIgnored(): boolean; - isModified(): boolean; - isNew(): boolean; - isRenamed(): boolean; - isTypechange(): boolean; - path(): string; - status(): string[]; - statusBit(): number; -} diff --git a/types/sosuisen__nodegit/status-list.d.ts b/types/sosuisen__nodegit/status-list.d.ts deleted file mode 100644 index 1b470ceb..00000000 --- a/types/sosuisen__nodegit/status-list.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Repository } from './repository'; -import { DiffPerfdata } from './diff-perf-data'; -import { StatusOptions } from './status-options'; - -export class StatusList { - static create(repo: Repository, opts?: StatusOptions): Promise; - - entrycount(): number; - - free(): void; - getPerfdata(): Promise; -} diff --git a/types/sosuisen__nodegit/status-options.d.ts b/types/sosuisen__nodegit/status-options.d.ts deleted file mode 100644 index f0189706..00000000 --- a/types/sosuisen__nodegit/status-options.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Strarray } from './str-array'; - -export interface StatusOptions { - version?: number; - show?: number; - flags?: number; - pathspec?: Strarray | string | string[]; - [key: string]: any; -} diff --git a/types/sosuisen__nodegit/status.d.ts b/types/sosuisen__nodegit/status.d.ts deleted file mode 100644 index 5b657d1c..00000000 --- a/types/sosuisen__nodegit/status.d.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Repository } from './repository'; -import { StatusList } from './status-list'; -import { StatusOptions } from './status-options'; -import { StatusEntry } from './status-entry'; - -export namespace Status { - const enum STATUS { - CURRENT = 0, - INDEX_NEW = 1, - INDEX_MODIFIED = 2, - INDEX_DELETED = 4, - INDEX_RENAMED = 8, - INDEX_TYPECHANGE = 16, - WT_NEW = 128, - WT_MODIFIED = 256, - WT_DELETED = 512, - WT_TYPECHANGE = 1024, - WT_RENAMED = 2048, - WT_UNREADABLE = 4096, - IGNORED = 16384, - CONFLICTED = 32768 - } - - const enum OPT { - INCLUDE_UNTRACKED = 1, - INCLUDE_IGNORED = 2, - INCLUDE_UNMODIFIED = 4, - EXCLUDE_SUBMODULES = 8, - RECURSE_UNTRACKED_DIRS = 16, - DISABLE_PATHSPEC_MATCH = 32, - RECURSE_IGNORED_DIRS = 64, - RENAMES_HEAD_TO_INDEX = 128, - RENAMES_INDEX_TO_WORKDIR = 256, - SORT_CASE_SENSITIVELY = 512, - SORT_CASE_INSENSITIVELY = 1024, - RENAMES_FROM_REWRITES = 2048, - NO_REFRESH = 4096, - UPDATE_INDEX = 8192, - INCLUDE_UNREADABLE = 16384, - INCLUDE_UNREADABLE_AS_UNTRACKED = 32768 - } - - const enum SHOW { - INDEX_AND_WORKDIR = 0, - INDEX_ONLY = 1, - WORKDIR_ONLY = 2 - } -} - -export class Status { - static byIndex(statuslist: StatusList, idx: number): StatusEntry; - static file(repo: Repository, path: string): number; - static foreach(repo: Repository, callback?: Function): Promise; - static foreachExt(repo: Repository, opts?: StatusOptions, callback?: Function): Promise; - static shouldIgnore(ignored: number, repo: Repository, path: string): number; -} diff --git a/types/sosuisen__nodegit/str-array.d.ts b/types/sosuisen__nodegit/str-array.d.ts deleted file mode 100644 index 44f5914b..00000000 --- a/types/sosuisen__nodegit/str-array.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -export class Strarray { - copy(src: Strarray): number; - - free(): void; - strings: string[]; - count: number; -} diff --git a/types/sosuisen__nodegit/submodule-update-options.d.ts b/types/sosuisen__nodegit/submodule-update-options.d.ts deleted file mode 100644 index 5be827b3..00000000 --- a/types/sosuisen__nodegit/submodule-update-options.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { CheckoutOptions } from './checkout-options'; -import { FetchOptions } from './fetch-options'; - -export interface SubmoduleUpdateOptions { - version?: number; - checkoutOpts?: CheckoutOptions; - fetchOpts?: FetchOptions; - cloneCheckoutStrategy?: number; - [key: string]: any; -} diff --git a/types/sosuisen__nodegit/submodule.d.ts b/types/sosuisen__nodegit/submodule.d.ts deleted file mode 100644 index 4ac5ce3a..00000000 --- a/types/sosuisen__nodegit/submodule.d.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { Repository } from './repository'; -import { Buf } from './buf'; -import { Oid } from './oid'; -import { SubmoduleUpdateOptions } from './submodule-update-options'; - -export namespace Submodule { - const enum IGNORE { - UNSPECIFIED = -1, - NONE = 1, - UNTRACKED = 2, - DIRTY = 3, - ALL = 4 - } - - const enum RECURSE { - NO = 0, - YES = 1, - ONDEMAND = 2 - } - - const enum STATUS { - IN_HEAD = 1, - IN_INDEX = 2, - IN_CONFIG = 4, - IN_WD = 8, - INDEX_ADDED = 16, - INDEX_DELETED = 32, - INDEX_MODIFIED = 64, - WD_UNINITIALIZED = 128, - WD_ADDED = 256, - WD_DELETED = 512, - WD_MODIFIED = 1024, - WD_INDEX_MODIFIED = 2048, - WD_WD_MODIFIED = 4096, - WD_UNTRACKED = 8192 - } - - const enum UPDATE { - CHECKOUT = 1, - REBASE = 2, - MERGE = 3, - NONE = 4, - DEFAULT = 0 - } -} - -export class Submodule { - static addSetup(repo: Repository, url: string, path: string, useGitLink: number): Promise; - static foreach(repo: Repository, callback?: Function): Promise; - static lookup(repo: Repository, name: string): Promise; - static resolveUrl(repo: Repository, url: string): Promise; - static setBranch(repo: Repository, name: string, branch: string): number; - static setFetchRecurseSubmodules(repo: Repository, name: string, fetchRecurseSubmodules: number): number; - static setIgnore(repo: Repository, name: string, ignore: number): Promise; - static setUpdate(repo: Repository, name: string, update: number): Promise; - static setUrl(repo: Repository, name: string, url: string): Promise; - static status(repo: Repository, name: string, ignore: number): Promise; - static updateInitOptions(opts: SubmoduleUpdateOptions, version: number): number; - - addFinalize(): Promise; - addToIndex(writeIndex: number): Promise; - branch(): string; - fetchRecurseSubmodules(): number; - - free(): void; - headId(): Oid; - ignore(): number; - indexId(): Oid; - init(overwrite: number): Promise; - location(): Promise; - name(): string; - open(): Promise; - owner(): Repository; - path(): string; - reload(force: number): number; - repoInit(useGitLink: number): Promise; - sync(): Promise; - /** - * Updates a submodule - * - * - */ - update(init: number, options?: SubmoduleUpdateOptions): Promise; - updateStrategy(): number; - url(): string; - wdId(): Oid; -} diff --git a/types/sosuisen__nodegit/tag.d.ts b/types/sosuisen__nodegit/tag.d.ts deleted file mode 100644 index 662e8abc..00000000 --- a/types/sosuisen__nodegit/tag.d.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Repository } from './repository'; -import { Oid } from './oid'; -import { Object } from './object'; -import { Signature } from './signature'; -import { Strarray } from './str-array'; - -export class Tag { - static annotationCreate(repo: Repository, tagName: string, target: Object, tagger: Signature, message: string): Promise; - static create(repo: Repository, tagName: string, target: Object, tagger: Signature, message: string, force: number): Promise; - static createLightweight(repo: Repository, tagName: string, target: Object, force: number): Promise; - static delete(repo: Repository, tagName: string): Promise; - static list(repo: Repository): Promise; - static listMatch(tagNames: Strarray | string | string[], pattern: string, repo: Repository): number; - /** - * Retrieves the tag pointed to by the oid - * - * - */ - static lookup(repo: Repository, id: string | Oid | Tag): Promise; - static lookupPrefix(repo: Repository, id: Oid, len: number): Promise; - - dup(): Promise; - - free(): void; - id(): Oid; - message(): string; - name(): string; - owner(): Repository; - peel(tagTargetOut: Object): number; - tagger(): Signature; - target(): Promise; - targetId(): Oid; - targetType(): number; -} diff --git a/types/sosuisen__nodegit/time.d.ts b/types/sosuisen__nodegit/time.d.ts deleted file mode 100644 index cb42ea68..00000000 --- a/types/sosuisen__nodegit/time.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -export class Time { - time(): number; - offset(): number; -} diff --git a/types/sosuisen__nodegit/transfer-progress.d.ts b/types/sosuisen__nodegit/transfer-progress.d.ts deleted file mode 100644 index 1589d4b6..00000000 --- a/types/sosuisen__nodegit/transfer-progress.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -export class TransferProgress { - totalObjects: number; - indexedObjects: number; - receivedObjects: number; - localObjects: number; - totalDeltas: number; - indexedDeltas: number; - receivedBytes: number; -} diff --git a/types/sosuisen__nodegit/transport.d.ts b/types/sosuisen__nodegit/transport.d.ts deleted file mode 100644 index f4f47213..00000000 --- a/types/sosuisen__nodegit/transport.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Remote } from './remote'; -import { Strarray } from './str-array'; -import { Cert } from './cert'; - -export namespace Transport { - const enum FLAGS { - NONE = 0 - } -} - -export class Transport { - static sshWithPaths(owner: Remote, payload: Strarray | string | string[]): Promise; - static unregister(prefix: string): number; - init(version: number): number; - smartCertificateCheck(cert: Cert, valid: number, hostName: string): number; -} diff --git a/types/sosuisen__nodegit/tree-builder.d.ts b/types/sosuisen__nodegit/tree-builder.d.ts deleted file mode 100644 index bd8728e1..00000000 --- a/types/sosuisen__nodegit/tree-builder.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Oid } from './oid'; -import { Repository } from './repository'; -import { Tree } from './tree'; -import { TreeEntry } from './tree-entry'; - -export class Treebuilder { - static create(repo: Repository, source?: Tree): Promise; - clear(): void; - entrycount(): number; - free(): void; - get(filename: string): TreeEntry; - insert(filename: string, id: Oid, filemode: number): Promise; - remove(filename: string): number; - write(): Promise; -} diff --git a/types/sosuisen__nodegit/tree-entry.d.ts b/types/sosuisen__nodegit/tree-entry.d.ts deleted file mode 100644 index a5e68a60..00000000 --- a/types/sosuisen__nodegit/tree-entry.d.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { Tree } from './tree'; -import { Oid } from './oid'; -import { Blob } from './blob'; -import { Repository } from './repository'; - -export namespace TreeEntry { - const enum FILEMODE { - UNREADABLE = 0, - TREE = 16384, - BLOB = 33188, - EXECUTABLE = 33261, - LINK = 40960, - COMMIT = 57344 - } -} - -export class TreeEntry { - filemode(): TreeEntry.FILEMODE; - filemodeRaw(): TreeEntry.FILEMODE; - free(): void; - getBlob(): Promise; - getTree(): Promise; - id(): Oid; - isBlob(): boolean; - isFile(): boolean; - isTree(): boolean; - isDirectory(): boolean; - isSubmodule(): boolean; - /** - * Retrieve the SHA for this TreeEntry. - */ - sha(): string; - name(): string; - /** - * Retrieve the SHA for this TreeEntry. Alias for sha - */ - oid(): string; - /** - * Returns the path for this entry. - */ - path(): string; - /** - * Alias for path - */ - toString(): string; - toObject(repo: Repository): Object; - type(): number; -} diff --git a/types/sosuisen__nodegit/tree-update.d.ts b/types/sosuisen__nodegit/tree-update.d.ts deleted file mode 100644 index fde63d06..00000000 --- a/types/sosuisen__nodegit/tree-update.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Oid } from './oid'; - -export class TreeUpdate { - action: number; - filemode: number; - id: Oid; - path: string; -} diff --git a/types/sosuisen__nodegit/tree.d.ts b/types/sosuisen__nodegit/tree.d.ts deleted file mode 100644 index c850ffb4..00000000 --- a/types/sosuisen__nodegit/tree.d.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { Oid } from './oid'; -import { TreeEntry } from './tree-entry'; -import { Repository } from './repository'; -import { Object } from './object'; -import { Treebuilder } from './tree-builder'; -import { DiffFile } from './diff-file'; -import { TreeUpdate } from './tree-update'; -import { Diff } from './diff'; - -export namespace Tree { - const enum WALK_MODE { - WALK_PRE = 0, - WALK_POST = 1 - } -} - -export class Tree { - static entryCmp(tree1: TreeEntry, tree2: TreeEntry): number; - static entryDup(dest: TreeEntry, source: TreeEntry): number; - static lookupPrefix(repo: Repository, id: Oid, len: number): Promise; - /** - * Retrieves the tree pointed to by the oid - */ - static lookup(repo: Repository, id: string | Oid | Tree, callback?: Function): Promise; - - entryById(id: Oid): TreeEntry; - _entryByIndex(idx: number): TreeEntry; - /** - * Get an entry by name; if the tree is a directory, the name is the filename. - */ - entryByName(name: string): TreeEntry; - _entryByName(filename: string): TreeEntry; - entryByPath(path: string): Promise; - entryCount(): number; - - free(): void; - id(): Oid; - owner(): Repository; - /** - * Diff two trees - */ - diff(tree: Tree, callback?: Function): Promise; - /** - * Diff two trees with options - */ - diffWithOptions(tree: Tree, options?: Object, callback?: Function): Promise; - /** - * Get an entry at the ith position. - */ - entryByIndex(i: number): TreeEntry; - /** - * Get an entry at a path. Unlike by name, this takes a fully qualified path, like /foo/bar/baz.javascript - */ - getEntry(filePath: string): Promise; - /** - * Return an array of the entries in this tree (excluding its children). - */ - entries(): TreeEntry[]; - /** - * Recursively walk the tree in breadth-first order. Fires an event for each entry. - */ - walk(blobsOnly?: boolean): NodeJS.EventEmitter & { - /** - * Start walking the tree and emitting events. This should be called after event listeners have been attached. - */ - start: () => void; - }; - /** - * Return the path of this tree, like /lib/foo/bar - * - * - */ - path(): string; - /** - * Make builder. This is helpful for modifying trees. - */ - builder(): Treebuilder; - dup(): Promise; - createUpdated(repo: Repository, nUpdates: number, updates: TreeUpdate): Promise; -} diff --git a/types/sosuisen__nodegit/wrapper.d.ts b/types/sosuisen__nodegit/wrapper.d.ts deleted file mode 100644 index 8982280a..00000000 --- a/types/sosuisen__nodegit/wrapper.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -export class Wrapper { - toBuffer(bufSize: number): Buffer; -} From 739813c764fb6463a18b1a84f8414766dac8934a Mon Sep 17 00:00:00 2001 From: sosuisen Date: Mon, 2 Aug 2021 19:41:33 +0900 Subject: [PATCH 128/297] fix: remove saveAppInfo and loadAppInfo --- src/git_documentdb.ts | 31 ------------------------------- src/types_gitddb.ts | 3 --- test/git_documentdb.test.ts | 20 -------------------- 3 files changed, 54 deletions(-) diff --git a/src/git_documentdb.ts b/src/git_documentdb.ts index c09f4288..9cace6f4 100644 --- a/src/git_documentdb.ts +++ b/src/git_documentdb.ts @@ -767,37 +767,6 @@ export class GitDocumentDB this.author.email = email ?? this.author.email; } - /** - * Save app-specific info into .gitddb/app.json - * - * @public - */ - async saveAppInfo (info: { [key: string]: any }) { - // Do not use this.put() because it increments TaskQueue.statistics.put. - await putWorker( - this, - '', - GIT_DOCUMENTDB_APP_INFO_ID + JSON_EXT, - toSortedJSONString(info), - PUT_APP_INFO_MESSAGE - ); - } - - /** - * Load app-specific info from .gitddb/app.json - * - * @returns JSON object. It returns undefined if app.json does not exist. - * - * @public - */ - async loadAppInfo () { - const info = await this.get(GIT_DOCUMENTDB_APP_INFO_ID).catch(() => undefined); - if (info?._id) { - delete info._id; - } - return info; - } - /** * Load DatabaseInfo from .gitddb/info.json * diff --git a/src/types_gitddb.ts b/src/types_gitddb.ts index 721b2bbc..72cc809d 100644 --- a/src/types_gitddb.ts +++ b/src/types_gitddb.ts @@ -81,8 +81,5 @@ export interface GitDDBInterface { saveAuthor(): Promise; loadAuthor(): Promise; - saveAppInfo(info: { [key: string]: any }): void; - loadAppInfo(): { [key: string]: any }; - loadDbInfo(): void; } diff --git a/test/git_documentdb.test.ts b/test/git_documentdb.test.ts index 08ae24ea..157b8e26 100644 --- a/test/git_documentdb.test.ts +++ b/test/git_documentdb.test.ts @@ -183,24 +183,4 @@ describe('', () => { await gitDDB.destroy(); }); - - it('save and load AppInfo', async () => { - const dbName = monoId(); - const gitDDB: GitDocumentDB = new GitDocumentDB({ - dbName, - localDir, - }); - - await gitDDB.open(); - - const json = { - appName: 'foo', - appVersion: 1, - }; - await gitDDB.saveAppInfo(json); - - await expect(gitDDB.loadAppInfo()).resolves.toEqual(json); - - await gitDDB.destroy(); - }); }); From 283a875b7aa5475834df094f91cf2c3ae071956c Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 3 Aug 2021 01:09:04 +0900 Subject: [PATCH 129/297] fix: move test for remote-plugin to test_plugin/ --- .npmignore | 1 + package.json | 9 +++++---- test/{plugin => internal_plugin}/checkfetch.test.ts | 2 +- test/{plugin => internal_plugin}/clone.test.ts | 2 +- test/{plugin => internal_plugin}/fetch.test.ts | 2 +- test/{plugin => internal_plugin}/push.test.ts | 2 +- {test => test_plugin}/remote_nodegit/3way_merge.test.ts | 4 ++-- .../remote_nodegit/3way_merge_ot.test.ts | 4 ++-- {test => test_plugin}/remote_nodegit/combine.test.ts | 4 ++-- .../remote_nodegit/network_git_documentdb.test.ts | 4 ++-- .../remote_nodegit/network_history.test.ts | 4 ++-- .../remote_nodegit/network_task_queue.test.ts | 4 ++-- .../remote_nodegit/on_sync_event.test.ts | 4 ++-- {test => test_plugin}/remote_nodegit/sync.test.ts | 4 ++-- {test => test_plugin}/remote_nodegit/sync_clone.test.ts | 4 ++-- {test => test_plugin}/remote_nodegit/sync_events.test.ts | 4 ++-- {test => test_plugin}/remote_nodegit/sync_live.test.ts | 4 ++-- .../remote_nodegit/sync_trypush.test.ts | 4 ++-- .../remote_nodegit/sync_trysync.test.ts | 4 ++-- tsconfig.eslint.json | 1 + 20 files changed, 37 insertions(+), 34 deletions(-) rename test/{plugin => internal_plugin}/checkfetch.test.ts (99%) rename test/{plugin => internal_plugin}/clone.test.ts (99%) rename test/{plugin => internal_plugin}/fetch.test.ts (99%) rename test/{plugin => internal_plugin}/push.test.ts (99%) rename {test => test_plugin}/remote_nodegit/3way_merge.test.ts (92%) rename {test => test_plugin}/remote_nodegit/3way_merge_ot.test.ts (92%) rename {test => test_plugin}/remote_nodegit/combine.test.ts (93%) rename {test => test_plugin}/remote_nodegit/network_git_documentdb.test.ts (91%) rename {test => test_plugin}/remote_nodegit/network_history.test.ts (92%) rename {test => test_plugin}/remote_nodegit/network_task_queue.test.ts (92%) rename {test => test_plugin}/remote_nodegit/on_sync_event.test.ts (92%) rename {test => test_plugin}/remote_nodegit/sync.test.ts (92%) rename {test => test_plugin}/remote_nodegit/sync_clone.test.ts (93%) rename {test => test_plugin}/remote_nodegit/sync_events.test.ts (92%) rename {test => test_plugin}/remote_nodegit/sync_live.test.ts (93%) rename {test => test_plugin}/remote_nodegit/sync_trypush.test.ts (92%) rename {test => test_plugin}/remote_nodegit/sync_trysync.test.ts (92%) diff --git a/.npmignore b/.npmignore index 4585b884..e16ec5f4 100644 --- a/.npmignore +++ b/.npmignore @@ -33,6 +33,7 @@ node_modules/ # test coverage/ test/ +test_plugin/ dist/test/ .nyc_output/ diff --git a/package.json b/package.json index 1b545d12..900a1921 100644 --- a/package.json +++ b/package.json @@ -10,11 +10,12 @@ "scripts": { "build": "rm -rf dist/* && npm run lint && tsc --project src/tsconfig.json", "doc": "npm run build && npm run api-extractor && npm run crlf", - "mocha": "rm -rf test/database* && npx cross-env TS_NODE_FILES=true TS_NODE_PROJECT=tsconfig.mocha.json mocha", - "mocha-unit": "rm -rf test/database* && npx cross-env TS_NODE_FILES=true TS_NODE_PROJECT=tsconfig.mocha.json mocha --retries 0", + "mocha": "npm run rm-test-db && npx cross-env TS_NODE_FILES=true TS_NODE_PROJECT=tsconfig.mocha.json mocha", + "mocha-unit": "npm run rm-test-db && npx cross-env TS_NODE_FILES=true TS_NODE_PROJECT=tsconfig.mocha.json mocha --retries 0", "compile-tests": "tsc --project test/tsconfig.json", - "rm-test-db": "rm -rf test/database*", - "test": "npm run rm-test-db && npx nyc npm run mocha \"test/**/*.test.ts\" && npm run rm-test-db", + "rm-test-db": "rm -rf test/database* test_plugin/database*", + "test": "npx nyc npm run mocha \"test/**/*.test.ts\" && npm run rm-test-db", + "test-plugin": "npm run mocha \"test_plugin/**/*.test.ts\" && npm run rm-test-db", "upload-coverage": "npx coveralls < coverage/lcov.info", "prepare": "", "prepublishOnly": "npm run build && npm test", diff --git a/test/plugin/checkfetch.test.ts b/test/internal_plugin/checkfetch.test.ts similarity index 99% rename from test/plugin/checkfetch.test.ts rename to test/internal_plugin/checkfetch.test.ts index b9931fbd..6996e447 100644 --- a/test/plugin/checkfetch.test.ts +++ b/test/internal_plugin/checkfetch.test.ts @@ -70,7 +70,7 @@ const maybe = ? describe : describe.skip; -maybe(' checkFetch', () => { +maybe(' checkFetch', () => { const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') ? process.env.GITDDB_GITHUB_USER_URL : process.env.GITDDB_GITHUB_USER_URL + '/'; diff --git a/test/plugin/clone.test.ts b/test/internal_plugin/clone.test.ts similarity index 99% rename from test/plugin/clone.test.ts rename to test/internal_plugin/clone.test.ts index ac46027a..226434b0 100644 --- a/test/plugin/clone.test.ts +++ b/test/internal_plugin/clone.test.ts @@ -70,7 +70,7 @@ const maybe = ? describe : describe.skip; -maybe(' clone', () => { +maybe(' clone', () => { const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') ? process.env.GITDDB_GITHUB_USER_URL : process.env.GITDDB_GITHUB_USER_URL + '/'; diff --git a/test/plugin/fetch.test.ts b/test/internal_plugin/fetch.test.ts similarity index 99% rename from test/plugin/fetch.test.ts rename to test/internal_plugin/fetch.test.ts index d8a23353..281d4c6d 100644 --- a/test/plugin/fetch.test.ts +++ b/test/internal_plugin/fetch.test.ts @@ -70,7 +70,7 @@ const maybe = ? describe : describe.skip; -maybe(' fetch', () => { +maybe(' fetch', () => { const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') ? process.env.GITDDB_GITHUB_USER_URL : process.env.GITDDB_GITHUB_USER_URL + '/'; diff --git a/test/plugin/push.test.ts b/test/internal_plugin/push.test.ts similarity index 99% rename from test/plugin/push.test.ts rename to test/internal_plugin/push.test.ts index 84dfdc8d..3998ddb2 100644 --- a/test/plugin/push.test.ts +++ b/test/internal_plugin/push.test.ts @@ -80,7 +80,7 @@ const maybe = ? describe : describe.skip; -maybe(' push', () => { +maybe(' push', () => { const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') ? process.env.GITDDB_GITHUB_USER_URL : process.env.GITDDB_GITHUB_USER_URL + '/'; diff --git a/test/remote_nodegit/3way_merge.test.ts b/test_plugin/remote_nodegit/3way_merge.test.ts similarity index 92% rename from test/remote_nodegit/3way_merge.test.ts rename to test_plugin/remote_nodegit/3way_merge.test.ts index 41554ee8..9b8165ec 100644 --- a/test/remote_nodegit/3way_merge.test.ts +++ b/test_plugin/remote_nodegit/3way_merge.test.ts @@ -14,12 +14,12 @@ */ import path from 'path'; import fs from 'fs-extra'; -import { syncThreeWayMergeBase } from '../remote_base/3way_merge'; +import { syncThreeWayMergeBase } from '../../test/remote_base/3way_merge'; import { ConnectionSettingsGitHub } from '../../src/types'; import { GitDocumentDB } from '../../src/git_documentdb'; const reposPrefix = 'test_3way_merge_nodegit__'; -const localDir = `./test/database_3way_merge_nodegit`; +const localDir = `./test_plugin/database_3way_merge_nodegit`; beforeEach(function () { // @ts-ignore diff --git a/test/remote_nodegit/3way_merge_ot.test.ts b/test_plugin/remote_nodegit/3way_merge_ot.test.ts similarity index 92% rename from test/remote_nodegit/3way_merge_ot.test.ts rename to test_plugin/remote_nodegit/3way_merge_ot.test.ts index ff9c6adb..dbfd754e 100644 --- a/test/remote_nodegit/3way_merge_ot.test.ts +++ b/test_plugin/remote_nodegit/3way_merge_ot.test.ts @@ -16,10 +16,10 @@ import path from 'path'; import fs from 'fs-extra'; import { ConnectionSettingsGitHub } from '../../src/types'; import { GitDocumentDB } from '../../src/git_documentdb'; -import { threeWayMergeOtBase } from '../remote_base/3way_merge_ot'; +import { threeWayMergeOtBase } from '../../test/remote_base/3way_merge_ot'; const reposPrefix = 'test_3way_merge_ot_nodegit__'; -const localDir = `./test/database_3way_merge_ot_nodegit`; +const localDir = `./test_plugin/database_3way_merge_ot_nodegit`; beforeEach(function () { // @ts-ignore diff --git a/test/remote_nodegit/combine.test.ts b/test_plugin/remote_nodegit/combine.test.ts similarity index 93% rename from test/remote_nodegit/combine.test.ts rename to test_plugin/remote_nodegit/combine.test.ts index 194be53e..94169f42 100644 --- a/test/remote_nodegit/combine.test.ts +++ b/test_plugin/remote_nodegit/combine.test.ts @@ -14,12 +14,12 @@ */ import path from 'path'; import fs from 'fs-extra'; -import { syncCombineBase } from '../remote_base/combine'; +import { syncCombineBase } from '../../test/remote_base/combine'; import { ConnectionSettingsGitHub } from '../../src/types'; import { GitDocumentDB } from '../../src/git_documentdb'; const reposPrefix = 'test_combine_nodegit__'; -const localDir = `./test/database_combine_nodegit`; +const localDir = `./test_plugin/database_combine_nodegit`; beforeEach(function () { // @ts-ignore diff --git a/test/remote_nodegit/network_git_documentdb.test.ts b/test_plugin/remote_nodegit/network_git_documentdb.test.ts similarity index 91% rename from test/remote_nodegit/network_git_documentdb.test.ts rename to test_plugin/remote_nodegit/network_git_documentdb.test.ts index 2135b6b5..75040780 100644 --- a/test/remote_nodegit/network_git_documentdb.test.ts +++ b/test_plugin/remote_nodegit/network_git_documentdb.test.ts @@ -14,12 +14,12 @@ */ import path from 'path'; import fs from 'fs-extra'; -import { networkGitDocumentDBBase } from '../remote_base/network_git_documentdb'; +import { networkGitDocumentDBBase } from '../../test/remote_base/network_git_documentdb'; import { ConnectionSettingsGitHub } from '../../src/types'; import { GitDocumentDB } from '../../src/git_documentdb'; const reposPrefix = 'test_network_git_documentdb_nodegit__'; -const localDir = `./test/database_network_git_documentdb_nodegit`; +const localDir = `./test_plugin/database_network_git_documentdb_nodegit`; beforeEach(function () { // @ts-ignore diff --git a/test/remote_nodegit/network_history.test.ts b/test_plugin/remote_nodegit/network_history.test.ts similarity index 92% rename from test/remote_nodegit/network_history.test.ts rename to test_plugin/remote_nodegit/network_history.test.ts index e2b6a3cc..c1001286 100644 --- a/test/remote_nodegit/network_history.test.ts +++ b/test_plugin/remote_nodegit/network_history.test.ts @@ -16,10 +16,10 @@ import path from 'path'; import fs from 'fs-extra'; import { ConnectionSettingsGitHub } from '../../src/types'; import { GitDocumentDB } from '../../src/git_documentdb'; -import { networkHistoryBase } from '../remote_base/network_history'; +import { networkHistoryBase } from '../../test/remote_base/network_history'; const reposPrefix = 'test_network_history_nodegit__'; -const localDir = `./test/database_network_history_nodegit`; +const localDir = `./test_plugin/database_network_history_nodegit`; beforeEach(function () { // @ts-ignore diff --git a/test/remote_nodegit/network_task_queue.test.ts b/test_plugin/remote_nodegit/network_task_queue.test.ts similarity index 92% rename from test/remote_nodegit/network_task_queue.test.ts rename to test_plugin/remote_nodegit/network_task_queue.test.ts index b0863e8d..a180f70f 100644 --- a/test/remote_nodegit/network_task_queue.test.ts +++ b/test_plugin/remote_nodegit/network_task_queue.test.ts @@ -16,10 +16,10 @@ import path from 'path'; import fs from 'fs-extra'; import { ConnectionSettingsGitHub } from '../../src/types'; import { GitDocumentDB } from '../../src/git_documentdb'; -import { networkTaskQueueBase } from '../remote_base/network_task_queue'; +import { networkTaskQueueBase } from '../../test/remote_base/network_task_queue'; const reposPrefix = 'test_network_task_queue_nodegit__'; -const localDir = `./test/database_network_task_queue_nodegit`; +const localDir = `./test_plugin/database_network_task_queue_nodegit`; beforeEach(function () { // @ts-ignore diff --git a/test/remote_nodegit/on_sync_event.test.ts b/test_plugin/remote_nodegit/on_sync_event.test.ts similarity index 92% rename from test/remote_nodegit/on_sync_event.test.ts rename to test_plugin/remote_nodegit/on_sync_event.test.ts index e4083ee6..1473b972 100644 --- a/test/remote_nodegit/on_sync_event.test.ts +++ b/test_plugin/remote_nodegit/on_sync_event.test.ts @@ -14,12 +14,12 @@ */ import path from 'path'; import fs from 'fs-extra'; -import { onSyncEventBase } from '../remote_base/on_sync_event'; +import { onSyncEventBase } from '../../test/remote_base/on_sync_event'; import { ConnectionSettingsGitHub } from '../../src/types'; import { GitDocumentDB } from '../../src/git_documentdb'; const reposPrefix = 'test_on_sync_event_nodegit__'; -const localDir = `./test/database_on_sync_event_nodegit`; +const localDir = `./test_plugin/database_on_sync_event_nodegit`; beforeEach(function () { // @ts-ignore diff --git a/test/remote_nodegit/sync.test.ts b/test_plugin/remote_nodegit/sync.test.ts similarity index 92% rename from test/remote_nodegit/sync.test.ts rename to test_plugin/remote_nodegit/sync.test.ts index b3a4bfa9..1e8e1b3f 100644 --- a/test/remote_nodegit/sync.test.ts +++ b/test_plugin/remote_nodegit/sync.test.ts @@ -11,10 +11,10 @@ import path from 'path'; import fs from 'fs-extra'; import { ConnectionSettingsGitHub } from '../../src/types'; import { GitDocumentDB } from '../../src/git_documentdb'; -import { syncBase } from '../remote_base/sync'; +import { syncBase } from '../../test/remote_base/sync'; const reposPrefix = 'test_sync_constructor_nodegit__'; -const localDir = `./test/database_sync_constructor_nodegit`; +const localDir = `./test_plugin/database_sync_constructor_nodegit`; beforeEach(function () { // @ts-ignore diff --git a/test/remote_nodegit/sync_clone.test.ts b/test_plugin/remote_nodegit/sync_clone.test.ts similarity index 93% rename from test/remote_nodegit/sync_clone.test.ts rename to test_plugin/remote_nodegit/sync_clone.test.ts index 790e052e..98e93ad2 100644 --- a/test/remote_nodegit/sync_clone.test.ts +++ b/test_plugin/remote_nodegit/sync_clone.test.ts @@ -14,12 +14,12 @@ */ import path from 'path'; import fs from 'fs-extra'; -import { syncCloneBase } from '../remote_base/sync_clone'; +import { syncCloneBase } from '../../test/remote_base/sync_clone'; import { ConnectionSettingsGitHub } from '../../src/types'; import { GitDocumentDB } from '../../src/git_documentdb'; const reposPrefix = 'test_sync_clone_nodegit___'; -const localDir = `./test/database_sync_clone_nodegit`; +const localDir = `./test_plugin/database_sync_clone_nodegit`; beforeEach(function () { // @ts-ignore diff --git a/test/remote_nodegit/sync_events.test.ts b/test_plugin/remote_nodegit/sync_events.test.ts similarity index 92% rename from test/remote_nodegit/sync_events.test.ts rename to test_plugin/remote_nodegit/sync_events.test.ts index cb641722..ece785c4 100644 --- a/test/remote_nodegit/sync_events.test.ts +++ b/test_plugin/remote_nodegit/sync_events.test.ts @@ -14,12 +14,12 @@ */ import path from 'path'; import fs from 'fs-extra'; -import { syncEventsBase } from '../remote_base/sync_events'; +import { syncEventsBase } from '../../test/remote_base/sync_events'; import { ConnectionSettingsGitHub } from '../../src/types'; import { GitDocumentDB } from '../../src/git_documentdb'; const reposPrefix = 'test_sync_events_nodegit___'; -const localDir = `./test/database_sync_events_nodegit`; +const localDir = `./test_plugin/database_sync_events_nodegit`; beforeEach(function () { // @ts-ignore diff --git a/test/remote_nodegit/sync_live.test.ts b/test_plugin/remote_nodegit/sync_live.test.ts similarity index 93% rename from test/remote_nodegit/sync_live.test.ts rename to test_plugin/remote_nodegit/sync_live.test.ts index 1dfc52d8..3fbb3032 100644 --- a/test/remote_nodegit/sync_live.test.ts +++ b/test_plugin/remote_nodegit/sync_live.test.ts @@ -14,12 +14,12 @@ */ import path from 'path'; import fs from 'fs-extra'; -import { syncLiveBase } from '../remote_base/sync_live'; +import { syncLiveBase } from '../../test/remote_base/sync_live'; import { ConnectionSettingsGitHub } from '../../src/types'; import { GitDocumentDB } from '../../src/git_documentdb'; const reposPrefix = 'test_sync_live_nodegit___'; -const localDir = `./test/database_sync_live_nodegit`; +const localDir = `./test_plugin/database_sync_live_nodegit`; beforeEach(function () { // @ts-ignore diff --git a/test/remote_nodegit/sync_trypush.test.ts b/test_plugin/remote_nodegit/sync_trypush.test.ts similarity index 92% rename from test/remote_nodegit/sync_trypush.test.ts rename to test_plugin/remote_nodegit/sync_trypush.test.ts index a83287ab..cb6f3ab7 100644 --- a/test/remote_nodegit/sync_trypush.test.ts +++ b/test_plugin/remote_nodegit/sync_trypush.test.ts @@ -14,12 +14,12 @@ */ import path from 'path'; import fs from 'fs-extra'; -import { syncTryPushBase } from '../remote_base/sync_trypush'; +import { syncTryPushBase } from '../../test/remote_base/sync_trypush'; import { ConnectionSettingsGitHub } from '../../src/types'; import { GitDocumentDB } from '../../src/git_documentdb'; const reposPrefix = 'test_sync_trypush_nodegit___'; -const localDir = `./test/database_sync_trypush_nodegit`; +const localDir = `./test_plugin/database_sync_trypush_nodegit`; beforeEach(function () { // @ts-ignore diff --git a/test/remote_nodegit/sync_trysync.test.ts b/test_plugin/remote_nodegit/sync_trysync.test.ts similarity index 92% rename from test/remote_nodegit/sync_trysync.test.ts rename to test_plugin/remote_nodegit/sync_trysync.test.ts index ebe9ae2a..73e60eac 100644 --- a/test/remote_nodegit/sync_trysync.test.ts +++ b/test_plugin/remote_nodegit/sync_trysync.test.ts @@ -14,12 +14,12 @@ */ import path from 'path'; import fs from 'fs-extra'; -import { syncTrySyncBase } from '../remote_base/sync_trysync'; +import { syncTrySyncBase } from '../../test/remote_base/sync_trysync'; import { ConnectionSettingsGitHub } from '../../src/types'; import { GitDocumentDB } from '../../src/git_documentdb'; const reposPrefix = 'test_sync_trysync_nodegit___'; -const localDir = `./test/database_sync_trysync_nodegit`; +const localDir = `./test_plugin/database_sync_trysync_nodegit`; beforeEach(function () { // @ts-ignore diff --git a/tsconfig.eslint.json b/tsconfig.eslint.json index 6f757a15..f6a55ac3 100644 --- a/tsconfig.eslint.json +++ b/tsconfig.eslint.json @@ -3,6 +3,7 @@ "include": [ "src/**/*", "test/**/*", + "test_plugin/**/*", "webpack.*" ], } \ No newline at end of file From 10b8791e5fb182d0cc7b478ca3c41b30dcda6429 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 3 Aug 2021 01:09:56 +0900 Subject: [PATCH 130/297] build: bump to v0.4.1-beta.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 900a1921..a24333c2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "git-documentdb", - "version": "0.4.0", + "version": "0.4.1-beta.0", "description": "Offline-first database that syncs with Git", "main": "dist/main.js", "types": "dist/main.d.ts", From ad6c56149afa0c2673c04c2db49bd6ae822f1f33 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 3 Aug 2021 02:32:40 +0900 Subject: [PATCH 131/297] fix: add type for RemoteEngine --- src/remote/remote_engine.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/remote/remote_engine.ts b/src/remote/remote_engine.ts index 80633e3f..d3c0f1b8 100644 --- a/src/remote/remote_engine.ts +++ b/src/remote/remote_engine.ts @@ -17,6 +17,9 @@ export const RemoteEngine: { [key: string]: RemoteEngineInterface } = {}; * @public */ export interface RemoteEngineInterface { + type: string; + name: string; + checkFetch: ( workingDir: string, options: RemoteOptions, From 4d1b741c7b204dc84ba477359d99cce1b5e64191 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 3 Aug 2021 02:33:19 +0900 Subject: [PATCH 132/297] build: bump to v0.4.1-beta.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a24333c2..a4193eb5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "git-documentdb", - "version": "0.4.1-beta.0", + "version": "0.4.1-beta.2", "description": "Offline-first database that syncs with Git", "main": "dist/main.js", "types": "dist/main.d.ts", From 2d65594cafcce7ee86d6f3d61681c9cd55c3384b Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 3 Aug 2021 11:06:38 +0900 Subject: [PATCH 133/297] fix: adding plugin example --- examples/package-lock.json | 4692 +++++++++++++++++++----------------- examples/package.json | 3 +- examples/src/index.ts | 4 +- examples/src/plugin.ts | 83 + 4 files changed, 2598 insertions(+), 2184 deletions(-) create mode 100644 examples/src/plugin.ts diff --git a/examples/package-lock.json b/examples/package-lock.json index 5f002f38..c2a13e49 100644 --- a/examples/package-lock.json +++ b/examples/package-lock.json @@ -9,11 +9,11 @@ "requires": { "@octokit/rest": "^18.3.5", "@sosuisen/jsondiffpatch": "^0.4.7", - "@sosuisen/nodegit": "^0.27.3", "@types/async-lock": "^1.1.2", "async-lock": "^1.3.0", "cross-blob": "^2.0.0", "fs-extra": "^9.1.0", + "git-documentdb-remote-errors": "^1.0.3", "isomorphic-git": "^1.8.2", "ot-json1": "^1.0.2", "rimraf": "^3.0.2", @@ -28,35 +28,58 @@ "integrity": "sha512-TeyhRGefTOtA9N3udMrvheafoXcz/dvTTdZLcieeZQxm1SSeaQDUQ/rUH6QTOiHVNMtjOCrZ9J5rk1A4mPYuag==" }, "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", "requires": { - "@babel/highlight": "^7.10.4" + "@babel/highlight": "^7.14.5" } }, + "@babel/compat-data": { + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.7.tgz", + "integrity": "sha512-nS6dZaISCXJ3+518CWiBfEr//gHyMO02uDxBkXTKZDN5POruCnOZ1N4YBRZDCabwF8nZMWBpRxIicmXtBs+fvw==" + }, "@babel/core": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.10.tgz", - "integrity": "sha512-eTAlQKq65zHfkHZV0sIVODCPGVgoo1HdBlbSLi9CqOzuZanMv2ihzY+4paiKr1mH+XmYESMAmJ/dpZ68eN6d8w==", - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.12.10", - "@babel/helper-module-transforms": "^7.12.1", - "@babel/helpers": "^7.12.5", - "@babel/parser": "^7.12.10", - "@babel/template": "^7.12.7", - "@babel/traverse": "^7.12.10", - "@babel/types": "^7.12.10", + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.6.tgz", + "integrity": "sha512-gJnOEWSqTk96qG5BoIrl5bVtc23DCycmIePPYnamY9RboYdI4nFy5vAQMSl81O5K/W0sLDWfGysnOECC+KUUCA==", + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.14.5", + "@babel/helper-compilation-targets": "^7.14.5", + "@babel/helper-module-transforms": "^7.14.5", + "@babel/helpers": "^7.14.6", + "@babel/parser": "^7.14.6", + "@babel/template": "^7.14.5", + "@babel/traverse": "^7.14.5", + "@babel/types": "^7.14.5", "convert-source-map": "^1.7.0", "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", + "gensync": "^1.0.0-beta.2", "json5": "^2.1.2", - "lodash": "^4.17.19", - "semver": "^5.4.1", + "semver": "^6.3.0", "source-map": "^0.5.0" }, "dependencies": { + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -64,12 +87,29 @@ } } }, + "@babel/eslint-parser": { + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.14.7.tgz", + "integrity": "sha512-6WPwZqO5priAGIwV6msJcdc9TsEPzYeYdS/Xuoap+/ihkgN6dzHp2bcAAwyWZ5bLzk0vvjDmKvRwkqNaiJ8BiQ==", + "requires": { + "eslint-scope": "^5.1.1", + "eslint-visitor-keys": "^2.1.0", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, "@babel/generator": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", - "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz", + "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==", "requires": { - "@babel/types": "^7.12.11", + "@babel/types": "^7.14.5", "jsesc": "^2.5.1", "source-map": "^0.5.0" }, @@ -81,232 +121,244 @@ } } }, + "@babel/helper-compilation-targets": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.14.5.tgz", + "integrity": "sha512-v+QtZqXEiOnpO6EYvlImB6zCD2Lel06RzOPzmkz/D/XgQiUu3C/Jb1LOqSt/AIA34TYi/Q+KlT8vTQrgdxkbLw==", + "requires": { + "@babel/compat-data": "^7.14.5", + "@babel/helper-validator-option": "^7.14.5", + "browserslist": "^4.16.6", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, "@babel/helper-function-name": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", - "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz", + "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==", "requires": { - "@babel/helper-get-function-arity": "^7.12.10", - "@babel/template": "^7.12.7", - "@babel/types": "^7.12.11" + "@babel/helper-get-function-arity": "^7.14.5", + "@babel/template": "^7.14.5", + "@babel/types": "^7.14.5" } }, "@babel/helper-get-function-arity": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", - "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz", + "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==", "requires": { - "@babel/types": "^7.12.10" + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.14.5.tgz", + "integrity": "sha512-R1PXiz31Uc0Vxy4OEOm07x0oSjKAdPPCh3tPivn/Eo8cvz6gveAeuyUUPB21Hoiif0uoPQSSdhIPS3352nvdyQ==", + "requires": { + "@babel/types": "^7.14.5" } }, "@babel/helper-member-expression-to-functions": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", - "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.14.7.tgz", + "integrity": "sha512-TMUt4xKxJn6ccjcOW7c4hlwyJArizskAhoSTOCkA0uZ+KghIaci0Qg9R043kUMWI9mtQfgny+NQ5QATnZ+paaA==", "requires": { - "@babel/types": "^7.12.7" + "@babel/types": "^7.14.5" } }, "@babel/helper-module-imports": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", - "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz", + "integrity": "sha512-SwrNHu5QWS84XlHwGYPDtCxcA0hrSlL2yhWYLgeOc0w7ccOl2qv4s/nARI0aYZW+bSwAL5CukeXA47B/1NKcnQ==", "requires": { - "@babel/types": "^7.12.5" + "@babel/types": "^7.14.5" } }, "@babel/helper-module-transforms": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz", - "integrity": "sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.5.tgz", + "integrity": "sha512-iXpX4KW8LVODuAieD7MzhNjmM6dzYY5tfRqT+R9HDXWl0jPn/djKmA+G9s/2C2T9zggw5tK1QNqZ70USfedOwA==", "requires": { - "@babel/helper-module-imports": "^7.12.1", - "@babel/helper-replace-supers": "^7.12.1", - "@babel/helper-simple-access": "^7.12.1", - "@babel/helper-split-export-declaration": "^7.11.0", - "@babel/helper-validator-identifier": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.12.1", - "@babel/types": "^7.12.1", - "lodash": "^4.17.19" + "@babel/helper-module-imports": "^7.14.5", + "@babel/helper-replace-supers": "^7.14.5", + "@babel/helper-simple-access": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5", + "@babel/helper-validator-identifier": "^7.14.5", + "@babel/template": "^7.14.5", + "@babel/traverse": "^7.14.5", + "@babel/types": "^7.14.5" } }, "@babel/helper-optimise-call-expression": { - "version": "7.12.10", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz", - "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.14.5.tgz", + "integrity": "sha512-IqiLIrODUOdnPU9/F8ib1Fx2ohlgDhxnIDU7OEVi+kAbEZcyiF7BLU8W6PfvPi9LzztjS7kcbzbmL7oG8kD6VA==", "requires": { - "@babel/types": "^7.12.10" + "@babel/types": "^7.14.5" } }, "@babel/helper-replace-supers": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz", - "integrity": "sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.14.5.tgz", + "integrity": "sha512-3i1Qe9/8x/hCHINujn+iuHy+mMRLoc77b2nI9TB0zjH1hvn9qGlXjWlggdwUcju36PkPCy/lpM7LLUdcTyH4Ow==", "requires": { - "@babel/helper-member-expression-to-functions": "^7.12.7", - "@babel/helper-optimise-call-expression": "^7.12.10", - "@babel/traverse": "^7.12.10", - "@babel/types": "^7.12.11" + "@babel/helper-member-expression-to-functions": "^7.14.5", + "@babel/helper-optimise-call-expression": "^7.14.5", + "@babel/traverse": "^7.14.5", + "@babel/types": "^7.14.5" } }, "@babel/helper-simple-access": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz", - "integrity": "sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.14.5.tgz", + "integrity": "sha512-nfBN9xvmCt6nrMZjfhkl7i0oTV3yxR4/FztsbOASyTvVcoYd0TRHh7eMLdlEcCqobydC0LAF3LtC92Iwxo0wyw==", "requires": { - "@babel/types": "^7.12.1" + "@babel/types": "^7.14.5" } }, "@babel/helper-split-export-declaration": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", - "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz", + "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==", "requires": { - "@babel/types": "^7.12.11" + "@babel/types": "^7.14.5" } }, "@babel/helper-validator-identifier": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==" + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", + "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==" + }, + "@babel/helper-validator-option": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", + "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==" }, "@babel/helpers": { - "version": "7.12.5", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.12.5.tgz", - "integrity": "sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA==", + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.14.6.tgz", + "integrity": "sha512-yesp1ENQBiLI+iYHSJdoZKUtRpfTlL1grDIX9NRlAVppljLw/4tTyYupIB7uIYmC3stW/imAv8EqaKaS/ibmeA==", "requires": { - "@babel/template": "^7.10.4", - "@babel/traverse": "^7.12.5", - "@babel/types": "^7.12.5" + "@babel/template": "^7.14.5", + "@babel/traverse": "^7.14.5", + "@babel/types": "^7.14.5" } }, "@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.14.5", "chalk": "^2.0.0", "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "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==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } } }, "@babel/parser": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", - "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==" + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.7.tgz", + "integrity": "sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==" }, "@babel/template": { - "version": "7.12.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", - "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", + "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.12.7", - "@babel/types": "^7.12.7" + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.14.5", + "@babel/types": "^7.14.5" } }, "@babel/traverse": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", - "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", - "requires": { - "@babel/code-frame": "^7.12.11", - "@babel/generator": "^7.12.11", - "@babel/helper-function-name": "^7.12.11", - "@babel/helper-split-export-declaration": "^7.12.11", - "@babel/parser": "^7.12.11", - "@babel/types": "^7.12.12", + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.7.tgz", + "integrity": "sha512-9vDr5NzHu27wgwejuKL7kIOm4bwEtaPQ4Z6cpCmjSuaRqpH/7xc4qcGEscwMqlkwgcXl6MvqoAjZkQ24uSdIZQ==", + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.14.5", + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-hoist-variables": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5", + "@babel/parser": "^7.14.7", + "@babel/types": "^7.14.5", "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.19" + "globals": "^11.1.0" + }, + "dependencies": { + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "requires": { + "ms": "2.1.2" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } } }, "@babel/types": { - "version": "7.12.12", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", - "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", "requires": { - "@babel/helper-validator-identifier": "^7.12.11", - "lodash": "^4.17.19", + "@babel/helper-validator-identifier": "^7.14.5", "to-fast-properties": "^2.0.0" } }, "@eslint/eslintrc": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.2.2.tgz", - "integrity": "sha512-EfB5OHNYp1F4px/LI/FEnGylop7nOqkQ1LRzCM0KccA2U8tvV8w01KBv37LbO7nW4H+YhKyo2LcJhRwjjV17QQ==", + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.2.tgz", + "integrity": "sha512-8nmGq/4ycLpIwzvhI4tNDmQztZ8sp+hI7cyG8i1nQDhkAbRzHpXPidRAHlNvCZQpJTKw5ItIpMw9RSToGF00mg==", "requires": { "ajv": "^6.12.4", "debug": "^4.1.1", "espree": "^7.3.0", - "globals": "^12.1.0", + "globals": "^13.9.0", "ignore": "^4.0.6", "import-fresh": "^3.2.1", "js-yaml": "^3.13.1", - "lodash": "^4.17.19", "minimatch": "^3.0.4", "strip-json-comments": "^3.1.1" }, "dependencies": { - "globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "requires": { - "type-fest": "^0.8.1" + "ms": "2.1.2" } }, "ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "strip-json-comments": { + "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==" } } }, @@ -316,9 +368,9 @@ "integrity": "sha1-/S0rVakCnGs3psk16MiHGucN+gc=" }, "@glimmer/interfaces": { - "version": "0.56.1", - "resolved": "https://registry.npmjs.org/@glimmer/interfaces/-/interfaces-0.56.1.tgz", - "integrity": "sha512-+0KvSd7c9QmkEeCFHaBDub1DBeTONw+x6MZUcb/MlA3FfNis2aFs7kHVkjkdzp0Ust54Wn448dgWZFW27EuVJA==", + "version": "0.56.2", + "resolved": "https://registry.npmjs.org/@glimmer/interfaces/-/interfaces-0.56.2.tgz", + "integrity": "sha512-nRgcsTuyZ90aEoCuYVHKGDs3LpAv9n/JKiJ6iecpEYtyGgcPqSI3GjrJRl6k+1s5wnldEH1kjWq+ccCiXmA99w==", "requires": { "@simple-dom/interface": "^1.4.0" } @@ -335,15 +387,45 @@ } }, "@glimmer/util": { - "version": "0.56.1", - "resolved": "https://registry.npmjs.org/@glimmer/util/-/util-0.56.1.tgz", - "integrity": "sha512-g7R5hMtZ2BLF+AsYhSE1xoh0gOJALof4/JL6zovYvqrsKTLYGK1Qe3RKXSt8dPav8Ac0LXt+cOd6jHPGSrEs+A==", + "version": "0.56.2", + "resolved": "https://registry.npmjs.org/@glimmer/util/-/util-0.56.2.tgz", + "integrity": "sha512-AljXCX5HBjJkmNt4DNYmJmVvwqKjFF4lU6e0SBftwhzK85RbETYwpb3YWrghcjSCxoodwIu1zNFiKOA+xD6txw==", "requires": { "@glimmer/env": "0.1.7", - "@glimmer/interfaces": "^0.56.1", + "@glimmer/interfaces": "^0.56.2", "@simple-dom/interface": "^1.4.0" } }, + "@humanwhocodes/config-array": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "requires": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "dependencies": { + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "@humanwhocodes/object-schema": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", + "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==" + }, "@iarna/toml": { "version": "2.2.5", "resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-2.2.5.tgz", @@ -359,23 +441,123 @@ "get-package-type": "^0.1.0", "js-yaml": "^3.13.1", "resolve-from": "^5.0.0" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" + } } }, "@istanbuljs/schema": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", - "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==" + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==" }, "@jest/types": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.2.tgz", - "integrity": "sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz", + "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==", "requires": { "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^16.0.0", "chalk": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } } }, "@jsbits/deep-clone": { @@ -384,16 +566,16 @@ "integrity": "sha512-aKhOhRv18tlhkjapBrcyAt8U1SmyzKi2QoO4GGMlXRfQhwm7USDSo/pX8MgB8tYB3MLaevuvwufynKSDA7U3EA==" }, "@microsoft/api-extractor": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.16.0.tgz", - "integrity": "sha512-6CIpg4Iw4DWJszZMwYhh8OQ0bsmKq6CFjeCHfciDzmV+cUJ8ysJrO4LhYKNHEMOcfUYIv0EVoYul7/zMXTv9eA==", + "version": "7.18.1", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.18.1.tgz", + "integrity": "sha512-qljUF2Q0zAx1vJrjKkJVGN7OVbsXki+Pji99jywyl6L/FK3YZ7PpstUJYE6uBcLPy6rhNPWPAsHNTMpG/kHIsg==", "requires": { - "@microsoft/api-extractor-model": "7.13.2", + "@microsoft/api-extractor-model": "7.13.3", "@microsoft/tsdoc": "0.13.2", "@microsoft/tsdoc-config": "~0.15.2", - "@rushstack/node-core-library": "3.38.0", + "@rushstack/node-core-library": "3.39.0", "@rushstack/rig-package": "0.2.12", - "@rushstack/ts-command-line": "4.7.10", + "@rushstack/ts-command-line": "4.8.0", "colors": "~1.2.1", "lodash": "~4.17.15", "resolve": "~1.17.0", @@ -402,63 +584,6 @@ "typescript": "~4.3.2" }, "dependencies": { - "@microsoft/api-extractor-model": { - "version": "7.13.2", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.13.2.tgz", - "integrity": "sha512-gA9Q8q5TPM2YYk7rLinAv9KqcodrmRC13BVmNzLswjtFxpz13lRh0BmrqD01/sddGpGMIuWFYlfUM4VSWxnggA==", - "requires": { - "@microsoft/tsdoc": "0.13.2", - "@microsoft/tsdoc-config": "~0.15.2", - "@rushstack/node-core-library": "3.38.0" - } - }, - "@rushstack/node-core-library": { - "version": "3.38.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.38.0.tgz", - "integrity": "sha512-cmvl0yQx8sSmbuXwiRYJi8TO+jpTtrLJQ8UmFHhKvgPVJAW8cV8dnpD1Xx/BvTGrJZ2XtRAIkAhBS9okBnap4w==", - "requires": { - "@types/node": "10.17.13", - "colors": "~1.2.1", - "fs-extra": "~7.0.1", - "import-lazy": "~4.0.0", - "jju": "~1.4.0", - "resolve": "~1.17.0", - "semver": "~7.3.0", - "timsort": "~0.3.0", - "z-schema": "~3.18.3" - } - }, - "@types/node": { - "version": "10.17.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.13.tgz", - "integrity": "sha512-pMCcqU2zT4TjqYFrWtYHKal7Sl30Ims6ulZ4UFXxI4xbtQqK/qqKwkDoBFCfooRqqmRu9vY3xaJRwxSh673aYg==" - }, - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "requires": { - "path-parse": "^1.0.6" - } - }, "semver": { "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", @@ -466,11 +591,6 @@ "requires": { "lru-cache": "^6.0.0" } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" } } }, @@ -500,33 +620,37 @@ "resolve": "~1.19.0" }, "dependencies": { - "@microsoft/tsdoc": { - "version": "0.13.2", - "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.13.2.tgz", - "integrity": "sha512-WrHvO8PDL8wd8T2+zBGKrMwVL5IyzR3ryWUsl0PXgEV0QHup4mTLi0QcATefGI6Gx9Anu7vthPyyyLpY0EpiQg==" + "resolve": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "requires": { + "is-core-module": "^2.1.0", + "path-parse": "^1.0.6" + } } } }, "@nodelib/fs.scandir": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz", - "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "requires": { - "@nodelib/fs.stat": "2.0.4", + "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "@nodelib/fs.stat": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz", - "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==" + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" }, "@nodelib/fs.walk": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz", - "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "requires": { - "@nodelib/fs.scandir": "2.1.4", + "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, @@ -539,13 +663,13 @@ } }, "@octokit/core": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.3.0.tgz", - "integrity": "sha512-GGMpjaodCBY7JrtOwfolMocwZw9Pj5NxuQqfaJhGau4tkyonm0JRV9D6juQYLMb1Kl261++4Q980o0FlAtg8jg==", + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.5.1.tgz", + "integrity": "sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw==", "requires": { "@octokit/auth-token": "^2.4.4", "@octokit/graphql": "^4.5.8", - "@octokit/request": "^5.4.12", + "@octokit/request": "^5.6.0", "@octokit/request-error": "^2.0.5", "@octokit/types": "^6.0.3", "before-after-hook": "^2.2.0", @@ -553,85 +677,69 @@ } }, "@octokit/endpoint": { - "version": "6.0.11", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.11.tgz", - "integrity": "sha512-fUIPpx+pZyoLW4GCs3yMnlj2LfoXTWDUVPTC4V3MUEKZm48W+XYpeWSZCv+vYF1ZABUm2CqnDVf1sFtIYrj7KQ==", + "version": "6.0.12", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz", + "integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==", "requires": { "@octokit/types": "^6.0.3", "is-plain-object": "^5.0.0", "universal-user-agent": "^6.0.0" - }, - "dependencies": { - "is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==" - } } }, "@octokit/graphql": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.6.1.tgz", - "integrity": "sha512-2lYlvf4YTDgZCTXTW4+OX+9WTLFtEUc6hGm4qM1nlZjzxj+arizM4aHWzBVBCxY9glh7GIs0WEuiSgbVzv8cmA==", + "version": "4.6.4", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.6.4.tgz", + "integrity": "sha512-SWTdXsVheRmlotWNjKzPOb6Js6tjSqA2a8z9+glDJng0Aqjzti8MEWOtuT8ZSu6wHnci7LZNuarE87+WJBG4vg==", "requires": { - "@octokit/request": "^5.3.0", + "@octokit/request": "^5.6.0", "@octokit/types": "^6.0.3", "universal-user-agent": "^6.0.0" } }, "@octokit/openapi-types": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-5.3.2.tgz", - "integrity": "sha512-NxF1yfYOUO92rCx3dwvA2onF30Vdlg7YUkMVXkeptqpzA3tRLplThhFleV/UKWFgh7rpKu1yYRbvNDUtzSopKA==" + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-8.2.1.tgz", + "integrity": "sha512-BJz6kWuL3n+y+qM8Pv+UGbSxH6wxKf/SBs5yzGufMHwDefsa+Iq7ZGy1BINMD2z9SkXlIzk1qiu988rMuGXEMg==" }, "@octokit/plugin-paginate-rest": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.11.0.tgz", - "integrity": "sha512-7L9xQank2G3r1dGqrVPo1z62V5utbykOUzlmNHPz87Pww/JpZQ9KyG5CHtUzgmB4n5iDRKYNK/86A8D98HP0yA==", + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.14.0.tgz", + "integrity": "sha512-S2uEu2uHeI7Vf+Lvj8tv3O5/5TCAa8GHS0dUQN7gdM7vKA6ZHAbR6HkAVm5yMb1mbedLEbxOuQ+Fa0SQ7tCDLA==", "requires": { - "@octokit/types": "^6.11.0" + "@octokit/types": "^6.18.0" } }, "@octokit/plugin-request-log": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.3.tgz", - "integrity": "sha512-4RFU4li238jMJAzLgAwkBAw+4Loile5haQMQr+uhFq27BmyJXcXSKvoQKqh0agsZEiUlW6iSv3FAgvmGkur7OQ==" + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz", + "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==" }, "@octokit/plugin-rest-endpoint-methods": { - "version": "4.13.5", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-4.13.5.tgz", - "integrity": "sha512-kYKcWkFm4Ldk8bZai2RVEP1z97k1C/Ay2FN9FNTBg7JIyKoiiJjks4OtT6cuKeZX39tqa+C3J9xeYc6G+6g8uQ==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.4.1.tgz", + "integrity": "sha512-Nx0g7I5ayAYghsLJP4Q1Ch2W9jYYM0FlWWWZocUro8rNxVwuZXGfFd7Rcqi9XDWepSXjg1WByiNJnZza2hIOvQ==", "requires": { - "@octokit/types": "^6.12.2", + "@octokit/types": "^6.18.1", "deprecation": "^2.3.1" } }, "@octokit/request": { - "version": "5.4.14", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.4.14.tgz", - "integrity": "sha512-VkmtacOIQp9daSnBmDI92xNIeLuSRDOIuplp/CJomkvzt7M18NXgG044Cx/LFKLgjKt9T2tZR6AtJayba9GTSA==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.0.tgz", + "integrity": "sha512-4cPp/N+NqmaGQwbh3vUsYqokQIzt7VjsgTYVXiwpUP2pxd5YiZB2XuTedbb0SPtv9XS7nzAKjAuQxmY8/aZkiA==", "requires": { "@octokit/endpoint": "^6.0.1", - "@octokit/request-error": "^2.0.0", - "@octokit/types": "^6.7.1", - "deprecation": "^2.0.0", + "@octokit/request-error": "^2.1.0", + "@octokit/types": "^6.16.1", "is-plain-object": "^5.0.0", "node-fetch": "^2.6.1", - "once": "^1.4.0", "universal-user-agent": "^6.0.0" - }, - "dependencies": { - "is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==" - } } }, "@octokit/request-error": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.0.5.tgz", - "integrity": "sha512-T/2wcCFyM7SkXzNoyVNWjyVlUwBvW3igM3Btr/eKYiPmucXTtkxt2RBsf6gn3LTzaLSLTQtNmvg+dGsOxQrjZg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz", + "integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==", "requires": { "@octokit/types": "^6.0.3", "deprecation": "^2.0.0", @@ -639,22 +747,22 @@ } }, "@octokit/rest": { - "version": "18.3.5", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.3.5.tgz", - "integrity": "sha512-ZPeRms3WhWxQBEvoIh0zzf8xdU2FX0Capa7+lTca8YHmRsO3QNJzf1H3PcuKKsfgp91/xVDRtX91sTe1kexlbw==", + "version": "18.6.7", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.6.7.tgz", + "integrity": "sha512-Kn6WrI2ZvmAztdx+HEaf88RuJn+LK72S8g6OpciE4kbZddAN84fu4fiPGxcEu052WmqKVnA/cnQsbNlrYC6rqQ==", "requires": { - "@octokit/core": "^3.2.3", + "@octokit/core": "^3.5.0", "@octokit/plugin-paginate-rest": "^2.6.2", "@octokit/plugin-request-log": "^1.0.2", - "@octokit/plugin-rest-endpoint-methods": "4.13.5" + "@octokit/plugin-rest-endpoint-methods": "5.4.1" } }, "@octokit/types": { - "version": "6.12.2", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.12.2.tgz", - "integrity": "sha512-kCkiN8scbCmSq+gwdJV0iLgHc0O/GTPY1/cffo9kECu1MvatLPh9E+qFhfRIktKfHEA6ZYvv6S1B4Wnv3bi3pA==", + "version": "6.18.1", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.18.1.tgz", + "integrity": "sha512-5YsddjO1U+xC8ZYKV8yZYebW55PCc7qiEEeZ+wZRr6qyclynzfyD65KZ5FdtIeP0/cANyFaD7hV69qElf1nMsQ==", "requires": { - "@octokit/openapi-types": "^5.3.2" + "@octokit/openapi-types": "^8.2.1" } }, "@rushstack/node-core-library": { @@ -688,22 +796,6 @@ "universalify": "^0.1.0" } }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "requires": { - "path-parse": "^1.0.6" - } - }, "semver": { "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", @@ -711,11 +803,6 @@ "requires": { "lru-cache": "^6.0.0" } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" } } }, @@ -728,20 +815,17 @@ "strip-json-comments": "~3.1.1" }, "dependencies": { - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "requires": { - "path-parse": "^1.0.6" - } + "strip-json-comments": { + "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==" } } }, "@rushstack/ts-command-line": { - "version": "4.7.10", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.7.10.tgz", - "integrity": "sha512-8t042g8eerypNOEcdpxwRA3uCmz0duMo21rG4Z2mdz7JxJeylDmzjlU3wDdef2t3P1Z61JCdZB6fbm1Mh0zi7w==", + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.8.0.tgz", + "integrity": "sha512-nZ8cbzVF1VmFPfSJfy8vEohdiFAH/59Y/Y+B4nsJbn4SkifLJ8LqNZ5+LxCC2UR242EXFumxlsY1d6fPBxck5Q==", "requires": { "@types/argparse": "1.0.38", "argparse": "~1.0.9", @@ -760,9 +844,9 @@ "integrity": "sha512-/aPsuoj/1Dw/kzhkgz+ES6TxG0zfTMGLwuK2ZG00k/iJzYHTLCE8mVU8EPqEOp/lmxPoq1C1C9RYToRKb2KEfg==" }, "@sinonjs/commons": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.2.tgz", - "integrity": "sha512-sruwd86RJHdsVf/AtBoijDmUqJp3B6hF/DGC23C+JaegnDHaZyewCjoVGTdg3J0uz3Zs7NnIT05OBOmML72lQw==", + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", + "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", "requires": { "type-detect": "4.0.8" } @@ -791,9 +875,9 @@ "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==" }, "@sosuisen/api-documenter": { - "version": "7.13.25", - "resolved": "https://registry.npmjs.org/@sosuisen/api-documenter/-/api-documenter-7.13.25.tgz", - "integrity": "sha512-/BW6yDpP9DJGUtD/KD42DQR+Od7Gje1gAnrpwotwpEGhqCzAPyzZiV5z/1eegZfWbnmvtrPSbsCAtVkAhXmLZA==", + "version": "7.13.27", + "resolved": "https://registry.npmjs.org/@sosuisen/api-documenter/-/api-documenter-7.13.27.tgz", + "integrity": "sha512-Y3uEwBRSbxEvlLXRD/YcaRhsVNVWMDRLE/EOVDAUzPYy5FrdXiNK0GZNdmxrjCe2E58W/bGKUTZnw9sOI2YOZg==", "requires": { "@microsoft/api-extractor-model": "^7.13.3", "@microsoft/tsdoc": "^0.13.2", @@ -802,25 +886,6 @@ "colors": "~1.2.1", "js-yaml": "~3.13.1", "resolve": "~1.17.0" - }, - "dependencies": { - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "requires": { - "path-parse": "^1.0.6" - } - } } }, "@sosuisen/jsondiffpatch": { @@ -830,93 +895,6 @@ "requires": { "chalk": "^2.3.0", "diff-match-patch": "^1.0.0" - }, - "dependencies": { - "ansi-styles": { - "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==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@sosuisen/nodegit": { - "version": "0.27.3", - "resolved": "https://registry.npmjs.org/@sosuisen/nodegit/-/nodegit-0.27.3.tgz", - "integrity": "sha512-0/SSdtXK+grdpbhJP116MtkyHWA1yJ+Tnnzsj5OEPj/bC5s9Losc52p8WKiDn1uKeJcN5F5Zg+VOx4vkBKD4dg==", - "requires": { - "fs-extra": "^7.0.0", - "got": "^10.7.0", - "json5": "^2.1.0", - "lodash": "^4.17.14", - "nan": "^2.14.0", - "node-gyp": "^4.0.0", - "node-pre-gyp": "^0.13.0", - "ramda": "^0.25.0", - "tar-fs": "^1.16.3" - }, - "dependencies": { - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" - } } }, "@szmarczak/http-timer": { @@ -927,33 +905,54 @@ "defer-to-connect": "^2.0.0" } }, + "@tsconfig/node10": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", + "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==" + }, + "@tsconfig/node12": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", + "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==" + }, + "@tsconfig/node14": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", + "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==" + }, + "@tsconfig/node16": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", + "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==" + }, "@types/argparse": { "version": "1.0.38", "resolved": "https://registry.npmjs.org/@types/argparse/-/argparse-1.0.38.tgz", "integrity": "sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==" }, "@types/async-lock": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@types/async-lock/-/async-lock-1.1.2.tgz", - "integrity": "sha512-j9n4bb6RhgFIydBe0+kpjnBPYumDaDyU8zvbWykyVMkku+c2CSu31MZkLeaBfqIwU+XCxlDpYDfyMQRkM0AkeQ==" + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@types/async-lock/-/async-lock-1.1.3.tgz", + "integrity": "sha512-UpeDcjGKsYEQMeqEbfESm8OWJI305I7b9KE4ji3aBjoKWyN5CTdn8izcA1FM1DVDne30R5fNEnIy89vZw5LXJQ==" }, "@types/cacheable-request": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.1.tgz", - "integrity": "sha512-ykFq2zmBGOCbpIXtoVbz4SKY5QriWPh3AjyU4G74RYbtt5yOc5OfaY75ftjg7mikMOla1CTGpX3lLbuJh8DTrQ==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", + "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", "requires": { "@types/http-cache-semantics": "*", "@types/keyv": "*", "@types/node": "*", "@types/responselike": "*" + }, + "dependencies": { + "@types/node": { + "version": "16.3.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.3.1.tgz", + "integrity": "sha512-N87VuQi7HEeRJkhzovao/JviiqKjDKMVKxKMfUvSKw+MbkbW8R0nA3fi/MQhhlxV2fQ+2ReM+/Nt4efdrJx3zA==" + } } }, - "@types/eslint-visitor-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", - "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==", - "optional": true - }, "@types/expect": { "version": "24.3.0", "resolved": "https://registry.npmjs.org/@types/expect/-/expect-24.3.0.tgz", @@ -963,26 +962,26 @@ } }, "@types/fs-extra": { - "version": "9.0.6", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.6.tgz", - "integrity": "sha512-ecNRHw4clCkowNOBJH1e77nvbPxHYnWIXMv1IAoG/9+MYGkgoyr3Ppxr7XYFNL41V422EDhyV4/4SSK8L2mlig==", + "version": "9.0.12", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.12.tgz", + "integrity": "sha512-I+bsBr67CurCGnSenZZ7v94gd3tc3+Aj2taxMT4yu4ABLuOgOjeFxX3dokG24ztSRg5tnT00sL8BszO7gSMoIw==", "requires": { "@types/node": "*" } }, "@types/glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==", + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-w+LsMxKyYQm347Otw+IfBXOv9UWVjpHpCDdbBMt8Kz/xbvCYNjP+0qPh91Km3iKfSRLBB0P7fAMf0KHrPu+MyA==", "requires": { "@types/minimatch": "*", "@types/node": "*" } }, "@types/http-cache-semantics": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.0.tgz", - "integrity": "sha512-c3Xy026kOF7QOTn00hbIllV1dLR9hG9NkSrLQgCVs8NF6sBU+VGWjD3wLPhmh1TYAc7ugCFsvHYMN4VcBN1U1A==" + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", + "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==" }, "@types/istanbul-lib-coverage": { "version": "2.0.3", @@ -1006,48 +1005,50 @@ } }, "@types/json-schema": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz", - "integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==", + "version": "7.0.8", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.8.tgz", + "integrity": "sha512-YSBPTLTVm2e2OoQIDYx8HaeWJ5tTToLH67kXR7zYNGupXMEHa2++G8k+DczX2cFVgalypqtyZIcU19AFcmOpmg==", "optional": true }, - "@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=" - }, "@types/keyv": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.1.tgz", - "integrity": "sha512-MPtoySlAZQ37VoLaPcTHCu1RWJ4llDkULYZIzOYxlhxBqYPB0RsRlmMU0R6tahtFe27mIdkHV+551ZWV4PLmVw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.2.tgz", + "integrity": "sha512-/FvAK2p4jQOaJ6CGDHJTqZcUtbZe820qIeTg7o0Shg7drB4JHeL+V/dhSaly7NXx6u8eSee+r7coT+yuJEvDLg==", "requires": { "@types/node": "*" + }, + "dependencies": { + "@types/node": { + "version": "16.3.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.3.1.tgz", + "integrity": "sha512-N87VuQi7HEeRJkhzovao/JviiqKjDKMVKxKMfUvSKw+MbkbW8R0nA3fi/MQhhlxV2fQ+2ReM+/Nt4efdrJx3zA==" + } } }, "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==" + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==" }, "@types/mocha": { - "version": "8.2.2", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.2.tgz", - "integrity": "sha512-Lwh0lzzqT5Pqh6z61P3c3P5nm6fzQK/MMHl9UKeneAeInVflBSz1O2EkX6gM6xfJd7FBXBY5purtLx7fUiZ7Hw==" + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.3.tgz", + "integrity": "sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw==" }, "@types/node": { - "version": "14.14.20", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.20.tgz", - "integrity": "sha512-Y93R97Ouif9JEOWPIUyU+eyIdyRqQR0I8Ez1dzku4hDx34NWh4HbtIc3WNzwB1Y9ULvNGeu5B8h8bVL5cAk4/A==" + "version": "14.17.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.5.tgz", + "integrity": "sha512-bjqH2cX/O33jXT/UmReo2pM7DIJREPMnarixbQ57DOOzzFaI6D2+IcwaJQaJpv0M1E9TIhPCYVxrkcityLjlqA==" }, "@types/normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==" + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", + "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==" }, "@types/parse-git-config": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-git-config/-/parse-git-config-3.0.0.tgz", - "integrity": "sha512-5C14/81ohSwjB5I0EweuG3qyn6CqgVOgk9orxHDwVvUdDbS4FMXANXnKz3CA3H2Jk2oa3vzMEpXtDQ5u0dCcTQ==" + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/parse-git-config/-/parse-git-config-3.0.1.tgz", + "integrity": "sha512-cBVLXlpIpP23p+jQm8d2TrTfxyub3aiqfqgd0TWRnMqwCJMskYiveNJT11YwN+gbo3+0ZFFmtaepKzN7pxExlA==" }, "@types/parse-json": { "version": "4.0.0", @@ -1060,12 +1061,19 @@ "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", "requires": { "@types/node": "*" + }, + "dependencies": { + "@types/node": { + "version": "16.3.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.3.1.tgz", + "integrity": "sha512-N87VuQi7HEeRJkhzovao/JviiqKjDKMVKxKMfUvSKw+MbkbW8R0nA3fi/MQhhlxV2fQ+2ReM+/Nt4efdrJx3zA==" + } } }, "@types/rimraf": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-3.0.0.tgz", - "integrity": "sha512-7WhJ0MdpFgYQPXlF4Dx+DhgvlPCfz/x5mHaeDQAKhcenvQP1KCpLQ18JklAqeGMYSAT2PxLpzd0g2/HE7fj7hQ==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-3.0.1.tgz", + "integrity": "sha512-CAoSlbco40aKZ0CkelBF2g3JeN6aioRaTVnqSX5pWsn/WApm6IDxI4e4tD9D0dY/meCkyyleP1IQDVN13F4maA==", "requires": { "@types/glob": "*", "@types/node": "*" @@ -1080,40 +1088,41 @@ } }, "@types/sinonjs__fake-timers": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.2.tgz", - "integrity": "sha512-dIPoZ3g5gcx9zZEszaxLSVTvMReD3xxyyDnQUjA6IYDG9Ba2AV0otMPs+77sG9ojB4Qr2N2Vk5RnKeuA0X/0bg==" + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.3.tgz", + "integrity": "sha512-E1dU4fzC9wN2QK2Cr1MLCfyHM8BoNnRFvuf45LYMPNDA+WqbNzC45S4UzPxvp1fFJ1rvSGU0bPvdd35VLmXG8g==" }, "@types/stack-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", - "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==" }, "@types/unist": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz", - "integrity": "sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==" + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.5.tgz", + "integrity": "sha512-wnra4Vw9dopnuybR6HBywJ/URYpYrKLoepBTEtgfJup8Ahoi2zJECPP2cwiXp7btTvOT2CULv87aQRA4eZSP6g==" }, "@types/yargs": { - "version": "16.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.3.tgz", - "integrity": "sha512-YlFfTGS+zqCgXuXNV26rOIeETOkXnGQXP/pjjL9P0gO/EP9jTmc7pUBhx+jVEIxpq41RX33GQ7N3DzOSfZoglQ==", + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", "requires": { "@types/yargs-parser": "*" } }, "@types/yargs-parser": { - "version": "20.2.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.0.tgz", - "integrity": "sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==" + "version": "20.2.1", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", + "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==" }, "@typescript-eslint/eslint-plugin": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.28.0.tgz", - "integrity": "sha512-KcF6p3zWhf1f8xO84tuBailV5cN92vhS+VT7UJsPzGBm9VnQqfI9AsiMUFUCYHTYPg1uCCo+HyiDnpDuvkAMfQ==", + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.28.2.tgz", + "integrity": "sha512-PGqpLLzHSxq956rzNGasO3GsAPf2lY9lDUBXhS++SKonglUmJypaUtcKzRtUte8CV7nruwnDxtLUKpVxs0wQBw==", + "optional": true, "requires": { - "@typescript-eslint/experimental-utils": "4.28.0", - "@typescript-eslint/scope-manager": "4.28.0", + "@typescript-eslint/experimental-utils": "4.28.2", + "@typescript-eslint/scope-manager": "4.28.2", "debug": "^4.3.1", "functional-red-black-tree": "^1.0.1", "regexpp": "^3.1.0", @@ -1121,173 +1130,99 @@ "tsutils": "^3.21.0" }, "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.28.0.tgz", - "integrity": "sha512-eCALCeScs5P/EYjwo6se9bdjtrh8ByWjtHzOkC4Tia6QQWtQr3PHovxh3TdYTuFcurkYI4rmFsRFpucADIkseg==", + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "optional": true, "requires": { - "@typescript-eslint/types": "4.28.0", - "@typescript-eslint/visitor-keys": "4.28.0" + "ms": "2.1.2" } }, - "@typescript-eslint/types": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.28.0.tgz", - "integrity": "sha512-p16xMNKKoiJCVZY5PW/AfILw2xe1LfruTcfAKBj3a+wgNYP5I9ZEKNDOItoRt53p4EiPV6iRSICy8EPanG9ZVA==" - }, - "@typescript-eslint/visitor-keys": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.0.tgz", - "integrity": "sha512-PjJyTWwrlrvM5jazxYF5ZPs/nl0kHDZMVbuIcbpawVXaDPelp3+S9zpOz5RmVUfS/fD5l5+ZXNKnWhNYjPzCvw==", - "requires": { - "@typescript-eslint/types": "4.28.0", - "eslint-visitor-keys": "^2.0.0" - } + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "optional": true }, "semver": { "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "optional": true, "requires": { "lru-cache": "^6.0.0" } - }, - "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "requires": { - "tslib": "^1.8.1" - } } } }, "@typescript-eslint/experimental-utils": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.28.0.tgz", - "integrity": "sha512-9XD9s7mt3QWMk82GoyUpc/Ji03vz4T5AYlHF9DcoFNfJ/y3UAclRsfGiE2gLfXtyC+JRA3trR7cR296TEb1oiQ==", + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.28.2.tgz", + "integrity": "sha512-MwHPsL6qo98RC55IoWWP8/opTykjTp4JzfPu1VfO2Z0MshNP0UZ1GEV5rYSSnZSUI8VD7iHvtIPVGW5Nfh7klQ==", + "optional": true, "requires": { "@types/json-schema": "^7.0.7", - "@typescript-eslint/scope-manager": "4.28.0", - "@typescript-eslint/types": "4.28.0", - "@typescript-eslint/typescript-estree": "4.28.0", + "@typescript-eslint/scope-manager": "4.28.2", + "@typescript-eslint/types": "4.28.2", + "@typescript-eslint/typescript-estree": "4.28.2", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0" + } + }, + "@typescript-eslint/parser": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.28.2.tgz", + "integrity": "sha512-Q0gSCN51eikAgFGY+gnd5p9bhhCUAl0ERMiDKrTzpSoMYRubdB8MJrTTR/BBii8z+iFwz8oihxd0RAdP4l8w8w==", + "optional": true, + "requires": { + "@typescript-eslint/scope-manager": "4.28.2", + "@typescript-eslint/types": "4.28.2", + "@typescript-eslint/typescript-estree": "4.28.2", + "debug": "^4.3.1" }, "dependencies": { - "@types/json-schema": { - "version": "7.0.7", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", - "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==" - }, - "@typescript-eslint/scope-manager": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.28.0.tgz", - "integrity": "sha512-eCALCeScs5P/EYjwo6se9bdjtrh8ByWjtHzOkC4Tia6QQWtQr3PHovxh3TdYTuFcurkYI4rmFsRFpucADIkseg==", - "requires": { - "@typescript-eslint/types": "4.28.0", - "@typescript-eslint/visitor-keys": "4.28.0" - } - }, - "@typescript-eslint/types": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.28.0.tgz", - "integrity": "sha512-p16xMNKKoiJCVZY5PW/AfILw2xe1LfruTcfAKBj3a+wgNYP5I9ZEKNDOItoRt53p4EiPV6iRSICy8EPanG9ZVA==" - }, - "@typescript-eslint/typescript-estree": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.0.tgz", - "integrity": "sha512-m19UQTRtxMzKAm8QxfKpvh6OwQSXaW1CdZPoCaQuLwAq7VZMNuhJmZR4g5281s2ECt658sldnJfdpSZZaxUGMQ==", - "requires": { - "@typescript-eslint/types": "4.28.0", - "@typescript-eslint/visitor-keys": "4.28.0", - "debug": "^4.3.1", - "globby": "^11.0.3", - "is-glob": "^4.0.1", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.0.tgz", - "integrity": "sha512-PjJyTWwrlrvM5jazxYF5ZPs/nl0kHDZMVbuIcbpawVXaDPelp3+S9zpOz5RmVUfS/fD5l5+ZXNKnWhNYjPzCvw==", - "requires": { - "@typescript-eslint/types": "4.28.0", - "eslint-visitor-keys": "^2.0.0" - } - }, - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "requires": { - "eslint-visitor-keys": "^2.0.0" - } - }, - "globby": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", - "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" - } - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "optional": true, "requires": { - "lru-cache": "^6.0.0" + "ms": "2.1.2" } }, - "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "requires": { - "tslib": "^1.8.1" - } + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "optional": true } } }, - "@typescript-eslint/parser": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.28.0.tgz", - "integrity": "sha512-7x4D22oPY8fDaOCvkuXtYYTQ6mTMmkivwEzS+7iml9F9VkHGbbZ3x4fHRwxAb5KeuSkLqfnYjs46tGx2Nour4A==", - "requires": { - "@typescript-eslint/scope-manager": "4.28.0", - "@typescript-eslint/types": "4.28.0", - "@typescript-eslint/typescript-estree": "4.28.0", - "debug": "^4.3.1" - } - }, "@typescript-eslint/scope-manager": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.28.0.tgz", - "integrity": "sha512-eCALCeScs5P/EYjwo6se9bdjtrh8ByWjtHzOkC4Tia6QQWtQr3PHovxh3TdYTuFcurkYI4rmFsRFpucADIkseg==", + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.28.2.tgz", + "integrity": "sha512-MqbypNjIkJFEFuOwPWNDjq0nqXAKZvDNNs9yNseoGBB1wYfz1G0WHC2AVOy4XD7di3KCcW3+nhZyN6zruqmp2A==", + "optional": true, "requires": { - "@typescript-eslint/types": "4.28.0", - "@typescript-eslint/visitor-keys": "4.28.0" + "@typescript-eslint/types": "4.28.2", + "@typescript-eslint/visitor-keys": "4.28.2" } }, "@typescript-eslint/types": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.28.0.tgz", - "integrity": "sha512-p16xMNKKoiJCVZY5PW/AfILw2xe1LfruTcfAKBj3a+wgNYP5I9ZEKNDOItoRt53p4EiPV6iRSICy8EPanG9ZVA==" + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.28.2.tgz", + "integrity": "sha512-Gr15fuQVd93uD9zzxbApz3wf7ua3yk4ZujABZlZhaxxKY8ojo448u7XTm/+ETpy0V0dlMtj6t4VdDvdc0JmUhA==", + "optional": true }, "@typescript-eslint/typescript-estree": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.0.tgz", - "integrity": "sha512-m19UQTRtxMzKAm8QxfKpvh6OwQSXaW1CdZPoCaQuLwAq7VZMNuhJmZR4g5281s2ECt658sldnJfdpSZZaxUGMQ==", + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.2.tgz", + "integrity": "sha512-86lLstLvK6QjNZjMoYUBMMsULFw0hPHJlk1fzhAVoNjDBuPVxiwvGuPQq3fsBMCxuDJwmX87tM/AXoadhHRljg==", + "optional": true, "requires": { - "@typescript-eslint/types": "4.28.0", - "@typescript-eslint/visitor-keys": "4.28.0", + "@typescript-eslint/types": "4.28.2", + "@typescript-eslint/visitor-keys": "4.28.2", "debug": "^4.3.1", "globby": "^11.0.3", "is-glob": "^4.0.1", @@ -1295,30 +1230,39 @@ "tsutils": "^3.21.0" }, "dependencies": { + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "optional": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "optional": true + }, "semver": { "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "optional": true, "requires": { "lru-cache": "^6.0.0" } - }, - "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "requires": { - "tslib": "^1.8.1" - } } } }, "@typescript-eslint/visitor-keys": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.0.tgz", - "integrity": "sha512-PjJyTWwrlrvM5jazxYF5ZPs/nl0kHDZMVbuIcbpawVXaDPelp3+S9zpOz5RmVUfS/fD5l5+ZXNKnWhNYjPzCvw==", + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.2.tgz", + "integrity": "sha512-aT2B4PLyyRDUVUafXzpZFoc0C9t0za4BJAKP5sgWIhG+jHECQZUEjuQSCIwZdiJJ4w4cgu5r3Kh20SOdtEBl0w==", + "optional": true, "requires": { - "@typescript-eslint/types": "4.28.0", + "@typescript-eslint/types": "4.28.2", "eslint-visitor-keys": "^2.0.0" } }, @@ -1338,9 +1282,9 @@ "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" }, "acorn-jsx": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", - "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==" + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==" }, "aggregate-error": { "version": "3.1.0", @@ -1385,22 +1329,22 @@ "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==" }, "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" }, "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "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==", "requires": { - "color-convert": "^2.0.1" + "color-convert": "^1.9.0" } }, "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -1447,14 +1391,14 @@ } }, "array-includes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.2.tgz", - "integrity": "sha512-w2GspexNQpx+PutG3QpT437/BenZBj0M/MZGn5mzv/MofYqo0xmRHzn4lFsoDlWJ+THYsGJmFlW68WlDFx7VRw==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", + "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==", "requires": { - "call-bind": "^1.0.0", + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1", - "get-intrinsic": "^1.0.1", + "es-abstract": "^1.18.0-next.2", + "get-intrinsic": "^1.1.1", "is-string": "^1.0.5" } }, @@ -1527,35 +1471,15 @@ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" }, - "babel-eslint": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", - "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==", - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.0", - "@babel/traverse": "^7.7.0", - "@babel/types": "^7.7.0", - "eslint-visitor-keys": "^1.0.0", - "resolve": "^1.12.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==" - } - } - }, "bail": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==" }, "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "bcrypt-pbkdf": { "version": "1.0.2", @@ -1566,9 +1490,9 @@ } }, "before-after-hook": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.0.tgz", - "integrity": "sha512-jH6rKQIfroBbhEXVmI7XmXe3ix5S/PgJqpzdDPnR8JGLHWNYLsYZ6tK5iWOF/Ra3oqEX0NobXGlzbiylIzVphQ==" + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz", + "integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ==" }, "binary-extensions": { "version": "2.2.0", @@ -1585,9 +1509,9 @@ } }, "blob-polyfill": { - "version": "4.0.20200601", - "resolved": "https://registry.npmjs.org/blob-polyfill/-/blob-polyfill-4.0.20200601.tgz", - "integrity": "sha512-1jB6WOIp6IDxNyng5+9A8g/f0uiphib2ELCN+XAnlssinsW8s1k4VYG9b1TxIUd3pdm9RJSLQuBh6iohYmD4hA==" + "version": "5.0.20210201", + "resolved": "https://registry.npmjs.org/blob-polyfill/-/blob-polyfill-5.0.20210201.tgz", + "integrity": "sha512-SrH6IG6aXL9pCgSysBCiDpGcAJ1j6/c1qCwR3sTEQJhb+MTk6FITNA6eW6WNYQDNZVi4Z9GjxH5v2MMTv59CrQ==" }, "brace-expansion": { "version": "1.1.11", @@ -1611,6 +1535,18 @@ "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" }, + "browserslist": { + "version": "4.16.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", + "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", + "requires": { + "caniuse-lite": "^1.0.30001219", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.723", + "escalade": "^3.1.1", + "node-releases": "^1.1.71" + } + }, "buffer-alloc": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", @@ -1645,27 +1581,17 @@ } }, "cacheable-request": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.1.tgz", - "integrity": "sha512-lt0mJ6YAnsrBErpTMWeu5kl/tg9xMAWjavYTN6VQXM1A/teBITuNcccXsCxF0tDQQJf9DfAaX5O4e0zp0KlfZw==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", + "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", "requires": { "clone-response": "^1.0.2", "get-stream": "^5.1.0", "http-cache-semantics": "^4.0.0", "keyv": "^4.0.0", "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", + "normalize-url": "^6.0.1", "responselike": "^2.0.0" - }, - "dependencies": { - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "requires": { - "pump": "^3.0.0" - } - } } }, "caching-transform": { @@ -1680,12 +1606,12 @@ } }, "call-bind": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.0.tgz", - "integrity": "sha512-AEXsYIyyDY3MCzbwdhzG3Jx1R0J2wetQyUynn6dYHAO+bg8l1k7jwZtRv4ryryFs7EP+NDlikJlVe59jr0cM2w==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", "requires": { "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.0" + "get-intrinsic": "^1.0.2" } }, "callsites": { @@ -1694,9 +1620,14 @@ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" }, "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==" + }, + "caniuse-lite": { + "version": "1.0.30001243", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001243.tgz", + "integrity": "sha512-vNxw9mkTBtkmLFnJRv/2rhs1yufpDfCkBZexG3Y0xdOH2Z/eE/85E4Dl5j1YUN34nZVsSp6vVRFQRrez9wJMRA==" }, "caseless": { "version": "0.12.0", @@ -1704,12 +1635,13 @@ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" }, "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, "character-entities": { @@ -1789,13 +1721,43 @@ "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==" }, "cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "requires": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" + "wrap-ansi": "^7.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + } + } } }, "clone-response": { @@ -1824,17 +1786,22 @@ "integrity": "sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==" }, "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "requires": { - "color-name": "~1.1.4" + "color-name": "1.1.3" } }, "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "colorette": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==" }, "colors": { "version": "1.2.5", @@ -1880,9 +1847,9 @@ "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=" }, "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", "requires": { "safe-buffer": "~5.1.1" } @@ -1902,12 +1869,25 @@ "parse-json": "^5.0.0", "path-type": "^4.0.0", "yaml": "^1.10.0" + }, + "dependencies": { + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + } } }, "coveralls": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.1.0.tgz", - "integrity": "sha512-sHxOu2ELzW8/NC1UP5XVLbZDzO4S3VxfFye3XYCznopHy02YjNkHcj5bKaVw2O7hVaBdBjEdQGpie4II1mWhuQ==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.1.1.tgz", + "integrity": "sha512-+dxnG2NHncSD1NrqbSM3dn/lE57O6Qf/koe9+I7c+wzkqRmEvcp0kgJdxKInzYzkICKkFMZsX3Vct3++tsF9ww==", "requires": { "js-yaml": "^3.13.1", "lcov-parse": "^1.0.0", @@ -1940,12 +1920,12 @@ } }, "cross-blob": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/cross-blob/-/cross-blob-2.0.0.tgz", - "integrity": "sha512-NWzFuyG4GTZnM9MtQvjPYVlO12lZCSBdoHIHCZl9WKShsK3CqO+bEH7nuKwlVomlByb37XvT6nVY5uQxDBmk5Q==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/cross-blob/-/cross-blob-2.0.1.tgz", + "integrity": "sha512-ARuKPPo3I6DSqizal4UCyMCiGPQdMpMJS3Owx6Lleuh26vSt2UnfWRwbMLCYqbJUrcol+KzGVSLR91ezSHP80A==", "requires": { - "blob-polyfill": "^4.0.20200601", - "fetch-blob": "^2.0.1" + "blob-polyfill": "^5.0.20210201", + "fetch-blob": "^2.1.2" } }, "cross-env": { @@ -1954,42 +1934,24 @@ "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", "requires": { "cross-spawn": "^7.0.1" + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" }, "dependencies": { - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "requires": { - "isexe": "^2.0.0" + "isexe": "^2.0.0" } } } @@ -2008,17 +1970,17 @@ "integrity": "sha512-hpA5C/YrPjucXypHPPc0oJ1l9Hf6wWbiOL7Ik42cxnsUOhWiCB/fylKbKqqJalW9FgkNQCw16YO8uW9Hs0Iy1A==" }, "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "requires": { - "ms": "2.1.2" + "ms": "^2.1.1" } }, "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==" }, "decompress-response": { "version": "5.0.0", @@ -2054,12 +2016,19 @@ "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==", "requires": { "strip-bom": "^4.0.0" + }, + "dependencies": { + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" + } } }, "defer-to-connect": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.0.tgz", - "integrity": "sha512-bYL2d05vOSf1JEZNx5vSAtPuBMkX8K9EUutg7zlKvTqKXHt7RhWJFbmd7qakVuf13i+IkGmp6FwSsONOf6VYIg==" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==" }, "define-properties": { "version": "1.1.3", @@ -2105,9 +2074,9 @@ "integrity": "sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==" }, "diff-sequences": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.1.tgz", - "integrity": "sha512-XPLijkfJUh/PIBnfkcSHgvD6tlYixmcMAn3osTk6jt+H0v/mgURto1XUiD9DKuGX5NDoVS6dSlA23gd9FUaCFg==" + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz", + "integrity": "sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==" }, "diff3": { "version": "0.0.3", @@ -2164,6 +2133,11 @@ "yallist": "^2.1.2" } }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", @@ -2176,6 +2150,11 @@ "resolved": "https://registry.npmjs.org/editorconfig-to-prettier/-/editorconfig-to-prettier-0.1.1.tgz", "integrity": "sha512-MMadSSVRDb4uKdxV6bCXXN4cTsxIsXYtV4XdPu6FOCSAw6zsCIDA+QEktEU+u6h+c/mTrul5NR+pwFpPxwetiQ==" }, + "electron-to-chromium": { + "version": "1.3.772", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.772.tgz", + "integrity": "sha512-X/6VRCXWALzdX+RjCtBU6cyg8WZgoxm9YA02COmDOiNJEZ59WkQggDbWZ4t/giHi/3GS+cvdrP6gbLISANAGYA==" + }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -2206,22 +2185,26 @@ } }, "es-abstract": { - "version": "1.18.0-next.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", - "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz", + "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==", "requires": { + "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-negative-zero": "^2.0.0", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", + "has-symbols": "^1.0.2", + "is-callable": "^1.2.3", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.3", + "is-string": "^1.0.6", + "object-inspect": "^1.10.3", "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" } }, "es-to-primitive": { @@ -2250,28 +2233,31 @@ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "eslint": { - "version": "7.17.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.17.0.tgz", - "integrity": "sha512-zJk08MiBgwuGoxes5sSQhOtibZ75pz0J35XTRlZOk9xMffhpA9BTbQZxoXZzOl5zMbleShbGwtw+1kGferfFwQ==", + "version": "7.30.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.30.0.tgz", + "integrity": "sha512-VLqz80i3as3NdloY44BQSJpFw534L9Oh+6zJOUaViV4JPd+DaHwutqP7tcpkW3YiXbK6s05RZl7yl7cQn+lijg==", "requires": { - "@babel/code-frame": "^7.0.0", - "@eslint/eslintrc": "^0.2.2", + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.2", + "@humanwhocodes/config-array": "^0.5.0", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.0.1", "doctrine": "^3.0.0", "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", "eslint-scope": "^5.1.1", "eslint-utils": "^2.1.0", "eslint-visitor-keys": "^2.0.0", "espree": "^7.3.1", - "esquery": "^1.2.0", + "esquery": "^1.4.0", "esutils": "^2.0.2", - "file-entry-cache": "^6.0.0", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^12.1.0", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", "ignore": "^4.0.6", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", @@ -2279,7 +2265,7 @@ "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", - "lodash": "^4.17.19", + "lodash.merge": "^4.6.2", "minimatch": "^3.0.4", "natural-compare": "^1.4.0", "optionator": "^0.9.1", @@ -2288,101 +2274,124 @@ "semver": "^7.2.1", "strip-ansi": "^6.0.0", "strip-json-comments": "^3.1.0", - "table": "^6.0.4", + "table": "^6.0.9", "text-table": "^0.2.0", "v8-compile-cache": "^2.0.3" }, "dependencies": { - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "@babel/highlight": "^7.10.4" } }, - "globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "requires": { - "type-fest": "^0.8.1" + "color-convert": "^2.0.1" } }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" + "color-name": "~1.1.4" } }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "ms": "2.1.2" } }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "requires": { + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==" + } + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "semver": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", - "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "requires": { "lru-cache": "^6.0.0" } }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "requires": { - "shebang-regex": "^3.0.0" + "ansi-regex": "^5.0.0" } }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "requires": { - "prelude-ls": "^1.2.1" - } + "strip-json-comments": { + "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==" }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "requires": { - "isexe": "^2.0.0" + "has-flag": "^4.0.0" } } } @@ -2405,116 +2414,27 @@ } }, "eslint-config-standard": { - "version": "14.1.1", - "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-14.1.1.tgz", - "integrity": "sha512-Z9B+VR+JIXRxz21udPTL9HpFMyoMUEeX1G251EQ6e05WD9aPVtVBn09XUmZ259wCMlCDmYDSZG62Hhm+ZTJcUg==" + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-16.0.3.tgz", + "integrity": "sha512-x4fmJL5hGqNJKGHSjnLdgA6U6h1YW/G2dW9fA+cyVur4SK6lyue8+UgNKWlZtUDTXvgKDD/Oa3GQjmB5kjtVvg==" }, "eslint-config-standardize": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/eslint-config-standardize/-/eslint-config-standardize-0.7.1.tgz", - "integrity": "sha512-8tut4nppZ+kpOHPa/AG8Wzr/HAEmNGnJXrGa10dCBKmNGaBsXtLkYL1hb1s80EGyw1JchIyHOpy/z9vHWeqAeQ==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/eslint-config-standardize/-/eslint-config-standardize-0.7.2.tgz", + "integrity": "sha512-n2dt7la221Qig7FjQsrKn5NyK5jSEkkAy7xWSnY96XdG7H9FcUSDt5I1THyA6zHwEYcAtUFv8VOPBOK6oYEvfg==", "requires": { "@jsbits/deep-clone": "~1.1.1", - "@typescript-eslint/eslint-plugin": "~3.9.0", - "@typescript-eslint/parser": "~3.9.0", + "@typescript-eslint/eslint-plugin": "^4.14.0", + "@typescript-eslint/parser": "^4.14.0", "confusing-browser-globals": "*", "deepmerge": "~4.2.2", - "eslint-config-standard": "~14.1.1", - "eslint-plugin-import": "~2.22.0", + "eslint-config-standard": "~16.0.2", + "eslint-plugin-import": "~2.22.1", "eslint-plugin-node": "~11.1.0", "eslint-plugin-promise": "~4.2.1", - "eslint-plugin-react": "~7.20.5", - "eslint-plugin-react-hooks": "~4.0.8", - "eslint-plugin-standard": "~4.0.1", - "eslint-plugin-unicorn": "~21.0.0" - }, - "dependencies": { - "@typescript-eslint/eslint-plugin": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.9.1.tgz", - "integrity": "sha512-XIr+Mfv7i4paEdBf0JFdIl9/tVxyj+rlilWIfZ97Be0lZ7hPvUbS5iHt9Glc8kRI53dsr0PcAEudbf8rO2wGgg==", - "optional": true, - "requires": { - "@typescript-eslint/experimental-utils": "3.9.1", - "debug": "^4.1.1", - "functional-red-black-tree": "^1.0.1", - "regexpp": "^3.0.0", - "semver": "^7.3.2", - "tsutils": "^3.17.1" - } - }, - "@typescript-eslint/experimental-utils": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-3.9.1.tgz", - "integrity": "sha512-lkiZ8iBBaYoyEKhCkkw4SAeatXyBq9Ece5bZXdLe1LWBUwTszGbmbiqmQbwWA8cSYDnjWXp9eDbXpf9Sn0hLAg==", - "optional": true, - "requires": { - "@types/json-schema": "^7.0.3", - "@typescript-eslint/types": "3.9.1", - "@typescript-eslint/typescript-estree": "3.9.1", - "eslint-scope": "^5.0.0", - "eslint-utils": "^2.0.0" - } - }, - "@typescript-eslint/parser": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-3.9.1.tgz", - "integrity": "sha512-y5QvPFUn4Vl4qM40lI+pNWhTcOWtpZAJ8pOEQ21fTTW4xTJkRplMjMRje7LYTXqVKKX9GJhcyweMz2+W1J5bMg==", - "optional": true, - "requires": { - "@types/eslint-visitor-keys": "^1.0.0", - "@typescript-eslint/experimental-utils": "3.9.1", - "@typescript-eslint/types": "3.9.1", - "@typescript-eslint/typescript-estree": "3.9.1", - "eslint-visitor-keys": "^1.1.0" - } - }, - "@typescript-eslint/types": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-3.9.1.tgz", - "integrity": "sha512-15JcTlNQE1BsYy5NBhctnEhEoctjXOjOK+Q+rk8ugC+WXU9rAcS2BYhoh6X4rOaXJEpIYDl+p7ix+A5U0BqPTw==", - "optional": true - }, - "@typescript-eslint/typescript-estree": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-3.9.1.tgz", - "integrity": "sha512-IqM0gfGxOmIKPhiHW/iyAEXwSVqMmR2wJ9uXHNdFpqVvPaQ3dWg302vW127sBpAiqM9SfHhyS40NKLsoMpN2KA==", - "optional": true, - "requires": { - "@typescript-eslint/types": "3.9.1", - "@typescript-eslint/visitor-keys": "3.9.1", - "debug": "^4.1.1", - "glob": "^7.1.6", - "is-glob": "^4.0.1", - "lodash": "^4.17.15", - "semver": "^7.3.2", - "tsutils": "^3.17.1" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-3.9.1.tgz", - "integrity": "sha512-zxdtUjeoSh+prCpogswMwVUJfEFmCOjdzK9rpNjNBfm6EyPt99x3RrJoBOGZO23FCt0WPKUCOL5mb/9D5LjdwQ==", - "optional": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - } - }, - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "optional": true - }, - "semver": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", - "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", - "optional": true, - "requires": { - "lru-cache": "^6.0.0" - } - } + "eslint-plugin-react": "~7.22.0", + "eslint-plugin-react-hooks": "~4.2.0", + "eslint-plugin-unicorn": "~26.0.1" } }, "eslint-import-resolver-node": { @@ -2542,78 +2462,12 @@ } }, "eslint-module-utils": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz", - "integrity": "sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.1.tgz", + "integrity": "sha512-ZXI9B8cxAJIH4nfkhTwcRTEAnrVfobYqwjWy/QMCZ8rHkZHFjf9yO4BzpiF9kCSfNlMG54eKigISHpX0+AaT4A==", "requires": { - "debug": "^2.6.9", + "debug": "^3.2.7", "pkg-dir": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" - }, - "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "requires": { - "find-up": "^2.1.0" - } - } } }, "eslint-plugin-es": { @@ -2623,6 +2477,21 @@ "requires": { "eslint-utils": "^2.0.0", "regexpp": "^3.0.0" + }, + "dependencies": { + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==" + } } }, "eslint-plugin-import": { @@ -2662,80 +2531,10 @@ "isarray": "^1.0.0" } }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" - }, - "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", - "requires": { - "pify": "^2.0.0" - } - }, - "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", - "requires": { - "load-json-file": "^2.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" - } - }, - "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" - } } } }, @@ -2752,6 +2551,19 @@ "semver": "^6.1.0" }, "dependencies": { + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==" + }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -2775,20 +2587,20 @@ "integrity": "sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw==" }, "eslint-plugin-react": { - "version": "7.20.6", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.20.6.tgz", - "integrity": "sha512-kidMTE5HAEBSLu23CUDvj8dc3LdBU0ri1scwHBZjI41oDv4tjsWZKU7MQccFzH1QYPYhsnTF2ovh7JlcIcmxgg==", + "version": "7.22.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.22.0.tgz", + "integrity": "sha512-p30tuX3VS+NWv9nQot9xIGAHBXR0+xJVaZriEsHoJrASGCJZDJ8JLNM0YqKqI0AKm6Uxaa1VUHoNEibxRCMQHA==", "requires": { "array-includes": "^3.1.1", "array.prototype.flatmap": "^1.2.3", "doctrine": "^2.1.0", "has": "^1.0.3", - "jsx-ast-utils": "^2.4.1", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", "object.entries": "^1.1.2", "object.fromentries": "^2.0.2", "object.values": "^1.1.1", "prop-types": "^15.7.2", - "resolve": "^1.17.0", + "resolve": "^1.18.1", "string.prototype.matchall": "^4.0.2" }, "dependencies": { @@ -2797,56 +2609,152 @@ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "requires": { - "esutils": "^2.0.2" + "esutils": "^2.0.2" + } + }, + "resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + } + } + }, + "eslint-plugin-react-hooks": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.2.0.tgz", + "integrity": "sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ==" + }, + "eslint-plugin-unicorn": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-26.0.1.tgz", + "integrity": "sha512-SWgF9sIVY74zqkkSN2dclSCqRfocWSUGD0haC0NX2oRfmdp9p8dQvJYkYSQePaCyssPUE/pqpsIEEZNTh8crUA==", + "requires": { + "ci-info": "^2.0.0", + "clean-regexp": "^1.0.0", + "eslint-ast-utils": "^1.1.0", + "eslint-template-visitor": "^2.2.2", + "eslint-utils": "^2.1.0", + "import-modules": "^2.1.0", + "lodash": "^4.17.20", + "pluralize": "^8.0.0", + "read-pkg-up": "^7.0.1", + "regexp-tree": "^0.1.21", + "reserved-words": "^0.1.2", + "safe-regex": "^2.1.1", + "semver": "^7.3.4" + }, + "dependencies": { + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==" + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==" + } } - } - } - }, - "eslint-plugin-react-hooks": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.0.8.tgz", - "integrity": "sha512-6SSb5AiMCPd8FDJrzah+Z4F44P2CdOaK026cXFV+o/xSRzfOiV1FNFeLl2z6xm3yqWOQEZ5OfVgiec90qV2xrQ==" - }, - "eslint-plugin-standard": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-4.0.2.tgz", - "integrity": "sha512-nKptN8l7jksXkwFk++PhJB3cCDTcXOEyhISIN86Ue2feJ1LFyY3PrY3/xT2keXlJSY5bpmbiTG0f885/YKAvTA==" - }, - "eslint-plugin-unicorn": { - "version": "21.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-21.0.0.tgz", - "integrity": "sha512-S8v7+v4gZTQPj4pKKvexhgSUaLQSyItvxW2SVZDaX9Iu5IjlAmF2eni+L6w8a2aqshxgU8Lle4FIAVDtuejSKQ==", - "requires": { - "ci-info": "^2.0.0", - "clean-regexp": "^1.0.0", - "eslint-ast-utils": "^1.1.0", - "eslint-template-visitor": "^2.0.0", - "eslint-utils": "^2.1.0", - "import-modules": "^2.0.0", - "lodash": "^4.17.15", - "pluralize": "^8.0.0", - "read-pkg-up": "^7.0.1", - "regexp-tree": "^0.1.21", - "reserved-words": "^0.1.2", - "safe-regex": "^2.1.1", - "semver": "^7.3.2" - }, - "dependencies": { - "safe-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz", - "integrity": "sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==", + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", "requires": { - "regexp-tree": "~0.1.1" + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" } }, "semver": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", - "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "requires": { "lru-cache": "^6.0.0" } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" } } }, @@ -2860,35 +2768,30 @@ } }, "eslint-template-visitor": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/eslint-template-visitor/-/eslint-template-visitor-2.2.2.tgz", - "integrity": "sha512-SkcLjzKw3JjKTWHacRDeLBa2gxb600zbCKTkXj/V97QnZ9yxkknoPL8vc8PFueqbFXP7mYNTQzjCjcMpTRdRaA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/eslint-template-visitor/-/eslint-template-visitor-2.3.2.tgz", + "integrity": "sha512-3ydhqFpuV7x1M9EK52BPNj6V0Kwu0KKkcIAfpUhwHbR8ocRln/oUHgfxQupY8O1h4Qv/POHDumb/BwwNfxbtnA==", "requires": { - "babel-eslint": "^10.1.0", + "@babel/core": "^7.12.16", + "@babel/eslint-parser": "^7.12.16", "eslint-visitor-keys": "^2.0.0", "esquery": "^1.3.1", "multimap": "^1.1.0" } }, "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "optional": true, "requires": { - "eslint-visitor-keys": "^1.1.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==" - } + "eslint-visitor-keys": "^2.0.0" } }, "eslint-visitor-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", - "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==" }, "espree": { "version": "7.3.1", @@ -2913,9 +2816,9 @@ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" }, "esquery": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", - "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", "requires": { "estraverse": "^5.1.0" }, @@ -2958,16 +2861,16 @@ "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==" }, "expect": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.0.2.tgz", - "integrity": "sha512-YJFNJe2+P2DqH+ZrXy+ydRQYO87oxRUonZImpDodR1G7qo3NYd3pL+NQ9Keqpez3cehczYwZDBC3A7xk3n7M/w==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.0.6.tgz", + "integrity": "sha512-psNLt8j2kwg42jGBDSfAlU49CEZxejN1f1PlANWDZqIhBOVU/c2Pm888FcjWJzFewhIsNWfZJeLjUjtKGiPuSw==", "requires": { - "@jest/types": "^27.0.2", + "@jest/types": "^27.0.6", "ansi-styles": "^5.0.0", - "jest-get-type": "^27.0.1", - "jest-matcher-utils": "^27.0.2", - "jest-message-util": "^27.0.2", - "jest-regex-util": "^27.0.1" + "jest-get-type": "^27.0.6", + "jest-matcher-utils": "^27.0.6", + "jest-message-util": "^27.0.6", + "jest-regex-util": "^27.0.6" }, "dependencies": { "ansi-styles": { @@ -2998,16 +2901,16 @@ "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==" }, "fast-glob": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", - "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", + "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", + "optional": true, "requires": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.0", + "glob-parent": "^5.1.2", "merge2": "^1.3.0", - "micromatch": "^4.0.2", - "picomatch": "^2.2.1" + "micromatch": "^4.0.4" } }, "fast-json-stable-stringify": { @@ -3021,9 +2924,9 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" }, "fastq": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.10.0.tgz", - "integrity": "sha512-NL2Qc5L3iQEsyYzweq7qfgy5OtXCmGzGvhElGEd/SoFWEMOEczNh5s5ocaF01HDetxz+p8ecjNPA6cZxxIHmzA==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.1.tgz", + "integrity": "sha512-HOnr8Mc60eNYl1gzwp6r5RoUyAn5/glBolUzP/Ez6IFVPMPirxn/9phgL6zhOtaTy7ISwPvQ+wT+hfcRZh/bzw==", "requires": { "reusify": "^1.0.4" } @@ -3034,9 +2937,9 @@ "integrity": "sha512-YKqtUDwqLyfyMnmbw8XD6Q8j9i/HggKtPEI+pZ1+8bvheBu78biSmNaXWusx1TauGqtUUGx/cBb1mKdq2rLYow==" }, "file-entry-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.0.tgz", - "integrity": "sha512-fqoO76jZ3ZnYrXLDRxBR1YvOvc0k844kcOg40bgsPrE25LAb/PDqTY+ho64Xh2c8ZXgIKldchCFHczG2UVRcWA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "requires": { "flat-cache": "^3.0.4" } @@ -3057,6 +2960,59 @@ "commondir": "^1.0.1", "make-dir": "^3.0.2", "pkg-dir": "^4.1.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "requires": { + "find-up": "^4.0.0" + } + } } }, "find-parent-dir": { @@ -3070,12 +3026,11 @@ "integrity": "sha1-0kJyei2QRyXfVxTyPf3N7doLbvg=" }, "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "locate-path": "^2.0.0" } }, "flat": { @@ -3093,9 +3048,9 @@ } }, "flatted": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.0.tgz", - "integrity": "sha512-tW+UkmtNg/jv9CSofAKvgVcO7c2URjhTdW1ZTkcAritblu8tajiYy7YisnIflEwtKssCtOxpnBRoCB7iap0/TA==" + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.1.tgz", + "integrity": "sha512-OMQjaErSFHmHqZe+PSidH5n8j3O0F2DdnVh8JB4j4eUQ2k6KvB0qGfrKIhapvez5JerBbmWkaLYUYWISaESoXg==" }, "flatten": { "version": "1.0.3", @@ -3109,44 +3064,6 @@ "requires": { "cross-spawn": "^7.0.0", "signal-exit": "^3.0.2" - }, - "dependencies": { - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "requires": { - "isexe": "^2.0.0" - } - } } }, "forever-agent": { @@ -3183,6 +3100,22 @@ "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" + }, + "dependencies": { + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" + } } }, "fs-minipass": { @@ -3221,39 +3154,6 @@ "string-width": "^1.0.1", "strip-ansi": "^3.0.1", "wide-align": "^1.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "^2.0.0" - } - } } }, "gensync": { @@ -3267,9 +3167,9 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" }, "get-intrinsic": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.0.2.tgz", - "integrity": "sha512-aeX0vrFm21ILl3+JpFFRNe9aUvp6VFZb2/CTbgLb8j75kOhvoNYjt9d8KA/tJG4gSo8nzEDedRl0h7vDmBYRVg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", "requires": { "function-bind": "^1.1.1", "has": "^1.0.3", @@ -3286,6 +3186,14 @@ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==" }, + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "requires": { + "pump": "^3.0.0" + } + }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -3299,10 +3207,25 @@ "resolved": "https://registry.npmjs.org/git-config-path/-/git-config-path-2.0.0.tgz", "integrity": "sha512-qc8h1KIQbJpp+241id3GuAtkdyJ+IK+LIVtkiFTRKRrmddDzs3SI9CvP1QYmWBFvm1I/PWRwj//of8bgAc0ltA==" }, + "git-documentdb-plugin-remote-nodegit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.0.tgz", + "integrity": "sha512-fZLcid1l2aMZ1aGHJC3/H0tDY3wrpK1R2YjuHGODlRsxJmupFUa/+63P+4qUepHc+HcmuHP3n8ucbxamlGQThQ==", + "requires": { + "git-documentdb-remote-errors": "^1.0.3", + "nodegit": "^0.27.0", + "tslog": "^3.2.0" + } + }, + "git-documentdb-remote-errors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/git-documentdb-remote-errors/-/git-documentdb-remote-errors-1.0.3.tgz", + "integrity": "sha512-14fN8VAQeBC7+Phs6TYB1D5PJDE/dF8dxbigKpsBEqR1FvpAQerSPptxVsQgkU33xwwZBOm7yCwVD2KKmQatOQ==" + }, "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -3313,22 +3236,33 @@ } }, "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "requires": { "is-glob": "^4.0.1" } }, "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + "version": "13.10.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.10.0.tgz", + "integrity": "sha512-piHC3blgLGFjvOuMmWZX60f+na1lXFDhQXBf1UYp2fXPXqvEUbOhNwi6BsQ0bQishwedgnjkwv1d9zKf+MWw3g==", + "requires": { + "type-fest": "^0.20.2" + }, + "dependencies": { + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==" + } + } }, "globby": { "version": "11.0.4", "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", + "optional": true, "requires": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -3381,27 +3315,12 @@ "responselike": "^2.0.0", "to-readable-stream": "^2.0.0", "type-fest": "^0.10.0" - }, - "dependencies": { - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "requires": { - "pump": "^3.0.0" - } - }, - "type-fest": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.10.0.tgz", - "integrity": "sha512-EUV9jo4sffrwlg8s0zDhP0T2WD3pru5Xi0+HTE3zTUmBaZNhfkite9PdSJwdXLwPVW0jnAHT56pZHIOYckPEiw==" - } } }, "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" }, "graphql": { "version": "15.3.0", @@ -3414,9 +3333,9 @@ "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==" }, "handlebars": { - "version": "4.7.6", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.6.tgz", - "integrity": "sha512-1f2BACcBfiwAfStCKZNrUCgqNZkGsAT7UM3kkYtXuLo0KnaVfjKOyf7PRzB6++aK9STyT1Pd2ZCPe3EGOXleXA==", + "version": "4.7.7", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", + "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", "requires": { "minimist": "^1.2.5", "neo-async": "^2.6.0", @@ -3447,15 +3366,20 @@ "function-bind": "^1.1.1" } }, + "has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==" + }, "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" }, "has-unicode": { "version": "2.0.1", @@ -3471,10 +3395,10 @@ "type-fest": "^0.8.0" }, "dependencies": { - "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" } } }, @@ -3484,9 +3408,9 @@ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" }, "hosted-git-info": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", - "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==" + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==" }, "html-element-attributes": { "version": "2.2.1", @@ -3537,9 +3461,9 @@ "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==" }, "ignore-walk": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz", - "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.4.tgz", + "integrity": "sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ==", "requires": { "minimatch": "^3.0.4" } @@ -3551,13 +3475,6 @@ "requires": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" - } } }, "import-lazy": { @@ -3605,33 +3522,13 @@ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" }, "internal-slot": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.2.tgz", - "integrity": "sha512-2cQNfwhAfJIkU4KZPkDI+Gj5yNNnbqi40W9Gge6dfnk4TocEVm00B3bdiL+JINrbGJil2TeHvM4rETGzk/f/0g==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", "requires": { - "es-abstract": "^1.17.0-next.1", + "get-intrinsic": "^1.1.0", "has": "^1.0.3", - "side-channel": "^1.0.2" - }, - "dependencies": { - "es-abstract": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", - "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - } + "side-channel": "^1.0.4" } }, "is-alphabetical": { @@ -3653,6 +3550,11 @@ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" }, + "is-bigint": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz", + "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==" + }, "is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -3661,23 +3563,36 @@ "binary-extensions": "^2.0.0" } }, + "is-boolean-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz", + "integrity": "sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng==", + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==" + }, "is-callable": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", - "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==" + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==" }, "is-core-module": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", - "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", + "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", "requires": { "has": "^1.0.3" } }, "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==" + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz", + "integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==" }, "is-decimal": { "version": "1.0.4", @@ -3690,9 +3605,12 @@ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" }, "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } }, "is-glob": { "version": "4.0.1", @@ -3717,30 +3635,46 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" }, + "is-number-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz", + "integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==" + }, "is-plain-obj": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==" }, + "is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==" + }, "is-regex": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", - "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", + "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", "requires": { - "has-symbols": "^1.0.1" + "call-bind": "^1.0.2", + "has-symbols": "^1.0.2" } }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" + }, "is-string": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", - "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==" + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz", + "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==" }, "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", "requires": { - "has-symbols": "^1.0.1" + "has-symbols": "^1.0.2" } }, "is-typedarray": { @@ -3774,9 +3708,9 @@ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, "isomorphic-git": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/isomorphic-git/-/isomorphic-git-1.8.2.tgz", - "integrity": "sha512-wp3on2Kks1sE/tLUmGLPV7EEAj+JRK8WoL2ZSfJHVQfWzRqMRv96bqzDjyYpC6COGKlDQnhTNCucRf83S3cuMw==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/isomorphic-git/-/isomorphic-git-1.9.1.tgz", + "integrity": "sha512-vzceJaiBdaJI5aT1di4dxWWf6sao3WQFQJ6UTi1tXO4zyDfsuyIadVOA4YQzdwKhLilV9msgM8HIvpOE94kmQg==", "requires": { "async-lock": "^1.1.0", "clean-git-ref": "^2.0.1", @@ -3791,11 +3725,6 @@ "simple-get": "^3.0.2" }, "dependencies": { - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" - }, "readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", @@ -3846,59 +3775,16 @@ }, "istanbul-lib-processinfo": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz", - "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==", - "requires": { - "archy": "^1.0.0", - "cross-spawn": "^7.0.0", - "istanbul-lib-coverage": "^3.0.0-alpha.1", - "make-dir": "^3.0.0", - "p-map": "^3.0.0", - "rimraf": "^3.0.0", - "uuid": "^3.3.3" - }, - "dependencies": { - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "requires": { - "isexe": "^2.0.0" - } - } + "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz", + "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==", + "requires": { + "archy": "^1.0.0", + "cross-spawn": "^7.0.0", + "istanbul-lib-coverage": "^3.0.0-alpha.1", + "make-dir": "^3.0.0", + "p-map": "^3.0.0", + "rimraf": "^3.0.0", + "uuid": "^3.3.3" } }, "istanbul-lib-report": { @@ -3909,6 +3795,21 @@ "istanbul-lib-coverage": "^3.0.0", "make-dir": "^3.0.0", "supports-color": "^7.1.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } } }, "istanbul-lib-source-maps": { @@ -3919,6 +3820,21 @@ "debug": "^4.1.1", "istanbul-lib-coverage": "^3.0.0", "source-map": "^0.6.1" + }, + "dependencies": { + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } } }, "istanbul-reports": { @@ -3931,14 +3847,59 @@ } }, "jest-diff": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.0.2.tgz", - "integrity": "sha512-BFIdRb0LqfV1hBt8crQmw6gGQHVDhM87SpMIZ45FPYKReZYG5er1+5pIn2zKqvrJp6WNox0ylR8571Iwk2Dmgw==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.0.6.tgz", + "integrity": "sha512-Z1mqgkTCSYaFgwTlP/NUiRzdqgxmmhzHY1Tq17zL94morOHfHu3K4bgSgl+CR4GLhpV8VxkuOYuIWnQ9LnFqmg==", "requires": { "chalk": "^4.0.0", - "diff-sequences": "^27.0.1", - "jest-get-type": "^27.0.1", - "pretty-format": "^27.0.2" + "diff-sequences": "^27.0.6", + "jest-get-type": "^27.0.6", + "pretty-format": "^27.0.6" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } } }, "jest-docblock": { @@ -3950,126 +3911,131 @@ } }, "jest-get-type": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.1.tgz", - "integrity": "sha512-9Tggo9zZbu0sHKebiAijyt1NM77Z0uO4tuWOxUCujAiSeXv30Vb5D4xVF4UR4YWNapcftj+PbByU54lKD7/xMg==" + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", + "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==" }, "jest-matcher-utils": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.0.2.tgz", - "integrity": "sha512-Qczi5xnTNjkhcIB0Yy75Txt+Ez51xdhOxsukN7awzq2auZQGPHcQrJ623PZj0ECDEMOk2soxWx05EXdXGd1CbA==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.0.6.tgz", + "integrity": "sha512-OFgF2VCQx9vdPSYTHWJ9MzFCehs20TsyFi6bIHbk5V1u52zJOnvF0Y/65z3GLZHKRuTgVPY4Z6LVePNahaQ+tA==", "requires": { "chalk": "^4.0.0", - "jest-diff": "^27.0.2", - "jest-get-type": "^27.0.1", - "pretty-format": "^27.0.2" + "jest-diff": "^27.0.6", + "jest-get-type": "^27.0.6", + "pretty-format": "^27.0.6" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } } }, "jest-message-util": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.0.2.tgz", - "integrity": "sha512-rTqWUX42ec2LdMkoUPOzrEd1Tcm+R1KfLOmFK+OVNo4MnLsEaxO5zPDb2BbdSmthdM/IfXxOZU60P/WbWF8BTw==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.0.6.tgz", + "integrity": "sha512-rBxIs2XK7rGy+zGxgi+UJKP6WqQ+KrBbD1YMj517HYN3v2BG66t3Xan3FWqYHKZwjdB700KiAJ+iES9a0M+ixw==", "requires": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.0.2", + "@jest/types": "^27.0.6", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.4", - "pretty-format": "^27.0.2", + "pretty-format": "^27.0.6", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, "dependencies": { - "@babel/code-frame": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", - "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", - "requires": { - "@babel/highlight": "^7.14.5" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", - "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==" - }, - "@babel/highlight": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", - "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "requires": { - "@babel/helper-validator-identifier": "^7.14.5", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - } + "color-convert": "^2.0.1" } }, - "ansi-styles": { - "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==", + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "requires": { - "color-convert": "^1.9.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "requires": { - "color-name": "1.1.3" + "color-name": "~1.1.4" } }, "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - } - }, - "picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "requires": { - "has-flag": "^3.0.0" + "has-flag": "^4.0.0" } } } }, "jest-regex-util": { - "version": "27.0.1", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.0.1.tgz", - "integrity": "sha512-6nY6QVcpTgEKQy1L41P4pr3aOddneK17kn3HJw6SdwGiKfgCGTvH02hVXL0GU8GEKtPH83eD2DIDgxHXOxVohQ==" + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.0.6.tgz", + "integrity": "sha512-SUhPzBsGa1IKm8hx2F4NfTGGp+r7BXJ4CulsZ1k2kI+mGLG+lxGrs76veN2LF/aUdGosJBzKgXmNCw+BzFqBDQ==" }, "jju": { "version": "1.4.0", @@ -4082,9 +4048,9 @@ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", "requires": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -4139,20 +4105,19 @@ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, "json5": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", - "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", "requires": { "minimist": "^1.2.5" } }, "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" + "graceful-fs": "^4.1.6" } }, "jsonify": { @@ -4172,12 +4137,12 @@ } }, "jsx-ast-utils": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.4.1.tgz", - "integrity": "sha512-z1xSldJ6imESSzOjd3NNkieVJKRlKYSOtMG8SFyCj2FIrvSaSuli/WjpBkEzCBoR9bYYYFgqJw61Xhu7Lcgk+w==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz", + "integrity": "sha512-EIsmt3O3ljsU6sot/J4E1zDRxfBNrhjyf/OKjlydwgEimQuznlM4Wv7U+ueONJMyEn1WRE0K8dhi3dVAXYT24Q==", "requires": { - "array-includes": "^3.1.1", - "object.assign": "^4.1.0" + "array-includes": "^3.1.2", + "object.assign": "^4.1.2" } }, "just-extend": { @@ -4203,6 +4168,15 @@ "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==" }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, "lines-and-columns": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", @@ -4224,33 +4198,31 @@ "strip-bom": "^3.0.0" }, "dependencies": { - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "requires": { - "error-ex": "^1.2.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" } } }, "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", "requires": { - "p-locate": "^4.1.0" + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" } }, "lodash": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" }, "lodash.flattendeep": { "version": "4.4.0", @@ -4267,6 +4239,16 @@ "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" + }, + "lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=" + }, "lodash.zip": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.zip/-/lodash.zip-4.2.0.tgz", @@ -4283,6 +4265,51 @@ "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", "requires": { "chalk": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } } }, "loose-envify": { @@ -4304,6 +4331,13 @@ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "requires": { "yallist": "^4.0.0" + }, + "dependencies": { + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } } }, "make-dir": { @@ -4346,13 +4380,6 @@ "requires": { "map-age-cleaner": "^0.1.3", "mimic-fn": "^3.0.0" - }, - "dependencies": { - "mimic-fn": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz", - "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==" - } } }, "merge2": { @@ -4361,27 +4388,32 @@ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" }, "micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", "requires": { "braces": "^3.0.1", - "picomatch": "^2.0.5" + "picomatch": "^2.2.3" } }, "mime-db": { - "version": "1.45.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz", - "integrity": "sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==" + "version": "1.48.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz", + "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==" }, "mime-types": { - "version": "2.1.28", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.28.tgz", - "integrity": "sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ==", + "version": "2.1.31", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz", + "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==", "requires": { - "mime-db": "1.45.0" + "mime-db": "1.48.0" } }, + "mimic-fn": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz", + "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==" + }, "mimic-response": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", @@ -4415,13 +4447,6 @@ "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" - }, - "dependencies": { - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - } } }, "minizlib": { @@ -4432,10 +4457,18 @@ "minipass": "^2.9.0" } }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "requires": { + "minimist": "^1.2.5" + } + }, "mocha": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.3.2.tgz", - "integrity": "sha512-UdmISwr/5w+uXLPKspgoV7/RXZwKRTiTjJ2/AC5ZiEztIoOYdfKb19+9jNmEInzx5pBsCyJQzarAxqIGBNYJhg==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.4.0.tgz", + "integrity": "sha512-hJaO0mwDXmZS4ghXsvPVriOhsxQ7ofcpQdm8dE+jISUOKopitvnXFQmpRR7jd2K6VBG6E26gU3IAbXXGIbu4sQ==", "requires": { "@ungap/promise-all-settled": "1.1.2", "ansi-colors": "4.1.1", @@ -4469,14 +4502,19 @@ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" + "ms": "2.1.2" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } } }, "diff": { @@ -4498,6 +4536,24 @@ "path-exists": "^4.0.0" } }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "requires": { + "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" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, "js-yaml": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", @@ -4514,11 +4570,6 @@ "p-locate": "^5.0.0" } }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, "p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -4535,6 +4586,16 @@ "p-limit": "^3.0.2" } }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "strip-json-comments": { + "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==" + }, "supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -4550,47 +4611,13 @@ "requires": { "isexe": "^2.0.0" } - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "y18n": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", - "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==" - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - }, - "yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==" } } }, "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "multimap": { "version": "1.1.0", @@ -4618,23 +4645,13 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" }, "needle": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/needle/-/needle-2.6.0.tgz", - "integrity": "sha512-KKYdza4heMsEfSWD7VPUIz3zX2XDwOyX2d+geb4vrERZMT5RMU6ujjaD+I5Yr54uZxQ2w6XRTAhHBbSCyovZBg==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-2.8.0.tgz", + "integrity": "sha512-ZTq6WYkN/3782H1393me3utVYdq2XyqNUFBsprEE3VMAT0+hP/cItpnITpqsY6ep2yeFE4Tqtqwc74VqUlUYtw==", "requires": { "debug": "^3.2.6", "iconv-lite": "^0.4.4", "sax": "^1.2.4" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "requires": { - "ms": "^2.1.1" - } - } } }, "neo-async": { @@ -4677,14 +4694,6 @@ "which": "1" }, "dependencies": { - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "requires": { - "minimist": "^1.2.5" - } - }, "rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -4692,11 +4701,6 @@ "requires": { "glob": "^7.1.3" } - }, - "semver": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", - "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" } } }, @@ -4717,14 +4721,6 @@ "tar": "^4" }, "dependencies": { - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "requires": { - "minimist": "^1.2.5" - } - }, "nopt": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", @@ -4739,19 +4735,52 @@ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "requires": { - "glob": "^7.1.3" + "glob": "^7.1.3" + } + } + } + }, + "node-preload": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", + "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", + "requires": { + "process-on-spawn": "^1.0.0" + } + }, + "node-releases": { + "version": "1.1.73", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz", + "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==" + }, + "nodegit": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/nodegit/-/nodegit-0.27.0.tgz", + "integrity": "sha512-E9K4gPjWiA0b3Tx5lfWCzG7Cvodi2idl3V5UD2fZrOrHikIfrN7Fc2kWLtMUqqomyoToYJLeIC8IV7xb1CYRLA==", + "requires": { + "fs-extra": "^7.0.0", + "got": "^10.7.0", + "json5": "^2.1.0", + "lodash": "^4.17.14", + "nan": "^2.14.0", + "node-gyp": "^4.0.0", + "node-pre-gyp": "^0.13.0", + "ramda": "^0.25.0", + "tar-fs": "^1.16.3" + }, + "dependencies": { + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" } } } }, - "node-preload": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", - "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", - "requires": { - "process-on-spawn": "^1.0.0" - } - }, "nopt": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", @@ -4777,14 +4806,14 @@ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" }, "normalize-url": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", - "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==" + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==" }, "npm-bundled": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.1.tgz", - "integrity": "sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.2.tgz", + "integrity": "sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ==", "requires": { "npm-normalize-package-bin": "^1.0.1" } @@ -4852,6 +4881,167 @@ "spawn-wrap": "^2.0.0", "test-exclude": "^6.0.0", "yargs": "^15.0.2" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" + }, + "yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.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": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } } }, "oauth-sign": { @@ -4865,9 +5055,9 @@ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, "object-inspect": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", - "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==" + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz", + "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==" }, "object-keys": { "version": "1.1.1", @@ -4886,36 +5076,34 @@ } }, "object.entries": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.3.tgz", - "integrity": "sha512-ym7h7OZebNS96hn5IJeyUmaWhaSM4SVtAPPfNLQEI2MYWCO2egsITb9nab2+i/Pwibx+R0mtn+ltKJXRSeTMGg==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.4.tgz", + "integrity": "sha512-h4LWKWE+wKQGhtMjZEBud7uLGhqyLwj8fpHOarZhD2uY3C9cRtk57VQ89ke3moByLXMedqs3XCHzyb4AmA2DjA==", "requires": { - "call-bind": "^1.0.0", + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1", - "has": "^1.0.3" + "es-abstract": "^1.18.2" } }, "object.fromentries": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.3.tgz", - "integrity": "sha512-IDUSMXs6LOSJBWE++L0lzIbSqHl9KDCfff2x/JSEIDtEUavUnyMYC2ZGay/04Zq4UT8lvd4xNhU4/YHKibAOlw==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.4.tgz", + "integrity": "sha512-EsFBshs5RUUpQEY1D4q/m59kMfz4YJvxuNCJcv/jWwOJr34EaVnG11ZrZa0UHB3wnzV1wx8m58T4hQL8IuNXlQ==", "requires": { - "call-bind": "^1.0.0", + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1", + "es-abstract": "^1.18.0-next.2", "has": "^1.0.3" } }, "object.values": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.2.tgz", - "integrity": "sha512-MYC0jvJopr8EK6dPBiO8Nb9mvjdypOachO5REGk6MXzujbBrAisKo3HmdEI6kZDL6fC31Mwee/5YbtMebixeag==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.4.tgz", + "integrity": "sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg==", "requires": { - "call-bind": "^1.0.0", + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1", - "has": "^1.0.3" + "es-abstract": "^1.18.2" } }, "once": { @@ -4926,6 +5114,19 @@ "wrappy": "1" } }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, "os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", @@ -4969,9 +5170,9 @@ } }, "p-cancelable": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.0.0.tgz", - "integrity": "sha512-wvPXDmbMmu2ksjkB4Z3nZWTSkJEb9lqVdMaCKpZUGJG9TMiNp9XcbG3fn9fPKjem04fJMJnXoyFPk2FmgiaiNg==" + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==" }, "p-defer": { "version": "1.0.0", @@ -4992,19 +5193,19 @@ "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" }, "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", "requires": { - "p-try": "^2.0.0" + "p-try": "^1.0.0" } }, "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", "requires": { - "p-limit": "^2.2.0" + "p-limit": "^1.1.0" } }, "p-map": { @@ -5024,9 +5225,9 @@ } }, "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" }, "package-hash": { "version": "4.0.0", @@ -5075,30 +5276,32 @@ } }, "parse-json": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.1.0.tgz", - "integrity": "sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" + "error-ex": "^1.2.0" } }, "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + }, "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "path-to-regexp": { "version": "1.8.0", @@ -5126,21 +5329,21 @@ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==" + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==" }, "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" }, "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", "requires": { - "find-up": "^4.0.0" + "find-up": "^2.1.0" } }, "please-upgrade-node": { @@ -5157,61 +5360,15 @@ "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==" }, "postcss": { - "version": "7.0.35", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", - "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", "requires": { "chalk": "^2.4.2", "source-map": "^0.6.1", "supports-color": "^6.1.0" }, "dependencies": { - "ansi-styles": { - "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==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, "supports-color": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", @@ -5263,6 +5420,11 @@ "uniq": "^1.0.1" } }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" + }, "prettier-linter-helpers": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", @@ -5336,6 +5498,14 @@ "yaml-unist-parser": "1.3.1" }, "dependencies": { + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "requires": { + "@babel/highlight": "^7.10.4" + } + }, "@babel/parser": { "version": "7.12.0", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.0.tgz", @@ -5355,10 +5525,48 @@ "tsutils": "^3.17.1" } }, - "camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==" + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "requires": { + "ms": "2.1.2" + } }, "escape-string-regexp": { "version": "4.0.0", @@ -5370,6 +5578,19 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==" }, + "fast-glob": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", + "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" + } + }, "get-stream": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.0.tgz", @@ -5395,11 +5616,40 @@ } } }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, "ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "resolve": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "requires": { + "is-core-module": "^2.1.0", + "path-parse": "^1.0.6" + } + }, "semver": { "version": "7.3.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", @@ -5407,20 +5657,51 @@ "requires": { "lru-cache": "^6.0.0" } + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } } } }, "pretty-format": { - "version": "27.0.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.2.tgz", - "integrity": "sha512-mXKbbBPnYTG7Yra9qFBtqj+IXcsvxsvOBco3QHxtxTl+hHKq6QdzMZ+q0CtL4ORHZgwGImRr2XZUX2EWzORxig==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.6.tgz", + "integrity": "sha512-8tGD7gBIENgzqA+UBzObyWqQ5B778VIFZA/S66cclyd5YkFLYs2Js7gxDKf0MXtTc9zcS7t1xhdfcElJ3YIvkQ==", "requires": { - "@jest/types": "^27.0.2", + "@jest/types": "^27.0.6", "ansi-regex": "^5.0.0", "ansi-styles": "^5.0.0", "react-is": "^17.0.1" }, "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, "ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", @@ -5497,6 +5778,11 @@ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" + }, "ramda": { "version": "0.25.0", "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.25.0.tgz", @@ -5519,13 +5805,6 @@ "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" - } } }, "react-is": { @@ -5534,31 +5813,37 @@ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" }, "read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" }, "dependencies": { - "type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==" + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "requires": { + "pify": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" } } }, "read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", "requires": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" } }, "readable-stream": { @@ -5584,9 +5869,9 @@ } }, "regexp-tree": { - "version": "0.1.21", - "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.21.tgz", - "integrity": "sha512-kUUXjX4AnqnR8KRTCrayAo9PzYMRKmVoGgaz2tBuz0MF3g1ZbGebmtW0yFHfFK9CmBjQKeYIgoL22pFLBJY7sw==" + "version": "0.1.23", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.23.tgz", + "integrity": "sha512-+7HWfb4Bvu8Rs2eQTUIpX9I/PlQkYOuTNbRpKLJlQpSgwSkzFYh+pUj0gtvglnOZLKB6YgnIgRuJ2/IlpL48qw==" }, "regexp-util": { "version": "1.2.2", @@ -5597,38 +5882,18 @@ } }, "regexp.prototype.flags": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz", - "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz", + "integrity": "sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA==", "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - }, - "dependencies": { - "es-abstract": { - "version": "1.17.7", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", - "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.2", - "is-regex": "^1.1.1", - "object-inspect": "^1.8.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.1", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - } + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" } }, "regexpp": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", - "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==" + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==" }, "release-zalgo": { "version": "1.0.0", @@ -5698,22 +5963,6 @@ "tough-cookie": "~2.5.0", "tunnel-agent": "^0.6.0", "uuid": "^3.3.2" - }, - "dependencies": { - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" - } } }, "require-directory": { @@ -5737,18 +5986,17 @@ "integrity": "sha1-AKCUD5jNUBrqqsMWQR2a3FKzGrE=" }, "resolve": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", - "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", "requires": { - "is-core-module": "^2.1.0", "path-parse": "^1.0.6" } }, "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" }, "responselike": { "version": "2.0.0", @@ -5772,15 +6020,26 @@ } }, "run-parallel": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.10.tgz", - "integrity": "sha512-zb/1OuZ6flOlH6tQyMPUrE3x3Ulxjlo9WIVXR4yVYi4H9UXQaeIsPbLn2R3O3vQCnDKkAl2qHiuocKKX4Tz/Sw==" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "requires": { + "queue-microtask": "^1.2.2" + } }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, + "safe-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz", + "integrity": "sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==", + "requires": { + "regexp-tree": "~0.1.1" + } + }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -5792,9 +6051,9 @@ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" }, "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" }, "semver-compare": { "version": "1.0.0", @@ -5823,6 +6082,19 @@ "safe-buffer": "^5.0.1" } }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + }, "side-channel": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", @@ -5869,9 +6141,9 @@ } }, "simple-html-tokenizer": { - "version": "0.5.10", - "resolved": "https://registry.npmjs.org/simple-html-tokenizer/-/simple-html-tokenizer-0.5.10.tgz", - "integrity": "sha512-1DHMUmvUOGuUZ9/+cX/+hOhWhRD5dEw6lodn8WuV+T+cQ31hhBcCu1dcDsNotowi4mMaNhrLyKoS+DtB81HdDA==" + "version": "0.5.11", + "resolved": "https://registry.npmjs.org/simple-html-tokenizer/-/simple-html-tokenizer-0.5.11.tgz", + "integrity": "sha512-C2WEK/Z3HoSFbYq8tI7ni3eOo/NneSPRoPpcM7WdLjFOArFuyXEjAoCdOC3DgMfRyziZQ1hCNR4mrNdWEvD0og==" }, "sinon": { "version": "10.0.0", @@ -5884,6 +6156,21 @@ "diff": "^4.0.2", "nise": "^4.1.0", "supports-color": "^7.1.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "requires": { + "has-flag": "^4.0.0" + } + } } }, "slash": { @@ -5899,6 +6186,34 @@ "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", "is-fullwidth-code-point": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + } } }, "source-map": { @@ -5962,9 +6277,9 @@ } }, "spdx-license-ids": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz", - "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==" + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz", + "integrity": "sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ==" }, "sprintf-js": { "version": "1.0.3", @@ -6018,44 +6333,45 @@ "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==" }, "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" } }, "string.prototype.matchall": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.3.tgz", - "integrity": "sha512-OBxYDA2ifZQ2e13cP82dWFMaCV9CGF8GzmN4fljBVw5O5wep0lu4gacm1OL6MjROoUnB8VbkWRThqkV2YFLNxw==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.5.tgz", + "integrity": "sha512-Z5ZaXO0svs0M2xd/6By3qpeKpLKd9mO4v4q3oMEQrk8Ck4xOD5d5XeBOOjGrmVZZ/AHB1S0CgG4N5r1G9N3E2Q==", "requires": { - "call-bind": "^1.0.0", + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1", - "has-symbols": "^1.0.1", - "internal-slot": "^1.0.2", - "regexp.prototype.flags": "^1.3.0", - "side-channel": "^1.0.3" + "es-abstract": "^1.18.2", + "get-intrinsic": "^1.1.1", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "regexp.prototype.flags": "^1.3.1", + "side-channel": "^1.0.4" } }, "string.prototype.trimend": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz", - "integrity": "sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", "requires": { - "call-bind": "^1.0.0", + "call-bind": "^1.0.2", "define-properties": "^1.1.3" } }, "string.prototype.trimstart": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz", - "integrity": "sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", "requires": { - "call-bind": "^1.0.0", + "call-bind": "^1.0.2", "define-properties": "^1.1.3" } }, @@ -6068,46 +6384,48 @@ } }, "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { - "ansi-regex": "^5.0.0" + "ansi-regex": "^2.0.0" } }, "strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" }, "strip-json-comments": { - "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==" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" }, "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "requires": { - "has-flag": "^4.0.0" + "has-flag": "^3.0.0" } }, "table": { - "version": "6.0.7", - "resolved": "https://registry.npmjs.org/table/-/table-6.0.7.tgz", - "integrity": "sha512-rxZevLGTUzWna/qBLObOe16kB2RTnnbhciwgPbMMlazz1yZGVEgnZK762xyVdVznhqxrfCeBMmMkgOOaPwjH7g==", + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz", + "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==", "requires": { - "ajv": "^7.0.2", - "lodash": "^4.17.20", + "ajv": "^8.0.1", + "lodash.clonedeep": "^4.5.0", + "lodash.truncate": "^4.4.2", "slice-ansi": "^4.0.0", - "string-width": "^4.2.0" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0" }, "dependencies": { "ajv": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-7.0.3.tgz", - "integrity": "sha512-R50QRlXSxqXcQP5SvKUrw8VZeypvo12i2IX0EeR5PiZ7bEKeHWgzgo264LDadUsCU42lTJVhFikTqJwNeH34gQ==", + "version": "8.6.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.1.tgz", + "integrity": "sha512-42VLtQUOLefAvKFAQIxIZDaThq6om/PrfP0CYk3/vn+y4BMNkKnbli8ON2QCiHov4KkzOSJ/xSoBJdayiiYvVQ==", "requires": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -6115,10 +6433,38 @@ "uri-js": "^4.2.2" } }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, "json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + } } } }, @@ -6134,21 +6480,6 @@ "mkdirp": "^0.5.0", "safe-buffer": "^5.1.2", "yallist": "^3.0.3" - }, - "dependencies": { - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "requires": { - "minimist": "^1.2.5" - } - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - } } }, "tar-fs": { @@ -6162,14 +6493,6 @@ "tar-stream": "^1.1.2" }, "dependencies": { - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "requires": { - "minimist": "^1.2.5" - } - }, "pump": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz", @@ -6238,6 +6561,15 @@ "is-number": "^7.0.0" } }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, "transform-file": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/transform-file/-/transform-file-1.0.1.tgz", @@ -6262,10 +6594,14 @@ "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==" }, "ts-node": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz", - "integrity": "sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.1.0.tgz", + "integrity": "sha512-6szn3+J9WyG2hE+5W8e0ruZrzyk1uFLYye6IGMBadnOzDh8aP7t8CbFpsfCiEx2+wMixAhjFt7lOZC4+l+WbEA==", "requires": { + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.1", "arg": "^4.1.0", "create-require": "^1.1.0", "diff": "^4.0.1", @@ -6275,29 +6611,13 @@ } }, "tsconfig-paths": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", - "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.10.1.tgz", + "integrity": "sha512-rETidPDgCpltxF7MjBZlAFPUHv5aHH2MymyPvh+vEyWAED4Eb/WeMbsnD/JDr4OKPOA1TssDHgIcpTN5Kh0p6Q==", "requires": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", + "json5": "^2.2.0", "minimist": "^1.2.0", "strip-bom": "^3.0.0" - }, - "dependencies": { - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "requires": { - "minimist": "^1.2.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" - } } }, "tslib": { @@ -6306,17 +6626,17 @@ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, "tslog": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/tslog/-/tslog-3.1.2.tgz", - "integrity": "sha512-sKhNPUMjf+POPxcWuGxinjilEjIzPCdehF/zIdp33ttv9ohIBWHMV9gpdGvJjWbZn09a5IqP1dmaYq56IPXZAg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/tslog/-/tslog-3.2.0.tgz", + "integrity": "sha512-xOCghepl5w+wcI4qXI7vJy6c53loF8OoC/EuKz1ktAPMtltEDz00yo1poKuyBYIQaq4ZDYKYFPD9PfqVrFXh0A==", "requires": { "source-map-support": "^0.5.19" } }, "tsutils": { - "version": "3.19.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.19.0.tgz", - "integrity": "sha512-A7BaLUPvcQ1cxVu72YfD+UMI3SQPTDv/w4ol6TOwLyI0hwfG9EC+cYlhdflJTmtYTgZ3KqdPSe/otxU4K3kArg==", + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", "requires": { "tslib": "^1.8.1" } @@ -6334,15 +6654,23 @@ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "requires": { + "prelude-ls": "^1.2.1" + } + }, "type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" }, "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.10.0.tgz", + "integrity": "sha512-EUV9jo4sffrwlg8s0zDhP0T2WD3pru5Xi0+HTE3zTUmBaZNhfkite9PdSJwdXLwPVW0jnAHT56pZHIOYckPEiw==" }, "typedarray-to-buffer": { "version": "3.1.5", @@ -6353,14 +6681,14 @@ } }, "typescript": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.4.tgz", - "integrity": "sha512-uauPG7XZn9F/mo+7MrsRjyvbxFpzemRjKEZXS4AK83oP2KKOJPvb+9cO/gmnv8arWZvhnjVOXz7B49m1l0e9Ew==" + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz", + "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==" }, "uglify-js": { - "version": "3.12.4", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.12.4.tgz", - "integrity": "sha512-L5i5jg/SHkEqzN18gQMTWsZk3KelRsfD1wUVNqtq0kzqWQqcJjyL8yc1o8hJgRrWqrAl2mUFbhfznEIoi7zi2A==", + "version": "3.13.10", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.10.tgz", + "integrity": "sha512-57H3ACYFXeo1IaZ1w02sfA71wI60MGco/IQFjOqK+WtKoprh7Go2/yvd2HPtoJILO2Or84ncLccI4xoHMTSbGg==", "optional": true }, "ulid": { @@ -6368,6 +6696,17 @@ "resolved": "https://registry.npmjs.org/ulid/-/ulid-2.3.0.tgz", "integrity": "sha512-keqHubrlpvT6G2wH0OEfSW4mquYRcbe/J8NMmveoQOjUqmo+hXtO+ORCpWhdbZ7k72UtY61BL7haGxW6enBnjw==" }, + "unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "requires": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + } + }, "unherit": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.3.tgz", @@ -6401,13 +6740,6 @@ "is-plain-obj": "^2.0.0", "trough": "^1.0.0", "vfile": "^4.0.0" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==" - } } }, "uniq": { @@ -6458,14 +6790,14 @@ "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==" }, "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" }, "uri-js": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", - "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "requires": { "punycode": "^2.1.0" } @@ -6475,10 +6807,15 @@ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + }, "v8-compile-cache": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz", - "integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==" + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==" }, "validate-npm-package-license": { "version": "3.0.4", @@ -6513,13 +6850,6 @@ "is-buffer": "^2.0.0", "unist-util-stringify-position": "^2.0.0", "vfile-message": "^2.0.0" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==" - } } }, "vfile-location": { @@ -6546,54 +6876,10 @@ "tslib": "^1.9.3" }, "dependencies": { - "ansi-styles": { - "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==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, "leven": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } } } }, @@ -6605,6 +6891,18 @@ "isexe": "^2.0.0" } }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", @@ -6616,35 +6914,6 @@ "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", "requires": { "string-width": "^1.0.2 || 2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "requires": { - "ansi-regex": "^3.0.0" - } - } } }, "word-wrap": { @@ -6663,13 +6932,64 @@ "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==" }, "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "requires": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + } + } } }, "wrappy": { @@ -6694,19 +7014,19 @@ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" }, "y18n": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", - "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==" + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" }, "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, "yaml": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz", - "integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==" + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" }, "yaml-unist-parser": { "version": "1.3.1", @@ -6719,31 +7039,53 @@ } }, "yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "requires": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + } + } } }, "yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==" }, "yargs-unparser": { "version": "2.0.0", @@ -6754,18 +7096,6 @@ "decamelize": "^4.0.0", "flat": "^5.0.2", "is-plain-obj": "^2.1.0" - }, - "dependencies": { - "camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==" - }, - "decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==" - } } }, "yn": { diff --git a/examples/package.json b/examples/package.json index 022c135e..62ba247e 100644 --- a/examples/package.json +++ b/examples/package.json @@ -7,7 +7,8 @@ "build": "rm -rf dist/ && tsc", "start": "npm run build && node dist/index.js", "collection": "npm run build && node dist/collection.js", - "sync": "rm -rf ./git-documentdb/ && npm run build && node dist/sync.js" + "sync": "rm -rf ./git-documentdb/ && npm run build && node dist/sync.js", + "plugin": "npm run build && node dist/plugin.js" }, "author": "", "license": "MPL-2.0", diff --git a/examples/src/index.ts b/examples/src/index.ts index b1d4b909..5ea33520 100644 --- a/examples/src/index.ts +++ b/examples/src/index.ts @@ -30,7 +30,7 @@ const gitddb_example = async () => { console.log(`$ gitDDB.put({ flower: 'cherry blossoms' ... }) # Create`); console.log(await gitDDB.get('nara')); - // log: { _id: 'nara', flower: 'cherry blossoms', season: 'spring' } + // log: { flower: 'cherry blossoms', season: 'spring', _id: 'nara' } // Note that _id and a filename are linked. // So _id is better to be ASCII characters and a case-insensitive name for cross-platform. @@ -98,7 +98,7 @@ const gitddb_example = async () => { console.log(`\n$ gitDDB.get('nara', 2) # Get a document two revisions older than the latest.`); console.log(oldDoc); - // log: { _id: 'nara', flower: 'cherry blossoms', season: 'spring' } + // log: { flower: 'cherry blossoms', season: 'spring', _id: 'nara' } /** * Synchronization diff --git a/examples/src/plugin.ts b/examples/src/plugin.ts new file mode 100644 index 00000000..db6a9b83 --- /dev/null +++ b/examples/src/plugin.ts @@ -0,0 +1,83 @@ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +import { GitDocumentDB, RemoteOptions } from 'git-documentdb'; +import { sleep } from './utils'; + +// Load NodeGit plugin to connect remote repository +GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + +const remote_plugin_example = async () => { + const gitDDB = new GitDocumentDB({ + dbName: 'db_plugin', // Git working directory + }); + await gitDDB.open(); + await gitDDB.put({ name: 'foo'}); + + /** + * This example assumes you have an account on GitHub. + * Please get your personal access token with checked [repo]. + * (See https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token ) + */ + let github_repository = 'https://github.com/enter_your_account_name/git-documentdb-example-sync.git'; + let github_repository2 = 'https://github.com/enter_your_account_name/git-documentdb-example-sync2.git'; + let your_github_personal_access_token = 'Enter your personal access token with checked [repo]'; + /** + * You can also set them from environment variables: + * - GITDDB_GITHUB_USER_URL + * URL of your GitHub account + * e.g.) https://github.com/foo/ + * - GITDDB_PERSONAL_ACCESS_TOKEN + * A personal access token of your GitHub account + */ + if (process.env.GITDDB_GITHUB_USER_URL) github_repository = process.env.GITDDB_GITHUB_USER_URL + 'git-documentdb-example-sync.git'; + if (process.env.GITDDB_GITHUB_USER_URL) github_repository2 = process.env.GITDDB_GITHUB_USER_URL + 'git-documentdb-example-sync2.git'; + if (process.env.GITDDB_PERSONAL_ACCESS_TOKEN) your_github_personal_access_token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN; + // @ts-ignore + if (your_github_personal_access_token === 'Enter your personal access token with checked [repo]') { + console.log('Please set your personal access token.'); + return; + } + + // Use default engine (isomorphic-git) + const remoteOptionsDefault: RemoteOptions = { + live: true, + remoteUrl: github_repository, + interval: 5000, // Sync every 5,000 msec + connection: { + type: 'github', + personalAccessToken: your_github_personal_access_token, + }, + }; + const syncDefault = await gitDDB.sync(remoteOptionsDefault); + console.log('## Default RemoteEngine: ' + syncDefault.engine); + syncDefault.on('start', () => { console.log('[default] synchronizing...')}); + syncDefault.on('complete', () => { console.log('[default] completed')}); + + // Set NodeGit engine + const remoteOptionsNodeGit: RemoteOptions = { + live: true, + remoteUrl: github_repository2, + interval: 5000, // Sync every 5,000 msec + connection: { + type: 'github', + personalAccessToken: your_github_personal_access_token, + engine: 'nodegit' + }, + }; + const syncNodeGit= await gitDDB.sync(remoteOptionsNodeGit); + console.log('## Current RemoteEngine: ' + syncNodeGit.engine); + syncNodeGit.on('start', () => { console.log('[NodeGit] synchronizing...')}); + syncNodeGit.on('complete', () => { console.log('[NodeGit] completed')}); + + await sleep(10000); + await gitDDB.close(); +}; + +remote_plugin_example(); + From ac8283346770afd8a0cd309bb3c9f428cbd61672 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 3 Aug 2021 15:52:17 +0900 Subject: [PATCH 134/297] test: remove default of createGitRemote --- test/internal_plugin/fetch.test.ts | 164 ++++++++++++++++++++++------- test/internal_plugin/push.test.ts | 149 ++++++++++++++++++-------- test/remote_utils.ts | 10 +- 3 files changed, 240 insertions(+), 83 deletions(-) diff --git a/test/internal_plugin/fetch.test.ts b/test/internal_plugin/fetch.test.ts index 281d4c6d..6dac5337 100644 --- a/test/internal_plugin/fetch.test.ts +++ b/test/internal_plugin/fetch.test.ts @@ -24,6 +24,8 @@ import sinon from 'sinon'; import { GitDocumentDB } from '../../src/git_documentdb'; import { fetch } from '../../src/plugin/remote-isomorphic-git'; import { createGitRemote, destroyDBs, removeRemoteRepositories } from '../remote_utils'; +import { Sync } from '../../src/remote/sync'; +import { ConnectionSettingsGitHub } from '../../src/types'; const reposPrefix = 'test_remote_isomorphic_git_fetch___'; const localDir = `./test/database_fetch`; @@ -90,11 +92,21 @@ maybe(' fetch', () => { await dbA.open(); const remoteUrl = remoteURLBase + 'test-public.git'; - await createGitRemote(dbA.workingDir, remoteUrl); - const res = await fetch(dbA.workingDir, { + const remoteOptions = { remoteUrl, - connection: { type: 'github' }, - }).catch(error => error); + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + connection: { type: 'github' } as ConnectionSettingsGitHub, + }; + const sync = new Sync(dbA, remoteOptions); + await createGitRemote(dbA.workingDir, remoteUrl, sync.remoteName); + + const res = await fetch( + dbA.workingDir, + remoteOptions, + sync.remoteName, + dbA.defaultBranch, + dbA.defaultBranch + ).catch(error => error); expect(res).toBeUndefined(); await destroyDBs([dbA]); @@ -108,12 +120,25 @@ maybe(' fetch', () => { await dbA.open(); const remoteUrl = remoteURLBase + 'test-public.git'; - - await createGitRemote(dbA.workingDir, remoteUrl); - const res = await fetch(dbA.workingDir, { + const remoteOptions = { remoteUrl, - connection: { type: 'github', personalAccessToken: token }, - }).catch(error => error); + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + connection: { + type: 'github', + personalAccessToken: token, + } as ConnectionSettingsGitHub, + }; + const sync = new Sync(dbA, remoteOptions); + await createGitRemote(dbA.workingDir, remoteUrl, sync.remoteName); + + const res = await fetch( + dbA.workingDir, + remoteOptions, + sync.remoteName, + dbA.defaultBranch, + dbA.defaultBranch + ).catch(error => error); + expect(res).toBeUndefined(); await destroyDBs([dbA]); @@ -127,12 +152,25 @@ maybe(' fetch', () => { await dbA.open(); const remoteUrl = remoteURLBase + 'test-private.git'; - await createGitRemote(dbA.workingDir, remoteUrl); - - const res = await fetch(dbA.workingDir, { + const remoteOptions = { remoteUrl, - connection: { type: 'github', personalAccessToken: token }, - }).catch(error => error); + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + connection: { + type: 'github', + personalAccessToken: token, + } as ConnectionSettingsGitHub, + }; + const sync = new Sync(dbA, remoteOptions); + await createGitRemote(dbA.workingDir, remoteUrl, sync.remoteName); + + const res = await fetch( + dbA.workingDir, + remoteOptions, + sync.remoteName, + dbA.defaultBranch, + dbA.defaultBranch + ).catch(error => error); + expect(res).toBeUndefined(); await destroyDBs([dbA]); @@ -146,7 +184,16 @@ maybe(' fetch', () => { await dbA.open(); const remoteUrl = remoteURLBase + 'test-private.git'; - await createGitRemote(dbA.workingDir, remoteUrl); + const remoteOptions = { + remoteUrl, + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + connection: { + type: 'github', + personalAccessToken: token, + } as ConnectionSettingsGitHub, + }; + const sync = new Sync(dbA, remoteOptions); + await createGitRemote(dbA.workingDir, remoteUrl, sync.remoteName); const stubFetch = sandbox.stub(git, 'fetch'); stubFetch.onCall(0).rejects(new Error('connect EACCES')); @@ -154,16 +201,48 @@ maybe(' fetch', () => { stubFetch.onCall(2).rejects(new Error('connect EACCES')); stubFetch.onCall(3).resolves(undefined); - const res = await fetch(dbA.workingDir, { - remoteUrl, - connection: { type: 'github', personalAccessToken: token }, - }).catch(error => error); + const res = await fetch( + dbA.workingDir, + remoteOptions, + sync.remoteName, + dbA.defaultBranch, + dbA.defaultBranch + ).catch(error => error); + expect(res).toBeUndefined(); expect(stubFetch.callCount).toBe(4); await destroyDBs([dbA]); }); + + it('when fetch from multiple Sync instances', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = remoteURLBase + 'test-public.git'; + const remoteOptions = { + remoteUrl, + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + connection: { type: 'github' } as ConnectionSettingsGitHub, + }; + const sync = new Sync(dbA, remoteOptions); + await createGitRemote(dbA.workingDir, remoteUrl, sync.remoteName); + + const res = await fetch( + dbA.workingDir, + remoteOptions, + sync.remoteName, + dbA.defaultBranch, + dbA.defaultBranch + ).catch(error => error); + expect(res).toBeUndefined(); + + await destroyDBs([dbA]); + }); }); it('throws NetworkError after retrying push()', async () => { @@ -174,15 +253,28 @@ maybe(' fetch', () => { await dbA.open(); const remoteUrl = remoteURLBase + 'test-private.git'; - await createGitRemote(dbA.workingDir, remoteUrl); + const remoteOptions = { + remoteUrl, + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + connection: { + type: 'github', + personalAccessToken: token, + } as ConnectionSettingsGitHub, + }; + const sync = new Sync(dbA, remoteOptions); + await createGitRemote(dbA.workingDir, remoteUrl, sync.remoteName); const stubFetch = sandbox.stub(git, 'fetch'); stubFetch.rejects(new Error('connect EACCES')); - const res = await fetch(dbA.workingDir, { - remoteUrl, - connection: { type: 'github', personalAccessToken: token }, - }).catch(error => error); + const res = await fetch( + dbA.workingDir, + remoteOptions, + sync.remoteName, + dbA.defaultBranch, + dbA.defaultBranch + ).catch(error => error); + expect(res).toBeInstanceOf(NetworkError); expect(stubFetch.callCount).toBe(4); @@ -231,7 +323,7 @@ maybe(' fetch', () => { await dbA.open(); const remoteUrl = 'foo-bar'; - await createGitRemote(dbA.workingDir, remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl, 'origin'); const err = await fetch(dbA.workingDir, { remoteUrl }).catch(error => error); @@ -249,7 +341,7 @@ maybe(' fetch', () => { await dbA.open(); const remoteUrl = 'https://foo.example.com:xxxx'; - await createGitRemote(dbA.workingDir, remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl, 'origin'); const err = await fetch(dbA.workingDir, { remoteUrl }).catch(error => error); expect(err).toBeInstanceOf(InvalidURLFormatError); @@ -266,7 +358,7 @@ maybe(' fetch', () => { await dbA.open(); const remoteUrl = 'https://foo.bar.example.com/gitddb-plugin/sync-test-invalid.git'; - await createGitRemote(dbA.workingDir, remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl, 'origin'); const err = await fetch(dbA.workingDir, { remoteUrl }).catch(error => error); expect(err).toBeInstanceOf(InvalidURLFormatError); expect(err.message).toMatch(/^URL format is invalid: Error: getaddrinfo ENOTFOUND/); @@ -283,7 +375,7 @@ maybe(' fetch', () => { await dbA.open(); const remoteUrl = 'https://127.0.0.1/gitddb-plugin/sync-test-invalid.git'; - await createGitRemote(dbA.workingDir, remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl, 'origin'); const err = await fetch(dbA.workingDir, { remoteUrl, @@ -309,7 +401,7 @@ maybe(' fetch', () => { const remoteUrl = remoteURLBase + 'test-private.git'; - await createGitRemote(dbA.workingDir, remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl, 'origin'); const err = await fetch(dbA.workingDir, { remoteUrl, @@ -330,7 +422,7 @@ maybe(' fetch', () => { await dbA.open(); const remoteUrl = remoteURLBase + 'test-private.git'; - await createGitRemote(dbA.workingDir, remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl, 'origin'); const err = await fetch(dbA.workingDir, { remoteUrl }).catch(error => error); @@ -348,7 +440,7 @@ maybe(' fetch', () => { await dbA.open(); const remoteUrl = remoteURLBase + 'test-private.git'; - await createGitRemote(dbA.workingDir, remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl, 'origin'); const err = await fetch(dbA.workingDir, { remoteUrl, @@ -371,7 +463,7 @@ maybe(' fetch', () => { await dbA.open(); const remoteUrl = remoteURLBase + 'sync-test-invalid.git'; - await createGitRemote(dbA.workingDir, remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl, 'origin'); const err = await fetch(dbA.workingDir, { remoteUrl, @@ -392,7 +484,7 @@ maybe(' fetch', () => { await dbA.open(); const remoteUrl = 'foo-bar'; - await createGitRemote(dbA.workingDir, remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl, 'origin'); const err = await fetch(dbA.workingDir, { remoteUrl, @@ -414,7 +506,7 @@ maybe(' fetch', () => { await dbA.open(); const remoteUrl = remoteURLBase + 'foo/bar/test.git'; - await createGitRemote(dbA.workingDir, remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl, 'origin'); await expect( fetch(dbA.workingDir, { @@ -434,7 +526,7 @@ maybe(' fetch', () => { await dbA.open(); const remoteUrl = remoteURLBase + 'test-private.git'; - await createGitRemote(dbA.workingDir, remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl, 'origin'); await expect( // @ts-ignore @@ -452,7 +544,7 @@ maybe(' fetch', () => { await dbA.open(); const remoteUrl = remoteURLBase + 'test-private.git'; - await createGitRemote(dbA.workingDir, remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl, 'origin'); await expect( // @ts-ignore diff --git a/test/internal_plugin/push.test.ts b/test/internal_plugin/push.test.ts index 3998ddb2..3e638d3a 100644 --- a/test/internal_plugin/push.test.ts +++ b/test/internal_plugin/push.test.ts @@ -25,7 +25,7 @@ import { } from 'git-documentdb-remote-errors'; import sinon from 'sinon'; import { GitDocumentDB } from '../../src/git_documentdb'; -import { RemoteOptions } from '../../src/types'; +import { ConnectionSettingsGitHub, RemoteOptions } from '../../src/types'; import { clone, push } from '../../src/plugin/remote-isomorphic-git'; import { createClonedDatabases, @@ -34,6 +34,7 @@ import { destroyDBs, removeRemoteRepositories, } from '../remote_utils'; +import { Sync } from '../../src/remote/sync'; const reposPrefix = 'test_remote_isomorphic_git_push___'; const localDir = `./test/database_push`; @@ -116,15 +117,28 @@ maybe(' push', () => { localDir, }); const remoteUrl = remoteURLBase + serialId(); + const remoteOptions = { + remoteUrl, + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + connection: { + type: 'github', + personalAccessToken: token, + } as ConnectionSettingsGitHub, + }; + const sync = new Sync(dbA, remoteOptions); + await dbA.open(); await dbA.put({ name: 'fromA' }); await createRemoteRepository(remoteUrl); - await createGitRemote(dbA.workingDir, remoteUrl); - const res = await push(dbA.workingDir, { - remoteUrl, - connection: { type: 'github', personalAccessToken: token }, - }).catch(error => error); + await createGitRemote(dbA.workingDir, remoteUrl, sync.remoteName); + const res = await push( + dbA.workingDir, + remoteOptions, + sync.remoteName, + dbA.defaultBranch, + dbA.defaultBranch + ).catch(error => error); expect(res).toBeUndefined(); @@ -137,19 +151,28 @@ maybe(' push', () => { localDir, }); const remoteUrl = remoteURLBase + 'test-public.git'; + const remoteOptions = { + remoteUrl, + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + connection: { + type: 'github', + personalAccessToken: token, + } as ConnectionSettingsGitHub, + }; + const sync = new Sync(dbA, remoteOptions); fs.ensureDirSync(dbA.workingDir); - await clone(dbA.workingDir, { - remoteUrl: remoteUrl, - connection: { type: 'github', personalAccessToken: token }, - }); + await clone(dbA.workingDir, remoteOptions, sync.remoteName); await dbA.open(); await dbA.put({ name: 'fromA' }); // await createGitRemote(dbA.workingDir, remoteUrl); // Not need because cloned repository. - const res = await push(dbA.workingDir, { - remoteUrl, - connection: { type: 'github', personalAccessToken: token }, - }).catch(error => error); + const res = await push( + dbA.workingDir, + remoteOptions, + sync.remoteName, + dbA.defaultBranch, + dbA.defaultBranch + ).catch(error => error); expect(res).toBeUndefined(); @@ -163,19 +186,29 @@ maybe(' push', () => { }); const remoteUrl = remoteURLBase + 'test-private.git'; + const remoteOptions = { + remoteUrl, + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + connection: { + type: 'github', + personalAccessToken: token, + } as ConnectionSettingsGitHub, + }; + const sync = new Sync(dbA, remoteOptions); fs.ensureDirSync(dbA.workingDir); - await clone(dbA.workingDir, { - remoteUrl: remoteUrl, - connection: { type: 'github', personalAccessToken: token }, - }); + await clone(dbA.workingDir, remoteOptions); await dbA.open(); await dbA.put({ name: 'fromA' }); - await createGitRemote(dbA.workingDir, remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl, sync.remoteName); + + const res = await push( + dbA.workingDir, + remoteOptions, + sync.remoteName, + dbA.defaultBranch, + dbA.defaultBranch + ).catch(error => error); - const res = await push(dbA.workingDir, { - remoteUrl, - connection: { type: 'github', personalAccessToken: token }, - }).catch(error => error); expect(res).toBeUndefined(); await destroyDBs([dbA]); @@ -187,10 +220,19 @@ maybe(' push', () => { localDir, }); const remoteUrl = remoteURLBase + serialId(); + const remoteOptions = { + remoteUrl, + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + connection: { + type: 'github', + personalAccessToken: token, + } as ConnectionSettingsGitHub, + }; + const sync = new Sync(dbA, remoteOptions); await dbA.open(); await dbA.put({ name: 'fromA' }); await createRemoteRepository(remoteUrl); - await createGitRemote(dbA.workingDir, remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl, sync.remoteName); const stubPush = sandbox.stub(git, 'push'); stubPush.onCall(0).rejects(new Error('connect EACCES')); @@ -198,10 +240,13 @@ maybe(' push', () => { stubPush.onCall(2).rejects(new Error('connect EACCES')); stubPush.onCall(3).resolves(undefined); - const res = await push(dbA.workingDir, { - remoteUrl, - connection: { type: 'github', personalAccessToken: token }, - }).catch((error: Error) => error); + const res = await push( + dbA.workingDir, + remoteOptions, + sync.remoteName, + dbA.defaultBranch, + dbA.defaultBranch + ).catch(error => error); expect(res).toBeUndefined(); @@ -217,18 +262,30 @@ maybe(' push', () => { localDir, }); const remoteUrl = remoteURLBase + serialId(); + const remoteOptions = { + remoteUrl, + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + connection: { + type: 'github', + personalAccessToken: token, + } as ConnectionSettingsGitHub, + }; + const sync = new Sync(dbA, remoteOptions); await dbA.open(); await dbA.put({ name: 'fromA' }); await createRemoteRepository(remoteUrl); - await createGitRemote(dbA.workingDir, remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl, sync.remoteName); const stubPush = sandbox.stub(git, 'push'); stubPush.rejects(new Error('connect EACCES')); - const res = await push(dbA.workingDir, { - remoteUrl, - connection: { type: 'github', personalAccessToken: token }, - }).catch((error: Error) => error); + const res = await push( + dbA.workingDir, + remoteOptions, + sync.remoteName, + dbA.defaultBranch, + dbA.defaultBranch + ).catch(error => error); expect(res).toBeInstanceOf(NetworkError); @@ -245,7 +302,7 @@ maybe(' push', () => { await dbA.open(); const remoteUrl = 'foo-bar'; - await createGitRemote(dbA.workingDir, remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl, 'origin'); // type is 'none' const err = await push(dbA.workingDir, { @@ -267,7 +324,7 @@ maybe(' push', () => { await dbA.open(); const remoteUrl = 'https://foo.example.com:xxxx'; - await createGitRemote(dbA.workingDir, remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl, 'origin'); const err = await push(dbA.workingDir, { remoteUrl, @@ -288,7 +345,7 @@ maybe(' push', () => { await dbA.open(); const remoteUrl = 'https://foo.bar.example.com/gitddb-plugin/sync-test-invalid.git'; - await createGitRemote(dbA.workingDir, remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl, 'origin'); const err = await push(dbA.workingDir, { remoteUrl, @@ -310,7 +367,7 @@ maybe(' push', () => { await dbA.open(); const remoteUrl = 'https://127.0.0.1/gitddb-plugin/sync-test-invalid.git'; - await createGitRemote(dbA.workingDir, remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl, 'origin'); const err = await push(dbA.workingDir, { remoteUrl, @@ -335,7 +392,7 @@ maybe(' push', () => { await dbA.open(); const remoteUrl = remoteURLBase + 'test-public.git'; - await createGitRemote(dbA.workingDir, remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl, 'origin'); const err = await push(dbA.workingDir, { remoteUrl, @@ -356,7 +413,7 @@ maybe(' push', () => { await dbA.open(); const remoteUrl = remoteURLBase + 'test-public.git'; - await createGitRemote(dbA.workingDir, remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl, 'origin'); const err = await push(dbA.workingDir, { remoteUrl }).catch(error => error); @@ -374,7 +431,7 @@ maybe(' push', () => { await dbA.open(); const remoteUrl = remoteURLBase + 'test-private.git'; - await createGitRemote(dbA.workingDir, remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl, 'origin'); const err = await push(dbA.workingDir, { remoteUrl, @@ -397,7 +454,7 @@ maybe(' push', () => { await dbA.open(); const remoteUrl = remoteURLBase + 'sync-test-invalid.git'; - await createGitRemote(dbA.workingDir, remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl, 'origin'); const err = await push(dbA.workingDir, { remoteUrl, @@ -418,7 +475,7 @@ maybe(' push', () => { await dbA.open(); const remoteUrl = 'foo-bar'; - await createGitRemote(dbA.workingDir, remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl, 'origin'); const err = await push(dbA.workingDir, { remoteUrl, @@ -440,7 +497,7 @@ maybe(' push', () => { await dbA.open(); const remoteUrl = remoteURLBase + 'foo/bar/test.git'; - await createGitRemote(dbA.workingDir, remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl, 'origin'); await expect( push(dbA.workingDir, { @@ -460,7 +517,7 @@ maybe(' push', () => { await dbA.open(); const remoteUrl = remoteURLBase + 'test-private.git'; - await createGitRemote(dbA.workingDir, remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl, 'origin'); await expect( // @ts-ignore @@ -478,7 +535,7 @@ maybe(' push', () => { await dbA.open(); const remoteUrl = remoteURLBase + 'test-private.git'; - await createGitRemote(dbA.workingDir, remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl, 'origin'); await expect( // @ts-ignore @@ -506,7 +563,7 @@ maybe(' push', () => { // const remoteUrl = privateRepositoryOfAnotherUser; const remoteUrl = 'https://github.com/sosuisen/git-documentdb.git'; - await createGitRemote(dbA.workingDir, remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl, 'origin'); const err = await push(dbA.workingDir, { remoteUrl, diff --git a/test/remote_utils.ts b/test/remote_utils.ts index 965eccc2..9bc7dd84 100644 --- a/test/remote_utils.ts +++ b/test/remote_utils.ts @@ -403,8 +403,15 @@ export const destroyDBs = async (DBs: GitDocumentDB[]) => { export async function createGitRemote ( localDir: string, remoteUrl: string, - remoteName = 'origin' + remoteName: string ) { + await git.addRemote({ + fs, + dir: localDir, + remote: remoteName, + url: remoteUrl, + }); + /* await git.setConfig({ fs, dir: localDir, @@ -417,4 +424,5 @@ export async function createGitRemote ( path: `remote.${remoteName}.fetch`, value: `+refs/heads/*:refs/remotes/${remoteName}/*`, }); +*/ } From 5f04777452865333b5cdea4fc2fc9c996eb857b6 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 3 Aug 2021 15:54:02 +0900 Subject: [PATCH 135/297] fix: add branch name arguments to fetch() --- src/plugin/remote-isomorphic-git.ts | 7 +++++++ src/remote/remote_engine.ts | 2 ++ src/remote/sync_worker.ts | 9 ++++++++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/plugin/remote-isomorphic-git.ts b/src/plugin/remote-isomorphic-git.ts index 90c13de0..191c2552 100644 --- a/src/plugin/remote-isomorphic-git.ts +++ b/src/plugin/remote-isomorphic-git.ts @@ -322,6 +322,8 @@ export async function fetch ( workingDir: string, remoteOptions: RemoteOptions, remoteName?: string, + localBranchName?: string, + remoteBranchName?: string, logger?: Logger ): Promise { logger ??= new Logger({ @@ -334,6 +336,8 @@ export async function fetch ( logger.debug(`remote-isomorphic-git: fetch: ${remoteOptions.remoteUrl}`); remoteName ??= 'origin'; + localBranchName ??= 'main'; + remoteBranchName ??= 'main'; const urlOfRemote = await git.getConfig({ fs, @@ -352,6 +356,9 @@ export async function fetch ( dir: workingDir, http: httpClient, url: remoteOptions.remoteUrl!, + remote: remoteName, + ref: localBranchName, + remoteRef: remoteBranchName, }; const cred = createCredentialCallback(remoteOptions); if (cred) { diff --git a/src/remote/remote_engine.ts b/src/remote/remote_engine.ts index d3c0f1b8..4f51557d 100644 --- a/src/remote/remote_engine.ts +++ b/src/remote/remote_engine.ts @@ -30,6 +30,8 @@ export interface RemoteEngineInterface { workingDir: string, remoteOptions: RemoteOptions, remoteName?: string, + localBranchName?: string, + remoteBranchName?: string, logger?: Logger ) => Promise; push: ( diff --git a/src/remote/sync_worker.ts b/src/remote/sync_worker.ts index be477f99..dc3fa5d8 100644 --- a/src/remote/sync_worker.ts +++ b/src/remote/sync_worker.ts @@ -84,7 +84,14 @@ export async function syncWorker ( * Fetch */ await RemoteEngine[sync.engine] - .fetch(gitDDB.workingDir, sync.options, sync.remoteName, gitDDB.logger) + .fetch( + gitDDB.workingDir, + sync.options, + sync.remoteName, + gitDDB.defaultBranch, + gitDDB.defaultBranch, + gitDDB.logger + ) .catch(err => { throw wrappingRemoteEngineError(err); }); From 4c5ccef31ddbdf85dbeae719f7995df6315c3855 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 3 Aug 2021 15:55:06 +0900 Subject: [PATCH 136/297] test: add non-parallel mochar for .only option --- package-lock.json | 44 ++++++++++---------------------------------- package.json | 5 +++-- 2 files changed, 13 insertions(+), 36 deletions(-) diff --git a/package-lock.json b/package-lock.json index a7850f4d..87ac4f4b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "git-documentdb", - "version": "0.4.0", + "version": "0.4.1-beta.2", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -970,9 +970,9 @@ } }, "@szmarczak/http-timer": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.5.tgz", - "integrity": "sha512-PyRA9sm1Yayuj5OIoJ1hGt2YISX45w9WcFbh6ddT0Z/0yaFxOtGLInr4jUfU1EAFVs0Yfyfev4RNwBlUaHdlDQ==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", "dev": true, "requires": { "defer-to-connect": "^2.0.0" @@ -1023,14 +1023,6 @@ "@types/keyv": "*", "@types/node": "*", "@types/responselike": "*" - }, - "dependencies": { - "@types/node": { - "version": "16.3.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.3.1.tgz", - "integrity": "sha512-N87VuQi7HEeRJkhzovao/JviiqKjDKMVKxKMfUvSKw+MbkbW8R0nA3fi/MQhhlxV2fQ+2ReM+/Nt4efdrJx3zA==", - "dev": true - } } }, "@types/expect": { @@ -1104,14 +1096,6 @@ "dev": true, "requires": { "@types/node": "*" - }, - "dependencies": { - "@types/node": { - "version": "16.3.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.3.1.tgz", - "integrity": "sha512-N87VuQi7HEeRJkhzovao/JviiqKjDKMVKxKMfUvSKw+MbkbW8R0nA3fi/MQhhlxV2fQ+2ReM+/Nt4efdrJx3zA==", - "dev": true - } } }, "@types/minimatch": { @@ -1157,14 +1141,6 @@ "dev": true, "requires": { "@types/node": "*" - }, - "dependencies": { - "@types/node": { - "version": "16.3.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.3.1.tgz", - "integrity": "sha512-N87VuQi7HEeRJkhzovao/JviiqKjDKMVKxKMfUvSKw+MbkbW8R0nA3fi/MQhhlxV2fQ+2ReM+/Nt4efdrJx3zA==", - "dev": true - } } }, "@types/rimraf": { @@ -3552,9 +3528,9 @@ "dev": true }, "git-documentdb-plugin-remote-nodegit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.0.tgz", - "integrity": "sha512-fZLcid1l2aMZ1aGHJC3/H0tDY3wrpK1R2YjuHGODlRsxJmupFUa/+63P+4qUepHc+HcmuHP3n8ucbxamlGQThQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.1.tgz", + "integrity": "sha512-KXkRQZXGHqeyp6yG4hm4h3hiecWRv6GqlK227oITwC0uBZ222IMpPkEF0S6MDkhZaPAbiFiKsS4U7Fr0WMx4Fg==", "dev": true, "requires": { "git-documentdb-remote-errors": "^1.0.3", @@ -7205,9 +7181,9 @@ } }, "tar": { - "version": "4.4.13", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", - "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", + "version": "4.4.15", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.15.tgz", + "integrity": "sha512-ItbufpujXkry7bHH9NpQyTXPbJ72iTlXgkBAYsAjDXk3Ds8t/3NfO5P4xZGy7u+sYuQUbimgzswX4uQIEeNVOA==", "dev": true, "requires": { "chownr": "^1.1.1", diff --git a/package.json b/package.json index a4193eb5..1aaae8d1 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,8 @@ "build": "rm -rf dist/* && npm run lint && tsc --project src/tsconfig.json", "doc": "npm run build && npm run api-extractor && npm run crlf", "mocha": "npm run rm-test-db && npx cross-env TS_NODE_FILES=true TS_NODE_PROJECT=tsconfig.mocha.json mocha", - "mocha-unit": "npm run rm-test-db && npx cross-env TS_NODE_FILES=true TS_NODE_PROJECT=tsconfig.mocha.json mocha --retries 0", + "mocha-unit-parallel": "npm run rm-test-db && npx cross-env TS_NODE_FILES=true TS_NODE_PROJECT=tsconfig.mocha.json mocha --retries 0", + "mocha-unit": "npm run rm-test-db && npx cross-env TS_NODE_FILES=true TS_NODE_PROJECT=tsconfig.mocha.json mocha --retries 0 --no-parallel", "compile-tests": "tsc --project test/tsconfig.json", "rm-test-db": "rm -rf test/database* test_plugin/database*", "test": "npx nyc npm run mocha \"test/**/*.test.ts\" && npm run rm-test-db", @@ -61,7 +62,7 @@ "eslint-config-standardize": "^0.7.1", "eslint-plugin-prettierx": "^0.14.0", "expect": "^27.0.2", - "git-documentdb-plugin-remote-nodegit": "^1.0.0", + "git-documentdb-plugin-remote-nodegit": "^1.0.1", "mocha": "^8.3.2", "nyc": "^15.1.0", "parse-git-config": "^3.0.0", From ca498c821ad9e40b0744b039b6d09b9f8ff03c62 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 3 Aug 2021 15:55:22 +0900 Subject: [PATCH 137/297] fix: adding example for plugin --- examples/package-lock.json | 1246 ++++++++++++++++++++++++++++++++++++ examples/package.json | 3 +- examples/src/plugin.ts | 1 + 3 files changed, 1249 insertions(+), 1 deletion(-) diff --git a/examples/package-lock.json b/examples/package-lock.json index c2a13e49..b3299269 100644 --- a/examples/package-lock.json +++ b/examples/package-lock.json @@ -4,6 +4,415 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@sindresorhus/is": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-2.1.1.tgz", + "integrity": "sha512-/aPsuoj/1Dw/kzhkgz+ES6TxG0zfTMGLwuK2ZG00k/iJzYHTLCE8mVU8EPqEOp/lmxPoq1C1C9RYToRKb2KEfg==" + }, + "@szmarczak/http-timer": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "requires": { + "defer-to-connect": "^2.0.0" + } + }, + "@types/cacheable-request": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", + "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", + "requires": { + "@types/http-cache-semantics": "*", + "@types/keyv": "*", + "@types/node": "*", + "@types/responselike": "*" + } + }, + "@types/http-cache-semantics": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", + "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==" + }, + "@types/keyv": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.2.tgz", + "integrity": "sha512-/FvAK2p4jQOaJ6CGDHJTqZcUtbZe820qIeTg7o0Shg7drB4JHeL+V/dhSaly7NXx6u8eSee+r7coT+yuJEvDLg==", + "requires": { + "@types/node": "*" + } + }, + "@types/node": { + "version": "16.4.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.4.10.tgz", + "integrity": "sha512-TmVHsm43br64js9BqHWqiDZA+xMtbUpI1MBIA0EyiBmoV9pcEYFOSdj5fr6enZNfh4fChh+AGOLIzGwJnkshyQ==" + }, + "@types/responselike": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", + "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", + "requires": { + "@types/node": "*" + } + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + }, + "are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "bl": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", + "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==", + "requires": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "requires": { + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" + } + }, + "buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" + }, + "buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=" + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "cacheable-lookup": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-2.0.1.tgz", + "integrity": "sha512-EMMbsiOTcdngM/K6gV/OxF2x0t07+vMOWxZNSCRQMjO2MY2nhZQ6OYhOOpyQrbhqsgtvKGI7hcq6xjnA92USjg==", + "requires": { + "@types/keyv": "^3.1.1", + "keyv": "^4.0.0" + } + }, + "cacheable-request": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", + "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, + "clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "requires": { + "mimic-response": "^1.0.0" + }, + "dependencies": { + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" + } + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "decompress-response": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-5.0.0.tgz", + "integrity": "sha512-TLZWWybuxWgoW7Lykv+gq9xvzOsUjQ9tF09Tj6NSTYGMTCHNXzrPnD6Hi+TgZq19PyTAGH4Ll/NIM/eTGglnMw==", + "requires": { + "mimic-response": "^2.0.0" + } + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + }, + "defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==" + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + }, + "detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" + }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "requires": { + "once": "^1.4.0" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "requires": { + "minipass": "^2.6.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "requires": { + "pump": "^3.0.0" + } + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "^1.0.0" + } + }, "git-documentdb": { "version": "file:..", "requires": { @@ -7121,11 +7530,848 @@ } } }, + "git-documentdb-plugin-remote-nodegit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.1.tgz", + "integrity": "sha512-KXkRQZXGHqeyp6yG4hm4h3hiecWRv6GqlK227oITwC0uBZ222IMpPkEF0S6MDkhZaPAbiFiKsS4U7Fr0WMx4Fg==", + "requires": { + "git-documentdb-remote-errors": "^1.0.3", + "nodegit": "^0.27.0", + "tslog": "^3.2.0" + } + }, + "git-documentdb-remote-errors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/git-documentdb-remote-errors/-/git-documentdb-remote-errors-1.0.3.tgz", + "integrity": "sha512-14fN8VAQeBC7+Phs6TYB1D5PJDE/dF8dxbigKpsBEqR1FvpAQerSPptxVsQgkU33xwwZBOm7yCwVD2KKmQatOQ==" + }, + "glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "requires": { + "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" + } + }, + "got": { + "version": "10.7.0", + "resolved": "https://registry.npmjs.org/got/-/got-10.7.0.tgz", + "integrity": "sha512-aWTDeNw9g+XqEZNcTjMMZSy7B7yE9toWOFYip7ofFTLleJhvZwUxxTxkTpKvF+p1SAA4VHmuEy7PiHTHyq8tJg==", + "requires": { + "@sindresorhus/is": "^2.0.0", + "@szmarczak/http-timer": "^4.0.0", + "@types/cacheable-request": "^6.0.1", + "cacheable-lookup": "^2.0.0", + "cacheable-request": "^7.0.1", + "decompress-response": "^5.0.0", + "duplexer3": "^0.1.4", + "get-stream": "^5.0.0", + "lowercase-keys": "^2.0.0", + "mimic-response": "^2.1.0", + "p-cancelable": "^2.0.0", + "p-event": "^4.0.0", + "responselike": "^2.0.0", + "to-readable-stream": "^2.0.0", + "type-fest": "^0.10.0" + } + }, + "graceful-fs": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "requires": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + }, + "http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.4.tgz", + "integrity": "sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ==", + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + }, + "json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "requires": { + "minimist": "^1.2.5" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "keyv": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.3.tgz", + "integrity": "sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA==", + "requires": { + "json-buffer": "3.0.1" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" + }, + "mime-db": { + "version": "1.49.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz", + "integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==" + }, + "mime-types": { + "version": "2.1.32", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz", + "integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==", + "requires": { + "mime-db": "1.49.0" + } + }, + "mimic-response": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", + "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "requires": { + "minipass": "^2.9.0" + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "requires": { + "minimist": "^1.2.5" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "nan": { + "version": "2.14.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", + "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==" + }, + "needle": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-2.8.0.tgz", + "integrity": "sha512-ZTq6WYkN/3782H1393me3utVYdq2XyqNUFBsprEE3VMAT0+hP/cItpnITpqsY6ep2yeFE4Tqtqwc74VqUlUYtw==", + "requires": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-gyp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-4.0.0.tgz", + "integrity": "sha512-2XiryJ8sICNo6ej8d0idXDEMKfVfFK7kekGCtJAuelGsYHQxhj13KTf95swTCN2dZ/4lTfZ84Fu31jqJEEgjWA==", + "requires": { + "glob": "^7.0.3", + "graceful-fs": "^4.1.2", + "mkdirp": "^0.5.0", + "nopt": "2 || 3", + "npmlog": "0 || 1 || 2 || 3 || 4", + "osenv": "0", + "request": "^2.87.0", + "rimraf": "2", + "semver": "~5.3.0", + "tar": "^4.4.8", + "which": "1" + } + }, + "node-pre-gyp": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.13.0.tgz", + "integrity": "sha512-Md1D3xnEne8b/HGVQkZZwV27WUi1ZRuZBij24TNaZwUPU3ZAFtvT6xxJGaUVillfmMKnn5oD1HoGsp2Ftik7SQ==", + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + }, + "dependencies": { + "nopt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", + "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + } + } + }, + "nodegit": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/nodegit/-/nodegit-0.27.0.tgz", + "integrity": "sha512-E9K4gPjWiA0b3Tx5lfWCzG7Cvodi2idl3V5UD2fZrOrHikIfrN7Fc2kWLtMUqqomyoToYJLeIC8IV7xb1CYRLA==", + "requires": { + "fs-extra": "^7.0.0", + "got": "^10.7.0", + "json5": "^2.1.0", + "lodash": "^4.17.14", + "nan": "^2.14.0", + "node-gyp": "^4.0.0", + "node-pre-gyp": "^0.13.0", + "ramda": "^0.25.0", + "tar-fs": "^1.16.3" + } + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "requires": { + "abbrev": "1" + } + }, + "normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==" + }, + "npm-bundled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.2.tgz", + "integrity": "sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ==", + "requires": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npm-normalize-package-bin": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", + "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==" + }, + "npm-packlist": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", + "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1", + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==" + }, + "p-event": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz", + "integrity": "sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==", + "requires": { + "p-timeout": "^3.1.0" + } + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" + }, + "p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "requires": { + "p-finally": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + }, + "ramda": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.25.0.tgz", + "integrity": "sha512-GXpfrYVPwx3K7RQ6aYT8KPS8XViSXUVJT1ONhoKPE9VAleW42YE+U+8VEyGWt41EnEQW7gwecYJriTI0pKoecQ==" + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "responselike": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz", + "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==", + "requires": { + "lowercase-keys": "^2.0.0" + } + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + }, + "tar": { + "version": "4.4.15", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.15.tgz", + "integrity": "sha512-ItbufpujXkry7bHH9NpQyTXPbJ72iTlXgkBAYsAjDXk3Ds8t/3NfO5P4xZGy7u+sYuQUbimgzswX4uQIEeNVOA==", + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + } + }, + "tar-fs": { + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.3.tgz", + "integrity": "sha512-NvCeXpYx7OsmOh8zIOP/ebG55zZmxLE0etfWRbWok+q2Qo8x/vOR/IJT1taADXPe+jsiu9axDb3X4B+iIgNlKw==", + "requires": { + "chownr": "^1.0.1", + "mkdirp": "^0.5.1", + "pump": "^1.0.0", + "tar-stream": "^1.1.2" + }, + "dependencies": { + "pump": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz", + "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, + "tar-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", + "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", + "requires": { + "bl": "^1.0.0", + "buffer-alloc": "^1.2.0", + "end-of-stream": "^1.0.0", + "fs-constants": "^1.0.0", + "readable-stream": "^2.3.0", + "to-buffer": "^1.1.1", + "xtend": "^4.0.0" + } + }, + "to-buffer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", + "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==" + }, + "to-readable-stream": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-2.1.0.tgz", + "integrity": "sha512-o3Qa6DGg1CEXshSdvWNX2sN4QHqg03SPq7U6jPXRahlQdl5dK8oXjkU/2/sGrnOZKeGV1zLSO8qPwyKklPPE7w==" + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "tslog": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/tslog/-/tslog-3.2.0.tgz", + "integrity": "sha512-xOCghepl5w+wcI4qXI7vJy6c53loF8OoC/EuKz1ktAPMtltEDz00yo1poKuyBYIQaq4ZDYKYFPD9PfqVrFXh0A==", + "requires": { + "source-map-support": "^0.5.19" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + }, + "type-fest": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.10.0.tgz", + "integrity": "sha512-EUV9jo4sffrwlg8s0zDhP0T2WD3pru5Xi0+HTE3zTUmBaZNhfkite9PdSJwdXLwPVW0jnAHT56pZHIOYckPEiw==" + }, "typescript": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz", "integrity": "sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==", "dev": true + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "requires": { + "punycode": "^2.1.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" } } } diff --git a/examples/package.json b/examples/package.json index 62ba247e..81aca231 100644 --- a/examples/package.json +++ b/examples/package.json @@ -13,7 +13,8 @@ "author": "", "license": "MPL-2.0", "dependencies": { - "git-documentdb": "file:.." + "git-documentdb": "file:..", + "git-documentdb-plugin-remote-nodegit": "^1.0.1" }, "devDependencies": { "typescript": "^4.1.3" diff --git a/examples/src/plugin.ts b/examples/src/plugin.ts index db6a9b83..4debfc15 100644 --- a/examples/src/plugin.ts +++ b/examples/src/plugin.ts @@ -71,6 +71,7 @@ const remote_plugin_example = async () => { }, }; const syncNodeGit= await gitDDB.sync(remoteOptionsNodeGit); + console.log('## Current RemoteEngine: ' + syncNodeGit.engine); syncNodeGit.on('start', () => { console.log('[NodeGit] synchronizing...')}); syncNodeGit.on('complete', () => { console.log('[NodeGit] completed')}); From 2ffa298679ec008df5ee974c71d483892e9da7e9 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 3 Aug 2021 19:31:04 +0900 Subject: [PATCH 138/297] debugging fetch and push --- examples/src/plugin.ts | 2 +- src/plugin/remote-isomorphic-git.ts | 1 - src/remote/sync.ts | 152 ++++++++++++---------- test/internal_plugin/checkfetch.test.ts | 162 +++++++++++++++++++----- test/internal_plugin/fetch.test.ts | 71 ++++++++++- test/remote_base/sync.ts | 26 ++-- test/remote_base/sync_live.ts | 1 + test/remote_utils.ts | 5 +- 8 files changed, 295 insertions(+), 125 deletions(-) diff --git a/examples/src/plugin.ts b/examples/src/plugin.ts index 4debfc15..b1bcfefd 100644 --- a/examples/src/plugin.ts +++ b/examples/src/plugin.ts @@ -67,7 +67,7 @@ const remote_plugin_example = async () => { connection: { type: 'github', personalAccessToken: your_github_personal_access_token, - engine: 'nodegit' + //engine: 'nodegit' }, }; const syncNodeGit= await gitDDB.sync(remoteOptionsNodeGit); diff --git a/src/plugin/remote-isomorphic-git.ts b/src/plugin/remote-isomorphic-git.ts index 191c2552..e917ec2c 100644 --- a/src/plugin/remote-isomorphic-git.ts +++ b/src/plugin/remote-isomorphic-git.ts @@ -368,7 +368,6 @@ export async function fetch ( for (let i = 0; i < remoteOptions.retry! + 1; i++) { // eslint-disable-next-line no-await-in-loop const res = await git.fetch(fetchOption).catch(err => err); - let error = ''; if (res instanceof Error) { error = res.toString(); diff --git a/src/remote/sync.ts b/src/remote/sync.ts index 130595c9..c1cf247d 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -479,15 +479,32 @@ export class Sync implements SyncInterface { }); } - // eslint-disable-next-line no-await-in-loop - const remoteResult: boolean | Error = await RemoteEngine[this._engine] - .checkFetch( - this._gitDDB.workingDir, - this._options, - this.remoteName, - this._gitDDB.logger - ) - .catch(err => err); + let remoteResult: boolean | Error; + if (this._options === 'push') { + // Do not download remote. + // eslint-disable-next-line no-await-in-loop + remoteResult = await RemoteEngine[this._engine] + .checkFetch( + this._gitDDB.workingDir, + this._options, + this.remoteName, + this._gitDDB.logger + ) + .catch(err => err); + } + else { + // eslint-disable-next-line no-await-in-loop + remoteResult = await RemoteEngine[this._engine] + .fetch( + this._gitDDB.workingDir, + this._options, + this.remoteName, + this._gitDDB.defaultBranch, + this._gitDDB.defaultBranch, + this._gitDDB.logger + ) + .catch(err => err); + } if (typeof remoteResult === 'boolean') { // nop @@ -520,43 +537,80 @@ export class Sync implements SyncInterface { action: 'nop', }; if (this._options === 'pull') { + // Do not create a new remote repository because the direction is 'pull'. /** * TODO: Implement case when sync_direction is 'pull'. */ } - else if (isNewRemoteRepository) { - this._gitDDB.logger.debug('upstream branch is not set yet. tryPush..'); - // trySync() pushes local commits to the remote branch. - - // Remote repository may not be created yet due to internal delay of GitHub. - // Retry if not exist. - for (let i = 0; i < this._options.retry! + 1; i++) { - // eslint-disable-next-line no-await-in-loop - const syncResultOrError = await this.tryPush().catch(err => err); - if (syncResultOrError instanceof Error) { - if (syncResultOrError instanceof RemoteErr.HTTPError404NotFound) { - // eslint-disable-next-line no-await-in-loop - await sleep(this._options.retryInterval!); - if (i === this._options.retry!) { - throw syncResultOrError; + else { + // push or both + if (this._options === 'both') { + // Check remote branch after fetching. + const remoteCommitOid = await git + .resolveRef({ + fs, + dir: this._gitDDB.workingDir, + ref: `refs/remotes/${this.remoteName}/${this._gitDDB.defaultBranch}`, + }) + .catch(() => undefined); + if (remoteCommitOid === undefined) { + // Remote repository is empty. + isNewRemoteRepository = true; + } + } + if (isNewRemoteRepository) { + this._gitDDB.logger.debug('upstream branch is not set yet. tryPush..'); + + // Remote repository may not be created yet due to internal delay of GitHub. + // Retry if not exist. + for (let i = 0; i < this._options.retry! + 1; i++) { + // eslint-disable-next-line no-await-in-loop + const syncResultOrError = await this.tryPush().catch(err => err); + if (syncResultOrError instanceof Error) { + if (syncResultOrError instanceof RemoteErr.HTTPError404NotFound) { + // eslint-disable-next-line no-await-in-loop + await sleep(this._options.retryInterval!); + if (i === this._options.retry!) { + throw syncResultOrError; + } + continue; } - continue; + throw syncResultOrError; } - throw syncResultOrError; + syncResult = syncResultOrError; + break; } - syncResult = syncResultOrError; - break; } + else if (this._options.syncDirection === 'push') { + this._gitDDB.logger.debug('upstream_branch exists. tryPush..'); + syncResult = await this.tryPush(); + } + else if (this._options.syncDirection === 'both') { + this._gitDDB.logger.debug('upstream_branch exists. trySync..'); + syncResult = await this.trySync(); + } + } - // An upstream branch must be set to a local branch after the first push - // because refs/remotes/origin/main is not created until the first push. + const branchRemote = await git.getConfig({ + fs, + dir: this._gitDDB.workingDir, + path: `branch.${this._gitDDB.defaultBranch}.remote`, + }); + if (branchRemote === undefined) { await git.setConfig({ fs, dir: this._gitDDB.workingDir, path: `branch.${this._gitDDB.defaultBranch}.remote`, value: this.remoteName, }); + } + const branchMerge = await git.getConfig({ + fs, + dir: this._gitDDB.workingDir, + path: `branch.${this._gitDDB.defaultBranch}.merge`, + }); + if (branchMerge === undefined) { await git.setConfig({ fs, dir: this._gitDDB.workingDir, @@ -564,44 +618,6 @@ export class Sync implements SyncInterface { value: `refs/heads/${this._gitDDB.defaultBranch}`, }); } - else { - const branchRemote = await git.getConfig({ - fs, - dir: this._gitDDB.workingDir, - path: `branch.${this._gitDDB.defaultBranch}.remote`, - }); - if (branchRemote === undefined) { - await git.setConfig({ - fs, - dir: this._gitDDB.workingDir, - path: `branch.${this._gitDDB.defaultBranch}.remote`, - value: this.remoteName, - }); - } - - const branchMerge = await git.getConfig({ - fs, - dir: this._gitDDB.workingDir, - path: `branch.${this._gitDDB.defaultBranch}.merge`, - }); - if (branchMerge === undefined) { - await git.setConfig({ - fs, - dir: this._gitDDB.workingDir, - path: `branch.${this._gitDDB.defaultBranch}.merge`, - value: `refs/heads/${this._gitDDB.defaultBranch}`, - }); - } - - if (this._options.syncDirection === 'push') { - this._gitDDB.logger.debug('upstream_branch exists. tryPush..'); - syncResult = await this.tryPush(); - } - else if (this._options.syncDirection === 'both') { - this._gitDDB.logger.debug('upstream_branch exists. trySync..'); - syncResult = await this.trySync(); - } - } if (this._options.live) { if (this._syncTimer === undefined) { diff --git a/test/internal_plugin/checkfetch.test.ts b/test/internal_plugin/checkfetch.test.ts index 6996e447..66a5d9ac 100644 --- a/test/internal_plugin/checkfetch.test.ts +++ b/test/internal_plugin/checkfetch.test.ts @@ -23,7 +23,15 @@ import { import sinon from 'sinon'; import { GitDocumentDB } from '../../src/git_documentdb'; import { checkFetch } from '../../src/plugin/remote-isomorphic-git'; -import { createGitRemote, destroyDBs, removeRemoteRepositories } from '../remote_utils'; +import { + createGitRemote, + createRemoteRepository, + destroyDBs, + destroyRemoteRepository, + removeRemoteRepositories, +} from '../remote_utils'; +import { ConnectionSettingsGitHub } from '../../src/types'; +import { Sync } from '../../src/remote/sync'; const reposPrefix = 'test_remote_isomorphic_git_check_fetch___'; const localDir = `./test/database_check_fetch`; @@ -90,11 +98,16 @@ maybe(' checkFetch', () => { await dbA.open(); const remoteUrl = remoteURLBase + 'test-public.git'; - await createGitRemote(dbA.workingDir, remoteUrl); - const res = await checkFetch(dbA.workingDir, { + const remoteOptions = { remoteUrl, - connection: { type: 'github' }, - }).catch(error => error); + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + connection: { type: 'github' } as ConnectionSettingsGitHub, + }; + const sync = new Sync(dbA, remoteOptions); + await createGitRemote(dbA.workingDir, remoteUrl, sync.remoteName); + const res = await checkFetch(dbA.workingDir, remoteOptions, sync.remoteName).catch( + error => error + ); expect(res).not.toBeInstanceOf(Error); await destroyDBs([dbA]); @@ -108,11 +121,19 @@ maybe(' checkFetch', () => { await dbA.open(); const remoteUrl = remoteURLBase + 'test-public.git'; - await createGitRemote(dbA.workingDir, remoteUrl); - const res = await checkFetch(dbA.workingDir, { + const remoteOptions = { remoteUrl, - connection: { type: 'github', personalAccessToken: token }, - }).catch(error => error); + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + connection: { + type: 'github', + personalAccessToken: token, + } as ConnectionSettingsGitHub, + }; + const sync = new Sync(dbA, remoteOptions); + await createGitRemote(dbA.workingDir, remoteUrl, sync.remoteName); + const res = await checkFetch(dbA.workingDir, remoteOptions, sync.remoteName).catch( + error => error + ); expect(res).not.toBeInstanceOf(Error); await destroyDBs([dbA]); @@ -126,11 +147,20 @@ maybe(' checkFetch', () => { await dbA.open(); const remoteUrl = remoteURLBase + 'test-private.git'; - await createGitRemote(dbA.workingDir, remoteUrl); - const res = await checkFetch(dbA.workingDir, { + const remoteOptions = { remoteUrl, - connection: { type: 'github', personalAccessToken: token }, - }).catch(error => error); + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + connection: { + type: 'github', + personalAccessToken: token, + } as ConnectionSettingsGitHub, + }; + const sync = new Sync(dbA, remoteOptions); + await createGitRemote(dbA.workingDir, remoteUrl, sync.remoteName); + const res = await checkFetch(dbA.workingDir, remoteOptions, sync.remoteName).catch( + error => error + ); + expect(res).not.toBeInstanceOf(Error); await destroyDBs([dbA]); @@ -144,7 +174,16 @@ maybe(' checkFetch', () => { await dbA.open(); const remoteUrl = remoteURLBase + 'test-private.git'; - await createGitRemote(dbA.workingDir, remoteUrl); + const remoteOptions = { + remoteUrl, + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + connection: { + type: 'github', + personalAccessToken: token, + } as ConnectionSettingsGitHub, + }; + const sync = new Sync(dbA, remoteOptions); + await createGitRemote(dbA.workingDir, remoteUrl, sync.remoteName); const stubRemote = sandbox.stub(git, 'getRemoteInfo2'); stubRemote.onCall(0).rejects(new Error('connect EACCES')); @@ -152,16 +191,61 @@ maybe(' checkFetch', () => { stubRemote.onCall(2).rejects(new Error('connect EACCES')); stubRemote.onCall(3).resolves(undefined); - const res = await checkFetch(dbA.workingDir, { - remoteUrl, - connection: { type: 'github', personalAccessToken: token }, - }).catch(error => error); + const res = await checkFetch(dbA.workingDir, remoteOptions, sync.remoteName).catch( + error => error + ); expect(res).not.toBeInstanceOf(Error); expect(stubRemote.callCount).toBe(4); await destroyDBs([dbA]); }); + + it('when fetch from multiple Sync instances', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = remoteURLBase + 'test-public.git'; + const remoteOptions = { + remoteUrl, + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + connection: { + type: 'github', + personalAccessToken: token, + } as ConnectionSettingsGitHub, + }; + const sync = new Sync(dbA, remoteOptions); + await createGitRemote(dbA.workingDir, remoteUrl, sync.remoteName); + + const res = await checkFetch(dbA.workingDir, remoteOptions, sync.remoteName).catch( + error => error + ); + expect(res).not.toBeInstanceOf(Error); + + const remoteUrl2 = remoteURLBase + 'test-public2.git'; + await destroyRemoteRepository(remoteUrl2); + await createRemoteRepository(remoteUrl2); + const remoteOptions2 = { + remoteUrl: remoteUrl2, + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + connection: { + type: 'github', + personalAccessToken: token, + } as ConnectionSettingsGitHub, + }; + const sync2 = new Sync(dbA, remoteOptions2); + await createGitRemote(dbA.workingDir, remoteUrl2, sync2.remoteName); + + const res2 = await checkFetch(dbA.workingDir, remoteOptions2, sync2.remoteName).catch( + error => error + ); + expect(res2).not.toBeInstanceOf(Error); + + await destroyDBs([dbA]); + }); }); it('throws NetworkError after retries', async () => { @@ -172,15 +256,23 @@ maybe(' checkFetch', () => { await dbA.open(); const remoteUrl = remoteURLBase + 'test-private.git'; - await createGitRemote(dbA.workingDir, remoteUrl); + const remoteOptions = { + remoteUrl, + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + connection: { + type: 'github', + personalAccessToken: token, + } as ConnectionSettingsGitHub, + }; + const sync = new Sync(dbA, remoteOptions); + await createGitRemote(dbA.workingDir, remoteUrl, sync.remoteName); const stubRemote = sandbox.stub(git, 'getRemoteInfo2'); stubRemote.rejects(new Error('connect EACCES')); - const res = await checkFetch(dbA.workingDir, { - remoteUrl, - connection: { type: 'github', personalAccessToken: token }, - }).catch(error => error); + const res = await checkFetch(dbA.workingDir, remoteOptions, sync.remoteName).catch( + error => error + ); expect(res).toBeInstanceOf(NetworkError); expect(stubRemote.callCount).toBe(4); @@ -209,7 +301,7 @@ maybe(' checkFetch', () => { }); await dbA.open(); const remoteUrl = 'foo-bar'; - await createGitRemote(dbA.workingDir, remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl, 'origin'); const err = await checkFetch(dbA.workingDir, { remoteUrl }).catch(error => error); expect(err).toBeInstanceOf(InvalidURLFormatError); @@ -225,7 +317,7 @@ maybe(' checkFetch', () => { }); await dbA.open(); const remoteUrl = 'https://foo.example.com:xxxx'; - await createGitRemote(dbA.workingDir, remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl, 'origin'); const err = await checkFetch(dbA.workingDir, { remoteUrl }).catch(error => error); expect(err).toBeInstanceOf(InvalidURLFormatError); expect(err.message).toMatch(/^URL format is invalid: Error: getaddrinfo ENOTFOUND/); @@ -241,7 +333,7 @@ maybe(' checkFetch', () => { await dbA.open(); const remoteUrl = 'https://foo.bar.example.com/gitddb-plugin/sync-test-invalid.git'; - await createGitRemote(dbA.workingDir, remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl, 'origin'); const err = await checkFetch(dbA.workingDir, { remoteUrl }).catch(error => error); expect(err).toBeInstanceOf(InvalidURLFormatError); expect(err.message).toMatch(/^URL format is invalid: Error: getaddrinfo ENOTFOUND/); @@ -258,7 +350,7 @@ maybe(' checkFetch', () => { await dbA.open(); const remoteUrl = 'https://127.0.0.1/gitddb-plugin/sync-test-invalid.git'; - await createGitRemote(dbA.workingDir, remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl, 'origin'); const err = await checkFetch(dbA.workingDir, { remoteUrl, connection: { @@ -281,7 +373,7 @@ maybe(' checkFetch', () => { await dbA.open(); const remoteUrl = remoteURLBase + 'test-private.git'; - await createGitRemote(dbA.workingDir, remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl, 'origin'); const err = await checkFetch(dbA.workingDir, { remoteUrl, connection: { type: 'github' }, @@ -302,7 +394,7 @@ maybe(' checkFetch', () => { const remoteUrl = remoteURLBase + 'test-private.git'; - await createGitRemote(dbA.workingDir, remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl, 'origin'); const err = await checkFetch(dbA.workingDir, { remoteUrl }).catch(error => error); expect(err).toBeInstanceOf(HTTPError401AuthorizationRequired); @@ -319,7 +411,7 @@ maybe(' checkFetch', () => { await dbA.open(); const remoteUrl = remoteURLBase + 'test-private.git'; - await createGitRemote(dbA.workingDir, remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl, 'origin'); const err = await checkFetch(dbA.workingDir, { remoteUrl, connection: { type: 'github', personalAccessToken: 'foo-bar' }, @@ -341,7 +433,7 @@ maybe(' checkFetch', () => { await dbA.open(); const remoteUrl = remoteURLBase + 'sync-test-invalid.git'; - await createGitRemote(dbA.workingDir, remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl, 'origin'); const err = await checkFetch(dbA.workingDir, { remoteUrl, connection: { type: 'github', personalAccessToken: token }, @@ -360,7 +452,7 @@ maybe(' checkFetch', () => { }); await dbA.open(); const remoteUrl = 'foo-bar'; - await createGitRemote(dbA.workingDir, remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl, 'origin'); const err = await checkFetch(dbA.workingDir, { remoteUrl, connection: { type: 'github', personalAccessToken: token }, @@ -381,7 +473,7 @@ maybe(' checkFetch', () => { await dbA.open(); const remoteUrl = remoteURLBase + 'foo/bar/test.git'; - await createGitRemote(dbA.workingDir, remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl, 'origin'); await expect( checkFetch(dbA.workingDir, { remoteUrl, @@ -400,7 +492,7 @@ maybe(' checkFetch', () => { await dbA.open(); const remoteUrl = remoteURLBase + 'test-private.git'; - await createGitRemote(dbA.workingDir, remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl, 'origin'); await expect( // @ts-ignore checkFetch(dbA.workingDir, { remoteUrl, connection: { type: 'foo' } }) @@ -417,7 +509,7 @@ maybe(' checkFetch', () => { await dbA.open(); const remoteUrl = 'git@foo.example.com:bar/sync-test.git'; - await createGitRemote(dbA.workingDir, remoteUrl); + await createGitRemote(dbA.workingDir, remoteUrl, 'origin'); await expect( checkFetch(dbA.workingDir, { remoteUrl, diff --git a/test/internal_plugin/fetch.test.ts b/test/internal_plugin/fetch.test.ts index 6dac5337..4217ffcb 100644 --- a/test/internal_plugin/fetch.test.ts +++ b/test/internal_plugin/fetch.test.ts @@ -23,7 +23,13 @@ import { import sinon from 'sinon'; import { GitDocumentDB } from '../../src/git_documentdb'; import { fetch } from '../../src/plugin/remote-isomorphic-git'; -import { createGitRemote, destroyDBs, removeRemoteRepositories } from '../remote_utils'; +import { + createGitRemote, + createRemoteRepository, + destroyDBs, + destroyRemoteRepository, + removeRemoteRepositories, +} from '../remote_utils'; import { Sync } from '../../src/remote/sync'; import { ConnectionSettingsGitHub } from '../../src/types'; @@ -64,6 +70,8 @@ after(() => { * GITDDB_PERSONAL_ACCESS_TOKEN: The personal access token of your GitHub account * GitHub repositories: * remoteURLBase + 'test-private.git' must be a private repository. + * remoteURLBase + 'test-public.git' must be a public repository. + * remoteURLBase + 'test-public2.git' must be a public repository. */ const userHome = process.env[process.platform === 'win32' ? 'USERPROFILE' : 'HOME'] ?? ''; @@ -216,6 +224,39 @@ maybe(' fetch', () => { await destroyDBs([dbA]); }); + it('when fetch from empty repository', async () => { + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + + const remoteUrl = remoteURLBase + serialId(); + await destroyRemoteRepository(remoteUrl).catch(() => {}); + await createRemoteRepository(remoteUrl); + const remoteOptions = { + remoteUrl, + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + connection: { + type: 'github', + personalAccessToken: token, + } as ConnectionSettingsGitHub, + }; + const sync = new Sync(dbA, remoteOptions); + await createGitRemote(dbA.workingDir, remoteUrl, sync.remoteName); + + const res = await fetch( + dbA.workingDir, + remoteOptions, + sync.remoteName, + dbA.defaultBranch, + dbA.defaultBranch + ).catch(error => error); + expect(res).toBeUndefined(); + + await destroyDBs([dbA]); + }); + it('when fetch from multiple Sync instances', async () => { const dbA: GitDocumentDB = new GitDocumentDB({ dbName: serialId(), @@ -227,7 +268,10 @@ maybe(' fetch', () => { const remoteOptions = { remoteUrl, // eslint-disable-next-line @typescript-eslint/consistent-type-assertions - connection: { type: 'github' } as ConnectionSettingsGitHub, + connection: { + type: 'github', + personalAccessToken: token, + } as ConnectionSettingsGitHub, }; const sync = new Sync(dbA, remoteOptions); await createGitRemote(dbA.workingDir, remoteUrl, sync.remoteName); @@ -241,6 +285,29 @@ maybe(' fetch', () => { ).catch(error => error); expect(res).toBeUndefined(); + const remoteUrl2 = remoteURLBase + 'test-public2.git'; + await destroyRemoteRepository(remoteUrl2); + await createRemoteRepository(remoteUrl2); + const remoteOptions2 = { + remoteUrl: remoteUrl2, + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + connection: { + type: 'github', + personalAccessToken: token, + } as ConnectionSettingsGitHub, + }; + const sync2 = new Sync(dbA, remoteOptions2); + await createGitRemote(dbA.workingDir, remoteUrl2, sync2.remoteName); + + const res2 = await fetch( + dbA.workingDir, + remoteOptions2, + sync2.remoteName, + dbA.defaultBranch, + dbA.defaultBranch + ).catch(error => error); + expect(res2).toBeUndefined(); + await destroyDBs([dbA]); }); }); diff --git a/test/remote_base/sync.ts b/test/remote_base/sync.ts index ec2a2673..fbeede64 100644 --- a/test/remote_base/sync.ts +++ b/test/remote_base/sync.ts @@ -356,8 +356,8 @@ export const syncBase = ( remoteUrl: remoteURL, connection, }; - const stubCheckFetch = sandbox.stub(RemoteEngine[connection.engine!], 'checkFetch'); - stubCheckFetch.onFirstCall().rejects(new RemoteEngineErr.InvalidURLFormatError('')); + const stubFetch = sandbox.stub(RemoteEngine[connection.engine!], 'fetch'); + stubFetch.onFirstCall().rejects(new RemoteEngineErr.InvalidURLFormatError('')); const sync = new Sync(gitDDB, options); await expect(sync.init()).rejects.toThrowError(RemoteErr.InvalidURLFormatError); @@ -377,10 +377,8 @@ export const syncBase = ( remoteUrl: remoteURL, connection, }; - const stubCheckFetch = sandbox.stub(RemoteEngine[connection.engine!], 'checkFetch'); - stubCheckFetch - .onFirstCall() - .rejects(new RemoteEngineErr.InvalidRepositoryURLError('')); + const stubFetch = sandbox.stub(RemoteEngine[connection.engine!], 'fetch'); + stubFetch.onFirstCall().rejects(new RemoteEngineErr.InvalidRepositoryURLError('')); const sync = new Sync(gitDDB, options); await expect(sync.init()).rejects.toThrowError(RemoteErr.InvalidRepositoryURLError); @@ -400,8 +398,8 @@ export const syncBase = ( remoteUrl: remoteURL, connection, }; - const stubCheckFetch = sandbox.stub(RemoteEngine[connection.engine!], 'checkFetch'); - stubCheckFetch.onFirstCall().rejects(new RemoteEngineErr.InvalidSSHKeyPathError()); + const stubFetch = sandbox.stub(RemoteEngine[connection.engine!], 'fetch'); + stubFetch.onFirstCall().rejects(new RemoteEngineErr.InvalidSSHKeyPathError()); const sync = new Sync(gitDDB, options); await expect(sync.init()).rejects.toThrowError(RemoteErr.InvalidSSHKeyPathError); @@ -421,8 +419,8 @@ export const syncBase = ( remoteUrl: remoteURL, connection, }; - const stubCheckFetch = sandbox.stub(RemoteEngine[connection.engine!], 'checkFetch'); - stubCheckFetch + const stubFetch = sandbox.stub(RemoteEngine[connection.engine!], 'fetch'); + stubFetch .onFirstCall() .rejects(new RemoteEngineErr.InvalidAuthenticationTypeError('')); @@ -446,8 +444,8 @@ export const syncBase = ( remoteUrl: remoteURL, connection, }; - const stubCheckFetch = sandbox.stub(RemoteEngine[connection.engine!], 'checkFetch'); - stubCheckFetch + const stubFetch = sandbox.stub(RemoteEngine[connection.engine!], 'fetch'); + stubFetch .onFirstCall() .rejects(new RemoteEngineErr.HTTPError401AuthorizationRequired('')); @@ -471,8 +469,8 @@ export const syncBase = ( remoteUrl: remoteURL, connection, }; - const stubCheckFetch = sandbox.stub(RemoteEngine[connection.engine!], 'checkFetch'); - stubCheckFetch.rejects(new RemoteEngineErr.NetworkError('')); + const stubFetch = sandbox.stub(RemoteEngine[connection.engine!], 'fetch'); + stubFetch.rejects(new RemoteEngineErr.NetworkError('')); const sync = new Sync(gitDDB, options); diff --git a/test/remote_base/sync_live.ts b/test/remote_base/sync_live.ts index 8674de92..9a457c56 100644 --- a/test/remote_base/sync_live.ts +++ b/test/remote_base/sync_live.ts @@ -190,6 +190,7 @@ export const syncLiveBase = ( dbName: dbNameA, localDir: localDir, }); + dbA.logLevel = 'trace'; const interval = MINIMUM_SYNC_INTERVAL; const options: RemoteOptions = { remoteUrl: remoteURL, diff --git a/test/remote_utils.ts b/test/remote_utils.ts index 9bc7dd84..a29b8b44 100644 --- a/test/remote_utils.ts +++ b/test/remote_utils.ts @@ -265,10 +265,7 @@ export const destroyRemoteRepository = async (remoteURL: string) => { }, }) .destroy() - .catch(err => { - console.debug('Cannot delete: ' + remoteURL); - console.debug(err); - }); + .catch(() => {}); }; export async function removeRemoteRepositories (reposPrefix: string) { From 5e7cbdd5e5246766a058242afffea07d485b5d86 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 4 Aug 2021 04:20:26 +0900 Subject: [PATCH 139/297] remote unused block --- src/plugin/remote-isomorphic-git.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/plugin/remote-isomorphic-git.ts b/src/plugin/remote-isomorphic-git.ts index e917ec2c..1e9adae4 100644 --- a/src/plugin/remote-isomorphic-git.ts +++ b/src/plugin/remote-isomorphic-git.ts @@ -461,9 +461,6 @@ export async function push ( throw new InvalidGitRemoteError(`remote '${remoteName}' does not exist`); } - // const localBranch = 'refs/heads/' + localBranchName; - // const remoteBranch = 'refs/heads/' + remoteBranchName; - remoteOptions.retry ??= NETWORK_RETRY; remoteOptions.retryInterval ??= NETWORK_RETRY_INTERVAL; From 2cdd2f4620aefbf044c163bd948ac66b6a01dcb1 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 4 Aug 2021 04:21:08 +0900 Subject: [PATCH 140/297] build: bump git-documentdb-plugin-remote-nodegit to v1.0.3 --- package-lock.json | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 87ac4f4b..1b5907c0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3528,9 +3528,9 @@ "dev": true }, "git-documentdb-plugin-remote-nodegit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.1.tgz", - "integrity": "sha512-KXkRQZXGHqeyp6yG4hm4h3hiecWRv6GqlK227oITwC0uBZ222IMpPkEF0S6MDkhZaPAbiFiKsS4U7Fr0WMx4Fg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.3.tgz", + "integrity": "sha512-80cxPE+jIjDpECCXAmNtjZxMFVNc38yFkZmEd3hRp6EvSQhX6nky0kmEFWZ1aeFnTq0oATEJvEJg9yO8zYkyng==", "dev": true, "requires": { "git-documentdb-remote-errors": "^1.0.3", diff --git a/package.json b/package.json index 1aaae8d1..230402a5 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ "eslint-config-standardize": "^0.7.1", "eslint-plugin-prettierx": "^0.14.0", "expect": "^27.0.2", - "git-documentdb-plugin-remote-nodegit": "^1.0.1", + "git-documentdb-plugin-remote-nodegit": "^1.0.3", "mocha": "^8.3.2", "nyc": "^15.1.0", "parse-git-config": "^3.0.0", From 0659a72935341af4622bde43ea93fa9b7e4cdb55 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 4 Aug 2021 04:21:43 +0900 Subject: [PATCH 141/297] debugging examples/src/plugin.ts --- examples/package-lock.json | 6 ++-- examples/package.json | 2 +- examples/src/plugin.ts | 59 +++++++++++++++++++------------------- 3 files changed, 33 insertions(+), 34 deletions(-) diff --git a/examples/package-lock.json b/examples/package-lock.json index b3299269..8c7901b1 100644 --- a/examples/package-lock.json +++ b/examples/package-lock.json @@ -7531,9 +7531,9 @@ } }, "git-documentdb-plugin-remote-nodegit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.1.tgz", - "integrity": "sha512-KXkRQZXGHqeyp6yG4hm4h3hiecWRv6GqlK227oITwC0uBZ222IMpPkEF0S6MDkhZaPAbiFiKsS4U7Fr0WMx4Fg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.3.tgz", + "integrity": "sha512-80cxPE+jIjDpECCXAmNtjZxMFVNc38yFkZmEd3hRp6EvSQhX6nky0kmEFWZ1aeFnTq0oATEJvEJg9yO8zYkyng==", "requires": { "git-documentdb-remote-errors": "^1.0.3", "nodegit": "^0.27.0", diff --git a/examples/package.json b/examples/package.json index 81aca231..ca8c15fb 100644 --- a/examples/package.json +++ b/examples/package.json @@ -14,7 +14,7 @@ "license": "MPL-2.0", "dependencies": { "git-documentdb": "file:..", - "git-documentdb-plugin-remote-nodegit": "^1.0.1" + "git-documentdb-plugin-remote-nodegit": "^1.0.3" }, "devDependencies": { "typescript": "^4.1.3" diff --git a/examples/src/plugin.ts b/examples/src/plugin.ts index b1bcfefd..c09d18b6 100644 --- a/examples/src/plugin.ts +++ b/examples/src/plugin.ts @@ -8,8 +8,30 @@ import { GitDocumentDB, RemoteOptions } from 'git-documentdb'; import { sleep } from './utils'; +/** + * This example assumes you have an account on GitHub. + * Please get your personal access token with checked [repo]. + * (See https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token ) + */ +let github_repository = 'https://github.com/enter_your_account_name/git-documentdb-example-sync.git'; +let github_repository2 = 'https://github.com/enter_your_account_name/git-documentdb-example-sync2.git'; +let your_github_personal_access_token = 'Enter your personal access token with checked [repo]'; +/** + * You can also set them from environment variables: + * - GITDDB_GITHUB_USER_URL + * URL of your GitHub account + * e.g.) https://github.com/foo/ + * - GITDDB_PERSONAL_ACCESS_TOKEN + * A personal access token of your GitHub account + */ +if (process.env.GITDDB_GITHUB_USER_URL) github_repository = process.env.GITDDB_GITHUB_USER_URL + 'git-documentdb-example-sync.git'; +if (process.env.GITDDB_GITHUB_USER_URL) github_repository2 = process.env.GITDDB_GITHUB_USER_URL + 'git-documentdb-example-sync2.git'; +if (process.env.GITDDB_PERSONAL_ACCESS_TOKEN) your_github_personal_access_token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN; -// Load NodeGit plugin to connect remote repository + +/** + * Load NodeGit remote engine plugin to connect remote repository + */ GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); const remote_plugin_example = async () => { @@ -19,32 +41,7 @@ const remote_plugin_example = async () => { await gitDDB.open(); await gitDDB.put({ name: 'foo'}); - /** - * This example assumes you have an account on GitHub. - * Please get your personal access token with checked [repo]. - * (See https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token ) - */ - let github_repository = 'https://github.com/enter_your_account_name/git-documentdb-example-sync.git'; - let github_repository2 = 'https://github.com/enter_your_account_name/git-documentdb-example-sync2.git'; - let your_github_personal_access_token = 'Enter your personal access token with checked [repo]'; - /** - * You can also set them from environment variables: - * - GITDDB_GITHUB_USER_URL - * URL of your GitHub account - * e.g.) https://github.com/foo/ - * - GITDDB_PERSONAL_ACCESS_TOKEN - * A personal access token of your GitHub account - */ - if (process.env.GITDDB_GITHUB_USER_URL) github_repository = process.env.GITDDB_GITHUB_USER_URL + 'git-documentdb-example-sync.git'; - if (process.env.GITDDB_GITHUB_USER_URL) github_repository2 = process.env.GITDDB_GITHUB_USER_URL + 'git-documentdb-example-sync2.git'; - if (process.env.GITDDB_PERSONAL_ACCESS_TOKEN) your_github_personal_access_token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN; - // @ts-ignore - if (your_github_personal_access_token === 'Enter your personal access token with checked [repo]') { - console.log('Please set your personal access token.'); - return; - } - - // Use default engine (isomorphic-git) + // Use default remote engine (isomorphic-git) const remoteOptionsDefault: RemoteOptions = { live: true, remoteUrl: github_repository, @@ -54,12 +51,13 @@ const remote_plugin_example = async () => { personalAccessToken: your_github_personal_access_token, }, }; + // Add default synchronize to DB const syncDefault = await gitDDB.sync(remoteOptionsDefault); console.log('## Default RemoteEngine: ' + syncDefault.engine); syncDefault.on('start', () => { console.log('[default] synchronizing...')}); syncDefault.on('complete', () => { console.log('[default] completed')}); - // Set NodeGit engine + // Set NodeGit remote engine plugin const remoteOptionsNodeGit: RemoteOptions = { live: true, remoteUrl: github_repository2, @@ -67,12 +65,13 @@ const remote_plugin_example = async () => { connection: { type: 'github', personalAccessToken: your_github_personal_access_token, - //engine: 'nodegit' + engine: 'nodegit' }, }; + // Add extra synchronizer to DB const syncNodeGit= await gitDDB.sync(remoteOptionsNodeGit); - console.log('## Current RemoteEngine: ' + syncNodeGit.engine); + console.log('## Plugin RemoteEngine: ' + syncNodeGit.engine); syncNodeGit.on('start', () => { console.log('[NodeGit] synchronizing...')}); syncNodeGit.on('complete', () => { console.log('[NodeGit] completed')}); From e47b223ebc9a0c455795cfd792fa16f815469970 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 4 Aug 2021 12:36:08 +0900 Subject: [PATCH 142/297] debugging examples/src/plugin.ts --- .vscode/launch.json | 2 +- package.json | 2 +- src/remote/sync.ts | 12 ++++++++---- test/remote_base/sync.ts | 35 ++++++++++++++++++++++++++++++++++- test_plugin/tsconfig.json | 6 ++++++ 5 files changed, 50 insertions(+), 7 deletions(-) create mode 100644 test_plugin/tsconfig.json diff --git a/.vscode/launch.json b/.vscode/launch.json index c98ed1f4..0864e33c 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,7 +4,7 @@ "type": "pickString", "id": "choice", "description": "select a file", - "options": ["test/remote_nodegit/sync.test.js"], + "options": ["test_plugin/remote_nodegit/sync.test.js"], }], "configurations": [ { diff --git a/package.json b/package.json index 230402a5..2ff49728 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "mocha": "npm run rm-test-db && npx cross-env TS_NODE_FILES=true TS_NODE_PROJECT=tsconfig.mocha.json mocha", "mocha-unit-parallel": "npm run rm-test-db && npx cross-env TS_NODE_FILES=true TS_NODE_PROJECT=tsconfig.mocha.json mocha --retries 0", "mocha-unit": "npm run rm-test-db && npx cross-env TS_NODE_FILES=true TS_NODE_PROJECT=tsconfig.mocha.json mocha --retries 0 --no-parallel", - "compile-tests": "tsc --project test/tsconfig.json", + "compile-tests": "tsc --project test/tsconfig.json && tsc --project test_plugin/tsconfig.json ", "rm-test-db": "rm -rf test/database* test_plugin/database*", "test": "npx nyc npm run mocha \"test/**/*.test.ts\" && npm run rm-test-db", "test-plugin": "npm run mocha \"test_plugin/**/*.test.ts\" && npm run rm-test-db", diff --git a/src/remote/sync.ts b/src/remote/sync.ts index c1cf247d..79efec23 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -480,7 +480,9 @@ export class Sync implements SyncInterface { } let remoteResult: boolean | Error; - if (this._options === 'push') { + if (this._options.syncDirection === 'push') { + // Will return undefined + // Do not download remote. // eslint-disable-next-line no-await-in-loop remoteResult = await RemoteEngine[this._engine] @@ -493,6 +495,8 @@ export class Sync implements SyncInterface { .catch(err => err); } else { + // Will return true + // eslint-disable-next-line no-await-in-loop remoteResult = await RemoteEngine[this._engine] .fetch( @@ -506,7 +510,7 @@ export class Sync implements SyncInterface { .catch(err => err); } - if (typeof remoteResult === 'boolean') { + if (typeof remoteResult === 'boolean' || remoteResult === undefined) { // nop } else if (remoteResult instanceof RemoteEngineError.InvalidGitRemoteError) { @@ -536,7 +540,7 @@ export class Sync implements SyncInterface { let syncResult: SyncResult = { action: 'nop', }; - if (this._options === 'pull') { + if (this._options.syncDirection === 'pull') { // Do not create a new remote repository because the direction is 'pull'. /** * TODO: Implement case when sync_direction is 'pull'. @@ -544,7 +548,7 @@ export class Sync implements SyncInterface { } else { // push or both - if (this._options === 'both') { + if (this._options.syncDirection === 'both') { // Check remote branch after fetching. const remoteCommitOid = await git .resolveRef({ diff --git a/test/remote_base/sync.ts b/test/remote_base/sync.ts index fbeede64..b7522f1e 100644 --- a/test/remote_base/sync.ts +++ b/test/remote_base/sync.ts @@ -893,5 +893,38 @@ export const syncBase = ( }); }); - it.skip('Multiple Sync object'); + it('Multiple Sync object', async () => { + const gitDDB = new GitDocumentDB({ + dbName: 'db_plugin', // Git working directory + }); + await gitDDB.open(); + await gitDDB.put({ name: 'foo' }); + + const remoteOptions01: RemoteOptions = { + live: true, + remoteUrl: remoteURLBase + serialId(), + interval: 5000, // Sync every 5,000 msec + connection: { + type: 'github', + personalAccessToken: token, + }, + }; + + const sync01 = await gitDDB.sync(remoteOptions01); + + const remoteOptions02: RemoteOptions = { + live: true, + remoteUrl: remoteURLBase + serialId(), + interval: 5000, // Sync every 5,000 msec + connection: { + type: 'github', + personalAccessToken: token, + }, + }; + // Add extra synchronizer to DB + const sync02 = await gitDDB.sync(remoteOptions02); + expect(sync02).toBeInstanceOf(Sync); + + await gitDDB.destroy(); + }); }; diff --git a/test_plugin/tsconfig.json b/test_plugin/tsconfig.json new file mode 100644 index 00000000..607d44fc --- /dev/null +++ b/test_plugin/tsconfig.json @@ -0,0 +1,6 @@ +{ + "extends": "../tsconfig-base", + "include": [ + "**/*", + ], +} \ No newline at end of file From cdbaf22c63a4074de9c2a7535559670060bddd84 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 4 Aug 2021 14:27:50 +0900 Subject: [PATCH 143/297] docs: add comment --- src/remote/sync.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/remote/sync.ts b/src/remote/sync.ts index 79efec23..b0874078 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -481,7 +481,7 @@ export class Sync implements SyncInterface { let remoteResult: boolean | Error; if (this._options.syncDirection === 'push') { - // Will return undefined + // checkFetch will return undefined if succeeds. // Do not download remote. // eslint-disable-next-line no-await-in-loop @@ -495,7 +495,7 @@ export class Sync implements SyncInterface { .catch(err => err); } else { - // Will return true + // fetch will return true if succeeds. // eslint-disable-next-line no-await-in-loop remoteResult = await RemoteEngine[this._engine] From d0a8176a6268c99116052c1c2723208fb2f1042d Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 4 Aug 2021 14:28:31 +0900 Subject: [PATCH 144/297] fix: sort localChanges and remoteChanges --- src/remote/3way_merge.ts | 25 +++++++++++++++++++++++++ test/remote_base/sync.ts | 2 +- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/remote/3way_merge.ts b/src/remote/3way_merge.ts index ee9e353d..000014a6 100644 --- a/src/remote/3way_merge.ts +++ b/src/remote/3way_merge.ts @@ -295,6 +295,31 @@ export async function merge ( const mergedTreeOid = results.oid; + // Entries in walk are traversed in alphabetical order + // (https://isomorphic-git.org/docs/en/walk), + // but sometimes the order collapse. + + // eslint-disable-next-line complexity + const sortChangedFile = (a: ChangedFile, b: ChangedFile) => { + if (a.operation === 'insert' && b.operation === 'insert') { + if (a.new.name > b.new.name) return 1; + if (a.new.name < b.new.name) return -1; + return 0; + } + else if ( + (a.operation === 'update' || a.operation === 'delete') && + (b.operation === 'update' || b.operation === 'delete') + ) { + if (a.old.name > b.old.name) return 1; + if (a.old.name < b.old.name) return -1; + return 0; + } + // This line must not be reached. + return 0; + }; + localChanges.sort(sortChangedFile); + remoteChanges.sort(sortChangedFile); + return [mergedTreeOid, localChanges, remoteChanges, acceptedConflicts]; } diff --git a/test/remote_base/sync.ts b/test/remote_base/sync.ts index b7522f1e..5d390b8d 100644 --- a/test/remote_base/sync.ts +++ b/test/remote_base/sync.ts @@ -838,7 +838,7 @@ export const syncBase = ( syncDirection: 'pull', }; const sync = new Sync(gitDDB, options); - await expect(sync.init()).rejects.toThrowError(Err.PushNotAllowedError); + await expect(sync.init()).resolves.toEqual({ action: 'nop' }); await gitDDB.destroy(); }); From fbf038d89e1c8554e35a3ea9248f2ff879092db0 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 4 Aug 2021 18:06:01 +0900 Subject: [PATCH 145/297] fix: do not use instanceof to check errors from remote plugin --- src/remote/sync.ts | 27 +++++++++++++++++---------- test/remote_base/sync.ts | 2 +- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/remote/sync.ts b/src/remote/sync.ts index b0874078..f1eb2632 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -13,7 +13,6 @@ import { clearInterval, setInterval } from 'timers'; import crypto from 'crypto'; import git from 'isomorphic-git'; import fs from 'fs-extra'; -import * as RemoteEngineError from 'git-documentdb-remote-errors'; import { name as default_engine_name } from '../plugin/remote-isomorphic-git'; import { CONSOLE_STYLE, sleep } from '../utils'; @@ -510,25 +509,33 @@ export class Sync implements SyncInterface { .catch(err => err); } + /** + * Do not use 'instanceof' to compare git-documentdb-remote-errors + * because an error from RemoteEngine plugin may not have the same prototype + * in its prototype chain. + * - https://nodejs.org/en/blog/npm/peer-dependencies/ + * - https://stackoverflow.com/questions/46618852/require-and-instanceof/46630766 + * Use name property instead. + */ if (typeof remoteResult === 'boolean' || remoteResult === undefined) { // nop } - else if (remoteResult instanceof RemoteEngineError.InvalidGitRemoteError) { + else if (remoteResult.name === 'InvalidGitRemoteError') { // checkFetch hardly invoke this error because checkFetch is called just after addRemote. throw wrappingRemoteEngineError(remoteResult); } else if ( - remoteResult instanceof RemoteEngineError.InvalidURLFormatError || - remoteResult instanceof RemoteEngineError.InvalidRepositoryURLError || - remoteResult instanceof RemoteEngineError.InvalidSSHKeyPathError || - remoteResult instanceof RemoteEngineError.InvalidAuthenticationTypeError || - remoteResult instanceof RemoteEngineError.HTTPError401AuthorizationRequired || - remoteResult instanceof RemoteEngineError.NetworkError || - remoteResult instanceof RemoteEngineError.CannotConnectError + remoteResult.name === 'InvalidURLFormatError' || + remoteResult.name === 'InvalidRepositoryURLError' || + remoteResult.name === 'InvalidSSHKeyPathError' || + remoteResult.name === 'InvalidAuthenticationTypeError' || + remoteResult.name === 'HTTPError401AuthorizationRequired' || + remoteResult.name === 'NetworkError' || + remoteResult.name === 'CannotConnectError' ) { throw wrappingRemoteEngineError(remoteResult); } - else if (remoteResult instanceof RemoteEngineError.HTTPError404NotFound) { + else if (remoteResult.name === 'HTTPError404NotFound') { // Try to create repository by octokit // eslint-disable-next-line no-await-in-loop await this.remoteRepository.create().catch(err => { diff --git a/test/remote_base/sync.ts b/test/remote_base/sync.ts index 5d390b8d..3e2aa4c0 100644 --- a/test/remote_base/sync.ts +++ b/test/remote_base/sync.ts @@ -895,7 +895,7 @@ export const syncBase = ( it('Multiple Sync object', async () => { const gitDDB = new GitDocumentDB({ - dbName: 'db_plugin', // Git working directory + dbName: serialId(), }); await gitDDB.open(); await gitDDB.put({ name: 'foo' }); From bb085e198dc40d39239c1259c9aec45574a0698a Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 4 Aug 2021 18:06:51 +0900 Subject: [PATCH 146/297] build: package-lock.json for examples are updated --- examples/package-lock.json | 39 +++++++++----------------------------- 1 file changed, 9 insertions(+), 30 deletions(-) diff --git a/examples/package-lock.json b/examples/package-lock.json index 8c7901b1..3f4bcaba 100644 --- a/examples/package-lock.json +++ b/examples/package-lock.json @@ -1307,9 +1307,9 @@ } }, "@szmarczak/http-timer": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.5.tgz", - "integrity": "sha512-PyRA9sm1Yayuj5OIoJ1hGt2YISX45w9WcFbh6ddT0Z/0yaFxOtGLInr4jUfU1EAFVs0Yfyfev4RNwBlUaHdlDQ==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", "requires": { "defer-to-connect": "^2.0.0" } @@ -1353,13 +1353,6 @@ "@types/keyv": "*", "@types/node": "*", "@types/responselike": "*" - }, - "dependencies": { - "@types/node": { - "version": "16.3.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.3.1.tgz", - "integrity": "sha512-N87VuQi7HEeRJkhzovao/JviiqKjDKMVKxKMfUvSKw+MbkbW8R0nA3fi/MQhhlxV2fQ+2ReM+/Nt4efdrJx3zA==" - } } }, "@types/expect": { @@ -1425,13 +1418,6 @@ "integrity": "sha512-/FvAK2p4jQOaJ6CGDHJTqZcUtbZe820qIeTg7o0Shg7drB4JHeL+V/dhSaly7NXx6u8eSee+r7coT+yuJEvDLg==", "requires": { "@types/node": "*" - }, - "dependencies": { - "@types/node": { - "version": "16.3.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.3.1.tgz", - "integrity": "sha512-N87VuQi7HEeRJkhzovao/JviiqKjDKMVKxKMfUvSKw+MbkbW8R0nA3fi/MQhhlxV2fQ+2ReM+/Nt4efdrJx3zA==" - } } }, "@types/minimatch": { @@ -1470,13 +1456,6 @@ "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", "requires": { "@types/node": "*" - }, - "dependencies": { - "@types/node": { - "version": "16.3.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.3.1.tgz", - "integrity": "sha512-N87VuQi7HEeRJkhzovao/JviiqKjDKMVKxKMfUvSKw+MbkbW8R0nA3fi/MQhhlxV2fQ+2ReM+/Nt4efdrJx3zA==" - } } }, "@types/rimraf": { @@ -3617,9 +3596,9 @@ "integrity": "sha512-qc8h1KIQbJpp+241id3GuAtkdyJ+IK+LIVtkiFTRKRrmddDzs3SI9CvP1QYmWBFvm1I/PWRwj//of8bgAc0ltA==" }, "git-documentdb-plugin-remote-nodegit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.0.tgz", - "integrity": "sha512-fZLcid1l2aMZ1aGHJC3/H0tDY3wrpK1R2YjuHGODlRsxJmupFUa/+63P+4qUepHc+HcmuHP3n8ucbxamlGQThQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.3.tgz", + "integrity": "sha512-80cxPE+jIjDpECCXAmNtjZxMFVNc38yFkZmEd3hRp6EvSQhX6nky0kmEFWZ1aeFnTq0oATEJvEJg9yO8zYkyng==", "requires": { "git-documentdb-remote-errors": "^1.0.3", "nodegit": "^0.27.0", @@ -6878,9 +6857,9 @@ } }, "tar": { - "version": "4.4.13", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", - "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", + "version": "4.4.15", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.15.tgz", + "integrity": "sha512-ItbufpujXkry7bHH9NpQyTXPbJ72iTlXgkBAYsAjDXk3Ds8t/3NfO5P4xZGy7u+sYuQUbimgzswX4uQIEeNVOA==", "requires": { "chownr": "^1.1.1", "fs-minipass": "^1.2.5", From c77adf5cc7c952a59383b65a60c963e4dab191df Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 4 Aug 2021 19:11:26 +0900 Subject: [PATCH 147/297] fix: do not use instanceof to check git-documentdb-remote-errors --- src/remote/remote_engine.ts | 62 +++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/src/remote/remote_engine.ts b/src/remote/remote_engine.ts index 4f51557d..fb627301 100644 --- a/src/remote/remote_engine.ts +++ b/src/remote/remote_engine.ts @@ -1,7 +1,6 @@ /* eslint-disable unicorn/custom-error-definition */ /* eslint-disable @typescript-eslint/naming-convention */ import { Logger } from 'tslog'; -import * as RemoteErrors from 'git-documentdb-remote-errors'; import { RemoteOptions } from '../types'; /** @@ -50,6 +49,14 @@ export interface RemoteEngineInterface { ) => Promise; } +export class BaseError extends Error { + constructor (e: string) { + super(e); + this.name = new.target.name; + Object.setPrototypeOf(this, new.target.prototype); + } +} + /** * RemoteError * @@ -59,69 +66,69 @@ export namespace RemoteErr { /** * Copy error message from parent */ - export class CannotConnectError extends RemoteErrors.CannotConnectError { + export class CannotConnectError extends BaseError { constructor (mes: unknown) { super(''); this.message = mes as string; } } - export class HTTPError401AuthorizationRequired extends RemoteErrors.HTTPError401AuthorizationRequired { + export class HTTPError401AuthorizationRequired extends BaseError { constructor (mes: unknown) { super(''); this.message = mes as string; } } - export class HTTPError403Forbidden extends RemoteErrors.HTTPError403Forbidden { + export class HTTPError403Forbidden extends BaseError { constructor (mes: unknown) { super(''); this.message = mes as string; } } - export class HTTPError404NotFound extends RemoteErrors.HTTPError404NotFound { + export class HTTPError404NotFound extends BaseError { constructor (mes: unknown) { super(''); this.message = mes as string; } } - export class InvalidAuthenticationTypeError extends RemoteErrors.InvalidAuthenticationTypeError { + export class InvalidAuthenticationTypeError extends BaseError { constructor (mes: unknown) { super(''); this.message = mes as string; } } - export class InvalidGitRemoteError extends RemoteErrors.InvalidGitRemoteError { + export class InvalidGitRemoteError extends BaseError { constructor (mes: unknown) { super(''); this.message = mes as string; } } - export class InvalidRepositoryURLError extends RemoteErrors.InvalidRepositoryURLError { + export class InvalidRepositoryURLError extends BaseError { constructor (mes: unknown) { super(''); this.message = mes as string; } } - export class InvalidSSHKeyPathError extends RemoteErrors.InvalidSSHKeyPathError { + export class InvalidSSHKeyPathError extends BaseError { constructor (mes: unknown) { - super(); + super(''); this.message = mes as string; } } - export class InvalidURLFormatError extends RemoteErrors.InvalidURLFormatError { + export class InvalidURLFormatError extends BaseError { constructor (mes: unknown) { super(''); this.message = mes as string; } } - export class NetworkError extends RemoteErrors.NetworkError { + export class NetworkError extends BaseError { constructor (mes: unknown) { super(''); this.message = mes as string; } } - export class UnfetchedCommitExistsError extends RemoteErrors.UnfetchedCommitExistsError { + export class UnfetchedCommitExistsError extends BaseError { constructor (mes: unknown) { - super(); + super(''); this.message = mes as string; } } @@ -133,29 +140,30 @@ export namespace RemoteErr { * @public */ // eslint-disable-next-line complexity -export function wrappingRemoteEngineError (remoteEngineError: RemoteErrors.BaseError) { - switch (true) { - case remoteEngineError instanceof RemoteErrors.CannotConnectError: +export function wrappingRemoteEngineError (remoteEngineError: BaseError) { + // Do not use 'instanceof' to compare git-documentdb-remote-errors + switch (remoteEngineError.name) { + case 'CannotConnectError': return new RemoteErr.CannotConnectError(remoteEngineError.message); - case remoteEngineError instanceof RemoteErrors.HTTPError401AuthorizationRequired: + case 'HTTPError401AuthorizationRequired': return new RemoteErr.HTTPError401AuthorizationRequired(remoteEngineError.message); - case remoteEngineError instanceof RemoteErrors.HTTPError403Forbidden: + case 'HTTPError403Forbidden': return new RemoteErr.HTTPError403Forbidden(remoteEngineError.message); - case remoteEngineError instanceof RemoteErrors.HTTPError404NotFound: + case 'HTTPError404NotFound': return new RemoteErr.HTTPError404NotFound(remoteEngineError.message); - case remoteEngineError instanceof RemoteErrors.InvalidAuthenticationTypeError: + case 'InvalidAuthenticationTypeError': return new RemoteErr.InvalidAuthenticationTypeError(remoteEngineError.message); - case remoteEngineError instanceof RemoteErrors.InvalidGitRemoteError: + case 'InvalidGitRemoteError': return new RemoteErr.InvalidGitRemoteError(remoteEngineError.message); - case remoteEngineError instanceof RemoteErrors.InvalidRepositoryURLError: + case 'InvalidRepositoryURLError': return new RemoteErr.InvalidRepositoryURLError(remoteEngineError.message); - case remoteEngineError instanceof RemoteErrors.InvalidSSHKeyPathError: + case 'InvalidSSHKeyPathError': return new RemoteErr.InvalidSSHKeyPathError(remoteEngineError.message); - case remoteEngineError instanceof RemoteErrors.InvalidURLFormatError: + case 'InvalidURLFormatError': return new RemoteErr.InvalidURLFormatError(remoteEngineError.message); - case remoteEngineError instanceof RemoteErrors.NetworkError: + case 'NetworkError': return new RemoteErr.NetworkError(remoteEngineError.message); - case remoteEngineError instanceof RemoteErrors.UnfetchedCommitExistsError: + case 'UnfetchedCommitExistsError': return new RemoteErr.UnfetchedCommitExistsError(remoteEngineError.message); default: return new Error(remoteEngineError.message); From dd297b78488c56013b336eb9b1f5ee529188532f Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 4 Aug 2021 19:26:17 +0900 Subject: [PATCH 148/297] test: adding tests for Sync#init() --- test/remote_base/sync.ts | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/test/remote_base/sync.ts b/test/remote_base/sync.ts index 3e2aa4c0..ce40d684 100644 --- a/test/remote_base/sync.ts +++ b/test/remote_base/sync.ts @@ -762,7 +762,7 @@ export const syncBase = ( await gitDDB.destroy(); }); - it('calls tryPush() when remote repository exists', async () => { + it('throws UnfetchedCommitExistsError when tryPush to updated repository', async () => { const remoteURL = remoteURLBase + serialId(); const dbNameA = serialId(); const dbA: GitDocumentDB = new GitDocumentDB({ @@ -800,7 +800,7 @@ export const syncBase = ( await destroyDBs([dbA, dbB]); }); - it('calls trySync() when remote repository exists', async () => { + it('succeeds when trySync to updated repository', async () => { const [dbA, dbB, syncA, syncB] = await createClonedDatabases( remoteURLBase, localDir, @@ -824,7 +824,7 @@ export const syncBase = ( await destroyDBs([dbA, dbB]); }); - it('throws PushNotAllowedError.', async () => { + it('throws PushNotAllowedError when syncDirection is pull', async () => { const remoteURL = remoteURLBase + serialId(); const dbName = serialId(); const gitDDB: GitDocumentDB = new GitDocumentDB({ @@ -873,6 +873,13 @@ export const syncBase = ( await destroyDBs([dbA, dbB]); }); + + it('succeeds when a local repository does not exist and a remote repository does not exist.', async () => {}); + it('succeeds when a local repository does not exist and a remote empty repository exists.', async () => {}); + it('succeeds when a local repository does not exist and a remote fulfilled repository exists.', async () => {}); + it('succeeds when a local repository exists and a remote repository does not exist.', async () => {}); + it('succeeds when a local repository exists and a remote empty repository exists.', async () => {}); + it('succeeds when a local repository exists and a remote fulfilled repository exists.', async () => {}); }); describe(' syncImpl()', () => { From 5d8e49b9c4073acfd1244e5428e7b721ddadcc58 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 4 Aug 2021 22:12:33 +0900 Subject: [PATCH 149/297] test: add tests for init() --- .vscode/launch.json | 2 +- test/remote_base/sync.ts | 215 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 210 insertions(+), 7 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 0864e33c..9c035100 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,7 +4,7 @@ "type": "pickString", "id": "choice", "description": "select a file", - "options": ["test_plugin/remote_nodegit/sync.test.js"], + "options": ["test/remote_isomorphic_git/sync.test.js"], }], "configurations": [ { diff --git a/test/remote_base/sync.ts b/test/remote_base/sync.ts index ce40d684..55eaaffc 100644 --- a/test/remote_base/sync.ts +++ b/test/remote_base/sync.ts @@ -28,6 +28,7 @@ import { Err } from '../../src/error'; import { encodeToGitRemoteName, Sync, syncImpl } from '../../src/remote/sync'; import { createClonedDatabases, + createRemoteRepository, destroyDBs, removeRemoteRepositories, } from '../remote_utils'; @@ -874,12 +875,214 @@ export const syncBase = ( await destroyDBs([dbA, dbB]); }); - it('succeeds when a local repository does not exist and a remote repository does not exist.', async () => {}); - it('succeeds when a local repository does not exist and a remote empty repository exists.', async () => {}); - it('succeeds when a local repository does not exist and a remote fulfilled repository exists.', async () => {}); - it('succeeds when a local repository exists and a remote repository does not exist.', async () => {}); - it('succeeds when a local repository exists and a remote empty repository exists.', async () => {}); - it('succeeds when a local repository exists and a remote fulfilled repository exists.', async () => {}); + it('succeeds when a local repository does not exist and a remote repository does not exist.', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); + + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + await dbA.open(); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection, + }; + const sync = await dbA.sync(options); + const jsonA1 = { _id: '1', name: 'fromA' }; + await dbA.put(jsonA1); + + await expect(sync.trySync()).resolves.toMatchObject({ action: 'push' }); + + await destroyDBs([dbA]); + }); + + it('succeeds when a local repository does not exist and a remote empty repository exists.', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); + + await createRemoteRepository(remoteURL); + + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + await dbA.open(); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection, + }; + const [sync, result] = await dbA.sync(options, true); + + expect(result).toMatchObject({ action: 'push' }); + + const jsonA1 = { _id: '1', name: 'fromA' }; + await dbA.put(jsonA1); + + await expect(sync.trySync()).resolves.toMatchObject({ action: 'push' }); + + await destroyDBs([dbA]); + }); + + it('succeeds when a local repository does not exist and a remote fulfilled repository exists.', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); + + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + await dbA.open(); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection, + }; + const sync = await dbA.sync(options); + const jsonA1 = { _id: '1', name: 'fromA' }; + await dbA.put(jsonA1); + await sync.trySync(); + + // Destroy local DB + await dbA.destroy(); + + // Create it again + await dbA.open(); + const [sync_again, result] = await dbA.sync(options, true); + expect(result).toMatchObject({ action: 'combine database' }); + + await dbA.put(jsonA1); + await expect(sync_again.trySync()).resolves.toMatchObject({ action: 'push' }); + + await dbA.destroy(); + }); + + it('succeeds when a local repository exists and a remote repository does not exist.', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); + + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + await dbA.open(); + const jsonA1 = { _id: '1', name: 'fromA' }; + await dbA.put(jsonA1); + + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection, + }; + const [sync, result] = await dbA.sync(options, true); + expect(result).toMatchObject({ action: 'push' }); + + const jsonA2 = { _id: '2', name: 'fromA' }; + await dbA.put(jsonA2); + await expect(sync.trySync()).resolves.toMatchObject({ action: 'push' }); + + await dbA.destroy(); + }); + + it('succeeds when a local repository exists and a remote empty repository exists.', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); + + await createRemoteRepository(remoteURL); + + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + await dbA.open(); + const jsonA1 = { _id: '1', name: 'fromA' }; + await dbA.put(jsonA1); + + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection, + }; + const [sync, result] = await dbA.sync(options, true); + expect(result).toMatchObject({ action: 'push' }); + + const jsonA2 = { _id: '2', name: 'fromA' }; + await dbA.put(jsonA2); + await expect(sync.trySync()).resolves.toMatchObject({ action: 'push' }); + + await dbA.destroy(); + }); + + it('succeeds when a local repository exists and a remote consistent repository exists.', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); + + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + await dbA.open(); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection, + }; + const sync = await dbA.sync(options); + const jsonA1 = { _id: '1', name: 'fromA' }; + await dbA.put(jsonA1); + await sync.trySync(); + + // Close local DB + await dbA.close(); + + // Open it again + await dbA.open(); + + const [sync_again, result] = await dbA.sync(options, true); + expect(result).toMatchObject({ action: 'nop' }); + + await dbA.put(jsonA1); + await expect(sync_again.trySync()).resolves.toMatchObject({ action: 'push' }); + + await dbA.destroy(); + }); + + it('succeeds when a local repository exists and a remote inconsistent repository exists.', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); + + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + await dbA.open(); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection, + }; + const sync = await dbA.sync(options); + const jsonA1 = { _id: '1', name: 'fromA' }; + await dbA.put(jsonA1); + await sync.trySync(); + + // Destroy local DB + await dbA.destroy(); + + // Create another db + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir: localDir, + }); + await dbB.open(); + const jsonB1 = { _id: '1', name: 'fromB' }; + await dbB.put(jsonB1); + + const [sync_again, result] = await dbB.sync(options, true); + expect(result).toMatchObject({ action: 'combine database' }); + + const jsonB2 = { _id: '2', name: 'fromB' }; + await dbB.put(jsonB2); + await expect(sync_again.trySync()).resolves.toMatchObject({ action: 'push' }); + + await dbB.destroy(); + }); }); describe(' syncImpl()', () => { From 0616faae2b2cff05314326fc79c5fbe239ec6cdc Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 4 Aug 2021 23:55:47 +0900 Subject: [PATCH 150/297] fix: multiple Git remotes --- examples/package-lock.json | 6 +++--- src/remote/sync.ts | 2 ++ src/task_queue.ts | 6 ++++++ src/types.ts | 1 + test/remote_base/sync.ts | 37 ++++++++++++++++++++++++++++++++----- 5 files changed, 44 insertions(+), 8 deletions(-) diff --git a/examples/package-lock.json b/examples/package-lock.json index 3f4bcaba..d3cf31fb 100644 --- a/examples/package-lock.json +++ b/examples/package-lock.json @@ -42,9 +42,9 @@ } }, "@types/node": { - "version": "16.4.10", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.4.10.tgz", - "integrity": "sha512-TmVHsm43br64js9BqHWqiDZA+xMtbUpI1MBIA0EyiBmoV9pcEYFOSdj5fr6enZNfh4fChh+AGOLIzGwJnkshyQ==" + "version": "16.4.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.4.11.tgz", + "integrity": "sha512-nWSFUbuNiPKJEe1IViuodSI+9cM+vpM8SWF/O6dJK7wmGRNq55U7XavJHrlRrPkSMuUZUFzg1xaZ1B+ZZCrRWw==" }, "@types/responselike": { "version": "1.0.0", diff --git a/src/remote/sync.ts b/src/remote/sync.ts index f1eb2632..bb228d31 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -844,6 +844,7 @@ export class Sync implements SyncInterface { return { label: 'push', taskId: taskId!, + syncRemoteName: this.remoteName, func: callback(resolve, reject), cancel: cancel(resolve), }; @@ -1118,6 +1119,7 @@ export class Sync implements SyncInterface { return { label: 'sync', taskId: taskId!, + syncRemoteName: this.remoteName, func: callback(resolve, reject), cancel: cancel(resolve), }; diff --git a/src/task_queue.ts b/src/task_queue.ts index 0d80e5e0..7533a878 100644 --- a/src/task_queue.ts +++ b/src/task_queue.ts @@ -109,9 +109,12 @@ export class TaskQueue { // Skip consecutive sync/push events if ( (this._taskQueue.length === 0 && + this._currentTask?.syncRemoteName === task.syncRemoteName && ((this._currentTask?.label === 'sync' && task.label === 'sync') || (this._currentTask?.label === 'push' && task.label === 'push'))) || (this._taskQueue.length > 0 && + this._taskQueue[this._taskQueue.length - 1].syncRemoteName === + task.syncRemoteName && ((this._taskQueue[this._taskQueue.length - 1].label === 'sync' && task.label === 'sync') || (this._taskQueue[this._taskQueue.length - 1].label === 'push' && @@ -133,6 +136,7 @@ export class TaskQueue { shortName: task.shortName, collectionPath: task.collectionPath, enqueueTime: task.enqueueTime, + syncRemoteName: task.syncRemoteName, }; if (task.enqueueCallback) { try { @@ -232,6 +236,7 @@ export class TaskQueue { const collectionPath = this._currentTask.collectionPath; const fullDocPath = collectionPath ? collectionPath + shortName : ''; const taskId = this._currentTask.taskId; + const syncRemoteName = this._currentTask.syncRemoteName; this._isTaskQueueWorking = true; this._logger.debug( @@ -261,6 +266,7 @@ export class TaskQueue { shortName, collectionPath, enqueueTime: this._currentTask.enqueueTime, + syncRemoteName, }; this._currentTask.func(beforeResolve, beforeReject, taskMetadata).finally(() => { diff --git a/src/types.ts b/src/types.ts index 4fd80d95..82eedf33 100644 --- a/src/types.ts +++ b/src/types.ts @@ -789,6 +789,7 @@ export type TaskMetadata = { shortName?: string; collectionPath?: string; enqueueTime?: string; + syncRemoteName?: string; }; /** diff --git a/test/remote_base/sync.ts b/test/remote_base/sync.ts index 55eaaffc..0839d742 100644 --- a/test/remote_base/sync.ts +++ b/test/remote_base/sync.ts @@ -1103,9 +1103,10 @@ export const syncBase = ( }); }); - it('Multiple Sync object', async () => { + it('Multiple Sync objects', async () => { const gitDDB = new GitDocumentDB({ dbName: serialId(), + localDir, }); await gitDDB.open(); await gitDDB.put({ name: 'foo' }); @@ -1113,19 +1114,19 @@ export const syncBase = ( const remoteOptions01: RemoteOptions = { live: true, remoteUrl: remoteURLBase + serialId(), - interval: 5000, // Sync every 5,000 msec + interval: 3000, connection: { type: 'github', personalAccessToken: token, }, }; - const sync01 = await gitDDB.sync(remoteOptions01); + await gitDDB.sync(remoteOptions01); const remoteOptions02: RemoteOptions = { live: true, remoteUrl: remoteURLBase + serialId(), - interval: 5000, // Sync every 5,000 msec + interval: 3000, connection: { type: 'github', personalAccessToken: token, @@ -1135,6 +1136,32 @@ export const syncBase = ( const sync02 = await gitDDB.sync(remoteOptions02); expect(sync02).toBeInstanceOf(Sync); - await gitDDB.destroy(); + // Update remote from other DBs + const dbA = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbA.open(); + const syncA = await dbA.sync(remoteOptions01); + const jsonA1 = { _id: '1', name: 'fromA' }; + await dbA.put(jsonA1); + await syncA.trySync(); + + const dbB = new GitDocumentDB({ + dbName: serialId(), + localDir, + }); + await dbB.open(); + const syncB = await dbB.sync(remoteOptions02); + const jsonB2 = { _id: '2', name: 'fromB' }; + await dbB.put(jsonB2); + await syncB.trySync(); + + await sleep(remoteOptions01.interval! * 2); + + await expect(gitDDB.get('1')).resolves.toEqual(jsonA1); + await expect(gitDDB.get('2')).resolves.toEqual(jsonB2); + + await destroyDBs([gitDDB, dbA, dbB]); }); }; From 6ab63125533f2670fdf04b2b2993bd9dc8439adc Mon Sep 17 00:00:00 2001 From: sosuisen Date: Thu, 5 Aug 2021 03:40:01 +0900 Subject: [PATCH 151/297] fix: cancel periodic tryPush and trySync while pausing --- src/remote/push_worker.ts | 26 ++++++++--- src/remote/sync.ts | 91 ++++++++++++++++++++++++++++----------- src/remote/sync_worker.ts | 27 ++++++++---- src/task_queue.ts | 3 ++ src/types.ts | 1 + 5 files changed, 107 insertions(+), 41 deletions(-) diff --git a/src/remote/push_worker.ts b/src/remote/push_worker.ts index f3c99556..f7ca8d23 100644 --- a/src/remote/push_worker.ts +++ b/src/remote/push_worker.ts @@ -9,7 +9,13 @@ import git from 'isomorphic-git'; import fs from 'fs-extra'; import { GitDDBInterface } from '../types_gitddb'; -import { ChangedFile, NormalizedCommit, SyncResultPush, TaskMetadata } from '../types'; +import { + ChangedFile, + NormalizedCommit, + SyncResultCancel, + SyncResultPush, + TaskMetadata, +} from '../types'; import { SyncInterface } from '../types_sync'; import { getChanges, getCommitLogs } from './worker_utils'; import { RemoteEngine, wrappingRemoteEngineError } from './remote_engine'; @@ -26,7 +32,6 @@ import { RemoteEngine, wrappingRemoteEngineError } from './remote_engine'; * @throws - {@link HTTPError404NotFound} * @throws - {@link HTTPError403Forbidden} * @throws - {@link CannotConnectError} - * @throws - {@link UnfetchedCommitExistsError} * @throws - {@link CannotConnectError} * @throws - {@link HttpProtocolRequiredError} * @throws - {@link InvalidRepositoryURLError} @@ -43,8 +48,15 @@ export async function pushWorker ( sync: SyncInterface, taskMetadata: TaskMetadata, skipStartEvent = false, - skipGetChanges = false -): Promise { + afterMerge = false +): Promise { + const syncOptions = sync.options; + if (!afterMerge && taskMetadata.periodic && !syncOptions.live) { + const resultCancel: SyncResultCancel = { + action: 'canceled', + }; + return resultCancel; + } if (!skipStartEvent) { sync.eventHandlers.start.forEach(listener => { listener.func( @@ -121,7 +133,7 @@ export async function pushWorker ( await RemoteEngine[sync.engine] .push( gitDDB.workingDir, - sync.options, + syncOptions, sync.remoteName, gitDDB.defaultBranch, gitDDB.defaultBranch, @@ -131,7 +143,7 @@ export async function pushWorker ( throw wrappingRemoteEngineError(err); }); let remoteChanges: ChangedFile[] | undefined; - if (skipGetChanges) { + if (afterMerge) { remoteChanges = undefined; } else { @@ -147,7 +159,7 @@ export async function pushWorker ( // Get a list of commits which will be pushed to remote. let commitListRemote: NormalizedCommit[] | undefined; - if (sync.options.includeCommits) { + if (syncOptions.includeCommits) { commitListRemote = await getCommitLogs( gitDDB.workingDir, headCommitOid, diff --git a/src/remote/sync.ts b/src/remote/sync.ts index bb228d31..a5ba1b1b 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -637,10 +637,10 @@ export class Sync implements SyncInterface { }); this._syncTimer = setInterval(() => { if (this._options.syncDirection === 'push') { - this.tryPush().catch(() => undefined); + this.tryPushImpl(true).catch(() => undefined); } else if (this._options.syncDirection === 'both') { - this.trySync().catch(() => undefined); + this.trySyncImpl(true).catch(() => undefined); } }, this._options.interval!); } @@ -702,10 +702,10 @@ export class Sync implements SyncInterface { this._options.live = true; this._syncTimer = setInterval(() => { if (this._options.syncDirection === 'push') { - this.tryPush().catch(() => undefined); + this.tryPushImpl(true).catch(() => undefined); } else if (this._options.syncDirection === 'both') { - this.trySync().catch(() => undefined); + this.trySyncImpl(true).catch(() => undefined); } }, this._options.interval!); @@ -763,8 +763,19 @@ export class Sync implements SyncInterface { * * @public */ - // eslint-disable-next-line complexity async tryPush (): Promise { + return await this.tryPushImpl(false); + } + + /** + * tryPushImpl + * + * @internal + */ + // eslint-disable-next-line complexity + async tryPushImpl ( + calledAsPeriodicTask: boolean + ): Promise { if (this._isClosed) return { action: 'canceled' }; if (this._options.syncDirection === 'pull') { throw new Err.PushNotAllowedError(this._options.syncDirection); @@ -783,24 +794,25 @@ export class Sync implements SyncInterface { taskMetadata: TaskMetadata ) => pushWorker(this._gitDDB, this, taskMetadata) - .then((syncResultPush: SyncResultPush) => { + .then((syncResultPush: SyncResultPush | SyncResultCancel) => { this._gitDDB.logger.debug( - CONSOLE_STYLE.bgWhite().fgBlack().tag()`push_worker: ${JSON.stringify( + CONSOLE_STYLE.bgWhite().fgBlack().tag()`pushWorker: ${JSON.stringify( syncResultPush )}` ); - this.eventHandlers.change.forEach(listener => { - const filteredSyncResultPush = filterChanges( - JSON.parse(JSON.stringify(syncResultPush)), - listener.collectionPath - ) as SyncResultPush; - listener.func(filteredSyncResultPush, { - ...taskMetadata, - collectionPath: listener.collectionPath, - }); - }); if (syncResultPush.action === 'push') { + this.eventHandlers.change.forEach(listener => { + const filteredSyncResultPush = filterChanges( + JSON.parse(JSON.stringify(syncResultPush)), + listener.collectionPath + ) as SyncResultPush; + listener.func(filteredSyncResultPush, { + ...taskMetadata, + collectionPath: listener.collectionPath, + }); + }); + this.eventHandlers.remoteChange.forEach(listener => { const filteredSyncResultPush = filterChanges( JSON.parse(JSON.stringify(syncResultPush)), @@ -812,9 +824,12 @@ export class Sync implements SyncInterface { }); }); } - this.eventHandlers.complete.forEach(listener => { - listener.func({ ...taskMetadata, collectionPath: listener.collectionPath }); - }); + + if (syncResultPush.action !== 'canceled') { + this.eventHandlers.complete.forEach(listener => { + listener.func({ ...taskMetadata, collectionPath: listener.collectionPath }); + }); + } beforeResolve(); resolve(syncResultPush); @@ -834,6 +849,9 @@ export class Sync implements SyncInterface { const cancel = (resolve: (value: SyncResultCancel) => void) => () => { const result: SyncResultCancel = { action: 'canceled' }; + this._gitDDB.logger.debug( + CONSOLE_STYLE.bgWhite().fgBlack().tag()`pushWorker: ${JSON.stringify(result)}` + ); resolve(result); }; @@ -845,6 +863,7 @@ export class Sync implements SyncInterface { label: 'push', taskId: taskId!, syncRemoteName: this.remoteName, + periodic: calledAsPeriodicTask, func: callback(resolve, reject), cancel: cancel(resolve), }; @@ -913,8 +932,17 @@ export class Sync implements SyncInterface { * * @public */ - // eslint-disable-next-line complexity async trySync (): Promise { + return await this.trySyncImpl(false); + } + + /** + * trySyncImpl + * + * @internal + */ + // eslint-disable-next-line complexity + async trySyncImpl (calledAsPeriodicTask: boolean): Promise { if (this._isClosed) return { action: 'canceled' }; if (this._options.syncDirection === 'pull') { throw new Err.PushNotAllowedError(this._options.syncDirection); @@ -925,7 +953,9 @@ export class Sync implements SyncInterface { while (this._retrySyncCounter > 0) { // eslint-disable-next-line no-await-in-loop - const resultOrError = await this.enqueueSyncTask().catch((err: Error) => err); + const resultOrError = await this.enqueueSyncTask(calledAsPeriodicTask).catch( + (err: Error) => err + ); let error: Error | undefined; let result: SyncResult | undefined; @@ -999,6 +1029,9 @@ export class Sync implements SyncInterface { } // This line is reached when cancel() set _retrySyncCounter to 0; const cancel: SyncResultCancel = { action: 'canceled' }; + this._gitDDB.logger.debug( + CONSOLE_STYLE.bgWhite().fgBlack().tag()`syncWorker: ${JSON.stringify(cancel)}` + ); this._retrySyncCounter = 0; return cancel; } @@ -1008,7 +1041,7 @@ export class Sync implements SyncInterface { * * @public */ - enqueueSyncTask (): Promise { + enqueueSyncTask (calledAsPeriodicTask: boolean): Promise { const taskId = this._gitDDB.taskQueue.newTaskId(); const callback = ( resolve: (value: SyncResult) => void, @@ -1087,9 +1120,11 @@ export class Sync implements SyncInterface { }); } - this.eventHandlers.complete.forEach(listener => - listener.func({ ...taskMetadata, collectionPath: listener.collectionPath }) - ); + if (syncResult.action !== 'canceled') { + this.eventHandlers.complete.forEach(listener => + listener.func({ ...taskMetadata, collectionPath: listener.collectionPath }) + ); + } beforeResolve(); resolve(syncResult); @@ -1109,6 +1144,9 @@ export class Sync implements SyncInterface { const cancel = (resolve: (value: SyncResultCancel) => void) => () => { const result: SyncResultCancel = { action: 'canceled' }; + this._gitDDB.logger.debug( + CONSOLE_STYLE.bgWhite().fgBlack().tag()`syncWorker: ${JSON.stringify(result)}` + ); resolve(result); }; @@ -1120,6 +1158,7 @@ export class Sync implements SyncInterface { label: 'sync', taskId: taskId!, syncRemoteName: this.remoteName, + periodic: calledAsPeriodicTask, func: callback(resolve, reject), cancel: cancel(resolve), }; diff --git a/src/remote/sync_worker.ts b/src/remote/sync_worker.ts index dc3fa5d8..08268571 100644 --- a/src/remote/sync_worker.ts +++ b/src/remote/sync_worker.ts @@ -15,8 +15,10 @@ import { GitDDBInterface } from '../types_gitddb'; import { NormalizedCommit, SyncResult, + SyncResultCancel, SyncResultMergeAndPush, SyncResultMergeAndPushError, + SyncResultPush, SyncResultResolveConflictsAndPush, SyncResultResolveConflictsAndPushError, TaskMetadata, @@ -73,6 +75,13 @@ export async function syncWorker ( sync: SyncInterface, taskMetadata: TaskMetadata ): Promise { + const syncOptions = sync.options; + if (taskMetadata.periodic && !syncOptions.live) { + const resultCancel: SyncResultCancel = { + action: 'canceled', + }; + return resultCancel; + } sync.eventHandlers.start.forEach(listener => { listener.func( { ...taskMetadata, collectionPath: listener.collectionPath }, @@ -86,7 +95,7 @@ export async function syncWorker ( await RemoteEngine[sync.engine] .fetch( gitDDB.workingDir, - sync.options, + syncOptions, sync.remoteName, gitDDB.defaultBranch, gitDDB.defaultBranch, @@ -155,7 +164,7 @@ export async function syncWorker ( }, }; - if (sync.options.includeCommits) { + if (syncOptions.includeCommits) { // Get list of commits which has been merged to local const commitsFromRemote = await getCommitLogs( gitDDB.workingDir, @@ -202,7 +211,7 @@ export async function syncWorker ( let localCommits: NormalizedCommit[] | undefined; // Get list of commits which has been added to local - if (sync.options.includeCommits) { + if (syncOptions.includeCommits) { const mergeCommit = await git.readCommit({ fs, dir: gitDDB.workingDir, @@ -218,11 +227,12 @@ export async function syncWorker ( localCommits = [...commitsFromRemote, normalizeCommit(mergeCommit)]; } // Need push because it is merged normally. - const syncResultPush = await pushWorker(gitDDB, sync, taskMetadata, true, true).catch( + // Set afterMerge option true not to return SyncResultCancel. + const syncResultPush = (await pushWorker(gitDDB, sync, taskMetadata, true, true).catch( (err: Error) => { return err; } - ); + )) as SyncResultPush; if (syncResultPush instanceof Error) { const syncResultMergeAndPushError: SyncResultMergeAndPushError = { @@ -293,7 +303,7 @@ export async function syncWorker ( // Get list of commits which has been added to local let localCommits: NormalizedCommit[] | undefined; - if (sync.options.includeCommits) { + if (syncOptions.includeCommits) { const commitsFromRemote = await getCommitLogs( gitDDB.workingDir, oldRemoteCommitOid, @@ -309,11 +319,12 @@ export async function syncWorker ( } // Push - const syncResultPush = await pushWorker(gitDDB, sync, taskMetadata, true, true).catch( + // Set afterMerge option true not to return SyncResultCancel. + const syncResultPush = (await pushWorker(gitDDB, sync, taskMetadata, true, true).catch( (err: Error) => { return err; } - ); + )) as SyncResultPush; if (syncResultPush instanceof Error) { const syncResultResolveConflictsAndPushError: SyncResultResolveConflictsAndPushError = { diff --git a/src/task_queue.ts b/src/task_queue.ts index 7533a878..0b1a1b98 100644 --- a/src/task_queue.ts +++ b/src/task_queue.ts @@ -137,6 +137,7 @@ export class TaskQueue { collectionPath: task.collectionPath, enqueueTime: task.enqueueTime, syncRemoteName: task.syncRemoteName, + periodic: !!task.periodic, }; if (task.enqueueCallback) { try { @@ -237,6 +238,7 @@ export class TaskQueue { const fullDocPath = collectionPath ? collectionPath + shortName : ''; const taskId = this._currentTask.taskId; const syncRemoteName = this._currentTask.syncRemoteName; + const periodic = !!this._currentTask.periodic; this._isTaskQueueWorking = true; this._logger.debug( @@ -267,6 +269,7 @@ export class TaskQueue { collectionPath, enqueueTime: this._currentTask.enqueueTime, syncRemoteName, + periodic, }; this._currentTask.func(beforeResolve, beforeReject, taskMetadata).finally(() => { diff --git a/src/types.ts b/src/types.ts index 82eedf33..3f3b5894 100644 --- a/src/types.ts +++ b/src/types.ts @@ -790,6 +790,7 @@ export type TaskMetadata = { collectionPath?: string; enqueueTime?: string; syncRemoteName?: string; + periodic?: boolean; }; /** From 9bbd3ed6ebb6dfff8eaa8a3059f9cb139b6e199f Mon Sep 17 00:00:00 2001 From: sosuisen Date: Thu, 5 Aug 2021 03:41:38 +0900 Subject: [PATCH 152/297] test: fixing PushRejectedError in push of isomorphic-git --- src/plugin/remote-isomorphic-git.ts | 2 +- test/remote_base/sync_live.ts | 496 ++++++++++++++++------------ 2 files changed, 289 insertions(+), 209 deletions(-) diff --git a/src/plugin/remote-isomorphic-git.ts b/src/plugin/remote-isomorphic-git.ts index 1e9adae4..3dfecc3e 100644 --- a/src/plugin/remote-isomorphic-git.ts +++ b/src/plugin/remote-isomorphic-git.ts @@ -490,7 +490,7 @@ export async function push ( break; } - // console.warn('connect push error: ' + error); + // console.log('connect push error: ' + error); switch (true) { // NoRefspecError does not invoke because push does not need Remote when url is specified. // case error.startsWith('NoRefspecError'): diff --git a/test/remote_base/sync_live.ts b/test/remote_base/sync_live.ts index 9a457c56..219421de 100644 --- a/test/remote_base/sync_live.ts +++ b/test/remote_base/sync_live.ts @@ -34,225 +34,305 @@ export const syncLiveBase = ( await removeRemoteRepositories(reposPrefix); }); - // Test live - describe(' Sync', () => { - /** - * Repetitive Sync (live) - */ - describe('Repetitive Sync (live)', () => { - it('starts and pushes after interval when called from open() with live option.', async () => { - const remoteURL = remoteURLBase + serialId(); - - const dbNameA = serialId(); - - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, - }); - const interval = MINIMUM_SYNC_INTERVAL; - const options: RemoteOptions = { - remoteUrl: remoteURL, - live: true, - syncDirection: 'both', - interval, - connection, - }; - await dbA.open(); - const syncA = await dbA.sync(options); - - const jsonA1 = { _id: '1', name: 'fromA' }; - await dbA.put(jsonA1); - - expect(syncA.options.live).toBeTruthy(); - expect(syncA.options.interval).toBe(interval); - - // Wait live sync() - while (dbA.taskQueue.currentStatistics().sync === 0) { - // eslint-disable-next-line no-await-in-loop - await sleep(500); - } - - const dbNameB = serialId(); - const dbB: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameB, - localDir: localDir, - }); - await dbB.open(); - await dbB.sync(options); - await expect(dbB.get(jsonA1._id)).resolves.toMatchObject(jsonA1); - - await destroyDBs([dbA, dbB]); + /** + * Test periodic Sync (live) + */ + + describe(' periodic Sync', () => { + it('starts and pushes after interval when called from open() with live option.', async () => { + const remoteURL = remoteURLBase + serialId(); + + const dbNameA = serialId(); + + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, }); + const interval = MINIMUM_SYNC_INTERVAL; + const options: RemoteOptions = { + remoteUrl: remoteURL, + live: true, + syncDirection: 'both', + interval, + connection, + }; + await dbA.open(); + const syncA = await dbA.sync(options); + + const jsonA1 = { _id: '1', name: 'fromA' }; + await dbA.put(jsonA1); + + expect(syncA.options.live).toBeTruthy(); + expect(syncA.options.interval).toBe(interval); + + // Wait live sync() + while (dbA.taskQueue.currentStatistics().sync === 0) { + // eslint-disable-next-line no-await-in-loop + await sleep(500); + } + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir: localDir, + }); + await dbB.open(); + await dbB.sync(options); + await expect(dbB.get(jsonA1._id)).resolves.toMatchObject(jsonA1); - it('stops by pause()', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbNameA = serialId(); - - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, - }); - const interval = MINIMUM_SYNC_INTERVAL; - const options: RemoteOptions = { - remoteUrl: remoteURL, - live: true, - syncDirection: 'both', - interval, - connection, - }; - await dbA.open(); - const syncA = await dbA.sync(options); - - expect(syncA.options.live).toBeTruthy(); - const count = dbA.taskQueue.currentStatistics().sync; - syncA.pause(); - await sleep(interval * 2); - expect(syncA.options.live).toBeFalsy(); - expect(dbA.taskQueue.currentStatistics().sync).toBe(count); - - await destroyDBs([dbA]); + await destroyDBs([dbA, dbB]); + }); + + it('stops by pause()', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); + + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, }); + const interval = MINIMUM_SYNC_INTERVAL; + const options: RemoteOptions = { + remoteUrl: remoteURL, + live: true, + syncDirection: 'both', + interval, + connection, + }; + await dbA.open(); + const syncA = await dbA.sync(options); + + expect(syncA.options.live).toBeTruthy(); + const count = dbA.taskQueue.currentStatistics().sync; + syncA.pause(); + await sleep(interval * 2); + expect(syncA.options.live).toBeFalsy(); + expect(dbA.taskQueue.currentStatistics().sync).toBe(count); + + await destroyDBs([dbA]); + }); + + it('pause() and resume()', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); - it('pause() and resume()', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbNameA = serialId(); - - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, - }); - const interval = MINIMUM_SYNC_INTERVAL; - const options: RemoteOptions = { - remoteUrl: remoteURL, - live: true, - syncDirection: 'both', - interval, - connection, - }; - await dbA.open(); - const syncA = await dbA.sync(options); - - expect(syncA.options.live).toBeTruthy(); - const count = dbA.taskQueue.currentStatistics().sync; - expect(syncA.pause()).toBeTruthy(); - expect(syncA.pause()).toBeFalsy(); // ignored - - await sleep(interval * 2); - expect(syncA.options.live).toBeFalsy(); - expect(dbA.taskQueue.currentStatistics().sync).toBe(count); - - expect(syncA.resume()).toBeTruthy(); - expect(syncA.resume()).toBeFalsy(); // ignored - await sleep(interval * 2); - expect(syncA.options.live).toBeTruthy(); - expect(dbA.taskQueue.currentStatistics().sync).toBeGreaterThan(count); - - await destroyDBs([dbA]); + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, }); + const interval = MINIMUM_SYNC_INTERVAL; + const options: RemoteOptions = { + remoteUrl: remoteURL, + live: true, + syncDirection: 'both', + interval, + connection, + }; + await dbA.open(); + const syncA = await dbA.sync(options); + + expect(syncA.options.live).toBeTruthy(); + const count = dbA.taskQueue.currentStatistics().sync; + expect(syncA.pause()).toBeTruthy(); + expect(syncA.pause()).toBeFalsy(); // ignored + + await sleep(interval * 2); + expect(syncA.options.live).toBeFalsy(); + expect(dbA.taskQueue.currentStatistics().sync).toBe(count); + + expect(syncA.resume()).toBeTruthy(); + expect(syncA.resume()).toBeFalsy(); // ignored + await sleep(interval * 2); + expect(syncA.options.live).toBeTruthy(); + expect(dbA.taskQueue.currentStatistics().sync).toBeGreaterThan(count); + + await destroyDBs([dbA]); + }); + + it('stops by gitDDB.close()', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); - it('stops by gitDDB.close()', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbNameA = serialId(); - - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, - }); - const interval = MINIMUM_SYNC_INTERVAL; - const options: RemoteOptions = { - remoteUrl: remoteURL, - live: true, - syncDirection: 'both', - interval, - connection, - }; - await dbA.open(); - const syncA = await dbA.sync(options); - - expect(syncA.options.live).toBeTruthy(); - const count = dbA.taskQueue.currentStatistics().sync; - await dbA.close(); - - syncA.resume(); // resume() must be ignored after close(); - - await sleep(interval * 2); - expect(syncA.options.live).toBeFalsy(); - expect(dbA.taskQueue.currentStatistics().sync).toBe(count); - - await destroyDBs([dbA]); + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, }); + const interval = MINIMUM_SYNC_INTERVAL; + const options: RemoteOptions = { + remoteUrl: remoteURL, + live: true, + syncDirection: 'both', + interval, + connection, + }; + await dbA.open(); + const syncA = await dbA.sync(options); + + expect(syncA.options.live).toBeTruthy(); + const count = dbA.taskQueue.currentStatistics().sync; + await dbA.close(); + + syncA.resume(); // resume() must be ignored after close(); + + await sleep(interval * 2); + expect(syncA.options.live).toBeFalsy(); + expect(dbA.taskQueue.currentStatistics().sync).toBe(count); + + await destroyDBs([dbA]); + }); + + it('changes interval when resume() is called with new interval.', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); - it('changes interval when resume() is called with new interval.', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbNameA = serialId(); - - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, - }); - dbA.logLevel = 'trace'; - const interval = MINIMUM_SYNC_INTERVAL; - const options: RemoteOptions = { - remoteUrl: remoteURL, - live: true, - syncDirection: 'both', - interval, - connection, - }; - await dbA.open(); - const syncA = await dbA.sync(options); - - expect(syncA.options.interval).toBe(interval); - - const jsonA1 = { _id: '1', name: 'fromA' }; - await dbA.put(jsonA1); - // Wait live sync() - while (dbA.taskQueue.currentStatistics().sync === 0) { - // eslint-disable-next-line no-await-in-loop - await sleep(500); - } - syncA.pause(); - - const jsonA2 = { _id: '2', name: 'fromA' }; - await dbA.put(jsonA2); - - const currentCount = dbA.taskQueue.currentStatistics().sync; - // Change interval - syncA.resume({ - interval: interval * 3, - }); - expect(syncA.options.interval).toBe(interval * 3); - await sleep(interval); - // Check count before next sync() - expect(dbA.taskQueue.currentStatistics().sync).toBe(currentCount); - - await destroyDBs([dbA]); + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, }); + dbA.logLevel = 'trace'; + const interval = MINIMUM_SYNC_INTERVAL; + const options: RemoteOptions = { + remoteUrl: remoteURL, + live: true, + syncDirection: 'both', + interval, + connection, + }; + await dbA.open(); + const syncA = await dbA.sync(options); + + expect(syncA.options.interval).toBe(interval); + + const jsonA1 = { _id: '1', name: 'fromA' }; + await dbA.put(jsonA1); + // Wait live sync() + while (dbA.taskQueue.currentStatistics().sync === 0) { + // eslint-disable-next-line no-await-in-loop + await sleep(500); + } + syncA.pause(); + + const jsonA2 = { _id: '2', name: 'fromA' }; + await dbA.put(jsonA2); + + const currentCount = dbA.taskQueue.currentStatistics().sync; + // Change interval + syncA.resume({ + interval: interval * 3, + }); + expect(syncA.options.interval).toBe(interval * 3); + await sleep(interval); + // Check count before next sync() + expect(dbA.taskQueue.currentStatistics().sync).toBe(currentCount); + + await destroyDBs([dbA]); + }); + + it('repeats tryPush() automatically.', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); + + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + const interval = MINIMUM_SYNC_INTERVAL; + const options: RemoteOptions = { + remoteUrl: remoteURL, + live: true, + syncDirection: 'push', + interval, + connection, + }; + await dbA.open(); + const syncA = await dbA.sync(options); + syncA.on('error', (err: Error) => { + console.log(err); + }); + await sleep(interval * 5); + expect(dbA.taskQueue.currentStatistics().push).toBeGreaterThanOrEqual(2); + + await destroyDBs([dbA]); + }); + + it('repeats trySync() automatically.', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); + + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + const interval = MINIMUM_SYNC_INTERVAL; + const options: RemoteOptions = { + remoteUrl: remoteURL, + live: true, + syncDirection: 'both', + interval, + connection, + }; + await dbA.open(); + const syncA = await dbA.sync(options); + syncA.on('error', (err: Error) => { + console.log(err); + }); + await sleep(interval * 5); + expect(dbA.taskQueue.currentStatistics().sync).toBeGreaterThanOrEqual(2); + + await destroyDBs([dbA]); + }); + + it.only('skips pushWorker after pause.', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); + + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + const options: RemoteOptions = { + remoteUrl: remoteURL, + live: true, + syncDirection: 'push', + interval: 30000, + connection, + }; + await dbA.open(); + const syncA = await dbA.sync(options); + await dbA.put({ name: 'foo' }); + +// syncA.pause(); +// await expect(syncA.tryPushImpl(true)).resolves.toEqual({ action: 'canceled' }); +// syncA.resume(); +await syncA.tryPushImpl(true); + await expect(syncA.tryPushImpl(true)).resolves.toMatchObject({ action: 'nop' }); + +// await destroyDBs([dbA]); + }); + + it('skips syncWorker after pause.', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); - it('repeats trySync() automatically.', async () => { - const remoteURL = remoteURLBase + serialId(); - const dbNameA = serialId(); - - const dbA: GitDocumentDB = new GitDocumentDB({ - dbName: dbNameA, - localDir: localDir, - }); - const interval = MINIMUM_SYNC_INTERVAL; - const options: RemoteOptions = { - remoteUrl: remoteURL, - live: true, - syncDirection: 'both', - interval, - connection, - }; - await dbA.open(); - const syncA = await dbA.sync(options); - - await sleep(interval * 5); - expect(dbA.taskQueue.currentStatistics().sync).toBeGreaterThanOrEqual(3); - - await destroyDBs([dbA]); + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, }); + const options: RemoteOptions = { + remoteUrl: remoteURL, + live: true, + syncDirection: 'both', + interval: 1000000, + connection, + }; + await dbA.open(); + const syncA = await dbA.sync(options); + syncA.pause(); + await expect(syncA.trySyncImpl(true)).resolves.toEqual({ action: 'canceled' }); + syncA.resume(); + await expect(syncA.trySyncImpl(true)).resolves.toMatchObject({ action: 'nop' }); + + await destroyDBs([dbA]); }); }); }; From fbfe18643b0554da1d873cc8d10ea0b371226844 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Thu, 5 Aug 2021 14:49:27 +0900 Subject: [PATCH 153/297] fix: pushWorker returns SyncResultNop when local does not have ahead commits --- src/remote/push_worker.ts | 8 +++++++- src/remote/sync.ts | 18 +++++++++++------- src/types_sync.ts | 3 ++- test/remote_base/sync_live.ts | 20 ++++++++------------ test/remote_base/sync_trypush.ts | 22 +++++++++++++++++++++- 5 files changed, 49 insertions(+), 22 deletions(-) diff --git a/src/remote/push_worker.ts b/src/remote/push_worker.ts index f7ca8d23..939a471a 100644 --- a/src/remote/push_worker.ts +++ b/src/remote/push_worker.ts @@ -13,6 +13,7 @@ import { ChangedFile, NormalizedCommit, SyncResultCancel, + SyncResultNop, SyncResultPush, TaskMetadata, } from '../types'; @@ -43,13 +44,14 @@ import { RemoteEngine, wrappingRemoteEngineError } from './remote_engine'; * * @internal */ +// eslint-disable-next-line complexity export async function pushWorker ( gitDDB: GitDDBInterface, sync: SyncInterface, taskMetadata: TaskMetadata, skipStartEvent = false, afterMerge = false -): Promise { +): Promise { const syncOptions = sync.options; if (!afterMerge && taskMetadata.periodic && !syncOptions.live) { const resultCancel: SyncResultCancel = { @@ -112,6 +114,10 @@ export async function pushWorker ( let baseCommitOid: string | undefined; + if (localCommitOid === remoteCommitOid) { + return { action: 'nop' }; + } + if (remoteCommitOid === undefined) { // This is the first push in this repository. // Get the first commit. diff --git a/src/remote/sync.ts b/src/remote/sync.ts index a5ba1b1b..8123b1f6 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -32,6 +32,7 @@ import { SyncRemoteChangeCallback, SyncResult, SyncResultCancel, + SyncResultNop, SyncResultPush, SyncResumeCallback, SyncStartCallback, @@ -763,7 +764,7 @@ export class Sync implements SyncInterface { * * @public */ - async tryPush (): Promise { + async tryPush (): Promise { return await this.tryPushImpl(false); } @@ -775,7 +776,7 @@ export class Sync implements SyncInterface { // eslint-disable-next-line complexity async tryPushImpl ( calledAsPeriodicTask: boolean - ): Promise { + ): Promise { if (this._isClosed) return { action: 'canceled' }; if (this._options.syncDirection === 'pull') { throw new Err.PushNotAllowedError(this._options.syncDirection); @@ -786,7 +787,7 @@ export class Sync implements SyncInterface { */ const taskId = this._gitDDB.taskQueue.newTaskId(); const callback = ( - resolve: (value: SyncResultPush | SyncResultCancel) => void, + resolve: (value: SyncResultPush | SyncResultCancel | SyncResultNop) => void, reject: (reason: any) => void ) => ( beforeResolve: () => void, @@ -794,7 +795,7 @@ export class Sync implements SyncInterface { taskMetadata: TaskMetadata ) => pushWorker(this._gitDDB, this, taskMetadata) - .then((syncResultPush: SyncResultPush | SyncResultCancel) => { + .then((syncResultPush: SyncResultPush | SyncResultCancel | SyncResultNop) => { this._gitDDB.logger.debug( CONSOLE_STYLE.bgWhite().fgBlack().tag()`pushWorker: ${JSON.stringify( syncResultPush @@ -825,7 +826,7 @@ export class Sync implements SyncInterface { }); } - if (syncResultPush.action !== 'canceled') { + if (syncResultPush.action === 'push') { this.eventHandlers.complete.forEach(listener => { listener.func({ ...taskMetadata, collectionPath: listener.collectionPath }); }); @@ -856,7 +857,7 @@ export class Sync implements SyncInterface { }; const task = ( - resolve: (value: SyncResultPush | SyncResultCancel) => void, + resolve: (value: SyncResultPush | SyncResultCancel | SyncResultNop) => void, reject: (reason: any) => void ): Task => { return { @@ -870,7 +871,10 @@ export class Sync implements SyncInterface { }; const resultOrError = await new Promise( - (resolve: (value: SyncResultPush | SyncResultCancel) => void, reject) => { + ( + resolve: (value: SyncResultPush | SyncResultCancel | SyncResultNop) => void, + reject + ) => { this._gitDDB.taskQueue.pushToTaskQueue(task(resolve, reject)); // this._gitDDB.taskQueue.unshiftSyncTaskToTaskQueue(task(resolve, reject)); } diff --git a/src/types_sync.ts b/src/types_sync.ts index f64c2bb6..b416b6d4 100644 --- a/src/types_sync.ts +++ b/src/types_sync.ts @@ -14,6 +14,7 @@ import { SyncRemoteChangeCallback, SyncResult, SyncResultCancel, + SyncResultNop, SyncResultPush, SyncResumeCallback, SyncStartCallback, @@ -64,7 +65,7 @@ export interface SyncInterface { resume(options?: { interval?: number; retry?: number }): void; close(): void; - tryPush(): Promise; + tryPush(): Promise; trySync(): Promise; currentRetries(): number; diff --git a/test/remote_base/sync_live.ts b/test/remote_base/sync_live.ts index 219421de..d6157ab2 100644 --- a/test/remote_base/sync_live.ts +++ b/test/remote_base/sync_live.ts @@ -189,7 +189,6 @@ export const syncLiveBase = ( dbName: dbNameA, localDir: localDir, }); - dbA.logLevel = 'trace'; const interval = MINIMUM_SYNC_INTERVAL; const options: RemoteOptions = { remoteUrl: remoteURL, @@ -250,7 +249,7 @@ export const syncLiveBase = ( console.log(err); }); await sleep(interval * 5); - expect(dbA.taskQueue.currentStatistics().push).toBeGreaterThanOrEqual(2); + expect(dbA.taskQueue.currentStatistics().push).toBeGreaterThanOrEqual(3); await destroyDBs([dbA]); }); @@ -277,12 +276,12 @@ export const syncLiveBase = ( console.log(err); }); await sleep(interval * 5); - expect(dbA.taskQueue.currentStatistics().sync).toBeGreaterThanOrEqual(2); + expect(dbA.taskQueue.currentStatistics().sync).toBeGreaterThanOrEqual(3); await destroyDBs([dbA]); }); - it.only('skips pushWorker after pause.', async () => { + it('skips pushWorker after pause.', async () => { const remoteURL = remoteURLBase + serialId(); const dbNameA = serialId(); @@ -294,20 +293,17 @@ export const syncLiveBase = ( remoteUrl: remoteURL, live: true, syncDirection: 'push', - interval: 30000, + interval: 1000000, connection, }; await dbA.open(); const syncA = await dbA.sync(options); - await dbA.put({ name: 'foo' }); - -// syncA.pause(); -// await expect(syncA.tryPushImpl(true)).resolves.toEqual({ action: 'canceled' }); -// syncA.resume(); -await syncA.tryPushImpl(true); + syncA.pause(); + await expect(syncA.tryPushImpl(true)).resolves.toEqual({ action: 'canceled' }); + syncA.resume(); await expect(syncA.tryPushImpl(true)).resolves.toMatchObject({ action: 'nop' }); -// await destroyDBs([dbA]); + await destroyDBs([dbA]); }); it('skips syncWorker after pause.', async () => { diff --git a/test/remote_base/sync_trypush.ts b/test/remote_base/sync_trypush.ts index b94d0764..66222dee 100644 --- a/test/remote_base/sync_trypush.ts +++ b/test/remote_base/sync_trypush.ts @@ -30,6 +30,7 @@ import { ConnectionSettings, RemoteOptions, SyncResultCancel, + SyncResultNop, SyncResultPush, } from '../../src/types'; import { sleep } from '../../src/utils'; @@ -375,6 +376,25 @@ export const syncTryPushBase = ( await destroyDBs([dbA]); }); + it('returns SyncResultNop when local does not have ahead commits.', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); + + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection, + }; + await dbA.open(); + const syncA = await dbA.sync(options); + await expect(syncA.tryPush()).resolves.toEqual({ action: 'nop' }); + + await destroyDBs([dbA]); + }); + it('skips consecutive push tasks', async () => { const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { connection, @@ -382,7 +402,7 @@ export const syncTryPushBase = ( const jsonA1 = { _id: '1', name: 'fromA' }; await dbA.put(jsonA1); - const results: (SyncResultPush | SyncResultCancel)[] = []; + const results: (SyncResultPush | SyncResultCancel | SyncResultNop)[] = []; for (let i = 0; i < 10; i++) { // eslint-disable-next-line promise/catch-or-return syncA.tryPush().then(result => results.push(result)); From 88480c847f842e228df8c762bc5c1f65012a0c73 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Thu, 5 Aug 2021 16:40:55 +0900 Subject: [PATCH 154/297] fix: cancel periodic tryPush and trySync in Sync class --- src/remote/push_worker.ts | 8 +- src/remote/sync.ts | 188 +++++++++++++++++++++----------------- src/remote/sync_worker.ts | 9 -- src/task_queue.ts | 3 - src/types.ts | 1 - 5 files changed, 106 insertions(+), 103 deletions(-) diff --git a/src/remote/push_worker.ts b/src/remote/push_worker.ts index 939a471a..c32fb24f 100644 --- a/src/remote/push_worker.ts +++ b/src/remote/push_worker.ts @@ -51,14 +51,8 @@ export async function pushWorker ( taskMetadata: TaskMetadata, skipStartEvent = false, afterMerge = false -): Promise { +): Promise { const syncOptions = sync.options; - if (!afterMerge && taskMetadata.periodic && !syncOptions.live) { - const resultCancel: SyncResultCancel = { - action: 'canceled', - }; - return resultCancel; - } if (!skipStartEvent) { sync.eventHandlers.start.forEach(listener => { listener.func( diff --git a/src/remote/sync.ts b/src/remote/sync.ts index 8123b1f6..4213cfcc 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -793,9 +793,18 @@ export class Sync implements SyncInterface { beforeResolve: () => void, beforeReject: () => void, taskMetadata: TaskMetadata - ) => - pushWorker(this._gitDDB, this, taskMetadata) - .then((syncResultPush: SyncResultPush | SyncResultCancel | SyncResultNop) => { + ) => { + if (calledAsPeriodicTask && !this._options.live) { + return Promise.resolve().then(() => { + const resultCancel: SyncResultCancel = { + action: 'canceled', + }; + beforeResolve(); + resolve(resultCancel); + }); + } + return pushWorker(this._gitDDB, this, taskMetadata) + .then((syncResultPush: SyncResultPush | SyncResultNop) => { this._gitDDB.logger.debug( CONSOLE_STYLE.bgWhite().fgBlack().tag()`pushWorker: ${JSON.stringify( syncResultPush @@ -847,6 +856,7 @@ export class Sync implements SyncInterface { beforeReject(); reject(err); }); + }; const cancel = (resolve: (value: SyncResultCancel) => void) => () => { const result: SyncResultCancel = { action: 'canceled' }; @@ -864,7 +874,6 @@ export class Sync implements SyncInterface { label: 'push', taskId: taskId!, syncRemoteName: this.remoteName, - periodic: calledAsPeriodicTask, func: callback(resolve, reject), cancel: cancel(resolve), }; @@ -1054,97 +1063,111 @@ export class Sync implements SyncInterface { beforeResolve: () => void, beforeReject: () => void, taskMetadata: TaskMetadata - ) => - syncWorker(this._gitDDB, this, taskMetadata) - // eslint-disable-next-line complexity - .then((syncResult: SyncResult) => { - this._gitDDB.logger.debug( - CONSOLE_STYLE.bgWhite().fgBlack().tag()`syncWorker: ${JSON.stringify( - syncResult - )}` - ); + ) => { + if (calledAsPeriodicTask && !this._options.live) { + return Promise.resolve().then(() => { + const resultCancel: SyncResultCancel = { + action: 'canceled', + }; + beforeResolve(); + resolve(resultCancel); + }); + } - if ( - syncResult.action === 'resolve conflicts and push' || - syncResult.action === 'merge and push' || - syncResult.action === 'resolve conflicts and push error' || - syncResult.action === 'merge and push error' || - syncResult.action === 'fast-forward merge' || - syncResult.action === 'push' - ) { - this.eventHandlers.change.forEach(listener => { - let syncResultForChangeEvent = JSON.parse(JSON.stringify(syncResult)); - syncResultForChangeEvent = filterChanges( - syncResultForChangeEvent, - listener.collectionPath - ) as SyncResult; + return ( + syncWorker(this._gitDDB, this, taskMetadata) + // eslint-disable-next-line complexity + .then((syncResult: SyncResult) => { + this._gitDDB.logger.debug( + CONSOLE_STYLE.bgWhite().fgBlack().tag()`syncWorker: ${JSON.stringify( + syncResult + )}` + ); - listener.func(syncResultForChangeEvent, { - ...taskMetadata, - collectionPath: listener.collectionPath, + if ( + syncResult.action === 'resolve conflicts and push' || + syncResult.action === 'merge and push' || + syncResult.action === 'resolve conflicts and push error' || + syncResult.action === 'merge and push error' || + syncResult.action === 'fast-forward merge' || + syncResult.action === 'push' + ) { + this.eventHandlers.change.forEach(listener => { + let syncResultForChangeEvent = JSON.parse(JSON.stringify(syncResult)); + syncResultForChangeEvent = filterChanges( + syncResultForChangeEvent, + listener.collectionPath + ) as SyncResult; + + listener.func(syncResultForChangeEvent, { + ...taskMetadata, + collectionPath: listener.collectionPath, + }); }); - }); - } + } - if ( - syncResult.action === 'resolve conflicts and push' || - syncResult.action === 'merge and push' || - syncResult.action === 'resolve conflicts and push error' || - syncResult.action === 'merge and push error' || - syncResult.action === 'fast-forward merge' - ) { - this.eventHandlers.localChange.forEach(listener => { - let syncResultForLocalChangeEvent = JSON.parse(JSON.stringify(syncResult)); - syncResultForLocalChangeEvent = filterChanges( - syncResultForLocalChangeEvent, - listener.collectionPath - ) as SyncResult; - listener.func(syncResultForLocalChangeEvent.changes.local, { - ...taskMetadata, - collectionPath: listener.collectionPath, + if ( + syncResult.action === 'resolve conflicts and push' || + syncResult.action === 'merge and push' || + syncResult.action === 'resolve conflicts and push error' || + syncResult.action === 'merge and push error' || + syncResult.action === 'fast-forward merge' + ) { + this.eventHandlers.localChange.forEach(listener => { + let syncResultForLocalChangeEvent = JSON.parse(JSON.stringify(syncResult)); + syncResultForLocalChangeEvent = filterChanges( + syncResultForLocalChangeEvent, + listener.collectionPath + ) as SyncResult; + listener.func(syncResultForLocalChangeEvent.changes.local, { + ...taskMetadata, + collectionPath: listener.collectionPath, + }); }); - }); - } + } - if ( - syncResult.action === 'resolve conflicts and push' || - syncResult.action === 'merge and push' || - syncResult.action === 'push' - ) { - this.eventHandlers.remoteChange.forEach(listener => { - let syncResultForRemoteChangeEvent = JSON.parse(JSON.stringify(syncResult)); - syncResultForRemoteChangeEvent = filterChanges( - syncResultForRemoteChangeEvent, - listener.collectionPath - ) as SyncResult; - listener.func(syncResultForRemoteChangeEvent.changes.remote, { - ...taskMetadata, - collectionPath: listener.collectionPath, + if ( + syncResult.action === 'resolve conflicts and push' || + syncResult.action === 'merge and push' || + syncResult.action === 'push' + ) { + this.eventHandlers.remoteChange.forEach(listener => { + let syncResultForRemoteChangeEvent = JSON.parse(JSON.stringify(syncResult)); + syncResultForRemoteChangeEvent = filterChanges( + syncResultForRemoteChangeEvent, + listener.collectionPath + ) as SyncResult; + listener.func(syncResultForRemoteChangeEvent.changes.remote, { + ...taskMetadata, + collectionPath: listener.collectionPath, + }); }); - }); - } + } - if (syncResult.action !== 'canceled') { this.eventHandlers.complete.forEach(listener => - listener.func({ ...taskMetadata, collectionPath: listener.collectionPath }) + listener.func({ + ...taskMetadata, + collectionPath: listener.collectionPath, + }) ); - } - beforeResolve(); - resolve(syncResult); - }) - .catch((err: Error) => { - // console.log(`Error in syncWorker: ${err}`); - this.eventHandlers.error.forEach(listener => { - listener.func(err, { - ...taskMetadata, - collectionPath: listener.collectionPath, + beforeResolve(); + resolve(syncResult); + }) + .catch((err: Error) => { + // console.log(`Error in syncWorker: ${err}`); + this.eventHandlers.error.forEach(listener => { + listener.func(err, { + ...taskMetadata, + collectionPath: listener.collectionPath, + }); }); - }); - beforeReject(); - reject(err); - }); + beforeReject(); + reject(err); + }) + ); + }; const cancel = (resolve: (value: SyncResultCancel) => void) => () => { const result: SyncResultCancel = { action: 'canceled' }; @@ -1162,7 +1185,6 @@ export class Sync implements SyncInterface { label: 'sync', taskId: taskId!, syncRemoteName: this.remoteName, - periodic: calledAsPeriodicTask, func: callback(resolve, reject), cancel: cancel(resolve), }; diff --git a/src/remote/sync_worker.ts b/src/remote/sync_worker.ts index 08268571..389b5c07 100644 --- a/src/remote/sync_worker.ts +++ b/src/remote/sync_worker.ts @@ -15,7 +15,6 @@ import { GitDDBInterface } from '../types_gitddb'; import { NormalizedCommit, SyncResult, - SyncResultCancel, SyncResultMergeAndPush, SyncResultMergeAndPushError, SyncResultPush, @@ -76,12 +75,6 @@ export async function syncWorker ( taskMetadata: TaskMetadata ): Promise { const syncOptions = sync.options; - if (taskMetadata.periodic && !syncOptions.live) { - const resultCancel: SyncResultCancel = { - action: 'canceled', - }; - return resultCancel; - } sync.eventHandlers.start.forEach(listener => { listener.func( { ...taskMetadata, collectionPath: listener.collectionPath }, @@ -227,7 +220,6 @@ export async function syncWorker ( localCommits = [...commitsFromRemote, normalizeCommit(mergeCommit)]; } // Need push because it is merged normally. - // Set afterMerge option true not to return SyncResultCancel. const syncResultPush = (await pushWorker(gitDDB, sync, taskMetadata, true, true).catch( (err: Error) => { return err; @@ -319,7 +311,6 @@ export async function syncWorker ( } // Push - // Set afterMerge option true not to return SyncResultCancel. const syncResultPush = (await pushWorker(gitDDB, sync, taskMetadata, true, true).catch( (err: Error) => { return err; diff --git a/src/task_queue.ts b/src/task_queue.ts index 0b1a1b98..7533a878 100644 --- a/src/task_queue.ts +++ b/src/task_queue.ts @@ -137,7 +137,6 @@ export class TaskQueue { collectionPath: task.collectionPath, enqueueTime: task.enqueueTime, syncRemoteName: task.syncRemoteName, - periodic: !!task.periodic, }; if (task.enqueueCallback) { try { @@ -238,7 +237,6 @@ export class TaskQueue { const fullDocPath = collectionPath ? collectionPath + shortName : ''; const taskId = this._currentTask.taskId; const syncRemoteName = this._currentTask.syncRemoteName; - const periodic = !!this._currentTask.periodic; this._isTaskQueueWorking = true; this._logger.debug( @@ -269,7 +267,6 @@ export class TaskQueue { collectionPath, enqueueTime: this._currentTask.enqueueTime, syncRemoteName, - periodic, }; this._currentTask.func(beforeResolve, beforeReject, taskMetadata).finally(() => { diff --git a/src/types.ts b/src/types.ts index 3f3b5894..82eedf33 100644 --- a/src/types.ts +++ b/src/types.ts @@ -790,7 +790,6 @@ export type TaskMetadata = { collectionPath?: string; enqueueTime?: string; syncRemoteName?: string; - periodic?: boolean; }; /** From 7a21ca10d6384791153ff599ec33f5607886be56 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Thu, 5 Aug 2021 16:41:49 +0900 Subject: [PATCH 155/297] fix: make sure pushWorker returns SyncResultNop when local does not have ahead commits --- src/remote/push_worker.ts | 29 +++++++++++++++++++---------- test/remote_base/sync.ts | 9 +++++---- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/remote/push_worker.ts b/src/remote/push_worker.ts index c32fb24f..b14388bd 100644 --- a/src/remote/push_worker.ts +++ b/src/remote/push_worker.ts @@ -12,14 +12,13 @@ import { GitDDBInterface } from '../types_gitddb'; import { ChangedFile, NormalizedCommit, - SyncResultCancel, SyncResultNop, SyncResultPush, TaskMetadata, } from '../types'; import { SyncInterface } from '../types_sync'; import { getChanges, getCommitLogs } from './worker_utils'; -import { RemoteEngine, wrappingRemoteEngineError } from './remote_engine'; +import { RemoteEngine, RemoteErr, wrappingRemoteEngineError } from './remote_engine'; /** * Push and get changes @@ -108,10 +107,6 @@ export async function pushWorker ( let baseCommitOid: string | undefined; - if (localCommitOid === remoteCommitOid) { - return { action: 'nop' }; - } - if (remoteCommitOid === undefined) { // This is the first push in this repository. // Get the first commit. @@ -130,7 +125,7 @@ export async function pushWorker ( } // Push - await RemoteEngine[sync.engine] + const res = await RemoteEngine[sync.engine] .push( gitDDB.workingDir, syncOptions, @@ -139,9 +134,23 @@ export async function pushWorker ( gitDDB.defaultBranch, gitDDB.logger ) - .catch(err => { - throw wrappingRemoteEngineError(err); - }); + .catch(err => err); + + if (res instanceof Error) { + const error = wrappingRemoteEngineError(res); + if (error instanceof RemoteErr.UnfetchedCommitExistsError) { + if (localCommitOid === remoteCommitOid) { + return { action: 'nop' }; + } + } + throw error; + } + // NodeGit does not throw UnfetchedCommitExistsError when localCommitOid equals remoteCommitOid, + // So check it again here. + if (localCommitOid === remoteCommitOid) { + return { action: 'nop' }; + } + let remoteChanges: ChangedFile[] | undefined; if (afterMerge) { remoteChanges = undefined; diff --git a/test/remote_base/sync.ts b/test/remote_base/sync.ts index 0839d742..b798a0b6 100644 --- a/test/remote_base/sync.ts +++ b/test/remote_base/sync.ts @@ -763,7 +763,7 @@ export const syncBase = ( await gitDDB.destroy(); }); - it('throws UnfetchedCommitExistsError when tryPush to updated repository', async () => { + it('succeeds when tryPush to updated repository', async () => { const remoteURL = remoteURLBase + serialId(); const dbNameA = serialId(); const dbA: GitDocumentDB = new GitDocumentDB({ @@ -794,9 +794,10 @@ export const syncBase = ( await dbA.close(); await dbA.open(); - await expect(dbA.sync(optionA, true)).rejects.toThrowError( - RemoteErr.UnfetchedCommitExistsError - ); + const [sync, result] = await dbA.sync(optionA, true); + expect(result).toEqual({ + action: 'nop', + }); await destroyDBs([dbA, dbB]); }); From ce77cf31d98d554db1b352b5b4e3ceed7f584b4c Mon Sep 17 00:00:00 2001 From: sosuisen Date: Thu, 5 Aug 2021 17:07:37 +0900 Subject: [PATCH 156/297] docs: align with 0.4.1 --- .../git-documentdb.encodetogitremotename.md | 4 ++ ...-documentdb.gitddbinterface.loadappinfo.md | 21 ------- docs-api/git-documentdb.gitddbinterface.md | 2 - ...-documentdb.gitddbinterface.saveappinfo.md | 28 ---------- ...it-documentdb.gitdocumentdb.loadappinfo.md | 23 -------- docs-api/git-documentdb.gitdocumentdb.md | 2 - ...it-documentdb.gitdocumentdb.saveappinfo.md | 30 ---------- ...-documentdb.remoteengineinterface.fetch.md | 2 +- .../git-documentdb.remoteengineinterface.md | 4 +- ...t-documentdb.remoteengineinterface.name.md | 15 +++++ ...t-documentdb.remoteengineinterface.type.md | 15 +++++ ...documentdb.remoteerr.cannotconnecterror.md | 4 +- ...teerr.httperror401authorizationrequired.md | 4 +- ...umentdb.remoteerr.httperror403forbidden.md | 4 +- ...cumentdb.remoteerr.httperror404notfound.md | 4 +- ...emoteerr.invalidauthenticationtypeerror.md | 4 +- ...umentdb.remoteerr.invalidgitremoteerror.md | 4 +- ...tdb.remoteerr.invalidrepositoryurlerror.md | 4 +- ...mentdb.remoteerr.invalidsshkeypatherror.md | 4 +- ...umentdb.remoteerr.invalidurlformaterror.md | 4 +- .../git-documentdb.remoteerr.networkerror.md | 4 +- ...db.remoteerr.unfetchedcommitexistserror.md | 4 +- docs-api/git-documentdb.sync._constructor_.md | 4 ++ .../git-documentdb.sync.enqueuesynctask.md | 9 ++- docs-api/git-documentdb.sync.md | 2 +- docs-api/git-documentdb.sync.trypush.md | 4 +- .../git-documentdb.syncinterface.trypush.md | 4 +- docs-api/git-documentdb.taskmetadata.md | 1 + ...it-documentdb.wrappingremoteengineerror.md | 4 +- etc/git-documentdb.api.md | 55 +++++++++---------- src/remote/remote_engine.ts | 2 +- src/types.ts | 2 + 32 files changed, 109 insertions(+), 168 deletions(-) delete mode 100644 docs-api/git-documentdb.gitddbinterface.loadappinfo.md delete mode 100644 docs-api/git-documentdb.gitddbinterface.saveappinfo.md delete mode 100644 docs-api/git-documentdb.gitdocumentdb.loadappinfo.md delete mode 100644 docs-api/git-documentdb.gitdocumentdb.saveappinfo.md create mode 100644 docs-api/git-documentdb.remoteengineinterface.name.md create mode 100644 docs-api/git-documentdb.remoteengineinterface.type.md diff --git a/docs-api/git-documentdb.encodetogitremotename.md b/docs-api/git-documentdb.encodetogitremotename.md index b999c5c8..c6a34766 100644 --- a/docs-api/git-documentdb.encodetogitremotename.md +++ b/docs-api/git-documentdb.encodetogitremotename.md @@ -38,3 +38,7 @@ A remote name consists of \[remote address\]\_\[hash\]. Periods are replaced wit \[hash\] is the first seven characters of SHA-1 so that it may collide. Capitalize one of the remote addresses when hashes collide because a hostname and a domain name are not case sensitive. +## Exceptions + +[RemoteErr.InvalidURLFormatError](./git-documentdb.remoteerr.invalidurlformaterror.md) + diff --git a/docs-api/git-documentdb.gitddbinterface.loadappinfo.md b/docs-api/git-documentdb.gitddbinterface.loadappinfo.md deleted file mode 100644 index 5eb7a41a..00000000 --- a/docs-api/git-documentdb.gitddbinterface.loadappinfo.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -sidebar_label: loadAppInfo() -title: GitDDBInterface.loadAppInfo() method -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [GitDDBInterface](./git-documentdb.gitddbinterface.md) > [loadAppInfo](./git-documentdb.gitddbinterface.loadappinfo.md) - -## GitDDBInterface.loadAppInfo() method - -Signature: - -```typescript -loadAppInfo(): { - [key: string]: any; - }; -``` -Returns: - -{ \[key: string\]: any; } - diff --git a/docs-api/git-documentdb.gitddbinterface.md b/docs-api/git-documentdb.gitddbinterface.md index 19d5c8bc..6b155ec1 100644 --- a/docs-api/git-documentdb.gitddbinterface.md +++ b/docs-api/git-documentdb.gitddbinterface.md @@ -45,12 +45,10 @@ export interface GitDDBInterface | [getCommit(oid)](./git-documentdb.gitddbinterface.getcommit.md) | | | [getRemoteURLs()](./git-documentdb.gitddbinterface.getremoteurls.md) | | | [getSync(remoteURL)](./git-documentdb.gitddbinterface.getsync.md) | | -| [loadAppInfo()](./git-documentdb.gitddbinterface.loadappinfo.md) | | | [loadAuthor()](./git-documentdb.gitddbinterface.loadauthor.md) | | | [loadDbInfo()](./git-documentdb.gitddbinterface.loaddbinfo.md) | | | [open(options)](./git-documentdb.gitddbinterface.open.md) | \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* Public methods \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* | | [removeSync(remoteURL)](./git-documentdb.gitddbinterface.removesync.md) | | -| [saveAppInfo(info)](./git-documentdb.gitddbinterface.saveappinfo.md) | | | [saveAuthor()](./git-documentdb.gitddbinterface.saveauthor.md) | | | [sync(options, getSyncResult)](./git-documentdb.gitddbinterface.sync.md) | | | [sync(options)](./git-documentdb.gitddbinterface.sync_1.md) | | diff --git a/docs-api/git-documentdb.gitddbinterface.saveappinfo.md b/docs-api/git-documentdb.gitddbinterface.saveappinfo.md deleted file mode 100644 index 5c2a9f3f..00000000 --- a/docs-api/git-documentdb.gitddbinterface.saveappinfo.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -sidebar_label: saveAppInfo() -title: GitDDBInterface.saveAppInfo() method -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [GitDDBInterface](./git-documentdb.gitddbinterface.md) > [saveAppInfo](./git-documentdb.gitddbinterface.saveappinfo.md) - -## GitDDBInterface.saveAppInfo() method - -Signature: - -```typescript -saveAppInfo(info: { - [key: string]: any; - }): void; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| info | { \[key: string\]: any; } | | - -Returns: - -void - diff --git a/docs-api/git-documentdb.gitdocumentdb.loadappinfo.md b/docs-api/git-documentdb.gitdocumentdb.loadappinfo.md deleted file mode 100644 index 2c8aef16..00000000 --- a/docs-api/git-documentdb.gitdocumentdb.loadappinfo.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -sidebar_label: loadAppInfo() -title: GitDocumentDB.loadAppInfo() method -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [GitDocumentDB](./git-documentdb.gitdocumentdb.md) > [loadAppInfo](./git-documentdb.gitdocumentdb.loadappinfo.md) - -## GitDocumentDB.loadAppInfo() method - -Load app-specific info from .gitddb/app.json - -Signature: - -```typescript -loadAppInfo(): Promise; -``` -Returns: - -Promise<[JsonDoc](./git-documentdb.jsondoc.md) \| undefined> - -JSON object. It returns undefined if app.json does not exist. - diff --git a/docs-api/git-documentdb.gitdocumentdb.md b/docs-api/git-documentdb.gitdocumentdb.md index f793a91d..d849fc88 100644 --- a/docs-api/git-documentdb.gitdocumentdb.md +++ b/docs-api/git-documentdb.gitdocumentdb.md @@ -75,7 +75,6 @@ Call open() before using DB. | [insert(jsonDoc, options)](./git-documentdb.gitdocumentdb.insert.md) | | Insert a JSON document | | [insert(\_id, jsonDoc, options)](./git-documentdb.gitdocumentdb.insert_1.md) | | Insert a JSON document | | [insertFatDoc(name, doc, options)](./git-documentdb.gitdocumentdb.insertfatdoc.md) | | Insert a data | -| [loadAppInfo()](./git-documentdb.gitdocumentdb.loadappinfo.md) | | Load app-specific info from .gitddb/app.json | | [loadAuthor()](./git-documentdb.gitdocumentdb.loadauthor.md) | | Load author from .git/config | | [offSyncEvent(remoteURL, event, callback)](./git-documentdb.gitdocumentdb.offsyncevent.md) | | Remove SyncEvent handler | | [offSyncEvent(sync, event, callback)](./git-documentdb.gitdocumentdb.offsyncevent_1.md) | | Remove SyncEvent handler | @@ -87,7 +86,6 @@ Call open() before using DB. | [put(\_id, jsonDoc, options)](./git-documentdb.gitdocumentdb.put_1.md) | | Insert a JSON document if not exists. Otherwise, update it. | | [putFatDoc(name, doc, options)](./git-documentdb.gitdocumentdb.putfatdoc.md) | | Insert data if not exists. Otherwise, update it. | | [removeSync(remoteURL)](./git-documentdb.gitdocumentdb.removesync.md) | | Stop and unregister remote synchronization | -| [saveAppInfo(info)](./git-documentdb.gitdocumentdb.saveappinfo.md) | | Save app-specific info into .gitddb/app.json | | [saveAuthor()](./git-documentdb.gitdocumentdb.saveauthor.md) | | Save current author to .git/config | | [sync(options)](./git-documentdb.gitdocumentdb.sync.md) | | Synchronize with a remote repository | | [sync(options, getSyncResult)](./git-documentdb.gitdocumentdb.sync_1.md) | | Synchronize with a remote repository | diff --git a/docs-api/git-documentdb.gitdocumentdb.saveappinfo.md b/docs-api/git-documentdb.gitdocumentdb.saveappinfo.md deleted file mode 100644 index 31e8f420..00000000 --- a/docs-api/git-documentdb.gitdocumentdb.saveappinfo.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -sidebar_label: saveAppInfo() -title: GitDocumentDB.saveAppInfo() method -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [GitDocumentDB](./git-documentdb.gitdocumentdb.md) > [saveAppInfo](./git-documentdb.gitdocumentdb.saveappinfo.md) - -## GitDocumentDB.saveAppInfo() method - -Save app-specific info into .gitddb/app.json - -Signature: - -```typescript -saveAppInfo(info: { - [key: string]: any; - }): Promise; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| info | { \[key: string\]: any; } | | - -Returns: - -Promise<void> - diff --git a/docs-api/git-documentdb.remoteengineinterface.fetch.md b/docs-api/git-documentdb.remoteengineinterface.fetch.md index 2f509b04..3780659b 100644 --- a/docs-api/git-documentdb.remoteengineinterface.fetch.md +++ b/docs-api/git-documentdb.remoteengineinterface.fetch.md @@ -11,5 +11,5 @@ hide_title: true Signature: ```typescript -fetch: (workingDir: string, remoteOptions: RemoteOptions, remoteName?: string, logger?: Logger) => Promise; +fetch: (workingDir: string, remoteOptions: RemoteOptions, remoteName?: string, localBranchName?: string, remoteBranchName?: string, logger?: Logger) => Promise; ``` diff --git a/docs-api/git-documentdb.remoteengineinterface.md b/docs-api/git-documentdb.remoteengineinterface.md index a8279a07..980e160a 100644 --- a/docs-api/git-documentdb.remoteengineinterface.md +++ b/docs-api/git-documentdb.remoteengineinterface.md @@ -22,6 +22,8 @@ export interface RemoteEngineInterface | --- | --- | --- | | [checkFetch](./git-documentdb.remoteengineinterface.checkfetch.md) | (workingDir: string, options: [RemoteOptions](./git-documentdb.remoteoptions.md) , remoteName?: string, logger?: Logger) => Promise<boolean> | | | [clone](./git-documentdb.remoteengineinterface.clone.md) | (workingDir: string, remoteOptions: [RemoteOptions](./git-documentdb.remoteoptions.md) , remoteName: string, logger?: Logger) => Promise<void> | | -| [fetch](./git-documentdb.remoteengineinterface.fetch.md) | (workingDir: string, remoteOptions: [RemoteOptions](./git-documentdb.remoteoptions.md) , remoteName?: string, logger?: Logger) => Promise<void> | | +| [fetch](./git-documentdb.remoteengineinterface.fetch.md) | (workingDir: string, remoteOptions: [RemoteOptions](./git-documentdb.remoteoptions.md) , remoteName?: string, localBranchName?: string, remoteBranchName?: string, logger?: Logger) => Promise<void> | | +| [name](./git-documentdb.remoteengineinterface.name.md) | string | | | [push](./git-documentdb.remoteengineinterface.push.md) | (workingDir: string, remoteOptions: [RemoteOptions](./git-documentdb.remoteoptions.md) , remoteName?: string, localBranch?: string, remoteBranch?: string, logger?: Logger) => Promise<void> | | +| [type](./git-documentdb.remoteengineinterface.type.md) | string | | diff --git a/docs-api/git-documentdb.remoteengineinterface.name.md b/docs-api/git-documentdb.remoteengineinterface.name.md new file mode 100644 index 00000000..b6645743 --- /dev/null +++ b/docs-api/git-documentdb.remoteengineinterface.name.md @@ -0,0 +1,15 @@ +--- +sidebar_label: name +title: RemoteEngineInterface.name property +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [RemoteEngineInterface](./git-documentdb.remoteengineinterface.md) > [name](./git-documentdb.remoteengineinterface.name.md) + +## RemoteEngineInterface.name property + +Signature: + +```typescript +name: string; +``` diff --git a/docs-api/git-documentdb.remoteengineinterface.type.md b/docs-api/git-documentdb.remoteengineinterface.type.md new file mode 100644 index 00000000..1d6fd704 --- /dev/null +++ b/docs-api/git-documentdb.remoteengineinterface.type.md @@ -0,0 +1,15 @@ +--- +sidebar_label: type +title: RemoteEngineInterface.type property +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [RemoteEngineInterface](./git-documentdb.remoteengineinterface.md) > [type](./git-documentdb.remoteengineinterface.type.md) + +## RemoteEngineInterface.type property + +Signature: + +```typescript +type: string; +``` diff --git a/docs-api/git-documentdb.remoteerr.cannotconnecterror.md b/docs-api/git-documentdb.remoteerr.cannotconnecterror.md index 1ca70754..b4485319 100644 --- a/docs-api/git-documentdb.remoteerr.cannotconnecterror.md +++ b/docs-api/git-documentdb.remoteerr.cannotconnecterror.md @@ -13,11 +13,11 @@ Copy error message from parent Signature: ```typescript -class CannotConnectError extends RemoteErrors.CannotConnectError +class CannotConnectError extends BaseError ``` Extends: -RemoteErrors.CannotConnectError +BaseError ## Constructors diff --git a/docs-api/git-documentdb.remoteerr.httperror401authorizationrequired.md b/docs-api/git-documentdb.remoteerr.httperror401authorizationrequired.md index 96a225b1..0b095aee 100644 --- a/docs-api/git-documentdb.remoteerr.httperror401authorizationrequired.md +++ b/docs-api/git-documentdb.remoteerr.httperror401authorizationrequired.md @@ -11,11 +11,11 @@ hide_title: true Signature: ```typescript -class HTTPError401AuthorizationRequired extends RemoteErrors.HTTPError401AuthorizationRequired +class HTTPError401AuthorizationRequired extends BaseError ``` Extends: -RemoteErrors.HTTPError401AuthorizationRequired +BaseError ## Constructors diff --git a/docs-api/git-documentdb.remoteerr.httperror403forbidden.md b/docs-api/git-documentdb.remoteerr.httperror403forbidden.md index a3bebaf7..4f2db8e7 100644 --- a/docs-api/git-documentdb.remoteerr.httperror403forbidden.md +++ b/docs-api/git-documentdb.remoteerr.httperror403forbidden.md @@ -11,11 +11,11 @@ hide_title: true Signature: ```typescript -class HTTPError403Forbidden extends RemoteErrors.HTTPError403Forbidden +class HTTPError403Forbidden extends BaseError ``` Extends: -RemoteErrors.HTTPError403Forbidden +BaseError ## Constructors diff --git a/docs-api/git-documentdb.remoteerr.httperror404notfound.md b/docs-api/git-documentdb.remoteerr.httperror404notfound.md index 37ef08cc..ab4acffb 100644 --- a/docs-api/git-documentdb.remoteerr.httperror404notfound.md +++ b/docs-api/git-documentdb.remoteerr.httperror404notfound.md @@ -11,11 +11,11 @@ hide_title: true Signature: ```typescript -class HTTPError404NotFound extends RemoteErrors.HTTPError404NotFound +class HTTPError404NotFound extends BaseError ``` Extends: -RemoteErrors.HTTPError404NotFound +BaseError ## Constructors diff --git a/docs-api/git-documentdb.remoteerr.invalidauthenticationtypeerror.md b/docs-api/git-documentdb.remoteerr.invalidauthenticationtypeerror.md index 3e5f1694..3aaa6830 100644 --- a/docs-api/git-documentdb.remoteerr.invalidauthenticationtypeerror.md +++ b/docs-api/git-documentdb.remoteerr.invalidauthenticationtypeerror.md @@ -11,11 +11,11 @@ hide_title: true Signature: ```typescript -class InvalidAuthenticationTypeError extends RemoteErrors.InvalidAuthenticationTypeError +class InvalidAuthenticationTypeError extends BaseError ``` Extends: -RemoteErrors.InvalidAuthenticationTypeError +BaseError ## Constructors diff --git a/docs-api/git-documentdb.remoteerr.invalidgitremoteerror.md b/docs-api/git-documentdb.remoteerr.invalidgitremoteerror.md index c065bde7..f180cbc1 100644 --- a/docs-api/git-documentdb.remoteerr.invalidgitremoteerror.md +++ b/docs-api/git-documentdb.remoteerr.invalidgitremoteerror.md @@ -11,11 +11,11 @@ hide_title: true Signature: ```typescript -class InvalidGitRemoteError extends RemoteErrors.InvalidGitRemoteError +class InvalidGitRemoteError extends BaseError ``` Extends: -RemoteErrors.InvalidGitRemoteError +BaseError ## Constructors diff --git a/docs-api/git-documentdb.remoteerr.invalidrepositoryurlerror.md b/docs-api/git-documentdb.remoteerr.invalidrepositoryurlerror.md index 5a60f330..3c09021a 100644 --- a/docs-api/git-documentdb.remoteerr.invalidrepositoryurlerror.md +++ b/docs-api/git-documentdb.remoteerr.invalidrepositoryurlerror.md @@ -11,11 +11,11 @@ hide_title: true Signature: ```typescript -class InvalidRepositoryURLError extends RemoteErrors.InvalidRepositoryURLError +class InvalidRepositoryURLError extends BaseError ``` Extends: -RemoteErrors.InvalidRepositoryURLError +BaseError ## Constructors diff --git a/docs-api/git-documentdb.remoteerr.invalidsshkeypatherror.md b/docs-api/git-documentdb.remoteerr.invalidsshkeypatherror.md index 5b07c375..6de84175 100644 --- a/docs-api/git-documentdb.remoteerr.invalidsshkeypatherror.md +++ b/docs-api/git-documentdb.remoteerr.invalidsshkeypatherror.md @@ -11,11 +11,11 @@ hide_title: true Signature: ```typescript -class InvalidSSHKeyPathError extends RemoteErrors.InvalidSSHKeyPathError +class InvalidSSHKeyPathError extends BaseError ``` Extends: -RemoteErrors.InvalidSSHKeyPathError +BaseError ## Constructors diff --git a/docs-api/git-documentdb.remoteerr.invalidurlformaterror.md b/docs-api/git-documentdb.remoteerr.invalidurlformaterror.md index fee837d2..28b3322e 100644 --- a/docs-api/git-documentdb.remoteerr.invalidurlformaterror.md +++ b/docs-api/git-documentdb.remoteerr.invalidurlformaterror.md @@ -11,11 +11,11 @@ hide_title: true Signature: ```typescript -class InvalidURLFormatError extends RemoteErrors.InvalidURLFormatError +class InvalidURLFormatError extends BaseError ``` Extends: -RemoteErrors.InvalidURLFormatError +BaseError ## Constructors diff --git a/docs-api/git-documentdb.remoteerr.networkerror.md b/docs-api/git-documentdb.remoteerr.networkerror.md index b27c9186..01d853c6 100644 --- a/docs-api/git-documentdb.remoteerr.networkerror.md +++ b/docs-api/git-documentdb.remoteerr.networkerror.md @@ -11,11 +11,11 @@ hide_title: true Signature: ```typescript -class NetworkError extends RemoteErrors.NetworkError +class NetworkError extends BaseError ``` Extends: -RemoteErrors.NetworkError +BaseError ## Constructors diff --git a/docs-api/git-documentdb.remoteerr.unfetchedcommitexistserror.md b/docs-api/git-documentdb.remoteerr.unfetchedcommitexistserror.md index fe878eac..ffabc15a 100644 --- a/docs-api/git-documentdb.remoteerr.unfetchedcommitexistserror.md +++ b/docs-api/git-documentdb.remoteerr.unfetchedcommitexistserror.md @@ -11,11 +11,11 @@ hide_title: true Signature: ```typescript -class UnfetchedCommitExistsError extends RemoteErrors.UnfetchedCommitExistsError +class UnfetchedCommitExistsError extends BaseError ``` Extends: -RemoteErrors.UnfetchedCommitExistsError +BaseError ## Constructors diff --git a/docs-api/git-documentdb.sync._constructor_.md b/docs-api/git-documentdb.sync._constructor_.md index 8625492c..366280c6 100644 --- a/docs-api/git-documentdb.sync._constructor_.md +++ b/docs-api/git-documentdb.sync._constructor_.md @@ -31,3 +31,7 @@ constructor(gitDDB: GitDDBInterface, options?: RemoteOptions); [Err.SyncIntervalLessThanOrEqualToRetryIntervalError](./git-documentdb.err.syncintervallessthanorequaltoretryintervalerror.md) +\# Errors from encodeToGitRemoteName + +- [RemoteErr.InvalidURLFormatError](./git-documentdb.remoteerr.invalidurlformaterror.md) + diff --git a/docs-api/git-documentdb.sync.enqueuesynctask.md b/docs-api/git-documentdb.sync.enqueuesynctask.md index df43fcfb..3879e4b6 100644 --- a/docs-api/git-documentdb.sync.enqueuesynctask.md +++ b/docs-api/git-documentdb.sync.enqueuesynctask.md @@ -13,8 +13,15 @@ Enqueue sync task to TaskQueue Signature: ```typescript -enqueueSyncTask(): Promise; +enqueueSyncTask(calledAsPeriodicTask: boolean): Promise; ``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| calledAsPeriodicTask | boolean | | + Returns: Promise<[SyncResult](./git-documentdb.syncresult.md) > diff --git a/docs-api/git-documentdb.sync.md b/docs-api/git-documentdb.sync.md index ebc7b31b..c523f93b 100644 --- a/docs-api/git-documentdb.sync.md +++ b/docs-api/git-documentdb.sync.md @@ -43,7 +43,7 @@ export declare class Sync implements SyncInterface | --- | --- | --- | | [close()](./git-documentdb.sync.close.md) | | Stop and clear remote connection | | [currentRetries()](./git-documentdb.sync.currentretries.md) | | Return current retry count (incremental) | -| [enqueueSyncTask()](./git-documentdb.sync.enqueuesynctask.md) | | Enqueue sync task to TaskQueue | +| [enqueueSyncTask(calledAsPeriodicTask)](./git-documentdb.sync.enqueuesynctask.md) | | Enqueue sync task to TaskQueue | | [init()](./git-documentdb.sync.init.md) | | Initialize remote connection | | [off(event, callback)](./git-documentdb.sync.off.md) | | Remove SyncEvent handler | | [on(event, callback, collectionPath)](./git-documentdb.sync.on.md) | | Add SyncEvent handler | diff --git a/docs-api/git-documentdb.sync.trypush.md b/docs-api/git-documentdb.sync.trypush.md index 79cd7bc7..e36fae58 100644 --- a/docs-api/git-documentdb.sync.trypush.md +++ b/docs-api/git-documentdb.sync.trypush.md @@ -13,11 +13,11 @@ Try to push Signature: ```typescript -tryPush(): Promise; +tryPush(): Promise; ``` Returns: -Promise<[SyncResultPush](./git-documentdb.syncresultpush.md) \| [SyncResultCancel](./git-documentdb.syncresultcancel.md) > +Promise<[SyncResultPush](./git-documentdb.syncresultpush.md) \| [SyncResultCancel](./git-documentdb.syncresultcancel.md) \| [SyncResultNop](./git-documentdb.syncresultnop.md) > ## Exceptions diff --git a/docs-api/git-documentdb.syncinterface.trypush.md b/docs-api/git-documentdb.syncinterface.trypush.md index 5cb47db0..bd7867d5 100644 --- a/docs-api/git-documentdb.syncinterface.trypush.md +++ b/docs-api/git-documentdb.syncinterface.trypush.md @@ -11,9 +11,9 @@ hide_title: true Signature: ```typescript -tryPush(): Promise; +tryPush(): Promise; ``` Returns: -Promise<[SyncResultPush](./git-documentdb.syncresultpush.md) \| [SyncResultCancel](./git-documentdb.syncresultcancel.md) > +Promise<[SyncResultPush](./git-documentdb.syncresultpush.md) \| [SyncResultCancel](./git-documentdb.syncresultcancel.md) \| [SyncResultNop](./git-documentdb.syncresultnop.md) > diff --git a/docs-api/git-documentdb.taskmetadata.md b/docs-api/git-documentdb.taskmetadata.md index d6701e51..39e46e96 100644 --- a/docs-api/git-documentdb.taskmetadata.md +++ b/docs-api/git-documentdb.taskmetadata.md @@ -20,6 +20,7 @@ export declare type TaskMetadata = { shortName?: string; collectionPath?: string; enqueueTime?: string; + syncRemoteName?: string; }; ``` References: diff --git a/docs-api/git-documentdb.wrappingremoteengineerror.md b/docs-api/git-documentdb.wrappingremoteengineerror.md index a7bcc66e..5d4a58e6 100644 --- a/docs-api/git-documentdb.wrappingremoteengineerror.md +++ b/docs-api/git-documentdb.wrappingremoteengineerror.md @@ -13,14 +13,14 @@ wrappingRemoteEngineError Signature: ```typescript -export declare function wrappingRemoteEngineError(remoteEngineError: RemoteErrors.BaseError): Error; +export declare function wrappingRemoteEngineError(remoteEngineError: BaseError): Error; ``` ## Parameters | Parameter | Type | Description | | --- | --- | --- | -| remoteEngineError | RemoteErrors.BaseError | | +| remoteEngineError | BaseError | | Returns: diff --git a/etc/git-documentdb.api.md b/etc/git-documentdb.api.md index d9e06d4a..e5fa610c 100644 --- a/etc/git-documentdb.api.md +++ b/etc/git-documentdb.api.md @@ -6,7 +6,6 @@ import { JSONOp } from 'ot-json1'; import { Logger } from 'tslog'; -import * as RemoteErrors from 'git-documentdb-remote-errors'; import { TLogLevelName } from 'tslog'; // @public @@ -611,10 +610,6 @@ export interface GitDDBInterface { // (undocumented) isOpened: boolean; // (undocumented) - loadAppInfo(): { - [key: string]: any; - }; - // (undocumented) loadAuthor(): Promise; // (undocumented) loadDbInfo(): void; @@ -629,10 +624,6 @@ export interface GitDDBInterface { // (undocumented) rootCollection: ICollection; // (undocumented) - saveAppInfo(info: { - [key: string]: any; - }): void; - // (undocumented) saveAuthor(): Promise; // (undocumented) schema: Schema; @@ -688,7 +679,6 @@ export class GitDocumentDB implements GitDDBInterface, CRUDInterface, Collection insertFatDoc(name: string | undefined | null, doc: JsonDoc | string | Uint8Array, options?: PutOptions): Promise; get isClosing(): boolean; get isOpened(): boolean; - loadAppInfo(): Promise; loadAuthor(): Promise; // @internal loadDbInfo(): Promise; @@ -712,9 +702,6 @@ export class GitDocumentDB implements GitDDBInterface, CRUDInterface, Collection putFatDoc(name: string | undefined | null, doc: JsonDoc | Uint8Array | string, options?: PutOptions): Promise; removeSync(remoteURL: string): void; get rootCollection(): ICollection; - saveAppInfo(info: { - [key: string]: any; - }): Promise; saveAuthor(): Promise; get schema(): Schema; sync(options: RemoteOptions): Promise; @@ -880,54 +867,59 @@ export interface RemoteEngineInterface { // (undocumented) clone: (workingDir: string, remoteOptions: RemoteOptions, remoteName: string, logger?: Logger) => Promise; // (undocumented) - fetch: (workingDir: string, remoteOptions: RemoteOptions, remoteName?: string, logger?: Logger) => Promise; + fetch: (workingDir: string, remoteOptions: RemoteOptions, remoteName?: string, localBranchName?: string, remoteBranchName?: string, logger?: Logger) => Promise; + // (undocumented) + name: string; // (undocumented) push: (workingDir: string, remoteOptions: RemoteOptions, remoteName?: string, localBranch?: string, remoteBranch?: string, logger?: Logger) => Promise; + // (undocumented) + type: string; } // @public export namespace RemoteErr { - export class CannotConnectError extends RemoteErrors.CannotConnectError { + // Warning: (ae-forgotten-export) The symbol "BaseError" needs to be exported by the entry point main.d.ts + export class CannotConnectError extends BaseError { constructor(mes: unknown); } // (undocumented) - export class HTTPError401AuthorizationRequired extends RemoteErrors.HTTPError401AuthorizationRequired { + export class HTTPError401AuthorizationRequired extends BaseError { constructor(mes: unknown); } // (undocumented) - export class HTTPError403Forbidden extends RemoteErrors.HTTPError403Forbidden { + export class HTTPError403Forbidden extends BaseError { constructor(mes: unknown); } // (undocumented) - export class HTTPError404NotFound extends RemoteErrors.HTTPError404NotFound { + export class HTTPError404NotFound extends BaseError { constructor(mes: unknown); } // (undocumented) - export class InvalidAuthenticationTypeError extends RemoteErrors.InvalidAuthenticationTypeError { + export class InvalidAuthenticationTypeError extends BaseError { constructor(mes: unknown); } // (undocumented) - export class InvalidGitRemoteError extends RemoteErrors.InvalidGitRemoteError { + export class InvalidGitRemoteError extends BaseError { constructor(mes: unknown); } // (undocumented) - export class InvalidRepositoryURLError extends RemoteErrors.InvalidRepositoryURLError { + export class InvalidRepositoryURLError extends BaseError { constructor(mes: unknown); } // (undocumented) - export class InvalidSSHKeyPathError extends RemoteErrors.InvalidSSHKeyPathError { + export class InvalidSSHKeyPathError extends BaseError { constructor(mes: unknown); } // (undocumented) - export class InvalidURLFormatError extends RemoteErrors.InvalidURLFormatError { + export class InvalidURLFormatError extends BaseError { constructor(mes: unknown); } // (undocumented) - export class NetworkError extends RemoteErrors.NetworkError { + export class NetworkError extends BaseError { constructor(mes: unknown); } // (undocumented) - export class UnfetchedCommitExistsError extends RemoteErrors.UnfetchedCommitExistsError { + export class UnfetchedCommitExistsError extends BaseError { constructor(mes: unknown); } } @@ -971,7 +963,7 @@ export class Sync implements SyncInterface { currentRetries(): number; // (undocumented) get engine(): string; - enqueueSyncTask(): Promise; + enqueueSyncTask(calledAsPeriodicTask: boolean): Promise; // @internal eventHandlers: { change: { @@ -1029,8 +1021,12 @@ export class Sync implements SyncInterface { interval?: number; retry?: number; }): boolean; - tryPush(): Promise; + tryPush(): Promise; + // @internal + tryPushImpl(calledAsPeriodicTask: boolean): Promise; trySync(): Promise; + // @internal + trySyncImpl(calledAsPeriodicTask: boolean): Promise; } // Warning: (ae-internal-missing-underscore) The name "syncAndGetResultImpl" should be prefixed with an underscore because the declaration is marked as @internal @@ -1153,7 +1149,7 @@ export interface SyncInterface { retry?: number; }): void; // (undocumented) - tryPush(): Promise; + tryPush(): Promise; // (undocumented) trySync(): Promise; } @@ -1286,6 +1282,7 @@ export type TaskMetadata = { shortName?: string; collectionPath?: string; enqueueTime?: string; + syncRemoteName?: string; }; // @public @@ -1351,7 +1348,7 @@ export class Validator { } // @public -export function wrappingRemoteEngineError(remoteEngineError: RemoteErrors.BaseError): Error; +export function wrappingRemoteEngineError(remoteEngineError: BaseError): Error; // @public export type WriteOperation = 'insert' | 'update' | 'delete' | 'insert-merge' | 'update-merge'; diff --git a/src/remote/remote_engine.ts b/src/remote/remote_engine.ts index fb627301..be5dbb28 100644 --- a/src/remote/remote_engine.ts +++ b/src/remote/remote_engine.ts @@ -49,7 +49,7 @@ export interface RemoteEngineInterface { ) => Promise; } -export class BaseError extends Error { +class BaseError extends Error { constructor (e: string) { super(e); this.name = new.target.name; diff --git a/src/types.ts b/src/types.ts index 82eedf33..511f8b41 100644 --- a/src/types.ts +++ b/src/types.ts @@ -10,6 +10,8 @@ import { TLogLevelName } from 'tslog'; /** * Plugin types + * + * @public */ export type PluginTypes = 'db' | 'remote'; From 37b7f890648f42b7dd87ca3d75c516434535c575 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Thu, 5 Aug 2021 18:45:24 +0900 Subject: [PATCH 157/297] build: bump to v0.4.1-beta.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2ff49728..e97d080d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "git-documentdb", - "version": "0.4.1-beta.2", + "version": "0.4.1-beta.3", "description": "Offline-first database that syncs with Git", "main": "dist/main.js", "types": "dist/main.d.ts", From ba947298d74322c336e5b6888ae14af92ceabb91 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Thu, 5 Aug 2021 22:24:45 +0900 Subject: [PATCH 158/297] build: package-lock is updated --- package-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index 1b5907c0..2fa649ea 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "git-documentdb", - "version": "0.4.1-beta.2", + "version": "0.4.1-beta.3", "lockfileVersion": 1, "requires": true, "dependencies": { From 7b44a43eb1f595298b04f0f4e8a976d505b73e62 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Thu, 5 Aug 2021 23:32:30 +0900 Subject: [PATCH 159/297] docs: fix api docs --- ...ntdb.err.httpnetworkerror._constructor_.md | 24 --------------- .../git-documentdb.err.httpnetworkerror.md | 26 ----------------- docs-api/git-documentdb.err.md | 1 - docs-api/git-documentdb.md | 2 -- ...mentdb.remoteengineinterface.checkfetch.md | 15 ---------- ...-documentdb.remoteengineinterface.clone.md | 15 ---------- ...-documentdb.remoteengineinterface.fetch.md | 15 ---------- .../git-documentdb.remoteengineinterface.md | 29 ------------------- ...t-documentdb.remoteengineinterface.name.md | 15 ---------- ...t-documentdb.remoteengineinterface.push.md | 15 ---------- ...t-documentdb.remoteengineinterface.type.md | 15 ---------- ...documentdb.remoteerr.cannotconnecterror.md | 2 -- docs-api/git-documentdb.remoteerr.md | 2 +- ...it-documentdb.wrappingremoteengineerror.md | 28 ------------------ etc/git-documentdb.api.md | 18 ++++++++---- src/error.ts | 9 ------ src/remote/remote_engine.ts | 5 ++-- 17 files changed, 16 insertions(+), 220 deletions(-) delete mode 100644 docs-api/git-documentdb.err.httpnetworkerror._constructor_.md delete mode 100644 docs-api/git-documentdb.err.httpnetworkerror.md delete mode 100644 docs-api/git-documentdb.remoteengineinterface.checkfetch.md delete mode 100644 docs-api/git-documentdb.remoteengineinterface.clone.md delete mode 100644 docs-api/git-documentdb.remoteengineinterface.fetch.md delete mode 100644 docs-api/git-documentdb.remoteengineinterface.md delete mode 100644 docs-api/git-documentdb.remoteengineinterface.name.md delete mode 100644 docs-api/git-documentdb.remoteengineinterface.push.md delete mode 100644 docs-api/git-documentdb.remoteengineinterface.type.md delete mode 100644 docs-api/git-documentdb.wrappingremoteengineerror.md diff --git a/docs-api/git-documentdb.err.httpnetworkerror._constructor_.md b/docs-api/git-documentdb.err.httpnetworkerror._constructor_.md deleted file mode 100644 index 36071f0f..00000000 --- a/docs-api/git-documentdb.err.httpnetworkerror._constructor_.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -sidebar_label: (constructor) -title: Err.HTTPNetworkError.(constructor) -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [Err](./git-documentdb.err.md) > [HTTPNetworkError](./git-documentdb.err.httpnetworkerror.md) > [(constructor)](./git-documentdb.err.httpnetworkerror._constructor_.md) - -## Err.HTTPNetworkError.(constructor) - -Constructs a new instance of the `HTTPNetworkError` class - -Signature: - -```typescript -constructor(mes: unknown); -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| mes | unknown | | - diff --git a/docs-api/git-documentdb.err.httpnetworkerror.md b/docs-api/git-documentdb.err.httpnetworkerror.md deleted file mode 100644 index bc667c42..00000000 --- a/docs-api/git-documentdb.err.httpnetworkerror.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -sidebar_label: HTTPNetworkError -title: Err.HTTPNetworkError class -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [Err](./git-documentdb.err.md) > [HTTPNetworkError](./git-documentdb.err.httpnetworkerror.md) - -## Err.HTTPNetworkError class - - -Signature: - -```typescript -export class HTTPNetworkError extends BaseError -``` -Extends: - -BaseError - -## Constructors - -| Constructor | Modifiers | Description | -| --- | --- | --- | -| [(constructor)(mes)](./git-documentdb.err.httpnetworkerror._constructor_.md) | | Constructs a new instance of the HTTPNetworkError class | - diff --git a/docs-api/git-documentdb.err.md b/docs-api/git-documentdb.err.md index 5bc5fed6..1a5146cf 100644 --- a/docs-api/git-documentdb.err.md +++ b/docs-api/git-documentdb.err.md @@ -36,7 +36,6 @@ export declare namespace Err | [DocumentNotFoundError](./git-documentdb.err.documentnotfounderror.md) | | | [FileRemoveTimeoutError](./git-documentdb.err.fileremovetimeouterror.md) | | | [GitMergeBranchError](./git-documentdb.err.gitmergebrancherror.md) | | -| [HTTPNetworkError](./git-documentdb.err.httpnetworkerror.md) | | | [HttpProtocolRequiredError](./git-documentdb.err.httpprotocolrequirederror.md) | | | [IntervalTooSmallError](./git-documentdb.err.intervaltoosmallerror.md) | | | [InvalidCollectionPathCharacterError](./git-documentdb.err.invalidcollectionpathcharactererror.md) | | diff --git a/docs-api/git-documentdb.md b/docs-api/git-documentdb.md index 6b38731a..fd8d3c0c 100644 --- a/docs-api/git-documentdb.md +++ b/docs-api/git-documentdb.md @@ -26,7 +26,6 @@ Offline-first Database that Syncs with Git | Function | Description | | --- | --- | | [encodeToGitRemoteName(remoteURL)](./git-documentdb.encodetogitremotename.md) | encodeToRemoteName | -| [wrappingRemoteEngineError(remoteEngineError)](./git-documentdb.wrappingremoteengineerror.md) | wrappingRemoteEngineError | ## Interfaces @@ -35,7 +34,6 @@ Offline-first Database that Syncs with Git | [CollectionInterface](./git-documentdb.collectioninterface.md) | Interface for Collection | | [CRUDInterface](./git-documentdb.crudinterface.md) | Interface for GitDocumentDB CRUD | | [GitDDBInterface](./git-documentdb.gitddbinterface.md) | Interface of GitDocumentDB body | -| [RemoteEngineInterface](./git-documentdb.remoteengineinterface.md) | RemoteEngineInterface | | [SyncEventInterface](./git-documentdb.synceventinterface.md) | Interface for SyncEvent | | [SyncInterface](./git-documentdb.syncinterface.md) | Interface of Sync | diff --git a/docs-api/git-documentdb.remoteengineinterface.checkfetch.md b/docs-api/git-documentdb.remoteengineinterface.checkfetch.md deleted file mode 100644 index 103e0b5b..00000000 --- a/docs-api/git-documentdb.remoteengineinterface.checkfetch.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -sidebar_label: checkFetch -title: RemoteEngineInterface.checkFetch property -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [RemoteEngineInterface](./git-documentdb.remoteengineinterface.md) > [checkFetch](./git-documentdb.remoteengineinterface.checkfetch.md) - -## RemoteEngineInterface.checkFetch property - -Signature: - -```typescript -checkFetch: (workingDir: string, options: RemoteOptions, remoteName?: string, logger?: Logger) => Promise; -``` diff --git a/docs-api/git-documentdb.remoteengineinterface.clone.md b/docs-api/git-documentdb.remoteengineinterface.clone.md deleted file mode 100644 index cc9b78a5..00000000 --- a/docs-api/git-documentdb.remoteengineinterface.clone.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -sidebar_label: clone -title: RemoteEngineInterface.clone property -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [RemoteEngineInterface](./git-documentdb.remoteengineinterface.md) > [clone](./git-documentdb.remoteengineinterface.clone.md) - -## RemoteEngineInterface.clone property - -Signature: - -```typescript -clone: (workingDir: string, remoteOptions: RemoteOptions, remoteName: string, logger?: Logger) => Promise; -``` diff --git a/docs-api/git-documentdb.remoteengineinterface.fetch.md b/docs-api/git-documentdb.remoteengineinterface.fetch.md deleted file mode 100644 index 3780659b..00000000 --- a/docs-api/git-documentdb.remoteengineinterface.fetch.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -sidebar_label: fetch -title: RemoteEngineInterface.fetch property -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [RemoteEngineInterface](./git-documentdb.remoteengineinterface.md) > [fetch](./git-documentdb.remoteengineinterface.fetch.md) - -## RemoteEngineInterface.fetch property - -Signature: - -```typescript -fetch: (workingDir: string, remoteOptions: RemoteOptions, remoteName?: string, localBranchName?: string, remoteBranchName?: string, logger?: Logger) => Promise; -``` diff --git a/docs-api/git-documentdb.remoteengineinterface.md b/docs-api/git-documentdb.remoteengineinterface.md deleted file mode 100644 index 980e160a..00000000 --- a/docs-api/git-documentdb.remoteengineinterface.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -sidebar_label: RemoteEngineInterface interface -title: RemoteEngineInterface interface -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [RemoteEngineInterface](./git-documentdb.remoteengineinterface.md) - -## RemoteEngineInterface interface - -RemoteEngineInterface - -Signature: - -```typescript -export interface RemoteEngineInterface -``` - -## Properties - -| Property | Type | Description | -| --- | --- | --- | -| [checkFetch](./git-documentdb.remoteengineinterface.checkfetch.md) | (workingDir: string, options: [RemoteOptions](./git-documentdb.remoteoptions.md) , remoteName?: string, logger?: Logger) => Promise<boolean> | | -| [clone](./git-documentdb.remoteengineinterface.clone.md) | (workingDir: string, remoteOptions: [RemoteOptions](./git-documentdb.remoteoptions.md) , remoteName: string, logger?: Logger) => Promise<void> | | -| [fetch](./git-documentdb.remoteengineinterface.fetch.md) | (workingDir: string, remoteOptions: [RemoteOptions](./git-documentdb.remoteoptions.md) , remoteName?: string, localBranchName?: string, remoteBranchName?: string, logger?: Logger) => Promise<void> | | -| [name](./git-documentdb.remoteengineinterface.name.md) | string | | -| [push](./git-documentdb.remoteengineinterface.push.md) | (workingDir: string, remoteOptions: [RemoteOptions](./git-documentdb.remoteoptions.md) , remoteName?: string, localBranch?: string, remoteBranch?: string, logger?: Logger) => Promise<void> | | -| [type](./git-documentdb.remoteengineinterface.type.md) | string | | - diff --git a/docs-api/git-documentdb.remoteengineinterface.name.md b/docs-api/git-documentdb.remoteengineinterface.name.md deleted file mode 100644 index b6645743..00000000 --- a/docs-api/git-documentdb.remoteengineinterface.name.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -sidebar_label: name -title: RemoteEngineInterface.name property -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [RemoteEngineInterface](./git-documentdb.remoteengineinterface.md) > [name](./git-documentdb.remoteengineinterface.name.md) - -## RemoteEngineInterface.name property - -Signature: - -```typescript -name: string; -``` diff --git a/docs-api/git-documentdb.remoteengineinterface.push.md b/docs-api/git-documentdb.remoteengineinterface.push.md deleted file mode 100644 index bc73ed48..00000000 --- a/docs-api/git-documentdb.remoteengineinterface.push.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -sidebar_label: push -title: RemoteEngineInterface.push property -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [RemoteEngineInterface](./git-documentdb.remoteengineinterface.md) > [push](./git-documentdb.remoteengineinterface.push.md) - -## RemoteEngineInterface.push property - -Signature: - -```typescript -push: (workingDir: string, remoteOptions: RemoteOptions, remoteName?: string, localBranch?: string, remoteBranch?: string, logger?: Logger) => Promise; -``` diff --git a/docs-api/git-documentdb.remoteengineinterface.type.md b/docs-api/git-documentdb.remoteengineinterface.type.md deleted file mode 100644 index 1d6fd704..00000000 --- a/docs-api/git-documentdb.remoteengineinterface.type.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -sidebar_label: type -title: RemoteEngineInterface.type property -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [RemoteEngineInterface](./git-documentdb.remoteengineinterface.md) > [type](./git-documentdb.remoteengineinterface.type.md) - -## RemoteEngineInterface.type property - -Signature: - -```typescript -type: string; -``` diff --git a/docs-api/git-documentdb.remoteerr.cannotconnecterror.md b/docs-api/git-documentdb.remoteerr.cannotconnecterror.md index b4485319..b9b27d3f 100644 --- a/docs-api/git-documentdb.remoteerr.cannotconnecterror.md +++ b/docs-api/git-documentdb.remoteerr.cannotconnecterror.md @@ -8,8 +8,6 @@ hide_title: true ## RemoteErr.CannotConnectError class -Copy error message from parent - Signature: ```typescript diff --git a/docs-api/git-documentdb.remoteerr.md b/docs-api/git-documentdb.remoteerr.md index 0720a6e6..3d8364b4 100644 --- a/docs-api/git-documentdb.remoteerr.md +++ b/docs-api/git-documentdb.remoteerr.md @@ -20,7 +20,7 @@ export declare namespace RemoteErr | Class | Description | | --- | --- | -| [CannotConnectError](./git-documentdb.remoteerr.cannotconnecterror.md) | Copy error message from parent | +| [CannotConnectError](./git-documentdb.remoteerr.cannotconnecterror.md) | | | [HTTPError401AuthorizationRequired](./git-documentdb.remoteerr.httperror401authorizationrequired.md) | | | [HTTPError403Forbidden](./git-documentdb.remoteerr.httperror403forbidden.md) | | | [HTTPError404NotFound](./git-documentdb.remoteerr.httperror404notfound.md) | | diff --git a/docs-api/git-documentdb.wrappingremoteengineerror.md b/docs-api/git-documentdb.wrappingremoteengineerror.md deleted file mode 100644 index 5d4a58e6..00000000 --- a/docs-api/git-documentdb.wrappingremoteengineerror.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -sidebar_label: wrappingRemoteEngineError() function -title: wrappingRemoteEngineError() function -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [wrappingRemoteEngineError](./git-documentdb.wrappingremoteengineerror.md) - -## wrappingRemoteEngineError() function - -wrappingRemoteEngineError - -Signature: - -```typescript -export declare function wrappingRemoteEngineError(remoteEngineError: BaseError): Error; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| remoteEngineError | BaseError | | - -Returns: - -Error - diff --git a/etc/git-documentdb.api.md b/etc/git-documentdb.api.md index e5fa610c..c0568dae 100644 --- a/etc/git-documentdb.api.md +++ b/etc/git-documentdb.api.md @@ -374,10 +374,6 @@ export namespace Err { constructor(mes: string); } // (undocumented) - export class HTTPNetworkError extends BaseError { - constructor(mes: unknown); - } - // (undocumented) export class HttpProtocolRequiredError extends BaseError { constructor(url: unknown); } @@ -860,7 +856,9 @@ export const RemoteEngine: { [key: string]: RemoteEngineInterface; }; -// @public +// Warning: (ae-internal-missing-underscore) The name "RemoteEngineInterface" should be prefixed with an underscore because the declaration is marked as @internal +// +// @internal export interface RemoteEngineInterface { // (undocumented) checkFetch: (workingDir: string, options: RemoteOptions, remoteName?: string, logger?: Logger) => Promise; @@ -879,6 +877,8 @@ export interface RemoteEngineInterface { // @public export namespace RemoteErr { // Warning: (ae-forgotten-export) The symbol "BaseError" needs to be exported by the entry point main.d.ts + // + // (undocumented) export class CannotConnectError extends BaseError { constructor(mes: unknown); } @@ -1347,10 +1347,16 @@ export class Validator { validateLocalDir(localDir: string): void; } -// @public +// Warning: (ae-internal-missing-underscore) The name "wrappingRemoteEngineError" should be prefixed with an underscore because the declaration is marked as @internal +// +// @internal export function wrappingRemoteEngineError(remoteEngineError: BaseError): Error; // @public export type WriteOperation = 'insert' | 'update' | 'delete' | 'insert-merge' | 'update-merge'; +// Warnings were encountered during analysis: +// +// src/remote/remote_engine.ts:11:30 - (ae-incompatible-release-tags) The symbol "__index" is marked as @public, but its signature references "RemoteEngineInterface" which is marked as @internal + ``` diff --git a/src/error.ts b/src/error.ts index 8663f6d8..8c56f29a 100644 --- a/src/error.ts +++ b/src/error.ts @@ -372,15 +372,6 @@ Call removeRemote() before register it again.` } } - /** - * @public - */ - export class HTTPNetworkError extends BaseError { - constructor (mes: unknown) { - super(`HTTPNetworkError: ${mes}`); - } - } - /** * @public */ diff --git a/src/remote/remote_engine.ts b/src/remote/remote_engine.ts index be5dbb28..5b946750 100644 --- a/src/remote/remote_engine.ts +++ b/src/remote/remote_engine.ts @@ -13,7 +13,7 @@ export const RemoteEngine: { [key: string]: RemoteEngineInterface } = {}; /** * RemoteEngineInterface * - * @public + * @internal */ export interface RemoteEngineInterface { type: string; @@ -64,6 +64,7 @@ class BaseError extends Error { */ export namespace RemoteErr { /** + * @privateRemarks * Copy error message from parent */ export class CannotConnectError extends BaseError { @@ -137,7 +138,7 @@ export namespace RemoteErr { /** * wrappingRemoteEngineError * - * @public + * @internal */ // eslint-disable-next-line complexity export function wrappingRemoteEngineError (remoteEngineError: BaseError) { From 7b0adb6848fc8d53657aff4cfd653c9ead3d37ed Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 6 Aug 2021 00:39:28 +0900 Subject: [PATCH 160/297] fix: remove note about native module from README --- README.md | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index ad73173b..f9a7adbc 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Use GitDocumentDB to ... :green_book: Manage JSON documents in Git repository by CRUD and collection APIs. -:rocket: Synchronize automatically with a remote repository. +:rocket: Synchronize automatically with remote repositories.      *(No need to resolve conflicts manually!)* @@ -34,20 +34,6 @@ Node.js 12 or later ``` npm i git-documentdb ``` -**NOTE:**
-GitDocumentDB uses native addon (libgit2).
-If you receive errors about installation, you probably miss building tools and libraries.
-**In Ubuntu 18:**
-``` -sudo apt update -sudo apt install build-essential libssl-dev libkrb5-dev libc++-dev -``` -**In Windows 10:**
-The list below shows typical environments. -- Node.js 12, Python 2.7.x, and Visual Studio 2017 Community (with Desktop development with C++). -- npm config set msvs_version 2017 - -If you are still encountering install problems, documents about [NodeGit](https://github.com/nodegit/nodegit#getting-started) and [Building NodeGit from source](https://www.nodegit.org/guides/install/from-source/) may also help you. ## Import ```typescript @@ -241,8 +227,8 @@ https://github.com/sosuisen/inventory-manager - Automated combining of inconsistent repositories :feet: - v0.4 Work on both Node.js and browser - API renewal to manage any data types :feet: - - Remove native module (NodeGit) from default install :dog2:(Next) - - Connect with SSH key pair + - Remove native module (NodeGit) from default install :feet: + - Connect with SSH key pair :dog2:(Next) - Connect to GitHub with OAuth - Work on browser From 9663ba4d13614001f59a42e1102248bf1941ac12 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 6 Aug 2021 00:43:45 +0900 Subject: [PATCH 161/297] docs: update roadmap --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f9a7adbc..c2e8bdf8 100644 --- a/README.md +++ b/README.md @@ -228,6 +228,7 @@ https://github.com/sosuisen/inventory-manager - v0.4 Work on both Node.js and browser - API renewal to manage any data types :feet: - Remove native module (NodeGit) from default install :feet: + - Add plugin system for remote connection (isomorphic-git or NodeGit) :feet: - Connect with SSH key pair :dog2:(Next) - Connect to GitHub with OAuth - Work on browser @@ -242,6 +243,5 @@ https://github.com/sosuisen/inventory-manager - GitLab and Bitbucket - Push server - Migration - - Plugins (https://github.com/sosuisen/git-documentdb/projects/2) From 68b891967f381e06b33b03b78a852b5953c19206 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 6 Aug 2021 00:49:12 +0900 Subject: [PATCH 162/297] build: bump to v0.4.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e97d080d..fc4af93d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "git-documentdb", - "version": "0.4.1-beta.3", + "version": "0.4.1", "description": "Offline-first database that syncs with Git", "main": "dist/main.js", "types": "dist/main.d.ts", From 8c51e5748e3e9eea9837dff2818dfe71bbda0947 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 6 Aug 2021 19:11:49 +0900 Subject: [PATCH 163/297] build: bump git-documentdb-plugin-remote-nodegit to v1.0.4 --- examples/package-lock.json | 274 ++++++++++++++++++++++++------------ examples/package.json | 2 +- package-lock.json | 278 ++++++++++++++++++++++++------------- package.json | 2 +- 4 files changed, 365 insertions(+), 191 deletions(-) diff --git a/examples/package-lock.json b/examples/package-lock.json index d3cf31fb..af3a3144 100644 --- a/examples/package-lock.json +++ b/examples/package-lock.json @@ -9,6 +9,22 @@ "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-2.1.1.tgz", "integrity": "sha512-/aPsuoj/1Dw/kzhkgz+ES6TxG0zfTMGLwuK2ZG00k/iJzYHTLCE8mVU8EPqEOp/lmxPoq1C1C9RYToRKb2KEfg==" }, + "@sosuisen/nodegit": { + "version": "0.28.0-alpha.11", + "resolved": "https://registry.npmjs.org/@sosuisen/nodegit/-/nodegit-0.28.0-alpha.11.tgz", + "integrity": "sha512-mpztf9ncWxU7/agKQ6E7GvlBIa6H7m3YXuMjlPWVegHusqkbgPi4J01d2inCPhLz0CoC0F/L3LKJuDCAKDXJJg==", + "requires": { + "fs-extra": "^7.0.0", + "got": "^10.7.0", + "json5": "^2.1.0", + "lodash": "^4.17.14", + "nan": "^2.14.1", + "node-gyp": "^7.1.2", + "node-pre-gyp": "^0.13.0", + "ramda": "^0.25.0", + "tar-fs": "^1.16.3" + } + }, "@szmarczak/http-timer": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", @@ -42,9 +58,9 @@ } }, "@types/node": { - "version": "16.4.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.4.11.tgz", - "integrity": "sha512-nWSFUbuNiPKJEe1IViuodSI+9cM+vpM8SWF/O6dJK7wmGRNq55U7XavJHrlRrPkSMuUZUFzg1xaZ1B+ZZCrRWw==" + "version": "16.4.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.4.13.tgz", + "integrity": "sha512-bLL69sKtd25w7p1nvg9pigE4gtKVpGTPojBFLMkGHXuUgap2sLqQt2qUnqmVCDfzGUL0DRNZP+1prIZJbMeAXg==" }, "@types/responselike": { "version": "1.0.0", @@ -201,9 +217,9 @@ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" }, "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" }, "clone-response": { "version": "1.0.2", @@ -319,6 +335,11 @@ "once": "^1.4.0" } }, + "env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==" + }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -370,11 +391,11 @@ } }, "fs-minipass": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", - "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", "requires": { - "minipass": "^2.6.0" + "minipass": "^3.0.0" } }, "fs.realpath": { @@ -7510,12 +7531,12 @@ } }, "git-documentdb-plugin-remote-nodegit": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.3.tgz", - "integrity": "sha512-80cxPE+jIjDpECCXAmNtjZxMFVNc38yFkZmEd3hRp6EvSQhX6nky0kmEFWZ1aeFnTq0oATEJvEJg9yO8zYkyng==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.4.tgz", + "integrity": "sha512-+esXlN6PMmvwKZPU6dn/kSQnVe5QHU9xGzoNrLiqehz+VM1AXgNhsce/KipimG4wdzUS6tbS9QbgIgA4VjpbAw==", "requires": { + "@sosuisen/nodegit": "^0.28.0-alpha.11", "git-documentdb-remote-errors": "^1.0.3", - "nodegit": "^0.27.0", "tslog": "^3.2.0" } }, @@ -7560,9 +7581,9 @@ } }, "graceful-fs": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", + "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" }, "har-schema": { "version": "2.0.0", @@ -7731,6 +7752,14 @@ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, "mime-db": { "version": "1.49.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz", @@ -7763,29 +7792,26 @@ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, "minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" + "yallist": "^4.0.0" } }, "minizlib": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", - "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", "requires": { - "minipass": "^2.9.0" + "minipass": "^3.0.0", + "yallist": "^4.0.0" } }, "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "requires": { - "minimist": "^1.2.5" - } + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" }, "ms": { "version": "2.1.3", @@ -7793,9 +7819,9 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "nan": { - "version": "2.14.2", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", - "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==" + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", + "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==" }, "needle": { "version": "2.8.0", @@ -7808,21 +7834,20 @@ } }, "node-gyp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-4.0.0.tgz", - "integrity": "sha512-2XiryJ8sICNo6ej8d0idXDEMKfVfFK7kekGCtJAuelGsYHQxhj13KTf95swTCN2dZ/4lTfZ84Fu31jqJEEgjWA==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-7.1.2.tgz", + "integrity": "sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ==", "requires": { - "glob": "^7.0.3", - "graceful-fs": "^4.1.2", - "mkdirp": "^0.5.0", - "nopt": "2 || 3", - "npmlog": "0 || 1 || 2 || 3 || 4", - "osenv": "0", - "request": "^2.87.0", - "rimraf": "2", - "semver": "~5.3.0", - "tar": "^4.4.8", - "which": "1" + "env-paths": "^2.2.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.3", + "nopt": "^5.0.0", + "npmlog": "^4.1.2", + "request": "^2.88.2", + "rimraf": "^3.0.2", + "semver": "^7.3.2", + "tar": "^6.0.2", + "which": "^2.0.2" } }, "node-pre-gyp": { @@ -7842,6 +7867,44 @@ "tar": "^4" }, "dependencies": { + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, + "fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "requires": { + "minipass": "^2.6.0" + } + }, + "minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "requires": { + "minipass": "^2.9.0" + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "requires": { + "minimist": "^1.2.5" + } + }, "nopt": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", @@ -7850,29 +7913,45 @@ "abbrev": "1", "osenv": "^0.1.4" } + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "requires": { + "glob": "^7.1.3" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "tar": { + "version": "4.4.15", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.15.tgz", + "integrity": "sha512-ItbufpujXkry7bHH9NpQyTXPbJ72iTlXgkBAYsAjDXk3Ds8t/3NfO5P4xZGy7u+sYuQUbimgzswX4uQIEeNVOA==", + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + } + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" } } }, - "nodegit": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/nodegit/-/nodegit-0.27.0.tgz", - "integrity": "sha512-E9K4gPjWiA0b3Tx5lfWCzG7Cvodi2idl3V5UD2fZrOrHikIfrN7Fc2kWLtMUqqomyoToYJLeIC8IV7xb1CYRLA==", - "requires": { - "fs-extra": "^7.0.0", - "got": "^10.7.0", - "json5": "^2.1.0", - "lodash": "^4.17.14", - "nan": "^2.14.0", - "node-gyp": "^4.0.0", - "node-pre-gyp": "^0.13.0", - "ramda": "^0.25.0", - "tar-fs": "^1.16.3" - } - }, "nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", "requires": { "abbrev": "1" } @@ -8089,9 +8168,9 @@ } }, "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "requires": { "glob": "^7.1.3" } @@ -8112,9 +8191,12 @@ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" }, "semver": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", - "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "requires": { + "lru-cache": "^6.0.0" + } }, "set-blocking": { "version": "2.0.0", @@ -8188,17 +8270,16 @@ "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" }, "tar": { - "version": "4.4.15", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.15.tgz", - "integrity": "sha512-ItbufpujXkry7bHH9NpQyTXPbJ72iTlXgkBAYsAjDXk3Ds8t/3NfO5P4xZGy7u+sYuQUbimgzswX4uQIEeNVOA==", + "version": "6.1.6", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.6.tgz", + "integrity": "sha512-oaWyu5dQbHaYcyZCTfyPpC+VmI62/OM2RTUYavTk1MDr1cwW5Boi3baeYQKiZbY2uSQJGr+iMOzb/JFxLrft+g==", "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.8.6", - "minizlib": "^1.2.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.3" + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" } }, "tar-fs": { @@ -8212,6 +8293,19 @@ "tar-stream": "^1.1.2" }, "dependencies": { + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "requires": { + "minimist": "^1.2.5" + } + }, "pump": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz", @@ -8322,9 +8416,9 @@ } }, "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "requires": { "isexe": "^2.0.0" } @@ -8348,9 +8442,9 @@ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" }, "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } } diff --git a/examples/package.json b/examples/package.json index ca8c15fb..81badeb5 100644 --- a/examples/package.json +++ b/examples/package.json @@ -14,7 +14,7 @@ "license": "MPL-2.0", "dependencies": { "git-documentdb": "file:..", - "git-documentdb-plugin-remote-nodegit": "^1.0.3" + "git-documentdb-plugin-remote-nodegit": "^1.0.4" }, "devDependencies": { "typescript": "^4.1.3" diff --git a/package-lock.json b/package-lock.json index 2fa649ea..b653cd65 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "git-documentdb", - "version": "0.4.1-beta.3", + "version": "0.4.1", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -969,6 +969,36 @@ "diff-match-patch": "^1.0.0" } }, + "@sosuisen/nodegit": { + "version": "0.28.0-alpha.11", + "resolved": "https://registry.npmjs.org/@sosuisen/nodegit/-/nodegit-0.28.0-alpha.11.tgz", + "integrity": "sha512-mpztf9ncWxU7/agKQ6E7GvlBIa6H7m3YXuMjlPWVegHusqkbgPi4J01d2inCPhLz0CoC0F/L3LKJuDCAKDXJJg==", + "dev": true, + "requires": { + "fs-extra": "^7.0.0", + "got": "^10.7.0", + "json5": "^2.1.0", + "lodash": "^4.17.14", + "nan": "^2.14.1", + "node-gyp": "^7.1.2", + "node-pre-gyp": "^0.13.0", + "ramda": "^0.25.0", + "tar-fs": "^1.16.3" + }, + "dependencies": { + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + } + } + }, "@szmarczak/http-timer": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", @@ -1804,9 +1834,9 @@ } }, "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", "dev": true }, "ci-info": { @@ -2371,6 +2401,12 @@ "ansi-colors": "^4.1.1" } }, + "env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true + }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -3420,12 +3456,12 @@ } }, "fs-minipass": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", - "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", "dev": true, "requires": { - "minipass": "^2.6.0" + "minipass": "^3.0.0" } }, "fs.realpath": { @@ -3528,13 +3564,13 @@ "dev": true }, "git-documentdb-plugin-remote-nodegit": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.3.tgz", - "integrity": "sha512-80cxPE+jIjDpECCXAmNtjZxMFVNc38yFkZmEd3hRp6EvSQhX6nky0kmEFWZ1aeFnTq0oATEJvEJg9yO8zYkyng==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.4.tgz", + "integrity": "sha512-+esXlN6PMmvwKZPU6dn/kSQnVe5QHU9xGzoNrLiqehz+VM1AXgNhsce/KipimG4wdzUS6tbS9QbgIgA4VjpbAw==", "dev": true, "requires": { + "@sosuisen/nodegit": "^0.28.0-alpha.11", "git-documentdb-remote-errors": "^1.0.3", - "nodegit": "^0.27.0", "tslog": "^3.2.0" } }, @@ -4921,32 +4957,29 @@ } }, "minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", "dev": true, "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" + "yallist": "^4.0.0" } }, "minizlib": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", - "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", "dev": true, "requires": { - "minipass": "^2.9.0" + "minipass": "^3.0.0", + "yallist": "^4.0.0" } }, "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true }, "mocha": { "version": "8.4.0", @@ -5133,9 +5166,9 @@ "dev": true }, "nan": { - "version": "2.14.2", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", - "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==", + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", + "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==", "dev": true }, "nanoid": { @@ -5186,31 +5219,30 @@ "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" }, "node-gyp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-4.0.0.tgz", - "integrity": "sha512-2XiryJ8sICNo6ej8d0idXDEMKfVfFK7kekGCtJAuelGsYHQxhj13KTf95swTCN2dZ/4lTfZ84Fu31jqJEEgjWA==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-7.1.2.tgz", + "integrity": "sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ==", "dev": true, "requires": { - "glob": "^7.0.3", - "graceful-fs": "^4.1.2", - "mkdirp": "^0.5.0", - "nopt": "2 || 3", - "npmlog": "0 || 1 || 2 || 3 || 4", - "osenv": "0", - "request": "^2.87.0", - "rimraf": "2", - "semver": "~5.3.0", - "tar": "^4.4.8", - "which": "1" + "env-paths": "^2.2.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.3", + "nopt": "^5.0.0", + "npmlog": "^4.1.2", + "request": "^2.88.2", + "rimraf": "^3.0.2", + "semver": "^7.3.2", + "tar": "^6.0.2", + "which": "^2.0.2" }, "dependencies": { - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, "requires": { - "glob": "^7.1.3" + "lru-cache": "^6.0.0" } } } @@ -5233,6 +5265,49 @@ "tar": "^4" }, "dependencies": { + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "dev": true, + "requires": { + "minipass": "^2.6.0" + } + }, + "minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "dev": true, + "requires": { + "minipass": "^2.9.0" + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, "nopt": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", @@ -5251,6 +5326,27 @@ "requires": { "glob": "^7.1.3" } + }, + "tar": { + "version": "4.4.15", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.15.tgz", + "integrity": "sha512-ItbufpujXkry7bHH9NpQyTXPbJ72iTlXgkBAYsAjDXk3Ds8t/3NfO5P4xZGy7u+sYuQUbimgzswX4uQIEeNVOA==", + "dev": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + } + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true } } }, @@ -5269,40 +5365,10 @@ "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==", "dev": true }, - "nodegit": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/nodegit/-/nodegit-0.27.0.tgz", - "integrity": "sha512-E9K4gPjWiA0b3Tx5lfWCzG7Cvodi2idl3V5UD2fZrOrHikIfrN7Fc2kWLtMUqqomyoToYJLeIC8IV7xb1CYRLA==", - "dev": true, - "requires": { - "fs-extra": "^7.0.0", - "got": "^10.7.0", - "json5": "^2.1.0", - "lodash": "^4.17.14", - "nan": "^2.14.0", - "node-gyp": "^4.0.0", - "node-pre-gyp": "^0.13.0", - "ramda": "^0.25.0", - "tar-fs": "^1.16.3" - }, - "dependencies": { - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, "nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", "dev": true, "requires": { "abbrev": "1" @@ -7181,18 +7247,17 @@ } }, "tar": { - "version": "4.4.15", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.15.tgz", - "integrity": "sha512-ItbufpujXkry7bHH9NpQyTXPbJ72iTlXgkBAYsAjDXk3Ds8t/3NfO5P4xZGy7u+sYuQUbimgzswX4uQIEeNVOA==", + "version": "6.1.6", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.6.tgz", + "integrity": "sha512-oaWyu5dQbHaYcyZCTfyPpC+VmI62/OM2RTUYavTk1MDr1cwW5Boi3baeYQKiZbY2uSQJGr+iMOzb/JFxLrft+g==", "dev": true, "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.8.6", - "minizlib": "^1.2.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.3" + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" } }, "tar-fs": { @@ -7207,6 +7272,21 @@ "tar-stream": "^1.1.2" }, "dependencies": { + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, "pump": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz", @@ -7646,9 +7726,9 @@ } }, "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { "isexe": "^2.0.0" @@ -7799,9 +7879,9 @@ "dev": true }, "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, "yaml": { diff --git a/package.json b/package.json index fc4af93d..1699484f 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ "eslint-config-standardize": "^0.7.1", "eslint-plugin-prettierx": "^0.14.0", "expect": "^27.0.2", - "git-documentdb-plugin-remote-nodegit": "^1.0.3", + "git-documentdb-plugin-remote-nodegit": "^1.0.4", "mocha": "^8.3.2", "nyc": "^15.1.0", "parse-git-config": "^3.0.0", From b4d97204c319089d9a2f856eae83077a11c4ace4 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sat, 7 Aug 2021 04:38:33 +0900 Subject: [PATCH 164/297] fix: add example of SSH authentication --- examples/src/plugin.ts | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/examples/src/plugin.ts b/examples/src/plugin.ts index c09d18b6..758e8f68 100644 --- a/examples/src/plugin.ts +++ b/examples/src/plugin.ts @@ -14,19 +14,36 @@ import { sleep } from './utils'; * (See https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token ) */ let github_repository = 'https://github.com/enter_your_account_name/git-documentdb-example-sync.git'; -let github_repository2 = 'https://github.com/enter_your_account_name/git-documentdb-example-sync2.git'; +let github_repository2 = 'git@github.com:enter_your_account_name/git-documentdb-example-sync2.git'; + let your_github_personal_access_token = 'Enter your personal access token with checked [repo]'; + +let your_public_key_path = '/Enter/your/private/key/path'; +let your_private_key_path = '/Enter/your/public/key/path'; /** * You can also set them from environment variables: * - GITDDB_GITHUB_USER_URL * URL of your GitHub account * e.g.) https://github.com/foo/ + * * - GITDDB_PERSONAL_ACCESS_TOKEN * A personal access token of your GitHub account + * + * - GITDDB_GITHUB_USER_SSH + * SSH URL of your GitHub account + * e.g.) git@github.com:foo/ + * + * - SSH_PUBLIC_KEY_PATH + * ssk public key of your GitHub account + * + * - SSH_PRIVATE_KEY_PATH + * ssk private key of your GitHub account */ if (process.env.GITDDB_GITHUB_USER_URL) github_repository = process.env.GITDDB_GITHUB_USER_URL + 'git-documentdb-example-sync.git'; -if (process.env.GITDDB_GITHUB_USER_URL) github_repository2 = process.env.GITDDB_GITHUB_USER_URL + 'git-documentdb-example-sync2.git'; +if (process.env.GITDDB_GITHUB_USER_SSH) github_repository2 = process.env.GITDDB_GITHUB_USER_SSH + 'git-documentdb-example-sync2.git'; if (process.env.GITDDB_PERSONAL_ACCESS_TOKEN) your_github_personal_access_token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN; +if (process.env.SSH_PUBLIC_KEY_PATH) your_public_key_path = process.env.SSH_PUBLIC_KEY_PATH; +if (process.env.SSH_PRIVATE_KEY_PATH) your_private_key_path = process.env.SSH_PRIVATE_KEY_PATH; /** @@ -63,11 +80,14 @@ const remote_plugin_example = async () => { remoteUrl: github_repository2, interval: 5000, // Sync every 5,000 msec connection: { - type: 'github', - personalAccessToken: your_github_personal_access_token, + type: 'ssh', + publicKeyPath: your_public_key_path, + privateKeyPath: your_private_key_path, + passPhrase: '', engine: 'nodegit' }, }; + console.log(remoteOptionsNodeGit); // Add extra synchronizer to DB const syncNodeGit= await gitDDB.sync(remoteOptionsNodeGit); From 6621d5a66622d6f9eebc8974c645ecf9a91980a1 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sat, 7 Aug 2021 04:40:57 +0900 Subject: [PATCH 165/297] fix: update roadmap --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c2e8bdf8..cd82bddb 100644 --- a/README.md +++ b/README.md @@ -229,8 +229,8 @@ https://github.com/sosuisen/inventory-manager - API renewal to manage any data types :feet: - Remove native module (NodeGit) from default install :feet: - Add plugin system for remote connection (isomorphic-git or NodeGit) :feet: - - Connect with SSH key pair :dog2:(Next) - - Connect to GitHub with OAuth + - Connect with SSH key pair :feet: + - Connect to GitHub with OAuth :dog2:(Next) - Work on browser - Until v1.0 From 648587d86dcf5b01cc504e5902916f249aeb848a Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sat, 7 Aug 2021 23:04:46 +0900 Subject: [PATCH 166/297] fix: retry createRepository --- src/const.ts | 6 +-- src/git_documentdb.ts | 47 +++++++++++++++++------- test/git_documentdb_open.test.ts | 63 ++++++++++++++++++++++++++++++++ 3 files changed, 99 insertions(+), 17 deletions(-) diff --git a/src/const.ts b/src/const.ts index ac0b2e17..dcbd6266 100644 --- a/src/const.ts +++ b/src/const.ts @@ -42,15 +42,15 @@ export const DUPLICATED_FILE_POSTFIX = '-from-'; /** * @public */ -export const FILE_REMOVE_TIMEOUT = 7000; +export const FILE_CREATE_TIMEOUT = 2000; /** * @public */ -export const FIRST_COMMIT_MESSAGE = 'first commit'; +export const FILE_REMOVE_TIMEOUT = 7000; /** * @public */ -export const GIT_DOCUMENTDB_APP_INFO_ID = '.gitddb/app'; +export const FIRST_COMMIT_MESSAGE = 'first commit'; /** * @public */ diff --git a/src/git_documentdb.ts b/src/git_documentdb.ts index 9cace6f4..7370fe63 100644 --- a/src/git_documentdb.ts +++ b/src/git_documentdb.ts @@ -54,15 +54,14 @@ import { DATABASE_VERSION, DEFAULT_LOCAL_DIR, DEFAULT_LOG_LEVEL, + FILE_CREATE_TIMEOUT, FILE_REMOVE_TIMEOUT, FIRST_COMMIT_MESSAGE, - GIT_DOCUMENTDB_APP_INFO_ID, GIT_DOCUMENTDB_INFO_ID, JSON_EXT, - PUT_APP_INFO_MESSAGE, SET_DATABASE_ID_MESSAGE, } from './const'; -import { normalizeCommit, toSortedJSONString } from './utils'; +import { normalizeCommit, sleep, toSortedJSONString } from './utils'; import { SyncEventInterface, SyncInterface } from './types_sync'; import { CRUDInterface } from './types_crud_interface'; import { CollectionInterface, ICollection } from './types_collection'; @@ -380,18 +379,38 @@ export class GitDocumentDB * @internal */ private async _createRepository () { - /** - * Create directory - */ - await fs.ensureDir(this._workingDir).catch((err: Error) => { - throw new Err.CannotCreateDirectoryError(err.message); - }); - - await git - .init({ fs, dir: this._workingDir, defaultBranch: this.defaultBranch }) - .catch(err => { - return Promise.reject(err); + // Retry three times. + // Creating system files sometimes fail just after installing from Squirrel installer of Electron. + const retry = 3; + for (let i = 0; i < retry + 1; i++) { + // eslint-disable-next-line no-await-in-loop + const resEnsure = await fs.ensureDir(this._workingDir).catch((err: Error) => { + if (i >= retry) throw new Err.CannotCreateDirectoryError(err.message); + return 'cannot_create'; }); + if (resEnsure === 'cannot_create') { + // eslint-disable-next-line no-await-in-loop + await sleep(FILE_CREATE_TIMEOUT); + this.logger.debug('retrying ensureDir in createRepository'); + continue; + } + + // eslint-disable-next-line no-await-in-loop + const resInit = await git + .init({ fs, dir: this._workingDir, defaultBranch: this.defaultBranch }) + .catch(err => { + if (i >= retry) throw err; + return 'cannot_init'; + }); + if (resInit === 'cannot_init') { + // eslint-disable-next-line no-await-in-loop + await sleep(FILE_CREATE_TIMEOUT); + this.logger.debug('retrying git.init in createRepository'); + continue; + } + + break; + } // First commit const info = { diff --git a/test/git_documentdb_open.test.ts b/test/git_documentdb_open.test.ts index d4358cb0..b341f32a 100644 --- a/test/git_documentdb_open.test.ts +++ b/test/git_documentdb_open.test.ts @@ -105,6 +105,40 @@ describe('', () => { }); // You don't have permission await expect(gitDDB.open()).rejects.toThrowError(Err.CannotCreateDirectoryError); + expect(stubEnsureDir.callCount).toBe(4); // try 1 + retry 3 + }); + + it('succeeds after retry ensureDir in createRepository.', async () => { + const dbName = monoId(); + + const stubEnsureDir = sandbox.stub(fs_module, 'ensureDir'); + stubEnsureDir.onCall(0).rejects(); + stubEnsureDir.onCall(1).rejects(); + stubEnsureDir.onCall(2).rejects(); + stubEnsureDir.onCall(3).callsFake(function (dir: string) { + return stubEnsureDir.wrappedMethod(dir); + }); + // for push_worker + stubEnsureDir.onCall(4).callsFake(function (dir: string) { + return stubEnsureDir.wrappedMethod(dir); + }); + + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + }); + gitDDB.logLevel = 'trace'; + // You don't have permission + await expect(gitDDB.open()).resolves.toMatchObject({ + // dbId: dbOpenResult.dbId, + creator: DATABASE_CREATOR, + version: DATABASE_VERSION, + isNew: true, + isCreatedByGitDDB: true, + isValidVersion: true, + }); + + expect(stubEnsureDir.callCount).toBe(5); // try 1 + retry 3 + push_worker 1 }); it('creates a new repository.', async () => { @@ -156,6 +190,35 @@ describe('', () => { await gitDDB.destroy().catch(e => console.error(e)); fs.removeSync(path.resolve(defaultLocalDir)); }); + + it('succeeds after retry git.init in createRepository.', async () => { + const dbName = monoId(); + + const stubInit = sandbox.stub(git, 'init'); + stubInit.onCall(0).rejects(); + stubInit.onCall(1).rejects(); + stubInit.onCall(2).rejects(); + stubInit.onCall(3).callsFake(function (options: any) { + return stubInit.wrappedMethod(options); + }); + + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + }); + gitDDB.logLevel = 'trace'; + // You don't have permission + await expect(gitDDB.open()).resolves.toMatchObject({ + // dbId: dbOpenResult.dbId, + creator: DATABASE_CREATOR, + version: DATABASE_VERSION, + isNew: true, + isCreatedByGitDDB: true, + isValidVersion: true, + }); + + expect(stubInit.callCount).toBe(4); // try 1 + retry 3 + }); }); describe('open', () => { From 850a0ce504593795fa6cfe2bd22a165bdb1043e5 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sat, 7 Aug 2021 23:05:09 +0900 Subject: [PATCH 167/297] build: bump to v0.4.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1699484f..41601b19 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "git-documentdb", - "version": "0.4.1", + "version": "0.4.2", "description": "Offline-first database that syncs with Git", "main": "dist/main.js", "types": "dist/main.d.ts", From 72e28739eece69a099bf680167a96f7bfe2a2462 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sun, 8 Aug 2021 00:20:34 +0900 Subject: [PATCH 168/297] fix: retry pushWorker in createRepository --- src/git_documentdb.ts | 42 ++++++++++++++++++++------------ test/git_documentdb_open.test.ts | 31 +++++++++++++++++++++++ 2 files changed, 58 insertions(+), 15 deletions(-) diff --git a/src/git_documentdb.ts b/src/git_documentdb.ts index 7370fe63..1bc3e140 100644 --- a/src/git_documentdb.ts +++ b/src/git_documentdb.ts @@ -379,6 +379,13 @@ export class GitDocumentDB * @internal */ private async _createRepository () { + // First commit + const info = { + dbId: generateDatabaseId(), + creator: DATABASE_CREATOR, + version: DATABASE_VERSION, + }; + // Retry three times. // Creating system files sometimes fail just after installing from Squirrel installer of Electron. const retry = 3; @@ -409,24 +416,29 @@ export class GitDocumentDB continue; } + // Do not use this.put() because it increments TaskQueue.statistics.put. + // eslint-disable-next-line no-await-in-loop + const resPut = await putWorker( + this, + '', + GIT_DOCUMENTDB_INFO_ID + JSON_EXT, + toSortedJSONString(info), + FIRST_COMMIT_MESSAGE + ).catch(err => { + if (i >= retry) throw err; + return 'cannot_put'; + }); + if (resPut === 'cannot_put') { + // eslint-disable-next-line no-await-in-loop + await sleep(FILE_CREATE_TIMEOUT); + fs.removeSync(this._workingDir); + this.logger.debug('retrying putWorker in createRepository'); + continue; + } + break; } - // First commit - const info = { - dbId: generateDatabaseId(), - creator: DATABASE_CREATOR, - version: DATABASE_VERSION, - }; - // Do not use this.put() because it increments TaskQueue.statistics.put. - await putWorker( - this, - '', - GIT_DOCUMENTDB_INFO_ID + JSON_EXT, - toSortedJSONString(info), - FIRST_COMMIT_MESSAGE - ); - this._dbOpenResult.isNew = true; this._dbOpenResult = { ...this._dbOpenResult, ...info }; diff --git a/test/git_documentdb_open.test.ts b/test/git_documentdb_open.test.ts index b341f32a..68602cb2 100644 --- a/test/git_documentdb_open.test.ts +++ b/test/git_documentdb_open.test.ts @@ -27,6 +27,8 @@ import { sleep } from '../src/utils'; // eslint-disable-next-line @typescript-eslint/no-var-requires const fs_module = require('fs-extra'); +// eslint-disable-next-line @typescript-eslint/no-var-requires +const put_worker_module = require('../src/crud/put'); const ulid = monotonicFactory(); const monoId = () => { @@ -219,6 +221,35 @@ describe('', () => { expect(stubInit.callCount).toBe(4); // try 1 + retry 3 }); + + it('succeeds after retry putWorker in createRepository.', async () => { + const dbName = monoId(); + + const stubPut = sandbox.stub(put_worker_module, 'putWorker'); + stubPut.onCall(0).rejects(); + stubPut.onCall(1).rejects(); + stubPut.onCall(2).rejects(); + stubPut.onCall(3).callsFake(function (...options: any) { + return stubPut.wrappedMethod(...options); + }); + + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + }); + gitDDB.logLevel = 'trace'; + // You don't have permission + await expect(gitDDB.open()).resolves.toMatchObject({ + // dbId: dbOpenResult.dbId, + creator: DATABASE_CREATOR, + version: DATABASE_VERSION, + isNew: true, + isCreatedByGitDDB: true, + isValidVersion: true, + }); + + expect(stubPut.callCount).toBe(4); // try 1 + retry 3 + }); }); describe('open', () => { From 0bc8146951f4d4696f6d794b5d2e108d7c727007 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sun, 8 Aug 2021 00:20:56 +0900 Subject: [PATCH 169/297] build: bump to v0.4.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 41601b19..feb882d0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "git-documentdb", - "version": "0.4.2", + "version": "0.4.3", "description": "Offline-first database that syncs with Git", "main": "dist/main.js", "types": "dist/main.d.ts", From df2f2a971a873aa9365072162d16eb9137320005 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sun, 8 Aug 2021 04:32:52 +0900 Subject: [PATCH 170/297] docs: align docs with v0.4.3 --- docs-api/git-documentdb.file_create_timeout.md | 16 ++++++++++++++++ .../git-documentdb.git_documentdb_app_info_id.md | 16 ---------------- docs-api/git-documentdb.md | 2 +- etc/git-documentdb.api.md | 6 +++--- 4 files changed, 20 insertions(+), 20 deletions(-) create mode 100644 docs-api/git-documentdb.file_create_timeout.md delete mode 100644 docs-api/git-documentdb.git_documentdb_app_info_id.md diff --git a/docs-api/git-documentdb.file_create_timeout.md b/docs-api/git-documentdb.file_create_timeout.md new file mode 100644 index 00000000..1520445c --- /dev/null +++ b/docs-api/git-documentdb.file_create_timeout.md @@ -0,0 +1,16 @@ +--- +sidebar_label: FILE_CREATE_TIMEOUT variable +title: FILE_CREATE_TIMEOUT variable +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [FILE\_CREATE\_TIMEOUT](./git-documentdb.file_create_timeout.md) + +## FILE\_CREATE\_TIMEOUT variable + + +Signature: + +```typescript +FILE_CREATE_TIMEOUT = 2000 +``` diff --git a/docs-api/git-documentdb.git_documentdb_app_info_id.md b/docs-api/git-documentdb.git_documentdb_app_info_id.md deleted file mode 100644 index 80baf4b1..00000000 --- a/docs-api/git-documentdb.git_documentdb_app_info_id.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -sidebar_label: GIT_DOCUMENTDB_APP_INFO_ID variable -title: GIT_DOCUMENTDB_APP_INFO_ID variable -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [GIT\_DOCUMENTDB\_APP\_INFO\_ID](./git-documentdb.git_documentdb_app_info_id.md) - -## GIT\_DOCUMENTDB\_APP\_INFO\_ID variable - - -Signature: - -```typescript -GIT_DOCUMENTDB_APP_INFO_ID = ".gitddb/app" -``` diff --git a/docs-api/git-documentdb.md b/docs-api/git-documentdb.md index fd8d3c0c..6986feac 100644 --- a/docs-api/git-documentdb.md +++ b/docs-api/git-documentdb.md @@ -56,9 +56,9 @@ Offline-first Database that Syncs with Git | [DEFAULT\_LOG\_LEVEL](./git-documentdb.default_log_level.md) | | | [DEFAULT\_SYNC\_INTERVAL](./git-documentdb.default_sync_interval.md) | | | [DUPLICATED\_FILE\_POSTFIX](./git-documentdb.duplicated_file_postfix.md) | | +| [FILE\_CREATE\_TIMEOUT](./git-documentdb.file_create_timeout.md) | | | [FILE\_REMOVE\_TIMEOUT](./git-documentdb.file_remove_timeout.md) | | | [FIRST\_COMMIT\_MESSAGE](./git-documentdb.first_commit_message.md) | | -| [GIT\_DOCUMENTDB\_APP\_INFO\_ID](./git-documentdb.git_documentdb_app_info_id.md) | | | [GIT\_DOCUMENTDB\_INFO\_ID](./git-documentdb.git_documentdb_info_id.md) | | | [GIT\_DOCUMENTDB\_METADATA\_DIR](./git-documentdb.git_documentdb_metadata_dir.md) | | | [JSON\_EXT](./git-documentdb.json_ext.md) | | diff --git a/etc/git-documentdb.api.md b/etc/git-documentdb.api.md index c0568dae..0e9dc429 100644 --- a/etc/git-documentdb.api.md +++ b/etc/git-documentdb.api.md @@ -530,6 +530,9 @@ export type FatTextDoc = TextDocMetadata & { doc: string; }; +// @public (undocumented) +export const FILE_CREATE_TIMEOUT = 2000; + // @public (undocumented) export const FILE_REMOVE_TIMEOUT = 7000; @@ -563,9 +566,6 @@ export type GetOptions = { forceDocType?: DocType; }; -// @public (undocumented) -export const GIT_DOCUMENTDB_APP_INFO_ID = ".gitddb/app"; - // @public (undocumented) export const GIT_DOCUMENTDB_INFO_ID = ".gitddb/info"; From 63b2fbe825187dd5cba1d51d9b266da174590b04 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Mon, 16 Aug 2021 22:59:49 +0900 Subject: [PATCH 171/297] test: add bad cases for json_patch_ot --- test/remote_offline/json_patch_ot.test.ts | 67 +++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/test/remote_offline/json_patch_ot.test.ts b/test/remote_offline/json_patch_ot.test.ts index acc85ee3..4d28fd80 100644 --- a/test/remote_offline/json_patch_ot.test.ts +++ b/test/remote_offline/json_patch_ot.test.ts @@ -1038,6 +1038,73 @@ sighed Meg, looking down at her old dress.`, expect(jPatch.patch(ours, diffOurs!, theirs, diffTheirs)).toStrictEqual(merged); }); + it('merges non ASCII text 2', () => { + const base = { + _id: 'wagahai', + text: '吾輩は猫である。', + }; + + const ours = { + _id: 'wagahai', + text: `吾輩は猫だよ。`, + }; + + const theirs = { + _id: 'wagahai', + text: `吾輩は犬である。`, + }; + + const merged = { + _id: 'wagahai', + text: `吾輩は犬だよ。`, + }; + + const diffOurs = textOTDiff.diff(base, ours); + // console.log(diffOurs); + const diffTheirs = textOTDiff.diff(base, theirs); + // console.log(diffTheirs); + const patchOurs = jPatch.fromDiff(diffOurs!); + // console.log(patchOurs); + const patchTheirs = jPatch.fromDiff(diffTheirs!); + // console.log(patchTheirs); + + expect(jPatch.patch(ours, diffOurs!, theirs, diffTheirs)).toStrictEqual(merged); + }); + + it('merges non ASCII text 3', () => { + const base = { + _id: 'wagahai', + text: '吾輩は猫である。', + }; + + const ours = { + _id: 'wagahai', + text: `吾輩は猫だよ。`, + }; + + const theirs = { + _id: 'wagahai', + text: `吾輩は犬だよ。`, + }; + + // ! NOTE: Not good result + const merged = { + _id: 'wagahai', + text: `吾輩はだよ犬だよ。`, + }; + + const diffOurs = textOTDiff.diff(base, ours); + // console.log(diffOurs); + const diffTheirs = textOTDiff.diff(base, theirs); + // console.log(diffTheirs); + const patchOurs = jPatch.fromDiff(diffOurs!); + // console.log(patchOurs); + const patchTheirs = jPatch.fromDiff(diffTheirs!); + // console.log(patchTheirs); + + expect(jPatch.patch(ours, diffOurs!, theirs, diffTheirs)).toStrictEqual(merged); + }); + it.skip('merges conflicted primitives: add', () => {}); }); }); From 78e6fe656c33c20cad0eb8b7addd6389e883e8bc Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 24 Aug 2021 02:31:36 +0900 Subject: [PATCH 172/297] fix: cound not patch nested object --- .vscode/launch.json | 2 +- src/remote/json_patch_ot.ts | 106 +++++++------ test/remote_offline/json_patch_ot.test.ts | 175 +++++++++++++++++++++- 3 files changed, 235 insertions(+), 48 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 9c035100..3ed042c0 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,7 +4,7 @@ "type": "pickString", "id": "choice", "description": "select a file", - "options": ["test/remote_isomorphic_git/sync.test.js"], + "options": ["test/remote_offline/json_patch_ot.test.js"], }], "configurations": [ { diff --git a/src/remote/json_patch_ot.ts b/src/remote/json_patch_ot.ts index f2c6f0a3..763ba82a 100644 --- a/src/remote/json_patch_ot.ts +++ b/src/remote/json_patch_ot.ts @@ -96,7 +96,7 @@ export class JsonPatchOT implements IJsonPatch { } fromDiff (diff: { [key: string]: any }): JSONOp { - const operations: JSONOp = []; + const operations: JSONOp[] = []; const procTree = (ancestors: string[], tree: JsonDoc) => { const keys = Object.keys(tree); let sortedKeys: string[]; @@ -115,6 +115,7 @@ export class JsonPatchOT implements IJsonPatch { else { sortedKeys = keys.sort(); } + // eslint-disable-next-line complexity sortedKeys.forEach(key => { if (Array.isArray(tree[key])) { const arr = tree[key] as any[]; @@ -141,13 +142,23 @@ export class JsonPatchOT implements IJsonPatch { } } } + else if (typeof tree[key] === 'object') { + procTree(ancestors.concat(key), tree[key]); + } }); }; procTree([], diff); if (operations.length === 1) { return (operations[0] as unknown) as JSONOp; } - return operations; + /** + * A path can be a flat array format in the specification. e.g.) ['x', 'y', {i:2}] + * https://github.com/ottypes/json1/blob/master/spec.md + * However type.transform function does not accept the flat array format. + * Use a nested array format instead. e.g.) ['x', ['y', {i:2}]]. + * type.compose converts the flat array format to the nested array format. + */ + return operations.reduce(type.compose, null); } apply (doc: JsonDoc, op: JSONOp): JsonDoc { @@ -190,8 +201,8 @@ export class JsonPatchOT implements IJsonPatch { ): [JSONOp, JSONOp, JSONOp | undefined] { let transformedOp; try { - // console.log('trying ours: ' + JSON.stringify(_opOurs)); - // console.log('trying theirs: ' + JSON.stringify(_opTheirs)); + // console.log('trying ours: ' + JSON.stringify(opOurs)); + // console.log('trying theirs: ' + JSON.stringify(opTheirs)); if (strategy.startsWith('ours')) { transformedOp = type.transform(opTheirs, opOurs, 'right'); } @@ -215,59 +226,66 @@ export class JsonPatchOT implements IJsonPatch { conflictedOperation = conflict.op2; targetOperations = JSON.parse(JSON.stringify(opOurs)); } - // Location is array. - const conflictedLocation = conflictedOperation.slice(0, -1); + // Get JSON array of conflicted path + const conflictedPath = JSON.stringify(conflictedOperation.slice(0, -1)); + // Get p, r, d, i, e const conflictedCommands = Object.keys( conflictedOperation[conflictedOperation.length - 1] ); - if (targetOperations.length > 1 && !Array.isArray(targetOperations[0])) { - // Operation (e.g. {p: 0}) - const op: { [command: string]: string } = - targetOperations[targetOperations.length - 1]; - conflictedCommands.forEach(command => delete op[command]); - targetOperations[targetOperations.length - 1] = op; - } - else if (targetOperations.length > 1) { - // Search conflictedLocation in targetOperations - let loc = -1; - for (let i = 0; i < targetOperations.length; i++) { - if (targetOperations[i].length - 1 === conflictedLocation.length) { - for (let j = 0; j < conflictedLocation.length; j++) { - if (targetOperations[i][j] !== conflictedLocation[j]) { - break; - } - if (j === conflictedLocation.length - 1) { - loc = i; - } - } - if (loc >= 0) { - break; - } + const resolvedOperations: any[] = []; + + const stack: { pathFromRoot: string[]; opArray: any[] }[] = [ + { + pathFromRoot: [], + opArray: targetOperations, + }, + ]; + while (stack.length > 0) { + const { pathFromRoot, opArray } = stack.pop()!; + + if (opArray.length === 0) continue; + + const opPath: string[] = []; + for (const opElm of opArray) { + if (typeof opElm === 'string') { + pathFromRoot.push(opElm); } - } - if (loc >= 0) { - const op: { [command: string]: string } = - targetOperations[loc][targetOperations[loc].length - 1]; - // delete command - conflictedCommands.forEach(command => delete op[command]); - if (Object.keys(op).length > 0) { - targetOperations[loc][targetOperations[loc].length - 1] = op; + else if (Array.isArray(opElm)) { + stack.push({ + pathFromRoot: [...pathFromRoot], + opArray: JSON.parse(JSON.stringify(opElm)), + }); } else { - targetOperations.splice(loc, 1); - } - if (targetOperations.length === 1) { - targetOperations = targetOperations[0]; + // Operation (e.g. {p: 0}) + if (JSON.stringify(pathFromRoot) === conflictedPath) { + conflictedCommands.forEach(command => delete opElm[command]); + } + if (Object.keys(opElm).length > 0) { + const resolvedOp = pathFromRoot.concat(opElm); + resolvedOperations.push(resolvedOp); + } } - // console.log('# resolved: ' + JSON.stringify(targetOperations)); } } + // console.log('# resolved: ' + JSON.stringify(resolvedOperations)); + const resolvedOperationsComposed = resolvedOperations.reduce(type.compose, null); + // console.log('# resolved composed: ' + JSON.stringify(resolvedOperationsComposed)); + if (strategy.startsWith('ours')) { - return [JSON.parse(JSON.stringify(opOurs)), targetOperations, undefined]; + return [ + JSON.parse(JSON.stringify(opOurs)), + resolvedOperationsComposed, + undefined, + ]; } - return [targetOperations, JSON.parse(JSON.stringify(opTheirs)), undefined]; + return [ + resolvedOperationsComposed, + JSON.parse(JSON.stringify(opTheirs)), + undefined, + ]; } throw err; } diff --git a/test/remote_offline/json_patch_ot.test.ts b/test/remote_offline/json_patch_ot.test.ts index 4d28fd80..19980e64 100644 --- a/test/remote_offline/json_patch_ot.test.ts +++ b/test/remote_offline/json_patch_ot.test.ts @@ -435,7 +435,7 @@ describe(' OT', () => { expect(jPatch.apply(oldDoc, patch)).toStrictEqual(newDoc); }); - it('returns patch from diff (add to tail of text', () => { + it('returns patch from diff (add to tail of text)', () => { const oldDoc = { _id: 'nara', text: 'abc', @@ -524,7 +524,7 @@ describe(' OT', () => { expect(jPatch.apply(oldDoc, patch)).toStrictEqual(newDoc); }); - it('returns patch from diff (delete from tail of text', () => { + it('returns patch from diff (delete from tail of text)', () => { const oldDoc = { _id: 'nara', text: 'abcdef', @@ -1105,6 +1105,175 @@ sighed Meg, looking down at her old dress.`, expect(jPatch.patch(ours, diffOurs!, theirs, diffTheirs)).toStrictEqual(merged); }); - it.skip('merges conflicted primitives: add', () => {}); + it('merges non ASCII text', () => { + const base = { + _id: 'wagahai', + author: 'なし', + text: '吾輩は猫である。', + }; + + const ours = { + _id: 'wagahai', + author: '夏目漱石', + text: `吾輩は猫である。名前はまだ無い。`, + }; + + const theirs = { + _id: 'wagahai', + author: '太宰治', + text: `吾輩は犬である。`, + }; + + const merged = { + _id: 'wagahai', + author: '夏目漱石', + text: `吾輩は犬である。名前はまだ無い。`, + }; + + const diffOurs = textOTDiff.diff(base, ours); + // console.log(diffOurs); + const diffTheirs = textOTDiff.diff(base, theirs); + // console.log(diffTheirs); + const patchOurs = jPatch.fromDiff(diffOurs!); + // console.log(patchOurs); + const patchTheirs = jPatch.fromDiff(diffTheirs!); + // console.log(patchTheirs); + + expect(jPatch.patch(ours, diffOurs!, theirs, diffTheirs)).toStrictEqual(merged); + }); + }); + + describe('merge nested object', () => { + it('merges simple structure', () => { + const base = { + geometry: { + height: 300, + }, + }; + + const ours = { + geometry: { + height: 374, + }, + }; + + const theirs = { + geometry: { + height: 310, + }, + }; + + const merged = { + geometry: { + height: 374, + }, + }; + + const diffOurs = textOTDiff.diff(base, ours); + // console.log(diffOurs); + const diffTheirs = textOTDiff.diff(base, theirs); + // console.log(diffTheirs); + const patchOurs = jPatch.fromDiff(diffOurs!); + // console.log(patchOurs); + const patchTheirs = jPatch.fromDiff(diffTheirs!); + // console.log(patchTheirs); + + expect(jPatch.patch(ours, diffOurs!, theirs, diffTheirs)).toStrictEqual(merged); + }); + + it('merges complex structure', () => { + const base = { + condition: { + locked: false, + }, + geometry: { + height: 300, + width: 434, + x: 70, + y: 70, + z: 2, + }, + style: { + backgroundColor: '#ffffff', + opacity: 1, + uiColor: '#f5f5f5', + zoom: 0.85, + }, + _id: 'note/n01FCXJV361VCX5SEEY45V8X604/c01FCXJV1DPAJZ7X6M8YYF17TZF', + }; + + const ours = { + condition: { + locked: false, + }, + geometry: { + height: 374, + width: 324, + x: 64, + y: 80, + z: 2, + }, + style: { + backgroundColor: '#fff8d0', + opacity: 1, + uiColor: '#f5eec8', + zoom: 0.85, + }, + _id: 'note/n01FCXJV361VCX5SEEY45V8X604/c01FCXJV1DPAJZ7X6M8YYF17TZF', + }; + + const theirs = { + condition: { + locked: false, + }, + geometry: { + height: 300, + width: 434, + x: 250, + y: 54, + z: 160, + }, + style: { + backgroundColor: '#ffffff', + opacity: 1, + uiColor: '#f5f5f5', + zoom: 0.85, + }, + _id: 'note/n01FCXJV361VCX5SEEY45V8X604/c01FCXJV1DPAJZ7X6M8YYF17TZF', + }; + + const merged = { + condition: { + locked: false, + }, + geometry: { + height: 374, + width: 324, + x: 64, + y: 80, + z: 160, + }, + style: { + backgroundColor: '#fff8d0', + opacity: 1, + uiColor: '#f5eec8', + zoom: 0.85, + }, + _id: 'note/n01FCXJV361VCX5SEEY45V8X604/c01FCXJV1DPAJZ7X6M8YYF17TZF', + }; + + const diffOurs = textOTDiff.diff(base, ours); + // console.log(diffOurs); + const diffTheirs = textOTDiff.diff(base, theirs); + // console.log(diffTheirs); + const patchOurs = jPatch.fromDiff(diffOurs!); + // console.log(patchOurs); + const patchTheirs = jPatch.fromDiff(diffTheirs!); + // console.log(patchTheirs); + + expect(jPatch.patch(ours, diffOurs!, theirs, diffTheirs)).toStrictEqual(merged); + }); }); + + it.skip('merges conflicted primitives: add', () => {}); }); From ee0f0d58dc093e8f0469cf54ebaf06d8fde41603 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 24 Aug 2021 02:31:55 +0900 Subject: [PATCH 173/297] build: bump to v0.4.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index feb882d0..83e0cd2b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "git-documentdb", - "version": "0.4.3", + "version": "0.4.4", "description": "Offline-first database that syncs with Git", "main": "dist/main.js", "types": "dist/main.d.ts", From 3e814cfaab8435d059405d95e26edd2bd2053ca2 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sun, 29 Aug 2021 17:48:32 +0900 Subject: [PATCH 174/297] snapshot: try to debounce in taskQueue --- src/task_queue.ts | 55 +++++++++++++++++++++++++++++++++++++---------- src/types.ts | 1 + 2 files changed, 45 insertions(+), 11 deletions(-) diff --git a/src/task_queue.ts b/src/task_queue.ts index 7533a878..51107389 100644 --- a/src/task_queue.ts +++ b/src/task_queue.ts @@ -25,8 +25,9 @@ export class TaskQueue { private _logger: Logger; - // @ts-ignore - private _taskQueue: Task[] = []; + private _collectionQueue: { [collectionPath: string]: Task[] } = {}; + private _syncQueue: Task[] = []; + private _pushQueue: Task[] = []; private _isTaskQueueWorking = false; /** @@ -107,19 +108,39 @@ export class TaskQueue { // eslint-disable-next-line complexity .acquire('taskQueue', () => { // Skip consecutive sync/push events + if (this._currentTask?.label === 'sync') { + if ((this._syncQueue.length === 0 && + this._currentTask?.syncRemoteName === task.syncRemoteName && + this._currentTask?.label === 'sync' && task.label === 'sync') || + (this._syncQueue.length > 0 && + this._syncQueue[this._syncQueue.length - 1].syncRemoteName === + task.syncRemoteName && + ((this._taskQueue[this._taskQueue.length - 1].label === 'sync' && + task.label === 'sync') || + (this._taskQueue[this._taskQueue.length - 1].label === 'push' && + task.label === 'push'))) + + + } + + + } if ( (this._taskQueue.length === 0 && this._currentTask?.syncRemoteName === task.syncRemoteName && ((this._currentTask?.label === 'sync' && task.label === 'sync') || - (this._currentTask?.label === 'push' && task.label === 'push'))) || - (this._taskQueue.length > 0 && - this._taskQueue[this._taskQueue.length - 1].syncRemoteName === - task.syncRemoteName && - ((this._taskQueue[this._taskQueue.length - 1].label === 'sync' && - task.label === 'sync') || - (this._taskQueue[this._taskQueue.length - 1].label === 'push' && - task.label === 'push'))) - ) { + (this._currentTask?.label === 'push' && task.label === 'push'))) + + + || + (this._taskQueue.length > 0 && + this._taskQueue[this._taskQueue.length - 1].syncRemoteName === + task.syncRemoteName && + ((this._taskQueue[this._taskQueue.length - 1].label === 'sync' && + task.label === 'sync') || + (this._taskQueue[this._taskQueue.length - 1].label === 'push' && + task.label === 'push'))) + ) { task.cancel(); this._statistics.cancel++; throw new Err.ConsecutiveSyncSkippedError(task.label, task.taskId); @@ -270,6 +291,18 @@ export class TaskQueue { }; this._currentTask.func(beforeResolve, beforeReject, taskMetadata).finally(() => { + /* + this._lock + // eslint-disable-next-line complexity + .acquire('taskQueue', () => { + if (this._taskQueue.length > 0) { + const nextTask: Task; + for (const task of this._taskQueue) + if (this._currentTask?.collectionPath === task.collectionPath) { + + } + } + */ this._execTaskQueue(); }); } diff --git a/src/types.ts b/src/types.ts index 511f8b41..43a1ecbc 100644 --- a/src/types.ts +++ b/src/types.ts @@ -790,6 +790,7 @@ export type TaskMetadata = { shortId?: string; shortName?: string; collectionPath?: string; + debounceTime?: string; enqueueTime?: string; syncRemoteName?: string; }; From d575bed51a69558197a2e81ccb99ebc5d3a992c9 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Thu, 2 Sep 2021 19:30:35 +0900 Subject: [PATCH 175/297] snapshot: adding debounce to TaskQueue --- src/git_documentdb.ts | 3 +- src/task_queue.ts | 223 ++++++++++++++++++++++++---------------- src/types.ts | 1 + test/task_queue.test.ts | 61 ++++++++--- 4 files changed, 184 insertions(+), 104 deletions(-) diff --git a/src/git_documentdb.ts b/src/git_documentdb.ts index 1bc3e140..96aacab6 100644 --- a/src/git_documentdb.ts +++ b/src/git_documentdb.ts @@ -340,7 +340,8 @@ export class GitDocumentDB ); } - this._taskQueue = new TaskQueue(this.logger); + options.debounceTime ??= -1; + this._taskQueue = new TaskQueue(this.logger, options.debounceTime); // Set logLevel after initializing taskQueue. this.logLevel = options.logLevel ?? DEFAULT_LOG_LEVEL; diff --git a/src/task_queue.ts b/src/task_queue.ts index 51107389..9413816a 100644 --- a/src/task_queue.ts +++ b/src/task_queue.ts @@ -6,7 +6,7 @@ * found in the LICENSE file in the root directory of this source tree. */ -import { monotonicFactory } from 'ulid'; +import { decodeTime, monotonicFactory } from 'ulid'; import { Logger } from 'tslog'; import AsyncLock from 'async-lock'; import { Task, TaskMetadata, TaskStatistics } from './types'; @@ -25,11 +25,12 @@ export class TaskQueue { private _logger: Logger; - private _collectionQueue: { [collectionPath: string]: Task[] } = {}; - private _syncQueue: Task[] = []; - private _pushQueue: Task[] = []; + private _taskQueue: Task[] = []; private _isTaskQueueWorking = false; + private _debounceTime = -1; + private _lastTaskTime: { [fullDocPath: string]: number } = {}; + /** * Task Statistics * @@ -52,8 +53,11 @@ export class TaskQueue { * * @public */ - constructor (logger: Logger) { + constructor (logger: Logger, debounceTime?: number) { this._logger = logger; + if (debounceTime !== undefined) { + this._debounceTime = debounceTime; + } } /** @@ -108,39 +112,19 @@ export class TaskQueue { // eslint-disable-next-line complexity .acquire('taskQueue', () => { // Skip consecutive sync/push events - if (this._currentTask?.label === 'sync') { - if ((this._syncQueue.length === 0 && - this._currentTask?.syncRemoteName === task.syncRemoteName && - this._currentTask?.label === 'sync' && task.label === 'sync') || - (this._syncQueue.length > 0 && - this._syncQueue[this._syncQueue.length - 1].syncRemoteName === - task.syncRemoteName && - ((this._taskQueue[this._taskQueue.length - 1].label === 'sync' && - task.label === 'sync') || - (this._taskQueue[this._taskQueue.length - 1].label === 'push' && - task.label === 'push'))) - - - } - - - } if ( (this._taskQueue.length === 0 && this._currentTask?.syncRemoteName === task.syncRemoteName && ((this._currentTask?.label === 'sync' && task.label === 'sync') || - (this._currentTask?.label === 'push' && task.label === 'push'))) - - - || - (this._taskQueue.length > 0 && - this._taskQueue[this._taskQueue.length - 1].syncRemoteName === - task.syncRemoteName && - ((this._taskQueue[this._taskQueue.length - 1].label === 'sync' && - task.label === 'sync') || - (this._taskQueue[this._taskQueue.length - 1].label === 'push' && - task.label === 'push'))) - ) { + (this._currentTask?.label === 'push' && task.label === 'push'))) || + (this._taskQueue.length > 0 && + this._taskQueue[this._taskQueue.length - 1].syncRemoteName === + task.syncRemoteName && + ((this._taskQueue[this._taskQueue.length - 1].label === 'sync' && + task.label === 'sync') || + (this._taskQueue[this._taskQueue.length - 1].label === 'push' && + task.label === 'push'))) + ) { task.cancel(); this._statistics.cancel++; throw new Err.ConsecutiveSyncSkippedError(task.label, task.taskId); @@ -172,7 +156,12 @@ export class TaskQueue { ); } } - this._execTaskQueue(); + // Reentrant lock cannot be used in current AsyncLock + // because 'domain' module of Node.js is deprecated. + // Use setTimeout not to be deadlock. + setTimeout(() => { + this._execTaskQueue(); + }, 100); }) .catch(e => { if (e instanceof Err.ConsecutiveSyncSkippedError) { @@ -247,65 +236,125 @@ export class TaskQueue { /** * @internal */ + // eslint-disable-next-line complexity private _execTaskQueue () { if (this._taskQueue.length > 0 && !this._isTaskQueueWorking) { - this._currentTask = this._taskQueue.shift(); - if (this._currentTask !== undefined && this._currentTask.func !== undefined) { - const label = this._currentTask.label; - const shortId = this._currentTask.shortId; - const shortName = this._currentTask.shortName; - const collectionPath = this._currentTask.collectionPath; - const fullDocPath = collectionPath ? collectionPath + shortName : ''; - const taskId = this._currentTask.taskId; - const syncRemoteName = this._currentTask.syncRemoteName; + this._lock + // eslint-disable-next-line complexity + .acquire('taskQueue', async () => { + // put and update may be debounced. + if (this._debounceTime > 0) { + const skippedTasks: Task[] = []; + let nextTaskIndex = 0; + let lastTaskTime = 0; + let taskExistAfterDebounceTime = false; + do { + const nextTask = this._taskQueue[nextTaskIndex]; + // Check label + if (nextTask.label !== 'put' && nextTask.label !== 'update') continue; - this._isTaskQueueWorking = true; - this._logger.debug( - CONSOLE_STYLE.bgYellow().fgBlack().tag()`Start: ${label}(${fullDocPath})` - ); + const nextTaskTime = decodeTime(nextTask.enqueueTime!); + lastTaskTime = this._lastTaskTime[ + nextTask.collectionPath + nextTask.shortName! + ]; + console.log( + `# ${nextTask.taskId}: ${ + lastTaskTime + this._debounceTime + } : ${nextTaskTime}` + ); + // Check fullDocPath + if (lastTaskTime === undefined) continue; - const beforeResolve = () => { - this._logger.debug( - CONSOLE_STYLE.bgGreen().fgBlack().tag()`End: ${label}(${fullDocPath})` - ); - this._statistics[label]++; - this._isTaskQueueWorking = false; - this._currentTask = undefined; - }; - const beforeReject = () => { - this._logger.debug( - CONSOLE_STYLE.bgGreen().fgRed().tag()`End with error: ${label}(${fullDocPath})` - ); - this._statistics[label]++; - this._isTaskQueueWorking = false; - this._currentTask = undefined; - }; - const taskMetadata: TaskMetadata = { - label, - taskId, - shortId, - shortName, - collectionPath, - enqueueTime: this._currentTask.enqueueTime, - syncRemoteName, - }; + if (nextTaskTime <= lastTaskTime + this._debounceTime) { + skippedTasks.push(nextTask); + } + else { + taskExistAfterDebounceTime = true; + } + nextTaskIndex++; + } while (nextTaskIndex > this._taskQueue.length - 1); + if (skippedTasks.length > 0) { + const currentTime = Date.now(); + if (currentTime < lastTaskTime + this._debounceTime) { + // Wait until debounced time + console.log('# wait: ' + (lastTaskTime + this._debounceTime - currentTime)); + await sleep(lastTaskTime + this._debounceTime - currentTime); + } + if (!taskExistAfterDebounceTime) { + // Exclude the last one + skippedTasks.pop(); + } + // Remove skipped task + this._taskQueue = this._taskQueue.filter( + task => !skippedTasks.includes(task) + ); + for (const skippedTask of skippedTasks) { + // Skipped task throws TaskCancelError + skippedTask.cancel(); + } + skippedTasks.length = 0; + } + } - this._currentTask.func(beforeResolve, beforeReject, taskMetadata).finally(() => { - /* - this._lock - // eslint-disable-next-line complexity - .acquire('taskQueue', () => { - if (this._taskQueue.length > 0) { - const nextTask: Task; - for (const task of this._taskQueue) - if (this._currentTask?.collectionPath === task.collectionPath) { + this._currentTask = this._taskQueue.shift(); + }) + .finally(() => { + if (this._currentTask !== undefined && this._currentTask.func !== undefined) { + const label = this._currentTask.label; + const shortId = this._currentTask.shortId; + const shortName = this._currentTask.shortName; + const collectionPath = this._currentTask.collectionPath; + const fullDocPath = collectionPath ? collectionPath + shortName : ''; + const taskId = this._currentTask.taskId; + const syncRemoteName = this._currentTask.syncRemoteName; - } - } - */ - this._execTaskQueue(); + this._isTaskQueueWorking = true; + this._logger.debug( + CONSOLE_STYLE.bgYellow().fgBlack().tag()`Start: ${label}(${fullDocPath})` + ); + + const beforeResolve = () => { + this._logger.debug( + CONSOLE_STYLE.bgGreen().fgBlack().tag()`End: ${label}(${fullDocPath})` + ); + this._statistics[label]++; + this._isTaskQueueWorking = false; + this._currentTask = undefined; + }; + const beforeReject = () => { + this._logger.debug( + CONSOLE_STYLE.bgGreen() + .fgRed() + .tag()`End with error: ${label}(${fullDocPath})` + ); + this._statistics[label]++; + this._isTaskQueueWorking = false; + this._currentTask = undefined; + }; + const taskMetadata: TaskMetadata = { + label, + taskId, + shortId, + shortName, + collectionPath, + enqueueTime: this._currentTask.enqueueTime, + syncRemoteName, + }; + + this._currentTask + .func(beforeResolve, beforeReject, taskMetadata) + .finally(() => { + // put and update may be debounced. + console.log(`task complete: ${taskMetadata.taskId}`); + if (taskMetadata.label === 'put' || taskMetadata.label === 'update') { + this._lastTaskTime[ + taskMetadata.collectionPath! + taskMetadata.shortName! + ] = decodeTime(taskMetadata.enqueueTime!); + } + this._execTaskQueue(); + }); + } }); - } } } } diff --git a/src/types.ts b/src/types.ts index 43a1ecbc..3d5ea675 100644 --- a/src/types.ts +++ b/src/types.ts @@ -52,6 +52,7 @@ export type DatabaseOptions = { dbName: string; logLevel?: TLogLevelName; schema?: Schema; + debounceTime?: number; }; /** diff --git a/test/task_queue.test.ts b/test/task_queue.test.ts index 52a35416..bb27c0a1 100644 --- a/test/task_queue.test.ts +++ b/test/task_queue.test.ts @@ -13,23 +13,25 @@ import expect from 'expect'; import fs from 'fs-extra'; import { Logger } from 'tslog'; import { GitDocumentDB } from '../src/git_documentdb'; -import { createDatabase, destroyDBs, removeRemoteRepositories } from './remote_utils'; import { sleep } from '../src/utils'; import { TaskQueue } from '../src/task_queue'; import { TaskMetadata } from '../src/types'; +import { Err } from '../src/error'; const ulid = monotonicFactory(); const monoId = () => { return ulid(Date.now()); }; -const reposPrefix = 'test_task_queue___'; const localDir = './test/database_task_queue'; -let idCounter = 0; -const serialId = () => { - return `${reposPrefix}${idCounter++}`; -}; +const logger = new Logger({ + name: monoId(), + minLevel: 'info', + displayDateTime: false, + displayFunctionName: false, + displayFilePath: 'hidden', +}); beforeEach(function () { // @ts-ignore @@ -45,6 +47,42 @@ after(() => { }); describe('', () => { + it.only('debounces consecutive put to the same _id', async () => { + const dbName = monoId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + debounceTime: 3000, + }); + await gitDDB.open(); + let skippedTask00 = false; + gitDDB.put({ _id: 'a', name: '0' }, { taskId: '0' }).catch(err => { + if (err instanceof Err.TaskCancelError) skippedTask00 = true; + }); + let skippedTask01 = false; + gitDDB.put({ _id: 'a', name: '1' }, { taskId: '1' }).catch(err => { + if (err instanceof Err.TaskCancelError) skippedTask01 = true; + }); + let skippedTask02 = false; + gitDDB.put({ _id: 'a', name: '2' }, { taskId: '2' }).catch(err => { + if (err instanceof Err.TaskCancelError) skippedTask02 = true; + }); + let skippedTask03 = false; + gitDDB.put({ _id: 'a', name: '3' }, { taskId: '3' }).catch(err => { + if (err instanceof Err.TaskCancelError) skippedTask03 = true; + }); + await sleep(3300); + expect(skippedTask00).toBeFalsy(); + expect(skippedTask01).toBeTruthy(); + expect(skippedTask02).toBeTruthy(); + expect(skippedTask03).toBeFalsy(); + + const json = await gitDDB.get('a'); + expect(json!.name).toEqual('3'); + + await gitDDB.destroy(); + }); + it('increments statistics: put', async () => { const dbName = monoId(); const gitDDB: GitDocumentDB = new GitDocumentDB({ @@ -149,16 +187,7 @@ describe('', () => { }); it('returns newTaskId', () => { - const dbName = monoId(); - const taskQueue = new TaskQueue( - new Logger({ - name: dbName, - minLevel: 'info', - displayDateTime: false, - displayFunctionName: false, - displayFilePath: 'hidden', - }) - ); + const taskQueue = new TaskQueue(logger); // e.g.) 01BX5ZZKBKACTAV9WEVGEMMVRZ let prevId = ''; for (let i = 0; i < 30; i++) { From 5dee029ee406fe54f0c3b626853043923ec08a89 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Thu, 2 Sep 2021 23:10:27 +0900 Subject: [PATCH 176/297] fix: add debounceTime to TaskQueue --- src/task_queue.ts | 250 ++++++++++++++++++++-------------------- src/types.ts | 1 - test/task_queue.test.ts | 1 + 3 files changed, 128 insertions(+), 124 deletions(-) diff --git a/src/task_queue.ts b/src/task_queue.ts index 9413816a..4ea28246 100644 --- a/src/task_queue.ts +++ b/src/task_queue.ts @@ -13,6 +13,8 @@ import { Task, TaskMetadata, TaskStatistics } from './types'; import { CONSOLE_STYLE, sleep } from './utils'; import { Err } from './error'; +type DebounceType = 'exec' | 'skip' | 'exec-after-skip'; + /** * TaskQueue * @@ -110,7 +112,7 @@ export class TaskQueue { // Critical section this._lock // eslint-disable-next-line complexity - .acquire('taskQueue', () => { + .acquire('pushToQueue', () => { // Skip consecutive sync/push events if ( (this._taskQueue.length === 0 && @@ -156,12 +158,7 @@ export class TaskQueue { ); } } - // Reentrant lock cannot be used in current AsyncLock - // because 'domain' module of Node.js is deprecated. - // Use setTimeout not to be deadlock. - setTimeout(() => { - this._execTaskQueue(); - }, 100); + this._execTaskQueue(); }) .catch(e => { if (e instanceof Err.ConsecutiveSyncSkippedError) { @@ -233,128 +230,135 @@ export class TaskQueue { return isTimeout; } + private _checkDebouncedTask (task: Task): [DebounceType, number?] { + // Check label + if (task.label !== 'put' && task.label !== 'update') return ['exec']; + + const nextTaskTime = decodeTime(task.enqueueTime!); + const lastTaskTime = this._lastTaskTime[task.collectionPath + task.shortName!]; + this._logger.debug( + `# task [${task.taskId}]: debounce ${ + lastTaskTime + this._debounceTime + } : enqueue ${nextTaskTime}` + ); + // Check fullDocPath + if (lastTaskTime === undefined) return ['exec']; + + if (nextTaskTime <= lastTaskTime + this._debounceTime) { + return ['skip', lastTaskTime]; + } + + return ['exec-after-skip']; + } + /** * @internal */ // eslint-disable-next-line complexity - private _execTaskQueue () { - if (this._taskQueue.length > 0 && !this._isTaskQueueWorking) { - this._lock - // eslint-disable-next-line complexity - .acquire('taskQueue', async () => { - // put and update may be debounced. - if (this._debounceTime > 0) { - const skippedTasks: Task[] = []; - let nextTaskIndex = 0; - let lastTaskTime = 0; - let taskExistAfterDebounceTime = false; - do { - const nextTask = this._taskQueue[nextTaskIndex]; - // Check label - if (nextTask.label !== 'put' && nextTask.label !== 'update') continue; - - const nextTaskTime = decodeTime(nextTask.enqueueTime!); - lastTaskTime = this._lastTaskTime[ - nextTask.collectionPath + nextTask.shortName! - ]; - console.log( - `# ${nextTask.taskId}: ${ - lastTaskTime + this._debounceTime - } : ${nextTaskTime}` - ); - // Check fullDocPath - if (lastTaskTime === undefined) continue; - - if (nextTaskTime <= lastTaskTime + this._debounceTime) { - skippedTasks.push(nextTask); - } - else { - taskExistAfterDebounceTime = true; - } - nextTaskIndex++; - } while (nextTaskIndex > this._taskQueue.length - 1); - if (skippedTasks.length > 0) { - const currentTime = Date.now(); - if (currentTime < lastTaskTime + this._debounceTime) { - // Wait until debounced time - console.log('# wait: ' + (lastTaskTime + this._debounceTime - currentTime)); - await sleep(lastTaskTime + this._debounceTime - currentTime); - } - if (!taskExistAfterDebounceTime) { - // Exclude the last one - skippedTasks.pop(); - } - // Remove skipped task - this._taskQueue = this._taskQueue.filter( - task => !skippedTasks.includes(task) - ); - for (const skippedTask of skippedTasks) { - // Skipped task throws TaskCancelError - skippedTask.cancel(); - } - skippedTasks.length = 0; - } - } + private async _execTaskQueue () { + if (this._taskQueue.length === 0 || this._isTaskQueueWorking) return; - this._currentTask = this._taskQueue.shift(); - }) - .finally(() => { - if (this._currentTask !== undefined && this._currentTask.func !== undefined) { - const label = this._currentTask.label; - const shortId = this._currentTask.shortId; - const shortName = this._currentTask.shortName; - const collectionPath = this._currentTask.collectionPath; - const fullDocPath = collectionPath ? collectionPath + shortName : ''; - const taskId = this._currentTask.taskId; - const syncRemoteName = this._currentTask.syncRemoteName; - - this._isTaskQueueWorking = true; - this._logger.debug( - CONSOLE_STYLE.bgYellow().fgBlack().tag()`Start: ${label}(${fullDocPath})` - ); + this._isTaskQueueWorking = true; - const beforeResolve = () => { - this._logger.debug( - CONSOLE_STYLE.bgGreen().fgBlack().tag()`End: ${label}(${fullDocPath})` - ); - this._statistics[label]++; - this._isTaskQueueWorking = false; - this._currentTask = undefined; - }; - const beforeReject = () => { - this._logger.debug( - CONSOLE_STYLE.bgGreen() - .fgRed() - .tag()`End with error: ${label}(${fullDocPath})` - ); - this._statistics[label]++; - this._isTaskQueueWorking = false; - this._currentTask = undefined; - }; - const taskMetadata: TaskMetadata = { - label, - taskId, - shortId, - shortName, - collectionPath, - enqueueTime: this._currentTask.enqueueTime, - syncRemoteName, - }; - - this._currentTask - .func(beforeResolve, beforeReject, taskMetadata) - .finally(() => { - // put and update may be debounced. - console.log(`task complete: ${taskMetadata.taskId}`); - if (taskMetadata.label === 'put' || taskMetadata.label === 'update') { - this._lastTaskTime[ - taskMetadata.collectionPath! + taskMetadata.shortName! - ] = decodeTime(taskMetadata.enqueueTime!); - } - this._execTaskQueue(); - }); - } - }); + if (this._debounceTime > 0) { + // put and update may be debounced. + const [debounceType, lastTime] = this._checkDebouncedTask(this._taskQueue[0]); + if (debounceType === 'skip') { + // Wait until debounced time + const sleepTime = lastTime! + this._debounceTime - Date.now(); + this._logger.debug('# wait until debounceTime: ' + sleepTime); + await sleep(sleepTime); + } + } + + const skippedTasks: string[] = []; + let taskAfterSkip = ''; + this._logger.debug(`# checkDebouncedTask for task [${this._taskQueue[0].taskId}]`); + for (const task of this._taskQueue) { + const [debounceType] = this._checkDebouncedTask(task); + if (debounceType === 'skip') { + skippedTasks.push(task.taskId); + } + else if (debounceType === 'exec-after-skip') { + taskAfterSkip = task.taskId; + } + } + if (taskAfterSkip !== '') { + // Exclude the last task + skippedTasks.pop(); + } + + let nextTask = this._taskQueue.shift(); + do { + if (skippedTasks.includes(nextTask!.taskId)) { + nextTask!.cancel(); + nextTask = this._taskQueue.shift(); + } + else if (nextTask!.taskId === taskAfterSkip) { + delete this._lastTaskTime[nextTask!.collectionPath + nextTask!.shortName!]; + break; + } + else { + break; + } + } while (this._taskQueue.length > 0); + + this._currentTask = nextTask; + + if (this._currentTask !== undefined && this._currentTask.func !== undefined) { + const label = this._currentTask.label; + const shortId = this._currentTask.shortId; + const shortName = this._currentTask.shortName; + const collectionPath = this._currentTask.collectionPath; + const fullDocPath = collectionPath ? collectionPath + shortName : ''; + const taskId = this._currentTask.taskId; + const syncRemoteName = this._currentTask.syncRemoteName; + + this._logger.debug( + CONSOLE_STYLE.bgYellow().fgBlack().tag()`Start: ${label}(${fullDocPath})` + ); + + const beforeResolve = () => { + this._logger.debug( + CONSOLE_STYLE.bgGreen().fgBlack().tag()`End: ${label}(${fullDocPath})` + ); + this._statistics[label]++; + + if (taskMetadata.label === 'put' || taskMetadata.label === 'update') { + // put and update may be debounced. + this._logger.debug( + `# Set lastTaskTime of [${ + taskMetadata.collectionPath! + taskMetadata.shortName! + }]: ${decodeTime(taskMetadata.enqueueTime!)}` + ); + this._lastTaskTime[ + taskMetadata.collectionPath! + taskMetadata.shortName! + ] = decodeTime(taskMetadata.enqueueTime!); + } + this._isTaskQueueWorking = false; + this._currentTask = undefined; + }; + const beforeReject = () => { + this._logger.debug( + CONSOLE_STYLE.bgGreen().fgRed().tag()`End with error: ${label}(${fullDocPath})` + ); + this._statistics[label]++; + this._isTaskQueueWorking = false; + this._currentTask = undefined; + }; + const taskMetadata: TaskMetadata = { + label, + taskId, + shortId, + shortName, + collectionPath, + enqueueTime: this._currentTask.enqueueTime, + syncRemoteName, + }; + + this._currentTask.func(beforeResolve, beforeReject, taskMetadata).finally(() => { + this._execTaskQueue(); + }); } } } diff --git a/src/types.ts b/src/types.ts index 3d5ea675..0ddf994a 100644 --- a/src/types.ts +++ b/src/types.ts @@ -791,7 +791,6 @@ export type TaskMetadata = { shortId?: string; shortName?: string; collectionPath?: string; - debounceTime?: string; enqueueTime?: string; syncRemoteName?: string; }; diff --git a/test/task_queue.test.ts b/test/task_queue.test.ts index bb27c0a1..ee3e6ca2 100644 --- a/test/task_queue.test.ts +++ b/test/task_queue.test.ts @@ -53,6 +53,7 @@ describe('', () => { dbName, localDir, debounceTime: 3000, + logLevel: 'trace', }); await gitDDB.open(); let skippedTask00 = false; From 03491bb3f53d72e811d6e81073c6c564b9e00d2f Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 3 Sep 2021 02:18:29 +0900 Subject: [PATCH 177/297] fix: debounce can skip multiple _ids --- src/task_queue.ts | 102 +++++++++++------- test/remote_base/sync_trysync.ts | 65 +++++++++++- test/task_queue.test.ts | 177 ++++++++++++++++++++++++++++++- 3 files changed, 301 insertions(+), 43 deletions(-) diff --git a/src/task_queue.ts b/src/task_queue.ts index 4ea28246..295c1b36 100644 --- a/src/task_queue.ts +++ b/src/task_queue.ts @@ -6,6 +6,7 @@ * found in the LICENSE file in the root directory of this source tree. */ +import { exit } from 'process'; import { decodeTime, monotonicFactory } from 'ulid'; import { Logger } from 'tslog'; import AsyncLock from 'async-lock'; @@ -30,7 +31,7 @@ export class TaskQueue { private _taskQueue: Task[] = []; private _isTaskQueueWorking = false; - private _debounceTime = -1; + public debounceTime = -1; private _lastTaskTime: { [fullDocPath: string]: number } = {}; /** @@ -58,7 +59,7 @@ export class TaskQueue { constructor (logger: Logger, debounceTime?: number) { this._logger = logger; if (debounceTime !== undefined) { - this._debounceTime = debounceTime; + this.debounceTime = debounceTime; } } @@ -232,19 +233,20 @@ export class TaskQueue { private _checkDebouncedTask (task: Task): [DebounceType, number?] { // Check label - if (task.label !== 'put' && task.label !== 'update') return ['exec']; + if (task.label !== 'put' && task.label !== 'update' && task.label !== 'insert') + return ['exec']; const nextTaskTime = decodeTime(task.enqueueTime!); const lastTaskTime = this._lastTaskTime[task.collectionPath + task.shortName!]; this._logger.debug( `# task [${task.taskId}]: debounce ${ - lastTaskTime + this._debounceTime + lastTaskTime + this.debounceTime } : enqueue ${nextTaskTime}` ); // Check fullDocPath if (lastTaskTime === undefined) return ['exec']; - if (nextTaskTime <= lastTaskTime + this._debounceTime) { + if (nextTaskTime <= lastTaskTime + this.debounceTime) { return ['skip', lastTaskTime]; } @@ -260,50 +262,64 @@ export class TaskQueue { this._isTaskQueueWorking = true; - if (this._debounceTime > 0) { - // put and update may be debounced. - const [debounceType, lastTime] = this._checkDebouncedTask(this._taskQueue[0]); - if (debounceType === 'skip') { + if (this.debounceTime > 0) { + // put, update, insert may be debounced. + const [dType, lastTime] = this._checkDebouncedTask(this._taskQueue[0]); + if (dType === 'skip') { // Wait until debounced time - const sleepTime = lastTime! + this._debounceTime - Date.now(); + const sleepTime = lastTime! + this.debounceTime - Date.now(); this._logger.debug('# wait until debounceTime: ' + sleepTime); await sleep(sleepTime); } - } - const skippedTasks: string[] = []; - let taskAfterSkip = ''; - this._logger.debug(`# checkDebouncedTask for task [${this._taskQueue[0].taskId}]`); - for (const task of this._taskQueue) { - const [debounceType] = this._checkDebouncedTask(task); - if (debounceType === 'skip') { - skippedTasks.push(task.taskId); - } - else if (debounceType === 'exec-after-skip') { - taskAfterSkip = task.taskId; - } - } - if (taskAfterSkip !== '') { - // Exclude the last task - skippedTasks.pop(); - } + const skippedTasks: { [fullDocPath: string]: string[] } = {}; + const taskAfterSkip: { [fullDocPath: string]: string } = {}; - let nextTask = this._taskQueue.shift(); - do { - if (skippedTasks.includes(nextTask!.taskId)) { - nextTask!.cancel(); - nextTask = this._taskQueue.shift(); - } - else if (nextTask!.taskId === taskAfterSkip) { - delete this._lastTaskTime[nextTask!.collectionPath + nextTask!.shortName!]; - break; + this._logger.debug(`# checkDebouncedTask for task [${this._taskQueue[0].taskId}]`); + for (const task of this._taskQueue) { + const [debounceType] = this._checkDebouncedTask(task); + const fullDocPath = task.collectionPath + task.shortName!; + if (debounceType === 'skip') { + if (skippedTasks[fullDocPath] === undefined) { + skippedTasks[fullDocPath] = []; + } + skippedTasks[fullDocPath].push(task.taskId); + } + else if (debounceType === 'exec-after-skip') { + taskAfterSkip[fullDocPath] = task.taskId; + } } - else { - break; + + for (const fullDocPath of Object.keys(skippedTasks)) { + // Exclude the last task + if (taskAfterSkip[fullDocPath] === undefined) { + skippedTasks[fullDocPath].pop(); + } } - } while (this._taskQueue.length > 0); + let nextTask = this._taskQueue.shift(); + do { + const fullDocPath = nextTask!.collectionPath + nextTask!.shortName!; + if ( + skippedTasks[fullDocPath] && + skippedTasks[fullDocPath].includes(nextTask!.taskId) + ) { + nextTask!.cancel(); + nextTask = this._taskQueue.shift(); + } + else if (nextTask!.taskId === taskAfterSkip[fullDocPath]) { + delete this._lastTaskTime[fullDocPath]; + break; + } + else { + break; + } + } while (this._taskQueue.length > 0); - this._currentTask = nextTask; + this._currentTask = nextTask; + } + else { + this._currentTask = this._taskQueue.shift(); + } if (this._currentTask !== undefined && this._currentTask.func !== undefined) { const label = this._currentTask.label; @@ -324,7 +340,11 @@ export class TaskQueue { ); this._statistics[label]++; - if (taskMetadata.label === 'put' || taskMetadata.label === 'update') { + if ( + taskMetadata.label === 'put' || + taskMetadata.label === 'update' || + taskMetadata.label === 'insert' + ) { // put and update may be debounced. this._logger.debug( `# Set lastTaskTime of [${ diff --git a/test/remote_base/sync_trysync.ts b/test/remote_base/sync_trysync.ts index 2da5326e..4ea49309 100644 --- a/test/remote_base/sync_trysync.ts +++ b/test/remote_base/sync_trysync.ts @@ -41,6 +41,7 @@ import { } from '../remote_utils'; import { sleep, toSortedJSONString } from '../../src/utils'; import { JSON_EXT } from '../../src/const'; +import { Err } from '../../src/error'; // eslint-disable-next-line @typescript-eslint/no-var-requires const pushWorker_module = require('../../src/remote/push_worker'); @@ -804,7 +805,7 @@ export const syncTrySyncBase = ( } await sleep(10000); - // results will be include 9 cancels + // results will be include cancels let cancelCount = 0; results.forEach(res => { if (res.action === 'canceled') cancelCount++; @@ -821,6 +822,68 @@ export const syncTrySyncBase = ( await destroyDBs([dbA]); }); + it('skips consecutive put tasks mixed with sync tasks', async () => { + const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { + connection, + }); + dbA.taskQueue.debounceTime = 7000; + + let skippedTask00 = false; + dbA.put({ _id: 'a', name: '0' }, { taskId: '0' }).catch(err => { + if (err instanceof Err.TaskCancelError) skippedTask00 = true; + }); + const putter: Promise[] = []; + const validResult: (boolean | Record)[] = []; + for (let i = 1; i < 10; i++) { + putter.push( + dbA.put({ _id: 'a', name: `${i}` }, { taskId: `${i}` }).catch(err => { + if (err instanceof Err.TaskCancelError) return true; + }) + ); + validResult.push(true); + } + + const syncResults: SyncResult[] = []; + for (let i = 0; i < 3; i++) { + // eslint-disable-next-line promise/catch-or-return + syncA.trySync().then(result => syncResults.push(result)); + } + + for (let i = 10; i < 20; i++) { + putter.push( + dbA.put({ _id: 'a', name: `${i}` }, { taskId: `${i}` }).catch(err => { + if (err instanceof Err.TaskCancelError) return true; + }) + ); + validResult.push(true); + } + putter.push( + dbA.put({ _id: 'a', name: '20' }, { taskId: '20' }).catch(err => { + if (err instanceof Err.TaskCancelError) return true; + }) + ); + validResult.push({ _id: 'a' }); + const results = await Promise.all(putter); + + await sleep(10000); + + // Check skipped put() + expect(skippedTask00).toBeFalsy(); + expect(results).toMatchObject(validResult); + const json = await dbA.get('a'); + expect(json!.name).toEqual('20'); + + // Check sync + let cancelCount = 0; + syncResults.forEach(res => { + if (res.action === 'canceled') cancelCount++; + }); + expect(cancelCount).toBeGreaterThanOrEqual(1); + expect(dbA.taskQueue.currentStatistics().sync).toBeGreaterThanOrEqual(1); + + await destroyDBs([dbA]); + }); + it('syncs files under .gitddb', async () => { const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { connection, diff --git a/test/task_queue.test.ts b/test/task_queue.test.ts index ee3e6ca2..b9bdbd6b 100644 --- a/test/task_queue.test.ts +++ b/test/task_queue.test.ts @@ -47,7 +47,7 @@ after(() => { }); describe('', () => { - it.only('debounces consecutive put to the same _id', async () => { + it('debounces consecutive puts to the same _id', async () => { const dbName = monoId(); const gitDDB: GitDocumentDB = new GitDocumentDB({ dbName, @@ -84,6 +84,181 @@ describe('', () => { await gitDDB.destroy(); }); + it('debounces a lot of consecutive puts to the same _id', async () => { + const dbName = monoId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + debounceTime: 7000, + logLevel: 'trace', + }); + await gitDDB.open(); + let skippedTask00 = false; + gitDDB.put({ _id: 'a', name: '0' }, { taskId: '0' }).catch(err => { + if (err instanceof Err.TaskCancelError) skippedTask00 = true; + }); + const putter: Promise[] = []; + const validResult: (boolean | Record)[] = []; + for (let i = 1; i < 50; i++) { + putter.push( + gitDDB.put({ _id: 'a', name: `${i}` }, { taskId: `${i}` }).catch(err => { + if (err instanceof Err.TaskCancelError) return true; + }) + ); + validResult.push(true); + } + putter.push( + gitDDB.put({ _id: 'a', name: '50' }, { taskId: '50' }).catch(err => { + if (err instanceof Err.TaskCancelError) return true; + }) + ); + validResult.push({ _id: 'a' }); + + const results = await Promise.all(putter); + + expect(skippedTask00).toBeFalsy(); + expect(results).toMatchObject(validResult); + + const json = await gitDDB.get('a'); + expect(json!.name).toEqual('50'); + + await gitDDB.destroy(); + }); + + it('debounces a lot of consecutive puts to the mixed _ids', async () => { + const dbName = monoId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + debounceTime: 7000, + logLevel: 'trace', + }); + await gitDDB.open(); + let skippedTaskA00 = false; + gitDDB.put({ _id: 'a', name: '0' }, { taskId: 'a0' }).catch(err => { + if (err instanceof Err.TaskCancelError) skippedTaskA00 = true; + }); + let skippedTaskB00 = false; + gitDDB.put({ _id: 'b', name: '0' }, { taskId: 'b0' }).catch(err => { + if (err instanceof Err.TaskCancelError) skippedTaskB00 = true; + }); + let skippedTaskC00 = false; + gitDDB.put({ _id: 'c', name: '0' }, { taskId: 'c0' }).catch(err => { + if (err instanceof Err.TaskCancelError) skippedTaskC00 = true; + }); + const putter: Promise[] = []; + const validResult: (boolean | Record)[] = []; + for (let i = 1; i < 50; i++) { + putter.push( + gitDDB.put({ _id: 'a', name: `${i}` }, { taskId: `a${i}` }).catch(err => { + if (err instanceof Err.TaskCancelError) return true; + }) + ); + validResult.push(true); + putter.push( + gitDDB.put({ _id: 'b', name: `${i}` }, { taskId: `b${i}` }).catch(err => { + if (err instanceof Err.TaskCancelError) return true; + }) + ); + validResult.push(true); + putter.push( + gitDDB.put({ _id: 'c', name: `${i}` }, { taskId: `c${i}` }).catch(err => { + if (err instanceof Err.TaskCancelError) return true; + }) + ); + validResult.push(true); + } + putter.push( + gitDDB.put({ _id: 'a', name: '50' }, { taskId: 'a50' }).catch(err => { + if (err instanceof Err.TaskCancelError) return true; + }) + ); + validResult.push({ _id: 'a' }); + putter.push( + gitDDB.put({ _id: 'b', name: '50' }, { taskId: 'b50' }).catch(err => { + if (err instanceof Err.TaskCancelError) return true; + }) + ); + validResult.push({ _id: 'b' }); + putter.push( + gitDDB.put({ _id: 'c', name: '50' }, { taskId: 'c50' }).catch(err => { + if (err instanceof Err.TaskCancelError) return true; + }) + ); + validResult.push({ _id: 'c' }); + + const results = await Promise.all(putter); + + expect(skippedTaskA00).toBeFalsy(); + expect(skippedTaskB00).toBeFalsy(); + expect(skippedTaskC00).toBeFalsy(); + expect(results).toMatchObject(validResult); + + const jsonA = await gitDDB.get('a'); + expect(jsonA!.name).toEqual('50'); + const jsonB = await gitDDB.get('b'); + expect(jsonB!.name).toEqual('50'); + const jsonC = await gitDDB.get('c'); + expect(jsonC!.name).toEqual('50'); + + await gitDDB.destroy(); + }); + + it('debounces a lot of consecutive puts mixed with a delete command', async () => { + const dbName = monoId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + debounceTime: 7000, + logLevel: 'trace', + }); + await gitDDB.open(); + let skippedTask00 = false; + gitDDB.put({ _id: 'a', name: '0' }, { taskId: '0' }).catch(err => { + if (err instanceof Err.TaskCancelError) skippedTask00 = true; + }); + const putter: Promise[] = []; + const validResult: (boolean | Record)[] = []; + for (let i = 1; i < 10; i++) { + putter.push( + gitDDB.put({ _id: 'a', name: `${i}` }, { taskId: `${i}` }).catch(err => { + if (err instanceof Err.TaskCancelError) return true; + }) + ); + validResult.push(true); + } + // Delete + putter.push(gitDDB.delete('a')); + validResult.push({ + _id: 'a', + }); + + for (let i = 10; i < 20; i++) { + putter.push( + gitDDB.put({ _id: 'a', name: `${i}` }, { taskId: `${i}` }).catch(err => { + if (err instanceof Err.TaskCancelError) return true; + }) + ); + validResult.push(true); + } + putter.push( + gitDDB.put({ _id: 'a', name: '20' }, { taskId: '20' }).catch(err => { + if (err instanceof Err.TaskCancelError) return true; + }) + ); + validResult.push({ _id: 'a' }); + + const results = await Promise.all(putter); + + expect(skippedTask00).toBeFalsy(); + expect(results).toMatchObject(validResult); + + const json = await gitDDB.get('a'); + expect(json!.name).toEqual('20'); + + await gitDDB.destroy(); + }); + it('increments statistics: put', async () => { const dbName = monoId(); const gitDDB: GitDocumentDB = new GitDocumentDB({ From e757a16f28215a673957c9e0f83f0f7140e2b268 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 3 Sep 2021 02:19:03 +0900 Subject: [PATCH 178/297] build: bump to v0.4.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 83e0cd2b..b7ff176a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "git-documentdb", - "version": "0.4.4", + "version": "0.4.5", "description": "Offline-first database that syncs with Git", "main": "dist/main.js", "types": "dist/main.d.ts", From 3f0433f385abb15834ebdb84e3326a8cde475a62 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 3 Sep 2021 02:19:21 +0900 Subject: [PATCH 179/297] build: bump to v0.4.5-beta.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b7ff176a..50229aca 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "git-documentdb", - "version": "0.4.5", + "version": "0.4.5-beta.0", "description": "Offline-first database that syncs with Git", "main": "dist/main.js", "types": "dist/main.d.ts", From a50f87265f298a6c899dbe3d50deb5e759cb35a9 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 3 Sep 2021 18:27:32 +0900 Subject: [PATCH 180/297] fix: add debounceTime to collection --- src/collection.ts | 13 +++ src/crud/put.ts | 1 + src/git_documentdb.ts | 5 +- src/task_queue.ts | 187 +++++++++++++++++----------------------- src/types.ts | 11 ++- test/task_queue.test.ts | 41 +++++---- 6 files changed, 133 insertions(+), 125 deletions(-) diff --git a/src/collection.ts b/src/collection.ts index b73416af..b3d62acd 100644 --- a/src/collection.ts +++ b/src/collection.ts @@ -142,6 +142,7 @@ export class Collection implements ICollection { this._parent = undefined; options ??= { namePrefix: '', + debounceTime: 0, }; } else { @@ -350,6 +351,9 @@ export class Collection implements ICollection { return Promise.reject(err); } + options ??= {}; + options.debounceTime ??= this._options.debounceTime; + return putImpl( this._gitDDB, this.collectionPath, @@ -466,10 +470,12 @@ export class Collection implements ICollection { ) { options ??= {}; options.insertOrUpdate = 'insert'; + options.debounceTime ??= this._options.debounceTime; } else { jsonDocOrOptions ??= {}; (jsonDocOrOptions as PutOptions).insertOrUpdate = 'insert'; + (jsonDocOrOptions as PutOptions).debounceTime ??= this._options.debounceTime; } return this.put(shortIdOrDoc, jsonDocOrOptions, options); @@ -569,10 +575,12 @@ export class Collection implements ICollection { ) { options ??= {}; options.insertOrUpdate = 'update'; + options.debounceTime ??= this._options.debounceTime; } else { jsonDocOrOptions ??= {}; (jsonDocOrOptions as PutOptions).insertOrUpdate = 'update'; + (jsonDocOrOptions as PutOptions).debounceTime ??= this._options.debounceTime; } return this.put(shortIdOrDoc, jsonDocOrOptions, options); @@ -665,6 +673,9 @@ export class Collection implements ICollection { return Promise.reject(err); } + options ??= {}; + options.debounceTime ??= this._options.debounceTime; + return putImpl( this._gitDDB, this.collectionPath, @@ -740,6 +751,7 @@ export class Collection implements ICollection { // Resolve overloads options ??= {}; options.insertOrUpdate = 'insert'; + options.debounceTime ??= this._options.debounceTime; return this.putFatDoc(shortName, doc, options); } @@ -785,6 +797,7 @@ export class Collection implements ICollection { // Resolve overloads options ??= {}; options.insertOrUpdate = 'update'; + options.debounceTime ??= this._options.debounceTime; return this.putFatDoc(shortName, doc, options); } diff --git a/src/crud/put.ts b/src/crud/put.ts index a085e910..7e9e1a84 100644 --- a/src/crud/put.ts +++ b/src/crud/put.ts @@ -68,6 +68,7 @@ export function putImpl ( shortId, shortName, collectionPath, + debounceTime: options!.debounceTime, func: (beforeResolve, beforeReject) => putWorker( gitDDB, diff --git a/src/git_documentdb.ts b/src/git_documentdb.ts index 96aacab6..3e11c179 100644 --- a/src/git_documentdb.ts +++ b/src/git_documentdb.ts @@ -306,6 +306,7 @@ export class GitDocumentDB * * @public */ + // eslint-disable-next-line complexity constructor (options: DatabaseOptions & CollectionOptions) { if (options.dbName === undefined || options.dbName === '') { throw new Err.UndefinedDatabaseNameError(); @@ -340,14 +341,14 @@ export class GitDocumentDB ); } - options.debounceTime ??= -1; - this._taskQueue = new TaskQueue(this.logger, options.debounceTime); + this._taskQueue = new TaskQueue(this.logger); // Set logLevel after initializing taskQueue. this.logLevel = options.logLevel ?? DEFAULT_LOG_LEVEL; const collectionOptions = { namePrefix: options?.namePrefix ?? '', + debounceTime: options?.debounceTime ?? 0, }; this._rootCollection = new Collection(this, '', undefined, collectionOptions); diff --git a/src/task_queue.ts b/src/task_queue.ts index 295c1b36..56c45d22 100644 --- a/src/task_queue.ts +++ b/src/task_queue.ts @@ -6,7 +6,6 @@ * found in the LICENSE file in the root directory of this source tree. */ -import { exit } from 'process'; import { decodeTime, monotonicFactory } from 'ulid'; import { Logger } from 'tslog'; import AsyncLock from 'async-lock'; @@ -14,8 +13,6 @@ import { Task, TaskMetadata, TaskStatistics } from './types'; import { CONSOLE_STYLE, sleep } from './utils'; import { Err } from './error'; -type DebounceType = 'exec' | 'skip' | 'exec-after-skip'; - /** * TaskQueue * @@ -31,9 +28,6 @@ export class TaskQueue { private _taskQueue: Task[] = []; private _isTaskQueueWorking = false; - public debounceTime = -1; - private _lastTaskTime: { [fullDocPath: string]: number } = {}; - /** * Task Statistics * @@ -51,16 +45,17 @@ export class TaskQueue { private _currentTask: Task | undefined = undefined; + private _checkTimer: NodeJS.Timeout; /** * Constructor * * @public */ - constructor (logger: Logger, debounceTime?: number) { + constructor (logger: Logger) { this._logger = logger; - if (debounceTime !== undefined) { - this.debounceTime = debounceTime; - } + this._checkTimer = setInterval(() => { + this._checkTaskQueue(); + }, 100); } /** @@ -113,7 +108,7 @@ export class TaskQueue { // Critical section this._lock // eslint-disable-next-line complexity - .acquire('pushToQueue', () => { + .acquire('TaskQueue', () => { // Skip consecutive sync/push events if ( (this._taskQueue.length === 0 && @@ -145,7 +140,9 @@ export class TaskQueue { collectionPath: task.collectionPath, enqueueTime: task.enqueueTime, syncRemoteName: task.syncRemoteName, + debounceTime: task.debounceTime, }; + if (task.enqueueCallback) { try { task.enqueueCallback(taskMetadata); @@ -159,7 +156,6 @@ export class TaskQueue { ); } } - this._execTaskQueue(); }) .catch(e => { if (e instanceof Err.ConsecutiveSyncSkippedError) { @@ -178,6 +174,9 @@ export class TaskQueue { */ clear () { // Clear not queued jobs + + clearInterval(this._checkTimer); + // @ts-ignore this._lock.queues.taskQueue = null; @@ -231,96 +230,87 @@ export class TaskQueue { return isTimeout; } - private _checkDebouncedTask (task: Task): [DebounceType, number?] { - // Check label - if (task.label !== 'put' && task.label !== 'update' && task.label !== 'insert') - return ['exec']; - - const nextTaskTime = decodeTime(task.enqueueTime!); - const lastTaskTime = this._lastTaskTime[task.collectionPath + task.shortName!]; - this._logger.debug( - `# task [${task.taskId}]: debounce ${ - lastTaskTime + this.debounceTime - } : enqueue ${nextTaskTime}` - ); - // Check fullDocPath - if (lastTaskTime === undefined) return ['exec']; - - if (nextTaskTime <= lastTaskTime + this.debounceTime) { - return ['skip', lastTaskTime]; + private _pullTargetTask (targetIndex: number) { + if (targetIndex >= this._taskQueue.length) { + return undefined; } - - return ['exec-after-skip']; + if (targetIndex === 0) { + return this._taskQueue.shift(); + } + const [task] = this._taskQueue.splice(targetIndex, 1); + return task; } /** + * checkTaskQueue * @internal */ - // eslint-disable-next-line complexity - private async _execTaskQueue () { - if (this._taskQueue.length === 0 || this._isTaskQueueWorking) return; - - this._isTaskQueueWorking = true; - - if (this.debounceTime > 0) { - // put, update, insert may be debounced. - const [dType, lastTime] = this._checkDebouncedTask(this._taskQueue[0]); - if (dType === 'skip') { - // Wait until debounced time - const sleepTime = lastTime! + this.debounceTime - Date.now(); - this._logger.debug('# wait until debounceTime: ' + sleepTime); - await sleep(sleepTime); - } - - const skippedTasks: { [fullDocPath: string]: string[] } = {}; - const taskAfterSkip: { [fullDocPath: string]: string } = {}; + private _checkTaskQueue () { + if (this._lock.isBusy()) return; - this._logger.debug(`# checkDebouncedTask for task [${this._taskQueue[0].taskId}]`); - for (const task of this._taskQueue) { - const [debounceType] = this._checkDebouncedTask(task); - const fullDocPath = task.collectionPath + task.shortName!; - if (debounceType === 'skip') { - if (skippedTasks[fullDocPath] === undefined) { - skippedTasks[fullDocPath] = []; - } - skippedTasks[fullDocPath].push(task.taskId); - } - else if (debounceType === 'exec-after-skip') { - taskAfterSkip[fullDocPath] = task.taskId; - } - } + // eslint-disable-next-line complexity + this._lock.acquire('TaskQueue', () => { + if (this._taskQueue.length === 0 || this._isTaskQueueWorking) return; - for (const fullDocPath of Object.keys(skippedTasks)) { - // Exclude the last task - if (taskAfterSkip[fullDocPath] === undefined) { - skippedTasks[fullDocPath].pop(); - } - } - let nextTask = this._taskQueue.shift(); - do { - const fullDocPath = nextTask!.collectionPath + nextTask!.shortName!; + let taskIndex = 0; + while (taskIndex < this._taskQueue.length) { + const targetTask = this._taskQueue[taskIndex]; + console.log('# check task: ' + targetTask.taskId); if ( - skippedTasks[fullDocPath] && - skippedTasks[fullDocPath].includes(nextTask!.taskId) + targetTask.label !== 'put' && + targetTask.label !== 'update' && + targetTask.label !== 'insert' ) { - nextTask!.cancel(); - nextTask = this._taskQueue.shift(); - } - else if (nextTask!.taskId === taskAfterSkip[fullDocPath]) { - delete this._lastTaskTime[fullDocPath]; - break; + this._currentTask = this._pullTargetTask(taskIndex); + if (this._currentTask !== undefined) this._execTask(); + return; } - else { - break; + const targetFullDocPath = targetTask.collectionPath! + targetTask.shortName!; + const expiredTime = decodeTime(targetTask.enqueueTime!) + targetTask.debounceTime!; + const current = Date.now(); + if (expiredTime <= current) { + let nextPutExist = false; + for (let i = taskIndex + 1; i < this._taskQueue.length; i++) { + const tmpTask = this._taskQueue[i]; + if (decodeTime(tmpTask.enqueueTime!) > expiredTime) break; + + if ( + (tmpTask.label === 'put' || + tmpTask.label === 'insert' || + tmpTask.label === 'update' || + tmpTask.label === 'delete') && + targetFullDocPath === tmpTask.collectionPath! + tmpTask.shortName! + ) { + // eslint-disable-next-line max-depth + if (tmpTask.label === 'delete') { + console.log('# delete found!!'); + break; + } + nextPutExist = true; + break; + } + } + if (nextPutExist) { + const cancelTask = this._pullTargetTask(taskIndex); + console.log('# skip: ' + cancelTask?.taskId); + cancelTask?.cancel(); + continue; + } + this._currentTask = this._pullTargetTask(taskIndex); + if (this._currentTask !== undefined) this._execTask(); + return; } - } while (this._taskQueue.length > 0); - - this._currentTask = nextTask; - } - else { - this._currentTask = this._taskQueue.shift(); - } + taskIndex++; + } + }); + } + /** + * execTask + * @internal + */ + // eslint-disable-next-line complexity + private _execTask () { if (this._currentTask !== undefined && this._currentTask.func !== undefined) { const label = this._currentTask.label; const shortId = this._currentTask.shortId; @@ -340,21 +330,6 @@ export class TaskQueue { ); this._statistics[label]++; - if ( - taskMetadata.label === 'put' || - taskMetadata.label === 'update' || - taskMetadata.label === 'insert' - ) { - // put and update may be debounced. - this._logger.debug( - `# Set lastTaskTime of [${ - taskMetadata.collectionPath! + taskMetadata.shortName! - }]: ${decodeTime(taskMetadata.enqueueTime!)}` - ); - this._lastTaskTime[ - taskMetadata.collectionPath! + taskMetadata.shortName! - ] = decodeTime(taskMetadata.enqueueTime!); - } this._isTaskQueueWorking = false; this._currentTask = undefined; }; @@ -376,9 +351,7 @@ export class TaskQueue { syncRemoteName, }; - this._currentTask.func(beforeResolve, beforeReject, taskMetadata).finally(() => { - this._execTaskQueue(); - }); + this._currentTask.func(beforeResolve, beforeReject, taskMetadata).finally(() => {}); } } } diff --git a/src/types.ts b/src/types.ts index 0ddf994a..73fab1fd 100644 --- a/src/types.ts +++ b/src/types.ts @@ -52,7 +52,6 @@ export type DatabaseOptions = { dbName: string; logLevel?: TLogLevelName; schema?: Schema; - debounceTime?: number; }; /** @@ -317,10 +316,16 @@ export type CollectionPath = string; /** * Options for Collection constructor * + * @remarks + * - namePrefix: Automatically generated _id has a specified prefix in the collection. + * + * - debounceTime: put/insert/update operations for the same document are debounced by specified milliseconds in the collection. Default is 0. + * * @public */ export type CollectionOptions = { namePrefix?: string; + debounceTime?: number; }; /** @@ -335,6 +340,8 @@ export type CollectionOptions = { * * - enqueueCallback: A callback function called just after this put task is enqueued to TaskQueue. * + * - debounceTime: put/insert/update operations for the same document are debounced by specified milliseconds. This overwrite the same option in Collection Class. + * * @public */ export type PutOptions = { @@ -342,6 +349,7 @@ export type PutOptions = { insertOrUpdate?: 'insert' | 'update'; taskId?: string; enqueueCallback?: (taskMetadata: TaskMetadata) => void; + debounceTime?: number; }; /** @@ -793,6 +801,7 @@ export type TaskMetadata = { collectionPath?: string; enqueueTime?: string; syncRemoteName?: string; + debounceTime?: number; }; /** diff --git a/test/task_queue.test.ts b/test/task_queue.test.ts index b9bdbd6b..123305fe 100644 --- a/test/task_queue.test.ts +++ b/test/task_queue.test.ts @@ -72,8 +72,8 @@ describe('', () => { gitDDB.put({ _id: 'a', name: '3' }, { taskId: '3' }).catch(err => { if (err instanceof Err.TaskCancelError) skippedTask03 = true; }); - await sleep(3300); - expect(skippedTask00).toBeFalsy(); + await sleep(4000); + expect(skippedTask00).toBeTruthy(); expect(skippedTask01).toBeTruthy(); expect(skippedTask02).toBeTruthy(); expect(skippedTask03).toBeFalsy(); @@ -89,7 +89,7 @@ describe('', () => { const gitDDB: GitDocumentDB = new GitDocumentDB({ dbName, localDir, - debounceTime: 7000, + debounceTime: 3000, logLevel: 'trace', }); await gitDDB.open(); @@ -97,9 +97,11 @@ describe('', () => { gitDDB.put({ _id: 'a', name: '0' }, { taskId: '0' }).catch(err => { if (err instanceof Err.TaskCancelError) skippedTask00 = true; }); + await sleep(4000); + const putter: Promise[] = []; const validResult: (boolean | Record)[] = []; - for (let i = 1; i < 50; i++) { + for (let i = 1; i < 25; i++) { putter.push( gitDDB.put({ _id: 'a', name: `${i}` }, { taskId: `${i}` }).catch(err => { if (err instanceof Err.TaskCancelError) return true; @@ -108,7 +110,7 @@ describe('', () => { validResult.push(true); } putter.push( - gitDDB.put({ _id: 'a', name: '50' }, { taskId: '50' }).catch(err => { + gitDDB.put({ _id: 'a', name: '25' }, { taskId: '25' }).catch(err => { if (err instanceof Err.TaskCancelError) return true; }) ); @@ -117,10 +119,11 @@ describe('', () => { const results = await Promise.all(putter); expect(skippedTask00).toBeFalsy(); + expect(results).toMatchObject(validResult); const json = await gitDDB.get('a'); - expect(json!.name).toEqual('50'); + expect(json!.name).toEqual('25'); await gitDDB.destroy(); }); @@ -130,7 +133,7 @@ describe('', () => { const gitDDB: GitDocumentDB = new GitDocumentDB({ dbName, localDir, - debounceTime: 7000, + debounceTime: 3000, logLevel: 'trace', }); await gitDDB.open(); @@ -146,6 +149,8 @@ describe('', () => { gitDDB.put({ _id: 'c', name: '0' }, { taskId: 'c0' }).catch(err => { if (err instanceof Err.TaskCancelError) skippedTaskC00 = true; }); + await sleep(4000); + const putter: Promise[] = []; const validResult: (boolean | Record)[] = []; for (let i = 1; i < 50; i++) { @@ -192,6 +197,7 @@ describe('', () => { expect(skippedTaskA00).toBeFalsy(); expect(skippedTaskB00).toBeFalsy(); expect(skippedTaskC00).toBeFalsy(); + expect(results).toMatchObject(validResult); const jsonA = await gitDDB.get('a'); @@ -204,22 +210,19 @@ describe('', () => { await gitDDB.destroy(); }); - it('debounces a lot of consecutive puts mixed with a delete command', async () => { + it.only('debounces a lot of consecutive puts mixed with a delete command', async () => { const dbName = monoId(); const gitDDB: GitDocumentDB = new GitDocumentDB({ dbName, localDir, - debounceTime: 7000, + debounceTime: 3000, logLevel: 'trace', }); await gitDDB.open(); - let skippedTask00 = false; - gitDDB.put({ _id: 'a', name: '0' }, { taskId: '0' }).catch(err => { - if (err instanceof Err.TaskCancelError) skippedTask00 = true; - }); + const putter: Promise[] = []; const validResult: (boolean | Record)[] = []; - for (let i = 1; i < 10; i++) { + for (let i = 0; i < 9; i++) { putter.push( gitDDB.put({ _id: 'a', name: `${i}` }, { taskId: `${i}` }).catch(err => { if (err instanceof Err.TaskCancelError) return true; @@ -227,6 +230,15 @@ describe('', () => { ); validResult.push(true); } + + // put task just before delete task will be executed. + putter.push( + gitDDB.put({ _id: 'a', name: `9` }, { taskId: `9` }).catch(err => { + if (err instanceof Err.TaskCancelError) return false; + }) + ); + validResult.push(true); + // Delete putter.push(gitDDB.delete('a')); validResult.push({ @@ -250,7 +262,6 @@ describe('', () => { const results = await Promise.all(putter); - expect(skippedTask00).toBeFalsy(); expect(results).toMatchObject(validResult); const json = await gitDDB.get('a'); From 48b7ef30fd58ea58d7d5b01f17d3b5f775082607 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 3 Sep 2021 23:28:29 +0900 Subject: [PATCH 181/297] fix: use event timer for debounce --- src/collection.ts | 2 +- src/git_documentdb.ts | 2 +- src/task_queue.ts | 66 +++++++++++++++++++------------- src/types.ts | 4 +- test/remote_base/sync_trysync.ts | 32 ++++++++-------- test/task_queue.test.ts | 7 +++- 6 files changed, 66 insertions(+), 47 deletions(-) diff --git a/src/collection.ts b/src/collection.ts index b3d62acd..6ce03bb3 100644 --- a/src/collection.ts +++ b/src/collection.ts @@ -142,7 +142,7 @@ export class Collection implements ICollection { this._parent = undefined; options ??= { namePrefix: '', - debounceTime: 0, + debounceTime: -1, }; } else { diff --git a/src/git_documentdb.ts b/src/git_documentdb.ts index 3e11c179..45a67838 100644 --- a/src/git_documentdb.ts +++ b/src/git_documentdb.ts @@ -348,7 +348,7 @@ export class GitDocumentDB const collectionOptions = { namePrefix: options?.namePrefix ?? '', - debounceTime: options?.debounceTime ?? 0, + debounceTime: options?.debounceTime ?? -1, }; this._rootCollection = new Collection(this, '', undefined, collectionOptions); diff --git a/src/task_queue.ts b/src/task_queue.ts index 56c45d22..fab00739 100644 --- a/src/task_queue.ts +++ b/src/task_queue.ts @@ -255,7 +255,13 @@ export class TaskQueue { let taskIndex = 0; while (taskIndex < this._taskQueue.length) { const targetTask = this._taskQueue[taskIndex]; - console.log('# check task: ' + targetTask.taskId); + + if (targetTask.debounceTime! < 0) { + this._currentTask = this._pullTargetTask(taskIndex); + if (this._currentTask !== undefined) this._execTask(); + return; + } + if ( targetTask.label !== 'put' && targetTask.label !== 'update' && @@ -268,34 +274,42 @@ export class TaskQueue { const targetFullDocPath = targetTask.collectionPath! + targetTask.shortName!; const expiredTime = decodeTime(targetTask.enqueueTime!) + targetTask.debounceTime!; const current = Date.now(); - if (expiredTime <= current) { - let nextPutExist = false; - for (let i = taskIndex + 1; i < this._taskQueue.length; i++) { - const tmpTask = this._taskQueue[i]; - if (decodeTime(tmpTask.enqueueTime!) > expiredTime) break; - - if ( - (tmpTask.label === 'put' || - tmpTask.label === 'insert' || - tmpTask.label === 'update' || - tmpTask.label === 'delete') && - targetFullDocPath === tmpTask.collectionPath! + tmpTask.shortName! - ) { - // eslint-disable-next-line max-depth - if (tmpTask.label === 'delete') { - console.log('# delete found!!'); - break; - } - nextPutExist = true; + + let nextPutExist = false; + let nextDeleteExist = false; + for (let i = taskIndex + 1; i < this._taskQueue.length; i++) { + const tmpTask = this._taskQueue[i]; + if (decodeTime(tmpTask.enqueueTime!) > expiredTime) break; + + if ( + (tmpTask.label === 'put' || + tmpTask.label === 'insert' || + tmpTask.label === 'update' || + tmpTask.label === 'delete') && + targetFullDocPath === tmpTask.collectionPath! + tmpTask.shortName! + ) { + // eslint-disable-next-line max-depth + if (tmpTask.label === 'delete') { + nextDeleteExist = true; break; } + nextPutExist = true; + break; } - if (nextPutExist) { - const cancelTask = this._pullTargetTask(taskIndex); - console.log('# skip: ' + cancelTask?.taskId); - cancelTask?.cancel(); - continue; - } + } + + if (nextPutExist) { + const cancelTask = this._pullTargetTask(taskIndex); + cancelTask?.cancel(); + continue; + } + else if (nextDeleteExist) { + this._currentTask = this._pullTargetTask(taskIndex); + if (this._currentTask !== undefined) this._execTask(); + return; + } + + if (expiredTime <= current) { this._currentTask = this._pullTargetTask(taskIndex); if (this._currentTask !== undefined) this._execTask(); return; diff --git a/src/types.ts b/src/types.ts index 73fab1fd..391d412e 100644 --- a/src/types.ts +++ b/src/types.ts @@ -319,7 +319,7 @@ export type CollectionPath = string; * @remarks * - namePrefix: Automatically generated _id has a specified prefix in the collection. * - * - debounceTime: put/insert/update operations for the same document are debounced by specified milliseconds in the collection. Default is 0. + * - debounceTime: put/insert/update operations for the same document are debounced by specified milliseconds in the collection. Default is -1 (do not debounce). * * @public */ @@ -340,7 +340,7 @@ export type CollectionOptions = { * * - enqueueCallback: A callback function called just after this put task is enqueued to TaskQueue. * - * - debounceTime: put/insert/update operations for the same document are debounced by specified milliseconds. This overwrite the same option in Collection Class. + * - debounceTime: put/insert/update operations for the same document are debounced by specified milliseconds. This overwrite the same option in Collection Class. Default is -1 (do not debounce). * * @public */ diff --git a/test/remote_base/sync_trysync.ts b/test/remote_base/sync_trysync.ts index 4ea49309..4630ac17 100644 --- a/test/remote_base/sync_trysync.ts +++ b/test/remote_base/sync_trysync.ts @@ -826,19 +826,16 @@ export const syncTrySyncBase = ( const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { connection, }); - dbA.taskQueue.debounceTime = 7000; - let skippedTask00 = false; - dbA.put({ _id: 'a', name: '0' }, { taskId: '0' }).catch(err => { - if (err instanceof Err.TaskCancelError) skippedTask00 = true; - }); const putter: Promise[] = []; const validResult: (boolean | Record)[] = []; for (let i = 1; i < 10; i++) { putter.push( - dbA.put({ _id: 'a', name: `${i}` }, { taskId: `${i}` }).catch(err => { - if (err instanceof Err.TaskCancelError) return true; - }) + dbA + .put({ _id: 'a', name: `${i}` }, { taskId: `${i}`, debounceTime: 3000 }) + .catch(err => { + if (err instanceof Err.TaskCancelError) return true; + }) ); validResult.push(true); } @@ -851,16 +848,20 @@ export const syncTrySyncBase = ( for (let i = 10; i < 20; i++) { putter.push( - dbA.put({ _id: 'a', name: `${i}` }, { taskId: `${i}` }).catch(err => { - if (err instanceof Err.TaskCancelError) return true; - }) + dbA + .put({ _id: 'a', name: `${i}` }, { taskId: `${i}`, debounceTime: 3000 }) + .catch(err => { + if (err instanceof Err.TaskCancelError) return true; + }) ); validResult.push(true); } putter.push( - dbA.put({ _id: 'a', name: '20' }, { taskId: '20' }).catch(err => { - if (err instanceof Err.TaskCancelError) return true; - }) + dbA + .put({ _id: 'a', name: '20' }, { taskId: '20', debounceTime: 3000 }) + .catch(err => { + if (err instanceof Err.TaskCancelError) return true; + }) ); validResult.push({ _id: 'a' }); const results = await Promise.all(putter); @@ -868,7 +869,6 @@ export const syncTrySyncBase = ( await sleep(10000); // Check skipped put() - expect(skippedTask00).toBeFalsy(); expect(results).toMatchObject(validResult); const json = await dbA.get('a'); expect(json!.name).toEqual('20'); @@ -881,6 +881,8 @@ export const syncTrySyncBase = ( expect(cancelCount).toBeGreaterThanOrEqual(1); expect(dbA.taskQueue.currentStatistics().sync).toBeGreaterThanOrEqual(1); + dbA.taskQueue.clear(); + await destroyDBs([dbA]); }); diff --git a/test/task_queue.test.ts b/test/task_queue.test.ts index 123305fe..3f03152a 100644 --- a/test/task_queue.test.ts +++ b/test/task_queue.test.ts @@ -210,7 +210,7 @@ describe('', () => { await gitDDB.destroy(); }); - it.only('debounces a lot of consecutive puts mixed with a delete command', async () => { + it('debounces a lot of consecutive puts mixed with a delete command', async () => { const dbName = monoId(); const gitDDB: GitDocumentDB = new GitDocumentDB({ dbName, @@ -237,7 +237,7 @@ describe('', () => { if (err instanceof Err.TaskCancelError) return false; }) ); - validResult.push(true); + validResult.push({ _id: 'a' }); // Delete putter.push(gitDDB.delete('a')); @@ -386,6 +386,9 @@ describe('', () => { } prevId = id; } + + // clear() must be called to clear setInterval + taskQueue.clear(); }); it('clear() statistics', async () => { From 8c18c08efbff3815792cc1601b5a56474d88015e Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sat, 4 Sep 2021 01:23:29 +0900 Subject: [PATCH 182/297] fix: pass tests for debounce --- src/collection.ts | 36 +++++++++---- src/crud/put.ts | 2 + src/git_documentdb.ts | 4 +- src/task_queue.ts | 72 ++++++++++++++++++-------- test/crud/delete.test.ts | 2 +- test/crud/put.test.ts | 2 +- test/remote_base/network_task_queue.ts | 2 +- test/remote_base/sync.ts | 4 +- test/remote_base/sync_trysync.ts | 2 +- test/remote_utils.ts | 4 +- test/task_queue.test.ts | 5 +- 11 files changed, 95 insertions(+), 40 deletions(-) diff --git a/src/collection.ts b/src/collection.ts index 6ce03bb3..115ffbac 100644 --- a/src/collection.ts +++ b/src/collection.ts @@ -142,13 +142,13 @@ export class Collection implements ICollection { this._parent = undefined; options ??= { namePrefix: '', - debounceTime: -1, + debounceTime: undefined, }; + options.debounceTime ??= -1; } else { this._parent = parent; } - this._options = { ...parent?.options!, ...options }; } @@ -351,7 +351,9 @@ export class Collection implements ICollection { return Promise.reject(err); } - options ??= {}; + options ??= { + debounceTime: undefined, + }; options.debounceTime ??= this._options.debounceTime; return putImpl( @@ -468,12 +470,16 @@ export class Collection implements ICollection { shortIdOrDoc === undefined || shortIdOrDoc === null ) { - options ??= {}; + options ??= { + debounceTime: undefined, + }; options.insertOrUpdate = 'insert'; options.debounceTime ??= this._options.debounceTime; } else { - jsonDocOrOptions ??= {}; + jsonDocOrOptions ??= { + debounceTime: undefined, + }; (jsonDocOrOptions as PutOptions).insertOrUpdate = 'insert'; (jsonDocOrOptions as PutOptions).debounceTime ??= this._options.debounceTime; } @@ -573,12 +579,16 @@ export class Collection implements ICollection { shortIdOrDoc === undefined || shortIdOrDoc === null ) { - options ??= {}; + options ??= { + debounceTime: undefined, + }; options.insertOrUpdate = 'update'; options.debounceTime ??= this._options.debounceTime; } else { - jsonDocOrOptions ??= {}; + jsonDocOrOptions ??= { + debounceTime: undefined, + }; (jsonDocOrOptions as PutOptions).insertOrUpdate = 'update'; (jsonDocOrOptions as PutOptions).debounceTime ??= this._options.debounceTime; } @@ -673,7 +683,9 @@ export class Collection implements ICollection { return Promise.reject(err); } - options ??= {}; + options ??= { + debounceTime: undefined, + }; options.debounceTime ??= this._options.debounceTime; return putImpl( @@ -749,7 +761,9 @@ export class Collection implements ICollection { options?: PutOptions ): Promise { // Resolve overloads - options ??= {}; + options ??= { + debounceTime: undefined, + }; options.insertOrUpdate = 'insert'; options.debounceTime ??= this._options.debounceTime; @@ -795,7 +809,9 @@ export class Collection implements ICollection { options?: PutOptions ): Promise { // Resolve overloads - options ??= {}; + options ??= { + debounceTime: undefined, + }; options.insertOrUpdate = 'update'; options.debounceTime ??= this._options.debounceTime; diff --git a/src/crud/put.ts b/src/crud/put.ts index 7e9e1a84..b47b0b6d 100644 --- a/src/crud/put.ts +++ b/src/crud/put.ts @@ -52,7 +52,9 @@ export function putImpl ( insertOrUpdate: undefined, taskId: undefined, enqueueCallback: undefined, + debounceTime: undefined, }; + options.debounceTime ??= -1; const fullDocPath = collectionPath + shortName; diff --git a/src/git_documentdb.ts b/src/git_documentdb.ts index 45a67838..ad8fdbb8 100644 --- a/src/git_documentdb.ts +++ b/src/git_documentdb.ts @@ -481,6 +481,8 @@ export class GitDocumentDB if (this.isClosing) { throw new Err.DatabaseClosingError(); } + this._taskQueue.start(); + if (this.isOpened) { this._dbOpenResult.isNew = false; return this._dbOpenResult; @@ -542,7 +544,7 @@ export class GitDocumentDB } } } finally { - this.taskQueue.clear(); + this.taskQueue.stop(); this._synchronizers = {}; diff --git a/src/task_queue.ts b/src/task_queue.ts index fab00739..ae12d7a9 100644 --- a/src/task_queue.ts +++ b/src/task_queue.ts @@ -6,6 +6,11 @@ * found in the LICENSE file in the root directory of this source tree. */ +/** + * ! Must import both clearInterval and setInterval from 'timers' + */ +import { clearInterval, setInterval } from 'timers'; + import { decodeTime, monotonicFactory } from 'ulid'; import { Logger } from 'tslog'; import AsyncLock from 'async-lock'; @@ -21,7 +26,7 @@ import { Err } from './error'; export class TaskQueue { // Monotonic counter private _ulid = monotonicFactory(); - private _lock = new AsyncLock(); + private _lock: AsyncLock | undefined = new AsyncLock(); private _logger: Logger; @@ -45,17 +50,19 @@ export class TaskQueue { private _currentTask: Task | undefined = undefined; - private _checkTimer: NodeJS.Timeout; + private _checkTimer: NodeJS.Timeout | undefined; + private _checkTimerInterval = 100; + /** * Constructor * + * @remarks + * Must call start() after new TaskQueue() + * * @public */ constructor (logger: Logger) { this._logger = logger; - this._checkTimer = setInterval(() => { - this._checkTaskQueue(); - }, 100); } /** @@ -106,8 +113,7 @@ export class TaskQueue { // eslint-disable-next-line complexity pushToTaskQueue (task: Task) { // Critical section - this._lock - // eslint-disable-next-line complexity + this._lock! // eslint-disable-next-line complexity .acquire('TaskQueue', () => { // Skip consecutive sync/push events if ( @@ -168,17 +174,40 @@ export class TaskQueue { } /** - * Clear TaskQueue + * Start TaskQueue * * @public */ - clear () { - // Clear not queued jobs + start () { + if (this._lock === undefined) { + this._lock = new AsyncLock(); + } - clearInterval(this._checkTimer); + if (this._checkTimer === undefined) { + this._checkTimer = setInterval(() => { + this._checkTaskQueue(); + }, this._checkTimerInterval); + } + } - // @ts-ignore - this._lock.queues.taskQueue = null; + /** + * Stop TaskQueue + * + * @public + */ + stop () { + // Clear not queued job + + if (this._checkTimer !== undefined) { + clearInterval(this._checkTimer); + this._checkTimer = undefined; + } + + if (this._lock !== undefined) { + // @ts-ignore + this._lock.queues.taskQueue = null; + } + this._lock = undefined; // Cancel queued tasks this._taskQueue.forEach(task => task.cancel()); @@ -246,17 +275,18 @@ export class TaskQueue { * @internal */ private _checkTaskQueue () { + if (this._lock === undefined) return; if (this._lock.isBusy()) return; // eslint-disable-next-line complexity - this._lock.acquire('TaskQueue', () => { + this._lock!.acquire('TaskQueue', () => { if (this._taskQueue.length === 0 || this._isTaskQueueWorking) return; let taskIndex = 0; while (taskIndex < this._taskQueue.length) { const targetTask = this._taskQueue[taskIndex]; - if (targetTask.debounceTime! < 0) { + if (targetTask.debounceTime === undefined || targetTask.debounceTime! < 0) { this._currentTask = this._pullTargetTask(taskIndex); if (this._currentTask !== undefined) this._execTask(); return; @@ -326,6 +356,8 @@ export class TaskQueue { // eslint-disable-next-line complexity private _execTask () { if (this._currentTask !== undefined && this._currentTask.func !== undefined) { + this._isTaskQueueWorking = true; + const label = this._currentTask.label; const shortId = this._currentTask.shortId; const shortName = this._currentTask.shortName; @@ -343,17 +375,12 @@ export class TaskQueue { CONSOLE_STYLE.bgGreen().fgBlack().tag()`End: ${label}(${fullDocPath})` ); this._statistics[label]++; - - this._isTaskQueueWorking = false; - this._currentTask = undefined; }; const beforeReject = () => { this._logger.debug( CONSOLE_STYLE.bgGreen().fgRed().tag()`End with error: ${label}(${fullDocPath})` ); this._statistics[label]++; - this._isTaskQueueWorking = false; - this._currentTask = undefined; }; const taskMetadata: TaskMetadata = { label, @@ -365,7 +392,10 @@ export class TaskQueue { syncRemoteName, }; - this._currentTask.func(beforeResolve, beforeReject, taskMetadata).finally(() => {}); + this._currentTask.func(beforeResolve, beforeReject, taskMetadata).finally(() => { + this._isTaskQueueWorking = false; + this._currentTask = undefined; + }); } } } diff --git a/test/crud/delete.test.ts b/test/crud/delete.test.ts index be1c744e..a9508299 100644 --- a/test/crud/delete.test.ts +++ b/test/crud/delete.test.ts @@ -97,7 +97,7 @@ describe('', () => { } ); } - gitDDB.taskQueue.clear(); + gitDDB.taskQueue.stop(); await sleep(3000); expect(taskCancelErrorCount).toBeGreaterThan(0); await gitDDB.destroy(); diff --git a/test/crud/put.test.ts b/test/crud/put.test.ts index b0d59ae7..49978674 100644 --- a/test/crud/put.test.ts +++ b/test/crud/put.test.ts @@ -492,7 +492,7 @@ describe(' put', () => { } ); } - gitDDB.taskQueue.clear(); + gitDDB.taskQueue.stop(); await sleep(3000); expect(taskCancelErrorCount).toBeGreaterThan(0); await gitDDB.destroy(); diff --git a/test/remote_base/network_task_queue.ts b/test/remote_base/network_task_queue.ts index fae716f9..4b3fd844 100644 --- a/test/remote_base/network_task_queue.ts +++ b/test/remote_base/network_task_queue.ts @@ -77,7 +77,7 @@ export const networkTaskQueueBase = ( sync: 1, cancel: 0, }); - dbA.taskQueue.clear(); + dbA.taskQueue.stop(); expect(dbA.taskQueue.currentStatistics()).toEqual({ put: 0, insert: 0, diff --git a/test/remote_base/sync.ts b/test/remote_base/sync.ts index b798a0b6..17b19f1a 100644 --- a/test/remote_base/sync.ts +++ b/test/remote_base/sync.ts @@ -776,13 +776,14 @@ export const syncBase = ( syncDirection: 'push', connection, }; - await dbA.sync(optionA); + await dbA.sync(optionA, true); const dbNameB = serialId(); const dbB: GitDocumentDB = new GitDocumentDB({ dbName: dbNameB, localDir, }); + // Clone dbA await dbB.open(); const syncB = await dbB.sync({ @@ -793,6 +794,7 @@ export const syncBase = ( await syncB.tryPush(); await dbA.close(); + await dbA.open(); const [sync, result] = await dbA.sync(optionA, true); expect(result).toEqual({ diff --git a/test/remote_base/sync_trysync.ts b/test/remote_base/sync_trysync.ts index 4630ac17..34da6b06 100644 --- a/test/remote_base/sync_trysync.ts +++ b/test/remote_base/sync_trysync.ts @@ -881,7 +881,7 @@ export const syncTrySyncBase = ( expect(cancelCount).toBeGreaterThanOrEqual(1); expect(dbA.taskQueue.currentStatistics().sync).toBeGreaterThanOrEqual(1); - dbA.taskQueue.clear(); + dbA.taskQueue.stop(); await destroyDBs([dbA]); }); diff --git a/test/remote_utils.ts b/test/remote_utils.ts index a29b8b44..454d8908 100644 --- a/test/remote_utils.ts +++ b/test/remote_utils.ts @@ -392,7 +392,9 @@ export const destroyDBs = async (DBs: GitDocumentDB[]) => { /* throws FileRemoveTimeoutError */ }) ) - ).catch(() => {}); + ).catch(err => { + console.log(err); + }); await clock.tickAsync(FILE_REMOVE_TIMEOUT); clock.restore(); }; diff --git a/test/task_queue.test.ts b/test/task_queue.test.ts index 3f03152a..a61e3de3 100644 --- a/test/task_queue.test.ts +++ b/test/task_queue.test.ts @@ -375,6 +375,7 @@ describe('', () => { it('returns newTaskId', () => { const taskQueue = new TaskQueue(logger); + taskQueue.start(); // e.g.) 01BX5ZZKBKACTAV9WEVGEMMVRZ let prevId = ''; for (let i = 0; i < 30; i++) { @@ -388,7 +389,7 @@ describe('', () => { } // clear() must be called to clear setInterval - taskQueue.clear(); + taskQueue.stop(); }); it('clear() statistics', async () => { @@ -412,7 +413,7 @@ describe('', () => { sync: 0, cancel: 0, }); - gitDDB.taskQueue.clear(); + gitDDB.taskQueue.stop(); expect(gitDDB.taskQueue.currentStatistics()).toEqual({ put: 0, insert: 0, From e2d31d43e910b837af00cb257b1ed62d77ea8761 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sat, 4 Sep 2021 01:26:02 +0900 Subject: [PATCH 183/297] build: bump to v0.4.5-beta.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 50229aca..aa27324f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "git-documentdb", - "version": "0.4.5-beta.0", + "version": "0.4.5-beta.1", "description": "Offline-first database that syncs with Git", "main": "dist/main.js", "types": "dist/main.d.ts", From ce0b1ba1127f2b0f43a3320e6ea3171428f054e9 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sun, 5 Sep 2021 00:06:34 +0900 Subject: [PATCH 184/297] fix: do not debounce insert command --- src/task_queue.ts | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/task_queue.ts b/src/task_queue.ts index ae12d7a9..4179a4e8 100644 --- a/src/task_queue.ts +++ b/src/task_queue.ts @@ -292,11 +292,7 @@ export class TaskQueue { return; } - if ( - targetTask.label !== 'put' && - targetTask.label !== 'update' && - targetTask.label !== 'insert' - ) { + if (targetTask.label !== 'put' && targetTask.label !== 'update') { this._currentTask = this._pullTargetTask(taskIndex); if (this._currentTask !== undefined) this._execTask(); return; @@ -305,8 +301,9 @@ export class TaskQueue { const expiredTime = decodeTime(targetTask.enqueueTime!) + targetTask.debounceTime!; const current = Date.now(); - let nextPutExist = false; + let nextPutUpdateExist = false; let nextDeleteExist = false; + let nextInsertExist = false; for (let i = taskIndex + 1; i < this._taskQueue.length; i++) { const tmpTask = this._taskQueue[i]; if (decodeTime(tmpTask.enqueueTime!) > expiredTime) break; @@ -323,12 +320,16 @@ export class TaskQueue { nextDeleteExist = true; break; } - nextPutExist = true; + if (tmpTask.label === 'insert') { + nextInsertExist = true; + break; + } + nextPutUpdateExist = true; break; } } - if (nextPutExist) { + if (nextPutUpdateExist) { const cancelTask = this._pullTargetTask(taskIndex); cancelTask?.cancel(); continue; @@ -338,6 +339,11 @@ export class TaskQueue { if (this._currentTask !== undefined) this._execTask(); return; } + else if (nextInsertExist) { + this._currentTask = this._pullTargetTask(taskIndex); + if (this._currentTask !== undefined) this._execTask(); + return; + } if (expiredTime <= current) { this._currentTask = this._pullTargetTask(taskIndex); From fb16641b3fded495d5e9a0a2bbdbfbcdbbaf1e47 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sun, 5 Sep 2021 00:06:50 +0900 Subject: [PATCH 185/297] build: bump to v0.4.5-beta.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index aa27324f..627bebc2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "git-documentdb", - "version": "0.4.5-beta.1", + "version": "0.4.5-beta.2", "description": "Offline-first database that syncs with Git", "main": "dist/main.js", "types": "dist/main.d.ts", From fc1780f6b301566aaeabefdaa06b49d11c5c89ba Mon Sep 17 00:00:00 2001 From: sosuisen Date: Mon, 6 Sep 2021 16:16:35 +0900 Subject: [PATCH 186/297] test: add tests for debounce --- test/task_queue.test.ts | 506 +++++++++++++++++++++++++--------------- 1 file changed, 313 insertions(+), 193 deletions(-) diff --git a/test/task_queue.test.ts b/test/task_queue.test.ts index a61e3de3..4227b4b3 100644 --- a/test/task_queue.test.ts +++ b/test/task_queue.test.ts @@ -47,227 +47,347 @@ after(() => { }); describe('', () => { - it('debounces consecutive puts to the same _id', async () => { - const dbName = monoId(); - const gitDDB: GitDocumentDB = new GitDocumentDB({ - dbName, - localDir, - debounceTime: 3000, - logLevel: 'trace', - }); - await gitDDB.open(); - let skippedTask00 = false; - gitDDB.put({ _id: 'a', name: '0' }, { taskId: '0' }).catch(err => { - if (err instanceof Err.TaskCancelError) skippedTask00 = true; - }); - let skippedTask01 = false; - gitDDB.put({ _id: 'a', name: '1' }, { taskId: '1' }).catch(err => { - if (err instanceof Err.TaskCancelError) skippedTask01 = true; - }); - let skippedTask02 = false; - gitDDB.put({ _id: 'a', name: '2' }, { taskId: '2' }).catch(err => { - if (err instanceof Err.TaskCancelError) skippedTask02 = true; - }); - let skippedTask03 = false; - gitDDB.put({ _id: 'a', name: '3' }, { taskId: '3' }).catch(err => { - if (err instanceof Err.TaskCancelError) skippedTask03 = true; - }); - await sleep(4000); - expect(skippedTask00).toBeTruthy(); - expect(skippedTask01).toBeTruthy(); - expect(skippedTask02).toBeTruthy(); - expect(skippedTask03).toBeFalsy(); - - const json = await gitDDB.get('a'); - expect(json!.name).toEqual('3'); - - await gitDDB.destroy(); - }); - - it('debounces a lot of consecutive puts to the same _id', async () => { - const dbName = monoId(); - const gitDDB: GitDocumentDB = new GitDocumentDB({ - dbName, - localDir, - debounceTime: 3000, - logLevel: 'trace', - }); - await gitDDB.open(); - let skippedTask00 = false; - gitDDB.put({ _id: 'a', name: '0' }, { taskId: '0' }).catch(err => { - if (err instanceof Err.TaskCancelError) skippedTask00 = true; - }); - await sleep(4000); - - const putter: Promise[] = []; - const validResult: (boolean | Record)[] = []; - for (let i = 1; i < 25; i++) { + describe('debounce', () => { + it('debounces consecutive puts to the same _id', async () => { + const dbName = monoId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + debounceTime: 3000, + logLevel: 'trace', + }); + await gitDDB.open(); + let skippedTask00 = false; + gitDDB.put({ _id: 'a', name: '0' }, { taskId: '0' }).catch(err => { + if (err instanceof Err.TaskCancelError) skippedTask00 = true; + }); + let skippedTask01 = false; + gitDDB.put({ _id: 'a', name: '1' }, { taskId: '1' }).catch(err => { + if (err instanceof Err.TaskCancelError) skippedTask01 = true; + }); + let skippedTask02 = false; + gitDDB.put({ _id: 'a', name: '2' }, { taskId: '2' }).catch(err => { + if (err instanceof Err.TaskCancelError) skippedTask02 = true; + }); + let skippedTask03 = false; + gitDDB.put({ _id: 'a', name: '3' }, { taskId: '3' }).catch(err => { + if (err instanceof Err.TaskCancelError) skippedTask03 = true; + }); + await sleep(4000); + expect(skippedTask00).toBeTruthy(); + expect(skippedTask01).toBeTruthy(); + expect(skippedTask02).toBeTruthy(); + expect(skippedTask03).toBeFalsy(); + + const json = await gitDDB.get('a'); + expect(json!.name).toEqual('3'); + + await gitDDB.destroy(); + }); + + it('debounces a lot of consecutive puts to the same _id', async () => { + const dbName = monoId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + debounceTime: 3000, + logLevel: 'trace', + }); + await gitDDB.open(); + let skippedTask00 = false; + gitDDB.put({ _id: 'a', name: '0' }, { taskId: '0' }).catch(err => { + if (err instanceof Err.TaskCancelError) skippedTask00 = true; + }); + await sleep(4000); + + const putter: Promise[] = []; + const validResult: (boolean | Record)[] = []; + for (let i = 1; i < 25; i++) { + putter.push( + gitDDB.put({ _id: 'a', name: `${i}` }, { taskId: `${i}` }).catch(err => { + if (err instanceof Err.TaskCancelError) return true; + }) + ); + validResult.push(true); + } putter.push( - gitDDB.put({ _id: 'a', name: `${i}` }, { taskId: `${i}` }).catch(err => { + gitDDB.put({ _id: 'a', name: '25' }, { taskId: '25' }).catch(err => { if (err instanceof Err.TaskCancelError) return true; }) ); - validResult.push(true); - } - putter.push( - gitDDB.put({ _id: 'a', name: '25' }, { taskId: '25' }).catch(err => { - if (err instanceof Err.TaskCancelError) return true; - }) - ); - validResult.push({ _id: 'a' }); - - const results = await Promise.all(putter); - - expect(skippedTask00).toBeFalsy(); - - expect(results).toMatchObject(validResult); - - const json = await gitDDB.get('a'); - expect(json!.name).toEqual('25'); - - await gitDDB.destroy(); - }); - - it('debounces a lot of consecutive puts to the mixed _ids', async () => { - const dbName = monoId(); - const gitDDB: GitDocumentDB = new GitDocumentDB({ - dbName, - localDir, - debounceTime: 3000, - logLevel: 'trace', - }); - await gitDDB.open(); - let skippedTaskA00 = false; - gitDDB.put({ _id: 'a', name: '0' }, { taskId: 'a0' }).catch(err => { - if (err instanceof Err.TaskCancelError) skippedTaskA00 = true; - }); - let skippedTaskB00 = false; - gitDDB.put({ _id: 'b', name: '0' }, { taskId: 'b0' }).catch(err => { - if (err instanceof Err.TaskCancelError) skippedTaskB00 = true; - }); - let skippedTaskC00 = false; - gitDDB.put({ _id: 'c', name: '0' }, { taskId: 'c0' }).catch(err => { - if (err instanceof Err.TaskCancelError) skippedTaskC00 = true; - }); - await sleep(4000); - - const putter: Promise[] = []; - const validResult: (boolean | Record)[] = []; - for (let i = 1; i < 50; i++) { + validResult.push({ _id: 'a' }); + + const results = await Promise.all(putter); + + expect(skippedTask00).toBeFalsy(); + + expect(results).toMatchObject(validResult); + + const json = await gitDDB.get('a'); + expect(json!.name).toEqual('25'); + + await gitDDB.destroy(); + }); + + it('debounces a lot of consecutive puts to the mixed _ids', async () => { + const dbName = monoId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + debounceTime: 3000, + logLevel: 'trace', + }); + await gitDDB.open(); + let skippedTaskA00 = false; + gitDDB.put({ _id: 'a', name: '0' }, { taskId: 'a0' }).catch(err => { + if (err instanceof Err.TaskCancelError) skippedTaskA00 = true; + }); + let skippedTaskB00 = false; + gitDDB.put({ _id: 'b', name: '0' }, { taskId: 'b0' }).catch(err => { + if (err instanceof Err.TaskCancelError) skippedTaskB00 = true; + }); + let skippedTaskC00 = false; + gitDDB.put({ _id: 'c', name: '0' }, { taskId: 'c0' }).catch(err => { + if (err instanceof Err.TaskCancelError) skippedTaskC00 = true; + }); + await sleep(4000); + + const putter: Promise[] = []; + const validResult: (boolean | Record)[] = []; + for (let i = 1; i < 50; i++) { + putter.push( + gitDDB.put({ _id: 'a', name: `${i}` }, { taskId: `a${i}` }).catch(err => { + if (err instanceof Err.TaskCancelError) return true; + }) + ); + validResult.push(true); + putter.push( + gitDDB.put({ _id: 'b', name: `${i}` }, { taskId: `b${i}` }).catch(err => { + if (err instanceof Err.TaskCancelError) return true; + }) + ); + validResult.push(true); + putter.push( + gitDDB.put({ _id: 'c', name: `${i}` }, { taskId: `c${i}` }).catch(err => { + if (err instanceof Err.TaskCancelError) return true; + }) + ); + validResult.push(true); + } putter.push( - gitDDB.put({ _id: 'a', name: `${i}` }, { taskId: `a${i}` }).catch(err => { + gitDDB.put({ _id: 'a', name: '50' }, { taskId: 'a50' }).catch(err => { if (err instanceof Err.TaskCancelError) return true; }) ); - validResult.push(true); + validResult.push({ _id: 'a' }); putter.push( - gitDDB.put({ _id: 'b', name: `${i}` }, { taskId: `b${i}` }).catch(err => { + gitDDB.put({ _id: 'b', name: '50' }, { taskId: 'b50' }).catch(err => { if (err instanceof Err.TaskCancelError) return true; }) ); - validResult.push(true); + validResult.push({ _id: 'b' }); putter.push( - gitDDB.put({ _id: 'c', name: `${i}` }, { taskId: `c${i}` }).catch(err => { + gitDDB.put({ _id: 'c', name: '50' }, { taskId: 'c50' }).catch(err => { if (err instanceof Err.TaskCancelError) return true; }) ); - validResult.push(true); - } - putter.push( - gitDDB.put({ _id: 'a', name: '50' }, { taskId: 'a50' }).catch(err => { - if (err instanceof Err.TaskCancelError) return true; - }) - ); - validResult.push({ _id: 'a' }); - putter.push( - gitDDB.put({ _id: 'b', name: '50' }, { taskId: 'b50' }).catch(err => { - if (err instanceof Err.TaskCancelError) return true; - }) - ); - validResult.push({ _id: 'b' }); - putter.push( - gitDDB.put({ _id: 'c', name: '50' }, { taskId: 'c50' }).catch(err => { - if (err instanceof Err.TaskCancelError) return true; - }) - ); - validResult.push({ _id: 'c' }); - - const results = await Promise.all(putter); - - expect(skippedTaskA00).toBeFalsy(); - expect(skippedTaskB00).toBeFalsy(); - expect(skippedTaskC00).toBeFalsy(); - - expect(results).toMatchObject(validResult); - - const jsonA = await gitDDB.get('a'); - expect(jsonA!.name).toEqual('50'); - const jsonB = await gitDDB.get('b'); - expect(jsonB!.name).toEqual('50'); - const jsonC = await gitDDB.get('c'); - expect(jsonC!.name).toEqual('50'); - - await gitDDB.destroy(); - }); - - it('debounces a lot of consecutive puts mixed with a delete command', async () => { - const dbName = monoId(); - const gitDDB: GitDocumentDB = new GitDocumentDB({ - dbName, - localDir, - debounceTime: 3000, - logLevel: 'trace', - }); - await gitDDB.open(); + validResult.push({ _id: 'c' }); + + const results = await Promise.all(putter); + + expect(skippedTaskA00).toBeFalsy(); + expect(skippedTaskB00).toBeFalsy(); + expect(skippedTaskC00).toBeFalsy(); + + expect(results).toMatchObject(validResult); + + const jsonA = await gitDDB.get('a'); + expect(jsonA!.name).toEqual('50'); + const jsonB = await gitDDB.get('b'); + expect(jsonB!.name).toEqual('50'); + const jsonC = await gitDDB.get('c'); + expect(jsonC!.name).toEqual('50'); + + await gitDDB.destroy(); + }); + + it('debounces a lot of consecutive puts mixed with a delete command', async () => { + const dbName = monoId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + debounceTime: 3000, + logLevel: 'trace', + }); + await gitDDB.open(); + + const putter: Promise[] = []; + const validResult: (boolean | Record)[] = []; + for (let i = 0; i < 9; i++) { + putter.push( + gitDDB.put({ _id: 'a', name: `${i}` }, { taskId: `${i}` }).catch(err => { + if (err instanceof Err.TaskCancelError) return true; + }) + ); + validResult.push(true); + } - const putter: Promise[] = []; - const validResult: (boolean | Record)[] = []; - for (let i = 0; i < 9; i++) { + // put task just before delete task will be executed. putter.push( - gitDDB.put({ _id: 'a', name: `${i}` }, { taskId: `${i}` }).catch(err => { - if (err instanceof Err.TaskCancelError) return true; + gitDDB.put({ _id: 'a', name: `9` }, { taskId: `9` }).catch(err => { + if (err instanceof Err.TaskCancelError) return false; }) ); - validResult.push(true); - } - - // put task just before delete task will be executed. - putter.push( - gitDDB.put({ _id: 'a', name: `9` }, { taskId: `9` }).catch(err => { - if (err instanceof Err.TaskCancelError) return false; - }) - ); - validResult.push({ _id: 'a' }); - - // Delete - putter.push(gitDDB.delete('a')); - validResult.push({ - _id: 'a', - }); - - for (let i = 10; i < 20; i++) { + validResult.push({ _id: 'a' }); + + // Delete + putter.push(gitDDB.delete('a')); + validResult.push({ + _id: 'a', + }); + + for (let i = 10; i < 20; i++) { + putter.push( + gitDDB.put({ _id: 'a', name: `${i}` }, { taskId: `${i}` }).catch(err => { + if (err instanceof Err.TaskCancelError) return true; + }) + ); + validResult.push(true); + } putter.push( - gitDDB.put({ _id: 'a', name: `${i}` }, { taskId: `${i}` }).catch(err => { + gitDDB.put({ _id: 'a', name: '20' }, { taskId: '20' }).catch(err => { if (err instanceof Err.TaskCancelError) return true; }) ); - validResult.push(true); - } - putter.push( - gitDDB.put({ _id: 'a', name: '20' }, { taskId: '20' }).catch(err => { - if (err instanceof Err.TaskCancelError) return true; - }) - ); - validResult.push({ _id: 'a' }); + validResult.push({ _id: 'a' }); - const results = await Promise.all(putter); + const results = await Promise.all(putter); - expect(results).toMatchObject(validResult); + expect(results).toMatchObject(validResult); - const json = await gitDDB.get('a'); - expect(json!.name).toEqual('20'); + const json = await gitDDB.get('a'); + expect(json!.name).toEqual('20'); - await gitDDB.destroy(); + await gitDDB.destroy(); + }); + + it('debounces a lot of consecutive puts mixed with an insert command', async () => { + const dbName = monoId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + debounceTime: 3000, + logLevel: 'trace', + }); + await gitDDB.open(); + + const putter: Promise[] = []; + const validResult: (boolean | undefined | Record)[] = []; + for (let i = 0; i < 9; i++) { + putter.push( + gitDDB.put({ _id: 'a', name: `${i}` }, { taskId: `${i}` }).catch(err => { + if (err instanceof Err.TaskCancelError) return true; + }) + ); + validResult.push(true); + } + + // put task just before insert task will be executed. + putter.push( + gitDDB.put({ _id: 'a', name: `9` }, { taskId: `9` }).catch(err => { + if (err instanceof Err.TaskCancelError) return false; + }) + ); + validResult.push({ _id: 'a' }); + + // Insert throws error + putter.push(gitDDB.insert({ _id: 'a', name: '10' }).catch(() => undefined)); + validResult.push(undefined); + + const results = await Promise.all(putter); + + expect(results).toMatchObject(validResult); + + const json = await gitDDB.get('a'); + expect(json!.name).toEqual('9'); + + await gitDDB.destroy(); + }); + + it('Set different debounceTime in each collection', async () => { + const dbName = monoId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + debounceTime: 3000, + logLevel: 'trace', + }); + await gitDDB.open(); + const colA = gitDDB.collection('a', { debounceTime: 7000 }); + const colB = gitDDB.collection('b', { debounceTime: 5000 }); + const colC = gitDDB.collection('c', { debounceTime: 1000 }); + + const result: string[] = []; + colA + .put({ _id: 'a1' }) + .then(() => result.push('a1')) + .catch(() => {}); + colB + .put({ _id: 'b1' }) + .then(() => result.push('b1')) + .catch(() => {}); + colC + .put({ _id: 'c1' }) + .then(() => result.push('c1')) + .catch(() => {}); + colC + .put({ _id: 'c1' }) + .then(() => result.push('c2')) + .catch(() => {}); + await sleep(10000); + + expect(result).toEqual(['c2', 'b1', 'a1']); + await gitDDB.destroy(); + }); + + it('Collection debounceTime will be overwritten by method debounceTime', async () => { + const dbName = monoId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + debounceTime: 3000, + logLevel: 'trace', + }); + await gitDDB.open(); + let skippedTask00 = false; + gitDDB.put({ _id: 'a', name: '0' }, { taskId: '0' }).catch(err => { + if (err instanceof Err.TaskCancelError) skippedTask00 = true; + }); + let skippedTask01 = false; + gitDDB.put({ _id: 'a', name: '1' }, { taskId: '1' }).catch(err => { + if (err instanceof Err.TaskCancelError) skippedTask01 = true; + }); + let skippedTask02 = false; + gitDDB.put({ _id: 'a', name: '2' }, { taskId: '2' }).catch(err => { + if (err instanceof Err.TaskCancelError) skippedTask02 = true; + }); + + let skippedTask03 = false; + gitDDB.put({ _id: 'a', name: '3' }, { taskId: '3', debounceTime: 0 }).catch(err => { + if (err instanceof Err.TaskCancelError) skippedTask03 = true; + }); + await sleep(1000); + + expect(skippedTask00).toBeTruthy(); + expect(skippedTask01).toBeTruthy(); + expect(skippedTask02).toBeTruthy(); + expect(skippedTask03).toBeFalsy(); + + const json = await gitDDB.get('a'); + expect(json!.name).toEqual('3'); + + await gitDDB.destroy(); + }); }); it('increments statistics: put', async () => { From baf6decac5d929f58d6c574d1438d4154f974538 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Mon, 6 Sep 2021 16:20:17 +0900 Subject: [PATCH 187/297] build: bump to v0.4.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 627bebc2..b7ff176a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "git-documentdb", - "version": "0.4.5-beta.2", + "version": "0.4.5", "description": "Offline-first database that syncs with Git", "main": "dist/main.js", "types": "dist/main.d.ts", From e24a319ad5c125447db9a977b9201502234e9e3c Mon Sep 17 00:00:00 2001 From: sosuisen Date: Mon, 6 Sep 2021 17:01:30 +0900 Subject: [PATCH 188/297] docs: update docs-api for v0.4.5 --- docs-api/git-documentdb.collectionoptions.md | 8 +++++++ docs-api/git-documentdb.putoptions.md | 3 +++ docs-api/git-documentdb.taskmetadata.md | 1 + .../git-documentdb.taskqueue._constructor_.md | 4 ++++ docs-api/git-documentdb.taskqueue.clear.md | 21 ------------------- docs-api/git-documentdb.taskqueue.md | 3 ++- docs-api/git-documentdb.taskqueue.start.md | 21 +++++++++++++++++++ docs-api/git-documentdb.taskqueue.stop.md | 21 +++++++++++++++++++ etc/git-documentdb.api.md | 6 +++++- 9 files changed, 65 insertions(+), 23 deletions(-) delete mode 100644 docs-api/git-documentdb.taskqueue.clear.md create mode 100644 docs-api/git-documentdb.taskqueue.start.md create mode 100644 docs-api/git-documentdb.taskqueue.stop.md diff --git a/docs-api/git-documentdb.collectionoptions.md b/docs-api/git-documentdb.collectionoptions.md index c9e27222..de7fd47b 100644 --- a/docs-api/git-documentdb.collectionoptions.md +++ b/docs-api/git-documentdb.collectionoptions.md @@ -15,5 +15,13 @@ Options for Collection constructor ```typescript export declare type CollectionOptions = { namePrefix?: string; + debounceTime?: number; }; ``` + +## Remarks + +- namePrefix: Automatically generated \_id has a specified prefix in the collection. + +- debounceTime: put/insert/update operations for the same document are debounced by specified milliseconds in the collection. Default is -1 (do not debounce). + diff --git a/docs-api/git-documentdb.putoptions.md b/docs-api/git-documentdb.putoptions.md index 0d39c64d..a28617cb 100644 --- a/docs-api/git-documentdb.putoptions.md +++ b/docs-api/git-documentdb.putoptions.md @@ -18,6 +18,7 @@ export declare type PutOptions = { insertOrUpdate?: 'insert' | 'update'; taskId?: string; enqueueCallback?: (taskMetadata: TaskMetadata) => void; + debounceTime?: number; }; ``` References: @@ -34,3 +35,5 @@ export declare type PutOptions = { - enqueueCallback: A callback function called just after this put task is enqueued to TaskQueue. +- debounceTime: put/insert/update operations for the same document are debounced by specified milliseconds. This overwrite the same option in Collection Class. Default is -1 (do not debounce). + diff --git a/docs-api/git-documentdb.taskmetadata.md b/docs-api/git-documentdb.taskmetadata.md index 39e46e96..fc36f197 100644 --- a/docs-api/git-documentdb.taskmetadata.md +++ b/docs-api/git-documentdb.taskmetadata.md @@ -21,6 +21,7 @@ export declare type TaskMetadata = { collectionPath?: string; enqueueTime?: string; syncRemoteName?: string; + debounceTime?: number; }; ``` References: diff --git a/docs-api/git-documentdb.taskqueue._constructor_.md b/docs-api/git-documentdb.taskqueue._constructor_.md index 7a9d12c3..936e9ee0 100644 --- a/docs-api/git-documentdb.taskqueue._constructor_.md +++ b/docs-api/git-documentdb.taskqueue._constructor_.md @@ -22,3 +22,7 @@ constructor(logger: Logger); | --- | --- | --- | | logger | Logger | | +## Remarks + +Must call start() after new TaskQueue() + diff --git a/docs-api/git-documentdb.taskqueue.clear.md b/docs-api/git-documentdb.taskqueue.clear.md deleted file mode 100644 index f8874d62..00000000 --- a/docs-api/git-documentdb.taskqueue.clear.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -sidebar_label: clear() -title: TaskQueue.clear() method -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [TaskQueue](./git-documentdb.taskqueue.md) > [clear](./git-documentdb.taskqueue.clear.md) - -## TaskQueue.clear() method - -Clear TaskQueue - -Signature: - -```typescript -clear(): void; -``` -Returns: - -void - diff --git a/docs-api/git-documentdb.taskqueue.md b/docs-api/git-documentdb.taskqueue.md index 288e988e..30cc8597 100644 --- a/docs-api/git-documentdb.taskqueue.md +++ b/docs-api/git-documentdb.taskqueue.md @@ -26,9 +26,10 @@ export declare class TaskQueue | Method | Modifiers | Description | | --- | --- | --- | -| [clear()](./git-documentdb.taskqueue.clear.md) | | Clear TaskQueue | | [currentStatistics()](./git-documentdb.taskqueue.currentstatistics.md) | | Get current statistics | | [currentTaskId()](./git-documentdb.taskqueue.currenttaskid.md) | | Get current task ID | | [getEnqueueTime()](./git-documentdb.taskqueue.getenqueuetime.md) | | Get enqueue time | | [length()](./git-documentdb.taskqueue.length.md) | | Get length of TaskQueue | +| [start()](./git-documentdb.taskqueue.start.md) | | Start TaskQueue | +| [stop()](./git-documentdb.taskqueue.stop.md) | | Stop TaskQueue | diff --git a/docs-api/git-documentdb.taskqueue.start.md b/docs-api/git-documentdb.taskqueue.start.md new file mode 100644 index 00000000..7b37bc97 --- /dev/null +++ b/docs-api/git-documentdb.taskqueue.start.md @@ -0,0 +1,21 @@ +--- +sidebar_label: start() +title: TaskQueue.start() method +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [TaskQueue](./git-documentdb.taskqueue.md) > [start](./git-documentdb.taskqueue.start.md) + +## TaskQueue.start() method + +Start TaskQueue + +Signature: + +```typescript +start(): void; +``` +Returns: + +void + diff --git a/docs-api/git-documentdb.taskqueue.stop.md b/docs-api/git-documentdb.taskqueue.stop.md new file mode 100644 index 00000000..c120cfae --- /dev/null +++ b/docs-api/git-documentdb.taskqueue.stop.md @@ -0,0 +1,21 @@ +--- +sidebar_label: stop() +title: TaskQueue.stop() method +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [TaskQueue](./git-documentdb.taskqueue.md) > [stop](./git-documentdb.taskqueue.stop.md) + +## TaskQueue.stop() method + +Stop TaskQueue + +Signature: + +```typescript +stop(): void; +``` +Returns: + +void + diff --git a/etc/git-documentdb.api.md b/etc/git-documentdb.api.md index 0e9dc429..b8372e39 100644 --- a/etc/git-documentdb.api.md +++ b/etc/git-documentdb.api.md @@ -107,6 +107,7 @@ export interface CollectionInterface { // @public export type CollectionOptions = { namePrefix?: string; + debounceTime?: number; }; // @public @@ -821,6 +822,7 @@ export type PutOptions = { insertOrUpdate?: 'insert' | 'update'; taskId?: string; enqueueCallback?: (taskMetadata: TaskMetadata) => void; + debounceTime?: number; }; // @public @@ -1283,12 +1285,12 @@ export type TaskMetadata = { collectionPath?: string; enqueueTime?: string; syncRemoteName?: string; + debounceTime?: number; }; // @public export class TaskQueue { constructor(logger: Logger); - clear(): void; currentStatistics(): TaskStatistics; currentTaskId(): string | undefined; getEnqueueTime(): string; @@ -1299,6 +1301,8 @@ export class TaskQueue { pushToTaskQueue(task: Task): void; // @internal setLogger(logger: Logger): void; + start(): void; + stop(): void; // @internal (undocumented) waitCompletion(timeoutMsec: number): Promise; } From 434a9918065220a48cf4a6dedc08bd460405e949 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Mon, 6 Sep 2021 17:19:40 +0900 Subject: [PATCH 189/297] fix: add how to run plugin test --- examples/README.md | 4 ++ examples/package-lock.json | 111 ++++++++++++++++++++++++++++++++++++- 2 files changed, 114 insertions(+), 1 deletion(-) diff --git a/examples/README.md b/examples/README.md index 5932c074..b779a80d 100644 --- a/examples/README.md +++ b/examples/README.md @@ -21,4 +21,8 @@ $ npm run collection Start an example for Synchronization. ``` $ npm run sync +``` +Start an example for Plugin. +``` +$ npm run plugin ``` \ No newline at end of file diff --git a/examples/package-lock.json b/examples/package-lock.json index af3a3144..688951ec 100644 --- a/examples/package-lock.json +++ b/examples/package-lock.json @@ -1327,6 +1327,33 @@ "diff-match-patch": "^1.0.0" } }, + "@sosuisen/nodegit": { + "version": "0.28.0-alpha.11", + "resolved": "https://registry.npmjs.org/@sosuisen/nodegit/-/nodegit-0.28.0-alpha.11.tgz", + "integrity": "sha512-mpztf9ncWxU7/agKQ6E7GvlBIa6H7m3YXuMjlPWVegHusqkbgPi4J01d2inCPhLz0CoC0F/L3LKJuDCAKDXJJg==", + "requires": { + "fs-extra": "^7.0.0", + "got": "^10.7.0", + "json5": "^2.1.0", + "lodash": "^4.17.14", + "nan": "^2.14.1", + "node-pre-gyp": "^0.13.0", + "ramda": "^0.25.0", + "tar-fs": "^1.16.3" + }, + "dependencies": { + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + } + } + }, "@szmarczak/http-timer": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", @@ -2585,6 +2612,11 @@ "ansi-colors": "^4.1.1" } }, + "env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==" + }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -5098,7 +5130,6 @@ "osenv": "0", "request": "^2.87.0", "rimraf": "2", - "semver": "~5.3.0", "tar": "^4.4.8", "which": "1" }, @@ -5110,6 +5141,14 @@ "requires": { "glob": "^7.1.3" } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "requires": { + "lru-cache": "^6.0.0" + } } } }, @@ -5130,6 +5169,44 @@ "tar": "^4" }, "dependencies": { + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, + "fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "requires": { + "minipass": "^2.6.0" + } + }, + "minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "requires": { + "minipass": "^2.9.0" + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "requires": { + "minimist": "^1.2.5" + } + }, "nopt": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", @@ -5146,6 +5223,25 @@ "requires": { "glob": "^7.1.3" } + }, + "tar": { + "version": "4.4.15", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.15.tgz", + "integrity": "sha512-ItbufpujXkry7bHH9NpQyTXPbJ72iTlXgkBAYsAjDXk3Ds8t/3NfO5P4xZGy7u+sYuQUbimgzswX4uQIEeNVOA==", + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + } + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" } } }, @@ -6902,6 +6998,19 @@ "tar-stream": "^1.1.2" }, "dependencies": { + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "requires": { + "minimist": "^1.2.5" + } + }, "pump": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz", From ee37eafce481a782f196086da6af8cc84f691105 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 8 Sep 2021 14:07:09 +0900 Subject: [PATCH 190/297] build: bump to v0.4.6 --- .npmignore | 3 +++ package.json | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.npmignore b/.npmignore index e16ec5f4..21828505 100644 --- a/.npmignore +++ b/.npmignore @@ -40,3 +40,6 @@ dist/test/ # api-extractor temp/ etc/ + +# script +remove_remote_repositories.mjs diff --git a/package.json b/package.json index b7ff176a..82cb081e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "git-documentdb", - "version": "0.4.5", + "version": "0.4.6", "description": "Offline-first database that syncs with Git", "main": "dist/main.js", "types": "dist/main.d.ts", From 184479d5e4d2ee564bf217e3b913b8f7cd79a830 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Mon, 11 Oct 2021 19:29:02 +0900 Subject: [PATCH 191/297] fix: add global FILE_EXT --- src/const.ts | 15 +++++++++++++++ src/git_documentdb.ts | 4 ++++ src/types.ts | 6 ++++++ 3 files changed, 25 insertions(+) diff --git a/src/const.ts b/src/const.ts index dcbd6266..e7303e03 100644 --- a/src/const.ts +++ b/src/const.ts @@ -63,6 +63,21 @@ export const GIT_DOCUMENTDB_METADATA_DIR = '.gitddb'; * @public */ export const JSON_EXT = '.json'; +/** + * @public + */ +export const FRONT_MATTER_EXT = '.md'; +/** + * !ALERT: It is not const for simplicity. + * + * @internal + */ +// eslint-disable-next-line import/no-mutable-exports, @typescript-eslint/naming-convention, prefer-const +export let FILE_EXT = '.json'; +// eslint-disable-next-line @typescript-eslint/naming-convention +export const setFileExt = (ext: string) => { + FILE_EXT = ext; +}; /** * @public */ diff --git a/src/git_documentdb.ts b/src/git_documentdb.ts index ad8fdbb8..18156de1 100644 --- a/src/git_documentdb.ts +++ b/src/git_documentdb.ts @@ -57,9 +57,11 @@ import { FILE_CREATE_TIMEOUT, FILE_REMOVE_TIMEOUT, FIRST_COMMIT_MESSAGE, + FRONT_MATTER_EXT, GIT_DOCUMENTDB_INFO_ID, JSON_EXT, SET_DATABASE_ID_MESSAGE, + setFileExt, } from './const'; import { normalizeCommit, sleep, toSortedJSONString } from './utils'; import { SyncEventInterface, SyncInterface } from './types_sync'; @@ -322,6 +324,8 @@ export class GitDocumentDB }, }; + setFileExt(options.serializeFormat === 'front-matter' ? FRONT_MATTER_EXT : JSON_EXT); + // Get full-path this._workingDir = path.resolve(this._localDir, this._dbName); diff --git a/src/types.ts b/src/types.ts index 391d412e..f0c47a91 100644 --- a/src/types.ts +++ b/src/types.ts @@ -52,6 +52,7 @@ export type DatabaseOptions = { dbName: string; logLevel?: TLogLevelName; schema?: Schema; + serializeFormat?: SerializeFormat; }; /** @@ -289,6 +290,11 @@ export type FatBinaryDoc = BinaryDocMetadata & { */ export type FatDoc = FatJsonDoc | FatTextDoc | FatBinaryDoc; +/** + * Format for serialization + */ +export type SerializeFormat = 'json' | 'front-matter'; + /** * CollectionPath * From bf0fe5bca96a006cad3e0f36a0795b54beacbd72 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Mon, 11 Oct 2021 22:12:30 +0900 Subject: [PATCH 192/297] fix: use JSON_EXTENSION instead of JSON_EXT to handle front matter + markdown file --- src/collection.ts | 86 +++---- src/const.ts | 8 +- src/crud/blob.ts | 4 +- src/crud/find.ts | 9 +- src/crud/get.ts | 6 +- src/crud/history.ts | 6 +- src/error.ts | 4 +- src/git_documentdb.ts | 68 ++--- src/remote/3way_merge.ts | 4 +- src/remote/combine.ts | 8 +- src/remote/worker_utils.ts | 10 +- src/types.ts | 8 +- src/utils.ts | 18 +- src/validator.ts | 3 + test/collection_delete.test.ts | 24 +- test/collection_find.test.ts | 136 +++++----- test/collection_get.test.ts | 36 +-- test/collection_insert.test.ts | 18 +- test/collection_put.test.ts | 40 +-- test/collection_update.test.ts | 18 +- test/crud/blob.test.ts | 4 +- test/crud/delete.test.ts | 36 +-- test/crud/find.test.ts | 379 ++++++++++++++++++---------- test/crud/get.test.ts | 34 +-- test/crud/history.test.ts | 36 +-- test/crud/put.test.ts | 100 ++++---- test/git_documentdb_crud.test.ts | 200 +++++++-------- test/git_documentdb_open.test.ts | 6 +- test/remote_base/3way_merge.ts | 82 +++--- test/remote_base/3way_merge_ot.ts | 22 +- test/remote_base/combine.ts | 20 +- test/remote_base/network_history.ts | 4 +- test/remote_base/sync_trysync.ts | 4 +- test/remote_utils.ts | 20 +- 34 files changed, 799 insertions(+), 662 deletions(-) diff --git a/src/collection.ts b/src/collection.ts index 115ffbac..842698e7 100644 --- a/src/collection.ts +++ b/src/collection.ts @@ -37,7 +37,7 @@ import { import { GitDDBInterface } from './types_gitddb'; import { Validator } from './validator'; import { toSortedJSONString } from './utils'; -import { GIT_DOCUMENTDB_METADATA_DIR, JSON_EXT } from './const'; +import { GIT_DOCUMENTDB_METADATA_DIR, JSON_EXTENSION } from './const'; import { getImpl } from './crud/get'; import { getHistoryImpl } from './crud/history'; import { deleteImpl } from './crud/delete'; @@ -52,7 +52,7 @@ import { ICollection } from './types_collection'; * @remarks * In a collection API, shortId (shortName) is used instead of _id (name). * - * - shortId is a file path whose collectionPath and .json extension are omitted. (_id = collectionPath + shortId) + * - shortId is a file path whose collectionPath and JSON_EXTENSION extension are omitted. (_id = collectionPath + shortId) * * - shortName is a file path whose collectionPath is omitted. (name = collectionPath + shortName) * @@ -229,10 +229,10 @@ export class Collection implements ICollection { /** * Insert a JSON document if not exists. Otherwise, update it. * - * @param jsonDoc - JsonDoc whose _id is shortId. shortId is a file path whose collectionPath and .json extension are omitted. + * @param jsonDoc - JsonDoc whose _id is shortId. shortId is a file path whose collectionPath and ${JSON_EXTENSION} extension are omitted. * * @remarks - * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}${jsonDoc._id}.json`. + * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}${jsonDoc._id}${JSON_EXTENSION}`. * * - If _id is undefined, it is automatically generated. * @@ -258,10 +258,10 @@ export class Collection implements ICollection { /** * Insert a JSON document if not exists. Otherwise, update it. * - * @param shortId - shortId is a file path whose collectionPath and .json extension are omitted. + * @param shortId - shortId is a file path whose collectionPath and ${JSON_EXTENSION} extension are omitted. * * @remarks - * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortId}.json`. + * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortId}${JSON_EXTENSION}`. * * - If shortId is undefined, it is automatically generated. * @@ -323,14 +323,14 @@ export class Collection implements ICollection { if (!shortIdOrDoc) shortIdOrDoc = this.generateId(); shortId = shortIdOrDoc; _id = this.collectionPath + shortId; - shortName = shortId + JSON_EXT; + shortName = shortId + JSON_EXTENSION; jsonDoc = jsonDocOrOptions as JsonDoc; } else { if (!shortIdOrDoc._id) shortIdOrDoc._id = this.generateId(); shortId = shortIdOrDoc._id; _id = this.collectionPath + shortId; - shortName = shortId + JSON_EXT; + shortName = shortId + JSON_EXTENSION; jsonDoc = shortIdOrDoc as JsonDoc; options = jsonDocOrOptions as PutOptions; } @@ -377,14 +377,14 @@ export class Collection implements ICollection { /** * Insert a JSON document * - * @param jsonDoc - JsonDoc whose _id is shortId. shortId is a file path whose collectionPath and .json extension are omitted. + * @param jsonDoc - JsonDoc whose _id is shortId. shortId is a file path whose collectionPath and ${JSON_EXTENSION} extension are omitted. * * @remarks * - Throws SameIdExistsError when a document that has the same _id exists. It might be better to use put() instead of insert(). * * - If _id is undefined, it is automatically generated. * - * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${jsonDoc._id}.json`. + * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${jsonDoc._id}${JSON_EXTENSION}`. * * @param jsonDoc - See {@link JsonDoc} for restriction. * @@ -414,12 +414,12 @@ export class Collection implements ICollection { /** * Insert a JSON document * - * @param shortId - shortId is a file path whose collectionPath and .json extension are omitted. + * @param shortId - shortId is a file path whose collectionPath and ${JSON_EXTENSION} extension are omitted. * * @remarks * - Throws SameIdExistsError when a document that has the same _id exists. It might be better to use put() instead of insert(). * - * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortId}.json`. + * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortId}${JSON_EXTENSION}`. * * - If shortId is undefined, it is automatically generated. * @@ -490,12 +490,12 @@ export class Collection implements ICollection { /** * Update a JSON document * - * @param jsonDoc - JsonDoc whose _id is shortId. shortId is a file path whose collectionPath and .json extension are omitted. + * @param jsonDoc - JsonDoc whose _id is shortId. shortId is a file path whose collectionPath and ${JSON_EXTENSION} extension are omitted. * * @remarks * - Throws DocumentNotFoundError if a specified document does not exist. It might be better to use put() instead of update(). * - * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${jsonDoc._id}.json`. + * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${jsonDoc._id}${JSON_EXTENSION}`. * * - If _id is undefined, it is automatically generated. * @@ -525,12 +525,12 @@ export class Collection implements ICollection { /** * Update a JSON document * - * @param shortId - shortId is a file path whose collectionPath and .json extension are omitted. + * @param shortId - shortId is a file path whose collectionPath and ${JSON_EXTENSION} extension are omitted. * * @remarks * - Throws DocumentNotFoundError if a specified data does not exist. It might be better to use put() instead of update(). * - * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortId}.json`. + * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortId}${JSON_EXTENSION}`. * * - An update operation is not skipped even if no change occurred on a specified data. * @@ -599,14 +599,14 @@ export class Collection implements ICollection { /** * Insert data if not exists. Otherwise, update it. * - * @param shortName - shortName is a file path whose collectionPath is omitted. shortName of JsonDoc must ends with .json extension. + * @param shortName - shortName is a file path whose collectionPath is omitted. shortName of JsonDoc must ends with ${JSON_EXTENSION} extension. * * @remarks - * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortName}.json`. + * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortName}${JSON_EXTENSION}`. * * - If shortName is undefined, it is automatically generated. * - * - _id property of a JsonDoc is automatically set or overwritten by shortName parameter whose .json extension is omitted. + * - _id property of a JsonDoc is automatically set or overwritten by shortName parameter whose ${JSON_EXTENSION} extension is omitted. * * - An update operation is not skipped even if no change occurred on a specified data. * @@ -650,13 +650,13 @@ export class Collection implements ICollection { data = doc; } else if (typeof doc === 'object') { - if (!shortName) shortName = this.generateId() + JSON_EXT; + if (!shortName) shortName = this.generateId() + JSON_EXTENSION; docType = 'json'; // JsonDoc - if (!shortName.endsWith(JSON_EXT)) { + if (!shortName.endsWith(JSON_EXTENSION)) { return Promise.reject(new Err.InvalidJsonFileExtensionError()); } - shortId = shortName.replace(new RegExp(JSON_EXT + '$'), ''); + shortId = shortName.replace(new RegExp(JSON_EXTENSION + '$'), ''); // Validate JSON let clone; @@ -725,16 +725,16 @@ export class Collection implements ICollection { /** * Insert a data * - * @param shortName - shortName is a file path whose collectionPath is omitted. shortName of JsonDoc must ends with .json extension. + * @param shortName - shortName is a file path whose collectionPath is omitted. shortName of JsonDoc must ends with ${JSON_EXTENSION} extension. * * @remarks * - Throws SameIdExistsError when data that has the same _id exists. It might be better to use put() instead of insert(). * - * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortName}.json`. + * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortName}${JSON_EXTENSION}`. * * - If shortName is undefined, it is automatically generated. * - * - _id property of a JsonDoc is automatically set or overwritten by shortName parameter whose .json extension is omitted. + * - _id property of a JsonDoc is automatically set or overwritten by shortName parameter whose ${JSON_EXTENSION} extension is omitted. * * @throws {@link Err.InvalidJsonObjectError} * @@ -773,14 +773,14 @@ export class Collection implements ICollection { /** * Update a data * - * @param shortName - shortName is a file path whose collectionPath is omitted. shortName of JsonDoc must ends with .json extension. + * @param shortName - shortName is a file path whose collectionPath is omitted. shortName of JsonDoc must ends with ${JSON_EXTENSION} extension. * * @remarks * - Throws DocumentNotFoundError if a specified data does not exist. It might be better to use put() instead of update(). * - * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortName}.json`. + * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortName}${JSON_EXTENSION}`. * - * - _id property of a JsonDoc is automatically set or overwritten by shortName parameter whose .json extension is omitted. + * - _id property of a JsonDoc is automatically set or overwritten by shortName parameter whose ${JSON_EXTENSION} extension is omitted. * * - An update operation is not skipped even if no change occurred on a specified data. * @@ -821,7 +821,7 @@ export class Collection implements ICollection { /** * Get a JSON document * - * @param shortId - shortId is a file path whose collectionPath and .json extension are omitted. + * @param shortId - shortId is a file path whose collectionPath and ${JSON_EXTENSION} extension are omitted. * * @returns * - undefined if a specified document does not exist. @@ -834,7 +834,7 @@ export class Collection implements ICollection { * @public */ get (_id: string): Promise { - const shortName = _id + JSON_EXT; + const shortName = _id + JSON_EXTENSION; return getImpl(this._gitDDB, shortName, this.collectionPath, { forceDocType: 'json', }) as Promise; @@ -848,7 +848,7 @@ export class Collection implements ICollection { * @returns * - undefined if a specified data does not exist. * - * - FatJsonDoc if the file extension is '.json'. Be careful that JsonDoc may not have _id property when an app other than GitDocumentDB creates it. + * - FatJsonDoc if the file extension is JSON_EXTENSION. Be careful that JsonDoc may not have _id property when an app other than GitDocumentDB creates it. * * - FatBinaryDoc if described in .gitattribtues, otherwise FatTextDoc. * @@ -894,7 +894,7 @@ export class Collection implements ICollection { /** * Get an old revision of a JSON document * - * @param shortId - shortId is a file path whose collectionPath and .json extension are omitted. + * @param shortId - shortId is a file path whose collectionPath and ${JSON_EXTENSION} extension are omitted. * @param revision - Specify a number to go back to old revision. Default is 0. * See {@link git-documentdb#Collection.getHistory} for the array of revisions. * @param historyOptions - The array of revisions is filtered by HistoryOptions.filter. @@ -918,7 +918,7 @@ export class Collection implements ICollection { revision: number, historyOptions?: HistoryOptions ): Promise { - const shortName = shortId + JSON_EXT; + const shortName = shortId + JSON_EXTENSION; return getImpl( this._gitDDB, shortName, @@ -943,7 +943,7 @@ export class Collection implements ICollection { * @remarks * - undefined if a specified data does not exist or it is deleted. * - * - JsonDoc if the file extension is '.json'. Be careful that JsonDoc may not have _id property when an app other than GitDocumentDB creates it. + * - JsonDoc if the file extension is JSON_EXTENSION. Be careful that JsonDoc may not have _id property when an app other than GitDocumentDB creates it. * * - FatBinaryDoc if described in .gitattribtues, otherwise FatTextDoc. * @@ -985,7 +985,7 @@ export class Collection implements ICollection { * @remarks * - By default, revisions are sorted by reverse chronological order. However, keep in mind that Git dates may not be consistent across repositories. * - * @param shortId - shortId is a file path whose collectionPath and .json extension is omitted. + * @param shortId - shortId is a file path whose collectionPath and ${JSON_EXTENSION} extension is omitted. * @param historyOptions - The array of revisions is filtered by HistoryOptions.filter. * * @returns Array of JsonDoc or undefined. @@ -1029,7 +1029,7 @@ export class Collection implements ICollection { _id: string, historyOptions?: HistoryOptions ): Promise<(JsonDoc | undefined)[]> { - const shortName = _id + JSON_EXT; + const shortName = _id + JSON_EXTENSION; return getHistoryImpl( this._gitDDB, shortName, @@ -1051,7 +1051,7 @@ export class Collection implements ICollection { * @returns Array of FatDoc or undefined. * - undefined if a specified data does not exist or it is deleted. * - * - Array of FatJsonDoc if isJsonDocCollection is true or the file extension is '.json'. Be careful that JsonDoc may not have _id property when an app other than GitDocumentDB creates it. + * - Array of FatJsonDoc if isJsonDocCollection is true or the file extension is JSON_EXTENSION. Be careful that JsonDoc may not have _id property when an app other than GitDocumentDB creates it. * * - Array of FatBinaryDoc if described in .gitattribtues, otherwise array of FatTextDoc. * @@ -1080,7 +1080,7 @@ export class Collection implements ICollection { /** * Delete a JSON document * - * @param shortId - shortId is a file path whose collectionPath and .json extension is omitted. + * @param shortId - shortId is a file path whose collectionPath and ${JSON_EXTENSION} extension is omitted. * * @throws {@link Err.UndefinedDocumentIdError} * @@ -1100,7 +1100,7 @@ export class Collection implements ICollection { /** * Delete a document by _id property in JsonDoc * - * @param jsonDoc - JsonDoc whose _id is shortId. Only the _id property is referenced. shortId is a file path whose collectionPath and .json extension are omitted. + * @param jsonDoc - JsonDoc whose _id is shortId. Only the _id property is referenced. shortId is a file path whose collectionPath and ${JSON_EXTENSION} extension are omitted. * * @throws {@link Err.UndefinedDocumentIdError} * @@ -1139,7 +1139,7 @@ export class Collection implements ICollection { else { return Promise.reject(new Err.UndefinedDocumentIdError()); } - const shortName = shortId + JSON_EXT; + const shortName = shortId + JSON_EXTENSION; return deleteImpl(this._gitDDB, this.collectionPath, shortId, shortName, options).then( res => { @@ -1176,15 +1176,15 @@ export class Collection implements ICollection { return Promise.reject(new Err.UndefinedDocumentIdError()); } - const docType: DocType = shortName.endsWith('.json') ? 'json' : 'text'; + const docType: DocType = shortName.endsWith(JSON_EXTENSION) ? 'json' : 'text'; if (docType === 'text') { // TODO: select binary or text by .gitattribtues } - const shortId = shortName.replace(new RegExp(JSON_EXT + '$'), ''); + const shortId = shortName.replace(new RegExp(JSON_EXTENSION + '$'), ''); return deleteImpl(this._gitDDB, this.collectionPath, shortId, shortName, options).then( res => { - // NOTE: Cannot detect JsonDoc whose file path does not end with '.json' + // NOTE: Cannot detect JsonDoc whose file path does not end with JSON_EXTENSION if (docType === 'json') { const deleteResult: DeleteResultJsonDoc = { ...res, diff --git a/src/const.ts b/src/const.ts index e7303e03..d2ba1a63 100644 --- a/src/const.ts +++ b/src/const.ts @@ -62,21 +62,21 @@ export const GIT_DOCUMENTDB_METADATA_DIR = '.gitddb'; /** * @public */ -export const JSON_EXT = '.json'; +export const JSON_POSTFIX = '.json'; /** * @public */ -export const FRONT_MATTER_EXT = '.md'; +export const FRONT_MATTER_POSTFIX = '.md'; /** * !ALERT: It is not const for simplicity. * * @internal */ // eslint-disable-next-line import/no-mutable-exports, @typescript-eslint/naming-convention, prefer-const -export let FILE_EXT = '.json'; +export let JSON_EXTENSION = JSON_POSTFIX; // eslint-disable-next-line @typescript-eslint/naming-convention export const setFileExt = (ext: string) => { - FILE_EXT = ext; + JSON_EXTENSION = ext; }; /** * @public diff --git a/src/crud/blob.ts b/src/crud/blob.ts index 47dce986..c21dcb4d 100644 --- a/src/crud/blob.ts +++ b/src/crud/blob.ts @@ -8,7 +8,7 @@ import fs from 'fs'; import { readBlob, ReadBlobResult, resolveRef } from 'isomorphic-git'; -import { JSON_EXT } from '../const'; +import { JSON_EXTENSION } from '../const'; import { utf8decode } from '../utils'; import { Err } from '../error'; import { FatBinaryDoc, FatDoc, FatJsonDoc, FatTextDoc, JsonDoc } from '../types'; @@ -33,7 +33,7 @@ export function blobToJsonDoc ( if (withMetadata) { const fatJsonDoc: FatJsonDoc = { _id: shortId, - name: shortId + JSON_EXT, + name: shortId + JSON_EXTENSION, fileOid: readBlobResult.oid, type: 'json', doc: jsonDoc, diff --git a/src/crud/find.ts b/src/crud/find.ts index 5794a64f..95567938 100644 --- a/src/crud/find.ts +++ b/src/crud/find.ts @@ -8,7 +8,7 @@ import fs from 'fs'; import { readBlob, readTree, resolveRef, TreeEntry, TreeObject } from 'isomorphic-git'; -import { GIT_DOCUMENTDB_METADATA_DIR, JSON_EXT } from '../const'; +import { GIT_DOCUMENTDB_METADATA_DIR, JSON_EXTENSION } from '../const'; import { Err } from '../error'; import { Doc, @@ -142,7 +142,7 @@ export async function findImpl ( } } else { - if (findOnlyJson && !fullDocPath.endsWith('.json')) { + if (findOnlyJson && !fullDocPath.endsWith(JSON_EXTENSION)) { continue; } // eslint-disable-next-line no-await-in-loop @@ -156,13 +156,14 @@ export async function findImpl ( // Skip if cannot read if (readBlobResult) { const docType: DocType = - options.forceDocType ?? (fullDocPath.endsWith('.json') ? 'json' : 'text'); + options.forceDocType ?? + (fullDocPath.endsWith(JSON_EXTENSION) ? 'json' : 'text'); if (docType === 'text') { // TODO: select binary or text by .gitattribtues } const shortName = fullDocPath.replace(new RegExp('^' + collectionPath), ''); if (docType === 'json') { - const shortId = shortName.replace(new RegExp(JSON_EXT + '$'), ''); + const shortId = shortName.replace(new RegExp(JSON_EXTENSION + '$'), ''); if (withMetadata) { docs.push(blobToJsonDoc(shortId, readBlobResult, true) as FatJsonDoc); } diff --git a/src/crud/get.ts b/src/crud/get.ts index d1dcfddc..541e010a 100644 --- a/src/crud/get.ts +++ b/src/crud/get.ts @@ -7,7 +7,7 @@ */ import { ReadBlobResult } from 'isomorphic-git'; -import { JSON_EXT } from '../const'; +import { JSON_EXTENSION } from '../const'; import { GitDDBInterface } from '../types_gitddb'; import { Err } from '../error'; import { @@ -98,7 +98,7 @@ export async function getImpl ( if (readBlobResult === undefined) return undefined; const docType: DocType = - options.forceDocType ?? (fullDocPath.endsWith('.json') ? 'json' : 'text'); + options.forceDocType ?? (fullDocPath.endsWith(JSON_EXTENSION) ? 'json' : 'text'); if (docType === 'text') { // TODO: select binary or text by .gitattribtues } @@ -107,7 +107,7 @@ export async function getImpl ( if (internalOptions.oid !== '') { return blobToJsonDocWithoutOverwrittenId(readBlobResult); } - const shortId = shortName.replace(new RegExp(JSON_EXT + '$'), ''); + const shortId = shortName.replace(new RegExp(JSON_EXTENSION + '$'), ''); return blobToJsonDoc(shortId, readBlobResult, internalOptions.withMetadata); } else if (docType === 'text') { diff --git a/src/crud/history.ts b/src/crud/history.ts index ecce7487..f1f2570c 100644 --- a/src/crud/history.ts +++ b/src/crud/history.ts @@ -11,7 +11,7 @@ import fs from 'fs-extra'; import { Doc, DocType, FatDoc, GetOptions, HistoryFilter, HistoryOptions } from '../types'; import { GitDDBInterface } from '../types_gitddb'; import { Err } from '../error'; -import { JSON_EXT } from '../const'; +import { JSON_EXTENSION } from '../const'; import { blobToBinary, blobToJsonDoc, blobToText } from './blob'; /** @@ -46,7 +46,7 @@ export async function getHistoryImpl ( const fullDocPath = collectionPath + shortName; const docType: DocType = - options.forceDocType ?? (fullDocPath.endsWith('.json') ? 'json' : 'text'); + options.forceDocType ?? (fullDocPath.endsWith(JSON_EXTENSION) ? 'json' : 'text'); if (docType === 'text') { // TODO: select binary or text by .gitattribtues @@ -88,7 +88,7 @@ export async function getHistoryImpl ( docArray.push(undefined); } else if (docType === 'json') { - const shortId = shortName.replace(new RegExp(JSON_EXT + '$'), ''); + const shortId = shortName.replace(new RegExp(JSON_EXTENSION + '$'), ''); // eslint-disable-next-line max-depth if (withMetaData) { diff --git a/src/error.ts b/src/error.ts index 8c56f29a..875c40d7 100644 --- a/src/error.ts +++ b/src/error.ts @@ -6,6 +6,8 @@ * found in the LICENSE file in the root directory of this source tree. */ +import { JSON_EXTENSION } from './const'; + /* eslint-disable unicorn/custom-error-definition */ /** @@ -132,7 +134,7 @@ export namespace Err { */ export class InvalidJsonFileExtensionError extends BaseError { constructor () { - super(`JSON file extension must be .json`); + super(`JSON file extension must be ${JSON_EXTENSION}`); } } diff --git a/src/git_documentdb.ts b/src/git_documentdb.ts index 18156de1..f16dee61 100644 --- a/src/git_documentdb.ts +++ b/src/git_documentdb.ts @@ -57,9 +57,9 @@ import { FILE_CREATE_TIMEOUT, FILE_REMOVE_TIMEOUT, FIRST_COMMIT_MESSAGE, - FRONT_MATTER_EXT, + FRONT_MATTER_POSTFIX, GIT_DOCUMENTDB_INFO_ID, - JSON_EXT, + JSON_POSTFIX, SET_DATABASE_ID_MESSAGE, setFileExt, } from './const'; @@ -324,7 +324,9 @@ export class GitDocumentDB }, }; - setFileExt(options.serializeFormat === 'front-matter' ? FRONT_MATTER_EXT : JSON_EXT); + setFileExt( + options.serializeFormat === 'front-matter' ? FRONT_MATTER_POSTFIX : JSON_POSTFIX + ); // Get full-path this._workingDir = path.resolve(this._localDir, this._dbName); @@ -427,7 +429,7 @@ export class GitDocumentDB const resPut = await putWorker( this, '', - GIT_DOCUMENTDB_INFO_ID + JSON_EXT, + GIT_DOCUMENTDB_INFO_ID + JSON_POSTFIX, toSortedJSONString(info), FIRST_COMMIT_MESSAGE ).catch(err => { @@ -824,7 +826,7 @@ export class GitDocumentDB // Don't use get() because isOpened is false. const readBlobResult = await readLatestBlob( this.workingDir, - GIT_DOCUMENTDB_INFO_ID + JSON_EXT + GIT_DOCUMENTDB_INFO_ID + JSON_POSTFIX ).catch(() => undefined); if (readBlobResult !== undefined) { try { @@ -848,7 +850,7 @@ export class GitDocumentDB await putWorker( this, '', - GIT_DOCUMENTDB_INFO_ID + JSON_EXT, + GIT_DOCUMENTDB_INFO_ID + JSON_POSTFIX, toSortedJSONString(info), SET_DATABASE_ID_MESSAGE ); @@ -883,10 +885,10 @@ export class GitDocumentDB /** * Insert a JSON document if not exists. Otherwise, update it. * - * @param jsonDoc - JsonDoc whose _id is shortId. shortId is a file path whose collectionPath and .json extension are omitted. + * @param jsonDoc - JsonDoc whose _id is shortId. shortId is a file path whose collectionPath and ${JSON_EXTENSION} extension are omitted. * * @remarks - * - The saved file path is `${GitDocumentDB#workingDir}/${jsonDoc._id}.json` on the file system. + * - The saved file path is `${GitDocumentDB#workingDir}/${jsonDoc._id}${JSON_EXTENSION}` on the file system. * * - If _id is undefined, it is automatically generated. * @@ -914,10 +916,10 @@ export class GitDocumentDB /** * Insert a JSON document if not exists. Otherwise, update it. * - * @param _id - _id is a file path whose .json extension is omitted. + * @param _id - _id is a file path whose ${JSON_EXTENSION} extension is omitted. * * @remarks - * - The saved file path is `${GitDocumentDB#workingDir}/${_id}.json` on the file system. + * - The saved file path is `${GitDocumentDB#workingDir}/${_id}${JSON_EXTENSION}` on the file system. * * - If _id is undefined, it is automatically generated. * @@ -961,14 +963,14 @@ export class GitDocumentDB /** * Insert a JSON document * - * @param jsonDoc - JsonDoc whose _id is shortId. shortId is a file path whose collectionPath and .json extension are omitted. + * @param jsonDoc - JsonDoc whose _id is shortId. shortId is a file path whose collectionPath and ${JSON_EXTENSION} extension are omitted. * * @remarks * - Throws SameIdExistsError when a document that has the same _id exists. It might be better to use put() instead of insert(). * * - If _id is undefined, it is automatically generated. * - * - The saved file path is `${GitDocumentDB#workingDir}/${jsonDoc._id}.json` on the file system. + * - The saved file path is `${GitDocumentDB#workingDir}/${jsonDoc._id}${JSON_EXTENSION}` on the file system. * * - This is an alias of GitDocumentDB#rootCollection.insert() * @@ -998,12 +1000,12 @@ export class GitDocumentDB /** * Insert a JSON document * - * @param _id - _id is a file path whose .json extension is omitted. + * @param _id - _id is a file path whose ${JSON_EXTENSION} extension is omitted. * * @remarks * - Throws SameIdExistsError when a document that has the same id exists. It might be better to use put() instead of insert(). * - * - The saved file path is `${GitDocumentDB#workingDir}/${_id}.json` on the file system. + * - The saved file path is `${GitDocumentDB#workingDir}/${_id}${JSON_EXTENSION}` on the file system. * * - If _id is undefined, it is automatically generated. * @@ -1049,14 +1051,14 @@ export class GitDocumentDB /** * Update a JSON document * - * @param jsonDoc - JsonDoc whose _id is shortId. shortId is a file path whose collectionPath and .json extension are omitted. + * @param jsonDoc - JsonDoc whose _id is shortId. shortId is a file path whose collectionPath and ${JSON_EXTENSION} extension are omitted. * * @remarks * - Throws DocumentNotFoundError if a specified document does not exist. It might be better to use put() instead of update(). * * - If _id is undefined, it is automatically generated. * - * - The saved file path is `${GitDocumentDB#workingDir}/${_id}.json` on the file system. + * - The saved file path is `${GitDocumentDB#workingDir}/${_id}${JSON_EXTENSION}` on the file system. * * - This is an alias of GitDocumentDB#rootCollection.update() * @@ -1084,12 +1086,12 @@ export class GitDocumentDB /** * Update a JSON document * - * @param _id - _id is a file path whose .json extension is omitted. + * @param _id - _id is a file path whose ${JSON_EXTENSION} extension is omitted. * * @remarks * - Throws DocumentNotFoundError if a specified document does not exist. It might be better to use put() instead of update(). * - * - The saved file path is `${GitDocumentDB#workingDir}/${_id}.json` on the file system. + * - The saved file path is `${GitDocumentDB#workingDir}/${_id}${JSON_EXTENSION}` on the file system. * * - An update operation is not skipped even if no change occurred on a specified document. * @@ -1134,11 +1136,11 @@ export class GitDocumentDB * @param name - name is a file path. * * @remarks - * - The saved file path is `${GitDocumentDB#workingDir}/${name}.json`. + * - The saved file path is `${GitDocumentDB#workingDir}/${name}${JSON_EXTENSION}`. * * - If a name parameter is undefined, it is automatically generated. * - * - _id property of a JsonDoc is automatically set or overwritten by name parameter whose .json extension is removed. + * - _id property of a JsonDoc is automatically set or overwritten by name parameter whose ${JSON_EXTENSION} extension is removed. * * - An update operation is not skipped even if no change occurred on a specified data. * @@ -1178,11 +1180,11 @@ export class GitDocumentDB * @remarks * - Throws SameIdExistsError when data that has the same _id exists. It might be better to use put() instead of insert(). * - * - The saved file path is `${GitDocumentDB#workingDir}/${name}.json`. + * - The saved file path is `${GitDocumentDB#workingDir}/${name}${JSON_EXTENSION}`. * * - If a name parameter is undefined, it is automatically generated. * - * - _id property of a JsonDoc is automatically set or overwritten by name parameter whose .json extension is omitted. + * - _id property of a JsonDoc is automatically set or overwritten by name parameter whose ${JSON_EXTENSION} extension is omitted. * * - This is an alias of GitDocumentDB#rootCollection.insertFatDoc() * @@ -1221,9 +1223,9 @@ export class GitDocumentDB * @remarks * - Throws DocumentNotFoundError if a specified data does not exist. It might be better to use put() instead of update(). * - * - The saved file path is `${GitDocumentDB#workingDir}/${name}.json`. + * - The saved file path is `${GitDocumentDB#workingDir}/${name}${JSON_EXTENSION}`. * - * - _id property of a JsonDoc is automatically set or overwritten by name parameter whose .json extension is omitted. + * - _id property of a JsonDoc is automatically set or overwritten by name parameter whose ${JSON_EXTENSION} extension is omitted. * * - An update operation is not skipped even if no change occurred on a specified data. * @@ -1259,7 +1261,7 @@ export class GitDocumentDB /** * Get a JSON document * - * @param _id - _id is a file path whose .json extension is omitted. + * @param _id - _id is a file path whose ${JSON_EXTENSION} extension is omitted. * * @returns * - undefined if a specified document does not exist. @@ -1285,7 +1287,7 @@ export class GitDocumentDB * @returns * - undefined if a specified data does not exist. * - * - FatJsonDoc if the file extension is '.json'. Be careful that JsonDoc may not have _id property when an app other than GitDocumentDB creates it. + * - FatJsonDoc if the file extension is JSON_EXTENSION. Be careful that JsonDoc may not have _id property when an app other than GitDocumentDB creates it. * * - FatBinaryDoc if described in .gitattribtues, otherwise FatTextDoc. * @@ -1324,7 +1326,7 @@ export class GitDocumentDB /** * Get an old revision of a document * - * @param _id - _id is a file path whose .json extension is omitted. + * @param _id - _id is a file path whose ${JSON_EXTENSION} extension is omitted. * @param revision - Specify a number to go back to old revision. Default is 0. * See {@link git-documentdb#GitDocumentDB.getHistory} for the array of revisions. * @param historyOptions - The array of revisions is filtered by HistoryOptions.filter. @@ -1364,7 +1366,7 @@ export class GitDocumentDB * @remarks * - undefined if a specified data does not exist or it is deleted. * - * - JsonDoc if the file extension is '.json'. Be careful that JsonDoc may not have _id property when an app other than GitDocumentDB creates it. + * - JsonDoc if the file extension is JSON_EXTENSION. Be careful that JsonDoc may not have _id property when an app other than GitDocumentDB creates it. * * - FatBinaryDoc if described in .gitattribtues, otherwise FatTextDoc. * @@ -1400,7 +1402,7 @@ export class GitDocumentDB /** * Get revision history of a document * - * @param _id - _id is a file path whose .json extension is omitted. + * @param _id - _id is a file path whose ${JSON_EXTENSION} extension is omitted. * @param historyOptions - The array of revisions is filtered by HistoryOptions.filter. * * @remarks @@ -1411,7 +1413,7 @@ export class GitDocumentDB * @returns Array of FatDoc or undefined. * - undefined if a specified document does not exist or it is deleted. * - * - JsonDoc if isJsonDocCollection is true or the file extension is '.json'. + * - JsonDoc if isJsonDocCollection is true or the file extension is JSON_EXTENSION. * * - Uint8Array or string if isJsonDocCollection is false. * @@ -1471,7 +1473,7 @@ export class GitDocumentDB * @returns Array of FatDoc or undefined. * - undefined if a specified data does not exist or it is deleted. * - * - Array of FatJsonDoc if isJsonDocCollection is true or the file extension is '.json'. Be careful that JsonDoc may not have _id property when an app other than GitDocumentDB creates it. + * - Array of FatJsonDoc if isJsonDocCollection is true or the file extension is JSON_EXTENSION. Be careful that JsonDoc may not have _id property when an app other than GitDocumentDB creates it. * * - Array of FatBinaryDoc if described in .gitattribtues, otherwise array of FatTextDoc. * @@ -1493,7 +1495,7 @@ export class GitDocumentDB /** * Delete a JSON document * - * @param _id - _id is a file path whose .json extension is omitted. + * @param _id - _id is a file path whose ${JSON_EXTENSION} extension is omitted. * * @remarks * - This is an alias of GitDocumentDB#rootCollection.delete() @@ -1516,7 +1518,7 @@ export class GitDocumentDB /** * Delete a document by _id property in JsonDoc * - * @param jsonDoc - Only the _id property of the JsonDoc is referenced. _id is a file path whose .json extension is omitted. + * @param jsonDoc - Only the _id property of the JsonDoc is referenced. _id is a file path whose ${JSON_EXTENSION} extension is omitted. * * @remarks * - This is an alias of GitDocumentDB#rootCollection.delete() diff --git a/src/remote/3way_merge.ts b/src/remote/3way_merge.ts index 000014a6..9c7bace3 100644 --- a/src/remote/3way_merge.ts +++ b/src/remote/3way_merge.ts @@ -1,7 +1,7 @@ import nodePath, { basename } from 'path'; import git, { TreeEntry, WalkerEntry } from 'isomorphic-git'; import fs from 'fs-extra'; -import { DEFAULT_CONFLICT_RESOLUTION_STRATEGY } from '../const'; +import { DEFAULT_CONFLICT_RESOLUTION_STRATEGY, JSON_EXTENSION } from '../const'; import { Err } from '../error'; import { AcceptedConflict, @@ -357,7 +357,7 @@ export async function threeWayMerge ( AcceptedConflict | undefined ] > { - const docType: DocType = fullDocPath.endsWith('.json') ? 'json' : 'text'; + const docType: DocType = fullDocPath.endsWith(JSON_EXTENSION) ? 'json' : 'text'; if (docType === 'text') { // TODO: select binary or text by .gitattribtues } diff --git a/src/remote/combine.ts b/src/remote/combine.ts index 4f39e8cc..26875021 100644 --- a/src/remote/combine.ts +++ b/src/remote/combine.ts @@ -21,7 +21,7 @@ import { } from '../types'; import { GitDDBInterface } from '../types_gitddb'; import { Err } from '../error'; -import { DUPLICATED_FILE_POSTFIX, FILE_REMOVE_TIMEOUT, JSON_EXT } from '../const'; +import { DUPLICATED_FILE_POSTFIX, FILE_REMOVE_TIMEOUT, JSON_EXTENSION } from '../const'; import { getAllMetadata, toSortedJSONString } from '../utils'; import { RemoteEngine, wrappingRemoteEngineError } from './remote_engine'; @@ -102,7 +102,7 @@ export async function combineDatabaseWithTheirs ( await fs.ensureDir(dir); - const docType: DocType = localFilePath.endsWith('.json') ? 'json' : 'text'; + const docType: DocType = localFilePath.endsWith(JSON_EXTENSION) ? 'json' : 'text'; // eslint-disable-next-line max-depth if (docType === 'text') { // TODO: select binary or text by .gitattribtues @@ -128,9 +128,9 @@ export async function combineDatabaseWithTheirs ( if (doc._id !== undefined) { doc._id = _id + postfix; } - duplicatedFileName = _id + postfix + JSON_EXT; + duplicatedFileName = _id + postfix + JSON_EXTENSION; duplicatedFileId = _id + postfix; - duplicatedFileExt = JSON_EXT; + duplicatedFileExt = JSON_EXTENSION; fs.writeFileSync( path.resolve(remoteDir, duplicatedFileName), toSortedJSONString(doc) diff --git a/src/remote/worker_utils.ts b/src/remote/worker_utils.ts index 46a20486..2cff8571 100644 --- a/src/remote/worker_utils.ts +++ b/src/remote/worker_utils.ts @@ -10,7 +10,7 @@ import nodePath from 'path'; import git, { ReadBlobResult, ReadCommitResult } from 'isomorphic-git'; import fs from 'fs-extra'; import { normalizeCommit, toSortedJSONString, utf8decode } from '../utils'; -import { JSON_EXT } from '../const'; +import { JSON_EXTENSION } from '../const'; import { Err } from '../error'; import { ChangedFile, @@ -55,7 +55,7 @@ export async function getFatDocFromData ( let fatDoc: FatDoc; const { oid } = await git.hashBlob({ object: data }); if (docType === 'json') { - const _id = fullDocPath.replace(new RegExp(JSON_EXT + '$'), ''); + const _id = fullDocPath.replace(new RegExp(JSON_EXTENSION + '$'), ''); if (typeof data !== 'string') { data = utf8decode(data); } @@ -129,7 +129,7 @@ export function getFatDocFromReadBlobResult ( ) { let fatDoc: FatDoc; if (docType === 'json') { - const _id = fullDocPath.replace(new RegExp(JSON_EXT + '$'), ''); + const _id = fullDocPath.replace(new RegExp(JSON_EXTENSION + '$'), ''); fatDoc = blobToJsonDoc(_id, readBlobResult, true) as FatJsonDoc; } else if (docType === 'text') { @@ -169,7 +169,7 @@ export async function getChanges ( a = null; } - const docType: DocType = fullDocPath.endsWith('.json') ? 'json' : 'text'; + const docType: DocType = fullDocPath.endsWith(JSON_EXTENSION) ? 'json' : 'text'; if (docType === 'text') { // TODO: select binary or text by .gitattribtues } @@ -237,7 +237,7 @@ export async function getAndWriteLocalChanges ( return; } - const docType: DocType = fullDocPath.endsWith('.json') ? 'json' : 'text'; + const docType: DocType = fullDocPath.endsWith(JSON_EXTENSION) ? 'json' : 'text'; if (docType === 'text') { // TODO: select binary or text by .gitattribtues } diff --git a/src/types.ts b/src/types.ts index f0c47a91..af4713bc 100644 --- a/src/types.ts +++ b/src/types.ts @@ -196,9 +196,9 @@ export type Doc = JsonDoc | string | Uint8Array; * Metadata for JsonDoc * * @remarks - * - _id: _id of a JSON document. This is a file name without .json extension. + * - _id: _id of a JSON document. This is a file name without ${JSON_EXTENSION} extension. * - * - name: A file name in Git. e.g.) "foo.json", "bar/baz.json" + * - name: A file name in Git. e.g.) "foo.json", "bar/baz.md" * * - fileOid: SHA-1 hash of Git object (40 characters) * @@ -457,7 +457,7 @@ export type FindOptions = { * Result of put APIs (put, update, insert, putFatDoc, updateFatDoc, and insertFatDoc) * * @remarks - * - _id: _id of a JSON document. This is a file name without .json extension. PutResult does not have _id if a document is not {@link JsonDoc} type. + * - _id: _id of a JSON document. This is a file name without ${JSON_EXTENSION} extension. PutResult does not have _id if a document is not {@link JsonDoc} type. * * - name: A file name in Git. e.g.) "foo.json", "bar/baz.md" * @@ -504,7 +504,7 @@ export type PutResultBinary = { * Result of delete() * * @remarks - * - _id: _id of a JSON document. This is a file name without .json extension. PutResult does not have _id if a document is not {@link JsonDoc} type. + * - _id: _id of a JSON document. This is a file name without ${JSON_EXTENSION} extension. PutResult does not have _id if a document is not {@link JsonDoc} type. * * - name: A file name in Git. e.g.) "foo.json", "bar/baz.md" * diff --git a/src/utils.ts b/src/utils.ts index 476183fc..30ce946a 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -23,7 +23,7 @@ import { NormalizedCommit, TextDocMetadata, } from './types'; -import { GIT_DOCUMENTDB_METADATA_DIR, JSON_EXT } from './const'; +import { FRONT_MATTER_POSTFIX, GIT_DOCUMENTDB_METADATA_DIR, JSON_EXTENSION, JSON_POSTFIX } from './const'; /** * @internal @@ -82,6 +82,18 @@ export function toSortedJSONString (obj: Record) { ); } +export function toFrontMatterMarkdown (obj: Record) { + const _body = typeof obj._body === 'string' ? obj._body : ''; + +} + +export function serializeJSON (obj: Record) { + if (JSON_EXTENSION === FRONT_MATTER_POSTFIX) { + return toFrontMatterMarkdown(obj); + } + return toSortedJSONString(obj); +} + /** * Get metadata of all files from current Git index * @@ -141,12 +153,12 @@ export async function getAllMetadata (workingDir: string): Promise { expect(deleteResult._id).toBe(_id); expect(deleteResult.fileOid).toBe(putResult.fileOid); expect(deleteResult.commit.message).toBe( - `delete: users/${_id}${JSON_EXT}(${shortOid})` + `delete: users/${_id}${JSON_EXTENSION}(${shortOid})` ); // Check commit directly @@ -114,7 +114,7 @@ describe('delete(shortId)', () => { dir: gitDDB.workingDir, oid: commitOid, }); - expect(commit.message).toEqual(`delete: users/${_id}${JSON_EXT}(${shortOid})\n`); + expect(commit.message).toEqual(`delete: users/${_id}${JSON_EXTENSION}(${shortOid})\n`); await expect(users.delete(_id)).rejects.toThrowError(Err.DocumentNotFoundError); await expect(users.get(_id)).resolves.toBeUndefined(); @@ -153,7 +153,7 @@ describe('delete(shortId)', () => { expect(deleteResult._id).toBe(_id); expect(deleteResult.fileOid).toBe(putResult.fileOid); expect(deleteResult.commit.message).toBe( - `delete: ${users.collectionPath}${_id}${JSON_EXT}(${shortOid})` + `delete: ${users.collectionPath}${_id}${JSON_EXTENSION}(${shortOid})` ); // Check commit directly @@ -164,7 +164,7 @@ describe('delete(shortId)', () => { oid: commitOid, }); expect(commit.message).toEqual( - `delete: ${users.collectionPath}${_id}${JSON_EXT}(${shortOid})\n` + `delete: ${users.collectionPath}${_id}${JSON_EXTENSION}(${shortOid})\n` ); await expect(users.delete(_id)).rejects.toThrowError(Err.DocumentNotFoundError); @@ -248,7 +248,7 @@ describe('delete(jsonDoc)', () => { // Check NormalizedCommit expect(deleteResult.commit.oid).toBe(currentCommitOid); expect(deleteResult.commit.message).toBe( - `delete: ${users.collectionPath}${_id}${JSON_EXT}(${oid.substr(0, SHORT_SHA_LENGTH)})` + `delete: ${users.collectionPath}${_id}${JSON_EXTENSION}(${oid.substr(0, SHORT_SHA_LENGTH)})` ); expect(deleteResult.commit.parent).toEqual([prevCommitOid]); expect(deleteResult.commit.author.name).toEqual(gitDDB.author.name); @@ -316,11 +316,11 @@ describe('deleteFatDoc(name)', () => { const shortOid = putResult.fileOid.substr(0, SHORT_SHA_LENGTH); // Delete - const deleteResult = (await users.deleteFatDoc(_id + JSON_EXT)) as DeleteResultJsonDoc; + const deleteResult = (await users.deleteFatDoc(_id + JSON_EXTENSION)) as DeleteResultJsonDoc; expect(deleteResult._id).toBe(_id); expect(deleteResult.fileOid).toBe(putResult.fileOid); expect(deleteResult.commit.message).toBe( - `delete: users/${_id}${JSON_EXT}(${shortOid})` + `delete: users/${_id}${JSON_EXTENSION}(${shortOid})` ); // Check commit directly @@ -330,7 +330,7 @@ describe('deleteFatDoc(name)', () => { dir: gitDDB.workingDir, oid: commitOid, }); - expect(commit.message).toEqual(`delete: users/${_id}${JSON_EXT}(${shortOid})\n`); + expect(commit.message).toEqual(`delete: users/${_id}${JSON_EXTENSION}(${shortOid})\n`); await expect(users.delete(_id)).rejects.toThrowError(Err.DocumentNotFoundError); await expect(users.get(_id)).resolves.toBeUndefined(); @@ -365,11 +365,11 @@ describe('deleteFatDoc(name)', () => { const shortOid = putResult.fileOid.substr(0, SHORT_SHA_LENGTH); // Delete - const deleteResult = (await users.deleteFatDoc(_id + JSON_EXT)) as DeleteResultJsonDoc; + const deleteResult = (await users.deleteFatDoc(_id + JSON_EXTENSION)) as DeleteResultJsonDoc; expect(deleteResult._id).toBe(_id); expect(deleteResult.fileOid).toBe(putResult.fileOid); expect(deleteResult.commit.message).toBe( - `delete: ${users.collectionPath}${_id}${JSON_EXT}(${shortOid})` + `delete: ${users.collectionPath}${_id}${JSON_EXTENSION}(${shortOid})` ); // Check commit directly @@ -380,7 +380,7 @@ describe('deleteFatDoc(name)', () => { oid: commitOid, }); expect(commit.message).toEqual( - `delete: ${users.collectionPath}${_id}${JSON_EXT}(${shortOid})\n` + `delete: ${users.collectionPath}${_id}${JSON_EXTENSION}(${shortOid})\n` ); await expect(users.delete(_id)).rejects.toThrowError(Err.DocumentNotFoundError); diff --git a/test/collection_find.test.ts b/test/collection_find.test.ts index deba1746..9f71ba57 100644 --- a/test/collection_find.test.ts +++ b/test/collection_find.test.ts @@ -13,7 +13,7 @@ import git from 'isomorphic-git'; import expect from 'expect'; import { monotonicFactory } from 'ulid'; import { Collection } from '../src/collection'; -import { JSON_EXT } from '../src/const'; +import { JSON_EXTENSION } from '../src/const'; import { toSortedJSONString } from '../src/utils'; import { GitDocumentDB } from '../src/git_documentdb'; import { Err } from '../src/error'; @@ -70,7 +70,7 @@ describe('', () => { const col = new Collection(gitDDB, 'col01'); await addOneData( gitDDB, - col.collectionPath + 'invalidJSON' + JSON_EXT, + col.collectionPath + 'invalidJSON' + JSON_EXTENSION, 'invalidJSON' ); @@ -117,27 +117,27 @@ describe('', () => { await addOneData( gitDDB, - col.collectionPath + _id_b + JSON_EXT, + col.collectionPath + _id_b + JSON_EXTENSION, toSortedJSONString(json_b) ); await addOneData( gitDDB, - col.collectionPath + _id_a + JSON_EXT, + col.collectionPath + _id_a + JSON_EXTENSION, toSortedJSONString(json_a) ); await addOneData( gitDDB, - col.collectionPath + _id_d + JSON_EXT, + col.collectionPath + _id_d + JSON_EXTENSION, toSortedJSONString(json_d) ); await addOneData( gitDDB, - col.collectionPath + _id_c01 + JSON_EXT, + col.collectionPath + _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01) ); await addOneData( gitDDB, - col.collectionPath + _id_c02 + JSON_EXT, + col.collectionPath + _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02) ); @@ -180,37 +180,37 @@ describe('', () => { await addOneData( gitDDB, - col.collectionPath + _id_b + JSON_EXT, + col.collectionPath + _id_b + JSON_EXTENSION, toSortedJSONString(json_b) ); await addOneData( gitDDB, - col.collectionPath + _id_a + JSON_EXT, + col.collectionPath + _id_a + JSON_EXTENSION, toSortedJSONString(json_a) ); await addOneData( gitDDB, - col.collectionPath + _id_d + JSON_EXT, + col.collectionPath + _id_d + JSON_EXTENSION, toSortedJSONString(json_d) ); await addOneData( gitDDB, - col.collectionPath + _id_c000 + JSON_EXT, + col.collectionPath + _id_c000 + JSON_EXTENSION, toSortedJSONString(json_c000) ); await addOneData( gitDDB, - col.collectionPath + _id_c001 + JSON_EXT, + col.collectionPath + _id_c001 + JSON_EXTENSION, toSortedJSONString(json_c001) ); await addOneData( gitDDB, - col.collectionPath + _id_c01 + JSON_EXT, + col.collectionPath + _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01) ); await addOneData( gitDDB, - col.collectionPath + _id_c02 + JSON_EXT, + col.collectionPath + _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02) ); @@ -248,37 +248,37 @@ describe('', () => { await addOneData( gitDDB, - col.collectionPath + _id_b + JSON_EXT, + col.collectionPath + _id_b + JSON_EXTENSION, toSortedJSONString(json_b) ); await addOneData( gitDDB, - col.collectionPath + _id_a + JSON_EXT, + col.collectionPath + _id_a + JSON_EXTENSION, toSortedJSONString(json_a) ); await addOneData( gitDDB, - col.collectionPath + _id_d + JSON_EXT, + col.collectionPath + _id_d + JSON_EXTENSION, toSortedJSONString(json_d) ); await addOneData( gitDDB, - col.collectionPath + _id_c000 + JSON_EXT, + col.collectionPath + _id_c000 + JSON_EXTENSION, toSortedJSONString(json_c000) ); await addOneData( gitDDB, - col.collectionPath + _id_c001 + JSON_EXT, + col.collectionPath + _id_c001 + JSON_EXTENSION, toSortedJSONString(json_c001) ); await addOneData( gitDDB, - col.collectionPath + _id_c01 + JSON_EXT, + col.collectionPath + _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01) ); await addOneData( gitDDB, - col.collectionPath + _id_c02 + JSON_EXT, + col.collectionPath + _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02) ); @@ -319,37 +319,37 @@ describe('', () => { await addOneData( gitDDB, - col.collectionPath + _id_b + JSON_EXT, + col.collectionPath + _id_b + JSON_EXTENSION, toSortedJSONString(json_b) ); await addOneData( gitDDB, - col.collectionPath + _id_a + JSON_EXT, + col.collectionPath + _id_a + JSON_EXTENSION, toSortedJSONString(json_a) ); await addOneData( gitDDB, - col.collectionPath + _id_d + JSON_EXT, + col.collectionPath + _id_d + JSON_EXTENSION, toSortedJSONString(json_d) ); await addOneData( gitDDB, - col.collectionPath + _id_c000 + JSON_EXT, + col.collectionPath + _id_c000 + JSON_EXTENSION, toSortedJSONString(json_c000) ); await addOneData( gitDDB, - col.collectionPath + _id_c001 + JSON_EXT, + col.collectionPath + _id_c001 + JSON_EXTENSION, toSortedJSONString(json_c001) ); await addOneData( gitDDB, - col.collectionPath + _id_c01 + JSON_EXT, + col.collectionPath + _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01) ); await addOneData( gitDDB, - col.collectionPath + _id_c02 + JSON_EXT, + col.collectionPath + _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02) ); @@ -392,37 +392,37 @@ describe('', () => { await addOneData( gitDDB, - col.collectionPath + _id_b + JSON_EXT, + col.collectionPath + _id_b + JSON_EXTENSION, toSortedJSONString(json_b) ); await addOneData( gitDDB, - col.collectionPath + _id_a + JSON_EXT, + col.collectionPath + _id_a + JSON_EXTENSION, toSortedJSONString(json_a) ); await addOneData( gitDDB, - col.collectionPath + _id_d + JSON_EXT, + col.collectionPath + _id_d + JSON_EXTENSION, toSortedJSONString(json_d) ); await addOneData( gitDDB, - col.collectionPath + _id_c000 + JSON_EXT, + col.collectionPath + _id_c000 + JSON_EXTENSION, toSortedJSONString(json_c000) ); await addOneData( gitDDB, - col.collectionPath + _id_c001 + JSON_EXT, + col.collectionPath + _id_c001 + JSON_EXTENSION, toSortedJSONString(json_c001) ); await addOneData( gitDDB, - col.collectionPath + _id_c01 + JSON_EXT, + col.collectionPath + _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01) ); await addOneData( gitDDB, - col.collectionPath + _id_c02 + JSON_EXT, + col.collectionPath + _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02) ); @@ -460,37 +460,37 @@ describe('', () => { await addOneData( gitDDB, - col.collectionPath + _id_b + JSON_EXT, + col.collectionPath + _id_b + JSON_EXTENSION, toSortedJSONString(json_b) ); await addOneData( gitDDB, - col.collectionPath + _id_a + JSON_EXT, + col.collectionPath + _id_a + JSON_EXTENSION, toSortedJSONString(json_a) ); await addOneData( gitDDB, - col.collectionPath + _id_d + JSON_EXT, + col.collectionPath + _id_d + JSON_EXTENSION, toSortedJSONString(json_d) ); await addOneData( gitDDB, - col.collectionPath + _id_c000 + JSON_EXT, + col.collectionPath + _id_c000 + JSON_EXTENSION, toSortedJSONString(json_c000) ); await addOneData( gitDDB, - col.collectionPath + _id_c001 + JSON_EXT, + col.collectionPath + _id_c001 + JSON_EXTENSION, toSortedJSONString(json_c001) ); await addOneData( gitDDB, - col.collectionPath + _id_c01 + JSON_EXT, + col.collectionPath + _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01) ); await addOneData( gitDDB, - col.collectionPath + _id_c02 + JSON_EXT, + col.collectionPath + _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02) ); @@ -531,43 +531,43 @@ describe('', () => { await addOneData( gitDDB, - col.collectionPath + _id_p + JSON_EXT, + col.collectionPath + _id_p + JSON_EXTENSION, toSortedJSONString(json_p) ); await addOneData( gitDDB, - col.collectionPath + _id_b + JSON_EXT, + col.collectionPath + _id_b + JSON_EXTENSION, toSortedJSONString(json_b) ); await addOneData( gitDDB, - col.collectionPath + _id_a + JSON_EXT, + col.collectionPath + _id_a + JSON_EXTENSION, toSortedJSONString(json_a) ); await addOneData( gitDDB, - col.collectionPath + _id_d + JSON_EXT, + col.collectionPath + _id_d + JSON_EXTENSION, toSortedJSONString(json_d) ); await addOneData( gitDDB, - col.collectionPath + _id_c000 + JSON_EXT, + col.collectionPath + _id_c000 + JSON_EXTENSION, toSortedJSONString(json_c000) ); await addOneData( gitDDB, - col.collectionPath + _id_c001 + JSON_EXT, + col.collectionPath + _id_c001 + JSON_EXTENSION, toSortedJSONString(json_c001) ); await addOneData( gitDDB, - col.collectionPath + _id_c01 + JSON_EXT, + col.collectionPath + _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01) ); await addOneData( gitDDB, - col.collectionPath + _id_c02 + JSON_EXT, + col.collectionPath + _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02) ); @@ -608,43 +608,43 @@ describe('', () => { await addOneData( gitDDB, - col.collectionPath + _id_p + JSON_EXT, + col.collectionPath + _id_p + JSON_EXTENSION, toSortedJSONString(json_p) ); await addOneData( gitDDB, - col.collectionPath + _id_b + JSON_EXT, + col.collectionPath + _id_b + JSON_EXTENSION, toSortedJSONString(json_b) ); await addOneData( gitDDB, - col.collectionPath + _id_a + JSON_EXT, + col.collectionPath + _id_a + JSON_EXTENSION, toSortedJSONString(json_a) ); await addOneData( gitDDB, - col.collectionPath + _id_d + JSON_EXT, + col.collectionPath + _id_d + JSON_EXTENSION, toSortedJSONString(json_d) ); await addOneData( gitDDB, - col.collectionPath + _id_c000 + JSON_EXT, + col.collectionPath + _id_c000 + JSON_EXTENSION, toSortedJSONString(json_c000) ); await addOneData( gitDDB, - col.collectionPath + _id_c001 + JSON_EXT, + col.collectionPath + _id_c001 + JSON_EXTENSION, toSortedJSONString(json_c001) ); await addOneData( gitDDB, - col.collectionPath + _id_c01 + JSON_EXT, + col.collectionPath + _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01) ); await addOneData( gitDDB, - col.collectionPath + _id_c02 + JSON_EXT, + col.collectionPath + _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02) ); @@ -681,62 +681,62 @@ describe('', () => { await addOneData( gitDDB, - col.collectionPath + _id_b + JSON_EXT, + col.collectionPath + _id_b + JSON_EXTENSION, toSortedJSONString(json_b) ); await addOneData( gitDDB, - col.collectionPath + _id_a + JSON_EXT, + col.collectionPath + _id_a + JSON_EXTENSION, toSortedJSONString(json_a) ); await addOneData( gitDDB, - col.collectionPath + _id_d + JSON_EXT, + col.collectionPath + _id_d + JSON_EXTENSION, toSortedJSONString(json_d) ); await addOneData( gitDDB, - col.collectionPath + _id_c01 + JSON_EXT, + col.collectionPath + _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01) ); await addOneData( gitDDB, - col.collectionPath + _id_c02 + JSON_EXT, + col.collectionPath + _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02) ); await expect(col.findFatDoc()).resolves.toEqual([ { _id: _id_a, - name: _id_a + JSON_EXT, + name: _id_a + JSON_EXTENSION, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_a) })).oid, type: 'json', doc: json_a_, }, { _id: _id_b, - name: _id_b + JSON_EXT, + name: _id_b + JSON_EXTENSION, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_b) })).oid, type: 'json', doc: json_b_, }, { _id: _id_c01, - name: _id_c01 + JSON_EXT, + name: _id_c01 + JSON_EXTENSION, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_c01) })).oid, type: 'json', doc: json_c01_, }, { _id: _id_c02, - name: _id_c02 + JSON_EXT, + name: _id_c02 + JSON_EXTENSION, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_c02) })).oid, type: 'json', doc: json_c02_, }, { _id: _id_d, - name: _id_d + JSON_EXT, + name: _id_d + JSON_EXTENSION, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_d) })).oid, type: 'json', doc: json_d_, diff --git a/test/collection_get.test.ts b/test/collection_get.test.ts index 7054198f..ec11c05e 100644 --- a/test/collection_get.test.ts +++ b/test/collection_get.test.ts @@ -12,7 +12,7 @@ import fs from 'fs-extra'; import git from 'isomorphic-git'; import expect from 'expect'; import { monotonicFactory } from 'ulid'; -import { JSON_EXT } from '../src/const'; +import { JSON_EXTENSION } from '../src/const'; import { Collection } from '../src/collection'; import { sleep, toSortedJSONString } from '../src/utils'; import { GitDocumentDB } from '../src/git_documentdb'; @@ -69,7 +69,7 @@ describe(' get()', () => { const col = new Collection(gitDDB, 'col01'); const shortId = 'prof01'; - const fullDocPath = col.collectionPath + shortId + JSON_EXT; + const fullDocPath = col.collectionPath + shortId + JSON_EXTENSION; await addOneData(gitDDB, fullDocPath, 'invalid data'); await expect(col.get(shortId)).rejects.toThrowError(Err.InvalidJsonObjectError); @@ -86,7 +86,7 @@ describe(' get()', () => { await gitDDB.open(); const col = new Collection(gitDDB, 'col01'); const shortId = 'prof01'; - const fullDocPath = col.collectionPath + shortId + JSON_EXT; + const fullDocPath = col.collectionPath + shortId + JSON_EXTENSION; const json01 = { _id: shortId, name: 'v1' }; const json02 = { _id: shortId, name: 'v2' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json01)); @@ -119,7 +119,7 @@ describe(' get()', () => { await gitDDB.open(); const col = new Collection(gitDDB, 'col01'); const shortId = 'prof01'; - const fullDocPath = col.collectionPath + shortId + JSON_EXT; + const fullDocPath = col.collectionPath + shortId + JSON_EXTENSION; const json01 = { _id: shortId, name: 'v1' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json01)); await removeOneData(gitDDB, fullDocPath); @@ -137,7 +137,7 @@ describe(' get()', () => { await gitDDB.open(); const col = new Collection(gitDDB, 'col01/col02/col03/'); const shortId = 'dir01/prof01'; - const fullDocPath = col.collectionPath + shortId + JSON_EXT; + const fullDocPath = col.collectionPath + shortId + JSON_EXTENSION; const json01 = { _id: shortId, name: 'v1' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json01)); @@ -154,7 +154,7 @@ describe(' get()', () => { await gitDDB.open(); const col = new Collection(gitDDB, 'dir01/dir02/dir03'); const shortId = 'prof01'; - const fullDocPath = col.collectionPath + shortId + JSON_EXT; + const fullDocPath = col.collectionPath + shortId + JSON_EXTENSION; const json01 = { _id: shortId, name: 'v1' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json01)); @@ -174,8 +174,8 @@ describe(' getFatDoc()', () => { await gitDDB.open(); const col = new Collection(gitDDB); const shortId = 'prof01'; - const shortName = shortId + JSON_EXT; - const fullDocPath = col.collectionPath + shortId + JSON_EXT; + const shortName = shortId + JSON_EXTENSION; + const fullDocPath = col.collectionPath + shortId + JSON_EXTENSION; const json01 = { _id: shortId, name: 'v1' }; const json02 = { _id: shortId, name: 'v2' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json01)); @@ -200,7 +200,7 @@ describe(' getFatDoc()', () => { await gitDDB.open(); const col = new Collection(gitDDB); const shortId = 'prof01'; - const shortName = shortId + JSON_EXT; + const shortName = shortId + JSON_EXTENSION; await expect(col.getFatDoc(shortName)).resolves.toBeUndefined(); await gitDDB.destroy(); @@ -217,7 +217,7 @@ describe(' getDocByOid()', () => { await gitDDB.open(); const col = new Collection(gitDDB, 'col01/col02/col03/'); const shortId = 'dir01/prof01'; - const fullDocPath = col.collectionPath + shortId + JSON_EXT; + const fullDocPath = col.collectionPath + shortId + JSON_EXTENSION; const json01 = { _id: shortId, name: 'v1' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json01)); const { oid } = await git.hashBlob({ object: toSortedJSONString(json01) }); @@ -234,7 +234,7 @@ describe(' getDocByOid()', () => { await gitDDB.open(); const col = new Collection(gitDDB, 'col01/col02/col03/'); const shortId = 'dir01/prof01'; - const fullDocPath = col.collectionPath + shortId + JSON_EXT; + const fullDocPath = col.collectionPath + shortId + JSON_EXTENSION; const json01 = { _id: shortId, name: 'v1' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json01)); await expect(col.getDocByOid('not exist', 'json')).resolves.toBeUndefined(); @@ -250,7 +250,7 @@ describe(' getDocByOid()', () => { await gitDDB.open(); const col = new Collection(gitDDB, 'col01/col02/col03/'); const shortId = 'dir01/prof01'; - const shortName = shortId + JSON_EXT; + const shortName = shortId + JSON_EXTENSION; const fullDocPath = col.collectionPath + shortName; // JsonDoc without _id const json01 = { name: 'v1' }; @@ -269,10 +269,10 @@ describe('', () => { }); const targetId = '01'; - const targetName = targetId + JSON_EXT; + const targetName = targetId + JSON_EXTENSION; const collectionPath = 'col01/'; const col = new Collection(gitDDB, collectionPath); - const fullDocPath = collectionPath + targetId + JSON_EXT; + const fullDocPath = collectionPath + targetId + JSON_EXTENSION; const json01 = { _id: collectionPath + targetId, name: 'v01' }; const json02 = { _id: collectionPath + targetId, name: 'v02' }; @@ -720,7 +720,7 @@ describe(' getFatDocHistory()', () => { const col = new Collection(gitDDB, 'col01'); const _idA = 'profA'; - const shortNameA = _idA + JSON_EXT; + const shortNameA = _idA + JSON_EXTENSION; const jsonA01 = { _id: _idA, name: 'v01' }; const jsonA02 = { _id: _idA, name: 'v02' }; const jsonA03 = { _id: _idA, name: 'v03' }; @@ -728,7 +728,7 @@ describe(' getFatDocHistory()', () => { await col.put(jsonA02); await col.put(jsonA03); const _idB = 'profB'; - const shortNameB = _idB + JSON_EXT; + const shortNameB = _idB + JSON_EXTENSION; const jsonB01 = { _id: _idB, name: 'v01' }; const jsonB02 = { _id: _idB, name: 'v02' }; await col.put(jsonB01); @@ -757,7 +757,7 @@ describe(' getFatDocHistory()', () => { await gitDDB.open(); const col = new Collection(gitDDB, 'col01'); const _idA = 'profA'; - const shortNameA = _idA + JSON_EXT; + const shortNameA = _idA + JSON_EXTENSION; const jsonA01 = { _id: _idA, name: 'v01' }; const jsonA02 = { _id: _idA, name: 'v02' }; const jsonA03 = { _id: _idA, name: 'v03' }; @@ -772,7 +772,7 @@ describe(' getFatDocHistory()', () => { await col.put(jsonA03); const _idB = 'profB'; - const shortNameB = _idB + JSON_EXT; + const shortNameB = _idB + JSON_EXTENSION; const jsonB01 = { _id: _idB, name: 'v01' }; const jsonB02 = { _id: _idB, name: 'v02' }; diff --git a/test/collection_insert.test.ts b/test/collection_insert.test.ts index f1595dab..168cb586 100644 --- a/test/collection_insert.test.ts +++ b/test/collection_insert.test.ts @@ -14,7 +14,7 @@ import expect from 'expect'; import { monotonicFactory } from 'ulid'; import { PutResultJsonDoc } from '../src/types'; import { Collection } from '../src/collection'; -import { JSON_EXT, SHORT_SHA_LENGTH } from '../src/const'; +import { JSON_EXTENSION, SHORT_SHA_LENGTH } from '../src/const'; import { toSortedJSONString } from '../src/utils'; import { GitDocumentDB } from '../src/git_documentdb'; import { Err } from '../src/error'; @@ -87,7 +87,7 @@ describe(' insert(jsonDoc)', () => { expect(putResult.fileOid).toBe(fileOid); expect(putResult.commit.oid).toBe(currentCommitOid); expect(putResult.commit.message).toBe( - `insert: ${col.collectionPath}${_id}${JSON_EXT}(${shortOid})` + `insert: ${col.collectionPath}${_id}${JSON_EXTENSION}(${shortOid})` ); expect(putResult.commit.parent).toEqual([prevCommitOid]); @@ -101,7 +101,7 @@ describe(' insert(jsonDoc)', () => { expect(putResult.commit.committer.timestamp).toBeLessThanOrEqual(afterTimestamp); // fs.access() throw error when a file cannot be accessed. - const filePath = path.resolve(gitDDB.workingDir, col.collectionPath, _id + JSON_EXT); + const filePath = path.resolve(gitDDB.workingDir, col.collectionPath, _id + JSON_EXTENSION); await expect(fs.access(filePath)).resolves.not.toThrowError(); expect(fs.readFileSync(filePath, 'utf8')).toBe(toSortedJSONString(internalJson)); @@ -145,7 +145,7 @@ describe(' insert(jsonDoc)', () => { const fileOid = (await git.hashBlob({ object: toSortedJSONString(internalJson) })).oid; const shortOid = fileOid.substr(0, SHORT_SHA_LENGTH); expect(putResult.commit.message).toBe( - `insert: ${col.collectionPath}${_id}${JSON_EXT}(${shortOid})` + `insert: ${col.collectionPath}${_id}${JSON_EXTENSION}(${shortOid})` ); await gitDDB.destroy(); @@ -204,7 +204,7 @@ describe(' insert(shortId, jsonDoc)', () => { expect(putResult.fileOid).toBe(fileOid); expect(putResult.commit.oid).toBe(currentCommitOid); expect(putResult.commit.message).toBe( - `insert: ${col.collectionPath}${_id}${JSON_EXT}(${shortOid})` + `insert: ${col.collectionPath}${_id}${JSON_EXTENSION}(${shortOid})` ); expect(putResult.commit.parent).toEqual([prevCommitOid]); @@ -218,7 +218,7 @@ describe(' insert(shortId, jsonDoc)', () => { expect(putResult.commit.committer.timestamp).toBeLessThanOrEqual(afterTimestamp); // fs.access() throw error when a file cannot be accessed. - const filePath = path.resolve(gitDDB.workingDir, col.collectionPath, _id + JSON_EXT); + const filePath = path.resolve(gitDDB.workingDir, col.collectionPath, _id + JSON_EXTENSION); await expect(fs.access(filePath)).resolves.not.toThrowError(); expect(fs.readFileSync(filePath, 'utf8')).toBe(toSortedJSONString(internalJson)); @@ -264,7 +264,7 @@ describe(' insertFatDoc(shortName, jsonDoc)', () => { const col = new Collection(gitDDB, 'col01'); const _id = 'prof01'; - const shortName = _id + JSON_EXT; + const shortName = _id + JSON_EXTENSION; const json = { _id, name: 'Shirase' }; const internalJson = JSON.parse(JSON.stringify(json)); internalJson._id = col.collectionPath + _id; @@ -286,7 +286,7 @@ describe(' insertFatDoc(shortName, jsonDoc)', () => { expect(putResult.fileOid).toBe(fileOid); expect(putResult.commit.oid).toBe(currentCommitOid); expect(putResult.commit.message).toBe( - `insert: ${col.collectionPath}${_id}${JSON_EXT}(${shortOid})` + `insert: ${col.collectionPath}${_id}${JSON_EXTENSION}(${shortOid})` ); expect(putResult.commit.parent).toEqual([prevCommitOid]); @@ -300,7 +300,7 @@ describe(' insertFatDoc(shortName, jsonDoc)', () => { expect(putResult.commit.committer.timestamp).toBeLessThanOrEqual(afterTimestamp); // fs.access() throw error when a file cannot be accessed. - const filePath = path.resolve(gitDDB.workingDir, col.collectionPath, _id + JSON_EXT); + const filePath = path.resolve(gitDDB.workingDir, col.collectionPath, _id + JSON_EXTENSION); await expect(fs.access(filePath)).resolves.not.toThrowError(); expect(fs.readFileSync(filePath, 'utf8')).toBe(toSortedJSONString(internalJson)); diff --git a/test/collection_put.test.ts b/test/collection_put.test.ts index 434294a1..11d52ac5 100644 --- a/test/collection_put.test.ts +++ b/test/collection_put.test.ts @@ -14,7 +14,7 @@ import fs from 'fs-extra'; import { monotonicFactory } from 'ulid'; import { PutResultJsonDoc } from '../src/types'; import { toSortedJSONString } from '../src/utils'; -import { JSON_EXT, SHORT_SHA_LENGTH } from '../src/const'; +import { JSON_EXTENSION, SHORT_SHA_LENGTH } from '../src/const'; import { GitDocumentDB } from '../src/git_documentdb'; import { Err } from '../src/error'; import { Collection } from '../src/collection'; @@ -247,12 +247,12 @@ describe('', () => { oid: commitOid, }); expect(commit.message).toEqual( - `insert: ${col.collectionPath}${_id}${JSON_EXT}(${shortOid})\n` + `insert: ${col.collectionPath}${_id}${JSON_EXTENSION}(${shortOid})\n` ); // Check filename // fs.access() throw error when a file cannot be accessed. - const filePath = path.resolve(gitDDB.workingDir, col.collectionPath, _id + JSON_EXT); + const filePath = path.resolve(gitDDB.workingDir, col.collectionPath, _id + JSON_EXTENSION); await expect(fs.access(filePath)).resolves.not.toThrowError(); // Read JSON and check doc._id expect(fs.readJSONSync(filePath)._id).toBe(col.collectionPath + _id); @@ -298,7 +298,7 @@ describe('', () => { expect(putResult.fileOid).toBe(fileOid); expect(putResult.commit.oid).toBe(currentCommitOid); expect(putResult.commit.message).toBe( - `insert: ${col.collectionPath}${_id}${JSON_EXT}(${shortOid})` + `insert: ${col.collectionPath}${_id}${JSON_EXTENSION}(${shortOid})` ); expect(putResult.commit.parent).toEqual([prevCommitOid]); @@ -312,7 +312,7 @@ describe('', () => { expect(putResult.commit.committer.timestamp).toBeLessThanOrEqual(afterTimestamp); // fs.access() throw error when a file cannot be accessed. - const filePath = path.resolve(gitDDB.workingDir, col.collectionPath, _id + JSON_EXT); + const filePath = path.resolve(gitDDB.workingDir, col.collectionPath, _id + JSON_EXTENSION); await expect(fs.access(filePath)).resolves.not.toThrowError(); expect(fs.readFileSync(filePath, 'utf8')).toBe(toSortedJSONString(internalJson)); @@ -337,7 +337,7 @@ describe('', () => { .oid; const shortOid = fileOid.substr(0, SHORT_SHA_LENGTH); expect(putResult.commit.message).toBe( - `insert: ${col.collectionPath}${_id}${JSON_EXT}(${shortOid})` + `insert: ${col.collectionPath}${_id}${JSON_EXTENSION}(${shortOid})` ); await gitDDB.destroy(); @@ -361,7 +361,7 @@ describe('', () => { // fs.access() throw error when a file cannot be accessed. const filePath = path.resolve( gitDDB.workingDir, - col.collectionPath + _id + JSON_EXT + col.collectionPath + _id + JSON_EXTENSION ); await expect(fs.access(filePath)).resolves.not.toThrowError(); // Read JSON and check doc._id @@ -387,14 +387,14 @@ describe('', () => { await git.hashBlob({ object: toSortedJSONString(internalJson) }) ).oid.substr(0, SHORT_SHA_LENGTH); expect(putResult.commit.message).toBe( - `insert: ${col.collectionPath}${_id}${JSON_EXT}(${shortOid})` + `insert: ${col.collectionPath}${_id}${JSON_EXTENSION}(${shortOid})` ); // Check filename // fs.access() throw error when a file cannot be accessed. const filePath = path.resolve( gitDDB.workingDir, - col.collectionPath + _id + JSON_EXT + col.collectionPath + _id + JSON_EXTENSION ); await expect(fs.access(filePath)).resolves.not.toThrowError(); expect(fs.readFileSync(filePath, 'utf8')).toBe(toSortedJSONString(internalJson)); @@ -411,7 +411,7 @@ describe('', () => { oid: commitOid, }); expect(commit.message).toEqual( - `insert: ${col.collectionPath}${_id}${JSON_EXT}(${shortOid})\n` + `insert: ${col.collectionPath}${_id}${JSON_EXTENSION}(${shortOid})\n` ); gitDDB.destroy(); @@ -497,7 +497,7 @@ describe('', () => { const putResult = await col.put(updatedJson); expect(putResult.commit.message).toBe( - `update: ${col.collectionPath}${_id}${JSON_EXT}(${fileOid.substr( + `update: ${col.collectionPath}${_id}${JSON_EXTENSION}(${fileOid.substr( 0, SHORT_SHA_LENGTH )})` @@ -624,7 +624,7 @@ describe('', () => { expect(putResult.fileOid).toBe(fileOid); expect(putResult.commit.oid).toBe(currentCommitOid); expect(putResult.commit.message).toBe( - `insert: ${col.collectionPath}${_id}${JSON_EXT}(${shortOid})` + `insert: ${col.collectionPath}${_id}${JSON_EXTENSION}(${shortOid})` ); expect(putResult.commit.parent).toEqual([prevCommitOid]); @@ -638,7 +638,7 @@ describe('', () => { expect(putResult.commit.committer.timestamp).toBeLessThanOrEqual(afterTimestamp); // fs.access() throw error when a file cannot be accessed. - const filePath = path.resolve(gitDDB.workingDir, col.collectionPath, _id + JSON_EXT); + const filePath = path.resolve(gitDDB.workingDir, col.collectionPath, _id + JSON_EXTENSION); await expect(fs.access(filePath)).resolves.not.toThrowError(); expect(fs.readFileSync(filePath, 'utf8')).toBe(toSortedJSONString(internalJson)); @@ -693,14 +693,14 @@ describe('', () => { expect(putResult._id).toBe(_id); expect(putResult.commit.message).toBe( - `insert: ${col.collectionPath}${_id}${JSON_EXT}(${shortOid})` + `insert: ${col.collectionPath}${_id}${JSON_EXTENSION}(${shortOid})` ); // _id of original json must not be overwritten expect(json._id).toBe('id-in-doc'); // fs.access() throw error when a file cannot be accessed. - const fullDocPath = col.collectionPath + _id + JSON_EXT; + const fullDocPath = col.collectionPath + _id + JSON_EXTENSION; const filePath = path.resolve(gitDDB.workingDir, fullDocPath); await expect(fs.access(filePath)).resolves.not.toThrowError(); expect(fs.readFileSync(filePath, 'utf8')).toBe(toSortedJSONString(internalJson)); @@ -728,7 +728,7 @@ describe('', () => { 'A': 'A', }); - const filePath = path.resolve(gitDDB.workingDir, col.collectionPath + 'id' + JSON_EXT); + const filePath = path.resolve(gitDDB.workingDir, col.collectionPath + 'id' + JSON_EXTENSION); const jsonStr = fs.readFileSync(filePath, 'utf8'); expect(jsonStr).toBe(`{ "1": 1, @@ -771,7 +771,7 @@ describe('', () => { const filePath = path.resolve( gitDDB.workingDir, col.collectionPath, - putResult._id + JSON_EXT + putResult._id + JSON_EXTENSION ); await expect(fs.access(filePath)).resolves.not.toThrowError(); @@ -809,7 +809,7 @@ describe('', () => { const col = new Collection(gitDDB, 'col01'); const _id = 'dir01/prof01'; - const shortName = _id + JSON_EXT; + const shortName = _id + JSON_EXTENSION; // Check put operation const json = { _id, name: 'Shirase' }; @@ -833,7 +833,7 @@ describe('', () => { expect(putResult.fileOid).toBe(fileOid); expect(putResult.commit.oid).toBe(currentCommitOid); expect(putResult.commit.message).toBe( - `insert: ${col.collectionPath}${_id}${JSON_EXT}(${shortOid})` + `insert: ${col.collectionPath}${_id}${JSON_EXTENSION}(${shortOid})` ); expect(putResult.commit.parent).toEqual([prevCommitOid]); @@ -847,7 +847,7 @@ describe('', () => { expect(putResult.commit.committer.timestamp).toBeLessThanOrEqual(afterTimestamp); // fs.access() throw error when a file cannot be accessed. - const filePath = path.resolve(gitDDB.workingDir, col.collectionPath, _id + JSON_EXT); + const filePath = path.resolve(gitDDB.workingDir, col.collectionPath, _id + JSON_EXTENSION); await expect(fs.access(filePath)).resolves.not.toThrowError(); expect(fs.readFileSync(filePath, 'utf8')).toBe(toSortedJSONString(internalJson)); diff --git a/test/collection_update.test.ts b/test/collection_update.test.ts index 8e997d50..7f887ddd 100644 --- a/test/collection_update.test.ts +++ b/test/collection_update.test.ts @@ -17,7 +17,7 @@ import { Err } from '../src/error'; import { GitDocumentDB } from '../src/git_documentdb'; import { Collection } from '../src/collection'; import { toSortedJSONString } from '../src/utils'; -import { JSON_EXT, SHORT_SHA_LENGTH } from '../src/const'; +import { JSON_EXTENSION, SHORT_SHA_LENGTH } from '../src/const'; const ulid = monotonicFactory(); const monoId = () => { @@ -85,7 +85,7 @@ describe(' update(jsonDoc)', () => { expect(putResult.fileOid).toBe(fileOid); expect(putResult.commit.oid).toBe(currentCommitOid); expect(putResult.commit.message).toBe( - `update: ${col.collectionPath}${_id}${JSON_EXT}(${shortOid})` + `update: ${col.collectionPath}${_id}${JSON_EXTENSION}(${shortOid})` ); expect(putResult.commit.parent).toEqual([prevCommitOid]); @@ -99,7 +99,7 @@ describe(' update(jsonDoc)', () => { expect(putResult.commit.committer.timestamp).toBeLessThanOrEqual(afterTimestamp); // fs.access() throw error when a file cannot be accessed. - const filePath = path.resolve(gitDDB.workingDir, col.collectionPath, _id + JSON_EXT); + const filePath = path.resolve(gitDDB.workingDir, col.collectionPath, _id + JSON_EXTENSION); await expect(fs.access(filePath)).resolves.not.toThrowError(); expect(fs.readFileSync(filePath, 'utf8')).toBe(toSortedJSONString(internalJson)); @@ -147,7 +147,7 @@ describe(' update(jsonDoc)', () => { const fileOid = (await git.hashBlob({ object: toSortedJSONString(internalJson) })).oid; const shortOid = fileOid.substr(0, SHORT_SHA_LENGTH); expect(putResult.commit.message).toBe( - `update: ${col.collectionPath}${_id}${JSON_EXT}(${shortOid})` + `update: ${col.collectionPath}${_id}${JSON_EXTENSION}(${shortOid})` ); await gitDDB.destroy(); @@ -204,7 +204,7 @@ describe(' update(shortId, jsonDoc)', () => { expect(putResult.fileOid).toBe(fileOid); expect(putResult.commit.oid).toBe(currentCommitOid); expect(putResult.commit.message).toBe( - `update: ${col.collectionPath}${_id}${JSON_EXT}(${shortOid})` + `update: ${col.collectionPath}${_id}${JSON_EXTENSION}(${shortOid})` ); expect(putResult.commit.parent).toEqual([prevCommitOid]); @@ -218,7 +218,7 @@ describe(' update(shortId, jsonDoc)', () => { expect(putResult.commit.committer.timestamp).toBeLessThanOrEqual(afterTimestamp); // fs.access() throw error when a file cannot be accessed. - const filePath = path.resolve(gitDDB.workingDir, col.collectionPath, _id + JSON_EXT); + const filePath = path.resolve(gitDDB.workingDir, col.collectionPath, _id + JSON_EXTENSION); await expect(fs.access(filePath)).resolves.not.toThrowError(); expect(fs.readFileSync(filePath, 'utf8')).toBe(toSortedJSONString(internalJson)); @@ -259,7 +259,7 @@ describe(' updateFatDoc(shortName, jsonDoc)', () => { await gitDDB.open(); const col = new Collection(gitDDB, 'col01'); const _id = 'prof01'; - const shortName = _id + JSON_EXT; + const shortName = _id + JSON_EXTENSION; const json = { _id, name: 'Shirase' }; const insertResult = await col.insert(json); @@ -286,7 +286,7 @@ describe(' updateFatDoc(shortName, jsonDoc)', () => { expect(putResult.fileOid).toBe(fileOid); expect(putResult.commit.oid).toBe(currentCommitOid); expect(putResult.commit.message).toBe( - `update: ${col.collectionPath}${_id}${JSON_EXT}(${shortOid})` + `update: ${col.collectionPath}${_id}${JSON_EXTENSION}(${shortOid})` ); expect(putResult.commit.parent).toEqual([prevCommitOid]); @@ -300,7 +300,7 @@ describe(' updateFatDoc(shortName, jsonDoc)', () => { expect(putResult.commit.committer.timestamp).toBeLessThanOrEqual(afterTimestamp); // fs.access() throw error when a file cannot be accessed. - const filePath = path.resolve(gitDDB.workingDir, col.collectionPath, _id + JSON_EXT); + const filePath = path.resolve(gitDDB.workingDir, col.collectionPath, _id + JSON_EXTENSION); await expect(fs.access(filePath)).resolves.not.toThrowError(); expect(fs.readFileSync(filePath, 'utf8')).toBe(toSortedJSONString(internalJson)); diff --git a/test/crud/blob.test.ts b/test/crud/blob.test.ts index ef58f97f..87691bd5 100644 --- a/test/crud/blob.test.ts +++ b/test/crud/blob.test.ts @@ -24,7 +24,7 @@ import { import { Err } from '../../src/error'; import { GitDocumentDB } from '../../src/git_documentdb'; import { toSortedJSONString, utf8encode } from '../../src/utils'; -import { JSON_EXT } from '../../src/const'; +import { JSON_EXTENSION } from '../../src/const'; // eslint-disable-next-line @typescript-eslint/no-var-requires const git_module = require('isomorphic-git'); @@ -101,7 +101,7 @@ describe('', () => { }; expect(blobToJsonDoc(shortId, readBlobResult, true)).toEqual({ _id: shortId, - name: shortId + JSON_EXT, + name: shortId + JSON_EXTENSION, fileOid, type: 'json', doc: json, diff --git a/test/crud/delete.test.ts b/test/crud/delete.test.ts index a9508299..ea036761 100644 --- a/test/crud/delete.test.ts +++ b/test/crud/delete.test.ts @@ -13,7 +13,7 @@ import fs from 'fs-extra'; import git from 'isomorphic-git'; import expect from 'expect'; import sinon from 'sinon'; -import { JSON_EXT, SHORT_SHA_LENGTH } from '../../src/const'; +import { JSON_EXTENSION, SHORT_SHA_LENGTH } from '../../src/const'; import { Err } from '../../src/error'; import { GitDocumentDB } from '../../src/git_documentdb'; import { deleteImpl, deleteWorker } from '../../src/crud/delete'; @@ -67,7 +67,7 @@ describe('', () => { // Call close() without await gitDDB.close().catch(() => {}); const _id = 'prof01'; - await expect(deleteImpl(gitDDB, '', _id, _id + JSON_EXT)).rejects.toThrowError( + await expect(deleteImpl(gitDDB, '', _id, _id + JSON_EXTENSION)).rejects.toThrowError( Err.DatabaseClosingError ); @@ -116,7 +116,7 @@ describe('', () => { const putResult = await gitDDB.put(json); await expect( - deleteImpl(gitDDB, '', _id, _id + JSON_EXT + '_invalid') + deleteImpl(gitDDB, '', _id, _id + JSON_EXTENSION + '_invalid') ).rejects.toThrowError(Err.DocumentNotFoundError); await gitDDB.destroy(); @@ -139,7 +139,7 @@ describe('', () => { // Delete const { oid } = await git.hashBlob({ object: toSortedJSONString(json) }); const beforeTimestamp = Math.floor(Date.now() / 1000) * 1000; - const pickedDeleteResult = await deleteImpl(gitDDB, '', _id, _id + JSON_EXT); + const pickedDeleteResult = await deleteImpl(gitDDB, '', _id, _id + JSON_EXTENSION); const afterTimestamp = Math.floor(Date.now() / 1000) * 1000; const currentCommitOid = await git.resolveRef({ @@ -151,7 +151,7 @@ describe('', () => { // Check NormalizedCommit expect(pickedDeleteResult.commit.oid).toBe(currentCommitOid); expect(pickedDeleteResult.commit.message).toBe( - `delete: ${_id}${JSON_EXT}(${oid.substr(0, SHORT_SHA_LENGTH)})` + `delete: ${_id}${JSON_EXTENSION}(${oid.substr(0, SHORT_SHA_LENGTH)})` ); expect(pickedDeleteResult.commit.parent).toEqual([prevCommitOid]); expect(pickedDeleteResult.commit.author.name).toEqual(gitDDB.author.name); @@ -188,10 +188,10 @@ describe('', () => { // Delete const shortOid = putResult.fileOid.substr(0, SHORT_SHA_LENGTH); - const pickedDeleteResult = await deleteImpl(gitDDB, '', _id, _id + JSON_EXT); + const pickedDeleteResult = await deleteImpl(gitDDB, '', _id, _id + JSON_EXTENSION); expect(pickedDeleteResult.commit.message).toEqual( - `delete: ${_id}${JSON_EXT}(${shortOid})` + `delete: ${_id}${JSON_EXTENSION}(${shortOid})` ); // Check commit directly @@ -201,7 +201,7 @@ describe('', () => { dir: gitDDB.workingDir, oid: commitOid, }); - expect(commit.message).toEqual(`delete: ${_id}${JSON_EXT}(${shortOid})\n`); + expect(commit.message).toEqual(`delete: ${_id}${JSON_EXTENSION}(${shortOid})\n`); await gitDDB.destroy(); }); @@ -219,11 +219,11 @@ describe('', () => { const putResult = await gitDDB.put(doc); // Delete - const deleteResult = await deleteImpl(gitDDB, '', _id, _id + JSON_EXT); + const deleteResult = await deleteImpl(gitDDB, '', _id, _id + JSON_EXTENSION); const shortOid = putResult.fileOid.substr(0, SHORT_SHA_LENGTH); expect(deleteResult.fileOid).toBe(putResult.fileOid); - expect(deleteResult.commit.message).toBe(`delete: ${_id}${JSON_EXT}(${shortOid})`); + expect(deleteResult.commit.message).toBe(`delete: ${_id}${JSON_EXTENSION}(${shortOid})`); // Check commit directly const commitOid = await git.resolveRef({ fs, dir: gitDDB.workingDir, ref: 'HEAD' }); @@ -232,7 +232,7 @@ describe('', () => { dir: gitDDB.workingDir, oid: commitOid, }); - expect(commit.message).toEqual(`delete: ${_id}${JSON_EXT}(${shortOid})\n`); + expect(commit.message).toEqual(`delete: ${_id}${JSON_EXTENSION}(${shortOid})\n`); await gitDDB.destroy(); }); @@ -269,17 +269,17 @@ describe('', () => { ]); await Promise.all([ - deleteImpl(gitDDB, '', _id_a, _id_a + JSON_EXT), - deleteImpl(gitDDB, '', _id_b, _id_b + JSON_EXT), - deleteImpl(gitDDB, '', _id_c01, _id_c01 + JSON_EXT), - deleteImpl(gitDDB, '', _id_c02, _id_c02 + JSON_EXT), - deleteImpl(gitDDB, '', _id_d, _id_d + JSON_EXT), + deleteImpl(gitDDB, '', _id_a, _id_a + JSON_EXTENSION), + deleteImpl(gitDDB, '', _id_b, _id_b + JSON_EXTENSION), + deleteImpl(gitDDB, '', _id_c01, _id_c01 + JSON_EXTENSION), + deleteImpl(gitDDB, '', _id_c02, _id_c02 + JSON_EXTENSION), + deleteImpl(gitDDB, '', _id_d, _id_d + JSON_EXTENSION), ]); await expect(gitDDB.findFatDoc({ recursive: true })).resolves.toEqual([ { _id: _id_p, - name: _id_p + JSON_EXT, + name: _id_p + JSON_EXTENSION, fileOid: expect.stringMatching(/^[\da-z]{40}$/), type: 'json', doc: { _id: _id_p, name: name_p }, @@ -384,7 +384,7 @@ describe('', () => { const stubEnsureDir = sandbox.stub(fs_module, 'remove'); stubEnsureDir.rejects(); - await expect(deleteWorker(gitDDB, '', 'prof01' + JSON_EXT, '')).rejects.toThrowError( + await expect(deleteWorker(gitDDB, '', 'prof01' + JSON_EXTENSION, '')).rejects.toThrowError( Err.CannotDeleteDataError ); await gitDDB.destroy(); diff --git a/test/crud/find.test.ts b/test/crud/find.test.ts index b5d6d347..31851648 100644 --- a/test/crud/find.test.ts +++ b/test/crud/find.test.ts @@ -14,7 +14,12 @@ import { monotonicFactory } from 'ulid'; import { sleep, toSortedJSONString } from '../../src/utils'; import { Err } from '../../src/error'; import { GitDocumentDB } from '../../src/git_documentdb'; -import { FIRST_COMMIT_MESSAGE, GIT_DOCUMENTDB_INFO_ID, JSON_EXT } from '../../src/const'; +import { + FIRST_COMMIT_MESSAGE, + GIT_DOCUMENTDB_INFO_ID, + JSON_EXTENSION, + JSON_POSTFIX, +} from '../../src/const'; import { findImpl } from '../../src/crud/find'; import { addOneData } from '../utils'; @@ -94,7 +99,7 @@ describe(' find()', () => { }); await gitDDB.open(); - await addOneData(gitDDB, 'invalidJSON' + JSON_EXT, 'invalidJSON'); + await addOneData(gitDDB, 'invalidJSON' + JSON_EXTENSION, 'invalidJSON'); await expect(findImpl(gitDDB, '', true, false)).rejects.toThrowError( Err.InvalidJsonObjectError @@ -111,15 +116,15 @@ describe(' find()', () => { localDir, }); - const infoPath = path.resolve(gitDDB.workingDir, GIT_DOCUMENTDB_INFO_ID + JSON_EXT); + const infoPath = path.resolve(gitDDB.workingDir, GIT_DOCUMENTDB_INFO_ID + JSON_POSTFIX); await fs.ensureDir(path.dirname(infoPath)); // Create empty repository await git.init({ fs, dir: gitDDB.workingDir, defaultBranch: 'main' }); - await fs.writeFile(infoPath, {}); + await fs.writeFile(infoPath, toSortedJSONString({})); await git.add({ fs, dir: gitDDB.workingDir, - filepath: GIT_DOCUMENTDB_INFO_ID + JSON_EXT, + filepath: GIT_DOCUMENTDB_INFO_ID + JSON_POSTFIX, }); await git.commit({ fs, @@ -133,7 +138,7 @@ describe(' find()', () => { const _id = '1'; const json = { _id }; - await addOneData(gitDDB, _id + JSON_EXT, toSortedJSONString(json)); + await addOneData(gitDDB, _id + JSON_EXTENSION, toSortedJSONString(json)); await gitDDB.open(); @@ -172,10 +177,10 @@ describe(' find()', () => { const json_1 = { _id: _id_1, name: name_1 }; const json_c = { _id: _id_c, name: name_c }; - await addOneData(gitDDB, _id_b + JSON_EXT, toSortedJSONString(json_b)); - await addOneData(gitDDB, _id_a + JSON_EXT, toSortedJSONString(json_a)); - await addOneData(gitDDB, _id_1 + JSON_EXT, toSortedJSONString(json_1)); - await addOneData(gitDDB, _id_c + JSON_EXT, toSortedJSONString(json_c)); + await addOneData(gitDDB, _id_b + JSON_EXTENSION, toSortedJSONString(json_b)); + await addOneData(gitDDB, _id_a + JSON_EXTENSION, toSortedJSONString(json_a)); + await addOneData(gitDDB, _id_1 + JSON_EXTENSION, toSortedJSONString(json_1)); + await addOneData(gitDDB, _id_c + JSON_EXTENSION, toSortedJSONString(json_c)); await expect(findImpl(gitDDB, '', true, false)).resolves.toEqual([ json_1, @@ -201,10 +206,10 @@ describe(' find()', () => { const json_1 = { _id: _id_1, name: name_1 }; const json_c = { _id: _id_c, name: name_c }; - await addOneData(gitDDB, _id_b + JSON_EXT, toSortedJSONString(json_b)); - await addOneData(gitDDB, _id_a + JSON_EXT, toSortedJSONString(json_a)); - await addOneData(gitDDB, _id_1 + JSON_EXT, toSortedJSONString(json_1)); - await addOneData(gitDDB, _id_c + JSON_EXT, toSortedJSONString(json_c)); + await addOneData(gitDDB, _id_b + JSON_EXTENSION, toSortedJSONString(json_b)); + await addOneData(gitDDB, _id_a + JSON_EXTENSION, toSortedJSONString(json_a)); + await addOneData(gitDDB, _id_1 + JSON_EXTENSION, toSortedJSONString(json_1)); + await addOneData(gitDDB, _id_c + JSON_EXTENSION, toSortedJSONString(json_c)); await expect(findImpl(gitDDB, '', true, false)).resolves.toEqual([ json_1, @@ -237,11 +242,11 @@ describe(' find()', () => { const json_c01 = { _id: _id_c01, name: name_c01 }; const json_c02 = { _id: _id_c02, name: name_c02 }; - await addOneData(gitDDB, _id_b + JSON_EXT, toSortedJSONString(json_b)); - await addOneData(gitDDB, _id_a + JSON_EXT, toSortedJSONString(json_a)); - await addOneData(gitDDB, _id_d + JSON_EXT, toSortedJSONString(json_d)); - await addOneData(gitDDB, _id_c01 + JSON_EXT, toSortedJSONString(json_c01)); - await addOneData(gitDDB, _id_c02 + JSON_EXT, toSortedJSONString(json_c02)); + await addOneData(gitDDB, _id_b + JSON_EXTENSION, toSortedJSONString(json_b)); + await addOneData(gitDDB, _id_a + JSON_EXTENSION, toSortedJSONString(json_a)); + await addOneData(gitDDB, _id_d + JSON_EXTENSION, toSortedJSONString(json_d)); + await addOneData(gitDDB, _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01)); + await addOneData(gitDDB, _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02)); await expect(findImpl(gitDDB, '', true, false)).resolves.toEqual([ json_a, @@ -269,11 +274,11 @@ describe(' find()', () => { const json_c01 = { _id: _id_c01, name: name_c01 }; const json_c02 = { _id: _id_c02, name: name_c02 }; - await addOneData(gitDDB, _id_b + JSON_EXT, toSortedJSONString(json_b)); - await addOneData(gitDDB, _id_a + JSON_EXT, toSortedJSONString(json_a)); - await addOneData(gitDDB, _id_d + JSON_EXT, toSortedJSONString(json_d)); - await addOneData(gitDDB, _id_c01 + JSON_EXT, toSortedJSONString(json_c01)); - await addOneData(gitDDB, _id_c02 + JSON_EXT, toSortedJSONString(json_c02)); + await addOneData(gitDDB, _id_b + JSON_EXTENSION, toSortedJSONString(json_b)); + await addOneData(gitDDB, _id_a + JSON_EXTENSION, toSortedJSONString(json_a)); + await addOneData(gitDDB, _id_d + JSON_EXTENSION, toSortedJSONString(json_d)); + await addOneData(gitDDB, _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01)); + await addOneData(gitDDB, _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02)); await expect(findImpl(gitDDB, '', true, false, { recursive: false })).resolves.toEqual([ json_a, @@ -298,8 +303,8 @@ describe(' find()', () => { const json_1 = { _id: _id_1, name: name_1 }; const json_c = { _id: _id_c, name: name_c }; - await addOneData(gitDDB, _id_b + JSON_EXT, toSortedJSONString(json_b)); - await addOneData(gitDDB, _id_a + JSON_EXT, toSortedJSONString(json_a)); + await addOneData(gitDDB, _id_b + JSON_EXTENSION, toSortedJSONString(json_b)); + await addOneData(gitDDB, _id_a + JSON_EXTENSION, toSortedJSONString(json_a)); await addOneData(gitDDB, _id_1, toSortedJSONString(json_1)); await addOneData(gitDDB, _id_c, toSortedJSONString(json_c)); @@ -325,13 +330,13 @@ describe(' find()', () => { const json_c01 = { _id: _id_c01, name: name_c01 }; const json_c02 = { _id: _id_c02, name: name_c02 }; - await addOneData(gitDDB, _id_b + JSON_EXT, toSortedJSONString(json_b)); - await addOneData(gitDDB, _id_a + JSON_EXT, toSortedJSONString(json_a)); - await addOneData(gitDDB, _id_d + JSON_EXT, toSortedJSONString(json_d)); - await addOneData(gitDDB, _id_c000 + JSON_EXT, toSortedJSONString(json_c000)); - await addOneData(gitDDB, _id_c001 + JSON_EXT, toSortedJSONString(json_c001)); - await addOneData(gitDDB, _id_c01 + JSON_EXT, toSortedJSONString(json_c01)); - await addOneData(gitDDB, _id_c02 + JSON_EXT, toSortedJSONString(json_c02)); + await addOneData(gitDDB, _id_b + JSON_EXTENSION, toSortedJSONString(json_b)); + await addOneData(gitDDB, _id_a + JSON_EXTENSION, toSortedJSONString(json_a)); + await addOneData(gitDDB, _id_d + JSON_EXTENSION, toSortedJSONString(json_d)); + await addOneData(gitDDB, _id_c000 + JSON_EXTENSION, toSortedJSONString(json_c000)); + await addOneData(gitDDB, _id_c001 + JSON_EXTENSION, toSortedJSONString(json_c001)); + await addOneData(gitDDB, _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01)); + await addOneData(gitDDB, _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02)); const prefix = 'citrus/'; @@ -359,13 +364,13 @@ describe(' find()', () => { const json_c01 = { _id: _id_c01, name: name_c01 }; const json_c02 = { _id: _id_c02, name: name_c02 }; - await addOneData(gitDDB, _id_b + JSON_EXT, toSortedJSONString(json_b)); - await addOneData(gitDDB, _id_a + JSON_EXT, toSortedJSONString(json_a)); - await addOneData(gitDDB, _id_d + JSON_EXT, toSortedJSONString(json_d)); - await addOneData(gitDDB, _id_c000 + JSON_EXT, toSortedJSONString(json_c000)); - await addOneData(gitDDB, _id_c001 + JSON_EXT, toSortedJSONString(json_c001)); - await addOneData(gitDDB, _id_c01 + JSON_EXT, toSortedJSONString(json_c01)); - await addOneData(gitDDB, _id_c02 + JSON_EXT, toSortedJSONString(json_c02)); + await addOneData(gitDDB, _id_b + JSON_EXTENSION, toSortedJSONString(json_b)); + await addOneData(gitDDB, _id_a + JSON_EXTENSION, toSortedJSONString(json_a)); + await addOneData(gitDDB, _id_d + JSON_EXTENSION, toSortedJSONString(json_d)); + await addOneData(gitDDB, _id_c000 + JSON_EXTENSION, toSortedJSONString(json_c000)); + await addOneData(gitDDB, _id_c001 + JSON_EXTENSION, toSortedJSONString(json_c001)); + await addOneData(gitDDB, _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01)); + await addOneData(gitDDB, _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02)); const prefix = 'cit'; @@ -392,13 +397,13 @@ describe(' find()', () => { const json_c01 = { _id: _id_c01, name: name_c01 }; const json_c02 = { _id: _id_c02, name: name_c02 }; - await addOneData(gitDDB, _id_b + JSON_EXT, toSortedJSONString(json_b)); - await addOneData(gitDDB, _id_a + JSON_EXT, toSortedJSONString(json_a)); - await addOneData(gitDDB, _id_d + JSON_EXT, toSortedJSONString(json_d)); - await addOneData(gitDDB, _id_c000 + JSON_EXT, toSortedJSONString(json_c000)); - await addOneData(gitDDB, _id_c001 + JSON_EXT, toSortedJSONString(json_c001)); - await addOneData(gitDDB, _id_c01 + JSON_EXT, toSortedJSONString(json_c01)); - await addOneData(gitDDB, _id_c02 + JSON_EXT, toSortedJSONString(json_c02)); + await addOneData(gitDDB, _id_b + JSON_EXTENSION, toSortedJSONString(json_b)); + await addOneData(gitDDB, _id_a + JSON_EXTENSION, toSortedJSONString(json_a)); + await addOneData(gitDDB, _id_d + JSON_EXTENSION, toSortedJSONString(json_d)); + await addOneData(gitDDB, _id_c000 + JSON_EXTENSION, toSortedJSONString(json_c000)); + await addOneData(gitDDB, _id_c001 + JSON_EXTENSION, toSortedJSONString(json_c001)); + await addOneData(gitDDB, _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01)); + await addOneData(gitDDB, _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02)); const prefix = 'citrus'; @@ -428,13 +433,13 @@ describe(' find()', () => { const json_c01 = { _id: _id_c01, name: name_c01 }; const json_c02 = { _id: _id_c02, name: name_c02 }; - await addOneData(gitDDB, _id_b + JSON_EXT, toSortedJSONString(json_b)); - await addOneData(gitDDB, _id_a + JSON_EXT, toSortedJSONString(json_a)); - await addOneData(gitDDB, _id_d + JSON_EXT, toSortedJSONString(json_d)); - await addOneData(gitDDB, _id_c000 + JSON_EXT, toSortedJSONString(json_c000)); - await addOneData(gitDDB, _id_c001 + JSON_EXT, toSortedJSONString(json_c001)); - await addOneData(gitDDB, _id_c01 + JSON_EXT, toSortedJSONString(json_c01)); - await addOneData(gitDDB, _id_c02 + JSON_EXT, toSortedJSONString(json_c02)); + await addOneData(gitDDB, _id_b + JSON_EXTENSION, toSortedJSONString(json_b)); + await addOneData(gitDDB, _id_a + JSON_EXTENSION, toSortedJSONString(json_a)); + await addOneData(gitDDB, _id_d + JSON_EXTENSION, toSortedJSONString(json_d)); + await addOneData(gitDDB, _id_c000 + JSON_EXTENSION, toSortedJSONString(json_c000)); + await addOneData(gitDDB, _id_c001 + JSON_EXTENSION, toSortedJSONString(json_c001)); + await addOneData(gitDDB, _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01)); + await addOneData(gitDDB, _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02)); const prefix = 'citrus/y'; @@ -461,13 +466,13 @@ describe(' find()', () => { const json_c01 = { _id: _id_c01, name: name_c01 }; const json_c02 = { _id: _id_c02, name: name_c02 }; - await addOneData(gitDDB, _id_b + JSON_EXT, toSortedJSONString(json_b)); - await addOneData(gitDDB, _id_a + JSON_EXT, toSortedJSONString(json_a)); - await addOneData(gitDDB, _id_d + JSON_EXT, toSortedJSONString(json_d)); - await addOneData(gitDDB, _id_c000 + JSON_EXT, toSortedJSONString(json_c000)); - await addOneData(gitDDB, _id_c001 + JSON_EXT, toSortedJSONString(json_c001)); - await addOneData(gitDDB, _id_c01 + JSON_EXT, toSortedJSONString(json_c01)); - await addOneData(gitDDB, _id_c02 + JSON_EXT, toSortedJSONString(json_c02)); + await addOneData(gitDDB, _id_b + JSON_EXTENSION, toSortedJSONString(json_b)); + await addOneData(gitDDB, _id_a + JSON_EXTENSION, toSortedJSONString(json_a)); + await addOneData(gitDDB, _id_d + JSON_EXTENSION, toSortedJSONString(json_d)); + await addOneData(gitDDB, _id_c000 + JSON_EXTENSION, toSortedJSONString(json_c000)); + await addOneData(gitDDB, _id_c001 + JSON_EXTENSION, toSortedJSONString(json_c001)); + await addOneData(gitDDB, _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01)); + await addOneData(gitDDB, _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02)); const prefix = 'not_exist/'; @@ -493,15 +498,15 @@ describe(' find()', () => { const json_c01 = { _id: _id_c01, name: name_c01 }; const json_c02 = { _id: _id_c02, name: name_c02 }; - await addOneData(gitDDB, _id_p + JSON_EXT, toSortedJSONString(json_p)); + await addOneData(gitDDB, _id_p + JSON_EXTENSION, toSortedJSONString(json_p)); - await addOneData(gitDDB, _id_b + JSON_EXT, toSortedJSONString(json_b)); - await addOneData(gitDDB, _id_a + JSON_EXT, toSortedJSONString(json_a)); - await addOneData(gitDDB, _id_d + JSON_EXT, toSortedJSONString(json_d)); - await addOneData(gitDDB, _id_c000 + JSON_EXT, toSortedJSONString(json_c000)); - await addOneData(gitDDB, _id_c001 + JSON_EXT, toSortedJSONString(json_c001)); - await addOneData(gitDDB, _id_c01 + JSON_EXT, toSortedJSONString(json_c01)); - await addOneData(gitDDB, _id_c02 + JSON_EXT, toSortedJSONString(json_c02)); + await addOneData(gitDDB, _id_b + JSON_EXTENSION, toSortedJSONString(json_b)); + await addOneData(gitDDB, _id_a + JSON_EXTENSION, toSortedJSONString(json_a)); + await addOneData(gitDDB, _id_d + JSON_EXTENSION, toSortedJSONString(json_d)); + await addOneData(gitDDB, _id_c000 + JSON_EXTENSION, toSortedJSONString(json_c000)); + await addOneData(gitDDB, _id_c001 + JSON_EXTENSION, toSortedJSONString(json_c001)); + await addOneData(gitDDB, _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01)); + await addOneData(gitDDB, _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02)); await expect( findImpl(gitDDB, '', true, false, { prefix: 'pear/Japan' }) @@ -552,10 +557,26 @@ describe(' find()', () => { const json_1_ = { _id: _id_1, name: name_1 }; const json_c_ = { _id: _id_c, name: name_c }; - await addOneData(gitDDB, colPath + _id_b + JSON_EXT, toSortedJSONString(json_b)); - await addOneData(gitDDB, colPath + _id_a + JSON_EXT, toSortedJSONString(json_a)); - await addOneData(gitDDB, colPath + _id_1 + JSON_EXT, toSortedJSONString(json_1)); - await addOneData(gitDDB, colPath + _id_c + JSON_EXT, toSortedJSONString(json_c)); + await addOneData( + gitDDB, + colPath + _id_b + JSON_EXTENSION, + toSortedJSONString(json_b) + ); + await addOneData( + gitDDB, + colPath + _id_a + JSON_EXTENSION, + toSortedJSONString(json_a) + ); + await addOneData( + gitDDB, + colPath + _id_1 + JSON_EXTENSION, + toSortedJSONString(json_1) + ); + await addOneData( + gitDDB, + colPath + _id_c + JSON_EXTENSION, + toSortedJSONString(json_c) + ); await expect(findImpl(gitDDB, colPath, true, false)).resolves.toEqual([ json_1_, @@ -588,11 +609,31 @@ describe(' find()', () => { const json_c01_ = { _id: _id_c01, name: name_c01 }; const json_c02_ = { _id: _id_c02, name: name_c02 }; - await addOneData(gitDDB, colPath + _id_b + JSON_EXT, toSortedJSONString(json_b)); - await addOneData(gitDDB, colPath + _id_a + JSON_EXT, toSortedJSONString(json_a)); - await addOneData(gitDDB, colPath + _id_d + JSON_EXT, toSortedJSONString(json_d)); - await addOneData(gitDDB, colPath + _id_c01 + JSON_EXT, toSortedJSONString(json_c01)); - await addOneData(gitDDB, colPath + _id_c02 + JSON_EXT, toSortedJSONString(json_c02)); + await addOneData( + gitDDB, + colPath + _id_b + JSON_EXTENSION, + toSortedJSONString(json_b) + ); + await addOneData( + gitDDB, + colPath + _id_a + JSON_EXTENSION, + toSortedJSONString(json_a) + ); + await addOneData( + gitDDB, + colPath + _id_d + JSON_EXTENSION, + toSortedJSONString(json_d) + ); + await addOneData( + gitDDB, + colPath + _id_c01 + JSON_EXTENSION, + toSortedJSONString(json_c01) + ); + await addOneData( + gitDDB, + colPath + _id_c02 + JSON_EXTENSION, + toSortedJSONString(json_c02) + ); await expect(findImpl(gitDDB, colPath, true, false)).resolves.toEqual([ json_a_, @@ -631,27 +672,39 @@ describe(' find()', () => { const json_c01_ = { _id: _id_c01, name: name_c01 }; const json_c02_ = { _id: _id_c02, name: name_c02 }; - await addOneData(gitDDB, colPath + _id_b + JSON_EXT, toSortedJSONString(json_b)); - await addOneData(gitDDB, colPath + _id_a + JSON_EXT, toSortedJSONString(json_a)); - await addOneData(gitDDB, colPath + _id_d + JSON_EXT, toSortedJSONString(json_d)); await addOneData( gitDDB, - colPath + _id_c000 + JSON_EXT, + colPath + _id_b + JSON_EXTENSION, + toSortedJSONString(json_b) + ); + await addOneData( + gitDDB, + colPath + _id_a + JSON_EXTENSION, + toSortedJSONString(json_a) + ); + await addOneData( + gitDDB, + colPath + _id_d + JSON_EXTENSION, + toSortedJSONString(json_d) + ); + await addOneData( + gitDDB, + colPath + _id_c000 + JSON_EXTENSION, toSortedJSONString(json_c000) ); await addOneData( gitDDB, - colPath + _id_c001 + JSON_EXT, + colPath + _id_c001 + JSON_EXTENSION, toSortedJSONString(json_c001) ); await addOneData( gitDDB, - colPath + _id_c01 + JSON_EXT, + colPath + _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01) ); await addOneData( gitDDB, - colPath + _id_c02 + JSON_EXT, + colPath + _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02) ); @@ -690,27 +743,39 @@ describe(' find()', () => { const json_c01_ = { _id: _id_c01, name: name_c01 }; const json_c02_ = { _id: _id_c02, name: name_c02 }; - await addOneData(gitDDB, colPath + _id_b + JSON_EXT, toSortedJSONString(json_b)); - await addOneData(gitDDB, colPath + _id_a + JSON_EXT, toSortedJSONString(json_a)); - await addOneData(gitDDB, colPath + _id_d + JSON_EXT, toSortedJSONString(json_d)); await addOneData( gitDDB, - colPath + _id_c000 + JSON_EXT, + colPath + _id_b + JSON_EXTENSION, + toSortedJSONString(json_b) + ); + await addOneData( + gitDDB, + colPath + _id_a + JSON_EXTENSION, + toSortedJSONString(json_a) + ); + await addOneData( + gitDDB, + colPath + _id_d + JSON_EXTENSION, + toSortedJSONString(json_d) + ); + await addOneData( + gitDDB, + colPath + _id_c000 + JSON_EXTENSION, toSortedJSONString(json_c000) ); await addOneData( gitDDB, - colPath + _id_c001 + JSON_EXT, + colPath + _id_c001 + JSON_EXTENSION, toSortedJSONString(json_c001) ); await addOneData( gitDDB, - colPath + _id_c01 + JSON_EXT, + colPath + _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01) ); await addOneData( gitDDB, - colPath + _id_c02 + JSON_EXT, + colPath + _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02) ); @@ -748,27 +813,39 @@ describe(' find()', () => { const json_c01_ = { _id: _id_c01, name: name_c01 }; const json_c02_ = { _id: _id_c02, name: name_c02 }; - await addOneData(gitDDB, colPath + _id_b + JSON_EXT, toSortedJSONString(json_b)); - await addOneData(gitDDB, colPath + _id_a + JSON_EXT, toSortedJSONString(json_a)); - await addOneData(gitDDB, colPath + _id_d + JSON_EXT, toSortedJSONString(json_d)); await addOneData( gitDDB, - colPath + _id_c000 + JSON_EXT, + colPath + _id_b + JSON_EXTENSION, + toSortedJSONString(json_b) + ); + await addOneData( + gitDDB, + colPath + _id_a + JSON_EXTENSION, + toSortedJSONString(json_a) + ); + await addOneData( + gitDDB, + colPath + _id_d + JSON_EXTENSION, + toSortedJSONString(json_d) + ); + await addOneData( + gitDDB, + colPath + _id_c000 + JSON_EXTENSION, toSortedJSONString(json_c000) ); await addOneData( gitDDB, - colPath + _id_c001 + JSON_EXT, + colPath + _id_c001 + JSON_EXTENSION, toSortedJSONString(json_c001) ); await addOneData( gitDDB, - colPath + _id_c01 + JSON_EXT, + colPath + _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01) ); await addOneData( gitDDB, - colPath + _id_c02 + JSON_EXT, + colPath + _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02) ); @@ -809,27 +886,39 @@ describe(' find()', () => { const json_c01_ = { _id: _id_c01, name: name_c01 }; const json_c02_ = { _id: _id_c02, name: name_c02 }; - await addOneData(gitDDB, colPath + _id_b + JSON_EXT, toSortedJSONString(json_b)); - await addOneData(gitDDB, colPath + _id_a + JSON_EXT, toSortedJSONString(json_a)); - await addOneData(gitDDB, colPath + _id_d + JSON_EXT, toSortedJSONString(json_d)); await addOneData( gitDDB, - colPath + _id_c000 + JSON_EXT, + colPath + _id_b + JSON_EXTENSION, + toSortedJSONString(json_b) + ); + await addOneData( + gitDDB, + colPath + _id_a + JSON_EXTENSION, + toSortedJSONString(json_a) + ); + await addOneData( + gitDDB, + colPath + _id_d + JSON_EXTENSION, + toSortedJSONString(json_d) + ); + await addOneData( + gitDDB, + colPath + _id_c000 + JSON_EXTENSION, toSortedJSONString(json_c000) ); await addOneData( gitDDB, - colPath + _id_c001 + JSON_EXT, + colPath + _id_c001 + JSON_EXTENSION, toSortedJSONString(json_c001) ); await addOneData( gitDDB, - colPath + _id_c01 + JSON_EXT, + colPath + _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01) ); await addOneData( gitDDB, - colPath + _id_c02 + JSON_EXT, + colPath + _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02) ); @@ -867,27 +956,39 @@ describe(' find()', () => { const json_c01_ = { _id: _id_c01, name: name_c01 }; const json_c02_ = { _id: _id_c02, name: name_c02 }; - await addOneData(gitDDB, colPath + _id_b + JSON_EXT, toSortedJSONString(json_b)); - await addOneData(gitDDB, colPath + _id_a + JSON_EXT, toSortedJSONString(json_a)); - await addOneData(gitDDB, colPath + _id_d + JSON_EXT, toSortedJSONString(json_d)); await addOneData( gitDDB, - colPath + _id_c000 + JSON_EXT, + colPath + _id_b + JSON_EXTENSION, + toSortedJSONString(json_b) + ); + await addOneData( + gitDDB, + colPath + _id_a + JSON_EXTENSION, + toSortedJSONString(json_a) + ); + await addOneData( + gitDDB, + colPath + _id_d + JSON_EXTENSION, + toSortedJSONString(json_d) + ); + await addOneData( + gitDDB, + colPath + _id_c000 + JSON_EXTENSION, toSortedJSONString(json_c000) ); await addOneData( gitDDB, - colPath + _id_c001 + JSON_EXT, + colPath + _id_c001 + JSON_EXTENSION, toSortedJSONString(json_c001) ); await addOneData( gitDDB, - colPath + _id_c01 + JSON_EXT, + colPath + _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01) ); await addOneData( gitDDB, - colPath + _id_c02 + JSON_EXT, + colPath + _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02) ); @@ -927,29 +1028,45 @@ describe(' find()', () => { const json_c01_ = { _id: _id_c01, name: name_c01 }; const json_c02_ = { _id: _id_c02, name: name_c02 }; - await addOneData(gitDDB, colPath + _id_p + JSON_EXT, toSortedJSONString(json_p)); + await addOneData( + gitDDB, + colPath + _id_p + JSON_EXTENSION, + toSortedJSONString(json_p) + ); - await addOneData(gitDDB, colPath + _id_b + JSON_EXT, toSortedJSONString(json_b)); - await addOneData(gitDDB, colPath + _id_a + JSON_EXT, toSortedJSONString(json_a)); - await addOneData(gitDDB, colPath + _id_d + JSON_EXT, toSortedJSONString(json_d)); await addOneData( gitDDB, - colPath + _id_c000 + JSON_EXT, + colPath + _id_b + JSON_EXTENSION, + toSortedJSONString(json_b) + ); + await addOneData( + gitDDB, + colPath + _id_a + JSON_EXTENSION, + toSortedJSONString(json_a) + ); + await addOneData( + gitDDB, + colPath + _id_d + JSON_EXTENSION, + toSortedJSONString(json_d) + ); + await addOneData( + gitDDB, + colPath + _id_c000 + JSON_EXTENSION, toSortedJSONString(json_c000) ); await addOneData( gitDDB, - colPath + _id_c001 + JSON_EXT, + colPath + _id_c001 + JSON_EXTENSION, toSortedJSONString(json_c001) ); await addOneData( gitDDB, - colPath + _id_c01 + JSON_EXT, + colPath + _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01) ); await addOneData( gitDDB, - colPath + _id_c02 + JSON_EXT, + colPath + _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02) ); @@ -996,44 +1113,44 @@ describe(' find()', () => { const json_c01 = { _id: _id_c01, name: name_c01 }; const json_c02 = { _id: _id_c02, name: name_c02 }; - await addOneData(gitDDB, _id_b + JSON_EXT, toSortedJSONString(json_b)); - await addOneData(gitDDB, _id_a + JSON_EXT, toSortedJSONString(json_a)); - await addOneData(gitDDB, _id_d + JSON_EXT, toSortedJSONString(json_d)); - await addOneData(gitDDB, _id_c01 + JSON_EXT, toSortedJSONString(json_c01)); - await addOneData(gitDDB, _id_c02 + JSON_EXT, toSortedJSONString(json_c02)); + await addOneData(gitDDB, _id_b + JSON_EXTENSION, toSortedJSONString(json_b)); + await addOneData(gitDDB, _id_a + JSON_EXTENSION, toSortedJSONString(json_a)); + await addOneData(gitDDB, _id_d + JSON_EXTENSION, toSortedJSONString(json_d)); + await addOneData(gitDDB, _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01)); + await addOneData(gitDDB, _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02)); await expect(findImpl(gitDDB, '', true, true)).resolves.toEqual([ { _id: _id_a, - name: _id_a + JSON_EXT, + name: _id_a + JSON_EXTENSION, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_a) })).oid, type: 'json', doc: json_a, }, { _id: _id_b, - name: _id_b + JSON_EXT, + name: _id_b + JSON_EXTENSION, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_b) })).oid, type: 'json', doc: json_b, }, { _id: _id_c01, - name: _id_c01 + JSON_EXT, + name: _id_c01 + JSON_EXTENSION, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_c01) })).oid, type: 'json', doc: json_c01, }, { _id: _id_c02, - name: _id_c02 + JSON_EXT, + name: _id_c02 + JSON_EXTENSION, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_c02) })).oid, type: 'json', doc: json_c02, }, { _id: _id_d, - name: _id_d + JSON_EXT, + name: _id_d + JSON_EXTENSION, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_d) })).oid, type: 'json', doc: json_d, diff --git a/test/crud/get.test.ts b/test/crud/get.test.ts index 9b9710e4..4df2b354 100644 --- a/test/crud/get.test.ts +++ b/test/crud/get.test.ts @@ -17,7 +17,7 @@ import { sleep, toSortedJSONString } from '../../src/utils'; import { Err } from '../../src/error'; import { GitDocumentDB } from '../../src/git_documentdb'; import { getImpl } from '../../src/crud/get'; -import { JSON_EXT } from '../../src/const'; +import { JSON_EXTENSION } from '../../src/const'; import { addOneData, removeOneData } from '../utils'; // eslint-disable-next-line @typescript-eslint/no-var-requires @@ -103,7 +103,7 @@ describe(' getImpl()', () => { await gitDDB.open(); const shortId = 'prof01'; - const shortName = shortId + JSON_EXT; + const shortName = shortId + JSON_EXTENSION; const collectionPath = ''; const fullDocPath = collectionPath + shortName; const json = { _id: shortId, name: 'Shirase' }; @@ -122,7 +122,7 @@ describe(' getImpl()', () => { await gitDDB.open(); const shortId = 'dir01/prof01'; - const shortName = shortId + JSON_EXT; + const shortName = shortId + JSON_EXTENSION; const collectionPath = ''; const fullDocPath = collectionPath + shortName; const json = { _id: shortId, name: 'Shirase' }; @@ -141,7 +141,7 @@ describe(' getImpl()', () => { await gitDDB.open(); const shortId = 'dir01/prof01'; - const shortName = shortId + JSON_EXT; + const shortName = shortId + JSON_EXTENSION; const collectionPath = 'col01/col02/col03'; const fullDocPath = collectionPath + shortName; const json = { _id: shortId, name: 'Shirase' }; @@ -193,7 +193,7 @@ describe(' getImpl()', () => { await gitDDB.open(); const shortId = 'prof01'; - const shortName = shortId + JSON_EXT; + const shortName = shortId + JSON_EXTENSION; const collectionPath = ''; const fullDocPath = collectionPath + shortName; const json = { _id: shortId, name: 'Shirase' }; @@ -216,7 +216,7 @@ describe(' getImpl()', () => { await gitDDB.open(); const shortId = '枕草子/春はあけぼの'; - const shortName = shortId + JSON_EXT; + const shortName = shortId + JSON_EXTENSION; const collectionPath = ''; const fullDocPath = collectionPath + shortName; const json = { _id: shortId, name: 'Shirase' }; @@ -236,7 +236,7 @@ describe(' getImpl()', () => { await gitDDB.open(); const shortId = 'prof01'; - const shortName = shortId + JSON_EXT; + const shortName = shortId + JSON_EXTENSION; const collectionPath = ''; const fullDocPath = collectionPath + shortName; const json = { _id: shortId, name: 'Shirase' }; @@ -260,7 +260,7 @@ describe(' getImpl()', () => { await gitDDB.open(); const shortId = 'prof01'; - const shortName = shortId + JSON_EXT; + const shortName = shortId + JSON_EXTENSION; const collectionPath = ''; const fullDocPath = collectionPath + shortName; const json = { _id: shortId, name: 'Shirase' }; @@ -288,7 +288,7 @@ describe(' getImpl()', () => { await gitDDB.open(); const shortId = 'prof01'; - const shortName = shortId + JSON_EXT; + const shortName = shortId + JSON_EXTENSION; const collectionPath = ''; const fullDocPath = collectionPath + shortName; const json = { _id: shortId, name: 'Shirase' }; @@ -312,7 +312,7 @@ describe(' getImpl()', () => { await gitDDB.open(); const shortId = 'prof01'; - const shortName = shortId + JSON_EXT; + const shortName = shortId + JSON_EXTENSION; const collectionPath = ''; const fullDocPath = collectionPath + shortName; const json = { _id: shortId, name: 'Shirase' }; @@ -335,7 +335,7 @@ describe(' getImpl()', () => { await gitDDB.open(); const shortId = 'prof01'; - const shortName = shortId + JSON_EXT; + const shortName = shortId + JSON_EXTENSION; const collectionPath = ''; const fullDocPath = collectionPath + shortName; const json = { _id: shortId, name: 'Shirase' }; @@ -358,7 +358,7 @@ describe(' getImpl()', () => { await gitDDB.open(); const shortId = 'prof01'; - const shortName = shortId + JSON_EXT; + const shortName = shortId + JSON_EXTENSION; const collectionPath = ''; const fullDocPath = collectionPath + shortName; const json01 = { _id: shortId, name: 'v01' }; @@ -383,7 +383,7 @@ describe(' getImpl()', () => { await gitDDB.open(); const shortId = 'prof01'; - const shortName = shortId + JSON_EXT; + const shortName = shortId + JSON_EXTENSION; const collectionPath = ''; const fullDocPath = collectionPath + shortName; const json01 = { _id: shortId, name: 'v01' }; @@ -408,7 +408,7 @@ describe(' getImpl()', () => { await gitDDB.open(); const shortId = 'prof01'; - const shortName = shortId + JSON_EXT; + const shortName = shortId + JSON_EXTENSION; const collectionPath = ''; const fullDocPath = collectionPath + shortName; const json01 = { _id: shortId, name: 'v01' }; @@ -433,7 +433,7 @@ describe(' getImpl()', () => { await gitDDB.open(); const shortId = 'prof01'; - const shortName = shortId + JSON_EXT; + const shortName = shortId + JSON_EXTENSION; const collectionPath = ''; const fullDocPath = collectionPath + shortName; const json01 = { _id: shortId, name: 'v01' }; @@ -476,7 +476,7 @@ describe(' getImpl()', () => { await gitDDB.open(); const shortId = 'prof01'; - const shortName = shortId + JSON_EXT; + const shortName = shortId + JSON_EXTENSION; const collectionPath = ''; const fullDocPath = collectionPath + shortName; const json = { _id: shortId, name: 'Shirase' }; @@ -501,7 +501,7 @@ describe(' getImpl()', () => { }); const targetId = '01'; - const targetName = targetId + JSON_EXT; + const targetName = targetId + JSON_EXTENSION; const collectionPath = ''; const fullDocPath = collectionPath + targetName; diff --git a/test/crud/history.test.ts b/test/crud/history.test.ts index 3044a5ec..a2787519 100644 --- a/test/crud/history.test.ts +++ b/test/crud/history.test.ts @@ -23,7 +23,7 @@ import { GitDocumentDB } from '../../src/git_documentdb'; import { sleep, toSortedJSONString, utf8encode } from '../../src/utils'; import { getHistoryImpl, readOldBlob } from '../../src/crud/history'; -import { JSON_EXT } from '../../src/const'; +import { JSON_EXTENSION } from '../../src/const'; import { addOneData, removeOneData } from '../utils'; import { FatJsonDoc } from '../../src/types'; @@ -74,7 +74,7 @@ describe(' getHistoryImpl', () => { await gitDDB.open(); const _idA = 'profA'; - const shortNameA = _idA + JSON_EXT; + const shortNameA = _idA + JSON_EXTENSION; const jsonA01 = { _id: _idA, name: 'v01' }; const jsonA02 = { _id: _idA, name: 'v02' }; const jsonA03 = { _id: _idA, name: 'v03' }; @@ -82,7 +82,7 @@ describe(' getHistoryImpl', () => { await gitDDB.put(jsonA02); await gitDDB.put(jsonA03); const _idB = 'profB'; - const shortNameB = _idB + JSON_EXT; + const shortNameB = _idB + JSON_EXTENSION; const jsonB01 = { _id: _idB, name: 'v01' }; const jsonB02 = { _id: _idB, name: 'v02' }; await gitDDB.put(jsonB01); @@ -124,7 +124,7 @@ describe(' getHistoryImpl', () => { await gitDDB.open(); const _idA = 'profA'; - const shortNameA = _idA + JSON_EXT; + const shortNameA = _idA + JSON_EXTENSION; const jsonA01 = { _id: _idA, name: 'v01' }; const jsonA02 = { _id: _idA, name: 'v02' }; const jsonA03 = { _id: _idA, name: 'v03' }; @@ -139,7 +139,7 @@ describe(' getHistoryImpl', () => { await gitDDB.put(jsonA03); const _idB = 'profB'; - const shortNameB = _idB + JSON_EXT; + const shortNameB = _idB + JSON_EXTENSION; const jsonB01 = { _id: _idB, name: 'v01' }; const jsonB02 = { _id: _idB, name: 'v02' }; @@ -215,7 +215,7 @@ describe(' getHistoryImpl', () => { await gitDDB.open(); const _idA = 'profA'; - const shortNameA = _idA + JSON_EXT; + const shortNameA = _idA + JSON_EXTENSION; const jsonA01 = { _id: _idA, name: 'v01' }; const jsonA02 = { _id: _idA, name: 'v02' }; const jsonA03 = { _id: _idA, name: 'v03' }; @@ -297,7 +297,7 @@ describe(' getHistoryImpl', () => { await gitDDB.open(); const _idA = 'profA'; - const shortNameA = _idA + JSON_EXT; + const shortNameA = _idA + JSON_EXTENSION; const jsonA01 = { _id: _idA, name: 'v01' }; const jsonA02 = { _id: _idA, name: 'v02' }; const jsonA03 = { _id: _idA, name: 'v03' }; @@ -324,7 +324,7 @@ describe(' getHistoryImpl', () => { await gitDDB.open(); const _idA = 'profA'; - const shortNameA = _idA + JSON_EXT; + const shortNameA = _idA + JSON_EXTENSION; const jsonA01 = { _id: _idA, name: 'v01' }; const jsonA02 = { _id: _idA, name: 'v02' }; const jsonA03 = { _id: _idA, name: 'v03' }; @@ -393,7 +393,7 @@ describe(' readOldBlob()', () => { await gitDDB.open(); const shortId = 'prof01'; const collectionPath = ''; - const fullDocPath = collectionPath + shortId + JSON_EXT; + const fullDocPath = collectionPath + shortId + JSON_EXTENSION; const json = { _id: shortId, name: 'Shirase' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json)); @@ -412,7 +412,7 @@ describe(' readOldBlob()', () => { await gitDDB.open(); const shortId = 'prof01'; const collectionPath = ''; - const fullDocPath = collectionPath + shortId + JSON_EXT; + const fullDocPath = collectionPath + shortId + JSON_EXTENSION; const json = { _id: shortId, name: 'Shirase' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json)); await removeOneData(gitDDB, fullDocPath); @@ -432,7 +432,7 @@ describe(' readOldBlob()', () => { await gitDDB.open(); const shortId = 'prof01'; const collectionPath = ''; - const fullDocPath = collectionPath + shortId + JSON_EXT; + const fullDocPath = collectionPath + shortId + JSON_EXTENSION; const json = { _id: shortId, name: 'Shirase' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json)); await removeOneData(gitDDB, fullDocPath); @@ -455,7 +455,7 @@ describe(' readOldBlob()', () => { await gitDDB.open(); const shortId = 'prof01'; const collectionPath = ''; - const fullDocPath = collectionPath + shortId + JSON_EXT; + const fullDocPath = collectionPath + shortId + JSON_EXTENSION; const json01 = { _id: shortId, name: 'v01' }; const json02 = { _id: shortId, name: 'v02' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json01)); @@ -480,7 +480,7 @@ describe(' readOldBlob()', () => { await gitDDB.open(); const shortId = 'prof01'; const collectionPath = ''; - const fullDocPath = collectionPath + shortId + JSON_EXT; + const fullDocPath = collectionPath + shortId + JSON_EXTENSION; const json01 = { _id: shortId, name: 'v01' }; const json02 = { _id: shortId, name: 'v02' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json01)); @@ -505,7 +505,7 @@ describe(' readOldBlob()', () => { await gitDDB.open(); const shortId = 'prof01'; const collectionPath = ''; - const fullDocPath = collectionPath + shortId + JSON_EXT; + const fullDocPath = collectionPath + shortId + JSON_EXTENSION; const json01 = { _id: shortId, name: 'v01' }; const json02 = { _id: shortId, name: 'v02' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json01)); @@ -527,7 +527,7 @@ describe(' readOldBlob()', () => { await gitDDB.open(); const shortId = 'prof01'; const collectionPath = ''; - const fullDocPath = collectionPath + shortId + JSON_EXT; + const fullDocPath = collectionPath + shortId + JSON_EXTENSION; const json01 = { _id: shortId, name: 'v01' }; const json02 = { _id: shortId, name: 'v02' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json01)); @@ -565,7 +565,7 @@ describe(' readOldBlob()', () => { await gitDDB.open(); const shortId = 'prof01'; const collectionPath = ''; - const fullDocPath = collectionPath + shortId + JSON_EXT; + const fullDocPath = collectionPath + shortId + JSON_EXTENSION; const json = { _id: shortId, name: 'Shirase' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json)); @@ -587,7 +587,7 @@ describe(' readOldBlob()', () => { await gitDDB.open(); const shortId = 'prof01'; const collectionPath = ''; - const fullDocPath = collectionPath + shortId + JSON_EXT; + const fullDocPath = collectionPath + shortId + JSON_EXTENSION; const json01 = { _id: shortId, name: 'v01' }; const json02 = { _id: shortId, name: 'v02' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json01)); @@ -612,7 +612,7 @@ describe(' readOldBlob()', () => { const targetId = '01'; const collectionPath = ''; - const fullDocPath = collectionPath + targetId + JSON_EXT; + const fullDocPath = collectionPath + targetId + JSON_EXTENSION; const json01 = { _id: targetId, name: 'v01' }; const json02 = { _id: targetId, name: 'v02' }; diff --git a/test/crud/put.test.ts b/test/crud/put.test.ts index 49978674..713e7391 100644 --- a/test/crud/put.test.ts +++ b/test/crud/put.test.ts @@ -17,7 +17,7 @@ import { monotonicFactory } from 'ulid'; import { Err } from '../../src/error'; import { GitDocumentDB } from '../../src/git_documentdb'; import { putImpl, putWorker } from '../../src/crud/put'; -import { JSON_EXT, SHORT_SHA_LENGTH } from '../../src/const'; +import { JSON_EXTENSION, SHORT_SHA_LENGTH } from '../../src/const'; import { sleep, toSortedJSONString } from '../../src/utils'; import { TaskMetadata } from '../../src/types'; @@ -64,7 +64,7 @@ describe(' put', () => { gitDDB.close().catch(() => {}); const _id = 'prof01'; await expect( - putImpl(gitDDB, '', _id, _id + JSON_EXT, toSortedJSONString({ _id, name: 'shirase' })) + putImpl(gitDDB, '', _id, _id + JSON_EXTENSION, toSortedJSONString({ _id, name: 'shirase' })) ).rejects.toThrowError(Err.DatabaseClosingError); // wait close @@ -96,7 +96,7 @@ describe(' put', () => { gitDDB, '', _id, - _id + JSON_EXT, + _id + JSON_EXTENSION, toSortedJSONString(json) ); const afterTimestamp = Math.floor(Date.now() / 1000) * 1000; @@ -113,7 +113,7 @@ describe(' put', () => { // Check NormalizedCommit expect(pickedPutResult.commit.oid).toBe(currentCommitOid); expect(pickedPutResult.commit.message).toBe( - `insert: ${_id}${JSON_EXT}(${oid.substr(0, SHORT_SHA_LENGTH)})` + `insert: ${_id}${JSON_EXTENSION}(${oid.substr(0, SHORT_SHA_LENGTH)})` ); expect(pickedPutResult.commit.parent).toEqual([prevCommitOid]); expect(pickedPutResult.commit.author.name).toEqual(gitDDB.author.name); @@ -143,13 +143,13 @@ describe(' put', () => { gitDDB, '', _id, - _id + JSON_EXT, + _id + JSON_EXTENSION, toSortedJSONString(json) ); const shortOid = pickedPutResult.fileOid.substr(0, SHORT_SHA_LENGTH); expect(pickedPutResult.commit.message).toEqual( - `insert: ${_id}${JSON_EXT}(${shortOid})` + `insert: ${_id}${JSON_EXTENSION}(${shortOid})` ); // Check commit directly @@ -159,7 +159,7 @@ describe(' put', () => { dir: gitDDB.workingDir, oid: commitOid, }); - expect(commit.message).toEqual(`insert: ${_id}${JSON_EXT}(${shortOid})\n`); + expect(commit.message).toEqual(`insert: ${_id}${JSON_EXTENSION}(${shortOid})\n`); await gitDDB.destroy(); }); @@ -172,19 +172,19 @@ describe(' put', () => { await gitDDB.open(); const _id = 'prof01'; const json = { _id, name: 'Shirase' }; - await putImpl(gitDDB, '', _id, _id + JSON_EXT, toSortedJSONString(json)); + await putImpl(gitDDB, '', _id, _id + JSON_EXTENSION, toSortedJSONString(json)); // update const pickedPutResult = await putImpl( gitDDB, '', _id, - _id + JSON_EXT, + _id + JSON_EXTENSION, toSortedJSONString(json) ); const shortOid = pickedPutResult.fileOid.substr(0, SHORT_SHA_LENGTH); expect(pickedPutResult.commit.message).toEqual( - `update: ${_id}${JSON_EXT}(${shortOid})` + `update: ${_id}${JSON_EXTENSION}(${shortOid})` ); // Check commit directly @@ -194,7 +194,7 @@ describe(' put', () => { dir: gitDDB.workingDir, oid: commitOid, }); - expect(commit.message).toEqual(`update: ${_id}${JSON_EXT}(${shortOid})\n`); + expect(commit.message).toEqual(`update: ${_id}${JSON_EXTENSION}(${shortOid})\n`); await gitDDB.destroy(); }); @@ -211,11 +211,11 @@ describe(' put', () => { gitDDB, '', _id, - _id + JSON_EXT, + _id + JSON_EXTENSION, toSortedJSONString(json) ); const shortOid = pickedPutResult.fileOid.substr(0, SHORT_SHA_LENGTH); - const defaultCommitMessage = `insert: ${_id}${JSON_EXT}(${shortOid})`; + const defaultCommitMessage = `insert: ${_id}${JSON_EXTENSION}(${shortOid})`; expect(pickedPutResult.commit.message).toEqual(defaultCommitMessage); // Check commit directly @@ -245,7 +245,7 @@ describe(' put', () => { gitDDB, '', i.toString(), - i.toString() + JSON_EXT, + i.toString() + JSON_EXTENSION, toSortedJSONString({ _id: i.toString() }), { commitMessage: `${i}`, @@ -276,7 +276,7 @@ describe(' put', () => { gitDDB, '', _id, - _id + JSON_EXT, + _id + JSON_EXTENSION, toSortedJSONString(json), { commitMessage: myCommitMessage, @@ -325,54 +325,54 @@ describe(' put', () => { const json_p = { _id: _id_p, name: name_p }; await Promise.all([ - putImpl(gitDDB, '', _id_a, _id_a + JSON_EXT, toSortedJSONString(json_a)), - putImpl(gitDDB, '', _id_b, _id_b + JSON_EXT, toSortedJSONString(json_b)), - putImpl(gitDDB, '', _id_c01, _id_c01 + JSON_EXT, toSortedJSONString(json_c01)), - putImpl(gitDDB, '', _id_c02, _id_c02 + JSON_EXT, toSortedJSONString(json_c02)), - putImpl(gitDDB, '', _id_d, _id_d + JSON_EXT, toSortedJSONString(json_d)), - putImpl(gitDDB, '', _id_p, _id_p + JSON_EXT, toSortedJSONString(json_p)), + putImpl(gitDDB, '', _id_a, _id_a + JSON_EXTENSION, toSortedJSONString(json_a)), + putImpl(gitDDB, '', _id_b, _id_b + JSON_EXTENSION, toSortedJSONString(json_b)), + putImpl(gitDDB, '', _id_c01, _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01)), + putImpl(gitDDB, '', _id_c02, _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02)), + putImpl(gitDDB, '', _id_d, _id_d + JSON_EXTENSION, toSortedJSONString(json_d)), + putImpl(gitDDB, '', _id_p, _id_p + JSON_EXTENSION, toSortedJSONString(json_p)), ]); await expect(gitDDB.findFatDoc()).resolves.toEqual( expect.arrayContaining([ { _id: _id_a, - name: _id_a + JSON_EXT, + name: _id_a + JSON_EXTENSION, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_a) })).oid, type: 'json', doc: json_a, }, { _id: _id_b, - name: _id_b + JSON_EXT, + name: _id_b + JSON_EXTENSION, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_b) })).oid, type: 'json', doc: json_b, }, { _id: _id_c01, - name: _id_c01 + JSON_EXT, + name: _id_c01 + JSON_EXTENSION, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_c01) })).oid, type: 'json', doc: json_c01, }, { _id: _id_c02, - name: _id_c02 + JSON_EXT, + name: _id_c02 + JSON_EXTENSION, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_c02) })).oid, type: 'json', doc: json_c02, }, { _id: _id_d, - name: _id_d + JSON_EXT, + name: _id_d + JSON_EXTENSION, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_d) })).oid, type: 'json', doc: json_d, }, { _id: _id_p, - name: _id_p + JSON_EXT, + name: _id_p + JSON_EXTENSION, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_p) })).oid, type: 'json', doc: json_p, @@ -398,7 +398,7 @@ describe(' put', () => { gitDDB, '', i.toString(), - i.toString() + JSON_EXT, + i.toString() + JSON_EXTENSION, toSortedJSONString({ _id: i.toString() }) ) ); @@ -427,12 +427,12 @@ describe(' put', () => { gitDDB, '', i.toString(), - i.toString() + JSON_EXT, + i.toString() + JSON_EXTENSION, toSortedJSONString({ _id: i.toString() }) ); } // The last put() with await keyword is resolved after all preceding (queued) Promises - await putImpl(gitDDB, '', '99', '99' + JSON_EXT, toSortedJSONString({ _id: '99' })); + await putImpl(gitDDB, '', '99', '99' + JSON_EXTENSION, toSortedJSONString({ _id: '99' })); const fatDocs = await gitDDB.find(); expect(fatDocs.length).toBe(100); @@ -449,13 +449,13 @@ describe(' put', () => { const enqueueEvent: TaskMetadata[] = []; const id1 = gitDDB.taskQueue.newTaskId(); const id2 = gitDDB.taskQueue.newTaskId(); - await putImpl(gitDDB, '', '1', '1' + JSON_EXT, toSortedJSONString({ _id: '1' }), { + await putImpl(gitDDB, '', '1', '1' + JSON_EXTENSION, toSortedJSONString({ _id: '1' }), { taskId: id1, enqueueCallback: (taskMetadata: TaskMetadata) => { enqueueEvent.push(taskMetadata); }, }); - await putImpl(gitDDB, '', '2', '2' + JSON_EXT, toSortedJSONString({ _id: '2' }), { + await putImpl(gitDDB, '', '2', '2' + JSON_EXTENSION, toSortedJSONString({ _id: '2' }), { taskId: id2, enqueueCallback: (taskMetadata: TaskMetadata) => { enqueueEvent.push(taskMetadata); @@ -483,7 +483,7 @@ describe(' put', () => { gitDDB, '', i.toString(), - i.toString() + JSON_EXT, + i.toString() + JSON_EXTENSION, toSortedJSONString({ _id: i.toString() }) ).catch( // eslint-disable-next-line no-loop-func @@ -520,7 +520,7 @@ describe(' putWorker', () => { putWorker( gitDDB, '', - 'prof01' + JSON_EXT, + 'prof01' + JSON_EXTENSION, '{ "_id": "prof01", "name": "Shirase" }', 'message' ) @@ -535,7 +535,7 @@ describe(' putWorker', () => { localDir, }); await gitDDB.open(); - const fullDocPath = 'prof01' + JSON_EXT; + const fullDocPath = 'prof01' + JSON_EXTENSION; await putWorker( gitDDB, '', @@ -563,7 +563,7 @@ describe(' putWorker', () => { localDir, }); await gitDDB.open(); - const fullDocPath = 'prof01' + JSON_EXT; + const fullDocPath = 'prof01' + JSON_EXTENSION; await expect( putWorker( gitDDB, @@ -605,7 +605,7 @@ describe(' putWorker', () => { await gitDDB.open(); const json = { _id: 'prof01', name: 'Shirase' }; - const fullDocPath = json._id + JSON_EXT; + const fullDocPath = json._id + JSON_EXTENSION; await putWorker(gitDDB, '', fullDocPath, toSortedJSONString(json), 'message'); expect(readFileSync(path.resolve(gitDDB.workingDir, fullDocPath), 'utf8')).toBe( toSortedJSONString(json) @@ -623,7 +623,7 @@ describe(' putWorker', () => { await gitDDB.open(); const json = { _id: 'prof01', name: 'Shirase' }; - const fullDocPath = json._id + JSON_EXT; + const fullDocPath = json._id + JSON_EXTENSION; await putWorker(gitDDB, '', fullDocPath, toSortedJSONString(json), 'message'); const json2 = { _id: 'prof01', name: 'updated document' }; @@ -665,54 +665,54 @@ describe(' putWorker', () => { const json_p = { _id: _id_p, name: name_p }; await Promise.all([ - putWorker(gitDDB, '', _id_a + JSON_EXT, toSortedJSONString(json_a), 'message'), - putWorker(gitDDB, '', _id_b + JSON_EXT, toSortedJSONString(json_b), 'message'), - putWorker(gitDDB, '', _id_c01 + JSON_EXT, toSortedJSONString(json_c01), 'message'), - putWorker(gitDDB, '', _id_c02 + JSON_EXT, toSortedJSONString(json_c02), 'message'), - putWorker(gitDDB, '', _id_d + JSON_EXT, toSortedJSONString(json_d), 'message'), - putWorker(gitDDB, '', _id_p + JSON_EXT, toSortedJSONString(json_p), 'message'), + putWorker(gitDDB, '', _id_a + JSON_EXTENSION, toSortedJSONString(json_a), 'message'), + putWorker(gitDDB, '', _id_b + JSON_EXTENSION, toSortedJSONString(json_b), 'message'), + putWorker(gitDDB, '', _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01), 'message'), + putWorker(gitDDB, '', _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02), 'message'), + putWorker(gitDDB, '', _id_d + JSON_EXTENSION, toSortedJSONString(json_d), 'message'), + putWorker(gitDDB, '', _id_p + JSON_EXTENSION, toSortedJSONString(json_p), 'message'), ]); await expect(gitDDB.findFatDoc()).resolves.toEqual( expect.arrayContaining([ { _id: _id_a, - name: _id_a + JSON_EXT, + name: _id_a + JSON_EXTENSION, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_a) })).oid, type: 'json', doc: json_a, }, { _id: _id_b, - name: _id_b + JSON_EXT, + name: _id_b + JSON_EXTENSION, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_b) })).oid, type: 'json', doc: json_b, }, { _id: _id_c01, - name: _id_c01 + JSON_EXT, + name: _id_c01 + JSON_EXTENSION, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_c01) })).oid, type: 'json', doc: json_c01, }, { _id: _id_c02, - name: _id_c02 + JSON_EXT, + name: _id_c02 + JSON_EXTENSION, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_c02) })).oid, type: 'json', doc: json_c02, }, { _id: _id_d, - name: _id_d + JSON_EXT, + name: _id_d + JSON_EXTENSION, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_d) })).oid, type: 'json', doc: json_d, }, { _id: _id_p, - name: _id_p + JSON_EXT, + name: _id_p + JSON_EXTENSION, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_p) })).oid, type: 'json', doc: json_p, diff --git a/test/git_documentdb_crud.test.ts b/test/git_documentdb_crud.test.ts index 571ad65a..30c5d583 100644 --- a/test/git_documentdb_crud.test.ts +++ b/test/git_documentdb_crud.test.ts @@ -15,7 +15,7 @@ import fs from 'fs-extra'; import { DeleteResultJsonDoc, PutResultJsonDoc } from '../src/types'; import { GitDocumentDB } from '../src/git_documentdb'; import { sleep, toSortedJSONString } from '../src/utils'; -import { JSON_EXT, SHORT_SHA_LENGTH } from '../src/const'; +import { JSON_EXTENSION, SHORT_SHA_LENGTH } from '../src/const'; import { addOneData } from './utils'; import { Err } from '../src/error'; @@ -85,10 +85,10 @@ describe(' put(jsonDoc)', () => { const shortOid = fileOid.substr(0, SHORT_SHA_LENGTH); expect(putResult._id).toBe(_id); expect(putResult.fileOid).toBe(fileOid); - expect(putResult.commit.message).toBe(`insert: ${_id}${JSON_EXT}(${shortOid})`); + expect(putResult.commit.message).toBe(`insert: ${_id}${JSON_EXTENSION}(${shortOid})`); // fs.access() throw error when a file cannot be accessed. - const filePath = path.resolve(gitDDB.workingDir, _id + JSON_EXT); + const filePath = path.resolve(gitDDB.workingDir, _id + JSON_EXTENSION); await expect(fs.access(filePath)).resolves.not.toThrowError(); expect(fs.readFileSync(filePath, 'utf8')).toBe(toSortedJSONString(json)); @@ -196,10 +196,10 @@ describe(' put(_id, jsonDoc)', () => { const shortOid = fileOid.substr(0, SHORT_SHA_LENGTH); expect(putResult._id).toBe(_id); expect(putResult.fileOid).toBe(fileOid); - expect(putResult.commit.message).toBe(`insert: ${_id}${JSON_EXT}(${shortOid})`); + expect(putResult.commit.message).toBe(`insert: ${_id}${JSON_EXTENSION}(${shortOid})`); // fs.access() throw error when a file cannot be accessed. - const filePath = path.resolve(gitDDB.workingDir, _id + JSON_EXT); + const filePath = path.resolve(gitDDB.workingDir, _id + JSON_EXTENSION); await expect(fs.access(filePath)).resolves.not.toThrowError(); expect(fs.readFileSync(filePath, 'utf8')).toBe(toSortedJSONString(json)); @@ -279,17 +279,17 @@ describe(' putFatDoc(name, jsonDoc)', () => { }); await gitDDB.open(); const _id = 'prof01'; - const name = _id + JSON_EXT; + const name = _id + JSON_EXTENSION; const json = { _id, name: 'Shirase' }; const putResult = (await gitDDB.putFatDoc(name, json)) as PutResultJsonDoc; const fileOid = (await git.hashBlob({ object: toSortedJSONString(json) })).oid; const shortOid = fileOid.substr(0, SHORT_SHA_LENGTH); expect(putResult._id).toBe(_id); expect(putResult.fileOid).toBe(fileOid); - expect(putResult.commit.message).toBe(`insert: ${_id}${JSON_EXT}(${shortOid})`); + expect(putResult.commit.message).toBe(`insert: ${_id}${JSON_EXTENSION}(${shortOid})`); // fs.access() throw error when a file cannot be accessed. - const filePath = path.resolve(gitDDB.workingDir, _id + JSON_EXT); + const filePath = path.resolve(gitDDB.workingDir, _id + JSON_EXTENSION); await expect(fs.access(filePath)).resolves.not.toThrowError(); expect(fs.readFileSync(filePath, 'utf8')).toBe(toSortedJSONString(json)); @@ -312,10 +312,10 @@ describe(' insert(jsonDoc)', () => { const shortOid = fileOid.substr(0, SHORT_SHA_LENGTH); expect(putResult._id).toBe(_id); expect(putResult.fileOid).toBe(fileOid); - expect(putResult.commit.message).toBe(`insert: ${_id}${JSON_EXT}(${shortOid})`); + expect(putResult.commit.message).toBe(`insert: ${_id}${JSON_EXTENSION}(${shortOid})`); // fs.access() throw error when a file cannot be accessed. - const filePath = path.resolve(gitDDB.workingDir, _id + JSON_EXT); + const filePath = path.resolve(gitDDB.workingDir, _id + JSON_EXTENSION); await expect(fs.access(filePath)).resolves.not.toThrowError(); expect(fs.readFileSync(filePath, 'utf8')).toBe(toSortedJSONString(json)); @@ -357,10 +357,10 @@ describe(' insert(_id, jsonDoc)', () => { const shortOid = fileOid.substr(0, SHORT_SHA_LENGTH); expect(putResult._id).toBe(_id); expect(putResult.fileOid).toBe(fileOid); - expect(putResult.commit.message).toBe(`insert: ${_id}${JSON_EXT}(${shortOid})`); + expect(putResult.commit.message).toBe(`insert: ${_id}${JSON_EXTENSION}(${shortOid})`); // fs.access() throw error when a file cannot be accessed. - const filePath = path.resolve(gitDDB.workingDir, _id + JSON_EXT); + const filePath = path.resolve(gitDDB.workingDir, _id + JSON_EXTENSION); await expect(fs.access(filePath)).resolves.not.toThrowError(); expect(fs.readFileSync(filePath, 'utf8')).toBe(toSortedJSONString(json)); @@ -396,17 +396,17 @@ describe(' insertFatDoc(name, jsonDoc)', () => { }); await gitDDB.open(); const _id = 'prof01'; - const name = _id + JSON_EXT; + const name = _id + JSON_EXTENSION; const json = { _id, name: 'Shirase' }; const putResult = (await gitDDB.insertFatDoc(name, json)) as PutResultJsonDoc; const fileOid = (await git.hashBlob({ object: toSortedJSONString(json) })).oid; const shortOid = fileOid.substr(0, SHORT_SHA_LENGTH); expect(putResult._id).toBe(_id); expect(putResult.fileOid).toBe(fileOid); - expect(putResult.commit.message).toBe(`insert: ${_id}${JSON_EXT}(${shortOid})`); + expect(putResult.commit.message).toBe(`insert: ${_id}${JSON_EXTENSION}(${shortOid})`); // fs.access() throw error when a file cannot be accessed. - const filePath = path.resolve(gitDDB.workingDir, _id + JSON_EXT); + const filePath = path.resolve(gitDDB.workingDir, _id + JSON_EXTENSION); await expect(fs.access(filePath)).resolves.not.toThrowError(); expect(fs.readFileSync(filePath, 'utf8')).toBe(toSortedJSONString(json)); @@ -432,10 +432,10 @@ describe(' update(jsonDoc)', () => { const shortOid = fileOid.substr(0, SHORT_SHA_LENGTH); expect(putResult._id).toBe(_id); expect(putResult.fileOid).toBe(fileOid); - expect(putResult.commit.message).toBe(`update: ${_id}${JSON_EXT}(${shortOid})`); + expect(putResult.commit.message).toBe(`update: ${_id}${JSON_EXTENSION}(${shortOid})`); // fs.access() throw error when a file cannot be accessed. - const filePath = path.resolve(gitDDB.workingDir, _id + JSON_EXT); + const filePath = path.resolve(gitDDB.workingDir, _id + JSON_EXTENSION); await expect(fs.access(filePath)).resolves.not.toThrowError(); expect(fs.readFileSync(filePath, 'utf8')).toBe(toSortedJSONString(jsonUpdated)); @@ -480,10 +480,10 @@ describe(' update(_id, jsonDoc', () => { const shortOid = fileOid.substr(0, SHORT_SHA_LENGTH); expect(putResult._id).toBe(_id); expect(putResult.fileOid).toBe(fileOid); - expect(putResult.commit.message).toBe(`update: ${_id}${JSON_EXT}(${shortOid})`); + expect(putResult.commit.message).toBe(`update: ${_id}${JSON_EXTENSION}(${shortOid})`); // fs.access() throw error when a file cannot be accessed. - const filePath = path.resolve(gitDDB.workingDir, _id + JSON_EXT); + const filePath = path.resolve(gitDDB.workingDir, _id + JSON_EXTENSION); await expect(fs.access(filePath)).resolves.not.toThrowError(); expect(fs.readFileSync(filePath, 'utf8')).toBe(toSortedJSONString(jsonUpdated)); @@ -520,7 +520,7 @@ describe(' updateFatDoc(name, jsonDoc', () => { }); await gitDDB.open(); const _id = 'prof01'; - const name = _id + JSON_EXT; + const name = _id + JSON_EXTENSION; const json = { _id, name: 'Shirase' }; await gitDDB.insert(json); const jsonUpdated = { _id, name: 'updated' }; @@ -529,10 +529,10 @@ describe(' updateFatDoc(name, jsonDoc', () => { const shortOid = fileOid.substr(0, SHORT_SHA_LENGTH); expect(putResult._id).toBe(_id); expect(putResult.fileOid).toBe(fileOid); - expect(putResult.commit.message).toBe(`update: ${_id}${JSON_EXT}(${shortOid})`); + expect(putResult.commit.message).toBe(`update: ${_id}${JSON_EXTENSION}(${shortOid})`); // fs.access() throw error when a file cannot be accessed. - const filePath = path.resolve(gitDDB.workingDir, _id + JSON_EXT); + const filePath = path.resolve(gitDDB.workingDir, _id + JSON_EXTENSION); await expect(fs.access(filePath)).resolves.not.toThrowError(); expect(fs.readFileSync(filePath, 'utf8')).toBe(toSortedJSONString(jsonUpdated)); @@ -563,7 +563,7 @@ describe(' get()', () => { }); await gitDDB.open(); const shortId = 'dir01/prof01'; - const fullDocPath = shortId + JSON_EXT; + const fullDocPath = shortId + JSON_EXTENSION; const json01 = { _id: shortId, name: 'v1' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json01)); @@ -579,7 +579,7 @@ describe(' get()', () => { }); await gitDDB.open(); const shortId = 'prof01'; - const fullDocPath = shortId + JSON_EXT; + const fullDocPath = shortId + JSON_EXTENSION; const json01 = { _id: shortId, name: 'v1' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json01)); @@ -598,8 +598,8 @@ describe(' getFatDoc()', () => { }); await gitDDB.open(); const shortId = 'prof01'; - const shortName = shortId + JSON_EXT; - const fullDocPath = shortId + JSON_EXT; + const shortName = shortId + JSON_EXTENSION; + const fullDocPath = shortId + JSON_EXTENSION; const json01 = { _id: shortId, name: 'v1' }; const json02 = { _id: shortId, name: 'v2' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json01)); @@ -638,7 +638,7 @@ describe(' getDocByOid()', () => { }); await gitDDB.open(); const shortId = 'dir01/prof01'; - const fullDocPath = shortId + JSON_EXT; + const fullDocPath = shortId + JSON_EXTENSION; const json01 = { _id: shortId, name: 'v1' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json01)); const { oid } = await git.hashBlob({ object: toSortedJSONString(json01) }); @@ -654,7 +654,7 @@ describe(' getDocByOid()', () => { }); await gitDDB.open(); const shortId = 'dir01/prof01'; - const fullDocPath = shortId + JSON_EXT; + const fullDocPath = shortId + JSON_EXTENSION; const json01 = { _id: shortId, name: 'v1' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json01)); await expect(gitDDB.getDocByOid('not exist', 'json')).resolves.toBeUndefined(); @@ -670,8 +670,8 @@ describe('', () => { }); const targetId = '01'; - const targetName = targetId + JSON_EXT; - const fullDocPath = targetId + JSON_EXT; + const targetName = targetId + JSON_EXTENSION; + const fullDocPath = targetId + JSON_EXTENSION; const json01 = { _id: targetId, name: 'v01' }; const json02 = { _id: targetId, name: 'v02' }; @@ -1099,7 +1099,7 @@ describe(' getFatDocHistory()', () => { await gitDDB.open(); const _idA = 'profA'; - const shortNameA = _idA + JSON_EXT; + const shortNameA = _idA + JSON_EXTENSION; const jsonA01 = { _id: _idA, name: 'v01' }; const jsonA02 = { _id: _idA, name: 'v02' }; const jsonA03 = { _id: _idA, name: 'v03' }; @@ -1107,7 +1107,7 @@ describe(' getFatDocHistory()', () => { await gitDDB.put(jsonA02); await gitDDB.put(jsonA03); const _idB = 'profB'; - const shortNameB = _idB + JSON_EXT; + const shortNameB = _idB + JSON_EXTENSION; const jsonB01 = { _id: _idB, name: 'v01' }; const jsonB02 = { _id: _idB, name: 'v02' }; await gitDDB.put(jsonB01); @@ -1135,7 +1135,7 @@ describe(' getFatDocHistory()', () => { await gitDDB.open(); const _idA = 'profA'; - const shortNameA = _idA + JSON_EXT; + const shortNameA = _idA + JSON_EXTENSION; const jsonA01 = { _id: _idA, name: 'v01' }; const jsonA02 = { _id: _idA, name: 'v02' }; const jsonA03 = { _id: _idA, name: 'v03' }; @@ -1150,7 +1150,7 @@ describe(' getFatDocHistory()', () => { await gitDDB.put(jsonA03); const _idB = 'profB'; - const shortNameB = _idB + JSON_EXT; + const shortNameB = _idB + JSON_EXTENSION; const jsonB01 = { _id: _idB, name: 'v01' }; const jsonB02 = { _id: _idB, name: 'v02' }; @@ -1377,7 +1377,7 @@ describe(' delete(_id)', () => { const deleteResult = await gitDDB.delete(_id); expect(deleteResult._id).toBe(_id); expect(deleteResult.fileOid).toBe(putResult.fileOid); - expect(deleteResult.commit.message).toBe(`delete: ${_id}${JSON_EXT}(${shortOid})`); + expect(deleteResult.commit.message).toBe(`delete: ${_id}${JSON_EXTENSION}(${shortOid})`); // Check commit directly const commitOid = await git.resolveRef({ fs, dir: gitDDB.workingDir, ref: 'HEAD' }); @@ -1386,7 +1386,7 @@ describe(' delete(_id)', () => { dir: gitDDB.workingDir, oid: commitOid, }); - expect(commit.message).toEqual(`delete: ${_id}${JSON_EXT}(${shortOid})\n`); + expect(commit.message).toEqual(`delete: ${_id}${JSON_EXTENSION}(${shortOid})\n`); await expect(gitDDB.delete(_id)).rejects.toThrowError(Err.DocumentNotFoundError); await expect(gitDDB.get(_id)).resolves.toBeUndefined(); @@ -1466,7 +1466,7 @@ describe(' delete(jsonDoc)', () => { // Check NormalizedCommit expect(deleteResult.commit.oid).toBe(currentCommitOid); expect(deleteResult.commit.message).toBe( - `delete: ${_id}${JSON_EXT}(${oid.substr(0, SHORT_SHA_LENGTH)})` + `delete: ${_id}${JSON_EXTENSION}(${oid.substr(0, SHORT_SHA_LENGTH)})` ); expect(deleteResult.commit.parent).toEqual([prevCommitOid]); expect(deleteResult.commit.author.name).toEqual(gitDDB.author.name); @@ -1492,9 +1492,9 @@ describe(' deleteFatDoc(name)', () => { await gitDDB.open(); const _id = 'test/prof01'; - const name = _id + JSON_EXT; + const name = _id + JSON_EXTENSION; const _id2 = 'test/prof02'; - const name2 = _id2 + JSON_EXT; + const name2 = _id2 + JSON_EXTENSION; const putResult = await gitDDB.put({ _id: _id, name: 'Shirase' }); await gitDDB.put({ _id: _id2, name: 'Soya' }); @@ -1504,7 +1504,7 @@ describe(' deleteFatDoc(name)', () => { const deleteResult = (await gitDDB.deleteFatDoc(name)) as DeleteResultJsonDoc; expect(deleteResult._id).toBe(_id); expect(deleteResult.fileOid).toBe(putResult.fileOid); - expect(deleteResult.commit.message).toBe(`delete: ${_id}${JSON_EXT}(${shortOid})`); + expect(deleteResult.commit.message).toBe(`delete: ${_id}${JSON_EXTENSION}(${shortOid})`); // Check commit directly const commitOid = await git.resolveRef({ fs, dir: gitDDB.workingDir, ref: 'HEAD' }); @@ -1513,7 +1513,7 @@ describe(' deleteFatDoc(name)', () => { dir: gitDDB.workingDir, oid: commitOid, }); - expect(commit.message).toEqual(`delete: ${_id}${JSON_EXT}(${shortOid})\n`); + expect(commit.message).toEqual(`delete: ${_id}${JSON_EXTENSION}(${shortOid})\n`); await expect(gitDDB.deleteFatDoc(name)).rejects.toThrowError(Err.DocumentNotFoundError); await expect(gitDDB.get(_id)).resolves.toBeUndefined(); @@ -1565,7 +1565,7 @@ describe('', () => { }); await gitDDB.open(); - await addOneData(gitDDB, 'invalidJSON' + JSON_EXT, 'invalidJSON'); + await addOneData(gitDDB, 'invalidJSON' + JSON_EXTENSION, 'invalidJSON'); await expect(gitDDB.find()).rejects.toThrowError(Err.InvalidJsonObjectError); @@ -1607,11 +1607,11 @@ describe('', () => { const json_c01_ = { _id: _id_c01, name: name_c01 }; const json_c02_ = { _id: _id_c02, name: name_c02 }; - await addOneData(gitDDB, _id_b + JSON_EXT, toSortedJSONString(json_b)); - await addOneData(gitDDB, _id_a + JSON_EXT, toSortedJSONString(json_a)); - await addOneData(gitDDB, _id_d + JSON_EXT, toSortedJSONString(json_d)); - await addOneData(gitDDB, _id_c01 + JSON_EXT, toSortedJSONString(json_c01)); - await addOneData(gitDDB, _id_c02 + JSON_EXT, toSortedJSONString(json_c02)); + await addOneData(gitDDB, _id_b + JSON_EXTENSION, toSortedJSONString(json_b)); + await addOneData(gitDDB, _id_a + JSON_EXTENSION, toSortedJSONString(json_a)); + await addOneData(gitDDB, _id_d + JSON_EXTENSION, toSortedJSONString(json_d)); + await addOneData(gitDDB, _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01)); + await addOneData(gitDDB, _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02)); await expect(gitDDB.find()).resolves.toEqual([ json_a_, @@ -1649,13 +1649,13 @@ describe('', () => { const json_c01_ = { _id: _id_c01, name: name_c01 }; const json_c02_ = { _id: _id_c02, name: name_c02 }; - await addOneData(gitDDB, _id_b + JSON_EXT, toSortedJSONString(json_b)); - await addOneData(gitDDB, _id_a + JSON_EXT, toSortedJSONString(json_a)); - await addOneData(gitDDB, _id_d + JSON_EXT, toSortedJSONString(json_d)); - await addOneData(gitDDB, _id_c000 + JSON_EXT, toSortedJSONString(json_c000)); - await addOneData(gitDDB, _id_c001 + JSON_EXT, toSortedJSONString(json_c001)); - await addOneData(gitDDB, _id_c01 + JSON_EXT, toSortedJSONString(json_c01)); - await addOneData(gitDDB, _id_c02 + JSON_EXT, toSortedJSONString(json_c02)); + await addOneData(gitDDB, _id_b + JSON_EXTENSION, toSortedJSONString(json_b)); + await addOneData(gitDDB, _id_a + JSON_EXTENSION, toSortedJSONString(json_a)); + await addOneData(gitDDB, _id_d + JSON_EXTENSION, toSortedJSONString(json_d)); + await addOneData(gitDDB, _id_c000 + JSON_EXTENSION, toSortedJSONString(json_c000)); + await addOneData(gitDDB, _id_c001 + JSON_EXTENSION, toSortedJSONString(json_c001)); + await addOneData(gitDDB, _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01)); + await addOneData(gitDDB, _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02)); const prefix = 'citrus/'; @@ -1688,13 +1688,13 @@ describe('', () => { const json_c01_ = { _id: _id_c01, name: name_c01 }; const json_c02_ = { _id: _id_c02, name: name_c02 }; - await addOneData(gitDDB, _id_b + JSON_EXT, toSortedJSONString(json_b)); - await addOneData(gitDDB, _id_a + JSON_EXT, toSortedJSONString(json_a)); - await addOneData(gitDDB, _id_d + JSON_EXT, toSortedJSONString(json_d)); - await addOneData(gitDDB, _id_c000 + JSON_EXT, toSortedJSONString(json_c000)); - await addOneData(gitDDB, _id_c001 + JSON_EXT, toSortedJSONString(json_c001)); - await addOneData(gitDDB, _id_c01 + JSON_EXT, toSortedJSONString(json_c01)); - await addOneData(gitDDB, _id_c02 + JSON_EXT, toSortedJSONString(json_c02)); + await addOneData(gitDDB, _id_b + JSON_EXTENSION, toSortedJSONString(json_b)); + await addOneData(gitDDB, _id_a + JSON_EXTENSION, toSortedJSONString(json_a)); + await addOneData(gitDDB, _id_d + JSON_EXTENSION, toSortedJSONString(json_d)); + await addOneData(gitDDB, _id_c000 + JSON_EXTENSION, toSortedJSONString(json_c000)); + await addOneData(gitDDB, _id_c001 + JSON_EXTENSION, toSortedJSONString(json_c001)); + await addOneData(gitDDB, _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01)); + await addOneData(gitDDB, _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02)); const prefix = 'cit'; @@ -1730,13 +1730,13 @@ describe('', () => { const json_c01_ = { _id: _id_c01, name: name_c01 }; const json_c02_ = { _id: _id_c02, name: name_c02 }; - await addOneData(gitDDB, _id_b + JSON_EXT, toSortedJSONString(json_b)); - await addOneData(gitDDB, _id_a + JSON_EXT, toSortedJSONString(json_a)); - await addOneData(gitDDB, _id_d + JSON_EXT, toSortedJSONString(json_d)); - await addOneData(gitDDB, _id_c000 + JSON_EXT, toSortedJSONString(json_c000)); - await addOneData(gitDDB, _id_c001 + JSON_EXT, toSortedJSONString(json_c001)); - await addOneData(gitDDB, _id_c01 + JSON_EXT, toSortedJSONString(json_c01)); - await addOneData(gitDDB, _id_c02 + JSON_EXT, toSortedJSONString(json_c02)); + await addOneData(gitDDB, _id_b + JSON_EXTENSION, toSortedJSONString(json_b)); + await addOneData(gitDDB, _id_a + JSON_EXTENSION, toSortedJSONString(json_a)); + await addOneData(gitDDB, _id_d + JSON_EXTENSION, toSortedJSONString(json_d)); + await addOneData(gitDDB, _id_c000 + JSON_EXTENSION, toSortedJSONString(json_c000)); + await addOneData(gitDDB, _id_c001 + JSON_EXTENSION, toSortedJSONString(json_c001)); + await addOneData(gitDDB, _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01)); + await addOneData(gitDDB, _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02)); const prefix = 'citrus'; @@ -1774,13 +1774,13 @@ describe('', () => { const json_c01_ = { _id: _id_c01, name: name_c01 }; const json_c02_ = { _id: _id_c02, name: name_c02 }; - await addOneData(gitDDB, _id_b + JSON_EXT, toSortedJSONString(json_b)); - await addOneData(gitDDB, _id_a + JSON_EXT, toSortedJSONString(json_a)); - await addOneData(gitDDB, _id_d + JSON_EXT, toSortedJSONString(json_d)); - await addOneData(gitDDB, _id_c000 + JSON_EXT, toSortedJSONString(json_c000)); - await addOneData(gitDDB, _id_c001 + JSON_EXT, toSortedJSONString(json_c001)); - await addOneData(gitDDB, _id_c01 + JSON_EXT, toSortedJSONString(json_c01)); - await addOneData(gitDDB, _id_c02 + JSON_EXT, toSortedJSONString(json_c02)); + await addOneData(gitDDB, _id_b + JSON_EXTENSION, toSortedJSONString(json_b)); + await addOneData(gitDDB, _id_a + JSON_EXTENSION, toSortedJSONString(json_a)); + await addOneData(gitDDB, _id_d + JSON_EXTENSION, toSortedJSONString(json_d)); + await addOneData(gitDDB, _id_c000 + JSON_EXTENSION, toSortedJSONString(json_c000)); + await addOneData(gitDDB, _id_c001 + JSON_EXTENSION, toSortedJSONString(json_c001)); + await addOneData(gitDDB, _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01)); + await addOneData(gitDDB, _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02)); const prefix = 'citrus/y'; @@ -1813,13 +1813,13 @@ describe('', () => { const json_c01_ = { _id: _id_c01, name: name_c01 }; const json_c02_ = { _id: _id_c02, name: name_c02 }; - await addOneData(gitDDB, _id_b + JSON_EXT, toSortedJSONString(json_b)); - await addOneData(gitDDB, _id_a + JSON_EXT, toSortedJSONString(json_a)); - await addOneData(gitDDB, _id_d + JSON_EXT, toSortedJSONString(json_d)); - await addOneData(gitDDB, _id_c000 + JSON_EXT, toSortedJSONString(json_c000)); - await addOneData(gitDDB, _id_c001 + JSON_EXT, toSortedJSONString(json_c001)); - await addOneData(gitDDB, _id_c01 + JSON_EXT, toSortedJSONString(json_c01)); - await addOneData(gitDDB, _id_c02 + JSON_EXT, toSortedJSONString(json_c02)); + await addOneData(gitDDB, _id_b + JSON_EXTENSION, toSortedJSONString(json_b)); + await addOneData(gitDDB, _id_a + JSON_EXTENSION, toSortedJSONString(json_a)); + await addOneData(gitDDB, _id_d + JSON_EXTENSION, toSortedJSONString(json_d)); + await addOneData(gitDDB, _id_c000 + JSON_EXTENSION, toSortedJSONString(json_c000)); + await addOneData(gitDDB, _id_c001 + JSON_EXTENSION, toSortedJSONString(json_c001)); + await addOneData(gitDDB, _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01)); + await addOneData(gitDDB, _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02)); const prefix = 'not_exist/'; @@ -1855,15 +1855,15 @@ describe('', () => { const json_c01_ = { _id: _id_c01, name: name_c01 }; const json_c02_ = { _id: _id_c02, name: name_c02 }; - await addOneData(gitDDB, _id_p + JSON_EXT, toSortedJSONString(json_p)); + await addOneData(gitDDB, _id_p + JSON_EXTENSION, toSortedJSONString(json_p)); - await addOneData(gitDDB, _id_b + JSON_EXT, toSortedJSONString(json_b)); - await addOneData(gitDDB, _id_a + JSON_EXT, toSortedJSONString(json_a)); - await addOneData(gitDDB, _id_d + JSON_EXT, toSortedJSONString(json_d)); - await addOneData(gitDDB, _id_c000 + JSON_EXT, toSortedJSONString(json_c000)); - await addOneData(gitDDB, _id_c001 + JSON_EXT, toSortedJSONString(json_c001)); - await addOneData(gitDDB, _id_c01 + JSON_EXT, toSortedJSONString(json_c01)); - await addOneData(gitDDB, _id_c02 + JSON_EXT, toSortedJSONString(json_c02)); + await addOneData(gitDDB, _id_b + JSON_EXTENSION, toSortedJSONString(json_b)); + await addOneData(gitDDB, _id_a + JSON_EXTENSION, toSortedJSONString(json_a)); + await addOneData(gitDDB, _id_d + JSON_EXTENSION, toSortedJSONString(json_d)); + await addOneData(gitDDB, _id_c000 + JSON_EXTENSION, toSortedJSONString(json_c000)); + await addOneData(gitDDB, _id_c001 + JSON_EXTENSION, toSortedJSONString(json_c001)); + await addOneData(gitDDB, _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01)); + await addOneData(gitDDB, _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02)); await expect(gitDDB.find({ prefix: 'pear/Japan' })).resolves.toEqual([json_p_]); @@ -1889,44 +1889,44 @@ describe('', () => { const json_c01 = { _id: _id_c01, name: name_c01 }; const json_c02 = { _id: _id_c02, name: name_c02 }; - await addOneData(gitDDB, _id_b + JSON_EXT, toSortedJSONString(json_b)); - await addOneData(gitDDB, _id_a + JSON_EXT, toSortedJSONString(json_a)); - await addOneData(gitDDB, _id_d + JSON_EXT, toSortedJSONString(json_d)); - await addOneData(gitDDB, _id_c01 + JSON_EXT, toSortedJSONString(json_c01)); - await addOneData(gitDDB, _id_c02 + JSON_EXT, toSortedJSONString(json_c02)); + await addOneData(gitDDB, _id_b + JSON_EXTENSION, toSortedJSONString(json_b)); + await addOneData(gitDDB, _id_a + JSON_EXTENSION, toSortedJSONString(json_a)); + await addOneData(gitDDB, _id_d + JSON_EXTENSION, toSortedJSONString(json_d)); + await addOneData(gitDDB, _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01)); + await addOneData(gitDDB, _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02)); await expect(gitDDB.findFatDoc()).resolves.toEqual([ { _id: _id_a, - name: _id_a + JSON_EXT, + name: _id_a + JSON_EXTENSION, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_a) })).oid, type: 'json', doc: json_a, }, { _id: _id_b, - name: _id_b + JSON_EXT, + name: _id_b + JSON_EXTENSION, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_b) })).oid, type: 'json', doc: json_b, }, { _id: _id_c01, - name: _id_c01 + JSON_EXT, + name: _id_c01 + JSON_EXTENSION, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_c01) })).oid, type: 'json', doc: json_c01, }, { _id: _id_c02, - name: _id_c02 + JSON_EXT, + name: _id_c02 + JSON_EXTENSION, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_c02) })).oid, type: 'json', doc: json_c02, }, { _id: _id_d, - name: _id_d + JSON_EXT, + name: _id_d + JSON_EXTENSION, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_d) })).oid, type: 'json', doc: json_d, diff --git a/test/git_documentdb_open.test.ts b/test/git_documentdb_open.test.ts index 68602cb2..1383f6a9 100644 --- a/test/git_documentdb_open.test.ts +++ b/test/git_documentdb_open.test.ts @@ -21,7 +21,7 @@ import { DATABASE_VERSION, FIRST_COMMIT_MESSAGE, GIT_DOCUMENTDB_INFO_ID, - JSON_EXT, + JSON_POSTFIX, } from '../src/const'; import { sleep } from '../src/utils'; @@ -38,11 +38,11 @@ const monoId = () => { const localDir = `./test/database_open`; async function createDatabaseInfo (workingDir: string, info: string) { - const infoPath = path.resolve(workingDir, GIT_DOCUMENTDB_INFO_ID + JSON_EXT); + const infoPath = path.resolve(workingDir, GIT_DOCUMENTDB_INFO_ID + JSON_POSTFIX); await fs.ensureDir(path.dirname(infoPath)); await git.init({ fs, dir: workingDir, defaultBranch: 'main' }); await fs.writeFile(infoPath, info); - await git.add({ fs, dir: workingDir, filepath: GIT_DOCUMENTDB_INFO_ID + JSON_EXT }); + await git.add({ fs, dir: workingDir, filepath: GIT_DOCUMENTDB_INFO_ID + JSON_POSTFIX }); await git.commit({ fs, dir: workingDir, diff --git a/test/remote_base/3way_merge.ts b/test/remote_base/3way_merge.ts index 158bd74e..a5adb89a 100644 --- a/test/remote_base/3way_merge.ts +++ b/test/remote_base/3way_merge.ts @@ -35,7 +35,7 @@ import { getWorkingDirDocs, removeRemoteRepositories, } from '../remote_utils'; -import { JSON_EXT } from '../../src/const'; +import { JSON_EXTENSION } from '../../src/const'; export const syncThreeWayMergeBase = ( connection: ConnectionSettings, @@ -114,12 +114,12 @@ export const syncThreeWayMergeBase = ( local: getCommitInfo([ putResultA1, putResultA2, - `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_EXTENSION}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), remote: getCommitInfo([ putResultB1, putResultB3, - `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_EXTENSION}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), }); expect(syncResult1.changes.local.length).toBe(1); @@ -204,12 +204,12 @@ export const syncThreeWayMergeBase = ( local: getCommitInfo([ putResultA1, putResultA2, - `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_EXTENSION}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), remote: getCommitInfo([ putResultB1, putResultB2, - `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_EXTENSION}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), }); expect(syncResult1.changes.local.length).toBe(0); @@ -281,11 +281,11 @@ export const syncThreeWayMergeBase = ( expect(syncResult1.commits).toMatchObject({ local: getCommitInfo([ putResultA1, - `resolve: 1${JSON_EXT}(insert,${putResultA1.fileOid.substr(0, 7)},theirs)`, + `resolve: 1${JSON_EXTENSION}(insert,${putResultA1.fileOid.substr(0, 7)},theirs)`, ]), remote: getCommitInfo([ putResultB1, - `resolve: 1${JSON_EXT}(insert,${putResultA1.fileOid.substr(0, 7)},theirs)`, + `resolve: 1${JSON_EXTENSION}(insert,${putResultA1.fileOid.substr(0, 7)},theirs)`, ]), }); expect(syncResult1.changes.local.length).toBe(1); @@ -370,12 +370,12 @@ export const syncThreeWayMergeBase = ( local: getCommitInfo([ putResultA1, deleteResultA2, - `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_EXTENSION}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), remote: getCommitInfo([ putResultB1, deleteResultB2, - `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_EXTENSION}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), }); expect(syncResult1.changes.local.length).toBe(0); @@ -459,12 +459,12 @@ export const syncThreeWayMergeBase = ( expect(syncResult1.commits).toMatchObject({ local: getCommitInfo([ putResultA1, - `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_EXTENSION}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), remote: getCommitInfo([ putResultB1, deleteResultB2, - `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_EXTENSION}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), }); expect(syncResult1.changes.local.length).toBe(0); @@ -547,11 +547,11 @@ export const syncThreeWayMergeBase = ( expect(syncResult1.commits).toMatchObject({ local: getCommitInfo([ putResultA1dash, - `resolve: 1${JSON_EXT}(delete,${deleteResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_EXTENSION}(delete,${deleteResultB1.fileOid.substr(0, 7)},ours)`, ]), remote: getCommitInfo([ deleteResultB1, - `resolve: 1${JSON_EXT}(delete,${deleteResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_EXTENSION}(delete,${deleteResultB1.fileOid.substr(0, 7)},ours)`, ]), }); expect(syncResult1.changes.local.length).toBe(0); @@ -632,11 +632,11 @@ export const syncThreeWayMergeBase = ( expect(syncResult1.commits).toMatchObject({ local: getCommitInfo([ putResultA1dash, - `resolve: 1${JSON_EXT}(update,${putResultA1dash.fileOid.substr(0, 7)},theirs)`, + `resolve: 1${JSON_EXTENSION}(update,${putResultA1dash.fileOid.substr(0, 7)},theirs)`, ]), remote: getCommitInfo([ deleteResultB1, - `resolve: 1${JSON_EXT}(update,${putResultA1dash.fileOid.substr(0, 7)},theirs)`, + `resolve: 1${JSON_EXTENSION}(update,${putResultA1dash.fileOid.substr(0, 7)},theirs)`, ]), }); @@ -718,11 +718,11 @@ export const syncThreeWayMergeBase = ( local: getCommitInfo([ putResultA1, deleteResultA2, - `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_EXTENSION}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), remote: getCommitInfo([ putResultB1, - `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_EXTENSION}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), }); expect(syncResult1.changes.local.length).toBe(1); @@ -807,11 +807,11 @@ export const syncThreeWayMergeBase = ( local: getCommitInfo([ deleteResultA1, putResultA2, - `resolve: 1${JSON_EXT}(update,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_EXTENSION}(update,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), remote: getCommitInfo([ putResultB1, - `resolve: 1${JSON_EXT}(update,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_EXTENSION}(update,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), }); expect(syncResult1.changes.local.length).toBe(1); @@ -900,11 +900,11 @@ export const syncThreeWayMergeBase = ( local: getCommitInfo([ deleteResultA1, putResultA2, - `resolve: 1${JSON_EXT}(delete,${deleteResultA1.fileOid.substr(0, 7)},theirs)`, + `resolve: 1${JSON_EXTENSION}(delete,${deleteResultA1.fileOid.substr(0, 7)},theirs)`, ]), remote: getCommitInfo([ putResultB1, - `resolve: 1${JSON_EXT}(delete,${deleteResultA1.fileOid.substr(0, 7)},theirs)`, + `resolve: 1${JSON_EXTENSION}(delete,${deleteResultA1.fileOid.substr(0, 7)},theirs)`, ]), }); expect(syncResult1.changes.local.length).toBe(2); @@ -991,12 +991,12 @@ export const syncThreeWayMergeBase = ( local: getCommitInfo([ putResultA1, putResultA2dash, - `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_EXTENSION}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), remote: getCommitInfo([ putResultB1, putResultB2, - `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_EXTENSION}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), }); expect(syncResult1.changes.local.length).toBe(0); @@ -1084,12 +1084,12 @@ export const syncThreeWayMergeBase = ( local: getCommitInfo([ putResultA1, putResultA2dash, - `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_EXTENSION}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), remote: getCommitInfo([ putResultB1, putResultB2, - `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_EXTENSION}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), }); expect(syncResult1.changes.local.length).toBe(1); @@ -1180,12 +1180,12 @@ export const syncThreeWayMergeBase = ( local: getCommitInfo([ putResultA1, putResultA2dash, - `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_EXTENSION}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), remote: getCommitInfo([ putResultB1, putResultB2, - `resolve: 1${JSON_EXT}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_EXTENSION}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), }); expect(syncResult1.changes.local.length).toBe(0); @@ -1266,11 +1266,11 @@ export const syncThreeWayMergeBase = ( expect(syncResult1.commits).toMatchObject({ local: getCommitInfo([ putResultA1dash, - `resolve: 1${JSON_EXT}(update,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_EXTENSION}(update,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), remote: getCommitInfo([ putResultB1, - `resolve: 1${JSON_EXT}(update,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_EXTENSION}(update,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), }); expect(syncResult1.changes.local.length).toBe(0); @@ -1353,11 +1353,11 @@ export const syncThreeWayMergeBase = ( expect(syncResult1.commits).toMatchObject({ local: getCommitInfo([ putResultA1dash, - `resolve: 1${JSON_EXT}(update,${putResultA1dash.fileOid.substr(0, 7)},theirs)`, + `resolve: 1${JSON_EXTENSION}(update,${putResultA1dash.fileOid.substr(0, 7)},theirs)`, ]), remote: getCommitInfo([ putResultB1, - `resolve: 1${JSON_EXT}(update,${putResultA1dash.fileOid.substr(0, 7)},theirs)`, + `resolve: 1${JSON_EXTENSION}(update,${putResultA1dash.fileOid.substr(0, 7)},theirs)`, ]), }); expect(syncResult1.changes.local.length).toBe(1); @@ -1459,25 +1459,25 @@ export const syncThreeWayMergeBase = ( putResultA3dash, putResultA1dash, deleteResultA2, - `resolve: 1${JSON_EXT}(delete,${deleteResultB1.fileOid.substr( + `resolve: 1${JSON_EXTENSION}(delete,${deleteResultB1.fileOid.substr( 0, 7 - )},ours), 2${JSON_EXT}(update,${putResultB2.fileOid.substr( + )},ours), 2${JSON_EXTENSION}(update,${putResultB2.fileOid.substr( 0, 7 - )},ours), 3${JSON_EXT}(update,${putResultB3.fileOid.substr(0, 7)},ours)`, + )},ours), 3${JSON_EXTENSION}(update,${putResultB3.fileOid.substr(0, 7)},ours)`, ]), remote: getCommitInfo([ putResultB3, deleteResultB1, putResultB2, - `resolve: 1${JSON_EXT}(delete,${deleteResultB1.fileOid.substr( + `resolve: 1${JSON_EXTENSION}(delete,${deleteResultB1.fileOid.substr( 0, 7 - )},ours), 2${JSON_EXT}(update,${putResultB2.fileOid.substr( + )},ours), 2${JSON_EXTENSION}(update,${putResultB2.fileOid.substr( 0, 7 - )},ours), 3${JSON_EXT}(update,${putResultB3.fileOid.substr(0, 7)},ours)`, + )},ours), 3${JSON_EXTENSION}(update,${putResultB3.fileOid.substr(0, 7)},ours)`, ]), }); expect(syncResult1.changes.local.length).toBe(0); @@ -1595,11 +1595,11 @@ export const syncThreeWayMergeBase = ( expect(syncResult1.commits).toMatchObject({ local: getCommitInfo([ putResultA1dash, - `resolve: 1${JSON_EXT}(update,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_EXTENSION}(update,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), remote: getCommitInfo([ putResultB1, - `resolve: 1${JSON_EXT}(update,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_EXTENSION}(update,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), }); expect(syncResult1.changes.local.length).toBe(0); @@ -1691,11 +1691,11 @@ export const syncThreeWayMergeBase = ( expect(syncResult1.commits).toMatchObject({ local: getCommitInfo([ putResultA1dash, - `resolve: 1${JSON_EXT}(update,${putResultA1dash.fileOid.substr(0, 7)},theirs)`, + `resolve: 1${JSON_EXTENSION}(update,${putResultA1dash.fileOid.substr(0, 7)},theirs)`, ]), remote: getCommitInfo([ putResultB1, - `resolve: 1${JSON_EXT}(update,${putResultA1dash.fileOid.substr(0, 7)},theirs)`, + `resolve: 1${JSON_EXTENSION}(update,${putResultA1dash.fileOid.substr(0, 7)},theirs)`, ]), }); expect(syncResult1.changes.local.length).toBe(1); diff --git a/test/remote_base/3way_merge_ot.ts b/test/remote_base/3way_merge_ot.ts index c1597464..1e09b06b 100644 --- a/test/remote_base/3way_merge_ot.ts +++ b/test/remote_base/3way_merge_ot.ts @@ -33,7 +33,7 @@ import { removeRemoteRepositories, } from '../remote_utils'; -import { JSON_EXT } from '../../src/const'; +import { JSON_EXTENSION } from '../../src/const'; export const threeWayMergeOtBase = ( connection: ConnectionSettings, @@ -100,7 +100,7 @@ export const threeWayMergeOtBase = ( local: getCommitInfo([ putResultA1, putResultA2, - `resolve: 1${JSON_EXT}(insert-merge,${mergedDoc!.fileOid.substr( + `resolve: 1${JSON_EXTENSION}(insert-merge,${mergedDoc!.fileOid.substr( 0, 7 )},ours-diff)`, @@ -108,7 +108,7 @@ export const threeWayMergeOtBase = ( remote: getCommitInfo([ putResultB1, putResultB3, - `resolve: 1${JSON_EXT}(insert-merge,${mergedDoc!.fileOid.substr( + `resolve: 1${JSON_EXTENSION}(insert-merge,${mergedDoc!.fileOid.substr( 0, 7 )},ours-diff)`, @@ -201,14 +201,14 @@ export const threeWayMergeOtBase = ( expect(syncResult1.commits).toMatchObject({ local: getCommitInfo([ putResultA1, - `resolve: 1${JSON_EXT}(insert-merge,${mergedDoc!.fileOid.substr( + `resolve: 1${JSON_EXTENSION}(insert-merge,${mergedDoc!.fileOid.substr( 0, 7 )},theirs-diff)`, ]), remote: getCommitInfo([ putResultB1, - `resolve: 1${JSON_EXT}(insert-merge,${mergedDoc!.fileOid.substr( + `resolve: 1${JSON_EXTENSION}(insert-merge,${mergedDoc!.fileOid.substr( 0, 7 )},theirs-diff)`, @@ -286,11 +286,11 @@ export const threeWayMergeOtBase = ( expect(syncResult1.commits).toMatchObject({ local: getCommitInfo([ putResultA1dash, - `resolve: 1${JSON_EXT}(delete,${deleteResultB1.fileOid.substr(0, 7)},ours-diff)`, + `resolve: 1${JSON_EXTENSION}(delete,${deleteResultB1.fileOid.substr(0, 7)},ours-diff)`, ]), remote: getCommitInfo([ deleteResultB1, - `resolve: 1${JSON_EXT}(delete,${deleteResultB1.fileOid.substr(0, 7)},ours-diff)`, + `resolve: 1${JSON_EXTENSION}(delete,${deleteResultB1.fileOid.substr(0, 7)},ours-diff)`, ]), }); expect(syncResult1.changes.local.length).toBe(0); @@ -373,11 +373,11 @@ export const threeWayMergeOtBase = ( local: getCommitInfo([ deleteResultA1, putResultA2, - `resolve: 1${JSON_EXT}(update,${putResultB1.fileOid.substr(0, 7)},ours-diff)`, + `resolve: 1${JSON_EXTENSION}(update,${putResultB1.fileOid.substr(0, 7)},ours-diff)`, ]), remote: getCommitInfo([ putResultB1, - `resolve: 1${JSON_EXT}(update,${putResultB1.fileOid.substr(0, 7)},ours-diff)`, + `resolve: 1${JSON_EXTENSION}(update,${putResultB1.fileOid.substr(0, 7)},ours-diff)`, ]), }); expect(syncResult1.changes.local.length).toBe(1); @@ -479,14 +479,14 @@ export const threeWayMergeOtBase = ( expect(syncResult1.commits).toMatchObject({ local: getCommitInfo([ putResultA1dash, - `resolve: 1${JSON_EXT}(update-merge,${mergedDoc!.fileOid.substr( + `resolve: 1${JSON_EXTENSION}(update-merge,${mergedDoc!.fileOid.substr( 0, 7 )},theirs-diff)`, ]), remote: getCommitInfo([ putResultB1, - `resolve: 1${JSON_EXT}(update-merge,${mergedDoc!.fileOid.substr( + `resolve: 1${JSON_EXTENSION}(update-merge,${mergedDoc!.fileOid.substr( 0, 7 )},theirs-diff)`, diff --git a/test/remote_base/combine.ts b/test/remote_base/combine.ts index dd9477bc..27307f22 100644 --- a/test/remote_base/combine.ts +++ b/test/remote_base/combine.ts @@ -29,7 +29,7 @@ import { removeRemoteRepositories, } from '../remote_utils'; import { sleep } from '../../src/utils'; -import { JSON_EXT } from '../../src/const'; +import { JSON_EXTENSION } from '../../src/const'; export const syncCombineBase = ( connection: ConnectionSettings, @@ -292,7 +292,7 @@ export const syncCombineBase = ( expect(getWorkingDirDocs(dbA)).toEqual([jsonA1]); // jsonB1 is duplicated with postfix due to combine-head-with-theirs strategy jsonB1._id = jsonB1._id + '-from-' + dbIdB; - const duplicatedB1 = await dbB.getFatDoc(jsonB1._id + JSON_EXT); + const duplicatedB1 = await dbB.getFatDoc(jsonB1._id + JSON_EXTENSION); expect(syncResult).toEqual({ action: 'combine database', @@ -300,13 +300,13 @@ export const syncCombineBase = ( { original: { _id: jsonA1._id, - name: jsonA1._id + JSON_EXT, + name: jsonA1._id + JSON_EXTENSION, fileOid: putResultA1.fileOid, type: 'json', }, duplicate: { _id: jsonB1._id, - name: jsonB1._id + JSON_EXT, + name: jsonB1._id + JSON_EXTENSION, fileOid: duplicatedB1?.fileOid, type: 'json', }, @@ -361,7 +361,7 @@ export const syncCombineBase = ( expect(getWorkingDirDocs(dbA)).toEqual([jsonA1]); // jsonB1 is duplicated with postfix due to combine-head-with-theirs strategy jsonB1._id = jsonB1._id + '-from-' + dbIdB; - const duplicatedB1 = await dbB.getFatDoc(jsonB1._id + JSON_EXT); + const duplicatedB1 = await dbB.getFatDoc(jsonB1._id + JSON_EXTENSION); expect(syncResult).toEqual({ action: 'combine database', @@ -369,13 +369,13 @@ export const syncCombineBase = ( { original: { _id: jsonA1._id, - name: jsonA1._id + JSON_EXT, + name: jsonA1._id + JSON_EXTENSION, fileOid: putResultA1.fileOid, type: 'json', }, duplicate: { _id: jsonB1._id, - name: jsonB1._id + JSON_EXT, + name: jsonB1._id + JSON_EXTENSION, fileOid: duplicatedB1?.fileOid, type: 'json', }, @@ -435,7 +435,7 @@ export const syncCombineBase = ( }); jsonA1._id = jsonA1._id + '-from-' + dbIdA; - const duplicatedA1 = await dbA.getFatDoc(jsonA1._id + JSON_EXT); + const duplicatedA1 = await dbA.getFatDoc(jsonA1._id + JSON_EXTENSION); expect(getWorkingDirDocs(dbA)).toEqual([jsonA1, jsonB1, jsonB2]); // jsonA1 is duplicated with postfix due to combine-head-with-theirs strategy @@ -448,13 +448,13 @@ export const syncCombineBase = ( { original: { _id: jsonB1._id, - name: jsonB1._id + JSON_EXT, + name: jsonB1._id + JSON_EXTENSION, fileOid: putResultB1.fileOid, type: 'json', }, duplicate: { _id: jsonA1._id, - name: jsonA1._id + JSON_EXT, + name: jsonA1._id + JSON_EXTENSION, fileOid: duplicatedA1?.fileOid, type: 'json', }, diff --git a/test/remote_base/network_history.ts b/test/remote_base/network_history.ts index 17aca601..08ca1afa 100644 --- a/test/remote_base/network_history.ts +++ b/test/remote_base/network_history.ts @@ -21,7 +21,7 @@ import { removeRemoteRepositories, } from '../remote_utils'; import { sleep, toSortedJSONString, utf8encode } from '../../src/utils'; -import { JSON_EXT } from '../../src/const'; +import { JSON_EXTENSION } from '../../src/const'; import { getHistoryImpl, readOldBlob } from '../../src/crud/history'; export const networkHistoryBase = ( @@ -52,7 +52,7 @@ export const networkHistoryBase = ( ); const _id = 'prof'; - const shortName = _id + JSON_EXT; + const shortName = _id + JSON_EXTENSION; const jsonA1 = { _id, name: 'A-1' }; const jsonA2 = { _id, name: 'A-2' }; const jsonA3 = { _id, name: 'A-3' }; diff --git a/test/remote_base/sync_trysync.ts b/test/remote_base/sync_trysync.ts index 34da6b06..a420d88d 100644 --- a/test/remote_base/sync_trysync.ts +++ b/test/remote_base/sync_trysync.ts @@ -40,7 +40,7 @@ import { removeRemoteRepositories, } from '../remote_utils'; import { sleep, toSortedJSONString } from '../../src/utils'; -import { JSON_EXT } from '../../src/const'; +import { JSON_EXTENSION } from '../../src/const'; import { Err } from '../../src/error'; // eslint-disable-next-line @typescript-eslint/no-var-requires @@ -745,7 +745,7 @@ export const syncTrySyncBase = ( { fatDoc: { _id: jsonB1._id, - name: jsonB1._id + JSON_EXT, + name: jsonB1._id + JSON_EXTENSION, fileOid: putResultB1.fileOid, type: 'json', doc: jsonB1, diff --git a/test/remote_utils.ts b/test/remote_utils.ts index 454d8908..d71a6d36 100644 --- a/test/remote_utils.ts +++ b/test/remote_utils.ts @@ -16,7 +16,7 @@ import { } from '../src/types'; import { SyncInterface } from '../src/types_sync'; import { GitDocumentDB } from '../src/git_documentdb'; -import { FILE_REMOVE_TIMEOUT, GIT_DOCUMENTDB_METADATA_DIR, JSON_EXT } from '../src/const'; +import { FILE_REMOVE_TIMEOUT, GIT_DOCUMENTDB_METADATA_DIR, JSON_EXTENSION } from '../src/const'; import { RemoteRepository } from '../src/remote/remote_repository'; const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; @@ -63,7 +63,7 @@ export function getChangedFileInsert ( operation: 'insert', new: { _id: newDoc!._id, - name: newDoc!._id + JSON_EXT, + name: newDoc!._id + JSON_EXTENSION, fileOid: newResult!.fileOid, type: 'json', doc: newDoc, @@ -81,14 +81,14 @@ export function getChangedFileUpdate ( operation: 'update', old: { _id: oldDoc!._id, - name: oldDoc!._id + JSON_EXT, + name: oldDoc!._id + JSON_EXTENSION, fileOid: oldResult!.fileOid, type: 'json', doc: oldDoc!, }, new: { _id: newDoc!._id, - name: newDoc!._id + JSON_EXT, + name: newDoc!._id + JSON_EXTENSION, fileOid: newResult!.fileOid, type: 'json', doc: newDoc, @@ -104,7 +104,7 @@ export function getChangedFileDelete ( operation: 'delete', old: { _id: oldDoc!._id, - name: oldDoc!._id + JSON_EXT, + name: oldDoc!._id + JSON_EXTENSION, fileOid: oldResult!.fileOid, type: 'json', doc: oldDoc, @@ -120,7 +120,7 @@ export function getChangedFileInsertBySHA ( operation: 'insert', new: { _id: newDoc!._id, - name: newDoc!._id + JSON_EXT, + name: newDoc!._id + JSON_EXTENSION, fileOid: newFileSHA, type: 'json', doc: newDoc, @@ -138,14 +138,14 @@ export function getChangedFileUpdateBySHA ( operation: 'update', old: { _id: oldDoc!._id, - name: oldDoc!._id + JSON_EXT, + name: oldDoc!._id + JSON_EXTENSION, fileOid: oldFileSHA, type: 'json', doc: oldDoc!, }, new: { _id: newDoc!._id, - name: newDoc!._id + JSON_EXT, + name: newDoc!._id + JSON_EXTENSION, fileOid: newFileSHA, type: 'json', doc: newDoc, @@ -161,7 +161,7 @@ export function getChangedFileDeleteBySHA ( operation: 'delete', old: { _id: oldDoc!._id, - name: oldDoc!._id + JSON_EXT, + name: oldDoc!._id + JSON_EXTENSION, fileOid: oldFileSHA, type: 'json', doc: oldDoc, @@ -376,7 +376,7 @@ export const compareWorkingDirAndBlobs = async ( export const getWorkingDirDocs = (gitDDB: GitDocumentDB) => { return listFiles(gitDDB, gitDDB.workingDir).map(filepath => { const doc = fs.readJSONSync(gitDDB.workingDir + '/' + filepath); - doc._id = filepath.replace(new RegExp(JSON_EXT + '$'), ''); + doc._id = filepath.replace(new RegExp(JSON_EXTENSION + '$'), ''); return doc; }); }; From c622adcc1f25c025fa9a7e9f8e9586a8da51cced Mon Sep 17 00:00:00 2001 From: sosuisen Date: Mon, 11 Oct 2021 23:46:01 +0900 Subject: [PATCH 193/297] fix: add toFrontMatterMarkdown --- package-lock.json | 13811 +++++++++++++++++++++++++++++++++++++++----- package.json | 7 +- src/utils.ts | 9 +- 3 files changed, 12387 insertions(+), 1440 deletions(-) diff --git a/package-lock.json b/package-lock.json index b653cd65..53ed0c7d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,45 +1,10769 @@ { "name": "git-documentdb", - "version": "0.4.1", - "lockfileVersion": 1, + "version": "0.4.6", + "lockfileVersion": 2, "requires": true, + "packages": { + "": { + "name": "git-documentdb", + "version": "0.4.6", + "license": "MPL-2.0", + "dependencies": { + "@octokit/rest": "^18.3.5", + "@sosuisen/jsondiffpatch": "^0.4.7", + "@types/async-lock": "^1.1.2", + "@types/js-yaml": "^4.0.3", + "async-lock": "^1.3.0", + "cross-blob": "^2.0.0", + "fs-extra": "^9.1.0", + "git-documentdb-remote-errors": "^1.0.3", + "isomorphic-git": "^1.8.2", + "js-yaml": "^4.1.0", + "ot-json1": "^1.0.2", + "rimraf": "^3.0.2", + "tslog": "^3.1.2", + "ulid": "^2.3.0", + "unicount": "^1.2.0" + }, + "devDependencies": { + "@microsoft/api-extractor": "^7.16.0", + "@octokit/types": "^6.12.2", + "@sosuisen/api-documenter": "^7.13.27", + "@types/fs-extra": "^9.0.12", + "@types/mocha": "^8.2.2", + "@types/node": "^14.14.20", + "@types/parse-git-config": "^3.0.0", + "@types/rimraf": "^3.0.0", + "@types/sinon": "^9.0.11", + "@typescript-eslint/eslint-plugin": "^4.28.0", + "@typescript-eslint/parser": "^4.28.0", + "coveralls": "^3.1.0", + "crlf": "^1.1.1", + "cross-env": "^7.0.3", + "eslint": "^7.17.0", + "eslint-config-standardize": "^0.7.1", + "eslint-plugin-prettierx": "^0.14.0", + "eslint-plugin-unicorn": "^36.0.0", + "expect": "^27.0.2", + "git-documentdb-plugin-remote-nodegit": "^1.0.4", + "mocha": "^8.3.2", + "nyc": "^15.1.0", + "parse-git-config": "^3.0.0", + "sinon": "^10.0.0", + "ts-node": "^10.1.0", + "tsconfig-paths": "^3.9.0", + "typescript": "^4.3.4" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@angular/compiler": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-9.0.5.tgz", + "integrity": "sha512-TeyhRGefTOtA9N3udMrvheafoXcz/dvTTdZLcieeZQxm1SSeaQDUQ/rUH6QTOiHVNMtjOCrZ9J5rk1A4mPYuag==", + "dev": true, + "peerDependencies": { + "tslib": "^1.10.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.10.4" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.15.0.tgz", + "integrity": "sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.8.tgz", + "integrity": "sha512-3UG9dsxvYBMYwRv+gS41WKHno4K60/9GPy1CJaH6xy3Elq8CTtvtjT5R5jmNhXfCYLX2mTw+7/aq5ak/gOE0og==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.15.8", + "@babel/generator": "^7.15.8", + "@babel/helper-compilation-targets": "^7.15.4", + "@babel/helper-module-transforms": "^7.15.8", + "@babel/helpers": "^7.15.4", + "@babel/parser": "^7.15.8", + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.6", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/@babel/code-frame": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", + "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/core/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@babel/generator": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.8.tgz", + "integrity": "sha512-ECmAKstXbp1cvpTTZciZCgfOt6iN64lR0d+euv3UZisU5awfRawOvg07Utn/qBGuH4bRIEZKrA/4LzZyXhZr8g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.15.6", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/generator/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz", + "integrity": "sha512-rMWPCirulnPSe4d+gwdWXLfAXTTBj8M3guAf5xFQJ0nvFY7tfNAFnWdqaHegHlgDZOCT4qvhF3BYlSJag8yhqQ==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.15.0", + "@babel/helper-validator-option": "^7.14.5", + "browserslist": "^4.16.6", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz", + "integrity": "sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw==", + "dev": true, + "dependencies": { + "@babel/helper-get-function-arity": "^7.15.4", + "@babel/template": "^7.15.4", + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-get-function-arity": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz", + "integrity": "sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz", + "integrity": "sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.4.tgz", + "integrity": "sha512-cokOMkxC/BTyNP1AlY25HuBWM32iCEsLPI4BHDpJCHHm1FU2E7dKWWIXJgQgSFiu4lp8q3bL1BIKwqkSUviqtA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz", + "integrity": "sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.8.tgz", + "integrity": "sha512-DfAfA6PfpG8t4S6npwzLvTUpp0sS7JrcuaMiy1Y5645laRJIp/LiLGIBbQKaXSInK8tiGNI7FL7L8UvB8gdUZg==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.15.4", + "@babel/helper-replace-supers": "^7.15.4", + "@babel/helper-simple-access": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4", + "@babel/helper-validator-identifier": "^7.15.7", + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.15.4.tgz", + "integrity": "sha512-E/z9rfbAOt1vDW1DR7k4SzhzotVV5+qMciWV6LaG1g4jeFrkDlJedjtV4h0i4Q/ITnUu+Pk08M7fczsB9GXBDw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.4.tgz", + "integrity": "sha512-/ztT6khaXF37MS47fufrKvIsiQkx1LBRvSJNzRqmbyeZnTwU9qBxXYLaaT/6KaxfKhjs2Wy8kG8ZdsFUuWBjzw==", + "dev": true, + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.15.4", + "@babel/helper-optimise-call-expression": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.15.4.tgz", + "integrity": "sha512-UzazrDoIVOZZcTeHHEPYrr1MvTR/K+wgLg6MY6e1CJyaRhbibftF6fR2KU2sFRtI/nERUZR9fBd6aKgBlIBaPg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz", + "integrity": "sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.15.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", + "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", + "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.4.tgz", + "integrity": "sha512-V45u6dqEJ3w2rlryYYXf6i9rQ5YMNu4FLS6ngs8ikblhu2VdR1AqAd6aJjBzmf2Qzh6KOLqKHxEN9+TFbAkAVQ==", + "dev": true, + "dependencies": { + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.14.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.8.tgz", + "integrity": "sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/template": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.15.4.tgz", + "integrity": "sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.15.4", + "@babel/types": "^7.15.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template/node_modules/@babel/code-frame": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", + "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.4.tgz", + "integrity": "sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.15.4", + "@babel/helper-function-name": "^7.15.4", + "@babel/helper-hoist-variables": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4", + "@babel/parser": "^7.15.4", + "@babel/types": "^7.15.4", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/@babel/code-frame": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", + "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/types": { + "version": "7.15.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.6.tgz", + "integrity": "sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.14.9", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@cspotcode/source-map-consumer": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", + "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.6.1.tgz", + "integrity": "sha512-DX3Z+T5dt1ockmPdobJS/FAsQPW4V4SrWEhD2iYQT2Cb2tQsiMnYxrcUH9By/Z3B+v0S5LMBkQtV/XOBbpLEOg==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-consumer": "0.8.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", + "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/@eslint/eslintrc/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@glimmer/env": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/@glimmer/env/-/env-0.1.7.tgz", + "integrity": "sha1-/S0rVakCnGs3psk16MiHGucN+gc=", + "dev": true + }, + "node_modules/@glimmer/interfaces": { + "version": "0.56.2", + "resolved": "https://registry.npmjs.org/@glimmer/interfaces/-/interfaces-0.56.2.tgz", + "integrity": "sha512-nRgcsTuyZ90aEoCuYVHKGDs3LpAv9n/JKiJ6iecpEYtyGgcPqSI3GjrJRl6k+1s5wnldEH1kjWq+ccCiXmA99w==", + "dev": true, + "dependencies": { + "@simple-dom/interface": "^1.4.0" + } + }, + "node_modules/@glimmer/syntax": { + "version": "0.56.1", + "resolved": "https://registry.npmjs.org/@glimmer/syntax/-/syntax-0.56.1.tgz", + "integrity": "sha512-4TdtIQVFo9UfIVzXnXpMuzsA4mX06oF9NER8FmIPjBosNiQsYB7P8sABSG+2rtWgsh6CkFXkwvxZ++BB+alwOw==", + "dev": true, + "dependencies": { + "@glimmer/interfaces": "^0.56.1", + "@glimmer/util": "^0.56.1", + "handlebars": "^4.7.4", + "simple-html-tokenizer": "^0.5.9" + } + }, + "node_modules/@glimmer/util": { + "version": "0.56.2", + "resolved": "https://registry.npmjs.org/@glimmer/util/-/util-0.56.2.tgz", + "integrity": "sha512-AljXCX5HBjJkmNt4DNYmJmVvwqKjFF4lU6e0SBftwhzK85RbETYwpb3YWrghcjSCxoodwIu1zNFiKOA+xD6txw==", + "dev": true, + "dependencies": { + "@glimmer/env": "0.1.7", + "@glimmer/interfaces": "^0.56.2", + "@simple-dom/interface": "^1.4.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", + "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", + "dev": true + }, + "node_modules/@iarna/toml": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-2.2.5.tgz", + "integrity": "sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==", + "dev": true + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/types": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.2.5.tgz", + "integrity": "sha512-nmuM4VuDtCZcY+eTpw+0nvstwReMsjPoj7ZR80/BbixulhLaiX+fbv8oeLW8WZlJMcsGQsTmMKT/iTZu1Uy/lQ==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/types/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/types/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/types/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/types/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/types/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/types/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jsbits/deep-clone": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@jsbits/deep-clone/-/deep-clone-1.1.1.tgz", + "integrity": "sha512-aKhOhRv18tlhkjapBrcyAt8U1SmyzKi2QoO4GGMlXRfQhwm7USDSo/pX8MgB8tYB3MLaevuvwufynKSDA7U3EA==", + "dev": true, + "engines": { + "node": ">=4.2" + } + }, + "node_modules/@microsoft/api-extractor": { + "version": "7.18.15", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.18.15.tgz", + "integrity": "sha512-a8gPbb0gAO+gyWzGmB6eG9ACI3++JS0Y9049xKKITizbGV5PWrLlx3a5S1kSqVP7b6MxVK3QVnJskLzf8n1SkQ==", + "dev": true, + "dependencies": { + "@microsoft/api-extractor-model": "7.13.12", + "@microsoft/tsdoc": "0.13.2", + "@microsoft/tsdoc-config": "~0.15.2", + "@rushstack/node-core-library": "3.42.2", + "@rushstack/rig-package": "0.3.2", + "@rushstack/ts-command-line": "4.10.1", + "colors": "~1.2.1", + "lodash": "~4.17.15", + "resolve": "~1.17.0", + "semver": "~7.3.0", + "source-map": "~0.6.1", + "typescript": "~4.4.2" + }, + "bin": { + "api-extractor": "bin/api-extractor" + } + }, + "node_modules/@microsoft/api-extractor-model": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.13.12.tgz", + "integrity": "sha512-BTTGg1tgcDpW3CyW6QQ3VWFLzKyHxfyNGw68EAS/MXnNKx580HE08hLWrSjM2zHQ1J35v4PBUorsRK+FBkHl5Q==", + "dev": true, + "dependencies": { + "@microsoft/tsdoc": "0.13.2", + "@microsoft/tsdoc-config": "~0.15.2", + "@rushstack/node-core-library": "3.42.2" + } + }, + "node_modules/@microsoft/tsdoc": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.13.2.tgz", + "integrity": "sha512-WrHvO8PDL8wd8T2+zBGKrMwVL5IyzR3ryWUsl0PXgEV0QHup4mTLi0QcATefGI6Gx9Anu7vthPyyyLpY0EpiQg==", + "dev": true + }, + "node_modules/@microsoft/tsdoc-config": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.15.2.tgz", + "integrity": "sha512-mK19b2wJHSdNf8znXSMYVShAHktVr/ib0Ck2FA3lsVBSEhSI/TfXT7DJQkAYgcztTuwazGcg58ZjYdk0hTCVrA==", + "dev": true, + "dependencies": { + "@microsoft/tsdoc": "0.13.2", + "ajv": "~6.12.6", + "jju": "~1.4.0", + "resolve": "~1.19.0" + } + }, + "node_modules/@microsoft/tsdoc-config/node_modules/resolve": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "dev": true, + "dependencies": { + "is-core-module": "^2.1.0", + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@octokit/auth-token": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz", + "integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==", + "dependencies": { + "@octokit/types": "^6.0.3" + } + }, + "node_modules/@octokit/core": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.5.1.tgz", + "integrity": "sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw==", + "dependencies": { + "@octokit/auth-token": "^2.4.4", + "@octokit/graphql": "^4.5.8", + "@octokit/request": "^5.6.0", + "@octokit/request-error": "^2.0.5", + "@octokit/types": "^6.0.3", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/endpoint": { + "version": "6.0.12", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz", + "integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==", + "dependencies": { + "@octokit/types": "^6.0.3", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/graphql": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz", + "integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==", + "dependencies": { + "@octokit/request": "^5.6.0", + "@octokit/types": "^6.0.3", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/openapi-types": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-11.2.0.tgz", + "integrity": "sha512-PBsVO+15KSlGmiI8QAzaqvsNlZlrDlyAJYcrXBCvVUxCp7VnXjkwPoFHgjEJXx3WF9BAwkA6nfCUA7i9sODzKA==" + }, + "node_modules/@octokit/plugin-paginate-rest": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.17.0.tgz", + "integrity": "sha512-tzMbrbnam2Mt4AhuyCHvpRkS0oZ5MvwwcQPYGtMv4tUa5kkzG58SVB0fcsLulOZQeRnOgdkZWkRUiyBlh0Bkyw==", + "dependencies": { + "@octokit/types": "^6.34.0" + }, + "peerDependencies": { + "@octokit/core": ">=2" + } + }, + "node_modules/@octokit/plugin-request-log": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz", + "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==", + "peerDependencies": { + "@octokit/core": ">=3" + } + }, + "node_modules/@octokit/plugin-rest-endpoint-methods": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.13.0.tgz", + "integrity": "sha512-uJjMTkN1KaOIgNtUPMtIXDOjx6dGYysdIFhgA52x4xSadQCz3b/zJexvITDVpANnfKPW/+E0xkOvLntqMYpviA==", + "dependencies": { + "@octokit/types": "^6.34.0", + "deprecation": "^2.3.1" + }, + "peerDependencies": { + "@octokit/core": ">=3" + } + }, + "node_modules/@octokit/request": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.2.tgz", + "integrity": "sha512-je66CvSEVf0jCpRISxkUcCa0UkxmFs6eGDRSbfJtAVwbLH5ceqF+YEyC8lj8ystKyZTy8adWr0qmkY52EfOeLA==", + "dependencies": { + "@octokit/endpoint": "^6.0.1", + "@octokit/request-error": "^2.1.0", + "@octokit/types": "^6.16.1", + "is-plain-object": "^5.0.0", + "node-fetch": "^2.6.1", + "universal-user-agent": "^6.0.0" + } + }, + "node_modules/@octokit/request-error": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz", + "integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==", + "dependencies": { + "@octokit/types": "^6.0.3", + "deprecation": "^2.0.0", + "once": "^1.4.0" + } + }, + "node_modules/@octokit/rest": { + "version": "18.12.0", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.12.0.tgz", + "integrity": "sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==", + "dependencies": { + "@octokit/core": "^3.5.1", + "@octokit/plugin-paginate-rest": "^2.16.8", + "@octokit/plugin-request-log": "^1.0.4", + "@octokit/plugin-rest-endpoint-methods": "^5.12.0" + } + }, + "node_modules/@octokit/types": { + "version": "6.34.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.34.0.tgz", + "integrity": "sha512-s1zLBjWhdEI2zwaoSgyOFoKSl109CUcVBCc7biPJ3aAf6LGLU6szDvi31JPU7bxfla2lqfhjbbg/5DdFNxOwHw==", + "dependencies": { + "@octokit/openapi-types": "^11.2.0" + } + }, + "node_modules/@rushstack/node-core-library": { + "version": "3.42.2", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.42.2.tgz", + "integrity": "sha512-LJ52CiiWxKpzejYACqphQQ3geWZFt5gswki8+0sMl8qZ08YCHbqlS3N+sMZpuBEwLWvBYfq/d3IvtdLT3zI2UA==", + "dev": true, + "dependencies": { + "@types/node": "12.20.24", + "colors": "~1.2.1", + "fs-extra": "~7.0.1", + "import-lazy": "~4.0.0", + "jju": "~1.4.0", + "resolve": "~1.17.0", + "semver": "~7.3.0", + "timsort": "~0.3.0", + "z-schema": "~3.18.3" + } + }, + "node_modules/@rushstack/node-core-library/node_modules/@types/node": { + "version": "12.20.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.24.tgz", + "integrity": "sha512-yxDeaQIAJlMav7fH5AQqPH1u8YIuhYJXYBzxaQ4PifsU0GDO38MSdmEDeRlIxrKbC6NbEaaEHDanWb+y30U8SQ==", + "dev": true + }, + "node_modules/@rushstack/node-core-library/node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/@rushstack/node-core-library/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@rushstack/node-core-library/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/@rushstack/rig-package": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.3.2.tgz", + "integrity": "sha512-lJbud9zBY8+OOjkeQ+4zIVCvt2I8y1C3WcVx3g6NJgjf0pi6IYfbAWXXG+mVzevQmqanNCLyhyXSNP3E6u5OvQ==", + "dev": true, + "dependencies": { + "resolve": "~1.17.0", + "strip-json-comments": "~3.1.1" + } + }, + "node_modules/@rushstack/ts-command-line": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.10.1.tgz", + "integrity": "sha512-FhWnQCjHtxmZr5sVEgoV1VHTFaPfJXQbVwujAaZUzuFfgqX+v2P9o0AXmUi/LED4tmPJp7A1nVgPx0ClyGUbWA==", + "dev": true, + "dependencies": { + "@types/argparse": "1.0.38", + "argparse": "~1.0.9", + "colors": "~1.2.1", + "string-argv": "~0.3.1" + } + }, + "node_modules/@simple-dom/interface": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@simple-dom/interface/-/interface-1.4.0.tgz", + "integrity": "sha512-l5qumKFWU0S+4ZzMaLXFU8tQZsicHEMEyAxI5kDFGhJsRqDwe0a7/iPA/GdxlGyDKseQQAgIz5kzU7eXTrlSpA==", + "dev": true + }, + "node_modules/@sindresorhus/is": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-2.1.1.tgz", + "integrity": "sha512-/aPsuoj/1Dw/kzhkgz+ES6TxG0zfTMGLwuK2ZG00k/iJzYHTLCE8mVU8EPqEOp/lmxPoq1C1C9RYToRKb2KEfg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@sinonjs/commons": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", + "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", + "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, + "node_modules/@sinonjs/samsam": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-5.3.1.tgz", + "integrity": "sha512-1Hc0b1TtyfBu8ixF/tpfSHTVWKwCBLY4QJbkgnE7HcwyvT2xArDxb4K7dMgqRm3szI+LJbzmW/s4xxEhv6hwDg==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.6.0", + "lodash.get": "^4.4.2", + "type-detect": "^4.0.8" + } + }, + "node_modules/@sinonjs/text-encoding": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", + "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", + "dev": true + }, + "node_modules/@sosuisen/api-documenter": { + "version": "7.13.27", + "resolved": "https://registry.npmjs.org/@sosuisen/api-documenter/-/api-documenter-7.13.27.tgz", + "integrity": "sha512-Y3uEwBRSbxEvlLXRD/YcaRhsVNVWMDRLE/EOVDAUzPYy5FrdXiNK0GZNdmxrjCe2E58W/bGKUTZnw9sOI2YOZg==", + "dev": true, + "dependencies": { + "@microsoft/api-extractor-model": "^7.13.3", + "@microsoft/tsdoc": "^0.13.2", + "@rushstack/node-core-library": "^3.39.0", + "@rushstack/ts-command-line": "^4.7.10", + "colors": "~1.2.1", + "js-yaml": "~3.13.1", + "resolve": "~1.17.0" + }, + "bin": { + "api-documenter": "bin/api-documenter" + } + }, + "node_modules/@sosuisen/api-documenter/node_modules/js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@sosuisen/jsondiffpatch": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/@sosuisen/jsondiffpatch/-/jsondiffpatch-0.4.7.tgz", + "integrity": "sha512-PBux/ylEnBMhB5WSee+Ql2YPrO5K7YEnfSm5aZufOEkmewkduakSWdmSrmreUGmJKQWLWqRGSpql3tl7YlppTQ==", + "dependencies": { + "chalk": "^2.3.0", + "diff-match-patch": "^1.0.0" + }, + "bin": { + "jsondiffpatch": "bin/jsondiffpatch" + }, + "engines": { + "node": ">=8.17.0" + } + }, + "node_modules/@sosuisen/nodegit": { + "version": "0.28.0-alpha.11", + "resolved": "https://registry.npmjs.org/@sosuisen/nodegit/-/nodegit-0.28.0-alpha.11.tgz", + "integrity": "sha512-mpztf9ncWxU7/agKQ6E7GvlBIa6H7m3YXuMjlPWVegHusqkbgPi4J01d2inCPhLz0CoC0F/L3LKJuDCAKDXJJg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "fs-extra": "^7.0.0", + "got": "^10.7.0", + "json5": "^2.1.0", + "lodash": "^4.17.14", + "nan": "^2.14.1", + "node-gyp": "^7.1.2", + "node-pre-gyp": "^0.13.0", + "ramda": "^0.25.0", + "tar-fs": "^1.16.3" + }, + "engines": { + "node": ">= 12.19.0 < 13 || >= 14.10.0" + } + }, + "node_modules/@sosuisen/nodegit/node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/@sosuisen/nodegit/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@sosuisen/nodegit/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "dev": true, + "dependencies": { + "defer-to-connect": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", + "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", + "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", + "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", + "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", + "dev": true + }, + "node_modules/@types/argparse": { + "version": "1.0.38", + "resolved": "https://registry.npmjs.org/@types/argparse/-/argparse-1.0.38.tgz", + "integrity": "sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==", + "dev": true + }, + "node_modules/@types/async-lock": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@types/async-lock/-/async-lock-1.1.3.tgz", + "integrity": "sha512-UpeDcjGKsYEQMeqEbfESm8OWJI305I7b9KE4ji3aBjoKWyN5CTdn8izcA1FM1DVDne30R5fNEnIy89vZw5LXJQ==" + }, + "node_modules/@types/cacheable-request": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", + "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", + "dev": true, + "dependencies": { + "@types/http-cache-semantics": "*", + "@types/keyv": "*", + "@types/node": "*", + "@types/responselike": "*" + } + }, + "node_modules/@types/fs-extra": { + "version": "9.0.13", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz", + "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-w+LsMxKyYQm347Otw+IfBXOv9UWVjpHpCDdbBMt8Kz/xbvCYNjP+0qPh91Km3iKfSRLBB0P7fAMf0KHrPu+MyA==", + "dev": true, + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", + "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==", + "dev": true + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", + "dev": true + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/js-yaml": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.3.tgz", + "integrity": "sha512-5t9BhoORasuF5uCPr+d5/hdB++zRFUTMIZOzbNkr+jZh3yQht4HYbRDyj9fY8n2TZT30iW9huzav73x4NikqWg==" + }, + "node_modules/@types/json-schema": { + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", + "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", + "dev": true + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true + }, + "node_modules/@types/keyv": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.3.tgz", + "integrity": "sha512-FXCJgyyN3ivVgRoml4h94G/p3kY+u/B86La+QptcqJaWtBWtmc6TtkNfS40n9bIvyLteHh7zXOtgbobORKPbDg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "dev": true + }, + "node_modules/@types/mocha": { + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.3.tgz", + "integrity": "sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw==", + "dev": true + }, + "node_modules/@types/node": { + "version": "14.17.21", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.21.tgz", + "integrity": "sha512-zv8ukKci1mrILYiQOwGSV4FpkZhyxQtuFWGya2GujWg+zVAeRQ4qbaMmWp9vb9889CFA8JECH7lkwCL6Ygg8kA==", + "dev": true + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", + "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", + "dev": true + }, + "node_modules/@types/parse-git-config": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/parse-git-config/-/parse-git-config-3.0.1.tgz", + "integrity": "sha512-cBVLXlpIpP23p+jQm8d2TrTfxyub3aiqfqgd0TWRnMqwCJMskYiveNJT11YwN+gbo3+0ZFFmtaepKzN7pxExlA==", + "dev": true + }, + "node_modules/@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", + "dev": true + }, + "node_modules/@types/responselike": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", + "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-F3OznnSLAUxFrCEu/L5PY8+ny8DtcFRjx7fZZ9bycvXRi3KPTRS9HOitGZwvPg0juRhXFWIeKX58cnX5YqLohQ==", + "dev": true, + "dependencies": { + "@types/glob": "*", + "@types/node": "*" + } + }, + "node_modules/@types/sinon": { + "version": "9.0.11", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-9.0.11.tgz", + "integrity": "sha512-PwP4UY33SeeVKodNE37ZlOsR9cReypbMJOhZ7BVE0lB+Hix3efCOxiJWiE5Ia+yL9Cn2Ch72EjFTRze8RZsNtg==", + "dev": true, + "dependencies": { + "@types/sinonjs__fake-timers": "*" + } + }, + "node_modules/@types/sinonjs__fake-timers": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.4.tgz", + "integrity": "sha512-IFQTJARgMUBF+xVd2b+hIgXWrZEjND3vJtRCvIelcFB5SIXfjV4bOHbHJ0eXKh+0COrBRc8MqteKAz/j88rE0A==", + "dev": true + }, + "node_modules/@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", + "dev": true + }, + "node_modules/@types/unist": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", + "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==", + "dev": true + }, + "node_modules/@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "20.2.1", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", + "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz", + "integrity": "sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==", + "dev": true, + "dependencies": { + "@typescript-eslint/experimental-utils": "4.33.0", + "@typescript-eslint/scope-manager": "4.33.0", + "debug": "^4.3.1", + "functional-red-black-tree": "^1.0.1", + "ignore": "^5.1.8", + "regexpp": "^3.1.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^4.0.0", + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/experimental-utils": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz", + "integrity": "sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.7", + "@typescript-eslint/scope-manager": "4.33.0", + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/typescript-estree": "4.33.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + } + }, + "node_modules/@typescript-eslint/experimental-utils/node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.33.0.tgz", + "integrity": "sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "4.33.0", + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/typescript-estree": "4.33.0", + "debug": "^4.3.1" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", + "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/visitor-keys": "4.33.0" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", + "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", + "dev": true, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", + "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/visitor-keys": "4.33.0", + "debug": "^4.3.1", + "globby": "^11.0.3", + "is-glob": "^4.0.1", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", + "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.33.0", + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/angular-estree-parser": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/angular-estree-parser/-/angular-estree-parser-1.3.1.tgz", + "integrity": "sha512-jvlnNk4aoEmA6EKK12OnsOkCSdsWleBsYB+aWyH8kpfTB6Li1kxWVbHKVldH9zDCwVVi1hXfqPi/gbSv49tkbQ==", + "dev": true, + "dependencies": { + "lines-and-columns": "^1.1.6", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "@angular/compiler": ">= 6.0.0 < 9.0.6" + } + }, + "node_modules/angular-html-parser": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/angular-html-parser/-/angular-html-parser-1.7.0.tgz", + "integrity": "sha512-/yjeqDQXGblZuFMI6vpDgiIDuv816QpIqa/mCotc0I4R0F5t5sfX1ntZ8VsBVQOUYRjPw8ggYlPZto76gHtf7Q==", + "dev": true, + "dependencies": { + "tslib": "^1.9.3" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "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==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/append-transform": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", + "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", + "dev": true, + "dependencies": { + "default-require-extensions": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true + }, + "node_modules/archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", + "dev": true + }, + "node_modules/are-we-there-yet": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", + "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", + "dev": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "node_modules/are-we-there-yet/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "node_modules/are-we-there-yet/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/are-we-there-yet/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/array-includes": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", + "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1", + "get-intrinsic": "^1.1.1", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", + "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.5.tgz", + "integrity": "sha512-08u6rVyi1Lj7oqWbS9nUxliETrtIROT4XGTA4D/LWGten6E3ocm7cy9SIrmNHOL5XVbVuckUp3X6Xyg8/zpvHA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/async-lock": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/async-lock/-/async-lock-1.3.0.tgz", + "integrity": "sha512-8A7SkiisnEgME2zEedtDYPxUPzdv3x//E7n5IFktPAtMYSEAV7eNJF0rMwrVyUFj6d/8rgajLantbjcNRQYXIg==" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", + "dev": true + }, + "node_modules/bail": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", + "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/before-after-hook": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz", + "integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ==" + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/bl": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", + "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==", + "dev": true, + "dependencies": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/bl/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "node_modules/bl/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/bl/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/blob-polyfill": { + "version": "5.0.20210201", + "resolved": "https://registry.npmjs.org/blob-polyfill/-/blob-polyfill-5.0.20210201.tgz", + "integrity": "sha512-SrH6IG6aXL9pCgSysBCiDpGcAJ1j6/c1qCwR3sTEQJhb+MTk6FITNA6eW6WNYQDNZVi4Z9GjxH5v2MMTv59CrQ==" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "node_modules/browserslist": { + "version": "4.17.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.3.tgz", + "integrity": "sha512-59IqHJV5VGdcJZ+GZ2hU5n4Kv3YiASzW6Xk5g9tf5a/MAzGeFwgGWU39fVzNIOVcgB3+Gp+kiQu0HEfTVU/3VQ==", + "dev": true, + "dependencies": { + "caniuse-lite": "^1.0.30001264", + "electron-to-chromium": "^1.3.857", + "escalade": "^3.1.1", + "node-releases": "^1.1.77", + "picocolors": "^0.2.1" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, + "node_modules/buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "dev": true, + "dependencies": { + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" + } + }, + "node_modules/buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", + "dev": true + }, + "node_modules/buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=", + "dev": true + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "node_modules/builtin-modules": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", + "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cacheable-lookup": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-2.0.1.tgz", + "integrity": "sha512-EMMbsiOTcdngM/K6gV/OxF2x0t07+vMOWxZNSCRQMjO2MY2nhZQ6OYhOOpyQrbhqsgtvKGI7hcq6xjnA92USjg==", + "dev": true, + "dependencies": { + "@types/keyv": "^3.1.1", + "keyv": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cacheable-request": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", + "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", + "dev": true, + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/caching-transform": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", + "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", + "dev": true, + "dependencies": { + "hasha": "^5.0.0", + "make-dir": "^3.0.0", + "package-hash": "^4.0.0", + "write-file-atomic": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001265", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001265.tgz", + "integrity": "sha512-YzBnspggWV5hep1m9Z6sZVLOt7vrju8xWooFAgN6BA5qvy98qPAPb7vNUzypFaoh2pb3vlfzbDO8tB57UPGbtw==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/character-entities": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", + "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", + "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", + "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chokidar": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", + "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.1" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "node_modules/cjk-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/cjk-regex/-/cjk-regex-2.0.0.tgz", + "integrity": "sha512-E4gFi2f3jC0zFVHpaAcupW+gv9OejZ2aV3DP/LlSO0dDcZJAXw7W0ivn+vN17edN/PhU4HCgs1bfx7lPK7FpdA==", + "dev": true, + "dependencies": { + "regexp-util": "^1.2.1", + "unicode-regex": "^2.0.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/cjk-regex/node_modules/unicode-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-regex/-/unicode-regex-2.0.0.tgz", + "integrity": "sha512-5nbEG2YU7loyTvPABaKb+8B0u8L7vWCsVmCSsiaO249ZdMKlvrXlxR2ex4TUVAdzv/Cne/TdoXSSaJArGXaleQ==", + "dev": true, + "dependencies": { + "regexp-util": "^1.2.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/clean-git-ref": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/clean-git-ref/-/clean-git-ref-2.0.1.tgz", + "integrity": "sha512-bLSptAy2P0s6hU4PzuIMKmMJJSE6gLXGH1cntDu7bWJUksvuM+7ReOK61mozULErYvP6a15rnYl0zFDef+pyPw==" + }, + "node_modules/clean-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", + "integrity": "sha1-jffHquUf02h06PjQW5GAvBGj/tc=", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/cliui/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dev": true, + "dependencies": { + "mimic-response": "^1.0.0" + } + }, + "node_modules/clone-response/node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/collapse-white-space": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz", + "integrity": "sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "node_modules/colors": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz", + "integrity": "sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "node_modules/confusing-browser-globals": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.10.tgz", + "integrity": "sha512-gNld/3lySHwuhaVluJUKLePYirM3QNCKzVxqAdhJII9/WXKVX5PURzMVJspS1jTslSqjeuG4KMVTSouit5YPHA==", + "dev": true + }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "dev": true + }, + "node_modules/contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/convert-source-map": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.1" + } + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "node_modules/cosmiconfig": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz", + "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==", + "dev": true, + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/coveralls": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.1.1.tgz", + "integrity": "sha512-+dxnG2NHncSD1NrqbSM3dn/lE57O6Qf/koe9+I7c+wzkqRmEvcp0kgJdxKInzYzkICKkFMZsX3Vct3++tsF9ww==", + "dev": true, + "dependencies": { + "js-yaml": "^3.13.1", + "lcov-parse": "^1.0.0", + "log-driver": "^1.2.7", + "minimist": "^1.2.5", + "request": "^2.88.2" + }, + "bin": { + "coveralls": "bin/coveralls.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/coveralls/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/crc-32": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.0.tgz", + "integrity": "sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA==", + "dependencies": { + "exit-on-epipe": "~1.0.1", + "printj": "~1.1.0" + }, + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "node_modules/crlf": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/crlf/-/crlf-1.1.1.tgz", + "integrity": "sha1-JBcoQbTINSmmqkSJ337tlYsu0W8=", + "dev": true, + "dependencies": { + "glub": "^1.0.0", + "transform-file": "^1.0.1" + }, + "bin": { + "crlf": "bin/crlf" + } + }, + "node_modules/cross-blob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/cross-blob/-/cross-blob-2.0.1.tgz", + "integrity": "sha512-ARuKPPo3I6DSqizal4UCyMCiGPQdMpMJS3Owx6Lleuh26vSt2UnfWRwbMLCYqbJUrcol+KzGVSLR91ezSHP80A==", + "dependencies": { + "blob-polyfill": "^5.0.20210201", + "fetch-blob": "^2.1.2" + }, + "engines": { + "node": "^10.17.0 || >=12.3.0" + } + }, + "node_modules/cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "bin": { + "cross-env": "src/bin/cross-env.js", + "cross-env-shell": "src/bin/cross-env-shell.js" + }, + "engines": { + "node": ">=10.14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/dashify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dashify/-/dashify-2.0.0.tgz", + "integrity": "sha512-hpA5C/YrPjucXypHPPc0oJ1l9Hf6wWbiOL7Ik42cxnsUOhWiCB/fylKbKqqJalW9FgkNQCw16YO8uW9Hs0Iy1A==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress-response": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-5.0.0.tgz", + "integrity": "sha512-TLZWWybuxWgoW7Lykv+gq9xvzOsUjQ9tF09Tj6NSTYGMTCHNXzrPnD6Hi+TgZq19PyTAGH4Ll/NIM/eTGglnMw==", + "dev": true, + "dependencies": { + "mimic-response": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", + "dev": true + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/default-require-extensions": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz", + "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==", + "dev": true, + "dependencies": { + "strip-bom": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "dependencies": { + "object-keys": "^1.0.12" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "dev": true + }, + "node_modules/deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==" + }, + "node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", + "dev": true, + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diff-match-patch": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.5.tgz", + "integrity": "sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==" + }, + "node_modules/diff-sequences": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz", + "integrity": "sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/diff3": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/diff3/-/diff3-0.0.3.tgz", + "integrity": "sha1-1OXDpM305f4SEatC5pP8tDIVgPw=" + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/editorconfig": { + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", + "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", + "dev": true, + "dependencies": { + "commander": "^2.19.0", + "lru-cache": "^4.1.5", + "semver": "^5.6.0", + "sigmund": "^1.0.1" + }, + "bin": { + "editorconfig": "bin/editorconfig" + } + }, + "node_modules/editorconfig-to-prettier": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/editorconfig-to-prettier/-/editorconfig-to-prettier-0.1.1.tgz", + "integrity": "sha512-MMadSSVRDb4uKdxV6bCXXN4cTsxIsXYtV4XdPu6FOCSAw6zsCIDA+QEktEU+u6h+c/mTrul5NR+pwFpPxwetiQ==", + "dev": true + }, + "node_modules/editorconfig/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.3.864", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.864.tgz", + "integrity": "sha512-v4rbad8GO6/yVI92WOeU9Wgxc4NA0n4f6P1FvZTY+jyY7JHEhw3bduYu60v3Q1h81Cg6eo4ApZrFPuycwd5hGw==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", + "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.1", + "is-string": "^1.0.7", + "is-weakref": "^1.0.1", + "object-inspect": "^1.11.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eslint": { + "version": "7.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", + "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.3", + "@humanwhocodes/config-array": "^0.5.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-ast-utils": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/eslint-ast-utils/-/eslint-ast-utils-1.1.0.tgz", + "integrity": "sha512-otzzTim2/1+lVrlH19EfQQJEhVJSu0zOb9ygb3iapN6UlyaDtyRq4b5U1FuW0v1lRa9Fp/GJyHkSwm6NqABgCA==", + "dev": true, + "dependencies": { + "lodash.get": "^4.4.2", + "lodash.zip": "^4.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-config-standard": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-16.0.3.tgz", + "integrity": "sha512-x4fmJL5hGqNJKGHSjnLdgA6U6h1YW/G2dW9fA+cyVur4SK6lyue8+UgNKWlZtUDTXvgKDD/Oa3GQjmB5kjtVvg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "peerDependencies": { + "eslint": "^7.12.1", + "eslint-plugin-import": "^2.22.1", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "^4.2.1 || ^5.0.0" + } + }, + "node_modules/eslint-config-standardize": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/eslint-config-standardize/-/eslint-config-standardize-0.7.2.tgz", + "integrity": "sha512-n2dt7la221Qig7FjQsrKn5NyK5jSEkkAy7xWSnY96XdG7H9FcUSDt5I1THyA6zHwEYcAtUFv8VOPBOK6oYEvfg==", + "dev": true, + "dependencies": { + "@jsbits/deep-clone": "~1.1.1", + "confusing-browser-globals": "*", + "deepmerge": "~4.2.2", + "eslint-config-standard": "~16.0.2", + "eslint-plugin-import": "~2.22.1", + "eslint-plugin-node": "~11.1.0", + "eslint-plugin-promise": "~4.2.1", + "eslint-plugin-react": "~7.22.0", + "eslint-plugin-react-hooks": "~4.2.0", + "eslint-plugin-unicorn": "~26.0.1" + }, + "bin": { + "list-eslint-config": "bin/list-eslint-config.js" + }, + "engines": { + "node": "^10.13.0 || >=12.0.0" + }, + "optionalDependencies": { + "@typescript-eslint/eslint-plugin": "^4.14.0", + "@typescript-eslint/parser": "^4.14.0" + }, + "peerDependencies": { + "eslint": ">=7.17.0" + } + }, + "node_modules/eslint-config-standardize/node_modules/eslint-plugin-unicorn": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-26.0.1.tgz", + "integrity": "sha512-SWgF9sIVY74zqkkSN2dclSCqRfocWSUGD0haC0NX2oRfmdp9p8dQvJYkYSQePaCyssPUE/pqpsIEEZNTh8crUA==", + "dev": true, + "dependencies": { + "ci-info": "^2.0.0", + "clean-regexp": "^1.0.0", + "eslint-ast-utils": "^1.1.0", + "eslint-template-visitor": "^2.2.2", + "eslint-utils": "^2.1.0", + "import-modules": "^2.1.0", + "lodash": "^4.17.20", + "pluralize": "^8.0.0", + "read-pkg-up": "^7.0.1", + "regexp-tree": "^0.1.21", + "reserved-words": "^0.1.2", + "safe-regex": "^2.1.1", + "semver": "^7.3.4" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1" + }, + "peerDependencies": { + "eslint": ">=7.17.0" + } + }, + "node_modules/eslint-config-standardize/node_modules/eslint-plugin-unicorn/node_modules/eslint-template-visitor": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/eslint-template-visitor/-/eslint-template-visitor-2.3.2.tgz", + "integrity": "sha512-3ydhqFpuV7x1M9EK52BPNj6V0Kwu0KKkcIAfpUhwHbR8ocRln/oUHgfxQupY8O1h4Qv/POHDumb/BwwNfxbtnA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.16", + "@babel/eslint-parser": "^7.12.16", + "eslint-visitor-keys": "^2.0.0", + "esquery": "^1.3.1", + "multimap": "^1.1.0" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-config-standardize/node_modules/eslint-plugin-unicorn/node_modules/eslint-template-visitor/node_modules/@babel/eslint-parser": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.15.8.tgz", + "integrity": "sha512-fYP7QFngCvgxjUuw8O057SVH5jCXsbFFOoE77CFDcvzwBVgTOkMD/L4mIC5Ud1xf8chK/no2fRbSSn1wvNmKuQ==", + "dev": true, + "dependencies": { + "eslint-scope": "^5.1.1", + "eslint-visitor-keys": "^2.1.0", + "semver": "^6.3.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || >=14.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.11.0", + "eslint": ">=7.5.0" + } + }, + "node_modules/eslint-config-standardize/node_modules/eslint-plugin-unicorn/node_modules/eslint-template-visitor/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-config-standardize/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint-config-standardize/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint-config-standardize/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-config-standardize/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint-config-standardize/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint-config-standardize/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-config-standardize/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint-config-standardize/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", + "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "resolve": "^1.20.0" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dev": true, + "dependencies": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.2.tgz", + "integrity": "sha512-QG8pcgThYOuqxupd06oYTZoNOGaUdTY1PqK+oS6ElF6vs4pBdk/aYxFVQQXzcrAqp9m7cl7lb2ubazX+g16k2Q==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "pkg-dir": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.22.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz", + "integrity": "sha512-8K7JjINHOpH64ozkAhpT3sd+FswIZTfMZTjdx052pnWrgRCVfp8op9tbjpAk3DdUeI/Ba4C8OjdC0r90erHEOw==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.1", + "array.prototype.flat": "^1.2.3", + "contains-path": "^0.1.0", + "debug": "^2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.4", + "eslint-module-utils": "^2.6.0", + "has": "^1.0.3", + "minimatch": "^3.0.4", + "object.values": "^1.1.1", + "read-pkg-up": "^2.0.0", + "resolve": "^1.17.0", + "tsconfig-paths": "^3.9.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "dependencies": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "node_modules/eslint-plugin-import/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/eslint-plugin-node": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", + "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", + "dev": true, + "dependencies": { + "eslint-plugin-es": "^3.0.0", + "eslint-utils": "^2.0.0", + "ignore": "^5.1.1", + "minimatch": "^3.0.4", + "resolve": "^1.10.1", + "semver": "^6.1.0" + }, + "engines": { + "node": ">=8.10.0" + }, + "peerDependencies": { + "eslint": ">=5.16.0" + } + }, + "node_modules/eslint-plugin-node/node_modules/eslint-plugin-es": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", + "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "dev": true, + "dependencies": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + }, + "engines": { + "node": ">=8.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=4.19.1" + } + }, + "node_modules/eslint-plugin-node/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-prettierx": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettierx/-/eslint-plugin-prettierx-0.14.0.tgz", + "integrity": "sha512-Ak/sI2LO0B73qEFjepPNUplxLadqpT3BU/I16ExZ0mY1CjpjoJxiyKe7Nbb0VEH4XO4SbjhngGPSsod+S3/HPA==", + "dev": true, + "dependencies": { + "eslint-config-prettier": "~6.11.0", + "prettier-linter-helpers": "~1.0.0", + "prettierx": "~0.14.0" + }, + "bin": { + "list-eslint-config": "bin/list-eslint-config.js" + }, + "engines": { + "node": "^10.13.0 || >=12.0.0" + }, + "peerDependencies": { + "eslint": ">=7.2.0", + "typescript": ">=3.8.0" + } + }, + "node_modules/eslint-plugin-prettierx/node_modules/eslint-config-prettier": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.11.0.tgz", + "integrity": "sha512-oB8cpLWSAjOVFEJhhyMZh6NOEOtBVziaqdDQ86+qhDHFbZXoRTM7pNSvFRfW/W/L/LrQ38C99J5CGuRBBzBsdA==", + "dev": true, + "dependencies": { + "get-stdin": "^6.0.0" + }, + "bin": { + "eslint-config-prettier-check": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=3.14.1" + } + }, + "node_modules/eslint-plugin-promise": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz", + "integrity": "sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.22.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.22.0.tgz", + "integrity": "sha512-p30tuX3VS+NWv9nQot9xIGAHBXR0+xJVaZriEsHoJrASGCJZDJ8JLNM0YqKqI0AKm6Uxaa1VUHoNEibxRCMQHA==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.1", + "array.prototype.flatmap": "^1.2.3", + "doctrine": "^2.1.0", + "has": "^1.0.3", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "object.entries": "^1.1.2", + "object.fromentries": "^2.0.2", + "object.values": "^1.1.1", + "prop-types": "^15.7.2", + "resolve": "^1.18.1", + "string.prototype.matchall": "^4.0.2" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.2.0.tgz", + "integrity": "sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dev": true, + "dependencies": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-plugin-unicorn": { + "version": "36.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-36.0.0.tgz", + "integrity": "sha512-xxN2vSctGWnDW6aLElm/LKIwcrmk6mdiEcW55Uv5krcrVcIFSWMmEgc/hwpemYfZacKZ5npFERGNz4aThsp1AA==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.14.9", + "ci-info": "^3.2.0", + "clean-regexp": "^1.0.0", + "eslint-template-visitor": "^2.3.2", + "eslint-utils": "^3.0.0", + "is-builtin-module": "^3.1.0", + "lodash": "^4.17.21", + "pluralize": "^8.0.0", + "read-pkg-up": "^7.0.1", + "regexp-tree": "^0.1.23", + "safe-regex": "^2.1.1", + "semver": "^7.3.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1" + }, + "peerDependencies": { + "eslint": ">=7.32.0" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/ci-info": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz", + "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==", + "dev": true + }, + "node_modules/eslint-plugin-unicorn/node_modules/eslint-template-visitor": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/eslint-template-visitor/-/eslint-template-visitor-2.3.2.tgz", + "integrity": "sha512-3ydhqFpuV7x1M9EK52BPNj6V0Kwu0KKkcIAfpUhwHbR8ocRln/oUHgfxQupY8O1h4Qv/POHDumb/BwwNfxbtnA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.16", + "@babel/eslint-parser": "^7.12.16", + "eslint-visitor-keys": "^2.0.0", + "esquery": "^1.3.1", + "multimap": "^1.1.0" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/eslint-template-visitor/node_modules/@babel/eslint-parser": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.15.8.tgz", + "integrity": "sha512-fYP7QFngCvgxjUuw8O057SVH5jCXsbFFOoE77CFDcvzwBVgTOkMD/L4mIC5Ud1xf8chK/no2fRbSSn1wvNmKuQ==", + "dev": true, + "dependencies": { + "eslint-scope": "^5.1.1", + "eslint-visitor-keys": "^2.1.0", + "semver": "^6.3.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || >=14.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.11.0", + "eslint": ">=7.5.0" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/eslint-template-visitor/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eslint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/eslint/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/eslint/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/eslint/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "dev": true, + "dependencies": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/exit-on-epipe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz", + "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/expect": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.2.5.tgz", + "integrity": "sha512-ZrO0w7bo8BgGoP/bLz+HDCI+0Hfei9jUSZs5yI/Wyn9VkG9w8oJ7rHRgYj+MA7yqqFa0IwHA3flJzZtYugShJA==", + "dev": true, + "dependencies": { + "@jest/types": "^27.2.5", + "ansi-styles": "^5.0.0", + "jest-get-type": "^27.0.6", + "jest-matcher-utils": "^27.2.5", + "jest-message-util": "^27.2.5", + "jest-regex-util": "^27.0.6" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/expect/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true, + "engines": [ + "node >=0.6.0" + ] + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", + "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "node_modules/fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fetch-blob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-2.1.2.tgz", + "integrity": "sha512-YKqtUDwqLyfyMnmbw8XD6Q8j9i/HggKtPEI+pZ1+8bvheBu78biSmNaXWusx1TauGqtUUGx/cBb1mKdq2rLYow==", + "engines": { + "node": "^10.17.0 || >=12.3.0" + }, + "peerDependenciesMeta": { + "domexception": { + "optional": true + } + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-cache-dir": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dev": true, + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "node_modules/find-cache-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-cache-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-cache-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-cache-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-cache-dir/node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-parent-dir": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/find-parent-dir/-/find-parent-dir-0.3.0.tgz", + "integrity": "sha1-M8RLQpqysvBkYpnF+fcY83b/jVQ=", + "dev": true + }, + "node_modules/find-project-root": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/find-project-root/-/find-project-root-1.1.1.tgz", + "integrity": "sha1-0kJyei2QRyXfVxTyPf3N7doLbvg=", + "dev": true, + "bin": { + "find-project-root": "bin/find-project-root.js" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz", + "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", + "dev": true + }, + "node_modules/flatten": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.3.tgz", + "integrity": "sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg==", + "deprecated": "flatten is deprecated in favor of utility frameworks such as lodash.", + "dev": true + }, + "node_modules/foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/fromentries": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", + "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, + "node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "node_modules/gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "dev": true, + "dependencies": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "node_modules/gauge/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gauge/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-stdin": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", + "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/git-config-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/git-config-path/-/git-config-path-2.0.0.tgz", + "integrity": "sha512-qc8h1KIQbJpp+241id3GuAtkdyJ+IK+LIVtkiFTRKRrmddDzs3SI9CvP1QYmWBFvm1I/PWRwj//of8bgAc0ltA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/git-documentdb-plugin-remote-nodegit": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.4.tgz", + "integrity": "sha512-+esXlN6PMmvwKZPU6dn/kSQnVe5QHU9xGzoNrLiqehz+VM1AXgNhsce/KipimG4wdzUS6tbS9QbgIgA4VjpbAw==", + "dev": true, + "dependencies": { + "@sosuisen/nodegit": "^0.28.0-alpha.11", + "git-documentdb-remote-errors": "^1.0.3", + "tslog": "^3.2.0" + } + }, + "node_modules/git-documentdb-remote-errors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/git-documentdb-remote-errors/-/git-documentdb-remote-errors-1.0.3.tgz", + "integrity": "sha512-14fN8VAQeBC7+Phs6TYB1D5PJDE/dF8dxbigKpsBEqR1FvpAQerSPptxVsQgkU33xwwZBOm7yCwVD2KKmQatOQ==" + }, + "node_modules/glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dev": true, + "dependencies": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globals": { + "version": "13.11.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz", + "integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", + "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glub": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/glub/-/glub-1.0.3.tgz", + "integrity": "sha1-VsFkMpiuJQZcYxUAMze7pp0vuGY=", + "dev": true, + "dependencies": { + "glob": "^5.0.5", + "minimist": "^1.1.1" + }, + "bin": { + "glub": "bin/glub" + } + }, + "node_modules/got": { + "version": "10.7.0", + "resolved": "https://registry.npmjs.org/got/-/got-10.7.0.tgz", + "integrity": "sha512-aWTDeNw9g+XqEZNcTjMMZSy7B7yE9toWOFYip7ofFTLleJhvZwUxxTxkTpKvF+p1SAA4VHmuEy7PiHTHyq8tJg==", + "dev": true, + "dependencies": { + "@sindresorhus/is": "^2.0.0", + "@szmarczak/http-timer": "^4.0.0", + "@types/cacheable-request": "^6.0.1", + "cacheable-lookup": "^2.0.0", + "cacheable-request": "^7.0.1", + "decompress-response": "^5.0.0", + "duplexer3": "^0.1.4", + "get-stream": "^5.0.0", + "lowercase-keys": "^2.0.0", + "mimic-response": "^2.1.0", + "p-cancelable": "^2.0.0", + "p-event": "^4.0.0", + "responselike": "^2.0.0", + "to-readable-stream": "^2.0.0", + "type-fest": "^0.10.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/got/node_modules/type-fest": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.10.0.tgz", + "integrity": "sha512-EUV9jo4sffrwlg8s0zDhP0T2WD3pru5Xi0+HTE3zTUmBaZNhfkite9PdSJwdXLwPVW0jnAHT56pZHIOYckPEiw==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", + "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" + }, + "node_modules/graphql": { + "version": "15.3.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.3.0.tgz", + "integrity": "sha512-GTCJtzJmkFLWRfFJuoo9RWWa/FfamUHgiFosxi/X1Ani4AVWbeyBenZTNX6dM+7WSbbFfTo/25eh0LLkwHMw2w==", + "dev": true, + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true, + "engines": { + "node": ">=4.x" + } + }, + "node_modules/handlebars": { + "version": "4.7.7", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", + "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "dev": true, + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "engines": { + "node": ">=4" + } + }, + "node_modules/has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "dev": true + }, + "node_modules/hasha": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", + "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", + "dev": true, + "dependencies": { + "is-stream": "^2.0.0", + "type-fest": "^0.8.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hasha/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" + } + }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/html-element-attributes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/html-element-attributes/-/html-element-attributes-2.2.1.tgz", + "integrity": "sha512-gGTgCeQu+g1OFExZKWQ1LwbFXxLJ6cGdCGj64ByEaxatr/EPVc23D6Gxngb37ao+SNInP/sGu8FXxRsSxMm7aQ==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/html-styles": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/html-styles/-/html-styles-1.0.0.tgz", + "integrity": "sha1-oYBh/WUfmca3XEXI4FSaO8PgGnU=", + "dev": true + }, + "node_modules/html-tag-names": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/html-tag-names/-/html-tag-names-1.1.5.tgz", + "integrity": "sha512-aI5tKwNTBzOZApHIynaAwecLBv8TlZTEy/P4Sj2SzzAhBrGuI8yGZ0UIXVPQzOHGS+to2mjb04iy6VWt/8+d8A==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "dev": true + }, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/ignore-walk": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.4.tgz", + "integrity": "sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ==", + "dev": true, + "dependencies": { + "minimatch": "^3.0.4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-lazy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", + "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/import-modules": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-modules/-/import-modules-2.1.0.tgz", + "integrity": "sha512-8HEWcnkbGpovH9yInoisxaSoIg9Brbul+Ju3Kqe2UsYDUBJD/iQjSgEj0zPcTDPKfPp2fs5xlv1i+JSye/m1/A==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/indexes-of": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", + "dev": true + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "node_modules/internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-alphabetical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", + "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", + "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", + "dev": true, + "dependencies": { + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "engines": { + "node": ">=4" + } + }, + "node_modules/is-builtin-module": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.1.0.tgz", + "integrity": "sha512-OV7JjAgOTfAFJmHZLvpSTb4qi0nIILDV1gWPYDnDJUTNFM5aGlRAhk4QcT8i7TuAleeEV5Fdkqn3t4mS+Q11fg==", + "dev": true, + "dependencies": { + "builtin-modules": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-callable": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.7.0.tgz", + "integrity": "sha512-ByY+tjCciCr+9nLryBYcSD50EOGWt95c7tIsKTG1J2ixKKXPvF7Ej3AVd+UfDydAJom3biBGDBALaO79ktwgEQ==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-decimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", + "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hexadecimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", + "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", + "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", + "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "node_modules/is-weakref": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.1.tgz", + "integrity": "sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-whitespace-character": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz", + "integrity": "sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-word-character": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.4.tgz", + "integrity": "sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/isomorphic-git": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/isomorphic-git/-/isomorphic-git-1.10.1.tgz", + "integrity": "sha512-abbPpKkykIVDJ92rtYoD4AOuT5/7PABHR2fDBrsm7H0r2ZT+MGpPL/FynrEJM6nTcFSieaIDxnHNGhfHO/v+bA==", + "dependencies": { + "async-lock": "^1.1.0", + "clean-git-ref": "^2.0.1", + "crc-32": "^1.2.0", + "diff3": "0.0.3", + "ignore": "^5.1.4", + "minimisted": "^2.0.0", + "pako": "^1.0.10", + "pify": "^4.0.1", + "readable-stream": "^3.4.0", + "sha.js": "^2.4.9", + "simple-get": "^3.0.2" + }, + "bin": { + "isogit": "cli.cjs" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-hook": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", + "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", + "dev": true, + "dependencies": { + "append-transform": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/istanbul-lib-processinfo": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz", + "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==", + "dev": true, + "dependencies": { + "archy": "^1.0.0", + "cross-spawn": "^7.0.0", + "istanbul-lib-coverage": "^3.0.0-alpha.1", + "make-dir": "^3.0.0", + "p-map": "^3.0.0", + "rimraf": "^3.0.0", + "uuid": "^3.3.3" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", + "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-reports": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.3.tgz", + "integrity": "sha512-0i77ZFLsb9U3DHi22WzmIngVzfoyxxbQcZRqlF3KoKmCJGq9nhFHoGi8FqBztN2rE8w6hURnZghetn0xpkVb6A==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-diff": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.2.5.tgz", + "integrity": "sha512-7gfwwyYkeslOOVQY4tVq5TaQa92mWfC9COsVYMNVYyJTOYAqbIkoD3twi5A+h+tAPtAelRxkqY6/xu+jwTr0dA==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^27.0.6", + "jest-get-type": "^27.0.6", + "pretty-format": "^27.2.5" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-diff/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-diff/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-diff/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-diff/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-docblock": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", + "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==", + "dev": true, + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-get-type": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", + "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.2.5.tgz", + "integrity": "sha512-qNR/kh6bz0Dyv3m68Ck2g1fLW5KlSOUNcFQh87VXHZwWc/gY6XwnKofx76Qytz3x5LDWT09/2+yXndTkaG4aWg==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^27.2.5", + "jest-get-type": "^27.0.6", + "pretty-format": "^27.2.5" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-matcher-utils/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-matcher-utils/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.2.5.tgz", + "integrity": "sha512-ggXSLoPfIYcbmZ8glgEJZ8b+e0Msw/iddRmgkoO7lDAr9SmI65IIfv7VnvTnV4FGnIIUIjzM+fHRHO5RBvyAbQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.2.5", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.4", + "pretty-format": "^27.2.5", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-message-util/node_modules/@babel/code-frame": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", + "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/jest-message-util/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-message-util/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-message-util/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-regex-util": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.0.6.tgz", + "integrity": "sha512-SUhPzBsGa1IKm8hx2F4NfTGGp+r7BXJ4CulsZ1k2kI+mGLG+lxGrs76veN2LF/aUdGosJBzKgXmNCw+BzFqBDQ==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jju": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", + "integrity": "sha1-o6vicYryQaKykE+EpiWXDzia4yo=", + "dev": true + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/js-yaml/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "dev": true, + "dependencies": { + "jsonify": "~0.0.0" + } + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "node_modules/jsx-ast-utils": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.1.tgz", + "integrity": "sha512-uP5vu8xfy2F9A6LGC22KO7e2/vGTS1MhP+18f++ZNlf0Ohaxbc9nIEwHAsejlJKyzfZzU5UIhe5ItYkitcZnZA==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.3", + "object.assign": "^4.1.2" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/just-extend": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", + "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", + "dev": true + }, + "node_modules/keyv": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.3.tgz", + "integrity": "sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/lcov-parse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-1.0.0.tgz", + "integrity": "sha1-6w1GtUER68VhrLTECO+TY73I9+A=", + "dev": true, + "bin": { + "lcov-parse": "bin/cli.js" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, + "node_modules/linguist-languages": { + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/linguist-languages/-/linguist-languages-7.10.0.tgz", + "integrity": "sha512-Uqt94P4iAznscZtccnNE1IBi105U+fmQKEUlDJv54JDdFZDInomkepEIRpZLOQcPyGdcNu3JO9Tvo5wpQVbfKw==", + "dev": true + }, + "node_modules/load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/load-json-file/node_modules/parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "dependencies": { + "error-ex": "^1.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/load-json-file/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/load-json-file/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "node_modules/lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", + "dev": true + }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "dev": true + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, + "node_modules/lodash.zip": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.zip/-/lodash.zip-4.2.0.tgz", + "integrity": "sha1-7GZi5IlkCO1KtsVCo5kLcswIACA=", + "dev": true + }, + "node_modules/log-driver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", + "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", + "dev": true, + "engines": { + "node": ">=0.8.6" + } + }, + "node_modules/log-symbols": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", + "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/log-symbols/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/log-symbols/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/log-symbols/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/log-symbols/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/log-symbols/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "dev": true, + "dependencies": { + "p-defer": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/markdown-escapes": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.4.tgz", + "integrity": "sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mem": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/mem/-/mem-6.1.1.tgz", + "integrity": "sha512-Ci6bIfq/UgcxPTYa8dQQ5FY3BzKkT894bwXWXxC/zqs0XgMO2cT20CGkOqda7gZNkmK5VP4x89IGZ6K7hfbn3Q==", + "dev": true, + "dependencies": { + "map-age-cleaner": "^0.1.3", + "mimic-fn": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sindresorhus/mem?sponsor=1" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "dependencies": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.50.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz", + "integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.33", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.33.tgz", + "integrity": "sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==", + "dev": true, + "dependencies": { + "mime-db": "1.50.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz", + "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/mimic-response": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", + "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "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" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "node_modules/minimisted": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/minimisted/-/minimisted-2.0.1.tgz", + "integrity": "sha512-1oPjfuLQa2caorJUM8HV8lGgWCc0qqAO1MNv/k05G4qslmsndV/5WdNZrqCiyqiz3wohia2Ij2B7w2Dr7/IyrA==", + "dependencies": { + "minimist": "^1.2.5" + } + }, + "node_modules/minipass": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.5.tgz", + "integrity": "sha512-+8NzxD82XQoNKNrl1d/FSi+X8wAEWR+sbYAfIvub4Nz0d22plFG72CEVVaufV8PNf4qSslFTD8VMOxNVhHCjTw==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mocha": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.4.0.tgz", + "integrity": "sha512-hJaO0mwDXmZS4ghXsvPVriOhsxQ7ofcpQdm8dE+jISUOKopitvnXFQmpRR7jd2K6VBG6E26gU3IAbXXGIbu4sQ==", + "dev": true, + "dependencies": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.1", + "debug": "4.3.1", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.1.6", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "4.0.0", + "log-symbols": "4.0.0", + "minimatch": "3.0.4", + "ms": "2.1.3", + "nanoid": "3.1.20", + "serialize-javascript": "5.0.1", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "which": "2.0.2", + "wide-align": "1.1.3", + "workerpool": "6.1.0", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha" + }, + "engines": { + "node": ">= 10.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" + } + }, + "node_modules/mocha/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/mocha/node_modules/debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/mocha/node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/mocha/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "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" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mocha/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/mocha/node_modules/js-yaml": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", + "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/mocha/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/multimap": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/multimap/-/multimap-1.1.0.tgz", + "integrity": "sha512-0ZIR9PasPxGXmRsEF8jsDzndzHDj7tIav+JUmvIFB/WHswliFnquxECT/De7GR4yg99ky/NlRKJT82G1y271bw==", + "dev": true + }, + "node_modules/n-readlines": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/n-readlines/-/n-readlines-1.0.1.tgz", + "integrity": "sha512-z4SyAIVgMy7CkgsoNw7YVz40v0g4+WWvvqy8+ZdHrCtgevcEO758WQyrYcw3XPxcLxF+//RszTz/rO48nzD0wQ==", + "dev": true, + "engines": { + "node": ">=6.x.x" + } + }, + "node_modules/nan": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", + "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.1.20", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", + "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==", + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node_modules/needle": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/needle/-/needle-2.9.1.tgz", + "integrity": "sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ==", + "dev": true, + "dependencies": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + }, + "bin": { + "needle": "bin/needle" + }, + "engines": { + "node": ">= 4.4.x" + } + }, + "node_modules/needle/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node_modules/nise": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/nise/-/nise-4.1.0.tgz", + "integrity": "sha512-eQMEmGN/8arp0xsvGoQ+B1qvSkR73B1nWSCh7nOt5neMCtwcQVYQGdzQMhcNscktTsWB54xnlSQFzOAPJD8nXA==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.7.0", + "@sinonjs/fake-timers": "^6.0.0", + "@sinonjs/text-encoding": "^0.7.1", + "just-extend": "^4.0.2", + "path-to-regexp": "^1.7.0" + } + }, + "node_modules/node-fetch": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.5.tgz", + "integrity": "sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + } + }, + "node_modules/node-gyp": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-7.1.2.tgz", + "integrity": "sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ==", + "dev": true, + "dependencies": { + "env-paths": "^2.2.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.3", + "nopt": "^5.0.0", + "npmlog": "^4.1.2", + "request": "^2.88.2", + "rimraf": "^3.0.2", + "semver": "^7.3.2", + "tar": "^6.0.2", + "which": "^2.0.2" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": ">= 10.12.0" + } + }, + "node_modules/node-gyp/node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "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" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/node-pre-gyp": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.13.0.tgz", + "integrity": "sha512-Md1D3xnEne8b/HGVQkZZwV27WUi1ZRuZBij24TNaZwUPU3ZAFtvT6xxJGaUVillfmMKnn5oD1HoGsp2Ftik7SQ==", + "deprecated": "Please upgrade to @mapbox/node-pre-gyp: the non-scoped node-pre-gyp package is deprecated and only the @mapbox scoped package will recieve updates in the future", + "dev": true, + "dependencies": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/node-pre-gyp/node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "node_modules/node-pre-gyp/node_modules/fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "dev": true, + "dependencies": { + "minipass": "^2.6.0" + } + }, + "node_modules/node-pre-gyp/node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "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" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/node-pre-gyp/node_modules/minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "node_modules/node-pre-gyp/node_modules/minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "dev": true, + "dependencies": { + "minipass": "^2.9.0" + } + }, + "node_modules/node-pre-gyp/node_modules/nopt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", + "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", + "dev": true, + "dependencies": { + "abbrev": "1", + "osenv": "^0.1.4" + }, + "bin": { + "nopt": "bin/nopt.js" + } + }, + "node_modules/node-pre-gyp/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/node-pre-gyp/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/node-pre-gyp/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/node-pre-gyp/node_modules/tar": { + "version": "4.4.19", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", + "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", + "dev": true, + "dependencies": { + "chownr": "^1.1.4", + "fs-minipass": "^1.2.7", + "minipass": "^2.9.0", + "minizlib": "^1.3.3", + "mkdirp": "^0.5.5", + "safe-buffer": "^5.2.1", + "yallist": "^3.1.1" + }, + "engines": { + "node": ">=4.5" + } + }, + "node_modules/node-pre-gyp/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/node-preload": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", + "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", + "dev": true, + "dependencies": { + "process-on-spawn": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/node-releases": { + "version": "1.1.77", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.77.tgz", + "integrity": "sha512-rB1DUFUNAN4Gn9keO2K1efO35IDK7yKHCdCaIMvFO7yUYmmZYeDjnGKle26G4rwj+LKRQpjyUUvMkPglwGCYNQ==", + "dev": true + }, + "node_modules/nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "dev": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-bundled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.2.tgz", + "integrity": "sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ==", + "dev": true, + "dependencies": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "node_modules/npm-normalize-package-bin": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", + "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==", + "dev": true + }, + "node_modules/npm-packlist": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", + "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", + "dev": true, + "dependencies": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1", + "npm-normalize-package-bin": "^1.0.1" + } + }, + "node_modules/npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "dev": true, + "dependencies": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "node_modules/number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/nyc": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", + "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", + "dev": true, + "dependencies": { + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "caching-transform": "^4.0.0", + "convert-source-map": "^1.7.0", + "decamelize": "^1.2.0", + "find-cache-dir": "^3.2.0", + "find-up": "^4.1.0", + "foreground-child": "^2.0.0", + "get-package-type": "^0.1.0", + "glob": "^7.1.6", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-hook": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-processinfo": "^2.0.2", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "make-dir": "^3.0.0", + "node-preload": "^0.2.1", + "p-map": "^3.0.0", + "process-on-spawn": "^1.0.0", + "resolve-from": "^5.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "spawn-wrap": "^2.0.0", + "test-exclude": "^6.0.0", + "yargs": "^15.0.2" + }, + "bin": { + "nyc": "bin/nyc.js" + }, + "engines": { + "node": ">=8.9" + } + }, + "node_modules/nyc/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/nyc/node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/nyc/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/nyc/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/nyc/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "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" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/nyc/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nyc/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "node_modules/nyc/node_modules/yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.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": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nyc/node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", + "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.5.tgz", + "integrity": "sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.5.tgz", + "integrity": "sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.values": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", + "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "dev": true, + "dependencies": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "node_modules/ot-json1": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/ot-json1/-/ot-json1-1.0.2.tgz", + "integrity": "sha512-IhxkqVWQqlkWULoi/Q2AdzKk0N5vQRbUMUwubFXFCPcY4TsOZjmp2YKrk0/z1TeiECPadWEK060sdFdQ3Grokg==", + "dependencies": { + "ot-text-unicode": "4" + } + }, + "node_modules/ot-text-unicode": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ot-text-unicode/-/ot-text-unicode-4.0.0.tgz", + "integrity": "sha512-W7ZLU8QXesY2wagYFv47zErXud3E93FGImmSGJsQnBzE+idcPPyo2u2KMilIrTwBh4pbCizy71qRjmmV6aDhcQ==", + "dependencies": { + "unicount": "1.1" + } + }, + "node_modules/ot-text-unicode/node_modules/unicount": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unicount/-/unicount-1.1.0.tgz", + "integrity": "sha512-RlwWt1ywVW4WErPGAVHw/rIuJ2+MxvTME0siJ6lk9zBhpDfExDbspe6SRlWT3qU6AucNjotPl9qAJRVjP7guCQ==" + }, + "node_modules/p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-event": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz", + "integrity": "sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==", + "dev": true, + "dependencies": { + "p-timeout": "^3.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "dev": true, + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/package-hash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", + "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.15", + "hasha": "^5.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-entities": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.2.2.tgz", + "integrity": "sha512-NzfpbxW/NPrzZ/yYSoQxyqUZMZXIdCfE0OIN4ESsnptHJECoUk3FZktxNuzQf4tjt5UEopnxpYJbvYuxIFDdsg==", + "dev": true, + "dependencies": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + } + }, + "node_modules/parse-git-config": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/parse-git-config/-/parse-git-config-3.0.0.tgz", + "integrity": "sha512-wXoQGL1D+2COYWCD35/xbiKma1Z15xvZL8cI25wvxzled58V51SJM04Urt/uznS900iQor7QO04SgdfT/XlbuA==", + "dev": true, + "dependencies": { + "git-config-path": "^2.0.0", + "ini": "^1.3.5" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "dev": true, + "dependencies": { + "isarray": "0.0.1" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "node_modules/picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "dependencies": { + "find-up": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-dir/node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-dir/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/please-upgrade-node": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", + "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", + "dev": true, + "dependencies": { + "semver-compare": "^1.0.0" + } + }, + "node_modules/pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss": { + "version": "7.0.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "dev": true, + "dependencies": { + "picocolors": "^0.2.1", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/postcss-less": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-3.1.4.tgz", + "integrity": "sha512-7TvleQWNM2QLcHqvudt3VYjULVB49uiW6XzEUFmvwHzvsOEF5MwBrIXZDJQvJNFGjJQTzSzZnDoCJ8h/ljyGXA==", + "dev": true, + "dependencies": { + "postcss": "^7.0.14" + }, + "engines": { + "node": ">=6.14.4" + } + }, + "node_modules/postcss-media-query-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", + "integrity": "sha1-J7Ocb02U+Bsac7j3Y1HGCeXO8kQ=", + "dev": true + }, + "node_modules/postcss-scss": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-2.1.1.tgz", + "integrity": "sha512-jQmGnj0hSGLd9RscFw9LyuSVAa5Bl1/KBPqG1NQw9w8ND55nY4ZEsdlVuYJvLPpV+y0nwTV5v/4rHPzZRihQbA==", + "dev": true, + "dependencies": { + "postcss": "^7.0.6" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/postcss-selector-parser": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz", + "integrity": "sha1-+UN3iGBsPJrO4W/+jYsWKX8nu5A=", + "dev": true, + "dependencies": { + "flatten": "^1.0.2", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + }, + "node_modules/postcss-values-parser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-2.0.1.tgz", + "integrity": "sha512-2tLuBsA6P4rYTNKCXYG/71C7j1pU6pK503suYOmn4xYrQIzW+opD+7FAFNuGSdZC/3Qfy334QbeMu7MEb8gOxg==", + "dev": true, + "dependencies": { + "flatten": "^1.0.2", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + }, + "engines": { + "node": ">=6.14.4" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/prettierx": { + "version": "0.14.3", + "resolved": "https://registry.npmjs.org/prettierx/-/prettierx-0.14.3.tgz", + "integrity": "sha512-0VT3GgDAU6rvemeklrRzqVkILrGC1TSo/4STnsBqkreLx5Ck43W05lO60pMKWbG7SWM3DcUZZIR4FZ5pvvDwyQ==", + "dev": true, + "dependencies": { + "@angular/compiler": "9.0.5", + "@babel/code-frame": "7.12.11", + "@babel/parser": "7.12.0", + "@glimmer/syntax": "0.56.1", + "@iarna/toml": "2.2.5", + "@typescript-eslint/typescript-estree": "2.34.0", + "angular-estree-parser": "1.3.1", + "angular-html-parser": "1.7.0", + "camelcase": "6.2.0", + "chalk": "4.1.0", + "ci-info": "2.0.0", + "cjk-regex": "2.0.0", + "cosmiconfig": "7.0.0", + "dashify": "2.0.0", + "dedent": "0.7.0", + "diff": "4.0.2", + "editorconfig": "0.15.3", + "editorconfig-to-prettier": "0.1.1", + "escape-string-regexp": "4.0.0", + "esutils": "2.0.3", + "fast-glob": "3.2.4", + "find-parent-dir": "0.3.0", + "find-project-root": "1.1.1", + "get-stream": "6.0.0", + "globby": "11.0.1", + "graphql": "15.3.0", + "html-element-attributes": "2.2.1", + "html-styles": "1.0.0", + "html-tag-names": "1.1.5", + "ignore": "4.0.6", + "jest-docblock": "26.0.0", + "json-stable-stringify": "1.0.1", + "leven": "3.1.0", + "lines-and-columns": "1.1.6", + "linguist-languages": "7.10.0", + "lodash": "4.17.20", + "mem": "6.1.1", + "minimatch": "3.0.4", + "minimist": "1.2.5", + "n-readlines": "1.0.1", + "please-upgrade-node": "3.2.0", + "postcss-less": "3.1.4", + "postcss-media-query-parser": "0.2.3", + "postcss-scss": "2.1.1", + "postcss-selector-parser": "2.2.3", + "postcss-values-parser": "2.0.1", + "regexp-util": "1.2.2", + "remark-math": "1.0.6", + "remark-parse": "5.0.0", + "resolve": "1.19.0", + "semver": "7.3.4", + "srcset": "3.0.0", + "string-width": "4.2.0", + "tslib": "1.14.1", + "unicode-regex": "3.0.0", + "unified": "9.2.0", + "vnopts": "1.0.2", + "yaml-unist-parser": "1.3.1" + }, + "bin": { + "prettierx": "bin/prettierx.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "peerDependenciesMeta": { + "flow-parser": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/prettierx/node_modules/@babel/parser": { + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.0.tgz", + "integrity": "sha512-dYmySMYnlus2jwl7JnnajAj11obRStZoW9cG04wh4ZuhozDn11tDUrhHcUZ9iuNHqALAhh60XqNaYXpvuuE/Gg==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/prettierx/node_modules/@typescript-eslint/typescript-estree": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz", + "integrity": "sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "eslint-visitor-keys": "^1.1.0", + "glob": "^7.1.6", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/prettierx/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/prettierx/node_modules/camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/prettierx/node_modules/chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/prettierx/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/prettierx/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/prettierx/node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/prettierx/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/prettierx/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/prettierx/node_modules/fast-glob": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", + "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/prettierx/node_modules/get-stream": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.0.tgz", + "integrity": "sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/prettierx/node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "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" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/prettierx/node_modules/globby": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", + "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/prettierx/node_modules/globby/node_modules/ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/prettierx/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/prettierx/node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/prettierx/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/prettierx/node_modules/lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", + "dev": true + }, + "node_modules/prettierx/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/prettierx/node_modules/resolve": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "dev": true, + "dependencies": { + "is-core-module": "^2.1.0", + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/prettierx/node_modules/semver": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/prettierx/node_modules/string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/prettierx/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/prettierx/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/pretty-format": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.2.5.tgz", + "integrity": "sha512-+nYn2z9GgicO9JiqmY25Xtq8SYfZ/5VCpEU3pppHHNAhd1y+ZXxmNPd1evmNcAd6Hz4iBV2kf0UpGth5A/VJ7g==", + "dev": true, + "dependencies": { + "@jest/types": "^27.2.5", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/printj": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz", + "integrity": "sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==", + "bin": { + "printj": "bin/printj.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/process-on-spawn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", + "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", + "dev": true, + "dependencies": { + "fromentries": "^1.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "dev": true, + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true + }, + "node_modules/pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "node_modules/psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ramda": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.25.0.tgz", + "integrity": "sha512-GXpfrYVPwx3K7RQ6aYT8KPS8XViSXUVJT1ONhoKPE9VAleW42YE+U+8VEyGWt41EnEQW7gwecYJriTI0pKoecQ==", + "dev": true + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "node_modules/read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "dependencies": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "dependencies": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg/node_modules/path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "dependencies": { + "pify": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/regexp-tree": { + "version": "0.1.24", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.24.tgz", + "integrity": "sha512-s2aEVuLhvnVJW6s/iPgEGK6R+/xngd2jNQ+xy4bXNDKxZKJH6jpPHY6kVeVv1IeLCHgswRj+Kl3ELaDjG6V1iw==", + "dev": true, + "bin": { + "regexp-tree": "bin/regexp-tree" + } + }, + "node_modules/regexp-util": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/regexp-util/-/regexp-util-1.2.2.tgz", + "integrity": "sha512-5/rl2UD18oAlLQEIuKBeiSIOp1hb5wCXcakl5yvHxlY1wyWI4D5cUKKzCibBeu741PA9JKvZhMqbkDQqPusX3w==", + "dev": true, + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz", + "integrity": "sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/release-zalgo": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", + "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", + "dev": true, + "dependencies": { + "es6-error": "^4.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/remark-math": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/remark-math/-/remark-math-1.0.6.tgz", + "integrity": "sha512-I43wU/QOQpXvVFXKjA4FHp5xptK65+5F6yolm8+69/JV0EqSOB64wURUZ3JK50JtnTL8FvwLiH2PZ+fvsBxviA==", + "dev": true, + "dependencies": { + "trim-trailing-lines": "^1.1.0" + }, + "peerDependencies": { + "remark-parse": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0" + } + }, + "node_modules/remark-parse": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-5.0.0.tgz", + "integrity": "sha512-b3iXszZLH1TLoyUzrATcTQUZrwNl1rE70rVdSruJFlDaJ9z5aMkhrG43Pp68OgfHndL/ADz6V69Zow8cTQu+JA==", + "dev": true, + "dependencies": { + "collapse-white-space": "^1.0.2", + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-whitespace-character": "^1.0.0", + "is-word-character": "^1.0.0", + "markdown-escapes": "^1.0.0", + "parse-entities": "^1.1.0", + "repeat-string": "^1.5.4", + "state-toggle": "^1.0.0", + "trim": "0.0.1", + "trim-trailing-lines": "^1.0.0", + "unherit": "^1.0.4", + "unist-util-remove-position": "^1.0.0", + "vfile-location": "^2.0.0", + "xtend": "^4.0.1" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dev": true, + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "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==", + "dev": true + }, + "node_modules/reserved-words": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/reserved-words/-/reserved-words-0.1.2.tgz", + "integrity": "sha1-AKCUD5jNUBrqqsMWQR2a3FKzGrE=", + "dev": true + }, + "node_modules/resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "dependencies": { + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/responselike": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz", + "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==", + "dev": true, + "dependencies": { + "lowercase-keys": "^2.0.0" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "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" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/safe-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz", + "integrity": "sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==", + "dev": true, + "dependencies": { + "regexp-tree": "~0.1.1" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, + "node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", + "dev": true + }, + "node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/serialize-javascript": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", + "dev": true + }, + "node_modules/signal-exit": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", + "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==", + "dev": true + }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/simple-get": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz", + "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==", + "dependencies": { + "decompress-response": "^4.2.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/simple-get/node_modules/decompress-response": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", + "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", + "dependencies": { + "mimic-response": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/simple-html-tokenizer": { + "version": "0.5.11", + "resolved": "https://registry.npmjs.org/simple-html-tokenizer/-/simple-html-tokenizer-0.5.11.tgz", + "integrity": "sha512-C2WEK/Z3HoSFbYq8tI7ni3eOo/NneSPRoPpcM7WdLjFOArFuyXEjAoCdOC3DgMfRyziZQ1hCNR4mrNdWEvD0og==", + "dev": true + }, + "node_modules/sinon": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-10.0.0.tgz", + "integrity": "sha512-XAn5DxtGVJBlBWYrcYKEhWCz7FLwZGdyvANRyK06419hyEpdT0dMc5A8Vcxg5SCGHc40CsqoKsc1bt1CbJPfNw==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.8.1", + "@sinonjs/fake-timers": "^6.0.1", + "@sinonjs/samsam": "^5.3.1", + "diff": "^4.0.2", + "nise": "^4.1.0", + "supports-color": "^7.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/sinon" + } + }, + "node_modules/sinon/node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/sinon/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/sinon/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/slice-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.20", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", + "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/spawn-wrap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", + "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", + "dev": true, + "dependencies": { + "foreground-child": "^2.0.0", + "is-windows": "^1.0.2", + "make-dir": "^3.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "which": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz", + "integrity": "sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==", + "dev": true + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "node_modules/srcset": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/srcset/-/srcset-3.0.0.tgz", + "integrity": "sha512-D59vF08Qzu/C4GAOXVgMTLfgryt5fyWo93FZyhEWANo0PokFz/iWdDe13mX3O5TRf6l8vMTqckAfR4zPiaH0yQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stack-utils": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", + "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/state-toggle": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.3.tgz", + "integrity": "sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/string-argv": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", + "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", + "dev": true, + "engines": { + "node": ">=0.6.19" + } + }, + "node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.6.tgz", + "integrity": "sha512-6WgDX8HmQqvEd7J+G6VtAahhsQIssiZ8zl7zKh1VDMFyL3hRTJP4FTNA3RbIp2TOQ9AYNDcc7e3fH0Qbup+DBg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1", + "get-intrinsic": "^1.1.1", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "regexp.prototype.flags": "^1.3.1", + "side-channel": "^1.0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "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==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "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" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/table": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/table/-/table-6.7.2.tgz", + "integrity": "sha512-UFZK67uvyNivLeQbVtkiUs8Uuuxv24aSL4/Vil2PJVtMgU8Lx0CYkP12uCGa3kjyQzOSgV1+z9Wkb82fCGsO0g==", + "dev": true, + "dependencies": { + "ajv": "^8.0.1", + "lodash.clonedeep": "^4.5.0", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/table/node_modules/ajv": { + "version": "8.6.3", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.3.tgz", + "integrity": "sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/table/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/table/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/table/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar": { + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", + "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", + "dev": true, + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/tar-fs": { + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.3.tgz", + "integrity": "sha512-NvCeXpYx7OsmOh8zIOP/ebG55zZmxLE0etfWRbWok+q2Qo8x/vOR/IJT1taADXPe+jsiu9axDb3X4B+iIgNlKw==", + "dev": true, + "dependencies": { + "chownr": "^1.0.1", + "mkdirp": "^0.5.1", + "pump": "^1.0.0", + "tar-stream": "^1.1.2" + } + }, + "node_modules/tar-fs/node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "node_modules/tar-fs/node_modules/pump": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz", + "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/tar-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", + "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", + "dev": true, + "dependencies": { + "bl": "^1.0.0", + "buffer-alloc": "^1.2.0", + "end-of-stream": "^1.0.0", + "fs-constants": "^1.0.0", + "readable-stream": "^2.3.0", + "to-buffer": "^1.1.1", + "xtend": "^4.0.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/tar-stream/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "node_modules/tar-stream/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/tar-stream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/tar/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/test-exclude/node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "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" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "node_modules/timsort": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", + "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=", + "dev": true + }, + "node_modules/to-buffer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", + "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-readable-stream": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-2.1.0.tgz", + "integrity": "sha512-o3Qa6DGg1CEXshSdvWNX2sN4QHqg03SPq7U6jPXRahlQdl5dK8oXjkU/2/sGrnOZKeGV1zLSO8qPwyKklPPE7w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + }, + "node_modules/transform-file": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/transform-file/-/transform-file-1.0.1.tgz", + "integrity": "sha1-f5WYSs0j1Ov4q7R+6dg74WbRJoc=", + "dev": true, + "dependencies": { + "os-tmpdir": "^1.0.0" + } + }, + "node_modules/trim": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", + "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=", + "dev": true + }, + "node_modules/trim-trailing-lines": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.4.tgz", + "integrity": "sha512-rjUWSqnfTNrjbB9NQWfPMH/xRK1deHeGsHoVfpxJ++XeYXE0d6B1En37AHfw3jtfTU7dzMzZL2jjpe8Qb5gLIQ==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/trough": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", + "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/ts-node": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.1.tgz", + "integrity": "sha512-hCnyOyuGmD5wHleOQX6NIjJtYVIO8bPP8F2acWkB4W06wdlkgyvJtubO/I9NkI88hCFECbsEgoLc0VNkYmcSfw==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "0.6.1", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-node/node_modules/acorn": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", + "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ts-node/node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/tsconfig-paths": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz", + "integrity": "sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA==", + "dev": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/tsconfig-paths/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/tslog": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/tslog/-/tslog-3.2.2.tgz", + "integrity": "sha512-8dwb1cYpj3/w/MZTrSkPrdlA44loUodGT8N6ULMojqV4YByVM7ynhvVs9JwcIYxhhHf4bz1C5O3NKIPehnGp/w==", + "dependencies": { + "source-map-support": "^0.5.19" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typescript": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.3.tgz", + "integrity": "sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/uglify-js": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.14.2.tgz", + "integrity": "sha512-rtPMlmcO4agTUfz10CbgJ1k6UAoXM2gWb3GoMPPZB/+/Ackf8lNWk11K4rYi2D0apgoFRLtQOZhb+/iGNJq26A==", + "dev": true, + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/ulid": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/ulid/-/ulid-2.3.0.tgz", + "integrity": "sha512-keqHubrlpvT6G2wH0OEfSW4mquYRcbe/J8NMmveoQOjUqmo+hXtO+ORCpWhdbZ7k72UtY61BL7haGxW6enBnjw==", + "bin": { + "ulid": "bin/cli.js" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/unherit": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.3.tgz", + "integrity": "sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ==", + "dev": true, + "dependencies": { + "inherits": "^2.0.0", + "xtend": "^4.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/unicode-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unicode-regex/-/unicode-regex-3.0.0.tgz", + "integrity": "sha512-WiDJdORsqgxkZrjC8WsIP573130HNn7KsB0IDnUccW2BG2b19QQNloNhVe6DKk3Aef0UcoIHhNVj7IkkcYWrNw==", + "dev": true, + "dependencies": { + "regexp-util": "^1.2.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/unicount": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/unicount/-/unicount-1.2.0.tgz", + "integrity": "sha512-bbM0gwaKyIPll7smeeufgbN9sbJbrtr29o93HqF+4bzTeQcTN4zKtBKGwnLoGSG+E6gPQ/WL0t7xAhPKnWW4mQ==" + }, + "node_modules/unified": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-9.2.0.tgz", + "integrity": "sha512-vx2Z0vY+a3YoTj8+pttM3tiJHCwY5UFbYdiWrwBEbHmK8pvsPj2rtAX2BFfgXen8T39CJWblWRDT4L5WGXtDdg==", + "dev": true, + "dependencies": { + "bail": "^1.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^2.0.0", + "trough": "^1.0.0", + "vfile": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", + "dev": true + }, + "node_modules/unist-util-is": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz", + "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==", + "dev": true + }, + "node_modules/unist-util-remove-position": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-1.1.4.tgz", + "integrity": "sha512-tLqd653ArxJIPnKII6LMZwH+mb5q+n/GtXQZo6S6csPRs5zB0u79Yw8ouR3wTw8wxvdJFhpP6Y7jorWdCgLO0A==", + "dev": true, + "dependencies": { + "unist-util-visit": "^1.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", + "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", + "dev": true, + "dependencies": { + "@types/unist": "^2.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz", + "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==", + "dev": true, + "dependencies": { + "unist-util-visit-parents": "^2.0.0" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz", + "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==", + "dev": true, + "dependencies": { + "unist-util-is": "^3.0.0" + } + }, + "node_modules/universal-user-agent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", + "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==" + }, + "node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/validator": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-8.2.0.tgz", + "integrity": "sha512-Yw5wW34fSv5spzTXNkokD6S6/Oq92d8q/t14TqsS3fAiA1RYnxSFSIZ+CY3n6PGGRCq5HhJTSepQvFUS2QUDxA==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/vfile": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", + "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", + "dev": true, + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^2.0.0", + "vfile-message": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-location": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.6.tgz", + "integrity": "sha512-sSFdyCP3G6Ka0CEmN83A2YCMKIieHx0EDaj5IDP4g1pa5ZJ4FJDvpO0WODLxo4LUX4oe52gmSCK7Jw4SBghqxA==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", + "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", + "dev": true, + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vnopts": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/vnopts/-/vnopts-1.0.2.tgz", + "integrity": "sha512-d2rr2EFhAGHnTlURu49G7GWmiJV80HbAnkYdD9IFAtfhmxC+kSWEaZ6ZF064DJFTv9lQZQV1vuLTntyQpoanGQ==", + "dev": true, + "dependencies": { + "chalk": "^2.4.1", + "leven": "^2.1.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/vnopts/node_modules/leven": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", + "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "node_modules/wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "dependencies": { + "string-width": "^1.0.2 || 2" + } + }, + "node_modules/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "node_modules/workerpool": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz", + "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/yaml-unist-parser": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/yaml-unist-parser/-/yaml-unist-parser-1.3.1.tgz", + "integrity": "sha512-4aHBMpYcnByF8l2OKj5hlBJlxSYIMON8Z1Hm57ymbBL4omXMlGgY+pEf4Di6h2qNT8ZG8seTVvAQYNOa7CZ9eA==", + "dev": true, + "dependencies": { + "lines-and-columns": "^1.1.6", + "tslib": "^1.10.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser/node_modules/camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs-unparser/node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/z-schema": { + "version": "3.18.4", + "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-3.18.4.tgz", + "integrity": "sha512-DUOKC/IhbkdLKKiV89gw9DUauTV8U/8yJl1sjf6MtDmzevLKOF2duNJ495S3MFVjqZarr+qNGCPbkg4mu4PpLw==", + "dev": true, + "dependencies": { + "lodash.get": "^4.0.0", + "lodash.isequal": "^4.0.0", + "validator": "^8.0.0" + }, + "bin": { + "z-schema": "bin/z-schema" + }, + "optionalDependencies": { + "commander": "^2.7.1" + } + } + }, "dependencies": { "@angular/compiler": { "version": "9.0.5", "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-9.0.5.tgz", "integrity": "sha512-TeyhRGefTOtA9N3udMrvheafoXcz/dvTTdZLcieeZQxm1SSeaQDUQ/rUH6QTOiHVNMtjOCrZ9J5rk1A4mPYuag==", - "dev": true + "dev": true, + "requires": {} }, "@babel/code-frame": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", - "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dev": true, "requires": { - "@babel/highlight": "^7.14.5" + "@babel/highlight": "^7.10.4" } }, "@babel/compat-data": { - "version": "7.14.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.7.tgz", - "integrity": "sha512-nS6dZaISCXJ3+518CWiBfEr//gHyMO02uDxBkXTKZDN5POruCnOZ1N4YBRZDCabwF8nZMWBpRxIicmXtBs+fvw==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.15.0.tgz", + "integrity": "sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA==", "dev": true }, "@babel/core": { - "version": "7.14.6", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.6.tgz", - "integrity": "sha512-gJnOEWSqTk96qG5BoIrl5bVtc23DCycmIePPYnamY9RboYdI4nFy5vAQMSl81O5K/W0sLDWfGysnOECC+KUUCA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.14.5", - "@babel/generator": "^7.14.5", - "@babel/helper-compilation-targets": "^7.14.5", - "@babel/helper-module-transforms": "^7.14.5", - "@babel/helpers": "^7.14.6", - "@babel/parser": "^7.14.6", - "@babel/template": "^7.14.5", - "@babel/traverse": "^7.14.5", - "@babel/types": "^7.14.5", + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.8.tgz", + "integrity": "sha512-3UG9dsxvYBMYwRv+gS41WKHno4K60/9GPy1CJaH6xy3Elq8CTtvtjT5R5jmNhXfCYLX2mTw+7/aq5ak/gOE0og==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.15.8", + "@babel/generator": "^7.15.8", + "@babel/helper-compilation-targets": "^7.15.4", + "@babel/helper-module-transforms": "^7.15.8", + "@babel/helpers": "^7.15.4", + "@babel/parser": "^7.15.8", + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.6", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -48,21 +10772,15 @@ "source-map": "^0.5.0" }, "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "@babel/code-frame": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", + "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", "dev": true, "requires": { - "ms": "2.1.2" + "@babel/highlight": "^7.14.5" } }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -77,32 +10795,13 @@ } } }, - "@babel/eslint-parser": { - "version": "7.14.7", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.14.7.tgz", - "integrity": "sha512-6WPwZqO5priAGIwV6msJcdc9TsEPzYeYdS/Xuoap+/ihkgN6dzHp2bcAAwyWZ5bLzk0vvjDmKvRwkqNaiJ8BiQ==", - "dev": true, - "requires": { - "eslint-scope": "^5.1.1", - "eslint-visitor-keys": "^2.1.0", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, "@babel/generator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz", - "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==", + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.8.tgz", + "integrity": "sha512-ECmAKstXbp1cvpTTZciZCgfOt6iN64lR0d+euv3UZisU5awfRawOvg07Utn/qBGuH4bRIEZKrA/4LzZyXhZr8g==", "dev": true, "requires": { - "@babel/types": "^7.14.5", + "@babel/types": "^7.15.6", "jsesc": "^2.5.1", "source-map": "^0.5.0" }, @@ -116,12 +10815,12 @@ } }, "@babel/helper-compilation-targets": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.14.5.tgz", - "integrity": "sha512-v+QtZqXEiOnpO6EYvlImB6zCD2Lel06RzOPzmkz/D/XgQiUu3C/Jb1LOqSt/AIA34TYi/Q+KlT8vTQrgdxkbLw==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz", + "integrity": "sha512-rMWPCirulnPSe4d+gwdWXLfAXTTBj8M3guAf5xFQJ0nvFY7tfNAFnWdqaHegHlgDZOCT4qvhF3BYlSJag8yhqQ==", "dev": true, "requires": { - "@babel/compat-data": "^7.14.5", + "@babel/compat-data": "^7.15.0", "@babel/helper-validator-option": "^7.14.5", "browserslist": "^4.16.6", "semver": "^6.3.0" @@ -136,111 +10835,111 @@ } }, "@babel/helper-function-name": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz", - "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz", + "integrity": "sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.14.5", - "@babel/template": "^7.14.5", - "@babel/types": "^7.14.5" + "@babel/helper-get-function-arity": "^7.15.4", + "@babel/template": "^7.15.4", + "@babel/types": "^7.15.4" } }, "@babel/helper-get-function-arity": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz", - "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz", + "integrity": "sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA==", "dev": true, "requires": { - "@babel/types": "^7.14.5" + "@babel/types": "^7.15.4" } }, "@babel/helper-hoist-variables": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.14.5.tgz", - "integrity": "sha512-R1PXiz31Uc0Vxy4OEOm07x0oSjKAdPPCh3tPivn/Eo8cvz6gveAeuyUUPB21Hoiif0uoPQSSdhIPS3352nvdyQ==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz", + "integrity": "sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA==", "dev": true, "requires": { - "@babel/types": "^7.14.5" + "@babel/types": "^7.15.4" } }, "@babel/helper-member-expression-to-functions": { - "version": "7.14.7", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.14.7.tgz", - "integrity": "sha512-TMUt4xKxJn6ccjcOW7c4hlwyJArizskAhoSTOCkA0uZ+KghIaci0Qg9R043kUMWI9mtQfgny+NQ5QATnZ+paaA==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.4.tgz", + "integrity": "sha512-cokOMkxC/BTyNP1AlY25HuBWM32iCEsLPI4BHDpJCHHm1FU2E7dKWWIXJgQgSFiu4lp8q3bL1BIKwqkSUviqtA==", "dev": true, "requires": { - "@babel/types": "^7.14.5" + "@babel/types": "^7.15.4" } }, "@babel/helper-module-imports": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz", - "integrity": "sha512-SwrNHu5QWS84XlHwGYPDtCxcA0hrSlL2yhWYLgeOc0w7ccOl2qv4s/nARI0aYZW+bSwAL5CukeXA47B/1NKcnQ==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz", + "integrity": "sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA==", "dev": true, "requires": { - "@babel/types": "^7.14.5" + "@babel/types": "^7.15.4" } }, "@babel/helper-module-transforms": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.5.tgz", - "integrity": "sha512-iXpX4KW8LVODuAieD7MzhNjmM6dzYY5tfRqT+R9HDXWl0jPn/djKmA+G9s/2C2T9zggw5tK1QNqZ70USfedOwA==", + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.8.tgz", + "integrity": "sha512-DfAfA6PfpG8t4S6npwzLvTUpp0sS7JrcuaMiy1Y5645laRJIp/LiLGIBbQKaXSInK8tiGNI7FL7L8UvB8gdUZg==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.14.5", - "@babel/helper-replace-supers": "^7.14.5", - "@babel/helper-simple-access": "^7.14.5", - "@babel/helper-split-export-declaration": "^7.14.5", - "@babel/helper-validator-identifier": "^7.14.5", - "@babel/template": "^7.14.5", - "@babel/traverse": "^7.14.5", - "@babel/types": "^7.14.5" + "@babel/helper-module-imports": "^7.15.4", + "@babel/helper-replace-supers": "^7.15.4", + "@babel/helper-simple-access": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4", + "@babel/helper-validator-identifier": "^7.15.7", + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.6" } }, "@babel/helper-optimise-call-expression": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.14.5.tgz", - "integrity": "sha512-IqiLIrODUOdnPU9/F8ib1Fx2ohlgDhxnIDU7OEVi+kAbEZcyiF7BLU8W6PfvPi9LzztjS7kcbzbmL7oG8kD6VA==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.15.4.tgz", + "integrity": "sha512-E/z9rfbAOt1vDW1DR7k4SzhzotVV5+qMciWV6LaG1g4jeFrkDlJedjtV4h0i4Q/ITnUu+Pk08M7fczsB9GXBDw==", "dev": true, "requires": { - "@babel/types": "^7.14.5" + "@babel/types": "^7.15.4" } }, "@babel/helper-replace-supers": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.14.5.tgz", - "integrity": "sha512-3i1Qe9/8x/hCHINujn+iuHy+mMRLoc77b2nI9TB0zjH1hvn9qGlXjWlggdwUcju36PkPCy/lpM7LLUdcTyH4Ow==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.4.tgz", + "integrity": "sha512-/ztT6khaXF37MS47fufrKvIsiQkx1LBRvSJNzRqmbyeZnTwU9qBxXYLaaT/6KaxfKhjs2Wy8kG8ZdsFUuWBjzw==", "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "^7.14.5", - "@babel/helper-optimise-call-expression": "^7.14.5", - "@babel/traverse": "^7.14.5", - "@babel/types": "^7.14.5" + "@babel/helper-member-expression-to-functions": "^7.15.4", + "@babel/helper-optimise-call-expression": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" } }, "@babel/helper-simple-access": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.14.5.tgz", - "integrity": "sha512-nfBN9xvmCt6nrMZjfhkl7i0oTV3yxR4/FztsbOASyTvVcoYd0TRHh7eMLdlEcCqobydC0LAF3LtC92Iwxo0wyw==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.15.4.tgz", + "integrity": "sha512-UzazrDoIVOZZcTeHHEPYrr1MvTR/K+wgLg6MY6e1CJyaRhbibftF6fR2KU2sFRtI/nERUZR9fBd6aKgBlIBaPg==", "dev": true, "requires": { - "@babel/types": "^7.14.5" + "@babel/types": "^7.15.4" } }, "@babel/helper-split-export-declaration": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz", - "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz", + "integrity": "sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw==", "dev": true, "requires": { - "@babel/types": "^7.14.5" + "@babel/types": "^7.15.4" } }, "@babel/helper-validator-identifier": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", - "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", + "version": "7.15.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", + "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", "dev": true }, "@babel/helper-validator-option": { @@ -250,14 +10949,14 @@ "dev": true }, "@babel/helpers": { - "version": "7.14.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.14.6.tgz", - "integrity": "sha512-yesp1ENQBiLI+iYHSJdoZKUtRpfTlL1grDIX9NRlAVppljLw/4tTyYupIB7uIYmC3stW/imAv8EqaKaS/ibmeA==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.4.tgz", + "integrity": "sha512-V45u6dqEJ3w2rlryYYXf6i9rQ5YMNu4FLS6ngs8ikblhu2VdR1AqAd6aJjBzmf2Qzh6KOLqKHxEN9+TFbAkAVQ==", "dev": true, "requires": { - "@babel/template": "^7.14.5", - "@babel/traverse": "^7.14.5", - "@babel/types": "^7.14.5" + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" } }, "@babel/highlight": { @@ -272,46 +10971,57 @@ } }, "@babel/parser": { - "version": "7.14.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.7.tgz", - "integrity": "sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==", + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.8.tgz", + "integrity": "sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA==", "dev": true }, "@babel/template": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", - "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.15.4.tgz", + "integrity": "sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg==", "dev": true, "requires": { "@babel/code-frame": "^7.14.5", - "@babel/parser": "^7.14.5", - "@babel/types": "^7.14.5" + "@babel/parser": "^7.15.4", + "@babel/types": "^7.15.4" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", + "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.14.5" + } + } } }, "@babel/traverse": { - "version": "7.14.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.7.tgz", - "integrity": "sha512-9vDr5NzHu27wgwejuKL7kIOm4bwEtaPQ4Z6cpCmjSuaRqpH/7xc4qcGEscwMqlkwgcXl6MvqoAjZkQ24uSdIZQ==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.4.tgz", + "integrity": "sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA==", "dev": true, "requires": { "@babel/code-frame": "^7.14.5", - "@babel/generator": "^7.14.5", - "@babel/helper-function-name": "^7.14.5", - "@babel/helper-hoist-variables": "^7.14.5", - "@babel/helper-split-export-declaration": "^7.14.5", - "@babel/parser": "^7.14.7", - "@babel/types": "^7.14.5", + "@babel/generator": "^7.15.4", + "@babel/helper-function-name": "^7.15.4", + "@babel/helper-hoist-variables": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4", + "@babel/parser": "^7.15.4", + "@babel/types": "^7.15.4", "debug": "^4.1.0", "globals": "^11.1.0" }, "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "@babel/code-frame": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", + "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", "dev": true, "requires": { - "ms": "2.1.2" + "@babel/highlight": "^7.14.5" } }, "globals": { @@ -319,29 +11029,38 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true } } }, "@babel/types": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", - "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "version": "7.15.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.6.tgz", + "integrity": "sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.14.5", + "@babel/helper-validator-identifier": "^7.14.9", "to-fast-properties": "^2.0.0" } }, + "@cspotcode/source-map-consumer": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", + "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", + "dev": true + }, + "@cspotcode/source-map-support": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.6.1.tgz", + "integrity": "sha512-DX3Z+T5dt1ockmPdobJS/FAsQPW4V4SrWEhD2iYQT2Cb2tQsiMnYxrcUH9By/Z3B+v0S5LMBkQtV/XOBbpLEOg==", + "dev": true, + "requires": { + "@cspotcode/source-map-consumer": "0.8.0" + } + }, "@eslint/eslintrc": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.2.tgz", - "integrity": "sha512-8nmGq/4ycLpIwzvhI4tNDmQztZ8sp+hI7cyG8i1nQDhkAbRzHpXPidRAHlNvCZQpJTKw5ItIpMw9RSToGF00mg==", + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", + "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", "dev": true, "requires": { "ajv": "^6.12.4", @@ -355,32 +11074,21 @@ "strip-json-comments": "^3.1.1" }, "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, "ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "strip-json-comments": { - "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==", - "dev": true + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } } } }, @@ -431,23 +11139,6 @@ "@humanwhocodes/object-schema": "^1.2.0", "debug": "^4.1.1", "minimatch": "^3.0.4" - }, - "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } } }, "@humanwhocodes/object-schema": { @@ -475,12 +11166,6 @@ "resolve-from": "^5.0.0" }, "dependencies": { - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, "find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -491,6 +11176,16 @@ "path-exists": "^4.0.0" } }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -518,18 +11213,6 @@ "p-limit": "^2.2.0" } }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, "resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", @@ -545,9 +11228,9 @@ "dev": true }, "@jest/types": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz", - "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==", + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.2.5.tgz", + "integrity": "sha512-nmuM4VuDtCZcY+eTpw+0nvstwReMsjPoj7ZR80/BbixulhLaiX+fbv8oeLW8WZlJMcsGQsTmMKT/iTZu1Uy/lQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -567,9 +11250,9 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -615,45 +11298,34 @@ "dev": true }, "@microsoft/api-extractor": { - "version": "7.18.1", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.18.1.tgz", - "integrity": "sha512-qljUF2Q0zAx1vJrjKkJVGN7OVbsXki+Pji99jywyl6L/FK3YZ7PpstUJYE6uBcLPy6rhNPWPAsHNTMpG/kHIsg==", + "version": "7.18.15", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.18.15.tgz", + "integrity": "sha512-a8gPbb0gAO+gyWzGmB6eG9ACI3++JS0Y9049xKKITizbGV5PWrLlx3a5S1kSqVP7b6MxVK3QVnJskLzf8n1SkQ==", "dev": true, "requires": { - "@microsoft/api-extractor-model": "7.13.3", + "@microsoft/api-extractor-model": "7.13.12", "@microsoft/tsdoc": "0.13.2", "@microsoft/tsdoc-config": "~0.15.2", - "@rushstack/node-core-library": "3.39.0", - "@rushstack/rig-package": "0.2.12", - "@rushstack/ts-command-line": "4.8.0", + "@rushstack/node-core-library": "3.42.2", + "@rushstack/rig-package": "0.3.2", + "@rushstack/ts-command-line": "4.10.1", "colors": "~1.2.1", "lodash": "~4.17.15", "resolve": "~1.17.0", "semver": "~7.3.0", "source-map": "~0.6.1", - "typescript": "~4.3.2" - }, - "dependencies": { - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } + "typescript": "~4.4.2" } }, "@microsoft/api-extractor-model": { - "version": "7.13.3", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.13.3.tgz", - "integrity": "sha512-uXilAhu2GcvyY/0NwVRk3AN7TFYjkPnjHLV2UywTTz9uglS+Af0YjNrCy+aaK8qXtfbFWdBzkH9N2XU8/YBeRQ==", + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.13.12.tgz", + "integrity": "sha512-BTTGg1tgcDpW3CyW6QQ3VWFLzKyHxfyNGw68EAS/MXnNKx580HE08hLWrSjM2zHQ1J35v4PBUorsRK+FBkHl5Q==", "dev": true, "requires": { "@microsoft/tsdoc": "0.13.2", "@microsoft/tsdoc-config": "~0.15.2", - "@rushstack/node-core-library": "3.39.0" + "@rushstack/node-core-library": "3.42.2" } }, "@microsoft/tsdoc": { @@ -713,9 +11385,9 @@ } }, "@octokit/auth-token": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.4.5.tgz", - "integrity": "sha512-BpGYsPgJt05M7/L/5FoE1PiAbdxXFZkX/3kDYcsvd1v6UhlnE5e96dTDr0ezX/EFwciQxf3cNV0loipsURU+WA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz", + "integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==", "requires": { "@octokit/types": "^6.0.3" } @@ -745,9 +11417,9 @@ } }, "@octokit/graphql": { - "version": "4.6.4", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.6.4.tgz", - "integrity": "sha512-SWTdXsVheRmlotWNjKzPOb6Js6tjSqA2a8z9+glDJng0Aqjzti8MEWOtuT8ZSu6wHnci7LZNuarE87+WJBG4vg==", + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz", + "integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==", "requires": { "@octokit/request": "^5.6.0", "@octokit/types": "^6.0.3", @@ -755,36 +11427,37 @@ } }, "@octokit/openapi-types": { - "version": "8.2.1", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-8.2.1.tgz", - "integrity": "sha512-BJz6kWuL3n+y+qM8Pv+UGbSxH6wxKf/SBs5yzGufMHwDefsa+Iq7ZGy1BINMD2z9SkXlIzk1qiu988rMuGXEMg==" + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-11.2.0.tgz", + "integrity": "sha512-PBsVO+15KSlGmiI8QAzaqvsNlZlrDlyAJYcrXBCvVUxCp7VnXjkwPoFHgjEJXx3WF9BAwkA6nfCUA7i9sODzKA==" }, "@octokit/plugin-paginate-rest": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.14.0.tgz", - "integrity": "sha512-S2uEu2uHeI7Vf+Lvj8tv3O5/5TCAa8GHS0dUQN7gdM7vKA6ZHAbR6HkAVm5yMb1mbedLEbxOuQ+Fa0SQ7tCDLA==", + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.17.0.tgz", + "integrity": "sha512-tzMbrbnam2Mt4AhuyCHvpRkS0oZ5MvwwcQPYGtMv4tUa5kkzG58SVB0fcsLulOZQeRnOgdkZWkRUiyBlh0Bkyw==", "requires": { - "@octokit/types": "^6.18.0" + "@octokit/types": "^6.34.0" } }, "@octokit/plugin-request-log": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz", - "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==" + "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==", + "requires": {} }, "@octokit/plugin-rest-endpoint-methods": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.4.1.tgz", - "integrity": "sha512-Nx0g7I5ayAYghsLJP4Q1Ch2W9jYYM0FlWWWZocUro8rNxVwuZXGfFd7Rcqi9XDWepSXjg1WByiNJnZza2hIOvQ==", + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.13.0.tgz", + "integrity": "sha512-uJjMTkN1KaOIgNtUPMtIXDOjx6dGYysdIFhgA52x4xSadQCz3b/zJexvITDVpANnfKPW/+E0xkOvLntqMYpviA==", "requires": { - "@octokit/types": "^6.18.1", + "@octokit/types": "^6.34.0", "deprecation": "^2.3.1" } }, "@octokit/request": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.0.tgz", - "integrity": "sha512-4cPp/N+NqmaGQwbh3vUsYqokQIzt7VjsgTYVXiwpUP2pxd5YiZB2XuTedbb0SPtv9XS7nzAKjAuQxmY8/aZkiA==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.2.tgz", + "integrity": "sha512-je66CvSEVf0jCpRISxkUcCa0UkxmFs6eGDRSbfJtAVwbLH5ceqF+YEyC8lj8ystKyZTy8adWr0qmkY52EfOeLA==", "requires": { "@octokit/endpoint": "^6.0.1", "@octokit/request-error": "^2.1.0", @@ -805,31 +11478,31 @@ } }, "@octokit/rest": { - "version": "18.6.7", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.6.7.tgz", - "integrity": "sha512-Kn6WrI2ZvmAztdx+HEaf88RuJn+LK72S8g6OpciE4kbZddAN84fu4fiPGxcEu052WmqKVnA/cnQsbNlrYC6rqQ==", + "version": "18.12.0", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.12.0.tgz", + "integrity": "sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==", "requires": { - "@octokit/core": "^3.5.0", - "@octokit/plugin-paginate-rest": "^2.6.2", - "@octokit/plugin-request-log": "^1.0.2", - "@octokit/plugin-rest-endpoint-methods": "5.4.1" + "@octokit/core": "^3.5.1", + "@octokit/plugin-paginate-rest": "^2.16.8", + "@octokit/plugin-request-log": "^1.0.4", + "@octokit/plugin-rest-endpoint-methods": "^5.12.0" } }, "@octokit/types": { - "version": "6.18.1", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.18.1.tgz", - "integrity": "sha512-5YsddjO1U+xC8ZYKV8yZYebW55PCc7qiEEeZ+wZRr6qyclynzfyD65KZ5FdtIeP0/cANyFaD7hV69qElf1nMsQ==", + "version": "6.34.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.34.0.tgz", + "integrity": "sha512-s1zLBjWhdEI2zwaoSgyOFoKSl109CUcVBCc7biPJ3aAf6LGLU6szDvi31JPU7bxfla2lqfhjbbg/5DdFNxOwHw==", "requires": { - "@octokit/openapi-types": "^8.2.1" + "@octokit/openapi-types": "^11.2.0" } }, "@rushstack/node-core-library": { - "version": "3.39.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.39.0.tgz", - "integrity": "sha512-kgu3+7/zOBkZU0+NdJb1rcHcpk3/oTjn5c8cg5nUTn+JDjEw58yG83SoeJEcRNNdl11dGX0lKG2PxPsjCokZOQ==", + "version": "3.42.2", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.42.2.tgz", + "integrity": "sha512-LJ52CiiWxKpzejYACqphQQ3geWZFt5gswki8+0sMl8qZ08YCHbqlS3N+sMZpuBEwLWvBYfq/d3IvtdLT3zI2UA==", "dev": true, "requires": { - "@types/node": "10.17.13", + "@types/node": "12.20.24", "colors": "~1.2.1", "fs-extra": "~7.0.1", "import-lazy": "~4.0.0", @@ -841,9 +11514,9 @@ }, "dependencies": { "@types/node": { - "version": "10.17.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.13.tgz", - "integrity": "sha512-pMCcqU2zT4TjqYFrWtYHKal7Sl30Ims6ulZ4UFXxI4xbtQqK/qqKwkDoBFCfooRqqmRu9vY3xaJRwxSh673aYg==", + "version": "12.20.24", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.24.tgz", + "integrity": "sha512-yxDeaQIAJlMav7fH5AQqPH1u8YIuhYJXYBzxaQ4PifsU0GDO38MSdmEDeRlIxrKbC6NbEaaEHDanWb+y30U8SQ==", "dev": true }, "fs-extra": { @@ -857,39 +11530,37 @@ "universalify": "^0.1.0" } }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", "dev": true, "requires": { - "lru-cache": "^6.0.0" + "graceful-fs": "^4.1.6" } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true } } }, "@rushstack/rig-package": { - "version": "0.2.12", - "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.2.12.tgz", - "integrity": "sha512-nbePcvF8hQwv0ql9aeQxcaMPK/h1OLAC00W7fWCRWIvD2MchZOE8jumIIr66HGrfG2X1sw++m/ZYI4D+BM5ovQ==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.3.2.tgz", + "integrity": "sha512-lJbud9zBY8+OOjkeQ+4zIVCvt2I8y1C3WcVx3g6NJgjf0pi6IYfbAWXXG+mVzevQmqanNCLyhyXSNP3E6u5OvQ==", "dev": true, "requires": { "resolve": "~1.17.0", "strip-json-comments": "~3.1.1" - }, - "dependencies": { - "strip-json-comments": { - "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==", - "dev": true - } } }, "@rushstack/ts-command-line": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.8.0.tgz", - "integrity": "sha512-nZ8cbzVF1VmFPfSJfy8vEohdiFAH/59Y/Y+B4nsJbn4SkifLJ8LqNZ5+LxCC2UR242EXFumxlsY1d6fPBxck5Q==", + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.10.1.tgz", + "integrity": "sha512-FhWnQCjHtxmZr5sVEgoV1VHTFaPfJXQbVwujAaZUzuFfgqX+v2P9o0AXmUi/LED4tmPJp7A1nVgPx0ClyGUbWA==", "dev": true, "requires": { "@types/argparse": "1.0.38", @@ -958,6 +11629,18 @@ "colors": "~1.2.1", "js-yaml": "~3.13.1", "resolve": "~1.17.0" + }, + "dependencies": { + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + } } }, "@sosuisen/jsondiffpatch": { @@ -996,6 +11679,21 @@ "jsonfile": "^4.0.0", "universalify": "^0.1.0" } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true } } }, @@ -1055,19 +11753,10 @@ "@types/responselike": "*" } }, - "@types/expect": { - "version": "24.3.0", - "resolved": "https://registry.npmjs.org/@types/expect/-/expect-24.3.0.tgz", - "integrity": "sha512-aq5Z+YFBz5o2b6Sp1jigx5nsmoZMK5Ceurjwy6PZmRv7dEi1jLtkARfvB1ME+OXJUG+7TZUDcv3WoCr/aor6dQ==", - "dev": true, - "requires": { - "expect": "*" - } - }, "@types/fs-extra": { - "version": "9.0.12", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.12.tgz", - "integrity": "sha512-I+bsBr67CurCGnSenZZ7v94gd3tc3+Aj2taxMT4yu4ABLuOgOjeFxX3dokG24ztSRg5tnT00sL8BszO7gSMoIw==", + "version": "9.0.13", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz", + "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==", "dev": true, "requires": { "@types/node": "*" @@ -1113,16 +11802,27 @@ "@types/istanbul-lib-report": "*" } }, + "@types/js-yaml": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.3.tgz", + "integrity": "sha512-5t9BhoORasuF5uCPr+d5/hdB++zRFUTMIZOzbNkr+jZh3yQht4HYbRDyj9fY8n2TZT30iW9huzav73x4NikqWg==" + }, "@types/json-schema": { - "version": "7.0.8", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.8.tgz", - "integrity": "sha512-YSBPTLTVm2e2OoQIDYx8HaeWJ5tTToLH67kXR7zYNGupXMEHa2++G8k+DczX2cFVgalypqtyZIcU19AFcmOpmg==", + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", + "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", + "dev": true + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", "dev": true }, "@types/keyv": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.2.tgz", - "integrity": "sha512-/FvAK2p4jQOaJ6CGDHJTqZcUtbZe820qIeTg7o0Shg7drB4JHeL+V/dhSaly7NXx6u8eSee+r7coT+yuJEvDLg==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.3.tgz", + "integrity": "sha512-FXCJgyyN3ivVgRoml4h94G/p3kY+u/B86La+QptcqJaWtBWtmc6TtkNfS40n9bIvyLteHh7zXOtgbobORKPbDg==", "dev": true, "requires": { "@types/node": "*" @@ -1141,9 +11841,9 @@ "dev": true }, "@types/node": { - "version": "14.17.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.5.tgz", - "integrity": "sha512-bjqH2cX/O33jXT/UmReo2pM7DIJREPMnarixbQ57DOOzzFaI6D2+IcwaJQaJpv0M1E9TIhPCYVxrkcityLjlqA==", + "version": "14.17.21", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.21.tgz", + "integrity": "sha512-zv8ukKci1mrILYiQOwGSV4FpkZhyxQtuFWGya2GujWg+zVAeRQ4qbaMmWp9vb9889CFA8JECH7lkwCL6Ygg8kA==", "dev": true }, "@types/normalize-package-data": { @@ -1174,9 +11874,9 @@ } }, "@types/rimraf": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-3.0.1.tgz", - "integrity": "sha512-CAoSlbco40aKZ0CkelBF2g3JeN6aioRaTVnqSX5pWsn/WApm6IDxI4e4tD9D0dY/meCkyyleP1IQDVN13F4maA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-F3OznnSLAUxFrCEu/L5PY8+ny8DtcFRjx7fZZ9bycvXRi3KPTRS9HOitGZwvPg0juRhXFWIeKX58cnX5YqLohQ==", "dev": true, "requires": { "@types/glob": "*", @@ -1193,9 +11893,9 @@ } }, "@types/sinonjs__fake-timers": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.3.tgz", - "integrity": "sha512-E1dU4fzC9wN2QK2Cr1MLCfyHM8BoNnRFvuf45LYMPNDA+WqbNzC45S4UzPxvp1fFJ1rvSGU0bPvdd35VLmXG8g==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.4.tgz", + "integrity": "sha512-IFQTJARgMUBF+xVd2b+hIgXWrZEjND3vJtRCvIelcFB5SIXfjV4bOHbHJ0eXKh+0COrBRc8MqteKAz/j88rE0A==", "dev": true }, "@types/stack-utils": { @@ -1205,9 +11905,9 @@ "dev": true }, "@types/unist": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.5.tgz", - "integrity": "sha512-wnra4Vw9dopnuybR6HBywJ/URYpYrKLoepBTEtgfJup8Ahoi2zJECPP2cwiXp7btTvOT2CULv87aQRA4eZSP6g==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", + "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==", "dev": true }, "@types/yargs": { @@ -1226,153 +11926,96 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "4.28.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.28.2.tgz", - "integrity": "sha512-PGqpLLzHSxq956rzNGasO3GsAPf2lY9lDUBXhS++SKonglUmJypaUtcKzRtUte8CV7nruwnDxtLUKpVxs0wQBw==", + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz", + "integrity": "sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==", "dev": true, "requires": { - "@typescript-eslint/experimental-utils": "4.28.2", - "@typescript-eslint/scope-manager": "4.28.2", + "@typescript-eslint/experimental-utils": "4.33.0", + "@typescript-eslint/scope-manager": "4.33.0", "debug": "^4.3.1", "functional-red-black-tree": "^1.0.1", + "ignore": "^5.1.8", "regexpp": "^3.1.0", "semver": "^7.3.5", "tsutils": "^3.21.0" - }, - "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } } }, "@typescript-eslint/experimental-utils": { - "version": "4.28.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.28.2.tgz", - "integrity": "sha512-MwHPsL6qo98RC55IoWWP8/opTykjTp4JzfPu1VfO2Z0MshNP0UZ1GEV5rYSSnZSUI8VD7iHvtIPVGW5Nfh7klQ==", + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz", + "integrity": "sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==", "dev": true, "requires": { "@types/json-schema": "^7.0.7", - "@typescript-eslint/scope-manager": "4.28.2", - "@typescript-eslint/types": "4.28.2", - "@typescript-eslint/typescript-estree": "4.28.2", + "@typescript-eslint/scope-manager": "4.33.0", + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/typescript-estree": "4.33.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0" - } - }, - "@typescript-eslint/parser": { - "version": "4.28.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.28.2.tgz", - "integrity": "sha512-Q0gSCN51eikAgFGY+gnd5p9bhhCUAl0ERMiDKrTzpSoMYRubdB8MJrTTR/BBii8z+iFwz8oihxd0RAdP4l8w8w==", - "dev": true, - "requires": { - "@typescript-eslint/scope-manager": "4.28.2", - "@typescript-eslint/types": "4.28.2", - "@typescript-eslint/typescript-estree": "4.28.2", - "debug": "^4.3.1" }, "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", "dev": true, "requires": { - "ms": "2.1.2" + "eslint-visitor-keys": "^2.0.0" } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true } } }, + "@typescript-eslint/parser": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.33.0.tgz", + "integrity": "sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "4.33.0", + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/typescript-estree": "4.33.0", + "debug": "^4.3.1" + } + }, "@typescript-eslint/scope-manager": { - "version": "4.28.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.28.2.tgz", - "integrity": "sha512-MqbypNjIkJFEFuOwPWNDjq0nqXAKZvDNNs9yNseoGBB1wYfz1G0WHC2AVOy4XD7di3KCcW3+nhZyN6zruqmp2A==", + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", + "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", "dev": true, "requires": { - "@typescript-eslint/types": "4.28.2", - "@typescript-eslint/visitor-keys": "4.28.2" + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/visitor-keys": "4.33.0" } }, "@typescript-eslint/types": { - "version": "4.28.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.28.2.tgz", - "integrity": "sha512-Gr15fuQVd93uD9zzxbApz3wf7ua3yk4ZujABZlZhaxxKY8ojo448u7XTm/+ETpy0V0dlMtj6t4VdDvdc0JmUhA==", + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", + "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "4.28.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.2.tgz", - "integrity": "sha512-86lLstLvK6QjNZjMoYUBMMsULFw0hPHJlk1fzhAVoNjDBuPVxiwvGuPQq3fsBMCxuDJwmX87tM/AXoadhHRljg==", + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", + "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", "dev": true, "requires": { - "@typescript-eslint/types": "4.28.2", - "@typescript-eslint/visitor-keys": "4.28.2", + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/visitor-keys": "4.33.0", "debug": "^4.3.1", "globby": "^11.0.3", "is-glob": "^4.0.1", "semver": "^7.3.5", "tsutils": "^3.21.0" - }, - "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } } }, "@typescript-eslint/visitor-keys": { - "version": "4.28.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.2.tgz", - "integrity": "sha512-aT2B4PLyyRDUVUafXzpZFoc0C9t0za4BJAKP5sgWIhG+jHECQZUEjuQSCIwZdiJJ4w4cgu5r3Kh20SOdtEBl0w==", + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", + "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", "dev": true, "requires": { - "@typescript-eslint/types": "4.28.2", + "@typescript-eslint/types": "4.33.0", "eslint-visitor-keys": "^2.0.0" } }, @@ -1398,6 +12041,13 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "requires": {} + }, + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", "dev": true }, "aggregate-error": { @@ -1448,9 +12098,9 @@ "dev": true }, "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, "ansi-styles": { @@ -1493,13 +12143,45 @@ "dev": true }, "are-we-there-yet": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", + "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", "dev": true, "requires": { "delegates": "^1.0.0", "readable-stream": "^2.0.6" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } } }, "arg": { @@ -1518,16 +12200,16 @@ } }, "array-includes": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", - "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", + "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2", + "es-abstract": "^1.19.1", "get-intrinsic": "^1.1.1", - "is-string": "^1.0.5" + "is-string": "^1.0.7" } }, "array-union": { @@ -1537,26 +12219,25 @@ "dev": true }, "array.prototype.flat": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz", - "integrity": "sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", + "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==", "dev": true, "requires": { - "call-bind": "^1.0.0", + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1" + "es-abstract": "^1.19.0" } }, "array.prototype.flatmap": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.4.tgz", - "integrity": "sha512-r9Z0zYoxqHz60vvQbWEdXIEtCwHF0yxaWfno9qzXeNHvfyl3BZqygmGzb84dsubyaXLH4husF+NFgMSdpZhk2Q==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.5.tgz", + "integrity": "sha512-08u6rVyi1Lj7oqWbS9nUxliETrtIROT4XGTA4D/LWGten6E3ocm7cy9SIrmNHOL5XVbVuckUp3X6Xyg8/zpvHA==", "dev": true, "requires": { "call-bind": "^1.0.0", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1", - "function-bind": "^1.1.1" + "es-abstract": "^1.19.0" } }, "asn1": { @@ -1647,6 +12328,38 @@ "requires": { "readable-stream": "^2.3.5", "safe-buffer": "^5.1.1" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } } }, "blob-polyfill": { @@ -1679,16 +12392,16 @@ "dev": true }, "browserslist": { - "version": "4.16.6", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", - "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", + "version": "4.17.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.3.tgz", + "integrity": "sha512-59IqHJV5VGdcJZ+GZ2hU5n4Kv3YiASzW6Xk5g9tf5a/MAzGeFwgGWU39fVzNIOVcgB3+Gp+kiQu0HEfTVU/3VQ==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001219", - "colorette": "^1.2.2", - "electron-to-chromium": "^1.3.723", + "caniuse-lite": "^1.0.30001264", + "electron-to-chromium": "^1.3.857", "escalade": "^3.1.1", - "node-releases": "^1.1.71" + "node-releases": "^1.1.77", + "picocolors": "^0.2.1" } }, "buffer-alloc": { @@ -1714,9 +12427,15 @@ "dev": true }, "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "builtin-modules": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", + "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", + "dev": true }, "cacheable-lookup": { "version": "2.0.1", @@ -1772,15 +12491,15 @@ "dev": true }, "camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, "caniuse-lite": { - "version": "1.0.30001243", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001243.tgz", - "integrity": "sha512-vNxw9mkTBtkmLFnJRv/2rhs1yufpDfCkBZexG3Y0xdOH2Z/eE/85E4Dl5j1YUN34nZVsSp6vVRFQRrez9wJMRA==", + "version": "1.0.30001265", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001265.tgz", + "integrity": "sha512-YzBnspggWV5hep1m9Z6sZVLOt7vrju8xWooFAgN6BA5qvy98qPAPb7vNUzypFaoh2pb3vlfzbDO8tB57UPGbtw==", "dev": true }, "caseless": { @@ -1897,12 +12616,6 @@ "wrap-ansi": "^7.0.0" }, "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -1910,23 +12623,14 @@ "dev": true }, "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" + "strip-ansi": "^6.0.1" } } } @@ -1973,12 +12677,6 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, - "colorette": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", - "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", - "dev": true - }, "colors": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz", @@ -2055,20 +12753,6 @@ "parse-json": "^5.0.0", "path-type": "^4.0.0", "yaml": "^1.10.0" - }, - "dependencies": { - "parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - } - } } }, "coveralls": { @@ -2082,6 +12766,18 @@ "log-driver": "^1.2.7", "minimist": "^1.2.5", "request": "^2.88.2" + }, + "dependencies": { + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + } } }, "crc-32": { @@ -2136,17 +12832,6 @@ "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" - }, - "dependencies": { - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } } }, "dashdash": { @@ -2165,18 +12850,18 @@ "dev": true }, "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, "decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true }, "decompress-response": { @@ -2201,9 +12886,9 @@ "dev": true }, "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, "deepmerge": { @@ -2219,14 +12904,6 @@ "dev": true, "requires": { "strip-bom": "^4.0.0" - }, - "dependencies": { - "strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true - } } }, "defer-to-connect": { @@ -2274,9 +12951,9 @@ "dev": true }, "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", "dev": true }, "diff-match-patch": { @@ -2341,27 +13018,11 @@ "sigmund": "^1.0.1" }, "dependencies": { - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true } } }, @@ -2372,9 +13033,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.3.772", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.772.tgz", - "integrity": "sha512-X/6VRCXWALzdX+RjCtBU6cyg8WZgoxm9YA02COmDOiNJEZ59WkQggDbWZ4t/giHi/3GS+cvdrP6gbLISANAGYA==", + "version": "1.3.864", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.864.tgz", + "integrity": "sha512-v4rbad8GO6/yVI92WOeU9Wgxc4NA0n4f6P1FvZTY+jyY7JHEhw3bduYu60v3Q1h81Cg6eo4ApZrFPuycwd5hGw==", "dev": true }, "emoji-regex": { @@ -2417,22 +13078,26 @@ } }, "es-abstract": { - "version": "1.18.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz", - "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==", + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", + "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", "dev": true, "requires": { "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", "has": "^1.0.3", "has-symbols": "^1.0.2", - "is-callable": "^1.2.3", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.3", - "is-string": "^1.0.6", - "object-inspect": "^1.10.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.1", + "is-string": "^1.0.7", + "is-weakref": "^1.0.1", + "object-inspect": "^1.11.0", "object-keys": "^1.1.1", "object.assign": "^4.1.2", "string.prototype.trimend": "^1.0.4", @@ -2469,13 +13134,13 @@ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "eslint": { - "version": "7.30.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.30.0.tgz", - "integrity": "sha512-VLqz80i3as3NdloY44BQSJpFw534L9Oh+6zJOUaViV4JPd+DaHwutqP7tcpkW3YiXbK6s05RZl7yl7cQn+lijg==", + "version": "7.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", + "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", "dev": true, "requires": { "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.2", + "@eslint/eslintrc": "^0.4.3", "@humanwhocodes/config-array": "^0.5.0", "ajv": "^6.10.0", "chalk": "^4.0.0", @@ -2516,21 +13181,6 @@ "v8-compile-cache": "^2.0.3" }, "dependencies": { - "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.4" - } - }, - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -2541,9 +13191,9 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -2565,38 +13215,12 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } - } - }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -2609,35 +13233,15 @@ "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - }, - "strip-json-comments": { - "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==", - "dev": true + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } }, "supports-color": { "version": "7.2.0", @@ -2660,20 +13264,12 @@ "lodash.zip": "^4.2.0" } }, - "eslint-config-prettier": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.11.0.tgz", - "integrity": "sha512-oB8cpLWSAjOVFEJhhyMZh6NOEOtBVziaqdDQ86+qhDHFbZXoRTM7pNSvFRfW/W/L/LrQ38C99J5CGuRBBzBsdA==", - "dev": true, - "requires": { - "get-stdin": "^6.0.0" - } - }, "eslint-config-standard": { "version": "16.0.3", "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-16.0.3.tgz", "integrity": "sha512-x4fmJL5hGqNJKGHSjnLdgA6U6h1YW/G2dW9fA+cyVur4SK6lyue8+UgNKWlZtUDTXvgKDD/Oa3GQjmB5kjtVvg==", - "dev": true + "dev": true, + "requires": {} }, "eslint-config-standardize": { "version": "0.7.2", @@ -2693,69 +13289,188 @@ "eslint-plugin-react": "~7.22.0", "eslint-plugin-react-hooks": "~4.2.0", "eslint-plugin-unicorn": "~26.0.1" + }, + "dependencies": { + "eslint-plugin-unicorn": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-26.0.1.tgz", + "integrity": "sha512-SWgF9sIVY74zqkkSN2dclSCqRfocWSUGD0haC0NX2oRfmdp9p8dQvJYkYSQePaCyssPUE/pqpsIEEZNTh8crUA==", + "dev": true, + "requires": { + "ci-info": "^2.0.0", + "clean-regexp": "^1.0.0", + "eslint-ast-utils": "^1.1.0", + "eslint-template-visitor": "^2.2.2", + "eslint-utils": "^2.1.0", + "import-modules": "^2.1.0", + "lodash": "^4.17.20", + "pluralize": "^8.0.0", + "read-pkg-up": "^7.0.1", + "regexp-tree": "^0.1.21", + "reserved-words": "^0.1.2", + "safe-regex": "^2.1.1", + "semver": "^7.3.4" + }, + "dependencies": { + "eslint-template-visitor": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/eslint-template-visitor/-/eslint-template-visitor-2.3.2.tgz", + "integrity": "sha512-3ydhqFpuV7x1M9EK52BPNj6V0Kwu0KKkcIAfpUhwHbR8ocRln/oUHgfxQupY8O1h4Qv/POHDumb/BwwNfxbtnA==", + "dev": true, + "requires": { + "@babel/core": "^7.12.16", + "@babel/eslint-parser": "^7.12.16", + "eslint-visitor-keys": "^2.0.0", + "esquery": "^1.3.1", + "multimap": "^1.1.0" + }, + "dependencies": { + "@babel/eslint-parser": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.15.8.tgz", + "integrity": "sha512-fYP7QFngCvgxjUuw8O057SVH5jCXsbFFOoE77CFDcvzwBVgTOkMD/L4mIC5Ud1xf8chK/no2fRbSSn1wvNmKuQ==", + "dev": true, + "requires": { + "eslint-scope": "^5.1.1", + "eslint-visitor-keys": "^2.1.0", + "semver": "^6.3.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + } + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } } }, "eslint-import-resolver-node": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz", - "integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==", + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", + "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", "dev": true, "requires": { - "debug": "^2.6.9", - "resolve": "^1.13.1" + "debug": "^3.2.7", + "resolve": "^1.20.0" }, "dependencies": { "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "requires": { - "ms": "2.0.0" + "ms": "^2.1.1" } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true + "resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dev": true, + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } } } }, "eslint-module-utils": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.1.tgz", - "integrity": "sha512-ZXI9B8cxAJIH4nfkhTwcRTEAnrVfobYqwjWy/QMCZ8rHkZHFjf9yO4BzpiF9kCSfNlMG54eKigISHpX0+AaT4A==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.2.tgz", + "integrity": "sha512-QG8pcgThYOuqxupd06oYTZoNOGaUdTY1PqK+oS6ElF6vs4pBdk/aYxFVQQXzcrAqp9m7cl7lb2ubazX+g16k2Q==", "dev": true, "requires": { "debug": "^3.2.7", "pkg-dir": "^2.0.0" - } - }, - "eslint-plugin-es": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", - "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", - "dev": true, - "requires": { - "eslint-utils": "^2.0.0", - "regexpp": "^3.0.0" }, "dependencies": { - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "requires": { - "eslint-visitor-keys": "^1.1.0" + "ms": "^2.1.1" } - }, - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true } } }, @@ -2799,6 +13514,12 @@ "isarray": "^1.0.0" } }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -2821,21 +13542,16 @@ "semver": "^6.1.0" }, "dependencies": { - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "eslint-plugin-es": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", + "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", "dev": true, "requires": { - "eslint-visitor-keys": "^1.1.0" + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" } }, - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -2853,6 +13569,17 @@ "eslint-config-prettier": "~6.11.0", "prettier-linter-helpers": "~1.0.0", "prettierx": "~0.14.0" + }, + "dependencies": { + "eslint-config-prettier": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.11.0.tgz", + "integrity": "sha512-oB8cpLWSAjOVFEJhhyMZh6NOEOtBVziaqdDQ86+qhDHFbZXoRTM7pNSvFRfW/W/L/LrQ38C99J5CGuRBBzBsdA==", + "dev": true, + "requires": { + "get-stdin": "^6.0.0" + } + } } }, "eslint-plugin-promise": { @@ -2905,43 +13632,75 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.2.0.tgz", "integrity": "sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ==", - "dev": true + "dev": true, + "requires": {} }, "eslint-plugin-unicorn": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-26.0.1.tgz", - "integrity": "sha512-SWgF9sIVY74zqkkSN2dclSCqRfocWSUGD0haC0NX2oRfmdp9p8dQvJYkYSQePaCyssPUE/pqpsIEEZNTh8crUA==", + "version": "36.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-36.0.0.tgz", + "integrity": "sha512-xxN2vSctGWnDW6aLElm/LKIwcrmk6mdiEcW55Uv5krcrVcIFSWMmEgc/hwpemYfZacKZ5npFERGNz4aThsp1AA==", "dev": true, "requires": { - "ci-info": "^2.0.0", + "@babel/helper-validator-identifier": "^7.14.9", + "ci-info": "^3.2.0", "clean-regexp": "^1.0.0", - "eslint-ast-utils": "^1.1.0", - "eslint-template-visitor": "^2.2.2", - "eslint-utils": "^2.1.0", - "import-modules": "^2.1.0", - "lodash": "^4.17.20", + "eslint-template-visitor": "^2.3.2", + "eslint-utils": "^3.0.0", + "is-builtin-module": "^3.1.0", + "lodash": "^4.17.21", "pluralize": "^8.0.0", "read-pkg-up": "^7.0.1", - "regexp-tree": "^0.1.21", - "reserved-words": "^0.1.2", + "regexp-tree": "^0.1.23", "safe-regex": "^2.1.1", - "semver": "^7.3.4" + "semver": "^7.3.5" }, "dependencies": { - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "ci-info": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz", + "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==", + "dev": true + }, + "eslint-template-visitor": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/eslint-template-visitor/-/eslint-template-visitor-2.3.2.tgz", + "integrity": "sha512-3ydhqFpuV7x1M9EK52BPNj6V0Kwu0KKkcIAfpUhwHbR8ocRln/oUHgfxQupY8O1h4Qv/POHDumb/BwwNfxbtnA==", "dev": true, "requires": { - "eslint-visitor-keys": "^1.1.0" + "@babel/core": "^7.12.16", + "@babel/eslint-parser": "^7.12.16", + "eslint-visitor-keys": "^2.0.0", + "esquery": "^1.3.1", + "multimap": "^1.1.0" + }, + "dependencies": { + "@babel/eslint-parser": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.15.8.tgz", + "integrity": "sha512-fYP7QFngCvgxjUuw8O057SVH5jCXsbFFOoE77CFDcvzwBVgTOkMD/L4mIC5Ud1xf8chK/no2fRbSSn1wvNmKuQ==", + "dev": true, + "requires": { + "eslint-scope": "^5.1.1", + "eslint-visitor-keys": "^2.1.0", + "semver": "^6.3.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true + "eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^2.0.0" + } }, "find-up": { "version": "4.1.0", @@ -2980,30 +13739,6 @@ "p-limit": "^2.2.0" } }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, "read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -3035,15 +13770,6 @@ "type-fest": "^0.8.1" } }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, "type-fest": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", @@ -3062,26 +13788,21 @@ "estraverse": "^4.1.1" } }, - "eslint-template-visitor": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/eslint-template-visitor/-/eslint-template-visitor-2.3.2.tgz", - "integrity": "sha512-3ydhqFpuV7x1M9EK52BPNj6V0Kwu0KKkcIAfpUhwHbR8ocRln/oUHgfxQupY8O1h4Qv/POHDumb/BwwNfxbtnA==", - "dev": true, - "requires": { - "@babel/core": "^7.12.16", - "@babel/eslint-parser": "^7.12.16", - "eslint-visitor-keys": "^2.0.0", - "esquery": "^1.3.1", - "multimap": "^1.1.0" - } - }, "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, "requires": { - "eslint-visitor-keys": "^2.0.0" + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } } }, "eslint-visitor-keys": { @@ -3167,16 +13888,16 @@ "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==" }, "expect": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.0.6.tgz", - "integrity": "sha512-psNLt8j2kwg42jGBDSfAlU49CEZxejN1f1PlANWDZqIhBOVU/c2Pm888FcjWJzFewhIsNWfZJeLjUjtKGiPuSw==", + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.2.5.tgz", + "integrity": "sha512-ZrO0w7bo8BgGoP/bLz+HDCI+0Hfei9jUSZs5yI/Wyn9VkG9w8oJ7rHRgYj+MA7yqqFa0IwHA3flJzZtYugShJA==", "dev": true, "requires": { - "@jest/types": "^27.0.6", + "@jest/types": "^27.2.5", "ansi-styles": "^5.0.0", "jest-get-type": "^27.0.6", - "jest-matcher-utils": "^27.0.6", - "jest-message-util": "^27.0.6", + "jest-matcher-utils": "^27.2.5", + "jest-message-util": "^27.2.5", "jest-regex-util": "^27.0.6" }, "dependencies": { @@ -3238,9 +13959,9 @@ "dev": true }, "fastq": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.1.tgz", - "integrity": "sha512-HOnr8Mc60eNYl1gzwp6r5RoUyAn5/glBolUzP/Ez6IFVPMPirxn/9phgL6zhOtaTy7ISwPvQ+wT+hfcRZh/bzw==", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", "dev": true, "requires": { "reusify": "^1.0.4" @@ -3270,9 +13991,9 @@ } }, "find-cache-dir": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", - "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", "dev": true, "requires": { "commondir": "^1.0.1", @@ -3317,18 +14038,6 @@ "p-limit": "^2.2.0" } }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, "pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -3353,12 +14062,13 @@ "dev": true }, "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "requires": { - "locate-path": "^2.0.0" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" } }, "flat": { @@ -3378,9 +14088,9 @@ } }, "flatted": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.1.tgz", - "integrity": "sha512-OMQjaErSFHmHqZe+PSidH5n8j3O0F2DdnVh8JB4j4eUQ2k6KvB0qGfrKIhapvez5JerBbmWkaLYUYWISaESoXg==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz", + "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", "dev": true }, "flatten": { @@ -3437,22 +14147,6 @@ "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" - }, - "dependencies": { - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" - } } }, "fs-minipass": { @@ -3502,6 +14196,23 @@ "string-width": "^1.0.1", "strip-ansi": "^3.0.1", "wide-align": "^1.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } } }, "gensync": { @@ -3548,6 +14259,16 @@ "pump": "^3.0.0" } }, + "get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + } + }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -3580,14 +14301,14 @@ "integrity": "sha512-14fN8VAQeBC7+Phs6TYB1D5PJDE/dF8dxbigKpsBEqR1FvpAQerSPptxVsQgkU33xwwZBOm7yCwVD2KKmQatOQ==" }, "glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dev": true, "requires": { - "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", + "minimatch": "2 || 3", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } @@ -3602,20 +14323,12 @@ } }, "globals": { - "version": "13.10.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.10.0.tgz", - "integrity": "sha512-piHC3blgLGFjvOuMmWZX60f+na1lXFDhQXBf1UYp2fXPXqvEUbOhNwi6BsQ0bQishwedgnjkwv1d9zKf+MWw3g==", + "version": "13.11.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz", + "integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==", "dev": true, "requires": { "type-fest": "^0.20.2" - }, - "dependencies": { - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - } } }, "globby": { @@ -3640,21 +14353,6 @@ "requires": { "glob": "^5.0.5", "minimist": "^1.1.1" - }, - "dependencies": { - "glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } } }, "got": { @@ -3678,12 +14376,20 @@ "responselike": "^2.0.0", "to-readable-stream": "^2.0.0", "type-fest": "^0.10.0" + }, + "dependencies": { + "type-fest": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.10.0.tgz", + "integrity": "sha512-EUV9jo4sffrwlg8s0zDhP0T2WD3pru5Xi0+HTE3zTUmBaZNhfkite9PdSJwdXLwPVW0jnAHT56pZHIOYckPEiw==", + "dev": true + } } }, "graceful-fs": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", + "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" }, "graphql": { "version": "15.3.0", @@ -3752,6 +14458,15 @@ "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", "dev": true }, + "has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, "has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", @@ -3946,10 +14661,13 @@ "dev": true }, "is-bigint": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz", - "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==", - "dev": true + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "requires": { + "has-bigints": "^1.0.1" + } }, "is-binary-path": { "version": "2.1.0", @@ -3961,12 +14679,13 @@ } }, "is-boolean-object": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz", - "integrity": "sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", "dev": true, "requires": { - "call-bind": "^1.0.2" + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" } }, "is-buffer": { @@ -3975,26 +14694,38 @@ "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", "dev": true }, + "is-builtin-module": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.1.0.tgz", + "integrity": "sha512-OV7JjAgOTfAFJmHZLvpSTb4qi0nIILDV1gWPYDnDJUTNFM5aGlRAhk4QcT8i7TuAleeEV5Fdkqn3t4mS+Q11fg==", + "dev": true, + "requires": { + "builtin-modules": "^3.0.0" + } + }, "is-callable": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", - "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", "dev": true }, "is-core-module": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", - "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.7.0.tgz", + "integrity": "sha512-ByY+tjCciCr+9nLryBYcSD50EOGWt95c7tIsKTG1J2ixKKXPvF7Ej3AVd+UfDydAJom3biBGDBALaO79ktwgEQ==", "dev": true, "requires": { "has": "^1.0.3" } }, "is-date-object": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz", - "integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==", - "dev": true + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } }, "is-decimal": { "version": "1.0.4", @@ -4018,9 +14749,9 @@ } }, "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "requires": { "is-extglob": "^2.1.1" @@ -4045,10 +14776,13 @@ "dev": true }, "is-number-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz", - "integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==", - "dev": true + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", + "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } }, "is-plain-obj": { "version": "2.1.0", @@ -4062,26 +14796,35 @@ "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==" }, "is-regex": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", - "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dev": true, "requires": { "call-bind": "^1.0.2", - "has-symbols": "^1.0.2" + "has-tostringtag": "^1.0.0" } }, + "is-shared-array-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", + "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", + "dev": true + }, "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true }, "is-string": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz", - "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==", - "dev": true + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } }, "is-symbol": { "version": "1.0.4", @@ -4098,6 +14841,15 @@ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "dev": true }, + "is-weakref": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.1.tgz", + "integrity": "sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0" + } + }, "is-whitespace-character": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz", @@ -4117,9 +14869,9 @@ "dev": true }, "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true }, "isexe": { @@ -4129,9 +14881,9 @@ "dev": true }, "isomorphic-git": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/isomorphic-git/-/isomorphic-git-1.9.1.tgz", - "integrity": "sha512-vzceJaiBdaJI5aT1di4dxWWf6sao3WQFQJ6UTi1tXO4zyDfsuyIadVOA4YQzdwKhLilV9msgM8HIvpOE94kmQg==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/isomorphic-git/-/isomorphic-git-1.10.1.tgz", + "integrity": "sha512-abbPpKkykIVDJ92rtYoD4AOuT5/7PABHR2fDBrsm7H0r2ZT+MGpPL/FynrEJM6nTcFSieaIDxnHNGhfHO/v+bA==", "requires": { "async-lock": "^1.1.0", "clean-git-ref": "^2.0.1", @@ -4144,18 +14896,6 @@ "readable-stream": "^3.4.0", "sha.js": "^2.4.9", "simple-get": "^3.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } } }, "isstream": { @@ -4251,29 +14991,12 @@ "debug": "^4.1.1", "istanbul-lib-coverage": "^3.0.0", "source-map": "^0.6.1" - }, - "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } } }, "istanbul-reports": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", - "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.3.tgz", + "integrity": "sha512-0i77ZFLsb9U3DHi22WzmIngVzfoyxxbQcZRqlF3KoKmCJGq9nhFHoGi8FqBztN2rE8w6hURnZghetn0xpkVb6A==", "dev": true, "requires": { "html-escaper": "^2.0.0", @@ -4281,15 +15004,15 @@ } }, "jest-diff": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.0.6.tgz", - "integrity": "sha512-Z1mqgkTCSYaFgwTlP/NUiRzdqgxmmhzHY1Tq17zL94morOHfHu3K4bgSgl+CR4GLhpV8VxkuOYuIWnQ9LnFqmg==", + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.2.5.tgz", + "integrity": "sha512-7gfwwyYkeslOOVQY4tVq5TaQa92mWfC9COsVYMNVYyJTOYAqbIkoD3twi5A+h+tAPtAelRxkqY6/xu+jwTr0dA==", "dev": true, "requires": { "chalk": "^4.0.0", "diff-sequences": "^27.0.6", "jest-get-type": "^27.0.6", - "pretty-format": "^27.0.6" + "pretty-format": "^27.2.5" }, "dependencies": { "ansi-styles": { @@ -4302,9 +15025,9 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -4359,15 +15082,15 @@ "dev": true }, "jest-matcher-utils": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.0.6.tgz", - "integrity": "sha512-OFgF2VCQx9vdPSYTHWJ9MzFCehs20TsyFi6bIHbk5V1u52zJOnvF0Y/65z3GLZHKRuTgVPY4Z6LVePNahaQ+tA==", + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.2.5.tgz", + "integrity": "sha512-qNR/kh6bz0Dyv3m68Ck2g1fLW5KlSOUNcFQh87VXHZwWc/gY6XwnKofx76Qytz3x5LDWT09/2+yXndTkaG4aWg==", "dev": true, "requires": { "chalk": "^4.0.0", - "jest-diff": "^27.0.6", + "jest-diff": "^27.2.5", "jest-get-type": "^27.0.6", - "pretty-format": "^27.0.6" + "pretty-format": "^27.2.5" }, "dependencies": { "ansi-styles": { @@ -4380,9 +15103,9 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -4422,22 +15145,31 @@ } }, "jest-message-util": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.0.6.tgz", - "integrity": "sha512-rBxIs2XK7rGy+zGxgi+UJKP6WqQ+KrBbD1YMj517HYN3v2BG66t3Xan3FWqYHKZwjdB700KiAJ+iES9a0M+ixw==", + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.2.5.tgz", + "integrity": "sha512-ggXSLoPfIYcbmZ8glgEJZ8b+e0Msw/iddRmgkoO7lDAr9SmI65IIfv7VnvTnV4FGnIIUIjzM+fHRHO5RBvyAbQ==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.0.6", + "@jest/types": "^27.2.5", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.4", - "pretty-format": "^27.0.6", + "pretty-format": "^27.2.5", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, "dependencies": { + "@babel/code-frame": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", + "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.14.5" + } + }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -4448,9 +15180,9 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -4508,13 +15240,18 @@ "dev": true }, "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "argparse": "^2.0.1" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + } } }, "jsbn": { @@ -4584,12 +15321,12 @@ } }, "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "requires": { - "graceful-fs": "^4.1.6" + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" } }, "jsonify": { @@ -4611,12 +15348,12 @@ } }, "jsx-ast-utils": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz", - "integrity": "sha512-EIsmt3O3ljsU6sot/J4E1zDRxfBNrhjyf/OKjlydwgEimQuznlM4Wv7U+ueONJMyEn1WRE0K8dhi3dVAXYT24Q==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.1.tgz", + "integrity": "sha512-uP5vu8xfy2F9A6LGC22KO7e2/vGTS1MhP+18f++ZNlf0Ohaxbc9nIEwHAsejlJKyzfZzU5UIhe5ItYkitcZnZA==", "dev": true, "requires": { - "array-includes": "^3.1.2", + "array-includes": "^3.1.3", "object.assign": "^4.1.2" } }, @@ -4681,22 +15418,36 @@ "strip-bom": "^3.0.0" }, "dependencies": { + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true } } }, "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" + "p-locate": "^5.0.0" } }, "lodash": { @@ -4772,9 +15523,9 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -4829,20 +15580,13 @@ "dev": true }, "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", "dev": true, "requires": { - "yallist": "^4.0.0" - }, - "dependencies": { - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" } }, "make-dir": { @@ -4910,18 +15654,18 @@ } }, "mime-db": { - "version": "1.48.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz", - "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==", + "version": "1.50.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz", + "integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==", "dev": true }, "mime-types": { - "version": "2.1.31", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz", - "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==", + "version": "2.1.33", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.33.tgz", + "integrity": "sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==", "dev": true, "requires": { - "mime-db": "1.48.0" + "mime-db": "1.50.0" } }, "mimic-fn": { @@ -4957,12 +15701,20 @@ } }, "minipass": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", - "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.5.tgz", + "integrity": "sha512-+8NzxD82XQoNKNrl1d/FSi+X8wAEWR+sbYAfIvub4Nz0d22plFG72CEVVaufV8PNf4qSslFTD8VMOxNVhHCjTw==", "dev": true, "requires": { "yallist": "^4.0.0" + }, + "dependencies": { + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } } }, "minizlib": { @@ -4973,13 +15725,24 @@ "requires": { "minipass": "^3.0.0", "yallist": "^4.0.0" + }, + "dependencies": { + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } } }, "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } }, "mocha": { "version": "8.4.0", @@ -5037,28 +15800,12 @@ } } }, - "diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true - }, "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, "glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", @@ -5088,43 +15835,10 @@ "argparse": "^2.0.1" } }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "strip-json-comments": { - "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==", + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, "supports-color": { @@ -5135,22 +15849,13 @@ "requires": { "has-flag": "^4.0.0" } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } } } }, "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "multimap": { @@ -5184,14 +15889,25 @@ "dev": true }, "needle": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/needle/-/needle-2.8.0.tgz", - "integrity": "sha512-ZTq6WYkN/3782H1393me3utVYdq2XyqNUFBsprEE3VMAT0+hP/cItpnITpqsY6ep2yeFE4Tqtqwc74VqUlUYtw==", + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/needle/-/needle-2.9.1.tgz", + "integrity": "sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ==", "dev": true, "requires": { "debug": "^3.2.6", "iconv-lite": "^0.4.4", "sax": "^1.2.4" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } } }, "neo-async": { @@ -5214,9 +15930,12 @@ } }, "node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.5.tgz", + "integrity": "sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==", + "requires": { + "whatwg-url": "^5.0.0" + } }, "node-gyp": { "version": "7.1.2", @@ -5236,13 +15955,18 @@ "which": "^2.0.2" }, "dependencies": { - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "dev": true, "requires": { - "lru-cache": "^6.0.0" + "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" } } } @@ -5280,6 +16004,20 @@ "minipass": "^2.6.0" } }, + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "requires": { + "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" + } + }, "minipass": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", @@ -5299,15 +16037,6 @@ "minipass": "^2.9.0" } }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, "nopt": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", @@ -5327,19 +16056,31 @@ "glob": "^7.1.3" } }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, "tar": { - "version": "4.4.15", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.15.tgz", - "integrity": "sha512-ItbufpujXkry7bHH9NpQyTXPbJ72iTlXgkBAYsAjDXk3Ds8t/3NfO5P4xZGy7u+sYuQUbimgzswX4uQIEeNVOA==", + "version": "4.4.19", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", + "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", "dev": true, "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.8.6", - "minizlib": "^1.2.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.3" + "chownr": "^1.1.4", + "fs-minipass": "^1.2.7", + "minipass": "^2.9.0", + "minizlib": "^1.3.3", + "mkdirp": "^0.5.5", + "safe-buffer": "^5.2.1", + "yallist": "^3.1.1" } }, "yallist": { @@ -5360,9 +16101,9 @@ } }, "node-releases": { - "version": "1.1.73", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz", - "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==", + "version": "1.1.77", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.77.tgz", + "integrity": "sha512-rB1DUFUNAN4Gn9keO2K1efO35IDK7yKHCdCaIMvFO7yUYmmZYeDjnGKle26G4rwj+LKRQpjyUUvMkPglwGCYNQ==", "dev": true }, "nopt": { @@ -5384,6 +16125,14 @@ "resolve": "^1.10.0", "semver": "2 || 3 || 4 || 5", "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } } }, "normalize-path": { @@ -5477,12 +16226,6 @@ "yargs": "^15.0.2" }, "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -5492,12 +16235,6 @@ "color-convert": "^2.0.1" } }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, "cliui": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", @@ -5524,12 +16261,6 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, "find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -5540,6 +16271,20 @@ "path-exists": "^4.0.0" } }, + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "requires": { + "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" + } + }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -5573,18 +16318,6 @@ "p-limit": "^2.2.0" } }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, "resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", @@ -5592,23 +16325,14 @@ "dev": true }, "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" + "strip-ansi": "^6.0.1" } }, "wrap-ansi": { @@ -5672,9 +16396,9 @@ "dev": true }, "object-inspect": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz", - "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", + "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", "dev": true }, "object-keys": { @@ -5696,37 +16420,36 @@ } }, "object.entries": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.4.tgz", - "integrity": "sha512-h4LWKWE+wKQGhtMjZEBud7uLGhqyLwj8fpHOarZhD2uY3C9cRtk57VQ89ke3moByLXMedqs3XCHzyb4AmA2DjA==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.5.tgz", + "integrity": "sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==", "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.2" + "es-abstract": "^1.19.1" } }, "object.fromentries": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.4.tgz", - "integrity": "sha512-EsFBshs5RUUpQEY1D4q/m59kMfz4YJvxuNCJcv/jWwOJr34EaVnG11ZrZa0UHB3wnzV1wx8m58T4hQL8IuNXlQ==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.5.tgz", + "integrity": "sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw==", "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2", - "has": "^1.0.3" + "es-abstract": "^1.19.1" } }, "object.values": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.4.tgz", - "integrity": "sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", + "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.2" + "es-abstract": "^1.19.1" } }, "once": { @@ -5824,21 +16547,21 @@ "dev": true }, "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "requires": { - "p-try": "^1.0.0" + "yocto-queue": "^0.1.0" } }, "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "requires": { - "p-limit": "^1.1.0" + "p-limit": "^3.0.2" } }, "p-map": { @@ -5860,9 +16583,9 @@ } }, "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, "package-hash": { @@ -5916,18 +16639,21 @@ } }, "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "requires": { - "error-ex": "^1.2.0" + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" } }, "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, "path-is-absolute": { @@ -5954,14 +16680,6 @@ "dev": true, "requires": { "isarray": "0.0.1" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - } } }, "path-type": { @@ -5976,6 +16694,12 @@ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", "dev": true }, + "picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", + "dev": true + }, "picomatch": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", @@ -5994,6 +16718,57 @@ "dev": true, "requires": { "find-up": "^2.1.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + } } }, "please-upgrade-node": { @@ -6012,25 +16787,13 @@ "dev": true }, "postcss": { - "version": "7.0.36", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", - "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", + "version": "7.0.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", "dev": true, "requires": { - "chalk": "^2.4.2", - "source-map": "^0.6.1", - "supports-color": "^6.1.0" - }, - "dependencies": { - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "picocolors": "^0.2.1", + "source-map": "^0.6.1" } }, "postcss-less": { @@ -6160,15 +16923,6 @@ "yaml-unist-parser": "1.3.1" }, "dependencies": { - "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.4" - } - }, "@babel/parser": { "version": "7.12.0", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.0.tgz", @@ -6190,12 +16944,6 @@ "tsutils": "^3.17.1" } }, - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -6205,6 +16953,12 @@ "color-convert": "^2.0.1" } }, + "camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true + }, "chalk": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", @@ -6230,14 +16984,11 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true }, "escape-string-regexp": { "version": "4.0.0", @@ -6271,6 +17022,20 @@ "integrity": "sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg==", "dev": true }, + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "requires": { + "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" + } + }, "globby": { "version": "11.0.1", "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", @@ -6317,11 +17082,14 @@ "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", "dev": true }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } }, "resolve": { "version": "1.19.0", @@ -6353,15 +17121,6 @@ "strip-ansi": "^6.0.0" } }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -6370,27 +17129,27 @@ "requires": { "has-flag": "^4.0.0" } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true } } }, "pretty-format": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.6.tgz", - "integrity": "sha512-8tGD7gBIENgzqA+UBzObyWqQ5B778VIFZA/S66cclyd5YkFLYs2Js7gxDKf0MXtTc9zcS7t1xhdfcElJ3YIvkQ==", + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.2.5.tgz", + "integrity": "sha512-+nYn2z9GgicO9JiqmY25Xtq8SYfZ/5VCpEU3pppHHNAhd1y+ZXxmNPd1evmNcAd6Hz4iBV2kf0UpGth5A/VJ7g==", "dev": true, "requires": { - "@jest/types": "^27.0.6", - "ansi-regex": "^5.0.0", + "@jest/types": "^27.2.5", + "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", "react-is": "^17.0.1" }, "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, "ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", @@ -6509,6 +17268,14 @@ "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + } } }, "react-is": { @@ -6530,44 +17297,90 @@ "dependencies": { "path-type": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", "dev": true, "requires": { - "pify": "^2.0.0" + "p-limit": "^1.1.0" } }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true } } }, - "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" - } - }, "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" } }, "readdirp": { @@ -6580,9 +17393,9 @@ } }, "regexp-tree": { - "version": "0.1.23", - "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.23.tgz", - "integrity": "sha512-+7HWfb4Bvu8Rs2eQTUIpX9I/PlQkYOuTNbRpKLJlQpSgwSkzFYh+pUj0gtvglnOZLKB6YgnIgRuJ2/IlpL48qw==", + "version": "0.1.24", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.24.tgz", + "integrity": "sha512-s2aEVuLhvnVJW6s/iPgEGK6R+/xngd2jNQ+xy4bXNDKxZKJH6jpPHY6kVeVv1IeLCHgswRj+Kl3ELaDjG6V1iw==", "dev": true }, "regexp-util": { @@ -6745,6 +17558,21 @@ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "requires": { "glob": "^7.1.3" + }, + "dependencies": { + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "requires": { + "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" + } + } } }, "run-parallel": { @@ -6783,10 +17611,30 @@ "dev": true }, "semver": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", - "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", - "dev": true + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } }, "semver-compare": { "version": "1.0.0", @@ -6851,9 +17699,9 @@ "dev": true }, "signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", + "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==", "dev": true }, "simple-concat": { @@ -6901,6 +17749,12 @@ "supports-color": "^7.1.0" }, "dependencies": { + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -6973,9 +17827,9 @@ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" }, "source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "version": "0.5.20", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", + "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -6993,17 +17847,6 @@ "rimraf": "^3.0.0", "signal-exit": "^3.0.2", "which": "^2.0.1" - }, - "dependencies": { - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } } }, "spdx-correct": { @@ -7033,9 +17876,9 @@ } }, "spdx-license-ids": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz", - "integrity": "sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz", + "integrity": "sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==", "dev": true }, "sprintf-js": { @@ -7068,9 +17911,9 @@ } }, "stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", + "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", "dev": true, "requires": { "escape-string-regexp": "^2.0.0" @@ -7090,6 +17933,21 @@ "integrity": "sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ==", "dev": true }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + } + } + }, "string-argv": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", @@ -7105,17 +17963,34 @@ "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", "strip-ansi": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } } }, "string.prototype.matchall": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.5.tgz", - "integrity": "sha512-Z5ZaXO0svs0M2xd/6By3qpeKpLKd9mO4v4q3oMEQrk8Ck4xOD5d5XeBOOjGrmVZZ/AHB1S0CgG4N5r1G9N3E2Q==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.6.tgz", + "integrity": "sha512-6WgDX8HmQqvEd7J+G6VtAahhsQIssiZ8zl7zKh1VDMFyL3hRTJP4FTNA3RbIp2TOQ9AYNDcc7e3fH0Qbup+DBg==", "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.2", + "es-abstract": "^1.19.1", "get-intrinsic": "^1.1.1", "has-symbols": "^1.0.2", "internal-slot": "^1.0.3", @@ -7143,33 +18018,25 @@ "define-properties": "^1.1.3" } }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - }, "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { - "ansi-regex": "^2.0.0" + "ansi-regex": "^5.0.1" } }, "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true }, "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "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==", "dev": true }, "supports-color": { @@ -7181,23 +18048,23 @@ } }, "table": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz", - "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==", + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/table/-/table-6.7.2.tgz", + "integrity": "sha512-UFZK67uvyNivLeQbVtkiUs8Uuuxv24aSL4/Vil2PJVtMgU8Lx0CYkP12uCGa3kjyQzOSgV1+z9Wkb82fCGsO0g==", "dev": true, "requires": { "ajv": "^8.0.1", "lodash.clonedeep": "^4.5.0", "lodash.truncate": "^4.4.2", "slice-ansi": "^4.0.0", - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0" + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" }, "dependencies": { "ajv": { - "version": "8.6.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.1.tgz", - "integrity": "sha512-42VLtQUOLefAvKFAQIxIZDaThq6om/PrfP0CYk3/vn+y4BMNkKnbli8ON2QCiHov4KkzOSJ/xSoBJdayiiYvVQ==", + "version": "8.6.3", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.3.tgz", + "integrity": "sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -7206,12 +18073,6 @@ "uri-js": "^4.2.2" } }, - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -7225,31 +18086,22 @@ "dev": true }, "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" + "strip-ansi": "^6.0.1" } } } }, "tar": { - "version": "6.1.6", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.6.tgz", - "integrity": "sha512-oaWyu5dQbHaYcyZCTfyPpC+VmI62/OM2RTUYavTk1MDr1cwW5Boi3baeYQKiZbY2uSQJGr+iMOzb/JFxLrft+g==", + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", + "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", "dev": true, "requires": { "chownr": "^2.0.0", @@ -7258,6 +18110,20 @@ "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" + }, + "dependencies": { + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } } }, "tar-fs": { @@ -7278,15 +18144,6 @@ "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", "dev": true }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, "pump": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz", @@ -7312,6 +18169,38 @@ "readable-stream": "^2.3.0", "to-buffer": "^1.1.1", "xtend": "^4.0.0" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } } }, "test-exclude": { @@ -7323,6 +18212,22 @@ "@istanbuljs/schema": "^0.1.2", "glob": "^7.1.4", "minimatch": "^3.0.4" + }, + "dependencies": { + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "requires": { + "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" + } + } } }, "text-table": { @@ -7374,6 +18279,11 @@ "punycode": "^2.1.1" } }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + }, "transform-file": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/transform-file/-/transform-file-1.0.1.tgz", @@ -7402,32 +18312,66 @@ "dev": true }, "ts-node": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.1.0.tgz", - "integrity": "sha512-6szn3+J9WyG2hE+5W8e0ruZrzyk1uFLYye6IGMBadnOzDh8aP7t8CbFpsfCiEx2+wMixAhjFt7lOZC4+l+WbEA==", + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.1.tgz", + "integrity": "sha512-hCnyOyuGmD5wHleOQX6NIjJtYVIO8bPP8F2acWkB4W06wdlkgyvJtubO/I9NkI88hCFECbsEgoLc0VNkYmcSfw==", "dev": true, "requires": { + "@cspotcode/source-map-support": "0.6.1", "@tsconfig/node10": "^1.0.7", "@tsconfig/node12": "^1.0.7", "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.1", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", "arg": "^4.1.0", "create-require": "^1.1.0", "diff": "^4.0.1", "make-error": "^1.1.1", - "source-map-support": "^0.5.17", "yn": "3.1.1" + }, + "dependencies": { + "acorn": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", + "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", + "dev": true + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + } } }, "tsconfig-paths": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.10.1.tgz", - "integrity": "sha512-rETidPDgCpltxF7MjBZlAFPUHv5aHH2MymyPvh+vEyWAED4Eb/WeMbsnD/JDr4OKPOA1TssDHgIcpTN5Kh0p6Q==", + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz", + "integrity": "sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA==", "dev": true, "requires": { - "json5": "^2.2.0", + "@types/json5": "^0.0.29", + "json5": "^1.0.1", "minimist": "^1.2.0", "strip-bom": "^3.0.0" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } } }, "tslib": { @@ -7437,9 +18381,9 @@ "dev": true }, "tslog": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/tslog/-/tslog-3.2.0.tgz", - "integrity": "sha512-xOCghepl5w+wcI4qXI7vJy6c53loF8OoC/EuKz1ktAPMtltEDz00yo1poKuyBYIQaq4ZDYKYFPD9PfqVrFXh0A==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/tslog/-/tslog-3.2.2.tgz", + "integrity": "sha512-8dwb1cYpj3/w/MZTrSkPrdlA44loUodGT8N6ULMojqV4YByVM7ynhvVs9JwcIYxhhHf4bz1C5O3NKIPehnGp/w==", "requires": { "source-map-support": "^0.5.19" } @@ -7484,9 +18428,9 @@ "dev": true }, "type-fest": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.10.0.tgz", - "integrity": "sha512-EUV9jo4sffrwlg8s0zDhP0T2WD3pru5Xi0+HTE3zTUmBaZNhfkite9PdSJwdXLwPVW0jnAHT56pZHIOYckPEiw==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true }, "typedarray-to-buffer": { @@ -7499,15 +18443,15 @@ } }, "typescript": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz", - "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.3.tgz", + "integrity": "sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA==", "dev": true }, "uglify-js": { - "version": "3.13.10", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.10.tgz", - "integrity": "sha512-57H3ACYFXeo1IaZ1w02sfA71wI60MGco/IQFjOqK+WtKoprh7Go2/yvd2HPtoJILO2Or84ncLccI4xoHMTSbGg==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.14.2.tgz", + "integrity": "sha512-rtPMlmcO4agTUfz10CbgJ1k6UAoXM2gWb3GoMPPZB/+/Ackf8lNWk11K4rYi2D0apgoFRLtQOZhb+/iGNJq26A==", "dev": true, "optional": true }, @@ -7620,10 +18564,9 @@ "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==" }, "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" }, "uri-js": { "version": "4.4.1", @@ -7725,6 +18668,20 @@ } } }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -7791,12 +18748,6 @@ "strip-ansi": "^6.0.0" }, "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -7828,23 +18779,14 @@ "dev": true }, "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" + "strip-ansi": "^6.0.1" } } } @@ -7879,9 +18821,9 @@ "dev": true }, "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", "dev": true }, "yaml": { @@ -7916,12 +18858,6 @@ "yargs-parser": "^20.2.2" }, "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -7929,23 +18865,14 @@ "dev": true }, "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" + "strip-ansi": "^6.0.1" } } } @@ -7966,6 +18893,20 @@ "decamelize": "^4.0.0", "flat": "^5.0.2", "is-plain-obj": "^2.1.0" + }, + "dependencies": { + "camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true + }, + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true + } } }, "yn": { diff --git a/package.json b/package.json index 82cb081e..d36ab2d6 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,8 @@ "api-extractor": "api-extractor run --local --verbose && npx api-documenter markdown -i ./temp -o ./docs-api", "lint": "eslint --fix --ext .ts .", "crlf": "npx crlf --set=LF docs-api/* etc/* ", - "remove-remote": "node --experimental-modules --experimental-json-modules remove_remote_repositories.mjs" + "remove-remote": "node --experimental-modules --experimental-json-modules remove_remote_repositories.mjs", + "clear": "npx rimraf node_modules" }, "repository": { "type": "git", @@ -46,7 +47,6 @@ "@microsoft/api-extractor": "^7.16.0", "@octokit/types": "^6.12.2", "@sosuisen/api-documenter": "^7.13.27", - "@types/expect": "^24.3.0", "@types/fs-extra": "^9.0.12", "@types/mocha": "^8.2.2", "@types/node": "^14.14.20", @@ -61,6 +61,7 @@ "eslint": "^7.17.0", "eslint-config-standardize": "^0.7.1", "eslint-plugin-prettierx": "^0.14.0", + "eslint-plugin-unicorn": "^36.0.0", "expect": "^27.0.2", "git-documentdb-plugin-remote-nodegit": "^1.0.4", "mocha": "^8.3.2", @@ -75,11 +76,13 @@ "@octokit/rest": "^18.3.5", "@sosuisen/jsondiffpatch": "^0.4.7", "@types/async-lock": "^1.1.2", + "@types/js-yaml": "^4.0.3", "async-lock": "^1.3.0", "cross-blob": "^2.0.0", "fs-extra": "^9.1.0", "git-documentdb-remote-errors": "^1.0.3", "isomorphic-git": "^1.8.2", + "js-yaml": "^4.1.0", "ot-json1": "^1.0.2", "rimraf": "^3.0.2", "tslog": "^3.1.2", diff --git a/src/utils.ts b/src/utils.ts index 30ce946a..8270d319 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -7,6 +7,7 @@ */ import fs from 'fs-extra'; +import yaml from 'js-yaml'; import { readBlob, ReadCommitResult, @@ -23,7 +24,7 @@ import { NormalizedCommit, TextDocMetadata, } from './types'; -import { FRONT_MATTER_POSTFIX, GIT_DOCUMENTDB_METADATA_DIR, JSON_EXTENSION, JSON_POSTFIX } from './const'; +import { FRONT_MATTER_POSTFIX, GIT_DOCUMENTDB_METADATA_DIR, JSON_EXTENSION } from './const'; /** * @internal @@ -83,8 +84,10 @@ export function toSortedJSONString (obj: Record) { } export function toFrontMatterMarkdown (obj: Record) { - const _body = typeof obj._body === 'string' ? obj._body : ''; - + const body = typeof obj._body === 'string' ? obj._body : ''; + delete obj._body; + const frontMatter = '---\n' + yaml.dump(obj) + '---\n'; + return frontMatter + body; } export function serializeJSON (obj: Record) { From 452ce8a3ace0ead83c2c6053bfaeab2d2f7daedd Mon Sep 17 00:00:00 2001 From: sosuisen Date: Mon, 11 Oct 2021 23:46:09 +0900 Subject: [PATCH 194/297] fix: lint --- .eslintrc.json | 1 + src/remote/json_patch_ot.ts | 12 +++++----- test/collection_delete.test.ts | 13 +++++++--- test/collection_insert.test.ts | 18 +++++++++++--- test/collection_put.test.ts | 29 ++++++++++++++++++---- test/collection_update.test.ts | 18 +++++++++++--- test/crud/delete.test.ts | 10 ++++---- test/crud/put.test.ts | 32 +++++++++++++++++++++---- test/git_documentdb_crud.test.ts | 8 +++++-- test/remote_base/3way_merge.ts | 40 ++++++++++++++++++++++++------- test/remote_base/3way_merge_ot.ts | 20 ++++++++++++---- test/remote_utils.ts | 6 ++++- 12 files changed, 164 insertions(+), 43 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 1af7bad3..f777576b 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -31,6 +31,7 @@ }, "rules": { + "import/no-named-as-default-member": "off", "unicorn/no-unreadable-array-destructuring": "off", "no-restricted-syntax": [ "error", diff --git a/src/remote/json_patch_ot.ts b/src/remote/json_patch_ot.ts index 763ba82a..fd22b5a8 100644 --- a/src/remote/json_patch_ot.ts +++ b/src/remote/json_patch_ot.ts @@ -110,7 +110,7 @@ export class JsonPatchOT implements IJsonPatch { } const noBar = keys.slice(0, underBarStart); const underBar = keys.slice(underBarStart, keys.length); - sortedKeys = underBar.concat(noBar); // _1, _2, _3, 1, 2, 3 + sortedKeys = [...underBar, ...noBar]; // _1, _2, _3, 1, 2, 3 } else { sortedKeys = keys.sort(); @@ -120,10 +120,10 @@ export class JsonPatchOT implements IJsonPatch { if (Array.isArray(tree[key])) { const arr = tree[key] as any[]; if (arr.length === 1) { - operations.push(insertOp(ancestors.concat(key), arr[0])!); + operations.push(insertOp([...ancestors, ...key], arr[0])!); } else if (arr.length === 2) { - operations.push(replaceOp(ancestors.concat(key), arr[0], arr[1])!); + operations.push(replaceOp([...ancestors, ...key], arr[0], arr[1])!); } else if (arr.length === 3) { const firstItem = arr[0]; @@ -134,7 +134,7 @@ export class JsonPatchOT implements IJsonPatch { if (!isTextPatch) isTextPatch = firstItem.match(/^@@ -\d+?,\d+? \+\d+? @@\n/m); if (isTextPatch) { - const textOp = this.getTextOp(ancestors.concat(key), firstItem); + const textOp = this.getTextOp([...ancestors, ...key], firstItem); if (textOp) { operations.push(textOp); } @@ -143,7 +143,7 @@ export class JsonPatchOT implements IJsonPatch { } } else if (typeof tree[key] === 'object') { - procTree(ancestors.concat(key), tree[key]); + procTree([...ancestors, ...key], tree[key]); } }); }; @@ -264,7 +264,7 @@ export class JsonPatchOT implements IJsonPatch { conflictedCommands.forEach(command => delete opElm[command]); } if (Object.keys(opElm).length > 0) { - const resolvedOp = pathFromRoot.concat(opElm); + const resolvedOp = [...pathFromRoot, ...opElm]; resolvedOperations.push(resolvedOp); } } diff --git a/test/collection_delete.test.ts b/test/collection_delete.test.ts index 60037e04..fe138e81 100644 --- a/test/collection_delete.test.ts +++ b/test/collection_delete.test.ts @@ -248,7 +248,10 @@ describe('delete(jsonDoc)', () => { // Check NormalizedCommit expect(deleteResult.commit.oid).toBe(currentCommitOid); expect(deleteResult.commit.message).toBe( - `delete: ${users.collectionPath}${_id}${JSON_EXTENSION}(${oid.substr(0, SHORT_SHA_LENGTH)})` + `delete: ${users.collectionPath}${_id}${JSON_EXTENSION}(${oid.substr( + 0, + SHORT_SHA_LENGTH + )})` ); expect(deleteResult.commit.parent).toEqual([prevCommitOid]); expect(deleteResult.commit.author.name).toEqual(gitDDB.author.name); @@ -316,7 +319,9 @@ describe('deleteFatDoc(name)', () => { const shortOid = putResult.fileOid.substr(0, SHORT_SHA_LENGTH); // Delete - const deleteResult = (await users.deleteFatDoc(_id + JSON_EXTENSION)) as DeleteResultJsonDoc; + const deleteResult = (await users.deleteFatDoc( + _id + JSON_EXTENSION + )) as DeleteResultJsonDoc; expect(deleteResult._id).toBe(_id); expect(deleteResult.fileOid).toBe(putResult.fileOid); expect(deleteResult.commit.message).toBe( @@ -365,7 +370,9 @@ describe('deleteFatDoc(name)', () => { const shortOid = putResult.fileOid.substr(0, SHORT_SHA_LENGTH); // Delete - const deleteResult = (await users.deleteFatDoc(_id + JSON_EXTENSION)) as DeleteResultJsonDoc; + const deleteResult = (await users.deleteFatDoc( + _id + JSON_EXTENSION + )) as DeleteResultJsonDoc; expect(deleteResult._id).toBe(_id); expect(deleteResult.fileOid).toBe(putResult.fileOid); expect(deleteResult.commit.message).toBe( diff --git a/test/collection_insert.test.ts b/test/collection_insert.test.ts index 168cb586..345c1c3f 100644 --- a/test/collection_insert.test.ts +++ b/test/collection_insert.test.ts @@ -101,7 +101,11 @@ describe(' insert(jsonDoc)', () => { expect(putResult.commit.committer.timestamp).toBeLessThanOrEqual(afterTimestamp); // fs.access() throw error when a file cannot be accessed. - const filePath = path.resolve(gitDDB.workingDir, col.collectionPath, _id + JSON_EXTENSION); + const filePath = path.resolve( + gitDDB.workingDir, + col.collectionPath, + _id + JSON_EXTENSION + ); await expect(fs.access(filePath)).resolves.not.toThrowError(); expect(fs.readFileSync(filePath, 'utf8')).toBe(toSortedJSONString(internalJson)); @@ -218,7 +222,11 @@ describe(' insert(shortId, jsonDoc)', () => { expect(putResult.commit.committer.timestamp).toBeLessThanOrEqual(afterTimestamp); // fs.access() throw error when a file cannot be accessed. - const filePath = path.resolve(gitDDB.workingDir, col.collectionPath, _id + JSON_EXTENSION); + const filePath = path.resolve( + gitDDB.workingDir, + col.collectionPath, + _id + JSON_EXTENSION + ); await expect(fs.access(filePath)).resolves.not.toThrowError(); expect(fs.readFileSync(filePath, 'utf8')).toBe(toSortedJSONString(internalJson)); @@ -300,7 +308,11 @@ describe(' insertFatDoc(shortName, jsonDoc)', () => { expect(putResult.commit.committer.timestamp).toBeLessThanOrEqual(afterTimestamp); // fs.access() throw error when a file cannot be accessed. - const filePath = path.resolve(gitDDB.workingDir, col.collectionPath, _id + JSON_EXTENSION); + const filePath = path.resolve( + gitDDB.workingDir, + col.collectionPath, + _id + JSON_EXTENSION + ); await expect(fs.access(filePath)).resolves.not.toThrowError(); expect(fs.readFileSync(filePath, 'utf8')).toBe(toSortedJSONString(internalJson)); diff --git a/test/collection_put.test.ts b/test/collection_put.test.ts index 11d52ac5..998c6cab 100644 --- a/test/collection_put.test.ts +++ b/test/collection_put.test.ts @@ -252,7 +252,11 @@ describe('', () => { // Check filename // fs.access() throw error when a file cannot be accessed. - const filePath = path.resolve(gitDDB.workingDir, col.collectionPath, _id + JSON_EXTENSION); + const filePath = path.resolve( + gitDDB.workingDir, + col.collectionPath, + _id + JSON_EXTENSION + ); await expect(fs.access(filePath)).resolves.not.toThrowError(); // Read JSON and check doc._id expect(fs.readJSONSync(filePath)._id).toBe(col.collectionPath + _id); @@ -312,7 +316,11 @@ describe('', () => { expect(putResult.commit.committer.timestamp).toBeLessThanOrEqual(afterTimestamp); // fs.access() throw error when a file cannot be accessed. - const filePath = path.resolve(gitDDB.workingDir, col.collectionPath, _id + JSON_EXTENSION); + const filePath = path.resolve( + gitDDB.workingDir, + col.collectionPath, + _id + JSON_EXTENSION + ); await expect(fs.access(filePath)).resolves.not.toThrowError(); expect(fs.readFileSync(filePath, 'utf8')).toBe(toSortedJSONString(internalJson)); @@ -638,7 +646,11 @@ describe('', () => { expect(putResult.commit.committer.timestamp).toBeLessThanOrEqual(afterTimestamp); // fs.access() throw error when a file cannot be accessed. - const filePath = path.resolve(gitDDB.workingDir, col.collectionPath, _id + JSON_EXTENSION); + const filePath = path.resolve( + gitDDB.workingDir, + col.collectionPath, + _id + JSON_EXTENSION + ); await expect(fs.access(filePath)).resolves.not.toThrowError(); expect(fs.readFileSync(filePath, 'utf8')).toBe(toSortedJSONString(internalJson)); @@ -728,7 +740,10 @@ describe('', () => { 'A': 'A', }); - const filePath = path.resolve(gitDDB.workingDir, col.collectionPath + 'id' + JSON_EXTENSION); + const filePath = path.resolve( + gitDDB.workingDir, + col.collectionPath + 'id' + JSON_EXTENSION + ); const jsonStr = fs.readFileSync(filePath, 'utf8'); expect(jsonStr).toBe(`{ "1": 1, @@ -847,7 +862,11 @@ describe('', () => { expect(putResult.commit.committer.timestamp).toBeLessThanOrEqual(afterTimestamp); // fs.access() throw error when a file cannot be accessed. - const filePath = path.resolve(gitDDB.workingDir, col.collectionPath, _id + JSON_EXTENSION); + const filePath = path.resolve( + gitDDB.workingDir, + col.collectionPath, + _id + JSON_EXTENSION + ); await expect(fs.access(filePath)).resolves.not.toThrowError(); expect(fs.readFileSync(filePath, 'utf8')).toBe(toSortedJSONString(internalJson)); diff --git a/test/collection_update.test.ts b/test/collection_update.test.ts index 7f887ddd..cbd41e54 100644 --- a/test/collection_update.test.ts +++ b/test/collection_update.test.ts @@ -99,7 +99,11 @@ describe(' update(jsonDoc)', () => { expect(putResult.commit.committer.timestamp).toBeLessThanOrEqual(afterTimestamp); // fs.access() throw error when a file cannot be accessed. - const filePath = path.resolve(gitDDB.workingDir, col.collectionPath, _id + JSON_EXTENSION); + const filePath = path.resolve( + gitDDB.workingDir, + col.collectionPath, + _id + JSON_EXTENSION + ); await expect(fs.access(filePath)).resolves.not.toThrowError(); expect(fs.readFileSync(filePath, 'utf8')).toBe(toSortedJSONString(internalJson)); @@ -218,7 +222,11 @@ describe(' update(shortId, jsonDoc)', () => { expect(putResult.commit.committer.timestamp).toBeLessThanOrEqual(afterTimestamp); // fs.access() throw error when a file cannot be accessed. - const filePath = path.resolve(gitDDB.workingDir, col.collectionPath, _id + JSON_EXTENSION); + const filePath = path.resolve( + gitDDB.workingDir, + col.collectionPath, + _id + JSON_EXTENSION + ); await expect(fs.access(filePath)).resolves.not.toThrowError(); expect(fs.readFileSync(filePath, 'utf8')).toBe(toSortedJSONString(internalJson)); @@ -300,7 +308,11 @@ describe(' updateFatDoc(shortName, jsonDoc)', () => { expect(putResult.commit.committer.timestamp).toBeLessThanOrEqual(afterTimestamp); // fs.access() throw error when a file cannot be accessed. - const filePath = path.resolve(gitDDB.workingDir, col.collectionPath, _id + JSON_EXTENSION); + const filePath = path.resolve( + gitDDB.workingDir, + col.collectionPath, + _id + JSON_EXTENSION + ); await expect(fs.access(filePath)).resolves.not.toThrowError(); expect(fs.readFileSync(filePath, 'utf8')).toBe(toSortedJSONString(internalJson)); diff --git a/test/crud/delete.test.ts b/test/crud/delete.test.ts index ea036761..28e40d13 100644 --- a/test/crud/delete.test.ts +++ b/test/crud/delete.test.ts @@ -223,7 +223,9 @@ describe('', () => { const shortOid = putResult.fileOid.substr(0, SHORT_SHA_LENGTH); expect(deleteResult.fileOid).toBe(putResult.fileOid); - expect(deleteResult.commit.message).toBe(`delete: ${_id}${JSON_EXTENSION}(${shortOid})`); + expect(deleteResult.commit.message).toBe( + `delete: ${_id}${JSON_EXTENSION}(${shortOid})` + ); // Check commit directly const commitOid = await git.resolveRef({ fs, dir: gitDDB.workingDir, ref: 'HEAD' }); @@ -384,9 +386,9 @@ describe('', () => { const stubEnsureDir = sandbox.stub(fs_module, 'remove'); stubEnsureDir.rejects(); - await expect(deleteWorker(gitDDB, '', 'prof01' + JSON_EXTENSION, '')).rejects.toThrowError( - Err.CannotDeleteDataError - ); + await expect( + deleteWorker(gitDDB, '', 'prof01' + JSON_EXTENSION, '') + ).rejects.toThrowError(Err.CannotDeleteDataError); await gitDDB.destroy(); }); }); diff --git a/test/crud/put.test.ts b/test/crud/put.test.ts index 713e7391..d433c0b4 100644 --- a/test/crud/put.test.ts +++ b/test/crud/put.test.ts @@ -64,7 +64,13 @@ describe(' put', () => { gitDDB.close().catch(() => {}); const _id = 'prof01'; await expect( - putImpl(gitDDB, '', _id, _id + JSON_EXTENSION, toSortedJSONString({ _id, name: 'shirase' })) + putImpl( + gitDDB, + '', + _id, + _id + JSON_EXTENSION, + toSortedJSONString({ _id, name: 'shirase' }) + ) ).rejects.toThrowError(Err.DatabaseClosingError); // wait close @@ -432,7 +438,13 @@ describe(' put', () => { ); } // The last put() with await keyword is resolved after all preceding (queued) Promises - await putImpl(gitDDB, '', '99', '99' + JSON_EXTENSION, toSortedJSONString({ _id: '99' })); + await putImpl( + gitDDB, + '', + '99', + '99' + JSON_EXTENSION, + toSortedJSONString({ _id: '99' }) + ); const fatDocs = await gitDDB.find(); expect(fatDocs.length).toBe(100); @@ -667,8 +679,20 @@ describe(' putWorker', () => { await Promise.all([ putWorker(gitDDB, '', _id_a + JSON_EXTENSION, toSortedJSONString(json_a), 'message'), putWorker(gitDDB, '', _id_b + JSON_EXTENSION, toSortedJSONString(json_b), 'message'), - putWorker(gitDDB, '', _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01), 'message'), - putWorker(gitDDB, '', _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02), 'message'), + putWorker( + gitDDB, + '', + _id_c01 + JSON_EXTENSION, + toSortedJSONString(json_c01), + 'message' + ), + putWorker( + gitDDB, + '', + _id_c02 + JSON_EXTENSION, + toSortedJSONString(json_c02), + 'message' + ), putWorker(gitDDB, '', _id_d + JSON_EXTENSION, toSortedJSONString(json_d), 'message'), putWorker(gitDDB, '', _id_p + JSON_EXTENSION, toSortedJSONString(json_p), 'message'), ]); diff --git a/test/git_documentdb_crud.test.ts b/test/git_documentdb_crud.test.ts index 30c5d583..6ea9d284 100644 --- a/test/git_documentdb_crud.test.ts +++ b/test/git_documentdb_crud.test.ts @@ -1377,7 +1377,9 @@ describe(' delete(_id)', () => { const deleteResult = await gitDDB.delete(_id); expect(deleteResult._id).toBe(_id); expect(deleteResult.fileOid).toBe(putResult.fileOid); - expect(deleteResult.commit.message).toBe(`delete: ${_id}${JSON_EXTENSION}(${shortOid})`); + expect(deleteResult.commit.message).toBe( + `delete: ${_id}${JSON_EXTENSION}(${shortOid})` + ); // Check commit directly const commitOid = await git.resolveRef({ fs, dir: gitDDB.workingDir, ref: 'HEAD' }); @@ -1504,7 +1506,9 @@ describe(' deleteFatDoc(name)', () => { const deleteResult = (await gitDDB.deleteFatDoc(name)) as DeleteResultJsonDoc; expect(deleteResult._id).toBe(_id); expect(deleteResult.fileOid).toBe(putResult.fileOid); - expect(deleteResult.commit.message).toBe(`delete: ${_id}${JSON_EXTENSION}(${shortOid})`); + expect(deleteResult.commit.message).toBe( + `delete: ${_id}${JSON_EXTENSION}(${shortOid})` + ); // Check commit directly const commitOid = await git.resolveRef({ fs, dir: gitDDB.workingDir, ref: 'HEAD' }); diff --git a/test/remote_base/3way_merge.ts b/test/remote_base/3way_merge.ts index a5adb89a..b76b4fac 100644 --- a/test/remote_base/3way_merge.ts +++ b/test/remote_base/3way_merge.ts @@ -632,11 +632,17 @@ export const syncThreeWayMergeBase = ( expect(syncResult1.commits).toMatchObject({ local: getCommitInfo([ putResultA1dash, - `resolve: 1${JSON_EXTENSION}(update,${putResultA1dash.fileOid.substr(0, 7)},theirs)`, + `resolve: 1${JSON_EXTENSION}(update,${putResultA1dash.fileOid.substr( + 0, + 7 + )},theirs)`, ]), remote: getCommitInfo([ deleteResultB1, - `resolve: 1${JSON_EXTENSION}(update,${putResultA1dash.fileOid.substr(0, 7)},theirs)`, + `resolve: 1${JSON_EXTENSION}(update,${putResultA1dash.fileOid.substr( + 0, + 7 + )},theirs)`, ]), }); @@ -900,11 +906,17 @@ export const syncThreeWayMergeBase = ( local: getCommitInfo([ deleteResultA1, putResultA2, - `resolve: 1${JSON_EXTENSION}(delete,${deleteResultA1.fileOid.substr(0, 7)},theirs)`, + `resolve: 1${JSON_EXTENSION}(delete,${deleteResultA1.fileOid.substr( + 0, + 7 + )},theirs)`, ]), remote: getCommitInfo([ putResultB1, - `resolve: 1${JSON_EXTENSION}(delete,${deleteResultA1.fileOid.substr(0, 7)},theirs)`, + `resolve: 1${JSON_EXTENSION}(delete,${deleteResultA1.fileOid.substr( + 0, + 7 + )},theirs)`, ]), }); expect(syncResult1.changes.local.length).toBe(2); @@ -1353,11 +1365,17 @@ export const syncThreeWayMergeBase = ( expect(syncResult1.commits).toMatchObject({ local: getCommitInfo([ putResultA1dash, - `resolve: 1${JSON_EXTENSION}(update,${putResultA1dash.fileOid.substr(0, 7)},theirs)`, + `resolve: 1${JSON_EXTENSION}(update,${putResultA1dash.fileOid.substr( + 0, + 7 + )},theirs)`, ]), remote: getCommitInfo([ putResultB1, - `resolve: 1${JSON_EXTENSION}(update,${putResultA1dash.fileOid.substr(0, 7)},theirs)`, + `resolve: 1${JSON_EXTENSION}(update,${putResultA1dash.fileOid.substr( + 0, + 7 + )},theirs)`, ]), }); expect(syncResult1.changes.local.length).toBe(1); @@ -1691,11 +1709,17 @@ export const syncThreeWayMergeBase = ( expect(syncResult1.commits).toMatchObject({ local: getCommitInfo([ putResultA1dash, - `resolve: 1${JSON_EXTENSION}(update,${putResultA1dash.fileOid.substr(0, 7)},theirs)`, + `resolve: 1${JSON_EXTENSION}(update,${putResultA1dash.fileOid.substr( + 0, + 7 + )},theirs)`, ]), remote: getCommitInfo([ putResultB1, - `resolve: 1${JSON_EXTENSION}(update,${putResultA1dash.fileOid.substr(0, 7)},theirs)`, + `resolve: 1${JSON_EXTENSION}(update,${putResultA1dash.fileOid.substr( + 0, + 7 + )},theirs)`, ]), }); expect(syncResult1.changes.local.length).toBe(1); diff --git a/test/remote_base/3way_merge_ot.ts b/test/remote_base/3way_merge_ot.ts index 1e09b06b..47d7c9ff 100644 --- a/test/remote_base/3way_merge_ot.ts +++ b/test/remote_base/3way_merge_ot.ts @@ -286,11 +286,17 @@ export const threeWayMergeOtBase = ( expect(syncResult1.commits).toMatchObject({ local: getCommitInfo([ putResultA1dash, - `resolve: 1${JSON_EXTENSION}(delete,${deleteResultB1.fileOid.substr(0, 7)},ours-diff)`, + `resolve: 1${JSON_EXTENSION}(delete,${deleteResultB1.fileOid.substr( + 0, + 7 + )},ours-diff)`, ]), remote: getCommitInfo([ deleteResultB1, - `resolve: 1${JSON_EXTENSION}(delete,${deleteResultB1.fileOid.substr(0, 7)},ours-diff)`, + `resolve: 1${JSON_EXTENSION}(delete,${deleteResultB1.fileOid.substr( + 0, + 7 + )},ours-diff)`, ]), }); expect(syncResult1.changes.local.length).toBe(0); @@ -373,11 +379,17 @@ export const threeWayMergeOtBase = ( local: getCommitInfo([ deleteResultA1, putResultA2, - `resolve: 1${JSON_EXTENSION}(update,${putResultB1.fileOid.substr(0, 7)},ours-diff)`, + `resolve: 1${JSON_EXTENSION}(update,${putResultB1.fileOid.substr( + 0, + 7 + )},ours-diff)`, ]), remote: getCommitInfo([ putResultB1, - `resolve: 1${JSON_EXTENSION}(update,${putResultB1.fileOid.substr(0, 7)},ours-diff)`, + `resolve: 1${JSON_EXTENSION}(update,${putResultB1.fileOid.substr( + 0, + 7 + )},ours-diff)`, ]), }); expect(syncResult1.changes.local.length).toBe(1); diff --git a/test/remote_utils.ts b/test/remote_utils.ts index d71a6d36..bf6520ce 100644 --- a/test/remote_utils.ts +++ b/test/remote_utils.ts @@ -16,7 +16,11 @@ import { } from '../src/types'; import { SyncInterface } from '../src/types_sync'; import { GitDocumentDB } from '../src/git_documentdb'; -import { FILE_REMOVE_TIMEOUT, GIT_DOCUMENTDB_METADATA_DIR, JSON_EXTENSION } from '../src/const'; +import { + FILE_REMOVE_TIMEOUT, + GIT_DOCUMENTDB_METADATA_DIR, + JSON_EXTENSION, +} from '../src/const'; import { RemoteRepository } from '../src/remote/remote_repository'; const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; From b358b5ed2e466233e73c056833ef8e019e11e009 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 12 Oct 2021 02:25:55 +0900 Subject: [PATCH 195/297] fix: align functions and tests with toFrontMatterMarkdown() --- src/collection.ts | 134 +++++---- src/const.ts | 11 - src/crud/blob.ts | 6 +- src/crud/delete.ts | 4 +- src/crud/find.ts | 16 +- src/crud/get.ts | 8 +- src/crud/history.ts | 10 +- src/crud/put.ts | 4 +- src/error.ts | 4 +- src/git_documentdb.ts | 74 ++--- src/remote/3way_merge.ts | 137 +++++++-- src/remote/combine.ts | 27 +- src/remote/json_patch_ot.ts | 23 +- src/remote/push_worker.ts | 7 +- src/remote/sync_worker.ts | 3 +- src/remote/worker_utils.ts | 50 ++-- src/types.ts | 6 +- src/types_gitddb.ts | 1 + src/utils.ts | 17 +- test/collection_delete.test.ts | 24 +- test/collection_find.test.ts | 136 ++++----- test/collection_get.test.ts | 36 +-- test/collection_insert.test.ts | 18 +- test/collection_put.test.ts | 40 +-- test/collection_update.test.ts | 18 +- test/crud/blob.test.ts | 16 +- test/crud/delete.test.ts | 36 +-- test/crud/find.test.ts | 420 +++++++++++++--------------- test/crud/get.test.ts | 118 +++++--- test/crud/history.test.ts | 51 ++-- test/crud/put.test.ts | 231 +++++++++++---- test/git_documentdb_crud.test.ts | 204 +++++++------- test/remote_base/3way_merge.ts | 88 +++--- test/remote_base/3way_merge_ot.ts | 28 +- test/remote_base/combine.ts | 20 +- test/remote_base/network_history.ts | 14 +- test/remote_base/sync_trysync.ts | 4 +- test/remote_utils.ts | 20 +- 38 files changed, 1160 insertions(+), 904 deletions(-) diff --git a/src/collection.ts b/src/collection.ts index 842698e7..78cd0aad 100644 --- a/src/collection.ts +++ b/src/collection.ts @@ -36,8 +36,8 @@ import { } from './types'; import { GitDDBInterface } from './types_gitddb'; import { Validator } from './validator'; -import { toSortedJSONString } from './utils'; -import { GIT_DOCUMENTDB_METADATA_DIR, JSON_EXTENSION } from './const'; +import { serializeJSON } from './utils'; +import { GIT_DOCUMENTDB_METADATA_DIR } from './const'; import { getImpl } from './crud/get'; import { getHistoryImpl } from './crud/history'; import { deleteImpl } from './crud/delete'; @@ -52,7 +52,7 @@ import { ICollection } from './types_collection'; * @remarks * In a collection API, shortId (shortName) is used instead of _id (name). * - * - shortId is a file path whose collectionPath and JSON_EXTENSION extension are omitted. (_id = collectionPath + shortId) + * - shortId is a file path whose collectionPath and jsonExt extension are omitted. (_id = collectionPath + shortId) * * - shortName is a file path whose collectionPath is omitted. (name = collectionPath + shortName) * @@ -229,10 +229,10 @@ export class Collection implements ICollection { /** * Insert a JSON document if not exists. Otherwise, update it. * - * @param jsonDoc - JsonDoc whose _id is shortId. shortId is a file path whose collectionPath and ${JSON_EXTENSION} extension are omitted. + * @param jsonDoc - JsonDoc whose _id is shortId. shortId is a file path whose collectionPath and ${jsonExt} extension are omitted. * * @remarks - * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}${jsonDoc._id}${JSON_EXTENSION}`. + * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}${jsonDoc._id}${jsonExt}`. * * - If _id is undefined, it is automatically generated. * @@ -258,10 +258,10 @@ export class Collection implements ICollection { /** * Insert a JSON document if not exists. Otherwise, update it. * - * @param shortId - shortId is a file path whose collectionPath and ${JSON_EXTENSION} extension are omitted. + * @param shortId - shortId is a file path whose collectionPath and ${jsonExt} extension are omitted. * * @remarks - * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortId}${JSON_EXTENSION}`. + * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortId}${jsonExt}`. * * - If shortId is undefined, it is automatically generated. * @@ -323,14 +323,14 @@ export class Collection implements ICollection { if (!shortIdOrDoc) shortIdOrDoc = this.generateId(); shortId = shortIdOrDoc; _id = this.collectionPath + shortId; - shortName = shortId + JSON_EXTENSION; + shortName = shortId + this._gitDDB.jsonExt; jsonDoc = jsonDocOrOptions as JsonDoc; } else { if (!shortIdOrDoc._id) shortIdOrDoc._id = this.generateId(); shortId = shortIdOrDoc._id; _id = this.collectionPath + shortId; - shortName = shortId + JSON_EXTENSION; + shortName = shortId + this._gitDDB.jsonExt; jsonDoc = shortIdOrDoc as JsonDoc; options = jsonDocOrOptions as PutOptions; } @@ -343,7 +343,7 @@ export class Collection implements ICollection { return Promise.reject(new Err.InvalidJsonObjectError(shortId)); } clone._id = _id; - const data = toSortedJSONString(clone); + const data = serializeJSON(clone, this._gitDDB.jsonExt); try { this._gitDDB.validator.validateId(shortId); this._gitDDB.validator.validateDocument(clone); @@ -377,14 +377,14 @@ export class Collection implements ICollection { /** * Insert a JSON document * - * @param jsonDoc - JsonDoc whose _id is shortId. shortId is a file path whose collectionPath and ${JSON_EXTENSION} extension are omitted. + * @param jsonDoc - JsonDoc whose _id is shortId. shortId is a file path whose collectionPath and ${jsonExt} extension are omitted. * * @remarks * - Throws SameIdExistsError when a document that has the same _id exists. It might be better to use put() instead of insert(). * * - If _id is undefined, it is automatically generated. * - * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${jsonDoc._id}${JSON_EXTENSION}`. + * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${jsonDoc._id}${jsonExt}`. * * @param jsonDoc - See {@link JsonDoc} for restriction. * @@ -414,12 +414,12 @@ export class Collection implements ICollection { /** * Insert a JSON document * - * @param shortId - shortId is a file path whose collectionPath and ${JSON_EXTENSION} extension are omitted. + * @param shortId - shortId is a file path whose collectionPath and ${jsonExt} extension are omitted. * * @remarks * - Throws SameIdExistsError when a document that has the same _id exists. It might be better to use put() instead of insert(). * - * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortId}${JSON_EXTENSION}`. + * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortId}${jsonExt}`. * * - If shortId is undefined, it is automatically generated. * @@ -490,12 +490,12 @@ export class Collection implements ICollection { /** * Update a JSON document * - * @param jsonDoc - JsonDoc whose _id is shortId. shortId is a file path whose collectionPath and ${JSON_EXTENSION} extension are omitted. + * @param jsonDoc - JsonDoc whose _id is shortId. shortId is a file path whose collectionPath and ${jsonExt} extension are omitted. * * @remarks * - Throws DocumentNotFoundError if a specified document does not exist. It might be better to use put() instead of update(). * - * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${jsonDoc._id}${JSON_EXTENSION}`. + * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${jsonDoc._id}${jsonExt}`. * * - If _id is undefined, it is automatically generated. * @@ -525,12 +525,12 @@ export class Collection implements ICollection { /** * Update a JSON document * - * @param shortId - shortId is a file path whose collectionPath and ${JSON_EXTENSION} extension are omitted. + * @param shortId - shortId is a file path whose collectionPath and ${jsonExt} extension are omitted. * * @remarks * - Throws DocumentNotFoundError if a specified data does not exist. It might be better to use put() instead of update(). * - * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortId}${JSON_EXTENSION}`. + * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortId}${jsonExt}`. * * - An update operation is not skipped even if no change occurred on a specified data. * @@ -599,14 +599,14 @@ export class Collection implements ICollection { /** * Insert data if not exists. Otherwise, update it. * - * @param shortName - shortName is a file path whose collectionPath is omitted. shortName of JsonDoc must ends with ${JSON_EXTENSION} extension. + * @param shortName - shortName is a file path whose collectionPath is omitted. shortName of JsonDoc must ends with ${jsonExt} extension. * * @remarks - * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortName}${JSON_EXTENSION}`. + * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortName}${jsonExt}`. * * - If shortName is undefined, it is automatically generated. * - * - _id property of a JsonDoc is automatically set or overwritten by shortName parameter whose ${JSON_EXTENSION} extension is omitted. + * - _id property of a JsonDoc is automatically set or overwritten by shortName parameter whose ${jsonExt} extension is omitted. * * - An update operation is not skipped even if no change occurred on a specified data. * @@ -650,13 +650,13 @@ export class Collection implements ICollection { data = doc; } else if (typeof doc === 'object') { - if (!shortName) shortName = this.generateId() + JSON_EXTENSION; + if (!shortName) shortName = this.generateId() + this._gitDDB.jsonExt; docType = 'json'; // JsonDoc - if (!shortName.endsWith(JSON_EXTENSION)) { + if (!shortName.endsWith(this._gitDDB.jsonExt)) { return Promise.reject(new Err.InvalidJsonFileExtensionError()); } - shortId = shortName.replace(new RegExp(JSON_EXTENSION + '$'), ''); + shortId = shortName.replace(new RegExp(this._gitDDB.jsonExt + '$'), ''); // Validate JSON let clone; @@ -666,7 +666,7 @@ export class Collection implements ICollection { return Promise.reject(new Err.InvalidJsonObjectError(shortId)); } clone._id = this.collectionPath + shortId; - data = toSortedJSONString(clone); + data = serializeJSON(clone, this._gitDDB.jsonExt); try { this._gitDDB.validator.validateDocument(clone); } catch (err) { @@ -725,16 +725,16 @@ export class Collection implements ICollection { /** * Insert a data * - * @param shortName - shortName is a file path whose collectionPath is omitted. shortName of JsonDoc must ends with ${JSON_EXTENSION} extension. + * @param shortName - shortName is a file path whose collectionPath is omitted. shortName of JsonDoc must ends with ${jsonExt} extension. * * @remarks * - Throws SameIdExistsError when data that has the same _id exists. It might be better to use put() instead of insert(). * - * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortName}${JSON_EXTENSION}`. + * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortName}${jsonExt}`. * * - If shortName is undefined, it is automatically generated. * - * - _id property of a JsonDoc is automatically set or overwritten by shortName parameter whose ${JSON_EXTENSION} extension is omitted. + * - _id property of a JsonDoc is automatically set or overwritten by shortName parameter whose ${jsonExt} extension is omitted. * * @throws {@link Err.InvalidJsonObjectError} * @@ -773,14 +773,14 @@ export class Collection implements ICollection { /** * Update a data * - * @param shortName - shortName is a file path whose collectionPath is omitted. shortName of JsonDoc must ends with ${JSON_EXTENSION} extension. + * @param shortName - shortName is a file path whose collectionPath is omitted. shortName of JsonDoc must ends with ${jsonExt} extension. * * @remarks * - Throws DocumentNotFoundError if a specified data does not exist. It might be better to use put() instead of update(). * - * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortName}${JSON_EXTENSION}`. + * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortName}${jsonExt}`. * - * - _id property of a JsonDoc is automatically set or overwritten by shortName parameter whose ${JSON_EXTENSION} extension is omitted. + * - _id property of a JsonDoc is automatically set or overwritten by shortName parameter whose ${jsonExt} extension is omitted. * * - An update operation is not skipped even if no change occurred on a specified data. * @@ -821,7 +821,7 @@ export class Collection implements ICollection { /** * Get a JSON document * - * @param shortId - shortId is a file path whose collectionPath and ${JSON_EXTENSION} extension are omitted. + * @param shortId - shortId is a file path whose collectionPath and ${jsonExt} extension are omitted. * * @returns * - undefined if a specified document does not exist. @@ -834,8 +834,8 @@ export class Collection implements ICollection { * @public */ get (_id: string): Promise { - const shortName = _id + JSON_EXTENSION; - return getImpl(this._gitDDB, shortName, this.collectionPath, { + const shortName = _id + this._gitDDB.jsonExt; + return getImpl(this._gitDDB, shortName, this.collectionPath, this._gitDDB.jsonExt, { forceDocType: 'json', }) as Promise; } @@ -848,7 +848,7 @@ export class Collection implements ICollection { * @returns * - undefined if a specified data does not exist. * - * - FatJsonDoc if the file extension is JSON_EXTENSION. Be careful that JsonDoc may not have _id property when an app other than GitDocumentDB creates it. + * - FatJsonDoc if the file extension is jsonExt. Be careful that JsonDoc may not have _id property when an app other than GitDocumentDB creates it. * * - FatBinaryDoc if described in .gitattribtues, otherwise FatTextDoc. * @@ -860,9 +860,16 @@ export class Collection implements ICollection { * @public */ getFatDoc (shortName: string, getOptions?: GetOptions): Promise { - return getImpl(this._gitDDB, shortName, this.collectionPath, getOptions, { - withMetadata: true, - }) as Promise; + return getImpl( + this._gitDDB, + shortName, + this.collectionPath, + this._gitDDB.jsonExt, + getOptions, + { + withMetadata: true, + } + ) as Promise; } /** @@ -883,6 +890,7 @@ export class Collection implements ICollection { this._gitDDB, '', this.collectionPath, + this._gitDDB.jsonExt, { forceDocType: docType }, { withMetadata: false, @@ -894,7 +902,7 @@ export class Collection implements ICollection { /** * Get an old revision of a JSON document * - * @param shortId - shortId is a file path whose collectionPath and ${JSON_EXTENSION} extension are omitted. + * @param shortId - shortId is a file path whose collectionPath and ${jsonExt} extension are omitted. * @param revision - Specify a number to go back to old revision. Default is 0. * See {@link git-documentdb#Collection.getHistory} for the array of revisions. * @param historyOptions - The array of revisions is filtered by HistoryOptions.filter. @@ -918,11 +926,12 @@ export class Collection implements ICollection { revision: number, historyOptions?: HistoryOptions ): Promise { - const shortName = shortId + JSON_EXTENSION; + const shortName = shortId + this._gitDDB.jsonExt; return getImpl( this._gitDDB, shortName, this.collectionPath, + this._gitDDB.jsonExt, { forceDocType: 'json' }, { withMetadata: false, @@ -943,7 +952,7 @@ export class Collection implements ICollection { * @remarks * - undefined if a specified data does not exist or it is deleted. * - * - JsonDoc if the file extension is JSON_EXTENSION. Be careful that JsonDoc may not have _id property when an app other than GitDocumentDB creates it. + * - JsonDoc if the file extension is jsonExt. Be careful that JsonDoc may not have _id property when an app other than GitDocumentDB creates it. * * - FatBinaryDoc if described in .gitattribtues, otherwise FatTextDoc. * @@ -970,6 +979,7 @@ export class Collection implements ICollection { this._gitDDB, shortName, this.collectionPath, + this._gitDDB.jsonExt, getOptions, { withMetadata: true, @@ -985,7 +995,7 @@ export class Collection implements ICollection { * @remarks * - By default, revisions are sorted by reverse chronological order. However, keep in mind that Git dates may not be consistent across repositories. * - * @param shortId - shortId is a file path whose collectionPath and ${JSON_EXTENSION} extension is omitted. + * @param shortId - shortId is a file path whose collectionPath and ${jsonExt} extension is omitted. * @param historyOptions - The array of revisions is filtered by HistoryOptions.filter. * * @returns Array of JsonDoc or undefined. @@ -1029,11 +1039,12 @@ export class Collection implements ICollection { _id: string, historyOptions?: HistoryOptions ): Promise<(JsonDoc | undefined)[]> { - const shortName = _id + JSON_EXTENSION; + const shortName = _id + this._gitDDB.jsonExt; return getHistoryImpl( this._gitDDB, shortName, this.collectionPath, + this._gitDDB.jsonExt, historyOptions, { forceDocType: 'json' }, false @@ -1051,7 +1062,7 @@ export class Collection implements ICollection { * @returns Array of FatDoc or undefined. * - undefined if a specified data does not exist or it is deleted. * - * - Array of FatJsonDoc if isJsonDocCollection is true or the file extension is JSON_EXTENSION. Be careful that JsonDoc may not have _id property when an app other than GitDocumentDB creates it. + * - Array of FatJsonDoc if isJsonDocCollection is true or the file extension is jsonExt. Be careful that JsonDoc may not have _id property when an app other than GitDocumentDB creates it. * * - Array of FatBinaryDoc if described in .gitattribtues, otherwise array of FatTextDoc. * @@ -1071,6 +1082,7 @@ export class Collection implements ICollection { this._gitDDB, shortName, this.collectionPath, + this._gitDDB.jsonExt, historyOptions, getOptions, true @@ -1080,7 +1092,7 @@ export class Collection implements ICollection { /** * Delete a JSON document * - * @param shortId - shortId is a file path whose collectionPath and ${JSON_EXTENSION} extension is omitted. + * @param shortId - shortId is a file path whose collectionPath and ${jsonExt} extension is omitted. * * @throws {@link Err.UndefinedDocumentIdError} * @@ -1100,7 +1112,7 @@ export class Collection implements ICollection { /** * Delete a document by _id property in JsonDoc * - * @param jsonDoc - JsonDoc whose _id is shortId. Only the _id property is referenced. shortId is a file path whose collectionPath and ${JSON_EXTENSION} extension are omitted. + * @param jsonDoc - JsonDoc whose _id is shortId. Only the _id property is referenced. shortId is a file path whose collectionPath and ${jsonExt} extension are omitted. * * @throws {@link Err.UndefinedDocumentIdError} * @@ -1139,7 +1151,7 @@ export class Collection implements ICollection { else { return Promise.reject(new Err.UndefinedDocumentIdError()); } - const shortName = shortId + JSON_EXTENSION; + const shortName = shortId + this._gitDDB.jsonExt; return deleteImpl(this._gitDDB, this.collectionPath, shortId, shortName, options).then( res => { @@ -1176,15 +1188,15 @@ export class Collection implements ICollection { return Promise.reject(new Err.UndefinedDocumentIdError()); } - const docType: DocType = shortName.endsWith(JSON_EXTENSION) ? 'json' : 'text'; + const docType: DocType = shortName.endsWith(this._gitDDB.jsonExt) ? 'json' : 'text'; if (docType === 'text') { // TODO: select binary or text by .gitattribtues } - const shortId = shortName.replace(new RegExp(JSON_EXTENSION + '$'), ''); + const shortId = shortName.replace(new RegExp(this._gitDDB.jsonExt + '$'), ''); return deleteImpl(this._gitDDB, this.collectionPath, shortId, shortName, options).then( res => { - // NOTE: Cannot detect JsonDoc whose file path does not end with JSON_EXTENSION + // NOTE: Cannot detect JsonDoc whose file path does not end with jsonExt if (docType === 'json') { const deleteResult: DeleteResultJsonDoc = { ...res, @@ -1224,9 +1236,14 @@ export class Collection implements ICollection { find (options?: FindOptions): Promise { options ??= {}; options.forceDocType ??= 'json'; - return findImpl(this._gitDDB, this.collectionPath, true, false, options) as Promise< - JsonDoc[] - >; + return findImpl( + this._gitDDB, + this.collectionPath, + this._gitDDB.jsonExt, + true, + false, + options + ) as Promise; } /** @@ -1238,9 +1255,14 @@ export class Collection implements ICollection { * @public */ findFatDoc (options?: FindOptions): Promise { - return findImpl(this._gitDDB, this.collectionPath, false, true, options) as Promise< - FatDoc[] - >; + return findImpl( + this._gitDDB, + this.collectionPath, + this._gitDDB.jsonExt, + false, + true, + options + ) as Promise; } /*********************************************** diff --git a/src/const.ts b/src/const.ts index d2ba1a63..66a0fc6d 100644 --- a/src/const.ts +++ b/src/const.ts @@ -67,17 +67,6 @@ export const JSON_POSTFIX = '.json'; * @public */ export const FRONT_MATTER_POSTFIX = '.md'; -/** - * !ALERT: It is not const for simplicity. - * - * @internal - */ -// eslint-disable-next-line import/no-mutable-exports, @typescript-eslint/naming-convention, prefer-const -export let JSON_EXTENSION = JSON_POSTFIX; -// eslint-disable-next-line @typescript-eslint/naming-convention -export const setFileExt = (ext: string) => { - JSON_EXTENSION = ext; -}; /** * @public */ diff --git a/src/crud/blob.ts b/src/crud/blob.ts index c21dcb4d..558fc206 100644 --- a/src/crud/blob.ts +++ b/src/crud/blob.ts @@ -8,7 +8,6 @@ import fs from 'fs'; import { readBlob, ReadBlobResult, resolveRef } from 'isomorphic-git'; -import { JSON_EXTENSION } from '../const'; import { utf8decode } from '../utils'; import { Err } from '../error'; import { FatBinaryDoc, FatDoc, FatJsonDoc, FatTextDoc, JsonDoc } from '../types'; @@ -21,7 +20,8 @@ import { FatBinaryDoc, FatDoc, FatJsonDoc, FatTextDoc, JsonDoc } from '../types' export function blobToJsonDoc ( shortId: string, readBlobResult: ReadBlobResult, - withMetadata: boolean + withMetadata: boolean, + jsonExt: string ): FatJsonDoc | JsonDoc { try { const text = utf8decode(readBlobResult.blob); @@ -33,7 +33,7 @@ export function blobToJsonDoc ( if (withMetadata) { const fatJsonDoc: FatJsonDoc = { _id: shortId, - name: shortId + JSON_EXTENSION, + name: shortId + jsonExt, fileOid: readBlobResult.oid, type: 'json', doc: jsonDoc, diff --git a/src/crud/delete.ts b/src/crud/delete.ts index 441b8337..8f7153d9 100644 --- a/src/crud/delete.ts +++ b/src/crud/delete.ts @@ -160,8 +160,8 @@ export async function deleteWorker ( /* not empty */ }); } - } catch (err) { - return Promise.reject(new Err.CannotDeleteDataError(err.message)); + } catch (err: unknown) { + return Promise.reject(new Err.CannotDeleteDataError((err as Error).message)); } return { diff --git a/src/crud/find.ts b/src/crud/find.ts index 95567938..c3d4ee1b 100644 --- a/src/crud/find.ts +++ b/src/crud/find.ts @@ -8,7 +8,7 @@ import fs from 'fs'; import { readBlob, readTree, resolveRef, TreeEntry, TreeObject } from 'isomorphic-git'; -import { GIT_DOCUMENTDB_METADATA_DIR, JSON_EXTENSION } from '../const'; +import { GIT_DOCUMENTDB_METADATA_DIR } from '../const'; import { Err } from '../error'; import { Doc, @@ -34,6 +34,7 @@ import { blobToBinary, blobToJsonDoc, blobToText } from './blob'; export async function findImpl ( gitDDB: GitDDBInterface, collectionPath: string, + jsonExt: string, findOnlyJson: boolean, withMetadata: boolean, options?: FindOptions @@ -142,7 +143,7 @@ export async function findImpl ( } } else { - if (findOnlyJson && !fullDocPath.endsWith(JSON_EXTENSION)) { + if (findOnlyJson && !fullDocPath.endsWith(jsonExt)) { continue; } // eslint-disable-next-line no-await-in-loop @@ -156,19 +157,20 @@ export async function findImpl ( // Skip if cannot read if (readBlobResult) { const docType: DocType = - options.forceDocType ?? - (fullDocPath.endsWith(JSON_EXTENSION) ? 'json' : 'text'); + options.forceDocType ?? (fullDocPath.endsWith(jsonExt) ? 'json' : 'text'); if (docType === 'text') { // TODO: select binary or text by .gitattribtues } const shortName = fullDocPath.replace(new RegExp('^' + collectionPath), ''); if (docType === 'json') { - const shortId = shortName.replace(new RegExp(JSON_EXTENSION + '$'), ''); + const shortId = shortName.replace(new RegExp(jsonExt + '$'), ''); if (withMetadata) { - docs.push(blobToJsonDoc(shortId, readBlobResult, true) as FatJsonDoc); + docs.push( + blobToJsonDoc(shortId, readBlobResult, true, jsonExt) as FatJsonDoc + ); } else { - docs.push(blobToJsonDoc(shortId, readBlobResult, false) as JsonDoc); + docs.push(blobToJsonDoc(shortId, readBlobResult, false, jsonExt) as JsonDoc); } } else if (docType === 'text') { diff --git a/src/crud/get.ts b/src/crud/get.ts index 541e010a..5d033c97 100644 --- a/src/crud/get.ts +++ b/src/crud/get.ts @@ -7,7 +7,6 @@ */ import { ReadBlobResult } from 'isomorphic-git'; -import { JSON_EXTENSION } from '../const'; import { GitDDBInterface } from '../types_gitddb'; import { Err } from '../error'; import { @@ -40,6 +39,7 @@ export async function getImpl ( gitDDB: GitDDBInterface, shortName: string, collectionPath: string, + jsonExt: string, options?: GetOptions, internalOptions?: GetInternalOptions, historyOptions?: HistoryOptions @@ -98,7 +98,7 @@ export async function getImpl ( if (readBlobResult === undefined) return undefined; const docType: DocType = - options.forceDocType ?? (fullDocPath.endsWith(JSON_EXTENSION) ? 'json' : 'text'); + options.forceDocType ?? (fullDocPath.endsWith(jsonExt) ? 'json' : 'text'); if (docType === 'text') { // TODO: select binary or text by .gitattribtues } @@ -107,8 +107,8 @@ export async function getImpl ( if (internalOptions.oid !== '') { return blobToJsonDocWithoutOverwrittenId(readBlobResult); } - const shortId = shortName.replace(new RegExp(JSON_EXTENSION + '$'), ''); - return blobToJsonDoc(shortId, readBlobResult, internalOptions.withMetadata); + const shortId = shortName.replace(new RegExp(jsonExt + '$'), ''); + return blobToJsonDoc(shortId, readBlobResult, internalOptions.withMetadata, jsonExt); } else if (docType === 'text') { return blobToText(shortName, readBlobResult, internalOptions.withMetadata); diff --git a/src/crud/history.ts b/src/crud/history.ts index f1f2570c..ae9051e4 100644 --- a/src/crud/history.ts +++ b/src/crud/history.ts @@ -11,7 +11,6 @@ import fs from 'fs-extra'; import { Doc, DocType, FatDoc, GetOptions, HistoryFilter, HistoryOptions } from '../types'; import { GitDDBInterface } from '../types_gitddb'; import { Err } from '../error'; -import { JSON_EXTENSION } from '../const'; import { blobToBinary, blobToJsonDoc, blobToText } from './blob'; /** @@ -28,6 +27,7 @@ export async function getHistoryImpl ( gitDDB: GitDDBInterface, shortName: string, collectionPath: string, + jsonExt: string, historyOptions?: HistoryOptions, options?: GetOptions, withMetaData = false @@ -46,7 +46,7 @@ export async function getHistoryImpl ( const fullDocPath = collectionPath + shortName; const docType: DocType = - options.forceDocType ?? (fullDocPath.endsWith(JSON_EXTENSION) ? 'json' : 'text'); + options.forceDocType ?? (fullDocPath.endsWith(jsonExt) ? 'json' : 'text'); if (docType === 'text') { // TODO: select binary or text by .gitattribtues @@ -88,14 +88,14 @@ export async function getHistoryImpl ( docArray.push(undefined); } else if (docType === 'json') { - const shortId = shortName.replace(new RegExp(JSON_EXTENSION + '$'), ''); + const shortId = shortName.replace(new RegExp(jsonExt + '$'), ''); // eslint-disable-next-line max-depth if (withMetaData) { - docArray.push(blobToJsonDoc(shortId, readBlobResult, true) as FatDoc); + docArray.push(blobToJsonDoc(shortId, readBlobResult, true, jsonExt) as FatDoc); } else { - docArray.push(blobToJsonDoc(shortId, readBlobResult, false) as Doc); + docArray.push(blobToJsonDoc(shortId, readBlobResult, false, jsonExt) as Doc); } } else if (docType === 'text') { diff --git a/src/crud/put.ts b/src/crud/put.ts index b47b0b6d..e1b78606 100644 --- a/src/crud/put.ts +++ b/src/crud/put.ts @@ -181,8 +181,8 @@ export async function putWorker ( oid: commitOid, }); commit = normalizeCommit(readCommitResult); - } catch (err) { - throw new Err.CannotWriteDataError(err.message); + } catch (err: unknown) { + throw new Err.CannotWriteDataError((err as Error).message); } return { diff --git a/src/error.ts b/src/error.ts index 875c40d7..a54b8e47 100644 --- a/src/error.ts +++ b/src/error.ts @@ -6,8 +6,6 @@ * found in the LICENSE file in the root directory of this source tree. */ -import { JSON_EXTENSION } from './const'; - /* eslint-disable unicorn/custom-error-definition */ /** @@ -134,7 +132,7 @@ export namespace Err { */ export class InvalidJsonFileExtensionError extends BaseError { constructor () { - super(`JSON file extension must be ${JSON_EXTENSION}`); + super(`JSON file extension is invalid`); } } diff --git a/src/git_documentdb.ts b/src/git_documentdb.ts index f16dee61..1c6940ac 100644 --- a/src/git_documentdb.ts +++ b/src/git_documentdb.ts @@ -61,7 +61,6 @@ import { GIT_DOCUMENTDB_INFO_ID, JSON_POSTFIX, SET_DATABASE_ID_MESSAGE, - setFileExt, } from './const'; import { normalizeCommit, sleep, toSortedJSONString } from './utils'; import { SyncEventInterface, SyncInterface } from './types_sync'; @@ -131,6 +130,13 @@ export class GitDocumentDB /*********************************************** * Public properties (readonly) ***********************************************/ + /** + * File extension for serializing json object + */ + private _jsonExt = JSON_POSTFIX; + get jsonExt (): string { + return this._jsonExt; + } /** * Default Git branch @@ -324,9 +330,8 @@ export class GitDocumentDB }, }; - setFileExt( - options.serializeFormat === 'front-matter' ? FRONT_MATTER_POSTFIX : JSON_POSTFIX - ); + this._jsonExt = + options.serializeFormat === 'front-matter' ? FRONT_MATTER_POSTFIX : JSON_POSTFIX; // Get full-path this._workingDir = path.resolve(this._localDir, this._dbName); @@ -830,7 +835,12 @@ export class GitDocumentDB ).catch(() => undefined); if (readBlobResult !== undefined) { try { - info = blobToJsonDoc(GIT_DOCUMENTDB_INFO_ID, readBlobResult, false) as DatabaseInfo; + info = blobToJsonDoc( + GIT_DOCUMENTDB_INFO_ID, + readBlobResult, + false, + JSON_POSTFIX + ) as DatabaseInfo; } catch (e) {} } @@ -885,10 +895,10 @@ export class GitDocumentDB /** * Insert a JSON document if not exists. Otherwise, update it. * - * @param jsonDoc - JsonDoc whose _id is shortId. shortId is a file path whose collectionPath and ${JSON_EXTENSION} extension are omitted. + * @param jsonDoc - JsonDoc whose _id is shortId. shortId is a file path whose collectionPath and ${jsonExt} extension are omitted. * * @remarks - * - The saved file path is `${GitDocumentDB#workingDir}/${jsonDoc._id}${JSON_EXTENSION}` on the file system. + * - The saved file path is `${GitDocumentDB#workingDir}/${jsonDoc._id}${jsonExt}` on the file system. * * - If _id is undefined, it is automatically generated. * @@ -916,10 +926,10 @@ export class GitDocumentDB /** * Insert a JSON document if not exists. Otherwise, update it. * - * @param _id - _id is a file path whose ${JSON_EXTENSION} extension is omitted. + * @param _id - _id is a file path whose ${jsonExt} extension is omitted. * * @remarks - * - The saved file path is `${GitDocumentDB#workingDir}/${_id}${JSON_EXTENSION}` on the file system. + * - The saved file path is `${GitDocumentDB#workingDir}/${_id}${jsonExt}` on the file system. * * - If _id is undefined, it is automatically generated. * @@ -963,14 +973,14 @@ export class GitDocumentDB /** * Insert a JSON document * - * @param jsonDoc - JsonDoc whose _id is shortId. shortId is a file path whose collectionPath and ${JSON_EXTENSION} extension are omitted. + * @param jsonDoc - JsonDoc whose _id is shortId. shortId is a file path whose collectionPath and ${jsonExt} extension are omitted. * * @remarks * - Throws SameIdExistsError when a document that has the same _id exists. It might be better to use put() instead of insert(). * * - If _id is undefined, it is automatically generated. * - * - The saved file path is `${GitDocumentDB#workingDir}/${jsonDoc._id}${JSON_EXTENSION}` on the file system. + * - The saved file path is `${GitDocumentDB#workingDir}/${jsonDoc._id}${jsonExt}` on the file system. * * - This is an alias of GitDocumentDB#rootCollection.insert() * @@ -1000,12 +1010,12 @@ export class GitDocumentDB /** * Insert a JSON document * - * @param _id - _id is a file path whose ${JSON_EXTENSION} extension is omitted. + * @param _id - _id is a file path whose ${jsonExt} extension is omitted. * * @remarks * - Throws SameIdExistsError when a document that has the same id exists. It might be better to use put() instead of insert(). * - * - The saved file path is `${GitDocumentDB#workingDir}/${_id}${JSON_EXTENSION}` on the file system. + * - The saved file path is `${GitDocumentDB#workingDir}/${_id}${jsonExt}` on the file system. * * - If _id is undefined, it is automatically generated. * @@ -1051,14 +1061,14 @@ export class GitDocumentDB /** * Update a JSON document * - * @param jsonDoc - JsonDoc whose _id is shortId. shortId is a file path whose collectionPath and ${JSON_EXTENSION} extension are omitted. + * @param jsonDoc - JsonDoc whose _id is shortId. shortId is a file path whose collectionPath and ${jsonExt} extension are omitted. * * @remarks * - Throws DocumentNotFoundError if a specified document does not exist. It might be better to use put() instead of update(). * * - If _id is undefined, it is automatically generated. * - * - The saved file path is `${GitDocumentDB#workingDir}/${_id}${JSON_EXTENSION}` on the file system. + * - The saved file path is `${GitDocumentDB#workingDir}/${_id}${jsonExt}` on the file system. * * - This is an alias of GitDocumentDB#rootCollection.update() * @@ -1086,12 +1096,12 @@ export class GitDocumentDB /** * Update a JSON document * - * @param _id - _id is a file path whose ${JSON_EXTENSION} extension is omitted. + * @param _id - _id is a file path whose ${jsonExt} extension is omitted. * * @remarks * - Throws DocumentNotFoundError if a specified document does not exist. It might be better to use put() instead of update(). * - * - The saved file path is `${GitDocumentDB#workingDir}/${_id}${JSON_EXTENSION}` on the file system. + * - The saved file path is `${GitDocumentDB#workingDir}/${_id}${jsonExt}` on the file system. * * - An update operation is not skipped even if no change occurred on a specified document. * @@ -1136,11 +1146,11 @@ export class GitDocumentDB * @param name - name is a file path. * * @remarks - * - The saved file path is `${GitDocumentDB#workingDir}/${name}${JSON_EXTENSION}`. + * - The saved file path is `${GitDocumentDB#workingDir}/${name}${jsonExt}`. * * - If a name parameter is undefined, it is automatically generated. * - * - _id property of a JsonDoc is automatically set or overwritten by name parameter whose ${JSON_EXTENSION} extension is removed. + * - _id property of a JsonDoc is automatically set or overwritten by name parameter whose ${jsonExt} extension is removed. * * - An update operation is not skipped even if no change occurred on a specified data. * @@ -1180,11 +1190,11 @@ export class GitDocumentDB * @remarks * - Throws SameIdExistsError when data that has the same _id exists. It might be better to use put() instead of insert(). * - * - The saved file path is `${GitDocumentDB#workingDir}/${name}${JSON_EXTENSION}`. + * - The saved file path is `${GitDocumentDB#workingDir}/${name}${jsonExt}`. * * - If a name parameter is undefined, it is automatically generated. * - * - _id property of a JsonDoc is automatically set or overwritten by name parameter whose ${JSON_EXTENSION} extension is omitted. + * - _id property of a JsonDoc is automatically set or overwritten by name parameter whose ${jsonExt} extension is omitted. * * - This is an alias of GitDocumentDB#rootCollection.insertFatDoc() * @@ -1223,9 +1233,9 @@ export class GitDocumentDB * @remarks * - Throws DocumentNotFoundError if a specified data does not exist. It might be better to use put() instead of update(). * - * - The saved file path is `${GitDocumentDB#workingDir}/${name}${JSON_EXTENSION}`. + * - The saved file path is `${GitDocumentDB#workingDir}/${name}${jsonExt}`. * - * - _id property of a JsonDoc is automatically set or overwritten by name parameter whose ${JSON_EXTENSION} extension is omitted. + * - _id property of a JsonDoc is automatically set or overwritten by name parameter whose ${jsonExt} extension is omitted. * * - An update operation is not skipped even if no change occurred on a specified data. * @@ -1261,7 +1271,7 @@ export class GitDocumentDB /** * Get a JSON document * - * @param _id - _id is a file path whose ${JSON_EXTENSION} extension is omitted. + * @param _id - _id is a file path whose ${jsonExt} extension is omitted. * * @returns * - undefined if a specified document does not exist. @@ -1287,7 +1297,7 @@ export class GitDocumentDB * @returns * - undefined if a specified data does not exist. * - * - FatJsonDoc if the file extension is JSON_EXTENSION. Be careful that JsonDoc may not have _id property when an app other than GitDocumentDB creates it. + * - FatJsonDoc if the file extension is jsonExt. Be careful that JsonDoc may not have _id property when an app other than GitDocumentDB creates it. * * - FatBinaryDoc if described in .gitattribtues, otherwise FatTextDoc. * @@ -1326,7 +1336,7 @@ export class GitDocumentDB /** * Get an old revision of a document * - * @param _id - _id is a file path whose ${JSON_EXTENSION} extension is omitted. + * @param _id - _id is a file path whose ${jsonExt} extension is omitted. * @param revision - Specify a number to go back to old revision. Default is 0. * See {@link git-documentdb#GitDocumentDB.getHistory} for the array of revisions. * @param historyOptions - The array of revisions is filtered by HistoryOptions.filter. @@ -1366,7 +1376,7 @@ export class GitDocumentDB * @remarks * - undefined if a specified data does not exist or it is deleted. * - * - JsonDoc if the file extension is JSON_EXTENSION. Be careful that JsonDoc may not have _id property when an app other than GitDocumentDB creates it. + * - JsonDoc if the file extension is jsonExt. Be careful that JsonDoc may not have _id property when an app other than GitDocumentDB creates it. * * - FatBinaryDoc if described in .gitattribtues, otherwise FatTextDoc. * @@ -1402,7 +1412,7 @@ export class GitDocumentDB /** * Get revision history of a document * - * @param _id - _id is a file path whose ${JSON_EXTENSION} extension is omitted. + * @param _id - _id is a file path whose ${jsonExt} extension is omitted. * @param historyOptions - The array of revisions is filtered by HistoryOptions.filter. * * @remarks @@ -1413,7 +1423,7 @@ export class GitDocumentDB * @returns Array of FatDoc or undefined. * - undefined if a specified document does not exist or it is deleted. * - * - JsonDoc if isJsonDocCollection is true or the file extension is JSON_EXTENSION. + * - JsonDoc if isJsonDocCollection is true or the file extension is jsonExt. * * - Uint8Array or string if isJsonDocCollection is false. * @@ -1473,7 +1483,7 @@ export class GitDocumentDB * @returns Array of FatDoc or undefined. * - undefined if a specified data does not exist or it is deleted. * - * - Array of FatJsonDoc if isJsonDocCollection is true or the file extension is JSON_EXTENSION. Be careful that JsonDoc may not have _id property when an app other than GitDocumentDB creates it. + * - Array of FatJsonDoc if isJsonDocCollection is true or the file extension is jsonExt. Be careful that JsonDoc may not have _id property when an app other than GitDocumentDB creates it. * * - Array of FatBinaryDoc if described in .gitattribtues, otherwise array of FatTextDoc. * @@ -1495,7 +1505,7 @@ export class GitDocumentDB /** * Delete a JSON document * - * @param _id - _id is a file path whose ${JSON_EXTENSION} extension is omitted. + * @param _id - _id is a file path whose ${jsonExt} extension is omitted. * * @remarks * - This is an alias of GitDocumentDB#rootCollection.delete() @@ -1518,7 +1528,7 @@ export class GitDocumentDB /** * Delete a document by _id property in JsonDoc * - * @param jsonDoc - Only the _id property of the JsonDoc is referenced. _id is a file path whose ${JSON_EXTENSION} extension is omitted. + * @param jsonDoc - Only the _id property of the JsonDoc is referenced. _id is a file path whose ${jsonExt} extension is omitted. * * @remarks * - This is an alias of GitDocumentDB#rootCollection.delete() diff --git a/src/remote/3way_merge.ts b/src/remote/3way_merge.ts index 9c7bace3..3dff408b 100644 --- a/src/remote/3way_merge.ts +++ b/src/remote/3way_merge.ts @@ -1,7 +1,7 @@ import nodePath, { basename } from 'path'; import git, { TreeEntry, WalkerEntry } from 'isomorphic-git'; import fs from 'fs-extra'; -import { DEFAULT_CONFLICT_RESOLUTION_STRATEGY, JSON_EXTENSION } from '../const'; +import { DEFAULT_CONFLICT_RESOLUTION_STRATEGY } from '../const'; import { Err } from '../error'; import { AcceptedConflict, @@ -15,7 +15,7 @@ import { } from '../types'; import { GitDDBInterface } from '../types_gitddb'; import { getFatDocFromData, writeBlobToFile } from './worker_utils'; -import { toSortedJSONString, utf8decode } from '../utils'; +import { serializeJSON, utf8decode } from '../utils'; import { JsonDiff } from './json_diff'; import { SyncInterface } from '../types_sync'; import { isSameFatDoc } from '../crud/blob'; @@ -58,7 +58,8 @@ function getMergedJsonDoc ( strategy: ConflictResolutionStrategyLabels, base: JsonDoc | undefined, ours: JsonDoc, - theirs: JsonDoc + theirs: JsonDoc, + jsonExt: string ): string { let result: { [key: string]: string }; if (strategy === 'ours') { @@ -88,7 +89,7 @@ function getMergedJsonDoc ( else { throw new Err.InvalidConflictResolutionStrategyError(); } - return toSortedJSONString(result); + return serializeJSON(result, jsonExt); } /** @@ -157,7 +158,8 @@ function getMergedDocument ( base: Uint8Array | undefined, ours: Uint8Array, theirs: Uint8Array, - docType: DocType + docType: DocType, + jsonExt: string ): string | Uint8Array { if (docType === 'json') { const oursDoc = JSON.parse(utf8decode(ours)); @@ -169,7 +171,15 @@ function getMergedDocument ( else { baseDoc = undefined; } - return getMergedJsonDoc(jsonDiff, jsonPatch, strategy, baseDoc, oursDoc, theirsDoc); + return getMergedJsonDoc( + jsonDiff, + jsonPatch, + strategy, + baseDoc, + oursDoc, + theirsDoc, + jsonExt + ); } else if (docType === 'text') { const oursDoc = utf8decode(ours); @@ -357,7 +367,7 @@ export async function threeWayMerge ( AcceptedConflict | undefined ] > { - const docType: DocType = fullDocPath.endsWith(JSON_EXTENSION) ? 'json' : 'text'; + const docType: DocType = fullDocPath.endsWith(gitDDB.jsonExt) ? 'json' : 'text'; if (docType === 'text') { // TODO: select binary or text by .gitattribtues } @@ -375,7 +385,12 @@ export async function threeWayMerge ( // Write it to the index. // console.log(' #case 1 - Accept theirs (insert): ' + fullDocPath); const theirsData = (await theirs.content())!; - const theirsFatDoc = await getFatDocFromData(theirsData, fullDocPath, docType); + const theirsFatDoc = await getFatDocFromData( + theirsData, + fullDocPath, + docType, + gitDDB.jsonExt + ); await writeBlobToFile(gitDDB.workingDir, fullDocPath, theirsData); await git.add({ fs, dir: gitDDB.workingDir, filepath: fullDocPath }); return [ @@ -399,7 +414,12 @@ export async function threeWayMerge ( // It has already been added to the index. // console.log(' #case 2 - Accept ours (insert): ' + fullDocPath); const oursData = (await ours.content())!; - const oursFatDoc = await getFatDocFromData(oursData, fullDocPath, docType); + const oursFatDoc = await getFatDocFromData( + oursData, + fullDocPath, + docType, + gitDDB.jsonExt + ); return [ { mode: (await ours.mode()).toString(8), @@ -443,8 +463,18 @@ export async function threeWayMerge ( // ! Conflict const oursData = (await ours.content())!; const theirsData = (await theirs.content())!; - const oursFatDoc = await getFatDocFromData(oursData, fullDocPath, docType); - const theirsFatDoc = await getFatDocFromData(theirsData, fullDocPath, docType); + const oursFatDoc = await getFatDocFromData( + oursData, + fullDocPath, + docType, + gitDDB.jsonExt + ); + const theirsFatDoc = await getFatDocFromData( + theirsData, + fullDocPath, + docType, + gitDDB.jsonExt + ); const strategy = await getStrategy( conflictResolutionStrategy, @@ -497,9 +527,10 @@ export async function threeWayMerge ( undefined, oursData, theirsData, - docType + docType, + gitDDB.jsonExt ); - resultFatDoc = await getFatDocFromData(data, fullDocPath, docType); + resultFatDoc = await getFatDocFromData(data, fullDocPath, docType, gitDDB.jsonExt); await writeBlobToFile(gitDDB.workingDir, fullDocPath, data); await git.add({ fs, dir: gitDDB.workingDir, filepath: fullDocPath }); @@ -546,7 +577,12 @@ export async function threeWayMerge ( const baseOid = await base.oid(); const theirsOid = await theirs.oid(); const theirsData = (await theirs.content())!; - const theirsFatDoc = await getFatDocFromData(theirsData, fullDocPath, docType); + const theirsFatDoc = await getFatDocFromData( + theirsData, + fullDocPath, + docType, + gitDDB.jsonExt + ); if (baseOid === theirsOid) { // A file has been removed from ours. @@ -569,7 +605,12 @@ export async function threeWayMerge ( if (strategy === 'ours' || strategy === 'ours-diff') { // console.log(' #case 8 - Conflict. Accept ours (delete): ' + fullDocPath); const baseData = (await base.content())!; - const baseFatDoc = await getFatDocFromData(baseData, fullDocPath, docType); + const baseFatDoc = await getFatDocFromData( + baseData, + fullDocPath, + docType, + gitDDB.jsonExt + ); const acceptedConflict: AcceptedConflict = { fatDoc: baseFatDoc, strategy: strategy, @@ -614,7 +655,12 @@ export async function threeWayMerge ( const baseOid = await base.oid(); const oursOid = await ours.oid(); const oursData = (await ours.content())!; - const oursFatDoc = await getFatDocFromData(oursData, fullDocPath, docType); + const oursFatDoc = await getFatDocFromData( + oursData, + fullDocPath, + docType, + gitDDB.jsonExt + ); if (baseOid === oursOid) { // A file has been removed from theirs. @@ -663,7 +709,12 @@ export async function threeWayMerge ( else if (strategy === 'theirs' || strategy === 'theirs-diff') { // console.log(' #case 12 - Conflict. Accept theirs (delete): ' + fullDocPath); const baseData = (await base.content())!; - const baseFatDoc = await getFatDocFromData(baseData, fullDocPath, docType); + const baseFatDoc = await getFatDocFromData( + baseData, + fullDocPath, + docType, + gitDDB.jsonExt + ); const acceptedConflicts: AcceptedConflict = { fatDoc: baseFatDoc, strategy: strategy, @@ -708,9 +759,19 @@ export async function threeWayMerge ( else if (baseOid === oursOid) { // console.log(' #case 14 - Accept theirs (update): ' + fullDocPath); const oursData = (await ours.content())!; - const oursFatDoc = await getFatDocFromData(oursData, fullDocPath, docType); + const oursFatDoc = await getFatDocFromData( + oursData, + fullDocPath, + docType, + gitDDB.jsonExt + ); const theirsData = (await theirs.content())!; - const theirsFatDoc = await getFatDocFromData(theirsData, fullDocPath, docType); + const theirsFatDoc = await getFatDocFromData( + theirsData, + fullDocPath, + docType, + gitDDB.jsonExt + ); await writeBlobToFile(gitDDB.workingDir, fullDocPath, theirsData); await git.add({ fs, dir: gitDDB.workingDir, filepath: fullDocPath }); return [ @@ -732,9 +793,19 @@ export async function threeWayMerge ( else if (baseOid === theirsOid) { // console.log(' #case 15 - Accept ours (update): ' + fullDocPath); const oursData = (await ours.content())!; - const oursFatDoc = await getFatDocFromData(oursData, fullDocPath, docType); + const oursFatDoc = await getFatDocFromData( + oursData, + fullDocPath, + docType, + gitDDB.jsonExt + ); const theirsData = (await theirs.content())!; - const theirsFatDoc = await getFatDocFromData(theirsData, fullDocPath, docType); + const theirsFatDoc = await getFatDocFromData( + theirsData, + fullDocPath, + docType, + gitDDB.jsonExt + ); return [ { mode: (await theirs.mode()).toString(8), @@ -757,8 +828,18 @@ export async function threeWayMerge ( const baseData = (await base.content())!; const oursData = (await ours.content())!; const theirsData = (await theirs.content())!; - const oursFatDoc = await getFatDocFromData(oursData, fullDocPath, docType); - const theirsFatDoc = await getFatDocFromData(theirsData, fullDocPath, docType); + const oursFatDoc = await getFatDocFromData( + oursData, + fullDocPath, + docType, + gitDDB.jsonExt + ); + const theirsFatDoc = await getFatDocFromData( + theirsData, + fullDocPath, + docType, + gitDDB.jsonExt + ); const strategy = await getStrategy( conflictResolutionStrategy, oursFatDoc, @@ -820,9 +901,15 @@ export async function threeWayMerge ( baseData, oursData, theirsData, - docType + docType, + gitDDB.jsonExt + ); + const resultFatDoc = await getFatDocFromData( + data, + fullDocPath, + docType, + gitDDB.jsonExt ); - const resultFatDoc = await getFatDocFromData(data, fullDocPath, docType); await writeBlobToFile(gitDDB.workingDir, fullDocPath, data); await git.add({ fs, dir: gitDDB.workingDir, filepath: fullDocPath }); diff --git a/src/remote/combine.ts b/src/remote/combine.ts index 26875021..74cd6da9 100644 --- a/src/remote/combine.ts +++ b/src/remote/combine.ts @@ -21,8 +21,8 @@ import { } from '../types'; import { GitDDBInterface } from '../types_gitddb'; import { Err } from '../error'; -import { DUPLICATED_FILE_POSTFIX, FILE_REMOVE_TIMEOUT, JSON_EXTENSION } from '../const'; -import { getAllMetadata, toSortedJSONString } from '../utils'; +import { DUPLICATED_FILE_POSTFIX, FILE_REMOVE_TIMEOUT } from '../const'; +import { getAllMetadata, serializeJSON } from '../utils'; import { RemoteEngine, wrappingRemoteEngineError } from './remote_engine'; /** @@ -90,8 +90,14 @@ export async function combineDatabaseWithTheirs ( value: `refs/heads/${gitDDB.defaultBranch}`, }); - const localMetadataList: DocMetadata[] = await getAllMetadata(gitDDB.workingDir); - const remoteMetadataList: DocMetadata[] = await getAllMetadata(remoteDir); + const localMetadataList: DocMetadata[] = await getAllMetadata( + gitDDB.workingDir, + gitDDB.jsonExt + ); + const remoteMetadataList: DocMetadata[] = await getAllMetadata( + remoteDir, + gitDDB.jsonExt + ); const remoteNames = remoteMetadataList.map(meta => meta.name); for (let i = 0; i < localMetadataList.length; i++) { @@ -102,7 +108,7 @@ export async function combineDatabaseWithTheirs ( await fs.ensureDir(dir); - const docType: DocType = localFilePath.endsWith(JSON_EXTENSION) ? 'json' : 'text'; + const docType: DocType = localFilePath.endsWith(gitDDB.jsonExt) ? 'json' : 'text'; // eslint-disable-next-line max-depth if (docType === 'text') { // TODO: select binary or text by .gitattribtues @@ -128,15 +134,16 @@ export async function combineDatabaseWithTheirs ( if (doc._id !== undefined) { doc._id = _id + postfix; } - duplicatedFileName = _id + postfix + JSON_EXTENSION; + duplicatedFileName = _id + postfix + gitDDB.jsonExt; duplicatedFileId = _id + postfix; - duplicatedFileExt = JSON_EXTENSION; + duplicatedFileExt = gitDDB.jsonExt; fs.writeFileSync( path.resolve(remoteDir, duplicatedFileName), - toSortedJSONString(doc) + serializeJSON(doc, gitDDB.jsonExt) ); - const duplicatedOid = (await git.hashBlob({ object: toSortedJSONString(doc) })) - .oid; + const duplicatedOid = ( + await git.hashBlob({ object: serializeJSON(doc, gitDDB.jsonExt) }) + ).oid; original = { _id, name: meta.name, diff --git a/src/remote/json_patch_ot.ts b/src/remote/json_patch_ot.ts index fd22b5a8..0133961f 100644 --- a/src/remote/json_patch_ot.ts +++ b/src/remote/json_patch_ot.ts @@ -1,3 +1,4 @@ +/* eslint-disable unicorn/prefer-spread */ /* eslint-disable max-depth */ import { editOp, insertOp, JSONOp, moveOp, replaceOp, type } from 'ot-json1'; import { uniCount } from 'unicount'; @@ -110,7 +111,7 @@ export class JsonPatchOT implements IJsonPatch { } const noBar = keys.slice(0, underBarStart); const underBar = keys.slice(underBarStart, keys.length); - sortedKeys = [...underBar, ...noBar]; // _1, _2, _3, 1, 2, 3 + sortedKeys = underBar.concat(noBar); // _1, _2, _3, 1, 2, 3 } else { sortedKeys = keys.sort(); @@ -120,10 +121,10 @@ export class JsonPatchOT implements IJsonPatch { if (Array.isArray(tree[key])) { const arr = tree[key] as any[]; if (arr.length === 1) { - operations.push(insertOp([...ancestors, ...key], arr[0])!); + operations.push(insertOp(ancestors.concat(key), arr[0])!); } else if (arr.length === 2) { - operations.push(replaceOp([...ancestors, ...key], arr[0], arr[1])!); + operations.push(replaceOp(ancestors.concat(key), arr[0], arr[1])!); } else if (arr.length === 3) { const firstItem = arr[0]; @@ -134,7 +135,7 @@ export class JsonPatchOT implements IJsonPatch { if (!isTextPatch) isTextPatch = firstItem.match(/^@@ -\d+?,\d+? \+\d+? @@\n/m); if (isTextPatch) { - const textOp = this.getTextOp([...ancestors, ...key], firstItem); + const textOp = this.getTextOp(ancestors.concat(key), firstItem); if (textOp) { operations.push(textOp); } @@ -143,7 +144,7 @@ export class JsonPatchOT implements IJsonPatch { } } else if (typeof tree[key] === 'object') { - procTree([...ancestors, ...key], tree[key]); + procTree(ancestors.concat(key), tree[key]); } }); }; @@ -209,10 +210,14 @@ export class JsonPatchOT implements IJsonPatch { else { transformedOp = type.transform(opOurs, opTheirs, 'right'); } - } catch (err) { - if (err.conflict) { + } catch (err: unknown) { + if ((err as { conflict: any }).conflict) { // console.log('conflict: ' + JSON.stringify(err.conflict)); - const conflict = err.conflict as { type: number; op1: any[]; op2: any[] }; + const conflict = (err as { conflict: any }).conflict as { + type: number; + op1: any[]; + op2: any[]; + }; let conflictedOperation; // Remove conflicted op from targetOperations @@ -264,7 +269,7 @@ export class JsonPatchOT implements IJsonPatch { conflictedCommands.forEach(command => delete opElm[command]); } if (Object.keys(opElm).length > 0) { - const resolvedOp = [...pathFromRoot, ...opElm]; + const resolvedOp = pathFromRoot.concat(opElm); resolvedOperations.push(resolvedOp); } } diff --git a/src/remote/push_worker.ts b/src/remote/push_worker.ts index b14388bd..c34722c1 100644 --- a/src/remote/push_worker.ts +++ b/src/remote/push_worker.ts @@ -156,7 +156,12 @@ export async function pushWorker ( remoteChanges = undefined; } else { - remoteChanges = await getChanges(gitDDB.workingDir, remoteCommitOid, headCommitOid); + remoteChanges = await getChanges( + gitDDB.workingDir, + remoteCommitOid, + headCommitOid, + gitDDB.jsonExt + ); } const syncResult: SyncResultPush = { diff --git a/src/remote/sync_worker.ts b/src/remote/sync_worker.ts index 389b5c07..a7bfb79a 100644 --- a/src/remote/sync_worker.ts +++ b/src/remote/sync_worker.ts @@ -147,7 +147,8 @@ export async function syncWorker ( const localChanges = await getAndWriteLocalChanges( gitDDB.workingDir, oldCommitOid, - newCommitOid! + newCommitOid!, + gitDDB.jsonExt ); const syncResultFastForwardMerge: SyncResult = { diff --git a/src/remote/worker_utils.ts b/src/remote/worker_utils.ts index 2cff8571..bb8a898f 100644 --- a/src/remote/worker_utils.ts +++ b/src/remote/worker_utils.ts @@ -9,8 +9,7 @@ import nodePath from 'path'; import git, { ReadBlobResult, ReadCommitResult } from 'isomorphic-git'; import fs from 'fs-extra'; -import { normalizeCommit, toSortedJSONString, utf8decode } from '../utils'; -import { JSON_EXTENSION } from '../const'; +import { normalizeCommit, serializeJSON, utf8decode } from '../utils'; import { Err } from '../error'; import { ChangedFile, @@ -50,12 +49,13 @@ export async function writeBlobToFile ( export async function getFatDocFromData ( data: string | Uint8Array, fullDocPath: string, - docType: DocType + docType: DocType, + jsonExt: string ) { let fatDoc: FatDoc; const { oid } = await git.hashBlob({ object: data }); if (docType === 'json') { - const _id = fullDocPath.replace(new RegExp(JSON_EXTENSION + '$'), ''); + const _id = fullDocPath.replace(new RegExp(jsonExt + '$'), ''); if (typeof data !== 'string') { data = utf8decode(data); } @@ -107,14 +107,15 @@ export async function getFatDocFromOid ( workingDir: string, fullDocPath: string, fileOid: string, - docType: DocType + docType: DocType, + jsonExt: string ) { const readBlobResult = await git.readBlob({ fs, dir: workingDir, oid: fileOid, }); - return getFatDocFromReadBlobResult(fullDocPath, readBlobResult, docType); + return getFatDocFromReadBlobResult(fullDocPath, readBlobResult, docType, jsonExt); } /** @@ -125,12 +126,13 @@ export async function getFatDocFromOid ( export function getFatDocFromReadBlobResult ( fullDocPath: string, readBlobResult: ReadBlobResult, - docType: DocType + docType: DocType, + jsonExt: string ) { let fatDoc: FatDoc; if (docType === 'json') { - const _id = fullDocPath.replace(new RegExp(JSON_EXTENSION + '$'), ''); - fatDoc = blobToJsonDoc(_id, readBlobResult, true) as FatJsonDoc; + const _id = fullDocPath.replace(new RegExp(jsonExt + '$'), ''); + fatDoc = blobToJsonDoc(_id, readBlobResult, true, jsonExt) as FatJsonDoc; } else if (docType === 'text') { fatDoc = blobToText(fullDocPath, readBlobResult, true) as FatTextDoc; @@ -151,7 +153,8 @@ export function getFatDocFromReadBlobResult ( export async function getChanges ( workingDir: string, oldCommitOid: string | undefined, - newCommitOid: string + newCommitOid: string, + jsonExt: string ) { return await git.walk({ fs, @@ -169,7 +172,7 @@ export async function getChanges ( a = null; } - const docType: DocType = fullDocPath.endsWith(JSON_EXTENSION) ? 'json' : 'text'; + const docType: DocType = fullDocPath.endsWith(jsonExt) ? 'json' : 'text'; if (docType === 'text') { // TODO: select binary or text by .gitattribtues } @@ -188,20 +191,20 @@ export async function getChanges ( if (bOid === undefined && aOid !== undefined) { change = { operation: 'delete', - old: await getFatDocFromOid(workingDir, fullDocPath, aOid, docType), + old: await getFatDocFromOid(workingDir, fullDocPath, aOid, docType, jsonExt), }; } else if (aOid === undefined && bOid !== undefined) { change = { operation: 'insert', - new: await getFatDocFromOid(workingDir, fullDocPath, bOid, docType), + new: await getFatDocFromOid(workingDir, fullDocPath, bOid, docType, jsonExt), }; } else if (aOid !== undefined && bOid !== undefined && aOid !== bOid) { change = { operation: 'update', - old: await getFatDocFromOid(workingDir, fullDocPath, aOid, docType), - new: await getFatDocFromOid(workingDir, fullDocPath, bOid, docType), + old: await getFatDocFromOid(workingDir, fullDocPath, aOid, docType, jsonExt), + new: await getFatDocFromOid(workingDir, fullDocPath, bOid, docType, jsonExt), }; } else { @@ -223,7 +226,8 @@ export async function getChanges ( export async function getAndWriteLocalChanges ( workingDir: string, oldCommitOid: string, - newCommitOid: string + newCommitOid: string, + jsonExt: string ) { return await git.walk({ fs, @@ -237,7 +241,7 @@ export async function getAndWriteLocalChanges ( return; } - const docType: DocType = fullDocPath.endsWith(JSON_EXTENSION) ? 'json' : 'text'; + const docType: DocType = fullDocPath.endsWith(jsonExt) ? 'json' : 'text'; if (docType === 'text') { // TODO: select binary or text by .gitattribtues } @@ -256,7 +260,7 @@ export async function getAndWriteLocalChanges ( if (bOid === undefined && aOid !== undefined) { change = { operation: 'delete', - old: await getFatDocFromOid(workingDir, fullDocPath, aOid, docType), + old: await getFatDocFromOid(workingDir, fullDocPath, aOid, docType, jsonExt), }; await git.remove({ fs, dir: workingDir, filepath: fullDocPath }); const path = nodePath.resolve(workingDir, fullDocPath); @@ -267,13 +271,13 @@ export async function getAndWriteLocalChanges ( else if (aOid === undefined && bOid !== undefined) { change = { operation: 'insert', - new: await getFatDocFromOid(workingDir, fullDocPath, bOid, docType), + new: await getFatDocFromOid(workingDir, fullDocPath, bOid, docType, jsonExt), }; if (change.new.type === 'json') { await writeBlobToFile( workingDir, fullDocPath, - toSortedJSONString(change.new.doc) + serializeJSON(change.new.doc, jsonExt) ); } else if (change.new.type === 'text' || change.new.type === 'binary') { @@ -284,14 +288,14 @@ export async function getAndWriteLocalChanges ( else if (aOid !== undefined && bOid !== undefined && aOid !== bOid) { change = { operation: 'update', - old: await getFatDocFromOid(workingDir, fullDocPath, aOid, docType), - new: await getFatDocFromOid(workingDir, fullDocPath, bOid, docType), + old: await getFatDocFromOid(workingDir, fullDocPath, aOid, docType, jsonExt), + new: await getFatDocFromOid(workingDir, fullDocPath, bOid, docType, jsonExt), }; if (change.new.type === 'json') { await writeBlobToFile( workingDir, fullDocPath, - toSortedJSONString(change.new.doc) + serializeJSON(change.new.doc, jsonExt) ); } else if (change.new.type === 'text' || change.new.type === 'binary') { diff --git a/src/types.ts b/src/types.ts index af4713bc..8dfa09c8 100644 --- a/src/types.ts +++ b/src/types.ts @@ -196,7 +196,7 @@ export type Doc = JsonDoc | string | Uint8Array; * Metadata for JsonDoc * * @remarks - * - _id: _id of a JSON document. This is a file name without ${JSON_EXTENSION} extension. + * - _id: _id of a JSON document. This is a file name without ${jsonExt} extension. * * - name: A file name in Git. e.g.) "foo.json", "bar/baz.md" * @@ -457,7 +457,7 @@ export type FindOptions = { * Result of put APIs (put, update, insert, putFatDoc, updateFatDoc, and insertFatDoc) * * @remarks - * - _id: _id of a JSON document. This is a file name without ${JSON_EXTENSION} extension. PutResult does not have _id if a document is not {@link JsonDoc} type. + * - _id: _id of a JSON document. This is a file name without ${jsonExt} extension. PutResult does not have _id if a document is not {@link JsonDoc} type. * * - name: A file name in Git. e.g.) "foo.json", "bar/baz.md" * @@ -504,7 +504,7 @@ export type PutResultBinary = { * Result of delete() * * @remarks - * - _id: _id of a JSON document. This is a file name without ${JSON_EXTENSION} extension. PutResult does not have _id if a document is not {@link JsonDoc} type. + * - _id: _id of a JSON document. This is a file name without ${jsonExt} extension. PutResult does not have _id if a document is not {@link JsonDoc} type. * * - name: A file name in Git. e.g.) "foo.json", "bar/baz.md" * diff --git a/src/types_gitddb.ts b/src/types_gitddb.ts index 72cc809d..b422e30c 100644 --- a/src/types_gitddb.ts +++ b/src/types_gitddb.ts @@ -30,6 +30,7 @@ export interface GitDDBInterface { /*********************************************** * Public properties (readonly) ***********************************************/ + jsonExt: string; defaultBranch: string; localDir: string; dbName: string; diff --git a/src/utils.ts b/src/utils.ts index 8270d319..76c84f99 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -24,7 +24,7 @@ import { NormalizedCommit, TextDocMetadata, } from './types'; -import { FRONT_MATTER_POSTFIX, GIT_DOCUMENTDB_METADATA_DIR, JSON_EXTENSION } from './const'; +import { FRONT_MATTER_POSTFIX, GIT_DOCUMENTDB_METADATA_DIR, JSON_POSTFIX } from './const'; /** * @internal @@ -86,12 +86,12 @@ export function toSortedJSONString (obj: Record) { export function toFrontMatterMarkdown (obj: Record) { const body = typeof obj._body === 'string' ? obj._body : ''; delete obj._body; - const frontMatter = '---\n' + yaml.dump(obj) + '---\n'; + const frontMatter = '---\n' + yaml.dump(obj, { sortKeys: true }) + '---\n'; return frontMatter + body; } -export function serializeJSON (obj: Record) { - if (JSON_EXTENSION === FRONT_MATTER_POSTFIX) { +export function serializeJSON (obj: Record, jsonExt: string) { + if (jsonExt === FRONT_MATTER_POSTFIX) { return toFrontMatterMarkdown(obj); } return toSortedJSONString(obj); @@ -103,7 +103,10 @@ export function serializeJSON (obj: Record) { * @internal */ // eslint-disable-next-line complexity -export async function getAllMetadata (workingDir: string): Promise { +export async function getAllMetadata ( + workingDir: string, + jsonExt: string +): Promise { const files: DocMetadata[] = []; const commitOid = await resolveRef({ fs, dir: workingDir, ref: 'HEAD' }).catch( () => undefined @@ -156,12 +159,12 @@ export async function getAllMetadata (workingDir: string): Promise { expect(deleteResult._id).toBe(_id); expect(deleteResult.fileOid).toBe(putResult.fileOid); expect(deleteResult.commit.message).toBe( - `delete: users/${_id}${JSON_EXTENSION}(${shortOid})` + `delete: users/${_id}${JSON_POSTFIX}(${shortOid})` ); // Check commit directly @@ -114,7 +114,7 @@ describe('delete(shortId)', () => { dir: gitDDB.workingDir, oid: commitOid, }); - expect(commit.message).toEqual(`delete: users/${_id}${JSON_EXTENSION}(${shortOid})\n`); + expect(commit.message).toEqual(`delete: users/${_id}${JSON_POSTFIX}(${shortOid})\n`); await expect(users.delete(_id)).rejects.toThrowError(Err.DocumentNotFoundError); await expect(users.get(_id)).resolves.toBeUndefined(); @@ -153,7 +153,7 @@ describe('delete(shortId)', () => { expect(deleteResult._id).toBe(_id); expect(deleteResult.fileOid).toBe(putResult.fileOid); expect(deleteResult.commit.message).toBe( - `delete: ${users.collectionPath}${_id}${JSON_EXTENSION}(${shortOid})` + `delete: ${users.collectionPath}${_id}${JSON_POSTFIX}(${shortOid})` ); // Check commit directly @@ -164,7 +164,7 @@ describe('delete(shortId)', () => { oid: commitOid, }); expect(commit.message).toEqual( - `delete: ${users.collectionPath}${_id}${JSON_EXTENSION}(${shortOid})\n` + `delete: ${users.collectionPath}${_id}${JSON_POSTFIX}(${shortOid})\n` ); await expect(users.delete(_id)).rejects.toThrowError(Err.DocumentNotFoundError); @@ -248,7 +248,7 @@ describe('delete(jsonDoc)', () => { // Check NormalizedCommit expect(deleteResult.commit.oid).toBe(currentCommitOid); expect(deleteResult.commit.message).toBe( - `delete: ${users.collectionPath}${_id}${JSON_EXTENSION}(${oid.substr( + `delete: ${users.collectionPath}${_id}${JSON_POSTFIX}(${oid.substr( 0, SHORT_SHA_LENGTH )})` @@ -320,12 +320,12 @@ describe('deleteFatDoc(name)', () => { const shortOid = putResult.fileOid.substr(0, SHORT_SHA_LENGTH); // Delete const deleteResult = (await users.deleteFatDoc( - _id + JSON_EXTENSION + _id + JSON_POSTFIX )) as DeleteResultJsonDoc; expect(deleteResult._id).toBe(_id); expect(deleteResult.fileOid).toBe(putResult.fileOid); expect(deleteResult.commit.message).toBe( - `delete: users/${_id}${JSON_EXTENSION}(${shortOid})` + `delete: users/${_id}${JSON_POSTFIX}(${shortOid})` ); // Check commit directly @@ -335,7 +335,7 @@ describe('deleteFatDoc(name)', () => { dir: gitDDB.workingDir, oid: commitOid, }); - expect(commit.message).toEqual(`delete: users/${_id}${JSON_EXTENSION}(${shortOid})\n`); + expect(commit.message).toEqual(`delete: users/${_id}${JSON_POSTFIX}(${shortOid})\n`); await expect(users.delete(_id)).rejects.toThrowError(Err.DocumentNotFoundError); await expect(users.get(_id)).resolves.toBeUndefined(); @@ -371,12 +371,12 @@ describe('deleteFatDoc(name)', () => { const shortOid = putResult.fileOid.substr(0, SHORT_SHA_LENGTH); // Delete const deleteResult = (await users.deleteFatDoc( - _id + JSON_EXTENSION + _id + JSON_POSTFIX )) as DeleteResultJsonDoc; expect(deleteResult._id).toBe(_id); expect(deleteResult.fileOid).toBe(putResult.fileOid); expect(deleteResult.commit.message).toBe( - `delete: ${users.collectionPath}${_id}${JSON_EXTENSION}(${shortOid})` + `delete: ${users.collectionPath}${_id}${JSON_POSTFIX}(${shortOid})` ); // Check commit directly @@ -387,7 +387,7 @@ describe('deleteFatDoc(name)', () => { oid: commitOid, }); expect(commit.message).toEqual( - `delete: ${users.collectionPath}${_id}${JSON_EXTENSION}(${shortOid})\n` + `delete: ${users.collectionPath}${_id}${JSON_POSTFIX}(${shortOid})\n` ); await expect(users.delete(_id)).rejects.toThrowError(Err.DocumentNotFoundError); diff --git a/test/collection_find.test.ts b/test/collection_find.test.ts index 9f71ba57..deeb5ffd 100644 --- a/test/collection_find.test.ts +++ b/test/collection_find.test.ts @@ -13,7 +13,7 @@ import git from 'isomorphic-git'; import expect from 'expect'; import { monotonicFactory } from 'ulid'; import { Collection } from '../src/collection'; -import { JSON_EXTENSION } from '../src/const'; +import { JSON_POSTFIX } from '../src/const'; import { toSortedJSONString } from '../src/utils'; import { GitDocumentDB } from '../src/git_documentdb'; import { Err } from '../src/error'; @@ -70,7 +70,7 @@ describe('', () => { const col = new Collection(gitDDB, 'col01'); await addOneData( gitDDB, - col.collectionPath + 'invalidJSON' + JSON_EXTENSION, + col.collectionPath + 'invalidJSON' + JSON_POSTFIX, 'invalidJSON' ); @@ -117,27 +117,27 @@ describe('', () => { await addOneData( gitDDB, - col.collectionPath + _id_b + JSON_EXTENSION, + col.collectionPath + _id_b + JSON_POSTFIX, toSortedJSONString(json_b) ); await addOneData( gitDDB, - col.collectionPath + _id_a + JSON_EXTENSION, + col.collectionPath + _id_a + JSON_POSTFIX, toSortedJSONString(json_a) ); await addOneData( gitDDB, - col.collectionPath + _id_d + JSON_EXTENSION, + col.collectionPath + _id_d + JSON_POSTFIX, toSortedJSONString(json_d) ); await addOneData( gitDDB, - col.collectionPath + _id_c01 + JSON_EXTENSION, + col.collectionPath + _id_c01 + JSON_POSTFIX, toSortedJSONString(json_c01) ); await addOneData( gitDDB, - col.collectionPath + _id_c02 + JSON_EXTENSION, + col.collectionPath + _id_c02 + JSON_POSTFIX, toSortedJSONString(json_c02) ); @@ -180,37 +180,37 @@ describe('', () => { await addOneData( gitDDB, - col.collectionPath + _id_b + JSON_EXTENSION, + col.collectionPath + _id_b + JSON_POSTFIX, toSortedJSONString(json_b) ); await addOneData( gitDDB, - col.collectionPath + _id_a + JSON_EXTENSION, + col.collectionPath + _id_a + JSON_POSTFIX, toSortedJSONString(json_a) ); await addOneData( gitDDB, - col.collectionPath + _id_d + JSON_EXTENSION, + col.collectionPath + _id_d + JSON_POSTFIX, toSortedJSONString(json_d) ); await addOneData( gitDDB, - col.collectionPath + _id_c000 + JSON_EXTENSION, + col.collectionPath + _id_c000 + JSON_POSTFIX, toSortedJSONString(json_c000) ); await addOneData( gitDDB, - col.collectionPath + _id_c001 + JSON_EXTENSION, + col.collectionPath + _id_c001 + JSON_POSTFIX, toSortedJSONString(json_c001) ); await addOneData( gitDDB, - col.collectionPath + _id_c01 + JSON_EXTENSION, + col.collectionPath + _id_c01 + JSON_POSTFIX, toSortedJSONString(json_c01) ); await addOneData( gitDDB, - col.collectionPath + _id_c02 + JSON_EXTENSION, + col.collectionPath + _id_c02 + JSON_POSTFIX, toSortedJSONString(json_c02) ); @@ -248,37 +248,37 @@ describe('', () => { await addOneData( gitDDB, - col.collectionPath + _id_b + JSON_EXTENSION, + col.collectionPath + _id_b + JSON_POSTFIX, toSortedJSONString(json_b) ); await addOneData( gitDDB, - col.collectionPath + _id_a + JSON_EXTENSION, + col.collectionPath + _id_a + JSON_POSTFIX, toSortedJSONString(json_a) ); await addOneData( gitDDB, - col.collectionPath + _id_d + JSON_EXTENSION, + col.collectionPath + _id_d + JSON_POSTFIX, toSortedJSONString(json_d) ); await addOneData( gitDDB, - col.collectionPath + _id_c000 + JSON_EXTENSION, + col.collectionPath + _id_c000 + JSON_POSTFIX, toSortedJSONString(json_c000) ); await addOneData( gitDDB, - col.collectionPath + _id_c001 + JSON_EXTENSION, + col.collectionPath + _id_c001 + JSON_POSTFIX, toSortedJSONString(json_c001) ); await addOneData( gitDDB, - col.collectionPath + _id_c01 + JSON_EXTENSION, + col.collectionPath + _id_c01 + JSON_POSTFIX, toSortedJSONString(json_c01) ); await addOneData( gitDDB, - col.collectionPath + _id_c02 + JSON_EXTENSION, + col.collectionPath + _id_c02 + JSON_POSTFIX, toSortedJSONString(json_c02) ); @@ -319,37 +319,37 @@ describe('', () => { await addOneData( gitDDB, - col.collectionPath + _id_b + JSON_EXTENSION, + col.collectionPath + _id_b + JSON_POSTFIX, toSortedJSONString(json_b) ); await addOneData( gitDDB, - col.collectionPath + _id_a + JSON_EXTENSION, + col.collectionPath + _id_a + JSON_POSTFIX, toSortedJSONString(json_a) ); await addOneData( gitDDB, - col.collectionPath + _id_d + JSON_EXTENSION, + col.collectionPath + _id_d + JSON_POSTFIX, toSortedJSONString(json_d) ); await addOneData( gitDDB, - col.collectionPath + _id_c000 + JSON_EXTENSION, + col.collectionPath + _id_c000 + JSON_POSTFIX, toSortedJSONString(json_c000) ); await addOneData( gitDDB, - col.collectionPath + _id_c001 + JSON_EXTENSION, + col.collectionPath + _id_c001 + JSON_POSTFIX, toSortedJSONString(json_c001) ); await addOneData( gitDDB, - col.collectionPath + _id_c01 + JSON_EXTENSION, + col.collectionPath + _id_c01 + JSON_POSTFIX, toSortedJSONString(json_c01) ); await addOneData( gitDDB, - col.collectionPath + _id_c02 + JSON_EXTENSION, + col.collectionPath + _id_c02 + JSON_POSTFIX, toSortedJSONString(json_c02) ); @@ -392,37 +392,37 @@ describe('', () => { await addOneData( gitDDB, - col.collectionPath + _id_b + JSON_EXTENSION, + col.collectionPath + _id_b + JSON_POSTFIX, toSortedJSONString(json_b) ); await addOneData( gitDDB, - col.collectionPath + _id_a + JSON_EXTENSION, + col.collectionPath + _id_a + JSON_POSTFIX, toSortedJSONString(json_a) ); await addOneData( gitDDB, - col.collectionPath + _id_d + JSON_EXTENSION, + col.collectionPath + _id_d + JSON_POSTFIX, toSortedJSONString(json_d) ); await addOneData( gitDDB, - col.collectionPath + _id_c000 + JSON_EXTENSION, + col.collectionPath + _id_c000 + JSON_POSTFIX, toSortedJSONString(json_c000) ); await addOneData( gitDDB, - col.collectionPath + _id_c001 + JSON_EXTENSION, + col.collectionPath + _id_c001 + JSON_POSTFIX, toSortedJSONString(json_c001) ); await addOneData( gitDDB, - col.collectionPath + _id_c01 + JSON_EXTENSION, + col.collectionPath + _id_c01 + JSON_POSTFIX, toSortedJSONString(json_c01) ); await addOneData( gitDDB, - col.collectionPath + _id_c02 + JSON_EXTENSION, + col.collectionPath + _id_c02 + JSON_POSTFIX, toSortedJSONString(json_c02) ); @@ -460,37 +460,37 @@ describe('', () => { await addOneData( gitDDB, - col.collectionPath + _id_b + JSON_EXTENSION, + col.collectionPath + _id_b + JSON_POSTFIX, toSortedJSONString(json_b) ); await addOneData( gitDDB, - col.collectionPath + _id_a + JSON_EXTENSION, + col.collectionPath + _id_a + JSON_POSTFIX, toSortedJSONString(json_a) ); await addOneData( gitDDB, - col.collectionPath + _id_d + JSON_EXTENSION, + col.collectionPath + _id_d + JSON_POSTFIX, toSortedJSONString(json_d) ); await addOneData( gitDDB, - col.collectionPath + _id_c000 + JSON_EXTENSION, + col.collectionPath + _id_c000 + JSON_POSTFIX, toSortedJSONString(json_c000) ); await addOneData( gitDDB, - col.collectionPath + _id_c001 + JSON_EXTENSION, + col.collectionPath + _id_c001 + JSON_POSTFIX, toSortedJSONString(json_c001) ); await addOneData( gitDDB, - col.collectionPath + _id_c01 + JSON_EXTENSION, + col.collectionPath + _id_c01 + JSON_POSTFIX, toSortedJSONString(json_c01) ); await addOneData( gitDDB, - col.collectionPath + _id_c02 + JSON_EXTENSION, + col.collectionPath + _id_c02 + JSON_POSTFIX, toSortedJSONString(json_c02) ); @@ -531,43 +531,43 @@ describe('', () => { await addOneData( gitDDB, - col.collectionPath + _id_p + JSON_EXTENSION, + col.collectionPath + _id_p + JSON_POSTFIX, toSortedJSONString(json_p) ); await addOneData( gitDDB, - col.collectionPath + _id_b + JSON_EXTENSION, + col.collectionPath + _id_b + JSON_POSTFIX, toSortedJSONString(json_b) ); await addOneData( gitDDB, - col.collectionPath + _id_a + JSON_EXTENSION, + col.collectionPath + _id_a + JSON_POSTFIX, toSortedJSONString(json_a) ); await addOneData( gitDDB, - col.collectionPath + _id_d + JSON_EXTENSION, + col.collectionPath + _id_d + JSON_POSTFIX, toSortedJSONString(json_d) ); await addOneData( gitDDB, - col.collectionPath + _id_c000 + JSON_EXTENSION, + col.collectionPath + _id_c000 + JSON_POSTFIX, toSortedJSONString(json_c000) ); await addOneData( gitDDB, - col.collectionPath + _id_c001 + JSON_EXTENSION, + col.collectionPath + _id_c001 + JSON_POSTFIX, toSortedJSONString(json_c001) ); await addOneData( gitDDB, - col.collectionPath + _id_c01 + JSON_EXTENSION, + col.collectionPath + _id_c01 + JSON_POSTFIX, toSortedJSONString(json_c01) ); await addOneData( gitDDB, - col.collectionPath + _id_c02 + JSON_EXTENSION, + col.collectionPath + _id_c02 + JSON_POSTFIX, toSortedJSONString(json_c02) ); @@ -608,43 +608,43 @@ describe('', () => { await addOneData( gitDDB, - col.collectionPath + _id_p + JSON_EXTENSION, + col.collectionPath + _id_p + JSON_POSTFIX, toSortedJSONString(json_p) ); await addOneData( gitDDB, - col.collectionPath + _id_b + JSON_EXTENSION, + col.collectionPath + _id_b + JSON_POSTFIX, toSortedJSONString(json_b) ); await addOneData( gitDDB, - col.collectionPath + _id_a + JSON_EXTENSION, + col.collectionPath + _id_a + JSON_POSTFIX, toSortedJSONString(json_a) ); await addOneData( gitDDB, - col.collectionPath + _id_d + JSON_EXTENSION, + col.collectionPath + _id_d + JSON_POSTFIX, toSortedJSONString(json_d) ); await addOneData( gitDDB, - col.collectionPath + _id_c000 + JSON_EXTENSION, + col.collectionPath + _id_c000 + JSON_POSTFIX, toSortedJSONString(json_c000) ); await addOneData( gitDDB, - col.collectionPath + _id_c001 + JSON_EXTENSION, + col.collectionPath + _id_c001 + JSON_POSTFIX, toSortedJSONString(json_c001) ); await addOneData( gitDDB, - col.collectionPath + _id_c01 + JSON_EXTENSION, + col.collectionPath + _id_c01 + JSON_POSTFIX, toSortedJSONString(json_c01) ); await addOneData( gitDDB, - col.collectionPath + _id_c02 + JSON_EXTENSION, + col.collectionPath + _id_c02 + JSON_POSTFIX, toSortedJSONString(json_c02) ); @@ -681,62 +681,62 @@ describe('', () => { await addOneData( gitDDB, - col.collectionPath + _id_b + JSON_EXTENSION, + col.collectionPath + _id_b + JSON_POSTFIX, toSortedJSONString(json_b) ); await addOneData( gitDDB, - col.collectionPath + _id_a + JSON_EXTENSION, + col.collectionPath + _id_a + JSON_POSTFIX, toSortedJSONString(json_a) ); await addOneData( gitDDB, - col.collectionPath + _id_d + JSON_EXTENSION, + col.collectionPath + _id_d + JSON_POSTFIX, toSortedJSONString(json_d) ); await addOneData( gitDDB, - col.collectionPath + _id_c01 + JSON_EXTENSION, + col.collectionPath + _id_c01 + JSON_POSTFIX, toSortedJSONString(json_c01) ); await addOneData( gitDDB, - col.collectionPath + _id_c02 + JSON_EXTENSION, + col.collectionPath + _id_c02 + JSON_POSTFIX, toSortedJSONString(json_c02) ); await expect(col.findFatDoc()).resolves.toEqual([ { _id: _id_a, - name: _id_a + JSON_EXTENSION, + name: _id_a + JSON_POSTFIX, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_a) })).oid, type: 'json', doc: json_a_, }, { _id: _id_b, - name: _id_b + JSON_EXTENSION, + name: _id_b + JSON_POSTFIX, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_b) })).oid, type: 'json', doc: json_b_, }, { _id: _id_c01, - name: _id_c01 + JSON_EXTENSION, + name: _id_c01 + JSON_POSTFIX, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_c01) })).oid, type: 'json', doc: json_c01_, }, { _id: _id_c02, - name: _id_c02 + JSON_EXTENSION, + name: _id_c02 + JSON_POSTFIX, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_c02) })).oid, type: 'json', doc: json_c02_, }, { _id: _id_d, - name: _id_d + JSON_EXTENSION, + name: _id_d + JSON_POSTFIX, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_d) })).oid, type: 'json', doc: json_d_, diff --git a/test/collection_get.test.ts b/test/collection_get.test.ts index ec11c05e..00d25dcc 100644 --- a/test/collection_get.test.ts +++ b/test/collection_get.test.ts @@ -12,7 +12,7 @@ import fs from 'fs-extra'; import git from 'isomorphic-git'; import expect from 'expect'; import { monotonicFactory } from 'ulid'; -import { JSON_EXTENSION } from '../src/const'; +import { JSON_POSTFIX } from '../src/const'; import { Collection } from '../src/collection'; import { sleep, toSortedJSONString } from '../src/utils'; import { GitDocumentDB } from '../src/git_documentdb'; @@ -69,7 +69,7 @@ describe(' get()', () => { const col = new Collection(gitDDB, 'col01'); const shortId = 'prof01'; - const fullDocPath = col.collectionPath + shortId + JSON_EXTENSION; + const fullDocPath = col.collectionPath + shortId + JSON_POSTFIX; await addOneData(gitDDB, fullDocPath, 'invalid data'); await expect(col.get(shortId)).rejects.toThrowError(Err.InvalidJsonObjectError); @@ -86,7 +86,7 @@ describe(' get()', () => { await gitDDB.open(); const col = new Collection(gitDDB, 'col01'); const shortId = 'prof01'; - const fullDocPath = col.collectionPath + shortId + JSON_EXTENSION; + const fullDocPath = col.collectionPath + shortId + JSON_POSTFIX; const json01 = { _id: shortId, name: 'v1' }; const json02 = { _id: shortId, name: 'v2' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json01)); @@ -119,7 +119,7 @@ describe(' get()', () => { await gitDDB.open(); const col = new Collection(gitDDB, 'col01'); const shortId = 'prof01'; - const fullDocPath = col.collectionPath + shortId + JSON_EXTENSION; + const fullDocPath = col.collectionPath + shortId + JSON_POSTFIX; const json01 = { _id: shortId, name: 'v1' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json01)); await removeOneData(gitDDB, fullDocPath); @@ -137,7 +137,7 @@ describe(' get()', () => { await gitDDB.open(); const col = new Collection(gitDDB, 'col01/col02/col03/'); const shortId = 'dir01/prof01'; - const fullDocPath = col.collectionPath + shortId + JSON_EXTENSION; + const fullDocPath = col.collectionPath + shortId + JSON_POSTFIX; const json01 = { _id: shortId, name: 'v1' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json01)); @@ -154,7 +154,7 @@ describe(' get()', () => { await gitDDB.open(); const col = new Collection(gitDDB, 'dir01/dir02/dir03'); const shortId = 'prof01'; - const fullDocPath = col.collectionPath + shortId + JSON_EXTENSION; + const fullDocPath = col.collectionPath + shortId + JSON_POSTFIX; const json01 = { _id: shortId, name: 'v1' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json01)); @@ -174,8 +174,8 @@ describe(' getFatDoc()', () => { await gitDDB.open(); const col = new Collection(gitDDB); const shortId = 'prof01'; - const shortName = shortId + JSON_EXTENSION; - const fullDocPath = col.collectionPath + shortId + JSON_EXTENSION; + const shortName = shortId + JSON_POSTFIX; + const fullDocPath = col.collectionPath + shortId + JSON_POSTFIX; const json01 = { _id: shortId, name: 'v1' }; const json02 = { _id: shortId, name: 'v2' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json01)); @@ -200,7 +200,7 @@ describe(' getFatDoc()', () => { await gitDDB.open(); const col = new Collection(gitDDB); const shortId = 'prof01'; - const shortName = shortId + JSON_EXTENSION; + const shortName = shortId + JSON_POSTFIX; await expect(col.getFatDoc(shortName)).resolves.toBeUndefined(); await gitDDB.destroy(); @@ -217,7 +217,7 @@ describe(' getDocByOid()', () => { await gitDDB.open(); const col = new Collection(gitDDB, 'col01/col02/col03/'); const shortId = 'dir01/prof01'; - const fullDocPath = col.collectionPath + shortId + JSON_EXTENSION; + const fullDocPath = col.collectionPath + shortId + JSON_POSTFIX; const json01 = { _id: shortId, name: 'v1' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json01)); const { oid } = await git.hashBlob({ object: toSortedJSONString(json01) }); @@ -234,7 +234,7 @@ describe(' getDocByOid()', () => { await gitDDB.open(); const col = new Collection(gitDDB, 'col01/col02/col03/'); const shortId = 'dir01/prof01'; - const fullDocPath = col.collectionPath + shortId + JSON_EXTENSION; + const fullDocPath = col.collectionPath + shortId + JSON_POSTFIX; const json01 = { _id: shortId, name: 'v1' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json01)); await expect(col.getDocByOid('not exist', 'json')).resolves.toBeUndefined(); @@ -250,7 +250,7 @@ describe(' getDocByOid()', () => { await gitDDB.open(); const col = new Collection(gitDDB, 'col01/col02/col03/'); const shortId = 'dir01/prof01'; - const shortName = shortId + JSON_EXTENSION; + const shortName = shortId + JSON_POSTFIX; const fullDocPath = col.collectionPath + shortName; // JsonDoc without _id const json01 = { name: 'v1' }; @@ -269,10 +269,10 @@ describe('', () => { }); const targetId = '01'; - const targetName = targetId + JSON_EXTENSION; + const targetName = targetId + JSON_POSTFIX; const collectionPath = 'col01/'; const col = new Collection(gitDDB, collectionPath); - const fullDocPath = collectionPath + targetId + JSON_EXTENSION; + const fullDocPath = collectionPath + targetId + JSON_POSTFIX; const json01 = { _id: collectionPath + targetId, name: 'v01' }; const json02 = { _id: collectionPath + targetId, name: 'v02' }; @@ -720,7 +720,7 @@ describe(' getFatDocHistory()', () => { const col = new Collection(gitDDB, 'col01'); const _idA = 'profA'; - const shortNameA = _idA + JSON_EXTENSION; + const shortNameA = _idA + JSON_POSTFIX; const jsonA01 = { _id: _idA, name: 'v01' }; const jsonA02 = { _id: _idA, name: 'v02' }; const jsonA03 = { _id: _idA, name: 'v03' }; @@ -728,7 +728,7 @@ describe(' getFatDocHistory()', () => { await col.put(jsonA02); await col.put(jsonA03); const _idB = 'profB'; - const shortNameB = _idB + JSON_EXTENSION; + const shortNameB = _idB + JSON_POSTFIX; const jsonB01 = { _id: _idB, name: 'v01' }; const jsonB02 = { _id: _idB, name: 'v02' }; await col.put(jsonB01); @@ -757,7 +757,7 @@ describe(' getFatDocHistory()', () => { await gitDDB.open(); const col = new Collection(gitDDB, 'col01'); const _idA = 'profA'; - const shortNameA = _idA + JSON_EXTENSION; + const shortNameA = _idA + JSON_POSTFIX; const jsonA01 = { _id: _idA, name: 'v01' }; const jsonA02 = { _id: _idA, name: 'v02' }; const jsonA03 = { _id: _idA, name: 'v03' }; @@ -772,7 +772,7 @@ describe(' getFatDocHistory()', () => { await col.put(jsonA03); const _idB = 'profB'; - const shortNameB = _idB + JSON_EXTENSION; + const shortNameB = _idB + JSON_POSTFIX; const jsonB01 = { _id: _idB, name: 'v01' }; const jsonB02 = { _id: _idB, name: 'v02' }; diff --git a/test/collection_insert.test.ts b/test/collection_insert.test.ts index 345c1c3f..cc0a3554 100644 --- a/test/collection_insert.test.ts +++ b/test/collection_insert.test.ts @@ -14,7 +14,7 @@ import expect from 'expect'; import { monotonicFactory } from 'ulid'; import { PutResultJsonDoc } from '../src/types'; import { Collection } from '../src/collection'; -import { JSON_EXTENSION, SHORT_SHA_LENGTH } from '../src/const'; +import { JSON_POSTFIX, SHORT_SHA_LENGTH } from '../src/const'; import { toSortedJSONString } from '../src/utils'; import { GitDocumentDB } from '../src/git_documentdb'; import { Err } from '../src/error'; @@ -87,7 +87,7 @@ describe(' insert(jsonDoc)', () => { expect(putResult.fileOid).toBe(fileOid); expect(putResult.commit.oid).toBe(currentCommitOid); expect(putResult.commit.message).toBe( - `insert: ${col.collectionPath}${_id}${JSON_EXTENSION}(${shortOid})` + `insert: ${col.collectionPath}${_id}${JSON_POSTFIX}(${shortOid})` ); expect(putResult.commit.parent).toEqual([prevCommitOid]); @@ -104,7 +104,7 @@ describe(' insert(jsonDoc)', () => { const filePath = path.resolve( gitDDB.workingDir, col.collectionPath, - _id + JSON_EXTENSION + _id + JSON_POSTFIX ); await expect(fs.access(filePath)).resolves.not.toThrowError(); @@ -149,7 +149,7 @@ describe(' insert(jsonDoc)', () => { const fileOid = (await git.hashBlob({ object: toSortedJSONString(internalJson) })).oid; const shortOid = fileOid.substr(0, SHORT_SHA_LENGTH); expect(putResult.commit.message).toBe( - `insert: ${col.collectionPath}${_id}${JSON_EXTENSION}(${shortOid})` + `insert: ${col.collectionPath}${_id}${JSON_POSTFIX}(${shortOid})` ); await gitDDB.destroy(); @@ -208,7 +208,7 @@ describe(' insert(shortId, jsonDoc)', () => { expect(putResult.fileOid).toBe(fileOid); expect(putResult.commit.oid).toBe(currentCommitOid); expect(putResult.commit.message).toBe( - `insert: ${col.collectionPath}${_id}${JSON_EXTENSION}(${shortOid})` + `insert: ${col.collectionPath}${_id}${JSON_POSTFIX}(${shortOid})` ); expect(putResult.commit.parent).toEqual([prevCommitOid]); @@ -225,7 +225,7 @@ describe(' insert(shortId, jsonDoc)', () => { const filePath = path.resolve( gitDDB.workingDir, col.collectionPath, - _id + JSON_EXTENSION + _id + JSON_POSTFIX ); await expect(fs.access(filePath)).resolves.not.toThrowError(); @@ -272,7 +272,7 @@ describe(' insertFatDoc(shortName, jsonDoc)', () => { const col = new Collection(gitDDB, 'col01'); const _id = 'prof01'; - const shortName = _id + JSON_EXTENSION; + const shortName = _id + JSON_POSTFIX; const json = { _id, name: 'Shirase' }; const internalJson = JSON.parse(JSON.stringify(json)); internalJson._id = col.collectionPath + _id; @@ -294,7 +294,7 @@ describe(' insertFatDoc(shortName, jsonDoc)', () => { expect(putResult.fileOid).toBe(fileOid); expect(putResult.commit.oid).toBe(currentCommitOid); expect(putResult.commit.message).toBe( - `insert: ${col.collectionPath}${_id}${JSON_EXTENSION}(${shortOid})` + `insert: ${col.collectionPath}${_id}${JSON_POSTFIX}(${shortOid})` ); expect(putResult.commit.parent).toEqual([prevCommitOid]); @@ -311,7 +311,7 @@ describe(' insertFatDoc(shortName, jsonDoc)', () => { const filePath = path.resolve( gitDDB.workingDir, col.collectionPath, - _id + JSON_EXTENSION + _id + JSON_POSTFIX ); await expect(fs.access(filePath)).resolves.not.toThrowError(); diff --git a/test/collection_put.test.ts b/test/collection_put.test.ts index 998c6cab..4bb91ab0 100644 --- a/test/collection_put.test.ts +++ b/test/collection_put.test.ts @@ -14,7 +14,7 @@ import fs from 'fs-extra'; import { monotonicFactory } from 'ulid'; import { PutResultJsonDoc } from '../src/types'; import { toSortedJSONString } from '../src/utils'; -import { JSON_EXTENSION, SHORT_SHA_LENGTH } from '../src/const'; +import { JSON_POSTFIX, SHORT_SHA_LENGTH } from '../src/const'; import { GitDocumentDB } from '../src/git_documentdb'; import { Err } from '../src/error'; import { Collection } from '../src/collection'; @@ -247,7 +247,7 @@ describe('', () => { oid: commitOid, }); expect(commit.message).toEqual( - `insert: ${col.collectionPath}${_id}${JSON_EXTENSION}(${shortOid})\n` + `insert: ${col.collectionPath}${_id}${JSON_POSTFIX}(${shortOid})\n` ); // Check filename @@ -255,7 +255,7 @@ describe('', () => { const filePath = path.resolve( gitDDB.workingDir, col.collectionPath, - _id + JSON_EXTENSION + _id + JSON_POSTFIX ); await expect(fs.access(filePath)).resolves.not.toThrowError(); // Read JSON and check doc._id @@ -302,7 +302,7 @@ describe('', () => { expect(putResult.fileOid).toBe(fileOid); expect(putResult.commit.oid).toBe(currentCommitOid); expect(putResult.commit.message).toBe( - `insert: ${col.collectionPath}${_id}${JSON_EXTENSION}(${shortOid})` + `insert: ${col.collectionPath}${_id}${JSON_POSTFIX}(${shortOid})` ); expect(putResult.commit.parent).toEqual([prevCommitOid]); @@ -319,7 +319,7 @@ describe('', () => { const filePath = path.resolve( gitDDB.workingDir, col.collectionPath, - _id + JSON_EXTENSION + _id + JSON_POSTFIX ); await expect(fs.access(filePath)).resolves.not.toThrowError(); expect(fs.readFileSync(filePath, 'utf8')).toBe(toSortedJSONString(internalJson)); @@ -345,7 +345,7 @@ describe('', () => { .oid; const shortOid = fileOid.substr(0, SHORT_SHA_LENGTH); expect(putResult.commit.message).toBe( - `insert: ${col.collectionPath}${_id}${JSON_EXTENSION}(${shortOid})` + `insert: ${col.collectionPath}${_id}${JSON_POSTFIX}(${shortOid})` ); await gitDDB.destroy(); @@ -369,7 +369,7 @@ describe('', () => { // fs.access() throw error when a file cannot be accessed. const filePath = path.resolve( gitDDB.workingDir, - col.collectionPath + _id + JSON_EXTENSION + col.collectionPath + _id + JSON_POSTFIX ); await expect(fs.access(filePath)).resolves.not.toThrowError(); // Read JSON and check doc._id @@ -395,14 +395,14 @@ describe('', () => { await git.hashBlob({ object: toSortedJSONString(internalJson) }) ).oid.substr(0, SHORT_SHA_LENGTH); expect(putResult.commit.message).toBe( - `insert: ${col.collectionPath}${_id}${JSON_EXTENSION}(${shortOid})` + `insert: ${col.collectionPath}${_id}${JSON_POSTFIX}(${shortOid})` ); // Check filename // fs.access() throw error when a file cannot be accessed. const filePath = path.resolve( gitDDB.workingDir, - col.collectionPath + _id + JSON_EXTENSION + col.collectionPath + _id + JSON_POSTFIX ); await expect(fs.access(filePath)).resolves.not.toThrowError(); expect(fs.readFileSync(filePath, 'utf8')).toBe(toSortedJSONString(internalJson)); @@ -419,7 +419,7 @@ describe('', () => { oid: commitOid, }); expect(commit.message).toEqual( - `insert: ${col.collectionPath}${_id}${JSON_EXTENSION}(${shortOid})\n` + `insert: ${col.collectionPath}${_id}${JSON_POSTFIX}(${shortOid})\n` ); gitDDB.destroy(); @@ -505,7 +505,7 @@ describe('', () => { const putResult = await col.put(updatedJson); expect(putResult.commit.message).toBe( - `update: ${col.collectionPath}${_id}${JSON_EXTENSION}(${fileOid.substr( + `update: ${col.collectionPath}${_id}${JSON_POSTFIX}(${fileOid.substr( 0, SHORT_SHA_LENGTH )})` @@ -632,7 +632,7 @@ describe('', () => { expect(putResult.fileOid).toBe(fileOid); expect(putResult.commit.oid).toBe(currentCommitOid); expect(putResult.commit.message).toBe( - `insert: ${col.collectionPath}${_id}${JSON_EXTENSION}(${shortOid})` + `insert: ${col.collectionPath}${_id}${JSON_POSTFIX}(${shortOid})` ); expect(putResult.commit.parent).toEqual([prevCommitOid]); @@ -649,7 +649,7 @@ describe('', () => { const filePath = path.resolve( gitDDB.workingDir, col.collectionPath, - _id + JSON_EXTENSION + _id + JSON_POSTFIX ); await expect(fs.access(filePath)).resolves.not.toThrowError(); expect(fs.readFileSync(filePath, 'utf8')).toBe(toSortedJSONString(internalJson)); @@ -705,14 +705,14 @@ describe('', () => { expect(putResult._id).toBe(_id); expect(putResult.commit.message).toBe( - `insert: ${col.collectionPath}${_id}${JSON_EXTENSION}(${shortOid})` + `insert: ${col.collectionPath}${_id}${JSON_POSTFIX}(${shortOid})` ); // _id of original json must not be overwritten expect(json._id).toBe('id-in-doc'); // fs.access() throw error when a file cannot be accessed. - const fullDocPath = col.collectionPath + _id + JSON_EXTENSION; + const fullDocPath = col.collectionPath + _id + JSON_POSTFIX; const filePath = path.resolve(gitDDB.workingDir, fullDocPath); await expect(fs.access(filePath)).resolves.not.toThrowError(); expect(fs.readFileSync(filePath, 'utf8')).toBe(toSortedJSONString(internalJson)); @@ -742,7 +742,7 @@ describe('', () => { const filePath = path.resolve( gitDDB.workingDir, - col.collectionPath + 'id' + JSON_EXTENSION + col.collectionPath + 'id' + JSON_POSTFIX ); const jsonStr = fs.readFileSync(filePath, 'utf8'); expect(jsonStr).toBe(`{ @@ -786,7 +786,7 @@ describe('', () => { const filePath = path.resolve( gitDDB.workingDir, col.collectionPath, - putResult._id + JSON_EXTENSION + putResult._id + JSON_POSTFIX ); await expect(fs.access(filePath)).resolves.not.toThrowError(); @@ -824,7 +824,7 @@ describe('', () => { const col = new Collection(gitDDB, 'col01'); const _id = 'dir01/prof01'; - const shortName = _id + JSON_EXTENSION; + const shortName = _id + JSON_POSTFIX; // Check put operation const json = { _id, name: 'Shirase' }; @@ -848,7 +848,7 @@ describe('', () => { expect(putResult.fileOid).toBe(fileOid); expect(putResult.commit.oid).toBe(currentCommitOid); expect(putResult.commit.message).toBe( - `insert: ${col.collectionPath}${_id}${JSON_EXTENSION}(${shortOid})` + `insert: ${col.collectionPath}${_id}${JSON_POSTFIX}(${shortOid})` ); expect(putResult.commit.parent).toEqual([prevCommitOid]); @@ -865,7 +865,7 @@ describe('', () => { const filePath = path.resolve( gitDDB.workingDir, col.collectionPath, - _id + JSON_EXTENSION + _id + JSON_POSTFIX ); await expect(fs.access(filePath)).resolves.not.toThrowError(); expect(fs.readFileSync(filePath, 'utf8')).toBe(toSortedJSONString(internalJson)); diff --git a/test/collection_update.test.ts b/test/collection_update.test.ts index cbd41e54..434ef251 100644 --- a/test/collection_update.test.ts +++ b/test/collection_update.test.ts @@ -17,7 +17,7 @@ import { Err } from '../src/error'; import { GitDocumentDB } from '../src/git_documentdb'; import { Collection } from '../src/collection'; import { toSortedJSONString } from '../src/utils'; -import { JSON_EXTENSION, SHORT_SHA_LENGTH } from '../src/const'; +import { JSON_POSTFIX, SHORT_SHA_LENGTH } from '../src/const'; const ulid = monotonicFactory(); const monoId = () => { @@ -85,7 +85,7 @@ describe(' update(jsonDoc)', () => { expect(putResult.fileOid).toBe(fileOid); expect(putResult.commit.oid).toBe(currentCommitOid); expect(putResult.commit.message).toBe( - `update: ${col.collectionPath}${_id}${JSON_EXTENSION}(${shortOid})` + `update: ${col.collectionPath}${_id}${JSON_POSTFIX}(${shortOid})` ); expect(putResult.commit.parent).toEqual([prevCommitOid]); @@ -102,7 +102,7 @@ describe(' update(jsonDoc)', () => { const filePath = path.resolve( gitDDB.workingDir, col.collectionPath, - _id + JSON_EXTENSION + _id + JSON_POSTFIX ); await expect(fs.access(filePath)).resolves.not.toThrowError(); @@ -151,7 +151,7 @@ describe(' update(jsonDoc)', () => { const fileOid = (await git.hashBlob({ object: toSortedJSONString(internalJson) })).oid; const shortOid = fileOid.substr(0, SHORT_SHA_LENGTH); expect(putResult.commit.message).toBe( - `update: ${col.collectionPath}${_id}${JSON_EXTENSION}(${shortOid})` + `update: ${col.collectionPath}${_id}${JSON_POSTFIX}(${shortOid})` ); await gitDDB.destroy(); @@ -208,7 +208,7 @@ describe(' update(shortId, jsonDoc)', () => { expect(putResult.fileOid).toBe(fileOid); expect(putResult.commit.oid).toBe(currentCommitOid); expect(putResult.commit.message).toBe( - `update: ${col.collectionPath}${_id}${JSON_EXTENSION}(${shortOid})` + `update: ${col.collectionPath}${_id}${JSON_POSTFIX}(${shortOid})` ); expect(putResult.commit.parent).toEqual([prevCommitOid]); @@ -225,7 +225,7 @@ describe(' update(shortId, jsonDoc)', () => { const filePath = path.resolve( gitDDB.workingDir, col.collectionPath, - _id + JSON_EXTENSION + _id + JSON_POSTFIX ); await expect(fs.access(filePath)).resolves.not.toThrowError(); @@ -267,7 +267,7 @@ describe(' updateFatDoc(shortName, jsonDoc)', () => { await gitDDB.open(); const col = new Collection(gitDDB, 'col01'); const _id = 'prof01'; - const shortName = _id + JSON_EXTENSION; + const shortName = _id + JSON_POSTFIX; const json = { _id, name: 'Shirase' }; const insertResult = await col.insert(json); @@ -294,7 +294,7 @@ describe(' updateFatDoc(shortName, jsonDoc)', () => { expect(putResult.fileOid).toBe(fileOid); expect(putResult.commit.oid).toBe(currentCommitOid); expect(putResult.commit.message).toBe( - `update: ${col.collectionPath}${_id}${JSON_EXTENSION}(${shortOid})` + `update: ${col.collectionPath}${_id}${JSON_POSTFIX}(${shortOid})` ); expect(putResult.commit.parent).toEqual([prevCommitOid]); @@ -311,7 +311,7 @@ describe(' updateFatDoc(shortName, jsonDoc)', () => { const filePath = path.resolve( gitDDB.workingDir, col.collectionPath, - _id + JSON_EXTENSION + _id + JSON_POSTFIX ); await expect(fs.access(filePath)).resolves.not.toThrowError(); diff --git a/test/crud/blob.test.ts b/test/crud/blob.test.ts index 87691bd5..f3677663 100644 --- a/test/crud/blob.test.ts +++ b/test/crud/blob.test.ts @@ -24,7 +24,7 @@ import { import { Err } from '../../src/error'; import { GitDocumentDB } from '../../src/git_documentdb'; import { toSortedJSONString, utf8encode } from '../../src/utils'; -import { JSON_EXTENSION } from '../../src/const'; +import { JSON_POSTFIX } from '../../src/const'; // eslint-disable-next-line @typescript-eslint/no-var-requires const git_module = require('isomorphic-git'); @@ -61,9 +61,9 @@ describe('', () => { oid: (await git.hashBlob({ object: text })).oid, blob: utf8encode(text), }; - expect(() => blobToJsonDoc(shortId, readBlobResult, false)).toThrowError( - Err.InvalidJsonObjectError - ); + expect(() => + blobToJsonDoc(shortId, readBlobResult, false, JSON_POSTFIX) + ).toThrowError(Err.InvalidJsonObjectError); }); it('returns JsonDoc', async () => { @@ -74,7 +74,7 @@ describe('', () => { oid: (await git.hashBlob({ object: text })).oid, blob: utf8encode(text), }; - expect(blobToJsonDoc(shortId, readBlobResult, false)).toEqual(json); + expect(blobToJsonDoc(shortId, readBlobResult, false, JSON_POSTFIX)).toEqual(json); }); it('returns JsonDoc with overwritten _id', async () => { @@ -87,7 +87,7 @@ describe('', () => { oid: (await git.hashBlob({ object: text })).oid, blob: utf8encode(text), }; - expect(blobToJsonDoc(shortId2, readBlobResult, false)).toEqual(json2); + expect(blobToJsonDoc(shortId2, readBlobResult, false, JSON_POSTFIX)).toEqual(json2); }); it('returns FatJsonDoc', async () => { @@ -99,9 +99,9 @@ describe('', () => { oid: fileOid, blob: utf8encode(text), }; - expect(blobToJsonDoc(shortId, readBlobResult, true)).toEqual({ + expect(blobToJsonDoc(shortId, readBlobResult, true, JSON_POSTFIX)).toEqual({ _id: shortId, - name: shortId + JSON_EXTENSION, + name: shortId + JSON_POSTFIX, fileOid, type: 'json', doc: json, diff --git a/test/crud/delete.test.ts b/test/crud/delete.test.ts index 28e40d13..553754da 100644 --- a/test/crud/delete.test.ts +++ b/test/crud/delete.test.ts @@ -13,7 +13,7 @@ import fs from 'fs-extra'; import git from 'isomorphic-git'; import expect from 'expect'; import sinon from 'sinon'; -import { JSON_EXTENSION, SHORT_SHA_LENGTH } from '../../src/const'; +import { JSON_POSTFIX, SHORT_SHA_LENGTH } from '../../src/const'; import { Err } from '../../src/error'; import { GitDocumentDB } from '../../src/git_documentdb'; import { deleteImpl, deleteWorker } from '../../src/crud/delete'; @@ -67,7 +67,7 @@ describe('', () => { // Call close() without await gitDDB.close().catch(() => {}); const _id = 'prof01'; - await expect(deleteImpl(gitDDB, '', _id, _id + JSON_EXTENSION)).rejects.toThrowError( + await expect(deleteImpl(gitDDB, '', _id, _id + JSON_POSTFIX)).rejects.toThrowError( Err.DatabaseClosingError ); @@ -116,7 +116,7 @@ describe('', () => { const putResult = await gitDDB.put(json); await expect( - deleteImpl(gitDDB, '', _id, _id + JSON_EXTENSION + '_invalid') + deleteImpl(gitDDB, '', _id, _id + JSON_POSTFIX + '_invalid') ).rejects.toThrowError(Err.DocumentNotFoundError); await gitDDB.destroy(); @@ -139,7 +139,7 @@ describe('', () => { // Delete const { oid } = await git.hashBlob({ object: toSortedJSONString(json) }); const beforeTimestamp = Math.floor(Date.now() / 1000) * 1000; - const pickedDeleteResult = await deleteImpl(gitDDB, '', _id, _id + JSON_EXTENSION); + const pickedDeleteResult = await deleteImpl(gitDDB, '', _id, _id + JSON_POSTFIX); const afterTimestamp = Math.floor(Date.now() / 1000) * 1000; const currentCommitOid = await git.resolveRef({ @@ -151,7 +151,7 @@ describe('', () => { // Check NormalizedCommit expect(pickedDeleteResult.commit.oid).toBe(currentCommitOid); expect(pickedDeleteResult.commit.message).toBe( - `delete: ${_id}${JSON_EXTENSION}(${oid.substr(0, SHORT_SHA_LENGTH)})` + `delete: ${_id}${JSON_POSTFIX}(${oid.substr(0, SHORT_SHA_LENGTH)})` ); expect(pickedDeleteResult.commit.parent).toEqual([prevCommitOid]); expect(pickedDeleteResult.commit.author.name).toEqual(gitDDB.author.name); @@ -188,10 +188,10 @@ describe('', () => { // Delete const shortOid = putResult.fileOid.substr(0, SHORT_SHA_LENGTH); - const pickedDeleteResult = await deleteImpl(gitDDB, '', _id, _id + JSON_EXTENSION); + const pickedDeleteResult = await deleteImpl(gitDDB, '', _id, _id + JSON_POSTFIX); expect(pickedDeleteResult.commit.message).toEqual( - `delete: ${_id}${JSON_EXTENSION}(${shortOid})` + `delete: ${_id}${JSON_POSTFIX}(${shortOid})` ); // Check commit directly @@ -201,7 +201,7 @@ describe('', () => { dir: gitDDB.workingDir, oid: commitOid, }); - expect(commit.message).toEqual(`delete: ${_id}${JSON_EXTENSION}(${shortOid})\n`); + expect(commit.message).toEqual(`delete: ${_id}${JSON_POSTFIX}(${shortOid})\n`); await gitDDB.destroy(); }); @@ -219,12 +219,12 @@ describe('', () => { const putResult = await gitDDB.put(doc); // Delete - const deleteResult = await deleteImpl(gitDDB, '', _id, _id + JSON_EXTENSION); + const deleteResult = await deleteImpl(gitDDB, '', _id, _id + JSON_POSTFIX); const shortOid = putResult.fileOid.substr(0, SHORT_SHA_LENGTH); expect(deleteResult.fileOid).toBe(putResult.fileOid); expect(deleteResult.commit.message).toBe( - `delete: ${_id}${JSON_EXTENSION}(${shortOid})` + `delete: ${_id}${JSON_POSTFIX}(${shortOid})` ); // Check commit directly @@ -234,7 +234,7 @@ describe('', () => { dir: gitDDB.workingDir, oid: commitOid, }); - expect(commit.message).toEqual(`delete: ${_id}${JSON_EXTENSION}(${shortOid})\n`); + expect(commit.message).toEqual(`delete: ${_id}${JSON_POSTFIX}(${shortOid})\n`); await gitDDB.destroy(); }); @@ -271,17 +271,17 @@ describe('', () => { ]); await Promise.all([ - deleteImpl(gitDDB, '', _id_a, _id_a + JSON_EXTENSION), - deleteImpl(gitDDB, '', _id_b, _id_b + JSON_EXTENSION), - deleteImpl(gitDDB, '', _id_c01, _id_c01 + JSON_EXTENSION), - deleteImpl(gitDDB, '', _id_c02, _id_c02 + JSON_EXTENSION), - deleteImpl(gitDDB, '', _id_d, _id_d + JSON_EXTENSION), + deleteImpl(gitDDB, '', _id_a, _id_a + JSON_POSTFIX), + deleteImpl(gitDDB, '', _id_b, _id_b + JSON_POSTFIX), + deleteImpl(gitDDB, '', _id_c01, _id_c01 + JSON_POSTFIX), + deleteImpl(gitDDB, '', _id_c02, _id_c02 + JSON_POSTFIX), + deleteImpl(gitDDB, '', _id_d, _id_d + JSON_POSTFIX), ]); await expect(gitDDB.findFatDoc({ recursive: true })).resolves.toEqual([ { _id: _id_p, - name: _id_p + JSON_EXTENSION, + name: _id_p + JSON_POSTFIX, fileOid: expect.stringMatching(/^[\da-z]{40}$/), type: 'json', doc: { _id: _id_p, name: name_p }, @@ -387,7 +387,7 @@ describe('', () => { stubEnsureDir.rejects(); await expect( - deleteWorker(gitDDB, '', 'prof01' + JSON_EXTENSION, '') + deleteWorker(gitDDB, '', 'prof01' + JSON_POSTFIX, '') ).rejects.toThrowError(Err.CannotDeleteDataError); await gitDDB.destroy(); }); diff --git a/test/crud/find.test.ts b/test/crud/find.test.ts index 31851648..b954e412 100644 --- a/test/crud/find.test.ts +++ b/test/crud/find.test.ts @@ -17,7 +17,6 @@ import { GitDocumentDB } from '../../src/git_documentdb'; import { FIRST_COMMIT_MESSAGE, GIT_DOCUMENTDB_INFO_ID, - JSON_EXTENSION, JSON_POSTFIX, } from '../../src/const'; import { findImpl } from '../../src/crud/find'; @@ -81,7 +80,7 @@ describe(' find()', () => { } // Call close() without await gitDDB.close().catch(() => {}); - await expect(findImpl(gitDDB, '', true, false)).rejects.toThrowError( + await expect(findImpl(gitDDB, '', gitDDB.jsonExt, true, false)).rejects.toThrowError( Err.DatabaseClosingError ); while (gitDDB.isClosing) { @@ -99,9 +98,9 @@ describe(' find()', () => { }); await gitDDB.open(); - await addOneData(gitDDB, 'invalidJSON' + JSON_EXTENSION, 'invalidJSON'); + await addOneData(gitDDB, 'invalidJSON' + JSON_POSTFIX, 'invalidJSON'); - await expect(findImpl(gitDDB, '', true, false)).rejects.toThrowError( + await expect(findImpl(gitDDB, '', gitDDB.jsonExt, true, false)).rejects.toThrowError( Err.InvalidJsonObjectError ); @@ -138,11 +137,13 @@ describe(' find()', () => { const _id = '1'; const json = { _id }; - await addOneData(gitDDB, _id + JSON_EXTENSION, toSortedJSONString(json)); + await addOneData(gitDDB, _id + JSON_POSTFIX, toSortedJSONString(json)); await gitDDB.open(); - await expect(findImpl(gitDDB, '', true, false)).resolves.toEqual([json]); + await expect(findImpl(gitDDB, '', gitDDB.jsonExt, true, false)).resolves.toEqual([ + json, + ]); await gitDDB.destroy(); }); @@ -157,7 +158,7 @@ describe(' find()', () => { await gitDDB.open(); - await expect(findImpl(gitDDB, '', true, false)).resolves.toEqual([]); + await expect(findImpl(gitDDB, '', gitDDB.jsonExt, true, false)).resolves.toEqual([]); await gitDDB.destroy(); }); @@ -177,12 +178,12 @@ describe(' find()', () => { const json_1 = { _id: _id_1, name: name_1 }; const json_c = { _id: _id_c, name: name_c }; - await addOneData(gitDDB, _id_b + JSON_EXTENSION, toSortedJSONString(json_b)); - await addOneData(gitDDB, _id_a + JSON_EXTENSION, toSortedJSONString(json_a)); - await addOneData(gitDDB, _id_1 + JSON_EXTENSION, toSortedJSONString(json_1)); - await addOneData(gitDDB, _id_c + JSON_EXTENSION, toSortedJSONString(json_c)); + await addOneData(gitDDB, _id_b + JSON_POSTFIX, toSortedJSONString(json_b)); + await addOneData(gitDDB, _id_a + JSON_POSTFIX, toSortedJSONString(json_a)); + await addOneData(gitDDB, _id_1 + JSON_POSTFIX, toSortedJSONString(json_1)); + await addOneData(gitDDB, _id_c + JSON_POSTFIX, toSortedJSONString(json_c)); - await expect(findImpl(gitDDB, '', true, false)).resolves.toEqual([ + await expect(findImpl(gitDDB, '', gitDDB.jsonExt, true, false)).resolves.toEqual([ json_1, json_a, json_b, @@ -206,24 +207,21 @@ describe(' find()', () => { const json_1 = { _id: _id_1, name: name_1 }; const json_c = { _id: _id_c, name: name_c }; - await addOneData(gitDDB, _id_b + JSON_EXTENSION, toSortedJSONString(json_b)); - await addOneData(gitDDB, _id_a + JSON_EXTENSION, toSortedJSONString(json_a)); - await addOneData(gitDDB, _id_1 + JSON_EXTENSION, toSortedJSONString(json_1)); - await addOneData(gitDDB, _id_c + JSON_EXTENSION, toSortedJSONString(json_c)); + await addOneData(gitDDB, _id_b + JSON_POSTFIX, toSortedJSONString(json_b)); + await addOneData(gitDDB, _id_a + JSON_POSTFIX, toSortedJSONString(json_a)); + await addOneData(gitDDB, _id_1 + JSON_POSTFIX, toSortedJSONString(json_1)); + await addOneData(gitDDB, _id_c + JSON_POSTFIX, toSortedJSONString(json_c)); - await expect(findImpl(gitDDB, '', true, false)).resolves.toEqual([ + await expect(findImpl(gitDDB, '', gitDDB.jsonExt, true, false)).resolves.toEqual([ json_1, json_a, json_b, json_c, ]); - await expect(findImpl(gitDDB, '', true, false, { descending: true })).resolves.toEqual([ - json_c, - json_b, - json_a, - json_1, - ]); + await expect( + findImpl(gitDDB, '', gitDDB.jsonExt, true, false, { descending: true }) + ).resolves.toEqual([json_c, json_b, json_a, json_1]); await gitDDB.destroy(); }); @@ -242,13 +240,13 @@ describe(' find()', () => { const json_c01 = { _id: _id_c01, name: name_c01 }; const json_c02 = { _id: _id_c02, name: name_c02 }; - await addOneData(gitDDB, _id_b + JSON_EXTENSION, toSortedJSONString(json_b)); - await addOneData(gitDDB, _id_a + JSON_EXTENSION, toSortedJSONString(json_a)); - await addOneData(gitDDB, _id_d + JSON_EXTENSION, toSortedJSONString(json_d)); - await addOneData(gitDDB, _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01)); - await addOneData(gitDDB, _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02)); + await addOneData(gitDDB, _id_b + JSON_POSTFIX, toSortedJSONString(json_b)); + await addOneData(gitDDB, _id_a + JSON_POSTFIX, toSortedJSONString(json_a)); + await addOneData(gitDDB, _id_d + JSON_POSTFIX, toSortedJSONString(json_d)); + await addOneData(gitDDB, _id_c01 + JSON_POSTFIX, toSortedJSONString(json_c01)); + await addOneData(gitDDB, _id_c02 + JSON_POSTFIX, toSortedJSONString(json_c02)); - await expect(findImpl(gitDDB, '', true, false)).resolves.toEqual([ + await expect(findImpl(gitDDB, '', gitDDB.jsonExt, true, false)).resolves.toEqual([ json_a, json_b, json_c01, @@ -274,16 +272,15 @@ describe(' find()', () => { const json_c01 = { _id: _id_c01, name: name_c01 }; const json_c02 = { _id: _id_c02, name: name_c02 }; - await addOneData(gitDDB, _id_b + JSON_EXTENSION, toSortedJSONString(json_b)); - await addOneData(gitDDB, _id_a + JSON_EXTENSION, toSortedJSONString(json_a)); - await addOneData(gitDDB, _id_d + JSON_EXTENSION, toSortedJSONString(json_d)); - await addOneData(gitDDB, _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01)); - await addOneData(gitDDB, _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02)); + await addOneData(gitDDB, _id_b + JSON_POSTFIX, toSortedJSONString(json_b)); + await addOneData(gitDDB, _id_a + JSON_POSTFIX, toSortedJSONString(json_a)); + await addOneData(gitDDB, _id_d + JSON_POSTFIX, toSortedJSONString(json_d)); + await addOneData(gitDDB, _id_c01 + JSON_POSTFIX, toSortedJSONString(json_c01)); + await addOneData(gitDDB, _id_c02 + JSON_POSTFIX, toSortedJSONString(json_c02)); - await expect(findImpl(gitDDB, '', true, false, { recursive: false })).resolves.toEqual([ - json_a, - json_b, - ]); + await expect( + findImpl(gitDDB, '', gitDDB.jsonExt, true, false, { recursive: false }) + ).resolves.toEqual([json_a, json_b]); await gitDDB.destroy(); }); @@ -303,12 +300,15 @@ describe(' find()', () => { const json_1 = { _id: _id_1, name: name_1 }; const json_c = { _id: _id_c, name: name_c }; - await addOneData(gitDDB, _id_b + JSON_EXTENSION, toSortedJSONString(json_b)); - await addOneData(gitDDB, _id_a + JSON_EXTENSION, toSortedJSONString(json_a)); + await addOneData(gitDDB, _id_b + JSON_POSTFIX, toSortedJSONString(json_b)); + await addOneData(gitDDB, _id_a + JSON_POSTFIX, toSortedJSONString(json_a)); await addOneData(gitDDB, _id_1, toSortedJSONString(json_1)); await addOneData(gitDDB, _id_c, toSortedJSONString(json_c)); - await expect(findImpl(gitDDB, '', true, false)).resolves.toEqual([json_a, json_b]); + await expect(findImpl(gitDDB, '', gitDDB.jsonExt, true, false)).resolves.toEqual([ + json_a, + json_b, + ]); await gitDDB.destroy(); }); @@ -330,20 +330,19 @@ describe(' find()', () => { const json_c01 = { _id: _id_c01, name: name_c01 }; const json_c02 = { _id: _id_c02, name: name_c02 }; - await addOneData(gitDDB, _id_b + JSON_EXTENSION, toSortedJSONString(json_b)); - await addOneData(gitDDB, _id_a + JSON_EXTENSION, toSortedJSONString(json_a)); - await addOneData(gitDDB, _id_d + JSON_EXTENSION, toSortedJSONString(json_d)); - await addOneData(gitDDB, _id_c000 + JSON_EXTENSION, toSortedJSONString(json_c000)); - await addOneData(gitDDB, _id_c001 + JSON_EXTENSION, toSortedJSONString(json_c001)); - await addOneData(gitDDB, _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01)); - await addOneData(gitDDB, _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02)); + await addOneData(gitDDB, _id_b + JSON_POSTFIX, toSortedJSONString(json_b)); + await addOneData(gitDDB, _id_a + JSON_POSTFIX, toSortedJSONString(json_a)); + await addOneData(gitDDB, _id_d + JSON_POSTFIX, toSortedJSONString(json_d)); + await addOneData(gitDDB, _id_c000 + JSON_POSTFIX, toSortedJSONString(json_c000)); + await addOneData(gitDDB, _id_c001 + JSON_POSTFIX, toSortedJSONString(json_c001)); + await addOneData(gitDDB, _id_c01 + JSON_POSTFIX, toSortedJSONString(json_c01)); + await addOneData(gitDDB, _id_c02 + JSON_POSTFIX, toSortedJSONString(json_c02)); const prefix = 'citrus/'; - await expect(findImpl(gitDDB, '', true, false, { prefix })).resolves.toEqual([ - json_c01, - json_c02, - ]); + await expect( + findImpl(gitDDB, '', gitDDB.jsonExt, true, false, { prefix }) + ).resolves.toEqual([json_c01, json_c02]); await gitDDB.destroy(); }); @@ -364,18 +363,18 @@ describe(' find()', () => { const json_c01 = { _id: _id_c01, name: name_c01 }; const json_c02 = { _id: _id_c02, name: name_c02 }; - await addOneData(gitDDB, _id_b + JSON_EXTENSION, toSortedJSONString(json_b)); - await addOneData(gitDDB, _id_a + JSON_EXTENSION, toSortedJSONString(json_a)); - await addOneData(gitDDB, _id_d + JSON_EXTENSION, toSortedJSONString(json_d)); - await addOneData(gitDDB, _id_c000 + JSON_EXTENSION, toSortedJSONString(json_c000)); - await addOneData(gitDDB, _id_c001 + JSON_EXTENSION, toSortedJSONString(json_c001)); - await addOneData(gitDDB, _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01)); - await addOneData(gitDDB, _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02)); + await addOneData(gitDDB, _id_b + JSON_POSTFIX, toSortedJSONString(json_b)); + await addOneData(gitDDB, _id_a + JSON_POSTFIX, toSortedJSONString(json_a)); + await addOneData(gitDDB, _id_d + JSON_POSTFIX, toSortedJSONString(json_d)); + await addOneData(gitDDB, _id_c000 + JSON_POSTFIX, toSortedJSONString(json_c000)); + await addOneData(gitDDB, _id_c001 + JSON_POSTFIX, toSortedJSONString(json_c001)); + await addOneData(gitDDB, _id_c01 + JSON_POSTFIX, toSortedJSONString(json_c01)); + await addOneData(gitDDB, _id_c02 + JSON_POSTFIX, toSortedJSONString(json_c02)); const prefix = 'cit'; await expect( - findImpl(gitDDB, '', true, false, { prefix, recursive: false }) + findImpl(gitDDB, '', gitDDB.jsonExt, true, false, { prefix, recursive: false }) ).resolves.toEqual([json_c000, json_c001]); await gitDDB.destroy(); @@ -397,22 +396,19 @@ describe(' find()', () => { const json_c01 = { _id: _id_c01, name: name_c01 }; const json_c02 = { _id: _id_c02, name: name_c02 }; - await addOneData(gitDDB, _id_b + JSON_EXTENSION, toSortedJSONString(json_b)); - await addOneData(gitDDB, _id_a + JSON_EXTENSION, toSortedJSONString(json_a)); - await addOneData(gitDDB, _id_d + JSON_EXTENSION, toSortedJSONString(json_d)); - await addOneData(gitDDB, _id_c000 + JSON_EXTENSION, toSortedJSONString(json_c000)); - await addOneData(gitDDB, _id_c001 + JSON_EXTENSION, toSortedJSONString(json_c001)); - await addOneData(gitDDB, _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01)); - await addOneData(gitDDB, _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02)); + await addOneData(gitDDB, _id_b + JSON_POSTFIX, toSortedJSONString(json_b)); + await addOneData(gitDDB, _id_a + JSON_POSTFIX, toSortedJSONString(json_a)); + await addOneData(gitDDB, _id_d + JSON_POSTFIX, toSortedJSONString(json_d)); + await addOneData(gitDDB, _id_c000 + JSON_POSTFIX, toSortedJSONString(json_c000)); + await addOneData(gitDDB, _id_c001 + JSON_POSTFIX, toSortedJSONString(json_c001)); + await addOneData(gitDDB, _id_c01 + JSON_POSTFIX, toSortedJSONString(json_c01)); + await addOneData(gitDDB, _id_c02 + JSON_POSTFIX, toSortedJSONString(json_c02)); const prefix = 'citrus'; - await expect(findImpl(gitDDB, '', true, false, { prefix })).resolves.toEqual([ - json_c000, - json_c001, - json_c01, - json_c02, - ]); + await expect( + findImpl(gitDDB, '', gitDDB.jsonExt, true, false, { prefix }) + ).resolves.toEqual([json_c000, json_c001, json_c01, json_c02]); await gitDDB.destroy(); }); @@ -433,19 +429,19 @@ describe(' find()', () => { const json_c01 = { _id: _id_c01, name: name_c01 }; const json_c02 = { _id: _id_c02, name: name_c02 }; - await addOneData(gitDDB, _id_b + JSON_EXTENSION, toSortedJSONString(json_b)); - await addOneData(gitDDB, _id_a + JSON_EXTENSION, toSortedJSONString(json_a)); - await addOneData(gitDDB, _id_d + JSON_EXTENSION, toSortedJSONString(json_d)); - await addOneData(gitDDB, _id_c000 + JSON_EXTENSION, toSortedJSONString(json_c000)); - await addOneData(gitDDB, _id_c001 + JSON_EXTENSION, toSortedJSONString(json_c001)); - await addOneData(gitDDB, _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01)); - await addOneData(gitDDB, _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02)); + await addOneData(gitDDB, _id_b + JSON_POSTFIX, toSortedJSONString(json_b)); + await addOneData(gitDDB, _id_a + JSON_POSTFIX, toSortedJSONString(json_a)); + await addOneData(gitDDB, _id_d + JSON_POSTFIX, toSortedJSONString(json_d)); + await addOneData(gitDDB, _id_c000 + JSON_POSTFIX, toSortedJSONString(json_c000)); + await addOneData(gitDDB, _id_c001 + JSON_POSTFIX, toSortedJSONString(json_c001)); + await addOneData(gitDDB, _id_c01 + JSON_POSTFIX, toSortedJSONString(json_c01)); + await addOneData(gitDDB, _id_c02 + JSON_POSTFIX, toSortedJSONString(json_c02)); const prefix = 'citrus/y'; - await expect(findImpl(gitDDB, '', true, false, { prefix })).resolves.toEqual([ - json_c02, - ]); + await expect( + findImpl(gitDDB, '', gitDDB.jsonExt, true, false, { prefix }) + ).resolves.toEqual([json_c02]); await gitDDB.destroy(); }); @@ -466,17 +462,19 @@ describe(' find()', () => { const json_c01 = { _id: _id_c01, name: name_c01 }; const json_c02 = { _id: _id_c02, name: name_c02 }; - await addOneData(gitDDB, _id_b + JSON_EXTENSION, toSortedJSONString(json_b)); - await addOneData(gitDDB, _id_a + JSON_EXTENSION, toSortedJSONString(json_a)); - await addOneData(gitDDB, _id_d + JSON_EXTENSION, toSortedJSONString(json_d)); - await addOneData(gitDDB, _id_c000 + JSON_EXTENSION, toSortedJSONString(json_c000)); - await addOneData(gitDDB, _id_c001 + JSON_EXTENSION, toSortedJSONString(json_c001)); - await addOneData(gitDDB, _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01)); - await addOneData(gitDDB, _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02)); + await addOneData(gitDDB, _id_b + JSON_POSTFIX, toSortedJSONString(json_b)); + await addOneData(gitDDB, _id_a + JSON_POSTFIX, toSortedJSONString(json_a)); + await addOneData(gitDDB, _id_d + JSON_POSTFIX, toSortedJSONString(json_d)); + await addOneData(gitDDB, _id_c000 + JSON_POSTFIX, toSortedJSONString(json_c000)); + await addOneData(gitDDB, _id_c001 + JSON_POSTFIX, toSortedJSONString(json_c001)); + await addOneData(gitDDB, _id_c01 + JSON_POSTFIX, toSortedJSONString(json_c01)); + await addOneData(gitDDB, _id_c02 + JSON_POSTFIX, toSortedJSONString(json_c02)); const prefix = 'not_exist/'; - await expect(findImpl(gitDDB, '', true, false, { prefix })).resolves.toEqual([]); + await expect( + findImpl(gitDDB, '', gitDDB.jsonExt, true, false, { prefix }) + ).resolves.toEqual([]); await gitDDB.destroy(); }); @@ -498,23 +496,23 @@ describe(' find()', () => { const json_c01 = { _id: _id_c01, name: name_c01 }; const json_c02 = { _id: _id_c02, name: name_c02 }; - await addOneData(gitDDB, _id_p + JSON_EXTENSION, toSortedJSONString(json_p)); + await addOneData(gitDDB, _id_p + JSON_POSTFIX, toSortedJSONString(json_p)); - await addOneData(gitDDB, _id_b + JSON_EXTENSION, toSortedJSONString(json_b)); - await addOneData(gitDDB, _id_a + JSON_EXTENSION, toSortedJSONString(json_a)); - await addOneData(gitDDB, _id_d + JSON_EXTENSION, toSortedJSONString(json_d)); - await addOneData(gitDDB, _id_c000 + JSON_EXTENSION, toSortedJSONString(json_c000)); - await addOneData(gitDDB, _id_c001 + JSON_EXTENSION, toSortedJSONString(json_c001)); - await addOneData(gitDDB, _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01)); - await addOneData(gitDDB, _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02)); + await addOneData(gitDDB, _id_b + JSON_POSTFIX, toSortedJSONString(json_b)); + await addOneData(gitDDB, _id_a + JSON_POSTFIX, toSortedJSONString(json_a)); + await addOneData(gitDDB, _id_d + JSON_POSTFIX, toSortedJSONString(json_d)); + await addOneData(gitDDB, _id_c000 + JSON_POSTFIX, toSortedJSONString(json_c000)); + await addOneData(gitDDB, _id_c001 + JSON_POSTFIX, toSortedJSONString(json_c001)); + await addOneData(gitDDB, _id_c01 + JSON_POSTFIX, toSortedJSONString(json_c01)); + await addOneData(gitDDB, _id_c02 + JSON_POSTFIX, toSortedJSONString(json_c02)); await expect( - findImpl(gitDDB, '', true, false, { prefix: 'pear/Japan' }) + findImpl(gitDDB, '', gitDDB.jsonExt, true, false, { prefix: 'pear/Japan' }) ).resolves.toEqual([json_p]); - await expect(findImpl(gitDDB, '', true, false, { prefix: 'pear' })).resolves.toEqual([ - json_p, - ]); + await expect( + findImpl(gitDDB, '', gitDDB.jsonExt, true, false, { prefix: 'pear' }) + ).resolves.toEqual([json_p]); await gitDDB.destroy(); }); @@ -531,7 +529,9 @@ describe(' find()', () => { await gitDDB.open(); - await expect(findImpl(gitDDB, 'col01', true, false)).resolves.toEqual([]); + await expect(findImpl(gitDDB, 'col01', gitDDB.jsonExt, true, false)).resolves.toEqual( + [] + ); await gitDDB.destroy(); }); @@ -557,33 +557,14 @@ describe(' find()', () => { const json_1_ = { _id: _id_1, name: name_1 }; const json_c_ = { _id: _id_c, name: name_c }; - await addOneData( - gitDDB, - colPath + _id_b + JSON_EXTENSION, - toSortedJSONString(json_b) - ); - await addOneData( - gitDDB, - colPath + _id_a + JSON_EXTENSION, - toSortedJSONString(json_a) - ); - await addOneData( - gitDDB, - colPath + _id_1 + JSON_EXTENSION, - toSortedJSONString(json_1) - ); - await addOneData( - gitDDB, - colPath + _id_c + JSON_EXTENSION, - toSortedJSONString(json_c) - ); + await addOneData(gitDDB, colPath + _id_b + JSON_POSTFIX, toSortedJSONString(json_b)); + await addOneData(gitDDB, colPath + _id_a + JSON_POSTFIX, toSortedJSONString(json_a)); + await addOneData(gitDDB, colPath + _id_1 + JSON_POSTFIX, toSortedJSONString(json_1)); + await addOneData(gitDDB, colPath + _id_c + JSON_POSTFIX, toSortedJSONString(json_c)); - await expect(findImpl(gitDDB, colPath, true, false)).resolves.toEqual([ - json_1_, - json_a_, - json_b_, - json_c_, - ]); + await expect( + findImpl(gitDDB, colPath, gitDDB.jsonExt, true, false) + ).resolves.toEqual([json_1_, json_a_, json_b_, json_c_]); await gitDDB.destroy(); }); @@ -609,39 +590,23 @@ describe(' find()', () => { const json_c01_ = { _id: _id_c01, name: name_c01 }; const json_c02_ = { _id: _id_c02, name: name_c02 }; + await addOneData(gitDDB, colPath + _id_b + JSON_POSTFIX, toSortedJSONString(json_b)); + await addOneData(gitDDB, colPath + _id_a + JSON_POSTFIX, toSortedJSONString(json_a)); + await addOneData(gitDDB, colPath + _id_d + JSON_POSTFIX, toSortedJSONString(json_d)); await addOneData( gitDDB, - colPath + _id_b + JSON_EXTENSION, - toSortedJSONString(json_b) - ); - await addOneData( - gitDDB, - colPath + _id_a + JSON_EXTENSION, - toSortedJSONString(json_a) - ); - await addOneData( - gitDDB, - colPath + _id_d + JSON_EXTENSION, - toSortedJSONString(json_d) - ); - await addOneData( - gitDDB, - colPath + _id_c01 + JSON_EXTENSION, + colPath + _id_c01 + JSON_POSTFIX, toSortedJSONString(json_c01) ); await addOneData( gitDDB, - colPath + _id_c02 + JSON_EXTENSION, + colPath + _id_c02 + JSON_POSTFIX, toSortedJSONString(json_c02) ); - await expect(findImpl(gitDDB, colPath, true, false)).resolves.toEqual([ - json_a_, - json_b_, - json_c01_, - json_c02_, - json_d_, - ]); + await expect( + findImpl(gitDDB, colPath, gitDDB.jsonExt, true, false) + ).resolves.toEqual([json_a_, json_b_, json_c01_, json_c02_, json_d_]); await gitDDB.destroy(); }); @@ -674,46 +639,45 @@ describe(' find()', () => { await addOneData( gitDDB, - colPath + _id_b + JSON_EXTENSION, + colPath + _id_b + JSON_POSTFIX, toSortedJSONString(json_b) ); await addOneData( gitDDB, - colPath + _id_a + JSON_EXTENSION, + colPath + _id_a + JSON_POSTFIX, toSortedJSONString(json_a) ); await addOneData( gitDDB, - colPath + _id_d + JSON_EXTENSION, + colPath + _id_d + JSON_POSTFIX, toSortedJSONString(json_d) ); await addOneData( gitDDB, - colPath + _id_c000 + JSON_EXTENSION, + colPath + _id_c000 + JSON_POSTFIX, toSortedJSONString(json_c000) ); await addOneData( gitDDB, - colPath + _id_c001 + JSON_EXTENSION, + colPath + _id_c001 + JSON_POSTFIX, toSortedJSONString(json_c001) ); await addOneData( gitDDB, - colPath + _id_c01 + JSON_EXTENSION, + colPath + _id_c01 + JSON_POSTFIX, toSortedJSONString(json_c01) ); await addOneData( gitDDB, - colPath + _id_c02 + JSON_EXTENSION, + colPath + _id_c02 + JSON_POSTFIX, toSortedJSONString(json_c02) ); const prefix = 'citrus/'; - await expect(findImpl(gitDDB, colPath, true, false, { prefix })).resolves.toEqual([ - json_c01_, - json_c02_, - ]); + await expect( + findImpl(gitDDB, colPath, gitDDB.jsonExt, true, false, { prefix }) + ).resolves.toEqual([json_c01_, json_c02_]); await gitDDB.destroy(); }); @@ -745,44 +709,47 @@ describe(' find()', () => { await addOneData( gitDDB, - colPath + _id_b + JSON_EXTENSION, + colPath + _id_b + JSON_POSTFIX, toSortedJSONString(json_b) ); await addOneData( gitDDB, - colPath + _id_a + JSON_EXTENSION, + colPath + _id_a + JSON_POSTFIX, toSortedJSONString(json_a) ); await addOneData( gitDDB, - colPath + _id_d + JSON_EXTENSION, + colPath + _id_d + JSON_POSTFIX, toSortedJSONString(json_d) ); await addOneData( gitDDB, - colPath + _id_c000 + JSON_EXTENSION, + colPath + _id_c000 + JSON_POSTFIX, toSortedJSONString(json_c000) ); await addOneData( gitDDB, - colPath + _id_c001 + JSON_EXTENSION, + colPath + _id_c001 + JSON_POSTFIX, toSortedJSONString(json_c001) ); await addOneData( gitDDB, - colPath + _id_c01 + JSON_EXTENSION, + colPath + _id_c01 + JSON_POSTFIX, toSortedJSONString(json_c01) ); await addOneData( gitDDB, - colPath + _id_c02 + JSON_EXTENSION, + colPath + _id_c02 + JSON_POSTFIX, toSortedJSONString(json_c02) ); const prefix = 'cit'; await expect( - findImpl(gitDDB, colPath, true, false, { prefix, recursive: false }) + findImpl(gitDDB, colPath, gitDDB.jsonExt, true, false, { + prefix, + recursive: false, + }) ).resolves.toEqual([json_c000_, json_c001_]); await gitDDB.destroy(); @@ -815,48 +782,45 @@ describe(' find()', () => { await addOneData( gitDDB, - colPath + _id_b + JSON_EXTENSION, + colPath + _id_b + JSON_POSTFIX, toSortedJSONString(json_b) ); await addOneData( gitDDB, - colPath + _id_a + JSON_EXTENSION, + colPath + _id_a + JSON_POSTFIX, toSortedJSONString(json_a) ); await addOneData( gitDDB, - colPath + _id_d + JSON_EXTENSION, + colPath + _id_d + JSON_POSTFIX, toSortedJSONString(json_d) ); await addOneData( gitDDB, - colPath + _id_c000 + JSON_EXTENSION, + colPath + _id_c000 + JSON_POSTFIX, toSortedJSONString(json_c000) ); await addOneData( gitDDB, - colPath + _id_c001 + JSON_EXTENSION, + colPath + _id_c001 + JSON_POSTFIX, toSortedJSONString(json_c001) ); await addOneData( gitDDB, - colPath + _id_c01 + JSON_EXTENSION, + colPath + _id_c01 + JSON_POSTFIX, toSortedJSONString(json_c01) ); await addOneData( gitDDB, - colPath + _id_c02 + JSON_EXTENSION, + colPath + _id_c02 + JSON_POSTFIX, toSortedJSONString(json_c02) ); const prefix = 'citrus'; - await expect(findImpl(gitDDB, colPath, true, false, { prefix })).resolves.toEqual([ - json_c000_, - json_c001_, - json_c01_, - json_c02_, - ]); + await expect( + findImpl(gitDDB, colPath, gitDDB.jsonExt, true, false, { prefix }) + ).resolves.toEqual([json_c000_, json_c001_, json_c01_, json_c02_]); await gitDDB.destroy(); }); @@ -888,45 +852,45 @@ describe(' find()', () => { await addOneData( gitDDB, - colPath + _id_b + JSON_EXTENSION, + colPath + _id_b + JSON_POSTFIX, toSortedJSONString(json_b) ); await addOneData( gitDDB, - colPath + _id_a + JSON_EXTENSION, + colPath + _id_a + JSON_POSTFIX, toSortedJSONString(json_a) ); await addOneData( gitDDB, - colPath + _id_d + JSON_EXTENSION, + colPath + _id_d + JSON_POSTFIX, toSortedJSONString(json_d) ); await addOneData( gitDDB, - colPath + _id_c000 + JSON_EXTENSION, + colPath + _id_c000 + JSON_POSTFIX, toSortedJSONString(json_c000) ); await addOneData( gitDDB, - colPath + _id_c001 + JSON_EXTENSION, + colPath + _id_c001 + JSON_POSTFIX, toSortedJSONString(json_c001) ); await addOneData( gitDDB, - colPath + _id_c01 + JSON_EXTENSION, + colPath + _id_c01 + JSON_POSTFIX, toSortedJSONString(json_c01) ); await addOneData( gitDDB, - colPath + _id_c02 + JSON_EXTENSION, + colPath + _id_c02 + JSON_POSTFIX, toSortedJSONString(json_c02) ); const prefix = 'citrus/y'; - await expect(findImpl(gitDDB, colPath, true, false, { prefix })).resolves.toEqual([ - json_c02_, - ]); + await expect( + findImpl(gitDDB, colPath, gitDDB.jsonExt, true, false, { prefix }) + ).resolves.toEqual([json_c02_]); await gitDDB.destroy(); }); @@ -958,45 +922,45 @@ describe(' find()', () => { await addOneData( gitDDB, - colPath + _id_b + JSON_EXTENSION, + colPath + _id_b + JSON_POSTFIX, toSortedJSONString(json_b) ); await addOneData( gitDDB, - colPath + _id_a + JSON_EXTENSION, + colPath + _id_a + JSON_POSTFIX, toSortedJSONString(json_a) ); await addOneData( gitDDB, - colPath + _id_d + JSON_EXTENSION, + colPath + _id_d + JSON_POSTFIX, toSortedJSONString(json_d) ); await addOneData( gitDDB, - colPath + _id_c000 + JSON_EXTENSION, + colPath + _id_c000 + JSON_POSTFIX, toSortedJSONString(json_c000) ); await addOneData( gitDDB, - colPath + _id_c001 + JSON_EXTENSION, + colPath + _id_c001 + JSON_POSTFIX, toSortedJSONString(json_c001) ); await addOneData( gitDDB, - colPath + _id_c01 + JSON_EXTENSION, + colPath + _id_c01 + JSON_POSTFIX, toSortedJSONString(json_c01) ); await addOneData( gitDDB, - colPath + _id_c02 + JSON_EXTENSION, + colPath + _id_c02 + JSON_POSTFIX, toSortedJSONString(json_c02) ); const prefix = 'not_exist/'; - await expect(findImpl(gitDDB, colPath, true, false, { prefix })).resolves.toEqual( - [] - ); + await expect( + findImpl(gitDDB, colPath, gitDDB.jsonExt, true, false, { prefix }) + ).resolves.toEqual([]); await gitDDB.destroy(); }); @@ -1030,52 +994,52 @@ describe(' find()', () => { await addOneData( gitDDB, - colPath + _id_p + JSON_EXTENSION, + colPath + _id_p + JSON_POSTFIX, toSortedJSONString(json_p) ); await addOneData( gitDDB, - colPath + _id_b + JSON_EXTENSION, + colPath + _id_b + JSON_POSTFIX, toSortedJSONString(json_b) ); await addOneData( gitDDB, - colPath + _id_a + JSON_EXTENSION, + colPath + _id_a + JSON_POSTFIX, toSortedJSONString(json_a) ); await addOneData( gitDDB, - colPath + _id_d + JSON_EXTENSION, + colPath + _id_d + JSON_POSTFIX, toSortedJSONString(json_d) ); await addOneData( gitDDB, - colPath + _id_c000 + JSON_EXTENSION, + colPath + _id_c000 + JSON_POSTFIX, toSortedJSONString(json_c000) ); await addOneData( gitDDB, - colPath + _id_c001 + JSON_EXTENSION, + colPath + _id_c001 + JSON_POSTFIX, toSortedJSONString(json_c001) ); await addOneData( gitDDB, - colPath + _id_c01 + JSON_EXTENSION, + colPath + _id_c01 + JSON_POSTFIX, toSortedJSONString(json_c01) ); await addOneData( gitDDB, - colPath + _id_c02 + JSON_EXTENSION, + colPath + _id_c02 + JSON_POSTFIX, toSortedJSONString(json_c02) ); await expect( - findImpl(gitDDB, colPath, true, false, { prefix: 'pear/Japan' }) + findImpl(gitDDB, colPath, gitDDB.jsonExt, true, false, { prefix: 'pear/Japan' }) ).resolves.toEqual([json_p_]); await expect( - findImpl(gitDDB, colPath, true, false, { prefix: 'pear' }) + findImpl(gitDDB, colPath, gitDDB.jsonExt, true, false, { prefix: 'pear' }) ).resolves.toEqual([json_p_]); await gitDDB.destroy(); @@ -1094,7 +1058,7 @@ describe(' find()', () => { await gitDDB.open(); - await expect(findImpl(gitDDB, '', true, true)).resolves.toEqual([]); + await expect(findImpl(gitDDB, '', gitDDB.jsonExt, true, true)).resolves.toEqual([]); await gitDDB.destroy(); }); @@ -1113,44 +1077,44 @@ describe(' find()', () => { const json_c01 = { _id: _id_c01, name: name_c01 }; const json_c02 = { _id: _id_c02, name: name_c02 }; - await addOneData(gitDDB, _id_b + JSON_EXTENSION, toSortedJSONString(json_b)); - await addOneData(gitDDB, _id_a + JSON_EXTENSION, toSortedJSONString(json_a)); - await addOneData(gitDDB, _id_d + JSON_EXTENSION, toSortedJSONString(json_d)); - await addOneData(gitDDB, _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01)); - await addOneData(gitDDB, _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02)); + await addOneData(gitDDB, _id_b + JSON_POSTFIX, toSortedJSONString(json_b)); + await addOneData(gitDDB, _id_a + JSON_POSTFIX, toSortedJSONString(json_a)); + await addOneData(gitDDB, _id_d + JSON_POSTFIX, toSortedJSONString(json_d)); + await addOneData(gitDDB, _id_c01 + JSON_POSTFIX, toSortedJSONString(json_c01)); + await addOneData(gitDDB, _id_c02 + JSON_POSTFIX, toSortedJSONString(json_c02)); - await expect(findImpl(gitDDB, '', true, true)).resolves.toEqual([ + await expect(findImpl(gitDDB, '', gitDDB.jsonExt, true, true)).resolves.toEqual([ { _id: _id_a, - name: _id_a + JSON_EXTENSION, + name: _id_a + JSON_POSTFIX, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_a) })).oid, type: 'json', doc: json_a, }, { _id: _id_b, - name: _id_b + JSON_EXTENSION, + name: _id_b + JSON_POSTFIX, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_b) })).oid, type: 'json', doc: json_b, }, { _id: _id_c01, - name: _id_c01 + JSON_EXTENSION, + name: _id_c01 + JSON_POSTFIX, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_c01) })).oid, type: 'json', doc: json_c01, }, { _id: _id_c02, - name: _id_c02 + JSON_EXTENSION, + name: _id_c02 + JSON_POSTFIX, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_c02) })).oid, type: 'json', doc: json_c02, }, { _id: _id_d, - name: _id_d + JSON_EXTENSION, + name: _id_d + JSON_POSTFIX, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_d) })).oid, type: 'json', doc: json_d, diff --git a/test/crud/get.test.ts b/test/crud/get.test.ts index 4df2b354..556232cb 100644 --- a/test/crud/get.test.ts +++ b/test/crud/get.test.ts @@ -17,7 +17,7 @@ import { sleep, toSortedJSONString } from '../../src/utils'; import { Err } from '../../src/error'; import { GitDocumentDB } from '../../src/git_documentdb'; import { getImpl } from '../../src/crud/get'; -import { JSON_EXTENSION } from '../../src/const'; +import { JSON_POSTFIX } from '../../src/const'; import { addOneData, removeOneData } from '../utils'; // eslint-disable-next-line @typescript-eslint/no-var-requires @@ -65,7 +65,9 @@ describe(' getImpl()', () => { } // Call close() without await gitDDB.close().catch(() => {}); - await expect(getImpl(gitDDB, 'tmp', '')).rejects.toThrowError(Err.DatabaseClosingError); + await expect(getImpl(gitDDB, 'tmp', '', gitDDB.jsonExt)).rejects.toThrowError( + Err.DatabaseClosingError + ); while (gitDDB.isClosing) { // eslint-disable-next-line no-await-in-loop await sleep(100); @@ -87,9 +89,9 @@ describe(' getImpl()', () => { const data = 'invalid data'; // JSON.parse() will throw error await addOneData(gitDDB, fullDocPath, data); - await expect(getImpl(gitDDB, shortName, collectionPath)).rejects.toThrowError( - Err.InvalidJsonObjectError - ); + await expect( + getImpl(gitDDB, shortName, collectionPath, gitDDB.jsonExt) + ).rejects.toThrowError(Err.InvalidJsonObjectError); await gitDDB.destroy(); }); @@ -103,12 +105,14 @@ describe(' getImpl()', () => { await gitDDB.open(); const shortId = 'prof01'; - const shortName = shortId + JSON_EXTENSION; + const shortName = shortId + JSON_POSTFIX; const collectionPath = ''; const fullDocPath = collectionPath + shortName; const json = { _id: shortId, name: 'Shirase' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json)); - await expect(getImpl(gitDDB, shortName, collectionPath)).resolves.toEqual(json); + await expect( + getImpl(gitDDB, shortName, collectionPath, gitDDB.jsonExt) + ).resolves.toEqual(json); await gitDDB.destroy(); }); @@ -122,12 +126,14 @@ describe(' getImpl()', () => { await gitDDB.open(); const shortId = 'dir01/prof01'; - const shortName = shortId + JSON_EXTENSION; + const shortName = shortId + JSON_POSTFIX; const collectionPath = ''; const fullDocPath = collectionPath + shortName; const json = { _id: shortId, name: 'Shirase' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json)); - await expect(getImpl(gitDDB, shortName, collectionPath)).resolves.toEqual(json); + await expect( + getImpl(gitDDB, shortName, collectionPath, gitDDB.jsonExt) + ).resolves.toEqual(json); await gitDDB.destroy(); }); @@ -141,12 +147,14 @@ describe(' getImpl()', () => { await gitDDB.open(); const shortId = 'dir01/prof01'; - const shortName = shortId + JSON_EXTENSION; + const shortName = shortId + JSON_POSTFIX; const collectionPath = 'col01/col02/col03'; const fullDocPath = collectionPath + shortName; const json = { _id: shortId, name: 'Shirase' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json)); - await expect(getImpl(gitDDB, shortName, collectionPath)).resolves.toEqual(json); + await expect( + getImpl(gitDDB, shortName, collectionPath, gitDDB.jsonExt) + ).resolves.toEqual(json); await gitDDB.destroy(); }); @@ -163,7 +171,9 @@ describe(' getImpl()', () => { const shortName = 'prof01.json'; const collectionPath = ''; - await expect(getImpl(gitDDB, shortName, collectionPath)).resolves.toBeUndefined(); + await expect( + getImpl(gitDDB, shortName, collectionPath, gitDDB.jsonExt) + ).resolves.toBeUndefined(); await gitDDB.destroy(); }); @@ -179,7 +189,9 @@ describe(' getImpl()', () => { const shortName = 'dir01/prof01.json'; const collectionPath = ''; - await expect(getImpl(gitDDB, shortName, collectionPath)).resolves.toBeUndefined(); + await expect( + getImpl(gitDDB, shortName, collectionPath, gitDDB.jsonExt) + ).resolves.toBeUndefined(); await gitDDB.destroy(); }); @@ -193,7 +205,7 @@ describe(' getImpl()', () => { await gitDDB.open(); const shortId = 'prof01'; - const shortName = shortId + JSON_EXTENSION; + const shortName = shortId + JSON_POSTFIX; const collectionPath = ''; const fullDocPath = collectionPath + shortName; const json = { _id: shortId, name: 'Shirase' }; @@ -202,7 +214,9 @@ describe(' getImpl()', () => { const stubReadBlob = sandbox.stub(git_module, 'readBlob'); stubReadBlob.rejects(); - await expect(getImpl(gitDDB, shortName, collectionPath)).resolves.toBeUndefined(); + await expect( + getImpl(gitDDB, shortName, collectionPath, gitDDB.jsonExt) + ).resolves.toBeUndefined(); await gitDDB.destroy(); }); @@ -216,12 +230,14 @@ describe(' getImpl()', () => { await gitDDB.open(); const shortId = '枕草子/春はあけぼの'; - const shortName = shortId + JSON_EXTENSION; + const shortName = shortId + JSON_POSTFIX; const collectionPath = ''; const fullDocPath = collectionPath + shortName; const json = { _id: shortId, name: 'Shirase' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json)); - await expect(getImpl(gitDDB, shortName, collectionPath)).resolves.toEqual(json); + await expect( + getImpl(gitDDB, shortName, collectionPath, gitDDB.jsonExt) + ).resolves.toEqual(json); await gitDDB.destroy(); }); @@ -236,14 +252,14 @@ describe(' getImpl()', () => { await gitDDB.open(); const shortId = 'prof01'; - const shortName = shortId + JSON_EXTENSION; + const shortName = shortId + JSON_POSTFIX; const collectionPath = ''; const fullDocPath = collectionPath + shortName; const json = { _id: shortId, name: 'Shirase' }; const { oid } = await git.hashBlob({ object: toSortedJSONString(json) }); await addOneData(gitDDB, fullDocPath, toSortedJSONString(json)); await expect( - getImpl(gitDDB, shortName, collectionPath, undefined, { oid }) + getImpl(gitDDB, shortName, collectionPath, gitDDB.jsonExt, undefined, { oid }) ).resolves.toEqual(json); await gitDDB.destroy(); @@ -260,14 +276,16 @@ describe(' getImpl()', () => { await gitDDB.open(); const shortId = 'prof01'; - const shortName = shortId + JSON_EXTENSION; + const shortName = shortId + JSON_POSTFIX; const collectionPath = ''; const fullDocPath = collectionPath + shortName; const json = { _id: shortId, name: 'Shirase' }; const { oid } = await git.hashBlob({ object: toSortedJSONString(json) }); await addOneData(gitDDB, fullDocPath, toSortedJSONString(json)); await expect( - getImpl(gitDDB, shortName, collectionPath, undefined, { withMetadata: true }) + getImpl(gitDDB, shortName, collectionPath, gitDDB.jsonExt, undefined, { + withMetadata: true, + }) ).resolves.toEqual({ _id: shortId, name: shortName, @@ -288,14 +306,16 @@ describe(' getImpl()', () => { await gitDDB.open(); const shortId = 'prof01'; - const shortName = shortId + JSON_EXTENSION; + const shortName = shortId + JSON_POSTFIX; const collectionPath = ''; const fullDocPath = collectionPath + shortName; const json = { _id: shortId, name: 'Shirase' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json)); await expect( - getImpl(gitDDB, shortName, collectionPath, undefined, { revision: -1 }) + getImpl(gitDDB, shortName, collectionPath, gitDDB.jsonExt, undefined, { + revision: -1, + }) ).resolves.toBeUndefined(); await gitDDB.destroy(); @@ -312,7 +332,7 @@ describe(' getImpl()', () => { await gitDDB.open(); const shortId = 'prof01'; - const shortName = shortId + JSON_EXTENSION; + const shortName = shortId + JSON_POSTFIX; const collectionPath = ''; const fullDocPath = collectionPath + shortName; const json = { _id: shortId, name: 'Shirase' }; @@ -320,7 +340,9 @@ describe(' getImpl()', () => { await removeOneData(gitDDB, fullDocPath); await expect( - getImpl(gitDDB, shortName, collectionPath, undefined, { revision: 0 }) + getImpl(gitDDB, shortName, collectionPath, gitDDB.jsonExt, undefined, { + revision: 0, + }) ).resolves.toBeUndefined(); await gitDDB.destroy(); @@ -335,7 +357,7 @@ describe(' getImpl()', () => { await gitDDB.open(); const shortId = 'prof01'; - const shortName = shortId + JSON_EXTENSION; + const shortName = shortId + JSON_POSTFIX; const collectionPath = ''; const fullDocPath = collectionPath + shortName; const json = { _id: shortId, name: 'Shirase' }; @@ -343,7 +365,9 @@ describe(' getImpl()', () => { await removeOneData(gitDDB, fullDocPath); await expect( - getImpl(gitDDB, shortName, collectionPath, undefined, { revision: 1 }) + getImpl(gitDDB, shortName, collectionPath, gitDDB.jsonExt, undefined, { + revision: 1, + }) ).resolves.toEqual(json); await gitDDB.destroy(); @@ -358,7 +382,7 @@ describe(' getImpl()', () => { await gitDDB.open(); const shortId = 'prof01'; - const shortName = shortId + JSON_EXTENSION; + const shortName = shortId + JSON_POSTFIX; const collectionPath = ''; const fullDocPath = collectionPath + shortName; const json01 = { _id: shortId, name: 'v01' }; @@ -368,7 +392,9 @@ describe(' getImpl()', () => { await removeOneData(gitDDB, fullDocPath); await expect( - getImpl(gitDDB, shortName, collectionPath, undefined, { revision: 2 }) + getImpl(gitDDB, shortName, collectionPath, gitDDB.jsonExt, undefined, { + revision: 2, + }) ).resolves.toEqual(json01); await gitDDB.destroy(); @@ -383,7 +409,7 @@ describe(' getImpl()', () => { await gitDDB.open(); const shortId = 'prof01'; - const shortName = shortId + JSON_EXTENSION; + const shortName = shortId + JSON_POSTFIX; const collectionPath = ''; const fullDocPath = collectionPath + shortName; const json01 = { _id: shortId, name: 'v01' }; @@ -393,7 +419,9 @@ describe(' getImpl()', () => { await addOneData(gitDDB, fullDocPath, toSortedJSONString(json02)); await expect( - getImpl(gitDDB, shortName, collectionPath, undefined, { revision: 2 }) + getImpl(gitDDB, shortName, collectionPath, gitDDB.jsonExt, undefined, { + revision: 2, + }) ).resolves.toEqual(json01); await gitDDB.destroy(); @@ -408,7 +436,7 @@ describe(' getImpl()', () => { await gitDDB.open(); const shortId = 'prof01'; - const shortName = shortId + JSON_EXTENSION; + const shortName = shortId + JSON_POSTFIX; const collectionPath = ''; const fullDocPath = collectionPath + shortName; const json01 = { _id: shortId, name: 'v01' }; @@ -418,7 +446,9 @@ describe(' getImpl()', () => { await addOneData(gitDDB, fullDocPath, toSortedJSONString(json02)); await expect( - getImpl(gitDDB, shortName, collectionPath, undefined, { revision: 1 }) + getImpl(gitDDB, shortName, collectionPath, gitDDB.jsonExt, undefined, { + revision: 1, + }) ).resolves.toBeUndefined(); await gitDDB.destroy(); @@ -433,7 +463,7 @@ describe(' getImpl()', () => { await gitDDB.open(); const shortId = 'prof01'; - const shortName = shortId + JSON_EXTENSION; + const shortName = shortId + JSON_POSTFIX; const collectionPath = ''; const fullDocPath = collectionPath + shortName; const json01 = { _id: shortId, name: 'v01' }; @@ -443,7 +473,9 @@ describe(' getImpl()', () => { await addOneData(gitDDB, fullDocPath, toSortedJSONString(json02)); await expect( - getImpl(gitDDB, shortName, collectionPath, undefined, { revision: 3 }) + getImpl(gitDDB, shortName, collectionPath, gitDDB.jsonExt, undefined, { + revision: 3, + }) ).resolves.toBeUndefined(); await gitDDB.destroy(); @@ -461,7 +493,9 @@ describe(' getImpl()', () => { const collectionPath = ''; await expect( - getImpl(gitDDB, shortName, collectionPath, undefined, { revision: 0 }) + getImpl(gitDDB, shortName, collectionPath, gitDDB.jsonExt, undefined, { + revision: 0, + }) ).resolves.toBeUndefined(); await gitDDB.destroy(); @@ -476,7 +510,7 @@ describe(' getImpl()', () => { await gitDDB.open(); const shortId = 'prof01'; - const shortName = shortId + JSON_EXTENSION; + const shortName = shortId + JSON_POSTFIX; const collectionPath = ''; const fullDocPath = collectionPath + shortName; const json = { _id: shortId, name: 'Shirase' }; @@ -486,7 +520,9 @@ describe(' getImpl()', () => { stubReadBlob.rejects(); await expect( - getImpl(gitDDB, shortName, collectionPath, undefined, { revision: 0 }) + getImpl(gitDDB, shortName, collectionPath, gitDDB.jsonExt, undefined, { + revision: 0, + }) ).resolves.toBeUndefined(); await gitDDB.destroy(); @@ -501,7 +537,7 @@ describe(' getImpl()', () => { }); const targetId = '01'; - const targetName = targetId + JSON_EXTENSION; + const targetName = targetId + JSON_POSTFIX; const collectionPath = ''; const fullDocPath = collectionPath + targetName; @@ -763,6 +799,7 @@ describe(' getImpl()', () => { gitDDB, targetName, collectionPath, + gitDDB.jsonExt, undefined, { revision: 0 }, { @@ -781,6 +818,7 @@ describe(' getImpl()', () => { gitDDB, targetName, collectionPath, + gitDDB.jsonExt, undefined, { revision: 1 }, { @@ -801,6 +839,7 @@ describe(' getImpl()', () => { gitDDB, targetName, collectionPath, + gitDDB.jsonExt, undefined, { revision: 0 }, { @@ -817,6 +856,7 @@ describe(' getImpl()', () => { gitDDB, targetName, collectionPath, + gitDDB.jsonExt, undefined, { revision: 1 }, { diff --git a/test/crud/history.test.ts b/test/crud/history.test.ts index a2787519..f8b73a16 100644 --- a/test/crud/history.test.ts +++ b/test/crud/history.test.ts @@ -23,7 +23,7 @@ import { GitDocumentDB } from '../../src/git_documentdb'; import { sleep, toSortedJSONString, utf8encode } from '../../src/utils'; import { getHistoryImpl, readOldBlob } from '../../src/crud/history'; -import { JSON_EXTENSION } from '../../src/const'; +import { JSON_POSTFIX } from '../../src/const'; import { addOneData, removeOneData } from '../utils'; import { FatJsonDoc } from '../../src/types'; @@ -74,7 +74,7 @@ describe(' getHistoryImpl', () => { await gitDDB.open(); const _idA = 'profA'; - const shortNameA = _idA + JSON_EXTENSION; + const shortNameA = _idA + JSON_POSTFIX; const jsonA01 = { _id: _idA, name: 'v01' }; const jsonA02 = { _id: _idA, name: 'v02' }; const jsonA03 = { _id: _idA, name: 'v03' }; @@ -82,7 +82,7 @@ describe(' getHistoryImpl', () => { await gitDDB.put(jsonA02); await gitDDB.put(jsonA03); const _idB = 'profB'; - const shortNameB = _idB + JSON_EXTENSION; + const shortNameB = _idB + JSON_POSTFIX; const jsonB01 = { _id: _idB, name: 'v01' }; const jsonB02 = { _id: _idB, name: 'v02' }; await gitDDB.put(jsonB01); @@ -92,6 +92,8 @@ describe(' getHistoryImpl', () => { gitDDB, shortNameA, '', + gitDDB.jsonExt, + undefined, undefined, true @@ -104,6 +106,7 @@ describe(' getHistoryImpl', () => { gitDDB, shortNameB, '', + gitDDB.jsonExt, undefined, undefined, true @@ -124,7 +127,7 @@ describe(' getHistoryImpl', () => { await gitDDB.open(); const _idA = 'profA'; - const shortNameA = _idA + JSON_EXTENSION; + const shortNameA = _idA + JSON_POSTFIX; const jsonA01 = { _id: _idA, name: 'v01' }; const jsonA02 = { _id: _idA, name: 'v02' }; const jsonA03 = { _id: _idA, name: 'v03' }; @@ -139,7 +142,7 @@ describe(' getHistoryImpl', () => { await gitDDB.put(jsonA03); const _idB = 'profB'; - const shortNameB = _idB + JSON_EXTENSION; + const shortNameB = _idB + JSON_POSTFIX; const jsonB01 = { _id: _idB, name: 'v01' }; const jsonB02 = { _id: _idB, name: 'v02' }; @@ -155,6 +158,7 @@ describe(' getHistoryImpl', () => { gitDDB, shortNameA, '', + gitDDB.jsonExt, { filter: [{ author: { name: 'authorB', email: 'authorEmailB' } }], }, @@ -169,6 +173,7 @@ describe(' getHistoryImpl', () => { gitDDB, shortNameB, '', + gitDDB.jsonExt, { filter: [{ author: { name: 'authorB', email: 'authorEmailB' } }], }, @@ -197,6 +202,7 @@ describe(' getHistoryImpl', () => { gitDDB, 'invalid_id', '', + gitDDB.jsonExt, undefined, undefined, true @@ -215,7 +221,7 @@ describe(' getHistoryImpl', () => { await gitDDB.open(); const _idA = 'profA'; - const shortNameA = _idA + JSON_EXTENSION; + const shortNameA = _idA + JSON_POSTFIX; const jsonA01 = { _id: _idA, name: 'v01' }; const jsonA02 = { _id: _idA, name: 'v02' }; const jsonA03 = { _id: _idA, name: 'v03' }; @@ -231,6 +237,7 @@ describe(' getHistoryImpl', () => { gitDDB, shortNameA, '', + gitDDB.jsonExt, undefined, undefined, true @@ -261,7 +268,7 @@ describe(' getHistoryImpl', () => { // Call close() without await gitDDB.close().catch(() => {}); await expect( - getHistoryImpl(gitDDB, '0.json', '', undefined, undefined, true) + getHistoryImpl(gitDDB, '0.json', '', gitDDB.jsonExt, undefined, undefined, true) ).rejects.toThrowError(Err.DatabaseClosingError); while (gitDDB.isClosing) { @@ -281,7 +288,7 @@ describe(' getHistoryImpl', () => { await gitDDB.putFatDoc('1.json', 'invalid json'); await expect( - getHistoryImpl(gitDDB, '1.json', '', undefined, undefined, true) + getHistoryImpl(gitDDB, '1.json', '', gitDDB.jsonExt, undefined, undefined, true) ).rejects.toThrowError(Err.InvalidJsonObjectError); await destroyDBs([gitDDB]); @@ -297,7 +304,7 @@ describe(' getHistoryImpl', () => { await gitDDB.open(); const _idA = 'profA'; - const shortNameA = _idA + JSON_EXTENSION; + const shortNameA = _idA + JSON_POSTFIX; const jsonA01 = { _id: _idA, name: 'v01' }; const jsonA02 = { _id: _idA, name: 'v02' }; const jsonA03 = { _id: _idA, name: 'v03' }; @@ -306,7 +313,7 @@ describe(' getHistoryImpl', () => { await gitDDB.put(jsonA03); // Get - const historyA = await getHistoryImpl(gitDDB, shortNameA, ''); + const historyA = await getHistoryImpl(gitDDB, shortNameA, '', gitDDB.jsonExt); expect(historyA.length).toBe(3); expect(historyA[0]).toMatchObject(jsonA03); expect(historyA[1]).toMatchObject(jsonA02); @@ -324,7 +331,7 @@ describe(' getHistoryImpl', () => { await gitDDB.open(); const _idA = 'profA'; - const shortNameA = _idA + JSON_EXTENSION; + const shortNameA = _idA + JSON_POSTFIX; const jsonA01 = { _id: _idA, name: 'v01' }; const jsonA02 = { _id: _idA, name: 'v02' }; const jsonA03 = { _id: _idA, name: 'v03' }; @@ -340,6 +347,7 @@ describe(' getHistoryImpl', () => { gitDDB, shortNameA, '', + gitDDB.jsonExt, undefined, undefined, false @@ -371,6 +379,7 @@ describe(' getHistoryImpl', () => { gitDDB, 'invalid_id', '', + gitDDB.jsonExt, undefined, undefined, false @@ -393,7 +402,7 @@ describe(' readOldBlob()', () => { await gitDDB.open(); const shortId = 'prof01'; const collectionPath = ''; - const fullDocPath = collectionPath + shortId + JSON_EXTENSION; + const fullDocPath = collectionPath + shortId + JSON_POSTFIX; const json = { _id: shortId, name: 'Shirase' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json)); @@ -412,7 +421,7 @@ describe(' readOldBlob()', () => { await gitDDB.open(); const shortId = 'prof01'; const collectionPath = ''; - const fullDocPath = collectionPath + shortId + JSON_EXTENSION; + const fullDocPath = collectionPath + shortId + JSON_POSTFIX; const json = { _id: shortId, name: 'Shirase' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json)); await removeOneData(gitDDB, fullDocPath); @@ -432,7 +441,7 @@ describe(' readOldBlob()', () => { await gitDDB.open(); const shortId = 'prof01'; const collectionPath = ''; - const fullDocPath = collectionPath + shortId + JSON_EXTENSION; + const fullDocPath = collectionPath + shortId + JSON_POSTFIX; const json = { _id: shortId, name: 'Shirase' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json)); await removeOneData(gitDDB, fullDocPath); @@ -455,7 +464,7 @@ describe(' readOldBlob()', () => { await gitDDB.open(); const shortId = 'prof01'; const collectionPath = ''; - const fullDocPath = collectionPath + shortId + JSON_EXTENSION; + const fullDocPath = collectionPath + shortId + JSON_POSTFIX; const json01 = { _id: shortId, name: 'v01' }; const json02 = { _id: shortId, name: 'v02' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json01)); @@ -480,7 +489,7 @@ describe(' readOldBlob()', () => { await gitDDB.open(); const shortId = 'prof01'; const collectionPath = ''; - const fullDocPath = collectionPath + shortId + JSON_EXTENSION; + const fullDocPath = collectionPath + shortId + JSON_POSTFIX; const json01 = { _id: shortId, name: 'v01' }; const json02 = { _id: shortId, name: 'v02' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json01)); @@ -505,7 +514,7 @@ describe(' readOldBlob()', () => { await gitDDB.open(); const shortId = 'prof01'; const collectionPath = ''; - const fullDocPath = collectionPath + shortId + JSON_EXTENSION; + const fullDocPath = collectionPath + shortId + JSON_POSTFIX; const json01 = { _id: shortId, name: 'v01' }; const json02 = { _id: shortId, name: 'v02' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json01)); @@ -527,7 +536,7 @@ describe(' readOldBlob()', () => { await gitDDB.open(); const shortId = 'prof01'; const collectionPath = ''; - const fullDocPath = collectionPath + shortId + JSON_EXTENSION; + const fullDocPath = collectionPath + shortId + JSON_POSTFIX; const json01 = { _id: shortId, name: 'v01' }; const json02 = { _id: shortId, name: 'v02' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json01)); @@ -565,7 +574,7 @@ describe(' readOldBlob()', () => { await gitDDB.open(); const shortId = 'prof01'; const collectionPath = ''; - const fullDocPath = collectionPath + shortId + JSON_EXTENSION; + const fullDocPath = collectionPath + shortId + JSON_POSTFIX; const json = { _id: shortId, name: 'Shirase' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json)); @@ -587,7 +596,7 @@ describe(' readOldBlob()', () => { await gitDDB.open(); const shortId = 'prof01'; const collectionPath = ''; - const fullDocPath = collectionPath + shortId + JSON_EXTENSION; + const fullDocPath = collectionPath + shortId + JSON_POSTFIX; const json01 = { _id: shortId, name: 'v01' }; const json02 = { _id: shortId, name: 'v02' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json01)); @@ -612,7 +621,7 @@ describe(' readOldBlob()', () => { const targetId = '01'; const collectionPath = ''; - const fullDocPath = collectionPath + targetId + JSON_EXTENSION; + const fullDocPath = collectionPath + targetId + JSON_POSTFIX; const json01 = { _id: targetId, name: 'v01' }; const json02 = { _id: targetId, name: 'v02' }; diff --git a/test/crud/put.test.ts b/test/crud/put.test.ts index d433c0b4..5f30b1b0 100644 --- a/test/crud/put.test.ts +++ b/test/crud/put.test.ts @@ -17,7 +17,7 @@ import { monotonicFactory } from 'ulid'; import { Err } from '../../src/error'; import { GitDocumentDB } from '../../src/git_documentdb'; import { putImpl, putWorker } from '../../src/crud/put'; -import { JSON_EXTENSION, SHORT_SHA_LENGTH } from '../../src/const'; +import { JSON_POSTFIX, SHORT_SHA_LENGTH } from '../../src/const'; import { sleep, toSortedJSONString } from '../../src/utils'; import { TaskMetadata } from '../../src/types'; @@ -37,6 +37,7 @@ beforeEach(function () { // @ts-ignore console.log(`... ${this.currentTest.fullTitle()}`); sandbox = sinon.createSandbox(); + fs.removeSync(path.resolve(localDir)); }); afterEach(function () { @@ -44,7 +45,7 @@ afterEach(function () { }); after(() => { - fs.removeSync(path.resolve(localDir)); + // fs.removeSync(path.resolve(localDir)); }); describe(' put', () => { @@ -68,7 +69,7 @@ describe(' put', () => { gitDDB, '', _id, - _id + JSON_EXTENSION, + _id + JSON_POSTFIX, toSortedJSONString({ _id, name: 'shirase' }) ) ).rejects.toThrowError(Err.DatabaseClosingError); @@ -102,7 +103,7 @@ describe(' put', () => { gitDDB, '', _id, - _id + JSON_EXTENSION, + _id + JSON_POSTFIX, toSortedJSONString(json) ); const afterTimestamp = Math.floor(Date.now() / 1000) * 1000; @@ -119,7 +120,7 @@ describe(' put', () => { // Check NormalizedCommit expect(pickedPutResult.commit.oid).toBe(currentCommitOid); expect(pickedPutResult.commit.message).toBe( - `insert: ${_id}${JSON_EXTENSION}(${oid.substr(0, SHORT_SHA_LENGTH)})` + `insert: ${_id}${JSON_POSTFIX}(${oid.substr(0, SHORT_SHA_LENGTH)})` ); expect(pickedPutResult.commit.parent).toEqual([prevCommitOid]); expect(pickedPutResult.commit.author.name).toEqual(gitDDB.author.name); @@ -149,13 +150,13 @@ describe(' put', () => { gitDDB, '', _id, - _id + JSON_EXTENSION, + _id + JSON_POSTFIX, toSortedJSONString(json) ); const shortOid = pickedPutResult.fileOid.substr(0, SHORT_SHA_LENGTH); expect(pickedPutResult.commit.message).toEqual( - `insert: ${_id}${JSON_EXTENSION}(${shortOid})` + `insert: ${_id}${JSON_POSTFIX}(${shortOid})` ); // Check commit directly @@ -165,7 +166,7 @@ describe(' put', () => { dir: gitDDB.workingDir, oid: commitOid, }); - expect(commit.message).toEqual(`insert: ${_id}${JSON_EXTENSION}(${shortOid})\n`); + expect(commit.message).toEqual(`insert: ${_id}${JSON_POSTFIX}(${shortOid})\n`); await gitDDB.destroy(); }); @@ -178,19 +179,19 @@ describe(' put', () => { await gitDDB.open(); const _id = 'prof01'; const json = { _id, name: 'Shirase' }; - await putImpl(gitDDB, '', _id, _id + JSON_EXTENSION, toSortedJSONString(json)); + await putImpl(gitDDB, '', _id, _id + JSON_POSTFIX, toSortedJSONString(json)); // update const pickedPutResult = await putImpl( gitDDB, '', _id, - _id + JSON_EXTENSION, + _id + JSON_POSTFIX, toSortedJSONString(json) ); const shortOid = pickedPutResult.fileOid.substr(0, SHORT_SHA_LENGTH); expect(pickedPutResult.commit.message).toEqual( - `update: ${_id}${JSON_EXTENSION}(${shortOid})` + `update: ${_id}${JSON_POSTFIX}(${shortOid})` ); // Check commit directly @@ -200,7 +201,7 @@ describe(' put', () => { dir: gitDDB.workingDir, oid: commitOid, }); - expect(commit.message).toEqual(`update: ${_id}${JSON_EXTENSION}(${shortOid})\n`); + expect(commit.message).toEqual(`update: ${_id}${JSON_POSTFIX}(${shortOid})\n`); await gitDDB.destroy(); }); @@ -217,11 +218,11 @@ describe(' put', () => { gitDDB, '', _id, - _id + JSON_EXTENSION, + _id + JSON_POSTFIX, toSortedJSONString(json) ); const shortOid = pickedPutResult.fileOid.substr(0, SHORT_SHA_LENGTH); - const defaultCommitMessage = `insert: ${_id}${JSON_EXTENSION}(${shortOid})`; + const defaultCommitMessage = `insert: ${_id}${JSON_POSTFIX}(${shortOid})`; expect(pickedPutResult.commit.message).toEqual(defaultCommitMessage); // Check commit directly @@ -251,7 +252,7 @@ describe(' put', () => { gitDDB, '', i.toString(), - i.toString() + JSON_EXTENSION, + i.toString() + JSON_POSTFIX, toSortedJSONString({ _id: i.toString() }), { commitMessage: `${i}`, @@ -282,7 +283,7 @@ describe(' put', () => { gitDDB, '', _id, - _id + JSON_EXTENSION, + _id + JSON_POSTFIX, toSortedJSONString(json), { commitMessage: myCommitMessage, @@ -331,54 +332,54 @@ describe(' put', () => { const json_p = { _id: _id_p, name: name_p }; await Promise.all([ - putImpl(gitDDB, '', _id_a, _id_a + JSON_EXTENSION, toSortedJSONString(json_a)), - putImpl(gitDDB, '', _id_b, _id_b + JSON_EXTENSION, toSortedJSONString(json_b)), - putImpl(gitDDB, '', _id_c01, _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01)), - putImpl(gitDDB, '', _id_c02, _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02)), - putImpl(gitDDB, '', _id_d, _id_d + JSON_EXTENSION, toSortedJSONString(json_d)), - putImpl(gitDDB, '', _id_p, _id_p + JSON_EXTENSION, toSortedJSONString(json_p)), + putImpl(gitDDB, '', _id_a, _id_a + JSON_POSTFIX, toSortedJSONString(json_a)), + putImpl(gitDDB, '', _id_b, _id_b + JSON_POSTFIX, toSortedJSONString(json_b)), + putImpl(gitDDB, '', _id_c01, _id_c01 + JSON_POSTFIX, toSortedJSONString(json_c01)), + putImpl(gitDDB, '', _id_c02, _id_c02 + JSON_POSTFIX, toSortedJSONString(json_c02)), + putImpl(gitDDB, '', _id_d, _id_d + JSON_POSTFIX, toSortedJSONString(json_d)), + putImpl(gitDDB, '', _id_p, _id_p + JSON_POSTFIX, toSortedJSONString(json_p)), ]); await expect(gitDDB.findFatDoc()).resolves.toEqual( expect.arrayContaining([ { _id: _id_a, - name: _id_a + JSON_EXTENSION, + name: _id_a + JSON_POSTFIX, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_a) })).oid, type: 'json', doc: json_a, }, { _id: _id_b, - name: _id_b + JSON_EXTENSION, + name: _id_b + JSON_POSTFIX, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_b) })).oid, type: 'json', doc: json_b, }, { _id: _id_c01, - name: _id_c01 + JSON_EXTENSION, + name: _id_c01 + JSON_POSTFIX, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_c01) })).oid, type: 'json', doc: json_c01, }, { _id: _id_c02, - name: _id_c02 + JSON_EXTENSION, + name: _id_c02 + JSON_POSTFIX, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_c02) })).oid, type: 'json', doc: json_c02, }, { _id: _id_d, - name: _id_d + JSON_EXTENSION, + name: _id_d + JSON_POSTFIX, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_d) })).oid, type: 'json', doc: json_d, }, { _id: _id_p, - name: _id_p + JSON_EXTENSION, + name: _id_p + JSON_POSTFIX, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_p) })).oid, type: 'json', doc: json_p, @@ -404,7 +405,7 @@ describe(' put', () => { gitDDB, '', i.toString(), - i.toString() + JSON_EXTENSION, + i.toString() + JSON_POSTFIX, toSortedJSONString({ _id: i.toString() }) ) ); @@ -433,18 +434,12 @@ describe(' put', () => { gitDDB, '', i.toString(), - i.toString() + JSON_EXTENSION, + i.toString() + JSON_POSTFIX, toSortedJSONString({ _id: i.toString() }) ); } // The last put() with await keyword is resolved after all preceding (queued) Promises - await putImpl( - gitDDB, - '', - '99', - '99' + JSON_EXTENSION, - toSortedJSONString({ _id: '99' }) - ); + await putImpl(gitDDB, '', '99', '99' + JSON_POSTFIX, toSortedJSONString({ _id: '99' })); const fatDocs = await gitDDB.find(); expect(fatDocs.length).toBe(100); @@ -461,13 +456,13 @@ describe(' put', () => { const enqueueEvent: TaskMetadata[] = []; const id1 = gitDDB.taskQueue.newTaskId(); const id2 = gitDDB.taskQueue.newTaskId(); - await putImpl(gitDDB, '', '1', '1' + JSON_EXTENSION, toSortedJSONString({ _id: '1' }), { + await putImpl(gitDDB, '', '1', '1' + JSON_POSTFIX, toSortedJSONString({ _id: '1' }), { taskId: id1, enqueueCallback: (taskMetadata: TaskMetadata) => { enqueueEvent.push(taskMetadata); }, }); - await putImpl(gitDDB, '', '2', '2' + JSON_EXTENSION, toSortedJSONString({ _id: '2' }), { + await putImpl(gitDDB, '', '2', '2' + JSON_POSTFIX, toSortedJSONString({ _id: '2' }), { taskId: id2, enqueueCallback: (taskMetadata: TaskMetadata) => { enqueueEvent.push(taskMetadata); @@ -495,7 +490,7 @@ describe(' put', () => { gitDDB, '', i.toString(), - i.toString() + JSON_EXTENSION, + i.toString() + JSON_POSTFIX, toSortedJSONString({ _id: i.toString() }) ).catch( // eslint-disable-next-line no-loop-func @@ -511,6 +506,128 @@ describe(' put', () => { }); }); +describe(' put to front matter', () => { + it('write sorted front matter with markdown', async () => { + const dbName = monoId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + serializeFormat: 'front-matter', + }); + await gitDDB.open(); + await gitDDB.put({ + b: 'bbb', + a: 'aaa', + _id: 'foo', + _body: 'This is a body text.\nThe second line.', + c: 'ccc', + array: [1, 2, 3], + }); + const result = `--- +_id: foo +a: aaa +array: + - 1 + - 2 + - 3 +b: bbb +c: ccc +--- +This is a body text. +The second line.`; + const fullDocPath = 'foo.md'; + expect(readFileSync(path.resolve(gitDDB.workingDir, fullDocPath), 'utf8')).toBe(result); + + await gitDDB.close(); + await gitDDB.destroy(); + }); + + it('write hierarchical front matter with markdown', async () => { + const dbName = monoId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + serializeFormat: 'front-matter', + }); + await gitDDB.open(); + await gitDDB.put({ + a: { + a_1: 'a-1', + a_2: 'a-2', + }, + b: [{ b_1: 'b-1' }, { b_2: 'b-2' }], + _id: 'foo', + _body: 'This is a body text.\nThe second line.', + }); + const result = `--- +_id: foo +a: + a_1: a-1 + a_2: a-2 +b: + - b_1: b-1 + - b_2: b-2 +--- +This is a body text. +The second line.`; + const fullDocPath = 'foo.md'; + expect(readFileSync(path.resolve(gitDDB.workingDir, fullDocPath), 'utf8')).toBe(result); + + await gitDDB.close(); + await gitDDB.destroy(); + }); + + it('write non-ASCII front matter with markdown', async () => { + const dbName = monoId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + serializeFormat: 'front-matter', + }); + await gitDDB.open(); + await gitDDB.put({ + a: '春はあけぼの', + _id: 'foo', + _body: + 'やうやう白くなりゆく山ぎは、すこしあかりて、紫だちたる雲のほそくたなびきたる。', + }); + const result = `--- +_id: foo +a: 春はあけぼの +--- +やうやう白くなりゆく山ぎは、すこしあかりて、紫だちたる雲のほそくたなびきたる。`; + const fullDocPath = 'foo.md'; + expect(readFileSync(path.resolve(gitDDB.workingDir, fullDocPath), 'utf8')).toBe(result); + + await gitDDB.close(); + await gitDDB.destroy(); + }); + + it('write front matter without markdown', async () => { + const dbName = monoId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + serializeFormat: 'front-matter', + }); + await gitDDB.open(); + await gitDDB.put({ + _id: 'foo', + a: 'bar', + }); + const result = `--- +_id: foo +a: bar +--- +`; + const fullDocPath = 'foo.md'; + expect(readFileSync(path.resolve(gitDDB.workingDir, fullDocPath), 'utf8')).toBe(result); + + await gitDDB.close(); + await gitDDB.destroy(); + }); +}); + describe(' putWorker', () => { it('throws UndefinedDBError when Undefined DB', async () => { // @ts-ignore @@ -532,7 +649,7 @@ describe(' putWorker', () => { putWorker( gitDDB, '', - 'prof01' + JSON_EXTENSION, + 'prof01' + JSON_POSTFIX, '{ "_id": "prof01", "name": "Shirase" }', 'message' ) @@ -547,7 +664,7 @@ describe(' putWorker', () => { localDir, }); await gitDDB.open(); - const fullDocPath = 'prof01' + JSON_EXTENSION; + const fullDocPath = 'prof01' + JSON_POSTFIX; await putWorker( gitDDB, '', @@ -575,7 +692,7 @@ describe(' putWorker', () => { localDir, }); await gitDDB.open(); - const fullDocPath = 'prof01' + JSON_EXTENSION; + const fullDocPath = 'prof01' + JSON_POSTFIX; await expect( putWorker( gitDDB, @@ -617,7 +734,7 @@ describe(' putWorker', () => { await gitDDB.open(); const json = { _id: 'prof01', name: 'Shirase' }; - const fullDocPath = json._id + JSON_EXTENSION; + const fullDocPath = json._id + JSON_POSTFIX; await putWorker(gitDDB, '', fullDocPath, toSortedJSONString(json), 'message'); expect(readFileSync(path.resolve(gitDDB.workingDir, fullDocPath), 'utf8')).toBe( toSortedJSONString(json) @@ -635,7 +752,7 @@ describe(' putWorker', () => { await gitDDB.open(); const json = { _id: 'prof01', name: 'Shirase' }; - const fullDocPath = json._id + JSON_EXTENSION; + const fullDocPath = json._id + JSON_POSTFIX; await putWorker(gitDDB, '', fullDocPath, toSortedJSONString(json), 'message'); const json2 = { _id: 'prof01', name: 'updated document' }; @@ -677,66 +794,66 @@ describe(' putWorker', () => { const json_p = { _id: _id_p, name: name_p }; await Promise.all([ - putWorker(gitDDB, '', _id_a + JSON_EXTENSION, toSortedJSONString(json_a), 'message'), - putWorker(gitDDB, '', _id_b + JSON_EXTENSION, toSortedJSONString(json_b), 'message'), + putWorker(gitDDB, '', _id_a + JSON_POSTFIX, toSortedJSONString(json_a), 'message'), + putWorker(gitDDB, '', _id_b + JSON_POSTFIX, toSortedJSONString(json_b), 'message'), putWorker( gitDDB, '', - _id_c01 + JSON_EXTENSION, + _id_c01 + JSON_POSTFIX, toSortedJSONString(json_c01), 'message' ), putWorker( gitDDB, '', - _id_c02 + JSON_EXTENSION, + _id_c02 + JSON_POSTFIX, toSortedJSONString(json_c02), 'message' ), - putWorker(gitDDB, '', _id_d + JSON_EXTENSION, toSortedJSONString(json_d), 'message'), - putWorker(gitDDB, '', _id_p + JSON_EXTENSION, toSortedJSONString(json_p), 'message'), + putWorker(gitDDB, '', _id_d + JSON_POSTFIX, toSortedJSONString(json_d), 'message'), + putWorker(gitDDB, '', _id_p + JSON_POSTFIX, toSortedJSONString(json_p), 'message'), ]); await expect(gitDDB.findFatDoc()).resolves.toEqual( expect.arrayContaining([ { _id: _id_a, - name: _id_a + JSON_EXTENSION, + name: _id_a + JSON_POSTFIX, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_a) })).oid, type: 'json', doc: json_a, }, { _id: _id_b, - name: _id_b + JSON_EXTENSION, + name: _id_b + JSON_POSTFIX, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_b) })).oid, type: 'json', doc: json_b, }, { _id: _id_c01, - name: _id_c01 + JSON_EXTENSION, + name: _id_c01 + JSON_POSTFIX, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_c01) })).oid, type: 'json', doc: json_c01, }, { _id: _id_c02, - name: _id_c02 + JSON_EXTENSION, + name: _id_c02 + JSON_POSTFIX, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_c02) })).oid, type: 'json', doc: json_c02, }, { _id: _id_d, - name: _id_d + JSON_EXTENSION, + name: _id_d + JSON_POSTFIX, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_d) })).oid, type: 'json', doc: json_d, }, { _id: _id_p, - name: _id_p + JSON_EXTENSION, + name: _id_p + JSON_POSTFIX, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_p) })).oid, type: 'json', doc: json_p, diff --git a/test/git_documentdb_crud.test.ts b/test/git_documentdb_crud.test.ts index 6ea9d284..aa921d71 100644 --- a/test/git_documentdb_crud.test.ts +++ b/test/git_documentdb_crud.test.ts @@ -15,7 +15,7 @@ import fs from 'fs-extra'; import { DeleteResultJsonDoc, PutResultJsonDoc } from '../src/types'; import { GitDocumentDB } from '../src/git_documentdb'; import { sleep, toSortedJSONString } from '../src/utils'; -import { JSON_EXTENSION, SHORT_SHA_LENGTH } from '../src/const'; +import { JSON_POSTFIX, SHORT_SHA_LENGTH } from '../src/const'; import { addOneData } from './utils'; import { Err } from '../src/error'; @@ -85,10 +85,10 @@ describe(' put(jsonDoc)', () => { const shortOid = fileOid.substr(0, SHORT_SHA_LENGTH); expect(putResult._id).toBe(_id); expect(putResult.fileOid).toBe(fileOid); - expect(putResult.commit.message).toBe(`insert: ${_id}${JSON_EXTENSION}(${shortOid})`); + expect(putResult.commit.message).toBe(`insert: ${_id}${JSON_POSTFIX}(${shortOid})`); // fs.access() throw error when a file cannot be accessed. - const filePath = path.resolve(gitDDB.workingDir, _id + JSON_EXTENSION); + const filePath = path.resolve(gitDDB.workingDir, _id + JSON_POSTFIX); await expect(fs.access(filePath)).resolves.not.toThrowError(); expect(fs.readFileSync(filePath, 'utf8')).toBe(toSortedJSONString(json)); @@ -196,10 +196,10 @@ describe(' put(_id, jsonDoc)', () => { const shortOid = fileOid.substr(0, SHORT_SHA_LENGTH); expect(putResult._id).toBe(_id); expect(putResult.fileOid).toBe(fileOid); - expect(putResult.commit.message).toBe(`insert: ${_id}${JSON_EXTENSION}(${shortOid})`); + expect(putResult.commit.message).toBe(`insert: ${_id}${JSON_POSTFIX}(${shortOid})`); // fs.access() throw error when a file cannot be accessed. - const filePath = path.resolve(gitDDB.workingDir, _id + JSON_EXTENSION); + const filePath = path.resolve(gitDDB.workingDir, _id + JSON_POSTFIX); await expect(fs.access(filePath)).resolves.not.toThrowError(); expect(fs.readFileSync(filePath, 'utf8')).toBe(toSortedJSONString(json)); @@ -279,17 +279,17 @@ describe(' putFatDoc(name, jsonDoc)', () => { }); await gitDDB.open(); const _id = 'prof01'; - const name = _id + JSON_EXTENSION; + const name = _id + JSON_POSTFIX; const json = { _id, name: 'Shirase' }; const putResult = (await gitDDB.putFatDoc(name, json)) as PutResultJsonDoc; const fileOid = (await git.hashBlob({ object: toSortedJSONString(json) })).oid; const shortOid = fileOid.substr(0, SHORT_SHA_LENGTH); expect(putResult._id).toBe(_id); expect(putResult.fileOid).toBe(fileOid); - expect(putResult.commit.message).toBe(`insert: ${_id}${JSON_EXTENSION}(${shortOid})`); + expect(putResult.commit.message).toBe(`insert: ${_id}${JSON_POSTFIX}(${shortOid})`); // fs.access() throw error when a file cannot be accessed. - const filePath = path.resolve(gitDDB.workingDir, _id + JSON_EXTENSION); + const filePath = path.resolve(gitDDB.workingDir, _id + JSON_POSTFIX); await expect(fs.access(filePath)).resolves.not.toThrowError(); expect(fs.readFileSync(filePath, 'utf8')).toBe(toSortedJSONString(json)); @@ -312,10 +312,10 @@ describe(' insert(jsonDoc)', () => { const shortOid = fileOid.substr(0, SHORT_SHA_LENGTH); expect(putResult._id).toBe(_id); expect(putResult.fileOid).toBe(fileOid); - expect(putResult.commit.message).toBe(`insert: ${_id}${JSON_EXTENSION}(${shortOid})`); + expect(putResult.commit.message).toBe(`insert: ${_id}${JSON_POSTFIX}(${shortOid})`); // fs.access() throw error when a file cannot be accessed. - const filePath = path.resolve(gitDDB.workingDir, _id + JSON_EXTENSION); + const filePath = path.resolve(gitDDB.workingDir, _id + JSON_POSTFIX); await expect(fs.access(filePath)).resolves.not.toThrowError(); expect(fs.readFileSync(filePath, 'utf8')).toBe(toSortedJSONString(json)); @@ -357,10 +357,10 @@ describe(' insert(_id, jsonDoc)', () => { const shortOid = fileOid.substr(0, SHORT_SHA_LENGTH); expect(putResult._id).toBe(_id); expect(putResult.fileOid).toBe(fileOid); - expect(putResult.commit.message).toBe(`insert: ${_id}${JSON_EXTENSION}(${shortOid})`); + expect(putResult.commit.message).toBe(`insert: ${_id}${JSON_POSTFIX}(${shortOid})`); // fs.access() throw error when a file cannot be accessed. - const filePath = path.resolve(gitDDB.workingDir, _id + JSON_EXTENSION); + const filePath = path.resolve(gitDDB.workingDir, _id + JSON_POSTFIX); await expect(fs.access(filePath)).resolves.not.toThrowError(); expect(fs.readFileSync(filePath, 'utf8')).toBe(toSortedJSONString(json)); @@ -396,17 +396,17 @@ describe(' insertFatDoc(name, jsonDoc)', () => { }); await gitDDB.open(); const _id = 'prof01'; - const name = _id + JSON_EXTENSION; + const name = _id + JSON_POSTFIX; const json = { _id, name: 'Shirase' }; const putResult = (await gitDDB.insertFatDoc(name, json)) as PutResultJsonDoc; const fileOid = (await git.hashBlob({ object: toSortedJSONString(json) })).oid; const shortOid = fileOid.substr(0, SHORT_SHA_LENGTH); expect(putResult._id).toBe(_id); expect(putResult.fileOid).toBe(fileOid); - expect(putResult.commit.message).toBe(`insert: ${_id}${JSON_EXTENSION}(${shortOid})`); + expect(putResult.commit.message).toBe(`insert: ${_id}${JSON_POSTFIX}(${shortOid})`); // fs.access() throw error when a file cannot be accessed. - const filePath = path.resolve(gitDDB.workingDir, _id + JSON_EXTENSION); + const filePath = path.resolve(gitDDB.workingDir, _id + JSON_POSTFIX); await expect(fs.access(filePath)).resolves.not.toThrowError(); expect(fs.readFileSync(filePath, 'utf8')).toBe(toSortedJSONString(json)); @@ -432,10 +432,10 @@ describe(' update(jsonDoc)', () => { const shortOid = fileOid.substr(0, SHORT_SHA_LENGTH); expect(putResult._id).toBe(_id); expect(putResult.fileOid).toBe(fileOid); - expect(putResult.commit.message).toBe(`update: ${_id}${JSON_EXTENSION}(${shortOid})`); + expect(putResult.commit.message).toBe(`update: ${_id}${JSON_POSTFIX}(${shortOid})`); // fs.access() throw error when a file cannot be accessed. - const filePath = path.resolve(gitDDB.workingDir, _id + JSON_EXTENSION); + const filePath = path.resolve(gitDDB.workingDir, _id + JSON_POSTFIX); await expect(fs.access(filePath)).resolves.not.toThrowError(); expect(fs.readFileSync(filePath, 'utf8')).toBe(toSortedJSONString(jsonUpdated)); @@ -480,10 +480,10 @@ describe(' update(_id, jsonDoc', () => { const shortOid = fileOid.substr(0, SHORT_SHA_LENGTH); expect(putResult._id).toBe(_id); expect(putResult.fileOid).toBe(fileOid); - expect(putResult.commit.message).toBe(`update: ${_id}${JSON_EXTENSION}(${shortOid})`); + expect(putResult.commit.message).toBe(`update: ${_id}${JSON_POSTFIX}(${shortOid})`); // fs.access() throw error when a file cannot be accessed. - const filePath = path.resolve(gitDDB.workingDir, _id + JSON_EXTENSION); + const filePath = path.resolve(gitDDB.workingDir, _id + JSON_POSTFIX); await expect(fs.access(filePath)).resolves.not.toThrowError(); expect(fs.readFileSync(filePath, 'utf8')).toBe(toSortedJSONString(jsonUpdated)); @@ -520,7 +520,7 @@ describe(' updateFatDoc(name, jsonDoc', () => { }); await gitDDB.open(); const _id = 'prof01'; - const name = _id + JSON_EXTENSION; + const name = _id + JSON_POSTFIX; const json = { _id, name: 'Shirase' }; await gitDDB.insert(json); const jsonUpdated = { _id, name: 'updated' }; @@ -529,10 +529,10 @@ describe(' updateFatDoc(name, jsonDoc', () => { const shortOid = fileOid.substr(0, SHORT_SHA_LENGTH); expect(putResult._id).toBe(_id); expect(putResult.fileOid).toBe(fileOid); - expect(putResult.commit.message).toBe(`update: ${_id}${JSON_EXTENSION}(${shortOid})`); + expect(putResult.commit.message).toBe(`update: ${_id}${JSON_POSTFIX}(${shortOid})`); // fs.access() throw error when a file cannot be accessed. - const filePath = path.resolve(gitDDB.workingDir, _id + JSON_EXTENSION); + const filePath = path.resolve(gitDDB.workingDir, _id + JSON_POSTFIX); await expect(fs.access(filePath)).resolves.not.toThrowError(); expect(fs.readFileSync(filePath, 'utf8')).toBe(toSortedJSONString(jsonUpdated)); @@ -563,7 +563,7 @@ describe(' get()', () => { }); await gitDDB.open(); const shortId = 'dir01/prof01'; - const fullDocPath = shortId + JSON_EXTENSION; + const fullDocPath = shortId + JSON_POSTFIX; const json01 = { _id: shortId, name: 'v1' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json01)); @@ -579,7 +579,7 @@ describe(' get()', () => { }); await gitDDB.open(); const shortId = 'prof01'; - const fullDocPath = shortId + JSON_EXTENSION; + const fullDocPath = shortId + JSON_POSTFIX; const json01 = { _id: shortId, name: 'v1' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json01)); @@ -598,8 +598,8 @@ describe(' getFatDoc()', () => { }); await gitDDB.open(); const shortId = 'prof01'; - const shortName = shortId + JSON_EXTENSION; - const fullDocPath = shortId + JSON_EXTENSION; + const shortName = shortId + JSON_POSTFIX; + const fullDocPath = shortId + JSON_POSTFIX; const json01 = { _id: shortId, name: 'v1' }; const json02 = { _id: shortId, name: 'v2' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json01)); @@ -638,7 +638,7 @@ describe(' getDocByOid()', () => { }); await gitDDB.open(); const shortId = 'dir01/prof01'; - const fullDocPath = shortId + JSON_EXTENSION; + const fullDocPath = shortId + JSON_POSTFIX; const json01 = { _id: shortId, name: 'v1' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json01)); const { oid } = await git.hashBlob({ object: toSortedJSONString(json01) }); @@ -654,7 +654,7 @@ describe(' getDocByOid()', () => { }); await gitDDB.open(); const shortId = 'dir01/prof01'; - const fullDocPath = shortId + JSON_EXTENSION; + const fullDocPath = shortId + JSON_POSTFIX; const json01 = { _id: shortId, name: 'v1' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json01)); await expect(gitDDB.getDocByOid('not exist', 'json')).resolves.toBeUndefined(); @@ -670,8 +670,8 @@ describe('', () => { }); const targetId = '01'; - const targetName = targetId + JSON_EXTENSION; - const fullDocPath = targetId + JSON_EXTENSION; + const targetName = targetId + JSON_POSTFIX; + const fullDocPath = targetId + JSON_POSTFIX; const json01 = { _id: targetId, name: 'v01' }; const json02 = { _id: targetId, name: 'v02' }; @@ -1099,7 +1099,7 @@ describe(' getFatDocHistory()', () => { await gitDDB.open(); const _idA = 'profA'; - const shortNameA = _idA + JSON_EXTENSION; + const shortNameA = _idA + JSON_POSTFIX; const jsonA01 = { _id: _idA, name: 'v01' }; const jsonA02 = { _id: _idA, name: 'v02' }; const jsonA03 = { _id: _idA, name: 'v03' }; @@ -1107,7 +1107,7 @@ describe(' getFatDocHistory()', () => { await gitDDB.put(jsonA02); await gitDDB.put(jsonA03); const _idB = 'profB'; - const shortNameB = _idB + JSON_EXTENSION; + const shortNameB = _idB + JSON_POSTFIX; const jsonB01 = { _id: _idB, name: 'v01' }; const jsonB02 = { _id: _idB, name: 'v02' }; await gitDDB.put(jsonB01); @@ -1135,7 +1135,7 @@ describe(' getFatDocHistory()', () => { await gitDDB.open(); const _idA = 'profA'; - const shortNameA = _idA + JSON_EXTENSION; + const shortNameA = _idA + JSON_POSTFIX; const jsonA01 = { _id: _idA, name: 'v01' }; const jsonA02 = { _id: _idA, name: 'v02' }; const jsonA03 = { _id: _idA, name: 'v03' }; @@ -1150,7 +1150,7 @@ describe(' getFatDocHistory()', () => { await gitDDB.put(jsonA03); const _idB = 'profB'; - const shortNameB = _idB + JSON_EXTENSION; + const shortNameB = _idB + JSON_POSTFIX; const jsonB01 = { _id: _idB, name: 'v01' }; const jsonB02 = { _id: _idB, name: 'v02' }; @@ -1377,9 +1377,7 @@ describe(' delete(_id)', () => { const deleteResult = await gitDDB.delete(_id); expect(deleteResult._id).toBe(_id); expect(deleteResult.fileOid).toBe(putResult.fileOid); - expect(deleteResult.commit.message).toBe( - `delete: ${_id}${JSON_EXTENSION}(${shortOid})` - ); + expect(deleteResult.commit.message).toBe(`delete: ${_id}${JSON_POSTFIX}(${shortOid})`); // Check commit directly const commitOid = await git.resolveRef({ fs, dir: gitDDB.workingDir, ref: 'HEAD' }); @@ -1388,7 +1386,7 @@ describe(' delete(_id)', () => { dir: gitDDB.workingDir, oid: commitOid, }); - expect(commit.message).toEqual(`delete: ${_id}${JSON_EXTENSION}(${shortOid})\n`); + expect(commit.message).toEqual(`delete: ${_id}${JSON_POSTFIX}(${shortOid})\n`); await expect(gitDDB.delete(_id)).rejects.toThrowError(Err.DocumentNotFoundError); await expect(gitDDB.get(_id)).resolves.toBeUndefined(); @@ -1468,7 +1466,7 @@ describe(' delete(jsonDoc)', () => { // Check NormalizedCommit expect(deleteResult.commit.oid).toBe(currentCommitOid); expect(deleteResult.commit.message).toBe( - `delete: ${_id}${JSON_EXTENSION}(${oid.substr(0, SHORT_SHA_LENGTH)})` + `delete: ${_id}${JSON_POSTFIX}(${oid.substr(0, SHORT_SHA_LENGTH)})` ); expect(deleteResult.commit.parent).toEqual([prevCommitOid]); expect(deleteResult.commit.author.name).toEqual(gitDDB.author.name); @@ -1494,9 +1492,9 @@ describe(' deleteFatDoc(name)', () => { await gitDDB.open(); const _id = 'test/prof01'; - const name = _id + JSON_EXTENSION; + const name = _id + JSON_POSTFIX; const _id2 = 'test/prof02'; - const name2 = _id2 + JSON_EXTENSION; + const name2 = _id2 + JSON_POSTFIX; const putResult = await gitDDB.put({ _id: _id, name: 'Shirase' }); await gitDDB.put({ _id: _id2, name: 'Soya' }); @@ -1506,9 +1504,7 @@ describe(' deleteFatDoc(name)', () => { const deleteResult = (await gitDDB.deleteFatDoc(name)) as DeleteResultJsonDoc; expect(deleteResult._id).toBe(_id); expect(deleteResult.fileOid).toBe(putResult.fileOid); - expect(deleteResult.commit.message).toBe( - `delete: ${_id}${JSON_EXTENSION}(${shortOid})` - ); + expect(deleteResult.commit.message).toBe(`delete: ${_id}${JSON_POSTFIX}(${shortOid})`); // Check commit directly const commitOid = await git.resolveRef({ fs, dir: gitDDB.workingDir, ref: 'HEAD' }); @@ -1517,7 +1513,7 @@ describe(' deleteFatDoc(name)', () => { dir: gitDDB.workingDir, oid: commitOid, }); - expect(commit.message).toEqual(`delete: ${_id}${JSON_EXTENSION}(${shortOid})\n`); + expect(commit.message).toEqual(`delete: ${_id}${JSON_POSTFIX}(${shortOid})\n`); await expect(gitDDB.deleteFatDoc(name)).rejects.toThrowError(Err.DocumentNotFoundError); await expect(gitDDB.get(_id)).resolves.toBeUndefined(); @@ -1569,7 +1565,7 @@ describe('', () => { }); await gitDDB.open(); - await addOneData(gitDDB, 'invalidJSON' + JSON_EXTENSION, 'invalidJSON'); + await addOneData(gitDDB, 'invalidJSON' + JSON_POSTFIX, 'invalidJSON'); await expect(gitDDB.find()).rejects.toThrowError(Err.InvalidJsonObjectError); @@ -1611,11 +1607,11 @@ describe('', () => { const json_c01_ = { _id: _id_c01, name: name_c01 }; const json_c02_ = { _id: _id_c02, name: name_c02 }; - await addOneData(gitDDB, _id_b + JSON_EXTENSION, toSortedJSONString(json_b)); - await addOneData(gitDDB, _id_a + JSON_EXTENSION, toSortedJSONString(json_a)); - await addOneData(gitDDB, _id_d + JSON_EXTENSION, toSortedJSONString(json_d)); - await addOneData(gitDDB, _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01)); - await addOneData(gitDDB, _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02)); + await addOneData(gitDDB, _id_b + JSON_POSTFIX, toSortedJSONString(json_b)); + await addOneData(gitDDB, _id_a + JSON_POSTFIX, toSortedJSONString(json_a)); + await addOneData(gitDDB, _id_d + JSON_POSTFIX, toSortedJSONString(json_d)); + await addOneData(gitDDB, _id_c01 + JSON_POSTFIX, toSortedJSONString(json_c01)); + await addOneData(gitDDB, _id_c02 + JSON_POSTFIX, toSortedJSONString(json_c02)); await expect(gitDDB.find()).resolves.toEqual([ json_a_, @@ -1653,13 +1649,13 @@ describe('', () => { const json_c01_ = { _id: _id_c01, name: name_c01 }; const json_c02_ = { _id: _id_c02, name: name_c02 }; - await addOneData(gitDDB, _id_b + JSON_EXTENSION, toSortedJSONString(json_b)); - await addOneData(gitDDB, _id_a + JSON_EXTENSION, toSortedJSONString(json_a)); - await addOneData(gitDDB, _id_d + JSON_EXTENSION, toSortedJSONString(json_d)); - await addOneData(gitDDB, _id_c000 + JSON_EXTENSION, toSortedJSONString(json_c000)); - await addOneData(gitDDB, _id_c001 + JSON_EXTENSION, toSortedJSONString(json_c001)); - await addOneData(gitDDB, _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01)); - await addOneData(gitDDB, _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02)); + await addOneData(gitDDB, _id_b + JSON_POSTFIX, toSortedJSONString(json_b)); + await addOneData(gitDDB, _id_a + JSON_POSTFIX, toSortedJSONString(json_a)); + await addOneData(gitDDB, _id_d + JSON_POSTFIX, toSortedJSONString(json_d)); + await addOneData(gitDDB, _id_c000 + JSON_POSTFIX, toSortedJSONString(json_c000)); + await addOneData(gitDDB, _id_c001 + JSON_POSTFIX, toSortedJSONString(json_c001)); + await addOneData(gitDDB, _id_c01 + JSON_POSTFIX, toSortedJSONString(json_c01)); + await addOneData(gitDDB, _id_c02 + JSON_POSTFIX, toSortedJSONString(json_c02)); const prefix = 'citrus/'; @@ -1692,13 +1688,13 @@ describe('', () => { const json_c01_ = { _id: _id_c01, name: name_c01 }; const json_c02_ = { _id: _id_c02, name: name_c02 }; - await addOneData(gitDDB, _id_b + JSON_EXTENSION, toSortedJSONString(json_b)); - await addOneData(gitDDB, _id_a + JSON_EXTENSION, toSortedJSONString(json_a)); - await addOneData(gitDDB, _id_d + JSON_EXTENSION, toSortedJSONString(json_d)); - await addOneData(gitDDB, _id_c000 + JSON_EXTENSION, toSortedJSONString(json_c000)); - await addOneData(gitDDB, _id_c001 + JSON_EXTENSION, toSortedJSONString(json_c001)); - await addOneData(gitDDB, _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01)); - await addOneData(gitDDB, _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02)); + await addOneData(gitDDB, _id_b + JSON_POSTFIX, toSortedJSONString(json_b)); + await addOneData(gitDDB, _id_a + JSON_POSTFIX, toSortedJSONString(json_a)); + await addOneData(gitDDB, _id_d + JSON_POSTFIX, toSortedJSONString(json_d)); + await addOneData(gitDDB, _id_c000 + JSON_POSTFIX, toSortedJSONString(json_c000)); + await addOneData(gitDDB, _id_c001 + JSON_POSTFIX, toSortedJSONString(json_c001)); + await addOneData(gitDDB, _id_c01 + JSON_POSTFIX, toSortedJSONString(json_c01)); + await addOneData(gitDDB, _id_c02 + JSON_POSTFIX, toSortedJSONString(json_c02)); const prefix = 'cit'; @@ -1734,13 +1730,13 @@ describe('', () => { const json_c01_ = { _id: _id_c01, name: name_c01 }; const json_c02_ = { _id: _id_c02, name: name_c02 }; - await addOneData(gitDDB, _id_b + JSON_EXTENSION, toSortedJSONString(json_b)); - await addOneData(gitDDB, _id_a + JSON_EXTENSION, toSortedJSONString(json_a)); - await addOneData(gitDDB, _id_d + JSON_EXTENSION, toSortedJSONString(json_d)); - await addOneData(gitDDB, _id_c000 + JSON_EXTENSION, toSortedJSONString(json_c000)); - await addOneData(gitDDB, _id_c001 + JSON_EXTENSION, toSortedJSONString(json_c001)); - await addOneData(gitDDB, _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01)); - await addOneData(gitDDB, _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02)); + await addOneData(gitDDB, _id_b + JSON_POSTFIX, toSortedJSONString(json_b)); + await addOneData(gitDDB, _id_a + JSON_POSTFIX, toSortedJSONString(json_a)); + await addOneData(gitDDB, _id_d + JSON_POSTFIX, toSortedJSONString(json_d)); + await addOneData(gitDDB, _id_c000 + JSON_POSTFIX, toSortedJSONString(json_c000)); + await addOneData(gitDDB, _id_c001 + JSON_POSTFIX, toSortedJSONString(json_c001)); + await addOneData(gitDDB, _id_c01 + JSON_POSTFIX, toSortedJSONString(json_c01)); + await addOneData(gitDDB, _id_c02 + JSON_POSTFIX, toSortedJSONString(json_c02)); const prefix = 'citrus'; @@ -1778,13 +1774,13 @@ describe('', () => { const json_c01_ = { _id: _id_c01, name: name_c01 }; const json_c02_ = { _id: _id_c02, name: name_c02 }; - await addOneData(gitDDB, _id_b + JSON_EXTENSION, toSortedJSONString(json_b)); - await addOneData(gitDDB, _id_a + JSON_EXTENSION, toSortedJSONString(json_a)); - await addOneData(gitDDB, _id_d + JSON_EXTENSION, toSortedJSONString(json_d)); - await addOneData(gitDDB, _id_c000 + JSON_EXTENSION, toSortedJSONString(json_c000)); - await addOneData(gitDDB, _id_c001 + JSON_EXTENSION, toSortedJSONString(json_c001)); - await addOneData(gitDDB, _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01)); - await addOneData(gitDDB, _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02)); + await addOneData(gitDDB, _id_b + JSON_POSTFIX, toSortedJSONString(json_b)); + await addOneData(gitDDB, _id_a + JSON_POSTFIX, toSortedJSONString(json_a)); + await addOneData(gitDDB, _id_d + JSON_POSTFIX, toSortedJSONString(json_d)); + await addOneData(gitDDB, _id_c000 + JSON_POSTFIX, toSortedJSONString(json_c000)); + await addOneData(gitDDB, _id_c001 + JSON_POSTFIX, toSortedJSONString(json_c001)); + await addOneData(gitDDB, _id_c01 + JSON_POSTFIX, toSortedJSONString(json_c01)); + await addOneData(gitDDB, _id_c02 + JSON_POSTFIX, toSortedJSONString(json_c02)); const prefix = 'citrus/y'; @@ -1817,13 +1813,13 @@ describe('', () => { const json_c01_ = { _id: _id_c01, name: name_c01 }; const json_c02_ = { _id: _id_c02, name: name_c02 }; - await addOneData(gitDDB, _id_b + JSON_EXTENSION, toSortedJSONString(json_b)); - await addOneData(gitDDB, _id_a + JSON_EXTENSION, toSortedJSONString(json_a)); - await addOneData(gitDDB, _id_d + JSON_EXTENSION, toSortedJSONString(json_d)); - await addOneData(gitDDB, _id_c000 + JSON_EXTENSION, toSortedJSONString(json_c000)); - await addOneData(gitDDB, _id_c001 + JSON_EXTENSION, toSortedJSONString(json_c001)); - await addOneData(gitDDB, _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01)); - await addOneData(gitDDB, _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02)); + await addOneData(gitDDB, _id_b + JSON_POSTFIX, toSortedJSONString(json_b)); + await addOneData(gitDDB, _id_a + JSON_POSTFIX, toSortedJSONString(json_a)); + await addOneData(gitDDB, _id_d + JSON_POSTFIX, toSortedJSONString(json_d)); + await addOneData(gitDDB, _id_c000 + JSON_POSTFIX, toSortedJSONString(json_c000)); + await addOneData(gitDDB, _id_c001 + JSON_POSTFIX, toSortedJSONString(json_c001)); + await addOneData(gitDDB, _id_c01 + JSON_POSTFIX, toSortedJSONString(json_c01)); + await addOneData(gitDDB, _id_c02 + JSON_POSTFIX, toSortedJSONString(json_c02)); const prefix = 'not_exist/'; @@ -1859,15 +1855,15 @@ describe('', () => { const json_c01_ = { _id: _id_c01, name: name_c01 }; const json_c02_ = { _id: _id_c02, name: name_c02 }; - await addOneData(gitDDB, _id_p + JSON_EXTENSION, toSortedJSONString(json_p)); + await addOneData(gitDDB, _id_p + JSON_POSTFIX, toSortedJSONString(json_p)); - await addOneData(gitDDB, _id_b + JSON_EXTENSION, toSortedJSONString(json_b)); - await addOneData(gitDDB, _id_a + JSON_EXTENSION, toSortedJSONString(json_a)); - await addOneData(gitDDB, _id_d + JSON_EXTENSION, toSortedJSONString(json_d)); - await addOneData(gitDDB, _id_c000 + JSON_EXTENSION, toSortedJSONString(json_c000)); - await addOneData(gitDDB, _id_c001 + JSON_EXTENSION, toSortedJSONString(json_c001)); - await addOneData(gitDDB, _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01)); - await addOneData(gitDDB, _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02)); + await addOneData(gitDDB, _id_b + JSON_POSTFIX, toSortedJSONString(json_b)); + await addOneData(gitDDB, _id_a + JSON_POSTFIX, toSortedJSONString(json_a)); + await addOneData(gitDDB, _id_d + JSON_POSTFIX, toSortedJSONString(json_d)); + await addOneData(gitDDB, _id_c000 + JSON_POSTFIX, toSortedJSONString(json_c000)); + await addOneData(gitDDB, _id_c001 + JSON_POSTFIX, toSortedJSONString(json_c001)); + await addOneData(gitDDB, _id_c01 + JSON_POSTFIX, toSortedJSONString(json_c01)); + await addOneData(gitDDB, _id_c02 + JSON_POSTFIX, toSortedJSONString(json_c02)); await expect(gitDDB.find({ prefix: 'pear/Japan' })).resolves.toEqual([json_p_]); @@ -1893,44 +1889,44 @@ describe('', () => { const json_c01 = { _id: _id_c01, name: name_c01 }; const json_c02 = { _id: _id_c02, name: name_c02 }; - await addOneData(gitDDB, _id_b + JSON_EXTENSION, toSortedJSONString(json_b)); - await addOneData(gitDDB, _id_a + JSON_EXTENSION, toSortedJSONString(json_a)); - await addOneData(gitDDB, _id_d + JSON_EXTENSION, toSortedJSONString(json_d)); - await addOneData(gitDDB, _id_c01 + JSON_EXTENSION, toSortedJSONString(json_c01)); - await addOneData(gitDDB, _id_c02 + JSON_EXTENSION, toSortedJSONString(json_c02)); + await addOneData(gitDDB, _id_b + JSON_POSTFIX, toSortedJSONString(json_b)); + await addOneData(gitDDB, _id_a + JSON_POSTFIX, toSortedJSONString(json_a)); + await addOneData(gitDDB, _id_d + JSON_POSTFIX, toSortedJSONString(json_d)); + await addOneData(gitDDB, _id_c01 + JSON_POSTFIX, toSortedJSONString(json_c01)); + await addOneData(gitDDB, _id_c02 + JSON_POSTFIX, toSortedJSONString(json_c02)); await expect(gitDDB.findFatDoc()).resolves.toEqual([ { _id: _id_a, - name: _id_a + JSON_EXTENSION, + name: _id_a + JSON_POSTFIX, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_a) })).oid, type: 'json', doc: json_a, }, { _id: _id_b, - name: _id_b + JSON_EXTENSION, + name: _id_b + JSON_POSTFIX, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_b) })).oid, type: 'json', doc: json_b, }, { _id: _id_c01, - name: _id_c01 + JSON_EXTENSION, + name: _id_c01 + JSON_POSTFIX, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_c01) })).oid, type: 'json', doc: json_c01, }, { _id: _id_c02, - name: _id_c02 + JSON_EXTENSION, + name: _id_c02 + JSON_POSTFIX, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_c02) })).oid, type: 'json', doc: json_c02, }, { _id: _id_d, - name: _id_d + JSON_EXTENSION, + name: _id_d + JSON_POSTFIX, fileOid: (await git.hashBlob({ object: toSortedJSONString(json_d) })).oid, type: 'json', doc: json_d, diff --git a/test/remote_base/3way_merge.ts b/test/remote_base/3way_merge.ts index b76b4fac..c3fd803c 100644 --- a/test/remote_base/3way_merge.ts +++ b/test/remote_base/3way_merge.ts @@ -35,7 +35,7 @@ import { getWorkingDirDocs, removeRemoteRepositories, } from '../remote_utils'; -import { JSON_EXTENSION } from '../../src/const'; +import { JSON_POSTFIX } from '../../src/const'; export const syncThreeWayMergeBase = ( connection: ConnectionSettings, @@ -114,12 +114,12 @@ export const syncThreeWayMergeBase = ( local: getCommitInfo([ putResultA1, putResultA2, - `resolve: 1${JSON_EXTENSION}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_POSTFIX}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), remote: getCommitInfo([ putResultB1, putResultB3, - `resolve: 1${JSON_EXTENSION}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_POSTFIX}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), }); expect(syncResult1.changes.local.length).toBe(1); @@ -204,12 +204,12 @@ export const syncThreeWayMergeBase = ( local: getCommitInfo([ putResultA1, putResultA2, - `resolve: 1${JSON_EXTENSION}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_POSTFIX}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), remote: getCommitInfo([ putResultB1, putResultB2, - `resolve: 1${JSON_EXTENSION}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_POSTFIX}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), }); expect(syncResult1.changes.local.length).toBe(0); @@ -281,11 +281,11 @@ export const syncThreeWayMergeBase = ( expect(syncResult1.commits).toMatchObject({ local: getCommitInfo([ putResultA1, - `resolve: 1${JSON_EXTENSION}(insert,${putResultA1.fileOid.substr(0, 7)},theirs)`, + `resolve: 1${JSON_POSTFIX}(insert,${putResultA1.fileOid.substr(0, 7)},theirs)`, ]), remote: getCommitInfo([ putResultB1, - `resolve: 1${JSON_EXTENSION}(insert,${putResultA1.fileOid.substr(0, 7)},theirs)`, + `resolve: 1${JSON_POSTFIX}(insert,${putResultA1.fileOid.substr(0, 7)},theirs)`, ]), }); expect(syncResult1.changes.local.length).toBe(1); @@ -370,12 +370,12 @@ export const syncThreeWayMergeBase = ( local: getCommitInfo([ putResultA1, deleteResultA2, - `resolve: 1${JSON_EXTENSION}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_POSTFIX}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), remote: getCommitInfo([ putResultB1, deleteResultB2, - `resolve: 1${JSON_EXTENSION}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_POSTFIX}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), }); expect(syncResult1.changes.local.length).toBe(0); @@ -459,12 +459,12 @@ export const syncThreeWayMergeBase = ( expect(syncResult1.commits).toMatchObject({ local: getCommitInfo([ putResultA1, - `resolve: 1${JSON_EXTENSION}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_POSTFIX}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), remote: getCommitInfo([ putResultB1, deleteResultB2, - `resolve: 1${JSON_EXTENSION}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_POSTFIX}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), }); expect(syncResult1.changes.local.length).toBe(0); @@ -547,11 +547,11 @@ export const syncThreeWayMergeBase = ( expect(syncResult1.commits).toMatchObject({ local: getCommitInfo([ putResultA1dash, - `resolve: 1${JSON_EXTENSION}(delete,${deleteResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_POSTFIX}(delete,${deleteResultB1.fileOid.substr(0, 7)},ours)`, ]), remote: getCommitInfo([ deleteResultB1, - `resolve: 1${JSON_EXTENSION}(delete,${deleteResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_POSTFIX}(delete,${deleteResultB1.fileOid.substr(0, 7)},ours)`, ]), }); expect(syncResult1.changes.local.length).toBe(0); @@ -632,14 +632,14 @@ export const syncThreeWayMergeBase = ( expect(syncResult1.commits).toMatchObject({ local: getCommitInfo([ putResultA1dash, - `resolve: 1${JSON_EXTENSION}(update,${putResultA1dash.fileOid.substr( + `resolve: 1${JSON_POSTFIX}(update,${putResultA1dash.fileOid.substr( 0, 7 )},theirs)`, ]), remote: getCommitInfo([ deleteResultB1, - `resolve: 1${JSON_EXTENSION}(update,${putResultA1dash.fileOid.substr( + `resolve: 1${JSON_POSTFIX}(update,${putResultA1dash.fileOid.substr( 0, 7 )},theirs)`, @@ -724,11 +724,11 @@ export const syncThreeWayMergeBase = ( local: getCommitInfo([ putResultA1, deleteResultA2, - `resolve: 1${JSON_EXTENSION}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_POSTFIX}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), remote: getCommitInfo([ putResultB1, - `resolve: 1${JSON_EXTENSION}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_POSTFIX}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), }); expect(syncResult1.changes.local.length).toBe(1); @@ -813,11 +813,11 @@ export const syncThreeWayMergeBase = ( local: getCommitInfo([ deleteResultA1, putResultA2, - `resolve: 1${JSON_EXTENSION}(update,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_POSTFIX}(update,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), remote: getCommitInfo([ putResultB1, - `resolve: 1${JSON_EXTENSION}(update,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_POSTFIX}(update,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), }); expect(syncResult1.changes.local.length).toBe(1); @@ -906,17 +906,11 @@ export const syncThreeWayMergeBase = ( local: getCommitInfo([ deleteResultA1, putResultA2, - `resolve: 1${JSON_EXTENSION}(delete,${deleteResultA1.fileOid.substr( - 0, - 7 - )},theirs)`, + `resolve: 1${JSON_POSTFIX}(delete,${deleteResultA1.fileOid.substr(0, 7)},theirs)`, ]), remote: getCommitInfo([ putResultB1, - `resolve: 1${JSON_EXTENSION}(delete,${deleteResultA1.fileOid.substr( - 0, - 7 - )},theirs)`, + `resolve: 1${JSON_POSTFIX}(delete,${deleteResultA1.fileOid.substr(0, 7)},theirs)`, ]), }); expect(syncResult1.changes.local.length).toBe(2); @@ -1003,12 +997,12 @@ export const syncThreeWayMergeBase = ( local: getCommitInfo([ putResultA1, putResultA2dash, - `resolve: 1${JSON_EXTENSION}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_POSTFIX}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), remote: getCommitInfo([ putResultB1, putResultB2, - `resolve: 1${JSON_EXTENSION}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_POSTFIX}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), }); expect(syncResult1.changes.local.length).toBe(0); @@ -1096,12 +1090,12 @@ export const syncThreeWayMergeBase = ( local: getCommitInfo([ putResultA1, putResultA2dash, - `resolve: 1${JSON_EXTENSION}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_POSTFIX}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), remote: getCommitInfo([ putResultB1, putResultB2, - `resolve: 1${JSON_EXTENSION}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_POSTFIX}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), }); expect(syncResult1.changes.local.length).toBe(1); @@ -1192,12 +1186,12 @@ export const syncThreeWayMergeBase = ( local: getCommitInfo([ putResultA1, putResultA2dash, - `resolve: 1${JSON_EXTENSION}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_POSTFIX}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), remote: getCommitInfo([ putResultB1, putResultB2, - `resolve: 1${JSON_EXTENSION}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_POSTFIX}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), }); expect(syncResult1.changes.local.length).toBe(0); @@ -1278,11 +1272,11 @@ export const syncThreeWayMergeBase = ( expect(syncResult1.commits).toMatchObject({ local: getCommitInfo([ putResultA1dash, - `resolve: 1${JSON_EXTENSION}(update,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_POSTFIX}(update,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), remote: getCommitInfo([ putResultB1, - `resolve: 1${JSON_EXTENSION}(update,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_POSTFIX}(update,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), }); expect(syncResult1.changes.local.length).toBe(0); @@ -1365,14 +1359,14 @@ export const syncThreeWayMergeBase = ( expect(syncResult1.commits).toMatchObject({ local: getCommitInfo([ putResultA1dash, - `resolve: 1${JSON_EXTENSION}(update,${putResultA1dash.fileOid.substr( + `resolve: 1${JSON_POSTFIX}(update,${putResultA1dash.fileOid.substr( 0, 7 )},theirs)`, ]), remote: getCommitInfo([ putResultB1, - `resolve: 1${JSON_EXTENSION}(update,${putResultA1dash.fileOid.substr( + `resolve: 1${JSON_POSTFIX}(update,${putResultA1dash.fileOid.substr( 0, 7 )},theirs)`, @@ -1477,25 +1471,25 @@ export const syncThreeWayMergeBase = ( putResultA3dash, putResultA1dash, deleteResultA2, - `resolve: 1${JSON_EXTENSION}(delete,${deleteResultB1.fileOid.substr( + `resolve: 1${JSON_POSTFIX}(delete,${deleteResultB1.fileOid.substr( 0, 7 - )},ours), 2${JSON_EXTENSION}(update,${putResultB2.fileOid.substr( + )},ours), 2${JSON_POSTFIX}(update,${putResultB2.fileOid.substr( 0, 7 - )},ours), 3${JSON_EXTENSION}(update,${putResultB3.fileOid.substr(0, 7)},ours)`, + )},ours), 3${JSON_POSTFIX}(update,${putResultB3.fileOid.substr(0, 7)},ours)`, ]), remote: getCommitInfo([ putResultB3, deleteResultB1, putResultB2, - `resolve: 1${JSON_EXTENSION}(delete,${deleteResultB1.fileOid.substr( + `resolve: 1${JSON_POSTFIX}(delete,${deleteResultB1.fileOid.substr( 0, 7 - )},ours), 2${JSON_EXTENSION}(update,${putResultB2.fileOid.substr( + )},ours), 2${JSON_POSTFIX}(update,${putResultB2.fileOid.substr( 0, 7 - )},ours), 3${JSON_EXTENSION}(update,${putResultB3.fileOid.substr(0, 7)},ours)`, + )},ours), 3${JSON_POSTFIX}(update,${putResultB3.fileOid.substr(0, 7)},ours)`, ]), }); expect(syncResult1.changes.local.length).toBe(0); @@ -1613,11 +1607,11 @@ export const syncThreeWayMergeBase = ( expect(syncResult1.commits).toMatchObject({ local: getCommitInfo([ putResultA1dash, - `resolve: 1${JSON_EXTENSION}(update,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_POSTFIX}(update,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), remote: getCommitInfo([ putResultB1, - `resolve: 1${JSON_EXTENSION}(update,${putResultB1.fileOid.substr(0, 7)},ours)`, + `resolve: 1${JSON_POSTFIX}(update,${putResultB1.fileOid.substr(0, 7)},ours)`, ]), }); expect(syncResult1.changes.local.length).toBe(0); @@ -1709,14 +1703,14 @@ export const syncThreeWayMergeBase = ( expect(syncResult1.commits).toMatchObject({ local: getCommitInfo([ putResultA1dash, - `resolve: 1${JSON_EXTENSION}(update,${putResultA1dash.fileOid.substr( + `resolve: 1${JSON_POSTFIX}(update,${putResultA1dash.fileOid.substr( 0, 7 )},theirs)`, ]), remote: getCommitInfo([ putResultB1, - `resolve: 1${JSON_EXTENSION}(update,${putResultA1dash.fileOid.substr( + `resolve: 1${JSON_POSTFIX}(update,${putResultA1dash.fileOid.substr( 0, 7 )},theirs)`, diff --git a/test/remote_base/3way_merge_ot.ts b/test/remote_base/3way_merge_ot.ts index 47d7c9ff..2ad59aed 100644 --- a/test/remote_base/3way_merge_ot.ts +++ b/test/remote_base/3way_merge_ot.ts @@ -33,7 +33,7 @@ import { removeRemoteRepositories, } from '../remote_utils'; -import { JSON_EXTENSION } from '../../src/const'; +import { JSON_POSTFIX } from '../../src/const'; export const threeWayMergeOtBase = ( connection: ConnectionSettings, @@ -100,7 +100,7 @@ export const threeWayMergeOtBase = ( local: getCommitInfo([ putResultA1, putResultA2, - `resolve: 1${JSON_EXTENSION}(insert-merge,${mergedDoc!.fileOid.substr( + `resolve: 1${JSON_POSTFIX}(insert-merge,${mergedDoc!.fileOid.substr( 0, 7 )},ours-diff)`, @@ -108,7 +108,7 @@ export const threeWayMergeOtBase = ( remote: getCommitInfo([ putResultB1, putResultB3, - `resolve: 1${JSON_EXTENSION}(insert-merge,${mergedDoc!.fileOid.substr( + `resolve: 1${JSON_POSTFIX}(insert-merge,${mergedDoc!.fileOid.substr( 0, 7 )},ours-diff)`, @@ -201,14 +201,14 @@ export const threeWayMergeOtBase = ( expect(syncResult1.commits).toMatchObject({ local: getCommitInfo([ putResultA1, - `resolve: 1${JSON_EXTENSION}(insert-merge,${mergedDoc!.fileOid.substr( + `resolve: 1${JSON_POSTFIX}(insert-merge,${mergedDoc!.fileOid.substr( 0, 7 )},theirs-diff)`, ]), remote: getCommitInfo([ putResultB1, - `resolve: 1${JSON_EXTENSION}(insert-merge,${mergedDoc!.fileOid.substr( + `resolve: 1${JSON_POSTFIX}(insert-merge,${mergedDoc!.fileOid.substr( 0, 7 )},theirs-diff)`, @@ -286,14 +286,14 @@ export const threeWayMergeOtBase = ( expect(syncResult1.commits).toMatchObject({ local: getCommitInfo([ putResultA1dash, - `resolve: 1${JSON_EXTENSION}(delete,${deleteResultB1.fileOid.substr( + `resolve: 1${JSON_POSTFIX}(delete,${deleteResultB1.fileOid.substr( 0, 7 )},ours-diff)`, ]), remote: getCommitInfo([ deleteResultB1, - `resolve: 1${JSON_EXTENSION}(delete,${deleteResultB1.fileOid.substr( + `resolve: 1${JSON_POSTFIX}(delete,${deleteResultB1.fileOid.substr( 0, 7 )},ours-diff)`, @@ -379,17 +379,11 @@ export const threeWayMergeOtBase = ( local: getCommitInfo([ deleteResultA1, putResultA2, - `resolve: 1${JSON_EXTENSION}(update,${putResultB1.fileOid.substr( - 0, - 7 - )},ours-diff)`, + `resolve: 1${JSON_POSTFIX}(update,${putResultB1.fileOid.substr(0, 7)},ours-diff)`, ]), remote: getCommitInfo([ putResultB1, - `resolve: 1${JSON_EXTENSION}(update,${putResultB1.fileOid.substr( - 0, - 7 - )},ours-diff)`, + `resolve: 1${JSON_POSTFIX}(update,${putResultB1.fileOid.substr(0, 7)},ours-diff)`, ]), }); expect(syncResult1.changes.local.length).toBe(1); @@ -491,14 +485,14 @@ export const threeWayMergeOtBase = ( expect(syncResult1.commits).toMatchObject({ local: getCommitInfo([ putResultA1dash, - `resolve: 1${JSON_EXTENSION}(update-merge,${mergedDoc!.fileOid.substr( + `resolve: 1${JSON_POSTFIX}(update-merge,${mergedDoc!.fileOid.substr( 0, 7 )},theirs-diff)`, ]), remote: getCommitInfo([ putResultB1, - `resolve: 1${JSON_EXTENSION}(update-merge,${mergedDoc!.fileOid.substr( + `resolve: 1${JSON_POSTFIX}(update-merge,${mergedDoc!.fileOid.substr( 0, 7 )},theirs-diff)`, diff --git a/test/remote_base/combine.ts b/test/remote_base/combine.ts index 27307f22..613aa029 100644 --- a/test/remote_base/combine.ts +++ b/test/remote_base/combine.ts @@ -29,7 +29,7 @@ import { removeRemoteRepositories, } from '../remote_utils'; import { sleep } from '../../src/utils'; -import { JSON_EXTENSION } from '../../src/const'; +import { JSON_POSTFIX } from '../../src/const'; export const syncCombineBase = ( connection: ConnectionSettings, @@ -292,7 +292,7 @@ export const syncCombineBase = ( expect(getWorkingDirDocs(dbA)).toEqual([jsonA1]); // jsonB1 is duplicated with postfix due to combine-head-with-theirs strategy jsonB1._id = jsonB1._id + '-from-' + dbIdB; - const duplicatedB1 = await dbB.getFatDoc(jsonB1._id + JSON_EXTENSION); + const duplicatedB1 = await dbB.getFatDoc(jsonB1._id + JSON_POSTFIX); expect(syncResult).toEqual({ action: 'combine database', @@ -300,13 +300,13 @@ export const syncCombineBase = ( { original: { _id: jsonA1._id, - name: jsonA1._id + JSON_EXTENSION, + name: jsonA1._id + JSON_POSTFIX, fileOid: putResultA1.fileOid, type: 'json', }, duplicate: { _id: jsonB1._id, - name: jsonB1._id + JSON_EXTENSION, + name: jsonB1._id + JSON_POSTFIX, fileOid: duplicatedB1?.fileOid, type: 'json', }, @@ -361,7 +361,7 @@ export const syncCombineBase = ( expect(getWorkingDirDocs(dbA)).toEqual([jsonA1]); // jsonB1 is duplicated with postfix due to combine-head-with-theirs strategy jsonB1._id = jsonB1._id + '-from-' + dbIdB; - const duplicatedB1 = await dbB.getFatDoc(jsonB1._id + JSON_EXTENSION); + const duplicatedB1 = await dbB.getFatDoc(jsonB1._id + JSON_POSTFIX); expect(syncResult).toEqual({ action: 'combine database', @@ -369,13 +369,13 @@ export const syncCombineBase = ( { original: { _id: jsonA1._id, - name: jsonA1._id + JSON_EXTENSION, + name: jsonA1._id + JSON_POSTFIX, fileOid: putResultA1.fileOid, type: 'json', }, duplicate: { _id: jsonB1._id, - name: jsonB1._id + JSON_EXTENSION, + name: jsonB1._id + JSON_POSTFIX, fileOid: duplicatedB1?.fileOid, type: 'json', }, @@ -435,7 +435,7 @@ export const syncCombineBase = ( }); jsonA1._id = jsonA1._id + '-from-' + dbIdA; - const duplicatedA1 = await dbA.getFatDoc(jsonA1._id + JSON_EXTENSION); + const duplicatedA1 = await dbA.getFatDoc(jsonA1._id + JSON_POSTFIX); expect(getWorkingDirDocs(dbA)).toEqual([jsonA1, jsonB1, jsonB2]); // jsonA1 is duplicated with postfix due to combine-head-with-theirs strategy @@ -448,13 +448,13 @@ export const syncCombineBase = ( { original: { _id: jsonB1._id, - name: jsonB1._id + JSON_EXTENSION, + name: jsonB1._id + JSON_POSTFIX, fileOid: putResultB1.fileOid, type: 'json', }, duplicate: { _id: jsonA1._id, - name: jsonA1._id + JSON_EXTENSION, + name: jsonA1._id + JSON_POSTFIX, fileOid: duplicatedA1?.fileOid, type: 'json', }, diff --git a/test/remote_base/network_history.ts b/test/remote_base/network_history.ts index 08ca1afa..6834f5b3 100644 --- a/test/remote_base/network_history.ts +++ b/test/remote_base/network_history.ts @@ -21,7 +21,7 @@ import { removeRemoteRepositories, } from '../remote_utils'; import { sleep, toSortedJSONString, utf8encode } from '../../src/utils'; -import { JSON_EXTENSION } from '../../src/const'; +import { JSON_POSTFIX } from '../../src/const'; import { getHistoryImpl, readOldBlob } from '../../src/crud/history'; export const networkHistoryBase = ( @@ -52,7 +52,7 @@ export const networkHistoryBase = ( ); const _id = 'prof'; - const shortName = _id + JSON_EXTENSION; + const shortName = _id + JSON_POSTFIX; const jsonA1 = { _id, name: 'A-1' }; const jsonA2 = { _id, name: 'A-2' }; const jsonA3 = { _id, name: 'A-3' }; @@ -73,7 +73,15 @@ export const networkHistoryBase = ( await syncB.trySync(); // Resolve conflict. jsonB2 wins. // Get - const history = await getHistoryImpl(dbB, shortName, '', undefined, undefined, true); + const history = await getHistoryImpl( + dbB, + shortName, + '', + dbB.jsonExt, + undefined, + undefined, + true + ); expect(history[0]).toEqual({ _id, diff --git a/test/remote_base/sync_trysync.ts b/test/remote_base/sync_trysync.ts index a420d88d..4139d924 100644 --- a/test/remote_base/sync_trysync.ts +++ b/test/remote_base/sync_trysync.ts @@ -40,7 +40,7 @@ import { removeRemoteRepositories, } from '../remote_utils'; import { sleep, toSortedJSONString } from '../../src/utils'; -import { JSON_EXTENSION } from '../../src/const'; +import { JSON_POSTFIX } from '../../src/const'; import { Err } from '../../src/error'; // eslint-disable-next-line @typescript-eslint/no-var-requires @@ -745,7 +745,7 @@ export const syncTrySyncBase = ( { fatDoc: { _id: jsonB1._id, - name: jsonB1._id + JSON_EXTENSION, + name: jsonB1._id + JSON_POSTFIX, fileOid: putResultB1.fileOid, type: 'json', doc: jsonB1, diff --git a/test/remote_utils.ts b/test/remote_utils.ts index bf6520ce..93756c87 100644 --- a/test/remote_utils.ts +++ b/test/remote_utils.ts @@ -19,7 +19,7 @@ import { GitDocumentDB } from '../src/git_documentdb'; import { FILE_REMOVE_TIMEOUT, GIT_DOCUMENTDB_METADATA_DIR, - JSON_EXTENSION, + JSON_POSTFIX, } from '../src/const'; import { RemoteRepository } from '../src/remote/remote_repository'; @@ -67,7 +67,7 @@ export function getChangedFileInsert ( operation: 'insert', new: { _id: newDoc!._id, - name: newDoc!._id + JSON_EXTENSION, + name: newDoc!._id + JSON_POSTFIX, fileOid: newResult!.fileOid, type: 'json', doc: newDoc, @@ -85,14 +85,14 @@ export function getChangedFileUpdate ( operation: 'update', old: { _id: oldDoc!._id, - name: oldDoc!._id + JSON_EXTENSION, + name: oldDoc!._id + JSON_POSTFIX, fileOid: oldResult!.fileOid, type: 'json', doc: oldDoc!, }, new: { _id: newDoc!._id, - name: newDoc!._id + JSON_EXTENSION, + name: newDoc!._id + JSON_POSTFIX, fileOid: newResult!.fileOid, type: 'json', doc: newDoc, @@ -108,7 +108,7 @@ export function getChangedFileDelete ( operation: 'delete', old: { _id: oldDoc!._id, - name: oldDoc!._id + JSON_EXTENSION, + name: oldDoc!._id + JSON_POSTFIX, fileOid: oldResult!.fileOid, type: 'json', doc: oldDoc, @@ -124,7 +124,7 @@ export function getChangedFileInsertBySHA ( operation: 'insert', new: { _id: newDoc!._id, - name: newDoc!._id + JSON_EXTENSION, + name: newDoc!._id + JSON_POSTFIX, fileOid: newFileSHA, type: 'json', doc: newDoc, @@ -142,14 +142,14 @@ export function getChangedFileUpdateBySHA ( operation: 'update', old: { _id: oldDoc!._id, - name: oldDoc!._id + JSON_EXTENSION, + name: oldDoc!._id + JSON_POSTFIX, fileOid: oldFileSHA, type: 'json', doc: oldDoc!, }, new: { _id: newDoc!._id, - name: newDoc!._id + JSON_EXTENSION, + name: newDoc!._id + JSON_POSTFIX, fileOid: newFileSHA, type: 'json', doc: newDoc, @@ -165,7 +165,7 @@ export function getChangedFileDeleteBySHA ( operation: 'delete', old: { _id: oldDoc!._id, - name: oldDoc!._id + JSON_EXTENSION, + name: oldDoc!._id + JSON_POSTFIX, fileOid: oldFileSHA, type: 'json', doc: oldDoc, @@ -380,7 +380,7 @@ export const compareWorkingDirAndBlobs = async ( export const getWorkingDirDocs = (gitDDB: GitDocumentDB) => { return listFiles(gitDDB, gitDDB.workingDir).map(filepath => { const doc = fs.readJSONSync(gitDDB.workingDir + '/' + filepath); - doc._id = filepath.replace(new RegExp(JSON_EXTENSION + '$'), ''); + doc._id = filepath.replace(new RegExp(JSON_POSTFIX + '$'), ''); return doc; }); }; From aa947e9f37e6a2b72b183521611e737d109e9a84 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 12 Oct 2021 03:43:32 +0900 Subject: [PATCH 196/297] fix: can read Front Matter + Markdown --- .vscode/launch.json | 2 +- src/crud/blob.ts | 83 +++++++++++++++++++++++++------- src/utils.ts | 5 +- test/crud/blob.test.ts | 67 +++++++++++++++++++++++++- test/crud/get.test.ts | 28 ++++++++++- test/crud/put.test.ts | 2 +- test/git_documentdb_crud.test.ts | 32 +++++++++++- 7 files changed, 191 insertions(+), 28 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 3ed042c0..a1898383 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,7 +4,7 @@ "type": "pickString", "id": "choice", "description": "select a file", - "options": ["test/remote_offline/json_patch_ot.test.js"], + "options": ["test/crud/blob.test.js"], }], "configurations": [ { diff --git a/src/crud/blob.ts b/src/crud/blob.ts index 558fc206..9d6cb914 100644 --- a/src/crud/blob.ts +++ b/src/crud/blob.ts @@ -7,7 +7,9 @@ */ import fs from 'fs'; +import yaml from 'js-yaml'; import { readBlob, ReadBlobResult, resolveRef } from 'isomorphic-git'; +import { FRONT_MATTER_POSTFIX } from '../const'; import { utf8decode } from '../utils'; import { Err } from '../error'; import { FatBinaryDoc, FatDoc, FatJsonDoc, FatTextDoc, JsonDoc } from '../types'; @@ -17,33 +19,78 @@ import { FatBinaryDoc, FatDoc, FatJsonDoc, FatTextDoc, JsonDoc } from '../types' * * @throws {@link Err.InvalidJsonObjectError} */ +// eslint-disable-next-line complexity export function blobToJsonDoc ( shortId: string, readBlobResult: ReadBlobResult, withMetadata: boolean, jsonExt: string ): FatJsonDoc | JsonDoc { - try { - const text = utf8decode(readBlobResult.blob); - const jsonDoc = (JSON.parse(text) as unknown) as JsonDoc; - if (jsonDoc._id !== undefined) { - // Overwrite _id property by shortId (_id without collectionPath) if JsonDoc is created by GitDocumentedDB (_id !== undefined). - jsonDoc._id = shortId; + const text = utf8decode(readBlobResult.blob); + let jsonDoc: JsonDoc; + if (jsonExt === FRONT_MATTER_POSTFIX) { + const mdArray = text.split('\n'); + let yamlText = ''; + let markdownText = ''; + let startFrontMatter = false; + let endFrontMatter = false; + for (let i = 0; i < mdArray.length; i++) { + if (mdArray[i] === '---') { + if (!startFrontMatter) { + startFrontMatter = true; + } + else if (!endFrontMatter) { + endFrontMatter = true; + } + continue; + } + if (startFrontMatter && !endFrontMatter) { + if (yamlText !== '') { + yamlText += '\n'; + } + yamlText += mdArray[i]; + } + else if (endFrontMatter) { + if (markdownText !== '') { + markdownText += '\n'; + } + markdownText += mdArray[i]; + } } - if (withMetadata) { - const fatJsonDoc: FatJsonDoc = { - _id: shortId, - name: shortId + jsonExt, - fileOid: readBlobResult.oid, - type: 'json', - doc: jsonDoc, - }; - return fatJsonDoc; + if (!endFrontMatter) { + throw new Err.InvalidJsonObjectError(shortId); } - return jsonDoc; - } catch { - throw new Err.InvalidJsonObjectError(shortId); + try { + jsonDoc = yaml.load(yamlText) as JsonDoc; + } catch { + throw new Err.InvalidJsonObjectError(shortId); + } + if (markdownText !== '') { + jsonDoc._body = markdownText; + } + } + else { + try { + jsonDoc = (JSON.parse(text) as unknown) as JsonDoc; + } catch { + throw new Err.InvalidJsonObjectError(shortId); + } + } + if (jsonDoc._id !== undefined) { + // Overwrite _id property by shortId (_id without collectionPath) if JsonDoc is created by GitDocumentedDB (_id !== undefined). + jsonDoc._id = shortId; + } + if (withMetadata) { + const fatJsonDoc: FatJsonDoc = { + _id: shortId, + name: shortId + jsonExt, + fileOid: readBlobResult.oid, + type: 'json', + doc: jsonDoc, + }; + return fatJsonDoc; } + return jsonDoc; } /** diff --git a/src/utils.ts b/src/utils.ts index 76c84f99..9a17440a 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -85,8 +85,9 @@ export function toSortedJSONString (obj: Record) { export function toFrontMatterMarkdown (obj: Record) { const body = typeof obj._body === 'string' ? obj._body : ''; - delete obj._body; - const frontMatter = '---\n' + yaml.dump(obj, { sortKeys: true }) + '---\n'; + const clone = JSON.parse(JSON.stringify(obj)); + delete clone._body; + const frontMatter = '---\n' + yaml.dump(clone, { sortKeys: true }) + '---\n'; return frontMatter + body; } diff --git a/test/crud/blob.test.ts b/test/crud/blob.test.ts index f3677663..e5b8381d 100644 --- a/test/crud/blob.test.ts +++ b/test/crud/blob.test.ts @@ -23,8 +23,8 @@ import { } from '../../src/crud/blob'; import { Err } from '../../src/error'; import { GitDocumentDB } from '../../src/git_documentdb'; -import { toSortedJSONString, utf8encode } from '../../src/utils'; -import { JSON_POSTFIX } from '../../src/const'; +import { toFrontMatterMarkdown, toSortedJSONString, utf8encode } from '../../src/utils'; +import { FRONT_MATTER_POSTFIX, JSON_POSTFIX } from '../../src/const'; // eslint-disable-next-line @typescript-eslint/no-var-requires const git_module = require('isomorphic-git'); @@ -77,6 +77,69 @@ describe('', () => { expect(blobToJsonDoc(shortId, readBlobResult, false, JSON_POSTFIX)).toEqual(json); }); + it('throws InvalidJsonObjectError when Front-Matter + Markdown is empty', async () => { + const shortId = 'foo'; + const text = ''; + const readBlobResult: ReadBlobResult = { + oid: (await git.hashBlob({ object: text })).oid, + blob: utf8encode(text), + }; + expect(() => + blobToJsonDoc(shortId, readBlobResult, false, FRONT_MATTER_POSTFIX) + ).toThrowError(Err.InvalidJsonObjectError); + }); + + it('throws InvalidJsonObjectError when Front-Matter does not end', async () => { + const shortId = 'foo'; + const text = '---\na: foo'; + const readBlobResult: ReadBlobResult = { + oid: (await git.hashBlob({ object: text })).oid, + blob: utf8encode(text), + }; + expect(() => + blobToJsonDoc(shortId, readBlobResult, false, FRONT_MATTER_POSTFIX) + ).toThrowError(Err.InvalidJsonObjectError); + }); + + it('returns JsonDoc of Front-Matter + Markdown', async () => { + const shortId = 'foo'; + const json = { _id: shortId, propA: 'A', propB: 'B', _body: 'foo\nbar' }; + const text = toFrontMatterMarkdown(json); + const readBlobResult: ReadBlobResult = { + oid: (await git.hashBlob({ object: text })).oid, + blob: utf8encode(text), + }; + expect(blobToJsonDoc(shortId, readBlobResult, false, FRONT_MATTER_POSTFIX)).toEqual( + json + ); + }); + + it('returns JsonDoc of Front-Matter + Markdown that ends with \n', async () => { + const shortId = 'foo'; + const json = { _id: shortId, propA: 'A', propB: 'B', _body: 'foo\nbar\n' }; + const text = toFrontMatterMarkdown(json); + const readBlobResult: ReadBlobResult = { + oid: (await git.hashBlob({ object: text })).oid, + blob: utf8encode(text), + }; + expect(blobToJsonDoc(shortId, readBlobResult, false, FRONT_MATTER_POSTFIX)).toEqual( + json + ); + }); + + it('returns JsonDoc of Front-Matter without Markdown', async () => { + const shortId = 'foo'; + const json = { _id: shortId, propA: 'A', propB: 'B' }; + const text = toFrontMatterMarkdown(json); + const readBlobResult: ReadBlobResult = { + oid: (await git.hashBlob({ object: text })).oid, + blob: utf8encode(text), + }; + expect(blobToJsonDoc(shortId, readBlobResult, false, FRONT_MATTER_POSTFIX)).toEqual( + json + ); + }); + it('returns JsonDoc with overwritten _id', async () => { const shortId = 'foo'; const shortId2 = 'foo'; diff --git a/test/crud/get.test.ts b/test/crud/get.test.ts index 556232cb..451bcfa4 100644 --- a/test/crud/get.test.ts +++ b/test/crud/get.test.ts @@ -13,11 +13,11 @@ import git from 'isomorphic-git'; import expect from 'expect'; import { monotonicFactory } from 'ulid'; import sinon from 'sinon'; -import { sleep, toSortedJSONString } from '../../src/utils'; +import { sleep, toFrontMatterMarkdown, toSortedJSONString } from '../../src/utils'; import { Err } from '../../src/error'; import { GitDocumentDB } from '../../src/git_documentdb'; import { getImpl } from '../../src/crud/get'; -import { JSON_POSTFIX } from '../../src/const'; +import { FRONT_MATTER_POSTFIX, JSON_POSTFIX } from '../../src/const'; import { addOneData, removeOneData } from '../utils'; // eslint-disable-next-line @typescript-eslint/no-var-requires @@ -869,4 +869,28 @@ describe(' getImpl()', () => { ).resolves.toEqual(json14); }); }); + + describe('Front-Matter + Markdown', () => { + it('returns latest JsonDoc under deep collectionPath', async () => { + const dbName = monoId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + serializeFormat: 'front-matter', + }); + + await gitDDB.open(); + const shortId = 'dir01/prof01'; + const shortName = shortId + FRONT_MATTER_POSTFIX; + const collectionPath = 'col01/col02/col03'; + const fullDocPath = collectionPath + shortName; + const json = { _id: shortId, name: 'Shirase', _body: 'Journey to the Antarctic' }; + await addOneData(gitDDB, fullDocPath, toFrontMatterMarkdown(json)); + await expect( + getImpl(gitDDB, shortName, collectionPath, gitDDB.jsonExt) + ).resolves.toEqual(json); + + await gitDDB.destroy(); + }); + }); }); diff --git a/test/crud/put.test.ts b/test/crud/put.test.ts index 5f30b1b0..5bcce6e9 100644 --- a/test/crud/put.test.ts +++ b/test/crud/put.test.ts @@ -45,7 +45,7 @@ afterEach(function () { }); after(() => { - // fs.removeSync(path.resolve(localDir)); + fs.removeSync(path.resolve(localDir)); }); describe(' put', () => { diff --git a/test/git_documentdb_crud.test.ts b/test/git_documentdb_crud.test.ts index aa921d71..b0dcc586 100644 --- a/test/git_documentdb_crud.test.ts +++ b/test/git_documentdb_crud.test.ts @@ -14,8 +14,8 @@ import expect from 'expect'; import fs from 'fs-extra'; import { DeleteResultJsonDoc, PutResultJsonDoc } from '../src/types'; import { GitDocumentDB } from '../src/git_documentdb'; -import { sleep, toSortedJSONString } from '../src/utils'; -import { JSON_POSTFIX, SHORT_SHA_LENGTH } from '../src/const'; +import { sleep, toFrontMatterMarkdown, toSortedJSONString } from '../src/utils'; +import { FRONT_MATTER_POSTFIX, JSON_POSTFIX, SHORT_SHA_LENGTH } from '../src/const'; import { addOneData } from './utils'; import { Err } from '../src/error'; @@ -95,6 +95,34 @@ describe(' put(jsonDoc)', () => { await gitDDB.destroy(); }); + it('creates a Front Matter + Markdown file', async () => { + const dbName = monoId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + serializeFormat: 'front-matter', + }); + await gitDDB.open(); + const _id = 'prof01'; + // Check put operation + const json = { _id, name: 'Shirase', _body: 'Journey to the Antarctic' }; + const putResult = await gitDDB.put(json); + const fileOid = (await git.hashBlob({ object: toFrontMatterMarkdown(json) })).oid; + const shortOid = fileOid.substr(0, SHORT_SHA_LENGTH); + expect(putResult._id).toBe(_id); + expect(putResult.fileOid).toBe(fileOid); + expect(putResult.commit.message).toBe( + `insert: ${_id}${FRONT_MATTER_POSTFIX}(${shortOid})` + ); + + // fs.access() throw error when a file cannot be accessed. + const filePath = path.resolve(gitDDB.workingDir, _id + FRONT_MATTER_POSTFIX); + await expect(fs.access(filePath)).resolves.not.toThrowError(); + expect(fs.readFileSync(filePath, 'utf8')).toBe(toFrontMatterMarkdown(json)); + + await gitDDB.destroy(); + }); + it('puts with a commitMessage', async () => { const dbName = monoId(); const gitDDB: GitDocumentDB = new GitDocumentDB({ From 7bc12c96da0080f61678154c630511e3cd11ab90 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 12 Oct 2021 11:52:49 +0900 Subject: [PATCH 197/297] build: bump to v0.4.7-alpha.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d36ab2d6..ebaf318b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "git-documentdb", - "version": "0.4.6", + "version": "0.4.7-alpha.0", "description": "Offline-first database that syncs with Git", "main": "dist/main.js", "types": "dist/main.d.ts", From 7282697cf67489f069dd2a5c4af437b82a42d96f Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 12 Oct 2021 18:22:12 +0900 Subject: [PATCH 198/297] fix: add serializeFormat to DatabaseInfo --- package-lock.json | 4 ++-- package.json | 2 +- src/git_documentdb.ts | 25 +++++++++++++++++++++---- src/types.ts | 1 + test/git_documentdb_open.test.ts | 27 ++++++++++++++++++++++++++- 5 files changed, 51 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 53ed0c7d..e4e483b2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "git-documentdb", - "version": "0.4.6", + "version": "0.4.7-alpha.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "git-documentdb", - "version": "0.4.6", + "version": "0.4.7-alpha.0", "license": "MPL-2.0", "dependencies": { "@octokit/rest": "^18.3.5", diff --git a/package.json b/package.json index ebaf318b..db4e85e7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "git-documentdb", - "version": "0.4.7-alpha.0", + "version": "0.4.7-alpha.1", "description": "Offline-first database that syncs with Git", "main": "dist/main.js", "types": "dist/main.d.ts", diff --git a/src/git_documentdb.ts b/src/git_documentdb.ts index 1c6940ac..52cbfc46 100644 --- a/src/git_documentdb.ts +++ b/src/git_documentdb.ts @@ -41,6 +41,7 @@ import { PutResultJsonDoc, RemoteOptions, Schema, + SerializeFormat, SyncCallback, SyncEvent, SyncResult, @@ -79,13 +80,14 @@ export function generateDatabaseId () { return ulid(Date.now()); } -const INITIAL_DATABASE_OPEN_RESULT = { +const INITIAL_DATABASE_OPEN_RESULT: DatabaseOpenResult = { dbId: '', creator: '', version: '', isNew: false, isCreatedByGitDDB: true, isValidVersion: true, + serializeFormat: 'json', }; /** @@ -127,6 +129,11 @@ export class GitDocumentDB private _dbOpenResult: DatabaseOpenResult = { ...INITIAL_DATABASE_OPEN_RESULT }; + /** + * Serialize format + */ + private _serializeFormat: SerializeFormat = 'json'; + /*********************************************** * Public properties (readonly) ***********************************************/ @@ -330,8 +337,7 @@ export class GitDocumentDB }, }; - this._jsonExt = - options.serializeFormat === 'front-matter' ? FRONT_MATTER_POSTFIX : JSON_POSTFIX; + this._serializeFormat = options.serializeFormat ?? 'json'; // Get full-path this._workingDir = path.resolve(this._localDir, this._dbName); @@ -397,6 +403,7 @@ export class GitDocumentDB dbId: generateDatabaseId(), creator: DATABASE_CREATOR, version: DATABASE_VERSION, + serializeFormat: this._serializeFormat, }; // Retry three times. @@ -418,7 +425,7 @@ export class GitDocumentDB // eslint-disable-next-line no-await-in-loop const resInit = await git .init({ fs, dir: this._workingDir, defaultBranch: this.defaultBranch }) - .catch(err => { + .catch((err: Error) => { if (i >= retry) throw err; return 'cannot_init'; }); @@ -825,6 +832,7 @@ export class GitDocumentDB * * @internal */ + // eslint-disable-next-line complexity async loadDbInfo () { let info: DatabaseInfo | undefined; @@ -848,11 +856,20 @@ export class GitDocumentDB dbId: '', creator: '', version: '', + serializeFormat: this._serializeFormat, }; info.creator ??= ''; info.version ??= ''; + info.serializeFormat ??= this._serializeFormat; + + if (info.serializeFormat !== this._serializeFormat) { + // TODO: Change serialize format + } + this._jsonExt = + this._serializeFormat === 'front-matter' ? FRONT_MATTER_POSTFIX : JSON_POSTFIX; + // Set dbId if not exists. if (!info.dbId) { info.dbId = generateDatabaseId(); diff --git a/src/types.ts b/src/types.ts index 8dfa09c8..238b4c8d 100644 --- a/src/types.ts +++ b/src/types.ts @@ -135,6 +135,7 @@ export type DatabaseInfo = { dbId: string; creator: string; version: string; + serializeFormat: SerializeFormat; }; /** diff --git a/test/git_documentdb_open.test.ts b/test/git_documentdb_open.test.ts index 1383f6a9..3a88899c 100644 --- a/test/git_documentdb_open.test.ts +++ b/test/git_documentdb_open.test.ts @@ -160,6 +160,7 @@ describe('', () => { isNew: true, isCreatedByGitDDB: true, isValidVersion: true, + serializeFormat: 'json', }); expect((dbOpenResult as DatabaseInfo).dbId).toMatch(/^[\dA-HJKMNP-TV-Z]{26}$/); @@ -297,6 +298,7 @@ describe('', () => { isNew: false, isCreatedByGitDDB: true, isValidVersion: true, + serializeFormat: 'json', }); expect(gitDDB.isOpened).toBeTruthy(); @@ -333,6 +335,7 @@ describe('', () => { isNew: false, isCreatedByGitDDB: false, isValidVersion: false, + serializeFormat: 'json', }); await gitDDB.destroy(); }); @@ -363,6 +366,7 @@ describe('', () => { isNew: false, isCreatedByGitDDB: true, isValidVersion: false, + serializeFormat: 'json', }); await gitDDB.destroy(); }); @@ -394,6 +398,7 @@ describe('', () => { isNew: false, isCreatedByGitDDB: true, isValidVersion: true, + serializeFormat: 'json', }); }); @@ -405,7 +410,26 @@ describe('', () => { }); // Create db - await gitDDB.open(); + const dbOpenResult = await gitDDB.open(); + const newDbId = (dbOpenResult as DatabaseInfo).dbId; + await expect(gitDDB.open()).resolves.toMatchObject({ + dbId: newDbId, + creator: DATABASE_CREATOR, + version: DATABASE_VERSION, + isNew: false, + isCreatedByGitDDB: true, + isValidVersion: true, + }); + await gitDDB.destroy(); + }); + + it('loads serializeFormat.', async () => { + const dbName = monoId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + serializeFormat: 'front-matter', + }); const dbOpenResult = await gitDDB.open(); const newDbId = (dbOpenResult as DatabaseInfo).dbId; @@ -416,6 +440,7 @@ describe('', () => { isNew: false, isCreatedByGitDDB: true, isValidVersion: true, + serializeFormat: 'front-matter', }); await gitDDB.destroy(); }); From 84ceffbff21543b97b7920abc2b8bd5a6d1841dd Mon Sep 17 00:00:00 2001 From: sosuisen Date: Thu, 14 Oct 2021 02:57:48 +0900 Subject: [PATCH 199/297] fix: allow markdown without front matter --- src/crud/blob.ts | 21 ++++++++++++++++----- src/utils.ts | 11 +++++++++++ test/crud/blob.test.ts | 30 ++++++++++++++++++++++-------- test/crud/put.test.ts | 21 +++++++++++++++++++++ 4 files changed, 70 insertions(+), 13 deletions(-) diff --git a/src/crud/blob.ts b/src/crud/blob.ts index 9d6cb914..d8ecd458 100644 --- a/src/crud/blob.ts +++ b/src/crud/blob.ts @@ -58,12 +58,23 @@ export function blobToJsonDoc ( } } if (!endFrontMatter) { - throw new Err.InvalidJsonObjectError(shortId); + // throw new Err.InvalidJsonObjectError(shortId); + markdownText = text; + jsonDoc = { + _id: shortId, + }; } - try { - jsonDoc = yaml.load(yamlText) as JsonDoc; - } catch { - throw new Err.InvalidJsonObjectError(shortId); + else { + try { + jsonDoc = yaml.load(yamlText) as JsonDoc; + } catch { + throw new Err.InvalidJsonObjectError(shortId); + } + if (jsonDoc === undefined) { + jsonDoc = { + _id: shortId, + }; + } } if (markdownText !== '') { jsonDoc._body = markdownText; diff --git a/src/utils.ts b/src/utils.ts index 9a17440a..fe46a71d 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -87,6 +87,17 @@ export function toFrontMatterMarkdown (obj: Record) { const body = typeof obj._body === 'string' ? obj._body : ''; const clone = JSON.parse(JSON.stringify(obj)); delete clone._body; + let hasOnlyId = true; + for (const key of Object.keys(clone)) { + if (key !== '_id') { + hasOnlyId = false; + break; + } + } + if (hasOnlyId) { + return body; + } + const frontMatter = '---\n' + yaml.dump(clone, { sortKeys: true }) + '---\n'; return frontMatter + body; } diff --git a/test/crud/blob.test.ts b/test/crud/blob.test.ts index e5b8381d..6d4f38ef 100644 --- a/test/crud/blob.test.ts +++ b/test/crud/blob.test.ts @@ -77,28 +77,42 @@ describe('', () => { expect(blobToJsonDoc(shortId, readBlobResult, false, JSON_POSTFIX)).toEqual(json); }); - it('throws InvalidJsonObjectError when Front-Matter + Markdown is empty', async () => { + it('returns JsonDoc with only _id when Front-Matter + Markdown is empty', async () => { const shortId = 'foo'; const text = ''; const readBlobResult: ReadBlobResult = { oid: (await git.hashBlob({ object: text })).oid, blob: utf8encode(text), }; - expect(() => - blobToJsonDoc(shortId, readBlobResult, false, FRONT_MATTER_POSTFIX) - ).toThrowError(Err.InvalidJsonObjectError); + expect(blobToJsonDoc(shortId, readBlobResult, false, FRONT_MATTER_POSTFIX)).toEqual({ + _id: 'foo', + }); + }); + + it('returns JsonDoc with only _id and _body when Front-Matter is empty', async () => { + const shortId = 'foo'; + const text = 'bar\nbaz'; + const readBlobResult: ReadBlobResult = { + oid: (await git.hashBlob({ object: text })).oid, + blob: utf8encode(text), + }; + expect(blobToJsonDoc(shortId, readBlobResult, false, FRONT_MATTER_POSTFIX)).toEqual({ + _id: 'foo', + _body: text, + }); }); - it('throws InvalidJsonObjectError when Front-Matter does not end', async () => { + it('returns JsonDoc with only _id and _body when Front-Matter does not end', async () => { const shortId = 'foo'; const text = '---\na: foo'; const readBlobResult: ReadBlobResult = { oid: (await git.hashBlob({ object: text })).oid, blob: utf8encode(text), }; - expect(() => - blobToJsonDoc(shortId, readBlobResult, false, FRONT_MATTER_POSTFIX) - ).toThrowError(Err.InvalidJsonObjectError); + expect(blobToJsonDoc(shortId, readBlobResult, false, FRONT_MATTER_POSTFIX)).toEqual({ + _id: 'foo', + _body: text, + }); }); it('returns JsonDoc of Front-Matter + Markdown', async () => { diff --git a/test/crud/put.test.ts b/test/crud/put.test.ts index 5bcce6e9..93fb90a3 100644 --- a/test/crud/put.test.ts +++ b/test/crud/put.test.ts @@ -626,6 +626,27 @@ a: bar await gitDDB.close(); await gitDDB.destroy(); }); + + it('write markdown without front matter', async () => { + const dbName = monoId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + serializeFormat: 'front-matter', + }); + await gitDDB.open(); + await gitDDB.put({ + _id: 'foo', + _body: 'bar\nbaz', + }); + const result = `bar +baz`; + const fullDocPath = 'foo.md'; + expect(readFileSync(path.resolve(gitDDB.workingDir, fullDocPath), 'utf8')).toBe(result); + + await gitDDB.close(); + await gitDDB.destroy(); + }); }); describe(' putWorker', () => { From fa50e0159558e66fd20622d27daf4d1b384b2f14 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Thu, 14 Oct 2021 02:58:34 +0900 Subject: [PATCH 200/297] build: bump to v0.4.7-alpha.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index db4e85e7..fc93023e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "git-documentdb", - "version": "0.4.7-alpha.1", + "version": "0.4.7-alpha.2", "description": "Offline-first database that syncs with Git", "main": "dist/main.js", "types": "dist/main.d.ts", From 5219ecad84ae1040966529aab20b15c64f9a35b4 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Thu, 14 Oct 2021 15:20:33 +0900 Subject: [PATCH 201/297] fix: can read FrontMatterMarkdown --- .vscode/settings.json | 5 +- src/crud/blob.ts | 64 +++++++++------ src/crud/get.ts | 2 +- src/remote/3way_merge.ts | 8 +- src/remote/combine.ts | 21 ++++- src/remote/json_patch_ot.ts | 2 +- src/remote/worker_utils.ts | 4 +- test/crud/blob.test.ts | 21 ++++- test/remote_base/3way_merge_ot.ts | 132 +++++++++++++++++++++++++++++- test/remote_base/combine.ts | 102 ++++++++++++++++++++++- test/remote_utils.ts | 47 +++++++---- 11 files changed, 349 insertions(+), 59 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index f40e2b6f..1f83d012 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,4 +1,7 @@ { "editor.tabSize": 2, - "editor.detectIndentation": false + "editor.detectIndentation": false, + "cSpell.words": [ + "unicount" + ] } \ No newline at end of file diff --git a/src/crud/blob.ts b/src/crud/blob.ts index d8ecd458..e6dbe1f6 100644 --- a/src/crud/blob.ts +++ b/src/crud/blob.ts @@ -15,18 +15,11 @@ import { Err } from '../error'; import { FatBinaryDoc, FatDoc, FatJsonDoc, FatTextDoc, JsonDoc } from '../types'; /** - * blobToJsonDoc - * + * textToJsonDoc * @throws {@link Err.InvalidJsonObjectError} */ // eslint-disable-next-line complexity -export function blobToJsonDoc ( - shortId: string, - readBlobResult: ReadBlobResult, - withMetadata: boolean, - jsonExt: string -): FatJsonDoc | JsonDoc { - const text = utf8decode(readBlobResult.blob); +export function textToJsonDoc (text: string, jsonExt: string, shortId?: string): JsonDoc { let jsonDoc: JsonDoc; if (jsonExt === FRONT_MATTER_POSTFIX) { const mdArray = text.split('\n'); @@ -58,11 +51,15 @@ export function blobToJsonDoc ( } } if (!endFrontMatter) { - // throw new Err.InvalidJsonObjectError(shortId); markdownText = text; - jsonDoc = { - _id: shortId, - }; + if (shortId !== undefined) { + jsonDoc = { + _id: shortId, + }; + } + else { + jsonDoc = {}; + } } else { try { @@ -71,9 +68,14 @@ export function blobToJsonDoc ( throw new Err.InvalidJsonObjectError(shortId); } if (jsonDoc === undefined) { - jsonDoc = { - _id: shortId, - }; + if (shortId !== undefined) { + jsonDoc = { + _id: shortId, + }; + } + else { + jsonDoc = {}; + } } } if (markdownText !== '') { @@ -87,6 +89,22 @@ export function blobToJsonDoc ( throw new Err.InvalidJsonObjectError(shortId); } } + return jsonDoc; +} + +/** + * blobToJsonDoc + * + * @throws {@link Err.InvalidJsonObjectError} + */ +export function blobToJsonDoc ( + shortId: string, + readBlobResult: ReadBlobResult, + withMetadata: boolean, + jsonExt: string +): FatJsonDoc | JsonDoc { + const text = utf8decode(readBlobResult.blob); + const jsonDoc = textToJsonDoc(text, jsonExt, shortId); if (jsonDoc._id !== undefined) { // Overwrite _id property by shortId (_id without collectionPath) if JsonDoc is created by GitDocumentedDB (_id !== undefined). jsonDoc._id = shortId; @@ -109,16 +127,14 @@ export function blobToJsonDoc ( * * @throws {@link Err.InvalidJsonObjectError} */ +// eslint-disable-next-line complexity export function blobToJsonDocWithoutOverwrittenId ( - readBlobResult: ReadBlobResult + readBlobResult: ReadBlobResult, + jsonExt: string ): JsonDoc { - try { - const text = utf8decode(readBlobResult.blob); - const jsonDoc = (JSON.parse(text) as unknown) as JsonDoc; - return jsonDoc; - } catch (e) { - throw new Err.InvalidJsonObjectError(''); - } + const text = utf8decode(readBlobResult.blob); + const jsonDoc = textToJsonDoc(text, jsonExt); + return jsonDoc; } /** diff --git a/src/crud/get.ts b/src/crud/get.ts index 5d033c97..a6365362 100644 --- a/src/crud/get.ts +++ b/src/crud/get.ts @@ -105,7 +105,7 @@ export async function getImpl ( if (docType === 'json') { if (internalOptions.oid !== '') { - return blobToJsonDocWithoutOverwrittenId(readBlobResult); + return blobToJsonDocWithoutOverwrittenId(readBlobResult, jsonExt); } const shortId = shortName.replace(new RegExp(jsonExt + '$'), ''); return blobToJsonDoc(shortId, readBlobResult, internalOptions.withMetadata, jsonExt); diff --git a/src/remote/3way_merge.ts b/src/remote/3way_merge.ts index 3dff408b..deec369c 100644 --- a/src/remote/3way_merge.ts +++ b/src/remote/3way_merge.ts @@ -18,7 +18,7 @@ import { getFatDocFromData, writeBlobToFile } from './worker_utils'; import { serializeJSON, utf8decode } from '../utils'; import { JsonDiff } from './json_diff'; import { SyncInterface } from '../types_sync'; -import { isSameFatDoc } from '../crud/blob'; +import { isSameFatDoc, textToJsonDoc } from '../crud/blob'; /** * @internal @@ -162,11 +162,11 @@ function getMergedDocument ( jsonExt: string ): string | Uint8Array { if (docType === 'json') { - const oursDoc = JSON.parse(utf8decode(ours)); - const theirsDoc = JSON.parse(utf8decode(theirs)); + const oursDoc = textToJsonDoc(utf8decode(ours), jsonExt); + const theirsDoc = textToJsonDoc(utf8decode(theirs), jsonExt); let baseDoc: JsonDoc | undefined; if (base) { - baseDoc = JSON.parse(utf8decode(base)); + baseDoc = textToJsonDoc(utf8decode(base), jsonExt); } else { baseDoc = undefined; diff --git a/src/remote/combine.ts b/src/remote/combine.ts index 74cd6da9..c749ed5e 100644 --- a/src/remote/combine.ts +++ b/src/remote/combine.ts @@ -11,17 +11,23 @@ import git from 'isomorphic-git'; import fs from 'fs-extra'; import { ulid } from 'ulid'; import rimraf from 'rimraf'; +import { textToJsonDoc } from '../crud/blob'; import { DocMetadata, DocType, DuplicatedFile, + JsonDoc, JsonDocMetadata, RemoteOptions, SyncResultCombineDatabase, } from '../types'; import { GitDDBInterface } from '../types_gitddb'; import { Err } from '../error'; -import { DUPLICATED_FILE_POSTFIX, FILE_REMOVE_TIMEOUT } from '../const'; +import { + DUPLICATED_FILE_POSTFIX, + FILE_REMOVE_TIMEOUT, + FRONT_MATTER_POSTFIX, +} from '../const'; import { getAllMetadata, serializeJSON } from '../utils'; import { RemoteEngine, wrappingRemoteEngineError } from './remote_engine'; @@ -128,7 +134,18 @@ export async function combineDatabaseWithTheirs ( const remoteFile = remoteMetadataList.find(data => data.name === meta.name); if (docType === 'json') { - const doc = fs.readJSONSync(localFilePath); + let doc: JsonDoc; + // eslint-disable-next-line max-depth + if (gitDDB.jsonExt === FRONT_MATTER_POSTFIX) { + const txt = fs.readFileSync(localFilePath, { + encoding: 'utf8', + }); + doc = textToJsonDoc(txt, FRONT_MATTER_POSTFIX); + } + else { + doc = fs.readJSONSync(localFilePath); + } + const _id = (meta as JsonDocMetadata)._id; // eslint-disable-next-line max-depth if (doc._id !== undefined) { diff --git a/src/remote/json_patch_ot.ts b/src/remote/json_patch_ot.ts index 0133961f..5e0311a6 100644 --- a/src/remote/json_patch_ot.ts +++ b/src/remote/json_patch_ot.ts @@ -1,6 +1,6 @@ /* eslint-disable unicorn/prefer-spread */ /* eslint-disable max-depth */ -import { editOp, insertOp, JSONOp, moveOp, replaceOp, type } from 'ot-json1'; +import { editOp, insertOp, JSONOp, replaceOp, type } from 'ot-json1'; import { uniCount } from 'unicount'; import { ConflictResolutionStrategyLabels, IJsonPatch, JsonDoc } from '../types'; import { DEFAULT_CONFLICT_RESOLUTION_STRATEGY } from '../const'; diff --git a/src/remote/worker_utils.ts b/src/remote/worker_utils.ts index bb8a898f..28640ec6 100644 --- a/src/remote/worker_utils.ts +++ b/src/remote/worker_utils.ts @@ -21,7 +21,7 @@ import { JsonDoc, NormalizedCommit, } from '../types'; -import { blobToBinary, blobToJsonDoc, blobToText } from '../crud/blob'; +import { blobToBinary, blobToJsonDoc, blobToText, textToJsonDoc } from '../crud/blob'; /** * Write blob to file system @@ -60,7 +60,7 @@ export async function getFatDocFromData ( data = utf8decode(data); } try { - const jsonDoc = (JSON.parse(data) as unknown) as JsonDoc; + const jsonDoc = (textToJsonDoc(data, jsonExt) as unknown) as JsonDoc; if (jsonDoc._id !== undefined) { // Overwrite _id property by _id if JsonDoc is created by GitDocumentedDB (_id !== undefined). jsonDoc._id = _id; diff --git a/test/crud/blob.test.ts b/test/crud/blob.test.ts index 6d4f38ef..9e499cb3 100644 --- a/test/crud/blob.test.ts +++ b/test/crud/blob.test.ts @@ -193,9 +193,9 @@ describe('', () => { oid: (await git.hashBlob({ object: text })).oid, blob: utf8encode(text), }; - expect(() => blobToJsonDocWithoutOverwrittenId(readBlobResult)).toThrowError( - Err.InvalidJsonObjectError - ); + expect(() => + blobToJsonDocWithoutOverwrittenId(readBlobResult, JSON_POSTFIX) + ).toThrowError(Err.InvalidJsonObjectError); }); it('returns JsonDoc', async () => { @@ -206,7 +206,20 @@ describe('', () => { oid: (await git.hashBlob({ object: text })).oid, blob: utf8encode(text), }; - expect(blobToJsonDocWithoutOverwrittenId(readBlobResult)).toEqual(json); + expect(blobToJsonDocWithoutOverwrittenId(readBlobResult, JSON_POSTFIX)).toEqual(json); + }); + + it('returns JsonDoc in FrontMatterMarkdown', async () => { + const shortId = 'foo'; + const json = { _id: shortId, name: 'bar' }; + const text = toFrontMatterMarkdown(json); + const readBlobResult: ReadBlobResult = { + oid: (await git.hashBlob({ object: text })).oid, + blob: utf8encode(text), + }; + expect( + blobToJsonDocWithoutOverwrittenId(readBlobResult, FRONT_MATTER_POSTFIX) + ).toEqual(json); }); }); diff --git a/test/remote_base/3way_merge_ot.ts b/test/remote_base/3way_merge_ot.ts index 2ad59aed..f1bc9e62 100644 --- a/test/remote_base/3way_merge_ot.ts +++ b/test/remote_base/3way_merge_ot.ts @@ -16,6 +16,7 @@ import expect from 'expect'; import { GitDocumentDB } from '../../src/git_documentdb'; import { ConnectionSettings, + RemoteOptions, Schema, SyncResultMergeAndPush, SyncResultResolveConflictsAndPush, @@ -33,7 +34,7 @@ import { removeRemoteRepositories, } from '../remote_utils'; -import { JSON_POSTFIX } from '../../src/const'; +import { FRONT_MATTER_POSTFIX, JSON_POSTFIX } from '../../src/const'; export const threeWayMergeOtBase = ( connection: ConnectionSettings, @@ -539,6 +540,135 @@ export const threeWayMergeOtBase = ( await destroyDBs([dbA, dbB]); }); + /** + * before: jsonA1 + * dbA : +jsonA1 + * dbB : jsonB1 + * after : mergedJson + * + * 3-way merge: + * mergedJson:17 - Conflict. Accept theirs (update-merge) + */ + it('resolves case 17 - Conflict. Accept theirs (update-merge) in FrontMatterMarkdown', async () => { + const schema: Schema = { + json: { plainTextProperties: { name: true } }, + }; + const remoteURL = remoteURLBase + serialId(); + + const dbNameA = serialId(); + + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir, + schema, + serializeFormat: 'front-matter', + }); + + const options: RemoteOptions = { + remoteUrl: remoteURL, + includeCommits: true, + conflictResolutionStrategy: 'theirs-diff', + connection, + }; + + await dbA.open(); + const syncA = await dbA.sync(options); + + // A puts and pushes + const jsonA1 = { _id: '1', name: 'Hello, world!' }; + const putResultA1 = await dbA.put(jsonA1); + await syncA.tryPush(); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir: localDir, + schema, + serializeFormat: 'front-matter', + }); + // Clone dbA + await dbB.open(); + const syncB = await dbB.sync({ + ...syncA.options, + conflictResolutionStrategy: 'theirs-diff', + }); + + // A puts and pushes + const jsonA1dash = { _id: '1', name: 'Hello' }; + const putResultA1dash = await dbA.put(jsonA1dash); + await syncA.tryPush(); + + // B puts + const jsonB1 = { _id: '1', name: 'Hello, world! Hello, Nara!' }; + const putResultB1 = await dbB.put(jsonB1); + + const mergedJson = { _id: '1', name: 'Hello Hello, Nara!' }; + + // It will occur conflict on id 1.json. + const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; + + const mergedDoc = await dbB.getFatDoc('1.md'); + + expect(syncResult1.action).toBe('resolve conflicts and push'); + expect(syncResult1.commits).toMatchObject({ + local: getCommitInfo([ + putResultA1dash, + `resolve: 1${FRONT_MATTER_POSTFIX}(update-merge,${mergedDoc!.fileOid.substr( + 0, + 7 + )},theirs-diff)`, + ]), + remote: getCommitInfo([ + putResultB1, + `resolve: 1${FRONT_MATTER_POSTFIX}(update-merge,${mergedDoc!.fileOid.substr( + 0, + 7 + )},theirs-diff)`, + ]), + }); + expect(syncResult1.changes.local.length).toBe(1); + expect(syncResult1.changes.local).toEqual([ + getChangedFileUpdateBySHA( + jsonB1, + putResultB1.fileOid, + mergedJson, + mergedDoc!.fileOid, + FRONT_MATTER_POSTFIX + ), + ]); + + expect(syncResult1.changes.remote.length).toBe(1); + expect(syncResult1.changes.remote).toEqual([ + getChangedFileUpdateBySHA( + jsonA1dash, + putResultA1dash.fileOid, + mergedJson, + mergedDoc!.fileOid, + FRONT_MATTER_POSTFIX + ), + ]); + + expect(syncResult1.conflicts.length).toEqual(1); + expect(syncResult1.conflicts).toEqual([ + { + fatDoc: mergedDoc, + strategy: 'theirs-diff', + operation: 'update-merge', + }, + ]); + // Conflict occurs on 1.json + + expect(getWorkingDirDocs(dbB, FRONT_MATTER_POSTFIX)).toEqual([mergedJson]); + // Sync dbA + const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; + expect(getWorkingDirDocs(dbA, FRONT_MATTER_POSTFIX)).toEqual([mergedJson]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + + await destroyDBs([dbA, dbB]); + }); + describe('plaintext-OT Type', () => { /** * before: jsonA1 diff --git a/test/remote_base/combine.ts b/test/remote_base/combine.ts index 613aa029..40c9d3c4 100644 --- a/test/remote_base/combine.ts +++ b/test/remote_base/combine.ts @@ -17,8 +17,9 @@ import fs from 'fs-extra'; import git from 'isomorphic-git'; import expect from 'expect'; import parse from 'parse-git-config'; +import { textToJsonDoc } from '../../src/crud/blob'; import { Err } from '../../src/error'; -import { ConnectionSettings, DuplicatedFile } from '../../src/types'; +import { ConnectionSettings, DuplicatedFile, RemoteOptions } from '../../src/types'; import { GitDocumentDB } from '../../src/git_documentdb'; import { compareWorkingDirAndBlobs, @@ -29,7 +30,7 @@ import { removeRemoteRepositories, } from '../remote_utils'; import { sleep } from '../../src/utils'; -import { JSON_POSTFIX } from '../../src/const'; +import { FRONT_MATTER_POSTFIX, JSON_POSTFIX } from '../../src/const'; export const syncCombineBase = ( connection: ConnectionSettings, @@ -50,7 +51,7 @@ export const syncCombineBase = ( /** * Combine database */ - describe('with NodeGit', () => { + describe('with same serializeFormat', () => { it('throws NoMergeBaseFoundError when combineDbStrategy is throw-error in [both] direction', async () => { const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { combineDbStrategy: 'throw-error', @@ -501,6 +502,101 @@ export const syncCombineBase = ( const config = parse.sync({ cwd: dbB.workingDir, path: '.git/config' }); expect(config.user).toEqual(author); + await destroyDBs([dbA, dbB]); + }); + }); + describe('with same serializeFormat', () => { + it('returns SyncResult with duplicates when combine-head-with-theirs with deep local and deep remote', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir, + serializeFormat: 'front-matter', + }); + + const options: RemoteOptions = { + remoteUrl: remoteURL, + combineDbStrategy: 'combine-head-with-theirs', + syncDirection: 'both', + connection, + }; + + await dbA.open(); + const syncA = await dbA.sync(options); + + const dbIdA = dbA.dbId; + + const jsonA1 = { _id: 'deep/one', name: 'fromA' }; + const putResultA1 = await dbA.put(jsonA1); + await syncA.trySync(); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir, + serializeFormat: 'front-matter', + }); + await dbB.open(); + + const dbIdB = dbB.dbId; + expect(dbIdB).not.toBe(dbIdA); + + const jsonB1 = { _id: 'deep/one', name: 'fromB' }; + await dbB.put(jsonB1); + + const jsonB2 = { _id: '2', name: 'fromB' }; + await dbB.put(jsonB2); + + // Combine with remote db + const [sync, syncResult] = await dbB.sync(syncA.options, true); + + expect(dbB.dbId).toBe(dbIdA); + + // Put new doc to combined db. + const jsonB3 = { _id: '3', name: 'fromB' }; + await dbB.put(jsonB3); + + expect(getWorkingDirDocs(dbA, FRONT_MATTER_POSTFIX)).toEqual([jsonA1]); + // jsonB1 is duplicated with postfix due to combine-head-with-theirs strategy + jsonB1._id = jsonB1._id + '-from-' + dbIdB; + const duplicatedB1 = await dbB.getFatDoc(jsonB1._id + FRONT_MATTER_POSTFIX); + + expect(syncResult).toEqual({ + action: 'combine database', + duplicates: [ + { + original: { + _id: jsonA1._id, + name: jsonA1._id + FRONT_MATTER_POSTFIX, + fileOid: putResultA1.fileOid, + type: 'json', + }, + duplicate: { + _id: jsonB1._id, + name: jsonB1._id + FRONT_MATTER_POSTFIX, + fileOid: duplicatedB1?.fileOid, + type: 'json', + }, + }, + ], + }); + expect(getWorkingDirDocs(dbB, FRONT_MATTER_POSTFIX)).toEqual([ + jsonB2, + jsonB3, + jsonB1, + jsonA1, + ]); + + const rawJSON = textToJsonDoc( + fs.readFileSync(dbB.workingDir + '/deep/one.md', { encoding: 'utf8' }), + FRONT_MATTER_POSTFIX + ); + rawJSON._id = 'one'; // not 'deep/one' + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + await destroyDBs([dbA, dbB]); }); }); diff --git a/test/remote_utils.ts b/test/remote_utils.ts index 93756c87..4f09f770 100644 --- a/test/remote_utils.ts +++ b/test/remote_utils.ts @@ -4,6 +4,7 @@ import { Octokit } from '@octokit/rest'; import git from 'isomorphic-git'; import sinon from 'sinon'; import expect from 'expect'; +import { textToJsonDoc } from '../src/crud/blob'; import { ChangedFileDelete, ChangedFileInsert, @@ -18,6 +19,7 @@ import { SyncInterface } from '../src/types_sync'; import { GitDocumentDB } from '../src/git_documentdb'; import { FILE_REMOVE_TIMEOUT, + FRONT_MATTER_POSTFIX, GIT_DOCUMENTDB_METADATA_DIR, JSON_POSTFIX, } from '../src/const'; @@ -61,13 +63,14 @@ export function getCommitInfo (resultOrMessage: (PutResult | DeleteResult | stri */ export function getChangedFileInsert ( newDoc: JsonDoc, - newResult: PutResult | DeleteResult + newResult: PutResult | DeleteResult, + jsonExt = JSON_POSTFIX ): ChangedFileInsert { return { operation: 'insert', new: { _id: newDoc!._id, - name: newDoc!._id + JSON_POSTFIX, + name: newDoc!._id + jsonExt, fileOid: newResult!.fileOid, type: 'json', doc: newDoc, @@ -79,20 +82,21 @@ export function getChangedFileUpdate ( oldDoc: JsonDoc, oldResult: PutResult | DeleteResult, newDoc: JsonDoc, - newResult: PutResult | DeleteResult + newResult: PutResult | DeleteResult, + jsonExt = JSON_POSTFIX ): ChangedFileUpdate { return { operation: 'update', old: { _id: oldDoc!._id, - name: oldDoc!._id + JSON_POSTFIX, + name: oldDoc!._id + jsonExt, fileOid: oldResult!.fileOid, type: 'json', doc: oldDoc!, }, new: { _id: newDoc!._id, - name: newDoc!._id + JSON_POSTFIX, + name: newDoc!._id + jsonExt, fileOid: newResult!.fileOid, type: 'json', doc: newDoc, @@ -102,13 +106,14 @@ export function getChangedFileUpdate ( export function getChangedFileDelete ( oldDoc: JsonDoc, - oldResult: PutResult | DeleteResult + oldResult: PutResult | DeleteResult, + jsonExt = JSON_POSTFIX ): ChangedFileDelete { return { operation: 'delete', old: { _id: oldDoc!._id, - name: oldDoc!._id + JSON_POSTFIX, + name: oldDoc!._id + jsonExt, fileOid: oldResult!.fileOid, type: 'json', doc: oldDoc, @@ -118,13 +123,14 @@ export function getChangedFileDelete ( export function getChangedFileInsertBySHA ( newDoc: JsonDoc, - newFileSHA: string + newFileSHA: string, + jsonExt = JSON_POSTFIX ): ChangedFileInsert { return { operation: 'insert', new: { _id: newDoc!._id, - name: newDoc!._id + JSON_POSTFIX, + name: newDoc!._id + jsonExt, fileOid: newFileSHA, type: 'json', doc: newDoc, @@ -136,20 +142,21 @@ export function getChangedFileUpdateBySHA ( oldDoc: JsonDoc, oldFileSHA: string, newDoc: JsonDoc, - newFileSHA: string + newFileSHA: string, + jsonExt = JSON_POSTFIX ): ChangedFileUpdate { return { operation: 'update', old: { _id: oldDoc!._id, - name: oldDoc!._id + JSON_POSTFIX, + name: oldDoc!._id + jsonExt, fileOid: oldFileSHA, type: 'json', doc: oldDoc!, }, new: { _id: newDoc!._id, - name: newDoc!._id + JSON_POSTFIX, + name: newDoc!._id + jsonExt, fileOid: newFileSHA, type: 'json', doc: newDoc, @@ -159,13 +166,14 @@ export function getChangedFileUpdateBySHA ( export function getChangedFileDeleteBySHA ( oldDoc: JsonDoc, - oldFileSHA: string + oldFileSHA: string, + jsonExt = JSON_POSTFIX ): ChangedFileDelete { return { operation: 'delete', old: { _id: oldDoc!._id, - name: oldDoc!._id + JSON_POSTFIX, + name: oldDoc!._id + jsonExt, fileOid: oldFileSHA, type: 'json', doc: oldDoc, @@ -377,10 +385,17 @@ export const compareWorkingDirAndBlobs = async ( return true; }; -export const getWorkingDirDocs = (gitDDB: GitDocumentDB) => { +export const getWorkingDirDocs = (gitDDB: GitDocumentDB, jsonExt = JSON_POSTFIX) => { return listFiles(gitDDB, gitDDB.workingDir).map(filepath => { + if (jsonExt === FRONT_MATTER_POSTFIX) { + const txt = fs.readFileSync(gitDDB.workingDir + '/' + filepath, { encoding: 'utf8' }); + const doc = textToJsonDoc(txt, FRONT_MATTER_POSTFIX); + doc._id = filepath.replace(new RegExp(jsonExt + '$'), ''); + return doc; + } + const doc = fs.readJSONSync(gitDDB.workingDir + '/' + filepath); - doc._id = filepath.replace(new RegExp(JSON_POSTFIX + '$'), ''); + doc._id = filepath.replace(new RegExp(jsonExt + '$'), ''); return doc; }); }; From 0b986d493a5fe11d0226527f78364fed33cc8d76 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Thu, 14 Oct 2021 15:23:40 +0900 Subject: [PATCH 202/297] build: bump to v0.4.7-alpha.3 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index fc93023e..ebd440dd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "git-documentdb", - "version": "0.4.7-alpha.2", + "version": "0.4.7-alpha.3", "description": "Offline-first database that syncs with Git", "main": "dist/main.js", "types": "dist/main.d.ts", @@ -19,7 +19,7 @@ "test-plugin": "npm run mocha \"test_plugin/**/*.test.ts\" && npm run rm-test-db", "upload-coverage": "npx coveralls < coverage/lcov.info", "prepare": "", - "prepublishOnly": "npm run build && npm test", + "prepublishOnly": "npm run build && npm test", "api-extractor": "api-extractor run --local --verbose && npx api-documenter markdown -i ./temp -o ./docs-api", "lint": "eslint --fix --ext .ts .", "crlf": "npx crlf --set=LF docs-api/* etc/* ", From 78d809bf66d57ed2ab698ba353cf2e03c029179b Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 15 Oct 2021 19:25:29 +0900 Subject: [PATCH 203/297] fix: can use external id generator --- package-lock.json | 20 +++++++++++++-- package.json | 3 ++- src/collection.ts | 15 +++++++++--- src/git_documentdb.ts | 1 + src/types.ts | 1 + src/types_collection.ts | 2 +- test/collection.test.ts | 49 +++++++++++++++++++++++++++++++++++++ test/collection_put.test.ts | 26 ++++++++++++++++++++ 8 files changed, 110 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index e4e483b2..da0f23cc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "git-documentdb", - "version": "0.4.7-alpha.0", + "version": "0.4.7-alpha.3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "git-documentdb", - "version": "0.4.7-alpha.0", + "version": "0.4.7-alpha.3", "license": "MPL-2.0", "dependencies": { "@octokit/rest": "^18.3.5", @@ -46,6 +46,7 @@ "eslint-plugin-unicorn": "^36.0.0", "expect": "^27.0.2", "git-documentdb-plugin-remote-nodegit": "^1.0.4", + "hmtid": "^0.1.0", "mocha": "^8.3.2", "nyc": "^15.1.0", "parse-git-config": "^3.0.0", @@ -4901,6 +4902,15 @@ "he": "bin/he" } }, + "node_modules/hmtid": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/hmtid/-/hmtid-0.1.0.tgz", + "integrity": "sha512-V+GXr9Q6ujl9zHQ+wUt66+H0HZ5KsvDuEWZ2l5cRRBGq1VRuz3THbObb0+eBrA1+H2Z6Vu0jTyMBICSqsDjQzA==", + "dev": true, + "bin": { + "hmtid": "bin/cli.js" + } + }, "node_modules/hosted-git-info": { "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", @@ -14497,6 +14507,12 @@ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true }, + "hmtid": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/hmtid/-/hmtid-0.1.0.tgz", + "integrity": "sha512-V+GXr9Q6ujl9zHQ+wUt66+H0HZ5KsvDuEWZ2l5cRRBGq1VRuz3THbObb0+eBrA1+H2Z6Vu0jTyMBICSqsDjQzA==", + "dev": true + }, "hosted-git-info": { "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", diff --git a/package.json b/package.json index ebd440dd..4bc840fb 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "test-plugin": "npm run mocha \"test_plugin/**/*.test.ts\" && npm run rm-test-db", "upload-coverage": "npx coveralls < coverage/lcov.info", "prepare": "", - "prepublishOnly": "npm run build && npm test", + "prepublishOnly": "npm run build && npm test", "api-extractor": "api-extractor run --local --verbose && npx api-documenter markdown -i ./temp -o ./docs-api", "lint": "eslint --fix --ext .ts .", "crlf": "npx crlf --set=LF docs-api/* etc/* ", @@ -64,6 +64,7 @@ "eslint-plugin-unicorn": "^36.0.0", "expect": "^27.0.2", "git-documentdb-plugin-remote-nodegit": "^1.0.4", + "hmtid": "^0.1.0", "mocha": "^8.3.2", "nyc": "^15.1.0", "parse-git-config": "^3.0.0", diff --git a/src/collection.ts b/src/collection.ts index 78cd0aad..d8925b39 100644 --- a/src/collection.ts +++ b/src/collection.ts @@ -136,7 +136,6 @@ export class Collection implements ICollection { this._gitDDB = gitDDB; this._collectionPath = Validator.normalizeCollectionPath(collectionPathFromParent); this._gitDDB.validator.validateCollectionPath(this.collectionPath); - this._monoID = monotonicFactory(); if (parent === undefined) { this._parent = undefined; @@ -150,6 +149,13 @@ export class Collection implements ICollection { this._parent = parent; } this._options = { ...parent?.options!, ...options }; + + if (this._options.idGenerator !== undefined) { + this._monoID = this._options.idGenerator; + } + else { + this._monoID = monotonicFactory(); + } } /*********************************************** @@ -166,8 +172,11 @@ export class Collection implements ICollection { * * @public */ - generateId () { - return this._options.namePrefix + this._monoID(Date.now()); + generateId (seedTime?: number) { + if (seedTime === undefined) { + seedTime = Date.now(); + } + return this._options.namePrefix + this._monoID(seedTime); } /** diff --git a/src/git_documentdb.ts b/src/git_documentdb.ts index 52cbfc46..1b2d7af2 100644 --- a/src/git_documentdb.ts +++ b/src/git_documentdb.ts @@ -366,6 +366,7 @@ export class GitDocumentDB const collectionOptions = { namePrefix: options?.namePrefix ?? '', debounceTime: options?.debounceTime ?? -1, + idGenerator: options?.idGenerator, }; this._rootCollection = new Collection(this, '', undefined, collectionOptions); diff --git a/src/types.ts b/src/types.ts index 238b4c8d..7f798a90 100644 --- a/src/types.ts +++ b/src/types.ts @@ -333,6 +333,7 @@ export type CollectionPath = string; export type CollectionOptions = { namePrefix?: string; debounceTime?: number; + idGenerator?: () => string; }; /** diff --git a/src/types_collection.ts b/src/types_collection.ts index f41a76a0..f705d167 100644 --- a/src/types_collection.ts +++ b/src/types_collection.ts @@ -28,7 +28,7 @@ export type ICollection = CollectionInterface & /*********************************************** * Public methods ***********************************************/ - generateId(): string; + generateId(seedTime?: number): string; }; /** diff --git a/test/collection.test.ts b/test/collection.test.ts index cee8c969..5dae268d 100644 --- a/test/collection.test.ts +++ b/test/collection.test.ts @@ -11,6 +11,7 @@ import path from 'path'; import expect from 'expect'; import fs from 'fs-extra'; import { monotonicFactory } from 'ulid'; +import { hmtid } from 'hmtid'; import { GitDocumentDB } from '../src/git_documentdb'; import { Err } from '../src/error'; import { Collection } from '../src/collection'; @@ -79,6 +80,34 @@ describe('', () => { await gitDDB.destroy(); }); + describe('generates ID', () => { + it('using default ulid', async () => { + const dbName = monoId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + }); + await gitDDB.open(); + const col = new Collection(gitDDB, 'col01'); + expect(col.generateId(1469918176385).startsWith('01ARYZ6S41')).toBeTruthy(); + await gitDDB.destroy(); + }); + + it('using hmtid', async () => { + const dbName = monoId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + idGenerator: hmtid, + }); + await gitDDB.open(); + expect( + gitDDB.rootCollection.generateId(1469918176385).startsWith('20160730223616') + ).toBeTruthy(); + await gitDDB.destroy(); + }); + }); + describe('parent', () => { it('sets parent', async () => { const dbName = monoId(); @@ -148,6 +177,26 @@ describe('', () => { await gitDDB.destroy(); }); + + it('idGenerator option is inherited by child', async () => { + const dbName = monoId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + }); + await gitDDB.open(); + + const root = await gitDDB.collection('', { idGenerator: hmtid }); + const col01 = await root.collection('col01'); + const col02 = await col01.collection('col02'); + + expect(gitDDB.rootCollection.generateId().length).toBe(26); // length of ulid + expect(root.generateId().length).toBe(22); // length of hmtid + expect(col01.generateId().length).toBe(22); + expect(col02.generateId().length).toBe(22); + + await gitDDB.destroy(); + }); }); describe('getCollections()', () => { diff --git a/test/collection_put.test.ts b/test/collection_put.test.ts index 4bb91ab0..a92e591e 100644 --- a/test/collection_put.test.ts +++ b/test/collection_put.test.ts @@ -12,6 +12,7 @@ import git from 'isomorphic-git'; import expect from 'expect'; import fs from 'fs-extra'; import { monotonicFactory } from 'ulid'; +import { hmtid } from 'hmtid'; import { PutResultJsonDoc } from '../src/types'; import { toSortedJSONString } from '../src/utils'; import { JSON_POSTFIX, SHORT_SHA_LENGTH } from '../src/const'; @@ -594,6 +595,31 @@ describe('', () => { await gitDDB.destroy(); }); + it('generates new _id with namePrefix by hmtid', async () => { + const dbName = monoId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + }); + await gitDDB.open(); + const namePrefix = 'item'; + const col = new Collection(gitDDB, 'col01', undefined, { + namePrefix, + idGenerator: hmtid, + }); + const json = { name: 'Shirase' }; + const putResult = await col.put(undefined, json); + expect(putResult._id.startsWith(namePrefix)).toBeTruthy(); + const autoGen = putResult._id.replace(namePrefix, ''); + expect(autoGen).toMatch(/^\d{14}_[\dA-HJKMNP-TV-Z]{7}$/); // Match hmtid + await expect(col.get(putResult._id)).resolves.toEqual({ + ...json, + _id: putResult._id, + }); + + await gitDDB.destroy(); + }); + it('creates a JSON file', async () => { const dbName = monoId(); const gitDDB: GitDocumentDB = new GitDocumentDB({ From 21918859445a7db6b590fad7618fc08a878241f2 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 22 Oct 2021 11:57:03 +0900 Subject: [PATCH 204/297] snapshot: fixing InvalidRepositoryURLError --- package-lock.json | 4 ++-- package.json | 2 +- src/remote/sync.ts | 2 +- test/remote_base/sync.ts | 29 +++++++++++++++++++++++++++++ 4 files changed, 33 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index da0f23cc..6a6c317b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "git-documentdb", - "version": "0.4.7-alpha.3", + "version": "0.4.7-alpha.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "git-documentdb", - "version": "0.4.7-alpha.3", + "version": "0.4.7-alpha.4", "license": "MPL-2.0", "dependencies": { "@octokit/rest": "^18.3.5", diff --git a/package.json b/package.json index 4bc840fb..a9a9b410 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "git-documentdb", - "version": "0.4.7-alpha.3", + "version": "0.4.7-alpha.4", "description": "Offline-first database that syncs with Git", "main": "dist/main.js", "types": "dist/main.d.ts", diff --git a/src/remote/sync.ts b/src/remote/sync.ts index 4213cfcc..fe52e451 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -59,7 +59,7 @@ import { Validator } from '../validator'; import { RemoteEngine, RemoteErr, wrappingRemoteEngineError } from './remote_engine'; /** - * encodeToRemoteName + * encodeToGitRemoteName * * @remarks * The first default name of Git remote is "origin". diff --git a/test/remote_base/sync.ts b/test/remote_base/sync.ts index 17b19f1a..167f2a57 100644 --- a/test/remote_base/sync.ts +++ b/test/remote_base/sync.ts @@ -1167,4 +1167,33 @@ export const syncBase = ( await destroyDBs([gitDDB, dbA, dbB]); }); + + it.only('set valid url after throwing RemoteErr.InvalidRepositoryURLError.', async () => { + const dbName = serialId(); + const remoteURL = remoteURLBase + serialId(); + + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + }); + await gitDDB.open(); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection, + }; + const stubFetch = sandbox.stub(RemoteEngine[connection.engine!], 'fetch'); + stubFetch.onFirstCall().rejects(new RemoteEngineErr.InvalidRepositoryURLError('')); + + await expect(gitDDB.sync(options)).rejects.toThrowError( + RemoteErr.InvalidRepositoryURLError + ); + + sandbox.restore(); + + await expect(gitDDB.sync(options)).rejects.toThrowError( + Err.RemoteAlreadyRegisteredError + ); + + await gitDDB.destroy(); + }); }; From 8309d9a4d2455b00b4781cde5aa51bd51eddc79d Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 22 Oct 2021 19:07:36 +0900 Subject: [PATCH 205/297] test: remove unused test --- test/remote_base/sync.ts | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/test/remote_base/sync.ts b/test/remote_base/sync.ts index 167f2a57..17b19f1a 100644 --- a/test/remote_base/sync.ts +++ b/test/remote_base/sync.ts @@ -1167,33 +1167,4 @@ export const syncBase = ( await destroyDBs([gitDDB, dbA, dbB]); }); - - it.only('set valid url after throwing RemoteErr.InvalidRepositoryURLError.', async () => { - const dbName = serialId(); - const remoteURL = remoteURLBase + serialId(); - - const gitDDB: GitDocumentDB = new GitDocumentDB({ - dbName, - localDir, - }); - await gitDDB.open(); - const options: RemoteOptions = { - remoteUrl: remoteURL, - connection, - }; - const stubFetch = sandbox.stub(RemoteEngine[connection.engine!], 'fetch'); - stubFetch.onFirstCall().rejects(new RemoteEngineErr.InvalidRepositoryURLError('')); - - await expect(gitDDB.sync(options)).rejects.toThrowError( - RemoteErr.InvalidRepositoryURLError - ); - - sandbox.restore(); - - await expect(gitDDB.sync(options)).rejects.toThrowError( - Err.RemoteAlreadyRegisteredError - ); - - await gitDDB.destroy(); - }); }; From 9571f22d72b9aa3c8971f8946be1028e668a0ac9 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 10 Nov 2021 13:59:28 +0900 Subject: [PATCH 206/297] build: move @types to devDependencies --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index a9a9b410..3dee85e9 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,8 @@ "@types/parse-git-config": "^3.0.0", "@types/rimraf": "^3.0.0", "@types/sinon": "^9.0.11", + "@types/async-lock": "^1.1.2", + "@types/js-yaml": "^4.0.3", "@typescript-eslint/eslint-plugin": "^4.28.0", "@typescript-eslint/parser": "^4.28.0", "coveralls": "^3.1.0", @@ -76,8 +78,6 @@ "dependencies": { "@octokit/rest": "^18.3.5", "@sosuisen/jsondiffpatch": "^0.4.7", - "@types/async-lock": "^1.1.2", - "@types/js-yaml": "^4.0.3", "async-lock": "^1.3.0", "cross-blob": "^2.0.0", "fs-extra": "^9.1.0", From e9eca1a0a48886f62b5d15e15cc2203c1061c905 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 10 Nov 2021 23:12:04 +0900 Subject: [PATCH 207/297] fix: use @sosuisen/isomorphic-git instead of original --- .vscode/launch.json | 2 +- package-lock.json | 102 +++++++++--------- package.json | 6 +- src/collection.ts | 2 +- src/crud/blob.ts | 2 +- src/crud/delete.ts | 2 +- src/crud/find.ts | 8 +- src/crud/get.ts | 2 +- src/crud/history.ts | 2 +- src/crud/put.ts | 2 +- src/git_documentdb.ts | 2 +- src/plugin/remote-isomorphic-git.ts | 6 +- src/remote/3way_merge.ts | 2 +- src/remote/combine.ts | 2 +- src/remote/push_worker.ts | 2 +- src/remote/sync.ts | 2 +- src/remote/sync_worker.ts | 2 +- src/remote/worker_utils.ts | 2 +- src/utils.ts | 2 +- test/collection_delete.test.ts | 2 +- test/collection_find.test.ts | 2 +- test/collection_get.test.ts | 2 +- test/collection_insert.test.ts | 2 +- test/collection_put.test.ts | 2 +- test/collection_update.test.ts | 2 +- test/crud/blob.test.ts | 4 +- test/crud/delete.test.ts | 2 +- test/crud/find.test.ts | 2 +- test/crud/get.test.ts | 4 +- test/crud/history.test.ts | 4 +- test/crud/put.test.ts | 2 +- test/git_documentdb_crud.test.ts | 2 +- test/git_documentdb_open.test.ts | 2 +- test/internal_plugin/checkfetch.test.ts | 2 +- test/internal_plugin/clone.test.ts | 2 +- test/internal_plugin/fetch.test.ts | 2 +- test/internal_plugin/push.test.ts | 10 +- test/remote_base/combine.ts | 2 +- test/remote_base/network_history.ts | 2 +- test/remote_base/sync.ts | 2 +- test/remote_base/sync_trysync.ts | 2 +- test/remote_isomorphic_git/3way_merge.test.ts | 2 +- .../3way_merge_ot.test.ts | 2 +- test/remote_isomorphic_git/combine.test.ts | 5 +- .../network_git_documentdb.test.ts | 2 +- .../network_history.test.ts | 2 +- .../network_task_queue.test.ts | 2 +- .../on_sync_event.test.ts | 5 +- test/remote_isomorphic_git/sync.test.ts | 7 +- test/remote_isomorphic_git/sync_clone.test.ts | 5 +- .../remote_isomorphic_git/sync_events.test.ts | 5 +- test/remote_isomorphic_git/sync_live.test.ts | 5 +- .../sync_trypush.test.ts | 5 +- .../sync_trysync.test.ts | 5 +- test/remote_utils.ts | 2 +- test/utils.ts | 2 +- 56 files changed, 150 insertions(+), 116 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index a1898383..21f204ce 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,7 +4,7 @@ "type": "pickString", "id": "choice", "description": "select a file", - "options": ["test/crud/blob.test.js"], + "options": ["test/remote_isomorphic_git/network_history.test.js"], }], "configurations": [ { diff --git a/package-lock.json b/package-lock.json index 6a6c317b..cceee4ce 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,14 +10,12 @@ "license": "MPL-2.0", "dependencies": { "@octokit/rest": "^18.3.5", + "@sosuisen/isomorphic-git": "^1.10.1-alpha.2", "@sosuisen/jsondiffpatch": "^0.4.7", - "@types/async-lock": "^1.1.2", - "@types/js-yaml": "^4.0.3", "async-lock": "^1.3.0", "cross-blob": "^2.0.0", "fs-extra": "^9.1.0", "git-documentdb-remote-errors": "^1.0.3", - "isomorphic-git": "^1.8.2", "js-yaml": "^4.1.0", "ot-json1": "^1.0.2", "rimraf": "^3.0.2", @@ -29,7 +27,9 @@ "@microsoft/api-extractor": "^7.16.0", "@octokit/types": "^6.12.2", "@sosuisen/api-documenter": "^7.13.27", + "@types/async-lock": "^1.1.2", "@types/fs-extra": "^9.0.12", + "@types/js-yaml": "^4.0.3", "@types/mocha": "^8.2.2", "@types/node": "^14.14.20", "@types/parse-git-config": "^3.0.0", @@ -1168,6 +1168,30 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/@sosuisen/isomorphic-git": { + "version": "1.10.1-alpha.2", + "resolved": "https://registry.npmjs.org/@sosuisen/isomorphic-git/-/isomorphic-git-1.10.1-alpha.2.tgz", + "integrity": "sha512-SyrIY8XOHbU6DQ6/4iACmHV/G/kmyBT68j1xt/7X5jeaEs3faVYtZam6E9SkGBqD2xe4e4y1mk2eq+NXIPbeLg==", + "dependencies": { + "async-lock": "^1.1.0", + "clean-git-ref": "^2.0.1", + "crc-32": "^1.2.0", + "diff3": "0.0.3", + "ignore": "^5.1.4", + "minimisted": "^2.0.0", + "pako": "^1.0.10", + "pify": "^4.0.1", + "readable-stream": "^3.4.0", + "sha.js": "^2.4.9", + "simple-get": "^3.0.2" + }, + "bin": { + "isogit": "cli.cjs" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@sosuisen/jsondiffpatch": { "version": "0.4.7", "resolved": "https://registry.npmjs.org/@sosuisen/jsondiffpatch/-/jsondiffpatch-0.4.7.tgz", @@ -1281,7 +1305,8 @@ "node_modules/@types/async-lock": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@types/async-lock/-/async-lock-1.1.3.tgz", - "integrity": "sha512-UpeDcjGKsYEQMeqEbfESm8OWJI305I7b9KE4ji3aBjoKWyN5CTdn8izcA1FM1DVDne30R5fNEnIy89vZw5LXJQ==" + "integrity": "sha512-UpeDcjGKsYEQMeqEbfESm8OWJI305I7b9KE4ji3aBjoKWyN5CTdn8izcA1FM1DVDne30R5fNEnIy89vZw5LXJQ==", + "dev": true }, "node_modules/@types/cacheable-request": { "version": "6.0.2", @@ -1347,7 +1372,8 @@ "node_modules/@types/js-yaml": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.3.tgz", - "integrity": "sha512-5t9BhoORasuF5uCPr+d5/hdB++zRFUTMIZOzbNkr+jZh3yQht4HYbRDyj9fY8n2TZT30iW9huzav73x4NikqWg==" + "integrity": "sha512-5t9BhoORasuF5uCPr+d5/hdB++zRFUTMIZOzbNkr+jZh3yQht4HYbRDyj9fY8n2TZT30iW9huzav73x4NikqWg==", + "dev": true }, "node_modules/@types/json-schema": { "version": "7.0.9", @@ -5470,30 +5496,6 @@ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, - "node_modules/isomorphic-git": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/isomorphic-git/-/isomorphic-git-1.10.1.tgz", - "integrity": "sha512-abbPpKkykIVDJ92rtYoD4AOuT5/7PABHR2fDBrsm7H0r2ZT+MGpPL/FynrEJM6nTcFSieaIDxnHNGhfHO/v+bA==", - "dependencies": { - "async-lock": "^1.1.0", - "clean-git-ref": "^2.0.1", - "crc-32": "^1.2.0", - "diff3": "0.0.3", - "ignore": "^5.1.4", - "minimisted": "^2.0.0", - "pako": "^1.0.10", - "pify": "^4.0.1", - "readable-stream": "^3.4.0", - "sha.js": "^2.4.9", - "simple-get": "^3.0.2" - }, - "bin": { - "isogit": "cli.cjs" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", @@ -11653,6 +11655,24 @@ } } }, + "@sosuisen/isomorphic-git": { + "version": "1.10.1-alpha.2", + "resolved": "https://registry.npmjs.org/@sosuisen/isomorphic-git/-/isomorphic-git-1.10.1-alpha.2.tgz", + "integrity": "sha512-SyrIY8XOHbU6DQ6/4iACmHV/G/kmyBT68j1xt/7X5jeaEs3faVYtZam6E9SkGBqD2xe4e4y1mk2eq+NXIPbeLg==", + "requires": { + "async-lock": "^1.1.0", + "clean-git-ref": "^2.0.1", + "crc-32": "^1.2.0", + "diff3": "0.0.3", + "ignore": "^5.1.4", + "minimisted": "^2.0.0", + "pako": "^1.0.10", + "pify": "^4.0.1", + "readable-stream": "^3.4.0", + "sha.js": "^2.4.9", + "simple-get": "^3.0.2" + } + }, "@sosuisen/jsondiffpatch": { "version": "0.4.7", "resolved": "https://registry.npmjs.org/@sosuisen/jsondiffpatch/-/jsondiffpatch-0.4.7.tgz", @@ -11749,7 +11769,8 @@ "@types/async-lock": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@types/async-lock/-/async-lock-1.1.3.tgz", - "integrity": "sha512-UpeDcjGKsYEQMeqEbfESm8OWJI305I7b9KE4ji3aBjoKWyN5CTdn8izcA1FM1DVDne30R5fNEnIy89vZw5LXJQ==" + "integrity": "sha512-UpeDcjGKsYEQMeqEbfESm8OWJI305I7b9KE4ji3aBjoKWyN5CTdn8izcA1FM1DVDne30R5fNEnIy89vZw5LXJQ==", + "dev": true }, "@types/cacheable-request": { "version": "6.0.2", @@ -11815,7 +11836,8 @@ "@types/js-yaml": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.3.tgz", - "integrity": "sha512-5t9BhoORasuF5uCPr+d5/hdB++zRFUTMIZOzbNkr+jZh3yQht4HYbRDyj9fY8n2TZT30iW9huzav73x4NikqWg==" + "integrity": "sha512-5t9BhoORasuF5uCPr+d5/hdB++zRFUTMIZOzbNkr+jZh3yQht4HYbRDyj9fY8n2TZT30iW9huzav73x4NikqWg==", + "dev": true }, "@types/json-schema": { "version": "7.0.9", @@ -14896,24 +14918,6 @@ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, - "isomorphic-git": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/isomorphic-git/-/isomorphic-git-1.10.1.tgz", - "integrity": "sha512-abbPpKkykIVDJ92rtYoD4AOuT5/7PABHR2fDBrsm7H0r2ZT+MGpPL/FynrEJM6nTcFSieaIDxnHNGhfHO/v+bA==", - "requires": { - "async-lock": "^1.1.0", - "clean-git-ref": "^2.0.1", - "crc-32": "^1.2.0", - "diff3": "0.0.3", - "ignore": "^5.1.4", - "minimisted": "^2.0.0", - "pako": "^1.0.10", - "pify": "^4.0.1", - "readable-stream": "^3.4.0", - "sha.js": "^2.4.9", - "simple-get": "^3.0.2" - } - }, "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", diff --git a/package.json b/package.json index 3dee85e9..2a37882a 100644 --- a/package.json +++ b/package.json @@ -47,14 +47,14 @@ "@microsoft/api-extractor": "^7.16.0", "@octokit/types": "^6.12.2", "@sosuisen/api-documenter": "^7.13.27", + "@types/async-lock": "^1.1.2", "@types/fs-extra": "^9.0.12", + "@types/js-yaml": "^4.0.3", "@types/mocha": "^8.2.2", "@types/node": "^14.14.20", "@types/parse-git-config": "^3.0.0", "@types/rimraf": "^3.0.0", "@types/sinon": "^9.0.11", - "@types/async-lock": "^1.1.2", - "@types/js-yaml": "^4.0.3", "@typescript-eslint/eslint-plugin": "^4.28.0", "@typescript-eslint/parser": "^4.28.0", "coveralls": "^3.1.0", @@ -77,12 +77,12 @@ }, "dependencies": { "@octokit/rest": "^18.3.5", + "@sosuisen/isomorphic-git": "^1.10.1-alpha.2", "@sosuisen/jsondiffpatch": "^0.4.7", "async-lock": "^1.3.0", "cross-blob": "^2.0.0", "fs-extra": "^9.1.0", "git-documentdb-remote-errors": "^1.0.3", - "isomorphic-git": "^1.8.2", "js-yaml": "^4.1.0", "ot-json1": "^1.0.2", "rimraf": "^3.0.2", diff --git a/src/collection.ts b/src/collection.ts index d8925b39..b520eee2 100644 --- a/src/collection.ts +++ b/src/collection.ts @@ -8,7 +8,7 @@ import fs from 'fs'; -import { readTree, resolveRef } from 'isomorphic-git'; +import { readTree, resolveRef } from '@sosuisen/isomorphic-git'; import { monotonicFactory, ULID } from 'ulid'; import { Err } from './error'; import { diff --git a/src/crud/blob.ts b/src/crud/blob.ts index e6dbe1f6..863d076c 100644 --- a/src/crud/blob.ts +++ b/src/crud/blob.ts @@ -8,7 +8,7 @@ import fs from 'fs'; import yaml from 'js-yaml'; -import { readBlob, ReadBlobResult, resolveRef } from 'isomorphic-git'; +import { readBlob, ReadBlobResult, resolveRef } from '@sosuisen/isomorphic-git'; import { FRONT_MATTER_POSTFIX } from '../const'; import { utf8decode } from '../utils'; import { Err } from '../error'; diff --git a/src/crud/delete.ts b/src/crud/delete.ts index 8f7153d9..66189e3d 100644 --- a/src/crud/delete.ts +++ b/src/crud/delete.ts @@ -8,7 +8,7 @@ import path from 'path'; import fs from 'fs-extra'; -import git from 'isomorphic-git'; +import git from '@sosuisen/isomorphic-git'; import { SHORT_SHA_LENGTH } from '../const'; import { GitDDBInterface } from '../types_gitddb'; import { Err } from '../error'; diff --git a/src/crud/find.ts b/src/crud/find.ts index c3d4ee1b..b1e331af 100644 --- a/src/crud/find.ts +++ b/src/crud/find.ts @@ -7,7 +7,13 @@ */ import fs from 'fs'; -import { readBlob, readTree, resolveRef, TreeEntry, TreeObject } from 'isomorphic-git'; +import { + readBlob, + readTree, + resolveRef, + TreeEntry, + TreeObject, +} from '@sosuisen/isomorphic-git'; import { GIT_DOCUMENTDB_METADATA_DIR } from '../const'; import { Err } from '../error'; import { diff --git a/src/crud/get.ts b/src/crud/get.ts index a6365362..57410af2 100644 --- a/src/crud/get.ts +++ b/src/crud/get.ts @@ -6,7 +6,7 @@ * found in the LICENSE file in the root directory of gitDDB source tree. */ -import { ReadBlobResult } from 'isomorphic-git'; +import { ReadBlobResult } from '@sosuisen/isomorphic-git'; import { GitDDBInterface } from '../types_gitddb'; import { Err } from '../error'; import { diff --git a/src/crud/history.ts b/src/crud/history.ts index ae9051e4..eeecdf32 100644 --- a/src/crud/history.ts +++ b/src/crud/history.ts @@ -6,7 +6,7 @@ * found in the LICENSE file in the root directory of gitDDB source tree. */ -import { log, readBlob, ReadBlobResult } from 'isomorphic-git'; +import { log, readBlob, ReadBlobResult } from '@sosuisen/isomorphic-git'; import fs from 'fs-extra'; import { Doc, DocType, FatDoc, GetOptions, HistoryFilter, HistoryOptions } from '../types'; import { GitDDBInterface } from '../types_gitddb'; diff --git a/src/crud/put.ts b/src/crud/put.ts index e1b78606..725139d5 100644 --- a/src/crud/put.ts +++ b/src/crud/put.ts @@ -8,7 +8,7 @@ import path from 'path'; import fs from 'fs-extra'; -import git from 'isomorphic-git'; +import git from '@sosuisen/isomorphic-git'; import { normalizeCommit } from '../utils'; import { SHORT_SHA_LENGTH } from '../const'; import { NormalizedCommit, PutOptions, PutResult } from '../types'; diff --git a/src/git_documentdb.ts b/src/git_documentdb.ts index 1b2d7af2..ae760ba4 100644 --- a/src/git_documentdb.ts +++ b/src/git_documentdb.ts @@ -7,7 +7,7 @@ */ import path from 'path'; -import git from 'isomorphic-git'; +import git from '@sosuisen/isomorphic-git'; import fs from 'fs-extra'; import rimraf from 'rimraf'; import { Logger, TLogLevelName } from 'tslog'; diff --git a/src/plugin/remote-isomorphic-git.ts b/src/plugin/remote-isomorphic-git.ts index 3dfecc3e..9ac1b83c 100644 --- a/src/plugin/remote-isomorphic-git.ts +++ b/src/plugin/remote-isomorphic-git.ts @@ -7,7 +7,7 @@ */ import fs from 'fs'; -import git from 'isomorphic-git'; +import git from '@sosuisen/isomorphic-git'; import { Logger } from 'tslog'; import { CannotConnectError, @@ -21,7 +21,7 @@ import { NetworkError, UnfetchedCommitExistsError, } from 'git-documentdb-remote-errors'; -import httpClient from 'isomorphic-git/http/node'; +import httpClient from '@sosuisen/isomorphic-git/http/node'; import { ConnectionSettingsGitHub, RemoteOptions } from '../types'; import { NETWORK_RETRY, NETWORK_RETRY_INTERVAL } from '../const'; import { sleep } from '../utils'; @@ -36,7 +36,7 @@ export const type = 'remote'; * @public */ // eslint-disable-next-line @typescript-eslint/naming-convention -export const name = 'isomorphic-git'; +export const name = '@sosuisen/isomorphic-git'; /** * Insert credential options for GitHub diff --git a/src/remote/3way_merge.ts b/src/remote/3way_merge.ts index deec369c..c66ef20a 100644 --- a/src/remote/3way_merge.ts +++ b/src/remote/3way_merge.ts @@ -1,5 +1,5 @@ import nodePath, { basename } from 'path'; -import git, { TreeEntry, WalkerEntry } from 'isomorphic-git'; +import git, { TreeEntry, WalkerEntry } from '@sosuisen/isomorphic-git'; import fs from 'fs-extra'; import { DEFAULT_CONFLICT_RESOLUTION_STRATEGY } from '../const'; import { Err } from '../error'; diff --git a/src/remote/combine.ts b/src/remote/combine.ts index c749ed5e..0ac25dff 100644 --- a/src/remote/combine.ts +++ b/src/remote/combine.ts @@ -7,7 +7,7 @@ * found in the LICENSE file in the root directory of this source tree. */ import path from 'path'; -import git from 'isomorphic-git'; +import git from '@sosuisen/isomorphic-git'; import fs from 'fs-extra'; import { ulid } from 'ulid'; import rimraf from 'rimraf'; diff --git a/src/remote/push_worker.ts b/src/remote/push_worker.ts index c34722c1..f3ddb84b 100644 --- a/src/remote/push_worker.ts +++ b/src/remote/push_worker.ts @@ -6,7 +6,7 @@ * found in the LICENSE file in the root directory of gitDDB source tree. */ -import git from 'isomorphic-git'; +import git from '@sosuisen/isomorphic-git'; import fs from 'fs-extra'; import { GitDDBInterface } from '../types_gitddb'; import { diff --git a/src/remote/sync.ts b/src/remote/sync.ts index fe52e451..1810932d 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -11,7 +11,7 @@ */ import { clearInterval, setInterval } from 'timers'; import crypto from 'crypto'; -import git from 'isomorphic-git'; +import git from '@sosuisen/isomorphic-git'; import fs from 'fs-extra'; import { name as default_engine_name } from '../plugin/remote-isomorphic-git'; diff --git a/src/remote/sync_worker.ts b/src/remote/sync_worker.ts index a7bfb79a..39daabfb 100644 --- a/src/remote/sync_worker.ts +++ b/src/remote/sync_worker.ts @@ -7,7 +7,7 @@ * found in the LICENSE file in the root directory of gitDDB source tree. */ -import git from 'isomorphic-git'; +import git from '@sosuisen/isomorphic-git'; import fs from 'fs-extra'; import { SHORT_SHA_LENGTH } from '../const'; import { normalizeCommit } from '../utils'; diff --git a/src/remote/worker_utils.ts b/src/remote/worker_utils.ts index 28640ec6..4184fdca 100644 --- a/src/remote/worker_utils.ts +++ b/src/remote/worker_utils.ts @@ -7,7 +7,7 @@ */ import nodePath from 'path'; -import git, { ReadBlobResult, ReadCommitResult } from 'isomorphic-git'; +import git, { ReadBlobResult, ReadCommitResult } from '@sosuisen/isomorphic-git'; import fs from 'fs-extra'; import { normalizeCommit, serializeJSON, utf8decode } from '../utils'; import { Err } from '../error'; diff --git a/src/utils.ts b/src/utils.ts index fe46a71d..14c4f8de 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -15,7 +15,7 @@ import { resolveRef, TreeEntry, TreeObject, -} from 'isomorphic-git'; +} from '@sosuisen/isomorphic-git'; import { BinaryDocMetadata, DocMetadata, diff --git a/test/collection_delete.test.ts b/test/collection_delete.test.ts index 79297eed..88e762c9 100644 --- a/test/collection_delete.test.ts +++ b/test/collection_delete.test.ts @@ -9,7 +9,7 @@ import path from 'path'; import fs from 'fs-extra'; -import git from 'isomorphic-git'; +import git from '@sosuisen/isomorphic-git'; import expect from 'expect'; import { monotonicFactory } from 'ulid'; import { DeleteResultJsonDoc } from '../src/types'; diff --git a/test/collection_find.test.ts b/test/collection_find.test.ts index deeb5ffd..46544ba1 100644 --- a/test/collection_find.test.ts +++ b/test/collection_find.test.ts @@ -9,7 +9,7 @@ import path from 'path'; import fs from 'fs-extra'; -import git from 'isomorphic-git'; +import git from '@sosuisen/isomorphic-git'; import expect from 'expect'; import { monotonicFactory } from 'ulid'; import { Collection } from '../src/collection'; diff --git a/test/collection_get.test.ts b/test/collection_get.test.ts index 00d25dcc..f02c0708 100644 --- a/test/collection_get.test.ts +++ b/test/collection_get.test.ts @@ -9,7 +9,7 @@ import path from 'path'; import fs from 'fs-extra'; -import git from 'isomorphic-git'; +import git from '@sosuisen/isomorphic-git'; import expect from 'expect'; import { monotonicFactory } from 'ulid'; import { JSON_POSTFIX } from '../src/const'; diff --git a/test/collection_insert.test.ts b/test/collection_insert.test.ts index cc0a3554..afb4654d 100644 --- a/test/collection_insert.test.ts +++ b/test/collection_insert.test.ts @@ -9,7 +9,7 @@ import path from 'path'; import fs from 'fs-extra'; -import git from 'isomorphic-git'; +import git from '@sosuisen/isomorphic-git'; import expect from 'expect'; import { monotonicFactory } from 'ulid'; import { PutResultJsonDoc } from '../src/types'; diff --git a/test/collection_put.test.ts b/test/collection_put.test.ts index a92e591e..24504489 100644 --- a/test/collection_put.test.ts +++ b/test/collection_put.test.ts @@ -8,7 +8,7 @@ */ import path from 'path'; -import git from 'isomorphic-git'; +import git from '@sosuisen/isomorphic-git'; import expect from 'expect'; import fs from 'fs-extra'; import { monotonicFactory } from 'ulid'; diff --git a/test/collection_update.test.ts b/test/collection_update.test.ts index 434ef251..7860fc01 100644 --- a/test/collection_update.test.ts +++ b/test/collection_update.test.ts @@ -8,7 +8,7 @@ */ import path from 'path'; -import git from 'isomorphic-git'; +import git from '@sosuisen/isomorphic-git'; import fs from 'fs-extra'; import expect from 'expect'; import { monotonicFactory } from 'ulid'; diff --git a/test/crud/blob.test.ts b/test/crud/blob.test.ts index 9e499cb3..052fb279 100644 --- a/test/crud/blob.test.ts +++ b/test/crud/blob.test.ts @@ -8,7 +8,7 @@ */ import path from 'path'; -import git, { ReadBlobResult } from 'isomorphic-git'; +import git, { ReadBlobResult } from '@sosuisen/isomorphic-git'; import expect from 'expect'; import fs from 'fs-extra'; import sinon from 'sinon'; @@ -27,7 +27,7 @@ import { toFrontMatterMarkdown, toSortedJSONString, utf8encode } from '../../src import { FRONT_MATTER_POSTFIX, JSON_POSTFIX } from '../../src/const'; // eslint-disable-next-line @typescript-eslint/no-var-requires -const git_module = require('isomorphic-git'); +const git_module = require('@sosuisen/isomorphic-git'); const ulid = monotonicFactory(); const monoId = () => { diff --git a/test/crud/delete.test.ts b/test/crud/delete.test.ts index 553754da..22a3d3d2 100644 --- a/test/crud/delete.test.ts +++ b/test/crud/delete.test.ts @@ -10,7 +10,7 @@ import path from 'path'; import { monotonicFactory } from 'ulid'; import fs from 'fs-extra'; -import git from 'isomorphic-git'; +import git from '@sosuisen/isomorphic-git'; import expect from 'expect'; import sinon from 'sinon'; import { JSON_POSTFIX, SHORT_SHA_LENGTH } from '../../src/const'; diff --git a/test/crud/find.test.ts b/test/crud/find.test.ts index b954e412..999854fa 100644 --- a/test/crud/find.test.ts +++ b/test/crud/find.test.ts @@ -7,7 +7,7 @@ * found in the LICENSE file in the root directory of this source tree. */ import path from 'path'; -import git from 'isomorphic-git'; +import git from '@sosuisen/isomorphic-git'; import fs from 'fs-extra'; import expect from 'expect'; import { monotonicFactory } from 'ulid'; diff --git a/test/crud/get.test.ts b/test/crud/get.test.ts index 451bcfa4..e4e24e72 100644 --- a/test/crud/get.test.ts +++ b/test/crud/get.test.ts @@ -9,7 +9,7 @@ import path from 'path'; import fs from 'fs-extra'; -import git from 'isomorphic-git'; +import git from '@sosuisen/isomorphic-git'; import expect from 'expect'; import { monotonicFactory } from 'ulid'; import sinon from 'sinon'; @@ -21,7 +21,7 @@ import { FRONT_MATTER_POSTFIX, JSON_POSTFIX } from '../../src/const'; import { addOneData, removeOneData } from '../utils'; // eslint-disable-next-line @typescript-eslint/no-var-requires -const git_module = require('isomorphic-git'); +const git_module = require('@sosuisen/isomorphic-git'); const ulid = monotonicFactory(); const monoId = () => { diff --git a/test/crud/history.test.ts b/test/crud/history.test.ts index f8b73a16..daaea2e1 100644 --- a/test/crud/history.test.ts +++ b/test/crud/history.test.ts @@ -9,7 +9,7 @@ import path from 'path'; import fs from 'fs-extra'; -import git from 'isomorphic-git'; +import git from '@sosuisen/isomorphic-git'; import expect from 'expect'; import { monotonicFactory } from 'ulid'; import sinon from 'sinon'; @@ -28,7 +28,7 @@ import { addOneData, removeOneData } from '../utils'; import { FatJsonDoc } from '../../src/types'; // eslint-disable-next-line @typescript-eslint/no-var-requires -const git_module = require('isomorphic-git'); +const git_module = require('@sosuisen/isomorphic-git'); const ulid = monotonicFactory(); const monoId = () => { diff --git a/test/crud/put.test.ts b/test/crud/put.test.ts index 93fb90a3..518df918 100644 --- a/test/crud/put.test.ts +++ b/test/crud/put.test.ts @@ -9,7 +9,7 @@ import path from 'path'; import { readFileSync } from 'fs'; -import git from 'isomorphic-git'; +import git from '@sosuisen/isomorphic-git'; import expect from 'expect'; import fs from 'fs-extra'; import sinon from 'sinon'; diff --git a/test/git_documentdb_crud.test.ts b/test/git_documentdb_crud.test.ts index b0dcc586..665b858e 100644 --- a/test/git_documentdb_crud.test.ts +++ b/test/git_documentdb_crud.test.ts @@ -8,7 +8,7 @@ */ import path from 'path'; -import git from 'isomorphic-git'; +import git from '@sosuisen/isomorphic-git'; import { monotonicFactory } from 'ulid'; import expect from 'expect'; import fs from 'fs-extra'; diff --git a/test/git_documentdb_open.test.ts b/test/git_documentdb_open.test.ts index 3a88899c..b3081a29 100644 --- a/test/git_documentdb_open.test.ts +++ b/test/git_documentdb_open.test.ts @@ -9,7 +9,7 @@ import path from 'path'; import expect from 'expect'; -import git from 'isomorphic-git'; +import git from '@sosuisen/isomorphic-git'; import { monotonicFactory } from 'ulid'; import fs from 'fs-extra'; import sinon from 'sinon'; diff --git a/test/internal_plugin/checkfetch.test.ts b/test/internal_plugin/checkfetch.test.ts index 66a5d9ac..3d8b6004 100644 --- a/test/internal_plugin/checkfetch.test.ts +++ b/test/internal_plugin/checkfetch.test.ts @@ -10,7 +10,7 @@ import path from 'path'; import fs from 'fs-extra'; import expect from 'expect'; -import git from 'isomorphic-git'; +import git from '@sosuisen/isomorphic-git'; import { HTTPError401AuthorizationRequired, HTTPError404NotFound, diff --git a/test/internal_plugin/clone.test.ts b/test/internal_plugin/clone.test.ts index 226434b0..90b7d63b 100644 --- a/test/internal_plugin/clone.test.ts +++ b/test/internal_plugin/clone.test.ts @@ -19,7 +19,7 @@ import { InvalidURLFormatError, NetworkError, } from 'git-documentdb-remote-errors'; -import git from 'isomorphic-git'; +import git from '@sosuisen/isomorphic-git'; import sinon from 'sinon'; import { GitDocumentDB } from '../../src/git_documentdb'; import { clone } from '../../src/plugin/remote-isomorphic-git'; diff --git a/test/internal_plugin/fetch.test.ts b/test/internal_plugin/fetch.test.ts index 4217ffcb..37f43f6b 100644 --- a/test/internal_plugin/fetch.test.ts +++ b/test/internal_plugin/fetch.test.ts @@ -10,7 +10,7 @@ import path from 'path'; import fs from 'fs-extra'; import expect from 'expect'; -import git from 'isomorphic-git'; +import git from '@sosuisen/isomorphic-git'; import { HTTPError401AuthorizationRequired, HTTPError404NotFound, diff --git a/test/internal_plugin/push.test.ts b/test/internal_plugin/push.test.ts index 3e638d3a..344f6e8a 100644 --- a/test/internal_plugin/push.test.ts +++ b/test/internal_plugin/push.test.ts @@ -8,7 +8,7 @@ */ import path from 'path'; -import git from 'isomorphic-git'; +import git from '@sosuisen/isomorphic-git'; import fs from 'fs-extra'; import expect from 'expect'; import { @@ -587,7 +587,7 @@ maybe(' push', () => { connection: { type: 'github', personalAccessToken: token, - engine: 'isomorphic-git', + engine: '@sosuisen/isomorphic-git', }, } ); @@ -618,7 +618,7 @@ maybe(' push', () => { connection: { type: 'github', personalAccessToken: token, - engine: 'isomorphic-git', + engine: '@sosuisen/isomorphic-git', }, }; await dbA.open(); @@ -643,7 +643,7 @@ maybe(' push', () => { connection: { type: 'github', personalAccessToken: token, - engine: 'isomorphic-git', + engine: '@sosuisen/isomorphic-git', }, }), push(dbB.workingDir, { @@ -651,7 +651,7 @@ maybe(' push', () => { connection: { type: 'github', personalAccessToken: token, - engine: 'isomorphic-git', + engine: '@sosuisen/isomorphic-git', }, }), ]) diff --git a/test/remote_base/combine.ts b/test/remote_base/combine.ts index 40c9d3c4..74dfa7a4 100644 --- a/test/remote_base/combine.ts +++ b/test/remote_base/combine.ts @@ -14,7 +14,7 @@ */ import fs from 'fs-extra'; -import git from 'isomorphic-git'; +import git from '@sosuisen/isomorphic-git'; import expect from 'expect'; import parse from 'parse-git-config'; import { textToJsonDoc } from '../../src/crud/blob'; diff --git a/test/remote_base/network_history.ts b/test/remote_base/network_history.ts index 6834f5b3..f00ec857 100644 --- a/test/remote_base/network_history.ts +++ b/test/remote_base/network_history.ts @@ -131,7 +131,7 @@ export const networkHistoryBase = ( }); describe(' readOldBlob()', () => { - it('skips a merge commit', async () => { + it.only('skips a merge commit', async () => { const [dbA, dbB, syncA, syncB] = await createClonedDatabases( remoteURLBase, localDir, diff --git a/test/remote_base/sync.ts b/test/remote_base/sync.ts index 17b19f1a..e67fc4e9 100644 --- a/test/remote_base/sync.ts +++ b/test/remote_base/sync.ts @@ -16,7 +16,7 @@ import crypto from 'crypto'; import fs from 'fs'; import { Octokit } from '@octokit/rest'; -import git from 'isomorphic-git'; +import git from '@sosuisen/isomorphic-git'; import expect from 'expect'; import sinon from 'sinon'; import * as RemoteEngineErr from 'git-documentdb-remote-errors'; diff --git a/test/remote_base/sync_trysync.ts b/test/remote_base/sync_trysync.ts index 4139d924..44d32319 100644 --- a/test/remote_base/sync_trysync.ts +++ b/test/remote_base/sync_trysync.ts @@ -12,7 +12,7 @@ * by using GitHub Personal Access Token * These tests create a new repository on GitHub if not exists. */ -import git from 'isomorphic-git'; +import git from '@sosuisen/isomorphic-git'; import fs from 'fs-extra'; import expect from 'expect'; import sinon from 'sinon'; diff --git a/test/remote_isomorphic_git/3way_merge.test.ts b/test/remote_isomorphic_git/3way_merge.test.ts index 698c0c9b..5b6cda92 100644 --- a/test/remote_isomorphic_git/3way_merge.test.ts +++ b/test/remote_isomorphic_git/3way_merge.test.ts @@ -54,6 +54,6 @@ const connection: ConnectionSettingsGitHub = { }; maybe( - 'isomorphic-git', + '@sosuisen/isomorphic-git', syncThreeWayMergeBase(connection, remoteURLBase, reposPrefix, localDir) ); diff --git a/test/remote_isomorphic_git/3way_merge_ot.test.ts b/test/remote_isomorphic_git/3way_merge_ot.test.ts index 75340ee7..4fb58d45 100644 --- a/test/remote_isomorphic_git/3way_merge_ot.test.ts +++ b/test/remote_isomorphic_git/3way_merge_ot.test.ts @@ -54,6 +54,6 @@ const connection: ConnectionSettingsGitHub = { }; maybe( - 'isomorphic-git', + '@sosuisen/isomorphic-git', threeWayMergeOtBase(connection, remoteURLBase, reposPrefix, localDir) ); diff --git a/test/remote_isomorphic_git/combine.test.ts b/test/remote_isomorphic_git/combine.test.ts index 6c520f78..f54bfb06 100644 --- a/test/remote_isomorphic_git/combine.test.ts +++ b/test/remote_isomorphic_git/combine.test.ts @@ -53,4 +53,7 @@ const connection: ConnectionSettingsGitHub = { personalAccessToken: token, }; -maybe('isomorphic-git', syncCombineBase(connection, remoteURLBase, reposPrefix, localDir)); +maybe( + '@sosuisen/isomorphic-git', + syncCombineBase(connection, remoteURLBase, reposPrefix, localDir) +); diff --git a/test/remote_isomorphic_git/network_git_documentdb.test.ts b/test/remote_isomorphic_git/network_git_documentdb.test.ts index 26c8d164..f284ff64 100644 --- a/test/remote_isomorphic_git/network_git_documentdb.test.ts +++ b/test/remote_isomorphic_git/network_git_documentdb.test.ts @@ -54,6 +54,6 @@ const connection: ConnectionSettingsGitHub = { }; maybe( - 'isomorphic-git', + '@sosuisen/isomorphic-git', networkGitDocumentDBBase(connection, remoteURLBase, reposPrefix, localDir) ); diff --git a/test/remote_isomorphic_git/network_history.test.ts b/test/remote_isomorphic_git/network_history.test.ts index dbf3e244..acae5476 100644 --- a/test/remote_isomorphic_git/network_history.test.ts +++ b/test/remote_isomorphic_git/network_history.test.ts @@ -54,6 +54,6 @@ const connection: ConnectionSettingsGitHub = { }; maybe( - 'isomorphic-git', + '@sosuisen/isomorphic-git', networkHistoryBase(connection, remoteURLBase, reposPrefix, localDir) ); diff --git a/test/remote_isomorphic_git/network_task_queue.test.ts b/test/remote_isomorphic_git/network_task_queue.test.ts index 333c985e..3742c27d 100644 --- a/test/remote_isomorphic_git/network_task_queue.test.ts +++ b/test/remote_isomorphic_git/network_task_queue.test.ts @@ -54,6 +54,6 @@ const connection: ConnectionSettingsGitHub = { }; maybe( - 'isomorphic-git', + '@sosuisen/isomorphic-git', networkTaskQueueBase(connection, remoteURLBase, reposPrefix, localDir) ); diff --git a/test/remote_isomorphic_git/on_sync_event.test.ts b/test/remote_isomorphic_git/on_sync_event.test.ts index 7c0d7434..1430aa1f 100644 --- a/test/remote_isomorphic_git/on_sync_event.test.ts +++ b/test/remote_isomorphic_git/on_sync_event.test.ts @@ -53,4 +53,7 @@ const connection: ConnectionSettingsGitHub = { personalAccessToken: token, }; -maybe('isomorphic-git', onSyncEventBase(connection, remoteURLBase, reposPrefix, localDir)); +maybe( + '@sosuisen/isomorphic-git', + onSyncEventBase(connection, remoteURLBase, reposPrefix, localDir) +); diff --git a/test/remote_isomorphic_git/sync.test.ts b/test/remote_isomorphic_git/sync.test.ts index 71f15233..36070f11 100644 --- a/test/remote_isomorphic_git/sync.test.ts +++ b/test/remote_isomorphic_git/sync.test.ts @@ -46,7 +46,10 @@ const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; const connection: ConnectionSettingsGitHub = { type: 'github', personalAccessToken: token, - engine: 'isomorphic-git', + engine: '@sosuisen/isomorphic-git', }; -maybe('isomorphic-git', syncBase(connection, remoteURLBase, reposPrefix, localDir, token)); +maybe( + '@sosuisen/isomorphic-git', + syncBase(connection, remoteURLBase, reposPrefix, localDir, token) +); diff --git a/test/remote_isomorphic_git/sync_clone.test.ts b/test/remote_isomorphic_git/sync_clone.test.ts index 8c38024b..9d14a675 100644 --- a/test/remote_isomorphic_git/sync_clone.test.ts +++ b/test/remote_isomorphic_git/sync_clone.test.ts @@ -53,4 +53,7 @@ const connection: ConnectionSettingsGitHub = { personalAccessToken: token, }; -maybe('isomorphic-git', syncCloneBase(connection, remoteURLBase, reposPrefix, localDir)); +maybe( + '@sosuisen/isomorphic-git', + syncCloneBase(connection, remoteURLBase, reposPrefix, localDir) +); diff --git a/test/remote_isomorphic_git/sync_events.test.ts b/test/remote_isomorphic_git/sync_events.test.ts index 57b4b8b2..5cae9832 100644 --- a/test/remote_isomorphic_git/sync_events.test.ts +++ b/test/remote_isomorphic_git/sync_events.test.ts @@ -53,4 +53,7 @@ const connection: ConnectionSettingsGitHub = { personalAccessToken: token, }; -maybe('isomorphic-git', syncEventsBase(connection, remoteURLBase, reposPrefix, localDir)); +maybe( + '@sosuisen/isomorphic-git', + syncEventsBase(connection, remoteURLBase, reposPrefix, localDir) +); diff --git a/test/remote_isomorphic_git/sync_live.test.ts b/test/remote_isomorphic_git/sync_live.test.ts index b274864f..1c15a30e 100644 --- a/test/remote_isomorphic_git/sync_live.test.ts +++ b/test/remote_isomorphic_git/sync_live.test.ts @@ -53,4 +53,7 @@ const connection: ConnectionSettingsGitHub = { personalAccessToken: token, }; -maybe('isomorphic-git', syncLiveBase(connection, remoteURLBase, reposPrefix, localDir)); +maybe( + '@sosuisen/isomorphic-git', + syncLiveBase(connection, remoteURLBase, reposPrefix, localDir) +); diff --git a/test/remote_isomorphic_git/sync_trypush.test.ts b/test/remote_isomorphic_git/sync_trypush.test.ts index c6465286..6e0fe30c 100644 --- a/test/remote_isomorphic_git/sync_trypush.test.ts +++ b/test/remote_isomorphic_git/sync_trypush.test.ts @@ -53,4 +53,7 @@ const connection: ConnectionSettingsGitHub = { personalAccessToken: token, }; -maybe('isomorphic-git', syncTryPushBase(connection, remoteURLBase, reposPrefix, localDir)); +maybe( + '@sosuisen/isomorphic-git', + syncTryPushBase(connection, remoteURLBase, reposPrefix, localDir) +); diff --git a/test/remote_isomorphic_git/sync_trysync.test.ts b/test/remote_isomorphic_git/sync_trysync.test.ts index b8a20805..cb4c3958 100644 --- a/test/remote_isomorphic_git/sync_trysync.test.ts +++ b/test/remote_isomorphic_git/sync_trysync.test.ts @@ -53,4 +53,7 @@ const connection: ConnectionSettingsGitHub = { personalAccessToken: token, }; -maybe('isomorphic-git', syncTrySyncBase(connection, remoteURLBase, reposPrefix, localDir)); +maybe( + '@sosuisen/isomorphic-git', + syncTrySyncBase(connection, remoteURLBase, reposPrefix, localDir) +); diff --git a/test/remote_utils.ts b/test/remote_utils.ts index 4f09f770..e303b209 100644 --- a/test/remote_utils.ts +++ b/test/remote_utils.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/naming-convention */ import fs from 'fs-extra'; import { Octokit } from '@octokit/rest'; -import git from 'isomorphic-git'; +import git from '@sosuisen/isomorphic-git'; import sinon from 'sinon'; import expect from 'expect'; import { textToJsonDoc } from '../src/crud/blob'; diff --git a/test/utils.ts b/test/utils.ts index 00b52445..6e6ead24 100644 --- a/test/utils.ts +++ b/test/utils.ts @@ -1,5 +1,5 @@ import path from 'path'; -import git from 'isomorphic-git'; +import git from '@sosuisen/isomorphic-git'; import fs from 'fs-extra'; import { GitDDBInterface } from '../src/types_gitddb'; From eefa7eecabdbc9ab949307ade4e9458e48c1718d Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 10 Nov 2021 23:47:07 +0900 Subject: [PATCH 208/297] fix: bump @sosuisen.isomorphic-git to 1.10.1-alpha.3 to debug push --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index cceee4ce..615c1a54 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "license": "MPL-2.0", "dependencies": { "@octokit/rest": "^18.3.5", - "@sosuisen/isomorphic-git": "^1.10.1-alpha.2", + "@sosuisen/isomorphic-git": "^1.10.1-alpha.3", "@sosuisen/jsondiffpatch": "^0.4.7", "async-lock": "^1.3.0", "cross-blob": "^2.0.0", @@ -1169,9 +1169,9 @@ } }, "node_modules/@sosuisen/isomorphic-git": { - "version": "1.10.1-alpha.2", - "resolved": "https://registry.npmjs.org/@sosuisen/isomorphic-git/-/isomorphic-git-1.10.1-alpha.2.tgz", - "integrity": "sha512-SyrIY8XOHbU6DQ6/4iACmHV/G/kmyBT68j1xt/7X5jeaEs3faVYtZam6E9SkGBqD2xe4e4y1mk2eq+NXIPbeLg==", + "version": "1.10.1-alpha.3", + "resolved": "https://registry.npmjs.org/@sosuisen/isomorphic-git/-/isomorphic-git-1.10.1-alpha.3.tgz", + "integrity": "sha512-nfwuK1l+SuLnbb4aumuG/GwpvO5IGUHdXyFMC9TxweOucOW19slDgaadSdeAPmbZc90ECZa5mTpC3AGxOMHNbA==", "dependencies": { "async-lock": "^1.1.0", "clean-git-ref": "^2.0.1", @@ -11656,9 +11656,9 @@ } }, "@sosuisen/isomorphic-git": { - "version": "1.10.1-alpha.2", - "resolved": "https://registry.npmjs.org/@sosuisen/isomorphic-git/-/isomorphic-git-1.10.1-alpha.2.tgz", - "integrity": "sha512-SyrIY8XOHbU6DQ6/4iACmHV/G/kmyBT68j1xt/7X5jeaEs3faVYtZam6E9SkGBqD2xe4e4y1mk2eq+NXIPbeLg==", + "version": "1.10.1-alpha.3", + "resolved": "https://registry.npmjs.org/@sosuisen/isomorphic-git/-/isomorphic-git-1.10.1-alpha.3.tgz", + "integrity": "sha512-nfwuK1l+SuLnbb4aumuG/GwpvO5IGUHdXyFMC9TxweOucOW19slDgaadSdeAPmbZc90ECZa5mTpC3AGxOMHNbA==", "requires": { "async-lock": "^1.1.0", "clean-git-ref": "^2.0.1", diff --git a/package.json b/package.json index 2a37882a..189b2444 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,7 @@ }, "dependencies": { "@octokit/rest": "^18.3.5", - "@sosuisen/isomorphic-git": "^1.10.1-alpha.2", + "@sosuisen/isomorphic-git": "^1.10.1-alpha.3", "@sosuisen/jsondiffpatch": "^0.4.7", "async-lock": "^1.3.0", "cross-blob": "^2.0.0", From bc0ffc479e089a6e2b74aab67aab1a39d5d243cb Mon Sep 17 00:00:00 2001 From: sosuisen Date: Thu, 11 Nov 2021 18:45:03 +0900 Subject: [PATCH 209/297] fix: bump @sosuisen/isomorphic-git to v1.10.1-alpha.5 to fix too slow push operation --- package-lock.json | 14 +++++++------- package.json | 4 ++-- test/remote_base/network_history.ts | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index 615c1a54..26a37ebe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "license": "MPL-2.0", "dependencies": { "@octokit/rest": "^18.3.5", - "@sosuisen/isomorphic-git": "^1.10.1-alpha.3", + "@sosuisen/isomorphic-git": "^1.10.1-alpha.5", "@sosuisen/jsondiffpatch": "^0.4.7", "async-lock": "^1.3.0", "cross-blob": "^2.0.0", @@ -1169,9 +1169,9 @@ } }, "node_modules/@sosuisen/isomorphic-git": { - "version": "1.10.1-alpha.3", - "resolved": "https://registry.npmjs.org/@sosuisen/isomorphic-git/-/isomorphic-git-1.10.1-alpha.3.tgz", - "integrity": "sha512-nfwuK1l+SuLnbb4aumuG/GwpvO5IGUHdXyFMC9TxweOucOW19slDgaadSdeAPmbZc90ECZa5mTpC3AGxOMHNbA==", + "version": "1.10.1-alpha.5", + "resolved": "https://registry.npmjs.org/@sosuisen/isomorphic-git/-/isomorphic-git-1.10.1-alpha.5.tgz", + "integrity": "sha512-zOyIsG7YtYSZzTM9iPI1DVqeLr7QW1a/ApuKlVwZvo9SoaGL4ItrMTu+k3b1UP+Q5kwOcL7XOX9n+SMEvq0tmQ==", "dependencies": { "async-lock": "^1.1.0", "clean-git-ref": "^2.0.1", @@ -11656,9 +11656,9 @@ } }, "@sosuisen/isomorphic-git": { - "version": "1.10.1-alpha.3", - "resolved": "https://registry.npmjs.org/@sosuisen/isomorphic-git/-/isomorphic-git-1.10.1-alpha.3.tgz", - "integrity": "sha512-nfwuK1l+SuLnbb4aumuG/GwpvO5IGUHdXyFMC9TxweOucOW19slDgaadSdeAPmbZc90ECZa5mTpC3AGxOMHNbA==", + "version": "1.10.1-alpha.5", + "resolved": "https://registry.npmjs.org/@sosuisen/isomorphic-git/-/isomorphic-git-1.10.1-alpha.5.tgz", + "integrity": "sha512-zOyIsG7YtYSZzTM9iPI1DVqeLr7QW1a/ApuKlVwZvo9SoaGL4ItrMTu+k3b1UP+Q5kwOcL7XOX9n+SMEvq0tmQ==", "requires": { "async-lock": "^1.1.0", "clean-git-ref": "^2.0.1", diff --git a/package.json b/package.json index 189b2444..df13a938 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "git-documentdb", - "version": "0.4.7-alpha.4", + "version": "0.4.7-alpha.5", "description": "Offline-first database that syncs with Git", "main": "dist/main.js", "types": "dist/main.d.ts", @@ -77,7 +77,7 @@ }, "dependencies": { "@octokit/rest": "^18.3.5", - "@sosuisen/isomorphic-git": "^1.10.1-alpha.3", + "@sosuisen/isomorphic-git": "^1.10.1-alpha.5", "@sosuisen/jsondiffpatch": "^0.4.7", "async-lock": "^1.3.0", "cross-blob": "^2.0.0", diff --git a/test/remote_base/network_history.ts b/test/remote_base/network_history.ts index f00ec857..6834f5b3 100644 --- a/test/remote_base/network_history.ts +++ b/test/remote_base/network_history.ts @@ -131,7 +131,7 @@ export const networkHistoryBase = ( }); describe(' readOldBlob()', () => { - it.only('skips a merge commit', async () => { + it('skips a merge commit', async () => { const [dbA, dbB, syncA, syncB] = await createClonedDatabases( remoteURLBase, localDir, From bb15c3c34809edf301f0495eb366f1eaf756e094 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Mon, 15 Nov 2021 16:59:21 +0900 Subject: [PATCH 210/297] test: fix title of test --- test/git_documentdb_destroy.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/git_documentdb_destroy.test.ts b/test/git_documentdb_destroy.test.ts index 7d1cab81..6041ccd2 100644 --- a/test/git_documentdb_destroy.test.ts +++ b/test/git_documentdb_destroy.test.ts @@ -34,7 +34,7 @@ after(() => { fs.removeSync(path.resolve(localDir)); }); -describe(' destroy()', () => { +describe(' destroy()', () => { it('closes and removes a database', async () => { const dbName = monoId(); From 0ddae979d9d30965583355393756bd3aacb85f0a Mon Sep 17 00:00:00 2001 From: sosuisen Date: Mon, 15 Nov 2021 16:59:55 +0900 Subject: [PATCH 211/297] test: add tests for new push cases --- test/remote_base/sync_trypush.ts | 54 ++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/test/remote_base/sync_trypush.ts b/test/remote_base/sync_trypush.ts index 66222dee..407b3f3c 100644 --- a/test/remote_base/sync_trypush.ts +++ b/test/remote_base/sync_trypush.ts @@ -28,6 +28,7 @@ import { } from '../remote_utils'; import { ConnectionSettings, + ConnectionSettingsGitHub, RemoteOptions, SyncResultCancel, SyncResultNop, @@ -527,5 +528,58 @@ export const syncTryPushBase = ( await destroyDBs([dbA, dbB]); }); + + it('pushes some commits. All commits can be cloned.', async () => { + const remoteURL = remoteURLBase + serialId(); + + const dbNameA = serialId(); + + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir, + }); + const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; + const options = { + remoteUrl: remoteURL, + connection, + includeCommits: true, + }; + await dbA.open(); + const syncA = await dbA.sync(options); + + const jsonA1 = { _id: 'A1' }; + const jsonA2 = { _id: 'A2' }; + const jsonA3 = { _id: 'A3' }; + const jsonA4 = { _id: 'A4' }; + const jsonA5 = { _id: 'A5' }; + const jsonA6 = { _id: 'A6' }; + await dbA.put(jsonA1); + await syncA.tryPush(); + + await dbA.put(jsonA2); + await dbA.put(jsonA3); + await syncA.tryPush(); + + await dbA.put(jsonA4); + await dbA.put(jsonA5); + await dbA.put(jsonA6); + await syncA.tryPush(); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir, + }); + // Clone dbA + await dbB.open(); + await dbB.sync(options); + await expect(dbB.get('A1')).resolves.toEqual(jsonA1); + await expect(dbB.get('A2')).resolves.toEqual(jsonA2); + await expect(dbB.get('A3')).resolves.toEqual(jsonA3); + await expect(dbB.get('A4')).resolves.toEqual(jsonA4); + await expect(dbB.get('A5')).resolves.toEqual(jsonA5); + await expect(dbB.get('A6')).resolves.toEqual(jsonA6); + await destroyDBs([dbA, dbB]); + }); }); }; From cb167813fa3765e06fd6e528ed635fbfcfacd69e Mon Sep 17 00:00:00 2001 From: sosuisen Date: Mon, 15 Nov 2021 17:05:24 +0900 Subject: [PATCH 212/297] fix: add logToTransport option to set transport to tslog --- src/git_documentdb.ts | 29 ++++++++++++++- src/types.ts | 9 ++++- test/git_documentdb_logger.test.ts | 58 ++++++++++++++++++++++++++++++ 3 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 test/git_documentdb_logger.test.ts diff --git a/src/git_documentdb.ts b/src/git_documentdb.ts index ae760ba4..4b727a2f 100644 --- a/src/git_documentdb.ts +++ b/src/git_documentdb.ts @@ -10,7 +10,7 @@ import path from 'path'; import git from '@sosuisen/isomorphic-git'; import fs from 'fs-extra'; import rimraf from 'rimraf'; -import { Logger, TLogLevelName } from 'tslog'; +import { ILogObject, Logger, TLogLevelName } from 'tslog'; import { ulid } from 'ulid'; import { RemoteEngine } from './remote/remote_engine'; import { Err } from './error'; @@ -220,6 +220,17 @@ export class GitDocumentDB return this._schema; } + private _logToTransport: ((logObject: ILogObject) => void) | undefined; + /** + * logToTransport function for all log levels. See https://tslog.js.org/#/?id=transports + * + * @readonly + * @public + */ + get logToTransport (): ((logObject: ILogObject) => void) | undefined { + return this._logToTransport; + } + private _taskQueue: TaskQueue; /** * Task queue @@ -287,6 +298,20 @@ export class GitDocumentDB displayFunctionName: false, displayFilePath: 'hidden', }); + if (this.logToTransport) { + this._logger.attachTransport( + { + silly: this.logToTransport, + debug: this.logToTransport, + trace: this.logToTransport, + info: this.logToTransport, + warn: this.logToTransport, + error: this.logToTransport, + fatal: this.logToTransport, + }, + level + ); + } if (this.taskQueue) this.taskQueue.setLogger(this._logger); } @@ -337,6 +362,8 @@ export class GitDocumentDB }, }; + this._logToTransport = options.logToTransport; + this._serializeFormat = options.serializeFormat ?? 'json'; // Get full-path diff --git a/src/types.ts b/src/types.ts index 7f798a90..ecf8eabe 100644 --- a/src/types.ts +++ b/src/types.ts @@ -6,7 +6,7 @@ * found in the LICENSE file in the root directory of this source tree. */ -import { TLogLevelName } from 'tslog'; +import { ILogObject, TLogLevelName } from 'tslog'; /** * Plugin types @@ -45,6 +45,12 @@ export type PluginTypes = 'db' | 'remote'; * * logLevel - Default is 'info'. * + * schema - Schema for a specific document type. + * + * serializeFormat - Format for serialization + * + * logToTransport - logToTransport function for all log levels. See https://tslog.js.org/#/?id=transports + * * @public */ export type DatabaseOptions = { @@ -53,6 +59,7 @@ export type DatabaseOptions = { logLevel?: TLogLevelName; schema?: Schema; serializeFormat?: SerializeFormat; + logToTransport?: (logObject: ILogObject) => void; }; /** diff --git a/test/git_documentdb_logger.test.ts b/test/git_documentdb_logger.test.ts new file mode 100644 index 00000000..1ed345de --- /dev/null +++ b/test/git_documentdb_logger.test.ts @@ -0,0 +1,58 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +import path from 'path'; +import fs from 'fs-extra'; +import expect from 'expect'; +import { monotonicFactory } from 'ulid'; +import { ILogObject } from 'tslog'; +import { Err } from '../src/error'; +import { GitDocumentDB } from '../src/git_documentdb'; + +const ulid = monotonicFactory(); +const monoId = () => { + return ulid(Date.now()); +}; + +const localDir = './test/database_logger'; + +beforeEach(function () { + // @ts-ignore + console.log(`... ${this.currentTest.fullTitle()}`); +}); + +before(() => { + fs.removeSync(path.resolve(localDir)); +}); + +after(() => { + fs.removeSync(path.resolve(localDir)); +}); + +describe(' logger', () => { + it('write log to a local file', async () => { + const dbName = monoId(); + const logPath = path.resolve(localDir + '/log.txt'); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + logLevel: 'silly', + logToTransport: (logObject: ILogObject) => { + fs.appendFileSync(logPath, logObject.argumentsArray[0] + '\n'); + }, + }); + await gitDDB.open(); + await gitDDB.put({ _id: 'test' }); + + const log = fs.readFileSync(logPath, 'utf-8'); + expect(log.startsWith('\u001b[43m\u001b[30mStart: put()\u001b[0m')).toBeTruthy(); + + await gitDDB.destroy(); + }); +}); From 4863360564b3452eba9fcab5e9df8690202c91d5 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Mon, 15 Nov 2021 17:17:59 +0900 Subject: [PATCH 213/297] build: bump to v0.4.7-alpha.7 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index df13a938..b2f3db57 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "git-documentdb", - "version": "0.4.7-alpha.5", + "version": "0.4.7-alpha.7", "description": "Offline-first database that syncs with Git", "main": "dist/main.js", "types": "dist/main.d.ts", From 3519cd57b8adb97cc3e6fce7cc64f5cb9bb59e51 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Mon, 15 Nov 2021 18:49:04 +0900 Subject: [PATCH 214/297] snapshot: adding ColoredLog --- src/git_documentdb.ts | 91 +++++++++++++++++++++++++++++++++++++++++-- src/remote/sync.ts | 22 ++++++----- src/task_queue.ts | 26 +++++++------ src/types.ts | 18 +++++++++ src/types_gitddb.ts | 5 ++- 5 files changed, 134 insertions(+), 28 deletions(-) diff --git a/src/git_documentdb.ts b/src/git_documentdb.ts index 4b727a2f..4ec7e755 100644 --- a/src/git_documentdb.ts +++ b/src/git_documentdb.ts @@ -19,6 +19,7 @@ import { Validator } from './validator'; import { CollectionOptions, CollectionPath, + ColoredLogger, DatabaseCloseOption, DatabaseInfo, DatabaseOpenResult, @@ -198,14 +199,96 @@ export class GitDocumentDB return this._dbOpenResult.dbId; } - private _logger!: Logger; // Use definite assignment assertion + private _tsLogger!: Logger; + + // Use definite assignment assertion + private _logger: ColoredLogger = { + silly: ( + mes: string, + colorTag?: () => (literals: TemplateStringsArray, ...placeholders: any[]) => string + ) => { + if (colorTag !== undefined) { + this._tsLogger.silly(colorTag()`${mes}`); + } + else { + this._tsLogger.silly(mes); + } + }, + debug: ( + mes: string, + colorTag?: () => (literals: TemplateStringsArray, ...placeholders: any[]) => string + ) => { + if (colorTag !== undefined) { + this._tsLogger.debug(colorTag()`${mes}`); + } + else { + this._tsLogger.debug(mes); + } + }, + trace: ( + mes: string, + colorTag?: () => (literals: TemplateStringsArray, ...placeholders: any[]) => string + ) => { + if (colorTag !== undefined) { + this._tsLogger.trace(colorTag()`${mes}`); + } + else { + this._tsLogger.trace(mes); + } + }, + info: ( + mes: string, + colorTag?: () => (literals: TemplateStringsArray, ...placeholders: any[]) => string + ) => { + if (colorTag !== undefined) { + this._tsLogger.info(colorTag()`${mes}`); + } + else { + this._tsLogger.info(mes); + } + }, + warn: ( + mes: string, + colorTag?: () => (literals: TemplateStringsArray, ...placeholders: any[]) => string + ) => { + if (colorTag !== undefined) { + this._tsLogger.warn(colorTag()`${mes}`); + } + else { + this._tsLogger.warn(mes); + } + }, + error: ( + mes: string, + colorTag?: () => (literals: TemplateStringsArray, ...placeholders: any[]) => string + ) => { + if (colorTag !== undefined) { + this._tsLogger.error(colorTag()`${mes}`); + } + else { + this._tsLogger.error(mes); + } + }, + fatal: ( + mes: string, + colorTag?: () => (literals: TemplateStringsArray, ...placeholders: any[]) => string + ) => { + if (colorTag !== undefined) { + this._tsLogger.fatal(colorTag()`${mes}`); + } + else { + this._tsLogger.fatal(mes); + } + }, + }; + /** * Get logger * * @readonly * @public */ - get logger (): Logger { + get logger (): ColoredLogger { return this._logger; } @@ -291,7 +374,7 @@ export class GitDocumentDB set logLevel (level: TLogLevelName) { this._logLevel = level; - this._logger = new Logger({ + this._tsLogger = new Logger({ name: this._dbName, minLevel: level as TLogLevelName, displayDateTime: false, @@ -299,7 +382,7 @@ export class GitDocumentDB displayFilePath: 'hidden', }); if (this.logToTransport) { - this._logger.attachTransport( + this._tsLogger.attachTransport( { silly: this.logToTransport, debug: this.logToTransport, diff --git a/src/remote/sync.ts b/src/remote/sync.ts index 1810932d..21510bbc 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -806,9 +806,8 @@ export class Sync implements SyncInterface { return pushWorker(this._gitDDB, this, taskMetadata) .then((syncResultPush: SyncResultPush | SyncResultNop) => { this._gitDDB.logger.debug( - CONSOLE_STYLE.bgWhite().fgBlack().tag()`pushWorker: ${JSON.stringify( - syncResultPush - )}` + `pushWorker: ${JSON.stringify(syncResultPush)}`, + CONSOLE_STYLE.bgWhite().fgBlack().tag ); if (syncResultPush.action === 'push') { @@ -861,7 +860,8 @@ export class Sync implements SyncInterface { const cancel = (resolve: (value: SyncResultCancel) => void) => () => { const result: SyncResultCancel = { action: 'canceled' }; this._gitDDB.logger.debug( - CONSOLE_STYLE.bgWhite().fgBlack().tag()`pushWorker: ${JSON.stringify(result)}` + `pushWorker: ${JSON.stringify(result)}`, + CONSOLE_STYLE.bgWhite().fgBlack().tag ); resolve(result); }; @@ -1022,7 +1022,8 @@ export class Sync implements SyncInterface { throw error; } this._gitDDB.logger.debug( - CONSOLE_STYLE.bgRed().tag()`...retrySync: ${this.currentRetries().toString()}` + `...retrySync: ${this.currentRetries().toString()}`, + CONSOLE_STYLE.bgRed().tag ); // eslint-disable-next-line no-await-in-loop await sleep(this._options.retryInterval!); @@ -1043,7 +1044,8 @@ export class Sync implements SyncInterface { // This line is reached when cancel() set _retrySyncCounter to 0; const cancel: SyncResultCancel = { action: 'canceled' }; this._gitDDB.logger.debug( - CONSOLE_STYLE.bgWhite().fgBlack().tag()`syncWorker: ${JSON.stringify(cancel)}` + `syncWorker: ${JSON.stringify(cancel)}`, + CONSOLE_STYLE.bgWhite().fgBlack().tag ); this._retrySyncCounter = 0; return cancel; @@ -1079,9 +1081,8 @@ export class Sync implements SyncInterface { // eslint-disable-next-line complexity .then((syncResult: SyncResult) => { this._gitDDB.logger.debug( - CONSOLE_STYLE.bgWhite().fgBlack().tag()`syncWorker: ${JSON.stringify( - syncResult - )}` + `syncWorker: ${JSON.stringify(syncResult)}`, + CONSOLE_STYLE.bgWhite().fgBlack().tag ); if ( @@ -1172,7 +1173,8 @@ export class Sync implements SyncInterface { const cancel = (resolve: (value: SyncResultCancel) => void) => () => { const result: SyncResultCancel = { action: 'canceled' }; this._gitDDB.logger.debug( - CONSOLE_STYLE.bgWhite().fgBlack().tag()`syncWorker: ${JSON.stringify(result)}` + `syncWorker: ${JSON.stringify(result)}`, + CONSOLE_STYLE.bgWhite().fgBlack().tag ); resolve(result); }; diff --git a/src/task_queue.ts b/src/task_queue.ts index 4179a4e8..341f2753 100644 --- a/src/task_queue.ts +++ b/src/task_queue.ts @@ -14,7 +14,7 @@ import { clearInterval, setInterval } from 'timers'; import { decodeTime, monotonicFactory } from 'ulid'; import { Logger } from 'tslog'; import AsyncLock from 'async-lock'; -import { Task, TaskMetadata, TaskStatistics } from './types'; +import { ColoredLogger, Task, TaskMetadata, TaskStatistics } from './types'; import { CONSOLE_STYLE, sleep } from './utils'; import { Err } from './error'; @@ -28,7 +28,7 @@ export class TaskQueue { private _ulid = monotonicFactory(); private _lock: AsyncLock | undefined = new AsyncLock(); - private _logger: Logger; + private _logger: ColoredLogger; private _taskQueue: Task[] = []; private _isTaskQueueWorking = false; @@ -61,7 +61,7 @@ export class TaskQueue { * * @public */ - constructor (logger: Logger) { + constructor (logger: ColoredLogger) { this._logger = logger; } @@ -70,7 +70,7 @@ export class TaskQueue { * * @internal */ - setLogger (logger: Logger) { + setLogger (logger: ColoredLogger) { this._logger = logger; } @@ -154,18 +154,17 @@ export class TaskQueue { task.enqueueCallback(taskMetadata); } catch (e) { this._logger.debug( - CONSOLE_STYLE.bgGreen() - .fgRed() - .tag()`Error in enqueueCallback (fullDocPath: ${ + `Error in enqueueCallback (fullDocPath: ${ task.collectionPath! + task.shortName - }) ${e}` + }) ${e}`, + CONSOLE_STYLE.bgGreen().fgRed().tag ); } } }) .catch(e => { if (e instanceof Err.ConsecutiveSyncSkippedError) { - this._logger.debug(CONSOLE_STYLE.bgGreen().fgRed().tag()`${e.message}`); + this._logger.debug(e.message, CONSOLE_STYLE.bgGreen().fgRed().tag); } else { throw e; @@ -373,18 +372,21 @@ export class TaskQueue { const syncRemoteName = this._currentTask.syncRemoteName; this._logger.debug( - CONSOLE_STYLE.bgYellow().fgBlack().tag()`Start: ${label}(${fullDocPath})` + `Start: ${label}(${fullDocPath})`, + CONSOLE_STYLE.bgYellow().fgBlack().tag ); const beforeResolve = () => { this._logger.debug( - CONSOLE_STYLE.bgGreen().fgBlack().tag()`End: ${label}(${fullDocPath})` + `End: ${label}(${fullDocPath})`, + CONSOLE_STYLE.bgGreen().fgBlack().tag ); this._statistics[label]++; }; const beforeReject = () => { this._logger.debug( - CONSOLE_STYLE.bgGreen().fgRed().tag()`End with error: ${label}(${fullDocPath})` + `End with error: ${label}(${fullDocPath})`, + CONSOLE_STYLE.bgGreen().fgRed().tag ); this._statistics[label]++; }; diff --git a/src/types.ts b/src/types.ts index ecf8eabe..c60e7a90 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1204,3 +1204,21 @@ export interface IJsonPatch { strategy?: ConflictResolutionStrategyLabels ): JsonDoc; } + +/** + * Colored log + */ +export type ColoredLog = ( + mes: string, + colorTag?: () => (literals: TemplateStringsArray, ...placeholders: any[]) => string +) => void; + +export type ColoredLogger = { + silly: ColoredLog; + debug: ColoredLog; + trace: ColoredLog; + info: ColoredLog; + warn: ColoredLog; + error: ColoredLog; + fatal: ColoredLog; +}; diff --git a/src/types_gitddb.ts b/src/types_gitddb.ts index b422e30c..8c18534e 100644 --- a/src/types_gitddb.ts +++ b/src/types_gitddb.ts @@ -6,9 +6,10 @@ * found in the LICENSE file in the root directory of this source tree. */ -import { Logger, TLogLevelName } from 'tslog'; +import { TLogLevelName } from 'tslog'; import { TaskQueue } from './task_queue'; import { + ColoredLogger, DatabaseCloseOption, DatabaseOpenResult, NormalizedCommit, @@ -37,7 +38,7 @@ export interface GitDDBInterface { isOpened: boolean; workingDir: string; dbId: string; - logger: Logger; + logger: ColoredLogger; schema: Schema; taskQueue: TaskQueue; isClosing: boolean; From eb75c05c17e66a787d28867c220941859169e659 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 16 Nov 2021 00:10:53 +0900 Subject: [PATCH 215/297] build: bump @sosuisen/isomorphic-git to v1.10.1-alpha.6 --- package-lock.json | 18 +++++++++--------- package.json | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index 26a37ebe..21d7ccee 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,16 @@ { "name": "git-documentdb", - "version": "0.4.7-alpha.4", + "version": "0.4.7-alpha.7", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "git-documentdb", - "version": "0.4.7-alpha.4", + "version": "0.4.7-alpha.7", "license": "MPL-2.0", "dependencies": { "@octokit/rest": "^18.3.5", - "@sosuisen/isomorphic-git": "^1.10.1-alpha.5", + "@sosuisen/isomorphic-git": "^1.10.1-alpha.6", "@sosuisen/jsondiffpatch": "^0.4.7", "async-lock": "^1.3.0", "cross-blob": "^2.0.0", @@ -1169,9 +1169,9 @@ } }, "node_modules/@sosuisen/isomorphic-git": { - "version": "1.10.1-alpha.5", - "resolved": "https://registry.npmjs.org/@sosuisen/isomorphic-git/-/isomorphic-git-1.10.1-alpha.5.tgz", - "integrity": "sha512-zOyIsG7YtYSZzTM9iPI1DVqeLr7QW1a/ApuKlVwZvo9SoaGL4ItrMTu+k3b1UP+Q5kwOcL7XOX9n+SMEvq0tmQ==", + "version": "1.10.1-alpha.6", + "resolved": "https://registry.npmjs.org/@sosuisen/isomorphic-git/-/isomorphic-git-1.10.1-alpha.6.tgz", + "integrity": "sha512-pVw6e6x6J3UPegoYh7mmF/V43ISRv4I0L9QPqX0sqkSBDuirmcrliLn/pMsvP8I7YLJakTfyGQLmzZuSGSAVfQ==", "dependencies": { "async-lock": "^1.1.0", "clean-git-ref": "^2.0.1", @@ -11656,9 +11656,9 @@ } }, "@sosuisen/isomorphic-git": { - "version": "1.10.1-alpha.5", - "resolved": "https://registry.npmjs.org/@sosuisen/isomorphic-git/-/isomorphic-git-1.10.1-alpha.5.tgz", - "integrity": "sha512-zOyIsG7YtYSZzTM9iPI1DVqeLr7QW1a/ApuKlVwZvo9SoaGL4ItrMTu+k3b1UP+Q5kwOcL7XOX9n+SMEvq0tmQ==", + "version": "1.10.1-alpha.6", + "resolved": "https://registry.npmjs.org/@sosuisen/isomorphic-git/-/isomorphic-git-1.10.1-alpha.6.tgz", + "integrity": "sha512-pVw6e6x6J3UPegoYh7mmF/V43ISRv4I0L9QPqX0sqkSBDuirmcrliLn/pMsvP8I7YLJakTfyGQLmzZuSGSAVfQ==", "requires": { "async-lock": "^1.1.0", "clean-git-ref": "^2.0.1", diff --git a/package.json b/package.json index b2f3db57..45d0af29 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,7 @@ }, "dependencies": { "@octokit/rest": "^18.3.5", - "@sosuisen/isomorphic-git": "^1.10.1-alpha.5", + "@sosuisen/isomorphic-git": "^1.10.1-alpha.6", "@sosuisen/jsondiffpatch": "^0.4.7", "async-lock": "^1.3.0", "cross-blob": "^2.0.0", From c1e5038e8e2182e0303f8b4648c9ca69fc1f54d0 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 16 Nov 2021 00:11:11 +0900 Subject: [PATCH 216/297] fix: add option for logColorEnabled --- src/git_documentdb.ts | 21 +++++--- src/remote/combine.ts | 2 +- src/remote/push_worker.ts | 2 +- src/remote/sync.ts | 4 +- src/remote/sync_worker.ts | 2 +- src/types.ts | 3 ++ src/types_gitddb.ts | 3 +- test/git_documentdb_logger.test.ts | 23 ++++++++ test/remote_base/sync_clone.ts | 2 +- test/remote_base/sync_live.ts | 2 +- test/task_queue.test.ts | 84 +++++++++++++++++++++++++++++- 11 files changed, 131 insertions(+), 17 deletions(-) diff --git a/src/git_documentdb.ts b/src/git_documentdb.ts index 4ec7e755..734a9698 100644 --- a/src/git_documentdb.ts +++ b/src/git_documentdb.ts @@ -200,6 +200,9 @@ export class GitDocumentDB } private _tsLogger!: Logger; + get tsLogger (): Logger { + return this._tsLogger; + } // Use definite assignment assertion private _logger: ColoredLogger = { @@ -207,7 +210,7 @@ export class GitDocumentDB mes: string, colorTag?: () => (literals: TemplateStringsArray, ...placeholders: any[]) => string ) => { - if (colorTag !== undefined) { + if (this._logColorEnabled && colorTag !== undefined) { this._tsLogger.silly(colorTag()`${mes}`); } else { @@ -218,7 +221,7 @@ export class GitDocumentDB mes: string, colorTag?: () => (literals: TemplateStringsArray, ...placeholders: any[]) => string ) => { - if (colorTag !== undefined) { + if (this._logColorEnabled && colorTag !== undefined) { this._tsLogger.debug(colorTag()`${mes}`); } else { @@ -229,7 +232,7 @@ export class GitDocumentDB mes: string, colorTag?: () => (literals: TemplateStringsArray, ...placeholders: any[]) => string ) => { - if (colorTag !== undefined) { + if (this._logColorEnabled && colorTag !== undefined) { this._tsLogger.trace(colorTag()`${mes}`); } else { @@ -240,7 +243,7 @@ export class GitDocumentDB mes: string, colorTag?: () => (literals: TemplateStringsArray, ...placeholders: any[]) => string ) => { - if (colorTag !== undefined) { + if (this._logColorEnabled && colorTag !== undefined) { this._tsLogger.info(colorTag()`${mes}`); } else { @@ -251,7 +254,7 @@ export class GitDocumentDB mes: string, colorTag?: () => (literals: TemplateStringsArray, ...placeholders: any[]) => string ) => { - if (colorTag !== undefined) { + if (this._logColorEnabled && colorTag !== undefined) { this._tsLogger.warn(colorTag()`${mes}`); } else { @@ -262,7 +265,7 @@ export class GitDocumentDB mes: string, colorTag?: () => (literals: TemplateStringsArray, ...placeholders: any[]) => string ) => { - if (colorTag !== undefined) { + if (this._logColorEnabled && colorTag !== undefined) { this._tsLogger.error(colorTag()`${mes}`); } else { @@ -273,7 +276,7 @@ export class GitDocumentDB mes: string, colorTag?: () => (literals: TemplateStringsArray, ...placeholders: any[]) => string ) => { - if (colorTag !== undefined) { + if (this._logColorEnabled && colorTag !== undefined) { this._tsLogger.fatal(colorTag()`${mes}`); } else { @@ -358,6 +361,8 @@ export class GitDocumentDB return this._rootCollection as ICollection; } + private _logColorEnabled: boolean; + /*********************************************** * Public properties ***********************************************/ @@ -473,6 +478,8 @@ export class GitDocumentDB // Set logLevel after initializing taskQueue. this.logLevel = options.logLevel ?? DEFAULT_LOG_LEVEL; + this._logColorEnabled = options.logColorEnabled ?? true; + const collectionOptions = { namePrefix: options?.namePrefix ?? '', debounceTime: options?.debounceTime ?? -1, diff --git a/src/remote/combine.ts b/src/remote/combine.ts index 0ac25dff..ad4afbfb 100644 --- a/src/remote/combine.ts +++ b/src/remote/combine.ts @@ -65,7 +65,7 @@ export async function combineDatabaseWithTheirs ( const duplicates: DuplicatedFile[] = []; try { await RemoteEngine[remoteOptions.connection!.engine!] - .clone(remoteDir, remoteOptions, remoteName, gitDDB.logger) + .clone(remoteDir, remoteOptions, remoteName, gitDDB.tsLogger) .catch(err => { throw wrappingRemoteEngineError(err); }); diff --git a/src/remote/push_worker.ts b/src/remote/push_worker.ts index f3ddb84b..70bf5b12 100644 --- a/src/remote/push_worker.ts +++ b/src/remote/push_worker.ts @@ -132,7 +132,7 @@ export async function pushWorker ( sync.remoteName, gitDDB.defaultBranch, gitDDB.defaultBranch, - gitDDB.logger + gitDDB.tsLogger ) .catch(err => err); diff --git a/src/remote/sync.ts b/src/remote/sync.ts index 21510bbc..eb22745f 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -490,7 +490,7 @@ export class Sync implements SyncInterface { this._gitDDB.workingDir, this._options, this.remoteName, - this._gitDDB.logger + this._gitDDB.tsLogger ) .catch(err => err); } @@ -505,7 +505,7 @@ export class Sync implements SyncInterface { this.remoteName, this._gitDDB.defaultBranch, this._gitDDB.defaultBranch, - this._gitDDB.logger + this._gitDDB.tsLogger ) .catch(err => err); } diff --git a/src/remote/sync_worker.ts b/src/remote/sync_worker.ts index 39daabfb..5b869d6e 100644 --- a/src/remote/sync_worker.ts +++ b/src/remote/sync_worker.ts @@ -92,7 +92,7 @@ export async function syncWorker ( sync.remoteName, gitDDB.defaultBranch, gitDDB.defaultBranch, - gitDDB.logger + gitDDB.tsLogger ) .catch(err => { throw wrappingRemoteEngineError(err); diff --git a/src/types.ts b/src/types.ts index c60e7a90..b46b7c0d 100644 --- a/src/types.ts +++ b/src/types.ts @@ -51,6 +51,8 @@ export type PluginTypes = 'db' | 'remote'; * * logToTransport - logToTransport function for all log levels. See https://tslog.js.org/#/?id=transports * + * logColorEnabled - Enable color for console log. Default is true. When you write log into a file by logToTransport, false is recommended. + * * @public */ export type DatabaseOptions = { @@ -60,6 +62,7 @@ export type DatabaseOptions = { schema?: Schema; serializeFormat?: SerializeFormat; logToTransport?: (logObject: ILogObject) => void; + logColorEnabled?: boolean; }; /** diff --git a/src/types_gitddb.ts b/src/types_gitddb.ts index 8c18534e..03187651 100644 --- a/src/types_gitddb.ts +++ b/src/types_gitddb.ts @@ -6,7 +6,7 @@ * found in the LICENSE file in the root directory of this source tree. */ -import { TLogLevelName } from 'tslog'; +import { Logger, TLogLevelName } from 'tslog'; import { TaskQueue } from './task_queue'; import { ColoredLogger, @@ -38,6 +38,7 @@ export interface GitDDBInterface { isOpened: boolean; workingDir: string; dbId: string; + tsLogger: Logger; logger: ColoredLogger; schema: Schema; taskQueue: TaskQueue; diff --git a/test/git_documentdb_logger.test.ts b/test/git_documentdb_logger.test.ts index 1ed345de..c5a40cb3 100644 --- a/test/git_documentdb_logger.test.ts +++ b/test/git_documentdb_logger.test.ts @@ -53,6 +53,29 @@ describe(' logger', () => { const log = fs.readFileSync(logPath, 'utf-8'); expect(log.startsWith('\u001b[43m\u001b[30mStart: put()\u001b[0m')).toBeTruthy(); + fs.removeSync(logPath); + await gitDDB.destroy(); + }); + + it('write log to a local file without color style', async () => { + const dbName = monoId(); + const logPath = path.resolve(localDir + '/log.txt'); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + logLevel: 'silly', + logToTransport: (logObject: ILogObject) => { + fs.appendFileSync(logPath, logObject.argumentsArray[0] + '\n'); + }, + logColorEnabled: false, + }); + await gitDDB.open(); + await gitDDB.put({ _id: 'test' }); + + const log = fs.readFileSync(logPath, 'utf-8'); + expect(log.startsWith('Start: put()')).toBeTruthy(); + + fs.removeSync(logPath); await gitDDB.destroy(); }); }); diff --git a/test/remote_base/sync_clone.ts b/test/remote_base/sync_clone.ts index 39cd0c09..2e43c689 100644 --- a/test/remote_base/sync_clone.ts +++ b/test/remote_base/sync_clone.ts @@ -49,7 +49,7 @@ export const syncCloneBase = ( workingDir, syncA.options, 'origin', - dbA.logger + dbA.tsLogger ); const dbB = new GitDocumentDB({ localDir, dbName: dbNameB }); diff --git a/test/remote_base/sync_live.ts b/test/remote_base/sync_live.ts index d6157ab2..e8663310 100644 --- a/test/remote_base/sync_live.ts +++ b/test/remote_base/sync_live.ts @@ -119,6 +119,7 @@ export const syncLiveBase = ( const dbA: GitDocumentDB = new GitDocumentDB({ dbName: dbNameA, localDir: localDir, + logLevel: 'silly', }); const interval = MINIMUM_SYNC_INTERVAL; const options: RemoteOptions = { @@ -130,7 +131,6 @@ export const syncLiveBase = ( }; await dbA.open(); const syncA = await dbA.sync(options); - expect(syncA.options.live).toBeTruthy(); const count = dbA.taskQueue.currentStatistics().sync; expect(syncA.pause()).toBeTruthy(); diff --git a/test/task_queue.test.ts b/test/task_queue.test.ts index 4227b4b3..56417392 100644 --- a/test/task_queue.test.ts +++ b/test/task_queue.test.ts @@ -15,7 +15,7 @@ import { Logger } from 'tslog'; import { GitDocumentDB } from '../src/git_documentdb'; import { sleep } from '../src/utils'; import { TaskQueue } from '../src/task_queue'; -import { TaskMetadata } from '../src/types'; +import { ColoredLogger, TaskMetadata } from '../src/types'; import { Err } from '../src/error'; const ulid = monotonicFactory(); @@ -25,7 +25,7 @@ const monoId = () => { const localDir = './test/database_task_queue'; -const logger = new Logger({ +const tsLogger = new Logger({ name: monoId(), minLevel: 'info', displayDateTime: false, @@ -33,6 +33,86 @@ const logger = new Logger({ displayFilePath: 'hidden', }); +const logger: ColoredLogger = { + silly: ( + mes: string, + colorTag?: () => (literals: TemplateStringsArray, ...placeholders: any[]) => string + ) => { + if (colorTag !== undefined) { + tsLogger.silly(colorTag()`${mes}`); + } + else { + tsLogger.silly(mes); + } + }, + debug: ( + mes: string, + colorTag?: () => (literals: TemplateStringsArray, ...placeholders: any[]) => string + ) => { + if (colorTag !== undefined) { + tsLogger.debug(colorTag()`${mes}`); + } + else { + tsLogger.debug(mes); + } + }, + trace: ( + mes: string, + colorTag?: () => (literals: TemplateStringsArray, ...placeholders: any[]) => string + ) => { + if (colorTag !== undefined) { + tsLogger.trace(colorTag()`${mes}`); + } + else { + tsLogger.trace(mes); + } + }, + info: ( + mes: string, + colorTag?: () => (literals: TemplateStringsArray, ...placeholders: any[]) => string + ) => { + if (colorTag !== undefined) { + tsLogger.info(colorTag()`${mes}`); + } + else { + tsLogger.info(mes); + } + }, + warn: ( + mes: string, + colorTag?: () => (literals: TemplateStringsArray, ...placeholders: any[]) => string + ) => { + if (colorTag !== undefined) { + tsLogger.warn(colorTag()`${mes}`); + } + else { + tsLogger.warn(mes); + } + }, + error: ( + mes: string, + colorTag?: () => (literals: TemplateStringsArray, ...placeholders: any[]) => string + ) => { + if (colorTag !== undefined) { + tsLogger.error(colorTag()`${mes}`); + } + else { + tsLogger.error(mes); + } + }, + fatal: ( + mes: string, + colorTag?: () => (literals: TemplateStringsArray, ...placeholders: any[]) => string + ) => { + if (colorTag !== undefined) { + tsLogger.fatal(colorTag()`${mes}`); + } + else { + tsLogger.fatal(mes); + } + }, +}; + beforeEach(function () { // @ts-ignore console.log(`... ${this.currentTest.fullTitle()}`); From f13db07d51a97bc02f808a4450b67dd9145840ae Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 16 Nov 2021 08:51:42 +0900 Subject: [PATCH 217/297] build: bump to v0.4.7-alpha.8 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 45d0af29..517f57fc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "git-documentdb", - "version": "0.4.7-alpha.7", + "version": "0.4.7-alpha.8", "description": "Offline-first database that syncs with Git", "main": "dist/main.js", "types": "dist/main.d.ts", From 7a13d8cdb9295d0b00caed388953fc98fdc9e597 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 16 Nov 2021 15:22:22 +0900 Subject: [PATCH 218/297] fix: add debug log for task queue --- src/task_queue.ts | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/task_queue.ts b/src/task_queue.ts index 341f2753..21a79b68 100644 --- a/src/task_queue.ts +++ b/src/task_queue.ts @@ -116,6 +116,11 @@ export class TaskQueue { this._lock! // eslint-disable-next-line complexity .acquire('TaskQueue', () => { // Skip consecutive sync/push events + this._logger.debug( + `Try to push ${task.label}@${task.taskId} into ${JSON.stringify( + this._taskQueue + )}` + ); if ( (this._taskQueue.length === 0 && this._currentTask?.syncRemoteName === task.syncRemoteName && @@ -372,20 +377,20 @@ export class TaskQueue { const syncRemoteName = this._currentTask.syncRemoteName; this._logger.debug( - `Start: ${label}(${fullDocPath})`, + `Start: ${label}(${fullDocPath})@${taskId}`, CONSOLE_STYLE.bgYellow().fgBlack().tag ); const beforeResolve = () => { this._logger.debug( - `End: ${label}(${fullDocPath})`, + `End: ${label}(${fullDocPath})@${taskId}`, CONSOLE_STYLE.bgGreen().fgBlack().tag ); this._statistics[label]++; }; const beforeReject = () => { this._logger.debug( - `End with error: ${label}(${fullDocPath})`, + `End with error: ${label}(${fullDocPath})@${taskId}`, CONSOLE_STYLE.bgGreen().fgRed().tag ); this._statistics[label]++; @@ -401,6 +406,9 @@ export class TaskQueue { }; this._currentTask.func(beforeResolve, beforeReject, taskMetadata).finally(() => { + this._logger.debug( + `Clear currentTask: ${this._currentTask?.label}@${this._currentTask?.taskId}` + ); this._isTaskQueueWorking = false; this._currentTask = undefined; }); From 3d98b2b8ba93dcfcf6547e7f1f053336036bb52c Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 16 Nov 2021 15:25:46 +0900 Subject: [PATCH 219/297] build: bump t v0.4.7-alpha.9 --- package.json | 2 +- src/task_queue.ts | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 517f57fc..18d5ffce 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "git-documentdb", - "version": "0.4.7-alpha.8", + "version": "0.4.7-alpha.9", "description": "Offline-first database that syncs with Git", "main": "dist/main.js", "types": "dist/main.d.ts", diff --git a/src/task_queue.ts b/src/task_queue.ts index 21a79b68..3a57e30e 100644 --- a/src/task_queue.ts +++ b/src/task_queue.ts @@ -117,9 +117,7 @@ export class TaskQueue { .acquire('TaskQueue', () => { // Skip consecutive sync/push events this._logger.debug( - `Try to push ${task.label}@${task.taskId} into ${JSON.stringify( - this._taskQueue - )}` + `Try to push ${task.label}@${task.taskId} into ${JSON.stringify(this._taskQueue)}` ); if ( (this._taskQueue.length === 0 && From 88596e55f474fba0d45f01917e5ffde12f42cc27 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Thu, 18 Nov 2021 00:34:56 +0900 Subject: [PATCH 220/297] test: add test for putFatDoc and getFatDoc for text files --- test/crud/get.test.ts | 39 +++++++++++++++++++++++++++++++++++++++ test/crud/put.test.ts | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) diff --git a/test/crud/get.test.ts b/test/crud/get.test.ts index e4e24e72..1fc7b892 100644 --- a/test/crud/get.test.ts +++ b/test/crud/get.test.ts @@ -870,6 +870,45 @@ describe(' getImpl()', () => { }); }); + describe(' get FatTextDoc', () => { + it('get text from .md without front-matter option', async () => { + const dbName = monoId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + }); + await gitDDB.open(); + const txt = 'Hello, world!'; + const fullDocPath = 'foo.md'; + await gitDDB.putFatDoc(fullDocPath, txt); + const fatDoc = await gitDDB.getFatDoc(fullDocPath); + expect(fatDoc?.doc).toBe(txt); + await gitDDB.close(); + await gitDDB.destroy(); + }); + + it('get YAML from .yml without front-matter option', async () => { + const dbName = monoId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + }); + await gitDDB.open(); + const yaml = ` +_id: foo +a: aaa +b: bbb +`; + const fullDocPath = 'foo.yml'; + await gitDDB.putFatDoc(fullDocPath, yaml); + const fatDoc = await gitDDB.getFatDoc(fullDocPath); + expect(fatDoc?.doc).toBe(yaml); + + await gitDDB.close(); + await gitDDB.destroy(); + }); + }); + describe('Front-Matter + Markdown', () => { it('returns latest JsonDoc under deep collectionPath', async () => { const dbName = monoId(); diff --git a/test/crud/put.test.ts b/test/crud/put.test.ts index 518df918..ee39a579 100644 --- a/test/crud/put.test.ts +++ b/test/crud/put.test.ts @@ -506,6 +506,44 @@ describe(' put', () => { }); }); +describe(' put FatTextDoc', () => { + it('write text into .md without front-matter option', async () => { + const dbName = monoId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + }); + await gitDDB.open(); + const txt = 'Hello, world!'; + const fullDocPath = 'foo.md'; + await gitDDB.putFatDoc(fullDocPath, txt); + expect(readFileSync(path.resolve(gitDDB.workingDir, fullDocPath), 'utf8')).toBe(txt); + + await gitDDB.close(); + await gitDDB.destroy(); + }); + + it('write YAML into .yml without front-matter option', async () => { + const dbName = monoId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + }); + await gitDDB.open(); + const yaml = ` +_id: foo +a: aaa +b: bbb +`; + const fullDocPath = 'foo.yml'; + await gitDDB.putFatDoc(fullDocPath, yaml); + expect(readFileSync(path.resolve(gitDDB.workingDir, fullDocPath), 'utf8')).toBe(yaml); + + await gitDDB.close(); + await gitDDB.destroy(); + }); +}); + describe(' put to front matter', () => { it('write sorted front matter with markdown', async () => { const dbName = monoId(); From 0f8d494635a656d3282f1b58faaf49b267d27e39 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Thu, 18 Nov 2021 11:32:48 +0900 Subject: [PATCH 221/297] snapshot: adding SerializeFormatJSON/SerializeFormatFrontMatter --- src/const.ts | 4 ++++ src/git_documentdb.ts | 6 ++++++ src/serialize_format.ts | 34 ++++++++++++++++++++++++++++++++++ src/types.ts | 13 ++++++++++++- src/utils.ts | 7 +++++++ test/crud/put.test.ts | 4 +--- 6 files changed, 64 insertions(+), 4 deletions(-) create mode 100644 src/serialize_format.ts diff --git a/src/const.ts b/src/const.ts index 66a0fc6d..0975644e 100644 --- a/src/const.ts +++ b/src/const.ts @@ -67,6 +67,10 @@ export const JSON_POSTFIX = '.json'; * @public */ export const FRONT_MATTER_POSTFIX = '.md'; +/** + * @public + */ +export const YAML_POSTFIX = '.yml'; /** * @public */ diff --git a/src/git_documentdb.ts b/src/git_documentdb.ts index 734a9698..15d6a6e0 100644 --- a/src/git_documentdb.ts +++ b/src/git_documentdb.ts @@ -63,6 +63,7 @@ import { GIT_DOCUMENTDB_INFO_ID, JSON_POSTFIX, SET_DATABASE_ID_MESSAGE, + YAML_POSTFIX, } from './const'; import { normalizeCommit, sleep, toSortedJSONString } from './utils'; import { SyncEventInterface, SyncInterface } from './types_sync'; @@ -146,6 +147,11 @@ export class GitDocumentDB return this._jsonExt; } + private _jsonExtAnother = YAML_POSTFIX; + get jsonExtAnother (): string { + return this._jsonExtAnother; + } + /** * Default Git branch * diff --git a/src/serialize_format.ts b/src/serialize_format.ts new file mode 100644 index 00000000..8dd0f1a2 --- /dev/null +++ b/src/serialize_format.ts @@ -0,0 +1,34 @@ +import { JsonDoc, SerializeFormat, SerializeFormatLabel } from './types'; + +export class SerializeFormatJSON implements SerializeFormat { + format: SerializeFormatLabel = 'json'; + extForObj = '.json'; + match (filePath: string): boolean { + return true; + } + + removeExt (filePath: string): string { + return filePath; + } + + serialize (doc: JsonDoc): string { + return ''; + } +} + +export class SerializeFormatFrontMatter implements SerializeFormat { + format: SerializeFormatLabel = 'json'; + extForObj = '.yml'; + extForText = '.md'; + match (filePath: string): boolean { + return true; + } + + removeExt (filePath: string): string { + return filePath; + } + + serialize (doc: JsonDoc): string { + return ''; + } +} diff --git a/src/types.ts b/src/types.ts index b46b7c0d..6cf65bdd 100644 --- a/src/types.ts +++ b/src/types.ts @@ -304,7 +304,18 @@ export type FatDoc = FatJsonDoc | FatTextDoc | FatBinaryDoc; /** * Format for serialization */ -export type SerializeFormat = 'json' | 'front-matter'; +export type SerializeFormatLabel = 'json' | 'front-matter'; + +/** + * Interface for serialize format classes + */ +export interface SerializeFormat { + format: SerializeFormatLabel; + extForObj: string; + match: (name: string) => boolean; + removeExt: (name: string) => string; + serialize: (doc: JsonDoc) => string; +} /** * CollectionPath diff --git a/src/utils.ts b/src/utils.ts index 14c4f8de..2831043d 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -83,7 +83,14 @@ export function toSortedJSONString (obj: Record) { ); } +export function toYAML (obj: Record) { + return yaml.dump(obj, { sortKeys: true }); +} + export function toFrontMatterMarkdown (obj: Record) { + if (obj._body === undefined) { + return toYAML(obj); + } const body = typeof obj._body === 'string' ? obj._body : ''; const clone = JSON.parse(JSON.stringify(obj)); delete clone._body; diff --git a/test/crud/put.test.ts b/test/crud/put.test.ts index ee39a579..fe02b36d 100644 --- a/test/crud/put.test.ts +++ b/test/crud/put.test.ts @@ -653,10 +653,8 @@ a: 春はあけぼの _id: 'foo', a: 'bar', }); - const result = `--- -_id: foo + const result = `_id: foo a: bar ---- `; const fullDocPath = 'foo.md'; expect(readFileSync(path.resolve(gitDDB.workingDir, fullDocPath), 'utf8')).toBe(result); From 7e17cb6eae05b75e767fd75b70b0bfbba7e8f8eb Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 19 Nov 2021 01:54:44 +0900 Subject: [PATCH 222/297] snapshot: use SerializeFormat in collection.ts --- src/collection.ts | 224 ++++++++++++++++++++++++++++------------ src/crud/blob.ts | 27 +++-- src/crud/find.ts | 16 +-- src/crud/get.ts | 17 ++- src/crud/history.ts | 25 +++-- src/serialize_format.ts | 59 ++++++++--- src/types.ts | 10 +- src/types_gitddb.ts | 4 +- src/utils.ts | 10 -- 9 files changed, 270 insertions(+), 122 deletions(-) diff --git a/src/collection.ts b/src/collection.ts index b520eee2..9bc3b48c 100644 --- a/src/collection.ts +++ b/src/collection.ts @@ -36,7 +36,6 @@ import { } from './types'; import { GitDDBInterface } from './types_gitddb'; import { Validator } from './validator'; -import { serializeJSON } from './utils'; import { GIT_DOCUMENTDB_METADATA_DIR } from './const'; import { getImpl } from './crud/get'; import { getHistoryImpl } from './crud/history'; @@ -52,7 +51,7 @@ import { ICollection } from './types_collection'; * @remarks * In a collection API, shortId (shortName) is used instead of _id (name). * - * - shortId is a file path whose collectionPath and jsonExt extension are omitted. (_id = collectionPath + shortId) + * - shortId is a file path whose collectionPath and extension are omitted. (_id = collectionPath + shortId) * * - shortName is a file path whose collectionPath is omitted. (name = collectionPath + shortName) * @@ -238,10 +237,10 @@ export class Collection implements ICollection { /** * Insert a JSON document if not exists. Otherwise, update it. * - * @param jsonDoc - JsonDoc whose _id is shortId. shortId is a file path whose collectionPath and ${jsonExt} extension are omitted. + * @param jsonDoc - JsonDoc whose _id is shortId. shortId is a file path whose collectionPath and extension are omitted. * * @remarks - * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}${jsonDoc._id}${jsonExt}`. + * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}${jsonDoc._id}${extension}`. * * - If _id is undefined, it is automatically generated. * @@ -267,10 +266,10 @@ export class Collection implements ICollection { /** * Insert a JSON document if not exists. Otherwise, update it. * - * @param shortId - shortId is a file path whose collectionPath and ${jsonExt} extension are omitted. + * @param shortId - shortId is a file path whose collectionPath and extension are omitted. * * @remarks - * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortId}${jsonExt}`. + * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortId}${extension}`. * * - If shortId is undefined, it is automatically generated. * @@ -320,7 +319,6 @@ export class Collection implements ICollection { ): Promise { let shortId: string; let _id: string; - let shortName: string; let jsonDoc: JsonDoc; // Resolve overloads @@ -332,14 +330,12 @@ export class Collection implements ICollection { if (!shortIdOrDoc) shortIdOrDoc = this.generateId(); shortId = shortIdOrDoc; _id = this.collectionPath + shortId; - shortName = shortId + this._gitDDB.jsonExt; jsonDoc = jsonDocOrOptions as JsonDoc; } else { if (!shortIdOrDoc._id) shortIdOrDoc._id = this.generateId(); shortId = shortIdOrDoc._id; _id = this.collectionPath + shortId; - shortName = shortId + this._gitDDB.jsonExt; jsonDoc = shortIdOrDoc as JsonDoc; options = jsonDocOrOptions as PutOptions; } @@ -352,7 +348,8 @@ export class Collection implements ICollection { return Promise.reject(new Err.InvalidJsonObjectError(shortId)); } clone._id = _id; - const data = serializeJSON(clone, this._gitDDB.jsonExt); + const { extension, data } = this._gitDDB.serializeFormat.serialize(clone); + const shortName = shortId + extension; try { this._gitDDB.validator.validateId(shortId); this._gitDDB.validator.validateDocument(clone); @@ -386,14 +383,14 @@ export class Collection implements ICollection { /** * Insert a JSON document * - * @param jsonDoc - JsonDoc whose _id is shortId. shortId is a file path whose collectionPath and ${jsonExt} extension are omitted. + * @param jsonDoc - JsonDoc whose _id is shortId. shortId is a file path whose collectionPath and extension are omitted. * * @remarks * - Throws SameIdExistsError when a document that has the same _id exists. It might be better to use put() instead of insert(). * * - If _id is undefined, it is automatically generated. * - * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${jsonDoc._id}${jsonExt}`. + * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${jsonDoc._id}${extension}`. * * @param jsonDoc - See {@link JsonDoc} for restriction. * @@ -423,12 +420,12 @@ export class Collection implements ICollection { /** * Insert a JSON document * - * @param shortId - shortId is a file path whose collectionPath and ${jsonExt} extension are omitted. + * @param shortId - shortId is a file path whose collectionPath and extension are omitted. * * @remarks * - Throws SameIdExistsError when a document that has the same _id exists. It might be better to use put() instead of insert(). * - * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortId}${jsonExt}`. + * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortId}${extension}`. * * - If shortId is undefined, it is automatically generated. * @@ -499,12 +496,12 @@ export class Collection implements ICollection { /** * Update a JSON document * - * @param jsonDoc - JsonDoc whose _id is shortId. shortId is a file path whose collectionPath and ${jsonExt} extension are omitted. + * @param jsonDoc - JsonDoc whose _id is shortId. shortId is a file path whose collectionPath and extension are omitted. * * @remarks * - Throws DocumentNotFoundError if a specified document does not exist. It might be better to use put() instead of update(). * - * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${jsonDoc._id}${jsonExt}`. + * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${jsonDoc._id}${extension}`. * * - If _id is undefined, it is automatically generated. * @@ -534,12 +531,12 @@ export class Collection implements ICollection { /** * Update a JSON document * - * @param shortId - shortId is a file path whose collectionPath and ${jsonExt} extension are omitted. + * @param shortId - shortId is a file path whose collectionPath and extension are omitted. * * @remarks * - Throws DocumentNotFoundError if a specified data does not exist. It might be better to use put() instead of update(). * - * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortId}${jsonExt}`. + * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortId}${extension}`. * * - An update operation is not skipped even if no change occurred on a specified data. * @@ -608,14 +605,14 @@ export class Collection implements ICollection { /** * Insert data if not exists. Otherwise, update it. * - * @param shortName - shortName is a file path whose collectionPath is omitted. shortName of JsonDoc must ends with ${jsonExt} extension. + * @param shortName - shortName is a file path whose collectionPath is omitted. shortName of JsonDoc must ends with extension. * * @remarks - * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortName}${jsonExt}`. + * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortName}${extension}`. * * - If shortName is undefined, it is automatically generated. * - * - _id property of a JsonDoc is automatically set or overwritten by shortName parameter whose ${jsonExt} extension is omitted. + * - _id property of a JsonDoc is automatically set or overwritten by shortName parameter whose extension is omitted. * * - An update operation is not skipped even if no change occurred on a specified data. * @@ -659,13 +656,14 @@ export class Collection implements ICollection { data = doc; } else if (typeof doc === 'object') { - if (!shortName) shortName = this.generateId() + this._gitDDB.jsonExt; + const extension = this._gitDDB.serializeFormat.extension(doc); + if (!shortName) shortName = this.generateId() + extension; docType = 'json'; // JsonDoc - if (!shortName.endsWith(this._gitDDB.jsonExt)) { + if (!shortName.endsWith(extension)) { return Promise.reject(new Err.InvalidJsonFileExtensionError()); } - shortId = shortName.replace(new RegExp(this._gitDDB.jsonExt + '$'), ''); + shortId = shortName.replace(new RegExp(extension + '$'), ''); // Validate JSON let clone; @@ -675,7 +673,8 @@ export class Collection implements ICollection { return Promise.reject(new Err.InvalidJsonObjectError(shortId)); } clone._id = this.collectionPath + shortId; - data = serializeJSON(clone, this._gitDDB.jsonExt); + data = this._gitDDB.serializeFormat.serialize(clone).data; + try { this._gitDDB.validator.validateDocument(clone); } catch (err) { @@ -734,16 +733,16 @@ export class Collection implements ICollection { /** * Insert a data * - * @param shortName - shortName is a file path whose collectionPath is omitted. shortName of JsonDoc must ends with ${jsonExt} extension. + * @param shortName - shortName is a file path whose collectionPath is omitted. shortName of JsonDoc must ends with extension. * * @remarks * - Throws SameIdExistsError when data that has the same _id exists. It might be better to use put() instead of insert(). * - * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortName}${jsonExt}`. + * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortName}${extension}`. * * - If shortName is undefined, it is automatically generated. * - * - _id property of a JsonDoc is automatically set or overwritten by shortName parameter whose ${jsonExt} extension is omitted. + * - _id property of a JsonDoc is automatically set or overwritten by shortName parameter whose extension is omitted. * * @throws {@link Err.InvalidJsonObjectError} * @@ -782,14 +781,14 @@ export class Collection implements ICollection { /** * Update a data * - * @param shortName - shortName is a file path whose collectionPath is omitted. shortName of JsonDoc must ends with ${jsonExt} extension. + * @param shortName - shortName is a file path whose collectionPath is omitted. shortName of JsonDoc must ends with extension. * * @remarks * - Throws DocumentNotFoundError if a specified data does not exist. It might be better to use put() instead of update(). * - * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortName}${jsonExt}`. + * - The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortName}${extension}`. * - * - _id property of a JsonDoc is automatically set or overwritten by shortName parameter whose ${jsonExt} extension is omitted. + * - _id property of a JsonDoc is automatically set or overwritten by shortName parameter whose extension is omitted. * * - An update operation is not skipped even if no change occurred on a specified data. * @@ -830,7 +829,7 @@ export class Collection implements ICollection { /** * Get a JSON document * - * @param shortId - shortId is a file path whose collectionPath and ${jsonExt} extension are omitted. + * @param shortId - shortId is a file path whose collectionPath and extension are omitted. * * @returns * - undefined if a specified document does not exist. @@ -843,10 +842,31 @@ export class Collection implements ICollection { * @public */ get (_id: string): Promise { - const shortName = _id + this._gitDDB.jsonExt; - return getImpl(this._gitDDB, shortName, this.collectionPath, this._gitDDB.jsonExt, { - forceDocType: 'json', - }) as Promise; + const shortName = _id + this._gitDDB.serializeFormat.firstExtension; + const result = getImpl( + this._gitDDB, + shortName, + this.collectionPath, + this._gitDDB.serializeFormat, + { + forceDocType: 'json', + } + ) as Promise; + if ( + result === undefined && + this._gitDDB.serializeFormat.secondExtension !== undefined + ) { + return getImpl( + this._gitDDB, + shortName, + this.collectionPath, + this._gitDDB.serializeFormat, + { + forceDocType: 'json', + } + ) as Promise; + } + return result; } /** @@ -857,7 +877,7 @@ export class Collection implements ICollection { * @returns * - undefined if a specified data does not exist. * - * - FatJsonDoc if the file extension is jsonExt. Be careful that JsonDoc may not have _id property when an app other than GitDocumentDB creates it. + * - FatJsonDoc if the file extension is SerializeFormat.extension. Be careful that JsonDoc may not have _id property when an app other than GitDocumentDB creates it. * * - FatBinaryDoc if described in .gitattribtues, otherwise FatTextDoc. * @@ -869,16 +889,32 @@ export class Collection implements ICollection { * @public */ getFatDoc (shortName: string, getOptions?: GetOptions): Promise { - return getImpl( + const result = getImpl( this._gitDDB, shortName, this.collectionPath, - this._gitDDB.jsonExt, + this._gitDDB.serializeFormat, getOptions, { withMetadata: true, } ) as Promise; + if ( + result === undefined && + this._gitDDB.serializeFormat.secondExtension !== undefined + ) { + return getImpl( + this._gitDDB, + shortName, + this.collectionPath, + this._gitDDB.serializeFormat, + getOptions, + { + withMetadata: true, + } + ) as Promise; + } + return result; } /** @@ -894,12 +930,12 @@ export class Collection implements ICollection { * * @public */ - getDocByOid (fileOid: string, docType: DocType = 'binary'): Promise { + getDocByOid (fileOid: string, docType: DocType = 'text'): Promise { return getImpl( this._gitDDB, '', this.collectionPath, - this._gitDDB.jsonExt, + this._gitDDB.serializeFormat, { forceDocType: docType }, { withMetadata: false, @@ -911,7 +947,7 @@ export class Collection implements ICollection { /** * Get an old revision of a JSON document * - * @param shortId - shortId is a file path whose collectionPath and ${jsonExt} extension are omitted. + * @param shortId - shortId is a file path whose collectionPath and extension are omitted. * @param revision - Specify a number to go back to old revision. Default is 0. * See {@link git-documentdb#Collection.getHistory} for the array of revisions. * @param historyOptions - The array of revisions is filtered by HistoryOptions.filter. @@ -919,6 +955,8 @@ export class Collection implements ICollection { * @remarks * - undefined if a specified document does not exist or it is deleted. * + * - If serializeFormat is front-matter, this function can't correctly distinguish files that has the same _id but different extension. Use getFatDocOldRevision() instead. e.g.) foo.md and foo.yml + * * @example * ``` * collection.getOldRevision(_shortId, 0); // returns the latest document. @@ -935,12 +973,12 @@ export class Collection implements ICollection { revision: number, historyOptions?: HistoryOptions ): Promise { - const shortName = shortId + this._gitDDB.jsonExt; - return getImpl( + let shortName = shortId + this._gitDDB.serializeFormat.firstExtension; + const result = getImpl( this._gitDDB, shortName, this.collectionPath, - this._gitDDB.jsonExt, + this._gitDDB.serializeFormat, { forceDocType: 'json' }, { withMetadata: false, @@ -948,6 +986,22 @@ export class Collection implements ICollection { }, historyOptions ) as Promise; + if (result === undefined && this._gitDDB.serializeFormat !== undefined) { + shortName = shortId + this._gitDDB.serializeFormat.secondExtension; + return getImpl( + this._gitDDB, + shortName, + this.collectionPath, + this._gitDDB.serializeFormat, + { forceDocType: 'json' }, + { + withMetadata: false, + revision: revision, + }, + historyOptions + ) as Promise; + } + return result; } /** @@ -961,7 +1015,7 @@ export class Collection implements ICollection { * @remarks * - undefined if a specified data does not exist or it is deleted. * - * - JsonDoc if the file extension is jsonExt. Be careful that JsonDoc may not have _id property when an app other than GitDocumentDB creates it. + * - JsonDoc if the file extension is SerializedFormat.extension. Be careful that JsonDoc may not have _id property when an app other than GitDocumentDB creates it. * * - FatBinaryDoc if described in .gitattribtues, otherwise FatTextDoc. * @@ -988,7 +1042,7 @@ export class Collection implements ICollection { this._gitDDB, shortName, this.collectionPath, - this._gitDDB.jsonExt, + this._gitDDB.serializeFormat, getOptions, { withMetadata: true, @@ -1004,11 +1058,12 @@ export class Collection implements ICollection { * @remarks * - By default, revisions are sorted by reverse chronological order. However, keep in mind that Git dates may not be consistent across repositories. * - * @param shortId - shortId is a file path whose collectionPath and ${jsonExt} extension is omitted. + * - If serializeFormat is front-matter, this function can't work for .yml files. Use getFatDocHistory() instead. e.g.) foo.yml + * + * @param shortId - shortId is a file path whose collectionPath and extension is omitted. * @param historyOptions - The array of revisions is filtered by HistoryOptions.filter. * - * @returns Array of JsonDoc or undefined. - * - undefined if a specified document does not exist or it is deleted. + * @returns Array of JsonDoc or undefined if a specified document does not exist or it is deleted. * * @example * ``` @@ -1048,12 +1103,12 @@ export class Collection implements ICollection { _id: string, historyOptions?: HistoryOptions ): Promise<(JsonDoc | undefined)[]> { - const shortName = _id + this._gitDDB.jsonExt; + const shortName = _id + this._gitDDB.serializeFormat.firstExtension; return getHistoryImpl( this._gitDDB, shortName, this.collectionPath, - this._gitDDB.jsonExt, + this._gitDDB.serializeFormat, historyOptions, { forceDocType: 'json' }, false @@ -1071,7 +1126,7 @@ export class Collection implements ICollection { * @returns Array of FatDoc or undefined. * - undefined if a specified data does not exist or it is deleted. * - * - Array of FatJsonDoc if isJsonDocCollection is true or the file extension is jsonExt. Be careful that JsonDoc may not have _id property when an app other than GitDocumentDB creates it. + * - Array of FatJsonDoc if isJsonDocCollection is true or the file extension is SerializeFormat.extension. Be careful that JsonDoc may not have _id property when an app other than GitDocumentDB creates it. * * - Array of FatBinaryDoc if described in .gitattribtues, otherwise array of FatTextDoc. * @@ -1091,7 +1146,7 @@ export class Collection implements ICollection { this._gitDDB, shortName, this.collectionPath, - this._gitDDB.jsonExt, + this._gitDDB.serializeFormat, historyOptions, getOptions, true @@ -1101,7 +1156,7 @@ export class Collection implements ICollection { /** * Delete a JSON document * - * @param shortId - shortId is a file path whose collectionPath and ${jsonExt} extension is omitted. + * @param shortId - shortId is a file path whose collectionPath and extension is omitted. * * @throws {@link Err.UndefinedDocumentIdError} * @@ -1121,7 +1176,7 @@ export class Collection implements ICollection { /** * Delete a document by _id property in JsonDoc * - * @param jsonDoc - JsonDoc whose _id is shortId. Only the _id property is referenced. shortId is a file path whose collectionPath and ${jsonExt} extension are omitted. + * @param jsonDoc - JsonDoc whose _id is shortId. Only the _id property is referenced. shortId is a file path whose collectionPath and extension are omitted. * * @throws {@link Err.UndefinedDocumentIdError} * @@ -1160,18 +1215,53 @@ export class Collection implements ICollection { else { return Promise.reject(new Err.UndefinedDocumentIdError()); } - const shortName = shortId + this._gitDDB.jsonExt; + let shortName = shortId + this._gitDDB.serializeFormat.firstExtension; - return deleteImpl(this._gitDDB, this.collectionPath, shortId, shortName, options).then( - res => { + let trySecondExtension = false; + const resultOrError = deleteImpl( + this._gitDDB, + this.collectionPath, + shortId, + shortName, + options + ) + .then(res => { const deleteResult: PutResultJsonDoc = { ...res, _id: shortId, type: 'json', }; return deleteResult; - } - ); + }) + .catch(err => { + if ( + err instanceof Err.DocumentNotFoundError && + this._gitDDB.serializeFormat.secondExtension !== undefined + ) + trySecondExtension = true; + return err; + }); + + if (trySecondExtension) { + shortName = shortId + this._gitDDB.serializeFormat.secondExtension; + return deleteImpl( + this._gitDDB, + this.collectionPath, + shortId, + shortName, + options + ).then(res => { + const deleteResult: PutResultJsonDoc = { + ...res, + _id: shortId, + type: 'json', + }; + return deleteResult; + }); + } + if (resultOrError instanceof Error) throw resultOrError; + + return resultOrError; } /** @@ -1197,15 +1287,17 @@ export class Collection implements ICollection { return Promise.reject(new Err.UndefinedDocumentIdError()); } - const docType: DocType = shortName.endsWith(this._gitDDB.jsonExt) ? 'json' : 'text'; + const docType: DocType = this._gitDDB.serializeFormat.hasObjectExtension(shortName) + ? 'json' + : 'text'; if (docType === 'text') { // TODO: select binary or text by .gitattribtues } - const shortId = shortName.replace(new RegExp(this._gitDDB.jsonExt + '$'), ''); + const shortId = this._gitDDB.serializeFormat.removeExtension(shortName); return deleteImpl(this._gitDDB, this.collectionPath, shortId, shortName, options).then( res => { - // NOTE: Cannot detect JsonDoc whose file path does not end with jsonExt + // NOTE: Cannot detect JsonDoc whose file path does not end with SerializeFormat.extension if (docType === 'json') { const deleteResult: DeleteResultJsonDoc = { ...res, @@ -1248,7 +1340,7 @@ export class Collection implements ICollection { return findImpl( this._gitDDB, this.collectionPath, - this._gitDDB.jsonExt, + this._gitDDB.serializeFormat, true, false, options @@ -1267,7 +1359,7 @@ export class Collection implements ICollection { return findImpl( this._gitDDB, this.collectionPath, - this._gitDDB.jsonExt, + this._gitDDB.serializeFormat, false, true, options diff --git a/src/crud/blob.ts b/src/crud/blob.ts index 863d076c..122eb348 100644 --- a/src/crud/blob.ts +++ b/src/crud/blob.ts @@ -12,16 +12,27 @@ import { readBlob, ReadBlobResult, resolveRef } from '@sosuisen/isomorphic-git'; import { FRONT_MATTER_POSTFIX } from '../const'; import { utf8decode } from '../utils'; import { Err } from '../error'; -import { FatBinaryDoc, FatDoc, FatJsonDoc, FatTextDoc, JsonDoc } from '../types'; +import { + FatBinaryDoc, + FatDoc, + FatJsonDoc, + FatTextDoc, + JsonDoc, + SerializeFormat, +} from '../types'; /** * textToJsonDoc * @throws {@link Err.InvalidJsonObjectError} */ // eslint-disable-next-line complexity -export function textToJsonDoc (text: string, jsonExt: string, shortId?: string): JsonDoc { +export function textToJsonDoc ( + text: string, + serializeFormat: SerializeFormat, + shortId?: string +): JsonDoc { let jsonDoc: JsonDoc; - if (jsonExt === FRONT_MATTER_POSTFIX) { + if (serializeFormat.format === 'front-matter') { const mdArray = text.split('\n'); let yamlText = ''; let markdownText = ''; @@ -101,10 +112,10 @@ export function blobToJsonDoc ( shortId: string, readBlobResult: ReadBlobResult, withMetadata: boolean, - jsonExt: string + serializeFormat: SerializeFormat ): FatJsonDoc | JsonDoc { const text = utf8decode(readBlobResult.blob); - const jsonDoc = textToJsonDoc(text, jsonExt, shortId); + const jsonDoc = textToJsonDoc(text, serializeFormat, shortId); if (jsonDoc._id !== undefined) { // Overwrite _id property by shortId (_id without collectionPath) if JsonDoc is created by GitDocumentedDB (_id !== undefined). jsonDoc._id = shortId; @@ -112,7 +123,7 @@ export function blobToJsonDoc ( if (withMetadata) { const fatJsonDoc: FatJsonDoc = { _id: shortId, - name: shortId + jsonExt, + name: shortId + serializeFormat.extension(jsonDoc), fileOid: readBlobResult.oid, type: 'json', doc: jsonDoc, @@ -130,10 +141,10 @@ export function blobToJsonDoc ( // eslint-disable-next-line complexity export function blobToJsonDocWithoutOverwrittenId ( readBlobResult: ReadBlobResult, - jsonExt: string + serializeFormat: SerializeFormat ): JsonDoc { const text = utf8decode(readBlobResult.blob); - const jsonDoc = textToJsonDoc(text, jsonExt); + const jsonDoc = textToJsonDoc(text, serializeFormat); return jsonDoc; } diff --git a/src/crud/find.ts b/src/crud/find.ts index b1e331af..4644f4e9 100644 --- a/src/crud/find.ts +++ b/src/crud/find.ts @@ -25,6 +25,7 @@ import { FatTextDoc, FindOptions, JsonDoc, + SerializeFormat, } from '../types'; import { GitDDBInterface } from '../types_gitddb'; import { blobToBinary, blobToJsonDoc, blobToText } from './blob'; @@ -40,7 +41,7 @@ import { blobToBinary, blobToJsonDoc, blobToText } from './blob'; export async function findImpl ( gitDDB: GitDDBInterface, collectionPath: string, - jsonExt: string, + serializeFormat: SerializeFormat, findOnlyJson: boolean, withMetadata: boolean, options?: FindOptions @@ -149,7 +150,7 @@ export async function findImpl ( } } else { - if (findOnlyJson && !fullDocPath.endsWith(jsonExt)) { + if (findOnlyJson && !serializeFormat.hasObjectExtension(fullDocPath)) { continue; } // eslint-disable-next-line no-await-in-loop @@ -163,20 +164,23 @@ export async function findImpl ( // Skip if cannot read if (readBlobResult) { const docType: DocType = - options.forceDocType ?? (fullDocPath.endsWith(jsonExt) ? 'json' : 'text'); + options.forceDocType ?? + (serializeFormat.hasObjectExtension(fullDocPath) ? 'json' : 'text'); if (docType === 'text') { // TODO: select binary or text by .gitattribtues } const shortName = fullDocPath.replace(new RegExp('^' + collectionPath), ''); if (docType === 'json') { - const shortId = shortName.replace(new RegExp(jsonExt + '$'), ''); + const shortId = serializeFormat.removeExtension(shortName); if (withMetadata) { docs.push( - blobToJsonDoc(shortId, readBlobResult, true, jsonExt) as FatJsonDoc + blobToJsonDoc(shortId, readBlobResult, true, serializeFormat) as FatJsonDoc ); } else { - docs.push(blobToJsonDoc(shortId, readBlobResult, false, jsonExt) as JsonDoc); + docs.push( + blobToJsonDoc(shortId, readBlobResult, false, serializeFormat) as JsonDoc + ); } } else if (docType === 'text') { diff --git a/src/crud/get.ts b/src/crud/get.ts index 57410af2..9ef5c0ce 100644 --- a/src/crud/get.ts +++ b/src/crud/get.ts @@ -16,6 +16,7 @@ import { GetInternalOptions, GetOptions, HistoryOptions, + SerializeFormat, } from '../types'; import { blobToBinary, @@ -39,7 +40,7 @@ export async function getImpl ( gitDDB: GitDDBInterface, shortName: string, collectionPath: string, - jsonExt: string, + serializeFormat: SerializeFormat, options?: GetOptions, internalOptions?: GetInternalOptions, historyOptions?: HistoryOptions @@ -98,17 +99,23 @@ export async function getImpl ( if (readBlobResult === undefined) return undefined; const docType: DocType = - options.forceDocType ?? (fullDocPath.endsWith(jsonExt) ? 'json' : 'text'); + options.forceDocType ?? + (serializeFormat.hasObjectExtension(fullDocPath) ? 'json' : 'text'); if (docType === 'text') { // TODO: select binary or text by .gitattribtues } if (docType === 'json') { if (internalOptions.oid !== '') { - return blobToJsonDocWithoutOverwrittenId(readBlobResult, jsonExt); + return blobToJsonDocWithoutOverwrittenId(readBlobResult, serializeFormat); } - const shortId = shortName.replace(new RegExp(jsonExt + '$'), ''); - return blobToJsonDoc(shortId, readBlobResult, internalOptions.withMetadata, jsonExt); + const shortId = serializeFormat.removeExtension(shortName); + return blobToJsonDoc( + shortId, + readBlobResult, + internalOptions.withMetadata, + serializeFormat + ); } else if (docType === 'text') { return blobToText(shortName, readBlobResult, internalOptions.withMetadata); diff --git a/src/crud/history.ts b/src/crud/history.ts index eeecdf32..cf8e41ff 100644 --- a/src/crud/history.ts +++ b/src/crud/history.ts @@ -8,7 +8,15 @@ import { log, readBlob, ReadBlobResult } from '@sosuisen/isomorphic-git'; import fs from 'fs-extra'; -import { Doc, DocType, FatDoc, GetOptions, HistoryFilter, HistoryOptions } from '../types'; +import { + Doc, + DocType, + FatDoc, + GetOptions, + HistoryFilter, + HistoryOptions, + SerializeFormat, +} from '../types'; import { GitDDBInterface } from '../types_gitddb'; import { Err } from '../error'; import { blobToBinary, blobToJsonDoc, blobToText } from './blob'; @@ -27,7 +35,7 @@ export async function getHistoryImpl ( gitDDB: GitDDBInterface, shortName: string, collectionPath: string, - jsonExt: string, + serializeFormat: SerializeFormat, historyOptions?: HistoryOptions, options?: GetOptions, withMetaData = false @@ -46,7 +54,8 @@ export async function getHistoryImpl ( const fullDocPath = collectionPath + shortName; const docType: DocType = - options.forceDocType ?? (fullDocPath.endsWith(jsonExt) ? 'json' : 'text'); + options.forceDocType ?? + (serializeFormat.hasObjectExtension(fullDocPath) ? 'json' : 'text'); if (docType === 'text') { // TODO: select binary or text by .gitattribtues @@ -88,14 +97,18 @@ export async function getHistoryImpl ( docArray.push(undefined); } else if (docType === 'json') { - const shortId = shortName.replace(new RegExp(jsonExt + '$'), ''); + const shortId = serializeFormat.removeExtension(shortName); // eslint-disable-next-line max-depth if (withMetaData) { - docArray.push(blobToJsonDoc(shortId, readBlobResult, true, jsonExt) as FatDoc); + docArray.push( + blobToJsonDoc(shortId, readBlobResult, true, serializeFormat) as FatDoc + ); } else { - docArray.push(blobToJsonDoc(shortId, readBlobResult, false, jsonExt) as Doc); + docArray.push( + blobToJsonDoc(shortId, readBlobResult, false, serializeFormat) as Doc + ); } } else if (docType === 'text') { diff --git a/src/serialize_format.ts b/src/serialize_format.ts index 8dd0f1a2..8572930d 100644 --- a/src/serialize_format.ts +++ b/src/serialize_format.ts @@ -1,34 +1,61 @@ +import { FRONT_MATTER_POSTFIX, JSON_POSTFIX, YAML_POSTFIX } from './const'; import { JsonDoc, SerializeFormat, SerializeFormatLabel } from './types'; +import { toFrontMatterMarkdown, toSortedJSONString, toYAML } from './utils'; export class SerializeFormatJSON implements SerializeFormat { format: SerializeFormatLabel = 'json'; - extForObj = '.json'; - match (filePath: string): boolean { - return true; + firstExtension = FRONT_MATTER_POSTFIX; + secondExtension = undefined; + + extension () { + return JSON_POSTFIX; + } + + removeExtension (path: string) { + if (path.endsWith(this.firstExtension)) + return path.replace(new RegExp(this.firstExtension + '$'), ''); + return path; } - removeExt (filePath: string): string { - return filePath; + hasObjectExtension (path: string) { + if (path.endsWith(this.firstExtension)) return true; + return false; } - serialize (doc: JsonDoc): string { - return ''; + serialize (doc: JsonDoc) { + return { extension: JSON_POSTFIX, data: toSortedJSONString(doc) }; } } export class SerializeFormatFrontMatter implements SerializeFormat { - format: SerializeFormatLabel = 'json'; - extForObj = '.yml'; - extForText = '.md'; - match (filePath: string): boolean { - return true; + format: SerializeFormatLabel = 'front-matter'; + firstExtension = FRONT_MATTER_POSTFIX; + secondExtension = YAML_POSTFIX; + + extension (doc: JsonDoc) { + if (doc._body === undefined) return YAML_POSTFIX; + return FRONT_MATTER_POSTFIX; + } + + removeExtension (path: string) { + if (path.endsWith(this.firstExtension)) + return path.replace(new RegExp(this.firstExtension + '$'), ''); + if (path.endsWith(this.secondExtension)) + return path.replace(new RegExp(this.secondExtension + '$'), ''); + return path; } - removeExt (filePath: string): string { - return filePath; + hasObjectExtension (path: string) { + if (path.endsWith(this.firstExtension) || path.endsWith(this.secondExtension)) + return true; + return false; } - serialize (doc: JsonDoc): string { - return ''; + serialize (doc: JsonDoc) { + const extension = this.extension(doc); + return { + extension, + data: extension === YAML_POSTFIX ? toYAML(doc) : toFrontMatterMarkdown(doc), + }; } } diff --git a/src/types.ts b/src/types.ts index 6cf65bdd..8b8d77b6 100644 --- a/src/types.ts +++ b/src/types.ts @@ -311,10 +311,12 @@ export type SerializeFormatLabel = 'json' | 'front-matter'; */ export interface SerializeFormat { format: SerializeFormatLabel; - extForObj: string; - match: (name: string) => boolean; - removeExt: (name: string) => string; - serialize: (doc: JsonDoc) => string; + firstExtension: string; + secondExtension: string | undefined; + removeExtension: (path: string) => string; + extension: (doc: JsonDoc) => string; + hasObjectExtension: (path: string) => boolean; + serialize: (doc: JsonDoc) => { extension: string; data: string }; } /** diff --git a/src/types_gitddb.ts b/src/types_gitddb.ts index 03187651..9058c154 100644 --- a/src/types_gitddb.ts +++ b/src/types_gitddb.ts @@ -7,6 +7,7 @@ */ import { Logger, TLogLevelName } from 'tslog'; +import { SerializeFormatFrontMatter, SerializeFormatJSON } from './serialize_format'; import { TaskQueue } from './task_queue'; import { ColoredLogger, @@ -16,6 +17,7 @@ import { OpenOptions, RemoteOptions, Schema, + SerializeFormatLabel, SyncResult, } from './types'; import { ICollection } from './types_collection'; @@ -31,7 +33,7 @@ export interface GitDDBInterface { /*********************************************** * Public properties (readonly) ***********************************************/ - jsonExt: string; + serializeFormat: SerializeFormatJSON | SerializeFormatFrontMatter; defaultBranch: string; localDir: string; dbName: string; diff --git a/src/utils.ts b/src/utils.ts index 2831043d..10cbbbc7 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -88,9 +88,6 @@ export function toYAML (obj: Record) { } export function toFrontMatterMarkdown (obj: Record) { - if (obj._body === undefined) { - return toYAML(obj); - } const body = typeof obj._body === 'string' ? obj._body : ''; const clone = JSON.parse(JSON.stringify(obj)); delete clone._body; @@ -109,13 +106,6 @@ export function toFrontMatterMarkdown (obj: Record) { return frontMatter + body; } -export function serializeJSON (obj: Record, jsonExt: string) { - if (jsonExt === FRONT_MATTER_POSTFIX) { - return toFrontMatterMarkdown(obj); - } - return toSortedJSONString(obj); -} - /** * Get metadata of all files from current Git index * From 547435de02da1e97da35a1e0ba94ce1e0129330a Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 19 Nov 2021 10:51:49 +0900 Subject: [PATCH 223/297] fix: replace jsonExt with serializeFormat --- src/git_documentdb.ts | 85 ++++++++++----------- src/remote/3way_merge.ts | 62 ++++++++------- src/remote/combine.ts | 22 +++--- src/remote/push_worker.ts | 2 +- src/remote/sync_worker.ts | 2 +- src/remote/worker_utils.ts | 99 ++++++++++++++++++------ src/serialize_format.ts | 4 +- src/types.ts | 10 +-- src/utils.ts | 9 ++- test/crud/find.test.ts | 112 ++++++++++++++-------------- test/crud/get.test.ts | 50 ++++++------- test/crud/history.test.ts | 22 +++--- test/remote_base/network_history.ts | 2 +- test/remote_utils.ts | 43 ++++++----- 14 files changed, 294 insertions(+), 230 deletions(-) diff --git a/src/git_documentdb.ts b/src/git_documentdb.ts index 15d6a6e0..4a15ad11 100644 --- a/src/git_documentdb.ts +++ b/src/git_documentdb.ts @@ -43,6 +43,7 @@ import { RemoteOptions, Schema, SerializeFormat, + SerializeFormatLabel, SyncCallback, SyncEvent, SyncResult, @@ -72,6 +73,7 @@ import { CollectionInterface, ICollection } from './types_collection'; import { blobToJsonDoc, readLatestBlob } from './crud/blob'; import * as remote_isomorphic_git from './plugin/remote-isomorphic-git'; +import { SerializeFormatFrontMatter, SerializeFormatJSON } from './serialize_format'; /** * Get database ID @@ -89,7 +91,7 @@ const INITIAL_DATABASE_OPEN_RESULT: DatabaseOpenResult = { isNew: false, isCreatedByGitDDB: true, isValidVersion: true, - serializeFormat: 'json', + serializeFormat: new SerializeFormatJSON(), }; /** @@ -131,25 +133,15 @@ export class GitDocumentDB private _dbOpenResult: DatabaseOpenResult = { ...INITIAL_DATABASE_OPEN_RESULT }; - /** - * Serialize format - */ - private _serializeFormat: SerializeFormat = 'json'; - /*********************************************** * Public properties (readonly) ***********************************************/ /** - * File extension for serializing json object + * Serialize format for json object */ - private _jsonExt = JSON_POSTFIX; - get jsonExt (): string { - return this._jsonExt; - } - - private _jsonExtAnother = YAML_POSTFIX; - get jsonExtAnother (): string { - return this._jsonExtAnother; + private _serializeFormat!: SerializeFormatJSON | SerializeFormatFrontMatter; + get serializeFormat () { + return this._serializeFormat; } /** @@ -458,7 +450,10 @@ export class GitDocumentDB this._logToTransport = options.logToTransport; - this._serializeFormat = options.serializeFormat ?? 'json'; + const format: SerializeFormatLabel = options.serializeFormat ?? 'json'; + if (format === 'front-matter') { + this._serializeFormat = new SerializeFormatFrontMatter(); + } // Get full-path this._workingDir = path.resolve(this._localDir, this._dbName); @@ -971,7 +966,7 @@ export class GitDocumentDB GIT_DOCUMENTDB_INFO_ID, readBlobResult, false, - JSON_POSTFIX + new SerializeFormatJSON() ) as DatabaseInfo; } catch (e) {} } @@ -991,8 +986,6 @@ export class GitDocumentDB if (info.serializeFormat !== this._serializeFormat) { // TODO: Change serialize format } - this._jsonExt = - this._serializeFormat === 'front-matter' ? FRONT_MATTER_POSTFIX : JSON_POSTFIX; // Set dbId if not exists. if (!info.dbId) { @@ -1036,10 +1029,10 @@ export class GitDocumentDB /** * Insert a JSON document if not exists. Otherwise, update it. * - * @param jsonDoc - JsonDoc whose _id is shortId. shortId is a file path whose collectionPath and ${jsonExt} extension are omitted. + * @param jsonDoc - JsonDoc whose _id is shortId. shortId is a file path whose collectionPath and extension are omitted. * * @remarks - * - The saved file path is `${GitDocumentDB#workingDir}/${jsonDoc._id}${jsonExt}` on the file system. + * - The saved file path is `${GitDocumentDB#workingDir}/${jsonDoc._id}${extension}` on the file system. * * - If _id is undefined, it is automatically generated. * @@ -1067,10 +1060,10 @@ export class GitDocumentDB /** * Insert a JSON document if not exists. Otherwise, update it. * - * @param _id - _id is a file path whose ${jsonExt} extension is omitted. + * @param _id - _id is a file path whose extension is omitted. * * @remarks - * - The saved file path is `${GitDocumentDB#workingDir}/${_id}${jsonExt}` on the file system. + * - The saved file path is `${GitDocumentDB#workingDir}/${_id}${extension}` on the file system. * * - If _id is undefined, it is automatically generated. * @@ -1114,14 +1107,14 @@ export class GitDocumentDB /** * Insert a JSON document * - * @param jsonDoc - JsonDoc whose _id is shortId. shortId is a file path whose collectionPath and ${jsonExt} extension are omitted. + * @param jsonDoc - JsonDoc whose _id is shortId. shortId is a file path whose collectionPath and extension are omitted. * * @remarks * - Throws SameIdExistsError when a document that has the same _id exists. It might be better to use put() instead of insert(). * * - If _id is undefined, it is automatically generated. * - * - The saved file path is `${GitDocumentDB#workingDir}/${jsonDoc._id}${jsonExt}` on the file system. + * - The saved file path is `${GitDocumentDB#workingDir}/${jsonDoc._id}${extension}` on the file system. * * - This is an alias of GitDocumentDB#rootCollection.insert() * @@ -1151,12 +1144,12 @@ export class GitDocumentDB /** * Insert a JSON document * - * @param _id - _id is a file path whose ${jsonExt} extension is omitted. + * @param _id - _id is a file path whose extension is omitted. * * @remarks * - Throws SameIdExistsError when a document that has the same id exists. It might be better to use put() instead of insert(). * - * - The saved file path is `${GitDocumentDB#workingDir}/${_id}${jsonExt}` on the file system. + * - The saved file path is `${GitDocumentDB#workingDir}/${_id}${extension}` on the file system. * * - If _id is undefined, it is automatically generated. * @@ -1202,14 +1195,14 @@ export class GitDocumentDB /** * Update a JSON document * - * @param jsonDoc - JsonDoc whose _id is shortId. shortId is a file path whose collectionPath and ${jsonExt} extension are omitted. + * @param jsonDoc - JsonDoc whose _id is shortId. shortId is a file path whose collectionPath and extension are omitted. * * @remarks * - Throws DocumentNotFoundError if a specified document does not exist. It might be better to use put() instead of update(). * * - If _id is undefined, it is automatically generated. * - * - The saved file path is `${GitDocumentDB#workingDir}/${_id}${jsonExt}` on the file system. + * - The saved file path is `${GitDocumentDB#workingDir}/${_id}extension` on the file system. * * - This is an alias of GitDocumentDB#rootCollection.update() * @@ -1237,12 +1230,12 @@ export class GitDocumentDB /** * Update a JSON document * - * @param _id - _id is a file path whose ${jsonExt} extension is omitted. + * @param _id - _id is a file path whose extension is omitted. * * @remarks * - Throws DocumentNotFoundError if a specified document does not exist. It might be better to use put() instead of update(). * - * - The saved file path is `${GitDocumentDB#workingDir}/${_id}${jsonExt}` on the file system. + * - The saved file path is `${GitDocumentDB#workingDir}/${_id}extension` on the file system. * * - An update operation is not skipped even if no change occurred on a specified document. * @@ -1287,11 +1280,11 @@ export class GitDocumentDB * @param name - name is a file path. * * @remarks - * - The saved file path is `${GitDocumentDB#workingDir}/${name}${jsonExt}`. + * - The saved file path is `${GitDocumentDB#workingDir}/${name}extension`. * * - If a name parameter is undefined, it is automatically generated. * - * - _id property of a JsonDoc is automatically set or overwritten by name parameter whose ${jsonExt} extension is removed. + * - _id property of a JsonDoc is automatically set or overwritten by name parameter whose extension is removed. * * - An update operation is not skipped even if no change occurred on a specified data. * @@ -1331,11 +1324,11 @@ export class GitDocumentDB * @remarks * - Throws SameIdExistsError when data that has the same _id exists. It might be better to use put() instead of insert(). * - * - The saved file path is `${GitDocumentDB#workingDir}/${name}${jsonExt}`. + * - The saved file path is `${GitDocumentDB#workingDir}/${name}extension`. * * - If a name parameter is undefined, it is automatically generated. * - * - _id property of a JsonDoc is automatically set or overwritten by name parameter whose ${jsonExt} extension is omitted. + * - _id property of a JsonDoc is automatically set or overwritten by name parameter whose extension is omitted. * * - This is an alias of GitDocumentDB#rootCollection.insertFatDoc() * @@ -1374,9 +1367,9 @@ export class GitDocumentDB * @remarks * - Throws DocumentNotFoundError if a specified data does not exist. It might be better to use put() instead of update(). * - * - The saved file path is `${GitDocumentDB#workingDir}/${name}${jsonExt}`. + * - The saved file path is `${GitDocumentDB#workingDir}/${name}extension`. * - * - _id property of a JsonDoc is automatically set or overwritten by name parameter whose ${jsonExt} extension is omitted. + * - _id property of a JsonDoc is automatically set or overwritten by name parameter whose extension is omitted. * * - An update operation is not skipped even if no change occurred on a specified data. * @@ -1412,7 +1405,7 @@ export class GitDocumentDB /** * Get a JSON document * - * @param _id - _id is a file path whose ${jsonExt} extension is omitted. + * @param _id - _id is a file path whose extension is omitted. * * @returns * - undefined if a specified document does not exist. @@ -1438,7 +1431,7 @@ export class GitDocumentDB * @returns * - undefined if a specified data does not exist. * - * - FatJsonDoc if the file extension is jsonExt. Be careful that JsonDoc may not have _id property when an app other than GitDocumentDB creates it. + * - FatJsonDoc if the file extension is SerializeFormat.extension. Be careful that JsonDoc may not have _id property when an app other than GitDocumentDB creates it. * * - FatBinaryDoc if described in .gitattribtues, otherwise FatTextDoc. * @@ -1477,7 +1470,7 @@ export class GitDocumentDB /** * Get an old revision of a document * - * @param _id - _id is a file path whose ${jsonExt} extension is omitted. + * @param _id - _id is a file path whose extension is omitted. * @param revision - Specify a number to go back to old revision. Default is 0. * See {@link git-documentdb#GitDocumentDB.getHistory} for the array of revisions. * @param historyOptions - The array of revisions is filtered by HistoryOptions.filter. @@ -1517,7 +1510,7 @@ export class GitDocumentDB * @remarks * - undefined if a specified data does not exist or it is deleted. * - * - JsonDoc if the file extension is jsonExt. Be careful that JsonDoc may not have _id property when an app other than GitDocumentDB creates it. + * - JsonDoc if the file extension is SerializeFormat.extension. Be careful that JsonDoc may not have _id property when an app other than GitDocumentDB creates it. * * - FatBinaryDoc if described in .gitattribtues, otherwise FatTextDoc. * @@ -1553,7 +1546,7 @@ export class GitDocumentDB /** * Get revision history of a document * - * @param _id - _id is a file path whose ${jsonExt} extension is omitted. + * @param _id - _id is a file path whose extension is omitted. * @param historyOptions - The array of revisions is filtered by HistoryOptions.filter. * * @remarks @@ -1564,7 +1557,7 @@ export class GitDocumentDB * @returns Array of FatDoc or undefined. * - undefined if a specified document does not exist or it is deleted. * - * - JsonDoc if isJsonDocCollection is true or the file extension is jsonExt. + * - JsonDoc if isJsonDocCollection is true or the file extension is SerializeFormat.extension. * * - Uint8Array or string if isJsonDocCollection is false. * @@ -1624,7 +1617,7 @@ export class GitDocumentDB * @returns Array of FatDoc or undefined. * - undefined if a specified data does not exist or it is deleted. * - * - Array of FatJsonDoc if isJsonDocCollection is true or the file extension is jsonExt. Be careful that JsonDoc may not have _id property when an app other than GitDocumentDB creates it. + * - Array of FatJsonDoc if isJsonDocCollection is true or the file extension is SerializeFormat.extension. Be careful that JsonDoc may not have _id property when an app other than GitDocumentDB creates it. * * - Array of FatBinaryDoc if described in .gitattribtues, otherwise array of FatTextDoc. * @@ -1646,7 +1639,7 @@ export class GitDocumentDB /** * Delete a JSON document * - * @param _id - _id is a file path whose ${jsonExt} extension is omitted. + * @param _id - _id is a file path whose extension is omitted. * * @remarks * - This is an alias of GitDocumentDB#rootCollection.delete() @@ -1669,7 +1662,7 @@ export class GitDocumentDB /** * Delete a document by _id property in JsonDoc * - * @param jsonDoc - Only the _id property of the JsonDoc is referenced. _id is a file path whose ${jsonExt} extension is omitted. + * @param jsonDoc - Only the _id property of the JsonDoc is referenced. _id is a file path whose extension is omitted. * * @remarks * - This is an alias of GitDocumentDB#rootCollection.delete() diff --git a/src/remote/3way_merge.ts b/src/remote/3way_merge.ts index c66ef20a..6675c9fe 100644 --- a/src/remote/3way_merge.ts +++ b/src/remote/3way_merge.ts @@ -12,10 +12,11 @@ import { FatDoc, IJsonPatch, JsonDoc, + SerializeFormat, } from '../types'; import { GitDDBInterface } from '../types_gitddb'; import { getFatDocFromData, writeBlobToFile } from './worker_utils'; -import { serializeJSON, utf8decode } from '../utils'; +import { utf8decode } from '../utils'; import { JsonDiff } from './json_diff'; import { SyncInterface } from '../types_sync'; import { isSameFatDoc, textToJsonDoc } from '../crud/blob'; @@ -59,7 +60,7 @@ function getMergedJsonDoc ( base: JsonDoc | undefined, ours: JsonDoc, theirs: JsonDoc, - jsonExt: string + serializeFormat: SerializeFormat ): string { let result: { [key: string]: string }; if (strategy === 'ours') { @@ -89,7 +90,7 @@ function getMergedJsonDoc ( else { throw new Err.InvalidConflictResolutionStrategyError(); } - return serializeJSON(result, jsonExt); + return serializeFormat.serialize(result).data; } /** @@ -159,14 +160,14 @@ function getMergedDocument ( ours: Uint8Array, theirs: Uint8Array, docType: DocType, - jsonExt: string + serializeFormat: SerializeFormat ): string | Uint8Array { if (docType === 'json') { - const oursDoc = textToJsonDoc(utf8decode(ours), jsonExt); - const theirsDoc = textToJsonDoc(utf8decode(theirs), jsonExt); + const oursDoc = textToJsonDoc(utf8decode(ours), serializeFormat); + const theirsDoc = textToJsonDoc(utf8decode(theirs), serializeFormat); let baseDoc: JsonDoc | undefined; if (base) { - baseDoc = textToJsonDoc(utf8decode(base), jsonExt); + baseDoc = textToJsonDoc(utf8decode(base), serializeFormat); } else { baseDoc = undefined; @@ -178,7 +179,7 @@ function getMergedDocument ( baseDoc, oursDoc, theirsDoc, - jsonExt + serializeFormat ); } else if (docType === 'text') { @@ -367,7 +368,9 @@ export async function threeWayMerge ( AcceptedConflict | undefined ] > { - const docType: DocType = fullDocPath.endsWith(gitDDB.jsonExt) ? 'json' : 'text'; + const docType: DocType = gitDDB.serializeFormat.hasObjectExtension(fullDocPath) + ? 'json' + : 'text'; if (docType === 'text') { // TODO: select binary or text by .gitattribtues } @@ -389,7 +392,7 @@ export async function threeWayMerge ( theirsData, fullDocPath, docType, - gitDDB.jsonExt + gitDDB.serializeFormat ); await writeBlobToFile(gitDDB.workingDir, fullDocPath, theirsData); await git.add({ fs, dir: gitDDB.workingDir, filepath: fullDocPath }); @@ -418,7 +421,7 @@ export async function threeWayMerge ( oursData, fullDocPath, docType, - gitDDB.jsonExt + gitDDB.serializeFormat ); return [ { @@ -467,13 +470,13 @@ export async function threeWayMerge ( oursData, fullDocPath, docType, - gitDDB.jsonExt + gitDDB.serializeFormat ); const theirsFatDoc = await getFatDocFromData( theirsData, fullDocPath, docType, - gitDDB.jsonExt + gitDDB.serializeFormat ); const strategy = await getStrategy( @@ -528,9 +531,14 @@ export async function threeWayMerge ( oursData, theirsData, docType, - gitDDB.jsonExt + gitDDB.serializeFormat + ); + resultFatDoc = await getFatDocFromData( + data, + fullDocPath, + docType, + gitDDB.serializeFormat ); - resultFatDoc = await getFatDocFromData(data, fullDocPath, docType, gitDDB.jsonExt); await writeBlobToFile(gitDDB.workingDir, fullDocPath, data); await git.add({ fs, dir: gitDDB.workingDir, filepath: fullDocPath }); @@ -581,7 +589,7 @@ export async function threeWayMerge ( theirsData, fullDocPath, docType, - gitDDB.jsonExt + gitDDB.serializeFormat ); if (baseOid === theirsOid) { @@ -609,7 +617,7 @@ export async function threeWayMerge ( baseData, fullDocPath, docType, - gitDDB.jsonExt + gitDDB.serializeFormat ); const acceptedConflict: AcceptedConflict = { fatDoc: baseFatDoc, @@ -659,7 +667,7 @@ export async function threeWayMerge ( oursData, fullDocPath, docType, - gitDDB.jsonExt + gitDDB.serializeFormat ); if (baseOid === oursOid) { @@ -713,7 +721,7 @@ export async function threeWayMerge ( baseData, fullDocPath, docType, - gitDDB.jsonExt + gitDDB.serializeFormat ); const acceptedConflicts: AcceptedConflict = { fatDoc: baseFatDoc, @@ -763,14 +771,14 @@ export async function threeWayMerge ( oursData, fullDocPath, docType, - gitDDB.jsonExt + gitDDB.serializeFormat ); const theirsData = (await theirs.content())!; const theirsFatDoc = await getFatDocFromData( theirsData, fullDocPath, docType, - gitDDB.jsonExt + gitDDB.serializeFormat ); await writeBlobToFile(gitDDB.workingDir, fullDocPath, theirsData); await git.add({ fs, dir: gitDDB.workingDir, filepath: fullDocPath }); @@ -797,14 +805,14 @@ export async function threeWayMerge ( oursData, fullDocPath, docType, - gitDDB.jsonExt + gitDDB.serializeFormat ); const theirsData = (await theirs.content())!; const theirsFatDoc = await getFatDocFromData( theirsData, fullDocPath, docType, - gitDDB.jsonExt + gitDDB.serializeFormat ); return [ { @@ -832,13 +840,13 @@ export async function threeWayMerge ( oursData, fullDocPath, docType, - gitDDB.jsonExt + gitDDB.serializeFormat ); const theirsFatDoc = await getFatDocFromData( theirsData, fullDocPath, docType, - gitDDB.jsonExt + gitDDB.serializeFormat ); const strategy = await getStrategy( conflictResolutionStrategy, @@ -902,13 +910,13 @@ export async function threeWayMerge ( oursData, theirsData, docType, - gitDDB.jsonExt + gitDDB.serializeFormat ); const resultFatDoc = await getFatDocFromData( data, fullDocPath, docType, - gitDDB.jsonExt + gitDDB.serializeFormat ); await writeBlobToFile(gitDDB.workingDir, fullDocPath, data); await git.add({ fs, dir: gitDDB.workingDir, filepath: fullDocPath }); diff --git a/src/remote/combine.ts b/src/remote/combine.ts index ad4afbfb..35169791 100644 --- a/src/remote/combine.ts +++ b/src/remote/combine.ts @@ -28,7 +28,7 @@ import { FILE_REMOVE_TIMEOUT, FRONT_MATTER_POSTFIX, } from '../const'; -import { getAllMetadata, serializeJSON } from '../utils'; +import { getAllMetadata } from '../utils'; import { RemoteEngine, wrappingRemoteEngineError } from './remote_engine'; /** @@ -98,11 +98,11 @@ export async function combineDatabaseWithTheirs ( const localMetadataList: DocMetadata[] = await getAllMetadata( gitDDB.workingDir, - gitDDB.jsonExt + gitDDB.serializeFormat ); const remoteMetadataList: DocMetadata[] = await getAllMetadata( remoteDir, - gitDDB.jsonExt + gitDDB.serializeFormat ); const remoteNames = remoteMetadataList.map(meta => meta.name); @@ -114,7 +114,9 @@ export async function combineDatabaseWithTheirs ( await fs.ensureDir(dir); - const docType: DocType = localFilePath.endsWith(gitDDB.jsonExt) ? 'json' : 'text'; + const docType: DocType = gitDDB.serializeFormat.hasObjectExtension(localFilePath) + ? 'json' + : 'text'; // eslint-disable-next-line max-depth if (docType === 'text') { // TODO: select binary or text by .gitattribtues @@ -136,11 +138,11 @@ export async function combineDatabaseWithTheirs ( if (docType === 'json') { let doc: JsonDoc; // eslint-disable-next-line max-depth - if (gitDDB.jsonExt === FRONT_MATTER_POSTFIX) { + if (gitDDB.serializeFormat.format === 'front-matter') { const txt = fs.readFileSync(localFilePath, { encoding: 'utf8', }); - doc = textToJsonDoc(txt, FRONT_MATTER_POSTFIX); + doc = textToJsonDoc(txt, gitDDB.serializeFormat); } else { doc = fs.readJSONSync(localFilePath); @@ -151,15 +153,15 @@ export async function combineDatabaseWithTheirs ( if (doc._id !== undefined) { doc._id = _id + postfix; } - duplicatedFileName = _id + postfix + gitDDB.jsonExt; + duplicatedFileName = _id + postfix + gitDDB.serializeFormat.extension(doc); duplicatedFileId = _id + postfix; - duplicatedFileExt = gitDDB.jsonExt; + duplicatedFileExt = gitDDB.serializeFormat.extension(doc); fs.writeFileSync( path.resolve(remoteDir, duplicatedFileName), - serializeJSON(doc, gitDDB.jsonExt) + gitDDB.serializeFormat.serialize(doc).data ); const duplicatedOid = ( - await git.hashBlob({ object: serializeJSON(doc, gitDDB.jsonExt) }) + await git.hashBlob({ object: gitDDB.serializeFormat.serialize(doc).data }) ).oid; original = { _id, diff --git a/src/remote/push_worker.ts b/src/remote/push_worker.ts index 70bf5b12..ee7e37f3 100644 --- a/src/remote/push_worker.ts +++ b/src/remote/push_worker.ts @@ -160,7 +160,7 @@ export async function pushWorker ( gitDDB.workingDir, remoteCommitOid, headCommitOid, - gitDDB.jsonExt + gitDDB.serializeFormat ); } diff --git a/src/remote/sync_worker.ts b/src/remote/sync_worker.ts index 5b869d6e..49d495c4 100644 --- a/src/remote/sync_worker.ts +++ b/src/remote/sync_worker.ts @@ -148,7 +148,7 @@ export async function syncWorker ( gitDDB.workingDir, oldCommitOid, newCommitOid!, - gitDDB.jsonExt + gitDDB.serializeFormat ); const syncResultFastForwardMerge: SyncResult = { diff --git a/src/remote/worker_utils.ts b/src/remote/worker_utils.ts index 4184fdca..d6f3c60b 100644 --- a/src/remote/worker_utils.ts +++ b/src/remote/worker_utils.ts @@ -9,7 +9,7 @@ import nodePath from 'path'; import git, { ReadBlobResult, ReadCommitResult } from '@sosuisen/isomorphic-git'; import fs from 'fs-extra'; -import { normalizeCommit, serializeJSON, utf8decode } from '../utils'; +import { normalizeCommit, utf8decode } from '../utils'; import { Err } from '../error'; import { ChangedFile, @@ -20,6 +20,7 @@ import { FatTextDoc, JsonDoc, NormalizedCommit, + SerializeFormat, } from '../types'; import { blobToBinary, blobToJsonDoc, blobToText, textToJsonDoc } from '../crud/blob'; @@ -50,17 +51,17 @@ export async function getFatDocFromData ( data: string | Uint8Array, fullDocPath: string, docType: DocType, - jsonExt: string + serializeFormat: SerializeFormat ) { let fatDoc: FatDoc; const { oid } = await git.hashBlob({ object: data }); if (docType === 'json') { - const _id = fullDocPath.replace(new RegExp(jsonExt + '$'), ''); + const _id = serializeFormat.removeExtension(fullDocPath); if (typeof data !== 'string') { data = utf8decode(data); } try { - const jsonDoc = (textToJsonDoc(data, jsonExt) as unknown) as JsonDoc; + const jsonDoc = (textToJsonDoc(data, serializeFormat) as unknown) as JsonDoc; if (jsonDoc._id !== undefined) { // Overwrite _id property by _id if JsonDoc is created by GitDocumentedDB (_id !== undefined). jsonDoc._id = _id; @@ -108,14 +109,14 @@ export async function getFatDocFromOid ( fullDocPath: string, fileOid: string, docType: DocType, - jsonExt: string + serializeFormat: SerializeFormat ) { const readBlobResult = await git.readBlob({ fs, dir: workingDir, oid: fileOid, }); - return getFatDocFromReadBlobResult(fullDocPath, readBlobResult, docType, jsonExt); + return getFatDocFromReadBlobResult(fullDocPath, readBlobResult, docType, serializeFormat); } /** @@ -127,12 +128,12 @@ export function getFatDocFromReadBlobResult ( fullDocPath: string, readBlobResult: ReadBlobResult, docType: DocType, - jsonExt: string + serializeFormat: SerializeFormat ) { let fatDoc: FatDoc; if (docType === 'json') { - const _id = fullDocPath.replace(new RegExp(jsonExt + '$'), ''); - fatDoc = blobToJsonDoc(_id, readBlobResult, true, jsonExt) as FatJsonDoc; + const _id = serializeFormat.removeExtension(fullDocPath); + fatDoc = blobToJsonDoc(_id, readBlobResult, true, serializeFormat) as FatJsonDoc; } else if (docType === 'text') { fatDoc = blobToText(fullDocPath, readBlobResult, true) as FatTextDoc; @@ -154,7 +155,7 @@ export async function getChanges ( workingDir: string, oldCommitOid: string | undefined, newCommitOid: string, - jsonExt: string + serializeFormat: SerializeFormat ) { return await git.walk({ fs, @@ -172,7 +173,9 @@ export async function getChanges ( a = null; } - const docType: DocType = fullDocPath.endsWith(jsonExt) ? 'json' : 'text'; + const docType: DocType = serializeFormat.hasObjectExtension(fullDocPath) + ? 'json' + : 'text'; if (docType === 'text') { // TODO: select binary or text by .gitattribtues } @@ -191,20 +194,44 @@ export async function getChanges ( if (bOid === undefined && aOid !== undefined) { change = { operation: 'delete', - old: await getFatDocFromOid(workingDir, fullDocPath, aOid, docType, jsonExt), + old: await getFatDocFromOid( + workingDir, + fullDocPath, + aOid, + docType, + serializeFormat + ), }; } else if (aOid === undefined && bOid !== undefined) { change = { operation: 'insert', - new: await getFatDocFromOid(workingDir, fullDocPath, bOid, docType, jsonExt), + new: await getFatDocFromOid( + workingDir, + fullDocPath, + bOid, + docType, + serializeFormat + ), }; } else if (aOid !== undefined && bOid !== undefined && aOid !== bOid) { change = { operation: 'update', - old: await getFatDocFromOid(workingDir, fullDocPath, aOid, docType, jsonExt), - new: await getFatDocFromOid(workingDir, fullDocPath, bOid, docType, jsonExt), + old: await getFatDocFromOid( + workingDir, + fullDocPath, + aOid, + docType, + serializeFormat + ), + new: await getFatDocFromOid( + workingDir, + fullDocPath, + bOid, + docType, + serializeFormat + ), }; } else { @@ -227,7 +254,7 @@ export async function getAndWriteLocalChanges ( workingDir: string, oldCommitOid: string, newCommitOid: string, - jsonExt: string + serializeFormat: SerializeFormat ) { return await git.walk({ fs, @@ -241,7 +268,9 @@ export async function getAndWriteLocalChanges ( return; } - const docType: DocType = fullDocPath.endsWith(jsonExt) ? 'json' : 'text'; + const docType: DocType = serializeFormat.hasObjectExtension(fullDocPath) + ? 'json' + : 'text'; if (docType === 'text') { // TODO: select binary or text by .gitattribtues } @@ -260,7 +289,13 @@ export async function getAndWriteLocalChanges ( if (bOid === undefined && aOid !== undefined) { change = { operation: 'delete', - old: await getFatDocFromOid(workingDir, fullDocPath, aOid, docType, jsonExt), + old: await getFatDocFromOid( + workingDir, + fullDocPath, + aOid, + docType, + serializeFormat + ), }; await git.remove({ fs, dir: workingDir, filepath: fullDocPath }); const path = nodePath.resolve(workingDir, fullDocPath); @@ -271,13 +306,19 @@ export async function getAndWriteLocalChanges ( else if (aOid === undefined && bOid !== undefined) { change = { operation: 'insert', - new: await getFatDocFromOid(workingDir, fullDocPath, bOid, docType, jsonExt), + new: await getFatDocFromOid( + workingDir, + fullDocPath, + bOid, + docType, + serializeFormat + ), }; if (change.new.type === 'json') { await writeBlobToFile( workingDir, fullDocPath, - serializeJSON(change.new.doc, jsonExt) + serializeFormat.serialize(change.new.doc).data ); } else if (change.new.type === 'text' || change.new.type === 'binary') { @@ -288,14 +329,26 @@ export async function getAndWriteLocalChanges ( else if (aOid !== undefined && bOid !== undefined && aOid !== bOid) { change = { operation: 'update', - old: await getFatDocFromOid(workingDir, fullDocPath, aOid, docType, jsonExt), - new: await getFatDocFromOid(workingDir, fullDocPath, bOid, docType, jsonExt), + old: await getFatDocFromOid( + workingDir, + fullDocPath, + aOid, + docType, + serializeFormat + ), + new: await getFatDocFromOid( + workingDir, + fullDocPath, + bOid, + docType, + serializeFormat + ), }; if (change.new.type === 'json') { await writeBlobToFile( workingDir, fullDocPath, - serializeJSON(change.new.doc, jsonExt) + serializeFormat.serialize(change.new.doc).data ); } else if (change.new.type === 'text' || change.new.type === 'binary') { diff --git a/src/serialize_format.ts b/src/serialize_format.ts index 8572930d..1782db81 100644 --- a/src/serialize_format.ts +++ b/src/serialize_format.ts @@ -32,8 +32,8 @@ export class SerializeFormatFrontMatter implements SerializeFormat { firstExtension = FRONT_MATTER_POSTFIX; secondExtension = YAML_POSTFIX; - extension (doc: JsonDoc) { - if (doc._body === undefined) return YAML_POSTFIX; + extension (doc?: JsonDoc) { + if (doc !== undefined && doc._body === undefined) return YAML_POSTFIX; return FRONT_MATTER_POSTFIX; } diff --git a/src/types.ts b/src/types.ts index 8b8d77b6..75b51f1a 100644 --- a/src/types.ts +++ b/src/types.ts @@ -60,7 +60,7 @@ export type DatabaseOptions = { dbName: string; logLevel?: TLogLevelName; schema?: Schema; - serializeFormat?: SerializeFormat; + serializeFormat?: SerializeFormatLabel; logToTransport?: (logObject: ILogObject) => void; logColorEnabled?: boolean; }; @@ -207,7 +207,7 @@ export type Doc = JsonDoc | string | Uint8Array; * Metadata for JsonDoc * * @remarks - * - _id: _id of a JSON document. This is a file name without ${jsonExt} extension. + * - _id: _id of a JSON document. This is a file name without extension. * * - name: A file name in Git. e.g.) "foo.json", "bar/baz.md" * @@ -314,7 +314,7 @@ export interface SerializeFormat { firstExtension: string; secondExtension: string | undefined; removeExtension: (path: string) => string; - extension: (doc: JsonDoc) => string; + extension: (doc?: JsonDoc) => string; hasObjectExtension: (path: string) => boolean; serialize: (doc: JsonDoc) => { extension: string; data: string }; } @@ -482,7 +482,7 @@ export type FindOptions = { * Result of put APIs (put, update, insert, putFatDoc, updateFatDoc, and insertFatDoc) * * @remarks - * - _id: _id of a JSON document. This is a file name without ${jsonExt} extension. PutResult does not have _id if a document is not {@link JsonDoc} type. + * - _id: _id of a JSON document. This is a file name without extension. PutResult does not have _id if a document is not {@link JsonDoc} type. * * - name: A file name in Git. e.g.) "foo.json", "bar/baz.md" * @@ -529,7 +529,7 @@ export type PutResultBinary = { * Result of delete() * * @remarks - * - _id: _id of a JSON document. This is a file name without ${jsonExt} extension. PutResult does not have _id if a document is not {@link JsonDoc} type. + * - _id: _id of a JSON document. This is a file name without extension. PutResult does not have _id if a document is not {@link JsonDoc} type. * * - name: A file name in Git. e.g.) "foo.json", "bar/baz.md" * diff --git a/src/utils.ts b/src/utils.ts index 10cbbbc7..e58f80c7 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -22,6 +22,7 @@ import { DocType, JsonDocMetadata, NormalizedCommit, + SerializeFormat, TextDocMetadata, } from './types'; import { FRONT_MATTER_POSTFIX, GIT_DOCUMENTDB_METADATA_DIR, JSON_POSTFIX } from './const'; @@ -114,7 +115,7 @@ export function toFrontMatterMarkdown (obj: Record) { // eslint-disable-next-line complexity export async function getAllMetadata ( workingDir: string, - jsonExt: string + serializeFormat: SerializeFormat ): Promise { const files: DocMetadata[] = []; const commitOid = await resolveRef({ fs, dir: workingDir, ref: 'HEAD' }).catch( @@ -168,12 +169,14 @@ export async function getAllMetadata ( // Skip if cannot read if (readBlobResult === undefined) continue; - const docType: DocType = fullDocPath.endsWith(jsonExt) ? 'json' : 'text'; + const docType: DocType = serializeFormat.hasObjectExtension(fullDocPath) + ? 'json' + : 'text'; if (docType === 'text') { // TODO: select binary or text by .gitattribtues } if (docType === 'json') { - const _id = fullDocPath.replace(new RegExp(jsonExt + '$'), ''); + const _id = serializeFormat.removeExtension(fullDocPath); const meta: JsonDocMetadata = { _id, name: fullDocPath, diff --git a/test/crud/find.test.ts b/test/crud/find.test.ts index 999854fa..f30f71dd 100644 --- a/test/crud/find.test.ts +++ b/test/crud/find.test.ts @@ -80,9 +80,9 @@ describe(' find()', () => { } // Call close() without await gitDDB.close().catch(() => {}); - await expect(findImpl(gitDDB, '', gitDDB.jsonExt, true, false)).rejects.toThrowError( - Err.DatabaseClosingError - ); + await expect( + findImpl(gitDDB, '', gitDDB.serializeFormat, true, false) + ).rejects.toThrowError(Err.DatabaseClosingError); while (gitDDB.isClosing) { // eslint-disable-next-line no-await-in-loop await sleep(100); @@ -100,9 +100,9 @@ describe(' find()', () => { await addOneData(gitDDB, 'invalidJSON' + JSON_POSTFIX, 'invalidJSON'); - await expect(findImpl(gitDDB, '', gitDDB.jsonExt, true, false)).rejects.toThrowError( - Err.InvalidJsonObjectError - ); + await expect( + findImpl(gitDDB, '', gitDDB.serializeFormat, true, false) + ).rejects.toThrowError(Err.InvalidJsonObjectError); await gitDDB.destroy(); }); @@ -141,9 +141,9 @@ describe(' find()', () => { await gitDDB.open(); - await expect(findImpl(gitDDB, '', gitDDB.jsonExt, true, false)).resolves.toEqual([ - json, - ]); + await expect( + findImpl(gitDDB, '', gitDDB.serializeFormat, true, false) + ).resolves.toEqual([json]); await gitDDB.destroy(); }); @@ -158,7 +158,9 @@ describe(' find()', () => { await gitDDB.open(); - await expect(findImpl(gitDDB, '', gitDDB.jsonExt, true, false)).resolves.toEqual([]); + await expect( + findImpl(gitDDB, '', gitDDB.serializeFormat, true, false) + ).resolves.toEqual([]); await gitDDB.destroy(); }); @@ -183,12 +185,9 @@ describe(' find()', () => { await addOneData(gitDDB, _id_1 + JSON_POSTFIX, toSortedJSONString(json_1)); await addOneData(gitDDB, _id_c + JSON_POSTFIX, toSortedJSONString(json_c)); - await expect(findImpl(gitDDB, '', gitDDB.jsonExt, true, false)).resolves.toEqual([ - json_1, - json_a, - json_b, - json_c, - ]); + await expect( + findImpl(gitDDB, '', gitDDB.serializeFormat, true, false) + ).resolves.toEqual([json_1, json_a, json_b, json_c]); await gitDDB.destroy(); }); @@ -212,15 +211,12 @@ describe(' find()', () => { await addOneData(gitDDB, _id_1 + JSON_POSTFIX, toSortedJSONString(json_1)); await addOneData(gitDDB, _id_c + JSON_POSTFIX, toSortedJSONString(json_c)); - await expect(findImpl(gitDDB, '', gitDDB.jsonExt, true, false)).resolves.toEqual([ - json_1, - json_a, - json_b, - json_c, - ]); + await expect( + findImpl(gitDDB, '', gitDDB.serializeFormat, true, false) + ).resolves.toEqual([json_1, json_a, json_b, json_c]); await expect( - findImpl(gitDDB, '', gitDDB.jsonExt, true, false, { descending: true }) + findImpl(gitDDB, '', gitDDB.serializeFormat, true, false, { descending: true }) ).resolves.toEqual([json_c, json_b, json_a, json_1]); await gitDDB.destroy(); @@ -246,13 +242,9 @@ describe(' find()', () => { await addOneData(gitDDB, _id_c01 + JSON_POSTFIX, toSortedJSONString(json_c01)); await addOneData(gitDDB, _id_c02 + JSON_POSTFIX, toSortedJSONString(json_c02)); - await expect(findImpl(gitDDB, '', gitDDB.jsonExt, true, false)).resolves.toEqual([ - json_a, - json_b, - json_c01, - json_c02, - json_d, - ]); + await expect( + findImpl(gitDDB, '', gitDDB.serializeFormat, true, false) + ).resolves.toEqual([json_a, json_b, json_c01, json_c02, json_d]); await gitDDB.destroy(); }); @@ -279,7 +271,7 @@ describe(' find()', () => { await addOneData(gitDDB, _id_c02 + JSON_POSTFIX, toSortedJSONString(json_c02)); await expect( - findImpl(gitDDB, '', gitDDB.jsonExt, true, false, { recursive: false }) + findImpl(gitDDB, '', gitDDB.serializeFormat, true, false, { recursive: false }) ).resolves.toEqual([json_a, json_b]); await gitDDB.destroy(); @@ -305,10 +297,9 @@ describe(' find()', () => { await addOneData(gitDDB, _id_1, toSortedJSONString(json_1)); await addOneData(gitDDB, _id_c, toSortedJSONString(json_c)); - await expect(findImpl(gitDDB, '', gitDDB.jsonExt, true, false)).resolves.toEqual([ - json_a, - json_b, - ]); + await expect( + findImpl(gitDDB, '', gitDDB.serializeFormat, true, false) + ).resolves.toEqual([json_a, json_b]); await gitDDB.destroy(); }); @@ -341,7 +332,7 @@ describe(' find()', () => { const prefix = 'citrus/'; await expect( - findImpl(gitDDB, '', gitDDB.jsonExt, true, false, { prefix }) + findImpl(gitDDB, '', gitDDB.serializeFormat, true, false, { prefix }) ).resolves.toEqual([json_c01, json_c02]); await gitDDB.destroy(); @@ -374,7 +365,10 @@ describe(' find()', () => { const prefix = 'cit'; await expect( - findImpl(gitDDB, '', gitDDB.jsonExt, true, false, { prefix, recursive: false }) + findImpl(gitDDB, '', gitDDB.serializeFormat, true, false, { + prefix, + recursive: false, + }) ).resolves.toEqual([json_c000, json_c001]); await gitDDB.destroy(); @@ -407,7 +401,7 @@ describe(' find()', () => { const prefix = 'citrus'; await expect( - findImpl(gitDDB, '', gitDDB.jsonExt, true, false, { prefix }) + findImpl(gitDDB, '', gitDDB.serializeFormat, true, false, { prefix }) ).resolves.toEqual([json_c000, json_c001, json_c01, json_c02]); await gitDDB.destroy(); @@ -440,7 +434,7 @@ describe(' find()', () => { const prefix = 'citrus/y'; await expect( - findImpl(gitDDB, '', gitDDB.jsonExt, true, false, { prefix }) + findImpl(gitDDB, '', gitDDB.serializeFormat, true, false, { prefix }) ).resolves.toEqual([json_c02]); await gitDDB.destroy(); @@ -473,7 +467,7 @@ describe(' find()', () => { const prefix = 'not_exist/'; await expect( - findImpl(gitDDB, '', gitDDB.jsonExt, true, false, { prefix }) + findImpl(gitDDB, '', gitDDB.serializeFormat, true, false, { prefix }) ).resolves.toEqual([]); await gitDDB.destroy(); @@ -507,11 +501,11 @@ describe(' find()', () => { await addOneData(gitDDB, _id_c02 + JSON_POSTFIX, toSortedJSONString(json_c02)); await expect( - findImpl(gitDDB, '', gitDDB.jsonExt, true, false, { prefix: 'pear/Japan' }) + findImpl(gitDDB, '', gitDDB.serializeFormat, true, false, { prefix: 'pear/Japan' }) ).resolves.toEqual([json_p]); await expect( - findImpl(gitDDB, '', gitDDB.jsonExt, true, false, { prefix: 'pear' }) + findImpl(gitDDB, '', gitDDB.serializeFormat, true, false, { prefix: 'pear' }) ).resolves.toEqual([json_p]); await gitDDB.destroy(); @@ -529,9 +523,9 @@ describe(' find()', () => { await gitDDB.open(); - await expect(findImpl(gitDDB, 'col01', gitDDB.jsonExt, true, false)).resolves.toEqual( - [] - ); + await expect( + findImpl(gitDDB, 'col01', gitDDB.serializeFormat, true, false) + ).resolves.toEqual([]); await gitDDB.destroy(); }); @@ -563,7 +557,7 @@ describe(' find()', () => { await addOneData(gitDDB, colPath + _id_c + JSON_POSTFIX, toSortedJSONString(json_c)); await expect( - findImpl(gitDDB, colPath, gitDDB.jsonExt, true, false) + findImpl(gitDDB, colPath, gitDDB.serializeFormat, true, false) ).resolves.toEqual([json_1_, json_a_, json_b_, json_c_]); await gitDDB.destroy(); @@ -605,7 +599,7 @@ describe(' find()', () => { ); await expect( - findImpl(gitDDB, colPath, gitDDB.jsonExt, true, false) + findImpl(gitDDB, colPath, gitDDB.serializeFormat, true, false) ).resolves.toEqual([json_a_, json_b_, json_c01_, json_c02_, json_d_]); await gitDDB.destroy(); @@ -676,7 +670,7 @@ describe(' find()', () => { const prefix = 'citrus/'; await expect( - findImpl(gitDDB, colPath, gitDDB.jsonExt, true, false, { prefix }) + findImpl(gitDDB, colPath, gitDDB.serializeFormat, true, false, { prefix }) ).resolves.toEqual([json_c01_, json_c02_]); await gitDDB.destroy(); @@ -746,7 +740,7 @@ describe(' find()', () => { const prefix = 'cit'; await expect( - findImpl(gitDDB, colPath, gitDDB.jsonExt, true, false, { + findImpl(gitDDB, colPath, gitDDB.serializeFormat, true, false, { prefix, recursive: false, }) @@ -819,7 +813,7 @@ describe(' find()', () => { const prefix = 'citrus'; await expect( - findImpl(gitDDB, colPath, gitDDB.jsonExt, true, false, { prefix }) + findImpl(gitDDB, colPath, gitDDB.serializeFormat, true, false, { prefix }) ).resolves.toEqual([json_c000_, json_c001_, json_c01_, json_c02_]); await gitDDB.destroy(); @@ -889,7 +883,7 @@ describe(' find()', () => { const prefix = 'citrus/y'; await expect( - findImpl(gitDDB, colPath, gitDDB.jsonExt, true, false, { prefix }) + findImpl(gitDDB, colPath, gitDDB.serializeFormat, true, false, { prefix }) ).resolves.toEqual([json_c02_]); await gitDDB.destroy(); @@ -959,7 +953,7 @@ describe(' find()', () => { const prefix = 'not_exist/'; await expect( - findImpl(gitDDB, colPath, gitDDB.jsonExt, true, false, { prefix }) + findImpl(gitDDB, colPath, gitDDB.serializeFormat, true, false, { prefix }) ).resolves.toEqual([]); await gitDDB.destroy(); @@ -1035,11 +1029,13 @@ describe(' find()', () => { ); await expect( - findImpl(gitDDB, colPath, gitDDB.jsonExt, true, false, { prefix: 'pear/Japan' }) + findImpl(gitDDB, colPath, gitDDB.serializeFormat, true, false, { + prefix: 'pear/Japan', + }) ).resolves.toEqual([json_p_]); await expect( - findImpl(gitDDB, colPath, gitDDB.jsonExt, true, false, { prefix: 'pear' }) + findImpl(gitDDB, colPath, gitDDB.serializeFormat, true, false, { prefix: 'pear' }) ).resolves.toEqual([json_p_]); await gitDDB.destroy(); @@ -1058,7 +1054,9 @@ describe(' find()', () => { await gitDDB.open(); - await expect(findImpl(gitDDB, '', gitDDB.jsonExt, true, true)).resolves.toEqual([]); + await expect( + findImpl(gitDDB, '', gitDDB.serializeFormat, true, true) + ).resolves.toEqual([]); await gitDDB.destroy(); }); @@ -1083,7 +1081,9 @@ describe(' find()', () => { await addOneData(gitDDB, _id_c01 + JSON_POSTFIX, toSortedJSONString(json_c01)); await addOneData(gitDDB, _id_c02 + JSON_POSTFIX, toSortedJSONString(json_c02)); - await expect(findImpl(gitDDB, '', gitDDB.jsonExt, true, true)).resolves.toEqual([ + await expect( + findImpl(gitDDB, '', gitDDB.serializeFormat, true, true) + ).resolves.toEqual([ { _id: _id_a, name: _id_a + JSON_POSTFIX, diff --git a/test/crud/get.test.ts b/test/crud/get.test.ts index 1fc7b892..6e7a95fa 100644 --- a/test/crud/get.test.ts +++ b/test/crud/get.test.ts @@ -65,7 +65,7 @@ describe(' getImpl()', () => { } // Call close() without await gitDDB.close().catch(() => {}); - await expect(getImpl(gitDDB, 'tmp', '', gitDDB.jsonExt)).rejects.toThrowError( + await expect(getImpl(gitDDB, 'tmp', '', gitDDB.serializeFormat)).rejects.toThrowError( Err.DatabaseClosingError ); while (gitDDB.isClosing) { @@ -90,7 +90,7 @@ describe(' getImpl()', () => { await addOneData(gitDDB, fullDocPath, data); await expect( - getImpl(gitDDB, shortName, collectionPath, gitDDB.jsonExt) + getImpl(gitDDB, shortName, collectionPath, gitDDB.serializeFormat) ).rejects.toThrowError(Err.InvalidJsonObjectError); await gitDDB.destroy(); @@ -111,7 +111,7 @@ describe(' getImpl()', () => { const json = { _id: shortId, name: 'Shirase' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json)); await expect( - getImpl(gitDDB, shortName, collectionPath, gitDDB.jsonExt) + getImpl(gitDDB, shortName, collectionPath, gitDDB.serializeFormat) ).resolves.toEqual(json); await gitDDB.destroy(); @@ -132,7 +132,7 @@ describe(' getImpl()', () => { const json = { _id: shortId, name: 'Shirase' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json)); await expect( - getImpl(gitDDB, shortName, collectionPath, gitDDB.jsonExt) + getImpl(gitDDB, shortName, collectionPath, gitDDB.serializeFormat) ).resolves.toEqual(json); await gitDDB.destroy(); @@ -153,7 +153,7 @@ describe(' getImpl()', () => { const json = { _id: shortId, name: 'Shirase' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json)); await expect( - getImpl(gitDDB, shortName, collectionPath, gitDDB.jsonExt) + getImpl(gitDDB, shortName, collectionPath, gitDDB.serializeFormat) ).resolves.toEqual(json); await gitDDB.destroy(); @@ -172,7 +172,7 @@ describe(' getImpl()', () => { const shortName = 'prof01.json'; const collectionPath = ''; await expect( - getImpl(gitDDB, shortName, collectionPath, gitDDB.jsonExt) + getImpl(gitDDB, shortName, collectionPath, gitDDB.serializeFormat) ).resolves.toBeUndefined(); await gitDDB.destroy(); @@ -190,7 +190,7 @@ describe(' getImpl()', () => { const collectionPath = ''; await expect( - getImpl(gitDDB, shortName, collectionPath, gitDDB.jsonExt) + getImpl(gitDDB, shortName, collectionPath, gitDDB.serializeFormat) ).resolves.toBeUndefined(); await gitDDB.destroy(); @@ -215,7 +215,7 @@ describe(' getImpl()', () => { stubReadBlob.rejects(); await expect( - getImpl(gitDDB, shortName, collectionPath, gitDDB.jsonExt) + getImpl(gitDDB, shortName, collectionPath, gitDDB.serializeFormat) ).resolves.toBeUndefined(); await gitDDB.destroy(); @@ -236,7 +236,7 @@ describe(' getImpl()', () => { const json = { _id: shortId, name: 'Shirase' }; await addOneData(gitDDB, fullDocPath, toSortedJSONString(json)); await expect( - getImpl(gitDDB, shortName, collectionPath, gitDDB.jsonExt) + getImpl(gitDDB, shortName, collectionPath, gitDDB.serializeFormat) ).resolves.toEqual(json); await gitDDB.destroy(); @@ -259,7 +259,7 @@ describe(' getImpl()', () => { const { oid } = await git.hashBlob({ object: toSortedJSONString(json) }); await addOneData(gitDDB, fullDocPath, toSortedJSONString(json)); await expect( - getImpl(gitDDB, shortName, collectionPath, gitDDB.jsonExt, undefined, { oid }) + getImpl(gitDDB, shortName, collectionPath, gitDDB.serializeFormat, undefined, { oid }) ).resolves.toEqual(json); await gitDDB.destroy(); @@ -283,7 +283,7 @@ describe(' getImpl()', () => { const { oid } = await git.hashBlob({ object: toSortedJSONString(json) }); await addOneData(gitDDB, fullDocPath, toSortedJSONString(json)); await expect( - getImpl(gitDDB, shortName, collectionPath, gitDDB.jsonExt, undefined, { + getImpl(gitDDB, shortName, collectionPath, gitDDB.serializeFormat, undefined, { withMetadata: true, }) ).resolves.toEqual({ @@ -313,7 +313,7 @@ describe(' getImpl()', () => { await addOneData(gitDDB, fullDocPath, toSortedJSONString(json)); await expect( - getImpl(gitDDB, shortName, collectionPath, gitDDB.jsonExt, undefined, { + getImpl(gitDDB, shortName, collectionPath, gitDDB.serializeFormat, undefined, { revision: -1, }) ).resolves.toBeUndefined(); @@ -340,7 +340,7 @@ describe(' getImpl()', () => { await removeOneData(gitDDB, fullDocPath); await expect( - getImpl(gitDDB, shortName, collectionPath, gitDDB.jsonExt, undefined, { + getImpl(gitDDB, shortName, collectionPath, gitDDB.serializeFormat, undefined, { revision: 0, }) ).resolves.toBeUndefined(); @@ -365,7 +365,7 @@ describe(' getImpl()', () => { await removeOneData(gitDDB, fullDocPath); await expect( - getImpl(gitDDB, shortName, collectionPath, gitDDB.jsonExt, undefined, { + getImpl(gitDDB, shortName, collectionPath, gitDDB.serializeFormat, undefined, { revision: 1, }) ).resolves.toEqual(json); @@ -392,7 +392,7 @@ describe(' getImpl()', () => { await removeOneData(gitDDB, fullDocPath); await expect( - getImpl(gitDDB, shortName, collectionPath, gitDDB.jsonExt, undefined, { + getImpl(gitDDB, shortName, collectionPath, gitDDB.serializeFormat, undefined, { revision: 2, }) ).resolves.toEqual(json01); @@ -419,7 +419,7 @@ describe(' getImpl()', () => { await addOneData(gitDDB, fullDocPath, toSortedJSONString(json02)); await expect( - getImpl(gitDDB, shortName, collectionPath, gitDDB.jsonExt, undefined, { + getImpl(gitDDB, shortName, collectionPath, gitDDB.serializeFormat, undefined, { revision: 2, }) ).resolves.toEqual(json01); @@ -446,7 +446,7 @@ describe(' getImpl()', () => { await addOneData(gitDDB, fullDocPath, toSortedJSONString(json02)); await expect( - getImpl(gitDDB, shortName, collectionPath, gitDDB.jsonExt, undefined, { + getImpl(gitDDB, shortName, collectionPath, gitDDB.serializeFormat, undefined, { revision: 1, }) ).resolves.toBeUndefined(); @@ -473,7 +473,7 @@ describe(' getImpl()', () => { await addOneData(gitDDB, fullDocPath, toSortedJSONString(json02)); await expect( - getImpl(gitDDB, shortName, collectionPath, gitDDB.jsonExt, undefined, { + getImpl(gitDDB, shortName, collectionPath, gitDDB.serializeFormat, undefined, { revision: 3, }) ).resolves.toBeUndefined(); @@ -493,7 +493,7 @@ describe(' getImpl()', () => { const collectionPath = ''; await expect( - getImpl(gitDDB, shortName, collectionPath, gitDDB.jsonExt, undefined, { + getImpl(gitDDB, shortName, collectionPath, gitDDB.serializeFormat, undefined, { revision: 0, }) ).resolves.toBeUndefined(); @@ -520,7 +520,7 @@ describe(' getImpl()', () => { stubReadBlob.rejects(); await expect( - getImpl(gitDDB, shortName, collectionPath, gitDDB.jsonExt, undefined, { + getImpl(gitDDB, shortName, collectionPath, gitDDB.serializeFormat, undefined, { revision: 0, }) ).resolves.toBeUndefined(); @@ -799,7 +799,7 @@ describe(' getImpl()', () => { gitDDB, targetName, collectionPath, - gitDDB.jsonExt, + gitDDB.serializeFormat, undefined, { revision: 0 }, { @@ -818,7 +818,7 @@ describe(' getImpl()', () => { gitDDB, targetName, collectionPath, - gitDDB.jsonExt, + gitDDB.serializeFormat, undefined, { revision: 1 }, { @@ -839,7 +839,7 @@ describe(' getImpl()', () => { gitDDB, targetName, collectionPath, - gitDDB.jsonExt, + gitDDB.serializeFormat, undefined, { revision: 0 }, { @@ -856,7 +856,7 @@ describe(' getImpl()', () => { gitDDB, targetName, collectionPath, - gitDDB.jsonExt, + gitDDB.serializeFormat, undefined, { revision: 1 }, { @@ -926,7 +926,7 @@ b: bbb const json = { _id: shortId, name: 'Shirase', _body: 'Journey to the Antarctic' }; await addOneData(gitDDB, fullDocPath, toFrontMatterMarkdown(json)); await expect( - getImpl(gitDDB, shortName, collectionPath, gitDDB.jsonExt) + getImpl(gitDDB, shortName, collectionPath, gitDDB.serializeFormat) ).resolves.toEqual(json); await gitDDB.destroy(); diff --git a/test/crud/history.test.ts b/test/crud/history.test.ts index daaea2e1..48aa6ef5 100644 --- a/test/crud/history.test.ts +++ b/test/crud/history.test.ts @@ -92,7 +92,7 @@ describe(' getHistoryImpl', () => { gitDDB, shortNameA, '', - gitDDB.jsonExt, + gitDDB.serializeFormat, undefined, undefined, @@ -106,7 +106,7 @@ describe(' getHistoryImpl', () => { gitDDB, shortNameB, '', - gitDDB.jsonExt, + gitDDB.serializeFormat, undefined, undefined, true @@ -158,7 +158,7 @@ describe(' getHistoryImpl', () => { gitDDB, shortNameA, '', - gitDDB.jsonExt, + gitDDB.serializeFormat, { filter: [{ author: { name: 'authorB', email: 'authorEmailB' } }], }, @@ -173,7 +173,7 @@ describe(' getHistoryImpl', () => { gitDDB, shortNameB, '', - gitDDB.jsonExt, + gitDDB.serializeFormat, { filter: [{ author: { name: 'authorB', email: 'authorEmailB' } }], }, @@ -202,7 +202,7 @@ describe(' getHistoryImpl', () => { gitDDB, 'invalid_id', '', - gitDDB.jsonExt, + gitDDB.serializeFormat, undefined, undefined, true @@ -237,7 +237,7 @@ describe(' getHistoryImpl', () => { gitDDB, shortNameA, '', - gitDDB.jsonExt, + gitDDB.serializeFormat, undefined, undefined, true @@ -268,7 +268,7 @@ describe(' getHistoryImpl', () => { // Call close() without await gitDDB.close().catch(() => {}); await expect( - getHistoryImpl(gitDDB, '0.json', '', gitDDB.jsonExt, undefined, undefined, true) + getHistoryImpl(gitDDB, '0.json', '', gitDDB.serializeFormat, undefined, undefined, true) ).rejects.toThrowError(Err.DatabaseClosingError); while (gitDDB.isClosing) { @@ -288,7 +288,7 @@ describe(' getHistoryImpl', () => { await gitDDB.putFatDoc('1.json', 'invalid json'); await expect( - getHistoryImpl(gitDDB, '1.json', '', gitDDB.jsonExt, undefined, undefined, true) + getHistoryImpl(gitDDB, '1.json', '', gitDDB.serializeFormat, undefined, undefined, true) ).rejects.toThrowError(Err.InvalidJsonObjectError); await destroyDBs([gitDDB]); @@ -313,7 +313,7 @@ describe(' getHistoryImpl', () => { await gitDDB.put(jsonA03); // Get - const historyA = await getHistoryImpl(gitDDB, shortNameA, '', gitDDB.jsonExt); + const historyA = await getHistoryImpl(gitDDB, shortNameA, '', gitDDB.serializeFormat); expect(historyA.length).toBe(3); expect(historyA[0]).toMatchObject(jsonA03); expect(historyA[1]).toMatchObject(jsonA02); @@ -347,7 +347,7 @@ describe(' getHistoryImpl', () => { gitDDB, shortNameA, '', - gitDDB.jsonExt, + gitDDB.serializeFormat, undefined, undefined, false @@ -379,7 +379,7 @@ describe(' getHistoryImpl', () => { gitDDB, 'invalid_id', '', - gitDDB.jsonExt, + gitDDB.serializeFormat, undefined, undefined, false diff --git a/test/remote_base/network_history.ts b/test/remote_base/network_history.ts index 6834f5b3..90725ace 100644 --- a/test/remote_base/network_history.ts +++ b/test/remote_base/network_history.ts @@ -77,7 +77,7 @@ export const networkHistoryBase = ( dbB, shortName, '', - dbB.jsonExt, + dbB.serializeFormat, undefined, undefined, true diff --git a/test/remote_utils.ts b/test/remote_utils.ts index e303b209..95a9b078 100644 --- a/test/remote_utils.ts +++ b/test/remote_utils.ts @@ -14,6 +14,7 @@ import { PutResult, RemoteOptions, Schema, + SerializeFormat, } from '../src/types'; import { SyncInterface } from '../src/types_sync'; import { GitDocumentDB } from '../src/git_documentdb'; @@ -24,6 +25,7 @@ import { JSON_POSTFIX, } from '../src/const'; import { RemoteRepository } from '../src/remote/remote_repository'; +import { SerializeFormatJSON } from '../src/serialize_format'; const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; @@ -64,13 +66,13 @@ export function getCommitInfo (resultOrMessage: (PutResult | DeleteResult | stri export function getChangedFileInsert ( newDoc: JsonDoc, newResult: PutResult | DeleteResult, - jsonExt = JSON_POSTFIX + serializeFormat: SerializeFormat = new SerializeFormatJSON() ): ChangedFileInsert { return { operation: 'insert', new: { _id: newDoc!._id, - name: newDoc!._id + jsonExt, + name: newDoc!._id + serializeFormat.extension(newDoc), fileOid: newResult!.fileOid, type: 'json', doc: newDoc, @@ -83,20 +85,20 @@ export function getChangedFileUpdate ( oldResult: PutResult | DeleteResult, newDoc: JsonDoc, newResult: PutResult | DeleteResult, - jsonExt = JSON_POSTFIX + serializeFormat: SerializeFormat = new SerializeFormatJSON() ): ChangedFileUpdate { return { operation: 'update', old: { _id: oldDoc!._id, - name: oldDoc!._id + jsonExt, + name: oldDoc!._id + serializeFormat.extension(oldDoc!), fileOid: oldResult!.fileOid, type: 'json', doc: oldDoc!, }, new: { _id: newDoc!._id, - name: newDoc!._id + jsonExt, + name: newDoc!._id + serializeFormat.extension(newDoc), fileOid: newResult!.fileOid, type: 'json', doc: newDoc, @@ -107,13 +109,13 @@ export function getChangedFileUpdate ( export function getChangedFileDelete ( oldDoc: JsonDoc, oldResult: PutResult | DeleteResult, - jsonExt = JSON_POSTFIX + serializeFormat: SerializeFormat = new SerializeFormatJSON() ): ChangedFileDelete { return { operation: 'delete', old: { _id: oldDoc!._id, - name: oldDoc!._id + jsonExt, + name: oldDoc!._id + serializeFormat.extension(oldDoc), fileOid: oldResult!.fileOid, type: 'json', doc: oldDoc, @@ -124,13 +126,13 @@ export function getChangedFileDelete ( export function getChangedFileInsertBySHA ( newDoc: JsonDoc, newFileSHA: string, - jsonExt = JSON_POSTFIX + serializeFormat: SerializeFormat = new SerializeFormatJSON() ): ChangedFileInsert { return { operation: 'insert', new: { _id: newDoc!._id, - name: newDoc!._id + jsonExt, + name: newDoc!._id + serializeFormat.extension(newDoc), fileOid: newFileSHA, type: 'json', doc: newDoc, @@ -143,20 +145,20 @@ export function getChangedFileUpdateBySHA ( oldFileSHA: string, newDoc: JsonDoc, newFileSHA: string, - jsonExt = JSON_POSTFIX + serializeFormat: SerializeFormat = new SerializeFormatJSON() ): ChangedFileUpdate { return { operation: 'update', old: { _id: oldDoc!._id, - name: oldDoc!._id + jsonExt, + name: oldDoc!._id + serializeFormat.extension(oldDoc!), fileOid: oldFileSHA, type: 'json', doc: oldDoc!, }, new: { _id: newDoc!._id, - name: newDoc!._id + jsonExt, + name: newDoc!._id + serializeFormat.extension(newDoc), fileOid: newFileSHA, type: 'json', doc: newDoc, @@ -167,13 +169,13 @@ export function getChangedFileUpdateBySHA ( export function getChangedFileDeleteBySHA ( oldDoc: JsonDoc, oldFileSHA: string, - jsonExt = JSON_POSTFIX + serializeFormat: SerializeFormat = new SerializeFormatJSON() ): ChangedFileDelete { return { operation: 'delete', old: { _id: oldDoc!._id, - name: oldDoc!._id + jsonExt, + name: oldDoc!._id + serializeFormat.extension(oldDoc), fileOid: oldFileSHA, type: 'json', doc: oldDoc, @@ -385,17 +387,20 @@ export const compareWorkingDirAndBlobs = async ( return true; }; -export const getWorkingDirDocs = (gitDDB: GitDocumentDB, jsonExt = JSON_POSTFIX) => { +export const getWorkingDirDocs = ( + gitDDB: GitDocumentDB, + serializeFormat: SerializeFormat = new SerializeFormatJSON() +) => { return listFiles(gitDDB, gitDDB.workingDir).map(filepath => { - if (jsonExt === FRONT_MATTER_POSTFIX) { + if (serializeFormat.format === 'front-matter') { const txt = fs.readFileSync(gitDDB.workingDir + '/' + filepath, { encoding: 'utf8' }); - const doc = textToJsonDoc(txt, FRONT_MATTER_POSTFIX); - doc._id = filepath.replace(new RegExp(jsonExt + '$'), ''); + const doc = textToJsonDoc(txt, serializeFormat); + doc._id = serializeFormat.removeExtension(filepath); return doc; } const doc = fs.readJSONSync(gitDDB.workingDir + '/' + filepath); - doc._id = filepath.replace(new RegExp(jsonExt + '$'), ''); + doc._id = serializeFormat.removeExtension(filepath); return doc; }); }; From f3503219237af1251632be9c420b426487da2464 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 19 Nov 2021 15:45:49 +0900 Subject: [PATCH 224/297] snapshot: fixing tests for SerializeFormat --- .vscode/launch.json | 2 +- src/collection.ts | 26 ++++++++------ src/git_documentdb.ts | 21 +++++++---- src/serialize_format.ts | 2 +- src/task_queue.ts | 5 ++- src/types.ts | 2 +- test/crud/blob.test.ts | 58 +++++++++++++++++++----------- test/crud/put.test.ts | 4 +-- test/git_documentdb_logger.test.ts | 7 ++-- test/remote_base/3way_merge_ot.ts | 13 ++++--- test/remote_base/combine.ts | 7 ++-- test/remote_utils.ts | 7 +--- 12 files changed, 91 insertions(+), 63 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 21f204ce..d65c7e1d 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,7 +4,7 @@ "type": "pickString", "id": "choice", "description": "select a file", - "options": ["test/remote_isomorphic_git/network_history.test.js"], + "options": ["test/crud/delete.test.js"], }], "configurations": [ { diff --git a/src/collection.ts b/src/collection.ts index 9bc3b48c..1eecc8cf 100644 --- a/src/collection.ts +++ b/src/collection.ts @@ -841,9 +841,9 @@ export class Collection implements ICollection { * * @public */ - get (_id: string): Promise { + async get (_id: string): Promise { const shortName = _id + this._gitDDB.serializeFormat.firstExtension; - const result = getImpl( + const result = (await getImpl( this._gitDDB, shortName, this.collectionPath, @@ -851,7 +851,7 @@ export class Collection implements ICollection { { forceDocType: 'json', } - ) as Promise; + )) as Promise; if ( result === undefined && this._gitDDB.serializeFormat.secondExtension !== undefined @@ -888,8 +888,11 @@ export class Collection implements ICollection { * * @public */ - getFatDoc (shortName: string, getOptions?: GetOptions): Promise { - const result = getImpl( + async getFatDoc ( + shortName: string, + getOptions?: GetOptions + ): Promise { + const result = (await getImpl( this._gitDDB, shortName, this.collectionPath, @@ -898,7 +901,7 @@ export class Collection implements ICollection { { withMetadata: true, } - ) as Promise; + )) as Promise; if ( result === undefined && this._gitDDB.serializeFormat.secondExtension !== undefined @@ -968,13 +971,13 @@ export class Collection implements ICollection { * * @public */ - getOldRevision ( + async getOldRevision ( shortId: string, revision: number, historyOptions?: HistoryOptions ): Promise { let shortName = shortId + this._gitDDB.serializeFormat.firstExtension; - const result = getImpl( + const result = (await getImpl( this._gitDDB, shortName, this.collectionPath, @@ -985,7 +988,7 @@ export class Collection implements ICollection { revision: revision, }, historyOptions - ) as Promise; + )) as Promise; if (result === undefined && this._gitDDB.serializeFormat !== undefined) { shortName = shortId + this._gitDDB.serializeFormat.secondExtension; return getImpl( @@ -1201,7 +1204,7 @@ export class Collection implements ICollection { options?: DeleteOptions ): Promise; - delete ( + async delete ( shortIdOrDoc: string | JsonDoc, options?: DeleteOptions ): Promise { @@ -1218,7 +1221,7 @@ export class Collection implements ICollection { let shortName = shortId + this._gitDDB.serializeFormat.firstExtension; let trySecondExtension = false; - const resultOrError = deleteImpl( + const resultOrError = await deleteImpl( this._gitDDB, this.collectionPath, shortId, @@ -1259,6 +1262,7 @@ export class Collection implements ICollection { return deleteResult; }); } + // eslint-disable-next-line promise/catch-or-return if (resultOrError instanceof Error) throw resultOrError; return resultOrError; diff --git a/src/git_documentdb.ts b/src/git_documentdb.ts index 4a15ad11..f70de58e 100644 --- a/src/git_documentdb.ts +++ b/src/git_documentdb.ts @@ -91,7 +91,7 @@ const INITIAL_DATABASE_OPEN_RESULT: DatabaseOpenResult = { isNew: false, isCreatedByGitDDB: true, isValidVersion: true, - serializeFormat: new SerializeFormatJSON(), + serialize: 'json', }; /** @@ -131,7 +131,9 @@ export class GitDocumentDB ***********************************************/ private _synchronizers: { [url: string]: Sync } = {}; - private _dbOpenResult: DatabaseOpenResult = { ...INITIAL_DATABASE_OPEN_RESULT }; + private _dbOpenResult: DatabaseOpenResult = { + ...INITIAL_DATABASE_OPEN_RESULT, + }; /*********************************************** * Public properties (readonly) @@ -454,6 +456,9 @@ export class GitDocumentDB if (format === 'front-matter') { this._serializeFormat = new SerializeFormatFrontMatter(); } + else { + this._serializeFormat = new SerializeFormatJSON(); + } // Get full-path this._workingDir = path.resolve(this._localDir, this._dbName); @@ -522,7 +527,7 @@ export class GitDocumentDB dbId: generateDatabaseId(), creator: DATABASE_CREATOR, version: DATABASE_VERSION, - serializeFormat: this._serializeFormat, + serialize: this._serializeFormat.format, }; // Retry three times. @@ -685,7 +690,9 @@ export class GitDocumentDB this._synchronizers = {}; - this._dbOpenResult = { ...INITIAL_DATABASE_OPEN_RESULT }; + this._dbOpenResult = { + ...INITIAL_DATABASE_OPEN_RESULT, + }; this._isClosing = false; } @@ -975,15 +982,15 @@ export class GitDocumentDB dbId: '', creator: '', version: '', - serializeFormat: this._serializeFormat, + serialize: this._serializeFormat.format, }; info.creator ??= ''; info.version ??= ''; - info.serializeFormat ??= this._serializeFormat; + info.serialize ??= this._serializeFormat.format; - if (info.serializeFormat !== this._serializeFormat) { + if (info.serialize !== this._serializeFormat.format) { // TODO: Change serialize format } diff --git a/src/serialize_format.ts b/src/serialize_format.ts index 1782db81..88b6a89a 100644 --- a/src/serialize_format.ts +++ b/src/serialize_format.ts @@ -4,7 +4,7 @@ import { toFrontMatterMarkdown, toSortedJSONString, toYAML } from './utils'; export class SerializeFormatJSON implements SerializeFormat { format: SerializeFormatLabel = 'json'; - firstExtension = FRONT_MATTER_POSTFIX; + firstExtension = JSON_POSTFIX; secondExtension = undefined; extension () { diff --git a/src/task_queue.ts b/src/task_queue.ts index 3a57e30e..93520990 100644 --- a/src/task_queue.ts +++ b/src/task_queue.ts @@ -12,7 +12,6 @@ import { clearInterval, setInterval } from 'timers'; import { decodeTime, monotonicFactory } from 'ulid'; -import { Logger } from 'tslog'; import AsyncLock from 'async-lock'; import { ColoredLogger, Task, TaskMetadata, TaskStatistics } from './types'; import { CONSOLE_STYLE, sleep } from './utils'; @@ -116,7 +115,7 @@ export class TaskQueue { this._lock! // eslint-disable-next-line complexity .acquire('TaskQueue', () => { // Skip consecutive sync/push events - this._logger.debug( + this._logger.silly( `Try to push ${task.label}@${task.taskId} into ${JSON.stringify(this._taskQueue)}` ); if ( @@ -404,7 +403,7 @@ export class TaskQueue { }; this._currentTask.func(beforeResolve, beforeReject, taskMetadata).finally(() => { - this._logger.debug( + this._logger.silly( `Clear currentTask: ${this._currentTask?.label}@${this._currentTask?.taskId}` ); this._isTaskQueueWorking = false; diff --git a/src/types.ts b/src/types.ts index 75b51f1a..70eda895 100644 --- a/src/types.ts +++ b/src/types.ts @@ -145,7 +145,7 @@ export type DatabaseInfo = { dbId: string; creator: string; version: string; - serializeFormat: SerializeFormat; + serialize: SerializeFormatLabel; }; /** diff --git a/test/crud/blob.test.ts b/test/crud/blob.test.ts index 052fb279..c956f230 100644 --- a/test/crud/blob.test.ts +++ b/test/crud/blob.test.ts @@ -24,7 +24,11 @@ import { import { Err } from '../../src/error'; import { GitDocumentDB } from '../../src/git_documentdb'; import { toFrontMatterMarkdown, toSortedJSONString, utf8encode } from '../../src/utils'; -import { FRONT_MATTER_POSTFIX, JSON_POSTFIX } from '../../src/const'; +import { JSON_POSTFIX } from '../../src/const'; +import { + SerializeFormatFrontMatter, + SerializeFormatJSON, +} from '../../src/serialize_format'; // eslint-disable-next-line @typescript-eslint/no-var-requires const git_module = require('@sosuisen/isomorphic-git'); @@ -62,7 +66,7 @@ describe('', () => { blob: utf8encode(text), }; expect(() => - blobToJsonDoc(shortId, readBlobResult, false, JSON_POSTFIX) + blobToJsonDoc(shortId, readBlobResult, false, new SerializeFormatJSON()) ).toThrowError(Err.InvalidJsonObjectError); }); @@ -74,7 +78,9 @@ describe('', () => { oid: (await git.hashBlob({ object: text })).oid, blob: utf8encode(text), }; - expect(blobToJsonDoc(shortId, readBlobResult, false, JSON_POSTFIX)).toEqual(json); + expect( + blobToJsonDoc(shortId, readBlobResult, false, new SerializeFormatJSON()) + ).toEqual(json); }); it('returns JsonDoc with only _id when Front-Matter + Markdown is empty', async () => { @@ -84,7 +90,9 @@ describe('', () => { oid: (await git.hashBlob({ object: text })).oid, blob: utf8encode(text), }; - expect(blobToJsonDoc(shortId, readBlobResult, false, FRONT_MATTER_POSTFIX)).toEqual({ + expect( + blobToJsonDoc(shortId, readBlobResult, false, new SerializeFormatFrontMatter()) + ).toEqual({ _id: 'foo', }); }); @@ -96,7 +104,9 @@ describe('', () => { oid: (await git.hashBlob({ object: text })).oid, blob: utf8encode(text), }; - expect(blobToJsonDoc(shortId, readBlobResult, false, FRONT_MATTER_POSTFIX)).toEqual({ + expect( + blobToJsonDoc(shortId, readBlobResult, false, new SerializeFormatFrontMatter()) + ).toEqual({ _id: 'foo', _body: text, }); @@ -109,7 +119,9 @@ describe('', () => { oid: (await git.hashBlob({ object: text })).oid, blob: utf8encode(text), }; - expect(blobToJsonDoc(shortId, readBlobResult, false, FRONT_MATTER_POSTFIX)).toEqual({ + expect( + blobToJsonDoc(shortId, readBlobResult, false, new SerializeFormatFrontMatter()) + ).toEqual({ _id: 'foo', _body: text, }); @@ -123,9 +135,9 @@ describe('', () => { oid: (await git.hashBlob({ object: text })).oid, blob: utf8encode(text), }; - expect(blobToJsonDoc(shortId, readBlobResult, false, FRONT_MATTER_POSTFIX)).toEqual( - json - ); + expect( + blobToJsonDoc(shortId, readBlobResult, false, new SerializeFormatFrontMatter()) + ).toEqual(json); }); it('returns JsonDoc of Front-Matter + Markdown that ends with \n', async () => { @@ -136,9 +148,9 @@ describe('', () => { oid: (await git.hashBlob({ object: text })).oid, blob: utf8encode(text), }; - expect(blobToJsonDoc(shortId, readBlobResult, false, FRONT_MATTER_POSTFIX)).toEqual( - json - ); + expect( + blobToJsonDoc(shortId, readBlobResult, false, new SerializeFormatFrontMatter()) + ).toEqual(json); }); it('returns JsonDoc of Front-Matter without Markdown', async () => { @@ -149,9 +161,9 @@ describe('', () => { oid: (await git.hashBlob({ object: text })).oid, blob: utf8encode(text), }; - expect(blobToJsonDoc(shortId, readBlobResult, false, FRONT_MATTER_POSTFIX)).toEqual( - json - ); + expect( + blobToJsonDoc(shortId, readBlobResult, false, new SerializeFormatFrontMatter()) + ).toEqual(json); }); it('returns JsonDoc with overwritten _id', async () => { @@ -164,7 +176,9 @@ describe('', () => { oid: (await git.hashBlob({ object: text })).oid, blob: utf8encode(text), }; - expect(blobToJsonDoc(shortId2, readBlobResult, false, JSON_POSTFIX)).toEqual(json2); + expect( + blobToJsonDoc(shortId2, readBlobResult, false, new SerializeFormatJSON()) + ).toEqual(json2); }); it('returns FatJsonDoc', async () => { @@ -176,7 +190,9 @@ describe('', () => { oid: fileOid, blob: utf8encode(text), }; - expect(blobToJsonDoc(shortId, readBlobResult, true, JSON_POSTFIX)).toEqual({ + expect( + blobToJsonDoc(shortId, readBlobResult, true, new SerializeFormatJSON()) + ).toEqual({ _id: shortId, name: shortId + JSON_POSTFIX, fileOid, @@ -194,7 +210,7 @@ describe('', () => { blob: utf8encode(text), }; expect(() => - blobToJsonDocWithoutOverwrittenId(readBlobResult, JSON_POSTFIX) + blobToJsonDocWithoutOverwrittenId(readBlobResult, new SerializeFormatJSON()) ).toThrowError(Err.InvalidJsonObjectError); }); @@ -206,7 +222,9 @@ describe('', () => { oid: (await git.hashBlob({ object: text })).oid, blob: utf8encode(text), }; - expect(blobToJsonDocWithoutOverwrittenId(readBlobResult, JSON_POSTFIX)).toEqual(json); + expect( + blobToJsonDocWithoutOverwrittenId(readBlobResult, new SerializeFormatJSON()) + ).toEqual(json); }); it('returns JsonDoc in FrontMatterMarkdown', async () => { @@ -218,7 +236,7 @@ describe('', () => { blob: utf8encode(text), }; expect( - blobToJsonDocWithoutOverwrittenId(readBlobResult, FRONT_MATTER_POSTFIX) + blobToJsonDocWithoutOverwrittenId(readBlobResult, new SerializeFormatFrontMatter()) ).toEqual(json); }); }); diff --git a/test/crud/put.test.ts b/test/crud/put.test.ts index fe02b36d..e83ff992 100644 --- a/test/crud/put.test.ts +++ b/test/crud/put.test.ts @@ -641,7 +641,7 @@ a: 春はあけぼの await gitDDB.destroy(); }); - it('write front matter without markdown', async () => { + it('write yaml when no markdown', async () => { const dbName = monoId(); const gitDDB: GitDocumentDB = new GitDocumentDB({ dbName, @@ -656,7 +656,7 @@ a: 春はあけぼの const result = `_id: foo a: bar `; - const fullDocPath = 'foo.md'; + const fullDocPath = 'foo.yml'; expect(readFileSync(path.resolve(gitDDB.workingDir, fullDocPath), 'utf8')).toBe(result); await gitDDB.close(); diff --git a/test/git_documentdb_logger.test.ts b/test/git_documentdb_logger.test.ts index c5a40cb3..61978e40 100644 --- a/test/git_documentdb_logger.test.ts +++ b/test/git_documentdb_logger.test.ts @@ -42,7 +42,7 @@ describe(' logger', () => { const gitDDB: GitDocumentDB = new GitDocumentDB({ dbName, localDir, - logLevel: 'silly', + logLevel: 'debug', logToTransport: (logObject: ILogObject) => { fs.appendFileSync(logPath, logObject.argumentsArray[0] + '\n'); }, @@ -51,8 +51,7 @@ describe(' logger', () => { await gitDDB.put({ _id: 'test' }); const log = fs.readFileSync(logPath, 'utf-8'); - expect(log.startsWith('\u001b[43m\u001b[30mStart: put()\u001b[0m')).toBeTruthy(); - + expect(log.startsWith('\u001b[43m\u001b[30mStart: put()')).toBeTruthy(); fs.removeSync(logPath); await gitDDB.destroy(); }); @@ -63,7 +62,7 @@ describe(' logger', () => { const gitDDB: GitDocumentDB = new GitDocumentDB({ dbName, localDir, - logLevel: 'silly', + logLevel: 'debug', logToTransport: (logObject: ILogObject) => { fs.appendFileSync(logPath, logObject.argumentsArray[0] + '\n'); }, diff --git a/test/remote_base/3way_merge_ot.ts b/test/remote_base/3way_merge_ot.ts index f1bc9e62..39e093f8 100644 --- a/test/remote_base/3way_merge_ot.ts +++ b/test/remote_base/3way_merge_ot.ts @@ -13,6 +13,7 @@ * These tests create a new repository on GitHub if not exists. */ import expect from 'expect'; +import { SerializeFormatFrontMatter } from '../../src/serialize_format'; import { GitDocumentDB } from '../../src/git_documentdb'; import { ConnectionSettings, @@ -633,7 +634,7 @@ export const threeWayMergeOtBase = ( putResultB1.fileOid, mergedJson, mergedDoc!.fileOid, - FRONT_MATTER_POSTFIX + dbA.serializeFormat ), ]); @@ -644,7 +645,7 @@ export const threeWayMergeOtBase = ( putResultA1dash.fileOid, mergedJson, mergedDoc!.fileOid, - FRONT_MATTER_POSTFIX + dbA.serializeFormat ), ]); @@ -658,10 +659,14 @@ export const threeWayMergeOtBase = ( ]); // Conflict occurs on 1.json - expect(getWorkingDirDocs(dbB, FRONT_MATTER_POSTFIX)).toEqual([mergedJson]); + expect(getWorkingDirDocs(dbB, new SerializeFormatFrontMatter())).toEqual([ + mergedJson, + ]); // Sync dbA const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; - expect(getWorkingDirDocs(dbA, FRONT_MATTER_POSTFIX)).toEqual([mergedJson]); + expect(getWorkingDirDocs(dbA, new SerializeFormatFrontMatter())).toEqual([ + mergedJson, + ]); await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); diff --git a/test/remote_base/combine.ts b/test/remote_base/combine.ts index 74dfa7a4..b19ec19e 100644 --- a/test/remote_base/combine.ts +++ b/test/remote_base/combine.ts @@ -31,6 +31,7 @@ import { } from '../remote_utils'; import { sleep } from '../../src/utils'; import { FRONT_MATTER_POSTFIX, JSON_POSTFIX } from '../../src/const'; +import { SerializeFormatFrontMatter } from '../../src/serialize_format'; export const syncCombineBase = ( connection: ConnectionSettings, @@ -557,7 +558,7 @@ export const syncCombineBase = ( const jsonB3 = { _id: '3', name: 'fromB' }; await dbB.put(jsonB3); - expect(getWorkingDirDocs(dbA, FRONT_MATTER_POSTFIX)).toEqual([jsonA1]); + expect(getWorkingDirDocs(dbA, new SerializeFormatFrontMatter())).toEqual([jsonA1]); // jsonB1 is duplicated with postfix due to combine-head-with-theirs strategy jsonB1._id = jsonB1._id + '-from-' + dbIdB; const duplicatedB1 = await dbB.getFatDoc(jsonB1._id + FRONT_MATTER_POSTFIX); @@ -581,7 +582,7 @@ export const syncCombineBase = ( }, ], }); - expect(getWorkingDirDocs(dbB, FRONT_MATTER_POSTFIX)).toEqual([ + expect(getWorkingDirDocs(dbB, new SerializeFormatFrontMatter())).toEqual([ jsonB2, jsonB3, jsonB1, @@ -590,7 +591,7 @@ export const syncCombineBase = ( const rawJSON = textToJsonDoc( fs.readFileSync(dbB.workingDir + '/deep/one.md', { encoding: 'utf8' }), - FRONT_MATTER_POSTFIX + dbA.serializeFormat ); rawJSON._id = 'one'; // not 'deep/one' diff --git a/test/remote_utils.ts b/test/remote_utils.ts index 95a9b078..abb1fcd9 100644 --- a/test/remote_utils.ts +++ b/test/remote_utils.ts @@ -18,12 +18,7 @@ import { } from '../src/types'; import { SyncInterface } from '../src/types_sync'; import { GitDocumentDB } from '../src/git_documentdb'; -import { - FILE_REMOVE_TIMEOUT, - FRONT_MATTER_POSTFIX, - GIT_DOCUMENTDB_METADATA_DIR, - JSON_POSTFIX, -} from '../src/const'; +import { FILE_REMOVE_TIMEOUT, GIT_DOCUMENTDB_METADATA_DIR } from '../src/const'; import { RemoteRepository } from '../src/remote/remote_repository'; import { SerializeFormatJSON } from '../src/serialize_format'; From 94ba94b08f709f17a12a0cbcbebd73947de6b247 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 19 Nov 2021 17:03:19 +0900 Subject: [PATCH 225/297] test: close db after open --- test/git_documentdb_open.test.ts | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/test/git_documentdb_open.test.ts b/test/git_documentdb_open.test.ts index b3081a29..d63695be 100644 --- a/test/git_documentdb_open.test.ts +++ b/test/git_documentdb_open.test.ts @@ -141,6 +141,7 @@ describe('', () => { }); expect(stubEnsureDir.callCount).toBe(5); // try 1 + retry 3 + push_worker 1 + await gitDDB.destroy(); }); it('creates a new repository.', async () => { @@ -160,7 +161,7 @@ describe('', () => { isNew: true, isCreatedByGitDDB: true, isValidVersion: true, - serializeFormat: 'json', + serialize: 'json', }); expect((dbOpenResult as DatabaseInfo).dbId).toMatch(/^[\dA-HJKMNP-TV-Z]{26}$/); @@ -221,6 +222,7 @@ describe('', () => { }); expect(stubInit.callCount).toBe(4); // try 1 + retry 3 + await gitDDB.destroy(); }); it('succeeds after retry putWorker in createRepository.', async () => { @@ -250,6 +252,8 @@ describe('', () => { }); expect(stubPut.callCount).toBe(4); // try 1 + retry 3 + + gitDDB.destroy(); }); }); @@ -298,7 +302,7 @@ describe('', () => { isNew: false, isCreatedByGitDDB: true, isValidVersion: true, - serializeFormat: 'json', + serialize: 'json', }); expect(gitDDB.isOpened).toBeTruthy(); @@ -335,7 +339,7 @@ describe('', () => { isNew: false, isCreatedByGitDDB: false, isValidVersion: false, - serializeFormat: 'json', + serialize: 'json', }); await gitDDB.destroy(); }); @@ -366,7 +370,7 @@ describe('', () => { isNew: false, isCreatedByGitDDB: true, isValidVersion: false, - serializeFormat: 'json', + serialize: 'json', }); await gitDDB.destroy(); }); @@ -398,8 +402,10 @@ describe('', () => { isNew: false, isCreatedByGitDDB: true, isValidVersion: true, - serializeFormat: 'json', + serialize: 'json', }); + + await gitDDB.destroy(); }); it('opens db twice.', async () => { @@ -428,7 +434,7 @@ describe('', () => { const gitDDB: GitDocumentDB = new GitDocumentDB({ dbName, localDir, - serializeFormat: 'front-matter', + serialize: 'front-matter', }); const dbOpenResult = await gitDDB.open(); @@ -440,7 +446,7 @@ describe('', () => { isNew: false, isCreatedByGitDDB: true, isValidVersion: true, - serializeFormat: 'front-matter', + serialize: 'front-matter', }); await gitDDB.destroy(); }); From a6c59113ad8c698f0ca39607b69c8749aba50abe Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 19 Nov 2021 17:07:29 +0900 Subject: [PATCH 226/297] test: add basic and crud tests for SerializeFormat --- .vscode/launch.json | 2 +- src/git_documentdb.ts | 8 +++++--- src/types.ts | 2 +- test/crud/get.test.ts | 6 ++++-- test/crud/put.test.ts | 10 +++++----- test/git_documentdb_crud.test.ts | 2 +- test/remote_base/3way_merge_ot.ts | 4 ++-- test/remote_base/combine.ts | 4 ++-- 8 files changed, 21 insertions(+), 17 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index d65c7e1d..5b6c20a2 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,7 +4,7 @@ "type": "pickString", "id": "choice", "description": "select a file", - "options": ["test/crud/delete.test.js"], + "options": ["test/git_documentdb_open.test.js"], }], "configurations": [ { diff --git a/src/git_documentdb.ts b/src/git_documentdb.ts index f70de58e..f33d6516 100644 --- a/src/git_documentdb.ts +++ b/src/git_documentdb.ts @@ -452,7 +452,7 @@ export class GitDocumentDB this._logToTransport = options.logToTransport; - const format: SerializeFormatLabel = options.serializeFormat ?? 'json'; + const format: SerializeFormatLabel = options.serialize ?? 'json'; if (format === 'front-matter') { this._serializeFormat = new SerializeFormatFrontMatter(); } @@ -623,7 +623,6 @@ export class GitDocumentDB if (this.isClosing) { throw new Err.DatabaseClosingError(); } - this._taskQueue.start(); if (this.isOpened) { this._dbOpenResult.isNew = false; @@ -645,8 +644,11 @@ export class GitDocumentDB throw new Err.RepositoryNotFoundError(gitDir); } } - await this.loadDbInfo(); + + // Start when no exception + this._taskQueue.start(); + return this._dbOpenResult; } diff --git a/src/types.ts b/src/types.ts index 70eda895..caf3f2f9 100644 --- a/src/types.ts +++ b/src/types.ts @@ -60,7 +60,7 @@ export type DatabaseOptions = { dbName: string; logLevel?: TLogLevelName; schema?: Schema; - serializeFormat?: SerializeFormatLabel; + serialize?: SerializeFormatLabel; logToTransport?: (logObject: ILogObject) => void; logColorEnabled?: boolean; }; diff --git a/test/crud/get.test.ts b/test/crud/get.test.ts index 6e7a95fa..6d7481f5 100644 --- a/test/crud/get.test.ts +++ b/test/crud/get.test.ts @@ -259,7 +259,9 @@ describe(' getImpl()', () => { const { oid } = await git.hashBlob({ object: toSortedJSONString(json) }); await addOneData(gitDDB, fullDocPath, toSortedJSONString(json)); await expect( - getImpl(gitDDB, shortName, collectionPath, gitDDB.serializeFormat, undefined, { oid }) + getImpl(gitDDB, shortName, collectionPath, gitDDB.serializeFormat, undefined, { + oid, + }) ).resolves.toEqual(json); await gitDDB.destroy(); @@ -915,7 +917,7 @@ b: bbb const gitDDB: GitDocumentDB = new GitDocumentDB({ dbName, localDir, - serializeFormat: 'front-matter', + serialize: 'front-matter', }); await gitDDB.open(); diff --git a/test/crud/put.test.ts b/test/crud/put.test.ts index e83ff992..4f9c00db 100644 --- a/test/crud/put.test.ts +++ b/test/crud/put.test.ts @@ -550,7 +550,7 @@ describe(' put to front matter', () => { const gitDDB: GitDocumentDB = new GitDocumentDB({ dbName, localDir, - serializeFormat: 'front-matter', + serialize: 'front-matter', }); await gitDDB.open(); await gitDDB.put({ @@ -585,7 +585,7 @@ The second line.`; const gitDDB: GitDocumentDB = new GitDocumentDB({ dbName, localDir, - serializeFormat: 'front-matter', + serialize: 'front-matter', }); await gitDDB.open(); await gitDDB.put({ @@ -620,7 +620,7 @@ The second line.`; const gitDDB: GitDocumentDB = new GitDocumentDB({ dbName, localDir, - serializeFormat: 'front-matter', + serialize: 'front-matter', }); await gitDDB.open(); await gitDDB.put({ @@ -646,7 +646,7 @@ a: 春はあけぼの const gitDDB: GitDocumentDB = new GitDocumentDB({ dbName, localDir, - serializeFormat: 'front-matter', + serialize: 'front-matter', }); await gitDDB.open(); await gitDDB.put({ @@ -668,7 +668,7 @@ a: bar const gitDDB: GitDocumentDB = new GitDocumentDB({ dbName, localDir, - serializeFormat: 'front-matter', + serialize: 'front-matter', }); await gitDDB.open(); await gitDDB.put({ diff --git a/test/git_documentdb_crud.test.ts b/test/git_documentdb_crud.test.ts index 665b858e..c47d456a 100644 --- a/test/git_documentdb_crud.test.ts +++ b/test/git_documentdb_crud.test.ts @@ -100,7 +100,7 @@ describe(' put(jsonDoc)', () => { const gitDDB: GitDocumentDB = new GitDocumentDB({ dbName, localDir, - serializeFormat: 'front-matter', + serialize: 'front-matter', }); await gitDDB.open(); const _id = 'prof01'; diff --git a/test/remote_base/3way_merge_ot.ts b/test/remote_base/3way_merge_ot.ts index 39e093f8..250bd913 100644 --- a/test/remote_base/3way_merge_ot.ts +++ b/test/remote_base/3way_merge_ot.ts @@ -562,7 +562,7 @@ export const threeWayMergeOtBase = ( dbName: dbNameA, localDir, schema, - serializeFormat: 'front-matter', + serialize: 'front-matter', }); const options: RemoteOptions = { @@ -585,7 +585,7 @@ export const threeWayMergeOtBase = ( dbName: dbNameB, localDir: localDir, schema, - serializeFormat: 'front-matter', + serialize: 'front-matter', }); // Clone dbA await dbB.open(); diff --git a/test/remote_base/combine.ts b/test/remote_base/combine.ts index b19ec19e..8a52a10c 100644 --- a/test/remote_base/combine.ts +++ b/test/remote_base/combine.ts @@ -513,7 +513,7 @@ export const syncCombineBase = ( const dbA: GitDocumentDB = new GitDocumentDB({ dbName: dbNameA, localDir, - serializeFormat: 'front-matter', + serialize: 'front-matter', }); const options: RemoteOptions = { @@ -536,7 +536,7 @@ export const syncCombineBase = ( const dbB: GitDocumentDB = new GitDocumentDB({ dbName: dbNameB, localDir, - serializeFormat: 'front-matter', + serialize: 'front-matter', }); await dbB.open(); From 88aee8b734297c9bd07e69d03f17c3a052006608 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 19 Nov 2021 19:28:35 +0900 Subject: [PATCH 227/297] test: add remote tests for SerializeFormat --- src/crud/blob.ts | 118 +++++++++------- src/crud/find.ts | 17 ++- src/crud/get.ts | 6 +- src/crud/history.ts | 17 ++- src/git_documentdb.ts | 3 +- src/remote/3way_merge.ts | 25 +++- src/remote/combine.ts | 3 +- src/remote/worker_utils.ts | 17 ++- test/crud/blob.test.ts | 130 +++++++++++++++--- test/remote_base/3way_merge.ts | 2 + test/remote_base/3way_merge_ot.ts | 12 +- test/remote_base/combine.ts | 83 +++++++++-- test/remote_base/on_sync_event.ts | 8 ++ test/remote_base/sync_events.ts | 3 +- .../remote_repository.test.ts | 1 - test/remote_utils.ts | 3 +- 16 files changed, 347 insertions(+), 101 deletions(-) diff --git a/src/crud/blob.ts b/src/crud/blob.ts index 122eb348..bd651128 100644 --- a/src/crud/blob.ts +++ b/src/crud/blob.ts @@ -9,7 +9,7 @@ import fs from 'fs'; import yaml from 'js-yaml'; import { readBlob, ReadBlobResult, resolveRef } from '@sosuisen/isomorphic-git'; -import { FRONT_MATTER_POSTFIX } from '../const'; +import { YAML_POSTFIX } from '../const'; import { utf8decode } from '../utils'; import { Err } from '../error'; import { @@ -29,56 +29,61 @@ import { export function textToJsonDoc ( text: string, serializeFormat: SerializeFormat, + extension: string, shortId?: string ): JsonDoc { let jsonDoc: JsonDoc; if (serializeFormat.format === 'front-matter') { - const mdArray = text.split('\n'); - let yamlText = ''; - let markdownText = ''; - let startFrontMatter = false; - let endFrontMatter = false; - for (let i = 0; i < mdArray.length; i++) { - if (mdArray[i] === '---') { - if (!startFrontMatter) { - startFrontMatter = true; - } - else if (!endFrontMatter) { - endFrontMatter = true; - } - continue; + if (extension === YAML_POSTFIX) { + try { + jsonDoc = yaml.load(text) as JsonDoc; + } catch { + throw new Err.InvalidJsonObjectError(shortId); } - if (startFrontMatter && !endFrontMatter) { - if (yamlText !== '') { - yamlText += '\n'; + if (jsonDoc === undefined) { + if (shortId !== undefined) { + jsonDoc = { + _id: shortId, + }; } - yamlText += mdArray[i]; - } - else if (endFrontMatter) { - if (markdownText !== '') { - markdownText += '\n'; + else { + jsonDoc = {}; } - markdownText += mdArray[i]; - } - } - if (!endFrontMatter) { - markdownText = text; - if (shortId !== undefined) { - jsonDoc = { - _id: shortId, - }; - } - else { - jsonDoc = {}; } } else { - try { - jsonDoc = yaml.load(yamlText) as JsonDoc; - } catch { - throw new Err.InvalidJsonObjectError(shortId); + const mdArray = text.split('\n'); + let yamlText = ''; + let markdownText = ''; + let startFrontMatter = false; + let endFrontMatter = false; + for (let i = 0; i < mdArray.length; i++) { + if (mdArray[i] === '---') { + // eslint-disable-next-line max-depth + if (!startFrontMatter) { + startFrontMatter = true; + } + else if (!endFrontMatter) { + endFrontMatter = true; + } + continue; + } + if (startFrontMatter && !endFrontMatter) { + if (yamlText !== '') { + yamlText += '\n'; + } + yamlText += mdArray[i]; + } + else if (endFrontMatter) { + if (markdownText !== '') { + markdownText += '\n'; + } + markdownText += mdArray[i]; + } } - if (jsonDoc === undefined) { + + if (!endFrontMatter) { + markdownText = text; if (shortId !== undefined) { jsonDoc = { _id: shortId, @@ -88,9 +93,26 @@ export function textToJsonDoc ( jsonDoc = {}; } } - } - if (markdownText !== '') { - jsonDoc._body = markdownText; + else { + try { + jsonDoc = yaml.load(yamlText) as JsonDoc; + } catch { + throw new Err.InvalidJsonObjectError(shortId); + } + if (jsonDoc === undefined) { + if (shortId !== undefined) { + jsonDoc = { + _id: shortId, + }; + } + else { + jsonDoc = {}; + } + } + } + if (markdownText !== '') { + jsonDoc._body = markdownText; + } } } else { @@ -112,10 +134,11 @@ export function blobToJsonDoc ( shortId: string, readBlobResult: ReadBlobResult, withMetadata: boolean, - serializeFormat: SerializeFormat + serializeFormat: SerializeFormat, + extension: string ): FatJsonDoc | JsonDoc { const text = utf8decode(readBlobResult.blob); - const jsonDoc = textToJsonDoc(text, serializeFormat, shortId); + const jsonDoc = textToJsonDoc(text, serializeFormat, extension, shortId); if (jsonDoc._id !== undefined) { // Overwrite _id property by shortId (_id without collectionPath) if JsonDoc is created by GitDocumentedDB (_id !== undefined). jsonDoc._id = shortId; @@ -141,10 +164,11 @@ export function blobToJsonDoc ( // eslint-disable-next-line complexity export function blobToJsonDocWithoutOverwrittenId ( readBlobResult: ReadBlobResult, - serializeFormat: SerializeFormat + serializeFormat: SerializeFormat, + extension: string ): JsonDoc { const text = utf8decode(readBlobResult.blob); - const jsonDoc = textToJsonDoc(text, serializeFormat); + const jsonDoc = textToJsonDoc(text, serializeFormat, extension); return jsonDoc; } diff --git a/src/crud/find.ts b/src/crud/find.ts index 4644f4e9..d359efc2 100644 --- a/src/crud/find.ts +++ b/src/crud/find.ts @@ -171,15 +171,28 @@ export async function findImpl ( } const shortName = fullDocPath.replace(new RegExp('^' + collectionPath), ''); if (docType === 'json') { + const [, extension] = fullDocPath.match(/.+(\..+?)$/)!; const shortId = serializeFormat.removeExtension(shortName); if (withMetadata) { docs.push( - blobToJsonDoc(shortId, readBlobResult, true, serializeFormat) as FatJsonDoc + blobToJsonDoc( + shortId, + readBlobResult, + true, + serializeFormat, + extension + ) as FatJsonDoc ); } else { docs.push( - blobToJsonDoc(shortId, readBlobResult, false, serializeFormat) as JsonDoc + blobToJsonDoc( + shortId, + readBlobResult, + false, + serializeFormat, + extension + ) as JsonDoc ); } } diff --git a/src/crud/get.ts b/src/crud/get.ts index 9ef5c0ce..9c23e377 100644 --- a/src/crud/get.ts +++ b/src/crud/get.ts @@ -106,15 +106,17 @@ export async function getImpl ( } if (docType === 'json') { + const [, extension] = fullDocPath.match(/.+(\..+?)$/)!; if (internalOptions.oid !== '') { - return blobToJsonDocWithoutOverwrittenId(readBlobResult, serializeFormat); + return blobToJsonDocWithoutOverwrittenId(readBlobResult, serializeFormat, extension); } const shortId = serializeFormat.removeExtension(shortName); return blobToJsonDoc( shortId, readBlobResult, internalOptions.withMetadata, - serializeFormat + serializeFormat, + extension ); } else if (docType === 'text') { diff --git a/src/crud/history.ts b/src/crud/history.ts index cf8e41ff..a77e3ce0 100644 --- a/src/crud/history.ts +++ b/src/crud/history.ts @@ -97,17 +97,30 @@ export async function getHistoryImpl ( docArray.push(undefined); } else if (docType === 'json') { + const [, extension] = fullDocPath.match(/.+(\..+?)$/)!; const shortId = serializeFormat.removeExtension(shortName); // eslint-disable-next-line max-depth if (withMetaData) { docArray.push( - blobToJsonDoc(shortId, readBlobResult, true, serializeFormat) as FatDoc + blobToJsonDoc( + shortId, + readBlobResult, + true, + serializeFormat, + extension + ) as FatDoc ); } else { docArray.push( - blobToJsonDoc(shortId, readBlobResult, false, serializeFormat) as Doc + blobToJsonDoc( + shortId, + readBlobResult, + false, + serializeFormat, + extension + ) as Doc ); } } diff --git a/src/git_documentdb.ts b/src/git_documentdb.ts index f33d6516..ebdad8a4 100644 --- a/src/git_documentdb.ts +++ b/src/git_documentdb.ts @@ -975,7 +975,8 @@ export class GitDocumentDB GIT_DOCUMENTDB_INFO_ID, readBlobResult, false, - new SerializeFormatJSON() + new SerializeFormatJSON(), + JSON_POSTFIX ) as DatabaseInfo; } catch (e) {} } diff --git a/src/remote/3way_merge.ts b/src/remote/3way_merge.ts index 6675c9fe..d13773c5 100644 --- a/src/remote/3way_merge.ts +++ b/src/remote/3way_merge.ts @@ -160,14 +160,15 @@ function getMergedDocument ( ours: Uint8Array, theirs: Uint8Array, docType: DocType, - serializeFormat: SerializeFormat + serializeFormat: SerializeFormat, + extension = '' ): string | Uint8Array { if (docType === 'json') { - const oursDoc = textToJsonDoc(utf8decode(ours), serializeFormat); - const theirsDoc = textToJsonDoc(utf8decode(theirs), serializeFormat); + const oursDoc = textToJsonDoc(utf8decode(ours), serializeFormat, extension); + const theirsDoc = textToJsonDoc(utf8decode(theirs), serializeFormat, extension); let baseDoc: JsonDoc | undefined; if (base) { - baseDoc = textToJsonDoc(utf8decode(base), serializeFormat); + baseDoc = textToJsonDoc(utf8decode(base), serializeFormat, extension); } else { baseDoc = undefined; @@ -523,6 +524,11 @@ export async function threeWayMerge ( } else { // Diff and patch + const extensionMatch = fullDocPath.match(/.+(\..+?)$/); + let extension = ''; + if (extensionMatch) { + extension = extensionMatch[1]; + } const data = await getMergedDocument( sync.jsonDiff, sync.jsonPatch, @@ -531,7 +537,8 @@ export async function threeWayMerge ( oursData, theirsData, docType, - gitDDB.serializeFormat + gitDDB.serializeFormat, + extension ); resultFatDoc = await getFatDocFromData( data, @@ -902,6 +909,11 @@ export async function threeWayMerge ( ]; } + const extensionMatch = fullDocPath.match(/.+(\..+?)$/); + let extension = ''; + if (extensionMatch) { + extension = extensionMatch[1]; + } const data = await getMergedDocument( sync.jsonDiff, sync.jsonPatch, @@ -910,7 +922,8 @@ export async function threeWayMerge ( oursData, theirsData, docType, - gitDDB.serializeFormat + gitDDB.serializeFormat, + extension ); const resultFatDoc = await getFatDocFromData( data, diff --git a/src/remote/combine.ts b/src/remote/combine.ts index 35169791..871043f6 100644 --- a/src/remote/combine.ts +++ b/src/remote/combine.ts @@ -142,7 +142,8 @@ export async function combineDatabaseWithTheirs ( const txt = fs.readFileSync(localFilePath, { encoding: 'utf8', }); - doc = textToJsonDoc(txt, gitDDB.serializeFormat); + const [, extension] = localFilePath.match(/.+(\..+?)$/)!; + doc = textToJsonDoc(txt, gitDDB.serializeFormat, extension); } else { doc = fs.readJSONSync(localFilePath); diff --git a/src/remote/worker_utils.ts b/src/remote/worker_utils.ts index d6f3c60b..34c45169 100644 --- a/src/remote/worker_utils.ts +++ b/src/remote/worker_utils.ts @@ -7,6 +7,7 @@ */ import nodePath from 'path'; +import { serialize } from 'v8'; import git, { ReadBlobResult, ReadCommitResult } from '@sosuisen/isomorphic-git'; import fs from 'fs-extra'; import { normalizeCommit, utf8decode } from '../utils'; @@ -61,7 +62,12 @@ export async function getFatDocFromData ( data = utf8decode(data); } try { - const jsonDoc = (textToJsonDoc(data, serializeFormat) as unknown) as JsonDoc; + const [, extension] = fullDocPath.match(/.+(\..+?)$/)!; + const jsonDoc = (textToJsonDoc( + data, + serializeFormat, + extension + ) as unknown) as JsonDoc; if (jsonDoc._id !== undefined) { // Overwrite _id property by _id if JsonDoc is created by GitDocumentedDB (_id !== undefined). jsonDoc._id = _id; @@ -133,7 +139,14 @@ export function getFatDocFromReadBlobResult ( let fatDoc: FatDoc; if (docType === 'json') { const _id = serializeFormat.removeExtension(fullDocPath); - fatDoc = blobToJsonDoc(_id, readBlobResult, true, serializeFormat) as FatJsonDoc; + const [, extension] = fullDocPath.match(/.+(\..+?)$/)!; + fatDoc = blobToJsonDoc( + _id, + readBlobResult, + true, + serializeFormat, + extension + ) as FatJsonDoc; } else if (docType === 'text') { fatDoc = blobToText(fullDocPath, readBlobResult, true) as FatTextDoc; diff --git a/test/crud/blob.test.ts b/test/crud/blob.test.ts index c956f230..d392e09d 100644 --- a/test/crud/blob.test.ts +++ b/test/crud/blob.test.ts @@ -23,8 +23,13 @@ import { } from '../../src/crud/blob'; import { Err } from '../../src/error'; import { GitDocumentDB } from '../../src/git_documentdb'; -import { toFrontMatterMarkdown, toSortedJSONString, utf8encode } from '../../src/utils'; -import { JSON_POSTFIX } from '../../src/const'; +import { + toFrontMatterMarkdown, + toSortedJSONString, + toYAML, + utf8encode, +} from '../../src/utils'; +import { FRONT_MATTER_POSTFIX, JSON_POSTFIX, YAML_POSTFIX } from '../../src/const'; import { SerializeFormatFrontMatter, SerializeFormatJSON, @@ -66,7 +71,13 @@ describe('', () => { blob: utf8encode(text), }; expect(() => - blobToJsonDoc(shortId, readBlobResult, false, new SerializeFormatJSON()) + blobToJsonDoc( + shortId, + readBlobResult, + false, + new SerializeFormatJSON(), + JSON_POSTFIX + ) ).toThrowError(Err.InvalidJsonObjectError); }); @@ -79,7 +90,13 @@ describe('', () => { blob: utf8encode(text), }; expect( - blobToJsonDoc(shortId, readBlobResult, false, new SerializeFormatJSON()) + blobToJsonDoc( + shortId, + readBlobResult, + false, + new SerializeFormatJSON(), + JSON_POSTFIX + ) ).toEqual(json); }); @@ -91,7 +108,13 @@ describe('', () => { blob: utf8encode(text), }; expect( - blobToJsonDoc(shortId, readBlobResult, false, new SerializeFormatFrontMatter()) + blobToJsonDoc( + shortId, + readBlobResult, + false, + new SerializeFormatFrontMatter(), + FRONT_MATTER_POSTFIX + ) ).toEqual({ _id: 'foo', }); @@ -105,7 +128,13 @@ describe('', () => { blob: utf8encode(text), }; expect( - blobToJsonDoc(shortId, readBlobResult, false, new SerializeFormatFrontMatter()) + blobToJsonDoc( + shortId, + readBlobResult, + false, + new SerializeFormatFrontMatter(), + FRONT_MATTER_POSTFIX + ) ).toEqual({ _id: 'foo', _body: text, @@ -120,7 +149,13 @@ describe('', () => { blob: utf8encode(text), }; expect( - blobToJsonDoc(shortId, readBlobResult, false, new SerializeFormatFrontMatter()) + blobToJsonDoc( + shortId, + readBlobResult, + false, + new SerializeFormatFrontMatter(), + FRONT_MATTER_POSTFIX + ) ).toEqual({ _id: 'foo', _body: text, @@ -136,7 +171,13 @@ describe('', () => { blob: utf8encode(text), }; expect( - blobToJsonDoc(shortId, readBlobResult, false, new SerializeFormatFrontMatter()) + blobToJsonDoc( + shortId, + readBlobResult, + false, + new SerializeFormatFrontMatter(), + FRONT_MATTER_POSTFIX + ) ).toEqual(json); }); @@ -149,20 +190,32 @@ describe('', () => { blob: utf8encode(text), }; expect( - blobToJsonDoc(shortId, readBlobResult, false, new SerializeFormatFrontMatter()) + blobToJsonDoc( + shortId, + readBlobResult, + false, + new SerializeFormatFrontMatter(), + FRONT_MATTER_POSTFIX + ) ).toEqual(json); }); - it('returns JsonDoc of Front-Matter without Markdown', async () => { + it('returns JsonDoc of YAML without Markdown', async () => { const shortId = 'foo'; const json = { _id: shortId, propA: 'A', propB: 'B' }; - const text = toFrontMatterMarkdown(json); + const text = toYAML(json); const readBlobResult: ReadBlobResult = { oid: (await git.hashBlob({ object: text })).oid, blob: utf8encode(text), }; expect( - blobToJsonDoc(shortId, readBlobResult, false, new SerializeFormatFrontMatter()) + blobToJsonDoc( + shortId, + readBlobResult, + false, + new SerializeFormatFrontMatter(), + YAML_POSTFIX + ) ).toEqual(json); }); @@ -177,7 +230,13 @@ describe('', () => { blob: utf8encode(text), }; expect( - blobToJsonDoc(shortId2, readBlobResult, false, new SerializeFormatJSON()) + blobToJsonDoc( + shortId2, + readBlobResult, + false, + new SerializeFormatJSON(), + JSON_POSTFIX + ) ).toEqual(json2); }); @@ -191,7 +250,13 @@ describe('', () => { blob: utf8encode(text), }; expect( - blobToJsonDoc(shortId, readBlobResult, true, new SerializeFormatJSON()) + blobToJsonDoc( + shortId, + readBlobResult, + true, + new SerializeFormatJSON(), + JSON_POSTFIX + ) ).toEqual({ _id: shortId, name: shortId + JSON_POSTFIX, @@ -210,7 +275,11 @@ describe('', () => { blob: utf8encode(text), }; expect(() => - blobToJsonDocWithoutOverwrittenId(readBlobResult, new SerializeFormatJSON()) + blobToJsonDocWithoutOverwrittenId( + readBlobResult, + new SerializeFormatJSON(), + JSON_POSTFIX + ) ).toThrowError(Err.InvalidJsonObjectError); }); @@ -223,20 +292,45 @@ describe('', () => { blob: utf8encode(text), }; expect( - blobToJsonDocWithoutOverwrittenId(readBlobResult, new SerializeFormatJSON()) + blobToJsonDocWithoutOverwrittenId( + readBlobResult, + new SerializeFormatJSON(), + JSON_POSTFIX + ) ).toEqual(json); }); it('returns JsonDoc in FrontMatterMarkdown', async () => { const shortId = 'foo'; - const json = { _id: shortId, name: 'bar' }; + const json = { _id: shortId, name: 'bar', _body: 'baz' }; const text = toFrontMatterMarkdown(json); const readBlobResult: ReadBlobResult = { oid: (await git.hashBlob({ object: text })).oid, blob: utf8encode(text), }; expect( - blobToJsonDocWithoutOverwrittenId(readBlobResult, new SerializeFormatFrontMatter()) + blobToJsonDocWithoutOverwrittenId( + readBlobResult, + new SerializeFormatFrontMatter(), + FRONT_MATTER_POSTFIX + ) + ).toEqual(json); + }); + + it('returns JsonDoc in YAML', async () => { + const shortId = 'foo'; + const json = { _id: shortId, name: 'bar' }; + const text = toYAML(json); + const readBlobResult: ReadBlobResult = { + oid: (await git.hashBlob({ object: text })).oid, + blob: utf8encode(text), + }; + expect( + blobToJsonDocWithoutOverwrittenId( + readBlobResult, + new SerializeFormatFrontMatter(), + YAML_POSTFIX + ) ).toEqual(json); }); }); diff --git a/test/remote_base/3way_merge.ts b/test/remote_base/3way_merge.ts index c3fd803c..b788af9c 100644 --- a/test/remote_base/3way_merge.ts +++ b/test/remote_base/3way_merge.ts @@ -68,6 +68,8 @@ export const syncThreeWayMergeBase = ( // @ts-ignore threeWayMerge(dbA, syncA, 'ours-diff', 'foo', undefined, undefined, undefined) ).rejects.toThrowError(Err.InvalidConflictStateError); + + await destroyDBs([dbA, dbB]); }); /** diff --git a/test/remote_base/3way_merge_ot.ts b/test/remote_base/3way_merge_ot.ts index 250bd913..7fd3616d 100644 --- a/test/remote_base/3way_merge_ot.ts +++ b/test/remote_base/3way_merge_ot.ts @@ -35,7 +35,7 @@ import { removeRemoteRepositories, } from '../remote_utils'; -import { FRONT_MATTER_POSTFIX, JSON_POSTFIX } from '../../src/const'; +import { FRONT_MATTER_POSTFIX, JSON_POSTFIX, YAML_POSTFIX } from '../../src/const'; export const threeWayMergeOtBase = ( connection: ConnectionSettings, @@ -577,7 +577,7 @@ export const threeWayMergeOtBase = ( // A puts and pushes const jsonA1 = { _id: '1', name: 'Hello, world!' }; - const putResultA1 = await dbA.put(jsonA1); + await dbA.put(jsonA1); await syncA.tryPush(); const dbNameB = serialId(); @@ -605,23 +605,23 @@ export const threeWayMergeOtBase = ( const mergedJson = { _id: '1', name: 'Hello Hello, Nara!' }; - // It will occur conflict on id 1.json. + // It will occur conflict on id 1.yml. const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; - const mergedDoc = await dbB.getFatDoc('1.md'); + const mergedDoc = await dbB.getFatDoc('1.yml'); expect(syncResult1.action).toBe('resolve conflicts and push'); expect(syncResult1.commits).toMatchObject({ local: getCommitInfo([ putResultA1dash, - `resolve: 1${FRONT_MATTER_POSTFIX}(update-merge,${mergedDoc!.fileOid.substr( + `resolve: 1${YAML_POSTFIX}(update-merge,${mergedDoc!.fileOid.substr( 0, 7 )},theirs-diff)`, ]), remote: getCommitInfo([ putResultB1, - `resolve: 1${FRONT_MATTER_POSTFIX}(update-merge,${mergedDoc!.fileOid.substr( + `resolve: 1${YAML_POSTFIX}(update-merge,${mergedDoc!.fileOid.substr( 0, 7 )},theirs-diff)`, diff --git a/test/remote_base/combine.ts b/test/remote_base/combine.ts index 8a52a10c..4d81e047 100644 --- a/test/remote_base/combine.ts +++ b/test/remote_base/combine.ts @@ -30,7 +30,7 @@ import { removeRemoteRepositories, } from '../remote_utils'; import { sleep } from '../../src/utils'; -import { FRONT_MATTER_POSTFIX, JSON_POSTFIX } from '../../src/const'; +import { FRONT_MATTER_POSTFIX, JSON_POSTFIX, YAML_POSTFIX } from '../../src/const'; import { SerializeFormatFrontMatter } from '../../src/serialize_format'; export const syncCombineBase = ( @@ -561,7 +561,7 @@ export const syncCombineBase = ( expect(getWorkingDirDocs(dbA, new SerializeFormatFrontMatter())).toEqual([jsonA1]); // jsonB1 is duplicated with postfix due to combine-head-with-theirs strategy jsonB1._id = jsonB1._id + '-from-' + dbIdB; - const duplicatedB1 = await dbB.getFatDoc(jsonB1._id + FRONT_MATTER_POSTFIX); + const duplicatedB1 = await dbB.getFatDoc(jsonB1._id + YAML_POSTFIX); expect(syncResult).toEqual({ action: 'combine database', @@ -569,13 +569,13 @@ export const syncCombineBase = ( { original: { _id: jsonA1._id, - name: jsonA1._id + FRONT_MATTER_POSTFIX, + name: jsonA1._id + YAML_POSTFIX, fileOid: putResultA1.fileOid, type: 'json', }, duplicate: { _id: jsonB1._id, - name: jsonB1._id + FRONT_MATTER_POSTFIX, + name: jsonB1._id + YAML_POSTFIX, fileOid: duplicatedB1?.fileOid, type: 'json', }, @@ -589,17 +589,80 @@ export const syncCombineBase = ( jsonA1, ]); - const rawJSON = textToJsonDoc( - fs.readFileSync(dbB.workingDir + '/deep/one.md', { encoding: 'utf8' }), - dbA.serializeFormat - ); - rawJSON._id = 'one'; // not 'deep/one' - await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); await destroyDBs([dbA, dbB]); }); }); + + it('has another extension', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir, + serialize: 'front-matter', + }); + + const options: RemoteOptions = { + remoteUrl: remoteURL, + combineDbStrategy: 'combine-head-with-theirs', + syncDirection: 'both', + connection, + }; + + await dbA.open(); + const syncA = await dbA.sync(options); + + const dbIdA = dbA.dbId; + + const jsonA1 = { _id: 'deep/one', name: 'fromA', _body: 'foo' }; // FrontMatter + Markdown + await dbA.put(jsonA1); + await syncA.trySync(); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir, + serialize: 'front-matter', + }); + await dbB.open(); + + const dbIdB = dbB.dbId; + expect(dbIdB).not.toBe(dbIdA); + + const jsonB1 = { _id: 'deep/one', name: 'fromB' }; // YAML + await dbB.put(jsonB1); + + // Combine with remote db + const [sync, syncResult] = await dbB.sync(syncA.options, true); + + expect(dbB.dbId).toBe(dbIdA); + + expect(getWorkingDirDocs(dbA, new SerializeFormatFrontMatter())).toEqual([jsonA1]); + + // Not duplicate because extension is different. + const fatDocA = await dbB.getFatDoc(jsonA1._id + FRONT_MATTER_POSTFIX); + expect(fatDocA?.doc).toEqual(jsonA1); + + const fatDocB = await dbB.getFatDoc(jsonB1._id + YAML_POSTFIX); + expect(fatDocB?.doc).toEqual(jsonB1); + + expect(syncResult).toEqual({ + action: 'combine database', + duplicates: [], + }); + + expect(getWorkingDirDocs(dbB, new SerializeFormatFrontMatter())).toEqual([ + jsonA1, + jsonB1, + ]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + + await destroyDBs([dbA, dbB]); + }); }); }; diff --git a/test/remote_base/on_sync_event.ts b/test/remote_base/on_sync_event.ts index 580d597d..35c7a8f5 100644 --- a/test/remote_base/on_sync_event.ts +++ b/test/remote_base/on_sync_event.ts @@ -113,6 +113,8 @@ export const onSyncEventBase = ( expect(() => { dbA.onSyncEvent('https://test.example.com', 'change', () => {}); }).toThrowError(Err.UndefinedSyncError); + + await destroyDBs([dbA]); }); it('with sync', async () => { @@ -202,6 +204,8 @@ export const onSyncEventBase = ( expect(() => { dbA.offSyncEvent('https://test.example.com', 'change', () => {}); }).toThrowError(Err.UndefinedSyncError); + + await destroyDBs([dbA]); }); it('with sync', async () => { @@ -295,6 +299,8 @@ export const onSyncEventBase = ( expect(() => { colA.onSyncEvent('https://test.example.com', 'change', () => {}); }).toThrowError(Err.UndefinedSyncError); + + await destroyDBs([dbA]); }); it('with sync', async () => { @@ -389,6 +395,8 @@ export const onSyncEventBase = ( expect(() => { colA.offSyncEvent('https://test.example.com', 'change', () => {}); }).toThrowError(Err.UndefinedSyncError); + + await destroyDBs([dbA]); }); it('with sync', async () => { diff --git a/test/remote_base/sync_events.ts b/test/remote_base/sync_events.ts index cb7cfbf9..d588f197 100644 --- a/test/remote_base/sync_events.ts +++ b/test/remote_base/sync_events.ts @@ -39,9 +39,8 @@ import { removeRemoteRepositories, } from '../remote_utils'; import { GitDocumentDB } from '../../src/git_documentdb'; -import { RemoteEngine, RemoteErr } from '../../src/remote/remote_engine'; +import { RemoteErr } from '../../src/remote/remote_engine'; import { Sync } from '../../src/remote/sync'; -import { Err } from '../../src/error'; import { MINIMUM_SYNC_INTERVAL } from '../../src/const'; // eslint-disable-next-line @typescript-eslint/no-var-requires diff --git a/test/remote_repository/remote_repository.test.ts b/test/remote_repository/remote_repository.test.ts index b5051ef3..36220b60 100644 --- a/test/remote_repository/remote_repository.test.ts +++ b/test/remote_repository/remote_repository.test.ts @@ -16,7 +16,6 @@ import path from 'path'; import { Octokit } from '@octokit/rest'; import expect from 'expect'; import fs from 'fs-extra'; -import { monotonicFactory } from 'ulid'; import { Err } from '../../src/error'; import { NETWORK_RETRY, NETWORK_RETRY_INTERVAL } from '../../src/const'; import { diff --git a/test/remote_utils.ts b/test/remote_utils.ts index abb1fcd9..6fb342f6 100644 --- a/test/remote_utils.ts +++ b/test/remote_utils.ts @@ -389,7 +389,8 @@ export const getWorkingDirDocs = ( return listFiles(gitDDB, gitDDB.workingDir).map(filepath => { if (serializeFormat.format === 'front-matter') { const txt = fs.readFileSync(gitDDB.workingDir + '/' + filepath, { encoding: 'utf8' }); - const doc = textToJsonDoc(txt, serializeFormat); + const [, extension] = filepath.match(/.+(\..+?)$/)!; + const doc = textToJsonDoc(txt, serializeFormat, extension); doc._id = serializeFormat.removeExtension(filepath); return doc; } From b9c71abf904c801e55c91f9b10e695948781b168 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sat, 20 Nov 2021 01:26:25 +0900 Subject: [PATCH 228/297] test: pass tests --- src/crud/get.ts | 6 +++++- test/remote_base/sync.ts | 2 +- test/remote_base/sync_events.ts | 4 ++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/crud/get.ts b/src/crud/get.ts index 9c23e377..0d05b9ed 100644 --- a/src/crud/get.ts +++ b/src/crud/get.ts @@ -106,7 +106,11 @@ export async function getImpl ( } if (docType === 'json') { - const [, extension] = fullDocPath.match(/.+(\..+?)$/)!; + const extMatch = fullDocPath.match(/.+(\..+?)$/)!; + let extension = ''; + if (extMatch) { + extension = extMatch[1]; + } if (internalOptions.oid !== '') { return blobToJsonDocWithoutOverwrittenId(readBlobResult, serializeFormat, extension); } diff --git a/test/remote_base/sync.ts b/test/remote_base/sync.ts index e67fc4e9..9a1d34d9 100644 --- a/test/remote_base/sync.ts +++ b/test/remote_base/sync.ts @@ -1160,7 +1160,7 @@ export const syncBase = ( await dbB.put(jsonB2); await syncB.trySync(); - await sleep(remoteOptions01.interval! * 2); + await sleep(remoteOptions01.interval! * 3); await expect(gitDDB.get('1')).resolves.toEqual(jsonA1); await expect(gitDDB.get('2')).resolves.toEqual(jsonB2); diff --git a/test/remote_base/sync_events.ts b/test/remote_base/sync_events.ts index d588f197..735f628d 100644 --- a/test/remote_base/sync_events.ts +++ b/test/remote_base/sync_events.ts @@ -1100,8 +1100,8 @@ export const syncEventsBase = ( // eslint-disable-next-line no-unmodified-loop-condition while (!complete) { // eslint-disable-next-line no-await-in-loop - await sleep(1000); - sleepTime += 1000; + await sleep(700); + sleepTime += 700; } expect(complete).toBe(true); From 96eab43afe3244d371ea8604912576acc019e4fe Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sat, 20 Nov 2021 12:31:35 +0900 Subject: [PATCH 229/297] test: add test for front-matter --- test/crud/blob.test.ts | 32 +++++++ test/remote_base/3way_merge.ts | 104 +++++++++++++++++++++- test/remote_base/3way_merge_ot.ts | 143 +++++++++++++++++++++++++++++- test/remote_utils.ts | 6 +- 4 files changed, 282 insertions(+), 3 deletions(-) diff --git a/test/crud/blob.test.ts b/test/crud/blob.test.ts index d392e09d..c35f6c1d 100644 --- a/test/crud/blob.test.ts +++ b/test/crud/blob.test.ts @@ -219,6 +219,20 @@ describe('', () => { ).toEqual(json); }); + it('returns JsonDoc of Markdown when file extension is unknown', async () => { + const shortId = 'foo'; + const json = { _id: shortId, propA: 'A', propB: 'B' }; + const jsonMarkdown = { _id: shortId, _body: '_id: foo\npropA: A\npropB: B\n' }; + const text = toYAML(json); + const readBlobResult: ReadBlobResult = { + oid: (await git.hashBlob({ object: text })).oid, + blob: utf8encode(text), + }; + expect( + blobToJsonDoc(shortId, readBlobResult, false, new SerializeFormatFrontMatter(), '') + ).toEqual(jsonMarkdown); + }); + it('returns JsonDoc with overwritten _id', async () => { const shortId = 'foo'; const shortId2 = 'foo'; @@ -333,6 +347,24 @@ describe('', () => { ) ).toEqual(json); }); + + it('returns JsonDoc of Markdown when shortId and file extension is unknown', async () => { + const shortId = 'foo'; + const json = { _id: shortId, propA: 'A', propB: 'B' }; + const jsonMarkdown = { _body: '_id: foo\npropA: A\npropB: B\n' }; + const text = toYAML(json); + const readBlobResult: ReadBlobResult = { + oid: (await git.hashBlob({ object: text })).oid, + blob: utf8encode(text), + }; + expect( + blobToJsonDocWithoutOverwrittenId( + readBlobResult, + new SerializeFormatFrontMatter(), + '' + ) + ).toEqual(jsonMarkdown); + }); }); describe('blobToText', () => { diff --git a/test/remote_base/3way_merge.ts b/test/remote_base/3way_merge.ts index b788af9c..a54f5909 100644 --- a/test/remote_base/3way_merge.ts +++ b/test/remote_base/3way_merge.ts @@ -35,7 +35,7 @@ import { getWorkingDirDocs, removeRemoteRepositories, } from '../remote_utils'; -import { JSON_POSTFIX } from '../../src/const'; +import { JSON_POSTFIX, YAML_POSTFIX } from '../../src/const'; export const syncThreeWayMergeBase = ( connection: ConnectionSettings, @@ -1750,4 +1750,106 @@ export const syncThreeWayMergeBase = ( await destroyDBs([dbA, dbB]); }); }); + + describe('with front-matter', () => { + /** + * before: + * dbA : jsonA1 jsonA2.yml + * dbB : jsonB1 jsonB2.md + * after : jsonB1 jsonA2.yml jsonB2.md + * + * 3-way merge: + * jsonB1: 4 - Conflict. Accept ours (insert) + * jsonA2: 1 - Accept theirs (insert) + * jsonB2: 2 - Accept ours (insert) + */ + it('files have the same name but different extension: resolves case 1 - Accept theirs (insert), case 2 - Accept ours (insert), case 4 - Conflict. Accept ours (insert)', async () => { + const [dbA, dbB, syncA, syncB] = await createClonedDatabases( + remoteURLBase, + localDir, + serialId, + { + conflictResolutionStrategy: 'ours', + connection, + }, + 'info', + 'front-matter' + ); + + // A puts and pushes + const jsonA1 = { _id: '1', name: 'fromA' }; + const putResultA1 = await dbA.put(jsonA1); + const jsonA2 = { _id: '2', name: 'fromA' }; // 2.yml + const putResultA2 = await dbA.put(jsonA2); + await syncA.tryPush(); + + // B puts the same file + const jsonB1 = { _id: '1', name: 'fromB' }; + const putResultB1 = await dbB.put(jsonB1); + + // B puts a new file + const jsonB2 = { _id: '2', name: 'fromB', _body: 'bodyFromB' }; // 2.md + const putResultB2 = await dbB.put(jsonB2); + + // It will occur conflict on id 1.json. + const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; + expect(syncResult1.action).toBe('resolve conflicts and push'); + expect(syncResult1.commits).toMatchObject({ + local: getCommitInfo([ + putResultA1, + putResultA2, + `resolve: 1${YAML_POSTFIX}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + ]), + remote: getCommitInfo([ + putResultB1, + putResultB2, + `resolve: 1${YAML_POSTFIX}(insert,${putResultB1.fileOid.substr(0, 7)},ours)`, + ]), + }); + expect(syncResult1.changes.local.length).toBe(1); + expect(syncResult1.changes.local).toEqual([ + getChangedFileInsert(jsonA2, putResultA2, dbA.serializeFormat), + ]); + + expect(syncResult1.changes.remote.length).toBe(2); + expect(syncResult1.changes.remote).toEqual( + expect.arrayContaining([ + getChangedFileInsert(jsonB2, putResultB2, dbB.serializeFormat), + getChangedFileUpdate( + jsonA1, + putResultA1, + jsonB1, + putResultB1, + dbA.serializeFormat + ), + ]) + ); + + expect(syncResult1.conflicts.length).toEqual(1); + expect(syncResult1.conflicts).toEqual([ + { + fatDoc: { + _id: '1', + name: '1.yml', + fileOid: putResultB1.fileOid, + type: 'json', + doc: jsonB1, + }, + strategy: 'ours', + operation: 'insert', + }, + ]); + // Conflict occurs on 1.json + + expect(getWorkingDirDocs(dbB, dbB.serializeFormat)).toEqual([jsonB1, jsonB2, jsonA2]); + // Sync dbA + await syncA.trySync(); + expect(getWorkingDirDocs(dbA, dbA.serializeFormat)).toEqual([jsonB1, jsonB2, jsonA2]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + + await destroyDBs([dbA, dbB]); + }); + }); }; diff --git a/test/remote_base/3way_merge_ot.ts b/test/remote_base/3way_merge_ot.ts index 7fd3616d..25a0b658 100644 --- a/test/remote_base/3way_merge_ot.ts +++ b/test/remote_base/3way_merge_ot.ts @@ -550,7 +550,7 @@ export const threeWayMergeOtBase = ( * 3-way merge: * mergedJson:17 - Conflict. Accept theirs (update-merge) */ - it('resolves case 17 - Conflict. Accept theirs (update-merge) in FrontMatterMarkdown', async () => { + it('resolves case 17 - Conflict. Accept theirs (update-merge) in FrontMatterMarkdown with .yml', async () => { const schema: Schema = { json: { plainTextProperties: { name: true } }, }; @@ -674,6 +674,147 @@ export const threeWayMergeOtBase = ( await destroyDBs([dbA, dbB]); }); + /** + * before: jsonA1 + * dbA : +jsonA1 + * dbB : jsonB1 + * after : mergedJson + * + * 3-way merge: + * mergedJson:17 - Conflict. Accept theirs (update-merge) + */ + it('resolves case 17 - Conflict. Accept theirs (update-merge) in FrontMatterMarkdown with .md', async () => { + const schema: Schema = { + json: { plainTextProperties: { name: true, _body: true } }, + }; + const remoteURL = remoteURLBase + serialId(); + + const dbNameA = serialId(); + + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir, + schema, + serialize: 'front-matter', + }); + + const options: RemoteOptions = { + remoteUrl: remoteURL, + includeCommits: true, + conflictResolutionStrategy: 'theirs-diff', + connection, + }; + + await dbA.open(); + const syncA = await dbA.sync(options); + + // A puts and pushes + const jsonA1 = { _id: '1', name: 'Hello, world!', _body: 'Hello, world!' }; + await dbA.put(jsonA1); + await syncA.tryPush(); + + const dbNameB = serialId(); + const dbB: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameB, + localDir: localDir, + schema, + serialize: 'front-matter', + }); + // Clone dbA + await dbB.open(); + const syncB = await dbB.sync({ + ...syncA.options, + conflictResolutionStrategy: 'theirs-diff', + }); + + // A puts and pushes + const jsonA1dash = { _id: '1', name: 'Hello', _body: 'Welcome!' }; + const putResultA1dash = await dbA.put(jsonA1dash); + await syncA.tryPush(); + + // B puts + const jsonB1 = { + _id: '1', + name: 'Hello, world! Hello, Nara!', + _body: 'Hello, world! Hello, Nara!', + }; + const putResultB1 = await dbB.put(jsonB1); + + const mergedJson = { + _id: '1', + name: 'Hello Hello, Nara!', + _body: 'Welcome! Hello, Nara!', + }; + + // It will occur conflict on id 1.yml. + const syncResult1 = (await syncB.trySync()) as SyncResultResolveConflictsAndPush; + + const mergedDoc = await dbB.getFatDoc('1.md'); + + expect(syncResult1.action).toBe('resolve conflicts and push'); + expect(syncResult1.commits).toMatchObject({ + local: getCommitInfo([ + putResultA1dash, + `resolve: 1${FRONT_MATTER_POSTFIX}(update-merge,${mergedDoc!.fileOid.substr( + 0, + 7 + )},theirs-diff)`, + ]), + remote: getCommitInfo([ + putResultB1, + `resolve: 1${FRONT_MATTER_POSTFIX}(update-merge,${mergedDoc!.fileOid.substr( + 0, + 7 + )},theirs-diff)`, + ]), + }); + expect(syncResult1.changes.local.length).toBe(1); + expect(syncResult1.changes.local).toEqual([ + getChangedFileUpdateBySHA( + jsonB1, + putResultB1.fileOid, + mergedJson, + mergedDoc!.fileOid, + dbA.serializeFormat + ), + ]); + + expect(syncResult1.changes.remote.length).toBe(1); + expect(syncResult1.changes.remote).toEqual([ + getChangedFileUpdateBySHA( + jsonA1dash, + putResultA1dash.fileOid, + mergedJson, + mergedDoc!.fileOid, + dbA.serializeFormat + ), + ]); + + expect(syncResult1.conflicts.length).toEqual(1); + expect(syncResult1.conflicts).toEqual([ + { + fatDoc: mergedDoc, + strategy: 'theirs-diff', + operation: 'update-merge', + }, + ]); + // Conflict occurs on 1.json + + expect(getWorkingDirDocs(dbB, new SerializeFormatFrontMatter())).toEqual([ + mergedJson, + ]); + // Sync dbA + const syncResult2 = (await syncA.trySync()) as SyncResultMergeAndPush; + expect(getWorkingDirDocs(dbA, new SerializeFormatFrontMatter())).toEqual([ + mergedJson, + ]); + + await expect(compareWorkingDirAndBlobs(dbA)).resolves.toBeTruthy(); + await expect(compareWorkingDirAndBlobs(dbB)).resolves.toBeTruthy(); + + await destroyDBs([dbA, dbB]); + }); + describe('plaintext-OT Type', () => { /** * before: jsonA1 diff --git a/test/remote_utils.ts b/test/remote_utils.ts index 6fb342f6..ebbbeaea 100644 --- a/test/remote_utils.ts +++ b/test/remote_utils.ts @@ -15,6 +15,7 @@ import { RemoteOptions, Schema, SerializeFormat, + SerializeFormatLabel, } from '../src/types'; import { SyncInterface } from '../src/types_sync'; import { GitDocumentDB } from '../src/git_documentdb'; @@ -214,7 +215,8 @@ export async function createClonedDatabases ( localDir: string, serialId: () => string, options?: RemoteOptions, - logLevel?: 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal' + logLevel?: 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal', + serialize: SerializeFormatLabel = 'json' ): Promise<[GitDocumentDB, GitDocumentDB, SyncInterface, SyncInterface]> { const remoteURL = remoteURLBase + serialId(); @@ -224,6 +226,7 @@ export async function createClonedDatabases ( dbName: dbNameA, localDir, logLevel: logLevel ?? 'info', + serialize, }); options ??= { remoteUrl: remoteURL, @@ -240,6 +243,7 @@ export async function createClonedDatabases ( dbName: dbNameB, localDir, logLevel: logLevel ?? 'info', + serialize, }); // Clone dbA await dbB.open(); From 367e36ef4eaad91131f22189d04b5ad9d563bed6 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sat, 20 Nov 2021 19:08:16 +0900 Subject: [PATCH 230/297] test: fix comments --- test/remote_base/combine.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/remote_base/combine.ts b/test/remote_base/combine.ts index 4d81e047..5d590c95 100644 --- a/test/remote_base/combine.ts +++ b/test/remote_base/combine.ts @@ -17,7 +17,6 @@ import fs from 'fs-extra'; import git from '@sosuisen/isomorphic-git'; import expect from 'expect'; import parse from 'parse-git-config'; -import { textToJsonDoc } from '../../src/crud/blob'; import { Err } from '../../src/error'; import { ConnectionSettings, DuplicatedFile, RemoteOptions } from '../../src/types'; import { GitDocumentDB } from '../../src/git_documentdb'; @@ -506,7 +505,8 @@ export const syncCombineBase = ( await destroyDBs([dbA, dbB]); }); }); - describe('with same serializeFormat', () => { + + describe('with same serializeFormat (front-matter)', () => { it('returns SyncResult with duplicates when combine-head-with-theirs with deep local and deep remote', async () => { const remoteURL = remoteURLBase + serialId(); const dbNameA = serialId(); @@ -596,7 +596,7 @@ export const syncCombineBase = ( }); }); - it('has another extension', async () => { + it('includes files which have the same name with another extension (.md, .yml)', async () => { const remoteURL = remoteURLBase + serialId(); const dbNameA = serialId(); const dbA: GitDocumentDB = new GitDocumentDB({ @@ -617,7 +617,7 @@ export const syncCombineBase = ( const dbIdA = dbA.dbId; - const jsonA1 = { _id: 'deep/one', name: 'fromA', _body: 'foo' }; // FrontMatter + Markdown + const jsonA1 = { _id: 'deep/one', name: 'fromA', _body: 'foo' }; // deep/one.md (FrontMatter + Markdown) await dbA.put(jsonA1); await syncA.trySync(); @@ -632,7 +632,7 @@ export const syncCombineBase = ( const dbIdB = dbB.dbId; expect(dbIdB).not.toBe(dbIdA); - const jsonB1 = { _id: 'deep/one', name: 'fromB' }; // YAML + const jsonB1 = { _id: 'deep/one', name: 'fromB' }; // deep/one.yml (YAML) await dbB.put(jsonB1); // Combine with remote db From 76a5b0ee8a2532cbf10791a29a3e346e90f72176 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sun, 21 Nov 2021 00:09:01 +0900 Subject: [PATCH 231/297] fix: can parse --- in markdown part --- src/crud/blob.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/crud/blob.ts b/src/crud/blob.ts index bd651128..815e5237 100644 --- a/src/crud/blob.ts +++ b/src/crud/blob.ts @@ -62,11 +62,12 @@ export function textToJsonDoc ( // eslint-disable-next-line max-depth if (!startFrontMatter) { startFrontMatter = true; + continue; } else if (!endFrontMatter) { endFrontMatter = true; + continue; } - continue; } if (startFrontMatter && !endFrontMatter) { if (yamlText !== '') { From ee891f8eef6438f014c97030b1466d5f3742f45a Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sun, 21 Nov 2021 00:09:39 +0900 Subject: [PATCH 232/297] fix: can get .yml --- src/collection.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/collection.ts b/src/collection.ts index 1eecc8cf..d03c93a8 100644 --- a/src/collection.ts +++ b/src/collection.ts @@ -842,7 +842,7 @@ export class Collection implements ICollection { * @public */ async get (_id: string): Promise { - const shortName = _id + this._gitDDB.serializeFormat.firstExtension; + let shortName = _id + this._gitDDB.serializeFormat.firstExtension; const result = (await getImpl( this._gitDDB, shortName, @@ -856,6 +856,7 @@ export class Collection implements ICollection { result === undefined && this._gitDDB.serializeFormat.secondExtension !== undefined ) { + shortName = _id + this._gitDDB.serializeFormat.secondExtension; return getImpl( this._gitDDB, shortName, From 937b24fd5029844bcab6a108187d747e3e905c06 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sun, 21 Nov 2021 00:10:14 +0900 Subject: [PATCH 233/297] test: add tests for .yml and .md --- test/collection_delete.test.ts | 73 +++++++++++++++++++++++++++++++- test/collection_get.test.ts | 51 +++++++++++++++++++++- test/crud/blob.test.ts | 19 +++++++++ test/crud/get.test.ts | 39 ----------------- test/git_documentdb_crud.test.ts | 36 ++++++++++++++++ 5 files changed, 176 insertions(+), 42 deletions(-) diff --git a/test/collection_delete.test.ts b/test/collection_delete.test.ts index 88e762c9..034abc65 100644 --- a/test/collection_delete.test.ts +++ b/test/collection_delete.test.ts @@ -13,7 +13,12 @@ import git from '@sosuisen/isomorphic-git'; import expect from 'expect'; import { monotonicFactory } from 'ulid'; import { DeleteResultJsonDoc } from '../src/types'; -import { JSON_POSTFIX, SHORT_SHA_LENGTH } from '../src/const'; +import { + FRONT_MATTER_POSTFIX, + JSON_POSTFIX, + SHORT_SHA_LENGTH, + YAML_POSTFIX, +} from '../src/const'; import { toSortedJSONString } from '../src/utils'; import { GitDocumentDB } from '../src/git_documentdb'; import { Err } from '../src/error'; @@ -213,6 +218,72 @@ describe('delete(shortId)', () => { await gitDDB.destroy(); }); + + describe('with front-matter', () => { + it('delete .md', async () => { + const dbName = monoId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + serialize: 'front-matter', + }); + + await gitDDB.open(); + const users = new Collection(gitDDB, 'users'); + const json = { _id: 'foo', name: 'var', _body: 'baz' }; + const putResult = await users.put(json); // save .md + const shortOid = putResult.fileOid.substr(0, SHORT_SHA_LENGTH); + // @ts-ignore + const deleteResult: DeleteResultJsonDoc = await users.delete('foo'); + expect(deleteResult._id).toBe(json._id); + expect(deleteResult.fileOid).toBe(putResult.fileOid); + expect(deleteResult.commit.message).toBe( + `delete: users/${json._id}${FRONT_MATTER_POSTFIX}(${shortOid})` + ); + await gitDDB.destroy(); + }); + + it('delete .yml by fallback', async () => { + const dbName = monoId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + serialize: 'front-matter', + }); + + await gitDDB.open(); + const users = new Collection(gitDDB, 'users'); + const json = { _id: 'foo', name: 'var' }; + const putResult = await users.put(json); // save .yml + const shortOid = putResult.fileOid.substr(0, SHORT_SHA_LENGTH); + // @ts-ignore + const deleteResult: DeleteResultJsonDoc = await users.delete('foo'); + expect(deleteResult._id).toBe(json._id); + expect(deleteResult.fileOid).toBe(putResult.fileOid); + expect(deleteResult.commit.message).toBe( + `delete: users/${json._id}${YAML_POSTFIX}(${shortOid})` + ); + await gitDDB.destroy(); + }); + + it('throws DocumentNotFoundError', async () => { + const dbName = monoId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + serialize: 'front-matter', + }); + + await gitDDB.open(); + const users = new Collection(gitDDB, 'users'); + // @ts-ignore + await expect(users.delete({ _id: 'Shirase' })).rejects.toThrowError( + Err.DocumentNotFoundError + ); + + await gitDDB.destroy(); + }); + }); }); describe('delete(jsonDoc)', () => { diff --git a/test/collection_get.test.ts b/test/collection_get.test.ts index f02c0708..c9b1bd41 100644 --- a/test/collection_get.test.ts +++ b/test/collection_get.test.ts @@ -12,9 +12,9 @@ import fs from 'fs-extra'; import git from '@sosuisen/isomorphic-git'; import expect from 'expect'; import { monotonicFactory } from 'ulid'; -import { JSON_POSTFIX } from '../src/const'; +import { FRONT_MATTER_POSTFIX, JSON_POSTFIX, YAML_POSTFIX } from '../src/const'; import { Collection } from '../src/collection'; -import { sleep, toSortedJSONString } from '../src/utils'; +import { sleep, toFrontMatterMarkdown, toSortedJSONString, toYAML } from '../src/utils'; import { GitDocumentDB } from '../src/git_documentdb'; import { Err } from '../src/error'; import { addOneData, removeOneData } from './utils'; @@ -162,6 +162,53 @@ describe(' get()', () => { await expect(col.get(shortId, 'invalid')).resolves.toEqual(json01); await gitDDB.destroy(); }); + + describe('with front-matter', () => { + it('returns foo.yml', async () => { + const dbName = monoId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + serialize: 'front-matter', + }); + + await gitDDB.open(); + const shortId = 'foo'; + const shortNameYAML = shortId + YAML_POSTFIX; + const fullDocPathYAML = shortNameYAML; + const jsonYAML = { _id: shortId, name: 'Shirase' }; + await addOneData(gitDDB, fullDocPathYAML, toYAML(jsonYAML)); // save foo.yml + + await expect(gitDDB.get(shortId)).resolves.toEqual(jsonYAML); + + await gitDDB.destroy(); + }); + + it('returns foo.md if both foo.md and foo.yml exist', async () => { + const dbName = monoId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + serialize: 'front-matter', + }); + + await gitDDB.open(); + const shortId = 'foo'; + const shortNameYAML = shortId + YAML_POSTFIX; + const fullDocPathYAML = shortNameYAML; + const jsonYAML = { _id: shortId, name: 'Shirase' }; + await addOneData(gitDDB, fullDocPathYAML, toYAML(jsonYAML)); // save foo.yml + + const shortNameMD = shortId + FRONT_MATTER_POSTFIX; + const fullDocPathMD = shortNameMD; + const jsonMD = { _id: shortId, name: 'Shirase', _body: 'var' }; + await addOneData(gitDDB, fullDocPathMD, toFrontMatterMarkdown(jsonMD)); // save foo.md + + await expect(gitDDB.get(shortId)).resolves.toEqual(jsonMD); + + await gitDDB.destroy(); + }); + }); }); describe(' getFatDoc()', () => { diff --git a/test/crud/blob.test.ts b/test/crud/blob.test.ts index c35f6c1d..c0eed192 100644 --- a/test/crud/blob.test.ts +++ b/test/crud/blob.test.ts @@ -200,6 +200,25 @@ describe('', () => { ).toEqual(json); }); + it('returns JsonDoc of Front-Matter and Markdown witch stats with ---', async () => { + const shortId = 'foo'; + const json = { _id: shortId, propA: 'A', propB: 'B', _body: '---\nfoo\nbar' }; + const text = toFrontMatterMarkdown(json); + const readBlobResult: ReadBlobResult = { + oid: (await git.hashBlob({ object: text })).oid, + blob: utf8encode(text), + }; + expect( + blobToJsonDoc( + shortId, + readBlobResult, + false, + new SerializeFormatFrontMatter(), + FRONT_MATTER_POSTFIX + ) + ).toEqual(json); + }); + it('returns JsonDoc of YAML without Markdown', async () => { const shortId = 'foo'; const json = { _id: shortId, propA: 'A', propB: 'B' }; diff --git a/test/crud/get.test.ts b/test/crud/get.test.ts index 6d7481f5..f60e93bc 100644 --- a/test/crud/get.test.ts +++ b/test/crud/get.test.ts @@ -872,45 +872,6 @@ describe(' getImpl()', () => { }); }); - describe(' get FatTextDoc', () => { - it('get text from .md without front-matter option', async () => { - const dbName = monoId(); - const gitDDB: GitDocumentDB = new GitDocumentDB({ - dbName, - localDir, - }); - await gitDDB.open(); - const txt = 'Hello, world!'; - const fullDocPath = 'foo.md'; - await gitDDB.putFatDoc(fullDocPath, txt); - const fatDoc = await gitDDB.getFatDoc(fullDocPath); - expect(fatDoc?.doc).toBe(txt); - await gitDDB.close(); - await gitDDB.destroy(); - }); - - it('get YAML from .yml without front-matter option', async () => { - const dbName = monoId(); - const gitDDB: GitDocumentDB = new GitDocumentDB({ - dbName, - localDir, - }); - await gitDDB.open(); - const yaml = ` -_id: foo -a: aaa -b: bbb -`; - const fullDocPath = 'foo.yml'; - await gitDDB.putFatDoc(fullDocPath, yaml); - const fatDoc = await gitDDB.getFatDoc(fullDocPath); - expect(fatDoc?.doc).toBe(yaml); - - await gitDDB.close(); - await gitDDB.destroy(); - }); - }); - describe('Front-Matter + Markdown', () => { it('returns latest JsonDoc under deep collectionPath', async () => { const dbName = monoId(); diff --git a/test/git_documentdb_crud.test.ts b/test/git_documentdb_crud.test.ts index c47d456a..e4a544f9 100644 --- a/test/git_documentdb_crud.test.ts +++ b/test/git_documentdb_crud.test.ts @@ -655,6 +655,42 @@ describe(' getFatDoc()', () => { await expect(gitDDB.getFatDoc(shortId)).resolves.toBeUndefined(); await gitDDB.destroy(); }); + + it('get text from .md without front-matter option', async () => { + const dbName = monoId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + }); + await gitDDB.open(); + const txt = 'Hello, world!'; + const fullDocPath = 'foo.md'; + await gitDDB.putFatDoc(fullDocPath, txt); + const fatDoc = await gitDDB.getFatDoc(fullDocPath); + expect(fatDoc?.doc).toBe(txt); + await gitDDB.close(); + await gitDDB.destroy(); + }); + + it('get YAML from .yml without front-matter option', async () => { + const dbName = monoId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + }); + await gitDDB.open(); + const yaml = ` +_id: foo +a: aaa +b: bbb +`; + const fullDocPath = 'foo.yml'; + await gitDDB.putFatDoc(fullDocPath, yaml); + const fatDoc = await gitDDB.getFatDoc(fullDocPath); + expect(fatDoc?.doc).toBe(yaml); + await gitDDB.close(); + await gitDDB.destroy(); + }); }); describe(' getDocByOid()', () => { From c704b2b809fd951192a483cd19256890e9138025 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sun, 21 Nov 2021 17:57:26 +0900 Subject: [PATCH 234/297] fix: lint --- test/crud/history.test.ts | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/test/crud/history.test.ts b/test/crud/history.test.ts index 48aa6ef5..60e5f862 100644 --- a/test/crud/history.test.ts +++ b/test/crud/history.test.ts @@ -268,7 +268,15 @@ describe(' getHistoryImpl', () => { // Call close() without await gitDDB.close().catch(() => {}); await expect( - getHistoryImpl(gitDDB, '0.json', '', gitDDB.serializeFormat, undefined, undefined, true) + getHistoryImpl( + gitDDB, + '0.json', + '', + gitDDB.serializeFormat, + undefined, + undefined, + true + ) ).rejects.toThrowError(Err.DatabaseClosingError); while (gitDDB.isClosing) { @@ -288,7 +296,15 @@ describe(' getHistoryImpl', () => { await gitDDB.putFatDoc('1.json', 'invalid json'); await expect( - getHistoryImpl(gitDDB, '1.json', '', gitDDB.serializeFormat, undefined, undefined, true) + getHistoryImpl( + gitDDB, + '1.json', + '', + gitDDB.serializeFormat, + undefined, + undefined, + true + ) ).rejects.toThrowError(Err.InvalidJsonObjectError); await destroyDBs([gitDDB]); From 7c8c028a680a69405059f58add2f2a25e4f2800f Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sun, 21 Nov 2021 17:57:52 +0900 Subject: [PATCH 235/297] test: add test for front-matter --- test/collection_get.test.ts | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/test/collection_get.test.ts b/test/collection_get.test.ts index c9b1bd41..29470db5 100644 --- a/test/collection_get.test.ts +++ b/test/collection_get.test.ts @@ -32,7 +32,7 @@ beforeEach(function () { }); after(() => { - fs.removeSync(path.resolve(localDir)); +// fs.removeSync(path.resolve(localDir)); }); describe(' get()', () => { @@ -164,6 +164,26 @@ describe(' get()', () => { }); describe('with front-matter', () => { + it('returns front-matter', async () => { + const dbName = monoId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + serialize: 'front-matter', + }); + + await gitDDB.open(); + const shortId = 'foo'; + const shortName = shortId + FRONT_MATTER_POSTFIX; + const fullDocPath = shortName; + const json = { _id: shortId, name: 'var', _body: 'baz' }; + await addOneData(gitDDB, fullDocPath, toFrontMatterMarkdown(json)); // save foo.md + + await expect(gitDDB.get(shortId)).resolves.toEqual(json); + + await gitDDB.destroy(); + }); + it('returns foo.yml', async () => { const dbName = monoId(); const gitDDB: GitDocumentDB = new GitDocumentDB({ From 1894d99377d4f3750bc64acf75a468ca4bdd1015 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sun, 21 Nov 2021 17:58:33 +0900 Subject: [PATCH 236/297] build: bump git-documentdb-plugin-remote-nodegit to v1.0.5-alpha.0 --- examples/package.json | 2 +- package-lock.json | 18 +++++++++--------- package.json | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/examples/package.json b/examples/package.json index 81badeb5..78f27f92 100644 --- a/examples/package.json +++ b/examples/package.json @@ -14,7 +14,7 @@ "license": "MPL-2.0", "dependencies": { "git-documentdb": "file:..", - "git-documentdb-plugin-remote-nodegit": "^1.0.4" + "git-documentdb-plugin-remote-nodegit": "^1.0.5-alpha.0" }, "devDependencies": { "typescript": "^4.1.3" diff --git a/package-lock.json b/package-lock.json index 21d7ccee..e36daa01 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "git-documentdb", - "version": "0.4.7-alpha.7", + "version": "0.4.7-alpha.9", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "git-documentdb", - "version": "0.4.7-alpha.7", + "version": "0.4.7-alpha.9", "license": "MPL-2.0", "dependencies": { "@octokit/rest": "^18.3.5", @@ -45,7 +45,7 @@ "eslint-plugin-prettierx": "^0.14.0", "eslint-plugin-unicorn": "^36.0.0", "expect": "^27.0.2", - "git-documentdb-plugin-remote-nodegit": "^1.0.4", + "git-documentdb-plugin-remote-nodegit": "^1.0.5-alpha.0", "hmtid": "^0.1.0", "mocha": "^8.3.2", "nyc": "^15.1.0", @@ -4633,9 +4633,9 @@ } }, "node_modules/git-documentdb-plugin-remote-nodegit": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.4.tgz", - "integrity": "sha512-+esXlN6PMmvwKZPU6dn/kSQnVe5QHU9xGzoNrLiqehz+VM1AXgNhsce/KipimG4wdzUS6tbS9QbgIgA4VjpbAw==", + "version": "1.0.5-alpha.0", + "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.5-alpha.0.tgz", + "integrity": "sha512-WJjWi0Ey3R/cD21FzDgtffxllOAeOhjDN87ysyR742zu7tj6VU9xCCnyC0VW54O+yiPW7lAuh9QcQS4kfNwxJA==", "dev": true, "dependencies": { "@sosuisen/nodegit": "^0.28.0-alpha.11", @@ -14317,9 +14317,9 @@ "dev": true }, "git-documentdb-plugin-remote-nodegit": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.4.tgz", - "integrity": "sha512-+esXlN6PMmvwKZPU6dn/kSQnVe5QHU9xGzoNrLiqehz+VM1AXgNhsce/KipimG4wdzUS6tbS9QbgIgA4VjpbAw==", + "version": "1.0.5-alpha.0", + "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.5-alpha.0.tgz", + "integrity": "sha512-WJjWi0Ey3R/cD21FzDgtffxllOAeOhjDN87ysyR742zu7tj6VU9xCCnyC0VW54O+yiPW7lAuh9QcQS4kfNwxJA==", "dev": true, "requires": { "@sosuisen/nodegit": "^0.28.0-alpha.11", diff --git a/package.json b/package.json index 18d5ffce..eb86ab1c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "git-documentdb", - "version": "0.4.7-alpha.9", + "version": "0.4.7-alpha.10", "description": "Offline-first database that syncs with Git", "main": "dist/main.js", "types": "dist/main.d.ts", @@ -65,7 +65,7 @@ "eslint-plugin-prettierx": "^0.14.0", "eslint-plugin-unicorn": "^36.0.0", "expect": "^27.0.2", - "git-documentdb-plugin-remote-nodegit": "^1.0.4", + "git-documentdb-plugin-remote-nodegit": "^1.0.5-alpha.0", "hmtid": "^0.1.0", "mocha": "^8.3.2", "nyc": "^15.1.0", From 1284fb034c2f9e44c906f67d98163277419eca7d Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sun, 21 Nov 2021 17:59:50 +0900 Subject: [PATCH 237/297] build: bump to 0.4.7-alpha.10 --- test/collection_get.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/collection_get.test.ts b/test/collection_get.test.ts index 29470db5..96e199a8 100644 --- a/test/collection_get.test.ts +++ b/test/collection_get.test.ts @@ -32,7 +32,7 @@ beforeEach(function () { }); after(() => { -// fs.removeSync(path.resolve(localDir)); + fs.removeSync(path.resolve(localDir)); }); describe(' get()', () => { From 5c47cd4ae71b457d979431ff18eeb30df85d2c09 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sun, 21 Nov 2021 21:03:34 +0900 Subject: [PATCH 238/297] fix: add benchmark --- benchmark/get.ts | 79 +++++++++++++++++++++++++++++++++++++++++ benchmark/tsconfig.json | 6 ++++ package.json | 1 + tsconfig.eslint.json | 1 + 4 files changed, 87 insertions(+) create mode 100644 benchmark/get.ts create mode 100644 benchmark/tsconfig.json diff --git a/benchmark/get.ts b/benchmark/get.ts new file mode 100644 index 00000000..bccf3311 --- /dev/null +++ b/benchmark/get.ts @@ -0,0 +1,79 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +import path from 'path'; +import fs from 'fs-extra'; +import { monotonicFactory } from 'ulid'; +import { GitDocumentDB } from '../src/git_documentdb'; + +const localDir = './benchmark/database_get'; + +const ulid = monotonicFactory(); +const monoId = () => { + return ulid(Date.now()); +}; + +// eslint-disable-next-line complexity +async function bench () { + const dbName = monoId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + }); + await gitDDB.open(); + + for (let i = 0; i < 200; i++) { + // eslint-disable-next-line no-await-in-loop + await gitDDB.put(`${i}`, { name: 'foo' }); + } + + for (let i = 0; i < 200; i++) { + // eslint-disable-next-line no-await-in-loop + await gitDDB.put(`large-${i}`, { + name: + '01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789', + }); + } + + console.time('Load from blob'); + for (let i = 0; i < 100; i++) { + // eslint-disable-next-line no-await-in-loop + const json = await gitDDB.get(`${i}`); + if (json!._id !== `${i}`) console.error('Error'); + } + console.timeEnd('Load from blob'); + + console.time('Load from file'); + for (let i = 100; i < 200; i++) { + const json = fs.readJSONSync(`${gitDDB.workingDir}/${i}.json`); + if (json._id !== `${i}`) console.error('Error'); + } + console.timeEnd('Load from file'); + + console.time('Load large file from blob'); + for (let i = 0; i < 100; i++) { + // eslint-disable-next-line no-await-in-loop + const json = await gitDDB.get(`large-${i}`); + if (json!._id !== `large-${i}`) console.error('Error'); + } + console.timeEnd('Load large file from blob'); + + console.time('Load large file from file'); + for (let i = 100; i < 200; i++) { + const json = fs.readJSONSync(`${gitDDB.workingDir}/large-${i}.json`); + if (json._id !== `large-${i}`) console.error('Error'); + } + console.timeEnd('Load large file from file'); + + await gitDDB.destroy(); + + fs.removeSync(path.resolve(localDir)); +} + +bench(); diff --git a/benchmark/tsconfig.json b/benchmark/tsconfig.json new file mode 100644 index 00000000..607d44fc --- /dev/null +++ b/benchmark/tsconfig.json @@ -0,0 +1,6 @@ +{ + "extends": "../tsconfig-base", + "include": [ + "**/*", + ], +} \ No newline at end of file diff --git a/package.json b/package.json index eb86ab1c..eb0fd66d 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "mocha-unit": "npm run rm-test-db && npx cross-env TS_NODE_FILES=true TS_NODE_PROJECT=tsconfig.mocha.json mocha --retries 0 --no-parallel", "compile-tests": "tsc --project test/tsconfig.json && tsc --project test_plugin/tsconfig.json ", "rm-test-db": "rm -rf test/database* test_plugin/database*", + "bench": "rm -rf benchmark/database* && npx ts-node ", "test": "npx nyc npm run mocha \"test/**/*.test.ts\" && npm run rm-test-db", "test-plugin": "npm run mocha \"test_plugin/**/*.test.ts\" && npm run rm-test-db", "upload-coverage": "npx coveralls < coverage/lcov.info", diff --git a/tsconfig.eslint.json b/tsconfig.eslint.json index f6a55ac3..5a24448a 100644 --- a/tsconfig.eslint.json +++ b/tsconfig.eslint.json @@ -4,6 +4,7 @@ "src/**/*", "test/**/*", "test_plugin/**/*", + "benchmark/**/*", "webpack.*" ], } \ No newline at end of file From dd49dedc0195a02431cb0d76780dd4f6e0c94dd0 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sun, 21 Nov 2021 22:42:52 +0900 Subject: [PATCH 239/297] fix: read file in working directory to check update/insert error --- src/crud/put.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/crud/put.ts b/src/crud/put.ts index 725139d5..8434caaa 100644 --- a/src/crud/put.ts +++ b/src/crud/put.ts @@ -128,14 +128,13 @@ export async function putWorker ( }); try { - await fs.writeFile(filePath, data); - const headCommit = await git .resolveRef({ fs, dir: gitDDB.workingDir, ref: 'HEAD' }) .catch(() => undefined); - const oldEntry = - headCommit === undefined + const oldEntryExists = fs.existsSync(filePath); + /* + const oldEntry = headCommit === undefined ? undefined : await git .readBlob({ @@ -145,8 +144,8 @@ export async function putWorker ( filepath: fullDocPath, }) .catch(() => undefined); - - if (oldEntry) { + */ + if (oldEntryExists) { if (insertOrUpdate === 'insert') return Promise.reject(new Err.SameIdExistsError()); insertOrUpdate ??= 'update'; } @@ -155,6 +154,7 @@ export async function putWorker ( return Promise.reject(new Err.DocumentNotFoundError()); insertOrUpdate ??= 'insert'; } + await fs.writeFile(filePath, data); await git.add({ fs, dir: gitDDB.workingDir, filepath: fullDocPath }); From b79e9453f0a67357515ac47d52003548fc114dec Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sun, 21 Nov 2021 22:44:33 +0900 Subject: [PATCH 240/297] fix: comment in benchmark --- benchmark/get.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/benchmark/get.ts b/benchmark/get.ts index bccf3311..66f6db89 100644 --- a/benchmark/get.ts +++ b/benchmark/get.ts @@ -41,13 +41,13 @@ async function bench () { }); } - console.time('Load from blob'); + console.time('Load by API'); for (let i = 0; i < 100; i++) { // eslint-disable-next-line no-await-in-loop const json = await gitDDB.get(`${i}`); if (json!._id !== `${i}`) console.error('Error'); } - console.timeEnd('Load from blob'); + console.timeEnd('Load by API'); console.time('Load from file'); for (let i = 100; i < 200; i++) { @@ -56,13 +56,13 @@ async function bench () { } console.timeEnd('Load from file'); - console.time('Load large file from blob'); + console.time('Load large file by API'); for (let i = 0; i < 100; i++) { // eslint-disable-next-line no-await-in-loop const json = await gitDDB.get(`large-${i}`); if (json!._id !== `large-${i}`) console.error('Error'); } - console.timeEnd('Load large file from blob'); + console.timeEnd('Load large file by API'); console.time('Load large file from file'); for (let i = 100; i < 200; i++) { From 07ea94a12bdb5bd5f030f4b9da6b1c8ddf07695b Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sun, 21 Nov 2021 22:45:29 +0900 Subject: [PATCH 241/297] fix: use getJsonDocFromWorkingDIr instead of getImpl because former is x10 or x100 faster --- src/collection.ts | 16 ++++-------- src/crud/get.ts | 62 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 11 deletions(-) diff --git a/src/collection.ts b/src/collection.ts index d03c93a8..55f04315 100644 --- a/src/collection.ts +++ b/src/collection.ts @@ -37,7 +37,7 @@ import { import { GitDDBInterface } from './types_gitddb'; import { Validator } from './validator'; import { GIT_DOCUMENTDB_METADATA_DIR } from './const'; -import { getImpl } from './crud/get'; +import { getImpl, getJsonDocFromWorkingDir } from './crud/get'; import { getHistoryImpl } from './crud/history'; import { deleteImpl } from './crud/delete'; import { findImpl } from './crud/find'; @@ -843,28 +843,22 @@ export class Collection implements ICollection { */ async get (_id: string): Promise { let shortName = _id + this._gitDDB.serializeFormat.firstExtension; - const result = (await getImpl( + const result = (await getJsonDocFromWorkingDir( this._gitDDB, shortName, this.collectionPath, - this._gitDDB.serializeFormat, - { - forceDocType: 'json', - } + this._gitDDB.serializeFormat )) as Promise; if ( result === undefined && this._gitDDB.serializeFormat.secondExtension !== undefined ) { shortName = _id + this._gitDDB.serializeFormat.secondExtension; - return getImpl( + return getJsonDocFromWorkingDir( this._gitDDB, shortName, this.collectionPath, - this._gitDDB.serializeFormat, - { - forceDocType: 'json', - } + this._gitDDB.serializeFormat ) as Promise; } return result; diff --git a/src/crud/get.ts b/src/crud/get.ts index 0d05b9ed..38f603ab 100644 --- a/src/crud/get.ts +++ b/src/crud/get.ts @@ -6,6 +6,8 @@ * found in the LICENSE file in the root directory of gitDDB source tree. */ +import path from 'path'; +import fs from 'fs-extra'; import { ReadBlobResult } from '@sosuisen/isomorphic-git'; import { GitDDBInterface } from '../types_gitddb'; import { Err } from '../error'; @@ -16,6 +18,7 @@ import { GetInternalOptions, GetOptions, HistoryOptions, + JsonDoc, SerializeFormat, } from '../types'; import { @@ -25,9 +28,68 @@ import { blobToText, readBlobByOid, readLatestBlob, + textToJsonDoc, } from './blob'; import { readOldBlob } from './history'; +/** + * Read file from working directory. + * This is x10 faster than readBlob() from loose object, + * x100 faster than readBlob() from packed object. + * + * @throws {@link Err.DatabaseClosingError} + * @throws {@link Err.RepositoryNotOpenError} + * @throws {@link Err.InvalidJsonObjectError} + */ +export async function getJsonDocFromWorkingDir ( + gitDDB: GitDDBInterface, + shortName: string, + collectionPath: string, + serializeFormat: SerializeFormat +): Promise { + if (gitDDB.isClosing) { + throw new Err.DatabaseClosingError(); + } + if (!gitDDB.isOpened) { + return Promise.reject(new Err.RepositoryNotOpenError()); + } + const fullDocPath = collectionPath + shortName; + const shortId = serializeFormat.removeExtension(shortName); + + if (serializeFormat.format === 'json') { + const jsonDoc = await fs.readJSON(gitDDB.workingDir + '/' + fullDocPath).catch(err => { + if (err instanceof SyntaxError) { + throw new Err.InvalidJsonObjectError(shortId); + } + else return undefined; + }); + if (jsonDoc === undefined) return undefined; + if (jsonDoc._id !== undefined) { + // Overwrite _id property by shortId (_id without collectionPath) if JsonDoc is created by GitDocumentedDB (_id !== undefined). + jsonDoc._id = shortId; + } + return jsonDoc; + } + + const extMatch = fullDocPath.match(/.+(\..+?)$/)!; + let extension = ''; + if (extMatch) { + extension = extMatch[1]; + } + const text = await fs + .readFile(gitDDB.workingDir + '/' + fullDocPath, 'utf-8') + .catch(() => { + return undefined; + }); + if (text === undefined) return undefined; + const jsonDoc = textToJsonDoc(text, serializeFormat, extension, shortId); + if (jsonDoc._id !== undefined) { + // Overwrite _id property by shortId (_id without collectionPath) if JsonDoc is created by GitDocumentedDB (_id !== undefined). + jsonDoc._id = shortId; + } + return jsonDoc; +} + /** * Common implementation of get-like commands * From 32ef0d915f95a17f17cff94d4c98893b474d729a Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sun, 21 Nov 2021 23:01:53 +0900 Subject: [PATCH 242/297] fix: remove unused code --- src/crud/put.ts | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/crud/put.ts b/src/crud/put.ts index 8434caaa..e78a636b 100644 --- a/src/crud/put.ts +++ b/src/crud/put.ts @@ -133,18 +133,7 @@ export async function putWorker ( .catch(() => undefined); const oldEntryExists = fs.existsSync(filePath); - /* - const oldEntry = headCommit === undefined - ? undefined - : await git - .readBlob({ - fs, - dir: gitDDB.workingDir, - oid: headCommit, - filepath: fullDocPath, - }) - .catch(() => undefined); - */ + if (oldEntryExists) { if (insertOrUpdate === 'insert') return Promise.reject(new Err.SameIdExistsError()); insertOrUpdate ??= 'update'; From 03105100c4680d20cc2eafdb15fbd08c66e1754e Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sun, 21 Nov 2021 23:17:29 +0900 Subject: [PATCH 243/297] fix: add getTextDocFromWorkingDir and getBinaryDocFromWorkingDir --- src/crud/get.ts | 62 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/src/crud/get.ts b/src/crud/get.ts index 38f603ab..744e6d72 100644 --- a/src/crud/get.ts +++ b/src/crud/get.ts @@ -33,7 +33,7 @@ import { import { readOldBlob } from './history'; /** - * Read file from working directory. + * Read json file from working directory. * This is x10 faster than readBlob() from loose object, * x100 faster than readBlob() from packed object. * @@ -90,6 +90,66 @@ export async function getJsonDocFromWorkingDir ( return jsonDoc; } +/** + * Read text file from working directory. + * This is x10 faster than readBlob() from loose object, + * x100 faster than readBlob() from packed object. + * + * @throws {@link Err.DatabaseClosingError} + * @throws {@link Err.RepositoryNotOpenError} + * @throws {@link Err.InvalidJsonObjectError} + */ +export async function getTextDocFromWorkingDir ( + gitDDB: GitDDBInterface, + shortName: string, + collectionPath: string, + serializeFormat: SerializeFormat +): Promise { + if (gitDDB.isClosing) { + throw new Err.DatabaseClosingError(); + } + if (!gitDDB.isOpened) { + return Promise.reject(new Err.RepositoryNotOpenError()); + } + const fullDocPath = collectionPath + shortName; + const textDoc = await fs + .readFile(gitDDB.workingDir + '/' + fullDocPath, 'utf-8') + .catch(() => { + return undefined; + }); + if (textDoc === undefined) return undefined; + return textDoc; +} + +/** + * Read binary file from working directory. + * This is x10 faster than readBlob() from loose object, + * x100 faster than readBlob() from packed object. + * + * @throws {@link Err.DatabaseClosingError} + * @throws {@link Err.RepositoryNotOpenError} + * @throws {@link Err.InvalidJsonObjectError} + */ +export async function getBinaryDocFromWorkingDir ( + gitDDB: GitDDBInterface, + shortName: string, + collectionPath: string, + serializeFormat: SerializeFormat +): Promise { + if (gitDDB.isClosing) { + throw new Err.DatabaseClosingError(); + } + if (!gitDDB.isOpened) { + return Promise.reject(new Err.RepositoryNotOpenError()); + } + const fullDocPath = collectionPath + shortName; + const binaryDoc = await fs.readFile(gitDDB.workingDir + '/' + fullDocPath).catch(() => { + return undefined; + }); + if (binaryDoc === undefined) return undefined; + return binaryDoc; +} + /** * Common implementation of get-like commands * From 7337c266266812d3ae97dc9c8f9efe36e7f8aee1 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sun, 21 Nov 2021 23:17:54 +0900 Subject: [PATCH 244/297] fix: use getXXXFromWorkingDir in find to be faster --- src/crud/find.ts | 124 +++++++++++++++++++++++++++++++---------------- 1 file changed, 83 insertions(+), 41 deletions(-) diff --git a/src/crud/find.ts b/src/crud/find.ts index d359efc2..a6a4fdd6 100644 --- a/src/crud/find.ts +++ b/src/crud/find.ts @@ -29,6 +29,11 @@ import { } from '../types'; import { GitDDBInterface } from '../types_gitddb'; import { blobToBinary, blobToJsonDoc, blobToText } from './blob'; +import { + getBinaryDocFromWorkingDir, + getJsonDocFromWorkingDir, + getTextDocFromWorkingDir, +} from './get'; /** * Implementation of find() @@ -153,27 +158,28 @@ export async function findImpl ( if (findOnlyJson && !serializeFormat.hasObjectExtension(fullDocPath)) { continue; } - // eslint-disable-next-line no-await-in-loop - const readBlobResult = await readBlob({ - fs, - dir: gitDDB.workingDir, - oid: commitOid, - filepath: fullDocPath, - }).catch(() => undefined); - // Skip if cannot read - if (readBlobResult) { - const docType: DocType = - options.forceDocType ?? - (serializeFormat.hasObjectExtension(fullDocPath) ? 'json' : 'text'); - if (docType === 'text') { - // TODO: select binary or text by .gitattribtues - } - const shortName = fullDocPath.replace(new RegExp('^' + collectionPath), ''); - if (docType === 'json') { - const [, extension] = fullDocPath.match(/.+(\..+?)$/)!; - const shortId = serializeFormat.removeExtension(shortName); - if (withMetadata) { + const docType: DocType = + options.forceDocType ?? + (serializeFormat.hasObjectExtension(fullDocPath) ? 'json' : 'text'); + if (docType === 'text') { + // TODO: select binary or text by .gitattribtues + } + const shortName = fullDocPath.replace(new RegExp('^' + collectionPath), ''); + + if (docType === 'json') { + const [, extension] = fullDocPath.match(/.+(\..+?)$/)!; + const shortId = serializeFormat.removeExtension(shortName); + if (withMetadata) { + // eslint-disable-next-line no-await-in-loop + const readBlobResult = await readBlob({ + fs, + dir: gitDDB.workingDir, + oid: commitOid, + filepath: fullDocPath, + }).catch(() => undefined); + // Skip if cannot read + if (readBlobResult) { docs.push( blobToJsonDoc( shortId, @@ -184,33 +190,69 @@ export async function findImpl ( ) as FatJsonDoc ); } - else { - docs.push( - blobToJsonDoc( - shortId, - readBlobResult, - false, - serializeFormat, - extension - ) as JsonDoc - ); - } } - else if (docType === 'text') { - if (withMetadata) { + else { + docs.push( + // eslint-disable-next-line no-await-in-loop + (await getJsonDocFromWorkingDir( + gitDDB, + shortName, + collectionPath, + serializeFormat + )) as JsonDoc + ); + } + } + else if (docType === 'text') { + if (withMetadata) { + // eslint-disable-next-line no-await-in-loop + const readBlobResult = await readBlob({ + fs, + dir: gitDDB.workingDir, + oid: commitOid, + filepath: fullDocPath, + }).catch(() => undefined); + // Skip if cannot read + if (readBlobResult) { docs.push(blobToText(shortName, readBlobResult, true) as FatTextDoc); } - else { - docs.push(blobToText(shortName, readBlobResult, false) as string); - } } - else if (docType === 'binary') { - if (withMetadata) { + else { + docs.push( + // eslint-disable-next-line no-await-in-loop + (await getTextDocFromWorkingDir( + gitDDB, + shortName, + collectionPath, + serializeFormat + )) as string + ); + } + } + else if (docType === 'binary') { + if (withMetadata) { + // eslint-disable-next-line no-await-in-loop + const readBlobResult = await readBlob({ + fs, + dir: gitDDB.workingDir, + oid: commitOid, + filepath: fullDocPath, + }).catch(() => undefined); + // Skip if cannot read + if (readBlobResult) { docs.push(blobToBinary(shortName, readBlobResult, true) as FatBinaryDoc); } - else { - docs.push(blobToBinary(shortName, readBlobResult, false) as Uint8Array); - } + } + else { + docs.push( + // eslint-disable-next-line no-await-in-loop + (await getBinaryDocFromWorkingDir( + gitDDB, + shortName, + collectionPath, + serializeFormat + )) as Uint8Array + ); } } } From 4735ae95d368718ad3248749fc1058024078861b Mon Sep 17 00:00:00 2001 From: sosuisen Date: Mon, 22 Nov 2021 00:05:47 +0900 Subject: [PATCH 245/297] fix: do not pause() when sync error occurs --- src/remote/sync.ts | 8 ++++---- test/remote_base/network_task_queue.ts | 12 +++++++++--- test/remote_base/sync_live.ts | 1 - test/remote_base/sync_trypush.ts | 2 +- test/remote_base/sync_trysync.ts | 2 +- test/remote_utils.ts | 5 ++++- 6 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/remote/sync.ts b/src/remote/sync.ts index eb22745f..bbbf6847 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -897,8 +897,8 @@ export class Sync implements SyncInterface { } } } - // Fatal error. Don't retry. - this.pause(); + // Fatal error. Don't retry? + // this.pause(); throw resultOrError; } @@ -1018,7 +1018,7 @@ export class Sync implements SyncInterface { if (error instanceof RemoteErr.UnfetchedCommitExistsError) { this._retrySyncCounter--; if (this._retrySyncCounter === 0) { - this.pause(); + // this.pause(); throw error; } this._gitDDB.logger.debug( @@ -1031,7 +1031,7 @@ export class Sync implements SyncInterface { else { // Throw error this._retrySyncCounter = 0; - this.pause(); + // this.pause(); throw error; } } diff --git a/test/remote_base/network_task_queue.ts b/test/remote_base/network_task_queue.ts index 4b3fd844..59c778fb 100644 --- a/test/remote_base/network_task_queue.ts +++ b/test/remote_base/network_task_queue.ts @@ -34,9 +34,15 @@ export const networkTaskQueueBase = ( describe(' remote', () => { it('increments statistics: push', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, - }); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + { + connection, + }, + undefined + ); // The first push in open() expect(dbA.taskQueue.currentStatistics().push).toBe(1); diff --git a/test/remote_base/sync_live.ts b/test/remote_base/sync_live.ts index e8663310..65946901 100644 --- a/test/remote_base/sync_live.ts +++ b/test/remote_base/sync_live.ts @@ -61,7 +61,6 @@ export const syncLiveBase = ( const jsonA1 = { _id: '1', name: 'fromA' }; await dbA.put(jsonA1); - expect(syncA.options.live).toBeTruthy(); expect(syncA.options.interval).toBe(interval); diff --git a/test/remote_base/sync_trypush.ts b/test/remote_base/sync_trypush.ts index 407b3f3c..e8512af1 100644 --- a/test/remote_base/sync_trypush.ts +++ b/test/remote_base/sync_trypush.ts @@ -453,7 +453,7 @@ export const syncTryPushBase = ( } expect(error).toBeInstanceOf(RemoteErr.NetworkError); - expect(syncA.options.live).toBeFalsy(); + // expect(syncA.options.live).toBeFalsy(); await destroyDBs([dbA]); }); diff --git a/test/remote_base/sync_trysync.ts b/test/remote_base/sync_trysync.ts index 44d32319..f99876aa 100644 --- a/test/remote_base/sync_trysync.ts +++ b/test/remote_base/sync_trysync.ts @@ -950,7 +950,7 @@ export const syncTrySyncBase = ( } expect(error).toBeInstanceOf(RemoteErr.NetworkError); - expect(syncA.options.live).toBeFalsy(); + // expect(syncA.options.live).toBeFalsy(); await destroyDBs([dbA]); }); diff --git a/test/remote_utils.ts b/test/remote_utils.ts index ebbbeaea..909dbd01 100644 --- a/test/remote_utils.ts +++ b/test/remote_utils.ts @@ -22,6 +22,7 @@ import { GitDocumentDB } from '../src/git_documentdb'; import { FILE_REMOVE_TIMEOUT, GIT_DOCUMENTDB_METADATA_DIR } from '../src/const'; import { RemoteRepository } from '../src/remote/remote_repository'; import { SerializeFormatJSON } from '../src/serialize_format'; +import { TLogLevelName } from 'tslog'; const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; @@ -184,7 +185,8 @@ export async function createDatabase ( localDir: string, serialId: () => string, options?: RemoteOptions, - schema?: Schema + schema?: Schema, + logLevel: TLogLevelName = 'info' ): Promise<[GitDocumentDB, SyncInterface]> { const remoteURL = remoteURLBase + serialId(); @@ -194,6 +196,7 @@ export async function createDatabase ( dbName: dbNameA, localDir, schema, + logLevel, }); options ??= { remoteUrl: remoteURL, From 93e0dc95e7cdf34a5a56f1bcadc9f1b4839cda7a Mon Sep 17 00:00:00 2001 From: sosuisen Date: Mon, 22 Nov 2021 00:30:55 +0900 Subject: [PATCH 246/297] build: bump to v0.4.7-alpha.11 --- package.json | 2 +- test/remote_utils.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index eb0fd66d..1bb86a2e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "git-documentdb", - "version": "0.4.7-alpha.10", + "version": "0.4.7-alpha.11", "description": "Offline-first database that syncs with Git", "main": "dist/main.js", "types": "dist/main.d.ts", diff --git a/test/remote_utils.ts b/test/remote_utils.ts index 909dbd01..0cbb667c 100644 --- a/test/remote_utils.ts +++ b/test/remote_utils.ts @@ -4,6 +4,7 @@ import { Octokit } from '@octokit/rest'; import git from '@sosuisen/isomorphic-git'; import sinon from 'sinon'; import expect from 'expect'; +import { TLogLevelName } from 'tslog'; import { textToJsonDoc } from '../src/crud/blob'; import { ChangedFileDelete, @@ -22,7 +23,6 @@ import { GitDocumentDB } from '../src/git_documentdb'; import { FILE_REMOVE_TIMEOUT, GIT_DOCUMENTDB_METADATA_DIR } from '../src/const'; import { RemoteRepository } from '../src/remote/remote_repository'; import { SerializeFormatJSON } from '../src/serialize_format'; -import { TLogLevelName } from 'tslog'; const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; From f934966f9f2ed0add8004e21e7543b6db93a83a1 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 23 Nov 2021 16:02:44 +0900 Subject: [PATCH 247/297] fix: return front-matter + markdown when _body is empty and filename ends with .md --- src/crud/blob.ts | 4 ++-- src/git_documentdb.ts | 2 -- src/remote/combine.ts | 6 +----- src/utils.ts | 2 +- test/crud/blob.test.ts | 42 +++++++++++++++++++++++++++++++++++++++++- 5 files changed, 45 insertions(+), 11 deletions(-) diff --git a/src/crud/blob.ts b/src/crud/blob.ts index 815e5237..80152d99 100644 --- a/src/crud/blob.ts +++ b/src/crud/blob.ts @@ -9,7 +9,7 @@ import fs from 'fs'; import yaml from 'js-yaml'; import { readBlob, ReadBlobResult, resolveRef } from '@sosuisen/isomorphic-git'; -import { YAML_POSTFIX } from '../const'; +import { FRONT_MATTER_POSTFIX, YAML_POSTFIX } from '../const'; import { utf8decode } from '../utils'; import { Err } from '../error'; import { @@ -111,7 +111,7 @@ export function textToJsonDoc ( } } } - if (markdownText !== '') { + if (markdownText !== '' || extension === FRONT_MATTER_POSTFIX) { jsonDoc._body = markdownText; } } diff --git a/src/git_documentdb.ts b/src/git_documentdb.ts index ebdad8a4..6c3575c9 100644 --- a/src/git_documentdb.ts +++ b/src/git_documentdb.ts @@ -60,11 +60,9 @@ import { FILE_CREATE_TIMEOUT, FILE_REMOVE_TIMEOUT, FIRST_COMMIT_MESSAGE, - FRONT_MATTER_POSTFIX, GIT_DOCUMENTDB_INFO_ID, JSON_POSTFIX, SET_DATABASE_ID_MESSAGE, - YAML_POSTFIX, } from './const'; import { normalizeCommit, sleep, toSortedJSONString } from './utils'; import { SyncEventInterface, SyncInterface } from './types_sync'; diff --git a/src/remote/combine.ts b/src/remote/combine.ts index 871043f6..fff52f0a 100644 --- a/src/remote/combine.ts +++ b/src/remote/combine.ts @@ -23,11 +23,7 @@ import { } from '../types'; import { GitDDBInterface } from '../types_gitddb'; import { Err } from '../error'; -import { - DUPLICATED_FILE_POSTFIX, - FILE_REMOVE_TIMEOUT, - FRONT_MATTER_POSTFIX, -} from '../const'; +import { DUPLICATED_FILE_POSTFIX, FILE_REMOVE_TIMEOUT } from '../const'; import { getAllMetadata } from '../utils'; import { RemoteEngine, wrappingRemoteEngineError } from './remote_engine'; diff --git a/src/utils.ts b/src/utils.ts index e58f80c7..80a5e2e4 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -25,7 +25,7 @@ import { SerializeFormat, TextDocMetadata, } from './types'; -import { FRONT_MATTER_POSTFIX, GIT_DOCUMENTDB_METADATA_DIR, JSON_POSTFIX } from './const'; +import { GIT_DOCUMENTDB_METADATA_DIR } from './const'; /** * @internal diff --git a/test/crud/blob.test.ts b/test/crud/blob.test.ts index c0eed192..bf92a943 100644 --- a/test/crud/blob.test.ts +++ b/test/crud/blob.test.ts @@ -100,7 +100,27 @@ describe('', () => { ).toEqual(json); }); - it('returns JsonDoc with only _id when Front-Matter + Markdown is empty', async () => { + it('returns JsonDoc with only _id when YAML_POSTFIX and Front-Matter + Markdown is empty', async () => { + const shortId = 'foo'; + const text = ''; + const readBlobResult: ReadBlobResult = { + oid: (await git.hashBlob({ object: text })).oid, + blob: utf8encode(text), + }; + expect( + blobToJsonDoc( + shortId, + readBlobResult, + false, + new SerializeFormatFrontMatter(), + YAML_POSTFIX + ) + ).toEqual({ + _id: 'foo', + }); + }); + + it('returns JsonDoc with only _id and _body when FRONT_MATTER_POSTFIX and Front-Matter + Markdown is empty', async () => { const shortId = 'foo'; const text = ''; const readBlobResult: ReadBlobResult = { @@ -117,6 +137,7 @@ describe('', () => { ) ).toEqual({ _id: 'foo', + _body: '', }); }); @@ -181,6 +202,25 @@ describe('', () => { ).toEqual(json); }); + it('returns JsonDoc of Front-Matter + Markdown when _body is empty', async () => { + const shortId = 'foo'; + const json = { _id: shortId, propA: 'A', propB: 'B', _body: '' }; + const text = toFrontMatterMarkdown(json); + const readBlobResult: ReadBlobResult = { + oid: (await git.hashBlob({ object: text })).oid, + blob: utf8encode(text), + }; + expect( + blobToJsonDoc( + shortId, + readBlobResult, + false, + new SerializeFormatFrontMatter(), + FRONT_MATTER_POSTFIX + ) + ).toEqual(json); + }); + it('returns JsonDoc of Front-Matter + Markdown that ends with \n', async () => { const shortId = 'foo'; const json = { _id: shortId, propA: 'A', propB: 'B', _body: 'foo\nbar\n' }; From 800d80acc373e52c268f6592cc82a8ff98435406 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 23 Nov 2021 16:14:37 +0900 Subject: [PATCH 248/297] build: bump to v0.4.7-alpha.12 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1bb86a2e..a14cc8a0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "git-documentdb", - "version": "0.4.7-alpha.11", + "version": "0.4.7-alpha.12", "description": "Offline-first database that syncs with Git", "main": "dist/main.js", "types": "dist/main.d.ts", From 45b297332c7a3fd6046a0fb034bd14199f8e2321 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Thu, 16 Dec 2021 16:33:12 +0900 Subject: [PATCH 249/297] fix: can patch delete property operation --- src/remote/json_patch_ot.ts | 17 +++-- test/remote_offline/json_patch_ot.test.ts | 78 +++++++++++++++++++++++ 2 files changed, 90 insertions(+), 5 deletions(-) diff --git a/src/remote/json_patch_ot.ts b/src/remote/json_patch_ot.ts index 5e0311a6..19aebca6 100644 --- a/src/remote/json_patch_ot.ts +++ b/src/remote/json_patch_ot.ts @@ -1,6 +1,6 @@ /* eslint-disable unicorn/prefer-spread */ /* eslint-disable max-depth */ -import { editOp, insertOp, JSONOp, replaceOp, type } from 'ot-json1'; +import { editOp, insertOp, JSONOp, removeOp, replaceOp, type } from 'ot-json1'; import { uniCount } from 'unicount'; import { ConflictResolutionStrategyLabels, IJsonPatch, JsonDoc } from '../types'; import { DEFAULT_CONFLICT_RESOLUTION_STRATEGY } from '../const'; @@ -102,6 +102,7 @@ export class JsonPatchOT implements IJsonPatch { const keys = Object.keys(tree); let sortedKeys: string[]; if (keys.includes('_t')) { + // is Array keys.sort(); // 1, 2, 3, _1, _2, _3 let underBarStart = 0; for (underBarStart = 0; underBarStart < keys.length; underBarStart++) { @@ -114,6 +115,7 @@ export class JsonPatchOT implements IJsonPatch { sortedKeys = underBar.concat(noBar); // _1, _2, _3, 1, 2, 3 } else { + // is Object sortedKeys = keys.sort(); } // eslint-disable-next-line complexity @@ -128,7 +130,10 @@ export class JsonPatchOT implements IJsonPatch { } else if (arr.length === 3) { const firstItem = arr[0]; - if (typeof firstItem === 'string') { + if (arr[1] === 0 && arr[2] === 0) { + operations.push(removeOp(ancestors.concat(key))); + } + else if (typeof firstItem === 'string') { let isTextPatch = firstItem.match(/^@@ -\d+?,\d+? \+\d+?,\d+? @@\n/m); if (!isTextPatch) isTextPatch = firstItem.match(/^@@ -\d+? \+\d+?,\d+? @@\n/m); @@ -177,12 +182,14 @@ export class JsonPatchOT implements IJsonPatch { if (docTheirs === undefined || diffTheirs === undefined) { return (type.apply(docOurs, this.fromDiff(diffOurs)) as unknown) as JsonDoc; } - // console.log(diffOurs); - // console.log(diffTheirs); + // console.log(JSON.stringify(diffOurs)); + // console.log(JSON.stringify(diffTheirs)); const opOurs = this.fromDiff(diffOurs); + // console.log('opOurs: ' + JSON.stringify(opOurs) + '\n'); const opTheirs = this.fromDiff(diffTheirs); + // console.log('opTheirs: ' + JSON.stringify(opTheirs) + '\n'); const transformedOp = this.transform(opTheirs, opOurs, strategy!); - // console.log('# transformed: ' + JSON.stringify(transformedOp)); + // console.log('# transformed: ' + JSON.stringify(transformedOp) + '\n'); let newDoc: JsonDoc; if (strategy.startsWith('ours')) { newDoc = (type.apply(docOurs, transformedOp!) as unknown) as JsonDoc; diff --git a/test/remote_offline/json_patch_ot.test.ts b/test/remote_offline/json_patch_ot.test.ts index 19980e64..7b527720 100644 --- a/test/remote_offline/json_patch_ot.test.ts +++ b/test/remote_offline/json_patch_ot.test.ts @@ -103,6 +103,24 @@ describe(' OT', () => { ); }); + it('patches from diff (delete)', () => { + const oldDoc = { + _id: 'nara', + age: 'Nara prefecture', + year: 1887, + current: true, + }; + const newDoc = { + _id: 'nara', + age: 'Nara prefecture', + year: 1887, + }; + + expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( + newDoc + ); + }); + it('merges independent changes (create)', () => { const base = { _id: 'nara', @@ -1273,6 +1291,66 @@ sighed Meg, looking down at her old dress.`, expect(jPatch.patch(ours, diffOurs!, theirs, diffTheirs)).toStrictEqual(merged); }); + + it('merge complex structure including delete operation', () => { + const docOurs = { + _id: 'note/n2021-10-12-15-30-30-_YFSS58F/c2021-12-06-05-54-52-GE43E73', + condition: { locked: false }, + date: { createdDate: '2021-12-06 05:54:52', modifiedDate: '2021-12-15 00:31:28' }, + geometry: { height: 900, width: 461, x: 706, y: 80, z: 5804 }, + label: { + enabled: false, + status: 'closedLabel', + text: 'foo', + }, + style: { backgroundColor: '#ffdd9e', opacity: 1, uiColor: '#f5d498', zoom: 0.85 }, + }; + + const docTheirs = {}; + + const newDoc = { + _id: 'note/n2021-10-12-15-30-30-_YFSS58F/c2021-12-06-05-54-52-GE43E73', + condition: { locked: false }, + date: { createdDate: '2021-12-06 05:54:52', modifiedDate: '2021-12-15 00:31:28' }, + geometry: { height: 900, width: 461, x: 1459, y: 180, z: 5953 }, + label: { + enabled: false, + status: 'openedSticker', + x: 1562, + y: 144, + height: 92, + width: 329, + text: 'foo bar', + }, + style: { backgroundColor: '#fff8d0', opacity: 1, uiColor: '#fff8d0', zoom: 0.85 }, + }; + + const diffOurs = { + date: { modifiedDate: ['2021-12-15 00:31:17', '2021-12-15 00:31:28'] }, + label: { + height: [64, 0, 0], + width: [461, 0, 0], + x: [706, 0, 0], + y: [80, 0, 0], + zoom: [0.85, 0, 0], + }, + }; + const diffTheirs = { + date: { modifiedDate: ['2021-12-15 00:31:17', '2021-12-15 07:36:11'] }, + geometry: { x: [706, 1459], y: [80, 180], z: [5804, 5953] }, + label: { + height: [64, 92], + status: ['closedLabel', 'openedSticker'], + text: ['foo', 'foo bar'], + width: [461, 329], + x: [706, 1562], + y: [80, 144], + }, + style: { backgroundColor: ['#ffdd9e', '#fff8d0'], uiColor: ['#f5d498', '#fff8d0'] }, + }; + + expect(jPatch.patch(docOurs, diffOurs, docTheirs, diffTheirs)).toStrictEqual(newDoc); + }); }); it.skip('merges conflicted primitives: add', () => {}); From 20e3de130ef2d7a1b9efe9c3145be1175337d6b3 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Thu, 16 Dec 2021 16:33:28 +0900 Subject: [PATCH 250/297] build: bump to v0.4.7-alpha.13 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a14cc8a0..065181dd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "git-documentdb", - "version": "0.4.7-alpha.12", + "version": "0.4.7-alpha.13", "description": "Offline-first database that syncs with Git", "main": "dist/main.js", "types": "dist/main.d.ts", From e05620dbf861e6965cc678c1d25252afe31d5574 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sat, 18 Dec 2021 01:23:48 +0900 Subject: [PATCH 251/297] fix: bump @sosuisen/isomorphic-git@1.10.1-alpha.8 --- package-lock.json | 18 +++++++++--------- package.json | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index e36daa01..f1d44261 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,16 @@ { "name": "git-documentdb", - "version": "0.4.7-alpha.9", + "version": "0.4.7-alpha.13", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "git-documentdb", - "version": "0.4.7-alpha.9", + "version": "0.4.7-alpha.13", "license": "MPL-2.0", "dependencies": { "@octokit/rest": "^18.3.5", - "@sosuisen/isomorphic-git": "^1.10.1-alpha.6", + "@sosuisen/isomorphic-git": "^1.10.1-alpha.8", "@sosuisen/jsondiffpatch": "^0.4.7", "async-lock": "^1.3.0", "cross-blob": "^2.0.0", @@ -1169,9 +1169,9 @@ } }, "node_modules/@sosuisen/isomorphic-git": { - "version": "1.10.1-alpha.6", - "resolved": "https://registry.npmjs.org/@sosuisen/isomorphic-git/-/isomorphic-git-1.10.1-alpha.6.tgz", - "integrity": "sha512-pVw6e6x6J3UPegoYh7mmF/V43ISRv4I0L9QPqX0sqkSBDuirmcrliLn/pMsvP8I7YLJakTfyGQLmzZuSGSAVfQ==", + "version": "1.10.1-alpha.8", + "resolved": "https://registry.npmjs.org/@sosuisen/isomorphic-git/-/isomorphic-git-1.10.1-alpha.8.tgz", + "integrity": "sha512-38pFxFkhQy6rEDBQhMFOXw9jvaV7RI+Dlw8SkYMxbhDvgAF7kfVy8DuyOoFqInlpy8rsTJWfGlHZPZFR+9LwrQ==", "dependencies": { "async-lock": "^1.1.0", "clean-git-ref": "^2.0.1", @@ -11656,9 +11656,9 @@ } }, "@sosuisen/isomorphic-git": { - "version": "1.10.1-alpha.6", - "resolved": "https://registry.npmjs.org/@sosuisen/isomorphic-git/-/isomorphic-git-1.10.1-alpha.6.tgz", - "integrity": "sha512-pVw6e6x6J3UPegoYh7mmF/V43ISRv4I0L9QPqX0sqkSBDuirmcrliLn/pMsvP8I7YLJakTfyGQLmzZuSGSAVfQ==", + "version": "1.10.1-alpha.8", + "resolved": "https://registry.npmjs.org/@sosuisen/isomorphic-git/-/isomorphic-git-1.10.1-alpha.8.tgz", + "integrity": "sha512-38pFxFkhQy6rEDBQhMFOXw9jvaV7RI+Dlw8SkYMxbhDvgAF7kfVy8DuyOoFqInlpy8rsTJWfGlHZPZFR+9LwrQ==", "requires": { "async-lock": "^1.1.0", "clean-git-ref": "^2.0.1", diff --git a/package.json b/package.json index 065181dd..224be066 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,7 @@ }, "dependencies": { "@octokit/rest": "^18.3.5", - "@sosuisen/isomorphic-git": "^1.10.1-alpha.6", + "@sosuisen/isomorphic-git": "^1.10.1-alpha.8", "@sosuisen/jsondiffpatch": "^0.4.7", "async-lock": "^1.3.0", "cross-blob": "^2.0.0", From b891f2e778026367dcc68c64a698b01f4589bae3 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sat, 18 Dec 2021 01:24:15 +0900 Subject: [PATCH 252/297] fix: bump to v0.4.7-alpha.14 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 224be066..675af927 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "git-documentdb", - "version": "0.4.7-alpha.13", + "version": "0.4.7-alpha.14", "description": "Offline-first database that syncs with Git", "main": "dist/main.js", "types": "dist/main.d.ts", From 871b82e9a1c5ee063a17619ac9775c9726594242 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sat, 18 Dec 2021 13:42:22 +0900 Subject: [PATCH 253/297] fix: add benchmark for push --- benchmark/push.ts | 136 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 benchmark/push.ts diff --git a/benchmark/push.ts b/benchmark/push.ts new file mode 100644 index 00000000..953d92ac --- /dev/null +++ b/benchmark/push.ts @@ -0,0 +1,136 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +/** + * GitDocumentDB + * Copyright (c) Hidekazu Kubota + * + * This source code is licensed under the Mozilla Public License Version 2.0 + * found in the LICENSE file in the root directory of this source tree. + */ + +import path from 'path'; +import fs from 'fs-extra'; +import { monotonicFactory } from 'ulid'; +import { ConnectionSettingsGitHub, RemoteOptions } from '../src/types'; +import { GitDocumentDB } from '../src/git_documentdb'; +import { removeRemoteRepositories } from '../test/remote_utils'; +import { Sync } from '../src/remote/sync'; + +// eslint-disable-next-line @typescript-eslint/no-var-requires +GitDocumentDB.plugin(require('git-documentdb-plugin-remote-nodegit')); + +const DATA_SIZE = 1000; + +const reposPrefix = 'benchmark_push___'; + +const remoteURLBase = process.env.GITDDB_GITHUB_USER_URL?.endsWith('/') + ? process.env.GITDDB_GITHUB_USER_URL + : process.env.GITDDB_GITHUB_USER_URL + '/'; + +const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; + +const ulid = monotonicFactory(); +const monoId = () => { + return ulid(Date.now()); +}; + +const putData = async (gitDDB: GitDocumentDB) => { + for (let i = 0; i < DATA_SIZE / 2; i++) { + // eslint-disable-next-line no-await-in-loop + await gitDDB.put(`${i}`, { name: 'foo' }); + } + // Update them + for (let i = 0; i < DATA_SIZE / 2; i++) { + // eslint-disable-next-line no-await-in-loop + await gitDDB.put(`${i}`, { name: 'foo bar' }); + } +}; + +const putLargeData = async (gitDDB: GitDocumentDB) => { + for (let i = 0; i < DATA_SIZE / 2; i++) { + // eslint-disable-next-line no-await-in-loop + await gitDDB.put(`large-${i}`, { + name: + '0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789', + }); + } + // Update them + for (let i = 0; i < DATA_SIZE / 2; i++) { + // eslint-disable-next-line no-await-in-loop + await gitDDB.put(`large-${i}`, { + name: + '01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789', + }); + } +}; + +// eslint-disable-next-line complexity +async function bench () { + console.log('# DATA_SIZE = ' + DATA_SIZE); + + await removeRemoteRepositories(reposPrefix); + + const isomorphicLocalDir = './benchmark/database_push_isomorphic'; + + const isomorphicDbName = monoId(); + const isomorphicGitDDB: GitDocumentDB = new GitDocumentDB({ + dbName: isomorphicDbName, + localDir: isomorphicLocalDir, + }); + await isomorphicGitDDB.open(); + const isomorphicConnection: ConnectionSettingsGitHub = { + type: 'github', + personalAccessToken: token, + }; + const isomorphicOptions: RemoteOptions = { + remoteUrl: remoteURLBase + reposPrefix + 'isomorphic', + connection: isomorphicConnection, + }; + const isomorphicSync = await isomorphicGitDDB.sync(isomorphicOptions); + + await putData(isomorphicGitDDB); + console.time('Push data by isomorphic git'); + await isomorphicSync.tryPush(); + console.timeEnd('Push data by isomorphic git'); + + await putLargeData(isomorphicGitDDB); + console.time('Push large data by isomorphic git'); + await isomorphicSync.tryPush(); + console.timeEnd('Push large data by isomorphic git'); + + await isomorphicGitDDB.destroy(); + fs.removeSync(path.resolve(isomorphicLocalDir)); + + const nodegitLocalDir = './benchmark/database_push_nodegit'; + + const nodegitDbName = monoId(); + const nodegitGitDDB: GitDocumentDB = new GitDocumentDB({ + dbName: nodegitDbName, + localDir: nodegitLocalDir, + }); + await nodegitGitDDB.open(); + const nodegitConnection: ConnectionSettingsGitHub = { + type: 'github', + personalAccessToken: token, + engine: 'nodegit', + }; + const nodegitOptions: RemoteOptions = { + remoteUrl: remoteURLBase + reposPrefix + 'nodegit', + connection: nodegitConnection, + }; + const nodegitSync = await nodegitGitDDB.sync(nodegitOptions); + + await putData(nodegitGitDDB); + console.time('Push data by nodegit git'); + await nodegitSync.tryPush(); + console.timeEnd('Push data by nodegit git'); + + await putLargeData(nodegitGitDDB); + console.time('Push large data by nodegit git'); + await nodegitSync.tryPush(); + console.timeEnd('Push large data by nodegit git'); + + await nodegitGitDDB.destroy(); + fs.removeSync(path.resolve(nodegitLocalDir)); +} + +bench(); From 2bbea7f7fbfd2afda270151516a66859cf138d14 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 21 Jan 2022 14:46:48 +0900 Subject: [PATCH 254/297] fix: can patch arrays --- src/remote/json_patch_ot.ts | 37 +++- test/remote_offline/json_patch_ot.test.ts | 254 +++++++++++++++++++++- 2 files changed, 282 insertions(+), 9 deletions(-) diff --git a/src/remote/json_patch_ot.ts b/src/remote/json_patch_ot.ts index 19aebca6..87ef016f 100644 --- a/src/remote/json_patch_ot.ts +++ b/src/remote/json_patch_ot.ts @@ -1,6 +1,6 @@ /* eslint-disable unicorn/prefer-spread */ /* eslint-disable max-depth */ -import { editOp, insertOp, JSONOp, removeOp, replaceOp, type } from 'ot-json1'; +import { editOp, insertOp, JSONOp, moveOp, removeOp, replaceOp, type } from 'ot-json1'; import { uniCount } from 'unicount'; import { ConflictResolutionStrategyLabels, IJsonPatch, JsonDoc } from '../types'; import { DEFAULT_CONFLICT_RESOLUTION_STRATEGY } from '../const'; @@ -8,7 +8,7 @@ import { DEFAULT_CONFLICT_RESOLUTION_STRATEGY } from '../const'; export class JsonPatchOT implements IJsonPatch { constructor () {} - private _textCreateOp (path: string[], startNum: number, str: string): JSONOp { + private _textCreateOp (path: (string | number)[], startNum: number, str: string): JSONOp { if (startNum > 0) { return editOp(path, 'text-unicode', [startNum, str]); } @@ -16,7 +16,7 @@ export class JsonPatchOT implements IJsonPatch { } private _textReplaceOp ( - path: string[], + path: (string | number)[], startNum: number, from: string, to: string @@ -27,7 +27,7 @@ export class JsonPatchOT implements IJsonPatch { return editOp(path, 'text-unicode', [{ d: uniCount(from) }, to]); } - private _textDeleteOp (path: string[], startNum: number, str: string) { + private _textDeleteOp (path: (string | number)[], startNum: number, str: string) { if (startNum > 0) { return editOp(path, 'text-unicode', [startNum, { d: uniCount(str) }]); } @@ -35,7 +35,7 @@ export class JsonPatchOT implements IJsonPatch { } // eslint-disable-next-line complexity - getTextOp (path: string[], text: string): JSONOp { + getTextOp (path: (string | number)[], text: string): JSONOp { // From text patch const operators: JSONOp[] = []; const lines = text.split('\n'); @@ -98,11 +98,13 @@ export class JsonPatchOT implements IJsonPatch { fromDiff (diff: { [key: string]: any }): JSONOp { const operations: JSONOp[] = []; - const procTree = (ancestors: string[], tree: JsonDoc) => { + const procTree = (ancestors: (string | number)[], tree: JsonDoc) => { const keys = Object.keys(tree); - let sortedKeys: string[]; - if (keys.includes('_t')) { + let sortedKeys: (string | number)[]; + const isArray = keys.includes('_t'); + if (isArray) { // is Array + // underscore _ means 'remove' operation keys.sort(); // 1, 2, 3, _1, _2, _3 let underBarStart = 0; for (underBarStart = 0; underBarStart < keys.length; underBarStart++) { @@ -123,16 +125,32 @@ export class JsonPatchOT implements IJsonPatch { if (Array.isArray(tree[key])) { const arr = tree[key] as any[]; if (arr.length === 1) { + if (isArray && typeof key === 'string') { + key = parseInt(key.replace(/^_/, ''), 10); // Remove heading underscore + } operations.push(insertOp(ancestors.concat(key), arr[0])!); } else if (arr.length === 2) { + if (isArray && typeof key === 'string') { + key = parseInt(key.replace(/^_/, ''), 10); // Remove heading underscore + } operations.push(replaceOp(ancestors.concat(key), arr[0], arr[1])!); } else if (arr.length === 3) { const firstItem = arr[0]; + if (isArray && typeof key === 'string') { + key = parseInt(key.replace(/^_/, ''), 10); // Remove heading underscore + } if (arr[1] === 0 && arr[2] === 0) { + // Deleted + // See https://github.com/benjamine/jsondiffpatch/blob/master/docs/deltas.md operations.push(removeOp(ancestors.concat(key))); } + else if (arr[0] === '' && arr[2] === 3) { + // Moved + // See https://github.com/benjamine/jsondiffpatch/blob/master/docs/deltas.md + operations.push(moveOp(ancestors.concat(key), ancestors.concat(arr[1]))); + } else if (typeof firstItem === 'string') { let isTextPatch = firstItem.match(/^@@ -\d+?,\d+? \+\d+?,\d+? @@\n/m); if (!isTextPatch) @@ -149,6 +167,9 @@ export class JsonPatchOT implements IJsonPatch { } } else if (typeof tree[key] === 'object') { + if (isArray && typeof key === 'string') { + key = parseInt(key.replace(/^_/, ''), 10); // Remove heading underscore + } procTree(ancestors.concat(key), tree[key]); } }); diff --git a/test/remote_offline/json_patch_ot.test.ts b/test/remote_offline/json_patch_ot.test.ts index 7b527720..12ff7f1a 100644 --- a/test/remote_offline/json_patch_ot.test.ts +++ b/test/remote_offline/json_patch_ot.test.ts @@ -13,7 +13,78 @@ const textOTDiff = new JsonDiff({ const jPatch = new JsonPatchOT(); describe(' OT', () => { - describe('for primitive', () => { + describe('apply', () => { + it('apply op', () => { + const oldDoc = { + _id: 'oldId', + }; + const op = ['_id', { r: true, i: 'newId' }]; + + expect(jPatch.apply(oldDoc, op)).toStrictEqual({ + _id: 'newId', + }); + }); + + it('apply complex op', () => { + const oldDoc = { + _id: 'old', + collapsedList: [163, 339, 451, 559, 604], + condition: {}, + geometry: { height: 686, width: 410, x: 390, y: 4, z: 8931 }, + label: { + height: 64, + status: 'closed', + text: 'old', + width: 400, + x: 390, + y: 4, + zoom: 1, + }, + }; + + const op = [ + [ + 'collapsedList', + [0, { r: true }], + [1, { r: true }], + [2, { r: true }], + [3, { r: true }], + [4, { r: true }], + ], + [ + 'geometry', + ['height', { r: true, i: 980 }], + ['width', { r: true, i: 650 }], + ['z', { r: true, i: 8937 }], + ], + [ + 'label', + 'text', + { + r: true, + i: 'updated', + }, + ], + ]; + + const newDoc = { + _id: 'old', + collapsedList: [], + condition: {}, + geometry: { height: 980, width: 650, x: 390, y: 4, z: 8937 }, + label: { + height: 64, + status: 'closed', + text: 'updated', + width: 400, + x: 390, + y: 4, + zoom: 1, + }, + }; + expect(jPatch.apply(oldDoc, op)).toStrictEqual(newDoc); + }); + it('applies patch (create)', () => { const oldDoc = { _id: 'nara', @@ -46,7 +117,188 @@ describe(' OT', () => { ]; expect(jPatch.apply(oldDoc, patch)).toStrictEqual(newDoc); }); + }); + + describe('for array', () => { + it('patches from diff (new property)', () => { + const oldDoc = { + _id: 'nara', + }; + const newDoc = { + _id: 'nara', + temple: ['Toshodaiji', 'Todaiji', 'Yakushiji'], + }; + + expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( + newDoc + ); + }); + + it('patches from diff (delete property)', () => { + const oldDoc = { + _id: 'nara', + temple: ['Toshodaiji', 'Todaiji', 'Yakushiji'], + }; + const newDoc = { + _id: 'nara', + }; + + expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( + newDoc + ); + }); + + it('patches from diff (insert at first)', () => { + const oldDoc = { + _id: 'nara', + temple: ['Todaiji', 'Yakushiji'], + }; + const newDoc = { + _id: 'nara', + temple: ['Toshodaiji', 'Todaiji', 'Yakushiji'], + }; + + const diff = primitiveDiff.diff(oldDoc, newDoc)!; + expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + }); + + it('patches from diff (insert at middle)', () => { + const oldDoc = { + _id: 'nara', + temple: ['Todaiji', 'Yakushiji'], + }; + const newDoc = { + _id: 'nara', + temple: ['Todaiji', 'Toshodaiji', 'Yakushiji'], + }; + + const diff = primitiveDiff.diff(oldDoc, newDoc)!; + expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + }); + + it('patches from diff (insert at last)', () => { + const oldDoc = { + _id: 'nara', + temple: ['Todaiji', 'Yakushiji'], + }; + const newDoc = { + _id: 'nara', + temple: ['Todaiji', 'Yakushiji', 'Toshodaiji'], + }; + + const diff = primitiveDiff.diff(oldDoc, newDoc)!; + expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + }); + + it('patches from diff (insert two members)', () => { + const oldDoc = { + _id: 'nara', + temple: ['Todaiji', 'Yakushiji'], + }; + const newDoc = { + _id: 'nara', + temple: ['Todaiji', 'Toshodaiji', 'Kofukuji', 'Yakushiji'], + }; + + const diff = primitiveDiff.diff(oldDoc, newDoc)!; + expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + }); + + it('patches from diff (moving)', () => { + const oldDoc = { + _id: 'nara', + temple: ['Todaiji', 'Yakushiji'], + }; + const newDoc = { + _id: 'nara', + temple: ['Yakushiji', 'Todaiji'], + }; + + const diff = primitiveDiff.diff(oldDoc, newDoc)!; + // { temple: { _t: 'a', _1: [ '', 0, 3 ] } } + // [ '', 0, 3 ] + // The first member is always ''. + // The second member 0 represents destinationIndex + // The last member 3 is the magical number that indicates "array move" + expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + }); + + it('patches from diff (deleting)', () => { + const oldDoc = { + _id: 'nara', + temple: ['Todaiji', 'Yakushiji'], + }; + const newDoc = { + _id: 'nara', + temple: ['Todaiji'], + }; + const diff = primitiveDiff.diff(oldDoc, newDoc)!; + expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + }); + + it('patches from diff (nesting arrays)', () => { + const oldDoc = { + cherry: [ + ['NaraPark', 'double cherry blossoms'], + ['MtYoshino', 'cherry blossoms'], + ], + }; + const newDoc = { + cherry: [ + ['NaraPark', 'double cherry blossoms'], + ['MtYoshino', 'awesome cherry blossoms'], + ], + }; + const diff = primitiveDiff.diff(oldDoc, newDoc)!; + expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + }); + + it('of objects', () => { + const oldDoc = { + _id: 'nara', + site: [ + { place: 'NaraPark', flower: ['cherry blossoms'] }, + { place: 'MtYoshino', flower: ['cherry blossoms'] }, + ], + }; + + const newDoc = { + _id: 'nara', + site: [ + { place: 'MtYoshino', flower: ['cherry blossoms'] }, + { place: 'NaraPark', flower: ['double cherry blossoms', 'Japanese apricot'] }, + ], + }; + const diff = primitiveDiff.diff(oldDoc, newDoc)!; + expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + }); + + it('of objects by objectHash', () => { + const myDiff = new JsonDiff({ + idOfSubtree: ['place'], + }); + + const oldDoc = { + _id: 'nara', + site: [ + { place: 'NaraPark', flower: ['cherry blossoms'] }, + { place: 'MtYoshino', flower: ['cherry blossoms'] }, + ], + }; + + const newDoc = { + _id: 'nara', + site: [ + { place: 'MtYoshino', flower: ['cherry blossoms'] }, + { place: 'NaraPark', flower: ['double cherry blossoms', 'Japanese apricot'] }, + ], + }; + const diff = myDiff.diff(oldDoc, newDoc)!; + expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + }); + }); + describe('for object', () => { it('returns patch from diff (create)', () => { const oldDoc = { _id: 'nara', From e33a940495156de82181597e2ab8c5a90dc3e278 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 21 Jan 2022 14:59:40 +0900 Subject: [PATCH 255/297] build: bump to v0.4.7-alpha.15 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 675af927..7912ed67 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "git-documentdb", - "version": "0.4.7-alpha.14", + "version": "0.4.7-alpha.15", "description": "Offline-first database that syncs with Git", "main": "dist/main.js", "types": "dist/main.d.ts", From dccaf5ecde6a609ba892ef3a4d187973a1d5ca34 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 1 Feb 2022 19:04:32 +0900 Subject: [PATCH 256/297] fix: delete FrontMatter not by fallback --- src/collection.ts | 60 +++++++++++++++-------------------------------- 1 file changed, 19 insertions(+), 41 deletions(-) diff --git a/src/collection.ts b/src/collection.ts index 55f04315..4e393c90 100644 --- a/src/collection.ts +++ b/src/collection.ts @@ -8,6 +8,7 @@ import fs from 'fs'; +import path from 'path'; import { readTree, resolveRef } from '@sosuisen/isomorphic-git'; import { monotonicFactory, ULID } from 'ulid'; import { Err } from './error'; @@ -1215,52 +1216,29 @@ export class Collection implements ICollection { } let shortName = shortId + this._gitDDB.serializeFormat.firstExtension; - let trySecondExtension = false; - const resultOrError = await deleteImpl( + // Check if file exists for deleting FrontMatter + if (this._gitDDB.serializeFormat.secondExtension !== undefined) { + const fullDocPath = this.collectionPath + shortName; + const filePath = path.resolve(this._gitDDB.workingDir, fullDocPath); + if (!fs.existsSync(filePath)) { + shortName = shortId + this._gitDDB.serializeFormat.secondExtension; + } + } + + return await deleteImpl( this._gitDDB, this.collectionPath, shortId, shortName, options - ) - .then(res => { - const deleteResult: PutResultJsonDoc = { - ...res, - _id: shortId, - type: 'json', - }; - return deleteResult; - }) - .catch(err => { - if ( - err instanceof Err.DocumentNotFoundError && - this._gitDDB.serializeFormat.secondExtension !== undefined - ) - trySecondExtension = true; - return err; - }); - - if (trySecondExtension) { - shortName = shortId + this._gitDDB.serializeFormat.secondExtension; - return deleteImpl( - this._gitDDB, - this.collectionPath, - shortId, - shortName, - options - ).then(res => { - const deleteResult: PutResultJsonDoc = { - ...res, - _id: shortId, - type: 'json', - }; - return deleteResult; - }); - } - // eslint-disable-next-line promise/catch-or-return - if (resultOrError instanceof Error) throw resultOrError; - - return resultOrError; + ).then(res => { + const deleteResult: PutResultJsonDoc = { + ...res, + _id: shortId, + type: 'json', + }; + return deleteResult; + }); } /** From d98f6393373a0837c364e957d3153137abe09575 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 1 Feb 2022 19:05:01 +0900 Subject: [PATCH 257/297] build: bump to v0.4.7-alpha.16 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7912ed67..ac7cdbe8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "git-documentdb", - "version": "0.4.7-alpha.15", + "version": "0.4.7-alpha.16", "description": "Offline-first database that syncs with Git", "main": "dist/main.js", "types": "dist/main.d.ts", From 43b50b7ff4f3a41fdf4e58fc329b5d18909b6f2a Mon Sep 17 00:00:00 2001 From: sosuisen Date: Thu, 10 Feb 2022 12:27:14 +0900 Subject: [PATCH 258/297] fix: json_patch_ot does not work correctly when both objects are the same --- src/remote/json_patch_ot.ts | 1 + test/remote_offline/json_diff.test.ts | 4 ++++ test/remote_offline/json_patch_ot.test.ts | 26 +++++++++++++++++++++++ 3 files changed, 31 insertions(+) diff --git a/src/remote/json_patch_ot.ts b/src/remote/json_patch_ot.ts index 87ef016f..7cf60b77 100644 --- a/src/remote/json_patch_ot.ts +++ b/src/remote/json_patch_ot.ts @@ -97,6 +97,7 @@ export class JsonPatchOT implements IJsonPatch { } fromDiff (diff: { [key: string]: any }): JSONOp { + if (diff === undefined) return null; // Do not be undefined. Use null. const operations: JSONOp[] = []; const procTree = (ancestors: (string | number)[], tree: JsonDoc) => { const keys = Object.keys(tree); diff --git a/test/remote_offline/json_diff.test.ts b/test/remote_offline/json_diff.test.ts index adc2aa6f..ca7eaaac 100644 --- a/test/remote_offline/json_diff.test.ts +++ b/test/remote_offline/json_diff.test.ts @@ -16,6 +16,10 @@ const textOTDiff = new JsonDiff({ }); describe(' diff', () => { + it('Equal', () => { + expect(textOTDiff.diff({}, {})).toBeUndefined(); + }); + describe('primitives', () => { it('adding values', () => { const oldDoc = { diff --git a/test/remote_offline/json_patch_ot.test.ts b/test/remote_offline/json_patch_ot.test.ts index 12ff7f1a..7cf59543 100644 --- a/test/remote_offline/json_patch_ot.test.ts +++ b/test/remote_offline/json_patch_ot.test.ts @@ -25,6 +25,16 @@ describe(' OT', () => { }); }); + it('apply empty op', () => { + const oldDoc = { + _id: 'oldId', + }; + // Do not be undefined. Use null. + expect(jPatch.apply(oldDoc, null)).toStrictEqual({ + _id: 'oldId', + }); + }); + it('apply complex op', () => { const oldDoc = { _id: 'old', @@ -119,6 +129,22 @@ describe(' OT', () => { }); }); + describe('patch', () => { + it('patches from undefined diff', () => { + const oldDoc = { + _id: 'nara', + }; + const newDoc = { + _id: 'nara', + }; + // primitiveDiff.diff(oldDoc, newDoc) will return undefined. + expect(primitiveDiff.diff(oldDoc, newDoc)).toBeUndefined(); + expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( + newDoc + ); + }); + }); + describe('for array', () => { it('patches from diff (new property)', () => { const oldDoc = { From 82c2bf7882bf4d835556cb3a84510bda88ffe6b1 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Thu, 10 Feb 2022 13:43:43 +0900 Subject: [PATCH 259/297] build: bump to v0.4.7-alpha.17 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ac7cdbe8..808f8daa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "git-documentdb", - "version": "0.4.7-alpha.16", + "version": "0.4.7-alpha.17", "description": "Offline-first database that syncs with Git", "main": "dist/main.js", "types": "dist/main.d.ts", From c16b80256ff6090e8942583ee6716ff6572e59ba Mon Sep 17 00:00:00 2001 From: sosuisen Date: Thu, 10 Feb 2022 14:05:50 +0900 Subject: [PATCH 260/297] test: add test for .md which does not have a fron matter --- test/collection_get.test.ts | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/test/collection_get.test.ts b/test/collection_get.test.ts index 96e199a8..27810067 100644 --- a/test/collection_get.test.ts +++ b/test/collection_get.test.ts @@ -228,6 +228,27 @@ describe(' get()', () => { await gitDDB.destroy(); }); + + it('returns _body with _id when .md does not have front matter', async () => { + const dbName = monoId(); + const gitDDB: GitDocumentDB = new GitDocumentDB({ + dbName, + localDir, + serialize: 'front-matter', + }); + + await gitDDB.open(); + const shortId = 'foo'; + const shortNameMD = shortId + '.md'; + const fullDocPathMD = shortNameMD; + const md = 'Hello'; + const jsonMD = { _id: 'foo', _body: md }; + await addOneData(gitDDB, fullDocPathMD, md); // save foo.md + + await expect(gitDDB.get(shortId)).resolves.toEqual(jsonMD); + + await gitDDB.destroy(); + }); }); }); From affe3b3fc224ee79af1ebc6f2f63f51c35603575 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 22 Apr 2022 19:01:50 +0900 Subject: [PATCH 261/297] fix: add runBeforeLiveSync --- src/remote/sync.ts | 18 +++++++++++++++++- src/types_sync.ts | 2 ++ test/remote_base/sync_live.ts | 36 +++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/src/remote/sync.ts b/src/remote/sync.ts index bbbf6847..788aec68 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -238,6 +238,7 @@ export class Sync implements SyncInterface { private _syncTimer: NodeJS.Timeout | undefined; private _retrySyncCounter = 0; // Decremental count private _isClosed = false; + /*********************************************** * Public properties (readonly) ***********************************************/ @@ -300,6 +301,14 @@ export class Sync implements SyncInterface { * Public properties ***********************************************/ + /** + * runBeforeLiveSync + * + * This function is executed just before each automated(live) synchronization event is queued. + * Set undefined to stop it. + */ + public runBeforeLiveSync: (() => void) | undefined = undefined; + /** * SyncEvent handlers * @@ -415,7 +424,7 @@ export class Sync implements SyncInterface { } /*********************************************** - * Public properties + * Public methods ***********************************************/ /** @@ -637,6 +646,13 @@ export class Sync implements SyncInterface { listener.func(); }); this._syncTimer = setInterval(() => { + if (this.runBeforeLiveSync !== undefined) { + try { + this.runBeforeLiveSync(); + } catch (e) { + this._gitDDB.logger.debug('Error in runBeforeLiveSync: ' + e); + } + } if (this._options.syncDirection === 'push') { this.tryPushImpl(true).catch(() => undefined); } diff --git a/src/types_sync.ts b/src/types_sync.ts index b416b6d4..27012dd3 100644 --- a/src/types_sync.ts +++ b/src/types_sync.ts @@ -38,6 +38,8 @@ export interface SyncInterface { /*********************************************** * Public properties ***********************************************/ + runBeforeLiveSync: (() => void) | undefined; + /** * @internal */ diff --git a/test/remote_base/sync_live.ts b/test/remote_base/sync_live.ts index 65946901..753eded2 100644 --- a/test/remote_base/sync_live.ts +++ b/test/remote_base/sync_live.ts @@ -329,5 +329,41 @@ export const syncLiveBase = ( await destroyDBs([dbA]); }); + + it('runBeforeLiveSync', async () => { + const remoteURL = remoteURLBase + serialId(); + const dbNameA = serialId(); + + const dbA: GitDocumentDB = new GitDocumentDB({ + dbName: dbNameA, + localDir: localDir, + }); + const interval = MINIMUM_SYNC_INTERVAL; + const options: RemoteOptions = { + remoteUrl: remoteURL, + live: true, + syncDirection: 'both', + interval, + connection, + }; + await dbA.open(); + const executed: number[] = []; + const syncA = await dbA.sync(options); + syncA.runBeforeLiveSync = () => { + executed.push(0); + }; + syncA.on('start', () => { + executed.push(1); + }); + syncA.on('error', (err: Error) => { + console.log(err); + }); + + await sleep(interval * 5); + executed.length = 6; + expect(JSON.stringify(executed)).toBe('[0,1,0,1,0,1]'); + + await destroyDBs([dbA]); + }); }); }; From 3bb109b23b2e4fdeb49b282ebb98d71e7050b5e2 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Fri, 22 Apr 2022 19:10:07 +0900 Subject: [PATCH 262/297] found error case in json_patch_ot.test.ts --- test/remote_offline/json_patch_ot.test.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/remote_offline/json_patch_ot.test.ts b/test/remote_offline/json_patch_ot.test.ts index 7cf59543..6134413e 100644 --- a/test/remote_offline/json_patch_ot.test.ts +++ b/test/remote_offline/json_patch_ot.test.ts @@ -322,6 +322,21 @@ describe(' OT', () => { const diff = myDiff.diff(oldDoc, newDoc)!; expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); }); + + it.only('delete two and add new one', () => { + const oldDoc = { + _id: 'nara', + temple: ['Toshodaiji', 'Todaiji'], + }; + const newDoc = { + _id: 'nara', + temple: ['Yakushiji'], + }; + + expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( + newDoc + ); + }); }); describe('for object', () => { From 9d00b31a1ca32e1a4358c54fc949197c014ee75d Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sat, 23 Apr 2022 00:10:14 +0900 Subject: [PATCH 263/297] fix: change available Node.js version --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cd82bddb..9ab4175a 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ https://gitddb.com/docs/api/git-documentdb.gitdocumentdb # Usage ## Getting started ### **Prerequisite** -Node.js 12 or later +Node.js v12 - v16 ### **Installation** ``` npm i git-documentdb From 5e2235287bbb8d7b55605c1219fe8c8c57c1f39e Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sat, 23 Apr 2022 00:20:05 +0900 Subject: [PATCH 264/297] test: add more error cases --- test/remote_offline/json_patch_ot.test.ts | 122 +++++++++++++++++----- 1 file changed, 97 insertions(+), 25 deletions(-) diff --git a/test/remote_offline/json_patch_ot.test.ts b/test/remote_offline/json_patch_ot.test.ts index 6134413e..b3f43910 100644 --- a/test/remote_offline/json_patch_ot.test.ts +++ b/test/remote_offline/json_patch_ot.test.ts @@ -145,8 +145,8 @@ describe(' OT', () => { }); }); - describe('for array', () => { - it('patches from diff (new property)', () => { + describe('for array: ', () => { + it('new property', () => { const oldDoc = { _id: 'nara', }; @@ -160,7 +160,7 @@ describe(' OT', () => { ); }); - it('patches from diff (delete property)', () => { + it('delete property', () => { const oldDoc = { _id: 'nara', temple: ['Toshodaiji', 'Todaiji', 'Yakushiji'], @@ -174,7 +174,21 @@ describe(' OT', () => { ); }); - it('patches from diff (insert at first)', () => { + it('insert to empty array', () => { + const oldDoc = { + _id: 'nara', + temple: [], + }; + const newDoc = { + _id: 'nara', + temple: ['Toshodaiji'], + }; + + const diff = primitiveDiff.diff(oldDoc, newDoc)!; + expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + }); + + it('insert at first', () => { const oldDoc = { _id: 'nara', temple: ['Todaiji', 'Yakushiji'], @@ -188,7 +202,7 @@ describe(' OT', () => { expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); }); - it('patches from diff (insert at middle)', () => { + it('insert at middle', () => { const oldDoc = { _id: 'nara', temple: ['Todaiji', 'Yakushiji'], @@ -202,7 +216,7 @@ describe(' OT', () => { expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); }); - it('patches from diff (insert at last)', () => { + it('insert at last', () => { const oldDoc = { _id: 'nara', temple: ['Todaiji', 'Yakushiji'], @@ -216,7 +230,7 @@ describe(' OT', () => { expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); }); - it('patches from diff (insert two members)', () => { + it('insert two members', () => { const oldDoc = { _id: 'nara', temple: ['Todaiji', 'Yakushiji'], @@ -230,7 +244,7 @@ describe(' OT', () => { expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); }); - it('patches from diff (moving)', () => { + it('move', () => { const oldDoc = { _id: 'nara', temple: ['Todaiji', 'Yakushiji'], @@ -249,7 +263,7 @@ describe(' OT', () => { expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); }); - it('patches from diff (deleting)', () => { + it('delete', () => { const oldDoc = { _id: 'nara', temple: ['Todaiji', 'Yakushiji'], @@ -262,7 +276,80 @@ describe(' OT', () => { expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); }); - it('patches from diff (nesting arrays)', () => { + it.only('clear array', () => { + const oldDoc = { + _id: 'nara', + temple: ['Todaiji', 'Yakushiji'], + }; + const newDoc = { + _id: 'nara', + temple: [], + }; + const diff = primitiveDiff.diff(oldDoc, newDoc)!; + expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + }); + + it('delete one and add new one at the first position', () => { + const oldDoc = { + _id: 'nara', + temple: ['Toshodaiji', 'Todaiji'], + }; + const newDoc = { + _id: 'nara', + temple: ['Yakushiji', 'Todaiji'], + }; + + expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( + newDoc + ); + }); + + it('delete one and add new one at the last position', () => { + const oldDoc = { + _id: 'nara', + temple: ['Toshodaiji', 'Todaiji'], + }; + const newDoc = { + _id: 'nara', + temple: ['Todaiji', 'Yakushiji'], + }; + + expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( + newDoc + ); + }); + + it('delete one and add new one', () => { + const oldDoc = { + _id: 'nara', + temple: ['Toshodaiji'], + }; + const newDoc = { + _id: 'nara', + temple: ['Yakushiji'], + }; + + expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( + newDoc + ); + }); + + it.only('delete two and add new one', () => { + const oldDoc = { + _id: 'nara', + temple: ['Toshodaiji', 'Todaiji'], + }; + const newDoc = { + _id: 'nara', + temple: ['Yakushiji'], + }; + + expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( + newDoc + ); + }); + + it('nesting arrays', () => { const oldDoc = { cherry: [ ['NaraPark', 'double cherry blossoms'], @@ -322,21 +409,6 @@ describe(' OT', () => { const diff = myDiff.diff(oldDoc, newDoc)!; expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); }); - - it.only('delete two and add new one', () => { - const oldDoc = { - _id: 'nara', - temple: ['Toshodaiji', 'Todaiji'], - }; - const newDoc = { - _id: 'nara', - temple: ['Yakushiji'], - }; - - expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( - newDoc - ); - }); }); describe('for object', () => { From f854432eef6f78c19e8cbd55d21b55716bd0a797 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sat, 23 Apr 2022 16:39:07 +0900 Subject: [PATCH 265/297] test: found condition of [Error: Cannot pick up or remove undefined]. It occurrs when delete two or more elements from array --- test/remote_offline/json_patch_ot.test.ts | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/test/remote_offline/json_patch_ot.test.ts b/test/remote_offline/json_patch_ot.test.ts index b3f43910..a0b7bb30 100644 --- a/test/remote_offline/json_patch_ot.test.ts +++ b/test/remote_offline/json_patch_ot.test.ts @@ -263,7 +263,7 @@ describe(' OT', () => { expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); }); - it('delete', () => { + it('delete one', () => { const oldDoc = { _id: 'nara', temple: ['Todaiji', 'Yakushiji'], @@ -276,7 +276,20 @@ describe(' OT', () => { expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); }); - it.only('clear array', () => { + it.only('delete two', () => { + const oldDoc = { + _id: 'nara', + temple: ['Todaiji', 'Yakushiji', 'Toshodaiji'], + }; + const newDoc = { + _id: 'nara', + temple: ['Todaiji'], + }; + const diff = primitiveDiff.diff(oldDoc, newDoc)!; + expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + }); + + it('clear array', () => { const oldDoc = { _id: 'nara', temple: ['Todaiji', 'Yakushiji'], From e2c8ea35a652bc938c4e78ab0b6146bf86c805b2 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sat, 23 Apr 2022 17:28:39 +0900 Subject: [PATCH 266/297] fix: json1 can handle deleting two or more elements from array --- .vscode/launch.json | 2 +- src/remote/json_patch_ot.ts | 12 +++++++-- test/remote_offline/json_patch_ot.test.ts | 31 +++++++++++++++++++++-- 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 5b6c20a2..3ed042c0 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,7 +4,7 @@ "type": "pickString", "id": "choice", "description": "select a file", - "options": ["test/git_documentdb_open.test.js"], + "options": ["test/remote_offline/json_patch_ot.test.js"], }], "configurations": [ { diff --git a/src/remote/json_patch_ot.ts b/src/remote/json_patch_ot.ts index 7cf60b77..697b8b1f 100644 --- a/src/remote/json_patch_ot.ts +++ b/src/remote/json_patch_ot.ts @@ -121,6 +121,7 @@ export class JsonPatchOT implements IJsonPatch { // is Object sortedKeys = keys.sort(); } + let removeOffset = 0; // eslint-disable-next-line complexity sortedKeys.forEach(key => { if (Array.isArray(tree[key])) { @@ -145,7 +146,13 @@ export class JsonPatchOT implements IJsonPatch { if (arr[1] === 0 && arr[2] === 0) { // Deleted // See https://github.com/benjamine/jsondiffpatch/blob/master/docs/deltas.md - operations.push(removeOp(ancestors.concat(key))); + if (typeof key === 'string') { + operations.push(removeOp(ancestors.concat(key))); + } + else { + operations.push(removeOp(ancestors.concat((key as number) - removeOffset))); + removeOffset++; + } } else if (arr[0] === '' && arr[2] === 3) { // Moved @@ -186,7 +193,8 @@ export class JsonPatchOT implements IJsonPatch { * Use a nested array format instead. e.g.) ['x', ['y', {i:2}]]. * type.compose converts the flat array format to the nested array format. */ - return operations.reduce(type.compose, null); + const reducedOperations = operations.reduce(type.compose, null); + return reducedOperations; } apply (doc: JsonDoc, op: JSONOp): JsonDoc { diff --git a/test/remote_offline/json_patch_ot.test.ts b/test/remote_offline/json_patch_ot.test.ts index a0b7bb30..f7c37be0 100644 --- a/test/remote_offline/json_patch_ot.test.ts +++ b/test/remote_offline/json_patch_ot.test.ts @@ -244,6 +244,20 @@ describe(' OT', () => { expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); }); + it('insert two members at a distance', () => { + const oldDoc = { + _id: 'nara', + temple: ['Todaiji', 'Yakushiji'], + }; + const newDoc = { + _id: 'nara', + temple: ['Todaiji', 'Toshodaiji', 'Yakushiji', 'Kofukuji'], + }; + + const diff = primitiveDiff.diff(oldDoc, newDoc)!; + expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + }); + it('move', () => { const oldDoc = { _id: 'nara', @@ -276,7 +290,7 @@ describe(' OT', () => { expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); }); - it.only('delete two', () => { + it('delete two', () => { const oldDoc = { _id: 'nara', temple: ['Todaiji', 'Yakushiji', 'Toshodaiji'], @@ -289,6 +303,19 @@ describe(' OT', () => { expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); }); + it('delete two at a distance', () => { + const oldDoc = { + _id: 'nara', + temple: ['Todaiji', 'Yakushiji', 'Toshodaiji'], + }; + const newDoc = { + _id: 'nara', + temple: ['Yakushiji'], + }; + const diff = primitiveDiff.diff(oldDoc, newDoc)!; + expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + }); + it('clear array', () => { const oldDoc = { _id: 'nara', @@ -347,7 +374,7 @@ describe(' OT', () => { ); }); - it.only('delete two and add new one', () => { + it('delete two and add new one', () => { const oldDoc = { _id: 'nara', temple: ['Toshodaiji', 'Todaiji'], From b74b0dc16b83835d4ba1c7c70e34f1b666b2fc60 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sat, 23 Apr 2022 18:27:24 +0900 Subject: [PATCH 267/297] fix: wait next test to avoid secondary rate limit of GitHub --- test/remote_base/sync.ts | 5 ++++- test/remote_base/sync_trypush.ts | 5 ++++- test/remote_base/sync_trysync.ts | 7 +++++-- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/test/remote_base/sync.ts b/test/remote_base/sync.ts index 9a1d34d9..be565bd1 100644 --- a/test/remote_base/sync.ts +++ b/test/remote_base/sync.ts @@ -48,7 +48,10 @@ export const syncBase = ( // Use sandbox to restore stub and spy in parallel mocha tests let sandbox: sinon.SinonSandbox; - beforeEach(function () { + beforeEach(async function () { + // To avoid secondary rate limit of GitHub + await new Promise(resolve => setTimeout(resolve, 3000)); + sandbox = sinon.createSandbox(); }); diff --git a/test/remote_base/sync_trypush.ts b/test/remote_base/sync_trypush.ts index e8512af1..0a3f94db 100644 --- a/test/remote_base/sync_trypush.ts +++ b/test/remote_base/sync_trypush.ts @@ -50,7 +50,10 @@ export const syncTryPushBase = ( // Use sandbox to restore stub and spy in parallel mocha tests let sandbox: sinon.SinonSandbox; - beforeEach(function () { + beforeEach(async function () { + // To avoid secondary rate limit of GitHub + await new Promise(resolve => setTimeout(resolve, 3000)); + sandbox = sinon.createSandbox(); }); diff --git a/test/remote_base/sync_trysync.ts b/test/remote_base/sync_trysync.ts index f99876aa..caae1d09 100644 --- a/test/remote_base/sync_trysync.ts +++ b/test/remote_base/sync_trysync.ts @@ -59,7 +59,10 @@ export const syncTrySyncBase = ( // Use sandbox to restore stub and spy in parallel mocha tests let sandbox: sinon.SinonSandbox; - beforeEach(function () { + beforeEach(async function () { + // To avoid secondary rate limit of GitHub + await new Promise(resolve => setTimeout(resolve, 3000)); + sandbox = sinon.createSandbox(); }); @@ -77,7 +80,7 @@ export const syncTrySyncBase = ( * dbA : * after : */ - it('returns SyncResultNop when no commit', async () => { + it.only('returns SyncResultNop when no commit', async () => { const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { connection, }); From 62f8051f7407dd5698361f4206598cd05b224db3 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sat, 23 Apr 2022 18:35:50 +0900 Subject: [PATCH 268/297] test: remove .only --- test/remote_base/sync_trysync.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/remote_base/sync_trysync.ts b/test/remote_base/sync_trysync.ts index caae1d09..9bef7c0b 100644 --- a/test/remote_base/sync_trysync.ts +++ b/test/remote_base/sync_trysync.ts @@ -80,7 +80,7 @@ export const syncTrySyncBase = ( * dbA : * after : */ - it.only('returns SyncResultNop when no commit', async () => { + it('returns SyncResultNop when no commit', async () => { const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { connection, }); From 4ee31b03b512b911cd08d6dbcd438f08a98f34e8 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sun, 24 Apr 2022 00:09:19 +0900 Subject: [PATCH 269/297] build: bump to 0.4.7-alpha.18 --- package.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 808f8daa..bdf69c4a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "git-documentdb", - "version": "0.4.7-alpha.17", + "version": "0.4.7-alpha.18", "description": "Offline-first database that syncs with Git", "main": "dist/main.js", "types": "dist/main.d.ts", @@ -10,13 +10,14 @@ "scripts": { "build": "rm -rf dist/* && npm run lint && tsc --project src/tsconfig.json", "doc": "npm run build && npm run api-extractor && npm run crlf", - "mocha": "npm run rm-test-db && npx cross-env TS_NODE_FILES=true TS_NODE_PROJECT=tsconfig.mocha.json mocha", + "mocha-parallel": "npm run rm-test-db && npx cross-env TS_NODE_FILES=true TS_NODE_PROJECT=tsconfig.mocha.json mocha", + "mocha-no-parallel": "npm run rm-test-db && npx cross-env TS_NODE_FILES=true TS_NODE_PROJECT=tsconfig.mocha.json mocha --retries 0 --no-parallel", "mocha-unit-parallel": "npm run rm-test-db && npx cross-env TS_NODE_FILES=true TS_NODE_PROJECT=tsconfig.mocha.json mocha --retries 0", "mocha-unit": "npm run rm-test-db && npx cross-env TS_NODE_FILES=true TS_NODE_PROJECT=tsconfig.mocha.json mocha --retries 0 --no-parallel", "compile-tests": "tsc --project test/tsconfig.json && tsc --project test_plugin/tsconfig.json ", "rm-test-db": "rm -rf test/database* test_plugin/database*", "bench": "rm -rf benchmark/database* && npx ts-node ", - "test": "npx nyc npm run mocha \"test/**/*.test.ts\" && npm run rm-test-db", + "test": "npx nyc npm run mocha-parallel \"test/**/*.test.ts\" && npm run rm-test-db", "test-plugin": "npm run mocha \"test_plugin/**/*.test.ts\" && npm run rm-test-db", "upload-coverage": "npx coveralls < coverage/lcov.info", "prepare": "", From 5a67a510a7a7102f267e534cd822187974644e5a Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 26 Apr 2022 22:07:24 +0900 Subject: [PATCH 270/297] test: use commonId to reduce GitHub API calls in sync.ts --- test/remote_base/sync.ts | 41 ++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/test/remote_base/sync.ts b/test/remote_base/sync.ts index 9a1d34d9..b89df6e4 100644 --- a/test/remote_base/sync.ts +++ b/test/remote_base/sync.ts @@ -46,6 +46,11 @@ export const syncBase = ( return `${reposPrefix}${idCounter++}`; }; + // Use commonId to reduce API calls to GitHub + const commonId = () => { + return `${reposPrefix}common`; + }; + // Use sandbox to restore stub and spy in parallel mocha tests let sandbox: sinon.SinonSandbox; beforeEach(function () { @@ -149,7 +154,7 @@ export const syncBase = ( */ describe(' constructor', () => { it('set live to false by default', async () => { - const remoteURL = remoteURLBase + serialId(); + const remoteURL = remoteURLBase + commonId(); const dbName = serialId(); const gitDDB: GitDocumentDB = new GitDocumentDB({ dbName, @@ -167,7 +172,7 @@ export const syncBase = ( }); it('set syncDirection to both by default', async () => { - const remoteURL = remoteURLBase + serialId(); + const remoteURL = remoteURLBase + commonId(); const dbName = serialId(); const gitDDB: GitDocumentDB = new GitDocumentDB({ dbName, @@ -185,7 +190,7 @@ export const syncBase = ( }); it('set combineDbStrategy to combine-head-with-theirs by default', async () => { - const remoteURL = remoteURLBase + serialId(); + const remoteURL = remoteURLBase + commonId(); const dbName = serialId(); const gitDDB: GitDocumentDB = new GitDocumentDB({ dbName, @@ -203,7 +208,7 @@ export const syncBase = ( }); it('set includeCommits to false by default', async () => { - const remoteURL = remoteURLBase + serialId(); + const remoteURL = remoteURLBase + commonId(); const dbName = serialId(); const gitDDB: GitDocumentDB = new GitDocumentDB({ dbName, @@ -221,7 +226,7 @@ export const syncBase = ( }); it('set conflictResolutionStrategy to ours-diff by default', async () => { - const remoteURL = remoteURLBase + serialId(); + const remoteURL = remoteURLBase + commonId(); const dbName = serialId(); const gitDDB: GitDocumentDB = new GitDocumentDB({ dbName, @@ -239,7 +244,7 @@ export const syncBase = ( }); it('accepts remoteURL which ends with .git', async () => { - const remoteURL = remoteURLBase + serialId() + '.git'; + const remoteURL = remoteURLBase + commonId() + '.git'; const dbName = serialId(); const gitDDB: GitDocumentDB = new GitDocumentDB({ dbName, @@ -273,7 +278,7 @@ export const syncBase = ( }); it('throws IntervalTooSmallError when interval is less than minimumSyncInterval.', async () => { - const remoteURL = remoteURLBase + serialId(); + const remoteURL = remoteURLBase + commonId(); const dbName = serialId(); const gitDDB: GitDocumentDB = new GitDocumentDB({ dbName, @@ -305,7 +310,7 @@ export const syncBase = ( }); it('throws SyncIntervalLessThanOrEqualToRetryIntervalError', async () => { - const remoteURL = remoteURLBase + serialId(); + const remoteURL = remoteURLBase + commonId(); const dbName = serialId(); const gitDDB: GitDocumentDB = new GitDocumentDB({ dbName, @@ -367,7 +372,7 @@ export const syncBase = ( it('throws RemoteErr.InvalidRepositoryURLError.', async () => { const dbName = serialId(); - const remoteURL = remoteURLBase + serialId(); + const remoteURL = remoteURLBase + commonId(); const gitDDB: GitDocumentDB = new GitDocumentDB({ dbName, @@ -388,7 +393,7 @@ export const syncBase = ( it('throws RemoteErr.InvalidSSHKeyPathError.', async () => { const dbName = serialId(); - const remoteURL = remoteURLBase + serialId(); + const remoteURL = remoteURLBase + commonId(); const gitDDB: GitDocumentDB = new GitDocumentDB({ dbName, @@ -409,7 +414,7 @@ export const syncBase = ( it('throws RemoteErr.InvalidAuthenticationTypeError.', async () => { const dbName = serialId(); - const remoteURL = remoteURLBase + serialId(); + const remoteURL = remoteURLBase + commonId(); const gitDDB: GitDocumentDB = new GitDocumentDB({ dbName, @@ -434,7 +439,7 @@ export const syncBase = ( it('throws RemoteErr.HTTPError401AuthorizationRequired.', async () => { const dbName = serialId(); - const remoteURL = remoteURLBase + serialId(); + const remoteURL = remoteURLBase + commonId(); const gitDDB: GitDocumentDB = new GitDocumentDB({ dbName, @@ -459,7 +464,7 @@ export const syncBase = ( it('throws NetworkError', async () => { const dbName = serialId(); - const remoteURL = remoteURLBase + serialId(); + const remoteURL = remoteURLBase + commonId(); const gitDDB: GitDocumentDB = new GitDocumentDB({ dbName, @@ -481,7 +486,7 @@ export const syncBase = ( }); it('throws CannotCreateRemoteRepositoryError', async () => { - const remoteURL = remoteURLBase + serialId(); + const remoteURL = remoteURLBase + commonId(); const dbNameA = serialId(); @@ -536,7 +541,7 @@ export const syncBase = ( }); it('sets Git remote in .git/config', async () => { - const remoteURL = remoteURLBase + serialId(); + const remoteURL = remoteURLBase + commonId(); const dbNameA = serialId(); @@ -585,7 +590,7 @@ export const syncBase = ( }); it('skip setting origin when it already exists.', async () => { - const remoteURL = remoteURLBase + serialId(); + const remoteURL = remoteURLBase + commonId(); const dbNameA = serialId(); @@ -829,7 +834,7 @@ export const syncBase = ( }); it('throws PushNotAllowedError when syncDirection is pull', async () => { - const remoteURL = remoteURLBase + serialId(); + const remoteURL = remoteURLBase + commonId(); const dbName = serialId(); const gitDDB: GitDocumentDB = new GitDocumentDB({ dbName, @@ -1091,7 +1096,7 @@ export const syncBase = ( describe(' syncImpl()', () => { it('throws RepositoryNotOpenError.', async () => { const dbName = serialId(); - const remoteURL = remoteURLBase + serialId(); + const remoteURL = remoteURLBase + commonId(); const gitDDB: GitDocumentDB = new GitDocumentDB({ dbName, localDir, From 124401c3227418675777075eeb33b8db4f00c074 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sat, 30 Apr 2022 01:39:02 +0900 Subject: [PATCH 271/297] fix: use common repository for test to avoid secondary rate limit of GitHub --- .vscode/launch.json | 2 +- package-lock.json | 959 ++++++------------ package.json | 6 +- src/collection.ts | 2 +- src/crud/blob.ts | 2 +- src/crud/delete.ts | 2 +- src/crud/find.ts | 2 +- src/crud/get.ts | 2 +- src/crud/history.ts | 2 +- src/crud/put.ts | 2 +- src/git_documentdb.ts | 2 +- src/plugin/remote-isomorphic-git.ts | 6 +- src/remote/3way_merge.ts | 2 +- src/remote/combine.ts | 2 +- src/remote/push_worker.ts | 2 +- src/remote/sync.ts | 2 +- src/remote/sync_worker.ts | 2 +- src/remote/worker_utils.ts | 2 +- src/utils.ts | 2 +- test/collection_delete.test.ts | 2 +- test/collection_find.test.ts | 2 +- test/collection_get.test.ts | 2 +- test/collection_insert.test.ts | 2 +- test/collection_put.test.ts | 2 +- test/collection_update.test.ts | 2 +- test/crud/blob.test.ts | 4 +- test/crud/delete.test.ts | 2 +- test/crud/find.test.ts | 2 +- test/crud/get.test.ts | 4 +- test/crud/history.test.ts | 4 +- test/crud/put.test.ts | 2 +- test/git_documentdb_crud.test.ts | 2 +- test/git_documentdb_open.test.ts | 2 +- test/internal_plugin/checkfetch.test.ts | 2 +- test/internal_plugin/clone.test.ts | 2 +- test/internal_plugin/fetch.test.ts | 2 +- test/internal_plugin/push.test.ts | 11 +- test/remote_base/3way_merge.ts | 242 +++-- test/remote_base/3way_merge_ot.ts | 47 +- test/remote_base/combine.ts | 178 +++- test/remote_base/network_history.ts | 10 + test/remote_base/network_task_queue.ts | 38 +- test/remote_base/on_sync_event.ts | 22 + test/remote_base/sync.ts | 7 +- test/remote_base/sync_clone.ts | 27 +- test/remote_base/sync_events.ts | 170 +++- test/remote_base/sync_trypush.ts | 145 ++- test/remote_base/sync_trysync.ts | 207 +++- test/remote_isomorphic_git/3way_merge.test.ts | 2 +- .../3way_merge_ot.test.ts | 2 +- test/remote_isomorphic_git/combine.test.ts | 2 +- .../network_git_documentdb.test.ts | 2 +- .../network_history.test.ts | 2 +- .../network_task_queue.test.ts | 2 +- .../on_sync_event.test.ts | 2 +- test/remote_isomorphic_git/sync.test.ts | 4 +- test/remote_isomorphic_git/sync_clone.test.ts | 2 +- .../remote_isomorphic_git/sync_events.test.ts | 2 +- test/remote_isomorphic_git/sync_live.test.ts | 2 +- .../sync_trypush.test.ts | 2 +- .../sync_trysync.test.ts | 4 +- test/remote_utils.ts | 61 +- test/utils.ts | 2 +- 63 files changed, 1276 insertions(+), 964 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 3ed042c0..acd1bdec 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,7 +4,7 @@ "type": "pickString", "id": "choice", "description": "select a file", - "options": ["test/remote_offline/json_patch_ot.test.js"], + "options": ["test/remote_isomorphic_git/sync_trysync.test.js"], }], "configurations": [ { diff --git a/package-lock.json b/package-lock.json index f1d44261..7ce40899 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,21 +1,22 @@ { "name": "git-documentdb", - "version": "0.4.7-alpha.13", + "version": "0.4.7-alpha.18", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "git-documentdb", - "version": "0.4.7-alpha.13", + "version": "0.4.7-alpha.18", "license": "MPL-2.0", "dependencies": { "@octokit/rest": "^18.3.5", - "@sosuisen/isomorphic-git": "^1.10.1-alpha.8", "@sosuisen/jsondiffpatch": "^0.4.7", "async-lock": "^1.3.0", "cross-blob": "^2.0.0", "fs-extra": "^9.1.0", + "git-documentdb-plugin-remote-nodegit": "^1.0.4", "git-documentdb-remote-errors": "^1.0.3", + "isomorphic-git": "^1.17.1", "js-yaml": "^4.1.0", "ot-json1": "^1.0.2", "rimraf": "^3.0.2", @@ -45,7 +46,6 @@ "eslint-plugin-prettierx": "^0.14.0", "eslint-plugin-unicorn": "^36.0.0", "expect": "^27.0.2", - "git-documentdb-plugin-remote-nodegit": "^1.0.5-alpha.0", "hmtid": "^0.1.0", "mocha": "^8.3.2", "nyc": "^15.1.0", @@ -1094,7 +1094,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-2.1.1.tgz", "integrity": "sha512-/aPsuoj/1Dw/kzhkgz+ES6TxG0zfTMGLwuK2ZG00k/iJzYHTLCE8mVU8EPqEOp/lmxPoq1C1C9RYToRKb2KEfg==", - "dev": true, "engines": { "node": ">=10" }, @@ -1168,30 +1167,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/@sosuisen/isomorphic-git": { - "version": "1.10.1-alpha.8", - "resolved": "https://registry.npmjs.org/@sosuisen/isomorphic-git/-/isomorphic-git-1.10.1-alpha.8.tgz", - "integrity": "sha512-38pFxFkhQy6rEDBQhMFOXw9jvaV7RI+Dlw8SkYMxbhDvgAF7kfVy8DuyOoFqInlpy8rsTJWfGlHZPZFR+9LwrQ==", - "dependencies": { - "async-lock": "^1.1.0", - "clean-git-ref": "^2.0.1", - "crc-32": "^1.2.0", - "diff3": "0.0.3", - "ignore": "^5.1.4", - "minimisted": "^2.0.0", - "pako": "^1.0.10", - "pify": "^4.0.1", - "readable-stream": "^3.4.0", - "sha.js": "^2.4.9", - "simple-get": "^3.0.2" - }, - "bin": { - "isogit": "cli.cjs" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@sosuisen/jsondiffpatch": { "version": "0.4.7", "resolved": "https://registry.npmjs.org/@sosuisen/jsondiffpatch/-/jsondiffpatch-0.4.7.tgz", @@ -1211,7 +1186,6 @@ "version": "0.28.0-alpha.11", "resolved": "https://registry.npmjs.org/@sosuisen/nodegit/-/nodegit-0.28.0-alpha.11.tgz", "integrity": "sha512-mpztf9ncWxU7/agKQ6E7GvlBIa6H7m3YXuMjlPWVegHusqkbgPi4J01d2inCPhLz0CoC0F/L3LKJuDCAKDXJJg==", - "dev": true, "hasInstallScript": true, "dependencies": { "fs-extra": "^7.0.0", @@ -1232,7 +1206,6 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, "dependencies": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", @@ -1246,7 +1219,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, "optionalDependencies": { "graceful-fs": "^4.1.6" } @@ -1255,7 +1227,6 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, "engines": { "node": ">= 4.0.0" } @@ -1264,7 +1235,6 @@ "version": "4.0.6", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", - "dev": true, "dependencies": { "defer-to-connect": "^2.0.0" }, @@ -1312,7 +1282,6 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", - "dev": true, "dependencies": { "@types/http-cache-semantics": "*", "@types/keyv": "*", @@ -1342,8 +1311,7 @@ "node_modules/@types/http-cache-semantics": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", - "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==", - "dev": true + "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==" }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.3", @@ -1375,6 +1343,11 @@ "integrity": "sha512-5t9BhoORasuF5uCPr+d5/hdB++zRFUTMIZOzbNkr+jZh3yQht4HYbRDyj9fY8n2TZT30iW9huzav73x4NikqWg==", "dev": true }, + "node_modules/@types/json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha512-3YP80IxxFJB4b5tYC2SUPwkg0XQLiu0nWvhRgEatgjf+29IcWO9X1k8xRv5DGssJ/lCrjYTjQPcobJr2yWIVuQ==" + }, "node_modules/@types/json-schema": { "version": "7.0.9", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", @@ -1388,10 +1361,9 @@ "dev": true }, "node_modules/@types/keyv": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.3.tgz", - "integrity": "sha512-FXCJgyyN3ivVgRoml4h94G/p3kY+u/B86La+QptcqJaWtBWtmc6TtkNfS40n9bIvyLteHh7zXOtgbobORKPbDg==", - "dev": true, + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", + "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", "dependencies": { "@types/node": "*" } @@ -1411,8 +1383,7 @@ "node_modules/@types/node": { "version": "14.17.21", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.21.tgz", - "integrity": "sha512-zv8ukKci1mrILYiQOwGSV4FpkZhyxQtuFWGya2GujWg+zVAeRQ4qbaMmWp9vb9889CFA8JECH7lkwCL6Ygg8kA==", - "dev": true + "integrity": "sha512-zv8ukKci1mrILYiQOwGSV4FpkZhyxQtuFWGya2GujWg+zVAeRQ4qbaMmWp9vb9889CFA8JECH7lkwCL6Ygg8kA==" }, "node_modules/@types/normalize-package-data": { "version": "2.4.1", @@ -1436,7 +1407,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", - "dev": true, "dependencies": { "@types/node": "*" } @@ -1677,8 +1647,7 @@ "node_modules/abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, "node_modules/acorn": { "version": "7.4.1", @@ -1727,7 +1696,6 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -1824,8 +1792,7 @@ "node_modules/aproba": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" }, "node_modules/archy": { "version": "1.0.0", @@ -1837,7 +1804,6 @@ "version": "1.1.7", "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", - "dev": true, "dependencies": { "delegates": "^1.0.0", "readable-stream": "^2.0.6" @@ -1846,14 +1812,12 @@ "node_modules/are-we-there-yet/node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, "node_modules/are-we-there-yet/node_modules/readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -1868,7 +1832,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, "dependencies": { "safe-buffer": "~5.1.0" } @@ -1954,7 +1917,6 @@ "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "dev": true, "dependencies": { "safer-buffer": "~2.1.0" } @@ -1963,7 +1925,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true, "engines": { "node": ">=0.8" } @@ -1985,8 +1946,7 @@ "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, "node_modules/at-least-node": { "version": "1.0.0", @@ -2000,7 +1960,6 @@ "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true, "engines": { "node": "*" } @@ -2008,8 +1967,7 @@ "node_modules/aws4": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", - "dev": true + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" }, "node_modules/bail": { "version": "1.0.5", @@ -2030,7 +1988,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dev": true, "dependencies": { "tweetnacl": "^0.14.3" } @@ -2053,7 +2010,6 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==", - "dev": true, "dependencies": { "readable-stream": "^2.3.5", "safe-buffer": "^5.1.1" @@ -2062,14 +2018,12 @@ "node_modules/bl/node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, "node_modules/bl/node_modules/readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -2084,7 +2038,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, "dependencies": { "safe-buffer": "~5.1.0" } @@ -2148,7 +2101,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", - "dev": true, "dependencies": { "buffer-alloc-unsafe": "^1.1.0", "buffer-fill": "^1.0.0" @@ -2157,14 +2109,12 @@ "node_modules/buffer-alloc-unsafe": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", - "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", - "dev": true + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" }, "node_modules/buffer-fill": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", - "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=", - "dev": true + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=" }, "node_modules/buffer-from": { "version": "1.1.2", @@ -2187,7 +2137,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-2.0.1.tgz", "integrity": "sha512-EMMbsiOTcdngM/K6gV/OxF2x0t07+vMOWxZNSCRQMjO2MY2nhZQ6OYhOOpyQrbhqsgtvKGI7hcq6xjnA92USjg==", - "dev": true, "dependencies": { "@types/keyv": "^3.1.1", "keyv": "^4.0.0" @@ -2200,7 +2149,6 @@ "version": "7.0.2", "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", - "dev": true, "dependencies": { "clone-response": "^1.0.2", "get-stream": "^5.1.0", @@ -2273,8 +2221,7 @@ "node_modules/caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" }, "node_modules/chalk": { "version": "2.4.2", @@ -2344,7 +2291,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true, "engines": { "node": ">=10" } @@ -2444,7 +2390,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", - "dev": true, "dependencies": { "mimic-response": "^1.0.0" } @@ -2453,7 +2398,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true, "engines": { "node": ">=4" } @@ -2462,7 +2406,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -2503,7 +2446,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "dependencies": { "delayed-stream": "~1.0.0" }, @@ -2523,6 +2465,18 @@ "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", "dev": true }, + "node_modules/compress-brotli": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/compress-brotli/-/compress-brotli-1.3.6.tgz", + "integrity": "sha512-au99/GqZtUtiCBliqLFbWlhnCxn+XSYjwZ77q6mKN4La4qOXDoLVPZ50iXr0WmAyMxl8yqoq3Yq4OeQNPPkyeQ==", + "dependencies": { + "@types/json-buffer": "~3.0.0", + "json-buffer": "~3.0.1" + }, + "engines": { + "node": ">= 12" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -2537,8 +2491,7 @@ "node_modules/console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" }, "node_modules/contains-path": { "version": "0.1.0", @@ -2561,8 +2514,7 @@ "node_modules/core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, "node_modules/cosmiconfig": { "version": "7.0.0", @@ -2613,13 +2565,9 @@ } }, "node_modules/crc-32": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.0.tgz", - "integrity": "sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA==", - "dependencies": { - "exit-on-epipe": "~1.0.1", - "printj": "~1.1.0" - }, + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", "bin": { "crc32": "bin/crc32.njs" }, @@ -2694,7 +2642,6 @@ "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, "dependencies": { "assert-plus": "^1.0.0" }, @@ -2741,7 +2688,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-5.0.0.tgz", "integrity": "sha512-TLZWWybuxWgoW7Lykv+gq9xvzOsUjQ9tF09Tj6NSTYGMTCHNXzrPnD6Hi+TgZq19PyTAGH4Ll/NIM/eTGglnMw==", - "dev": true, "dependencies": { "mimic-response": "^2.0.0" }, @@ -2759,7 +2705,6 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true, "engines": { "node": ">=4.0.0" } @@ -2795,7 +2740,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", - "dev": true, "engines": { "node": ">=10" } @@ -2816,7 +2760,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true, "engines": { "node": ">=0.4.0" } @@ -2824,8 +2767,7 @@ "node_modules/delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" }, "node_modules/deprecation": { "version": "2.3.1", @@ -2836,7 +2778,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", - "dev": true, "bin": { "detect-libc": "bin/detect-libc.js" }, @@ -2908,14 +2849,12 @@ "node_modules/duplexer3": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", - "dev": true + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" }, "node_modules/ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dev": true, "dependencies": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" @@ -2967,7 +2906,6 @@ "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, "dependencies": { "once": "^1.4.0" } @@ -2988,7 +2926,6 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "dev": true, "engines": { "node": ">=6" } @@ -4092,14 +4029,6 @@ "node": ">=0.10.0" } }, - "node_modules/exit-on-epipe": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz", - "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==", - "engines": { - "node": ">=0.8" - } - }, "node_modules/expect": { "version": "27.2.5", "resolved": "https://registry.npmjs.org/expect/-/expect-27.2.5.tgz", @@ -4132,14 +4061,12 @@ "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, "node_modules/extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true, "engines": [ "node >=0.6.0" ] @@ -4147,8 +4074,7 @@ "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "node_modules/fast-diff": { "version": "1.2.0", @@ -4175,8 +4101,7 @@ "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" }, "node_modules/fast-levenshtein": { "version": "2.0.6", @@ -4394,7 +4319,6 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true, "engines": { "node": "*" } @@ -4403,7 +4327,6 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.6", @@ -4436,8 +4359,7 @@ "node_modules/fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" }, "node_modules/fs-extra": { "version": "9.1.0", @@ -4457,7 +4379,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, "dependencies": { "minipass": "^3.0.0" }, @@ -4500,7 +4421,6 @@ "version": "2.7.4", "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "dev": true, "dependencies": { "aproba": "^1.0.3", "console-control-strings": "^1.0.0", @@ -4516,7 +4436,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -4525,7 +4444,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, "dependencies": { "ansi-regex": "^2.0.0" }, @@ -4587,7 +4505,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, "dependencies": { "pump": "^3.0.0" }, @@ -4618,7 +4535,6 @@ "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, "dependencies": { "assert-plus": "^1.0.0" } @@ -4633,10 +4549,9 @@ } }, "node_modules/git-documentdb-plugin-remote-nodegit": { - "version": "1.0.5-alpha.0", - "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.5-alpha.0.tgz", - "integrity": "sha512-WJjWi0Ey3R/cD21FzDgtffxllOAeOhjDN87ysyR742zu7tj6VU9xCCnyC0VW54O+yiPW7lAuh9QcQS4kfNwxJA==", - "dev": true, + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.4.tgz", + "integrity": "sha512-+esXlN6PMmvwKZPU6dn/kSQnVe5QHU9xGzoNrLiqehz+VM1AXgNhsce/KipimG4wdzUS6tbS9QbgIgA4VjpbAw==", "dependencies": { "@sosuisen/nodegit": "^0.28.0-alpha.11", "git-documentdb-remote-errors": "^1.0.3", @@ -4728,7 +4643,6 @@ "version": "10.7.0", "resolved": "https://registry.npmjs.org/got/-/got-10.7.0.tgz", "integrity": "sha512-aWTDeNw9g+XqEZNcTjMMZSy7B7yE9toWOFYip7ofFTLleJhvZwUxxTxkTpKvF+p1SAA4VHmuEy7PiHTHyq8tJg==", - "dev": true, "dependencies": { "@sindresorhus/is": "^2.0.0", "@szmarczak/http-timer": "^4.0.0", @@ -4757,7 +4671,6 @@ "version": "0.10.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.10.0.tgz", "integrity": "sha512-EUV9jo4sffrwlg8s0zDhP0T2WD3pru5Xi0+HTE3zTUmBaZNhfkite9PdSJwdXLwPVW0jnAHT56pZHIOYckPEiw==", - "dev": true, "engines": { "node": ">=8" }, @@ -4813,7 +4726,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true, "engines": { "node": ">=4" } @@ -4823,7 +4735,6 @@ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", "deprecated": "this library is no longer supported", - "dev": true, "dependencies": { "ajv": "^6.12.3", "har-schema": "^2.0.0" @@ -4891,8 +4802,7 @@ "node_modules/has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "dev": true + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" }, "node_modules/hasha": { "version": "5.2.2", @@ -4978,14 +4888,12 @@ "node_modules/http-cache-semantics": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", - "dev": true + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" }, "node_modules/http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dev": true, "dependencies": { "assert-plus": "^1.0.0", "jsprim": "^1.2.2", @@ -5000,7 +4908,6 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, @@ -5020,7 +4927,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.4.tgz", "integrity": "sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ==", - "dev": true, "dependencies": { "minimatch": "^3.0.4" } @@ -5103,8 +5009,7 @@ "node_modules/ini": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" }, "node_modules/internal-slot": { "version": "1.0.3", @@ -5287,7 +5192,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, "dependencies": { "number-is-nan": "^1.0.0" }, @@ -5440,8 +5344,7 @@ "node_modules/is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, "node_modules/is-weakref": { "version": "1.0.1", @@ -5493,14 +5396,36 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "node_modules/isomorphic-git": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/isomorphic-git/-/isomorphic-git-1.17.1.tgz", + "integrity": "sha512-JLZzAmc78yELH6+bZgMzqV0KGEi2duo+URWmyEnSbhhibHwDsMIlUw5tr1ZVHjC2CUQtU0X/5EY9Sbzsyx7nug==", + "dependencies": { + "async-lock": "^1.1.0", + "clean-git-ref": "^2.0.1", + "crc-32": "^1.2.0", + "diff3": "0.0.3", + "ignore": "^5.1.4", + "minimisted": "^2.0.0", + "pako": "^1.0.10", + "pify": "^4.0.1", + "readable-stream": "^3.4.0", + "sha.js": "^2.4.9", + "simple-get": "^4.0.1" + }, + "bin": { + "isogit": "cli.cjs" + }, + "engines": { + "node": ">=12" + } }, "node_modules/isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, "node_modules/istanbul-lib-coverage": { "version": "3.0.0", @@ -5960,8 +5885,7 @@ "node_modules/jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" }, "node_modules/jsesc": { "version": "2.5.2", @@ -5978,8 +5902,7 @@ "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", @@ -5990,14 +5913,12 @@ "node_modules/json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, "node_modules/json-stable-stringify": { "version": "1.0.1", @@ -6017,14 +5938,12 @@ "node_modules/json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, "node_modules/json5": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dev": true, "dependencies": { "minimist": "^1.2.5" }, @@ -6059,7 +5978,6 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "dev": true, "engines": [ "node >=0.6.0" ], @@ -6090,11 +6008,11 @@ "dev": true }, "node_modules/keyv": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.3.tgz", - "integrity": "sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA==", - "dev": true, + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.2.2.tgz", + "integrity": "sha512-uYS0vKTlBIjNCAUqrjlxmruxOEiZxZIHXyp32sdcGmP+ukFrmWUnE//RcPXJH3Vxrni1H2gsQbjHE0bH7MtMQQ==", "dependencies": { + "compress-brotli": "^1.3.6", "json-buffer": "3.0.1" } }, @@ -6204,8 +6122,7 @@ "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "node_modules/lodash.clonedeep": { "version": "4.5.0", @@ -6356,7 +6273,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true, "engines": { "node": ">=8" } @@ -6465,7 +6381,6 @@ "version": "1.50.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz", "integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -6474,7 +6389,6 @@ "version": "2.1.33", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.33.tgz", "integrity": "sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==", - "dev": true, "dependencies": { "mime-db": "1.50.0" }, @@ -6527,10 +6441,9 @@ } }, "node_modules/minipass": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.5.tgz", - "integrity": "sha512-+8NzxD82XQoNKNrl1d/FSi+X8wAEWR+sbYAfIvub4Nz0d22plFG72CEVVaufV8PNf4qSslFTD8VMOxNVhHCjTw==", - "dev": true, + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", + "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", "dependencies": { "yallist": "^4.0.0" }, @@ -6541,14 +6454,12 @@ "node_modules/minipass/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/minizlib": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dev": true, "dependencies": { "minipass": "^3.0.0", "yallist": "^4.0.0" @@ -6560,21 +6471,24 @@ "node_modules/minizlib/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", "dependencies": { - "minimist": "^1.2.5" + "minimist": "^1.2.6" }, "bin": { "mkdirp": "bin/cmd.js" } }, + "node_modules/mkdirp/node_modules/minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" + }, "node_modules/mocha": { "version": "8.4.0", "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.4.0.tgz", @@ -6725,8 +6639,7 @@ "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/multimap": { "version": "1.1.0", @@ -6746,8 +6659,7 @@ "node_modules/nan": { "version": "2.15.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", - "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==", - "dev": true + "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==" }, "node_modules/nanoid": { "version": "3.1.20", @@ -6771,7 +6683,6 @@ "version": "2.9.1", "resolved": "https://registry.npmjs.org/needle/-/needle-2.9.1.tgz", "integrity": "sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ==", - "dev": true, "dependencies": { "debug": "^3.2.6", "iconv-lite": "^0.4.4", @@ -6788,7 +6699,6 @@ "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, "dependencies": { "ms": "^2.1.1" } @@ -6827,7 +6737,6 @@ "version": "7.1.2", "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-7.1.2.tgz", "integrity": "sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ==", - "dev": true, "dependencies": { "env-paths": "^2.2.0", "glob": "^7.1.4", @@ -6851,7 +6760,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -6872,7 +6780,6 @@ "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.13.0.tgz", "integrity": "sha512-Md1D3xnEne8b/HGVQkZZwV27WUi1ZRuZBij24TNaZwUPU3ZAFtvT6xxJGaUVillfmMKnn5oD1HoGsp2Ftik7SQ==", "deprecated": "Please upgrade to @mapbox/node-pre-gyp: the non-scoped node-pre-gyp package is deprecated and only the @mapbox scoped package will recieve updates in the future", - "dev": true, "dependencies": { "detect-libc": "^1.0.2", "mkdirp": "^0.5.1", @@ -6892,14 +6799,12 @@ "node_modules/node-pre-gyp/node_modules/chownr": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" }, "node_modules/node-pre-gyp/node_modules/fs-minipass": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", - "dev": true, "dependencies": { "minipass": "^2.6.0" } @@ -6908,7 +6813,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -6928,7 +6832,6 @@ "version": "2.9.0", "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "dev": true, "dependencies": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -6938,7 +6841,6 @@ "version": "1.3.3", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", - "dev": true, "dependencies": { "minipass": "^2.9.0" } @@ -6947,7 +6849,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", - "dev": true, "dependencies": { "abbrev": "1", "osenv": "^0.1.4" @@ -6960,7 +6861,6 @@ "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, "dependencies": { "glob": "^7.1.3" }, @@ -6972,7 +6872,6 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, "funding": [ { "type": "github", @@ -6992,7 +6891,6 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, "bin": { "semver": "bin/semver" } @@ -7001,7 +6899,6 @@ "version": "4.4.19", "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", - "dev": true, "dependencies": { "chownr": "^1.1.4", "fs-minipass": "^1.2.7", @@ -7018,8 +6915,7 @@ "node_modules/node-pre-gyp/node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, "node_modules/node-preload": { "version": "0.2.1", @@ -7043,7 +6939,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "dev": true, "dependencies": { "abbrev": "1" }, @@ -7088,7 +6983,6 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", - "dev": true, "engines": { "node": ">=10" }, @@ -7100,7 +6994,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.2.tgz", "integrity": "sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ==", - "dev": true, "dependencies": { "npm-normalize-package-bin": "^1.0.1" } @@ -7108,14 +7001,12 @@ "node_modules/npm-normalize-package-bin": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", - "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==", - "dev": true + "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==" }, "node_modules/npm-packlist": { "version": "1.4.8", "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", - "dev": true, "dependencies": { "ignore-walk": "^3.0.1", "npm-bundled": "^1.0.1", @@ -7126,7 +7017,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "dev": true, "dependencies": { "are-we-there-yet": "~1.1.2", "console-control-strings": "~1.1.0", @@ -7138,7 +7028,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -7391,7 +7280,6 @@ "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true, "engines": { "node": "*" } @@ -7400,7 +7288,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -7518,7 +7405,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -7527,7 +7413,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -7536,7 +7421,6 @@ "version": "0.1.5", "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", - "dev": true, "dependencies": { "os-homedir": "^1.0.0", "os-tmpdir": "^1.0.0" @@ -7567,7 +7451,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", - "dev": true, "engines": { "node": ">=8" } @@ -7585,7 +7468,6 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz", "integrity": "sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==", - "dev": true, "dependencies": { "p-timeout": "^3.1.0" }, @@ -7600,7 +7482,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true, "engines": { "node": ">=4" } @@ -7651,7 +7532,6 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", - "dev": true, "dependencies": { "p-finally": "^1.0.0" }, @@ -7798,8 +7678,7 @@ "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, "node_modules/picocolors": { "version": "0.2.1", @@ -8437,22 +8316,10 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/printj": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz", - "integrity": "sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==", - "bin": { - "printj": "bin/printj.njs" - }, - "engines": { - "node": ">=0.8" - } - }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "node_modules/process-on-spawn": { "version": "1.0.0", @@ -8501,14 +8368,12 @@ "node_modules/psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", - "dev": true + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" }, "node_modules/pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -8518,7 +8383,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true, "engines": { "node": ">=6" } @@ -8527,7 +8391,6 @@ "version": "6.5.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true, "engines": { "node": ">=0.6" } @@ -8555,8 +8418,7 @@ "node_modules/ramda": { "version": "0.25.0", "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.25.0.tgz", - "integrity": "sha512-GXpfrYVPwx3K7RQ6aYT8KPS8XViSXUVJT1ONhoKPE9VAleW42YE+U+8VEyGWt41EnEQW7gwecYJriTI0pKoecQ==", - "dev": true + "integrity": "sha512-GXpfrYVPwx3K7RQ6aYT8KPS8XViSXUVJT1ONhoKPE9VAleW42YE+U+8VEyGWt41EnEQW7gwecYJriTI0pKoecQ==" }, "node_modules/randombytes": { "version": "2.1.0", @@ -8571,7 +8433,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", @@ -8586,7 +8447,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -8847,7 +8707,6 @@ "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", - "dev": true, "dependencies": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", @@ -8929,7 +8788,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz", "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==", - "dev": true, "dependencies": { "lowercase-keys": "^2.0.0" } @@ -9017,20 +8875,17 @@ "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "node_modules/sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" }, "node_modules/semver": { "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, "dependencies": { "lru-cache": "^6.0.0" }, @@ -9051,7 +8906,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, "dependencies": { "yallist": "^4.0.0" }, @@ -9062,8 +8916,7 @@ "node_modules/semver/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/serialize-javascript": { "version": "5.0.1", @@ -9077,8 +8930,7 @@ "node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, "node_modules/sha.js": { "version": "2.4.11", @@ -9136,8 +8988,7 @@ "node_modules/signal-exit": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", - "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==", - "dev": true + "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==" }, "node_modules/simple-concat": { "version": "1.0.1", @@ -9159,32 +9010,60 @@ ] }, "node_modules/simple-get": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz", - "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], "dependencies": { - "decompress-response": "^4.2.0", + "decompress-response": "^6.0.0", "once": "^1.3.1", "simple-concat": "^1.0.0" } }, "node_modules/simple-get/node_modules/decompress-response": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", - "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", "dependencies": { - "mimic-response": "^2.0.0" + "mimic-response": "^3.1.0" }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/simple-html-tokenizer": { - "version": "0.5.11", - "resolved": "https://registry.npmjs.org/simple-html-tokenizer/-/simple-html-tokenizer-0.5.11.tgz", - "integrity": "sha512-C2WEK/Z3HoSFbYq8tI7ni3eOo/NneSPRoPpcM7WdLjFOArFuyXEjAoCdOC3DgMfRyziZQ1hCNR4mrNdWEvD0og==", - "dev": true - }, + "node_modules/simple-get/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/simple-html-tokenizer": { + "version": "0.5.11", + "resolved": "https://registry.npmjs.org/simple-html-tokenizer/-/simple-html-tokenizer-0.5.11.tgz", + "integrity": "sha512-C2WEK/Z3HoSFbYq8tI7ni3eOo/NneSPRoPpcM7WdLjFOArFuyXEjAoCdOC3DgMfRyziZQ1hCNR4mrNdWEvD0og==", + "dev": true + }, "node_modules/sinon": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/sinon/-/sinon-10.0.0.tgz", @@ -9389,7 +9268,6 @@ "version": "1.16.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dev": true, "dependencies": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", @@ -9481,7 +9359,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, "dependencies": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -9495,7 +9372,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -9504,7 +9380,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, "dependencies": { "ansi-regex": "^2.0.0" }, @@ -9667,7 +9542,6 @@ "version": "6.1.11", "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", - "dev": true, "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", @@ -9684,7 +9558,6 @@ "version": "1.16.3", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.3.tgz", "integrity": "sha512-NvCeXpYx7OsmOh8zIOP/ebG55zZmxLE0etfWRbWok+q2Qo8x/vOR/IJT1taADXPe+jsiu9axDb3X4B+iIgNlKw==", - "dev": true, "dependencies": { "chownr": "^1.0.1", "mkdirp": "^0.5.1", @@ -9695,14 +9568,12 @@ "node_modules/tar-fs/node_modules/chownr": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" }, "node_modules/tar-fs/node_modules/pump": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz", "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==", - "dev": true, "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -9712,7 +9583,6 @@ "version": "1.6.2", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", - "dev": true, "dependencies": { "bl": "^1.0.0", "buffer-alloc": "^1.2.0", @@ -9729,14 +9599,12 @@ "node_modules/tar-stream/node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, "node_modules/tar-stream/node_modules/readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -9751,7 +9619,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, "dependencies": { "safe-buffer": "~5.1.0" } @@ -9760,7 +9627,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, "bin": { "mkdirp": "bin/cmd.js" }, @@ -9771,8 +9637,7 @@ "node_modules/tar/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/test-exclude": { "version": "6.0.0", @@ -9823,8 +9688,7 @@ "node_modules/to-buffer": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", - "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==", - "dev": true + "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==" }, "node_modules/to-fast-properties": { "version": "2.0.0", @@ -9839,7 +9703,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-2.1.0.tgz", "integrity": "sha512-o3Qa6DGg1CEXshSdvWNX2sN4QHqg03SPq7U6jPXRahlQdl5dK8oXjkU/2/sGrnOZKeGV1zLSO8qPwyKklPPE7w==", - "dev": true, "engines": { "node": ">=8" } @@ -9860,7 +9723,6 @@ "version": "2.5.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, "dependencies": { "psl": "^1.1.28", "punycode": "^2.1.1" @@ -10043,7 +9905,6 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, "dependencies": { "safe-buffer": "^5.0.1" }, @@ -10054,8 +9915,7 @@ "node_modules/tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" }, "node_modules/type-check": { "version": "0.4.0", @@ -10270,7 +10130,6 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, "dependencies": { "punycode": "^2.1.0" } @@ -10285,7 +10144,6 @@ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "dev": true, "bin": { "uuid": "bin/uuid" } @@ -10319,7 +10177,6 @@ "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, "engines": [ "node >=0.6.0" ], @@ -10410,7 +10267,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "dependencies": { "isexe": "^2.0.0" }, @@ -10447,7 +10303,6 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, "dependencies": { "string-width": "^1.0.2 || 2" } @@ -10567,7 +10422,6 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, "engines": { "node": ">=0.4" } @@ -11590,8 +11444,7 @@ "@sindresorhus/is": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-2.1.1.tgz", - "integrity": "sha512-/aPsuoj/1Dw/kzhkgz+ES6TxG0zfTMGLwuK2ZG00k/iJzYHTLCE8mVU8EPqEOp/lmxPoq1C1C9RYToRKb2KEfg==", - "dev": true + "integrity": "sha512-/aPsuoj/1Dw/kzhkgz+ES6TxG0zfTMGLwuK2ZG00k/iJzYHTLCE8mVU8EPqEOp/lmxPoq1C1C9RYToRKb2KEfg==" }, "@sinonjs/commons": { "version": "1.8.3", @@ -11655,24 +11508,6 @@ } } }, - "@sosuisen/isomorphic-git": { - "version": "1.10.1-alpha.8", - "resolved": "https://registry.npmjs.org/@sosuisen/isomorphic-git/-/isomorphic-git-1.10.1-alpha.8.tgz", - "integrity": "sha512-38pFxFkhQy6rEDBQhMFOXw9jvaV7RI+Dlw8SkYMxbhDvgAF7kfVy8DuyOoFqInlpy8rsTJWfGlHZPZFR+9LwrQ==", - "requires": { - "async-lock": "^1.1.0", - "clean-git-ref": "^2.0.1", - "crc-32": "^1.2.0", - "diff3": "0.0.3", - "ignore": "^5.1.4", - "minimisted": "^2.0.0", - "pako": "^1.0.10", - "pify": "^4.0.1", - "readable-stream": "^3.4.0", - "sha.js": "^2.4.9", - "simple-get": "^3.0.2" - } - }, "@sosuisen/jsondiffpatch": { "version": "0.4.7", "resolved": "https://registry.npmjs.org/@sosuisen/jsondiffpatch/-/jsondiffpatch-0.4.7.tgz", @@ -11686,7 +11521,6 @@ "version": "0.28.0-alpha.11", "resolved": "https://registry.npmjs.org/@sosuisen/nodegit/-/nodegit-0.28.0-alpha.11.tgz", "integrity": "sha512-mpztf9ncWxU7/agKQ6E7GvlBIa6H7m3YXuMjlPWVegHusqkbgPi4J01d2inCPhLz0CoC0F/L3LKJuDCAKDXJJg==", - "dev": true, "requires": { "fs-extra": "^7.0.0", "got": "^10.7.0", @@ -11703,7 +11537,6 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, "requires": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", @@ -11714,7 +11547,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, "requires": { "graceful-fs": "^4.1.6" } @@ -11722,8 +11554,7 @@ "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" } } }, @@ -11731,7 +11562,6 @@ "version": "4.0.6", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", - "dev": true, "requires": { "defer-to-connect": "^2.0.0" } @@ -11776,7 +11606,6 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", - "dev": true, "requires": { "@types/http-cache-semantics": "*", "@types/keyv": "*", @@ -11806,8 +11635,7 @@ "@types/http-cache-semantics": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", - "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==", - "dev": true + "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==" }, "@types/istanbul-lib-coverage": { "version": "2.0.3", @@ -11839,6 +11667,11 @@ "integrity": "sha512-5t9BhoORasuF5uCPr+d5/hdB++zRFUTMIZOzbNkr+jZh3yQht4HYbRDyj9fY8n2TZT30iW9huzav73x4NikqWg==", "dev": true }, + "@types/json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha512-3YP80IxxFJB4b5tYC2SUPwkg0XQLiu0nWvhRgEatgjf+29IcWO9X1k8xRv5DGssJ/lCrjYTjQPcobJr2yWIVuQ==" + }, "@types/json-schema": { "version": "7.0.9", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", @@ -11852,10 +11685,9 @@ "dev": true }, "@types/keyv": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.3.tgz", - "integrity": "sha512-FXCJgyyN3ivVgRoml4h94G/p3kY+u/B86La+QptcqJaWtBWtmc6TtkNfS40n9bIvyLteHh7zXOtgbobORKPbDg==", - "dev": true, + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", + "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", "requires": { "@types/node": "*" } @@ -11875,8 +11707,7 @@ "@types/node": { "version": "14.17.21", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.21.tgz", - "integrity": "sha512-zv8ukKci1mrILYiQOwGSV4FpkZhyxQtuFWGya2GujWg+zVAeRQ4qbaMmWp9vb9889CFA8JECH7lkwCL6Ygg8kA==", - "dev": true + "integrity": "sha512-zv8ukKci1mrILYiQOwGSV4FpkZhyxQtuFWGya2GujWg+zVAeRQ4qbaMmWp9vb9889CFA8JECH7lkwCL6Ygg8kA==" }, "@types/normalize-package-data": { "version": "2.4.1", @@ -11900,7 +11731,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", - "dev": true, "requires": { "@types/node": "*" } @@ -12060,8 +11890,7 @@ "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, "acorn": { "version": "7.4.1", @@ -12096,7 +11925,6 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, "requires": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -12165,8 +11993,7 @@ "aproba": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" }, "archy": { "version": "1.0.0", @@ -12178,7 +12005,6 @@ "version": "1.1.7", "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", - "dev": true, "requires": { "delegates": "^1.0.0", "readable-stream": "^2.0.6" @@ -12187,14 +12013,12 @@ "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, "readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -12209,7 +12033,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, "requires": { "safe-buffer": "~5.1.0" } @@ -12276,7 +12099,6 @@ "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "dev": true, "requires": { "safer-buffer": "~2.1.0" } @@ -12284,8 +12106,7 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" }, "astral-regex": { "version": "2.0.0", @@ -12301,8 +12122,7 @@ "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, "at-least-node": { "version": "1.0.0", @@ -12312,14 +12132,12 @@ "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" }, "aws4": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", - "dev": true + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" }, "bail": { "version": "1.0.5", @@ -12336,7 +12154,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dev": true, "requires": { "tweetnacl": "^0.14.3" } @@ -12356,7 +12173,6 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==", - "dev": true, "requires": { "readable-stream": "^2.3.5", "safe-buffer": "^5.1.1" @@ -12365,14 +12181,12 @@ "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, "readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -12387,7 +12201,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, "requires": { "safe-buffer": "~5.1.0" } @@ -12440,7 +12253,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", - "dev": true, "requires": { "buffer-alloc-unsafe": "^1.1.0", "buffer-fill": "^1.0.0" @@ -12449,14 +12261,12 @@ "buffer-alloc-unsafe": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", - "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", - "dev": true + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" }, "buffer-fill": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", - "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=", - "dev": true + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=" }, "buffer-from": { "version": "1.1.2", @@ -12473,7 +12283,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-2.0.1.tgz", "integrity": "sha512-EMMbsiOTcdngM/K6gV/OxF2x0t07+vMOWxZNSCRQMjO2MY2nhZQ6OYhOOpyQrbhqsgtvKGI7hcq6xjnA92USjg==", - "dev": true, "requires": { "@types/keyv": "^3.1.1", "keyv": "^4.0.0" @@ -12483,7 +12292,6 @@ "version": "7.0.2", "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", - "dev": true, "requires": { "clone-response": "^1.0.2", "get-stream": "^5.1.0", @@ -12537,8 +12345,7 @@ "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" }, "chalk": { "version": "2.4.2", @@ -12587,8 +12394,7 @@ "chownr": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" }, "ci-info": { "version": "2.0.0", @@ -12671,7 +12477,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", - "dev": true, "requires": { "mimic-response": "^1.0.0" }, @@ -12679,16 +12484,14 @@ "mimic-response": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" } } }, "code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" }, "collapse-white-space": { "version": "1.0.6", @@ -12719,7 +12522,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "requires": { "delayed-stream": "~1.0.0" } @@ -12736,6 +12538,15 @@ "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", "dev": true }, + "compress-brotli": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/compress-brotli/-/compress-brotli-1.3.6.tgz", + "integrity": "sha512-au99/GqZtUtiCBliqLFbWlhnCxn+XSYjwZ77q6mKN4La4qOXDoLVPZ50iXr0WmAyMxl8yqoq3Yq4OeQNPPkyeQ==", + "requires": { + "@types/json-buffer": "~3.0.0", + "json-buffer": "~3.0.1" + } + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -12750,8 +12561,7 @@ "console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" }, "contains-path": { "version": "0.1.0", @@ -12771,8 +12581,7 @@ "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, "cosmiconfig": { "version": "7.0.0", @@ -12813,13 +12622,9 @@ } }, "crc-32": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.0.tgz", - "integrity": "sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA==", - "requires": { - "exit-on-epipe": "~1.0.1", - "printj": "~1.1.0" - } + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==" }, "create-require": { "version": "1.1.1", @@ -12870,7 +12675,6 @@ "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, "requires": { "assert-plus": "^1.0.0" } @@ -12900,7 +12704,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-5.0.0.tgz", "integrity": "sha512-TLZWWybuxWgoW7Lykv+gq9xvzOsUjQ9tF09Tj6NSTYGMTCHNXzrPnD6Hi+TgZq19PyTAGH4Ll/NIM/eTGglnMw==", - "dev": true, "requires": { "mimic-response": "^2.0.0" } @@ -12914,8 +12717,7 @@ "deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" }, "deep-is": { "version": "0.1.4", @@ -12941,8 +12743,7 @@ "defer-to-connect": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", - "dev": true + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==" }, "define-properties": { "version": "1.1.3", @@ -12956,14 +12757,12 @@ "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, "delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" }, "deprecation": { "version": "2.3.1", @@ -12973,8 +12772,7 @@ "detect-libc": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", - "dev": true + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" }, "detect-newline": { "version": "3.1.0", @@ -13025,14 +12823,12 @@ "duplexer3": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", - "dev": true + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dev": true, "requires": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" @@ -13080,7 +12876,6 @@ "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, "requires": { "once": "^1.4.0" } @@ -13097,8 +12892,7 @@ "env-paths": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "dev": true + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==" }, "error-ex": { "version": "1.3.2", @@ -13914,11 +13708,6 @@ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, - "exit-on-epipe": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz", - "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==" - }, "expect": { "version": "27.2.5", "resolved": "https://registry.npmjs.org/expect/-/expect-27.2.5.tgz", @@ -13944,20 +13733,17 @@ "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "fast-diff": { "version": "1.2.0", @@ -13981,8 +13767,7 @@ "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" }, "fast-levenshtein": { "version": "2.0.6", @@ -14144,14 +13929,12 @@ "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" }, "form-data": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.6", @@ -14167,8 +13950,7 @@ "fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" }, "fs-extra": { "version": "9.1.0", @@ -14185,7 +13967,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, "requires": { "minipass": "^3.0.0" } @@ -14218,7 +13999,6 @@ "version": "2.7.4", "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "dev": true, "requires": { "aproba": "^1.0.3", "console-control-strings": "^1.0.0", @@ -14233,14 +14013,12 @@ "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, "requires": { "ansi-regex": "^2.0.0" } @@ -14286,7 +14064,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, "requires": { "pump": "^3.0.0" } @@ -14305,7 +14082,6 @@ "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, "requires": { "assert-plus": "^1.0.0" } @@ -14317,10 +14093,9 @@ "dev": true }, "git-documentdb-plugin-remote-nodegit": { - "version": "1.0.5-alpha.0", - "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.5-alpha.0.tgz", - "integrity": "sha512-WJjWi0Ey3R/cD21FzDgtffxllOAeOhjDN87ysyR742zu7tj6VU9xCCnyC0VW54O+yiPW7lAuh9QcQS4kfNwxJA==", - "dev": true, + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.4.tgz", + "integrity": "sha512-+esXlN6PMmvwKZPU6dn/kSQnVe5QHU9xGzoNrLiqehz+VM1AXgNhsce/KipimG4wdzUS6tbS9QbgIgA4VjpbAw==", "requires": { "@sosuisen/nodegit": "^0.28.0-alpha.11", "git-documentdb-remote-errors": "^1.0.3", @@ -14391,7 +14166,6 @@ "version": "10.7.0", "resolved": "https://registry.npmjs.org/got/-/got-10.7.0.tgz", "integrity": "sha512-aWTDeNw9g+XqEZNcTjMMZSy7B7yE9toWOFYip7ofFTLleJhvZwUxxTxkTpKvF+p1SAA4VHmuEy7PiHTHyq8tJg==", - "dev": true, "requires": { "@sindresorhus/is": "^2.0.0", "@szmarczak/http-timer": "^4.0.0", @@ -14413,8 +14187,7 @@ "type-fest": { "version": "0.10.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.10.0.tgz", - "integrity": "sha512-EUV9jo4sffrwlg8s0zDhP0T2WD3pru5Xi0+HTE3zTUmBaZNhfkite9PdSJwdXLwPVW0jnAHT56pZHIOYckPEiw==", - "dev": true + "integrity": "sha512-EUV9jo4sffrwlg8s0zDhP0T2WD3pru5Xi0+HTE3zTUmBaZNhfkite9PdSJwdXLwPVW0jnAHT56pZHIOYckPEiw==" } } }, @@ -14451,14 +14224,12 @@ "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" }, "har-validator": { "version": "5.1.5", "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "dev": true, "requires": { "ajv": "^6.12.3", "har-schema": "^2.0.0" @@ -14502,8 +14273,7 @@ "has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "dev": true + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" }, "hasha": { "version": "5.2.2", @@ -14568,14 +14338,12 @@ "http-cache-semantics": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", - "dev": true + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dev": true, "requires": { "assert-plus": "^1.0.0", "jsprim": "^1.2.2", @@ -14586,7 +14354,6 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, "requires": { "safer-buffer": ">= 2.1.2 < 3" } @@ -14600,7 +14367,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.4.tgz", "integrity": "sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ==", - "dev": true, "requires": { "minimatch": "^3.0.4" } @@ -14662,8 +14428,7 @@ "ini": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" }, "internal-slot": { "version": "1.0.3", @@ -14781,7 +14546,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, "requires": { "number-is-nan": "^1.0.0" } @@ -14876,8 +14640,7 @@ "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, "is-weakref": { "version": "1.0.1", @@ -14915,14 +14678,30 @@ "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "isomorphic-git": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/isomorphic-git/-/isomorphic-git-1.17.1.tgz", + "integrity": "sha512-JLZzAmc78yELH6+bZgMzqV0KGEi2duo+URWmyEnSbhhibHwDsMIlUw5tr1ZVHjC2CUQtU0X/5EY9Sbzsyx7nug==", + "requires": { + "async-lock": "^1.1.0", + "clean-git-ref": "^2.0.1", + "crc-32": "^1.2.0", + "diff3": "0.0.3", + "ignore": "^5.1.4", + "minimisted": "^2.0.0", + "pako": "^1.0.10", + "pify": "^4.0.1", + "readable-stream": "^3.4.0", + "sha.js": "^2.4.9", + "simple-get": "^4.0.1" + } }, "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, "istanbul-lib-coverage": { "version": "3.0.0", @@ -15277,8 +15056,7 @@ "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" }, "jsesc": { "version": "2.5.2", @@ -15289,8 +15067,7 @@ "json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" }, "json-parse-even-better-errors": { "version": "2.3.1", @@ -15301,14 +15078,12 @@ "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, "json-stable-stringify": { "version": "1.0.1", @@ -15328,14 +15103,12 @@ "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, "json5": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dev": true, "requires": { "minimist": "^1.2.5" } @@ -15359,7 +15132,6 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "dev": true, "requires": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", @@ -15384,11 +15156,11 @@ "dev": true }, "keyv": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.3.tgz", - "integrity": "sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA==", - "dev": true, + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.2.2.tgz", + "integrity": "sha512-uYS0vKTlBIjNCAUqrjlxmruxOEiZxZIHXyp32sdcGmP+ukFrmWUnE//RcPXJH3Vxrni1H2gsQbjHE0bH7MtMQQ==", "requires": { + "compress-brotli": "^1.3.6", "json-buffer": "3.0.1" } }, @@ -15473,8 +15245,7 @@ "lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "lodash.clonedeep": { "version": "4.5.0", @@ -15596,8 +15367,7 @@ "lowercase-keys": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" }, "lru-cache": { "version": "4.1.5", @@ -15676,14 +15446,12 @@ "mime-db": { "version": "1.50.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz", - "integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==", - "dev": true + "integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==" }, "mime-types": { "version": "2.1.33", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.33.tgz", "integrity": "sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==", - "dev": true, "requires": { "mime-db": "1.50.0" } @@ -15721,10 +15489,9 @@ } }, "minipass": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.5.tgz", - "integrity": "sha512-+8NzxD82XQoNKNrl1d/FSi+X8wAEWR+sbYAfIvub4Nz0d22plFG72CEVVaufV8PNf4qSslFTD8VMOxNVhHCjTw==", - "dev": true, + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", + "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", "requires": { "yallist": "^4.0.0" }, @@ -15732,8 +15499,7 @@ "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } }, @@ -15741,7 +15507,6 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dev": true, "requires": { "minipass": "^3.0.0", "yallist": "^4.0.0" @@ -15750,18 +15515,23 @@ "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } }, "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", "requires": { - "minimist": "^1.2.5" + "minimist": "^1.2.6" + }, + "dependencies": { + "minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" + } } }, "mocha": { @@ -15875,8 +15645,7 @@ "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "multimap": { "version": "1.1.0", @@ -15893,8 +15662,7 @@ "nan": { "version": "2.15.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", - "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==", - "dev": true + "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==" }, "nanoid": { "version": "3.1.20", @@ -15912,7 +15680,6 @@ "version": "2.9.1", "resolved": "https://registry.npmjs.org/needle/-/needle-2.9.1.tgz", "integrity": "sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ==", - "dev": true, "requires": { "debug": "^3.2.6", "iconv-lite": "^0.4.4", @@ -15923,7 +15690,6 @@ "version": "3.2.7", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, "requires": { "ms": "^2.1.1" } @@ -15961,7 +15727,6 @@ "version": "7.1.2", "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-7.1.2.tgz", "integrity": "sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ==", - "dev": true, "requires": { "env-paths": "^2.2.0", "glob": "^7.1.4", @@ -15979,7 +15744,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -15995,7 +15759,6 @@ "version": "0.13.0", "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.13.0.tgz", "integrity": "sha512-Md1D3xnEne8b/HGVQkZZwV27WUi1ZRuZBij24TNaZwUPU3ZAFtvT6xxJGaUVillfmMKnn5oD1HoGsp2Ftik7SQ==", - "dev": true, "requires": { "detect-libc": "^1.0.2", "mkdirp": "^0.5.1", @@ -16012,14 +15775,12 @@ "chownr": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" }, "fs-minipass": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", - "dev": true, "requires": { "minipass": "^2.6.0" } @@ -16028,7 +15789,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -16042,7 +15802,6 @@ "version": "2.9.0", "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "dev": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -16052,7 +15811,6 @@ "version": "1.3.3", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", - "dev": true, "requires": { "minipass": "^2.9.0" } @@ -16061,7 +15819,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", - "dev": true, "requires": { "abbrev": "1", "osenv": "^0.1.4" @@ -16071,7 +15828,6 @@ "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, "requires": { "glob": "^7.1.3" } @@ -16079,20 +15835,17 @@ "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" }, "tar": { "version": "4.4.19", "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", - "dev": true, "requires": { "chownr": "^1.1.4", "fs-minipass": "^1.2.7", @@ -16106,8 +15859,7 @@ "yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" } } }, @@ -16130,7 +15882,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "dev": true, "requires": { "abbrev": "1" } @@ -16164,14 +15915,12 @@ "normalize-url": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", - "dev": true + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==" }, "npm-bundled": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.2.tgz", "integrity": "sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ==", - "dev": true, "requires": { "npm-normalize-package-bin": "^1.0.1" } @@ -16179,14 +15928,12 @@ "npm-normalize-package-bin": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", - "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==", - "dev": true + "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==" }, "npm-packlist": { "version": "1.4.8", "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", - "dev": true, "requires": { "ignore-walk": "^3.0.1", "npm-bundled": "^1.0.1", @@ -16197,7 +15944,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "dev": true, "requires": { "are-we-there-yet": "~1.1.2", "console-control-strings": "~1.1.0", @@ -16208,8 +15954,7 @@ "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" }, "nyc": { "version": "15.1.0", @@ -16406,14 +16151,12 @@ "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, "object-inspect": { "version": "1.11.0", @@ -16497,20 +16240,17 @@ "os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" }, "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" }, "osenv": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", - "dev": true, "requires": { "os-homedir": "^1.0.0", "os-tmpdir": "^1.0.0" @@ -16542,8 +16282,7 @@ "p-cancelable": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", - "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", - "dev": true + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==" }, "p-defer": { "version": "1.0.0", @@ -16555,7 +16294,6 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz", "integrity": "sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==", - "dev": true, "requires": { "p-timeout": "^3.1.0" } @@ -16563,8 +16301,7 @@ "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" }, "p-limit": { "version": "3.1.0", @@ -16597,7 +16334,6 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", - "dev": true, "requires": { "p-finally": "^1.0.0" } @@ -16711,8 +16447,7 @@ "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, "picocolors": { "version": "0.2.1", @@ -17178,16 +16913,10 @@ } } }, - "printj": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz", - "integrity": "sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==" - }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "process-on-spawn": { "version": "1.0.0", @@ -17232,14 +16961,12 @@ "psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", - "dev": true + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" }, "pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -17248,14 +16975,12 @@ "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, "qs": { "version": "6.5.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" }, "queue-microtask": { "version": "1.2.3", @@ -17266,8 +16991,7 @@ "ramda": { "version": "0.25.0", "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.25.0.tgz", - "integrity": "sha512-GXpfrYVPwx3K7RQ6aYT8KPS8XViSXUVJT1ONhoKPE9VAleW42YE+U+8VEyGWt41EnEQW7gwecYJriTI0pKoecQ==", - "dev": true + "integrity": "sha512-GXpfrYVPwx3K7RQ6aYT8KPS8XViSXUVJT1ONhoKPE9VAleW42YE+U+8VEyGWt41EnEQW7gwecYJriTI0pKoecQ==" }, "randombytes": { "version": "2.1.0", @@ -17282,7 +17006,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, "requires": { "deep-extend": "^0.6.0", "ini": "~1.3.0", @@ -17293,8 +17016,7 @@ "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" } } }, @@ -17494,7 +17216,6 @@ "version": "2.88.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "dev": true, "requires": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", @@ -17561,7 +17282,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz", "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==", - "dev": true, "requires": { "lowercase-keys": "^2.0.0" } @@ -17621,20 +17341,17 @@ "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" }, "semver": { "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, "requires": { "lru-cache": "^6.0.0" }, @@ -17643,7 +17360,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, "requires": { "yallist": "^4.0.0" } @@ -17651,8 +17367,7 @@ "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } }, @@ -17674,8 +17389,7 @@ "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, "sha.js": { "version": "2.4.11", @@ -17721,8 +17435,7 @@ "signal-exit": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", - "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==", - "dev": true + "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==" }, "simple-concat": { "version": "1.0.1", @@ -17730,22 +17443,27 @@ "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==" }, "simple-get": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz", - "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", "requires": { - "decompress-response": "^4.2.0", + "decompress-response": "^6.0.0", "once": "^1.3.1", "simple-concat": "^1.0.0" }, "dependencies": { "decompress-response": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", - "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", "requires": { - "mimic-response": "^2.0.0" + "mimic-response": "^3.1.0" } + }, + "mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==" } } }, @@ -17917,7 +17635,6 @@ "version": "1.16.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dev": true, "requires": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", @@ -17978,7 +17695,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -17988,14 +17704,12 @@ "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, "requires": { "ansi-regex": "^2.0.0" } @@ -18122,7 +17836,6 @@ "version": "6.1.11", "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", - "dev": true, "requires": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", @@ -18135,14 +17848,12 @@ "mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } }, @@ -18150,7 +17861,6 @@ "version": "1.16.3", "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.3.tgz", "integrity": "sha512-NvCeXpYx7OsmOh8zIOP/ebG55zZmxLE0etfWRbWok+q2Qo8x/vOR/IJT1taADXPe+jsiu9axDb3X4B+iIgNlKw==", - "dev": true, "requires": { "chownr": "^1.0.1", "mkdirp": "^0.5.1", @@ -18161,14 +17871,12 @@ "chownr": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" }, "pump": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz", "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==", - "dev": true, "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -18180,7 +17888,6 @@ "version": "1.6.2", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", - "dev": true, "requires": { "bl": "^1.0.0", "buffer-alloc": "^1.2.0", @@ -18194,14 +17901,12 @@ "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, "readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -18216,7 +17921,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, "requires": { "safe-buffer": "~5.1.0" } @@ -18265,8 +17969,7 @@ "to-buffer": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", - "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==", - "dev": true + "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==" }, "to-fast-properties": { "version": "2.0.0", @@ -18277,8 +17980,7 @@ "to-readable-stream": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-2.1.0.tgz", - "integrity": "sha512-o3Qa6DGg1CEXshSdvWNX2sN4QHqg03SPq7U6jPXRahlQdl5dK8oXjkU/2/sGrnOZKeGV1zLSO8qPwyKklPPE7w==", - "dev": true + "integrity": "sha512-o3Qa6DGg1CEXshSdvWNX2sN4QHqg03SPq7U6jPXRahlQdl5dK8oXjkU/2/sGrnOZKeGV1zLSO8qPwyKklPPE7w==" }, "to-regex-range": { "version": "5.0.1", @@ -18293,7 +17995,6 @@ "version": "2.5.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, "requires": { "psl": "^1.1.28", "punycode": "^2.1.1" @@ -18421,7 +18122,6 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, "requires": { "safe-buffer": "^5.0.1" } @@ -18429,8 +18129,7 @@ "tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" }, "type-check": { "version": "0.4.0", @@ -18592,7 +18291,6 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, "requires": { "punycode": "^2.1.0" } @@ -18605,8 +18303,7 @@ "uuid": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" }, "v8-compile-cache": { "version": "2.3.0", @@ -18634,7 +18331,6 @@ "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, "requires": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", @@ -18706,7 +18402,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "requires": { "isexe": "^2.0.0" } @@ -18734,7 +18429,6 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, "requires": { "string-width": "^1.0.2 || 2" } @@ -18831,8 +18525,7 @@ "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" }, "y18n": { "version": "5.0.8", diff --git a/package.json b/package.json index bdf69c4a..f4247845 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "rm-test-db": "rm -rf test/database* test_plugin/database*", "bench": "rm -rf benchmark/database* && npx ts-node ", "test": "npx nyc npm run mocha-parallel \"test/**/*.test.ts\" && npm run rm-test-db", - "test-plugin": "npm run mocha \"test_plugin/**/*.test.ts\" && npm run rm-test-db", + "test-plugin": "npm run mocha-parallel \"test_plugin/**/*.test.ts\" && npm run rm-test-db", "upload-coverage": "npx coveralls < coverage/lcov.info", "prepare": "", "prepublishOnly": "npm run build && npm test", @@ -67,7 +67,6 @@ "eslint-plugin-prettierx": "^0.14.0", "eslint-plugin-unicorn": "^36.0.0", "expect": "^27.0.2", - "git-documentdb-plugin-remote-nodegit": "^1.0.5-alpha.0", "hmtid": "^0.1.0", "mocha": "^8.3.2", "nyc": "^15.1.0", @@ -79,12 +78,13 @@ }, "dependencies": { "@octokit/rest": "^18.3.5", - "@sosuisen/isomorphic-git": "^1.10.1-alpha.8", "@sosuisen/jsondiffpatch": "^0.4.7", "async-lock": "^1.3.0", "cross-blob": "^2.0.0", "fs-extra": "^9.1.0", + "git-documentdb-plugin-remote-nodegit": "^1.0.4", "git-documentdb-remote-errors": "^1.0.3", + "isomorphic-git": "^1.17.1", "js-yaml": "^4.1.0", "ot-json1": "^1.0.2", "rimraf": "^3.0.2", diff --git a/src/collection.ts b/src/collection.ts index 4e393c90..a1a14d51 100644 --- a/src/collection.ts +++ b/src/collection.ts @@ -9,7 +9,7 @@ import fs from 'fs'; import path from 'path'; -import { readTree, resolveRef } from '@sosuisen/isomorphic-git'; +import { readTree, resolveRef } from 'isomorphic-git'; import { monotonicFactory, ULID } from 'ulid'; import { Err } from './error'; import { diff --git a/src/crud/blob.ts b/src/crud/blob.ts index 80152d99..7b40bbb9 100644 --- a/src/crud/blob.ts +++ b/src/crud/blob.ts @@ -8,7 +8,7 @@ import fs from 'fs'; import yaml from 'js-yaml'; -import { readBlob, ReadBlobResult, resolveRef } from '@sosuisen/isomorphic-git'; +import { readBlob, ReadBlobResult, resolveRef } from 'isomorphic-git'; import { FRONT_MATTER_POSTFIX, YAML_POSTFIX } from '../const'; import { utf8decode } from '../utils'; import { Err } from '../error'; diff --git a/src/crud/delete.ts b/src/crud/delete.ts index 66189e3d..8f7153d9 100644 --- a/src/crud/delete.ts +++ b/src/crud/delete.ts @@ -8,7 +8,7 @@ import path from 'path'; import fs from 'fs-extra'; -import git from '@sosuisen/isomorphic-git'; +import git from 'isomorphic-git'; import { SHORT_SHA_LENGTH } from '../const'; import { GitDDBInterface } from '../types_gitddb'; import { Err } from '../error'; diff --git a/src/crud/find.ts b/src/crud/find.ts index a6a4fdd6..23c1ec05 100644 --- a/src/crud/find.ts +++ b/src/crud/find.ts @@ -13,7 +13,7 @@ import { resolveRef, TreeEntry, TreeObject, -} from '@sosuisen/isomorphic-git'; +} from 'isomorphic-git'; import { GIT_DOCUMENTDB_METADATA_DIR } from '../const'; import { Err } from '../error'; import { diff --git a/src/crud/get.ts b/src/crud/get.ts index 744e6d72..1681db0e 100644 --- a/src/crud/get.ts +++ b/src/crud/get.ts @@ -8,7 +8,7 @@ import path from 'path'; import fs from 'fs-extra'; -import { ReadBlobResult } from '@sosuisen/isomorphic-git'; +import { ReadBlobResult } from 'isomorphic-git'; import { GitDDBInterface } from '../types_gitddb'; import { Err } from '../error'; import { diff --git a/src/crud/history.ts b/src/crud/history.ts index a77e3ce0..7f4e3225 100644 --- a/src/crud/history.ts +++ b/src/crud/history.ts @@ -6,7 +6,7 @@ * found in the LICENSE file in the root directory of gitDDB source tree. */ -import { log, readBlob, ReadBlobResult } from '@sosuisen/isomorphic-git'; +import { log, readBlob, ReadBlobResult } from 'isomorphic-git'; import fs from 'fs-extra'; import { Doc, diff --git a/src/crud/put.ts b/src/crud/put.ts index e78a636b..b8e0b907 100644 --- a/src/crud/put.ts +++ b/src/crud/put.ts @@ -8,7 +8,7 @@ import path from 'path'; import fs from 'fs-extra'; -import git from '@sosuisen/isomorphic-git'; +import git from 'isomorphic-git'; import { normalizeCommit } from '../utils'; import { SHORT_SHA_LENGTH } from '../const'; import { NormalizedCommit, PutOptions, PutResult } from '../types'; diff --git a/src/git_documentdb.ts b/src/git_documentdb.ts index 6c3575c9..aa276cae 100644 --- a/src/git_documentdb.ts +++ b/src/git_documentdb.ts @@ -7,7 +7,7 @@ */ import path from 'path'; -import git from '@sosuisen/isomorphic-git'; +import git from 'isomorphic-git'; import fs from 'fs-extra'; import rimraf from 'rimraf'; import { ILogObject, Logger, TLogLevelName } from 'tslog'; diff --git a/src/plugin/remote-isomorphic-git.ts b/src/plugin/remote-isomorphic-git.ts index 9ac1b83c..3dfecc3e 100644 --- a/src/plugin/remote-isomorphic-git.ts +++ b/src/plugin/remote-isomorphic-git.ts @@ -7,7 +7,7 @@ */ import fs from 'fs'; -import git from '@sosuisen/isomorphic-git'; +import git from 'isomorphic-git'; import { Logger } from 'tslog'; import { CannotConnectError, @@ -21,7 +21,7 @@ import { NetworkError, UnfetchedCommitExistsError, } from 'git-documentdb-remote-errors'; -import httpClient from '@sosuisen/isomorphic-git/http/node'; +import httpClient from 'isomorphic-git/http/node'; import { ConnectionSettingsGitHub, RemoteOptions } from '../types'; import { NETWORK_RETRY, NETWORK_RETRY_INTERVAL } from '../const'; import { sleep } from '../utils'; @@ -36,7 +36,7 @@ export const type = 'remote'; * @public */ // eslint-disable-next-line @typescript-eslint/naming-convention -export const name = '@sosuisen/isomorphic-git'; +export const name = 'isomorphic-git'; /** * Insert credential options for GitHub diff --git a/src/remote/3way_merge.ts b/src/remote/3way_merge.ts index d13773c5..66e576de 100644 --- a/src/remote/3way_merge.ts +++ b/src/remote/3way_merge.ts @@ -1,5 +1,5 @@ import nodePath, { basename } from 'path'; -import git, { TreeEntry, WalkerEntry } from '@sosuisen/isomorphic-git'; +import git, { TreeEntry, WalkerEntry } from 'isomorphic-git'; import fs from 'fs-extra'; import { DEFAULT_CONFLICT_RESOLUTION_STRATEGY } from '../const'; import { Err } from '../error'; diff --git a/src/remote/combine.ts b/src/remote/combine.ts index fff52f0a..cee82b16 100644 --- a/src/remote/combine.ts +++ b/src/remote/combine.ts @@ -7,7 +7,7 @@ * found in the LICENSE file in the root directory of this source tree. */ import path from 'path'; -import git from '@sosuisen/isomorphic-git'; +import git from 'isomorphic-git'; import fs from 'fs-extra'; import { ulid } from 'ulid'; import rimraf from 'rimraf'; diff --git a/src/remote/push_worker.ts b/src/remote/push_worker.ts index ee7e37f3..8ab95a7d 100644 --- a/src/remote/push_worker.ts +++ b/src/remote/push_worker.ts @@ -6,7 +6,7 @@ * found in the LICENSE file in the root directory of gitDDB source tree. */ -import git from '@sosuisen/isomorphic-git'; +import git from 'isomorphic-git'; import fs from 'fs-extra'; import { GitDDBInterface } from '../types_gitddb'; import { diff --git a/src/remote/sync.ts b/src/remote/sync.ts index 788aec68..8ab801dd 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -11,7 +11,7 @@ */ import { clearInterval, setInterval } from 'timers'; import crypto from 'crypto'; -import git from '@sosuisen/isomorphic-git'; +import git from 'isomorphic-git'; import fs from 'fs-extra'; import { name as default_engine_name } from '../plugin/remote-isomorphic-git'; diff --git a/src/remote/sync_worker.ts b/src/remote/sync_worker.ts index 49d495c4..de265c10 100644 --- a/src/remote/sync_worker.ts +++ b/src/remote/sync_worker.ts @@ -7,7 +7,7 @@ * found in the LICENSE file in the root directory of gitDDB source tree. */ -import git from '@sosuisen/isomorphic-git'; +import git from 'isomorphic-git'; import fs from 'fs-extra'; import { SHORT_SHA_LENGTH } from '../const'; import { normalizeCommit } from '../utils'; diff --git a/src/remote/worker_utils.ts b/src/remote/worker_utils.ts index 34c45169..e32695ee 100644 --- a/src/remote/worker_utils.ts +++ b/src/remote/worker_utils.ts @@ -8,7 +8,7 @@ import nodePath from 'path'; import { serialize } from 'v8'; -import git, { ReadBlobResult, ReadCommitResult } from '@sosuisen/isomorphic-git'; +import git, { ReadBlobResult, ReadCommitResult } from 'isomorphic-git'; import fs from 'fs-extra'; import { normalizeCommit, utf8decode } from '../utils'; import { Err } from '../error'; diff --git a/src/utils.ts b/src/utils.ts index 80a5e2e4..4d1e44ef 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -15,7 +15,7 @@ import { resolveRef, TreeEntry, TreeObject, -} from '@sosuisen/isomorphic-git'; +} from 'isomorphic-git'; import { BinaryDocMetadata, DocMetadata, diff --git a/test/collection_delete.test.ts b/test/collection_delete.test.ts index 034abc65..4fd1bf03 100644 --- a/test/collection_delete.test.ts +++ b/test/collection_delete.test.ts @@ -9,7 +9,7 @@ import path from 'path'; import fs from 'fs-extra'; -import git from '@sosuisen/isomorphic-git'; +import git from 'isomorphic-git'; import expect from 'expect'; import { monotonicFactory } from 'ulid'; import { DeleteResultJsonDoc } from '../src/types'; diff --git a/test/collection_find.test.ts b/test/collection_find.test.ts index 46544ba1..deeb5ffd 100644 --- a/test/collection_find.test.ts +++ b/test/collection_find.test.ts @@ -9,7 +9,7 @@ import path from 'path'; import fs from 'fs-extra'; -import git from '@sosuisen/isomorphic-git'; +import git from 'isomorphic-git'; import expect from 'expect'; import { monotonicFactory } from 'ulid'; import { Collection } from '../src/collection'; diff --git a/test/collection_get.test.ts b/test/collection_get.test.ts index 27810067..9e2b4c28 100644 --- a/test/collection_get.test.ts +++ b/test/collection_get.test.ts @@ -9,7 +9,7 @@ import path from 'path'; import fs from 'fs-extra'; -import git from '@sosuisen/isomorphic-git'; +import git from 'isomorphic-git'; import expect from 'expect'; import { monotonicFactory } from 'ulid'; import { FRONT_MATTER_POSTFIX, JSON_POSTFIX, YAML_POSTFIX } from '../src/const'; diff --git a/test/collection_insert.test.ts b/test/collection_insert.test.ts index afb4654d..cc0a3554 100644 --- a/test/collection_insert.test.ts +++ b/test/collection_insert.test.ts @@ -9,7 +9,7 @@ import path from 'path'; import fs from 'fs-extra'; -import git from '@sosuisen/isomorphic-git'; +import git from 'isomorphic-git'; import expect from 'expect'; import { monotonicFactory } from 'ulid'; import { PutResultJsonDoc } from '../src/types'; diff --git a/test/collection_put.test.ts b/test/collection_put.test.ts index 24504489..a92e591e 100644 --- a/test/collection_put.test.ts +++ b/test/collection_put.test.ts @@ -8,7 +8,7 @@ */ import path from 'path'; -import git from '@sosuisen/isomorphic-git'; +import git from 'isomorphic-git'; import expect from 'expect'; import fs from 'fs-extra'; import { monotonicFactory } from 'ulid'; diff --git a/test/collection_update.test.ts b/test/collection_update.test.ts index 7860fc01..434ef251 100644 --- a/test/collection_update.test.ts +++ b/test/collection_update.test.ts @@ -8,7 +8,7 @@ */ import path from 'path'; -import git from '@sosuisen/isomorphic-git'; +import git from 'isomorphic-git'; import fs from 'fs-extra'; import expect from 'expect'; import { monotonicFactory } from 'ulid'; diff --git a/test/crud/blob.test.ts b/test/crud/blob.test.ts index bf92a943..a68ea321 100644 --- a/test/crud/blob.test.ts +++ b/test/crud/blob.test.ts @@ -8,7 +8,7 @@ */ import path from 'path'; -import git, { ReadBlobResult } from '@sosuisen/isomorphic-git'; +import git, { ReadBlobResult } from 'isomorphic-git'; import expect from 'expect'; import fs from 'fs-extra'; import sinon from 'sinon'; @@ -36,7 +36,7 @@ import { } from '../../src/serialize_format'; // eslint-disable-next-line @typescript-eslint/no-var-requires -const git_module = require('@sosuisen/isomorphic-git'); +const git_module = require('isomorphic-git'); const ulid = monotonicFactory(); const monoId = () => { diff --git a/test/crud/delete.test.ts b/test/crud/delete.test.ts index 22a3d3d2..553754da 100644 --- a/test/crud/delete.test.ts +++ b/test/crud/delete.test.ts @@ -10,7 +10,7 @@ import path from 'path'; import { monotonicFactory } from 'ulid'; import fs from 'fs-extra'; -import git from '@sosuisen/isomorphic-git'; +import git from 'isomorphic-git'; import expect from 'expect'; import sinon from 'sinon'; import { JSON_POSTFIX, SHORT_SHA_LENGTH } from '../../src/const'; diff --git a/test/crud/find.test.ts b/test/crud/find.test.ts index f30f71dd..61f4d691 100644 --- a/test/crud/find.test.ts +++ b/test/crud/find.test.ts @@ -7,7 +7,7 @@ * found in the LICENSE file in the root directory of this source tree. */ import path from 'path'; -import git from '@sosuisen/isomorphic-git'; +import git from 'isomorphic-git'; import fs from 'fs-extra'; import expect from 'expect'; import { monotonicFactory } from 'ulid'; diff --git a/test/crud/get.test.ts b/test/crud/get.test.ts index f60e93bc..6191e5df 100644 --- a/test/crud/get.test.ts +++ b/test/crud/get.test.ts @@ -9,7 +9,7 @@ import path from 'path'; import fs from 'fs-extra'; -import git from '@sosuisen/isomorphic-git'; +import git from 'isomorphic-git'; import expect from 'expect'; import { monotonicFactory } from 'ulid'; import sinon from 'sinon'; @@ -21,7 +21,7 @@ import { FRONT_MATTER_POSTFIX, JSON_POSTFIX } from '../../src/const'; import { addOneData, removeOneData } from '../utils'; // eslint-disable-next-line @typescript-eslint/no-var-requires -const git_module = require('@sosuisen/isomorphic-git'); +const git_module = require('isomorphic-git'); const ulid = monotonicFactory(); const monoId = () => { diff --git a/test/crud/history.test.ts b/test/crud/history.test.ts index 60e5f862..9b416c28 100644 --- a/test/crud/history.test.ts +++ b/test/crud/history.test.ts @@ -9,7 +9,7 @@ import path from 'path'; import fs from 'fs-extra'; -import git from '@sosuisen/isomorphic-git'; +import git from 'isomorphic-git'; import expect from 'expect'; import { monotonicFactory } from 'ulid'; import sinon from 'sinon'; @@ -28,7 +28,7 @@ import { addOneData, removeOneData } from '../utils'; import { FatJsonDoc } from '../../src/types'; // eslint-disable-next-line @typescript-eslint/no-var-requires -const git_module = require('@sosuisen/isomorphic-git'); +const git_module = require('isomorphic-git'); const ulid = monotonicFactory(); const monoId = () => { diff --git a/test/crud/put.test.ts b/test/crud/put.test.ts index 4f9c00db..519fa8ca 100644 --- a/test/crud/put.test.ts +++ b/test/crud/put.test.ts @@ -9,7 +9,7 @@ import path from 'path'; import { readFileSync } from 'fs'; -import git from '@sosuisen/isomorphic-git'; +import git from 'isomorphic-git'; import expect from 'expect'; import fs from 'fs-extra'; import sinon from 'sinon'; diff --git a/test/git_documentdb_crud.test.ts b/test/git_documentdb_crud.test.ts index e4a544f9..527512ad 100644 --- a/test/git_documentdb_crud.test.ts +++ b/test/git_documentdb_crud.test.ts @@ -8,7 +8,7 @@ */ import path from 'path'; -import git from '@sosuisen/isomorphic-git'; +import git from 'isomorphic-git'; import { monotonicFactory } from 'ulid'; import expect from 'expect'; import fs from 'fs-extra'; diff --git a/test/git_documentdb_open.test.ts b/test/git_documentdb_open.test.ts index d63695be..f6cbd1c1 100644 --- a/test/git_documentdb_open.test.ts +++ b/test/git_documentdb_open.test.ts @@ -9,7 +9,7 @@ import path from 'path'; import expect from 'expect'; -import git from '@sosuisen/isomorphic-git'; +import git from 'isomorphic-git'; import { monotonicFactory } from 'ulid'; import fs from 'fs-extra'; import sinon from 'sinon'; diff --git a/test/internal_plugin/checkfetch.test.ts b/test/internal_plugin/checkfetch.test.ts index 3d8b6004..66a5d9ac 100644 --- a/test/internal_plugin/checkfetch.test.ts +++ b/test/internal_plugin/checkfetch.test.ts @@ -10,7 +10,7 @@ import path from 'path'; import fs from 'fs-extra'; import expect from 'expect'; -import git from '@sosuisen/isomorphic-git'; +import git from 'isomorphic-git'; import { HTTPError401AuthorizationRequired, HTTPError404NotFound, diff --git a/test/internal_plugin/clone.test.ts b/test/internal_plugin/clone.test.ts index 90b7d63b..226434b0 100644 --- a/test/internal_plugin/clone.test.ts +++ b/test/internal_plugin/clone.test.ts @@ -19,7 +19,7 @@ import { InvalidURLFormatError, NetworkError, } from 'git-documentdb-remote-errors'; -import git from '@sosuisen/isomorphic-git'; +import git from 'isomorphic-git'; import sinon from 'sinon'; import { GitDocumentDB } from '../../src/git_documentdb'; import { clone } from '../../src/plugin/remote-isomorphic-git'; diff --git a/test/internal_plugin/fetch.test.ts b/test/internal_plugin/fetch.test.ts index 37f43f6b..4217ffcb 100644 --- a/test/internal_plugin/fetch.test.ts +++ b/test/internal_plugin/fetch.test.ts @@ -10,7 +10,7 @@ import path from 'path'; import fs from 'fs-extra'; import expect from 'expect'; -import git from '@sosuisen/isomorphic-git'; +import git from 'isomorphic-git'; import { HTTPError401AuthorizationRequired, HTTPError404NotFound, diff --git a/test/internal_plugin/push.test.ts b/test/internal_plugin/push.test.ts index 344f6e8a..09692231 100644 --- a/test/internal_plugin/push.test.ts +++ b/test/internal_plugin/push.test.ts @@ -8,7 +8,7 @@ */ import path from 'path'; -import git from '@sosuisen/isomorphic-git'; +import git from 'isomorphic-git'; import fs from 'fs-extra'; import expect from 'expect'; import { @@ -583,11 +583,12 @@ maybe(' push', () => { remoteURLBase, localDir, serialId, + serialId, { connection: { type: 'github', personalAccessToken: token, - engine: '@sosuisen/isomorphic-git', + engine: 'isomorphic-git', }, } ); @@ -618,7 +619,7 @@ maybe(' push', () => { connection: { type: 'github', personalAccessToken: token, - engine: '@sosuisen/isomorphic-git', + engine: 'isomorphic-git', }, }; await dbA.open(); @@ -643,7 +644,7 @@ maybe(' push', () => { connection: { type: 'github', personalAccessToken: token, - engine: '@sosuisen/isomorphic-git', + engine: 'isomorphic-git', }, }), push(dbB.workingDir, { @@ -651,7 +652,7 @@ maybe(' push', () => { connection: { type: 'github', personalAccessToken: token, - engine: '@sosuisen/isomorphic-git', + engine: 'isomorphic-git', }, }), ]) diff --git a/test/remote_base/3way_merge.ts b/test/remote_base/3way_merge.ts index a54f5909..65790394 100644 --- a/test/remote_base/3way_merge.ts +++ b/test/remote_base/3way_merge.ts @@ -34,6 +34,7 @@ import { getCommitInfo, getWorkingDirDocs, removeRemoteRepositories, + resetRemoteCommonRepository, } from '../remote_utils'; import { JSON_POSTFIX, YAML_POSTFIX } from '../../src/const'; @@ -48,16 +49,23 @@ export const syncThreeWayMergeBase = ( return `${reposPrefix}${idCounter++}`; }; + // Use commonId to reduce API calls to GitHub + const commonId = () => { + return `${reposPrefix}common`; + }; + before(async () => { await removeRemoteRepositories(reposPrefix); }); describe('', () => { it('throws InvalidConflictsStateError', async () => { + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); const [dbA, dbB, syncA, syncB] = await createClonedDatabases( remoteURLBase, localDir, serialId, + commonId, { conflictResolutionStrategy: 'ours', connection, @@ -84,10 +92,12 @@ export const syncThreeWayMergeBase = ( * jsonB3: 2 - Accept ours (insert) */ it('resolves case 1 - Accept theirs (insert), case 2 - Accept ours (insert), case 4 - Conflict. Accept ours (insert)', async () => { + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); const [dbA, dbB, syncA, syncB] = await createClonedDatabases( remoteURLBase, localDir, serialId, + commonId, { conflictResolutionStrategy: 'ours', connection, @@ -175,10 +185,12 @@ export const syncThreeWayMergeBase = ( * jsonA2: 3 - Accept both (insert) */ it('resolves case 3 - Accept both (insert), case 4 - Conflict. Accept ours (insert)', async () => { + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); const [dbA, dbB, syncA, syncB] = await createClonedDatabases( remoteURLBase, localDir, serialId, + commonId, { conflictResolutionStrategy: 'ours', connection, @@ -258,10 +270,12 @@ export const syncThreeWayMergeBase = ( * jsonA1: 5 - Conflict. Accept theirs (insert) */ it('resolves case 5 - Conflict. Accept theirs (insert)', async () => { + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); const [dbA, dbB, syncA, syncB] = await createClonedDatabases( remoteURLBase, localDir, serialId, + commonId, { conflictResolutionStrategy: 'theirs', connection, @@ -333,10 +347,17 @@ export const syncThreeWayMergeBase = ( * jsonA2: 6 - Accept both (delete) */ it('resolves case 6 - Accept both (delete), case 4 - Conflict. Accept ours (insert)', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - conflictResolutionStrategy: 'ours', - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + conflictResolutionStrategy: 'ours', + connection, + } + ); // A puts and pushes const jsonA2 = { _id: '2', name: 'fromA' }; await dbA.put(jsonA2); @@ -425,10 +446,17 @@ export const syncThreeWayMergeBase = ( * jsonA2: 7 - Accept ours (delete) */ it('resolves case 7 - Accept ours (delete), case 4 - Conflict. Accept ours (insert)', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - conflictResolutionStrategy: 'ours', - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + conflictResolutionStrategy: 'ours', + connection, + } + ); // A puts and pushes const jsonA2 = { _id: '2', name: 'fromA' }; await dbA.put(jsonA2); @@ -518,10 +546,17 @@ export const syncThreeWayMergeBase = ( * jsonA1: 8 - Conflict. Accept ours (delete) */ it('resolves case 8 - Conflict. Accept ours (delete)', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - conflictResolutionStrategy: 'ours', - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + conflictResolutionStrategy: 'ours', + connection, + } + ); // A puts and pushes const jsonA1 = { _id: '1', name: 'fromA' }; const putResultA1 = await dbA.put(jsonA1); @@ -603,10 +638,17 @@ export const syncThreeWayMergeBase = ( * jsonA1: 9 - Conflict. Accept theirs (update) */ it('resolves case 9 - Conflict. Accept ours (delete)', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - conflictResolutionStrategy: 'theirs', - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + conflictResolutionStrategy: 'theirs', + connection, + } + ); // A puts and pushes const jsonA1 = { _id: '1', name: 'fromA' }; const putResultA1 = await dbA.put(jsonA1); @@ -691,10 +733,17 @@ export const syncThreeWayMergeBase = ( * jsonA2:10 - Accept theirs (delete) */ it('resolves case 10 - Accept theirs (delete), case 4 - Conflict. Accept ours (insert)', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - conflictResolutionStrategy: 'ours', - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + conflictResolutionStrategy: 'ours', + connection, + } + ); // A puts and pushes const jsonA2 = { _id: '2', name: 'fromA' }; await dbA.put(jsonA2); @@ -781,10 +830,17 @@ export const syncThreeWayMergeBase = ( * jsonA2: 1 - Accept theirs (insert) */ it('resolves case 11 - Conflict. Accept ours (update), case 1 - Accept theirs (insert), ', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - conflictResolutionStrategy: 'ours', - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + conflictResolutionStrategy: 'ours', + connection, + } + ); // A puts and pushes const jsonA1 = { _id: '1', name: 'fromA' }; const putResultA1 = await dbA.put(jsonA1); @@ -871,10 +927,17 @@ export const syncThreeWayMergeBase = ( * jsonA2: 1 - Accept theirs (insert) */ it('resolves case 12 - accept theirs (delete), case 1 - Accept theirs (insert)', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - conflictResolutionStrategy: 'ours', - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + conflictResolutionStrategy: 'ours', + connection, + } + ); // A puts and pushes const jsonA1 = { _id: '1', name: 'fromA' }; const putResultA1 = await dbA.put(jsonA1); @@ -960,10 +1023,17 @@ export const syncThreeWayMergeBase = ( * jsonA2:13 - Accept both (update) */ it('resolves case 13 - Accept both (update), case 4 - Conflict. Accept ours (insert)', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - conflictResolutionStrategy: 'ours', - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + conflictResolutionStrategy: 'ours', + connection, + } + ); // A puts and pushes const jsonA2 = { _id: '2', name: 'fromA' }; const putResultA2 = await dbA.put(jsonA2); @@ -1053,10 +1123,17 @@ export const syncThreeWayMergeBase = ( * jsonA2:14 - Accept theirs (update) */ it('resolves case 14 - Accept theirs (update), case 4 - Conflict. Accept ours (insert)', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - conflictResolutionStrategy: 'ours', - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + conflictResolutionStrategy: 'ours', + connection, + } + ); // A puts and pushes const jsonA2 = { _id: '2', name: 'fromA' }; const putResultA2 = await dbA.put(jsonA2); @@ -1148,10 +1225,17 @@ export const syncThreeWayMergeBase = ( * jsonA2:15 - Accept ours (update) */ it('resolves case 15 - Accept ours (update), case 4 - Conflict. Accept ours (insert)', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - conflictResolutionStrategy: 'ours', - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + conflictResolutionStrategy: 'ours', + connection, + } + ); // A puts and pushes const jsonA2 = { _id: '2', name: 'fromA' }; const putResultA2 = await dbA.put(jsonA2); @@ -1241,10 +1325,17 @@ export const syncThreeWayMergeBase = ( * jsonB1:16 - Conflict. Accept ours (update) */ it('resolves case 16 - Conflict. Accept ours (update)', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - conflictResolutionStrategy: 'ours', - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + conflictResolutionStrategy: 'ours', + connection, + } + ); // A puts and pushes const jsonA1 = { _id: '1', name: 'fromA' }; const putResultA1 = await dbA.put(jsonA1); @@ -1325,10 +1416,17 @@ export const syncThreeWayMergeBase = ( * jsonA1:17 - Conflict. Accept theirs (update) */ it('resolves case 17 - Conflict. Accept theirs (update)', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - conflictResolutionStrategy: 'theirs', - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + conflictResolutionStrategy: 'theirs', + connection, + } + ); // A puts and pushes const jsonA1 = { _id: '1', name: 'fromA' }; const putResultA1 = await dbA.put(jsonA1); @@ -1418,10 +1516,17 @@ export const syncThreeWayMergeBase = ( * jsonB3:11 - Conflict. Accept ours (update) */ it('resolves many conflicts', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - conflictResolutionStrategy: 'ours', - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + conflictResolutionStrategy: 'ours', + connection, + } + ); // A puts and pushes const jsonA1 = { _id: '1', name: 'fromA' }; const putResultA1 = await dbA.put(jsonA1); @@ -1575,11 +1680,17 @@ export const syncThreeWayMergeBase = ( } return 'theirs'; }; - - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - conflictResolutionStrategy: userStrategyByDate, - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + conflictResolutionStrategy: userStrategyByDate, + connection, + } + ); // A puts and pushes const jsonA1 = { _id: '1', name: 'fromA' }; const putResultA1 = await dbA.put(jsonA1); @@ -1669,10 +1780,17 @@ export const syncThreeWayMergeBase = ( } return 'theirs'; }; - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - conflictResolutionStrategy: userStrategyByDate, - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + conflictResolutionStrategy: userStrategyByDate, + connection, + } + ); // A puts and pushes const jsonA1 = { _id: '1', name: 'fromA' }; const putResultA1 = await dbA.put(jsonA1); @@ -1764,10 +1882,12 @@ export const syncThreeWayMergeBase = ( * jsonB2: 2 - Accept ours (insert) */ it('files have the same name but different extension: resolves case 1 - Accept theirs (insert), case 2 - Accept ours (insert), case 4 - Conflict. Accept ours (insert)', async () => { + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); const [dbA, dbB, syncA, syncB] = await createClonedDatabases( remoteURLBase, localDir, serialId, + commonId, { conflictResolutionStrategy: 'ours', connection, diff --git a/test/remote_base/3way_merge_ot.ts b/test/remote_base/3way_merge_ot.ts index 25a0b658..5a3c2535 100644 --- a/test/remote_base/3way_merge_ot.ts +++ b/test/remote_base/3way_merge_ot.ts @@ -33,6 +33,7 @@ import { getCommitInfo, getWorkingDirDocs, removeRemoteRepositories, + resetRemoteCommonRepository, } from '../remote_utils'; import { FRONT_MATTER_POSTFIX, JSON_POSTFIX, YAML_POSTFIX } from '../../src/const'; @@ -47,6 +48,10 @@ export const threeWayMergeOtBase = ( const serialId = () => { return `${reposPrefix}${idCounter++}`; }; + // Use commonId to reduce API calls to GitHub + const commonId = () => { + return `${reposPrefix}common`; + }; before(async () => { await removeRemoteRepositories(reposPrefix); @@ -65,10 +70,12 @@ export const threeWayMergeOtBase = ( * jsonB3: 2 - Accept ours (insert) */ it('resolves case 1 - Accept theirs (insert), case 2 - Accept ours (insert), case 4 - Conflict. Accept ours (insert-merge)', async () => { + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); const [dbA, dbB, syncA, syncB] = await createClonedDatabases( remoteURLBase, localDir, serialId, + commonId, { conflictResolutionStrategy: 'ours-diff', connection, @@ -173,10 +180,12 @@ export const threeWayMergeOtBase = ( * jsonA1: 5 - Conflict. Accept theirs (insert) */ it('resolves case 5 - Conflict. Accept theirs (insert)', async () => { + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); const [dbA, dbB, syncA, syncB] = await createClonedDatabases( remoteURLBase, localDir, serialId, + commonId, { conflictResolutionStrategy: 'theirs-diff', connection, @@ -257,10 +266,17 @@ export const threeWayMergeOtBase = ( * jsonA1: 8 - Conflict. Accept ours (delete) */ it('resolves case 8 - Conflict. Accept ours (delete)', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - conflictResolutionStrategy: 'ours-diff', - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + conflictResolutionStrategy: 'ours-diff', + connection, + } + ); // A puts and pushes const jsonA1 = { _id: '1', name: 'fromA' }; const putResultA1 = await dbA.put(jsonA1); @@ -347,10 +363,17 @@ export const threeWayMergeOtBase = ( * jsonA2: 1 - Accept theirs (insert) */ it('resolves case 11 - Conflict. Accept ours (update), case 1 - Accept theirs (insert), ', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - conflictResolutionStrategy: 'ours-diff', - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + conflictResolutionStrategy: 'ours-diff', + connection, + } + ); // A puts and pushes const jsonA1 = { _id: '1', name: 'fromA' }; const putResultA1 = await dbA.put(jsonA1); @@ -439,10 +462,12 @@ export const threeWayMergeOtBase = ( const schema: Schema = { json: { plainTextProperties: { name: true } }, }; + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); const [dbA, syncA] = await createDatabase( remoteURLBase, localDir, serialId, + commonId, { conflictResolutionStrategy: 'theirs-diff', connection, @@ -829,10 +854,12 @@ export const threeWayMergeOtBase = ( const schema: Schema = { json: { plainTextProperties: { name: true } }, }; + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); const [dbA, syncA] = await createDatabase( remoteURLBase, localDir, serialId, + commonId, { conflictResolutionStrategy: 'ours-diff', connection, @@ -898,10 +925,12 @@ export const threeWayMergeOtBase = ( const schema: Schema = { json: { plainTextProperties: { name: true } }, }; + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); const [dbA, syncA] = await createDatabase( remoteURLBase, localDir, serialId, + commonId, { conflictResolutionStrategy: 'ours-diff', connection, @@ -967,10 +996,12 @@ export const threeWayMergeOtBase = ( const schema: Schema = { json: { plainTextProperties: { name: true } }, }; + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); const [dbA, syncA] = await createDatabase( remoteURLBase, localDir, serialId, + commonId, { conflictResolutionStrategy: 'ours-diff', connection, diff --git a/test/remote_base/combine.ts b/test/remote_base/combine.ts index 5d590c95..b6b25655 100644 --- a/test/remote_base/combine.ts +++ b/test/remote_base/combine.ts @@ -14,7 +14,7 @@ */ import fs from 'fs-extra'; -import git from '@sosuisen/isomorphic-git'; +import git from 'isomorphic-git'; import expect from 'expect'; import parse from 'parse-git-config'; import { Err } from '../../src/error'; @@ -27,6 +27,7 @@ import { destroyRemoteRepository, getWorkingDirDocs, removeRemoteRepositories, + resetRemoteCommonRepository, } from '../remote_utils'; import { sleep } from '../../src/utils'; import { FRONT_MATTER_POSTFIX, JSON_POSTFIX, YAML_POSTFIX } from '../../src/const'; @@ -43,6 +44,11 @@ export const syncCombineBase = ( return `${reposPrefix}${idCounter++}`; }; + // Use commonId to reduce API calls to GitHub + const commonId = () => { + return `${reposPrefix}common`; + }; + before(async () => { await removeRemoteRepositories(reposPrefix); }); @@ -53,11 +59,18 @@ export const syncCombineBase = ( */ describe('with same serializeFormat', () => { it('throws NoMergeBaseFoundError when combineDbStrategy is throw-error in [both] direction', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - combineDbStrategy: 'throw-error', - syncDirection: 'both', - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + combineDbStrategy: 'throw-error', + syncDirection: 'both', + connection, + } + ); const dbNameB = serialId(); const dbB: GitDocumentDB = new GitDocumentDB({ @@ -78,11 +91,18 @@ export const syncCombineBase = ( }); it('commits with valid commit message for combine-head-with-theirs', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - combineDbStrategy: 'combine-head-with-theirs', - syncDirection: 'both', - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + combineDbStrategy: 'combine-head-with-theirs', + syncDirection: 'both', + connection, + } + ); const dbNameB = serialId(); const dbB: GitDocumentDB = new GitDocumentDB({ @@ -116,11 +136,18 @@ export const syncCombineBase = ( }); it('succeeds when combine-head-with-theirs with empty local and empty remote', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - combineDbStrategy: 'combine-head-with-theirs', - syncDirection: 'both', - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + combineDbStrategy: 'combine-head-with-theirs', + syncDirection: 'both', + connection, + } + ); const dbNameB = serialId(); const dbB: GitDocumentDB = new GitDocumentDB({ @@ -148,11 +175,18 @@ export const syncCombineBase = ( }); it('succeeds combine-head-with-theirs with empty local and not empty remote', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - combineDbStrategy: 'combine-head-with-theirs', - syncDirection: 'both', - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + combineDbStrategy: 'combine-head-with-theirs', + syncDirection: 'both', + connection, + } + ); const jsonA1 = { _id: '1', name: 'fromA' }; await dbA.put(jsonA1); @@ -184,11 +218,18 @@ export const syncCombineBase = ( }); it('succeeds when combine-head-with-theirs with not empty local and empty remote', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - combineDbStrategy: 'combine-head-with-theirs', - syncDirection: 'both', - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + combineDbStrategy: 'combine-head-with-theirs', + syncDirection: 'both', + connection, + } + ); const dbNameB = serialId(); const dbB: GitDocumentDB = new GitDocumentDB({ @@ -219,11 +260,18 @@ export const syncCombineBase = ( }); it('succeeds when combine-head-with-theirs with deep local and deep remote', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - combineDbStrategy: 'combine-head-with-theirs', - syncDirection: 'both', - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + combineDbStrategy: 'combine-head-with-theirs', + syncDirection: 'both', + connection, + } + ); const jsonA1 = { _id: 'deep/one', name: 'fromA' }; await dbA.put(jsonA1); await syncA.trySync(); @@ -254,11 +302,18 @@ export const syncCombineBase = ( }); it('returns SyncResult with duplicates when combine-head-with-theirs with not empty local and not empty remote', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - combineDbStrategy: 'combine-head-with-theirs', - syncDirection: 'both', - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + combineDbStrategy: 'combine-head-with-theirs', + syncDirection: 'both', + connection, + } + ); const dbIdA = dbA.dbId; const jsonA1 = { _id: '1', name: 'fromA' }; @@ -323,11 +378,18 @@ export const syncCombineBase = ( }); it('returns SyncResult with duplicates when combine-head-with-theirs with deep local and deep remote', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - combineDbStrategy: 'combine-head-with-theirs', - syncDirection: 'both', - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + combineDbStrategy: 'combine-head-with-theirs', + syncDirection: 'both', + connection, + } + ); const dbIdA = dbA.dbId; const jsonA1 = { _id: 'deep/one', name: 'fromA' }; @@ -395,11 +457,18 @@ export const syncCombineBase = ( }); it('invokes combine event with duplicates when combine-head-with-theirs with not empty local and not empty remote', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - combineDbStrategy: 'combine-head-with-theirs', - syncDirection: 'both', - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + combineDbStrategy: 'combine-head-with-theirs', + syncDirection: 'both', + connection, + } + ); let duplicatedFiles: DuplicatedFile[] = []; syncA.on('combine', (duplicates: DuplicatedFile[]) => { duplicatedFiles = [...duplicates]; @@ -475,11 +544,18 @@ export const syncCombineBase = ( }); it('copies author from local repository', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - combineDbStrategy: 'combine-head-with-theirs', - syncDirection: 'both', - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + combineDbStrategy: 'combine-head-with-theirs', + syncDirection: 'both', + connection, + } + ); const dbNameB = serialId(); const dbB: GitDocumentDB = new GitDocumentDB({ diff --git a/test/remote_base/network_history.ts b/test/remote_base/network_history.ts index 90725ace..324a3f45 100644 --- a/test/remote_base/network_history.ts +++ b/test/remote_base/network_history.ts @@ -19,6 +19,7 @@ import { createClonedDatabases, destroyDBs, removeRemoteRepositories, + resetRemoteCommonRepository, } from '../remote_utils'; import { sleep, toSortedJSONString, utf8encode } from '../../src/utils'; import { JSON_POSTFIX } from '../../src/const'; @@ -35,16 +36,23 @@ export const networkHistoryBase = ( return `${reposPrefix}${idCounter++}`; }; + // Use commonId to reduce API calls to GitHub + const commonId = () => { + return `${reposPrefix}common`; + }; + before(async () => { await removeRemoteRepositories(reposPrefix); }); describe(' getHistoryImpl', () => { it('gets all revisions sorted by date from merged commit', async () => { + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); const [dbA, dbB, syncA, syncB] = await createClonedDatabases( remoteURLBase, localDir, serialId, + commonId, { conflictResolutionStrategy: 'ours', connection, @@ -132,10 +140,12 @@ export const networkHistoryBase = ( describe(' readOldBlob()', () => { it('skips a merge commit', async () => { + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); const [dbA, dbB, syncA, syncB] = await createClonedDatabases( remoteURLBase, localDir, serialId, + commonId, { conflictResolutionStrategy: 'ours', connection, diff --git a/test/remote_base/network_task_queue.ts b/test/remote_base/network_task_queue.ts index 59c778fb..1bd5beb8 100644 --- a/test/remote_base/network_task_queue.ts +++ b/test/remote_base/network_task_queue.ts @@ -15,7 +15,12 @@ import expect from 'expect'; import { ConnectionSettings } from '../../src/types'; -import { createDatabase, destroyDBs, removeRemoteRepositories } from '../remote_utils'; +import { + createDatabase, + destroyDBs, + removeRemoteRepositories, + resetRemoteCommonRepository, +} from '../remote_utils'; export const networkTaskQueueBase = ( connection: ConnectionSettings, @@ -28,6 +33,11 @@ export const networkTaskQueueBase = ( return `${reposPrefix}${idCounter++}`; }; + // Use commonId to reduce API calls to GitHub + const commonId = () => { + return `${reposPrefix}common`; + }; + before(async () => { await removeRemoteRepositories(reposPrefix); }); @@ -38,6 +48,7 @@ export const networkTaskQueueBase = ( remoteURLBase, localDir, serialId, + serialId, { connection, }, @@ -56,9 +67,16 @@ export const networkTaskQueueBase = ( }); it('increments statistics: sync', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + connection, + } + ); expect(dbA.taskQueue.currentStatistics().sync).toBe(0); @@ -69,9 +87,15 @@ export const networkTaskQueueBase = ( }); it('clear() statistics', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, - }); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + serialId, + { + connection, + } + ); await syncA.trySync(); expect(dbA.taskQueue.currentStatistics()).toEqual({ diff --git a/test/remote_base/on_sync_event.ts b/test/remote_base/on_sync_event.ts index 35c7a8f5..f77f9a90 100644 --- a/test/remote_base/on_sync_event.ts +++ b/test/remote_base/on_sync_event.ts @@ -26,6 +26,7 @@ import { getChangedFileInsert, getCommitInfo, removeRemoteRepositories, + resetRemoteCommonRepository, } from '../remote_utils'; import { sleep } from '../../src/utils'; import { GitDocumentDB } from '../../src/git_documentdb'; @@ -41,6 +42,11 @@ export const onSyncEventBase = ( return `${reposPrefix}${idCounter++}`; }; + // Use commonId to reduce API calls to GitHub + const commonId = () => { + return `${reposPrefix}common`; + }; + before(async () => { await removeRemoteRepositories(reposPrefix); }); @@ -48,10 +54,12 @@ export const onSyncEventBase = ( describe(' GitDocumentDB', () => { describe('onSyncEvent', () => { it('with remoteURL', async () => { + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); const [dbA, dbB, syncA, syncB] = await createClonedDatabases( remoteURLBase, localDir, serialId, + commonId, { connection, } @@ -118,10 +126,12 @@ export const onSyncEventBase = ( }); it('with sync', async () => { + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); const [dbA, dbB, syncA, syncB] = await createClonedDatabases( remoteURLBase, localDir, serialId, + commonId, { connection, } @@ -174,10 +184,12 @@ export const onSyncEventBase = ( describe('offSyncEvent', () => { it('with remoteURL', async () => { + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); const [dbA, dbB, syncA, syncB] = await createClonedDatabases( remoteURLBase, localDir, serialId, + commonId, { connection, } @@ -209,10 +221,12 @@ export const onSyncEventBase = ( }); it('with sync', async () => { + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); const [dbA, dbB, syncA, syncB] = await createClonedDatabases( remoteURLBase, localDir, serialId, + commonId, { connection, } @@ -232,10 +246,12 @@ export const onSyncEventBase = ( describe(' Collection', () => { describe('onSyncEvent', () => { it('with remoteURL', async () => { + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); const [dbA, dbB, syncA, syncB] = await createClonedDatabases( remoteURLBase, localDir, serialId, + commonId, { connection, } @@ -304,10 +320,12 @@ export const onSyncEventBase = ( }); it('with sync', async () => { + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); const [dbA, dbB, syncA, syncB] = await createClonedDatabases( remoteURLBase, localDir, serialId, + commonId, { connection, } @@ -363,10 +381,12 @@ export const onSyncEventBase = ( describe('offSyncEvent', () => { it('with remoteURL', async () => { + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); const [dbA, dbB, syncA, syncB] = await createClonedDatabases( remoteURLBase, localDir, serialId, + commonId, { connection, } @@ -400,10 +420,12 @@ export const onSyncEventBase = ( }); it('with sync', async () => { + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); const [dbA, dbB, syncA, syncB] = await createClonedDatabases( remoteURLBase, localDir, serialId, + commonId, { connection, } diff --git a/test/remote_base/sync.ts b/test/remote_base/sync.ts index 18092b82..e256e2fd 100644 --- a/test/remote_base/sync.ts +++ b/test/remote_base/sync.ts @@ -16,7 +16,7 @@ import crypto from 'crypto'; import fs from 'fs'; import { Octokit } from '@octokit/rest'; -import git from '@sosuisen/isomorphic-git'; +import git from 'isomorphic-git'; import expect from 'expect'; import sinon from 'sinon'; import * as RemoteEngineErr from 'git-documentdb-remote-errors'; @@ -53,9 +53,9 @@ export const syncBase = ( // Use sandbox to restore stub and spy in parallel mocha tests let sandbox: sinon.SinonSandbox; - beforeEach(async function () { + beforeEach(function () { // To avoid secondary rate limit of GitHub - await new Promise(resolve => setTimeout(resolve, 3000)); + // await new Promise(resolve => setTimeout(resolve, 3000)); sandbox = sinon.createSandbox(); }); @@ -817,6 +817,7 @@ export const syncBase = ( remoteURLBase, localDir, serialId, + commonId, { syncDirection: 'both', connection, diff --git a/test/remote_base/sync_clone.ts b/test/remote_base/sync_clone.ts index 2e43c689..a4d7571d 100644 --- a/test/remote_base/sync_clone.ts +++ b/test/remote_base/sync_clone.ts @@ -11,10 +11,13 @@ * Test clone * by using GitHub Personal Access Token */ -import path from 'path'; -import fs from 'fs-extra'; import expect from 'expect'; -import { createDatabase, destroyDBs, removeRemoteRepositories } from '../remote_utils'; +import { + createDatabase, + destroyDBs, + removeRemoteRepositories, + resetRemoteCommonRepository, +} from '../remote_utils'; import { GitDocumentDB } from '../../src/git_documentdb'; import { RemoteEngine } from '../../src/remote/remote_engine'; import { ConnectionSettings } from '../../src/types'; @@ -30,15 +33,27 @@ export const syncCloneBase = ( return `${reposPrefix}${idCounter++}`; }; + // Use commonId to reduce API calls to GitHub + const commonId = () => { + return `${reposPrefix}common`; + }; + before(async () => { await removeRemoteRepositories(reposPrefix); }); describe(' clone', () => { it('clones a repository', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + connection, + } + ); const jsonA1 = { _id: '1', name: 'fromA' }; await dbA.put(jsonA1); await syncA.tryPush(); diff --git a/test/remote_base/sync_events.ts b/test/remote_base/sync_events.ts index 735f628d..0d5c5106 100644 --- a/test/remote_base/sync_events.ts +++ b/test/remote_base/sync_events.ts @@ -37,6 +37,7 @@ import { getCommitInfo, getWorkingDirDocs, removeRemoteRepositories, + resetRemoteCommonRepository, } from '../remote_utils'; import { GitDocumentDB } from '../../src/git_documentdb'; import { RemoteErr } from '../../src/remote/remote_engine'; @@ -57,6 +58,11 @@ export const syncEventsBase = ( return `${reposPrefix}${idCounter++}`; }; + // Use commonId to reduce API calls to GitHub + const commonId = () => { + return `${reposPrefix}common`; + }; + // Use sandbox to restore stub and spy in parallel mocha tests let sandbox: sinon.SinonSandbox; beforeEach(function () { @@ -77,10 +83,12 @@ export const syncEventsBase = ( */ describe('change', () => { it('occurs once', async () => { + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); const [dbA, dbB, syncA, syncB] = await createClonedDatabases( remoteURLBase, localDir, serialId, + commonId, { connection } ); @@ -124,10 +132,12 @@ export const syncEventsBase = ( }); it('is propagated between local and remote sites', async () => { + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); const [dbA, dbB, syncA, syncB] = await createClonedDatabases( remoteURLBase, localDir, serialId, + commonId, { connection } ); @@ -195,10 +205,12 @@ export const syncEventsBase = ( * after : jsonB3 */ it('occurs with every retry', async () => { + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); const [dbA, dbB, syncA, syncB] = await createClonedDatabases( remoteURLBase, localDir, serialId, + commonId, { connection, } @@ -232,10 +244,12 @@ export const syncEventsBase = ( }); it('is followed by localChange', async () => { + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); const [dbA, dbB, syncA, syncB] = await createClonedDatabases( remoteURLBase, localDir, serialId, + commonId, { connection, } @@ -285,10 +299,12 @@ export const syncEventsBase = ( * after : jsonB3 */ it('occurs localChanges when SyncResultMergeAndPushError', async () => { + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); const [dbA, dbB, syncA, syncB] = await createClonedDatabases( remoteURLBase, localDir, serialId, + commonId, { connection, } @@ -320,10 +336,12 @@ export const syncEventsBase = ( }); it('is followed by remoteChange', async () => { + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); const [dbA, dbB, syncA, syncB] = await createClonedDatabases( remoteURLBase, localDir, serialId, + commonId, { connection, } @@ -372,10 +390,12 @@ export const syncEventsBase = ( * after : jsonB3 */ it('occurs remoteChanges after SyncResultMergeAndPushError', async () => { + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); const [dbA, dbB, syncA, syncB] = await createClonedDatabases( remoteURLBase, localDir, serialId, + commonId, { connection, } @@ -413,10 +433,12 @@ export const syncEventsBase = ( describe('filtered by collectionPath', () => { it('occurs change and localChange events', async () => { + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); const [dbA, dbB, syncA, syncB] = await createClonedDatabases( remoteURLBase, localDir, serialId, + commonId, { connection, } @@ -514,10 +536,12 @@ export const syncEventsBase = ( }); it('occurs change events with update and delete', async () => { + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); const [dbA, dbB, syncA, syncB] = await createClonedDatabases( remoteURLBase, localDir, serialId, + commonId, { connection, } @@ -582,10 +606,12 @@ export const syncEventsBase = ( }); it('occurs change and remoteChange events by trySync', async () => { + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); const [dbA, dbB, syncA, syncB] = await createClonedDatabases( remoteURLBase, localDir, serialId, + commonId, { connection, } @@ -680,10 +706,12 @@ export const syncEventsBase = ( }); it('occurs change and remoteChange events by tryPush', async () => { + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); const [dbA, dbB, syncA, syncB] = await createClonedDatabases( remoteURLBase, localDir, serialId, + commonId, { connection, } @@ -778,10 +806,12 @@ export const syncEventsBase = ( }); it('occurs change, localChange, and remoteChange events by merge and push', async () => { + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); const [dbA, dbB, syncA, syncB] = await createClonedDatabases( remoteURLBase, localDir, serialId, + commonId, { connection, } @@ -905,10 +935,12 @@ export const syncEventsBase = ( }); it('pause and resume', async () => { + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); const [dbA, dbB, syncA, syncB] = await createClonedDatabases( remoteURLBase, localDir, serialId, + commonId, { connection, includeCommits: true, @@ -997,12 +1029,19 @@ export const syncEventsBase = ( }); it('starts once', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, - includeCommits: true, - live: true, - interval: 3000, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + connection, + includeCommits: true, + live: true, + interval: 3000, + } + ); let start = false; syncA.on('start', () => { @@ -1027,12 +1066,19 @@ export const syncEventsBase = ( it('starts repeatedly', async () => { const interval = MINIMUM_SYNC_INTERVAL; - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, - includeCommits: true, - live: true, - interval, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + connection, + includeCommits: true, + live: true, + interval, + } + ); let counter = 0; syncA.on('start', () => { @@ -1048,12 +1094,19 @@ export const syncEventsBase = ( it('starts event returns taskMetaData and current retries', async () => { const interval = MINIMUM_SYNC_INTERVAL; - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, - includeCommits: true, - live: true, - interval, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + connection, + includeCommits: true, + live: true, + interval, + } + ); let counter = 0; let taskId = ''; @@ -1075,12 +1128,19 @@ export const syncEventsBase = ( it('completes once', async () => { const interval = MINIMUM_SYNC_INTERVAL; - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, - includeCommits: true, - live: true, - interval, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + connection, + includeCommits: true, + live: true, + interval, + } + ); let startTaskId = ''; syncA.on('start', (taskMetadata: TaskMetadata) => { @@ -1113,12 +1173,19 @@ export const syncEventsBase = ( it('completes repeatedly', async () => { const interval = MINIMUM_SYNC_INTERVAL; - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, - includeCommits: true, - live: true, - interval, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + connection, + includeCommits: true, + live: true, + interval, + } + ); let counter = 0; syncA.on('complete', () => { @@ -1133,17 +1200,29 @@ export const syncEventsBase = ( }); it('error', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, - }); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + serialId, + { + connection, + } + ); await dbA.put({ _id: '1', name: 'fromA' }); await syncA.trySync(); await destroyRemoteRepository(syncA.remoteURL); // Create different repository with the same repository name. - const [dbB, syncB] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, - }); + const [dbB, syncB] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + connection, + } + ); await dbB.put({ _id: '1', name: 'fromB' }); await syncB.trySync(); @@ -1173,12 +1252,19 @@ export const syncEventsBase = ( it('on and off', async () => { const interval = MINIMUM_SYNC_INTERVAL; - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, - includeCommits: true, - live: true, - interval, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + connection, + includeCommits: true, + live: true, + interval, + } + ); let counter = 0; const increment = () => { diff --git a/test/remote_base/sync_trypush.ts b/test/remote_base/sync_trypush.ts index 0a3f94db..a09902be 100644 --- a/test/remote_base/sync_trypush.ts +++ b/test/remote_base/sync_trypush.ts @@ -25,6 +25,7 @@ import { getCommitInfo, getWorkingDirDocs, removeRemoteRepositories, + resetRemoteCommonRepository, } from '../remote_utils'; import { ConnectionSettings, @@ -47,12 +48,15 @@ export const syncTryPushBase = ( const serialId = () => { return `${reposPrefix}${idCounter++}`; }; - + // Use commonId to reduce API calls to GitHub + const commonId = () => { + return `${reposPrefix}common`; + }; // Use sandbox to restore stub and spy in parallel mocha tests let sandbox: sinon.SinonSandbox; - beforeEach(async function () { + beforeEach(function () { // To avoid secondary rate limit of GitHub - await new Promise(resolve => setTimeout(resolve, 3000)); + // await new Promise(resolve => setTimeout(resolve, 3000)); sandbox = sinon.createSandbox(); }); @@ -72,9 +76,16 @@ export const syncTryPushBase = ( * after : jsonA1 */ it('changes one remote insertion when pushes after one put()', async function () { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + connection, + } + ); // Put and push const jsonA1 = { _id: '1', name: 'fromA' }; @@ -106,9 +117,16 @@ export const syncTryPushBase = ( * after : jsonA1 */ it('does not change remote when pushes after put() the same document again', async function () { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + connection, + } + ); const jsonA1 = { _id: '1', name: 'fromA' }; await dbA.put(jsonA1); await syncA.tryPush(); @@ -144,9 +162,16 @@ export const syncTryPushBase = ( * after : jsonA1 */ it('changes one remote update when pushes after put() updated document', async function () { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + connection, + } + ); const jsonA1 = { _id: '1', name: 'fromA' }; const putResultA1 = await dbA.put(jsonA1); await syncA.tryPush(); @@ -184,9 +209,16 @@ export const syncTryPushBase = ( * after : jsonA1 jsonA2 */ it('changes one remote insertion when pushes after put() another document', async function () { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + connection, + } + ); const jsonA1 = { _id: '1', name: 'fromA' }; await dbA.put(jsonA1); await syncA.tryPush(); @@ -226,9 +258,16 @@ export const syncTryPushBase = ( * after2: jsonA1 jsonA2 jsonA3 */ it('changes two remote insertions when pushes after put() two documents', async function () { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + connection, + } + ); // Two put commands and push const jsonA1 = { _id: '1', name: 'fromA' }; @@ -266,9 +305,16 @@ export const syncTryPushBase = ( * after : +jsonA1 jsonA2 */ it('changes one remote insertion and one remote update when pushes after put() updated document and another document', async function () { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + connection, + } + ); const jsonA1 = { _id: '1', name: 'fromA' }; const putResult1 = await dbA.put(jsonA1); @@ -309,9 +355,16 @@ export const syncTryPushBase = ( * after : */ it('changes one remote delete when pushes after one delete()', async function () { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + connection, + } + ); const jsonA1 = { _id: '1', name: 'fromA' }; await dbA.put(jsonA1); @@ -350,9 +403,16 @@ export const syncTryPushBase = ( * after : */ it('does not change remote when pushes after put() and delete()', async function () { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + connection, + } + ); const jsonA1 = { _id: '1', name: 'fromA' }; // Put and delete the same document @@ -400,9 +460,16 @@ export const syncTryPushBase = ( }); it('skips consecutive push tasks', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + connection, + } + ); const jsonA1 = { _id: '1', name: 'fromA' }; await dbA.put(jsonA1); @@ -430,12 +497,18 @@ export const syncTryPushBase = ( }); it('pauses live push after error', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, - live: true, - interval: 3000, - syncDirection: 'push', - }); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + serialId, + { + connection, + live: true, + interval: 3000, + syncDirection: 'push', + } + ); expect(syncA.options.live).toBeTruthy(); dbA.put({ name: 'fromA' }); diff --git a/test/remote_base/sync_trysync.ts b/test/remote_base/sync_trysync.ts index 9bef7c0b..8e2f0f04 100644 --- a/test/remote_base/sync_trysync.ts +++ b/test/remote_base/sync_trysync.ts @@ -12,7 +12,7 @@ * by using GitHub Personal Access Token * These tests create a new repository on GitHub if not exists. */ -import git from '@sosuisen/isomorphic-git'; +import git from 'isomorphic-git'; import fs from 'fs-extra'; import expect from 'expect'; import sinon from 'sinon'; @@ -38,6 +38,7 @@ import { getCommitInfo, getWorkingDirDocs, removeRemoteRepositories, + resetRemoteCommonRepository, } from '../remote_utils'; import { sleep, toSortedJSONString } from '../../src/utils'; import { JSON_POSTFIX } from '../../src/const'; @@ -57,11 +58,16 @@ export const syncTrySyncBase = ( return `${reposPrefix}${idCounter++}`; }; + // Use commonId to reduce API calls to GitHub + const commonId = () => { + return `${reposPrefix}common`; + }; + // Use sandbox to restore stub and spy in parallel mocha tests let sandbox: sinon.SinonSandbox; - beforeEach(async function () { + beforeEach(function () { // To avoid secondary rate limit of GitHub - await new Promise(resolve => setTimeout(resolve, 3000)); + // await new Promise(resolve => setTimeout(resolve, 3000)); sandbox = sinon.createSandbox(); }); @@ -81,9 +87,16 @@ export const syncTrySyncBase = ( * after : */ it('returns SyncResultNop when no commit', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + connection, + } + ); const syncResult1 = (await syncA.trySync()) as SyncResultPush; @@ -101,9 +114,16 @@ export const syncTrySyncBase = ( * after : jsonA1 */ it('which includes one remote creation when a local db creates a document', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + connection, + } + ); // A puts and pushes const jsonA1 = { _id: '1', name: 'fromA' }; @@ -131,9 +151,16 @@ export const syncTrySyncBase = ( * after : */ it('which includes one remote delete when a local db deletes a document', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + connection, + } + ); // A puts and pushes const jsonA1 = { _id: '1', name: 'fromA' }; @@ -164,9 +191,16 @@ export const syncTrySyncBase = ( * after : jsonA1 */ it('which includes one remote update when a local db a document', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + connection, + } + ); // A puts and pushes const jsonA1 = { _id: '1', name: 'fromA' }; const putResultA1 = await dbA.put(jsonA1); @@ -200,10 +234,12 @@ export const syncTrySyncBase = ( * after : jsonA1 */ it('which includes one local creation when a remote db creates a document', async () => { + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); const [dbA, dbB, syncA, syncB] = await createClonedDatabases( remoteURLBase, localDir, serialId, + commonId, { connection } ); // A puts and pushes @@ -241,10 +277,12 @@ export const syncTrySyncBase = ( * after : jsonA1 jsonA2 */ it('which includes two local creations when a remote db creates two documents', async () => { + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); const [dbA, dbB, syncA, syncB] = await createClonedDatabases( remoteURLBase, localDir, serialId, + commonId, { connection, } @@ -322,10 +360,12 @@ export const syncTrySyncBase = ( * after : jsonA1 jsonB2 */ it('which includes local and remote creations when a remote db creates a document and a local db creates another document', async () => { + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); const [dbA, dbB, syncA, syncB] = await createClonedDatabases( remoteURLBase, localDir, serialId, + commonId, { connection } ); // A puts and pushes @@ -375,10 +415,12 @@ export const syncTrySyncBase = ( * after : jsonA1 jsonA2 jsonB3 jsonB4 */ it('which includes two local creations and two remote creations when a remote db creates two documents and a local db creates two different documents', async () => { + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); const [dbA, dbB, syncA, syncB] = await createClonedDatabases( remoteURLBase, localDir, serialId, + commonId, { connection } ); @@ -437,10 +479,12 @@ export const syncTrySyncBase = ( * after : jsonA1 */ it('which does not include changes after a remote db creates a document and a local db creates exactly the same document', async () => { + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); const [dbA, dbB, syncA, syncB] = await createClonedDatabases( remoteURLBase, localDir, serialId, + commonId, { connection } ); @@ -479,9 +523,16 @@ export const syncTrySyncBase = ( * after : jsonA1 */ it('which does not include changes after a remote db updates a document and a local db updates exactly the same update', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + connection, + } + ); // A puts and pushes const jsonA1 = { _id: '1', name: 'fromA' }; @@ -533,9 +584,16 @@ export const syncTrySyncBase = ( * after : jsonA2 */ it('which include a local create and a remote delete when a remote db creates a document and a local db deletes another document', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + connection, + } + ); // A puts and pushes const jsonA1 = { _id: '1', name: 'fromA' }; await dbA.put(jsonA1); @@ -595,9 +653,16 @@ export const syncTrySyncBase = ( * after : jsonB2 */ it('which include a remote create and a local delete when a remote db deletes a document and a local db creates another document', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + connection, + } + ); // A puts and pushes const jsonA1 = { _id: '1', name: 'fromA' }; @@ -659,9 +724,16 @@ export const syncTrySyncBase = ( * after : */ it('which does not include changes when a remote db deletes a document and a local db deletes the same document', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + connection, + } + ); // A puts and pushes const jsonA1 = { _id: '1', name: 'fromA' }; await dbA.put(jsonA1); @@ -709,7 +781,8 @@ export const syncTrySyncBase = ( describe('returns SyncResolveConflictAndPush', () => { it('when two databases put the same _id document', async () => { - const remoteURL = remoteURLBase + serialId(); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const remoteURL = remoteURLBase + commonId(); const dbNameA = serialId(); const dbA: GitDocumentDB = new GitDocumentDB({ dbName: dbNameA, @@ -764,9 +837,16 @@ export const syncTrySyncBase = ( }); it('skips consecutive sync tasks', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + connection, + } + ); const results: SyncResult[] = []; for (let i = 0; i < 3; i++) { @@ -793,9 +873,16 @@ export const syncTrySyncBase = ( }); it('skips consecutive sync tasks after crud tasks', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + connection, + } + ); const jsonA1 = { _id: '1', name: 'fromA' }; for (let i = 0; i < 10; i++) { @@ -826,9 +913,16 @@ export const syncTrySyncBase = ( }); it('skips consecutive put tasks mixed with sync tasks', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + connection, + } + ); const putter: Promise[] = []; const validResult: (boolean | Record)[] = []; @@ -890,9 +984,16 @@ export const syncTrySyncBase = ( }); it('syncs files under .gitddb', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + connection, + } + ); const dbNameB = serialId(); const dbB: GitDocumentDB = new GitDocumentDB({ dbName: dbNameB, @@ -928,11 +1029,18 @@ export const syncTrySyncBase = ( }); it('pauses live sync after error', async () => { - const [dbA, syncA] = await createDatabase(remoteURLBase, localDir, serialId, { - connection, - live: true, - interval: 3000, - }); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const [dbA, syncA] = await createDatabase( + remoteURLBase, + localDir, + serialId, + commonId, + { + connection, + live: true, + interval: 3000, + } + ); expect(syncA.options.live).toBeTruthy(); dbA.put({ name: 'fromA' }); @@ -963,6 +1071,8 @@ export const syncTrySyncBase = ( */ describe('Retry trySync', () => { it('does not retry when retry option is 0 after UnfetchedCommitExistsError', async () => { + // Cannot use common repository when syncDirection is 'push' + // await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); const remoteURL = remoteURLBase + serialId(); const dbNameA = serialId(); const dbA: GitDocumentDB = new GitDocumentDB({ @@ -995,6 +1105,8 @@ export const syncTrySyncBase = ( }); it('retries every retry interval and fails after UnfetchedCommitExistsError', async () => { + // Cannot use common repository when syncDirection is 'push' + // await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); const remoteURL = remoteURLBase + serialId(); const dbNameA = serialId(); const dbA: GitDocumentDB = new GitDocumentDB({ @@ -1031,6 +1143,8 @@ export const syncTrySyncBase = ( }); it('retries every retry interval and succeeds after UnfetchedCommitExistsError', async () => { + // Cannot use common repository when syncDirection is 'push' + // await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); const remoteURL = remoteURLBase + serialId(); const dbNameA = serialId(); const dbA: GitDocumentDB = new GitDocumentDB({ @@ -1073,7 +1187,8 @@ export const syncTrySyncBase = ( }); it('Race condition of two trySync() calls does not throw UnfetchedCommitExistsError.', async () => { - const remoteURL = remoteURLBase + serialId(); + await resetRemoteCommonRepository(remoteURLBase, localDir, serialId, commonId); + const remoteURL = remoteURLBase + commonId(); const dbNameA = serialId(); const dbA: GitDocumentDB = new GitDocumentDB({ diff --git a/test/remote_isomorphic_git/3way_merge.test.ts b/test/remote_isomorphic_git/3way_merge.test.ts index 5b6cda92..698c0c9b 100644 --- a/test/remote_isomorphic_git/3way_merge.test.ts +++ b/test/remote_isomorphic_git/3way_merge.test.ts @@ -54,6 +54,6 @@ const connection: ConnectionSettingsGitHub = { }; maybe( - '@sosuisen/isomorphic-git', + 'isomorphic-git', syncThreeWayMergeBase(connection, remoteURLBase, reposPrefix, localDir) ); diff --git a/test/remote_isomorphic_git/3way_merge_ot.test.ts b/test/remote_isomorphic_git/3way_merge_ot.test.ts index 4fb58d45..75340ee7 100644 --- a/test/remote_isomorphic_git/3way_merge_ot.test.ts +++ b/test/remote_isomorphic_git/3way_merge_ot.test.ts @@ -54,6 +54,6 @@ const connection: ConnectionSettingsGitHub = { }; maybe( - '@sosuisen/isomorphic-git', + 'isomorphic-git', threeWayMergeOtBase(connection, remoteURLBase, reposPrefix, localDir) ); diff --git a/test/remote_isomorphic_git/combine.test.ts b/test/remote_isomorphic_git/combine.test.ts index f54bfb06..b851c54d 100644 --- a/test/remote_isomorphic_git/combine.test.ts +++ b/test/remote_isomorphic_git/combine.test.ts @@ -54,6 +54,6 @@ const connection: ConnectionSettingsGitHub = { }; maybe( - '@sosuisen/isomorphic-git', + 'isomorphic-git', syncCombineBase(connection, remoteURLBase, reposPrefix, localDir) ); diff --git a/test/remote_isomorphic_git/network_git_documentdb.test.ts b/test/remote_isomorphic_git/network_git_documentdb.test.ts index f284ff64..26c8d164 100644 --- a/test/remote_isomorphic_git/network_git_documentdb.test.ts +++ b/test/remote_isomorphic_git/network_git_documentdb.test.ts @@ -54,6 +54,6 @@ const connection: ConnectionSettingsGitHub = { }; maybe( - '@sosuisen/isomorphic-git', + 'isomorphic-git', networkGitDocumentDBBase(connection, remoteURLBase, reposPrefix, localDir) ); diff --git a/test/remote_isomorphic_git/network_history.test.ts b/test/remote_isomorphic_git/network_history.test.ts index acae5476..dbf3e244 100644 --- a/test/remote_isomorphic_git/network_history.test.ts +++ b/test/remote_isomorphic_git/network_history.test.ts @@ -54,6 +54,6 @@ const connection: ConnectionSettingsGitHub = { }; maybe( - '@sosuisen/isomorphic-git', + 'isomorphic-git', networkHistoryBase(connection, remoteURLBase, reposPrefix, localDir) ); diff --git a/test/remote_isomorphic_git/network_task_queue.test.ts b/test/remote_isomorphic_git/network_task_queue.test.ts index 3742c27d..333c985e 100644 --- a/test/remote_isomorphic_git/network_task_queue.test.ts +++ b/test/remote_isomorphic_git/network_task_queue.test.ts @@ -54,6 +54,6 @@ const connection: ConnectionSettingsGitHub = { }; maybe( - '@sosuisen/isomorphic-git', + 'isomorphic-git', networkTaskQueueBase(connection, remoteURLBase, reposPrefix, localDir) ); diff --git a/test/remote_isomorphic_git/on_sync_event.test.ts b/test/remote_isomorphic_git/on_sync_event.test.ts index 1430aa1f..be40be65 100644 --- a/test/remote_isomorphic_git/on_sync_event.test.ts +++ b/test/remote_isomorphic_git/on_sync_event.test.ts @@ -54,6 +54,6 @@ const connection: ConnectionSettingsGitHub = { }; maybe( - '@sosuisen/isomorphic-git', + 'isomorphic-git', onSyncEventBase(connection, remoteURLBase, reposPrefix, localDir) ); diff --git a/test/remote_isomorphic_git/sync.test.ts b/test/remote_isomorphic_git/sync.test.ts index 36070f11..ee9bc391 100644 --- a/test/remote_isomorphic_git/sync.test.ts +++ b/test/remote_isomorphic_git/sync.test.ts @@ -46,10 +46,10 @@ const token = process.env.GITDDB_PERSONAL_ACCESS_TOKEN!; const connection: ConnectionSettingsGitHub = { type: 'github', personalAccessToken: token, - engine: '@sosuisen/isomorphic-git', + engine: 'isomorphic-git', }; maybe( - '@sosuisen/isomorphic-git', + 'isomorphic-git', syncBase(connection, remoteURLBase, reposPrefix, localDir, token) ); diff --git a/test/remote_isomorphic_git/sync_clone.test.ts b/test/remote_isomorphic_git/sync_clone.test.ts index 9d14a675..c6da38d0 100644 --- a/test/remote_isomorphic_git/sync_clone.test.ts +++ b/test/remote_isomorphic_git/sync_clone.test.ts @@ -54,6 +54,6 @@ const connection: ConnectionSettingsGitHub = { }; maybe( - '@sosuisen/isomorphic-git', + 'isomorphic-git', syncCloneBase(connection, remoteURLBase, reposPrefix, localDir) ); diff --git a/test/remote_isomorphic_git/sync_events.test.ts b/test/remote_isomorphic_git/sync_events.test.ts index 5cae9832..f4ea4864 100644 --- a/test/remote_isomorphic_git/sync_events.test.ts +++ b/test/remote_isomorphic_git/sync_events.test.ts @@ -54,6 +54,6 @@ const connection: ConnectionSettingsGitHub = { }; maybe( - '@sosuisen/isomorphic-git', + 'isomorphic-git', syncEventsBase(connection, remoteURLBase, reposPrefix, localDir) ); diff --git a/test/remote_isomorphic_git/sync_live.test.ts b/test/remote_isomorphic_git/sync_live.test.ts index 1c15a30e..de0ea629 100644 --- a/test/remote_isomorphic_git/sync_live.test.ts +++ b/test/remote_isomorphic_git/sync_live.test.ts @@ -54,6 +54,6 @@ const connection: ConnectionSettingsGitHub = { }; maybe( - '@sosuisen/isomorphic-git', + 'isomorphic-git', syncLiveBase(connection, remoteURLBase, reposPrefix, localDir) ); diff --git a/test/remote_isomorphic_git/sync_trypush.test.ts b/test/remote_isomorphic_git/sync_trypush.test.ts index 6e0fe30c..64acb256 100644 --- a/test/remote_isomorphic_git/sync_trypush.test.ts +++ b/test/remote_isomorphic_git/sync_trypush.test.ts @@ -54,6 +54,6 @@ const connection: ConnectionSettingsGitHub = { }; maybe( - '@sosuisen/isomorphic-git', + 'isomorphic-git', syncTryPushBase(connection, remoteURLBase, reposPrefix, localDir) ); diff --git a/test/remote_isomorphic_git/sync_trysync.test.ts b/test/remote_isomorphic_git/sync_trysync.test.ts index cb4c3958..dc7e0a91 100644 --- a/test/remote_isomorphic_git/sync_trysync.test.ts +++ b/test/remote_isomorphic_git/sync_trysync.test.ts @@ -30,7 +30,7 @@ before(() => { }); after(() => { - fs.removeSync(path.resolve(localDir)); +// fs.removeSync(path.resolve(localDir)); }); // This test needs environment variables: @@ -54,6 +54,6 @@ const connection: ConnectionSettingsGitHub = { }; maybe( - '@sosuisen/isomorphic-git', + 'isomorphic-git', syncTrySyncBase(connection, remoteURLBase, reposPrefix, localDir) ); diff --git a/test/remote_utils.ts b/test/remote_utils.ts index 0cbb667c..534a31ed 100644 --- a/test/remote_utils.ts +++ b/test/remote_utils.ts @@ -1,15 +1,19 @@ /* eslint-disable @typescript-eslint/naming-convention */ import fs from 'fs-extra'; import { Octokit } from '@octokit/rest'; -import git from '@sosuisen/isomorphic-git'; +import git from 'isomorphic-git'; import sinon from 'sinon'; import expect from 'expect'; import { TLogLevelName } from 'tslog'; +import httpClient from 'isomorphic-git/http/node'; +import { createCredentialCallback, push } from '../src/plugin/remote-isomorphic-git'; +import { Sync } from '../src/remote/sync'; import { textToJsonDoc } from '../src/crud/blob'; import { ChangedFileDelete, ChangedFileInsert, ChangedFileUpdate, + DatabaseOpenResult, DeleteResult, JsonDoc, PutResult, @@ -180,17 +184,57 @@ export function getChangedFileDeleteBySHA ( }; } +export async function resetRemoteCommonRepository ( + remoteURLBase: string, + localDir: string, + localId: () => string, + remoteId: () => string +): Promise { + const dbName = remoteId(); + + // Create empty repository + const db: GitDocumentDB = new GitDocumentDB({ + dbName: 'common_' + localId(), + localDir, + }); + await db.open(); + const remoteURL = remoteURLBase + remoteId(); + const options: RemoteOptions = { + remoteUrl: remoteURL, + connection: { type: 'github', personalAccessToken: token }, + }; + const sync = new Sync(db, options); + await createGitRemote(db.workingDir, remoteURL, sync.remoteName); + + const cred = createCredentialCallback(options); + const pushOption: any = { + fs, + dir: db.workingDir, + http: httpClient, + url: remoteURL, + ref: 'main', + remote: 'origin', + remoteRef: 'main', + force: true, // force overwrite by empty repository + onAuth: cred, + }; + const res = await git.push(pushOption).catch(err => err); + + await db.destroy().catch(e => {}); +} + export async function createDatabase ( remoteURLBase: string, localDir: string, - serialId: () => string, + localId: () => string, + remoteId: () => string, options?: RemoteOptions, schema?: Schema, logLevel: TLogLevelName = 'info' ): Promise<[GitDocumentDB, SyncInterface]> { - const remoteURL = remoteURLBase + serialId(); + const remoteURL = remoteURLBase + remoteId(); - const dbNameA = serialId(); + const dbNameA = localId(); const dbA: GitDocumentDB = new GitDocumentDB({ dbName: dbNameA, @@ -216,14 +260,15 @@ export async function createDatabase ( export async function createClonedDatabases ( remoteURLBase: string, localDir: string, - serialId: () => string, + localId: () => string, + remoteId: () => string, options?: RemoteOptions, logLevel?: 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'fatal', serialize: SerializeFormatLabel = 'json' ): Promise<[GitDocumentDB, GitDocumentDB, SyncInterface, SyncInterface]> { - const remoteURL = remoteURLBase + serialId(); + const remoteURL = remoteURLBase + remoteId(); - const dbNameA = serialId(); + const dbNameA = localId(); const dbA: GitDocumentDB = new GitDocumentDB({ dbName: dbNameA, @@ -241,7 +286,7 @@ export async function createClonedDatabases ( options.includeCommits ??= true; await dbA.open(); await dbA.sync(options); - const dbNameB = serialId(); + const dbNameB = localId(); const dbB: GitDocumentDB = new GitDocumentDB({ dbName: dbNameB, localDir, diff --git a/test/utils.ts b/test/utils.ts index 6e6ead24..00b52445 100644 --- a/test/utils.ts +++ b/test/utils.ts @@ -1,5 +1,5 @@ import path from 'path'; -import git from '@sosuisen/isomorphic-git'; +import git from 'isomorphic-git'; import fs from 'fs-extra'; import { GitDDBInterface } from '../src/types_gitddb'; From 6d47e6b1b4a872c141846b3bf1a39a63cc339722 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sat, 30 Apr 2022 01:51:32 +0900 Subject: [PATCH 272/297] build: bump to v0.4.7-beta.1 --- package.json | 4 ++-- src/crud/find.ts | 8 +------- test/remote_isomorphic_git/combine.test.ts | 5 +---- test/remote_isomorphic_git/on_sync_event.test.ts | 5 +---- test/remote_isomorphic_git/sync.test.ts | 5 +---- test/remote_isomorphic_git/sync_clone.test.ts | 5 +---- test/remote_isomorphic_git/sync_events.test.ts | 5 +---- test/remote_isomorphic_git/sync_live.test.ts | 5 +---- test/remote_isomorphic_git/sync_trypush.test.ts | 5 +---- test/remote_isomorphic_git/sync_trysync.test.ts | 7 ++----- 10 files changed, 12 insertions(+), 42 deletions(-) diff --git a/package.json b/package.json index f4247845..b050d1b7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "git-documentdb", - "version": "0.4.7-alpha.18", + "version": "0.4.7-beta.1", "description": "Offline-first database that syncs with Git", "main": "dist/main.js", "types": "dist/main.d.ts", @@ -21,7 +21,7 @@ "test-plugin": "npm run mocha-parallel \"test_plugin/**/*.test.ts\" && npm run rm-test-db", "upload-coverage": "npx coveralls < coverage/lcov.info", "prepare": "", - "prepublishOnly": "npm run build && npm test", + "prepublishOnly": "", "api-extractor": "api-extractor run --local --verbose && npx api-documenter markdown -i ./temp -o ./docs-api", "lint": "eslint --fix --ext .ts .", "crlf": "npx crlf --set=LF docs-api/* etc/* ", diff --git a/src/crud/find.ts b/src/crud/find.ts index 23c1ec05..f3f8c470 100644 --- a/src/crud/find.ts +++ b/src/crud/find.ts @@ -7,13 +7,7 @@ */ import fs from 'fs'; -import { - readBlob, - readTree, - resolveRef, - TreeEntry, - TreeObject, -} from 'isomorphic-git'; +import { readBlob, readTree, resolveRef, TreeEntry, TreeObject } from 'isomorphic-git'; import { GIT_DOCUMENTDB_METADATA_DIR } from '../const'; import { Err } from '../error'; import { diff --git a/test/remote_isomorphic_git/combine.test.ts b/test/remote_isomorphic_git/combine.test.ts index b851c54d..6c520f78 100644 --- a/test/remote_isomorphic_git/combine.test.ts +++ b/test/remote_isomorphic_git/combine.test.ts @@ -53,7 +53,4 @@ const connection: ConnectionSettingsGitHub = { personalAccessToken: token, }; -maybe( - 'isomorphic-git', - syncCombineBase(connection, remoteURLBase, reposPrefix, localDir) -); +maybe('isomorphic-git', syncCombineBase(connection, remoteURLBase, reposPrefix, localDir)); diff --git a/test/remote_isomorphic_git/on_sync_event.test.ts b/test/remote_isomorphic_git/on_sync_event.test.ts index be40be65..7c0d7434 100644 --- a/test/remote_isomorphic_git/on_sync_event.test.ts +++ b/test/remote_isomorphic_git/on_sync_event.test.ts @@ -53,7 +53,4 @@ const connection: ConnectionSettingsGitHub = { personalAccessToken: token, }; -maybe( - 'isomorphic-git', - onSyncEventBase(connection, remoteURLBase, reposPrefix, localDir) -); +maybe('isomorphic-git', onSyncEventBase(connection, remoteURLBase, reposPrefix, localDir)); diff --git a/test/remote_isomorphic_git/sync.test.ts b/test/remote_isomorphic_git/sync.test.ts index ee9bc391..71f15233 100644 --- a/test/remote_isomorphic_git/sync.test.ts +++ b/test/remote_isomorphic_git/sync.test.ts @@ -49,7 +49,4 @@ const connection: ConnectionSettingsGitHub = { engine: 'isomorphic-git', }; -maybe( - 'isomorphic-git', - syncBase(connection, remoteURLBase, reposPrefix, localDir, token) -); +maybe('isomorphic-git', syncBase(connection, remoteURLBase, reposPrefix, localDir, token)); diff --git a/test/remote_isomorphic_git/sync_clone.test.ts b/test/remote_isomorphic_git/sync_clone.test.ts index c6da38d0..8c38024b 100644 --- a/test/remote_isomorphic_git/sync_clone.test.ts +++ b/test/remote_isomorphic_git/sync_clone.test.ts @@ -53,7 +53,4 @@ const connection: ConnectionSettingsGitHub = { personalAccessToken: token, }; -maybe( - 'isomorphic-git', - syncCloneBase(connection, remoteURLBase, reposPrefix, localDir) -); +maybe('isomorphic-git', syncCloneBase(connection, remoteURLBase, reposPrefix, localDir)); diff --git a/test/remote_isomorphic_git/sync_events.test.ts b/test/remote_isomorphic_git/sync_events.test.ts index f4ea4864..57b4b8b2 100644 --- a/test/remote_isomorphic_git/sync_events.test.ts +++ b/test/remote_isomorphic_git/sync_events.test.ts @@ -53,7 +53,4 @@ const connection: ConnectionSettingsGitHub = { personalAccessToken: token, }; -maybe( - 'isomorphic-git', - syncEventsBase(connection, remoteURLBase, reposPrefix, localDir) -); +maybe('isomorphic-git', syncEventsBase(connection, remoteURLBase, reposPrefix, localDir)); diff --git a/test/remote_isomorphic_git/sync_live.test.ts b/test/remote_isomorphic_git/sync_live.test.ts index de0ea629..b274864f 100644 --- a/test/remote_isomorphic_git/sync_live.test.ts +++ b/test/remote_isomorphic_git/sync_live.test.ts @@ -53,7 +53,4 @@ const connection: ConnectionSettingsGitHub = { personalAccessToken: token, }; -maybe( - 'isomorphic-git', - syncLiveBase(connection, remoteURLBase, reposPrefix, localDir) -); +maybe('isomorphic-git', syncLiveBase(connection, remoteURLBase, reposPrefix, localDir)); diff --git a/test/remote_isomorphic_git/sync_trypush.test.ts b/test/remote_isomorphic_git/sync_trypush.test.ts index 64acb256..c6465286 100644 --- a/test/remote_isomorphic_git/sync_trypush.test.ts +++ b/test/remote_isomorphic_git/sync_trypush.test.ts @@ -53,7 +53,4 @@ const connection: ConnectionSettingsGitHub = { personalAccessToken: token, }; -maybe( - 'isomorphic-git', - syncTryPushBase(connection, remoteURLBase, reposPrefix, localDir) -); +maybe('isomorphic-git', syncTryPushBase(connection, remoteURLBase, reposPrefix, localDir)); diff --git a/test/remote_isomorphic_git/sync_trysync.test.ts b/test/remote_isomorphic_git/sync_trysync.test.ts index dc7e0a91..45090ce2 100644 --- a/test/remote_isomorphic_git/sync_trysync.test.ts +++ b/test/remote_isomorphic_git/sync_trysync.test.ts @@ -30,7 +30,7 @@ before(() => { }); after(() => { -// fs.removeSync(path.resolve(localDir)); + // fs.removeSync(path.resolve(localDir)); }); // This test needs environment variables: @@ -53,7 +53,4 @@ const connection: ConnectionSettingsGitHub = { personalAccessToken: token, }; -maybe( - 'isomorphic-git', - syncTrySyncBase(connection, remoteURLBase, reposPrefix, localDir) -); +maybe('isomorphic-git', syncTrySyncBase(connection, remoteURLBase, reposPrefix, localDir)); From ddb8c25a53abb4c27d9447405fe06044a8343009 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sat, 30 Apr 2022 19:35:45 +0900 Subject: [PATCH 273/297] fixing json_patch_ot for array operation --- package-lock.json | 4 +- src/remote/json_patch_ot.ts | 74 +++++- test/remote_offline/json_patch_ot.test.ts | 270 +++++++++++++++++----- 3 files changed, 280 insertions(+), 68 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7ce40899..05efc33b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "git-documentdb", - "version": "0.4.7-alpha.18", + "version": "0.4.7-beta.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "git-documentdb", - "version": "0.4.7-alpha.18", + "version": "0.4.7-beta.1", "license": "MPL-2.0", "dependencies": { "@octokit/rest": "^18.3.5", diff --git a/src/remote/json_patch_ot.ts b/src/remote/json_patch_ot.ts index 697b8b1f..a2da7bd3 100644 --- a/src/remote/json_patch_ot.ts +++ b/src/remote/json_patch_ot.ts @@ -105,7 +105,7 @@ export class JsonPatchOT implements IJsonPatch { const isArray = keys.includes('_t'); if (isArray) { // is Array - // underscore _ means 'remove' operation + // underscore _ means 'remove' or 'move' operation keys.sort(); // 1, 2, 3, _1, _2, _3 let underBarStart = 0; for (underBarStart = 0; underBarStart < keys.length; underBarStart++) { @@ -114,14 +114,51 @@ export class JsonPatchOT implements IJsonPatch { } } const noBar = keys.slice(0, underBarStart); - const underBar = keys.slice(underBarStart, keys.length); + // eslint-disable-next-line complexity + const underBar = keys.slice(underBarStart, keys.length).sort((a, b) => { + // Delete commands must be before move commands + if ( + Array.isArray(tree[a]) && + tree[a].length === 3 && + tree[a][1] === 0 && + tree[a][2] === 0 + ) { + // a is delete + if ( + Array.isArray(tree[a]) && + tree[b].length === 3 && + tree[b][1] === 0 && + tree[b][2] === 0 + ) { + // b is also delete + return parseInt(a.slice(1), 10) - parseInt(b.slice(1), 10); + } + // b is move + return -1; + } + // a is move + if ( + Array.isArray(tree[a]) && + tree[b].length === 3 && + tree[b][1] === 0 && + tree[b][2] === 0 + ) { + // b is delete + return 1; + } + // b is also move + // sort by destination position + return tree[a][1] - tree[b][1]; + }); sortedKeys = underBar.concat(noBar); // _1, _2, _3, 1, 2, 3 } else { // is Object sortedKeys = keys.sort(); } - let removeOffset = 0; + const removedIndex: (string | number)[] = []; + const insertedIndex: (string | number)[] = []; + const movedOperation: { from: number; to: number }[] = []; // eslint-disable-next-line complexity sortedKeys.forEach(key => { if (Array.isArray(tree[key])) { @@ -131,6 +168,8 @@ export class JsonPatchOT implements IJsonPatch { key = parseInt(key.replace(/^_/, ''), 10); // Remove heading underscore } operations.push(insertOp(ancestors.concat(key), arr[0])!); + console.log('## insert:' + key); + insertedIndex.push(key); } else if (arr.length === 2) { if (isArray && typeof key === 'string') { @@ -147,17 +186,40 @@ export class JsonPatchOT implements IJsonPatch { // Deleted // See https://github.com/benjamine/jsondiffpatch/blob/master/docs/deltas.md if (typeof key === 'string') { + // Delete property operations.push(removeOp(ancestors.concat(key))); } else { - operations.push(removeOp(ancestors.concat((key as number) - removeOffset))); - removeOffset++; + // Delete from array + let offset = -removedIndex.length; + insertedIndex.forEach(index => { + if (parseInt(index as string, 10) < parseInt(key as string, 10)) offset++; + }); + operations.push(removeOp(ancestors.concat((key as number) + offset))); + removedIndex.push(key); } } else if (arr[0] === '' && arr[2] === 3) { // Moved // See https://github.com/benjamine/jsondiffpatch/blob/master/docs/deltas.md - operations.push(moveOp(ancestors.concat(key), ancestors.concat(arr[1]))); + + // Move先のインデックスが小さい操作から順に処理 + console.log("## " + insertedIndex); + let offset = 0; + insertedIndex.forEach(index => { + if (parseInt(index as string, 10) < parseInt(key as string, 10)) offset++; + }); + removedIndex.forEach(index => { + if (parseInt(index as string, 10) < parseInt(key as string, 10)) offset--; + }); + movedOperation.forEach(mop => { + if (mop.from < (key as number) && mop.to > arr[1]) offset--; + if (mop.from > (key as number) && mop.to < arr[1]) offset++; + }); + operations.push( + moveOp(ancestors.concat((key as number) + offset), ancestors.concat(arr[1])) + ); + movedOperation.push({ from: key as number, to: arr[1] }); } else if (typeof firstItem === 'string') { let isTextPatch = firstItem.match(/^@@ -\d+?,\d+? \+\d+?,\d+? @@\n/m); diff --git a/test/remote_offline/json_patch_ot.test.ts b/test/remote_offline/json_patch_ot.test.ts index f7c37be0..e1626eaf 100644 --- a/test/remote_offline/json_patch_ot.test.ts +++ b/test/remote_offline/json_patch_ot.test.ts @@ -190,12 +190,10 @@ describe(' OT', () => { it('insert at first', () => { const oldDoc = { - _id: 'nara', - temple: ['Todaiji', 'Yakushiji'], + number: ['1', '2'], }; const newDoc = { - _id: 'nara', - temple: ['Toshodaiji', 'Todaiji', 'Yakushiji'], + number: ['3', '1', '2'], }; const diff = primitiveDiff.diff(oldDoc, newDoc)!; @@ -204,12 +202,10 @@ describe(' OT', () => { it('insert at middle', () => { const oldDoc = { - _id: 'nara', - temple: ['Todaiji', 'Yakushiji'], + number: ['1', '2'], }; const newDoc = { - _id: 'nara', - temple: ['Todaiji', 'Toshodaiji', 'Yakushiji'], + number: ['1', '3', '2'], }; const diff = primitiveDiff.diff(oldDoc, newDoc)!; @@ -218,12 +214,10 @@ describe(' OT', () => { it('insert at last', () => { const oldDoc = { - _id: 'nara', - temple: ['Todaiji', 'Yakushiji'], + number: ['1', '2'], }; const newDoc = { - _id: 'nara', - temple: ['Todaiji', 'Yakushiji', 'Toshodaiji'], + number: ['1', '2', '3'], }; const diff = primitiveDiff.diff(oldDoc, newDoc)!; @@ -232,12 +226,10 @@ describe(' OT', () => { it('insert two members', () => { const oldDoc = { - _id: 'nara', - temple: ['Todaiji', 'Yakushiji'], + number: ['1', '2'], }; const newDoc = { - _id: 'nara', - temple: ['Todaiji', 'Toshodaiji', 'Kofukuji', 'Yakushiji'], + number: ['1', '3', '4', '2'], }; const diff = primitiveDiff.diff(oldDoc, newDoc)!; @@ -246,58 +238,161 @@ describe(' OT', () => { it('insert two members at a distance', () => { const oldDoc = { - _id: 'nara', - temple: ['Todaiji', 'Yakushiji'], + number: ['1', '2'], }; const newDoc = { - _id: 'nara', - temple: ['Todaiji', 'Toshodaiji', 'Yakushiji', 'Kofukuji'], + number: ['1', '3', '2', '4'], }; const diff = primitiveDiff.diff(oldDoc, newDoc)!; expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); }); - it('move', () => { + it('move from the first to the last(1)', () => { const oldDoc = { - _id: 'nara', - temple: ['Todaiji', 'Yakushiji'], + number: ['1', '2', '3'], }; const newDoc = { - _id: 'nara', - temple: ['Yakushiji', 'Todaiji'], + number: ['2', '3', '1'], }; const diff = primitiveDiff.diff(oldDoc, newDoc)!; - // { temple: { _t: 'a', _1: [ '', 0, 3 ] } } - // [ '', 0, 3 ] + // console.log(diff); + // { number: { _t: 'a', _0: [ '', 2, 3 ] } } // The first member is always ''. // The second member 0 represents destinationIndex // The last member 3 is the magical number that indicates "array move" expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); }); + it('move from the first to the last(2)', () => { + const oldDoc = { + number: ['1', '2', '3', '4'], + }; + const newDoc = { + number: ['2', '3', '4', '1'], + }; + + const diff = primitiveDiff.diff(oldDoc, newDoc)!; + expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + }); + + it('move from the last to the first(1)', () => { + const oldDoc = { + number: ['1', '2', '3'], + }; + const newDoc = { + number: ['3', '1', '2'], + }; + + const diff = primitiveDiff.diff(oldDoc, newDoc)!; + // console.log(diff); + // { number: { _t: 'a', _2: [ '', 0, 3 ] } } + // The first member is always ''. + // The second member 0 represents destinationIndex + // The last member 3 is the magical number that indicates "array move" + expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + }); + + it('move from the last to the first(2)', () => { + const oldDoc = { + number: ['1', '2', '3', '4'], + }; + const newDoc = { + number: ['4', '1', '2', '3'], + }; + + const diff = primitiveDiff.diff(oldDoc, newDoc)!; + expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + }); + + it('replace the last with the first(1)', () => { + const oldDoc = { + number: ['1', '2', '3'], + }; + const newDoc = { + number: ['3', '2', '1'], + }; + + const diff = primitiveDiff.diff(oldDoc, newDoc)!; + expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + }); + + it('replace the last with the first(2)', () => { + const oldDoc = { + number: ['1', '2', '3', '4'], + }; + const newDoc = { + number: ['4', '2', '3', '1'], + }; + + const diff = primitiveDiff.diff(oldDoc, newDoc)!; + expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + }); + + it('reverse', () => { + const oldDoc = { + number: ['1', '2', '3', '4'], + }; + const newDoc = { + number: ['4', '3', '2', '1'], + }; + + const diff = primitiveDiff.diff(oldDoc, newDoc)!; + expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + }); + + it('shuffle', () => { + const oldDoc = { + number: ['1', '2', '3', '4', '5'], + }; + const newDoc = { + number: ['4', '3', '2', '5', '1'], + }; + + const diff = primitiveDiff.diff(oldDoc, newDoc)!; + expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + }); + it('delete one', () => { const oldDoc = { - _id: 'nara', - temple: ['Todaiji', 'Yakushiji'], + number: ['1', '2'], }; const newDoc = { - _id: 'nara', - temple: ['Todaiji'], + number: ['1'], }; const diff = primitiveDiff.diff(oldDoc, newDoc)!; expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); }); - it('delete two', () => { + it('delete middle one', () => { const oldDoc = { - _id: 'nara', - temple: ['Todaiji', 'Yakushiji', 'Toshodaiji'], + number: ['1', '2', '3'], }; const newDoc = { - _id: 'nara', - temple: ['Todaiji'], + number: ['1', '3'], + }; + const diff = primitiveDiff.diff(oldDoc, newDoc)!; + expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + }); + + it('delete the last two', () => { + const oldDoc = { + number: ['1', '2', '3'], + }; + const newDoc = { + number: ['1'], + }; + const diff = primitiveDiff.diff(oldDoc, newDoc)!; + expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + }); + + it('delete the first two', () => { + const oldDoc = { + number: ['1', '2', '3'], + }; + const newDoc = { + number: ['3'], }; const diff = primitiveDiff.diff(oldDoc, newDoc)!; expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); @@ -305,12 +400,10 @@ describe(' OT', () => { it('delete two at a distance', () => { const oldDoc = { - _id: 'nara', - temple: ['Todaiji', 'Yakushiji', 'Toshodaiji'], + number: ['1', '2', '3'], }; const newDoc = { - _id: 'nara', - temple: ['Yakushiji'], + number: ['2'], }; const diff = primitiveDiff.diff(oldDoc, newDoc)!; expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); @@ -318,25 +411,21 @@ describe(' OT', () => { it('clear array', () => { const oldDoc = { - _id: 'nara', - temple: ['Todaiji', 'Yakushiji'], + number: ['1', '2'], }; const newDoc = { - _id: 'nara', - temple: [], + number: [], }; const diff = primitiveDiff.diff(oldDoc, newDoc)!; expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); }); - it('delete one and add new one at the first position', () => { + it('delete one, then add new one at the first position', () => { const oldDoc = { - _id: 'nara', - temple: ['Toshodaiji', 'Todaiji'], + number: ['1', '2'], }; const newDoc = { - _id: 'nara', - temple: ['Yakushiji', 'Todaiji'], + number: ['3', '2'], }; expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( @@ -344,14 +433,12 @@ describe(' OT', () => { ); }); - it('delete one and add new one at the last position', () => { + it('delete the first, then add the last', () => { const oldDoc = { - _id: 'nara', - temple: ['Toshodaiji', 'Todaiji'], + number: ['1', '2'], }; const newDoc = { - _id: 'nara', - temple: ['Todaiji', 'Yakushiji'], + number: ['2', '3'], }; expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( @@ -359,31 +446,94 @@ describe(' OT', () => { ); }); - it('delete one and add new one', () => { + it('delete one, then add new one', () => { + const oldDoc = { + number: ['1'], + }; + const newDoc = { + number: ['2'], + }; + + expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( + newDoc + ); + }); + + it('delete two, then add new one', () => { + const oldDoc = { + number: ['1', '2'], + }; + const newDoc = { + number: ['3'], + }; + + expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( + newDoc + ); + }); + + it('delete the first, then move the third to the second', () => { const oldDoc = { _id: 'nara', - temple: ['Toshodaiji'], + number: ['1', '2', '3', '4'], }; const newDoc = { _id: 'nara', - temple: ['Yakushiji'], + number: ['2', '4', '3'], }; + console.log(primitiveDiff.diff(oldDoc, newDoc)); expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( newDoc ); }); - it('delete two and add new one', () => { + it('delete the third, then move the first to the last', () => { const oldDoc = { _id: 'nara', - temple: ['Toshodaiji', 'Todaiji'], + number: ['1', '2', '3', '4'], }; const newDoc = { _id: 'nara', - temple: ['Yakushiji'], + number: ['2', '4', '1'], + }; + expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( + newDoc + ); + }); + + it('delete the first, then move the last to the first', () => { + const oldDoc = { + number: ['1', '2', '3'], }; + const newDoc = { + number: ['3', '2'], + }; + expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( + newDoc + ); + }); + it('delete the second, then move the last to the first', () => { + const oldDoc = { + number: ['1', '2', '3'], + }; + const newDoc = { + number: ['3', '1'], + }; + expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( + newDoc + ); + }); + + it.only('add the first, then move the last to the second', () => { + const oldDoc = { + number: ['1', '2', '3'], + }; + const newDoc = { + number: ['4', '3', '2', '1'], + }; + console.log(primitiveDiff.diff(oldDoc, newDoc)!); expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( newDoc ); From dd33df321263a7ad486e17c90e48d29d01c2ad20 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Sun, 1 May 2022 01:20:09 +0900 Subject: [PATCH 274/297] fix: conflict between insert and move op --- src/remote/json_patch_ot.ts | 157 +++++++++++++--------- test/remote_offline/json_patch_ot.test.ts | 21 ++- 2 files changed, 109 insertions(+), 69 deletions(-) diff --git a/src/remote/json_patch_ot.ts b/src/remote/json_patch_ot.ts index a2da7bd3..1b17ebd8 100644 --- a/src/remote/json_patch_ot.ts +++ b/src/remote/json_patch_ot.ts @@ -101,56 +101,59 @@ export class JsonPatchOT implements IJsonPatch { const operations: JSONOp[] = []; const procTree = (ancestors: (string | number)[], tree: JsonDoc) => { const keys = Object.keys(tree); - let sortedKeys: (string | number)[]; + let sortedKeys: (string | number)[] = []; const isArray = keys.includes('_t'); + + const nest: string[] = []; + const insOp: string[] = []; + const replOp: string[] = []; + const remOp: string[] = []; + const movOp: string[] = []; + const txtOp: string[] = []; + if (isArray) { // is Array // underscore _ means 'remove' or 'move' operation keys.sort(); // 1, 2, 3, _1, _2, _3 + // console.log('## start parse keys: ' + JSON.stringify(keys)); let underBarStart = 0; for (underBarStart = 0; underBarStart < keys.length; underBarStart++) { if (keys[underBarStart].startsWith('_')) { break; } } - const noBar = keys.slice(0, underBarStart); + + // no bar: insert/replace/text + keys.slice(0, underBarStart).forEach(key => { + if (!Array.isArray(tree[key])) nest.push(key); + else if (tree[key].length === 1) insOp.push(key); + else if (tree[key].length === 2) replOp.push(key); + else if (tree[key].length === 3 && typeof tree[key][0] === 'string') + txtOp.push(key); + }); + + // underBar: remove/move // eslint-disable-next-line complexity - const underBar = keys.slice(underBarStart, keys.length).sort((a, b) => { - // Delete commands must be before move commands - if ( - Array.isArray(tree[a]) && - tree[a].length === 3 && - tree[a][1] === 0 && - tree[a][2] === 0 - ) { - // a is delete - if ( - Array.isArray(tree[a]) && - tree[b].length === 3 && - tree[b][1] === 0 && - tree[b][2] === 0 - ) { - // b is also delete - return parseInt(a.slice(1), 10) - parseInt(b.slice(1), 10); - } - // b is move - return -1; + keys.slice(underBarStart, keys.length).forEach(key => { + if (!Array.isArray(tree[key])) nest.push(key); + else if (tree[key].length === 3) { + const arr = tree[key]; + if (arr[1] === 0 && arr[2] === 0) remOp.push(key); + else if (arr[0] === '' && arr[2] === 3) movOp.push(key); } - // a is move - if ( - Array.isArray(tree[a]) && - tree[b].length === 3 && - tree[b][1] === 0 && - tree[b][2] === 0 - ) { - // b is delete - return 1; - } - // b is also move - // sort by destination position - return tree[a][1] - tree[b][1]; }); - sortedKeys = underBar.concat(noBar); // _1, _2, _3, 1, 2, 3 + movOp.sort( + (a, b) => + // sort by destination position + tree[a][1] - tree[b][1] + ); + insOp.sort( + (a, b) => + // sort by destination position + parseInt(a, 10) - parseInt(b, 10) + ); + // sort order: replace, text, remove, insert, move + sortedKeys = sortedKeys.concat(replOp, txtOp, remOp, movOp, insOp, nest); } else { // is Object @@ -161,17 +164,33 @@ export class JsonPatchOT implements IJsonPatch { const movedOperation: { from: number; to: number }[] = []; // eslint-disable-next-line complexity sortedKeys.forEach(key => { + // console.log('# ' + key); if (Array.isArray(tree[key])) { const arr = tree[key] as any[]; if (arr.length === 1) { + // Insert if (isArray && typeof key === 'string') { key = parseInt(key.replace(/^_/, ''), 10); // Remove heading underscore } - operations.push(insertOp(ancestors.concat(key), arr[0])!); - console.log('## insert:' + key); - insertedIndex.push(key); + if (isArray) { + let dstOffset = 0; + movOp.forEach(mop => { + const from = parseInt(mop, 10); + const to = tree[mop][1] as number; + if (from < (key as number) && to > key) dstOffset++; + if (from > (key as number) && to < key) dstOffset--; + }); + operations.push( + insertOp(ancestors.concat((key as number) + dstOffset), arr[0])! + ); + insertedIndex.push(key); + } + else { + operations.push(insertOp(ancestors.concat(key), arr[0])!); + } } else if (arr.length === 2) { + // Replace if (isArray && typeof key === 'string') { key = parseInt(key.replace(/^_/, ''), 10); // Remove heading underscore } @@ -183,18 +202,15 @@ export class JsonPatchOT implements IJsonPatch { key = parseInt(key.replace(/^_/, ''), 10); // Remove heading underscore } if (arr[1] === 0 && arr[2] === 0) { - // Deleted + // Remove // See https://github.com/benjamine/jsondiffpatch/blob/master/docs/deltas.md if (typeof key === 'string') { - // Delete property + // Remove property operations.push(removeOp(ancestors.concat(key))); } else { - // Delete from array - let offset = -removedIndex.length; - insertedIndex.forEach(index => { - if (parseInt(index as string, 10) < parseInt(key as string, 10)) offset++; - }); + // Remove from array + const offset = -removedIndex.length; operations.push(removeOp(ancestors.concat((key as number) + offset))); removedIndex.push(key); } @@ -202,24 +218,39 @@ export class JsonPatchOT implements IJsonPatch { else if (arr[0] === '' && arr[2] === 3) { // Moved // See https://github.com/benjamine/jsondiffpatch/blob/master/docs/deltas.md + if (isArray) { + let offset = 0; + removedIndex.forEach(index => { + if (parseInt(index as string, 10) <= parseInt(key as string, 10)) + offset--; + }); + /* + insertedIndex.forEach(index => { + if (parseInt(index as string, 10) <= parseInt(key as string, 10)) + offset++; + }); + */ + movedOperation.forEach(mop => { + if (mop.from < (key as number) && mop.to > arr[1]) offset--; + if (mop.from > (key as number) && mop.to < arr[1]) offset++; + }); - // Move先のインデックスが小さい操作から順に処理 - console.log("## " + insertedIndex); - let offset = 0; - insertedIndex.forEach(index => { - if (parseInt(index as string, 10) < parseInt(key as string, 10)) offset++; - }); - removedIndex.forEach(index => { - if (parseInt(index as string, 10) < parseInt(key as string, 10)) offset--; - }); - movedOperation.forEach(mop => { - if (mop.from < (key as number) && mop.to > arr[1]) offset--; - if (mop.from > (key as number) && mop.to < arr[1]) offset++; - }); - operations.push( - moveOp(ancestors.concat((key as number) + offset), ancestors.concat(arr[1])) - ); - movedOperation.push({ from: key as number, to: arr[1] }); + let dstOffset = 0; + insOp.forEach(iop => { + if (parseInt(iop as string, 10) <= parseInt(arr[1] as string, 10)) + dstOffset--; + }); + operations.push( + moveOp( + ancestors.concat((key as number) + offset), + ancestors.concat((arr[1] as number) + dstOffset) + ) + ); + movedOperation.push({ from: key as number, to: arr[1] }); + } + else { + operations.push(moveOp(ancestors.concat(key), ancestors.concat(arr[1]))); + } } else if (typeof firstItem === 'string') { let isTextPatch = firstItem.match(/^@@ -\d+?,\d+? \+\d+?,\d+? @@\n/m); diff --git a/test/remote_offline/json_patch_ot.test.ts b/test/remote_offline/json_patch_ot.test.ts index e1626eaf..07d5cf55 100644 --- a/test/remote_offline/json_patch_ot.test.ts +++ b/test/remote_offline/json_patch_ot.test.ts @@ -427,7 +427,6 @@ describe(' OT', () => { const newDoc = { number: ['3', '2'], }; - expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( newDoc ); @@ -440,7 +439,6 @@ describe(' OT', () => { const newDoc = { number: ['2', '3'], }; - expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( newDoc ); @@ -481,8 +479,6 @@ describe(' OT', () => { _id: 'nara', number: ['2', '4', '3'], }; - console.log(primitiveDiff.diff(oldDoc, newDoc)); - expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( newDoc ); @@ -526,14 +522,27 @@ describe(' OT', () => { ); }); - it.only('add the first, then move the last to the second', () => { + it('add the first, then move the last to the second', () => { const oldDoc = { number: ['1', '2', '3'], }; const newDoc = { number: ['4', '3', '2', '1'], }; - console.log(primitiveDiff.diff(oldDoc, newDoc)!); + console.log(primitiveDiff.diff(oldDoc, newDoc)); + expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( + newDoc + ); + }); + + it('add the second, add the third, remove the last, then move the first to the last', () => { + const oldDoc = { + number: ['1', '2', '3'], + }; + const newDoc = { + number: ['3', '4', '5', '1'], + }; + console.log(primitiveDiff.diff(oldDoc, newDoc)); expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( newDoc ); From a1b681f9bfc9f5689aa31df0d7b56882604225a9 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Mon, 9 May 2022 18:48:10 +0900 Subject: [PATCH 275/297] fix: add type --- src/remote/json_patch_ot.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/remote/json_patch_ot.ts b/src/remote/json_patch_ot.ts index 1b17ebd8..3387559d 100644 --- a/src/remote/json_patch_ot.ts +++ b/src/remote/json_patch_ot.ts @@ -342,7 +342,7 @@ export class JsonPatchOT implements IJsonPatch { } } catch (err: unknown) { if ((err as { conflict: any }).conflict) { - // console.log('conflict: ' + JSON.stringify(err.conflict)); + // console.log('conflict: ' + JSON.stringify((err as { conflict: any }).conflict)); const conflict = (err as { conflict: any }).conflict as { type: number; op1: any[]; From 6ea5d28714a6f7d7ad95cdfe3f0aa77c310abd8d Mon Sep 17 00:00:00 2001 From: sosuisen Date: Mon, 9 May 2022 18:48:41 +0900 Subject: [PATCH 276/297] adding merge test for arrays --- test/remote_offline/json_patch_ot.test.ts | 868 +++++++++++++--------- 1 file changed, 531 insertions(+), 337 deletions(-) diff --git a/test/remote_offline/json_patch_ot.test.ts b/test/remote_offline/json_patch_ot.test.ts index 07d5cf55..b2e46e2b 100644 --- a/test/remote_offline/json_patch_ot.test.ts +++ b/test/remote_offline/json_patch_ot.test.ts @@ -13,7 +13,7 @@ const textOTDiff = new JsonDiff({ const jPatch = new JsonPatchOT(); describe(' OT', () => { - describe('apply', () => { + describe('apply:', () => { it('apply op', () => { const oldDoc = { _id: 'oldId', @@ -129,7 +129,7 @@ describe(' OT', () => { }); }); - describe('patch', () => { + describe('patch:', () => { it('patches from undefined diff', () => { const oldDoc = { _id: 'nara', @@ -145,7 +145,7 @@ describe(' OT', () => { }); }); - describe('for array: ', () => { + describe('for array:', () => { it('new property', () => { const oldDoc = { _id: 'nara', @@ -174,378 +174,402 @@ describe(' OT', () => { ); }); - it('insert to empty array', () => { - const oldDoc = { - _id: 'nara', - temple: [], - }; - const newDoc = { - _id: 'nara', - temple: ['Toshodaiji'], - }; + describe('insert:', () => { + it('insert to empty array', () => { + const oldDoc = { + _id: 'nara', + temple: [], + }; + const newDoc = { + _id: 'nara', + temple: ['Toshodaiji'], + }; - const diff = primitiveDiff.diff(oldDoc, newDoc)!; - expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); - }); - - it('insert at first', () => { - const oldDoc = { - number: ['1', '2'], - }; - const newDoc = { - number: ['3', '1', '2'], - }; + const diff = primitiveDiff.diff(oldDoc, newDoc)!; + expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + }); - const diff = primitiveDiff.diff(oldDoc, newDoc)!; - expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); - }); + it('insert at first', () => { + const oldDoc = { + number: ['1', '2'], + }; + const newDoc = { + number: ['3', '1', '2'], + }; - it('insert at middle', () => { - const oldDoc = { - number: ['1', '2'], - }; - const newDoc = { - number: ['1', '3', '2'], - }; - - const diff = primitiveDiff.diff(oldDoc, newDoc)!; - expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); - }); + const diff = primitiveDiff.diff(oldDoc, newDoc)!; + expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + }); - it('insert at last', () => { - const oldDoc = { - number: ['1', '2'], - }; - const newDoc = { - number: ['1', '2', '3'], - }; + it('insert at middle', () => { + const oldDoc = { + number: ['1', '2'], + }; + const newDoc = { + number: ['1', '3', '2'], + }; - const diff = primitiveDiff.diff(oldDoc, newDoc)!; - expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); - }); + const diff = primitiveDiff.diff(oldDoc, newDoc)!; + expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + }); - it('insert two members', () => { - const oldDoc = { - number: ['1', '2'], - }; - const newDoc = { - number: ['1', '3', '4', '2'], - }; + it('insert at last', () => { + const oldDoc = { + number: ['1', '2'], + }; + const newDoc = { + number: ['1', '2', '3'], + }; - const diff = primitiveDiff.diff(oldDoc, newDoc)!; - expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); - }); + const diff = primitiveDiff.diff(oldDoc, newDoc)!; + expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + }); - it('insert two members at a distance', () => { - const oldDoc = { - number: ['1', '2'], - }; - const newDoc = { - number: ['1', '3', '2', '4'], - }; + it('insert two members', () => { + const oldDoc = { + number: ['1', '2'], + }; + const newDoc = { + number: ['1', '3', '4', '2'], + }; - const diff = primitiveDiff.diff(oldDoc, newDoc)!; - expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); - }); + const diff = primitiveDiff.diff(oldDoc, newDoc)!; + expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + }); - it('move from the first to the last(1)', () => { - const oldDoc = { - number: ['1', '2', '3'], - }; - const newDoc = { - number: ['2', '3', '1'], - }; + it('insert two members at a distance', () => { + const oldDoc = { + number: ['1', '2'], + }; + const newDoc = { + number: ['1', '3', '2', '4'], + }; - const diff = primitiveDiff.diff(oldDoc, newDoc)!; - // console.log(diff); - // { number: { _t: 'a', _0: [ '', 2, 3 ] } } - // The first member is always ''. - // The second member 0 represents destinationIndex - // The last member 3 is the magical number that indicates "array move" - expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + const diff = primitiveDiff.diff(oldDoc, newDoc)!; + expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + }); }); - it('move from the first to the last(2)', () => { - const oldDoc = { - number: ['1', '2', '3', '4'], - }; - const newDoc = { - number: ['2', '3', '4', '1'], - }; + describe('move:', () => { + it('move from the first to the last(1)', () => { + const oldDoc = { + number: ['1', '2', '3'], + }; + const newDoc = { + number: ['2', '3', '1'], + }; + + const diff = primitiveDiff.diff(oldDoc, newDoc)!; + // console.log(diff); + // { number: { _t: 'a', _0: [ '', 2, 3 ] } } + // The first member is always ''. + // The second member 0 represents destinationIndex + // The last member 3 is the magical number that indicates "array move" + expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + }); - const diff = primitiveDiff.diff(oldDoc, newDoc)!; - expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); - }); + it('move from the first to the last(2)', () => { + const oldDoc = { + number: ['1', '2', '3', '4'], + }; + const newDoc = { + number: ['2', '3', '4', '1'], + }; - it('move from the last to the first(1)', () => { - const oldDoc = { - number: ['1', '2', '3'], - }; - const newDoc = { - number: ['3', '1', '2'], - }; + const diff = primitiveDiff.diff(oldDoc, newDoc)!; + expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + }); - const diff = primitiveDiff.diff(oldDoc, newDoc)!; - // console.log(diff); - // { number: { _t: 'a', _2: [ '', 0, 3 ] } } - // The first member is always ''. - // The second member 0 represents destinationIndex - // The last member 3 is the magical number that indicates "array move" - expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); - }); + it('move from the last to the first(1)', () => { + const oldDoc = { + number: ['1', '2', '3'], + }; + const newDoc = { + number: ['3', '1', '2'], + }; + + const diff = primitiveDiff.diff(oldDoc, newDoc)!; + // console.log(diff); + // { number: { _t: 'a', _2: [ '', 0, 3 ] } } + // The first member is always ''. + // The second member 0 represents destinationIndex + // The last member 3 is the magical number that indicates "array move" + expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + }); - it('move from the last to the first(2)', () => { - const oldDoc = { - number: ['1', '2', '3', '4'], - }; - const newDoc = { - number: ['4', '1', '2', '3'], - }; + it('move from the last to the first(2)', () => { + const oldDoc = { + number: ['1', '2', '3', '4'], + }; + const newDoc = { + number: ['4', '1', '2', '3'], + }; - const diff = primitiveDiff.diff(oldDoc, newDoc)!; - expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); - }); + const diff = primitiveDiff.diff(oldDoc, newDoc)!; + expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + }); - it('replace the last with the first(1)', () => { - const oldDoc = { - number: ['1', '2', '3'], - }; - const newDoc = { - number: ['3', '2', '1'], - }; + it('replace the last with the first(1)', () => { + const oldDoc = { + number: ['1', '2', '3'], + }; + const newDoc = { + number: ['3', '2', '1'], + }; - const diff = primitiveDiff.diff(oldDoc, newDoc)!; - expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); - }); + const diff = primitiveDiff.diff(oldDoc, newDoc)!; + expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + }); - it('replace the last with the first(2)', () => { - const oldDoc = { - number: ['1', '2', '3', '4'], - }; - const newDoc = { - number: ['4', '2', '3', '1'], - }; + it('replace the last with the first(2)', () => { + const oldDoc = { + number: ['1', '2', '3', '4'], + }; + const newDoc = { + number: ['4', '2', '3', '1'], + }; - const diff = primitiveDiff.diff(oldDoc, newDoc)!; - expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); - }); + const diff = primitiveDiff.diff(oldDoc, newDoc)!; + expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + }); - it('reverse', () => { - const oldDoc = { - number: ['1', '2', '3', '4'], - }; - const newDoc = { - number: ['4', '3', '2', '1'], - }; + it('reverse', () => { + const oldDoc = { + number: ['1', '2', '3', '4'], + }; + const newDoc = { + number: ['4', '3', '2', '1'], + }; - const diff = primitiveDiff.diff(oldDoc, newDoc)!; - expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); - }); + const diff = primitiveDiff.diff(oldDoc, newDoc)!; + expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + }); - it('shuffle', () => { - const oldDoc = { - number: ['1', '2', '3', '4', '5'], - }; - const newDoc = { - number: ['4', '3', '2', '5', '1'], - }; + it('shuffle', () => { + const oldDoc = { + number: ['1', '2', '3', '4', '5'], + }; + const newDoc = { + number: ['4', '3', '2', '5', '1'], + }; - const diff = primitiveDiff.diff(oldDoc, newDoc)!; - expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + const diff = primitiveDiff.diff(oldDoc, newDoc)!; + expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + }); }); - it('delete one', () => { - const oldDoc = { - number: ['1', '2'], - }; - const newDoc = { - number: ['1'], - }; - const diff = primitiveDiff.diff(oldDoc, newDoc)!; - expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); - }); + describe('delete:', () => { + it('delete one', () => { + const oldDoc = { + number: ['1', '2'], + }; + const newDoc = { + number: ['1'], + }; + const diff = primitiveDiff.diff(oldDoc, newDoc)!; + expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + }); - it('delete middle one', () => { - const oldDoc = { - number: ['1', '2', '3'], - }; - const newDoc = { - number: ['1', '3'], - }; - const diff = primitiveDiff.diff(oldDoc, newDoc)!; - expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); - }); + it('delete middle one', () => { + const oldDoc = { + number: ['1', '2', '3'], + }; + const newDoc = { + number: ['1', '3'], + }; + const diff = primitiveDiff.diff(oldDoc, newDoc)!; + expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + }); - it('delete the last two', () => { - const oldDoc = { - number: ['1', '2', '3'], - }; - const newDoc = { - number: ['1'], - }; - const diff = primitiveDiff.diff(oldDoc, newDoc)!; - expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); - }); + it('delete the last two', () => { + const oldDoc = { + number: ['1', '2', '3'], + }; + const newDoc = { + number: ['1'], + }; + const diff = primitiveDiff.diff(oldDoc, newDoc)!; + expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + }); - it('delete the first two', () => { - const oldDoc = { - number: ['1', '2', '3'], - }; - const newDoc = { - number: ['3'], - }; - const diff = primitiveDiff.diff(oldDoc, newDoc)!; - expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); - }); + it('delete the first two', () => { + const oldDoc = { + number: ['1', '2', '3'], + }; + const newDoc = { + number: ['3'], + }; + const diff = primitiveDiff.diff(oldDoc, newDoc)!; + expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + }); - it('delete two at a distance', () => { - const oldDoc = { - number: ['1', '2', '3'], - }; - const newDoc = { - number: ['2'], - }; - const diff = primitiveDiff.diff(oldDoc, newDoc)!; - expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); - }); + it('delete two at a distance', () => { + const oldDoc = { + number: ['1', '2', '3'], + }; + const newDoc = { + number: ['2'], + }; + const diff = primitiveDiff.diff(oldDoc, newDoc)!; + expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + }); - it('clear array', () => { - const oldDoc = { - number: ['1', '2'], - }; - const newDoc = { - number: [], - }; - const diff = primitiveDiff.diff(oldDoc, newDoc)!; - expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + it('clear array', () => { + const oldDoc = { + number: ['1', '2'], + }; + const newDoc = { + number: [], + }; + const diff = primitiveDiff.diff(oldDoc, newDoc)!; + expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); + }); }); - it('delete one, then add new one at the first position', () => { - const oldDoc = { - number: ['1', '2'], - }; - const newDoc = { - number: ['3', '2'], - }; - expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( - newDoc - ); - }); + describe('delete and insert:', () => { + it('delete one, then insert new one at the first position', () => { + const oldDoc = { + number: ['1', '2'], + }; + const newDoc = { + number: ['3', '2'], + }; + expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( + newDoc + ); + }); - it('delete the first, then add the last', () => { - const oldDoc = { - number: ['1', '2'], - }; - const newDoc = { - number: ['2', '3'], - }; - expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( - newDoc - ); - }); + it('delete the first, then insert the last', () => { + const oldDoc = { + number: ['1', '2'], + }; + const newDoc = { + number: ['2', '3'], + }; + expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( + newDoc + ); + }); - it('delete one, then add new one', () => { - const oldDoc = { - number: ['1'], - }; - const newDoc = { - number: ['2'], - }; + it('delete one, then insert new one', () => { + const oldDoc = { + number: ['1'], + }; + const newDoc = { + number: ['2'], + }; + + expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( + newDoc + ); + }); - expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( - newDoc - ); + it('delete two, then insert new one', () => { + const oldDoc = { + number: ['1', '2'], + }; + const newDoc = { + number: ['3'], + }; + + expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( + newDoc + ); + }); }); - it('delete two, then add new one', () => { - const oldDoc = { - number: ['1', '2'], - }; - const newDoc = { - number: ['3'], - }; - - expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( - newDoc - ); - }); + describe('delete and move:', () => { + it('delete the first, then move the third to the second', () => { + const oldDoc = { + _id: 'nara', + number: ['1', '2', '3', '4'], + }; + const newDoc = { + _id: 'nara', + number: ['2', '4', '3'], + }; + expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( + newDoc + ); + }); - it('delete the first, then move the third to the second', () => { - const oldDoc = { - _id: 'nara', - number: ['1', '2', '3', '4'], - }; - const newDoc = { - _id: 'nara', - number: ['2', '4', '3'], - }; - expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( - newDoc - ); - }); + it('delete the third, then move the first to the last', () => { + const oldDoc = { + _id: 'nara', + number: ['1', '2', '3', '4'], + }; + const newDoc = { + _id: 'nara', + number: ['2', '4', '1'], + }; + expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( + newDoc + ); + }); - it('delete the third, then move the first to the last', () => { - const oldDoc = { - _id: 'nara', - number: ['1', '2', '3', '4'], - }; - const newDoc = { - _id: 'nara', - number: ['2', '4', '1'], - }; - expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( - newDoc - ); - }); + it('delete the first, then move the last to the first', () => { + const oldDoc = { + number: ['1', '2', '3'], + }; + const newDoc = { + number: ['3', '2'], + }; + expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( + newDoc + ); + }); - it('delete the first, then move the last to the first', () => { - const oldDoc = { - number: ['1', '2', '3'], - }; - const newDoc = { - number: ['3', '2'], - }; - expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( - newDoc - ); + it('delete the second, then move the last to the first', () => { + const oldDoc = { + number: ['1', '2', '3'], + }; + const newDoc = { + number: ['3', '1'], + }; + expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( + newDoc + ); + }); }); - it('delete the second, then move the last to the first', () => { - const oldDoc = { - number: ['1', '2', '3'], - }; - const newDoc = { - number: ['3', '1'], - }; - expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( - newDoc - ); - }); + describe('insert and move:', () => { + it('insert the first, then move the last to the second', () => { + const oldDoc = { + number: ['1', '2', '3'], + }; + const newDoc = { + number: ['4', '3', '2', '1'], + }; + expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( + newDoc + ); + }); - it('add the first, then move the last to the second', () => { - const oldDoc = { - number: ['1', '2', '3'], - }; - const newDoc = { - number: ['4', '3', '2', '1'], - }; - console.log(primitiveDiff.diff(oldDoc, newDoc)); - expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( - newDoc - ); + it('insert the first, then move the last to the first', () => { + const oldDoc = { + number: ['1', '2', '3'], + }; + const newDoc = { + number: ['3', '4', '1', '2'], + }; + expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( + newDoc + ); + }); }); - it('add the second, add the third, remove the last, then move the first to the last', () => { - const oldDoc = { - number: ['1', '2', '3'], - }; - const newDoc = { - number: ['3', '4', '5', '1'], - }; - console.log(primitiveDiff.diff(oldDoc, newDoc)); - expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( - newDoc - ); + describe('composite:', () => { + it('insert after the second, insert after the third, remove the last, then move the first to the last', () => { + const oldDoc = { + number: ['1', '2', '3'], + }; + const newDoc = { + number: ['2', '4', '5', '1'], + }; + expect(jPatch.patch(oldDoc, primitiveDiff.diff(oldDoc, newDoc)!)).toStrictEqual( + newDoc + ); + }); }); it('nesting arrays', () => { @@ -582,6 +606,7 @@ describe(' OT', () => { ], }; const diff = primitiveDiff.diff(oldDoc, newDoc)!; + console.log(JSON.stringify(diff)); expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); }); @@ -606,11 +631,113 @@ describe(' OT', () => { ], }; const diff = myDiff.diff(oldDoc, newDoc)!; + console.log(JSON.stringify(diff)); expect(jPatch.patch(oldDoc, diff)).toStrictEqual(newDoc); }); + + describe('merge:', () => { + it('merges move and replace', () => { + const base = { + number: ['1', '2', '3'], + }; + + // move + const ours = { + number: ['3', '1', '2'], + }; + + // replace + const theirs = { + number: ['1', '2', '4'], + }; + + /** + * Result is not ['4', '1', '2' ], + * Replacing take precedence over moving + */ + const merged = { + number: ['1', '2', '4'], + }; + + const diffOurs = primitiveDiff.diff(base, ours); + // console.log(diffOurs); + const diffTheirs = primitiveDiff.diff(base, theirs); + // console.log(diffTheirs); + const patchOurs = jPatch.fromDiff(diffOurs!); + // console.log(patchOurs); + const patchTheirs = jPatch.fromDiff(diffTheirs!); + // console.log(patchTheirs); + + expect(jPatch.patch(ours, diffOurs!, theirs, diffTheirs)).toStrictEqual(merged); + }); + + it('merges move and replace (reverse)', () => { + const base = { + number: ['1', '2', '3'], + }; + + // replace + const ours = { + number: ['1', '2', '4'], + }; + + // move + const theirs = { + number: ['3', '1', '2'], + }; + + const merged = { + number: ['1', '2', '4'], + }; + + const diffOurs = primitiveDiff.diff(base, ours); + // console.log(diffOurs); + const diffTheirs = primitiveDiff.diff(base, theirs); + // console.log(diffTheirs); + const patchOurs = jPatch.fromDiff(diffOurs!); + // console.log(patchOurs); + const patchTheirs = jPatch.fromDiff(diffTheirs!); + // console.log(patchTheirs); + + expect(jPatch.patch(ours, diffOurs!, theirs, diffTheirs)).toStrictEqual(merged); + }); + + it.only('merges move and replace, another case', () => { + const base = { + number: ['1', '2', '3', '4'], + }; + + // move + const ours = { + number: ['5', '1', '2', '3'], + }; + + // replace + const theirs = { + number: ['1', '2', '3', '5'], + }; + + // TODO: + // 5 is duplicated. + const merged = { + number: ['5', '1', '2', '3', '5'], + }; + + const diffOurs = primitiveDiff.diff(base, ours); + // console.log(diffOurs); + const diffTheirs = primitiveDiff.diff(base, theirs); + // console.log(diffTheirs); + const patchOurs = jPatch.fromDiff(diffOurs!); + // console.log(patchOurs); + const patchTheirs = jPatch.fromDiff(diffTheirs!); + // console.log(patchTheirs); + + expect(jPatch.patch(ours, diffOurs!, theirs, diffTheirs)).toStrictEqual(merged); + }); + }); }); - describe('for object', () => { + describe('for object:', () => { it('returns patch from diff (create)', () => { const oldDoc = { _id: 'nara', @@ -768,9 +895,78 @@ describe(' OT', () => { expect(jPatch.patch(ours, diffOurs!, theirs, diffTheirs)).toStrictEqual(merged); }); + + it('merges conflicted changes (update and remove by ours-diff)', () => { + const base = { + _id: 'nara', + age: 'Nara prefecture', + }; + + const ours = { + _id: 'nara', + age: 'Heijo-kyo', + }; + + const theirs = { + _id: 'nara', + }; + + const merged = { + _id: 'nara', + age: 'Heijo-kyo', + }; + + const diffOurs = primitiveDiff.diff(base, ours); + const diffTheirs = primitiveDiff.diff(base, theirs); + + const patchOurs = jPatch.fromDiff(diffOurs!); + // console.log(patchOurs); + const patchTheirs = jPatch.fromDiff(diffTheirs!); + // console.log(patchTheirs); + + expect(jPatch.patch(ours, diffOurs!, theirs, diffTheirs)).toStrictEqual(merged); + }); + + it('merges conflicted changes (update by ours-diff)', () => { + // Default strategy is ours-diff + const base = { + _id: 'nara', + age: 'Nara prefecture', + deer: 100, + }; + + const ours = { + _id: 'nara', + age: 'Fujiwara-kyo', + deer: 1000, + }; + + const theirs = { + _id: 'nara', + age: 'Heijo-kyo', + deer: 100, + }; + + const merged = { + _id: 'nara', + age: 'Fujiwara-kyo', + deer: 1000, + }; + + const diffOurs = primitiveDiff.diff(base, ours); + // console.log(diffOurs); + const diffTheirs = primitiveDiff.diff(base, theirs); + // console.log(diffTheirs); + const patchOurs = jPatch.fromDiff(diffOurs!); + // console.log(patchOurs); + const patchTheirs = jPatch.fromDiff(diffTheirs!); + // console.log(patchTheirs); + + expect(jPatch.patch(ours, diffOurs!, theirs, diffTheirs)).toStrictEqual(merged); + }); }); - describe('for text', () => { + describe('for text:', () => { it('applies patch (create)', () => { const oldDoc = { _id: 'nara', @@ -960,7 +1156,7 @@ describe(' OT', () => { expect(jPatch.apply(oldDoc, patch)).toStrictEqual(newDoc); }); - it('returns patch from diff (add to head of text)', () => { + it('returns patch from diff (insert to head of text)', () => { const oldDoc = { _id: 'nara', text: 'abc', @@ -988,7 +1184,7 @@ describe(' OT', () => { expect(jPatch.apply(oldDoc, patch)).toStrictEqual(newDoc); }); - it('returns patch from diff (add to middle of text', () => { + it('returns patch from diff (insert to middle of text', () => { const oldDoc = { _id: 'nara', text: 'abc', @@ -1017,7 +1213,7 @@ describe(' OT', () => { expect(jPatch.apply(oldDoc, patch)).toStrictEqual(newDoc); }); - it('returns patch from diff (add to tail of text)', () => { + it('returns patch from diff (insert to tail of text)', () => { const oldDoc = { _id: 'nara', text: 'abc', @@ -1377,7 +1573,7 @@ sighed Meg, looking down at her old dress.`, expect(jPatch.patch(oldDoc, textOTDiff.diff(oldDoc, newDoc))).toStrictEqual(newDoc); }); - it('merges conflicted text: add', () => { + it('merges conflicted text: insert', () => { const base = { _id: 'littlewomen', text: '', @@ -1464,7 +1660,7 @@ grumbled Jo, lying on the rug.`, expect(jPatch.patch(ours, diffOurs!, theirs, diffTheirs)).toStrictEqual(merged); }); - it('merges conflicted text: add and delete', () => { + it('merges conflicted text: insert and delete', () => { const base = { _id: 'littlewomen', text: `"Christmas won't be Christmas without any presents," @@ -1725,7 +1921,7 @@ sighed Meg, looking down at her old dress.`, }); }); - describe('merge nested object', () => { + describe('merge nested object:', () => { it('merges simple structure', () => { const base = { geometry: { @@ -1916,6 +2112,4 @@ sighed Meg, looking down at her old dress.`, expect(jPatch.patch(docOurs, diffOurs, docTheirs, diffTheirs)).toStrictEqual(newDoc); }); }); - - it.skip('merges conflicted primitives: add', () => {}); }); From 0120a1d0262d0df9b7b9f43ad126dbf793321b61 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Mon, 9 May 2022 19:35:52 +0900 Subject: [PATCH 277/297] adding test for merging move operations --- src/remote/json_patch_ot.ts | 1 + test/remote_offline/json_patch_ot.test.ts | 156 ++++++++++++++++++++-- 2 files changed, 144 insertions(+), 13 deletions(-) diff --git a/src/remote/json_patch_ot.ts b/src/remote/json_patch_ot.ts index 3387559d..602c403f 100644 --- a/src/remote/json_patch_ot.ts +++ b/src/remote/json_patch_ot.ts @@ -341,6 +341,7 @@ export class JsonPatchOT implements IJsonPatch { transformedOp = type.transform(opOurs, opTheirs, 'right'); } } catch (err: unknown) { + // console.log('conflict: ' + JSON.stringify(err)); if ((err as { conflict: any }).conflict) { // console.log('conflict: ' + JSON.stringify((err as { conflict: any }).conflict)); const conflict = (err as { conflict: any }).conflict as { diff --git a/test/remote_offline/json_patch_ot.test.ts b/test/remote_offline/json_patch_ot.test.ts index b2e46e2b..55ff27e1 100644 --- a/test/remote_offline/json_patch_ot.test.ts +++ b/test/remote_offline/json_patch_ot.test.ts @@ -636,7 +636,7 @@ describe(' OT', () => { }); describe('merge:', () => { - it('merges move and replace', () => { + it('replacing take precedence over moving', () => { const base = { number: ['1', '2', '3'], }; @@ -663,15 +663,11 @@ describe(' OT', () => { // console.log(diffOurs); const diffTheirs = primitiveDiff.diff(base, theirs); // console.log(diffTheirs); - const patchOurs = jPatch.fromDiff(diffOurs!); - // console.log(patchOurs); - const patchTheirs = jPatch.fromDiff(diffTheirs!); - // console.log(patchTheirs); expect(jPatch.patch(ours, diffOurs!, theirs, diffTheirs)).toStrictEqual(merged); }); - it('merges move and replace (reverse)', () => { + it('replacing take precedence over moving (reverse)', () => { const base = { number: ['1', '2', '3'], }; @@ -686,6 +682,10 @@ describe(' OT', () => { number: ['3', '1', '2'], }; + /** + * Result is not ['4', '1', '2' ], + * Replacing take precedence over moving + */ const merged = { number: ['1', '2', '4'], }; @@ -702,25 +702,155 @@ describe(' OT', () => { expect(jPatch.patch(ours, diffOurs!, theirs, diffTheirs)).toStrictEqual(merged); }); - it.only('merges move and replace, another case', () => { + it('removing take precedence over moving', () => { const base = { - number: ['1', '2', '3', '4'], + number: ['1', '2', '3'], + }; + + // remove + const ours = { + number: ['1', '2'], + }; + + // move + const theirs = { + number: ['3', '1', '2'], + }; + + // Removing take precedence over moving + const merged = { + number: ['1', '2'], + }; + + const diffOurs = primitiveDiff.diff(base, ours); + // console.log(diffOurs); + const diffTheirs = primitiveDiff.diff(base, theirs); + // console.log(diffTheirs); + + expect(jPatch.patch(ours, diffOurs!, theirs, diffTheirs)).toStrictEqual(merged); + }); + + it('removing take precedence over moving (reverse)', () => { + const base = { + number: ['1', '2', '3'], + }; + + // move + const ours = { + number: ['3', '1', '2'], + }; + + // remove + const theirs = { + number: ['1', '2'], + }; + + // Removing take precedence over moving + const merged = { + number: ['1', '2'], + }; + + const diffOurs = primitiveDiff.diff(base, ours); + // console.log(diffOurs); + const diffTheirs = primitiveDiff.diff(base, theirs); + // console.log(diffTheirs); + + expect(jPatch.patch(ours, diffOurs!, theirs, diffTheirs)).toStrictEqual(merged); + }); + + it('merges remove and replace', () => { + const base = { + number: ['1', '2', '3'], + }; + + const ours = { + number: ['1', '2'], + }; + + const theirs = { + number: ['1', '2', '4'], + }; + + const merged = { + number: ['1', '2', '4'], + }; + + const diffOurs = primitiveDiff.diff(base, ours); + // console.log(diffOurs); + const diffTheirs = primitiveDiff.diff(base, theirs); + // console.log(diffTheirs); + + expect(jPatch.patch(ours, diffOurs!, theirs, diffTheirs)).toStrictEqual(merged); + }); + + it('merges insert and remove', () => { + const base = { + number: ['1', '2', '3'], + }; + + const ours = { + number: ['1', '2'], + }; + + const theirs = { + number: ['4', '1', '2', '3'], + }; + + const merged = { + number: ['4', '1', '2'], + }; + + const diffOurs = primitiveDiff.diff(base, ours); + // console.log(diffOurs); + const diffTheirs = primitiveDiff.diff(base, theirs); + // console.log(diffTheirs); + + expect(jPatch.patch(ours, diffOurs!, theirs, diffTheirs)).toStrictEqual(merged); + }); + + it.only('merges move and move', () => { + const base = { + number: ['1', '2', '3', '4', '5'], + }; + + const ours = { + number: ['5', '3', '2', '4', '1'], + }; + + const theirs = { + number: ['3', '4', '1', '5', '2'], + }; + + const merged = { + number: ['5', '3', '2', '4', '1'], + }; + + const diffOurs = primitiveDiff.diff(base, ours); + // console.log(diffOurs); + const diffTheirs = primitiveDiff.diff(base, theirs); + // console.log(diffTheirs); + + expect(jPatch.patch(ours, diffOurs!, theirs, diffTheirs)).toStrictEqual(merged); + }); + + it('merging insert operations results in duplicate members', () => { + const base = { + number: ['1', '2'], }; // move const ours = { - number: ['5', '1', '2', '3'], + number: ['1', '2', '3'], }; // replace const theirs = { - number: ['1', '2', '3', '5'], + number: ['3', '1', '2'], }; - // TODO: - // 5 is duplicated. + // 3 is duplicated. const merged = { - number: ['5', '1', '2', '3', '5'], + number: ['3', '1', '2', '3'], }; const diffOurs = primitiveDiff.diff(base, ours); From 77535bd44eec162321e157cc65195d64fe5f64ee Mon Sep 17 00:00:00 2001 From: sosuisen Date: Mon, 9 May 2022 22:36:42 +0900 Subject: [PATCH 278/297] test: add test for merging in arrays --- test/remote_offline/json_patch_ot.test.ts | 165 +++++++++++++++++++++- 1 file changed, 164 insertions(+), 1 deletion(-) diff --git a/test/remote_offline/json_patch_ot.test.ts b/test/remote_offline/json_patch_ot.test.ts index 55ff27e1..08c4764c 100644 --- a/test/remote_offline/json_patch_ot.test.ts +++ b/test/remote_offline/json_patch_ot.test.ts @@ -636,6 +636,87 @@ describe(' OT', () => { }); describe('merge:', () => { + it('merges insert and insert', () => { + const base = { + number: ['1', '2', '3'], + }; + + // move + const ours = { + number: ['1', '2', '4', '3'], + }; + + // replace + const theirs = { + number: ['1', '2', '3', '5'], + }; + + const merged = { + number: ['1', '2', '4', '3', '5'], + }; + + const diffOurs = primitiveDiff.diff(base, ours); + // console.log(diffOurs); + const diffTheirs = primitiveDiff.diff(base, theirs); + // console.log(diffTheirs); + + expect(jPatch.patch(ours, diffOurs!, theirs, diffTheirs)).toStrictEqual(merged); + }); + + it('merges insert and insert (2)', () => { + const base = { + number: ['1', '2', '3'], + }; + + // move + const ours = { + number: ['1', '2', '4', '3'], + }; + + // replace + const theirs = { + number: ['1', '2', '5', '3'], + }; + + const merged = { + number: ['1', '2', '4', '5', '3'], + }; + + const diffOurs = primitiveDiff.diff(base, ours); + // console.log(diffOurs); + const diffTheirs = primitiveDiff.diff(base, theirs); + // console.log(diffTheirs); + + expect(jPatch.patch(ours, diffOurs!, theirs, diffTheirs)).toStrictEqual(merged); + }); + + it('merges remove and remove', () => { + const base = { + number: ['1', '2', '3'], + }; + + // move + const ours = { + number: ['1', '2'], + }; + + // replace + const theirs = { + number: ['1', '3'], + }; + + const merged = { + number: ['1'], + }; + + const diffOurs = primitiveDiff.diff(base, ours); + // console.log(diffOurs); + const diffTheirs = primitiveDiff.diff(base, theirs); + // console.log(diffTheirs); + + expect(jPatch.patch(ours, diffOurs!, theirs, diffTheirs)).toStrictEqual(merged); + }); + it('replacing take precedence over moving', () => { const base = { number: ['1', '2', '3'], @@ -808,7 +889,42 @@ describe(' OT', () => { expect(jPatch.patch(ours, diffOurs!, theirs, diffTheirs)).toStrictEqual(merged); }); - it.only('merges move and move', () => { + it('merges move and move the same', () => { + /** + * See https://github.com/ottypes/json1#limitations. + * > We're missing a conflict for situations + * > when two operations both move the same object to different locations. + * > Currently the left operation will silently 'win' + * > and the other operation's move will be discarded. + * > But this behaviour should be user configurable + */ + const base = { + number: ['1', '2', '3', '4', '5'], + }; + + const ours = { + number: ['5', '2', '3', '4', '1'], + }; + + // Move the same to another position + const theirs = { + number: ['1', '2', '3', '5', '4'], + }; + + // Ours wins silently. + const merged = { + number: ['5', '2', '3', '4', '1'], + }; + + const diffOurs = primitiveDiff.diff(base, ours); + // console.log(diffOurs); + const diffTheirs = primitiveDiff.diff(base, theirs); + // console.log(diffTheirs); + + expect(jPatch.patch(ours, diffOurs!, theirs, diffTheirs)).toStrictEqual(merged); + }); + + it('merges move all and move all', () => { const base = { number: ['1', '2', '3', '4', '5'], }; @@ -821,6 +937,17 @@ describe(' OT', () => { number: ['3', '4', '1', '5', '2'], }; + /* + * TODO: + * The results are not predictable. + * JSON1 can not merge moves well. + * See https://github.com/ottypes/json1#limitations. + * > We're missing a conflict for situations + * > when two operations both move the same object to different locations. + * > Currently the left operation will silently 'win' + * > and the other operation's move will be discarded. + * > But this behaviour should be user configurable + */ const merged = { number: ['5', '3', '2', '4', '1'], }; @@ -833,6 +960,42 @@ describe(' OT', () => { expect(jPatch.patch(ours, diffOurs!, theirs, diffTheirs)).toStrictEqual(merged); }); + it('merges move all and move all (2)', () => { + const base = { + number: ['1', '2', '3', '4', '5'], + }; + + const ours = { + number: ['3', '4', '1', '5', '2'], + }; + + const theirs = { + number: ['5', '3', '2', '4', '1'], + }; + + /* + * TODO: + * The results are not predictable. + * JSON1 can not merge moves well. + * See https://github.com/ottypes/json1#limitations. + * > We're missing a conflict for situations + * > when two operations both move the same object to different locations. + * > Currently the left operation will silently 'win' + * > and the other operation's move will be discarded. + * > But this behaviour should be user configurable + */ + const merged = { + number: ['5', '3', '4', '1', '2'], + }; + + const diffOurs = primitiveDiff.diff(base, ours); + // console.log(diffOurs); + const diffTheirs = primitiveDiff.diff(base, theirs); + // console.log(diffTheirs); + + expect(jPatch.patch(ours, diffOurs!, theirs, diffTheirs)).toStrictEqual(merged); + }); + it('merging insert operations results in duplicate members', () => { const base = { number: ['1', '2'], From bc041a5527728ae3a84e94a0f0dd2378dc9bf363 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Mon, 9 May 2022 23:02:56 +0900 Subject: [PATCH 279/297] fix: rename from idOfSubtree to keyInArrayedObject --- docs-api/git-documentdb.jsondiffoptions.md | 14 +++++++------- docs-api/git-documentdb.md | 2 +- docs-api/git-documentdb.schema.md | 4 ++-- etc/git-documentdb.api.md | 6 +++--- src/git_documentdb.ts | 2 +- src/remote/json_diff.ts | 12 ++++++------ src/types.ts | 15 +++++++++------ test/remote_offline/json_diff.test.ts | 2 +- test/remote_offline/json_patch_ot.test.ts | 2 +- 9 files changed, 31 insertions(+), 28 deletions(-) diff --git a/docs-api/git-documentdb.jsondiffoptions.md b/docs-api/git-documentdb.jsondiffoptions.md index 598791b0..600c4b66 100644 --- a/docs-api/git-documentdb.jsondiffoptions.md +++ b/docs-api/git-documentdb.jsondiffoptions.md @@ -1,20 +1,20 @@ --- -sidebar_label: JsonDiffOptions type -title: JsonDiffOptions type +sidebar_label: JsonDiffPatchOptions type +title: JsonDiffPatchOptions type hide_title: true --- -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [JsonDiffOptions](./git-documentdb.jsondiffoptions.md) +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [JsonDiffPatchOptions](./git-documentdb.JsonDiffPatchOptions.md) -## JsonDiffOptions type +## JsonDiffPatchOptions type -JsonDiffOptions +JsonDiffPatchOptions Signature: ```typescript -export declare type JsonDiffOptions = { - idOfSubtree?: string[]; +export declare type JsonDiffPatchOptions = { + keyInArrayedObject?: string[]; plainTextProperties?: { [key: string]: any; }; diff --git a/docs-api/git-documentdb.md b/docs-api/git-documentdb.md index 6986feac..bb3fe29e 100644 --- a/docs-api/git-documentdb.md +++ b/docs-api/git-documentdb.md @@ -113,7 +113,7 @@ Offline-first Database that Syncs with Git | [HistoryFilter](./git-documentdb.historyfilter.md) | Filter for file history | | [HistoryOptions](./git-documentdb.historyoptions.md) | Options for getHistory() and getFatDocHistory() | | [ICollection](./git-documentdb.icollection.md) | Type for Collection Class | -| [JsonDiffOptions](./git-documentdb.jsondiffoptions.md) | JsonDiffOptions | +| [JsonDiffPatchOptions](./git-documentdb.JsonDiffPatchOptions.md) | JsonDiffPatchOptions | | [JsonDoc](./git-documentdb.jsondoc.md) | The type for a JSON document that is stored in a database | | [JsonDocMetadata](./git-documentdb.jsondocmetadata.md) | Metadata for JsonDoc | | [NormalizedCommit](./git-documentdb.normalizedcommit.md) | Normalized Commit | diff --git a/docs-api/git-documentdb.schema.md b/docs-api/git-documentdb.schema.md index afc52562..72a3ffa4 100644 --- a/docs-api/git-documentdb.schema.md +++ b/docs-api/git-documentdb.schema.md @@ -14,10 +14,10 @@ Schema for specific document type ```typescript export declare type Schema = { - json: JsonDiffOptions; + json: JsonDiffPatchOptions; }; ``` References: -[JsonDiffOptions](./git-documentdb.jsondiffoptions.md) +[JsonDiffPatchOptions](./git-documentdb.JsonDiffPatchOptions.md) diff --git a/etc/git-documentdb.api.md b/etc/git-documentdb.api.md index b8372e39..92b4b20c 100644 --- a/etc/git-documentdb.api.md +++ b/etc/git-documentdb.api.md @@ -752,8 +752,8 @@ export interface IJsonPatch { export const JSON_EXT = ".json"; // @public -export type JsonDiffOptions = { - idOfSubtree?: string[]; +export type JsonDiffPatchOptions = { + keyInArrayedObject?: string[]; plainTextProperties?: { [key: string]: any; }; @@ -949,7 +949,7 @@ export class RemoteRepository { // @public export type Schema = { - json: JsonDiffOptions; + json: JsonDiffPatchOptions; }; // @public (undocumented) diff --git a/src/git_documentdb.ts b/src/git_documentdb.ts index aa276cae..b9253260 100644 --- a/src/git_documentdb.ts +++ b/src/git_documentdb.ts @@ -443,7 +443,7 @@ export class GitDocumentDB this._schema = options.schema ?? { json: { - idOfSubtree: undefined, + keyInArrayedObject: undefined, plainTextProperties: undefined, }, }; diff --git a/src/remote/json_diff.ts b/src/remote/json_diff.ts index 94a9495e..6b52d23c 100644 --- a/src/remote/json_diff.ts +++ b/src/remote/json_diff.ts @@ -1,20 +1,20 @@ import { create } from '@sosuisen/jsondiffpatch'; -import { JsonDiffOptions, JsonDoc } from '../types'; +import { JsonDiffPatchOptions, JsonDoc } from '../types'; const JSON_DIFF_MINIMUM_TEXT_LENGTH = Number.MAX_SAFE_INTEGER; export class JsonDiff { private _jsonDiffPatch; - constructor (options?: JsonDiffOptions) { + constructor (options?: JsonDiffPatchOptions) { options ??= { - idOfSubtree: undefined, + keyInArrayedObject: undefined, plainTextProperties: undefined, }; - options.idOfSubtree ??= []; + options.keyInArrayedObject ??= []; const objectHash = (obj: { [key: string]: any }, index: number) => { - for (let i = 0; i < options!.idOfSubtree!.length; i++) { - const id = obj[options!.idOfSubtree![i]]; + for (let i = 0; i < options!.keyInArrayedObject!.length; i++) { + const id = obj[options!.keyInArrayedObject![i]]; if (id !== undefined) { return id; } diff --git a/src/types.ts b/src/types.ts index caf3f2f9..f55e2e94 100644 --- a/src/types.ts +++ b/src/types.ts @@ -83,18 +83,20 @@ export type OpenOptions = { * @public */ export type Schema = { - json: JsonDiffOptions; + json: JsonDiffPatchOptions; }; /** - * JsonDiffOptions + * JsonDiffPatchOptions * * @remarks - * - plainTextProperties: Only property whose key matches plainTextProperties uses text diff and patch algorithm (google-diff-match-patch). + * - plainTextProperties: Only property whose key matches plainTextProperties uses text-diff-and-patch algorithm (google-diff-match-patch). + * - keyInArrayedObject: To diff between arrays that contain objects as elements, you must specify a key in the object. See https://github.com/benjamine/jsondiffpatch/blob/master/docs/arrays.md#an-object-hash + * - keyOfUniqueArray: Set a key of a unique array. Unique array never include duplicated members after JSON patch. * * @example * ``` - * e.g. + * Example of plainTextProperties: * { a: { b: true }, c: true } matches 'b' (whose ancestor is only 'a') and 'c'. * { a: { _all: true } } matches all child properties of 'a'. * { a: { _regex: /abc/ } } matches child properties of 'a' which match /abc/. @@ -102,8 +104,9 @@ export type Schema = { * * @public */ -export type JsonDiffOptions = { - idOfSubtree?: string[]; +export type JsonDiffPatchOptions = { + keyInArrayedObject?: string[]; + keyOfUniqueArray?: string[]; plainTextProperties?: { [key: string]: any }; }; diff --git a/test/remote_offline/json_diff.test.ts b/test/remote_offline/json_diff.test.ts index ca7eaaac..8ed78528 100644 --- a/test/remote_offline/json_diff.test.ts +++ b/test/remote_offline/json_diff.test.ts @@ -395,7 +395,7 @@ describe(' diff', () => { it('of object by objectHash', () => { const myDiff = new JsonDiff({ - idOfSubtree: ['place'], + keyInArrayedObject: ['place'], }); const oldDoc = { diff --git a/test/remote_offline/json_patch_ot.test.ts b/test/remote_offline/json_patch_ot.test.ts index 08c4764c..6d1e6c04 100644 --- a/test/remote_offline/json_patch_ot.test.ts +++ b/test/remote_offline/json_patch_ot.test.ts @@ -612,7 +612,7 @@ describe(' OT', () => { it('of objects by objectHash', () => { const myDiff = new JsonDiff({ - idOfSubtree: ['place'], + keyInArrayedObject: ['place'], }); const oldDoc = { From 9a2b0f6d39618ec942dfcc859b2bced252ff5b5c Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 10 May 2022 00:46:19 +0900 Subject: [PATCH 280/297] fix: add keyOfUniqueArray option --- src/remote/json_patch_ot.ts | 87 ++++++- src/remote/sync.ts | 2 +- test/remote_offline/json_patch_ot.test.ts | 297 +++++++++++++++++++++- 3 files changed, 379 insertions(+), 7 deletions(-) diff --git a/src/remote/json_patch_ot.ts b/src/remote/json_patch_ot.ts index 602c403f..734f03f4 100644 --- a/src/remote/json_patch_ot.ts +++ b/src/remote/json_patch_ot.ts @@ -2,11 +2,24 @@ /* eslint-disable max-depth */ import { editOp, insertOp, JSONOp, moveOp, removeOp, replaceOp, type } from 'ot-json1'; import { uniCount } from 'unicount'; -import { ConflictResolutionStrategyLabels, IJsonPatch, JsonDoc } from '../types'; +import { + ConflictResolutionStrategyLabels, + IJsonPatch, + JsonDiffPatchOptions, + JsonDoc, +} from '../types'; import { DEFAULT_CONFLICT_RESOLUTION_STRATEGY } from '../const'; export class JsonPatchOT implements IJsonPatch { - constructor () {} + private _keyOfUniqueArray: string[]; + + constructor (options?: JsonDiffPatchOptions) { + options ??= { + keyOfUniqueArray: undefined, + }; + this._keyOfUniqueArray = + options.keyOfUniqueArray !== undefined ? options.keyOfUniqueArray : []; + } private _textCreateOp (path: (string | number)[], startNum: number, str: string): JSONOp { if (startNum > 0) { @@ -294,6 +307,7 @@ export class JsonPatchOT implements IJsonPatch { return (type.apply(doc, op) as unknown) as JsonDoc; } + // eslint-disable-next-line complexity patch ( docOurs: JsonDoc, diffOurs: { [key: string]: any }, @@ -321,6 +335,75 @@ export class JsonPatchOT implements IJsonPatch { // console.log('# apply to: ' + JSON.stringify(docTheirs)); newDoc = (type.apply(docTheirs, transformedOp!) as unknown) as JsonDoc; } + + if (this._keyOfUniqueArray !== undefined && this._keyOfUniqueArray.length > 0) { + const ourTrees: JsonDoc[] = [docOurs]; + const theirTrees: JsonDoc[] = [docTheirs]; + const trees: JsonDoc[] = [newDoc]; + while (trees.length > 0) { + const currentTree = trees.pop(); + const currentOurTree = ourTrees.pop(); + const currentTheirTree = theirTrees.pop(); + if ( + currentTree === undefined || + currentOurTree === undefined || + currentTheirTree === undefined + ) + break; + + Object.keys(currentTree!).forEach(key => { + if (!Array.isArray(currentTree![key]) && typeof currentTree![key] === 'object') { + trees.push(currentTree![key]); + ourTrees.push(currentOurTree![key]); + theirTrees.push(currentTheirTree![key]); + } + else if (this._keyOfUniqueArray.includes(key)) { + const array = currentTree![key] as any[]; + const ourArray = currentOurTree![key] as any[]; + const theirArray = currentTheirTree![key] as any[]; + if (Array.isArray(array)) { + // eslint-disable-next-line complexity + const unique = array.filter((x, i, self) => { + if (self.indexOf(x) === i && i !== self.lastIndexOf(x)) { + if ( + strategy!.startsWith('ours') && + ourArray.indexOf(x) <= theirArray.indexOf(x) + ) { + return true; + } + else if ( + strategy!.startsWith('theirs') && + ourArray.indexOf(x) > theirArray.indexOf(x) + ) { + return true; + } + return false; + } + else if (self.indexOf(x) !== i && i === self.lastIndexOf(x)) { + if ( + strategy!.startsWith('ours') && + ourArray.indexOf(x) > theirArray.indexOf(x) + ) { + return true; + } + else if ( + strategy!.startsWith('theirs') && + ourArray.indexOf(x) <= theirArray.indexOf(x) + ) { + return true; + } + return false; + } + + return true; + }); + currentTree![key] = unique; + } + } + }); + } + } + return newDoc; } diff --git a/src/remote/sync.ts b/src/remote/sync.ts index 8ab801dd..71b9c792 100644 --- a/src/remote/sync.ts +++ b/src/remote/sync.ts @@ -408,7 +408,7 @@ export class Sync implements SyncInterface { this._options.conflictResolutionStrategy ??= DEFAULT_CONFLICT_RESOLUTION_STRATEGY; this.jsonDiff = new JsonDiff(gitDDB.schema.json); - this.jsonPatch = new JsonPatchOT(); + this.jsonPatch = new JsonPatchOT(gitDDB.schema.json); this._options.connection ??= { type: 'none' }; this._options.connection.engine ??= default_engine_name; diff --git a/test/remote_offline/json_patch_ot.test.ts b/test/remote_offline/json_patch_ot.test.ts index 6d1e6c04..9aaf90c2 100644 --- a/test/remote_offline/json_patch_ot.test.ts +++ b/test/remote_offline/json_patch_ot.test.ts @@ -12,6 +12,10 @@ const textOTDiff = new JsonDiff({ const jPatch = new JsonPatchOT(); +const jPatchUniqueArray = new JsonPatchOT({ + keyOfUniqueArray: ['unique'], +}); + describe(' OT', () => { describe('apply:', () => { it('apply op', () => { @@ -995,7 +999,9 @@ describe(' OT', () => { expect(jPatch.patch(ours, diffOurs!, theirs, diffTheirs)).toStrictEqual(merged); }); + }); + describe('duplicated members in array', () => { it('merging insert operations results in duplicate members', () => { const base = { number: ['1', '2'], @@ -1020,13 +1026,296 @@ describe(' OT', () => { // console.log(diffOurs); const diffTheirs = primitiveDiff.diff(base, theirs); // console.log(diffTheirs); - const patchOurs = jPatch.fromDiff(diffOurs!); - // console.log(patchOurs); - const patchTheirs = jPatch.fromDiff(diffTheirs!); - // console.log(patchTheirs); expect(jPatch.patch(ours, diffOurs!, theirs, diffTheirs)).toStrictEqual(merged); }); + + it('merging insert operations results in duplicate members (2)', () => { + const base = { + number: ['1', '2'], + }; + + // move + const ours = { + number: ['1', '2', '3'], + }; + + // replace + const theirs = { + number: ['1', '2', '3'], + }; + + // 3 is duplicated. + const merged = { + number: ['1', '2', '3', '3'], + }; + + const diffOurs = primitiveDiff.diff(base, ours); + // console.log(diffOurs); + const diffTheirs = primitiveDiff.diff(base, theirs); + // console.log(diffTheirs); + + expect(jPatch.patch(ours, diffOurs!, theirs, diffTheirs)).toStrictEqual(merged); + }); + + it('merging insert operations by unique array', () => { + const base = { + unique: ['1', '2'], + }; + + const ours = { + unique: ['1', '2', '3'], + }; + + const theirs = { + unique: ['3', '1', '2'], + }; + + // Result is ['3', '1', '2', '3'] if not unique array. + // ours-diff strategy is applied to remove the first '3'. + const merged = { + unique: ['1', '2', '3'], + }; + + const diffOurs = primitiveDiff.diff(base, ours); + // console.log(diffOurs); + const diffTheirs = primitiveDiff.diff(base, theirs); + // console.log(diffTheirs); + + expect(jPatchUniqueArray.patch(ours, diffOurs!, theirs, diffTheirs)).toStrictEqual( + merged + ); + }); + + it('merging insert operations by unique array (reverse)', () => { + const base = { + unique: ['1', '2'], + }; + + const ours = { + unique: ['3', '1', '2'], + }; + + const theirs = { + unique: ['1', '2', '3'], + }; + + // Result is ['3', '1', '2', '3'] if not unique array. + // ours-diff strategy is applied to remove the last '3'. + const merged = { + unique: ['3', '1', '2'], + }; + + const diffOurs = primitiveDiff.diff(base, ours); + // console.log(diffOurs); + const diffTheirs = primitiveDiff.diff(base, theirs); + // console.log(diffTheirs); + + expect(jPatchUniqueArray.patch(ours, diffOurs!, theirs, diffTheirs)).toStrictEqual( + merged + ); + }); + + it('merging insert operations by unique array (2)', () => { + const base = { + unique: ['1', '2'], + }; + + const ours = { + unique: ['1', '2', '3'], + }; + + const theirs = { + unique: ['1', '2', '3'], + }; + + // Result is ['1', '2', '3', '3'] if not unique array. + // ours-diff strategy is applied to remove the last '3'. + const merged = { + unique: ['1', '2', '3'], + }; + + const diffOurs = primitiveDiff.diff(base, ours); + // console.log(diffOurs); + const diffTheirs = primitiveDiff.diff(base, theirs); + // console.log(diffTheirs); + + expect(jPatchUniqueArray.patch(ours, diffOurs!, theirs, diffTheirs)).toStrictEqual( + merged + ); + }); + + it('merging insert operations by unique array and theirs-diff', () => { + const base = { + unique: ['1', '2'], + }; + + const ours = { + unique: ['1', '2', '3'], + }; + + const theirs = { + unique: ['3', '1', '2'], + }; + + // Result is ['3', '1', '2', '3'] if not unique array. + // theirs-diff strategy is applied to remove the last '3'. + const merged = { + unique: ['3', '1', '2'], + }; + + const diffOurs = primitiveDiff.diff(base, ours); + // console.log(diffOurs); + const diffTheirs = primitiveDiff.diff(base, theirs); + // console.log(diffTheirs); + + expect( + jPatchUniqueArray.patch(ours, diffOurs!, theirs, diffTheirs, 'theirs-diff') + ).toStrictEqual(merged); + }); + + it('merging insert operations by unique array and theirs-diff (reverse)', () => { + const base = { + unique: ['1', '2'], + }; + + const ours = { + unique: ['3', '1', '2'], + }; + + const theirs = { + unique: ['1', '2', '3'], + }; + + // Result is ['3', '1', '2', '3'] if not unique array. + // theirs-diff strategy is applied to remove the first '3'. + const merged = { + unique: ['1', '2', '3'], + }; + + const diffOurs = primitiveDiff.diff(base, ours); + // console.log(diffOurs); + const diffTheirs = primitiveDiff.diff(base, theirs); + // console.log(diffTheirs); + + expect( + jPatchUniqueArray.patch(ours, diffOurs!, theirs, diffTheirs, 'theirs-diff') + ).toStrictEqual(merged); + }); + + it('merging insert operations by unique array in a deep subtree', () => { + const base = { + a: 'a', + b: { + c: 'c', + d: { + e: 'e', + unique: ['1', '2'], + }, + }, + }; + + const ours = { + a: 'a', + b: { + c: 'c', + d: { + e: 'e', + unique: ['1', '2', '3'], + }, + }, + }; + + const theirs = { + a: 'a', + b: { + c: 'c', + d: { + e: 'e', + unique: ['3', '1', '2'], + }, + }, + }; + + // Result is ['3', '1', '2', '3'] if not unique array. + // ours-diff strategy is applied to remove the first '3'. + const merged = { + a: 'a', + b: { + c: 'c', + d: { + e: 'e', + unique: ['1', '2', '3'], + }, + }, + }; + + const diffOurs = primitiveDiff.diff(base, ours); + // console.log(diffOurs); + const diffTheirs = primitiveDiff.diff(base, theirs); + // console.log(diffTheirs); + + expect(jPatchUniqueArray.patch(ours, diffOurs!, theirs, diffTheirs)).toStrictEqual( + merged + ); + }); + + it('multiple unique array appears', () => { + const base = { + unique: ['1', '2'], + b: { + c: 'c', + d: { + e: 'e', + unique: ['1', '2'], + }, + }, + }; + + const ours = { + unique: ['1', '2', '3'], + b: { + c: 'c', + d: { + e: 'e', + unique: ['1', '2', '3'], + }, + }, + }; + + const theirs = { + unique: ['3', '1', '2'], + b: { + c: 'c', + d: { + e: 'e', + unique: ['3', '1', '2'], + }, + }, + }; + + // Result is ['3', '1', '2', '3'] if not unique array. + // ours-diff strategy is applied to remove the first '3'. + const merged = { + unique: ['1', '2', '3'], + b: { + c: 'c', + d: { + e: 'e', + unique: ['1', '2', '3'], + }, + }, + }; + + const diffOurs = primitiveDiff.diff(base, ours); + // console.log(diffOurs); + const diffTheirs = primitiveDiff.diff(base, theirs); + // console.log(diffTheirs); + + expect(jPatchUniqueArray.patch(ours, diffOurs!, theirs, diffTheirs)).toStrictEqual( + merged + ); + }); }); }); From c428dae6815e31b4714df77e809cc46b6a2165aa Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 10 May 2022 09:59:34 +0900 Subject: [PATCH 281/297] fix: add prepublishOnly --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b050d1b7..047ee4b9 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "test-plugin": "npm run mocha-parallel \"test_plugin/**/*.test.ts\" && npm run rm-test-db", "upload-coverage": "npx coveralls < coverage/lcov.info", "prepare": "", - "prepublishOnly": "", + "prepublishOnly": "npm run build && npm test", "api-extractor": "api-extractor run --local --verbose && npx api-documenter markdown -i ./temp -o ./docs-api", "lint": "eslint --fix --ext .ts .", "crlf": "npx crlf --set=LF docs-api/* etc/* ", From f7f488542a09a316ace11a5aa11fef12e348768e Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 10 May 2022 12:41:48 +0900 Subject: [PATCH 282/297] fix: update docs-api --- .../git-documentdb.collection.delete_1.md | 2 +- .../git-documentdb.collection.generateid.md | 9 +- .../git-documentdb.collection.getfatdoc.md | 2 +- ...-documentdb.collection.getfatdochistory.md | 2 +- ...umentdb.collection.getfatdocoldrevision.md | 2 +- .../git-documentdb.collection.gethistory.md | 4 +- ...it-documentdb.collection.getoldrevision.md | 4 +- docs-api/git-documentdb.collection.insert.md | 4 +- .../git-documentdb.collection.insert_1.md | 4 +- .../git-documentdb.collection.insertfatdoc.md | 6 +- docs-api/git-documentdb.collection.md | 4 +- docs-api/git-documentdb.collection.put.md | 4 +- docs-api/git-documentdb.collection.put_1.md | 4 +- .../git-documentdb.collection.putfatdoc.md | 6 +- docs-api/git-documentdb.collection.update.md | 4 +- .../git-documentdb.collection.update_1.md | 2 +- .../git-documentdb.collection.updatefatdoc.md | 6 +- docs-api/git-documentdb.collectionoptions.md | 1 + docs-api/git-documentdb.databaseinfo.md | 6 ++ docs-api/git-documentdb.databaseoptions.md | 13 ++- docs-api/git-documentdb.deleteresult.md | 2 +- .../git-documentdb.encodetogitremotename.md | 2 +- .../git-documentdb.front_matter_postfix.md | 16 ++++ ...ocumentdb.gitddbinterface.defaultbranch.md | 2 - .../git-documentdb.gitddbinterface.logger.md | 2 +- docs-api/git-documentdb.gitddbinterface.md | 6 +- ...umentdb.gitddbinterface.serializeformat.md | 17 ++++ ...git-documentdb.gitddbinterface.tslogger.md | 15 ++++ .../git-documentdb.gitdocumentdb.delete.md | 2 +- .../git-documentdb.gitdocumentdb.delete_1.md | 2 +- docs-api/git-documentdb.gitdocumentdb.get.md | 2 +- .../git-documentdb.gitdocumentdb.getfatdoc.md | 2 +- ...cumentdb.gitdocumentdb.getfatdochistory.md | 2 +- ...ntdb.gitdocumentdb.getfatdocoldrevision.md | 2 +- ...git-documentdb.gitdocumentdb.gethistory.md | 4 +- ...documentdb.gitdocumentdb.getoldrevision.md | 2 +- .../git-documentdb.gitdocumentdb.insert.md | 4 +- .../git-documentdb.gitdocumentdb.insert_1.md | 4 +- ...t-documentdb.gitdocumentdb.insertfatdoc.md | 4 +- .../git-documentdb.gitdocumentdb.logger.md | 2 +- ...documentdb.gitdocumentdb.logtotransport.md | 17 ++++ docs-api/git-documentdb.gitdocumentdb.md | 5 +- docs-api/git-documentdb.gitdocumentdb.put.md | 4 +- .../git-documentdb.gitdocumentdb.put_1.md | 4 +- .../git-documentdb.gitdocumentdb.putfatdoc.md | 4 +- ...ocumentdb.gitdocumentdb.serializeformat.md | 15 ++++ .../git-documentdb.gitdocumentdb.tslogger.md | 17 ++++ .../git-documentdb.gitdocumentdb.update.md | 4 +- .../git-documentdb.gitdocumentdb.update_1.md | 4 +- ...t-documentdb.gitdocumentdb.updatefatdoc.md | 4 +- docs-api/git-documentdb.icollection.md | 2 +- docs-api/git-documentdb.json_ext.md | 16 ---- docs-api/git-documentdb.json_postfix.md | 16 ++++ ...=> git-documentdb.jsondiffpatchoptions.md} | 11 ++- docs-api/git-documentdb.jsondocmetadata.md | 4 +- docs-api/git-documentdb.md | 9 +- docs-api/git-documentdb.putresult.md | 2 +- docs-api/git-documentdb.schema.md | 2 +- .../git-documentdb.serializeformatlabel.md | 17 ++++ docs-api/git-documentdb.sync.md | 1 + .../git-documentdb.sync.runbeforelivesync.md | 19 ++++ docs-api/git-documentdb.syncinterface.md | 1 + ...umentdb.syncinterface.runbeforelivesync.md | 17 ++++ .../git-documentdb.taskqueue._constructor_.md | 4 +- docs-api/git-documentdb.yaml_postfix.md | 16 ++++ etc/git-documentdb.api.md | 87 +++++++++++++++++-- 66 files changed, 383 insertions(+), 102 deletions(-) create mode 100644 docs-api/git-documentdb.front_matter_postfix.md create mode 100644 docs-api/git-documentdb.gitddbinterface.serializeformat.md create mode 100644 docs-api/git-documentdb.gitddbinterface.tslogger.md create mode 100644 docs-api/git-documentdb.gitdocumentdb.logtotransport.md create mode 100644 docs-api/git-documentdb.gitdocumentdb.serializeformat.md create mode 100644 docs-api/git-documentdb.gitdocumentdb.tslogger.md delete mode 100644 docs-api/git-documentdb.json_ext.md create mode 100644 docs-api/git-documentdb.json_postfix.md rename docs-api/{git-documentdb.jsondiffoptions.md => git-documentdb.jsondiffpatchoptions.md} (58%) create mode 100644 docs-api/git-documentdb.serializeformatlabel.md create mode 100644 docs-api/git-documentdb.sync.runbeforelivesync.md create mode 100644 docs-api/git-documentdb.syncinterface.runbeforelivesync.md create mode 100644 docs-api/git-documentdb.yaml_postfix.md diff --git a/docs-api/git-documentdb.collection.delete_1.md b/docs-api/git-documentdb.collection.delete_1.md index 15450298..37a99950 100644 --- a/docs-api/git-documentdb.collection.delete_1.md +++ b/docs-api/git-documentdb.collection.delete_1.md @@ -20,7 +20,7 @@ delete(jsonDoc: JsonDoc, options?: DeleteOptions): Promise; | Parameter | Type | Description | | --- | --- | --- | -| jsonDoc | [JsonDoc](./git-documentdb.jsondoc.md) | JsonDoc whose \_id is shortId. Only the \_id property is referenced. shortId is a file path whose collectionPath and .json extension are omitted. | +| jsonDoc | [JsonDoc](./git-documentdb.jsondoc.md) | JsonDoc whose \_id is shortId. Only the \_id property is referenced. shortId is a file path whose collectionPath and extension are omitted. | | options | [DeleteOptions](./git-documentdb.deleteoptions.md) | | Returns: diff --git a/docs-api/git-documentdb.collection.generateid.md b/docs-api/git-documentdb.collection.generateid.md index ba1980d8..2bcb299c 100644 --- a/docs-api/git-documentdb.collection.generateid.md +++ b/docs-api/git-documentdb.collection.generateid.md @@ -13,8 +13,15 @@ Generate new \_id as monotonic ULID Signature: ```typescript -generateId(): string; +generateId(seedTime?: number): string; ``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| seedTime | number | | + Returns: string diff --git a/docs-api/git-documentdb.collection.getfatdoc.md b/docs-api/git-documentdb.collection.getfatdoc.md index e1cb4800..fa0294f2 100644 --- a/docs-api/git-documentdb.collection.getfatdoc.md +++ b/docs-api/git-documentdb.collection.getfatdoc.md @@ -29,7 +29,7 @@ Promise<[FatDoc](./git-documentdb.fatdoc.md) \| undefined> - undefined if a specified data does not exist. -- FatJsonDoc if the file extension is '.json'. Be careful that JsonDoc may not have \_id property when an app other than GitDocumentDB creates it. +- FatJsonDoc if the file extension is SerializeFormat.extension. Be careful that JsonDoc may not have \_id property when an app other than GitDocumentDB creates it. - FatBinaryDoc if described in .gitattribtues, otherwise FatTextDoc. diff --git a/docs-api/git-documentdb.collection.getfatdochistory.md b/docs-api/git-documentdb.collection.getfatdochistory.md index 9577eca6..5a3039c1 100644 --- a/docs-api/git-documentdb.collection.getfatdochistory.md +++ b/docs-api/git-documentdb.collection.getfatdochistory.md @@ -30,7 +30,7 @@ Promise<([FatDoc](./git-documentdb.fatdoc.md) \| undefined)\[\]> Array of FatDoc or undefined. - undefined if a specified data does not exist or it is deleted. -- Array of FatJsonDoc if isJsonDocCollection is true or the file extension is '.json'. Be careful that JsonDoc may not have \_id property when an app other than GitDocumentDB creates it. +- Array of FatJsonDoc if isJsonDocCollection is true or the file extension is SerializeFormat.extension. Be careful that JsonDoc may not have \_id property when an app other than GitDocumentDB creates it. - Array of FatBinaryDoc if described in .gitattribtues, otherwise array of FatTextDoc. diff --git a/docs-api/git-documentdb.collection.getfatdocoldrevision.md b/docs-api/git-documentdb.collection.getfatdocoldrevision.md index c5a85861..d690b23e 100644 --- a/docs-api/git-documentdb.collection.getfatdocoldrevision.md +++ b/docs-api/git-documentdb.collection.getfatdocoldrevision.md @@ -33,7 +33,7 @@ Promise<[FatDoc](./git-documentdb.fatdoc.md) \| undefined> - undefined if a specified data does not exist or it is deleted. -- JsonDoc if the file extension is '.json'. Be careful that JsonDoc may not have \_id property when an app other than GitDocumentDB creates it. +- JsonDoc if the file extension is SerializedFormat.extension. Be careful that JsonDoc may not have \_id property when an app other than GitDocumentDB creates it. - FatBinaryDoc if described in .gitattribtues, otherwise FatTextDoc. diff --git a/docs-api/git-documentdb.collection.gethistory.md b/docs-api/git-documentdb.collection.gethistory.md index e296419e..07990884 100644 --- a/docs-api/git-documentdb.collection.gethistory.md +++ b/docs-api/git-documentdb.collection.gethistory.md @@ -27,12 +27,14 @@ getHistory(_id: string, historyOptions?: HistoryOptions): Promise<(JsonDoc | und Promise<([JsonDoc](./git-documentdb.jsondoc.md) \| undefined)\[\]> -Array of JsonDoc or undefined. - undefined if a specified document does not exist or it is deleted. +Array of JsonDoc or undefined if a specified document does not exist or it is deleted. ## Remarks - By default, revisions are sorted by reverse chronological order. However, keep in mind that Git dates may not be consistent across repositories. +- If serializeFormat is front-matter, this function can't work for .yml files. Use getFatDocHistory() instead. e.g.) foo.yml + ## Example diff --git a/docs-api/git-documentdb.collection.getoldrevision.md b/docs-api/git-documentdb.collection.getoldrevision.md index b16f19d3..4e387b88 100644 --- a/docs-api/git-documentdb.collection.getoldrevision.md +++ b/docs-api/git-documentdb.collection.getoldrevision.md @@ -20,7 +20,7 @@ getOldRevision(shortId: string, revision: number, historyOptions?: HistoryOption | Parameter | Type | Description | | --- | --- | --- | -| shortId | string | shortId is a file path whose collectionPath and .json extension are omitted. | +| shortId | string | shortId is a file path whose collectionPath and extension are omitted. | | revision | number | Specify a number to go back to old revision. Default is 0. See [Collection.getHistory()](./git-documentdb.collection.gethistory.md) for the array of revisions. | | historyOptions | [HistoryOptions](./git-documentdb.historyoptions.md) | The array of revisions is filtered by HistoryOptions.filter. | @@ -32,6 +32,8 @@ Promise<[JsonDoc](./git-documentdb.jsondoc.md) \| undefined> - undefined if a specified document does not exist or it is deleted. +- If serializeFormat is front-matter, this function can't correctly distinguish files that has the same \_id but different extension. Use getFatDocOldRevision() instead. e.g.) foo.md and foo.yml + ## Example diff --git a/docs-api/git-documentdb.collection.insert.md b/docs-api/git-documentdb.collection.insert.md index 187278b9..b0bedd14 100644 --- a/docs-api/git-documentdb.collection.insert.md +++ b/docs-api/git-documentdb.collection.insert.md @@ -20,7 +20,7 @@ insert(jsonDoc: JsonDoc, options?: PutOptions): Promise; | Parameter | Type | Description | | --- | --- | --- | -| jsonDoc | [JsonDoc](./git-documentdb.jsondoc.md) | JsonDoc whose \_id is shortId. shortId is a file path whose collectionPath and .json extension are omitted. | +| jsonDoc | [JsonDoc](./git-documentdb.jsondoc.md) | JsonDoc whose \_id is shortId. shortId is a file path whose collectionPath and extension are omitted. | | options | [PutOptions](./git-documentdb.putoptions.md) | | Returns: @@ -33,7 +33,7 @@ Promise<[PutResultJsonDoc](./git-documentdb.putresultjsondoc.md) > - If \_id is undefined, it is automatically generated. -- The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${jsonDoc._id}.json` . +- The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${jsonDoc._id}${extension}` . ## Exceptions diff --git a/docs-api/git-documentdb.collection.insert_1.md b/docs-api/git-documentdb.collection.insert_1.md index 6f34871b..359bca77 100644 --- a/docs-api/git-documentdb.collection.insert_1.md +++ b/docs-api/git-documentdb.collection.insert_1.md @@ -20,7 +20,7 @@ insert(shortId: string | undefined | null, jsonDoc: JsonDoc, options?: PutOption | Parameter | Type | Description | | --- | --- | --- | -| shortId | string \| undefined \| null | shortId is a file path whose collectionPath and .json extension are omitted. | +| shortId | string \| undefined \| null | shortId is a file path whose collectionPath and extension are omitted. | | jsonDoc | [JsonDoc](./git-documentdb.jsondoc.md) | | | options | [PutOptions](./git-documentdb.putoptions.md) | | @@ -32,7 +32,7 @@ Promise<[PutResultJsonDoc](./git-documentdb.putresultjsondoc.md) > - Throws SameIdExistsError when a document that has the same \_id exists. It might be better to use put() instead of insert(). -- The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortId}.json` . +- The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortId}${extension}` . - If shortId is undefined, it is automatically generated. diff --git a/docs-api/git-documentdb.collection.insertfatdoc.md b/docs-api/git-documentdb.collection.insertfatdoc.md index 4de863b1..732f3592 100644 --- a/docs-api/git-documentdb.collection.insertfatdoc.md +++ b/docs-api/git-documentdb.collection.insertfatdoc.md @@ -20,7 +20,7 @@ insertFatDoc(shortName: string | undefined | null, doc: JsonDoc | string | Uint8 | Parameter | Type | Description | | --- | --- | --- | -| shortName | string \| undefined \| null | shortName is a file path whose collectionPath is omitted. shortName of JsonDoc must ends with .json extension. | +| shortName | string \| undefined \| null | shortName is a file path whose collectionPath is omitted. shortName of JsonDoc must ends with extension. | | doc | [JsonDoc](./git-documentdb.jsondoc.md) \| string \| Uint8Array | | | options | [PutOptions](./git-documentdb.putoptions.md) | | @@ -32,11 +32,11 @@ Promise<[PutResult](./git-documentdb.putresult.md) > - Throws SameIdExistsError when data that has the same \_id exists. It might be better to use put() instead of insert(). -- The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortName}.json` . +- The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortName}${extension}` . - If shortName is undefined, it is automatically generated. -- \_id property of a JsonDoc is automatically set or overwritten by shortName parameter whose .json extension is omitted. +- \_id property of a JsonDoc is automatically set or overwritten by shortName parameter whose extension is omitted. ## Exceptions diff --git a/docs-api/git-documentdb.collection.md b/docs-api/git-documentdb.collection.md index e7a3d777..a13fecb8 100644 --- a/docs-api/git-documentdb.collection.md +++ b/docs-api/git-documentdb.collection.md @@ -23,7 +23,7 @@ export declare class Collection implements ICollection In a collection API, shortId (shortName) is used instead of \_id (name). -- shortId is a file path whose collectionPath and .json extension are omitted. (\_id = collectionPath + shortId) +- shortId is a file path whose collectionPath and extension are omitted. (\_id = collectionPath + shortId) - shortName is a file path whose collectionPath is omitted. (name = collectionPath + shortName) @@ -67,7 +67,7 @@ gitDDB.collection('Nara').get({ _id: 'flower' }); // returns { _id: 'flower', na | [deleteFatDoc(shortName, options)](./git-documentdb.collection.deletefatdoc.md) | | Delete a data | | [find(options)](./git-documentdb.collection.find.md) | | Get all the JSON documents | | [findFatDoc(options)](./git-documentdb.collection.findfatdoc.md) | | Get all the FatDoc data | -| [generateId()](./git-documentdb.collection.generateid.md) | | Generate new \_id as monotonic ULID | +| [generateId(seedTime)](./git-documentdb.collection.generateid.md) | | Generate new \_id as monotonic ULID | | [get(\_id)](./git-documentdb.collection.get.md) | | Get a JSON document | | [getCollections(dirPath)](./git-documentdb.collection.getcollections.md) | | Get collections directly under the specified dirPath. | | [getDocByOid(fileOid, docType)](./git-documentdb.collection.getdocbyoid.md) | | Get a Doc which has specified oid | diff --git a/docs-api/git-documentdb.collection.put.md b/docs-api/git-documentdb.collection.put.md index 3849ca9f..1eabf22d 100644 --- a/docs-api/git-documentdb.collection.put.md +++ b/docs-api/git-documentdb.collection.put.md @@ -20,7 +20,7 @@ put(jsonDoc: JsonDoc, options?: PutOptions): Promise; | Parameter | Type | Description | | --- | --- | --- | -| jsonDoc | [JsonDoc](./git-documentdb.jsondoc.md) | JsonDoc whose \_id is shortId. shortId is a file path whose collectionPath and .json extension are omitted. | +| jsonDoc | [JsonDoc](./git-documentdb.jsondoc.md) | JsonDoc whose \_id is shortId. shortId is a file path whose collectionPath and extension are omitted. | | options | [PutOptions](./git-documentdb.putoptions.md) | | Returns: @@ -29,7 +29,7 @@ Promise<[PutResultJsonDoc](./git-documentdb.putresultjsondoc.md) > ## Remarks -- The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}${jsonDoc._id}.json` . +- The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}${jsonDoc._id}${extension}` . - If \_id is undefined, it is automatically generated. diff --git a/docs-api/git-documentdb.collection.put_1.md b/docs-api/git-documentdb.collection.put_1.md index c3418e62..4bc2d035 100644 --- a/docs-api/git-documentdb.collection.put_1.md +++ b/docs-api/git-documentdb.collection.put_1.md @@ -20,7 +20,7 @@ put(shortId: string | undefined | null, jsonDoc: JsonDoc, options?: PutOptions): | Parameter | Type | Description | | --- | --- | --- | -| shortId | string \| undefined \| null | shortId is a file path whose collectionPath and .json extension are omitted. | +| shortId | string \| undefined \| null | shortId is a file path whose collectionPath and extension are omitted. | | jsonDoc | [JsonDoc](./git-documentdb.jsondoc.md) | | | options | [PutOptions](./git-documentdb.putoptions.md) | | @@ -30,7 +30,7 @@ Promise<[PutResultJsonDoc](./git-documentdb.putresultjsondoc.md) > ## Remarks -- The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortId}.json` . +- The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortId}${extension}` . - If shortId is undefined, it is automatically generated. diff --git a/docs-api/git-documentdb.collection.putfatdoc.md b/docs-api/git-documentdb.collection.putfatdoc.md index ff93ccdf..0d07f38b 100644 --- a/docs-api/git-documentdb.collection.putfatdoc.md +++ b/docs-api/git-documentdb.collection.putfatdoc.md @@ -20,7 +20,7 @@ putFatDoc(shortName: string | undefined | null, doc: JsonDoc | Uint8Array | stri | Parameter | Type | Description | | --- | --- | --- | -| shortName | string \| undefined \| null | shortName is a file path whose collectionPath is omitted. shortName of JsonDoc must ends with .json extension. | +| shortName | string \| undefined \| null | shortName is a file path whose collectionPath is omitted. shortName of JsonDoc must ends with extension. | | doc | [JsonDoc](./git-documentdb.jsondoc.md) \| Uint8Array \| string | | | options | [PutOptions](./git-documentdb.putoptions.md) | | @@ -30,11 +30,11 @@ Promise<[PutResult](./git-documentdb.putresult.md) > ## Remarks -- The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortName}.json` . +- The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortName}${extension}` . - If shortName is undefined, it is automatically generated. -- \_id property of a JsonDoc is automatically set or overwritten by shortName parameter whose .json extension is omitted. +- \_id property of a JsonDoc is automatically set or overwritten by shortName parameter whose extension is omitted. - An update operation is not skipped even if no change occurred on a specified data. diff --git a/docs-api/git-documentdb.collection.update.md b/docs-api/git-documentdb.collection.update.md index 08137051..41e8c3f8 100644 --- a/docs-api/git-documentdb.collection.update.md +++ b/docs-api/git-documentdb.collection.update.md @@ -20,7 +20,7 @@ update(jsonDoc: JsonDoc, options?: PutOptions): Promise; | Parameter | Type | Description | | --- | --- | --- | -| jsonDoc | [JsonDoc](./git-documentdb.jsondoc.md) | JsonDoc whose \_id is shortId. shortId is a file path whose collectionPath and .json extension are omitted. | +| jsonDoc | [JsonDoc](./git-documentdb.jsondoc.md) | JsonDoc whose \_id is shortId. shortId is a file path whose collectionPath and extension are omitted. | | options | [PutOptions](./git-documentdb.putoptions.md) | | Returns: @@ -31,7 +31,7 @@ Promise<[PutResultJsonDoc](./git-documentdb.putresultjsondoc.md) > - Throws DocumentNotFoundError if a specified document does not exist. It might be better to use put() instead of update(). -- The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${jsonDoc._id}.json` . +- The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${jsonDoc._id}${extension}` . - If \_id is undefined, it is automatically generated. diff --git a/docs-api/git-documentdb.collection.update_1.md b/docs-api/git-documentdb.collection.update_1.md index 8cd6ca43..c6f78f73 100644 --- a/docs-api/git-documentdb.collection.update_1.md +++ b/docs-api/git-documentdb.collection.update_1.md @@ -32,7 +32,7 @@ Promise<[PutResultJsonDoc](./git-documentdb.putresultjsondoc.md) > - Throws DocumentNotFoundError if a specified data does not exist. It might be better to use put() instead of update(). -- The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortId}.json` . +- The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortId}${extension}` . - An update operation is not skipped even if no change occurred on a specified data. diff --git a/docs-api/git-documentdb.collection.updatefatdoc.md b/docs-api/git-documentdb.collection.updatefatdoc.md index a7928d88..cde510e3 100644 --- a/docs-api/git-documentdb.collection.updatefatdoc.md +++ b/docs-api/git-documentdb.collection.updatefatdoc.md @@ -20,7 +20,7 @@ updateFatDoc(shortName: string | undefined | null, doc: JsonDoc | string | Uint8 | Parameter | Type | Description | | --- | --- | --- | -| shortName | string \| undefined \| null | shortName is a file path whose collectionPath is omitted. shortName of JsonDoc must ends with .json extension. | +| shortName | string \| undefined \| null | shortName is a file path whose collectionPath is omitted. shortName of JsonDoc must ends with extension. | | doc | [JsonDoc](./git-documentdb.jsondoc.md) \| string \| Uint8Array | | | options | [PutOptions](./git-documentdb.putoptions.md) | | @@ -32,9 +32,9 @@ Promise<[PutResult](./git-documentdb.putresult.md) > - Throws DocumentNotFoundError if a specified data does not exist. It might be better to use put() instead of update(). -- The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortName}.json` . +- The saved file path is `${GitDocumentDB#workingDir}/${Collection#collectionPath}/${shortName}${extension}` . -- \_id property of a JsonDoc is automatically set or overwritten by shortName parameter whose .json extension is omitted. +- \_id property of a JsonDoc is automatically set or overwritten by shortName parameter whose extension is omitted. - An update operation is not skipped even if no change occurred on a specified data. diff --git a/docs-api/git-documentdb.collectionoptions.md b/docs-api/git-documentdb.collectionoptions.md index de7fd47b..d3d1193e 100644 --- a/docs-api/git-documentdb.collectionoptions.md +++ b/docs-api/git-documentdb.collectionoptions.md @@ -16,6 +16,7 @@ Options for Collection constructor export declare type CollectionOptions = { namePrefix?: string; debounceTime?: number; + idGenerator?: () => string; }; ``` diff --git a/docs-api/git-documentdb.databaseinfo.md b/docs-api/git-documentdb.databaseinfo.md index 43bdc322..140876ad 100644 --- a/docs-api/git-documentdb.databaseinfo.md +++ b/docs-api/git-documentdb.databaseinfo.md @@ -17,8 +17,12 @@ export declare type DatabaseInfo = { dbId: string; creator: string; version: string; + serialize: SerializeFormatLabel; }; ``` +References: + +[SerializeFormatLabel](./git-documentdb.serializeformatlabel.md) ## Remarks @@ -32,3 +36,5 @@ export declare type DatabaseInfo = { - version: A version of the GitDocumentDB specification. The version can be used for database migration. +- serialize: Serialize format of the database. + diff --git a/docs-api/git-documentdb.databaseoptions.md b/docs-api/git-documentdb.databaseoptions.md index a3a8e137..ca81ee44 100644 --- a/docs-api/git-documentdb.databaseoptions.md +++ b/docs-api/git-documentdb.databaseoptions.md @@ -18,11 +18,14 @@ export declare type DatabaseOptions = { dbName: string; logLevel?: TLogLevelName; schema?: Schema; + serialize?: SerializeFormatLabel; + logToTransport?: (logObject: ILogObject) => void; + logColorEnabled?: boolean; }; ``` References: -[Schema](./git-documentdb.schema.md) +[Schema](./git-documentdb.schema.md) , [SerializeFormatLabel](./git-documentdb.serializeformatlabel.md) ## Remarks @@ -52,3 +55,11 @@ dbName - A name of a git repository logLevel - Default is 'info'. +schema - Schema for a specific document type. + +serializeFormat - Format for serialization + +logToTransport - logToTransport function for all log levels. See https://tslog.js.org/\#/?id=transports + +logColorEnabled - Enable color for console log. Default is true. When you write log into a file by logToTransport, false is recommended. + diff --git a/docs-api/git-documentdb.deleteresult.md b/docs-api/git-documentdb.deleteresult.md index a5340638..ab30642b 100644 --- a/docs-api/git-documentdb.deleteresult.md +++ b/docs-api/git-documentdb.deleteresult.md @@ -21,7 +21,7 @@ export declare type DeleteResult = DeleteResultJsonDoc | DeleteResultText | Dele ## Remarks -- \_id: \_id of a JSON document. This is a file name without .json extension. PutResult does not have \_id if a document is not [JsonDoc](./git-documentdb.jsondoc.md) type. +- \_id: \_id of a JSON document. This is a file name without extension. PutResult does not have \_id if a document is not [JsonDoc](./git-documentdb.jsondoc.md) type. - name: A file name in Git. e.g.) "foo.json", "bar/baz.md" diff --git a/docs-api/git-documentdb.encodetogitremotename.md b/docs-api/git-documentdb.encodetogitremotename.md index c6a34766..5c118050 100644 --- a/docs-api/git-documentdb.encodetogitremotename.md +++ b/docs-api/git-documentdb.encodetogitremotename.md @@ -8,7 +8,7 @@ hide_title: true ## encodeToGitRemoteName() function -encodeToRemoteName +encodeToGitRemoteName Signature: diff --git a/docs-api/git-documentdb.front_matter_postfix.md b/docs-api/git-documentdb.front_matter_postfix.md new file mode 100644 index 00000000..3d1c9d4e --- /dev/null +++ b/docs-api/git-documentdb.front_matter_postfix.md @@ -0,0 +1,16 @@ +--- +sidebar_label: FRONT_MATTER_POSTFIX variable +title: FRONT_MATTER_POSTFIX variable +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [FRONT\_MATTER\_POSTFIX](./git-documentdb.front_matter_postfix.md) + +## FRONT\_MATTER\_POSTFIX variable + + +Signature: + +```typescript +FRONT_MATTER_POSTFIX = ".md" +``` diff --git a/docs-api/git-documentdb.gitddbinterface.defaultbranch.md b/docs-api/git-documentdb.gitddbinterface.defaultbranch.md index 5840f158..cb320c6e 100644 --- a/docs-api/git-documentdb.gitddbinterface.defaultbranch.md +++ b/docs-api/git-documentdb.gitddbinterface.defaultbranch.md @@ -8,8 +8,6 @@ hide_title: true ## GitDDBInterface.defaultBranch property -\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* Public properties (readonly) \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* - Signature: ```typescript diff --git a/docs-api/git-documentdb.gitddbinterface.logger.md b/docs-api/git-documentdb.gitddbinterface.logger.md index 389269e0..9bc214fa 100644 --- a/docs-api/git-documentdb.gitddbinterface.logger.md +++ b/docs-api/git-documentdb.gitddbinterface.logger.md @@ -11,5 +11,5 @@ hide_title: true Signature: ```typescript -logger: Logger; +logger: ColoredLogger; ``` diff --git a/docs-api/git-documentdb.gitddbinterface.md b/docs-api/git-documentdb.gitddbinterface.md index 6b155ec1..1df04f83 100644 --- a/docs-api/git-documentdb.gitddbinterface.md +++ b/docs-api/git-documentdb.gitddbinterface.md @@ -24,15 +24,17 @@ export interface GitDDBInterface | [committer](./git-documentdb.gitddbinterface.committer.md) | { name: string; email: string; } | | | [dbId](./git-documentdb.gitddbinterface.dbid.md) | string | | | [dbName](./git-documentdb.gitddbinterface.dbname.md) | string | | -| [defaultBranch](./git-documentdb.gitddbinterface.defaultbranch.md) | string | \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* Public properties (readonly) \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* | +| [defaultBranch](./git-documentdb.gitddbinterface.defaultbranch.md) | string | | | [isClosing](./git-documentdb.gitddbinterface.isclosing.md) | boolean | | | [isOpened](./git-documentdb.gitddbinterface.isopened.md) | boolean | | | [localDir](./git-documentdb.gitddbinterface.localdir.md) | string | | -| [logger](./git-documentdb.gitddbinterface.logger.md) | Logger | | +| [logger](./git-documentdb.gitddbinterface.logger.md) | ColoredLogger | | | [logLevel](./git-documentdb.gitddbinterface.loglevel.md) | TLogLevelName | \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* Public properties \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* | | [rootCollection](./git-documentdb.gitddbinterface.rootcollection.md) | [ICollection](./git-documentdb.icollection.md) | | | [schema](./git-documentdb.gitddbinterface.schema.md) | [Schema](./git-documentdb.schema.md) | | +| [serializeFormat](./git-documentdb.gitddbinterface.serializeformat.md) | SerializeFormatJSON \| SerializeFormatFrontMatter | \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* Public properties (readonly) \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* | | [taskQueue](./git-documentdb.gitddbinterface.taskqueue.md) | [TaskQueue](./git-documentdb.taskqueue.md) | | +| [tsLogger](./git-documentdb.gitddbinterface.tslogger.md) | Logger | | | [validator](./git-documentdb.gitddbinterface.validator.md) | [Validator](./git-documentdb.validator.md) | | | [workingDir](./git-documentdb.gitddbinterface.workingdir.md) | string | | diff --git a/docs-api/git-documentdb.gitddbinterface.serializeformat.md b/docs-api/git-documentdb.gitddbinterface.serializeformat.md new file mode 100644 index 00000000..c3fbfbf3 --- /dev/null +++ b/docs-api/git-documentdb.gitddbinterface.serializeformat.md @@ -0,0 +1,17 @@ +--- +sidebar_label: serializeFormat +title: GitDDBInterface.serializeFormat property +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [GitDDBInterface](./git-documentdb.gitddbinterface.md) > [serializeFormat](./git-documentdb.gitddbinterface.serializeformat.md) + +## GitDDBInterface.serializeFormat property + +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* Public properties (readonly) \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* + +Signature: + +```typescript +serializeFormat: SerializeFormatJSON | SerializeFormatFrontMatter; +``` diff --git a/docs-api/git-documentdb.gitddbinterface.tslogger.md b/docs-api/git-documentdb.gitddbinterface.tslogger.md new file mode 100644 index 00000000..a56cf3af --- /dev/null +++ b/docs-api/git-documentdb.gitddbinterface.tslogger.md @@ -0,0 +1,15 @@ +--- +sidebar_label: tsLogger +title: GitDDBInterface.tsLogger property +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [GitDDBInterface](./git-documentdb.gitddbinterface.md) > [tsLogger](./git-documentdb.gitddbinterface.tslogger.md) + +## GitDDBInterface.tsLogger property + +Signature: + +```typescript +tsLogger: Logger; +``` diff --git a/docs-api/git-documentdb.gitdocumentdb.delete.md b/docs-api/git-documentdb.gitdocumentdb.delete.md index 1b9bc9f5..461aca39 100644 --- a/docs-api/git-documentdb.gitdocumentdb.delete.md +++ b/docs-api/git-documentdb.gitdocumentdb.delete.md @@ -20,7 +20,7 @@ delete(_id: string, options?: DeleteOptions): Promise; | Parameter | Type | Description | | --- | --- | --- | -| \_id | string | \_id is a file path whose .json extension is omitted. | +| \_id | string | \_id is a file path whose extension is omitted. | | options | [DeleteOptions](./git-documentdb.deleteoptions.md) | | Returns: diff --git a/docs-api/git-documentdb.gitdocumentdb.delete_1.md b/docs-api/git-documentdb.gitdocumentdb.delete_1.md index a0b24568..51121e46 100644 --- a/docs-api/git-documentdb.gitdocumentdb.delete_1.md +++ b/docs-api/git-documentdb.gitdocumentdb.delete_1.md @@ -20,7 +20,7 @@ delete(jsonDoc: JsonDoc, options?: DeleteOptions): Promise; | Parameter | Type | Description | | --- | --- | --- | -| jsonDoc | [JsonDoc](./git-documentdb.jsondoc.md) | Only the \_id property of the JsonDoc is referenced. \_id is a file path whose .json extension is omitted. | +| jsonDoc | [JsonDoc](./git-documentdb.jsondoc.md) | Only the \_id property of the JsonDoc is referenced. \_id is a file path whose extension is omitted. | | options | [DeleteOptions](./git-documentdb.deleteoptions.md) | | Returns: diff --git a/docs-api/git-documentdb.gitdocumentdb.get.md b/docs-api/git-documentdb.gitdocumentdb.get.md index 371789c4..71bc184b 100644 --- a/docs-api/git-documentdb.gitdocumentdb.get.md +++ b/docs-api/git-documentdb.gitdocumentdb.get.md @@ -20,7 +20,7 @@ get(_id: string): Promise; | Parameter | Type | Description | | --- | --- | --- | -| \_id | string | \_id is a file path whose .json extension is omitted. | +| \_id | string | \_id is a file path whose extension is omitted. | Returns: diff --git a/docs-api/git-documentdb.gitdocumentdb.getfatdoc.md b/docs-api/git-documentdb.gitdocumentdb.getfatdoc.md index 905256c1..81b09d55 100644 --- a/docs-api/git-documentdb.gitdocumentdb.getfatdoc.md +++ b/docs-api/git-documentdb.gitdocumentdb.getfatdoc.md @@ -29,7 +29,7 @@ Promise<[FatDoc](./git-documentdb.fatdoc.md) \| undefined> - undefined if a specified data does not exist. -- FatJsonDoc if the file extension is '.json'. Be careful that JsonDoc may not have \_id property when an app other than GitDocumentDB creates it. +- FatJsonDoc if the file extension is SerializeFormat.extension. Be careful that JsonDoc may not have \_id property when an app other than GitDocumentDB creates it. - FatBinaryDoc if described in .gitattribtues, otherwise FatTextDoc. diff --git a/docs-api/git-documentdb.gitdocumentdb.getfatdochistory.md b/docs-api/git-documentdb.gitdocumentdb.getfatdochistory.md index bb58bd08..0c62a562 100644 --- a/docs-api/git-documentdb.gitdocumentdb.getfatdochistory.md +++ b/docs-api/git-documentdb.gitdocumentdb.getfatdochistory.md @@ -30,7 +30,7 @@ Promise<([FatDoc](./git-documentdb.fatdoc.md) \| undefined)\[\]> Array of FatDoc or undefined. - undefined if a specified data does not exist or it is deleted. -- Array of FatJsonDoc if isJsonDocCollection is true or the file extension is '.json'. Be careful that JsonDoc may not have \_id property when an app other than GitDocumentDB creates it. +- Array of FatJsonDoc if isJsonDocCollection is true or the file extension is SerializeFormat.extension. Be careful that JsonDoc may not have \_id property when an app other than GitDocumentDB creates it. - Array of FatBinaryDoc if described in .gitattribtues, otherwise array of FatTextDoc. diff --git a/docs-api/git-documentdb.gitdocumentdb.getfatdocoldrevision.md b/docs-api/git-documentdb.gitdocumentdb.getfatdocoldrevision.md index f80dde18..86fa1815 100644 --- a/docs-api/git-documentdb.gitdocumentdb.getfatdocoldrevision.md +++ b/docs-api/git-documentdb.gitdocumentdb.getfatdocoldrevision.md @@ -33,7 +33,7 @@ Promise<[FatDoc](./git-documentdb.fatdoc.md) \| undefined> - undefined if a specified data does not exist or it is deleted. -- JsonDoc if the file extension is '.json'. Be careful that JsonDoc may not have \_id property when an app other than GitDocumentDB creates it. +- JsonDoc if the file extension is SerializeFormat.extension. Be careful that JsonDoc may not have \_id property when an app other than GitDocumentDB creates it. - FatBinaryDoc if described in .gitattribtues, otherwise FatTextDoc. diff --git a/docs-api/git-documentdb.gitdocumentdb.gethistory.md b/docs-api/git-documentdb.gitdocumentdb.gethistory.md index 954334c0..0895d532 100644 --- a/docs-api/git-documentdb.gitdocumentdb.gethistory.md +++ b/docs-api/git-documentdb.gitdocumentdb.gethistory.md @@ -20,7 +20,7 @@ getHistory(_id: string, historyOptions?: HistoryOptions): Promise<(JsonDoc | und | Parameter | Type | Description | | --- | --- | --- | -| \_id | string | \_id is a file path whose .json extension is omitted. | +| \_id | string | \_id is a file path whose extension is omitted. | | historyOptions | [HistoryOptions](./git-documentdb.historyoptions.md) | The array of revisions is filtered by HistoryOptions.filter. | Returns: @@ -29,7 +29,7 @@ Promise<([JsonDoc](./git-documentdb.jsondoc.md) \| undefined)\[\]> Array of FatDoc or undefined. - undefined if a specified document does not exist or it is deleted. -- JsonDoc if isJsonDocCollection is true or the file extension is '.json'. +- JsonDoc if isJsonDocCollection is true or the file extension is SerializeFormat.extension. - Uint8Array or string if isJsonDocCollection is false. diff --git a/docs-api/git-documentdb.gitdocumentdb.getoldrevision.md b/docs-api/git-documentdb.gitdocumentdb.getoldrevision.md index 4ea99cb2..eafe2517 100644 --- a/docs-api/git-documentdb.gitdocumentdb.getoldrevision.md +++ b/docs-api/git-documentdb.gitdocumentdb.getoldrevision.md @@ -20,7 +20,7 @@ getOldRevision(_id: string, revision: number, historyOptions?: HistoryOptions): | Parameter | Type | Description | | --- | --- | --- | -| \_id | string | \_id is a file path whose .json extension is omitted. | +| \_id | string | \_id is a file path whose extension is omitted. | | revision | number | Specify a number to go back to old revision. Default is 0. See [GitDocumentDB.getHistory()](./git-documentdb.gitdocumentdb.gethistory.md) for the array of revisions. | | historyOptions | [HistoryOptions](./git-documentdb.historyoptions.md) | The array of revisions is filtered by HistoryOptions.filter. | diff --git a/docs-api/git-documentdb.gitdocumentdb.insert.md b/docs-api/git-documentdb.gitdocumentdb.insert.md index 9c0ffad6..e20f93f6 100644 --- a/docs-api/git-documentdb.gitdocumentdb.insert.md +++ b/docs-api/git-documentdb.gitdocumentdb.insert.md @@ -20,7 +20,7 @@ insert(jsonDoc: JsonDoc, options?: PutOptions): Promise; | Parameter | Type | Description | | --- | --- | --- | -| jsonDoc | [JsonDoc](./git-documentdb.jsondoc.md) | JsonDoc whose \_id is shortId. shortId is a file path whose collectionPath and .json extension are omitted. | +| jsonDoc | [JsonDoc](./git-documentdb.jsondoc.md) | JsonDoc whose \_id is shortId. shortId is a file path whose collectionPath and extension are omitted. | | options | [PutOptions](./git-documentdb.putoptions.md) | | Returns: @@ -33,7 +33,7 @@ Promise<[PutResultJsonDoc](./git-documentdb.putresultjsondoc.md) > - If \_id is undefined, it is automatically generated. -- The saved file path is `${GitDocumentDB#workingDir}/${jsonDoc._id}.json` on the file system. +- The saved file path is `${GitDocumentDB#workingDir}/${jsonDoc._id}${extension}` on the file system. - This is an alias of GitDocumentDB\#rootCollection.insert() diff --git a/docs-api/git-documentdb.gitdocumentdb.insert_1.md b/docs-api/git-documentdb.gitdocumentdb.insert_1.md index 6d804fa0..d1a4e446 100644 --- a/docs-api/git-documentdb.gitdocumentdb.insert_1.md +++ b/docs-api/git-documentdb.gitdocumentdb.insert_1.md @@ -20,7 +20,7 @@ insert(_id: string | undefined | null, jsonDoc: JsonDoc, options?: PutOptions): | Parameter | Type | Description | | --- | --- | --- | -| \_id | string \| undefined \| null | \_id is a file path whose .json extension is omitted. | +| \_id | string \| undefined \| null | \_id is a file path whose extension is omitted. | | jsonDoc | [JsonDoc](./git-documentdb.jsondoc.md) | | | options | [PutOptions](./git-documentdb.putoptions.md) | | @@ -32,7 +32,7 @@ Promise<[PutResultJsonDoc](./git-documentdb.putresultjsondoc.md) > - Throws SameIdExistsError when a document that has the same id exists. It might be better to use put() instead of insert(). -- The saved file path is `${GitDocumentDB#workingDir}/${_id}.json` on the file system. +- The saved file path is `${GitDocumentDB#workingDir}/${_id}${extension}` on the file system. - If \_id is undefined, it is automatically generated. diff --git a/docs-api/git-documentdb.gitdocumentdb.insertfatdoc.md b/docs-api/git-documentdb.gitdocumentdb.insertfatdoc.md index cc89fa14..41709318 100644 --- a/docs-api/git-documentdb.gitdocumentdb.insertfatdoc.md +++ b/docs-api/git-documentdb.gitdocumentdb.insertfatdoc.md @@ -32,11 +32,11 @@ Promise<[PutResult](./git-documentdb.putresult.md) > - Throws SameIdExistsError when data that has the same \_id exists. It might be better to use put() instead of insert(). -- The saved file path is `${GitDocumentDB#workingDir}/${name}.json` . +- The saved file path is `${GitDocumentDB#workingDir}/${name}extension` . - If a name parameter is undefined, it is automatically generated. -- \_id property of a JsonDoc is automatically set or overwritten by name parameter whose .json extension is omitted. +- \_id property of a JsonDoc is automatically set or overwritten by name parameter whose extension is omitted. - This is an alias of GitDocumentDB\#rootCollection.insertFatDoc() diff --git a/docs-api/git-documentdb.gitdocumentdb.logger.md b/docs-api/git-documentdb.gitdocumentdb.logger.md index 07d83193..8f7658e0 100644 --- a/docs-api/git-documentdb.gitdocumentdb.logger.md +++ b/docs-api/git-documentdb.gitdocumentdb.logger.md @@ -13,5 +13,5 @@ Get logger Signature: ```typescript -get logger(): Logger; +get logger(): ColoredLogger; ``` diff --git a/docs-api/git-documentdb.gitdocumentdb.logtotransport.md b/docs-api/git-documentdb.gitdocumentdb.logtotransport.md new file mode 100644 index 00000000..1270d5c0 --- /dev/null +++ b/docs-api/git-documentdb.gitdocumentdb.logtotransport.md @@ -0,0 +1,17 @@ +--- +sidebar_label: logToTransport +title: GitDocumentDB.logToTransport property +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [GitDocumentDB](./git-documentdb.gitdocumentdb.md) > [logToTransport](./git-documentdb.gitdocumentdb.logtotransport.md) + +## GitDocumentDB.logToTransport property + +logToTransport function for all log levels. See https://tslog.js.org/\#/?id=transports + +Signature: + +```typescript +get logToTransport(): ((logObject: ILogObject) => void) | undefined; +``` diff --git a/docs-api/git-documentdb.gitdocumentdb.md b/docs-api/git-documentdb.gitdocumentdb.md index d849fc88..50064485 100644 --- a/docs-api/git-documentdb.gitdocumentdb.md +++ b/docs-api/git-documentdb.gitdocumentdb.md @@ -41,11 +41,14 @@ Call open() before using DB. | [isClosing](./git-documentdb.gitdocumentdb.isclosing.md) | | boolean | DB is going to close | | [isOpened](./git-documentdb.gitdocumentdb.isopened.md) | | boolean | Test if a database is opened | | [localDir](./git-documentdb.gitdocumentdb.localdir.md) | | string | A local directory path that stores repositories of GitDocumentDB | -| [logger](./git-documentdb.gitdocumentdb.logger.md) | | Logger | Get logger | +| [logger](./git-documentdb.gitdocumentdb.logger.md) | | ColoredLogger | Get logger | | [logLevel](./git-documentdb.gitdocumentdb.loglevel.md) | | TLogLevelName | logLevel ('silly' \| 'trace' \| 'debug' \| 'info' \| 'warn' \| 'error' \| 'fatal') | +| [logToTransport](./git-documentdb.gitdocumentdb.logtotransport.md) | | ((logObject: ILogObject) => void) \| undefined | logToTransport function for all log levels. See https://tslog.js.org/\#/?id=transports | | [rootCollection](./git-documentdb.gitdocumentdb.rootcollection.md) | | [ICollection](./git-documentdb.icollection.md) | Default collection whose collectionPath is ''. | | [schema](./git-documentdb.gitdocumentdb.schema.md) | | [Schema](./git-documentdb.schema.md) | Schema for specific document type | +| [serializeFormat](./git-documentdb.gitdocumentdb.serializeformat.md) | | SerializeFormatJSON \| SerializeFormatFrontMatter | | | [taskQueue](./git-documentdb.gitdocumentdb.taskqueue.md) | | [TaskQueue](./git-documentdb.taskqueue.md) | Task queue | +| [tsLogger](./git-documentdb.gitdocumentdb.tslogger.md) | | Logger | Get logger | | [validator](./git-documentdb.gitdocumentdb.validator.md) | | [Validator](./git-documentdb.validator.md) | Name validator | | [workingDir](./git-documentdb.gitdocumentdb.workingdir.md) | | string | Get a full path of the current Git working directory | diff --git a/docs-api/git-documentdb.gitdocumentdb.put.md b/docs-api/git-documentdb.gitdocumentdb.put.md index 0d517f3a..da8fc7fb 100644 --- a/docs-api/git-documentdb.gitdocumentdb.put.md +++ b/docs-api/git-documentdb.gitdocumentdb.put.md @@ -20,7 +20,7 @@ put(jsonDoc: JsonDoc, options?: PutOptions): Promise; | Parameter | Type | Description | | --- | --- | --- | -| jsonDoc | [JsonDoc](./git-documentdb.jsondoc.md) | JsonDoc whose \_id is shortId. shortId is a file path whose collectionPath and .json extension are omitted. | +| jsonDoc | [JsonDoc](./git-documentdb.jsondoc.md) | JsonDoc whose \_id is shortId. shortId is a file path whose collectionPath and extension are omitted. | | options | [PutOptions](./git-documentdb.putoptions.md) | | Returns: @@ -29,7 +29,7 @@ Promise<[PutResultJsonDoc](./git-documentdb.putresultjsondoc.md) > ## Remarks -- The saved file path is `${GitDocumentDB#workingDir}/${jsonDoc._id}.json` on the file system. +- The saved file path is `${GitDocumentDB#workingDir}/${jsonDoc._id}${extension}` on the file system. - If \_id is undefined, it is automatically generated. diff --git a/docs-api/git-documentdb.gitdocumentdb.put_1.md b/docs-api/git-documentdb.gitdocumentdb.put_1.md index 7d7e561d..142aa9fa 100644 --- a/docs-api/git-documentdb.gitdocumentdb.put_1.md +++ b/docs-api/git-documentdb.gitdocumentdb.put_1.md @@ -20,7 +20,7 @@ put(_id: string | undefined | null, jsonDoc: JsonDoc, options?: PutOptions): Pro | Parameter | Type | Description | | --- | --- | --- | -| \_id | string \| undefined \| null | \_id is a file path whose .json extension is omitted. | +| \_id | string \| undefined \| null | \_id is a file path whose extension is omitted. | | jsonDoc | [JsonDoc](./git-documentdb.jsondoc.md) | | | options | [PutOptions](./git-documentdb.putoptions.md) | | @@ -30,7 +30,7 @@ Promise<[PutResultJsonDoc](./git-documentdb.putresultjsondoc.md) > ## Remarks -- The saved file path is `${GitDocumentDB#workingDir}/${_id}.json` on the file system. +- The saved file path is `${GitDocumentDB#workingDir}/${_id}${extension}` on the file system. - If \_id is undefined, it is automatically generated. diff --git a/docs-api/git-documentdb.gitdocumentdb.putfatdoc.md b/docs-api/git-documentdb.gitdocumentdb.putfatdoc.md index 1f4d9f8d..caf116d5 100644 --- a/docs-api/git-documentdb.gitdocumentdb.putfatdoc.md +++ b/docs-api/git-documentdb.gitdocumentdb.putfatdoc.md @@ -30,11 +30,11 @@ Promise<[PutResult](./git-documentdb.putresult.md) > ## Remarks -- The saved file path is `${GitDocumentDB#workingDir}/${name}.json` . +- The saved file path is `${GitDocumentDB#workingDir}/${name}extension` . - If a name parameter is undefined, it is automatically generated. -- \_id property of a JsonDoc is automatically set or overwritten by name parameter whose .json extension is removed. +- \_id property of a JsonDoc is automatically set or overwritten by name parameter whose extension is removed. - An update operation is not skipped even if no change occurred on a specified data. diff --git a/docs-api/git-documentdb.gitdocumentdb.serializeformat.md b/docs-api/git-documentdb.gitdocumentdb.serializeformat.md new file mode 100644 index 00000000..56c4dadb --- /dev/null +++ b/docs-api/git-documentdb.gitdocumentdb.serializeformat.md @@ -0,0 +1,15 @@ +--- +sidebar_label: serializeFormat +title: GitDocumentDB.serializeFormat property +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [GitDocumentDB](./git-documentdb.gitdocumentdb.md) > [serializeFormat](./git-documentdb.gitdocumentdb.serializeformat.md) + +## GitDocumentDB.serializeFormat property + +Signature: + +```typescript +get serializeFormat(): SerializeFormatJSON | SerializeFormatFrontMatter; +``` diff --git a/docs-api/git-documentdb.gitdocumentdb.tslogger.md b/docs-api/git-documentdb.gitdocumentdb.tslogger.md new file mode 100644 index 00000000..25375aff --- /dev/null +++ b/docs-api/git-documentdb.gitdocumentdb.tslogger.md @@ -0,0 +1,17 @@ +--- +sidebar_label: tsLogger +title: GitDocumentDB.tsLogger property +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [GitDocumentDB](./git-documentdb.gitdocumentdb.md) > [tsLogger](./git-documentdb.gitdocumentdb.tslogger.md) + +## GitDocumentDB.tsLogger property + +Get logger + +Signature: + +```typescript +get tsLogger(): Logger; +``` diff --git a/docs-api/git-documentdb.gitdocumentdb.update.md b/docs-api/git-documentdb.gitdocumentdb.update.md index 020bdf3e..0dacc612 100644 --- a/docs-api/git-documentdb.gitdocumentdb.update.md +++ b/docs-api/git-documentdb.gitdocumentdb.update.md @@ -20,7 +20,7 @@ update(jsonDoc: JsonDoc, options?: PutOptions): Promise; | Parameter | Type | Description | | --- | --- | --- | -| jsonDoc | [JsonDoc](./git-documentdb.jsondoc.md) | JsonDoc whose \_id is shortId. shortId is a file path whose collectionPath and .json extension are omitted. | +| jsonDoc | [JsonDoc](./git-documentdb.jsondoc.md) | JsonDoc whose \_id is shortId. shortId is a file path whose collectionPath and extension are omitted. | | options | [PutOptions](./git-documentdb.putoptions.md) | | Returns: @@ -33,7 +33,7 @@ Promise<[PutResultJsonDoc](./git-documentdb.putresultjsondoc.md) > - If \_id is undefined, it is automatically generated. -- The saved file path is `${GitDocumentDB#workingDir}/${_id}.json` on the file system. +- The saved file path is `${GitDocumentDB#workingDir}/${_id}extension` on the file system. - This is an alias of GitDocumentDB\#rootCollection.update() diff --git a/docs-api/git-documentdb.gitdocumentdb.update_1.md b/docs-api/git-documentdb.gitdocumentdb.update_1.md index 9a064314..2ce15b13 100644 --- a/docs-api/git-documentdb.gitdocumentdb.update_1.md +++ b/docs-api/git-documentdb.gitdocumentdb.update_1.md @@ -20,7 +20,7 @@ update(_id: string | undefined | null, jsonDoc: JsonDoc, options?: PutOptions): | Parameter | Type | Description | | --- | --- | --- | -| \_id | string \| undefined \| null | \_id is a file path whose .json extension is omitted. | +| \_id | string \| undefined \| null | \_id is a file path whose extension is omitted. | | jsonDoc | [JsonDoc](./git-documentdb.jsondoc.md) | | | options | [PutOptions](./git-documentdb.putoptions.md) | | @@ -32,7 +32,7 @@ Promise<[PutResultJsonDoc](./git-documentdb.putresultjsondoc.md) > - Throws DocumentNotFoundError if a specified document does not exist. It might be better to use put() instead of update(). -- The saved file path is `${GitDocumentDB#workingDir}/${_id}.json` on the file system. +- The saved file path is `${GitDocumentDB#workingDir}/${_id}extension` on the file system. - An update operation is not skipped even if no change occurred on a specified document. diff --git a/docs-api/git-documentdb.gitdocumentdb.updatefatdoc.md b/docs-api/git-documentdb.gitdocumentdb.updatefatdoc.md index bbc305d9..a84dbc37 100644 --- a/docs-api/git-documentdb.gitdocumentdb.updatefatdoc.md +++ b/docs-api/git-documentdb.gitdocumentdb.updatefatdoc.md @@ -32,9 +32,9 @@ Promise<[PutResult](./git-documentdb.putresult.md) > - Throws DocumentNotFoundError if a specified data does not exist. It might be better to use put() instead of update(). -- The saved file path is `${GitDocumentDB#workingDir}/${name}.json` . +- The saved file path is `${GitDocumentDB#workingDir}/${name}extension` . -- \_id property of a JsonDoc is automatically set or overwritten by name parameter whose .json extension is omitted. +- \_id property of a JsonDoc is automatically set or overwritten by name parameter whose extension is omitted. - An update operation is not skipped even if no change occurred on a specified data. diff --git a/docs-api/git-documentdb.icollection.md b/docs-api/git-documentdb.icollection.md index 54897bc8..17bbae1b 100644 --- a/docs-api/git-documentdb.icollection.md +++ b/docs-api/git-documentdb.icollection.md @@ -17,7 +17,7 @@ export declare type ICollection = CollectionInterface & CRUDInterface & SyncEven options: CollectionOptions; collectionPath: string; parent: ICollection | undefined; - generateId(): string; + generateId(seedTime?: number): string; }; ``` References: diff --git a/docs-api/git-documentdb.json_ext.md b/docs-api/git-documentdb.json_ext.md deleted file mode 100644 index 63d92084..00000000 --- a/docs-api/git-documentdb.json_ext.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -sidebar_label: JSON_EXT variable -title: JSON_EXT variable -hide_title: true ---- - -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [JSON\_EXT](./git-documentdb.json_ext.md) - -## JSON\_EXT variable - - -Signature: - -```typescript -JSON_EXT = ".json" -``` diff --git a/docs-api/git-documentdb.json_postfix.md b/docs-api/git-documentdb.json_postfix.md new file mode 100644 index 00000000..94f2391c --- /dev/null +++ b/docs-api/git-documentdb.json_postfix.md @@ -0,0 +1,16 @@ +--- +sidebar_label: JSON_POSTFIX variable +title: JSON_POSTFIX variable +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [JSON\_POSTFIX](./git-documentdb.json_postfix.md) + +## JSON\_POSTFIX variable + + +Signature: + +```typescript +JSON_POSTFIX = ".json" +``` diff --git a/docs-api/git-documentdb.jsondiffoptions.md b/docs-api/git-documentdb.jsondiffpatchoptions.md similarity index 58% rename from docs-api/git-documentdb.jsondiffoptions.md rename to docs-api/git-documentdb.jsondiffpatchoptions.md index 600c4b66..365214fc 100644 --- a/docs-api/git-documentdb.jsondiffoptions.md +++ b/docs-api/git-documentdb.jsondiffpatchoptions.md @@ -4,7 +4,7 @@ title: JsonDiffPatchOptions type hide_title: true --- -[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [JsonDiffPatchOptions](./git-documentdb.JsonDiffPatchOptions.md) +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [JsonDiffPatchOptions](./git-documentdb.jsondiffpatchoptions.md) ## JsonDiffPatchOptions type @@ -15,6 +15,7 @@ JsonDiffPatchOptions ```typescript export declare type JsonDiffPatchOptions = { keyInArrayedObject?: string[]; + keyOfUniqueArray?: string[]; plainTextProperties?: { [key: string]: any; }; @@ -23,13 +24,17 @@ export declare type JsonDiffPatchOptions = { ## Remarks -- plainTextProperties: Only property whose key matches plainTextProperties uses text diff and patch algorithm (google-diff-match-patch). +- plainTextProperties: Only property whose key matches plainTextProperties uses text-diff-and-patch algorithm (google-diff-match-patch). + +- keyInArrayedObject: To diff between arrays that contain objects as elements, you must specify a key in the object. See https://github.com/benjamine/jsondiffpatch/blob/master/docs/arrays.md\#an-object-hash + +- keyOfUniqueArray: Set a key of a unique array. Unique array never include duplicated members after JSON patch. ## Example ``` -e.g. +Example of plainTextProperties: { a: { b: true }, c: true } matches 'b' (whose ancestor is only 'a') and 'c'. { a: { _all: true } } matches all child properties of 'a'. { a: { _regex: /abc/ } } matches child properties of 'a' which match /abc/. diff --git a/docs-api/git-documentdb.jsondocmetadata.md b/docs-api/git-documentdb.jsondocmetadata.md index c9bfa3fd..23a9629f 100644 --- a/docs-api/git-documentdb.jsondocmetadata.md +++ b/docs-api/git-documentdb.jsondocmetadata.md @@ -23,9 +23,9 @@ export declare type JsonDocMetadata = { ## Remarks -- \_id: \_id of a JSON document. This is a file name without .json extension. +- \_id: \_id of a JSON document. This is a file name without extension. -- name: A file name in Git. e.g.) "foo.json", "bar/baz.json" +- name: A file name in Git. e.g.) "foo.json", "bar/baz.md" - fileOid: SHA-1 hash of Git object (40 characters) diff --git a/docs-api/git-documentdb.md b/docs-api/git-documentdb.md index bb3fe29e..4d8e6ab7 100644 --- a/docs-api/git-documentdb.md +++ b/docs-api/git-documentdb.md @@ -25,7 +25,7 @@ Offline-first Database that Syncs with Git | Function | Description | | --- | --- | -| [encodeToGitRemoteName(remoteURL)](./git-documentdb.encodetogitremotename.md) | encodeToRemoteName | +| [encodeToGitRemoteName(remoteURL)](./git-documentdb.encodetogitremotename.md) | encodeToGitRemoteName | ## Interfaces @@ -59,9 +59,10 @@ Offline-first Database that Syncs with Git | [FILE\_CREATE\_TIMEOUT](./git-documentdb.file_create_timeout.md) | | | [FILE\_REMOVE\_TIMEOUT](./git-documentdb.file_remove_timeout.md) | | | [FIRST\_COMMIT\_MESSAGE](./git-documentdb.first_commit_message.md) | | +| [FRONT\_MATTER\_POSTFIX](./git-documentdb.front_matter_postfix.md) | | | [GIT\_DOCUMENTDB\_INFO\_ID](./git-documentdb.git_documentdb_info_id.md) | | | [GIT\_DOCUMENTDB\_METADATA\_DIR](./git-documentdb.git_documentdb_metadata_dir.md) | | -| [JSON\_EXT](./git-documentdb.json_ext.md) | | +| [JSON\_POSTFIX](./git-documentdb.json_postfix.md) | | | [MAX\_FILE\_PATH\_LENGTH](./git-documentdb.max_file_path_length.md) | | | [MINIMUM\_SYNC\_INTERVAL](./git-documentdb.minimum_sync_interval.md) | | | [NETWORK\_RETRY\_INTERVAL](./git-documentdb.network_retry_interval.md) | | @@ -71,6 +72,7 @@ Offline-first Database that Syncs with Git | [RemoteEngine](./git-documentdb.remoteengine.md) | RemoteEngine | | [SET\_DATABASE\_ID\_MESSAGE](./git-documentdb.set_database_id_message.md) | | | [SHORT\_SHA\_LENGTH](./git-documentdb.short_sha_length.md) | | +| [YAML\_POSTFIX](./git-documentdb.yaml_postfix.md) | | ## Type Aliases @@ -113,7 +115,7 @@ Offline-first Database that Syncs with Git | [HistoryFilter](./git-documentdb.historyfilter.md) | Filter for file history | | [HistoryOptions](./git-documentdb.historyoptions.md) | Options for getHistory() and getFatDocHistory() | | [ICollection](./git-documentdb.icollection.md) | Type for Collection Class | -| [JsonDiffPatchOptions](./git-documentdb.JsonDiffPatchOptions.md) | JsonDiffPatchOptions | +| [JsonDiffPatchOptions](./git-documentdb.jsondiffpatchoptions.md) | JsonDiffPatchOptions | | [JsonDoc](./git-documentdb.jsondoc.md) | The type for a JSON document that is stored in a database | | [JsonDocMetadata](./git-documentdb.jsondocmetadata.md) | Metadata for JsonDoc | | [NormalizedCommit](./git-documentdb.normalizedcommit.md) | Normalized Commit | @@ -126,6 +128,7 @@ Offline-first Database that Syncs with Git | [PutResultText](./git-documentdb.putresulttext.md) | | | [RemoteOptions](./git-documentdb.remoteoptions.md) | Options for Sync class | | [Schema](./git-documentdb.schema.md) | Schema for specific document type | +| [SerializeFormatLabel](./git-documentdb.serializeformatlabel.md) | Format for serialization | | [SyncCallback](./git-documentdb.synccallback.md) | Union type of SyncEventCallbacks | | [SyncChangeCallback](./git-documentdb.syncchangecallback.md) | Callback of 'change' event | | [SyncCombineDatabaseCallback](./git-documentdb.synccombinedatabasecallback.md) | Callback of 'combine' event | diff --git a/docs-api/git-documentdb.putresult.md b/docs-api/git-documentdb.putresult.md index 181cc9ad..b09223d8 100644 --- a/docs-api/git-documentdb.putresult.md +++ b/docs-api/git-documentdb.putresult.md @@ -21,7 +21,7 @@ export declare type PutResult = PutResultJsonDoc | PutResultText | PutResultBina ## Remarks -- \_id: \_id of a JSON document. This is a file name without .json extension. PutResult does not have \_id if a document is not [JsonDoc](./git-documentdb.jsondoc.md) type. +- \_id: \_id of a JSON document. This is a file name without extension. PutResult does not have \_id if a document is not [JsonDoc](./git-documentdb.jsondoc.md) type. - name: A file name in Git. e.g.) "foo.json", "bar/baz.md" diff --git a/docs-api/git-documentdb.schema.md b/docs-api/git-documentdb.schema.md index 72a3ffa4..8d80f0b7 100644 --- a/docs-api/git-documentdb.schema.md +++ b/docs-api/git-documentdb.schema.md @@ -19,5 +19,5 @@ export declare type Schema = { ``` References: -[JsonDiffPatchOptions](./git-documentdb.JsonDiffPatchOptions.md) +[JsonDiffPatchOptions](./git-documentdb.jsondiffpatchoptions.md) diff --git a/docs-api/git-documentdb.serializeformatlabel.md b/docs-api/git-documentdb.serializeformatlabel.md new file mode 100644 index 00000000..2aaaf4f1 --- /dev/null +++ b/docs-api/git-documentdb.serializeformatlabel.md @@ -0,0 +1,17 @@ +--- +sidebar_label: SerializeFormatLabel type +title: SerializeFormatLabel type +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [SerializeFormatLabel](./git-documentdb.serializeformatlabel.md) + +## SerializeFormatLabel type + +Format for serialization + +Signature: + +```typescript +export declare type SerializeFormatLabel = 'json' | 'front-matter'; +``` diff --git a/docs-api/git-documentdb.sync.md b/docs-api/git-documentdb.sync.md index c523f93b..370ff77b 100644 --- a/docs-api/git-documentdb.sync.md +++ b/docs-api/git-documentdb.sync.md @@ -36,6 +36,7 @@ export declare class Sync implements SyncInterface | [remoteName](./git-documentdb.sync.remotename.md) | | string | remoteName | | [remoteRepository](./git-documentdb.sync.remoterepository.md) | | [RemoteRepository](./git-documentdb.remoterepository.md) | Remote repository | | [remoteURL](./git-documentdb.sync.remoteurl.md) | | string | remoteURL | +| [runBeforeLiveSync](./git-documentdb.sync.runbeforelivesync.md) | | (() => void) \| undefined | runBeforeLiveSync This function is executed just before each automated(live) synchronization event is queued. Set undefined to stop it. | ## Methods diff --git a/docs-api/git-documentdb.sync.runbeforelivesync.md b/docs-api/git-documentdb.sync.runbeforelivesync.md new file mode 100644 index 00000000..e4bc076a --- /dev/null +++ b/docs-api/git-documentdb.sync.runbeforelivesync.md @@ -0,0 +1,19 @@ +--- +sidebar_label: runBeforeLiveSync +title: Sync.runBeforeLiveSync property +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [Sync](./git-documentdb.sync.md) > [runBeforeLiveSync](./git-documentdb.sync.runbeforelivesync.md) + +## Sync.runBeforeLiveSync property + +runBeforeLiveSync + +This function is executed just before each automated(live) synchronization event is queued. Set undefined to stop it. + +Signature: + +```typescript +runBeforeLiveSync: (() => void) | undefined; +``` diff --git a/docs-api/git-documentdb.syncinterface.md b/docs-api/git-documentdb.syncinterface.md index e11fe670..41c6d8f1 100644 --- a/docs-api/git-documentdb.syncinterface.md +++ b/docs-api/git-documentdb.syncinterface.md @@ -27,6 +27,7 @@ export interface SyncInterface | [remoteName](./git-documentdb.syncinterface.remotename.md) | string | | | [remoteRepository](./git-documentdb.syncinterface.remoterepository.md) | [RemoteRepository](./git-documentdb.remoterepository.md) | | | [remoteURL](./git-documentdb.syncinterface.remoteurl.md) | string | \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* Public properties (readonly) \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* | +| [runBeforeLiveSync](./git-documentdb.syncinterface.runbeforelivesync.md) | (() => void) \| undefined | \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* Public properties \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* | ## Methods diff --git a/docs-api/git-documentdb.syncinterface.runbeforelivesync.md b/docs-api/git-documentdb.syncinterface.runbeforelivesync.md new file mode 100644 index 00000000..f4cdc111 --- /dev/null +++ b/docs-api/git-documentdb.syncinterface.runbeforelivesync.md @@ -0,0 +1,17 @@ +--- +sidebar_label: runBeforeLiveSync +title: SyncInterface.runBeforeLiveSync property +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [SyncInterface](./git-documentdb.syncinterface.md) > [runBeforeLiveSync](./git-documentdb.syncinterface.runbeforelivesync.md) + +## SyncInterface.runBeforeLiveSync property + +\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* Public properties \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* + +Signature: + +```typescript +runBeforeLiveSync: (() => void) | undefined; +``` diff --git a/docs-api/git-documentdb.taskqueue._constructor_.md b/docs-api/git-documentdb.taskqueue._constructor_.md index 936e9ee0..c76e19b3 100644 --- a/docs-api/git-documentdb.taskqueue._constructor_.md +++ b/docs-api/git-documentdb.taskqueue._constructor_.md @@ -13,14 +13,14 @@ Constructor Signature: ```typescript -constructor(logger: Logger); +constructor(logger: ColoredLogger); ``` ## Parameters | Parameter | Type | Description | | --- | --- | --- | -| logger | Logger | | +| logger | ColoredLogger | | ## Remarks diff --git a/docs-api/git-documentdb.yaml_postfix.md b/docs-api/git-documentdb.yaml_postfix.md new file mode 100644 index 00000000..0c428288 --- /dev/null +++ b/docs-api/git-documentdb.yaml_postfix.md @@ -0,0 +1,16 @@ +--- +sidebar_label: YAML_POSTFIX variable +title: YAML_POSTFIX variable +hide_title: true +--- + +[Home](./index.md) > [git-documentdb](./git-documentdb.md) > [YAML\_POSTFIX](./git-documentdb.yaml_postfix.md) + +## YAML\_POSTFIX variable + + +Signature: + +```typescript +YAML_POSTFIX = ".yml" +``` diff --git a/etc/git-documentdb.api.md b/etc/git-documentdb.api.md index 92b4b20c..d810e59c 100644 --- a/etc/git-documentdb.api.md +++ b/etc/git-documentdb.api.md @@ -4,6 +4,7 @@ ```ts +import { ILogObject } from 'tslog'; import { JSONOp } from 'ot-json1'; import { Logger } from 'tslog'; import { TLogLevelName } from 'tslog'; @@ -56,7 +57,7 @@ export class Collection implements ICollection { deleteFatDoc(shortName: string, options?: DeleteOptions): Promise; find(options?: FindOptions): Promise; findFatDoc(options?: FindOptions): Promise; - generateId(): string; + generateId(seedTime?: number): string; get(_id: string): Promise; getCollections(dirPath?: string): Promise; getDocByOid(fileOid: string, docType?: DocType): Promise; @@ -108,11 +109,30 @@ export interface CollectionInterface { export type CollectionOptions = { namePrefix?: string; debounceTime?: number; + idGenerator?: () => string; }; // @public export type CollectionPath = string; +// Warning: (ae-internal-missing-underscore) The name "ColoredLog" should be prefixed with an underscore because the declaration is marked as @internal +// +// @internal +export type ColoredLog = (mes: string, colorTag?: () => (literals: TemplateStringsArray, ...placeholders: any[]) => string) => void; + +// Warning: (ae-internal-missing-underscore) The name "ColoredLogger" should be prefixed with an underscore because the declaration is marked as @internal +// +// @internal +export type ColoredLogger = { + silly: ColoredLog; + debug: ColoredLog; + trace: ColoredLog; + info: ColoredLog; + warn: ColoredLog; + error: ColoredLog; + fatal: ColoredLog; +}; + // @public export type CombineDbStrategies = 'throw-error' | 'combine-head-with-ours' | 'combine-head-with-theirs' | 'combine-history-with-ours' | 'combine-history-with-theirs' | 'replace-with-ours' | 'replace-with-theirs'; @@ -219,6 +239,7 @@ export type DatabaseInfo = { dbId: string; creator: string; version: string; + serialize: SerializeFormatLabel; }; // @public @@ -234,6 +255,9 @@ export type DatabaseOptions = { dbName: string; logLevel?: TLogLevelName; schema?: Schema; + serialize?: SerializeFormatLabel; + logToTransport?: (logObject: ILogObject) => void; + logColorEnabled?: boolean; }; // @public (undocumented) @@ -548,6 +572,9 @@ export type FindOptions = { // @public (undocumented) export const FIRST_COMMIT_MESSAGE = "first commit"; +// @public (undocumented) +export const FRONT_MATTER_POSTFIX = ".md"; + // Warning: (ae-internal-missing-underscore) The name "generateDatabaseId" should be prefixed with an underscore because the declaration is marked as @internal // // @internal @@ -591,6 +618,7 @@ export interface GitDDBInterface { dbId: string; // (undocumented) dbName: string; + // (undocumented) defaultBranch: string; // (undocumented) destroy(options: DatabaseCloseOption): Promise<{ @@ -612,8 +640,10 @@ export interface GitDDBInterface { loadDbInfo(): void; // (undocumented) localDir: string; + // Warning: (ae-incompatible-release-tags) The symbol "logger" is marked as @public, but its signature references "ColoredLogger" which is marked as @internal + // // (undocumented) - logger: Logger; + logger: ColoredLogger; logLevel: TLogLevelName; open(options?: OpenOptions): Promise; // (undocumented) @@ -624,6 +654,9 @@ export interface GitDDBInterface { saveAuthor(): Promise; // (undocumented) schema: Schema; + // Warning: (ae-forgotten-export) The symbol "SerializeFormatJSON" needs to be exported by the entry point main.d.ts + // Warning: (ae-forgotten-export) The symbol "SerializeFormatFrontMatter" needs to be exported by the entry point main.d.ts + serializeFormat: SerializeFormatJSON | SerializeFormatFrontMatter; // (undocumented) sync(options: RemoteOptions, getSyncResult: boolean): Promise<[SyncInterface, SyncResult]>; // (undocumented) @@ -631,6 +664,8 @@ export interface GitDDBInterface { // (undocumented) taskQueue: TaskQueue; // (undocumented) + tsLogger: Logger; + // (undocumented) validator: Validator; // (undocumented) workingDir: string; @@ -680,9 +715,11 @@ export class GitDocumentDB implements GitDDBInterface, CRUDInterface, Collection // @internal loadDbInfo(): Promise; get localDir(): string; - get logger(): Logger; + // Warning: (ae-incompatible-release-tags) The symbol "logger" is marked as @public, but its signature references "ColoredLogger" which is marked as @internal + get logger(): ColoredLogger; get logLevel(): TLogLevelName; set logLevel(level: TLogLevelName); + get logToTransport(): ((logObject: ILogObject) => void) | undefined; // @eventProperty offSyncEvent(remoteURL: string, event: SyncEvent, callback: SyncCallback): void; // @eventProperty @@ -701,9 +738,12 @@ export class GitDocumentDB implements GitDDBInterface, CRUDInterface, Collection get rootCollection(): ICollection; saveAuthor(): Promise; get schema(): Schema; + // (undocumented) + get serializeFormat(): SerializeFormatJSON | SerializeFormatFrontMatter; sync(options: RemoteOptions): Promise; sync(options: RemoteOptions, getSyncResult: boolean): Promise<[Sync, SyncResult]>; get taskQueue(): TaskQueue; + get tsLogger(): Logger; update(jsonDoc: JsonDoc, options?: PutOptions): Promise; update(_id: string | undefined | null, jsonDoc: JsonDoc, options?: PutOptions): Promise; updateFatDoc(name: string | undefined | null, doc: JsonDoc | string | Uint8Array, options?: PutOptions): Promise; @@ -733,7 +773,7 @@ export type ICollection = CollectionInterface & CRUDInterface & SyncEventInterfa options: CollectionOptions; collectionPath: string; parent: ICollection | undefined; - generateId(): string; + generateId(seedTime?: number): string; }; // Warning: (ae-internal-missing-underscore) The name "IJsonPatch" should be prefixed with an underscore because the declaration is marked as @internal @@ -749,11 +789,12 @@ export interface IJsonPatch { } // @public (undocumented) -export const JSON_EXT = ".json"; +export const JSON_POSTFIX = ".json"; // @public export type JsonDiffPatchOptions = { keyInArrayedObject?: string[]; + keyOfUniqueArray?: string[]; plainTextProperties?: { [key: string]: any; }; @@ -952,6 +993,32 @@ export type Schema = { json: JsonDiffPatchOptions; }; +// Warning: (ae-internal-missing-underscore) The name "SerializeFormat" should be prefixed with an underscore because the declaration is marked as @internal +// +// @internal +export interface SerializeFormat { + // (undocumented) + extension: (doc?: JsonDoc) => string; + // (undocumented) + firstExtension: string; + // (undocumented) + format: SerializeFormatLabel; + // (undocumented) + hasObjectExtension: (path: string) => boolean; + // (undocumented) + removeExtension: (path: string) => string; + // (undocumented) + secondExtension: string | undefined; + // (undocumented) + serialize: (doc: JsonDoc) => { + extension: string; + data: string; + }; +} + +// @public +export type SerializeFormatLabel = 'json' | 'front-matter'; + // @public (undocumented) export const SET_DATABASE_ID_MESSAGE = "set database id"; @@ -1023,6 +1090,7 @@ export class Sync implements SyncInterface { interval?: number; retry?: number; }): boolean; + runBeforeLiveSync: (() => void) | undefined; tryPush(): Promise; // @internal tryPushImpl(calledAsPeriodicTask: boolean): Promise; @@ -1150,6 +1218,7 @@ export interface SyncInterface { interval?: number; retry?: number; }): void; + runBeforeLiveSync: (() => void) | undefined; // (undocumented) tryPush(): Promise; // (undocumented) @@ -1290,7 +1359,8 @@ export type TaskMetadata = { // @public export class TaskQueue { - constructor(logger: Logger); + // Warning: (ae-incompatible-release-tags) The symbol "__constructor" is marked as @public, but its signature references "ColoredLogger" which is marked as @internal + constructor(logger: ColoredLogger); currentStatistics(): TaskStatistics; currentTaskId(): string | undefined; getEnqueueTime(): string; @@ -1300,7 +1370,7 @@ export class TaskQueue { // @internal pushToTaskQueue(task: Task): void; // @internal - setLogger(logger: Logger): void; + setLogger(logger: ColoredLogger): void; start(): void; stop(): void; // @internal (undocumented) @@ -1359,6 +1429,9 @@ export function wrappingRemoteEngineError(remoteEngineError: BaseError): Error; // @public export type WriteOperation = 'insert' | 'update' | 'delete' | 'insert-merge' | 'update-merge'; +// @public (undocumented) +export const YAML_POSTFIX = ".yml"; + // Warnings were encountered during analysis: // // src/remote/remote_engine.ts:11:30 - (ae-incompatible-release-tags) The symbol "__index" is marked as @public, but its signature references "RemoteEngineInterface" which is marked as @internal From 0bc14da1417271ed8b5f60a0d0234020ff25410f Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 10 May 2022 12:42:05 +0900 Subject: [PATCH 283/297] fix: update examples --- examples/package-lock.json | 13514 +++++++++++++++++++++++++++++++++-- examples/package.json | 5 +- 2 files changed, 13107 insertions(+), 412 deletions(-) diff --git a/examples/package-lock.json b/examples/package-lock.json index 688951ec..c94b200e 100644 --- a/examples/package-lock.json +++ b/examples/package-lock.json @@ -1,8 +1,12039 @@ { "name": "git-documentdb-example", "version": "1.0.0", - "lockfileVersion": 1, + "lockfileVersion": 2, "requires": true, + "packages": { + "": { + "name": "git-documentdb-example", + "version": "1.0.0", + "license": "MPL-2.0", + "dependencies": { + "git-documentdb": "file:..", + "git-documentdb-plugin-remote-nodegit": "^1.0.4" + }, + "devDependencies": { + "typescript": "^4.1.3" + } + }, + "..": { + "version": "0.4.7-beta.1", + "integrity": "sha512-DASPwhhEM31y0AFkVAV+j5VBA4AYUY4a4LTnzTIbBpHZW8HhoxNxy1iTsgMKrldxNmBs8+HMDv1UgjoP9ZgTtw==", + "license": "MPL-2.0", + "dependencies": { + "@octokit/rest": "^18.3.5", + "@sosuisen/jsondiffpatch": "^0.4.7", + "async-lock": "^1.3.0", + "cross-blob": "^2.0.0", + "fs-extra": "^9.1.0", + "git-documentdb-plugin-remote-nodegit": "^1.0.4", + "git-documentdb-remote-errors": "^1.0.3", + "isomorphic-git": "^1.17.1", + "js-yaml": "^4.1.0", + "ot-json1": "^1.0.2", + "rimraf": "^3.0.2", + "tslog": "^3.1.2", + "ulid": "^2.3.0", + "unicount": "^1.2.0" + }, + "devDependencies": { + "@microsoft/api-extractor": "^7.16.0", + "@octokit/types": "^6.12.2", + "@sosuisen/api-documenter": "^7.13.27", + "@types/async-lock": "^1.1.2", + "@types/fs-extra": "^9.0.12", + "@types/js-yaml": "^4.0.3", + "@types/mocha": "^8.2.2", + "@types/node": "^14.14.20", + "@types/parse-git-config": "^3.0.0", + "@types/rimraf": "^3.0.0", + "@types/sinon": "^9.0.11", + "@typescript-eslint/eslint-plugin": "^4.28.0", + "@typescript-eslint/parser": "^4.28.0", + "coveralls": "^3.1.0", + "crlf": "^1.1.1", + "cross-env": "^7.0.3", + "eslint": "^7.17.0", + "eslint-config-standardize": "^0.7.1", + "eslint-plugin-prettierx": "^0.14.0", + "eslint-plugin-unicorn": "^36.0.0", + "expect": "^27.0.2", + "hmtid": "^0.1.0", + "mocha": "^8.3.2", + "nyc": "^15.1.0", + "parse-git-config": "^3.0.0", + "sinon": "^10.0.0", + "ts-node": "^10.1.0", + "tsconfig-paths": "^3.9.0", + "typescript": "^4.3.4" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "../node_modules/@angular/compiler": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-9.0.5.tgz", + "integrity": "sha512-TeyhRGefTOtA9N3udMrvheafoXcz/dvTTdZLcieeZQxm1SSeaQDUQ/rUH6QTOiHVNMtjOCrZ9J5rk1A4mPYuag==", + "dev": true, + "peerDependencies": { + "tslib": "^1.10.0" + } + }, + "../node_modules/@babel/code-frame": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "../node_modules/@babel/compat-data": { + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.7.tgz", + "integrity": "sha512-nS6dZaISCXJ3+518CWiBfEr//gHyMO02uDxBkXTKZDN5POruCnOZ1N4YBRZDCabwF8nZMWBpRxIicmXtBs+fvw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "../node_modules/@babel/core": { + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.6.tgz", + "integrity": "sha512-gJnOEWSqTk96qG5BoIrl5bVtc23DCycmIePPYnamY9RboYdI4nFy5vAQMSl81O5K/W0sLDWfGysnOECC+KUUCA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.14.5", + "@babel/helper-compilation-targets": "^7.14.5", + "@babel/helper-module-transforms": "^7.14.5", + "@babel/helpers": "^7.14.6", + "@babel/parser": "^7.14.6", + "@babel/template": "^7.14.5", + "@babel/traverse": "^7.14.5", + "@babel/types": "^7.14.5", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "../node_modules/@babel/core/node_modules/debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "../node_modules/@babel/core/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "../node_modules/@babel/core/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "../node_modules/@babel/core/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "../node_modules/@babel/eslint-parser": { + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.14.7.tgz", + "integrity": "sha512-6WPwZqO5priAGIwV6msJcdc9TsEPzYeYdS/Xuoap+/ihkgN6dzHp2bcAAwyWZ5bLzk0vvjDmKvRwkqNaiJ8BiQ==", + "dev": true, + "dependencies": { + "eslint-scope": "^5.1.1", + "eslint-visitor-keys": "^2.1.0", + "semver": "^6.3.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || >=14.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.11.0", + "eslint": ">=7.5.0" + } + }, + "../node_modules/@babel/eslint-parser/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "../node_modules/@babel/generator": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz", + "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.14.5", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "../node_modules/@babel/generator/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "../node_modules/@babel/helper-compilation-targets": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.14.5.tgz", + "integrity": "sha512-v+QtZqXEiOnpO6EYvlImB6zCD2Lel06RzOPzmkz/D/XgQiUu3C/Jb1LOqSt/AIA34TYi/Q+KlT8vTQrgdxkbLw==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.14.5", + "@babel/helper-validator-option": "^7.14.5", + "browserslist": "^4.16.6", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "../node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "../node_modules/@babel/helper-function-name": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz", + "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==", + "dev": true, + "dependencies": { + "@babel/helper-get-function-arity": "^7.14.5", + "@babel/template": "^7.14.5", + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "../node_modules/@babel/helper-get-function-arity": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz", + "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "../node_modules/@babel/helper-hoist-variables": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.14.5.tgz", + "integrity": "sha512-R1PXiz31Uc0Vxy4OEOm07x0oSjKAdPPCh3tPivn/Eo8cvz6gveAeuyUUPB21Hoiif0uoPQSSdhIPS3352nvdyQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "../node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.14.7.tgz", + "integrity": "sha512-TMUt4xKxJn6ccjcOW7c4hlwyJArizskAhoSTOCkA0uZ+KghIaci0Qg9R043kUMWI9mtQfgny+NQ5QATnZ+paaA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "../node_modules/@babel/helper-module-imports": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz", + "integrity": "sha512-SwrNHu5QWS84XlHwGYPDtCxcA0hrSlL2yhWYLgeOc0w7ccOl2qv4s/nARI0aYZW+bSwAL5CukeXA47B/1NKcnQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "../node_modules/@babel/helper-module-transforms": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.5.tgz", + "integrity": "sha512-iXpX4KW8LVODuAieD7MzhNjmM6dzYY5tfRqT+R9HDXWl0jPn/djKmA+G9s/2C2T9zggw5tK1QNqZ70USfedOwA==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.14.5", + "@babel/helper-replace-supers": "^7.14.5", + "@babel/helper-simple-access": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5", + "@babel/helper-validator-identifier": "^7.14.5", + "@babel/template": "^7.14.5", + "@babel/traverse": "^7.14.5", + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "../node_modules/@babel/helper-optimise-call-expression": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.14.5.tgz", + "integrity": "sha512-IqiLIrODUOdnPU9/F8ib1Fx2ohlgDhxnIDU7OEVi+kAbEZcyiF7BLU8W6PfvPi9LzztjS7kcbzbmL7oG8kD6VA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "../node_modules/@babel/helper-replace-supers": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.14.5.tgz", + "integrity": "sha512-3i1Qe9/8x/hCHINujn+iuHy+mMRLoc77b2nI9TB0zjH1hvn9qGlXjWlggdwUcju36PkPCy/lpM7LLUdcTyH4Ow==", + "dev": true, + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.14.5", + "@babel/helper-optimise-call-expression": "^7.14.5", + "@babel/traverse": "^7.14.5", + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "../node_modules/@babel/helper-simple-access": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.14.5.tgz", + "integrity": "sha512-nfBN9xvmCt6nrMZjfhkl7i0oTV3yxR4/FztsbOASyTvVcoYd0TRHh7eMLdlEcCqobydC0LAF3LtC92Iwxo0wyw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "../node_modules/@babel/helper-split-export-declaration": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz", + "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "../node_modules/@babel/helper-validator-identifier": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", + "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "../node_modules/@babel/helper-validator-option": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", + "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "../node_modules/@babel/helpers": { + "version": "7.14.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.14.6.tgz", + "integrity": "sha512-yesp1ENQBiLI+iYHSJdoZKUtRpfTlL1grDIX9NRlAVppljLw/4tTyYupIB7uIYmC3stW/imAv8EqaKaS/ibmeA==", + "dev": true, + "dependencies": { + "@babel/template": "^7.14.5", + "@babel/traverse": "^7.14.5", + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "../node_modules/@babel/highlight": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.14.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "../node_modules/@babel/parser": { + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.7.tgz", + "integrity": "sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "../node_modules/@babel/template": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", + "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.14.5", + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "../node_modules/@babel/traverse": { + "version": "7.14.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.7.tgz", + "integrity": "sha512-9vDr5NzHu27wgwejuKL7kIOm4bwEtaPQ4Z6cpCmjSuaRqpH/7xc4qcGEscwMqlkwgcXl6MvqoAjZkQ24uSdIZQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.14.5", + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-hoist-variables": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5", + "@babel/parser": "^7.14.7", + "@babel/types": "^7.14.5", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "../node_modules/@babel/traverse/node_modules/debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "../node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "../node_modules/@babel/traverse/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "../node_modules/@babel/types": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", + "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.14.5", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "../node_modules/@eslint/eslintrc": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.2.tgz", + "integrity": "sha512-8nmGq/4ycLpIwzvhI4tNDmQztZ8sp+hI7cyG8i1nQDhkAbRzHpXPidRAHlNvCZQpJTKw5ItIpMw9RSToGF00mg==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "../node_modules/@eslint/eslintrc/node_modules/debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "../node_modules/@eslint/eslintrc/node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "../node_modules/@eslint/eslintrc/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "../node_modules/@eslint/eslintrc/node_modules/strip-json-comments": { + "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==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../node_modules/@glimmer/env": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/@glimmer/env/-/env-0.1.7.tgz", + "integrity": "sha1-/S0rVakCnGs3psk16MiHGucN+gc=", + "dev": true + }, + "../node_modules/@glimmer/interfaces": { + "version": "0.56.2", + "resolved": "https://registry.npmjs.org/@glimmer/interfaces/-/interfaces-0.56.2.tgz", + "integrity": "sha512-nRgcsTuyZ90aEoCuYVHKGDs3LpAv9n/JKiJ6iecpEYtyGgcPqSI3GjrJRl6k+1s5wnldEH1kjWq+ccCiXmA99w==", + "dev": true, + "dependencies": { + "@simple-dom/interface": "^1.4.0" + } + }, + "../node_modules/@glimmer/syntax": { + "version": "0.56.1", + "resolved": "https://registry.npmjs.org/@glimmer/syntax/-/syntax-0.56.1.tgz", + "integrity": "sha512-4TdtIQVFo9UfIVzXnXpMuzsA4mX06oF9NER8FmIPjBosNiQsYB7P8sABSG+2rtWgsh6CkFXkwvxZ++BB+alwOw==", + "dev": true, + "dependencies": { + "@glimmer/interfaces": "^0.56.1", + "@glimmer/util": "^0.56.1", + "handlebars": "^4.7.4", + "simple-html-tokenizer": "^0.5.9" + } + }, + "../node_modules/@glimmer/util": { + "version": "0.56.2", + "resolved": "https://registry.npmjs.org/@glimmer/util/-/util-0.56.2.tgz", + "integrity": "sha512-AljXCX5HBjJkmNt4DNYmJmVvwqKjFF4lU6e0SBftwhzK85RbETYwpb3YWrghcjSCxoodwIu1zNFiKOA+xD6txw==", + "dev": true, + "dependencies": { + "@glimmer/env": "0.1.7", + "@glimmer/interfaces": "^0.56.2", + "@simple-dom/interface": "^1.4.0" + } + }, + "../node_modules/@humanwhocodes/config-array": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "../node_modules/@humanwhocodes/config-array/node_modules/debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "../node_modules/@humanwhocodes/config-array/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "../node_modules/@humanwhocodes/object-schema": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", + "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", + "dev": true + }, + "../node_modules/@iarna/toml": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-2.2.5.tgz", + "integrity": "sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==", + "dev": true + }, + "../node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "../node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/@istanbuljs/load-nyc-config/node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "../node_modules/@istanbuljs/load-nyc-config/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/@jest/types": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz", + "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "../node_modules/@jest/types/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "../node_modules/@jest/types/node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "../node_modules/@jest/types/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "../node_modules/@jest/types/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "../node_modules/@jest/types/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/@jest/types/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/@jsbits/deep-clone": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@jsbits/deep-clone/-/deep-clone-1.1.1.tgz", + "integrity": "sha512-aKhOhRv18tlhkjapBrcyAt8U1SmyzKi2QoO4GGMlXRfQhwm7USDSo/pX8MgB8tYB3MLaevuvwufynKSDA7U3EA==", + "dev": true, + "engines": { + "node": ">=4.2" + } + }, + "../node_modules/@microsoft/api-extractor": { + "version": "7.18.1", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.18.1.tgz", + "integrity": "sha512-qljUF2Q0zAx1vJrjKkJVGN7OVbsXki+Pji99jywyl6L/FK3YZ7PpstUJYE6uBcLPy6rhNPWPAsHNTMpG/kHIsg==", + "dev": true, + "dependencies": { + "@microsoft/api-extractor-model": "7.13.3", + "@microsoft/tsdoc": "0.13.2", + "@microsoft/tsdoc-config": "~0.15.2", + "@rushstack/node-core-library": "3.39.0", + "@rushstack/rig-package": "0.2.12", + "@rushstack/ts-command-line": "4.8.0", + "colors": "~1.2.1", + "lodash": "~4.17.15", + "resolve": "~1.17.0", + "semver": "~7.3.0", + "source-map": "~0.6.1", + "typescript": "~4.3.2" + }, + "bin": { + "api-extractor": "bin/api-extractor" + } + }, + "../node_modules/@microsoft/api-extractor-model": { + "version": "7.13.3", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.13.3.tgz", + "integrity": "sha512-uXilAhu2GcvyY/0NwVRk3AN7TFYjkPnjHLV2UywTTz9uglS+Af0YjNrCy+aaK8qXtfbFWdBzkH9N2XU8/YBeRQ==", + "dev": true, + "dependencies": { + "@microsoft/tsdoc": "0.13.2", + "@microsoft/tsdoc-config": "~0.15.2", + "@rushstack/node-core-library": "3.39.0" + } + }, + "../node_modules/@microsoft/api-extractor/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "../node_modules/@microsoft/tsdoc": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.13.2.tgz", + "integrity": "sha512-WrHvO8PDL8wd8T2+zBGKrMwVL5IyzR3ryWUsl0PXgEV0QHup4mTLi0QcATefGI6Gx9Anu7vthPyyyLpY0EpiQg==", + "dev": true + }, + "../node_modules/@microsoft/tsdoc-config": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.15.2.tgz", + "integrity": "sha512-mK19b2wJHSdNf8znXSMYVShAHktVr/ib0Ck2FA3lsVBSEhSI/TfXT7DJQkAYgcztTuwazGcg58ZjYdk0hTCVrA==", + "dev": true, + "dependencies": { + "@microsoft/tsdoc": "0.13.2", + "ajv": "~6.12.6", + "jju": "~1.4.0", + "resolve": "~1.19.0" + } + }, + "../node_modules/@microsoft/tsdoc-config/node_modules/resolve": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "dev": true, + "dependencies": { + "is-core-module": "^2.1.0", + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "../node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "../node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "../node_modules/@octokit/auth-token": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.4.5.tgz", + "integrity": "sha512-BpGYsPgJt05M7/L/5FoE1PiAbdxXFZkX/3kDYcsvd1v6UhlnE5e96dTDr0ezX/EFwciQxf3cNV0loipsURU+WA==", + "dependencies": { + "@octokit/types": "^6.0.3" + } + }, + "../node_modules/@octokit/core": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.5.1.tgz", + "integrity": "sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw==", + "dependencies": { + "@octokit/auth-token": "^2.4.4", + "@octokit/graphql": "^4.5.8", + "@octokit/request": "^5.6.0", + "@octokit/request-error": "^2.0.5", + "@octokit/types": "^6.0.3", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + } + }, + "../node_modules/@octokit/endpoint": { + "version": "6.0.12", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz", + "integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==", + "dependencies": { + "@octokit/types": "^6.0.3", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" + } + }, + "../node_modules/@octokit/graphql": { + "version": "4.6.4", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.6.4.tgz", + "integrity": "sha512-SWTdXsVheRmlotWNjKzPOb6Js6tjSqA2a8z9+glDJng0Aqjzti8MEWOtuT8ZSu6wHnci7LZNuarE87+WJBG4vg==", + "dependencies": { + "@octokit/request": "^5.6.0", + "@octokit/types": "^6.0.3", + "universal-user-agent": "^6.0.0" + } + }, + "../node_modules/@octokit/openapi-types": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-8.2.1.tgz", + "integrity": "sha512-BJz6kWuL3n+y+qM8Pv+UGbSxH6wxKf/SBs5yzGufMHwDefsa+Iq7ZGy1BINMD2z9SkXlIzk1qiu988rMuGXEMg==" + }, + "../node_modules/@octokit/plugin-paginate-rest": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.14.0.tgz", + "integrity": "sha512-S2uEu2uHeI7Vf+Lvj8tv3O5/5TCAa8GHS0dUQN7gdM7vKA6ZHAbR6HkAVm5yMb1mbedLEbxOuQ+Fa0SQ7tCDLA==", + "dependencies": { + "@octokit/types": "^6.18.0" + }, + "peerDependencies": { + "@octokit/core": ">=2" + } + }, + "../node_modules/@octokit/plugin-request-log": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz", + "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==", + "peerDependencies": { + "@octokit/core": ">=3" + } + }, + "../node_modules/@octokit/plugin-rest-endpoint-methods": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.4.1.tgz", + "integrity": "sha512-Nx0g7I5ayAYghsLJP4Q1Ch2W9jYYM0FlWWWZocUro8rNxVwuZXGfFd7Rcqi9XDWepSXjg1WByiNJnZza2hIOvQ==", + "dependencies": { + "@octokit/types": "^6.18.1", + "deprecation": "^2.3.1" + }, + "peerDependencies": { + "@octokit/core": ">=3" + } + }, + "../node_modules/@octokit/request": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.0.tgz", + "integrity": "sha512-4cPp/N+NqmaGQwbh3vUsYqokQIzt7VjsgTYVXiwpUP2pxd5YiZB2XuTedbb0SPtv9XS7nzAKjAuQxmY8/aZkiA==", + "dependencies": { + "@octokit/endpoint": "^6.0.1", + "@octokit/request-error": "^2.1.0", + "@octokit/types": "^6.16.1", + "is-plain-object": "^5.0.0", + "node-fetch": "^2.6.1", + "universal-user-agent": "^6.0.0" + } + }, + "../node_modules/@octokit/request-error": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz", + "integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==", + "dependencies": { + "@octokit/types": "^6.0.3", + "deprecation": "^2.0.0", + "once": "^1.4.0" + } + }, + "../node_modules/@octokit/rest": { + "version": "18.6.7", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.6.7.tgz", + "integrity": "sha512-Kn6WrI2ZvmAztdx+HEaf88RuJn+LK72S8g6OpciE4kbZddAN84fu4fiPGxcEu052WmqKVnA/cnQsbNlrYC6rqQ==", + "dependencies": { + "@octokit/core": "^3.5.0", + "@octokit/plugin-paginate-rest": "^2.6.2", + "@octokit/plugin-request-log": "^1.0.2", + "@octokit/plugin-rest-endpoint-methods": "5.4.1" + } + }, + "../node_modules/@octokit/types": { + "version": "6.18.1", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.18.1.tgz", + "integrity": "sha512-5YsddjO1U+xC8ZYKV8yZYebW55PCc7qiEEeZ+wZRr6qyclynzfyD65KZ5FdtIeP0/cANyFaD7hV69qElf1nMsQ==", + "dependencies": { + "@octokit/openapi-types": "^8.2.1" + } + }, + "../node_modules/@rushstack/node-core-library": { + "version": "3.39.0", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.39.0.tgz", + "integrity": "sha512-kgu3+7/zOBkZU0+NdJb1rcHcpk3/oTjn5c8cg5nUTn+JDjEw58yG83SoeJEcRNNdl11dGX0lKG2PxPsjCokZOQ==", + "dev": true, + "dependencies": { + "@types/node": "10.17.13", + "colors": "~1.2.1", + "fs-extra": "~7.0.1", + "import-lazy": "~4.0.0", + "jju": "~1.4.0", + "resolve": "~1.17.0", + "semver": "~7.3.0", + "timsort": "~0.3.0", + "z-schema": "~3.18.3" + } + }, + "../node_modules/@rushstack/node-core-library/node_modules/@types/node": { + "version": "10.17.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.13.tgz", + "integrity": "sha512-pMCcqU2zT4TjqYFrWtYHKal7Sl30Ims6ulZ4UFXxI4xbtQqK/qqKwkDoBFCfooRqqmRu9vY3xaJRwxSh673aYg==", + "dev": true + }, + "../node_modules/@rushstack/node-core-library/node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "../node_modules/@rushstack/node-core-library/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "../node_modules/@rushstack/rig-package": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.2.12.tgz", + "integrity": "sha512-nbePcvF8hQwv0ql9aeQxcaMPK/h1OLAC00W7fWCRWIvD2MchZOE8jumIIr66HGrfG2X1sw++m/ZYI4D+BM5ovQ==", + "dev": true, + "dependencies": { + "resolve": "~1.17.0", + "strip-json-comments": "~3.1.1" + } + }, + "../node_modules/@rushstack/rig-package/node_modules/strip-json-comments": { + "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==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../node_modules/@rushstack/ts-command-line": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.8.0.tgz", + "integrity": "sha512-nZ8cbzVF1VmFPfSJfy8vEohdiFAH/59Y/Y+B4nsJbn4SkifLJ8LqNZ5+LxCC2UR242EXFumxlsY1d6fPBxck5Q==", + "dev": true, + "dependencies": { + "@types/argparse": "1.0.38", + "argparse": "~1.0.9", + "colors": "~1.2.1", + "string-argv": "~0.3.1" + } + }, + "../node_modules/@simple-dom/interface": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@simple-dom/interface/-/interface-1.4.0.tgz", + "integrity": "sha512-l5qumKFWU0S+4ZzMaLXFU8tQZsicHEMEyAxI5kDFGhJsRqDwe0a7/iPA/GdxlGyDKseQQAgIz5kzU7eXTrlSpA==", + "dev": true + }, + "../node_modules/@sindresorhus/is": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-2.1.1.tgz", + "integrity": "sha512-/aPsuoj/1Dw/kzhkgz+ES6TxG0zfTMGLwuK2ZG00k/iJzYHTLCE8mVU8EPqEOp/lmxPoq1C1C9RYToRKb2KEfg==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "../node_modules/@sinonjs/commons": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", + "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "../node_modules/@sinonjs/fake-timers": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", + "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, + "../node_modules/@sinonjs/samsam": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-5.3.1.tgz", + "integrity": "sha512-1Hc0b1TtyfBu8ixF/tpfSHTVWKwCBLY4QJbkgnE7HcwyvT2xArDxb4K7dMgqRm3szI+LJbzmW/s4xxEhv6hwDg==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.6.0", + "lodash.get": "^4.4.2", + "type-detect": "^4.0.8" + } + }, + "../node_modules/@sinonjs/text-encoding": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", + "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", + "dev": true + }, + "../node_modules/@sosuisen/api-documenter": { + "version": "7.13.27", + "resolved": "https://registry.npmjs.org/@sosuisen/api-documenter/-/api-documenter-7.13.27.tgz", + "integrity": "sha512-Y3uEwBRSbxEvlLXRD/YcaRhsVNVWMDRLE/EOVDAUzPYy5FrdXiNK0GZNdmxrjCe2E58W/bGKUTZnw9sOI2YOZg==", + "dev": true, + "dependencies": { + "@microsoft/api-extractor-model": "^7.13.3", + "@microsoft/tsdoc": "^0.13.2", + "@rushstack/node-core-library": "^3.39.0", + "@rushstack/ts-command-line": "^4.7.10", + "colors": "~1.2.1", + "js-yaml": "~3.13.1", + "resolve": "~1.17.0" + }, + "bin": { + "api-documenter": "bin/api-documenter" + } + }, + "../node_modules/@sosuisen/jsondiffpatch": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/@sosuisen/jsondiffpatch/-/jsondiffpatch-0.4.7.tgz", + "integrity": "sha512-PBux/ylEnBMhB5WSee+Ql2YPrO5K7YEnfSm5aZufOEkmewkduakSWdmSrmreUGmJKQWLWqRGSpql3tl7YlppTQ==", + "dependencies": { + "chalk": "^2.3.0", + "diff-match-patch": "^1.0.0" + }, + "bin": { + "jsondiffpatch": "bin/jsondiffpatch" + }, + "engines": { + "node": ">=8.17.0" + } + }, + "../node_modules/@szmarczak/http-timer": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "dependencies": { + "defer-to-connect": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "../node_modules/@tsconfig/node10": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", + "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", + "dev": true + }, + "../node_modules/@tsconfig/node12": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", + "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", + "dev": true + }, + "../node_modules/@tsconfig/node14": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", + "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", + "dev": true + }, + "../node_modules/@tsconfig/node16": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", + "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", + "dev": true + }, + "../node_modules/@types/argparse": { + "version": "1.0.38", + "resolved": "https://registry.npmjs.org/@types/argparse/-/argparse-1.0.38.tgz", + "integrity": "sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==", + "dev": true + }, + "../node_modules/@types/async-lock": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@types/async-lock/-/async-lock-1.1.3.tgz", + "integrity": "sha512-UpeDcjGKsYEQMeqEbfESm8OWJI305I7b9KE4ji3aBjoKWyN5CTdn8izcA1FM1DVDne30R5fNEnIy89vZw5LXJQ==", + "dev": true + }, + "../node_modules/@types/cacheable-request": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", + "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", + "dependencies": { + "@types/http-cache-semantics": "*", + "@types/keyv": "*", + "@types/node": "*", + "@types/responselike": "*" + } + }, + "../node_modules/@types/fs-extra": { + "version": "9.0.12", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.12.tgz", + "integrity": "sha512-I+bsBr67CurCGnSenZZ7v94gd3tc3+Aj2taxMT4yu4ABLuOgOjeFxX3dokG24ztSRg5tnT00sL8BszO7gSMoIw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "../node_modules/@types/glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-w+LsMxKyYQm347Otw+IfBXOv9UWVjpHpCDdbBMt8Kz/xbvCYNjP+0qPh91Km3iKfSRLBB0P7fAMf0KHrPu+MyA==", + "dev": true, + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "../node_modules/@types/http-cache-semantics": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", + "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==" + }, + "../node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", + "dev": true + }, + "../node_modules/@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "../node_modules/@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "../node_modules/@types/json-schema": { + "version": "7.0.8", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.8.tgz", + "integrity": "sha512-YSBPTLTVm2e2OoQIDYx8HaeWJ5tTToLH67kXR7zYNGupXMEHa2++G8k+DczX2cFVgalypqtyZIcU19AFcmOpmg==", + "dev": true + }, + "../node_modules/@types/keyv": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.2.tgz", + "integrity": "sha512-/FvAK2p4jQOaJ6CGDHJTqZcUtbZe820qIeTg7o0Shg7drB4JHeL+V/dhSaly7NXx6u8eSee+r7coT+yuJEvDLg==", + "dependencies": { + "@types/node": "*" + } + }, + "../node_modules/@types/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "dev": true + }, + "../node_modules/@types/mocha": { + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.3.tgz", + "integrity": "sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw==", + "dev": true + }, + "../node_modules/@types/node": { + "version": "14.17.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.5.tgz", + "integrity": "sha512-bjqH2cX/O33jXT/UmReo2pM7DIJREPMnarixbQ57DOOzzFaI6D2+IcwaJQaJpv0M1E9TIhPCYVxrkcityLjlqA==" + }, + "../node_modules/@types/normalize-package-data": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", + "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", + "dev": true + }, + "../node_modules/@types/parse-git-config": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/parse-git-config/-/parse-git-config-3.0.1.tgz", + "integrity": "sha512-cBVLXlpIpP23p+jQm8d2TrTfxyub3aiqfqgd0TWRnMqwCJMskYiveNJT11YwN+gbo3+0ZFFmtaepKzN7pxExlA==", + "dev": true + }, + "../node_modules/@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", + "dev": true + }, + "../node_modules/@types/responselike": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", + "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", + "dependencies": { + "@types/node": "*" + } + }, + "../node_modules/@types/rimraf": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-3.0.1.tgz", + "integrity": "sha512-CAoSlbco40aKZ0CkelBF2g3JeN6aioRaTVnqSX5pWsn/WApm6IDxI4e4tD9D0dY/meCkyyleP1IQDVN13F4maA==", + "dev": true, + "dependencies": { + "@types/glob": "*", + "@types/node": "*" + } + }, + "../node_modules/@types/sinon": { + "version": "9.0.11", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-9.0.11.tgz", + "integrity": "sha512-PwP4UY33SeeVKodNE37ZlOsR9cReypbMJOhZ7BVE0lB+Hix3efCOxiJWiE5Ia+yL9Cn2Ch72EjFTRze8RZsNtg==", + "dev": true, + "dependencies": { + "@types/sinonjs__fake-timers": "*" + } + }, + "../node_modules/@types/sinonjs__fake-timers": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.3.tgz", + "integrity": "sha512-E1dU4fzC9wN2QK2Cr1MLCfyHM8BoNnRFvuf45LYMPNDA+WqbNzC45S4UzPxvp1fFJ1rvSGU0bPvdd35VLmXG8g==", + "dev": true + }, + "../node_modules/@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", + "dev": true + }, + "../node_modules/@types/unist": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.5.tgz", + "integrity": "sha512-wnra4Vw9dopnuybR6HBywJ/URYpYrKLoepBTEtgfJup8Ahoi2zJECPP2cwiXp7btTvOT2CULv87aQRA4eZSP6g==", + "dev": true + }, + "../node_modules/@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "../node_modules/@types/yargs-parser": { + "version": "20.2.1", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", + "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", + "dev": true + }, + "../node_modules/@typescript-eslint/eslint-plugin": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.28.2.tgz", + "integrity": "sha512-PGqpLLzHSxq956rzNGasO3GsAPf2lY9lDUBXhS++SKonglUmJypaUtcKzRtUte8CV7nruwnDxtLUKpVxs0wQBw==", + "dev": true, + "dependencies": { + "@typescript-eslint/experimental-utils": "4.28.2", + "@typescript-eslint/scope-manager": "4.28.2", + "debug": "^4.3.1", + "functional-red-black-tree": "^1.0.1", + "regexpp": "^3.1.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^4.0.0", + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "../node_modules/@typescript-eslint/eslint-plugin/node_modules/debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "../node_modules/@typescript-eslint/eslint-plugin/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "../node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "../node_modules/@typescript-eslint/experimental-utils": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.28.2.tgz", + "integrity": "sha512-MwHPsL6qo98RC55IoWWP8/opTykjTp4JzfPu1VfO2Z0MshNP0UZ1GEV5rYSSnZSUI8VD7iHvtIPVGW5Nfh7klQ==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.7", + "@typescript-eslint/scope-manager": "4.28.2", + "@typescript-eslint/types": "4.28.2", + "@typescript-eslint/typescript-estree": "4.28.2", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + } + }, + "../node_modules/@typescript-eslint/parser": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.28.2.tgz", + "integrity": "sha512-Q0gSCN51eikAgFGY+gnd5p9bhhCUAl0ERMiDKrTzpSoMYRubdB8MJrTTR/BBii8z+iFwz8oihxd0RAdP4l8w8w==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "4.28.2", + "@typescript-eslint/types": "4.28.2", + "@typescript-eslint/typescript-estree": "4.28.2", + "debug": "^4.3.1" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "../node_modules/@typescript-eslint/parser/node_modules/debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "../node_modules/@typescript-eslint/parser/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "../node_modules/@typescript-eslint/scope-manager": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.28.2.tgz", + "integrity": "sha512-MqbypNjIkJFEFuOwPWNDjq0nqXAKZvDNNs9yNseoGBB1wYfz1G0WHC2AVOy4XD7di3KCcW3+nhZyN6zruqmp2A==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.28.2", + "@typescript-eslint/visitor-keys": "4.28.2" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "../node_modules/@typescript-eslint/types": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.28.2.tgz", + "integrity": "sha512-Gr15fuQVd93uD9zzxbApz3wf7ua3yk4ZujABZlZhaxxKY8ojo448u7XTm/+ETpy0V0dlMtj6t4VdDvdc0JmUhA==", + "dev": true, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "../node_modules/@typescript-eslint/typescript-estree": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.2.tgz", + "integrity": "sha512-86lLstLvK6QjNZjMoYUBMMsULFw0hPHJlk1fzhAVoNjDBuPVxiwvGuPQq3fsBMCxuDJwmX87tM/AXoadhHRljg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.28.2", + "@typescript-eslint/visitor-keys": "4.28.2", + "debug": "^4.3.1", + "globby": "^11.0.3", + "is-glob": "^4.0.1", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "../node_modules/@typescript-eslint/typescript-estree/node_modules/debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "../node_modules/@typescript-eslint/typescript-estree/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "../node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "../node_modules/@typescript-eslint/visitor-keys": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.2.tgz", + "integrity": "sha512-aT2B4PLyyRDUVUafXzpZFoc0C9t0za4BJAKP5sgWIhG+jHECQZUEjuQSCIwZdiJJ4w4cgu5r3Kh20SOdtEBl0w==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.28.2", + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "../node_modules/@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, + "../node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "../node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "../node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "../node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "../node_modules/angular-estree-parser": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/angular-estree-parser/-/angular-estree-parser-1.3.1.tgz", + "integrity": "sha512-jvlnNk4aoEmA6EKK12OnsOkCSdsWleBsYB+aWyH8kpfTB6Li1kxWVbHKVldH9zDCwVVi1hXfqPi/gbSv49tkbQ==", + "dev": true, + "dependencies": { + "lines-and-columns": "^1.1.6", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "@angular/compiler": ">= 6.0.0 < 9.0.6" + } + }, + "../node_modules/angular-html-parser": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/angular-html-parser/-/angular-html-parser-1.7.0.tgz", + "integrity": "sha512-/yjeqDQXGblZuFMI6vpDgiIDuv816QpIqa/mCotc0I4R0F5t5sfX1ntZ8VsBVQOUYRjPw8ggYlPZto76gHtf7Q==", + "dev": true, + "dependencies": { + "tslib": "^1.9.3" + }, + "engines": { + "node": ">= 6" + } + }, + "../node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "../node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "engines": { + "node": ">=0.10.0" + } + }, + "../node_modules/ansi-styles": { + "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==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "../node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "../node_modules/append-transform": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", + "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", + "dev": true, + "dependencies": { + "default-require-extensions": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + }, + "../node_modules/archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", + "dev": true + }, + "../node_modules/are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "../node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "../node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "../node_modules/array-includes": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", + "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2", + "get-intrinsic": "^1.1.1", + "is-string": "^1.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/array.prototype.flat": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz", + "integrity": "sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../node_modules/array.prototype.flatmap": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.4.tgz", + "integrity": "sha512-r9Z0zYoxqHz60vvQbWEdXIEtCwHF0yxaWfno9qzXeNHvfyl3BZqygmGzb84dsubyaXLH4husF+NFgMSdpZhk2Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1", + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../node_modules/asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "../node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "engines": { + "node": ">=0.8" + } + }, + "../node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/async-lock": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/async-lock/-/async-lock-1.3.0.tgz", + "integrity": "sha512-8A7SkiisnEgME2zEedtDYPxUPzdv3x//E7n5IFktPAtMYSEAV7eNJF0rMwrVyUFj6d/8rgajLantbjcNRQYXIg==" + }, + "../node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "../node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "../node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "engines": { + "node": "*" + } + }, + "../node_modules/aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" + }, + "../node_modules/bail": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", + "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "../node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "../node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "../node_modules/before-after-hook": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz", + "integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ==" + }, + "../node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/bl": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", + "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==", + "dependencies": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + } + }, + "../node_modules/blob-polyfill": { + "version": "5.0.20210201", + "resolved": "https://registry.npmjs.org/blob-polyfill/-/blob-polyfill-5.0.20210201.tgz", + "integrity": "sha512-SrH6IG6aXL9pCgSysBCiDpGcAJ1j6/c1qCwR3sTEQJhb+MTk6FITNA6eW6WNYQDNZVi4Z9GjxH5v2MMTv59CrQ==" + }, + "../node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "../node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "../node_modules/browserslist": { + "version": "4.16.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", + "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", + "dev": true, + "dependencies": { + "caniuse-lite": "^1.0.30001219", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.723", + "escalade": "^3.1.1", + "node-releases": "^1.1.71" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, + "../node_modules/buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "dependencies": { + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" + } + }, + "../node_modules/buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" + }, + "../node_modules/buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=" + }, + "../node_modules/buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, + "../node_modules/cacheable-lookup": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-2.0.1.tgz", + "integrity": "sha512-EMMbsiOTcdngM/K6gV/OxF2x0t07+vMOWxZNSCRQMjO2MY2nhZQ6OYhOOpyQrbhqsgtvKGI7hcq6xjnA92USjg==", + "dependencies": { + "@types/keyv": "^3.1.1", + "keyv": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "../node_modules/cacheable-request": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", + "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/caching-transform": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", + "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", + "dev": true, + "dependencies": { + "hasha": "^5.0.0", + "make-dir": "^3.0.0", + "package-hash": "^4.0.0", + "write-file-atomic": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "../node_modules/camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../node_modules/caniuse-lite": { + "version": "1.0.30001243", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001243.tgz", + "integrity": "sha512-vNxw9mkTBtkmLFnJRv/2rhs1yufpDfCkBZexG3Y0xdOH2Z/eE/85E4Dl5j1YUN34nZVsSp6vVRFQRrez9wJMRA==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, + "../node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "../node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "../node_modules/character-entities": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", + "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "../node_modules/character-entities-legacy": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", + "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "../node_modules/character-reference-invalid": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", + "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "../node_modules/chokidar": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", + "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.1" + } + }, + "../node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, + "../node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "../node_modules/cjk-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/cjk-regex/-/cjk-regex-2.0.0.tgz", + "integrity": "sha512-E4gFi2f3jC0zFVHpaAcupW+gv9OejZ2aV3DP/LlSO0dDcZJAXw7W0ivn+vN17edN/PhU4HCgs1bfx7lPK7FpdA==", + "dev": true, + "dependencies": { + "regexp-util": "^1.2.1", + "unicode-regex": "^2.0.0" + }, + "engines": { + "node": ">= 4" + } + }, + "../node_modules/cjk-regex/node_modules/unicode-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-regex/-/unicode-regex-2.0.0.tgz", + "integrity": "sha512-5nbEG2YU7loyTvPABaKb+8B0u8L7vWCsVmCSsiaO249ZdMKlvrXlxR2ex4TUVAdzv/Cne/TdoXSSaJArGXaleQ==", + "dev": true, + "dependencies": { + "regexp-util": "^1.2.0" + }, + "engines": { + "node": ">= 4" + } + }, + "../node_modules/clean-git-ref": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/clean-git-ref/-/clean-git-ref-2.0.1.tgz", + "integrity": "sha512-bLSptAy2P0s6hU4PzuIMKmMJJSE6gLXGH1cntDu7bWJUksvuM+7ReOK61mozULErYvP6a15rnYl0zFDef+pyPw==" + }, + "../node_modules/clean-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", + "integrity": "sha1-jffHquUf02h06PjQW5GAvBGj/tc=", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "../node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "../node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "../node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/cliui/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/cliui/node_modules/string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dependencies": { + "mimic-response": "^1.0.0" + } + }, + "../node_modules/clone-response/node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "engines": { + "node": ">=4" + } + }, + "../node_modules/code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "engines": { + "node": ">=0.10.0" + } + }, + "../node_modules/collapse-white-space": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz", + "integrity": "sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "../node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "../node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "../node_modules/colorette": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", + "dev": true + }, + "../node_modules/colors": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz", + "integrity": "sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "../node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "../node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "../node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "../node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "../node_modules/confusing-browser-globals": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.10.tgz", + "integrity": "sha512-gNld/3lySHwuhaVluJUKLePYirM3QNCKzVxqAdhJII9/WXKVX5PURzMVJspS1jTslSqjeuG4KMVTSouit5YPHA==", + "dev": true + }, + "../node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + }, + "../node_modules/contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "../node_modules/convert-source-map": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.1" + } + }, + "../node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "../node_modules/cosmiconfig": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz", + "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==", + "dev": true, + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "../node_modules/cosmiconfig/node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../node_modules/coveralls": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.1.1.tgz", + "integrity": "sha512-+dxnG2NHncSD1NrqbSM3dn/lE57O6Qf/koe9+I7c+wzkqRmEvcp0kgJdxKInzYzkICKkFMZsX3Vct3++tsF9ww==", + "dev": true, + "dependencies": { + "js-yaml": "^3.13.1", + "lcov-parse": "^1.0.0", + "log-driver": "^1.2.7", + "minimist": "^1.2.5", + "request": "^2.88.2" + }, + "bin": { + "coveralls": "bin/coveralls.js" + }, + "engines": { + "node": ">=6" + } + }, + "../node_modules/crc-32": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.0.tgz", + "integrity": "sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA==", + "dependencies": { + "exit-on-epipe": "~1.0.1", + "printj": "~1.1.0" + }, + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "../node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "../node_modules/crlf": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/crlf/-/crlf-1.1.1.tgz", + "integrity": "sha1-JBcoQbTINSmmqkSJ337tlYsu0W8=", + "dev": true, + "dependencies": { + "glub": "^1.0.0", + "transform-file": "^1.0.1" + }, + "bin": { + "crlf": "bin/crlf" + } + }, + "../node_modules/cross-blob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/cross-blob/-/cross-blob-2.0.1.tgz", + "integrity": "sha512-ARuKPPo3I6DSqizal4UCyMCiGPQdMpMJS3Owx6Lleuh26vSt2UnfWRwbMLCYqbJUrcol+KzGVSLR91ezSHP80A==", + "dependencies": { + "blob-polyfill": "^5.0.20210201", + "fetch-blob": "^2.1.2" + }, + "engines": { + "node": "^10.17.0 || >=12.3.0" + } + }, + "../node_modules/cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "bin": { + "cross-env": "src/bin/cross-env.js", + "cross-env-shell": "src/bin/cross-env-shell.js" + }, + "engines": { + "node": ">=10.14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "../node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "../node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "../node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "../node_modules/dashify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dashify/-/dashify-2.0.0.tgz", + "integrity": "sha512-hpA5C/YrPjucXypHPPc0oJ1l9Hf6wWbiOL7Ik42cxnsUOhWiCB/fylKbKqqJalW9FgkNQCw16YO8uW9Hs0Iy1A==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "../node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "../node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../node_modules/decompress-response": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-5.0.0.tgz", + "integrity": "sha512-TLZWWybuxWgoW7Lykv+gq9xvzOsUjQ9tF09Tj6NSTYGMTCHNXzrPnD6Hi+TgZq19PyTAGH4Ll/NIM/eTGglnMw==", + "dependencies": { + "mimic-response": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "../node_modules/dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", + "dev": true + }, + "../node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "engines": { + "node": ">=4.0.0" + } + }, + "../node_modules/deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "../node_modules/deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "../node_modules/default-require-extensions": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz", + "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==", + "dev": true, + "dependencies": { + "strip-bom": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/default-require-extensions/node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "engines": { + "node": ">=10" + } + }, + "../node_modules/define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "dependencies": { + "object-keys": "^1.0.12" + }, + "engines": { + "node": ">= 0.4" + } + }, + "../node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "engines": { + "node": ">=0.4.0" + } + }, + "../node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + }, + "../node_modules/deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==" + }, + "../node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "../node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "../node_modules/diff-match-patch": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.5.tgz", + "integrity": "sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==" + }, + "../node_modules/diff-sequences": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz", + "integrity": "sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "../node_modules/diff3": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/diff3/-/diff3-0.0.3.tgz", + "integrity": "sha1-1OXDpM305f4SEatC5pP8tDIVgPw=" + }, + "../node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "../node_modules/duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" + }, + "../node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "../node_modules/editorconfig": { + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", + "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", + "dev": true, + "dependencies": { + "commander": "^2.19.0", + "lru-cache": "^4.1.5", + "semver": "^5.6.0", + "sigmund": "^1.0.1" + }, + "bin": { + "editorconfig": "bin/editorconfig" + } + }, + "../node_modules/editorconfig-to-prettier": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/editorconfig-to-prettier/-/editorconfig-to-prettier-0.1.1.tgz", + "integrity": "sha512-MMadSSVRDb4uKdxV6bCXXN4cTsxIsXYtV4XdPu6FOCSAw6zsCIDA+QEktEU+u6h+c/mTrul5NR+pwFpPxwetiQ==", + "dev": true + }, + "../node_modules/editorconfig/node_modules/lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "../node_modules/editorconfig/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "../node_modules/editorconfig/node_modules/yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "../node_modules/electron-to-chromium": { + "version": "1.3.772", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.772.tgz", + "integrity": "sha512-X/6VRCXWALzdX+RjCtBU6cyg8WZgoxm9YA02COmDOiNJEZ59WkQggDbWZ4t/giHi/3GS+cvdrP6gbLISANAGYA==", + "dev": true + }, + "../node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "../node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dependencies": { + "once": "^1.4.0" + } + }, + "../node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "../node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "../node_modules/es-abstract": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz", + "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "is-callable": "^1.2.3", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.3", + "is-string": "^1.0.6", + "object-inspect": "^1.10.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../node_modules/es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true + }, + "../node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "../node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "engines": { + "node": ">=0.8.0" + } + }, + "../node_modules/eslint": { + "version": "7.30.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.30.0.tgz", + "integrity": "sha512-VLqz80i3as3NdloY44BQSJpFw534L9Oh+6zJOUaViV4JPd+DaHwutqP7tcpkW3YiXbK6s05RZl7yl7cQn+lijg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.2", + "@humanwhocodes/config-array": "^0.5.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "../node_modules/eslint-ast-utils": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/eslint-ast-utils/-/eslint-ast-utils-1.1.0.tgz", + "integrity": "sha512-otzzTim2/1+lVrlH19EfQQJEhVJSu0zOb9ygb3iapN6UlyaDtyRq4b5U1FuW0v1lRa9Fp/GJyHkSwm6NqABgCA==", + "dev": true, + "dependencies": { + "lodash.get": "^4.4.2", + "lodash.zip": "^4.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "../node_modules/eslint-config-prettier": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.11.0.tgz", + "integrity": "sha512-oB8cpLWSAjOVFEJhhyMZh6NOEOtBVziaqdDQ86+qhDHFbZXoRTM7pNSvFRfW/W/L/LrQ38C99J5CGuRBBzBsdA==", + "dev": true, + "dependencies": { + "get-stdin": "^6.0.0" + }, + "bin": { + "eslint-config-prettier-check": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=3.14.1" + } + }, + "../node_modules/eslint-config-standard": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-16.0.3.tgz", + "integrity": "sha512-x4fmJL5hGqNJKGHSjnLdgA6U6h1YW/G2dW9fA+cyVur4SK6lyue8+UgNKWlZtUDTXvgKDD/Oa3GQjmB5kjtVvg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "peerDependencies": { + "eslint": "^7.12.1", + "eslint-plugin-import": "^2.22.1", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "^4.2.1 || ^5.0.0" + } + }, + "../node_modules/eslint-config-standardize": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/eslint-config-standardize/-/eslint-config-standardize-0.7.2.tgz", + "integrity": "sha512-n2dt7la221Qig7FjQsrKn5NyK5jSEkkAy7xWSnY96XdG7H9FcUSDt5I1THyA6zHwEYcAtUFv8VOPBOK6oYEvfg==", + "dev": true, + "dependencies": { + "@jsbits/deep-clone": "~1.1.1", + "confusing-browser-globals": "*", + "deepmerge": "~4.2.2", + "eslint-config-standard": "~16.0.2", + "eslint-plugin-import": "~2.22.1", + "eslint-plugin-node": "~11.1.0", + "eslint-plugin-promise": "~4.2.1", + "eslint-plugin-react": "~7.22.0", + "eslint-plugin-react-hooks": "~4.2.0", + "eslint-plugin-unicorn": "~26.0.1" + }, + "bin": { + "list-eslint-config": "bin/list-eslint-config.js" + }, + "engines": { + "node": "^10.13.0 || >=12.0.0" + }, + "optionalDependencies": { + "@typescript-eslint/eslint-plugin": "^4.14.0", + "@typescript-eslint/parser": "^4.14.0" + }, + "peerDependencies": { + "eslint": ">=7.17.0" + } + }, + "../node_modules/eslint-import-resolver-node": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz", + "integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==", + "dev": true, + "dependencies": { + "debug": "^2.6.9", + "resolve": "^1.13.1" + } + }, + "../node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "../node_modules/eslint-import-resolver-node/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "../node_modules/eslint-module-utils": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.1.tgz", + "integrity": "sha512-ZXI9B8cxAJIH4nfkhTwcRTEAnrVfobYqwjWy/QMCZ8rHkZHFjf9yO4BzpiF9kCSfNlMG54eKigISHpX0+AaT4A==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "pkg-dir": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "../node_modules/eslint-plugin-es": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", + "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "dev": true, + "dependencies": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + }, + "engines": { + "node": ">=8.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=4.19.1" + } + }, + "../node_modules/eslint-plugin-es/node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "../node_modules/eslint-plugin-es/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "../node_modules/eslint-plugin-import": { + "version": "2.22.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz", + "integrity": "sha512-8K7JjINHOpH64ozkAhpT3sd+FswIZTfMZTjdx052pnWrgRCVfp8op9tbjpAk3DdUeI/Ba4C8OjdC0r90erHEOw==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.1", + "array.prototype.flat": "^1.2.3", + "contains-path": "^0.1.0", + "debug": "^2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.4", + "eslint-module-utils": "^2.6.0", + "has": "^1.0.3", + "minimatch": "^3.0.4", + "object.values": "^1.1.1", + "read-pkg-up": "^2.0.0", + "resolve": "^1.17.0", + "tsconfig-paths": "^3.9.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0" + } + }, + "../node_modules/eslint-plugin-import/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "../node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "dependencies": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "../node_modules/eslint-plugin-import/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "../node_modules/eslint-plugin-node": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", + "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", + "dev": true, + "dependencies": { + "eslint-plugin-es": "^3.0.0", + "eslint-utils": "^2.0.0", + "ignore": "^5.1.1", + "minimatch": "^3.0.4", + "resolve": "^1.10.1", + "semver": "^6.1.0" + }, + "engines": { + "node": ">=8.10.0" + }, + "peerDependencies": { + "eslint": ">=5.16.0" + } + }, + "../node_modules/eslint-plugin-node/node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "../node_modules/eslint-plugin-node/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "../node_modules/eslint-plugin-node/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "../node_modules/eslint-plugin-prettierx": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettierx/-/eslint-plugin-prettierx-0.14.0.tgz", + "integrity": "sha512-Ak/sI2LO0B73qEFjepPNUplxLadqpT3BU/I16ExZ0mY1CjpjoJxiyKe7Nbb0VEH4XO4SbjhngGPSsod+S3/HPA==", + "dev": true, + "dependencies": { + "eslint-config-prettier": "~6.11.0", + "prettier-linter-helpers": "~1.0.0", + "prettierx": "~0.14.0" + }, + "bin": { + "list-eslint-config": "bin/list-eslint-config.js" + }, + "engines": { + "node": "^10.13.0 || >=12.0.0" + }, + "peerDependencies": { + "eslint": ">=7.2.0", + "typescript": ">=3.8.0" + } + }, + "../node_modules/eslint-plugin-promise": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz", + "integrity": "sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "../node_modules/eslint-plugin-react": { + "version": "7.22.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.22.0.tgz", + "integrity": "sha512-p30tuX3VS+NWv9nQot9xIGAHBXR0+xJVaZriEsHoJrASGCJZDJ8JLNM0YqKqI0AKm6Uxaa1VUHoNEibxRCMQHA==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.1", + "array.prototype.flatmap": "^1.2.3", + "doctrine": "^2.1.0", + "has": "^1.0.3", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "object.entries": "^1.1.2", + "object.fromentries": "^2.0.2", + "object.values": "^1.1.1", + "prop-types": "^15.7.2", + "resolve": "^1.18.1", + "string.prototype.matchall": "^4.0.2" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7" + } + }, + "../node_modules/eslint-plugin-react-hooks": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.2.0.tgz", + "integrity": "sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, + "../node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "../node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dev": true, + "dependencies": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../node_modules/eslint-plugin-unicorn": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-26.0.1.tgz", + "integrity": "sha512-SWgF9sIVY74zqkkSN2dclSCqRfocWSUGD0haC0NX2oRfmdp9p8dQvJYkYSQePaCyssPUE/pqpsIEEZNTh8crUA==", + "dev": true, + "dependencies": { + "ci-info": "^2.0.0", + "clean-regexp": "^1.0.0", + "eslint-ast-utils": "^1.1.0", + "eslint-template-visitor": "^2.2.2", + "eslint-utils": "^2.1.0", + "import-modules": "^2.1.0", + "lodash": "^4.17.20", + "pluralize": "^8.0.0", + "read-pkg-up": "^7.0.1", + "regexp-tree": "^0.1.21", + "reserved-words": "^0.1.2", + "safe-regex": "^2.1.1", + "semver": "^7.3.4" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1" + }, + "peerDependencies": { + "eslint": ">=7.17.0" + } + }, + "../node_modules/eslint-plugin-unicorn/node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "../node_modules/eslint-plugin-unicorn/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "../node_modules/eslint-plugin-unicorn/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/eslint-plugin-unicorn/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/eslint-plugin-unicorn/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../node_modules/eslint-plugin-unicorn/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/eslint-plugin-unicorn/node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "../node_modules/eslint-plugin-unicorn/node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../node_modules/eslint-plugin-unicorn/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/eslint-plugin-unicorn/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/eslint-plugin-unicorn/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../node_modules/eslint-plugin-unicorn/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/eslint-plugin-unicorn/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "../node_modules/eslint-plugin-unicorn/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "../node_modules/eslint-template-visitor": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/eslint-template-visitor/-/eslint-template-visitor-2.3.2.tgz", + "integrity": "sha512-3ydhqFpuV7x1M9EK52BPNj6V0Kwu0KKkcIAfpUhwHbR8ocRln/oUHgfxQupY8O1h4Qv/POHDumb/BwwNfxbtnA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.16", + "@babel/eslint-parser": "^7.12.16", + "eslint-visitor-keys": "^2.0.0", + "esquery": "^1.3.1", + "multimap": "^1.1.0" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "../node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "../node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "../node_modules/eslint/node_modules/@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.10.4" + } + }, + "../node_modules/eslint/node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/eslint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "../node_modules/eslint/node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "../node_modules/eslint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "../node_modules/eslint/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "../node_modules/eslint/node_modules/debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "../node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../node_modules/eslint/node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "../node_modules/eslint/node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "../node_modules/eslint/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/eslint/node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "../node_modules/eslint/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "../node_modules/eslint/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "../node_modules/eslint/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/eslint/node_modules/strip-json-comments": { + "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==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../node_modules/eslint/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "dev": true, + "dependencies": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "../node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "../node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "../node_modules/esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "../node_modules/esquery/node_modules/estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "../node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "../node_modules/esrecurse/node_modules/estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "../node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "../node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "../node_modules/exit-on-epipe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz", + "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==", + "engines": { + "node": ">=0.8" + } + }, + "../node_modules/expect": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.0.6.tgz", + "integrity": "sha512-psNLt8j2kwg42jGBDSfAlU49CEZxejN1f1PlANWDZqIhBOVU/c2Pm888FcjWJzFewhIsNWfZJeLjUjtKGiPuSw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.0.6", + "ansi-styles": "^5.0.0", + "jest-get-type": "^27.0.6", + "jest-matcher-utils": "^27.0.6", + "jest-message-util": "^27.0.6", + "jest-regex-util": "^27.0.6" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "../node_modules/expect/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "../node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "../node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "engines": [ + "node >=0.6.0" + ] + }, + "../node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "../node_modules/fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, + "../node_modules/fast-glob": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", + "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "../node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "../node_modules/fastq": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.1.tgz", + "integrity": "sha512-HOnr8Mc60eNYl1gzwp6r5RoUyAn5/glBolUzP/Ez6IFVPMPirxn/9phgL6zhOtaTy7ISwPvQ+wT+hfcRZh/bzw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "../node_modules/fetch-blob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-2.1.2.tgz", + "integrity": "sha512-YKqtUDwqLyfyMnmbw8XD6Q8j9i/HggKtPEI+pZ1+8bvheBu78biSmNaXWusx1TauGqtUUGx/cBb1mKdq2rLYow==", + "engines": { + "node": "^10.17.0 || >=12.3.0" + }, + "peerDependenciesMeta": { + "domexception": { + "optional": true + } + } + }, + "../node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "../node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/find-cache-dir": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", + "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", + "dev": true, + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "../node_modules/find-cache-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/find-cache-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/find-cache-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../node_modules/find-cache-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/find-cache-dir/node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "../node_modules/find-cache-dir/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/find-cache-dir/node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/find-parent-dir": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/find-parent-dir/-/find-parent-dir-0.3.0.tgz", + "integrity": "sha1-M8RLQpqysvBkYpnF+fcY83b/jVQ=", + "dev": true + }, + "../node_modules/find-project-root": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/find-project-root/-/find-project-root-1.1.1.tgz", + "integrity": "sha1-0kJyei2QRyXfVxTyPf3N7doLbvg=", + "dev": true, + "bin": { + "find-project-root": "bin/find-project-root.js" + } + }, + "../node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "../node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, + "../node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "../node_modules/flatted": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.1.tgz", + "integrity": "sha512-OMQjaErSFHmHqZe+PSidH5n8j3O0F2DdnVh8JB4j4eUQ2k6KvB0qGfrKIhapvez5JerBbmWkaLYUYWISaESoXg==", + "dev": true + }, + "../node_modules/flatten": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.3.tgz", + "integrity": "sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg==", + "deprecated": "flatten is deprecated in favor of utility frameworks such as lodash.", + "dev": true + }, + "../node_modules/foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "../node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "engines": { + "node": "*" + } + }, + "../node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "../node_modules/fromentries": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", + "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "../node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, + "../node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "../node_modules/fs-extra/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "../node_modules/fs-extra/node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "engines": { + "node": ">= 10.0.0" + } + }, + "../node_modules/fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "dependencies": { + "minipass": "^2.6.0" + } + }, + "../node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "../node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "../node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "../node_modules/gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "dependencies": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "../node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "../node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "../node_modules/get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "../node_modules/get-stdin": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", + "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "../node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "../node_modules/git-config-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/git-config-path/-/git-config-path-2.0.0.tgz", + "integrity": "sha512-qc8h1KIQbJpp+241id3GuAtkdyJ+IK+LIVtkiFTRKRrmddDzs3SI9CvP1QYmWBFvm1I/PWRwj//of8bgAc0ltA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "../node_modules/git-documentdb-plugin-remote-nodegit": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.3.tgz", + "integrity": "sha512-80cxPE+jIjDpECCXAmNtjZxMFVNc38yFkZmEd3hRp6EvSQhX6nky0kmEFWZ1aeFnTq0oATEJvEJg9yO8zYkyng==", + "dependencies": { + "git-documentdb-remote-errors": "^1.0.3", + "nodegit": "^0.27.0", + "tslog": "^3.2.0" + } + }, + "../node_modules/git-documentdb-remote-errors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/git-documentdb-remote-errors/-/git-documentdb-remote-errors-1.0.3.tgz", + "integrity": "sha512-14fN8VAQeBC7+Phs6TYB1D5PJDE/dF8dxbigKpsBEqR1FvpAQerSPptxVsQgkU33xwwZBOm7yCwVD2KKmQatOQ==" + }, + "../node_modules/glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "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" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "../node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "../node_modules/globals": { + "version": "13.10.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.10.0.tgz", + "integrity": "sha512-piHC3blgLGFjvOuMmWZX60f+na1lXFDhQXBf1UYp2fXPXqvEUbOhNwi6BsQ0bQishwedgnjkwv1d9zKf+MWw3g==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../node_modules/globals/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../node_modules/globby": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", + "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../node_modules/glub": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/glub/-/glub-1.0.3.tgz", + "integrity": "sha1-VsFkMpiuJQZcYxUAMze7pp0vuGY=", + "dev": true, + "dependencies": { + "glob": "^5.0.5", + "minimist": "^1.1.1" + }, + "bin": { + "glub": "bin/glub" + } + }, + "../node_modules/glub/node_modules/glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dev": true, + "dependencies": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "../node_modules/got": { + "version": "10.7.0", + "resolved": "https://registry.npmjs.org/got/-/got-10.7.0.tgz", + "integrity": "sha512-aWTDeNw9g+XqEZNcTjMMZSy7B7yE9toWOFYip7ofFTLleJhvZwUxxTxkTpKvF+p1SAA4VHmuEy7PiHTHyq8tJg==", + "dependencies": { + "@sindresorhus/is": "^2.0.0", + "@szmarczak/http-timer": "^4.0.0", + "@types/cacheable-request": "^6.0.1", + "cacheable-lookup": "^2.0.0", + "cacheable-request": "^7.0.1", + "decompress-response": "^5.0.0", + "duplexer3": "^0.1.4", + "get-stream": "^5.0.0", + "lowercase-keys": "^2.0.0", + "mimic-response": "^2.1.0", + "p-cancelable": "^2.0.0", + "p-event": "^4.0.0", + "responselike": "^2.0.0", + "to-readable-stream": "^2.0.0", + "type-fest": "^0.10.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "../node_modules/graceful-fs": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" + }, + "../node_modules/graphql": { + "version": "15.3.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.3.0.tgz", + "integrity": "sha512-GTCJtzJmkFLWRfFJuoo9RWWa/FfamUHgiFosxi/X1Ani4AVWbeyBenZTNX6dM+7WSbbFfTo/25eh0LLkwHMw2w==", + "dev": true, + "engines": { + "node": ">= 10.x" + } + }, + "../node_modules/growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true, + "engines": { + "node": ">=4.x" + } + }, + "../node_modules/handlebars": { + "version": "4.7.7", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", + "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "../node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "engines": { + "node": ">=4" + } + }, + "../node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "../node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "../node_modules/has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "engines": { + "node": ">=4" + } + }, + "../node_modules/has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + }, + "../node_modules/hasha": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", + "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", + "dev": true, + "dependencies": { + "is-stream": "^2.0.0", + "type-fest": "^0.8.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../node_modules/hasha/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" + } + }, + "../node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "../node_modules/html-element-attributes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/html-element-attributes/-/html-element-attributes-2.2.1.tgz", + "integrity": "sha512-gGTgCeQu+g1OFExZKWQ1LwbFXxLJ6cGdCGj64ByEaxatr/EPVc23D6Gxngb37ao+SNInP/sGu8FXxRsSxMm7aQ==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "../node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "../node_modules/html-styles": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/html-styles/-/html-styles-1.0.0.tgz", + "integrity": "sha1-oYBh/WUfmca3XEXI4FSaO8PgGnU=", + "dev": true + }, + "../node_modules/html-tag-names": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/html-tag-names/-/html-tag-names-1.1.5.tgz", + "integrity": "sha512-aI5tKwNTBzOZApHIynaAwecLBv8TlZTEy/P4Sj2SzzAhBrGuI8yGZ0UIXVPQzOHGS+to2mjb04iy6VWt/8+d8A==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "../node_modules/http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" + }, + "../node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "../node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "../node_modules/ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "engines": { + "node": ">= 4" + } + }, + "../node_modules/ignore-walk": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.4.tgz", + "integrity": "sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ==", + "dependencies": { + "minimatch": "^3.0.4" + } + }, + "../node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../node_modules/import-lazy": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", + "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/import-modules": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-modules/-/import-modules-2.1.0.tgz", + "integrity": "sha512-8HEWcnkbGpovH9yInoisxaSoIg9Brbul+Ju3Kqe2UsYDUBJD/iQjSgEj0zPcTDPKfPp2fs5xlv1i+JSye/m1/A==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "../node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/indexes-of": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", + "dev": true + }, + "../node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "../node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "../node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "../node_modules/internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "../node_modules/is-alphabetical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", + "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "../node_modules/is-alphanumerical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", + "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", + "dev": true, + "dependencies": { + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "../node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "../node_modules/is-bigint": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz", + "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/is-boolean-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz", + "integrity": "sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../node_modules/is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "engines": { + "node": ">=4" + } + }, + "../node_modules/is-callable": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../node_modules/is-core-module": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", + "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../node_modules/is-date-object": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz", + "integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../node_modules/is-decimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", + "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "../node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "../node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "../node_modules/is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "../node_modules/is-hexadecimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", + "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "../node_modules/is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "../node_modules/is-number-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz", + "integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "../node_modules/is-regex": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", + "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../node_modules/is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/is-string": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz", + "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "../node_modules/is-whitespace-character": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz", + "integrity": "sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "../node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "../node_modules/is-word-character": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.4.tgz", + "integrity": "sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "../node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "../node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "../node_modules/isomorphic-git": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/isomorphic-git/-/isomorphic-git-1.9.1.tgz", + "integrity": "sha512-vzceJaiBdaJI5aT1di4dxWWf6sao3WQFQJ6UTi1tXO4zyDfsuyIadVOA4YQzdwKhLilV9msgM8HIvpOE94kmQg==", + "dependencies": { + "async-lock": "^1.1.0", + "clean-git-ref": "^2.0.1", + "crc-32": "^1.2.0", + "diff3": "0.0.3", + "ignore": "^5.1.4", + "minimisted": "^2.0.0", + "pako": "^1.0.10", + "pify": "^4.0.1", + "readable-stream": "^3.4.0", + "sha.js": "^2.4.9", + "simple-get": "^3.0.2" + }, + "bin": { + "isogit": "cli.cjs" + }, + "engines": { + "node": ">=10" + } + }, + "../node_modules/isomorphic-git/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "../node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "../node_modules/istanbul-lib-coverage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/istanbul-lib-hook": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", + "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", + "dev": true, + "dependencies": { + "append-transform": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "../node_modules/istanbul-lib-processinfo": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz", + "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==", + "dev": true, + "dependencies": { + "archy": "^1.0.0", + "cross-spawn": "^7.0.0", + "istanbul-lib-coverage": "^3.0.0-alpha.1", + "make-dir": "^3.0.0", + "p-map": "^3.0.0", + "rimraf": "^3.0.0", + "uuid": "^3.3.3" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/istanbul-lib-report/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/istanbul-lib-source-maps": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", + "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/istanbul-lib-source-maps/node_modules/debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "../node_modules/istanbul-lib-source-maps/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "../node_modules/istanbul-reports": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", + "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/jest-diff": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.0.6.tgz", + "integrity": "sha512-Z1mqgkTCSYaFgwTlP/NUiRzdqgxmmhzHY1Tq17zL94morOHfHu3K4bgSgl+CR4GLhpV8VxkuOYuIWnQ9LnFqmg==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^27.0.6", + "jest-get-type": "^27.0.6", + "pretty-format": "^27.0.6" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "../node_modules/jest-diff/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "../node_modules/jest-diff/node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "../node_modules/jest-diff/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "../node_modules/jest-diff/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "../node_modules/jest-diff/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/jest-diff/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/jest-docblock": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", + "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==", + "dev": true, + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "../node_modules/jest-get-type": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", + "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "../node_modules/jest-matcher-utils": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.0.6.tgz", + "integrity": "sha512-OFgF2VCQx9vdPSYTHWJ9MzFCehs20TsyFi6bIHbk5V1u52zJOnvF0Y/65z3GLZHKRuTgVPY4Z6LVePNahaQ+tA==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^27.0.6", + "jest-get-type": "^27.0.6", + "pretty-format": "^27.0.6" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "../node_modules/jest-matcher-utils/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "../node_modules/jest-matcher-utils/node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "../node_modules/jest-matcher-utils/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "../node_modules/jest-matcher-utils/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "../node_modules/jest-matcher-utils/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/jest-matcher-utils/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/jest-message-util": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.0.6.tgz", + "integrity": "sha512-rBxIs2XK7rGy+zGxgi+UJKP6WqQ+KrBbD1YMj517HYN3v2BG66t3Xan3FWqYHKZwjdB700KiAJ+iES9a0M+ixw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.0.6", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.4", + "pretty-format": "^27.0.6", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "../node_modules/jest-message-util/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "../node_modules/jest-message-util/node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "../node_modules/jest-message-util/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "../node_modules/jest-message-util/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "../node_modules/jest-message-util/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/jest-message-util/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/jest-regex-util": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.0.6.tgz", + "integrity": "sha512-SUhPzBsGa1IKm8hx2F4NfTGGp+r7BXJ4CulsZ1k2kI+mGLG+lxGrs76veN2LF/aUdGosJBzKgXmNCw+BzFqBDQ==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "../node_modules/jju": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", + "integrity": "sha1-o6vicYryQaKykE+EpiWXDzia4yo=", + "dev": true + }, + "../node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "../node_modules/js-yaml": { + "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" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "../node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + }, + "../node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "../node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" + }, + "../node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "../node_modules/json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "../node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "../node_modules/json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "dev": true, + "dependencies": { + "jsonify": "~0.0.0" + } + }, + "../node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "../node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "../node_modules/json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "../node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "../node_modules/jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true, + "engines": { + "node": "*" + } + }, + "../node_modules/jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "../node_modules/jsx-ast-utils": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz", + "integrity": "sha512-EIsmt3O3ljsU6sot/J4E1zDRxfBNrhjyf/OKjlydwgEimQuznlM4Wv7U+ueONJMyEn1WRE0K8dhi3dVAXYT24Q==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.2", + "object.assign": "^4.1.2" + }, + "engines": { + "node": ">=4.0" + } + }, + "../node_modules/just-extend": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", + "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", + "dev": true + }, + "../node_modules/keyv": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.3.tgz", + "integrity": "sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA==", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "../node_modules/lcov-parse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-1.0.0.tgz", + "integrity": "sha1-6w1GtUER68VhrLTECO+TY73I9+A=", + "dev": true, + "bin": { + "lcov-parse": "bin/cli.js" + } + }, + "../node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "../node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "../node_modules/lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, + "../node_modules/linguist-languages": { + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/linguist-languages/-/linguist-languages-7.10.0.tgz", + "integrity": "sha512-Uqt94P4iAznscZtccnNE1IBi105U+fmQKEUlDJv54JDdFZDInomkepEIRpZLOQcPyGdcNu3JO9Tvo5wpQVbfKw==", + "dev": true + }, + "../node_modules/load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "../node_modules/load-json-file/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "../node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "../node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "../node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "../node_modules/lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", + "dev": true + }, + "../node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "dev": true + }, + "../node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=", + "dev": true + }, + "../node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "../node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, + "../node_modules/lodash.zip": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.zip/-/lodash.zip-4.2.0.tgz", + "integrity": "sha1-7GZi5IlkCO1KtsVCo5kLcswIACA=", + "dev": true + }, + "../node_modules/log-driver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", + "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", + "dev": true, + "engines": { + "node": ">=0.8.6" + } + }, + "../node_modules/log-symbols": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", + "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "../node_modules/log-symbols/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "../node_modules/log-symbols/node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "../node_modules/log-symbols/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "../node_modules/log-symbols/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "../node_modules/log-symbols/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/log-symbols/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "../node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "engines": { + "node": ">=8" + } + }, + "../node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "../node_modules/lru-cache/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "../node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../node_modules/make-dir/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "../node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "../node_modules/map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "dev": true, + "dependencies": { + "p-defer": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "../node_modules/markdown-escapes": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.4.tgz", + "integrity": "sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "../node_modules/mem": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/mem/-/mem-6.1.1.tgz", + "integrity": "sha512-Ci6bIfq/UgcxPTYa8dQQ5FY3BzKkT894bwXWXxC/zqs0XgMO2cT20CGkOqda7gZNkmK5VP4x89IGZ6K7hfbn3Q==", + "dev": true, + "dependencies": { + "map-age-cleaner": "^0.1.3", + "mimic-fn": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sindresorhus/mem?sponsor=1" + } + }, + "../node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "../node_modules/micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "dependencies": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + }, + "engines": { + "node": ">=8.6" + } + }, + "../node_modules/mime-db": { + "version": "1.48.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz", + "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==", + "engines": { + "node": ">= 0.6" + } + }, + "../node_modules/mime-types": { + "version": "2.1.31", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz", + "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==", + "dependencies": { + "mime-db": "1.48.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "../node_modules/mimic-fn": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz", + "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/mimic-response": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", + "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../node_modules/minimatch": { + "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" + }, + "engines": { + "node": "*" + } + }, + "../node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "../node_modules/minimisted": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/minimisted/-/minimisted-2.0.1.tgz", + "integrity": "sha512-1oPjfuLQa2caorJUM8HV8lGgWCc0qqAO1MNv/k05G4qslmsndV/5WdNZrqCiyqiz3wohia2Ij2B7w2Dr7/IyrA==", + "dependencies": { + "minimist": "^1.2.5" + } + }, + "../node_modules/minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dependencies": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "../node_modules/minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "dependencies": { + "minipass": "^2.9.0" + } + }, + "../node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "../node_modules/mocha": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.4.0.tgz", + "integrity": "sha512-hJaO0mwDXmZS4ghXsvPVriOhsxQ7ofcpQdm8dE+jISUOKopitvnXFQmpRR7jd2K6VBG6E26gU3IAbXXGIbu4sQ==", + "dev": true, + "dependencies": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.1", + "debug": "4.3.1", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.1.6", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "4.0.0", + "log-symbols": "4.0.0", + "minimatch": "3.0.4", + "ms": "2.1.3", + "nanoid": "3.1.20", + "serialize-javascript": "5.0.1", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "which": "2.0.2", + "wide-align": "1.1.3", + "workerpool": "6.1.0", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha" + }, + "engines": { + "node": ">= 10.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" + } + }, + "../node_modules/mocha/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "../node_modules/mocha/node_modules/debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "../node_modules/mocha/node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "../node_modules/mocha/node_modules/diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "../node_modules/mocha/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../node_modules/mocha/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../node_modules/mocha/node_modules/glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "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" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "../node_modules/mocha/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/mocha/node_modules/js-yaml": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", + "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "../node_modules/mocha/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../node_modules/mocha/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../node_modules/mocha/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../node_modules/mocha/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/mocha/node_modules/strip-json-comments": { + "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==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "../node_modules/mocha/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "../node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "../node_modules/multimap": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/multimap/-/multimap-1.1.0.tgz", + "integrity": "sha512-0ZIR9PasPxGXmRsEF8jsDzndzHDj7tIav+JUmvIFB/WHswliFnquxECT/De7GR4yg99ky/NlRKJT82G1y271bw==", + "dev": true + }, + "../node_modules/n-readlines": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/n-readlines/-/n-readlines-1.0.1.tgz", + "integrity": "sha512-z4SyAIVgMy7CkgsoNw7YVz40v0g4+WWvvqy8+ZdHrCtgevcEO758WQyrYcw3XPxcLxF+//RszTz/rO48nzD0wQ==", + "dev": true, + "engines": { + "node": ">=6.x.x" + } + }, + "../node_modules/nan": { + "version": "2.14.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", + "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==" + }, + "../node_modules/nanoid": { + "version": "3.1.20", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", + "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==", + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "../node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "../node_modules/needle": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-2.8.0.tgz", + "integrity": "sha512-ZTq6WYkN/3782H1393me3utVYdq2XyqNUFBsprEE3VMAT0+hP/cItpnITpqsY6ep2yeFE4Tqtqwc74VqUlUYtw==", + "dependencies": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + }, + "bin": { + "needle": "bin/needle" + }, + "engines": { + "node": ">= 4.4.x" + } + }, + "../node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "../node_modules/nise": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/nise/-/nise-4.1.0.tgz", + "integrity": "sha512-eQMEmGN/8arp0xsvGoQ+B1qvSkR73B1nWSCh7nOt5neMCtwcQVYQGdzQMhcNscktTsWB54xnlSQFzOAPJD8nXA==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.7.0", + "@sinonjs/fake-timers": "^6.0.0", + "@sinonjs/text-encoding": "^0.7.1", + "just-extend": "^4.0.2", + "path-to-regexp": "^1.7.0" + } + }, + "../node_modules/node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", + "engines": { + "node": "4.x || >=6.0.0" + } + }, + "../node_modules/node-gyp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-4.0.0.tgz", + "integrity": "sha512-2XiryJ8sICNo6ej8d0idXDEMKfVfFK7kekGCtJAuelGsYHQxhj13KTf95swTCN2dZ/4lTfZ84Fu31jqJEEgjWA==", + "dependencies": { + "glob": "^7.0.3", + "graceful-fs": "^4.1.2", + "mkdirp": "^0.5.0", + "nopt": "2 || 3", + "npmlog": "0 || 1 || 2 || 3 || 4", + "osenv": "0", + "request": "^2.87.0", + "rimraf": "2", + "semver": "~5.3.0", + "tar": "^4.4.8", + "which": "1" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "../node_modules/node-gyp/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "../node_modules/node-gyp/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "../node_modules/node-pre-gyp": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.13.0.tgz", + "integrity": "sha512-Md1D3xnEne8b/HGVQkZZwV27WUi1ZRuZBij24TNaZwUPU3ZAFtvT6xxJGaUVillfmMKnn5oD1HoGsp2Ftik7SQ==", + "deprecated": "Please upgrade to @mapbox/node-pre-gyp: the non-scoped node-pre-gyp package is deprecated and only the @mapbox scoped package will recieve updates in the future", + "dependencies": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "../node_modules/node-pre-gyp/node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, + "../node_modules/node-pre-gyp/node_modules/fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "dependencies": { + "minipass": "^2.6.0" + } + }, + "../node_modules/node-pre-gyp/node_modules/minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dependencies": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "../node_modules/node-pre-gyp/node_modules/minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "dependencies": { + "minipass": "^2.9.0" + } + }, + "../node_modules/node-pre-gyp/node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "../node_modules/node-pre-gyp/node_modules/nopt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", + "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", + "dependencies": { + "abbrev": "1", + "osenv": "^0.1.4" + }, + "bin": { + "nopt": "bin/nopt.js" + } + }, + "../node_modules/node-pre-gyp/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "../node_modules/node-pre-gyp/node_modules/tar": { + "version": "4.4.15", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.15.tgz", + "integrity": "sha512-ItbufpujXkry7bHH9NpQyTXPbJ72iTlXgkBAYsAjDXk3Ds8t/3NfO5P4xZGy7u+sYuQUbimgzswX4uQIEeNVOA==", + "dependencies": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + }, + "engines": { + "node": ">=4.5" + } + }, + "../node_modules/node-pre-gyp/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + }, + "../node_modules/node-preload": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", + "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", + "dev": true, + "dependencies": { + "process-on-spawn": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/node-releases": { + "version": "1.1.73", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz", + "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==", + "dev": true + }, + "../node_modules/nodegit": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/nodegit/-/nodegit-0.27.0.tgz", + "integrity": "sha512-E9K4gPjWiA0b3Tx5lfWCzG7Cvodi2idl3V5UD2fZrOrHikIfrN7Fc2kWLtMUqqomyoToYJLeIC8IV7xb1CYRLA==", + "hasInstallScript": true, + "dependencies": { + "fs-extra": "^7.0.0", + "got": "^10.7.0", + "json5": "^2.1.0", + "lodash": "^4.17.14", + "nan": "^2.14.0", + "node-gyp": "^4.0.0", + "node-pre-gyp": "^0.13.0", + "ramda": "^0.25.0", + "tar-fs": "^1.16.3" + }, + "engines": { + "node": ">= 6" + } + }, + "../node_modules/nodegit/node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "../node_modules/nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + } + }, + "../node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "../node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "../node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../node_modules/npm-bundled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.2.tgz", + "integrity": "sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ==", + "dependencies": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "../node_modules/npm-normalize-package-bin": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", + "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==" + }, + "../node_modules/npm-packlist": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", + "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", + "dependencies": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1", + "npm-normalize-package-bin": "^1.0.1" + } + }, + "../node_modules/npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "dependencies": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "../node_modules/number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "engines": { + "node": ">=0.10.0" + } + }, + "../node_modules/nyc": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", + "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", + "dev": true, + "dependencies": { + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "caching-transform": "^4.0.0", + "convert-source-map": "^1.7.0", + "decamelize": "^1.2.0", + "find-cache-dir": "^3.2.0", + "find-up": "^4.1.0", + "foreground-child": "^2.0.0", + "get-package-type": "^0.1.0", + "glob": "^7.1.6", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-hook": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-processinfo": "^2.0.2", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "make-dir": "^3.0.0", + "node-preload": "^0.2.1", + "p-map": "^3.0.0", + "process-on-spawn": "^1.0.0", + "resolve-from": "^5.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "spawn-wrap": "^2.0.0", + "test-exclude": "^6.0.0", + "yargs": "^15.0.2" + }, + "bin": { + "nyc": "bin/nyc.js" + }, + "engines": { + "node": ">=8.9" + } + }, + "../node_modules/nyc/node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/nyc/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "../node_modules/nyc/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "../node_modules/nyc/node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "../node_modules/nyc/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "../node_modules/nyc/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "../node_modules/nyc/node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "../node_modules/nyc/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/nyc/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/nyc/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/nyc/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../node_modules/nyc/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/nyc/node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "../node_modules/nyc/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/nyc/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/nyc/node_modules/string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/nyc/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/nyc/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/nyc/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "../node_modules/nyc/node_modules/yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.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": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/nyc/node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "../node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "engines": { + "node": "*" + } + }, + "../node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "engines": { + "node": ">=0.10.0" + } + }, + "../node_modules/object-inspect": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz", + "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "../node_modules/object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../node_modules/object.entries": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.4.tgz", + "integrity": "sha512-h4LWKWE+wKQGhtMjZEBud7uLGhqyLwj8fpHOarZhD2uY3C9cRtk57VQ89ke3moByLXMedqs3XCHzyb4AmA2DjA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "../node_modules/object.fromentries": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.4.tgz", + "integrity": "sha512-EsFBshs5RUUpQEY1D4q/m59kMfz4YJvxuNCJcv/jWwOJr34EaVnG11ZrZa0UHB3wnzV1wx8m58T4hQL8IuNXlQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2", + "has": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../node_modules/object.values": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.4.tgz", + "integrity": "sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dependencies": { + "wrappy": "1" + } + }, + "../node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "../node_modules/os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "engines": { + "node": ">=0.10.0" + } + }, + "../node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "engines": { + "node": ">=0.10.0" + } + }, + "../node_modules/osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "dependencies": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "../node_modules/ot-json1": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/ot-json1/-/ot-json1-1.0.2.tgz", + "integrity": "sha512-IhxkqVWQqlkWULoi/Q2AdzKk0N5vQRbUMUwubFXFCPcY4TsOZjmp2YKrk0/z1TeiECPadWEK060sdFdQ3Grokg==", + "dependencies": { + "ot-text-unicode": "4" + } + }, + "../node_modules/ot-text-unicode": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ot-text-unicode/-/ot-text-unicode-4.0.0.tgz", + "integrity": "sha512-W7ZLU8QXesY2wagYFv47zErXud3E93FGImmSGJsQnBzE+idcPPyo2u2KMilIrTwBh4pbCizy71qRjmmV6aDhcQ==", + "dependencies": { + "unicount": "1.1" + } + }, + "../node_modules/ot-text-unicode/node_modules/unicount": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unicount/-/unicount-1.1.0.tgz", + "integrity": "sha512-RlwWt1ywVW4WErPGAVHw/rIuJ2+MxvTME0siJ6lk9zBhpDfExDbspe6SRlWT3qU6AucNjotPl9qAJRVjP7guCQ==" + }, + "../node_modules/p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "engines": { + "node": ">=8" + } + }, + "../node_modules/p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "../node_modules/p-event": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz", + "integrity": "sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==", + "dependencies": { + "p-timeout": "^3.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "engines": { + "node": ">=4" + } + }, + "../node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "../node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "../node_modules/p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "../node_modules/package-hash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", + "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.15", + "hasha": "^5.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" + }, + "../node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "../node_modules/parse-entities": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.2.2.tgz", + "integrity": "sha512-NzfpbxW/NPrzZ/yYSoQxyqUZMZXIdCfE0OIN4ESsnptHJECoUk3FZktxNuzQf4tjt5UEopnxpYJbvYuxIFDdsg==", + "dev": true, + "dependencies": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + } + }, + "../node_modules/parse-git-config": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/parse-git-config/-/parse-git-config-3.0.0.tgz", + "integrity": "sha512-wXoQGL1D+2COYWCD35/xbiKma1Z15xvZL8cI25wvxzled58V51SJM04Urt/uznS900iQor7QO04SgdfT/XlbuA==", + "dev": true, + "dependencies": { + "git-config-path": "^2.0.0", + "ini": "^1.3.5" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "dependencies": { + "error-ex": "^1.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "../node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "../node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "engines": { + "node": ">=0.10.0" + } + }, + "../node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "../node_modules/path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "dev": true, + "dependencies": { + "isarray": "0.0.1" + } + }, + "../node_modules/path-to-regexp/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "../node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "../node_modules/picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "../node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "engines": { + "node": ">=6" + } + }, + "../node_modules/pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "dependencies": { + "find-up": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "../node_modules/please-upgrade-node": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", + "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", + "dev": true, + "dependencies": { + "semver-compare": "^1.0.0" + } + }, + "../node_modules/pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "../node_modules/postcss": { + "version": "7.0.36", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", + "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", + "dev": true, + "dependencies": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + }, + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "../node_modules/postcss-less": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-3.1.4.tgz", + "integrity": "sha512-7TvleQWNM2QLcHqvudt3VYjULVB49uiW6XzEUFmvwHzvsOEF5MwBrIXZDJQvJNFGjJQTzSzZnDoCJ8h/ljyGXA==", + "dev": true, + "dependencies": { + "postcss": "^7.0.14" + }, + "engines": { + "node": ">=6.14.4" + } + }, + "../node_modules/postcss-media-query-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", + "integrity": "sha1-J7Ocb02U+Bsac7j3Y1HGCeXO8kQ=", + "dev": true + }, + "../node_modules/postcss-scss": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-2.1.1.tgz", + "integrity": "sha512-jQmGnj0hSGLd9RscFw9LyuSVAa5Bl1/KBPqG1NQw9w8ND55nY4ZEsdlVuYJvLPpV+y0nwTV5v/4rHPzZRihQbA==", + "dev": true, + "dependencies": { + "postcss": "^7.0.6" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "../node_modules/postcss-selector-parser": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz", + "integrity": "sha1-+UN3iGBsPJrO4W/+jYsWKX8nu5A=", + "dev": true, + "dependencies": { + "flatten": "^1.0.2", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + }, + "../node_modules/postcss-values-parser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-2.0.1.tgz", + "integrity": "sha512-2tLuBsA6P4rYTNKCXYG/71C7j1pU6pK503suYOmn4xYrQIzW+opD+7FAFNuGSdZC/3Qfy334QbeMu7MEb8gOxg==", + "dev": true, + "dependencies": { + "flatten": "^1.0.2", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + }, + "engines": { + "node": ">=6.14.4" + } + }, + "../node_modules/postcss/node_modules/supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "../node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "../node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "../node_modules/prettierx": { + "version": "0.14.3", + "resolved": "https://registry.npmjs.org/prettierx/-/prettierx-0.14.3.tgz", + "integrity": "sha512-0VT3GgDAU6rvemeklrRzqVkILrGC1TSo/4STnsBqkreLx5Ck43W05lO60pMKWbG7SWM3DcUZZIR4FZ5pvvDwyQ==", + "dev": true, + "dependencies": { + "@angular/compiler": "9.0.5", + "@babel/code-frame": "7.12.11", + "@babel/parser": "7.12.0", + "@glimmer/syntax": "0.56.1", + "@iarna/toml": "2.2.5", + "@typescript-eslint/typescript-estree": "2.34.0", + "angular-estree-parser": "1.3.1", + "angular-html-parser": "1.7.0", + "camelcase": "6.2.0", + "chalk": "4.1.0", + "ci-info": "2.0.0", + "cjk-regex": "2.0.0", + "cosmiconfig": "7.0.0", + "dashify": "2.0.0", + "dedent": "0.7.0", + "diff": "4.0.2", + "editorconfig": "0.15.3", + "editorconfig-to-prettier": "0.1.1", + "escape-string-regexp": "4.0.0", + "esutils": "2.0.3", + "fast-glob": "3.2.4", + "find-parent-dir": "0.3.0", + "find-project-root": "1.1.1", + "get-stream": "6.0.0", + "globby": "11.0.1", + "graphql": "15.3.0", + "html-element-attributes": "2.2.1", + "html-styles": "1.0.0", + "html-tag-names": "1.1.5", + "ignore": "4.0.6", + "jest-docblock": "26.0.0", + "json-stable-stringify": "1.0.1", + "leven": "3.1.0", + "lines-and-columns": "1.1.6", + "linguist-languages": "7.10.0", + "lodash": "4.17.20", + "mem": "6.1.1", + "minimatch": "3.0.4", + "minimist": "1.2.5", + "n-readlines": "1.0.1", + "please-upgrade-node": "3.2.0", + "postcss-less": "3.1.4", + "postcss-media-query-parser": "0.2.3", + "postcss-scss": "2.1.1", + "postcss-selector-parser": "2.2.3", + "postcss-values-parser": "2.0.1", + "regexp-util": "1.2.2", + "remark-math": "1.0.6", + "remark-parse": "5.0.0", + "resolve": "1.19.0", + "semver": "7.3.4", + "srcset": "3.0.0", + "string-width": "4.2.0", + "tslib": "1.14.1", + "unicode-regex": "3.0.0", + "unified": "9.2.0", + "vnopts": "1.0.2", + "yaml-unist-parser": "1.3.1" + }, + "bin": { + "prettierx": "bin/prettierx.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "peerDependenciesMeta": { + "flow-parser": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "../node_modules/prettierx/node_modules/@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.10.4" + } + }, + "../node_modules/prettierx/node_modules/@babel/parser": { + "version": "7.12.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.0.tgz", + "integrity": "sha512-dYmySMYnlus2jwl7JnnajAj11obRStZoW9cG04wh4ZuhozDn11tDUrhHcUZ9iuNHqALAhh60XqNaYXpvuuE/Gg==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "../node_modules/prettierx/node_modules/@typescript-eslint/typescript-estree": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz", + "integrity": "sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "eslint-visitor-keys": "^1.1.0", + "glob": "^7.1.6", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "../node_modules/prettierx/node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/prettierx/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "../node_modules/prettierx/node_modules/chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "../node_modules/prettierx/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "../node_modules/prettierx/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "../node_modules/prettierx/node_modules/debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "../node_modules/prettierx/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../node_modules/prettierx/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "../node_modules/prettierx/node_modules/fast-glob": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", + "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/prettierx/node_modules/get-stream": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.0.tgz", + "integrity": "sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../node_modules/prettierx/node_modules/globby": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", + "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../node_modules/prettierx/node_modules/globby/node_modules/ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "../node_modules/prettierx/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/prettierx/node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "../node_modules/prettierx/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/prettierx/node_modules/lodash": { + "version": "4.17.20", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", + "dev": true + }, + "../node_modules/prettierx/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "../node_modules/prettierx/node_modules/resolve": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "dev": true, + "dependencies": { + "is-core-module": "^2.1.0", + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../node_modules/prettierx/node_modules/semver": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "../node_modules/prettierx/node_modules/string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/prettierx/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/prettierx/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/pretty-format": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.6.tgz", + "integrity": "sha512-8tGD7gBIENgzqA+UBzObyWqQ5B778VIFZA/S66cclyd5YkFLYs2Js7gxDKf0MXtTc9zcS7t1xhdfcElJ3YIvkQ==", + "dev": true, + "dependencies": { + "@jest/types": "^27.0.6", + "ansi-regex": "^5.0.0", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "../node_modules/pretty-format/node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "../node_modules/printj": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz", + "integrity": "sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==", + "bin": { + "printj": "bin/printj.njs" + }, + "engines": { + "node": ">=0.8" + } + }, + "../node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "../node_modules/process-on-spawn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", + "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", + "dev": true, + "dependencies": { + "fromentries": "^1.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "../node_modules/prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "dev": true, + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + }, + "../node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true + }, + "../node_modules/pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "../node_modules/psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" + }, + "../node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "../node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "engines": { + "node": ">=6" + } + }, + "../node_modules/qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "engines": { + "node": ">=0.6" + } + }, + "../node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "../node_modules/ramda": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.25.0.tgz", + "integrity": "sha512-GXpfrYVPwx3K7RQ6aYT8KPS8XViSXUVJT1ONhoKPE9VAleW42YE+U+8VEyGWt41EnEQW7gwecYJriTI0pKoecQ==" + }, + "../node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "../node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "../node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "../node_modules/read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "dependencies": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "../node_modules/read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "dependencies": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "../node_modules/read-pkg/node_modules/path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "dependencies": { + "pify": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "../node_modules/read-pkg/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "../node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "../node_modules/readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "../node_modules/regexp-tree": { + "version": "0.1.23", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.23.tgz", + "integrity": "sha512-+7HWfb4Bvu8Rs2eQTUIpX9I/PlQkYOuTNbRpKLJlQpSgwSkzFYh+pUj0gtvglnOZLKB6YgnIgRuJ2/IlpL48qw==", + "dev": true, + "bin": { + "regexp-tree": "bin/regexp-tree" + } + }, + "../node_modules/regexp-util": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/regexp-util/-/regexp-util-1.2.2.tgz", + "integrity": "sha512-5/rl2UD18oAlLQEIuKBeiSIOp1hb5wCXcakl5yvHxlY1wyWI4D5cUKKzCibBeu741PA9JKvZhMqbkDQqPusX3w==", + "dev": true, + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "node": ">= 4" + } + }, + "../node_modules/regexp.prototype.flags": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz", + "integrity": "sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "../node_modules/release-zalgo": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", + "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", + "dev": true, + "dependencies": { + "es6-error": "^4.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "../node_modules/remark-math": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/remark-math/-/remark-math-1.0.6.tgz", + "integrity": "sha512-I43wU/QOQpXvVFXKjA4FHp5xptK65+5F6yolm8+69/JV0EqSOB64wURUZ3JK50JtnTL8FvwLiH2PZ+fvsBxviA==", + "dev": true, + "dependencies": { + "trim-trailing-lines": "^1.1.0" + }, + "peerDependencies": { + "remark-parse": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0" + } + }, + "../node_modules/remark-parse": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-5.0.0.tgz", + "integrity": "sha512-b3iXszZLH1TLoyUzrATcTQUZrwNl1rE70rVdSruJFlDaJ9z5aMkhrG43Pp68OgfHndL/ADz6V69Zow8cTQu+JA==", + "dev": true, + "dependencies": { + "collapse-white-space": "^1.0.2", + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-whitespace-character": "^1.0.0", + "is-word-character": "^1.0.0", + "markdown-escapes": "^1.0.0", + "parse-entities": "^1.1.0", + "repeat-string": "^1.5.4", + "state-toggle": "^1.0.0", + "trim": "0.0.1", + "trim-trailing-lines": "^1.0.0", + "unherit": "^1.0.4", + "unist-util-remove-position": "^1.0.0", + "vfile-location": "^2.0.0", + "xtend": "^4.0.1" + } + }, + "../node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "../node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "../node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "../node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "../node_modules/require-main-filename": { + "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==", + "dev": true + }, + "../node_modules/reserved-words": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/reserved-words/-/reserved-words-0.1.2.tgz", + "integrity": "sha1-AKCUD5jNUBrqqsMWQR2a3FKzGrE=", + "dev": true + }, + "../node_modules/resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "dependencies": { + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "../node_modules/responselike": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz", + "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==", + "dependencies": { + "lowercase-keys": "^2.0.0" + } + }, + "../node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "../node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "../node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "../node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "../node_modules/safe-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz", + "integrity": "sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==", + "dev": true, + "dependencies": { + "regexp-tree": "~0.1.1" + } + }, + "../node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "../node_modules/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "../node_modules/semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", + "bin": { + "semver": "bin/semver" + } + }, + "../node_modules/semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", + "dev": true + }, + "../node_modules/serialize-javascript": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "../node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "../node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "../node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../node_modules/sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", + "dev": true + }, + "../node_modules/signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" + }, + "../node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "../node_modules/simple-get": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz", + "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==", + "dependencies": { + "decompress-response": "^4.2.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "../node_modules/simple-get/node_modules/decompress-response": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", + "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", + "dependencies": { + "mimic-response": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/simple-html-tokenizer": { + "version": "0.5.11", + "resolved": "https://registry.npmjs.org/simple-html-tokenizer/-/simple-html-tokenizer-0.5.11.tgz", + "integrity": "sha512-C2WEK/Z3HoSFbYq8tI7ni3eOo/NneSPRoPpcM7WdLjFOArFuyXEjAoCdOC3DgMfRyziZQ1hCNR4mrNdWEvD0og==", + "dev": true + }, + "../node_modules/sinon": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-10.0.0.tgz", + "integrity": "sha512-XAn5DxtGVJBlBWYrcYKEhWCz7FLwZGdyvANRyK06419hyEpdT0dMc5A8Vcxg5SCGHc40CsqoKsc1bt1CbJPfNw==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.8.1", + "@sinonjs/fake-timers": "^6.0.1", + "@sinonjs/samsam": "^5.3.1", + "diff": "^4.0.2", + "nise": "^4.1.0", + "supports-color": "^7.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/sinon" + } + }, + "../node_modules/sinon/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/sinon/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "../node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "../node_modules/slice-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "../node_modules/slice-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "../node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "../node_modules/source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "../node_modules/spawn-wrap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", + "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", + "dev": true, + "dependencies": { + "foreground-child": "^2.0.0", + "is-windows": "^1.0.2", + "make-dir": "^3.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "which": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/spawn-wrap/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "../node_modules/spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "../node_modules/spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "../node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "../node_modules/spdx-license-ids": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz", + "integrity": "sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ==", + "dev": true + }, + "../node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "../node_modules/srcset": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/srcset/-/srcset-3.0.0.tgz", + "integrity": "sha512-D59vF08Qzu/C4GAOXVgMTLfgryt5fyWo93FZyhEWANo0PokFz/iWdDe13mX3O5TRf6l8vMTqckAfR4zPiaH0yQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../node_modules/sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "../node_modules/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "../node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/state-toggle": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.3.tgz", + "integrity": "sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "../node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "../node_modules/string-argv": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", + "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", + "dev": true, + "engines": { + "node": ">=0.6.19" + } + }, + "../node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "../node_modules/string.prototype.matchall": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.5.tgz", + "integrity": "sha512-Z5ZaXO0svs0M2xd/6By3qpeKpLKd9mO4v4q3oMEQrk8Ck4xOD5d5XeBOOjGrmVZZ/AHB1S0CgG4N5r1G9N3E2Q==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.2", + "get-intrinsic": "^1.1.1", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "regexp.prototype.flags": "^1.3.1", + "side-channel": "^1.0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../node_modules/string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../node_modules/string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "../node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "../node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "engines": { + "node": ">=0.10.0" + } + }, + "../node_modules/supports-color": { + "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" + }, + "engines": { + "node": ">=4" + } + }, + "../node_modules/table": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz", + "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==", + "dev": true, + "dependencies": { + "ajv": "^8.0.1", + "lodash.clonedeep": "^4.5.0", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "../node_modules/table/node_modules/ajv": { + "version": "8.6.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.1.tgz", + "integrity": "sha512-42VLtQUOLefAvKFAQIxIZDaThq6om/PrfP0CYk3/vn+y4BMNkKnbli8ON2QCiHov4KkzOSJ/xSoBJdayiiYvVQ==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "../node_modules/table/node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/table/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/table/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "../node_modules/table/node_modules/string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/table/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/tar": { + "version": "4.4.15", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.15.tgz", + "integrity": "sha512-ItbufpujXkry7bHH9NpQyTXPbJ72iTlXgkBAYsAjDXk3Ds8t/3NfO5P4xZGy7u+sYuQUbimgzswX4uQIEeNVOA==", + "dependencies": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + }, + "engines": { + "node": ">=4.5" + } + }, + "../node_modules/tar-fs": { + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.3.tgz", + "integrity": "sha512-NvCeXpYx7OsmOh8zIOP/ebG55zZmxLE0etfWRbWok+q2Qo8x/vOR/IJT1taADXPe+jsiu9axDb3X4B+iIgNlKw==", + "dependencies": { + "chownr": "^1.0.1", + "mkdirp": "^0.5.1", + "pump": "^1.0.0", + "tar-stream": "^1.1.2" + } + }, + "../node_modules/tar-fs/node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, + "../node_modules/tar-fs/node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "../node_modules/tar-fs/node_modules/pump": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz", + "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "../node_modules/tar-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", + "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", + "dependencies": { + "bl": "^1.0.0", + "buffer-alloc": "^1.2.0", + "end-of-stream": "^1.0.0", + "fs-constants": "^1.0.0", + "readable-stream": "^2.3.0", + "to-buffer": "^1.1.1", + "xtend": "^4.0.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "../node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "../node_modules/timsort": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", + "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=", + "dev": true + }, + "../node_modules/to-buffer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", + "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==" + }, + "../node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "../node_modules/to-readable-stream": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-2.1.0.tgz", + "integrity": "sha512-o3Qa6DGg1CEXshSdvWNX2sN4QHqg03SPq7U6jPXRahlQdl5dK8oXjkU/2/sGrnOZKeGV1zLSO8qPwyKklPPE7w==", + "engines": { + "node": ">=8" + } + }, + "../node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "../node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "../node_modules/transform-file": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/transform-file/-/transform-file-1.0.1.tgz", + "integrity": "sha1-f5WYSs0j1Ov4q7R+6dg74WbRJoc=", + "dev": true, + "dependencies": { + "os-tmpdir": "^1.0.0" + } + }, + "../node_modules/trim": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", + "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=", + "dev": true + }, + "../node_modules/trim-trailing-lines": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.4.tgz", + "integrity": "sha512-rjUWSqnfTNrjbB9NQWfPMH/xRK1deHeGsHoVfpxJ++XeYXE0d6B1En37AHfw3jtfTU7dzMzZL2jjpe8Qb5gLIQ==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "../node_modules/trough": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", + "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "../node_modules/ts-node": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.1.0.tgz", + "integrity": "sha512-6szn3+J9WyG2hE+5W8e0ruZrzyk1uFLYye6IGMBadnOzDh8aP7t8CbFpsfCiEx2+wMixAhjFt7lOZC4+l+WbEA==", + "dev": true, + "dependencies": { + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.17", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "../node_modules/tsconfig-paths": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.10.1.tgz", + "integrity": "sha512-rETidPDgCpltxF7MjBZlAFPUHv5aHH2MymyPvh+vEyWAED4Eb/WeMbsnD/JDr4OKPOA1TssDHgIcpTN5Kh0p6Q==", + "dev": true, + "dependencies": { + "json5": "^2.2.0", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + } + }, + "../node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "../node_modules/tslog": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/tslog/-/tslog-3.2.0.tgz", + "integrity": "sha512-xOCghepl5w+wcI4qXI7vJy6c53loF8OoC/EuKz1ktAPMtltEDz00yo1poKuyBYIQaq4ZDYKYFPD9PfqVrFXh0A==", + "dependencies": { + "source-map-support": "^0.5.19" + }, + "engines": { + "node": ">=10" + } + }, + "../node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "../node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "../node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + }, + "../node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "../node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "../node_modules/type-fest": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.10.0.tgz", + "integrity": "sha512-EUV9jo4sffrwlg8s0zDhP0T2WD3pru5Xi0+HTE3zTUmBaZNhfkite9PdSJwdXLwPVW0jnAHT56pZHIOYckPEiw==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "../node_modules/typescript": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz", + "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "../node_modules/uglify-js": { + "version": "3.13.10", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.10.tgz", + "integrity": "sha512-57H3ACYFXeo1IaZ1w02sfA71wI60MGco/IQFjOqK+WtKoprh7Go2/yvd2HPtoJILO2Or84ncLccI4xoHMTSbGg==", + "dev": true, + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "../node_modules/ulid": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/ulid/-/ulid-2.3.0.tgz", + "integrity": "sha512-keqHubrlpvT6G2wH0OEfSW4mquYRcbe/J8NMmveoQOjUqmo+hXtO+ORCpWhdbZ7k72UtY61BL7haGxW6enBnjw==", + "bin": { + "ulid": "bin/cli.js" + } + }, + "../node_modules/unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../node_modules/unherit": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.3.tgz", + "integrity": "sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ==", + "dev": true, + "dependencies": { + "inherits": "^2.0.0", + "xtend": "^4.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "../node_modules/unicode-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unicode-regex/-/unicode-regex-3.0.0.tgz", + "integrity": "sha512-WiDJdORsqgxkZrjC8WsIP573130HNn7KsB0IDnUccW2BG2b19QQNloNhVe6DKk3Aef0UcoIHhNVj7IkkcYWrNw==", + "dev": true, + "dependencies": { + "regexp-util": "^1.2.0" + }, + "engines": { + "node": ">= 4" + } + }, + "../node_modules/unicount": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/unicount/-/unicount-1.2.0.tgz", + "integrity": "sha512-bbM0gwaKyIPll7smeeufgbN9sbJbrtr29o93HqF+4bzTeQcTN4zKtBKGwnLoGSG+E6gPQ/WL0t7xAhPKnWW4mQ==" + }, + "../node_modules/unified": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-9.2.0.tgz", + "integrity": "sha512-vx2Z0vY+a3YoTj8+pttM3tiJHCwY5UFbYdiWrwBEbHmK8pvsPj2rtAX2BFfgXen8T39CJWblWRDT4L5WGXtDdg==", + "dev": true, + "dependencies": { + "bail": "^1.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^2.0.0", + "trough": "^1.0.0", + "vfile": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "../node_modules/uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", + "dev": true + }, + "../node_modules/unist-util-is": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz", + "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==", + "dev": true + }, + "../node_modules/unist-util-remove-position": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-1.1.4.tgz", + "integrity": "sha512-tLqd653ArxJIPnKII6LMZwH+mb5q+n/GtXQZo6S6csPRs5zB0u79Yw8ouR3wTw8wxvdJFhpP6Y7jorWdCgLO0A==", + "dev": true, + "dependencies": { + "unist-util-visit": "^1.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "../node_modules/unist-util-stringify-position": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", + "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", + "dev": true, + "dependencies": { + "@types/unist": "^2.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "../node_modules/unist-util-visit": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz", + "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==", + "dev": true, + "dependencies": { + "unist-util-visit-parents": "^2.0.0" + } + }, + "../node_modules/unist-util-visit-parents": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz", + "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==", + "dev": true, + "dependencies": { + "unist-util-is": "^3.0.0" + } + }, + "../node_modules/universal-user-agent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", + "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==" + }, + "../node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "../node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "../node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "../node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "bin": { + "uuid": "bin/uuid" + } + }, + "../node_modules/v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "../node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "../node_modules/validator": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-8.2.0.tgz", + "integrity": "sha512-Yw5wW34fSv5spzTXNkokD6S6/Oq92d8q/t14TqsS3fAiA1RYnxSFSIZ+CY3n6PGGRCq5HhJTSepQvFUS2QUDxA==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "../node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "../node_modules/vfile": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", + "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", + "dev": true, + "dependencies": { + "@types/unist": "^2.0.0", + "is-buffer": "^2.0.0", + "unist-util-stringify-position": "^2.0.0", + "vfile-message": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "../node_modules/vfile-location": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.6.tgz", + "integrity": "sha512-sSFdyCP3G6Ka0CEmN83A2YCMKIieHx0EDaj5IDP4g1pa5ZJ4FJDvpO0WODLxo4LUX4oe52gmSCK7Jw4SBghqxA==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "../node_modules/vfile-message": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", + "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", + "dev": true, + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "../node_modules/vnopts": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/vnopts/-/vnopts-1.0.2.tgz", + "integrity": "sha512-d2rr2EFhAGHnTlURu49G7GWmiJV80HbAnkYdD9IFAtfhmxC+kSWEaZ6ZF064DJFTv9lQZQV1vuLTntyQpoanGQ==", + "dev": true, + "dependencies": { + "chalk": "^2.4.1", + "leven": "^2.1.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">= 6" + } + }, + "../node_modules/vnopts/node_modules/leven": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", + "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "../node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "../node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "../node_modules/which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "../node_modules/wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dependencies": { + "string-width": "^1.0.2 || 2" + } + }, + "../node_modules/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "../node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "../node_modules/workerpool": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz", + "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==", + "dev": true + }, + "../node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "../node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "../node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "../node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "../node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/wrap-ansi/node_modules/string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "../node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "../node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + }, + "../node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "../node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + }, + "../node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "../node_modules/yaml-unist-parser": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/yaml-unist-parser/-/yaml-unist-parser-1.3.1.tgz", + "integrity": "sha512-4aHBMpYcnByF8l2OKj5hlBJlxSYIMON8Z1Hm57ymbBL4omXMlGgY+pEf4Di6h2qNT8ZG8seTVvAQYNOa7CZ9eA==", + "dev": true, + "dependencies": { + "lines-and-columns": "^1.1.6", + "tslib": "^1.10.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">= 6" + } + }, + "../node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "../node_modules/yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "../node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "../node_modules/yargs/node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/yargs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "../node_modules/yargs/node_modules/string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "../node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "../node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "../node_modules/z-schema": { + "version": "3.18.4", + "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-3.18.4.tgz", + "integrity": "sha512-DUOKC/IhbkdLKKiV89gw9DUauTV8U/8yJl1sjf6MtDmzevLKOF2duNJ495S3MFVjqZarr+qNGCPbkg4mu4PpLw==", + "dev": true, + "dependencies": { + "lodash.get": "^4.0.0", + "lodash.isequal": "^4.0.0", + "validator": "^8.0.0" + }, + "bin": { + "z-schema": "bin/z-schema" + }, + "optionalDependencies": { + "commander": "^2.7.1" + } + }, + "node_modules/@sindresorhus/is": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-2.1.1.tgz", + "integrity": "sha512-/aPsuoj/1Dw/kzhkgz+ES6TxG0zfTMGLwuK2ZG00k/iJzYHTLCE8mVU8EPqEOp/lmxPoq1C1C9RYToRKb2KEfg==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@sosuisen/nodegit": { + "version": "0.28.0-alpha.11", + "resolved": "https://registry.npmjs.org/@sosuisen/nodegit/-/nodegit-0.28.0-alpha.11.tgz", + "integrity": "sha512-mpztf9ncWxU7/agKQ6E7GvlBIa6H7m3YXuMjlPWVegHusqkbgPi4J01d2inCPhLz0CoC0F/L3LKJuDCAKDXJJg==", + "hasInstallScript": true, + "dependencies": { + "fs-extra": "^7.0.0", + "got": "^10.7.0", + "json5": "^2.1.0", + "lodash": "^4.17.14", + "nan": "^2.14.1", + "node-gyp": "^7.1.2", + "node-pre-gyp": "^0.13.0", + "ramda": "^0.25.0", + "tar-fs": "^1.16.3" + }, + "engines": { + "node": ">= 12.19.0 < 13 || >= 14.10.0" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "dependencies": { + "defer-to-connect": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@types/cacheable-request": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", + "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", + "dependencies": { + "@types/http-cache-semantics": "*", + "@types/keyv": "*", + "@types/node": "*", + "@types/responselike": "*" + } + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", + "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==" + }, + "node_modules/@types/keyv": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.2.tgz", + "integrity": "sha512-/FvAK2p4jQOaJ6CGDHJTqZcUtbZe820qIeTg7o0Shg7drB4JHeL+V/dhSaly7NXx6u8eSee+r7coT+yuJEvDLg==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "16.4.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.4.13.tgz", + "integrity": "sha512-bLL69sKtd25w7p1nvg9pigE4gtKVpGTPojBFLMkGHXuUgap2sLqQt2qUnqmVCDfzGUL0DRNZP+1prIZJbMeAXg==" + }, + "node_modules/@types/responselike": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", + "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + }, + "node_modules/are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "node_modules/asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/bl": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", + "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==", + "dependencies": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "dependencies": { + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" + } + }, + "node_modules/buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" + }, + "node_modules/buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=" + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, + "node_modules/cacheable-lookup": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-2.0.1.tgz", + "integrity": "sha512-EMMbsiOTcdngM/K6gV/OxF2x0t07+vMOWxZNSCRQMjO2MY2nhZQ6OYhOOpyQrbhqsgtvKGI7hcq6xjnA92USjg==", + "dependencies": { + "@types/keyv": "^3.1.1", + "keyv": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cacheable-request": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", + "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "engines": { + "node": ">=10" + } + }, + "node_modules/clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dependencies": { + "mimic-response": "^1.0.0" + } + }, + "node_modules/clone-response/node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/decompress-response": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-5.0.0.tgz", + "integrity": "sha512-TLZWWybuxWgoW7Lykv+gq9xvzOsUjQ9tF09Tj6NSTYGMTCHNXzrPnD6Hi+TgZq19PyTAGH4Ll/NIM/eTGglnMw==", + "dependencies": { + "mimic-response": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "engines": { + "node": ">=10" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + }, + "node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "engines": [ + "node >=0.6.0" + ] + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, + "node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "node_modules/gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "dependencies": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/git-documentdb": { + "resolved": "..", + "link": true + }, + "node_modules/git-documentdb-plugin-remote-nodegit": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.4.tgz", + "integrity": "sha512-+esXlN6PMmvwKZPU6dn/kSQnVe5QHU9xGzoNrLiqehz+VM1AXgNhsce/KipimG4wdzUS6tbS9QbgIgA4VjpbAw==", + "dependencies": { + "@sosuisen/nodegit": "^0.28.0-alpha.11", + "git-documentdb-remote-errors": "^1.0.3", + "tslog": "^3.2.0" + } + }, + "node_modules/git-documentdb-remote-errors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/git-documentdb-remote-errors/-/git-documentdb-remote-errors-1.0.3.tgz", + "integrity": "sha512-14fN8VAQeBC7+Phs6TYB1D5PJDE/dF8dxbigKpsBEqR1FvpAQerSPptxVsQgkU33xwwZBOm7yCwVD2KKmQatOQ==" + }, + "node_modules/glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "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" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/got": { + "version": "10.7.0", + "resolved": "https://registry.npmjs.org/got/-/got-10.7.0.tgz", + "integrity": "sha512-aWTDeNw9g+XqEZNcTjMMZSy7B7yE9toWOFYip7ofFTLleJhvZwUxxTxkTpKvF+p1SAA4VHmuEy7PiHTHyq8tJg==", + "dependencies": { + "@sindresorhus/is": "^2.0.0", + "@szmarczak/http-timer": "^4.0.0", + "@types/cacheable-request": "^6.0.1", + "cacheable-lookup": "^2.0.0", + "cacheable-request": "^7.0.1", + "decompress-response": "^5.0.0", + "duplexer3": "^0.1.4", + "get-stream": "^5.0.0", + "lowercase-keys": "^2.0.0", + "mimic-response": "^2.1.0", + "p-cancelable": "^2.0.0", + "p-event": "^4.0.0", + "responselike": "^2.0.0", + "to-readable-stream": "^2.0.0", + "type-fest": "^0.10.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", + "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" + }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + }, + "node_modules/http-cache-semantics": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", + "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" + }, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore-walk": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.4.tgz", + "integrity": "sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ==", + "dependencies": { + "minimatch": "^3.0.4" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" + }, + "node_modules/json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "node_modules/json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "node_modules/keyv": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.3.tgz", + "integrity": "sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA==", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mime-db": { + "version": "1.49.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz", + "integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.32", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz", + "integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==", + "dependencies": { + "mime-db": "1.49.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-response": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", + "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimatch": { + "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" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "node_modules/minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/nan": { + "version": "2.15.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", + "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==" + }, + "node_modules/needle": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-2.8.0.tgz", + "integrity": "sha512-ZTq6WYkN/3782H1393me3utVYdq2XyqNUFBsprEE3VMAT0+hP/cItpnITpqsY6ep2yeFE4Tqtqwc74VqUlUYtw==", + "dependencies": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + }, + "bin": { + "needle": "bin/needle" + }, + "engines": { + "node": ">= 4.4.x" + } + }, + "node_modules/node-gyp": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-7.1.2.tgz", + "integrity": "sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ==", + "dependencies": { + "env-paths": "^2.2.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.3", + "nopt": "^5.0.0", + "npmlog": "^4.1.2", + "request": "^2.88.2", + "rimraf": "^3.0.2", + "semver": "^7.3.2", + "tar": "^6.0.2", + "which": "^2.0.2" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": ">= 10.12.0" + } + }, + "node_modules/node-pre-gyp": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.13.0.tgz", + "integrity": "sha512-Md1D3xnEne8b/HGVQkZZwV27WUi1ZRuZBij24TNaZwUPU3ZAFtvT6xxJGaUVillfmMKnn5oD1HoGsp2Ftik7SQ==", + "deprecated": "Please upgrade to @mapbox/node-pre-gyp: the non-scoped node-pre-gyp package is deprecated and only the @mapbox scoped package will recieve updates in the future", + "dependencies": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/node-pre-gyp/node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, + "node_modules/node-pre-gyp/node_modules/fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "dependencies": { + "minipass": "^2.6.0" + } + }, + "node_modules/node-pre-gyp/node_modules/minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dependencies": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "node_modules/node-pre-gyp/node_modules/minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "dependencies": { + "minipass": "^2.9.0" + } + }, + "node_modules/node-pre-gyp/node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/node-pre-gyp/node_modules/nopt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", + "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", + "dependencies": { + "abbrev": "1", + "osenv": "^0.1.4" + }, + "bin": { + "nopt": "bin/nopt.js" + } + }, + "node_modules/node-pre-gyp/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/node-pre-gyp/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/node-pre-gyp/node_modules/tar": { + "version": "4.4.15", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.15.tgz", + "integrity": "sha512-ItbufpujXkry7bHH9NpQyTXPbJ72iTlXgkBAYsAjDXk3Ds8t/3NfO5P4xZGy7u+sYuQUbimgzswX4uQIEeNVOA==", + "dependencies": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + }, + "engines": { + "node": ">=4.5" + } + }, + "node_modules/node-pre-gyp/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + }, + "node_modules/nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-bundled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.2.tgz", + "integrity": "sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ==", + "dependencies": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "node_modules/npm-normalize-package-bin": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", + "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==" + }, + "node_modules/npm-packlist": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", + "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", + "dependencies": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1", + "npm-normalize-package-bin": "^1.0.1" + } + }, + "node_modules/npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "dependencies": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "node_modules/number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "engines": { + "node": "*" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "dependencies": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "node_modules/p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/p-event": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz", + "integrity": "sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==", + "dependencies": { + "p-timeout": "^3.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "engines": { + "node": ">=4" + } + }, + "node_modules/p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "node_modules/psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/ramda": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.25.0.tgz", + "integrity": "sha512-GXpfrYVPwx3K7RQ6aYT8KPS8XViSXUVJT1ONhoKPE9VAleW42YE+U+8VEyGWt41EnEQW7gwecYJriTI0pKoecQ==" + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/responselike": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz", + "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==", + "dependencies": { + "lowercase-keys": "^2.0.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "node_modules/signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tar": { + "version": "6.1.6", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.6.tgz", + "integrity": "sha512-oaWyu5dQbHaYcyZCTfyPpC+VmI62/OM2RTUYavTk1MDr1cwW5Boi3baeYQKiZbY2uSQJGr+iMOzb/JFxLrft+g==", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/tar-fs": { + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.3.tgz", + "integrity": "sha512-NvCeXpYx7OsmOh8zIOP/ebG55zZmxLE0etfWRbWok+q2Qo8x/vOR/IJT1taADXPe+jsiu9axDb3X4B+iIgNlKw==", + "dependencies": { + "chownr": "^1.0.1", + "mkdirp": "^0.5.1", + "pump": "^1.0.0", + "tar-stream": "^1.1.2" + } + }, + "node_modules/tar-fs/node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, + "node_modules/tar-fs/node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/tar-fs/node_modules/pump": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz", + "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/tar-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", + "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", + "dependencies": { + "bl": "^1.0.0", + "buffer-alloc": "^1.2.0", + "end-of-stream": "^1.0.0", + "fs-constants": "^1.0.0", + "readable-stream": "^2.3.0", + "to-buffer": "^1.1.1", + "xtend": "^4.0.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/to-buffer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", + "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==" + }, + "node_modules/to-readable-stream": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-2.1.0.tgz", + "integrity": "sha512-o3Qa6DGg1CEXshSdvWNX2sN4QHqg03SPq7U6jPXRahlQdl5dK8oXjkU/2/sGrnOZKeGV1zLSO8qPwyKklPPE7w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tslog": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/tslog/-/tslog-3.2.0.tgz", + "integrity": "sha512-xOCghepl5w+wcI4qXI7vJy6c53loF8OoC/EuKz1ktAPMtltEDz00yo1poKuyBYIQaq4ZDYKYFPD9PfqVrFXh0A==", + "dependencies": { + "source-map-support": "^0.5.19" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + }, + "node_modules/type-fest": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.10.0.tgz", + "integrity": "sha512-EUV9jo4sffrwlg8s0zDhP0T2WD3pru5Xi0+HTE3zTUmBaZNhfkite9PdSJwdXLwPVW0jnAHT56pZHIOYckPEiw==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typescript": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz", + "integrity": "sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dependencies": { + "string-width": "^1.0.2 || 2" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + } + }, "dependencies": { "@sindresorhus/is": { "version": "2.1.1", @@ -437,17 +12468,47 @@ "git-documentdb": { "version": "file:..", "requires": { + "@microsoft/api-extractor": "^7.16.0", "@octokit/rest": "^18.3.5", + "@octokit/types": "^6.12.2", + "@sosuisen/api-documenter": "^7.13.27", "@sosuisen/jsondiffpatch": "^0.4.7", "@types/async-lock": "^1.1.2", + "@types/fs-extra": "^9.0.12", + "@types/js-yaml": "^4.0.3", + "@types/mocha": "^8.2.2", + "@types/node": "^14.14.20", + "@types/parse-git-config": "^3.0.0", + "@types/rimraf": "^3.0.0", + "@types/sinon": "^9.0.11", + "@typescript-eslint/eslint-plugin": "^4.28.0", + "@typescript-eslint/parser": "^4.28.0", "async-lock": "^1.3.0", + "coveralls": "^3.1.0", + "crlf": "^1.1.1", "cross-blob": "^2.0.0", + "cross-env": "^7.0.3", + "eslint": "^7.17.0", + "eslint-config-standardize": "^0.7.1", + "eslint-plugin-prettierx": "^0.14.0", + "eslint-plugin-unicorn": "^36.0.0", + "expect": "^27.0.2", "fs-extra": "^9.1.0", + "git-documentdb-plugin-remote-nodegit": "^1.0.4", "git-documentdb-remote-errors": "^1.0.3", - "isomorphic-git": "^1.8.2", + "hmtid": "^0.1.0", + "isomorphic-git": "^1.17.1", + "js-yaml": "^4.1.0", + "mocha": "^8.3.2", + "nyc": "^15.1.0", "ot-json1": "^1.0.2", + "parse-git-config": "^3.0.0", "rimraf": "^3.0.2", + "sinon": "^10.0.0", + "ts-node": "^10.1.0", + "tsconfig-paths": "^3.9.0", "tslog": "^3.1.2", + "typescript": "^4.3.4", "ulid": "^2.3.0", "unicount": "^1.2.0" }, @@ -455,12 +12516,15 @@ "@angular/compiler": { "version": "9.0.5", "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-9.0.5.tgz", - "integrity": "sha512-TeyhRGefTOtA9N3udMrvheafoXcz/dvTTdZLcieeZQxm1SSeaQDUQ/rUH6QTOiHVNMtjOCrZ9J5rk1A4mPYuag==" + "integrity": "sha512-TeyhRGefTOtA9N3udMrvheafoXcz/dvTTdZLcieeZQxm1SSeaQDUQ/rUH6QTOiHVNMtjOCrZ9J5rk1A4mPYuag==", + "dev": true, + "requires": {} }, "@babel/code-frame": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", + "dev": true, "requires": { "@babel/highlight": "^7.14.5" } @@ -468,12 +12532,14 @@ "@babel/compat-data": { "version": "7.14.7", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.7.tgz", - "integrity": "sha512-nS6dZaISCXJ3+518CWiBfEr//gHyMO02uDxBkXTKZDN5POruCnOZ1N4YBRZDCabwF8nZMWBpRxIicmXtBs+fvw==" + "integrity": "sha512-nS6dZaISCXJ3+518CWiBfEr//gHyMO02uDxBkXTKZDN5POruCnOZ1N4YBRZDCabwF8nZMWBpRxIicmXtBs+fvw==", + "dev": true }, "@babel/core": { "version": "7.14.6", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.6.tgz", "integrity": "sha512-gJnOEWSqTk96qG5BoIrl5bVtc23DCycmIePPYnamY9RboYdI4nFy5vAQMSl81O5K/W0sLDWfGysnOECC+KUUCA==", + "dev": true, "requires": { "@babel/code-frame": "^7.14.5", "@babel/generator": "^7.14.5", @@ -496,6 +12562,7 @@ "version": "4.3.2", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, "requires": { "ms": "2.1.2" } @@ -503,17 +12570,20 @@ "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true } } }, @@ -521,6 +12591,7 @@ "version": "7.14.7", "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.14.7.tgz", "integrity": "sha512-6WPwZqO5priAGIwV6msJcdc9TsEPzYeYdS/Xuoap+/ihkgN6dzHp2bcAAwyWZ5bLzk0vvjDmKvRwkqNaiJ8BiQ==", + "dev": true, "requires": { "eslint-scope": "^5.1.1", "eslint-visitor-keys": "^2.1.0", @@ -530,7 +12601,8 @@ "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true } } }, @@ -538,6 +12610,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz", "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==", + "dev": true, "requires": { "@babel/types": "^7.14.5", "jsesc": "^2.5.1", @@ -547,7 +12620,8 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true } } }, @@ -555,6 +12629,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.14.5.tgz", "integrity": "sha512-v+QtZqXEiOnpO6EYvlImB6zCD2Lel06RzOPzmkz/D/XgQiUu3C/Jb1LOqSt/AIA34TYi/Q+KlT8vTQrgdxkbLw==", + "dev": true, "requires": { "@babel/compat-data": "^7.14.5", "@babel/helper-validator-option": "^7.14.5", @@ -565,7 +12640,8 @@ "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true } } }, @@ -573,6 +12649,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz", "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==", + "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.14.5", "@babel/template": "^7.14.5", @@ -583,6 +12660,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz", "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==", + "dev": true, "requires": { "@babel/types": "^7.14.5" } @@ -591,6 +12669,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.14.5.tgz", "integrity": "sha512-R1PXiz31Uc0Vxy4OEOm07x0oSjKAdPPCh3tPivn/Eo8cvz6gveAeuyUUPB21Hoiif0uoPQSSdhIPS3352nvdyQ==", + "dev": true, "requires": { "@babel/types": "^7.14.5" } @@ -599,6 +12678,7 @@ "version": "7.14.7", "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.14.7.tgz", "integrity": "sha512-TMUt4xKxJn6ccjcOW7c4hlwyJArizskAhoSTOCkA0uZ+KghIaci0Qg9R043kUMWI9mtQfgny+NQ5QATnZ+paaA==", + "dev": true, "requires": { "@babel/types": "^7.14.5" } @@ -607,6 +12687,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz", "integrity": "sha512-SwrNHu5QWS84XlHwGYPDtCxcA0hrSlL2yhWYLgeOc0w7ccOl2qv4s/nARI0aYZW+bSwAL5CukeXA47B/1NKcnQ==", + "dev": true, "requires": { "@babel/types": "^7.14.5" } @@ -615,6 +12696,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.5.tgz", "integrity": "sha512-iXpX4KW8LVODuAieD7MzhNjmM6dzYY5tfRqT+R9HDXWl0jPn/djKmA+G9s/2C2T9zggw5tK1QNqZ70USfedOwA==", + "dev": true, "requires": { "@babel/helper-module-imports": "^7.14.5", "@babel/helper-replace-supers": "^7.14.5", @@ -630,6 +12712,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.14.5.tgz", "integrity": "sha512-IqiLIrODUOdnPU9/F8ib1Fx2ohlgDhxnIDU7OEVi+kAbEZcyiF7BLU8W6PfvPi9LzztjS7kcbzbmL7oG8kD6VA==", + "dev": true, "requires": { "@babel/types": "^7.14.5" } @@ -638,6 +12721,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.14.5.tgz", "integrity": "sha512-3i1Qe9/8x/hCHINujn+iuHy+mMRLoc77b2nI9TB0zjH1hvn9qGlXjWlggdwUcju36PkPCy/lpM7LLUdcTyH4Ow==", + "dev": true, "requires": { "@babel/helper-member-expression-to-functions": "^7.14.5", "@babel/helper-optimise-call-expression": "^7.14.5", @@ -649,6 +12733,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.14.5.tgz", "integrity": "sha512-nfBN9xvmCt6nrMZjfhkl7i0oTV3yxR4/FztsbOASyTvVcoYd0TRHh7eMLdlEcCqobydC0LAF3LtC92Iwxo0wyw==", + "dev": true, "requires": { "@babel/types": "^7.14.5" } @@ -657,6 +12742,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz", "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==", + "dev": true, "requires": { "@babel/types": "^7.14.5" } @@ -664,17 +12750,20 @@ "@babel/helper-validator-identifier": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", - "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==" + "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", + "dev": true }, "@babel/helper-validator-option": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", - "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==" + "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", + "dev": true }, "@babel/helpers": { "version": "7.14.6", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.14.6.tgz", "integrity": "sha512-yesp1ENQBiLI+iYHSJdoZKUtRpfTlL1grDIX9NRlAVppljLw/4tTyYupIB7uIYmC3stW/imAv8EqaKaS/ibmeA==", + "dev": true, "requires": { "@babel/template": "^7.14.5", "@babel/traverse": "^7.14.5", @@ -685,6 +12774,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.14.5", "chalk": "^2.0.0", @@ -694,12 +12784,14 @@ "@babel/parser": { "version": "7.14.7", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.7.tgz", - "integrity": "sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==" + "integrity": "sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==", + "dev": true }, "@babel/template": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", + "dev": true, "requires": { "@babel/code-frame": "^7.14.5", "@babel/parser": "^7.14.5", @@ -710,6 +12802,7 @@ "version": "7.14.7", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.7.tgz", "integrity": "sha512-9vDr5NzHu27wgwejuKL7kIOm4bwEtaPQ4Z6cpCmjSuaRqpH/7xc4qcGEscwMqlkwgcXl6MvqoAjZkQ24uSdIZQ==", + "dev": true, "requires": { "@babel/code-frame": "^7.14.5", "@babel/generator": "^7.14.5", @@ -726,6 +12819,7 @@ "version": "4.3.2", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, "requires": { "ms": "2.1.2" } @@ -733,12 +12827,14 @@ "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true } } }, @@ -746,6 +12842,7 @@ "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.14.5", "to-fast-properties": "^2.0.0" @@ -755,6 +12852,7 @@ "version": "0.4.2", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.2.tgz", "integrity": "sha512-8nmGq/4ycLpIwzvhI4tNDmQztZ8sp+hI7cyG8i1nQDhkAbRzHpXPidRAHlNvCZQpJTKw5ItIpMw9RSToGF00mg==", + "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.1.1", @@ -771,6 +12869,7 @@ "version": "4.3.2", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, "requires": { "ms": "2.1.2" } @@ -778,29 +12877,34 @@ "ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true }, "strip-json-comments": { "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==" + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true } } }, "@glimmer/env": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/@glimmer/env/-/env-0.1.7.tgz", - "integrity": "sha1-/S0rVakCnGs3psk16MiHGucN+gc=" + "integrity": "sha1-/S0rVakCnGs3psk16MiHGucN+gc=", + "dev": true }, "@glimmer/interfaces": { "version": "0.56.2", "resolved": "https://registry.npmjs.org/@glimmer/interfaces/-/interfaces-0.56.2.tgz", "integrity": "sha512-nRgcsTuyZ90aEoCuYVHKGDs3LpAv9n/JKiJ6iecpEYtyGgcPqSI3GjrJRl6k+1s5wnldEH1kjWq+ccCiXmA99w==", + "dev": true, "requires": { "@simple-dom/interface": "^1.4.0" } @@ -809,6 +12913,7 @@ "version": "0.56.1", "resolved": "https://registry.npmjs.org/@glimmer/syntax/-/syntax-0.56.1.tgz", "integrity": "sha512-4TdtIQVFo9UfIVzXnXpMuzsA4mX06oF9NER8FmIPjBosNiQsYB7P8sABSG+2rtWgsh6CkFXkwvxZ++BB+alwOw==", + "dev": true, "requires": { "@glimmer/interfaces": "^0.56.1", "@glimmer/util": "^0.56.1", @@ -820,6 +12925,7 @@ "version": "0.56.2", "resolved": "https://registry.npmjs.org/@glimmer/util/-/util-0.56.2.tgz", "integrity": "sha512-AljXCX5HBjJkmNt4DNYmJmVvwqKjFF4lU6e0SBftwhzK85RbETYwpb3YWrghcjSCxoodwIu1zNFiKOA+xD6txw==", + "dev": true, "requires": { "@glimmer/env": "0.1.7", "@glimmer/interfaces": "^0.56.2", @@ -830,6 +12936,7 @@ "version": "0.5.0", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "dev": true, "requires": { "@humanwhocodes/object-schema": "^1.2.0", "debug": "^4.1.1", @@ -840,6 +12947,7 @@ "version": "4.3.2", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, "requires": { "ms": "2.1.2" } @@ -847,24 +12955,28 @@ "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true } } }, "@humanwhocodes/object-schema": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", - "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==" + "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", + "dev": true }, "@iarna/toml": { "version": "2.2.5", "resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-2.2.5.tgz", - "integrity": "sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==" + "integrity": "sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==", + "dev": true }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, "requires": { "camelcase": "^5.3.1", "find-up": "^4.1.0", @@ -876,12 +12988,14 @@ "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true }, "find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, "requires": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -891,6 +13005,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, "requires": { "p-locate": "^4.1.0" } @@ -899,6 +13014,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, "requires": { "p-try": "^2.0.0" } @@ -907,6 +13023,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, "requires": { "p-limit": "^2.2.0" } @@ -914,29 +13031,34 @@ "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true }, "resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true } } }, "@istanbuljs/schema": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==" + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true }, "@jest/types": { "version": "27.0.6", "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz", "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==", + "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", @@ -949,6 +13071,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "requires": { "color-convert": "^2.0.1" } @@ -957,6 +13080,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -966,6 +13090,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "requires": { "color-name": "~1.1.4" } @@ -973,17 +13098,20 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "requires": { "has-flag": "^4.0.0" } @@ -993,12 +13121,14 @@ "@jsbits/deep-clone": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@jsbits/deep-clone/-/deep-clone-1.1.1.tgz", - "integrity": "sha512-aKhOhRv18tlhkjapBrcyAt8U1SmyzKi2QoO4GGMlXRfQhwm7USDSo/pX8MgB8tYB3MLaevuvwufynKSDA7U3EA==" + "integrity": "sha512-aKhOhRv18tlhkjapBrcyAt8U1SmyzKi2QoO4GGMlXRfQhwm7USDSo/pX8MgB8tYB3MLaevuvwufynKSDA7U3EA==", + "dev": true }, "@microsoft/api-extractor": { "version": "7.18.1", "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.18.1.tgz", "integrity": "sha512-qljUF2Q0zAx1vJrjKkJVGN7OVbsXki+Pji99jywyl6L/FK3YZ7PpstUJYE6uBcLPy6rhNPWPAsHNTMpG/kHIsg==", + "dev": true, "requires": { "@microsoft/api-extractor-model": "7.13.3", "@microsoft/tsdoc": "0.13.2", @@ -1018,6 +13148,7 @@ "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, "requires": { "lru-cache": "^6.0.0" } @@ -1028,6 +13159,7 @@ "version": "7.13.3", "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.13.3.tgz", "integrity": "sha512-uXilAhu2GcvyY/0NwVRk3AN7TFYjkPnjHLV2UywTTz9uglS+Af0YjNrCy+aaK8qXtfbFWdBzkH9N2XU8/YBeRQ==", + "dev": true, "requires": { "@microsoft/tsdoc": "0.13.2", "@microsoft/tsdoc-config": "~0.15.2", @@ -1037,12 +13169,14 @@ "@microsoft/tsdoc": { "version": "0.13.2", "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.13.2.tgz", - "integrity": "sha512-WrHvO8PDL8wd8T2+zBGKrMwVL5IyzR3ryWUsl0PXgEV0QHup4mTLi0QcATefGI6Gx9Anu7vthPyyyLpY0EpiQg==" + "integrity": "sha512-WrHvO8PDL8wd8T2+zBGKrMwVL5IyzR3ryWUsl0PXgEV0QHup4mTLi0QcATefGI6Gx9Anu7vthPyyyLpY0EpiQg==", + "dev": true }, "@microsoft/tsdoc-config": { "version": "0.15.2", "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.15.2.tgz", "integrity": "sha512-mK19b2wJHSdNf8znXSMYVShAHktVr/ib0Ck2FA3lsVBSEhSI/TfXT7DJQkAYgcztTuwazGcg58ZjYdk0hTCVrA==", + "dev": true, "requires": { "@microsoft/tsdoc": "0.13.2", "ajv": "~6.12.6", @@ -1054,6 +13188,7 @@ "version": "1.19.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "dev": true, "requires": { "is-core-module": "^2.1.0", "path-parse": "^1.0.6" @@ -1065,6 +13200,7 @@ "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, "requires": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -1073,12 +13209,14 @@ "@nodelib/fs.stat": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true }, "@nodelib/fs.walk": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, "requires": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -1142,7 +13280,8 @@ "@octokit/plugin-request-log": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz", - "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==" + "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==", + "requires": {} }, "@octokit/plugin-rest-endpoint-methods": { "version": "5.4.1", @@ -1199,6 +13338,7 @@ "version": "3.39.0", "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.39.0.tgz", "integrity": "sha512-kgu3+7/zOBkZU0+NdJb1rcHcpk3/oTjn5c8cg5nUTn+JDjEw58yG83SoeJEcRNNdl11dGX0lKG2PxPsjCokZOQ==", + "dev": true, "requires": { "@types/node": "10.17.13", "colors": "~1.2.1", @@ -1214,12 +13354,14 @@ "@types/node": { "version": "10.17.13", "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.13.tgz", - "integrity": "sha512-pMCcqU2zT4TjqYFrWtYHKal7Sl30Ims6ulZ4UFXxI4xbtQqK/qqKwkDoBFCfooRqqmRu9vY3xaJRwxSh673aYg==" + "integrity": "sha512-pMCcqU2zT4TjqYFrWtYHKal7Sl30Ims6ulZ4UFXxI4xbtQqK/qqKwkDoBFCfooRqqmRu9vY3xaJRwxSh673aYg==", + "dev": true }, "fs-extra": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, "requires": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", @@ -1230,6 +13372,7 @@ "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, "requires": { "lru-cache": "^6.0.0" } @@ -1240,6 +13383,7 @@ "version": "0.2.12", "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.2.12.tgz", "integrity": "sha512-nbePcvF8hQwv0ql9aeQxcaMPK/h1OLAC00W7fWCRWIvD2MchZOE8jumIIr66HGrfG2X1sw++m/ZYI4D+BM5ovQ==", + "dev": true, "requires": { "resolve": "~1.17.0", "strip-json-comments": "~3.1.1" @@ -1248,7 +13392,8 @@ "strip-json-comments": { "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==" + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true } } }, @@ -1256,6 +13401,7 @@ "version": "4.8.0", "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.8.0.tgz", "integrity": "sha512-nZ8cbzVF1VmFPfSJfy8vEohdiFAH/59Y/Y+B4nsJbn4SkifLJ8LqNZ5+LxCC2UR242EXFumxlsY1d6fPBxck5Q==", + "dev": true, "requires": { "@types/argparse": "1.0.38", "argparse": "~1.0.9", @@ -1266,7 +13412,8 @@ "@simple-dom/interface": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/@simple-dom/interface/-/interface-1.4.0.tgz", - "integrity": "sha512-l5qumKFWU0S+4ZzMaLXFU8tQZsicHEMEyAxI5kDFGhJsRqDwe0a7/iPA/GdxlGyDKseQQAgIz5kzU7eXTrlSpA==" + "integrity": "sha512-l5qumKFWU0S+4ZzMaLXFU8tQZsicHEMEyAxI5kDFGhJsRqDwe0a7/iPA/GdxlGyDKseQQAgIz5kzU7eXTrlSpA==", + "dev": true }, "@sindresorhus/is": { "version": "2.1.1", @@ -1277,6 +13424,7 @@ "version": "1.8.3", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "dev": true, "requires": { "type-detect": "4.0.8" } @@ -1285,6 +13433,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", + "dev": true, "requires": { "@sinonjs/commons": "^1.7.0" } @@ -1293,6 +13442,7 @@ "version": "5.3.1", "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-5.3.1.tgz", "integrity": "sha512-1Hc0b1TtyfBu8ixF/tpfSHTVWKwCBLY4QJbkgnE7HcwyvT2xArDxb4K7dMgqRm3szI+LJbzmW/s4xxEhv6hwDg==", + "dev": true, "requires": { "@sinonjs/commons": "^1.6.0", "lodash.get": "^4.4.2", @@ -1302,12 +13452,14 @@ "@sinonjs/text-encoding": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", - "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==" + "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", + "dev": true }, "@sosuisen/api-documenter": { "version": "7.13.27", "resolved": "https://registry.npmjs.org/@sosuisen/api-documenter/-/api-documenter-7.13.27.tgz", "integrity": "sha512-Y3uEwBRSbxEvlLXRD/YcaRhsVNVWMDRLE/EOVDAUzPYy5FrdXiNK0GZNdmxrjCe2E58W/bGKUTZnw9sOI2YOZg==", + "dev": true, "requires": { "@microsoft/api-extractor-model": "^7.13.3", "@microsoft/tsdoc": "^0.13.2", @@ -1327,33 +13479,6 @@ "diff-match-patch": "^1.0.0" } }, - "@sosuisen/nodegit": { - "version": "0.28.0-alpha.11", - "resolved": "https://registry.npmjs.org/@sosuisen/nodegit/-/nodegit-0.28.0-alpha.11.tgz", - "integrity": "sha512-mpztf9ncWxU7/agKQ6E7GvlBIa6H7m3YXuMjlPWVegHusqkbgPi4J01d2inCPhLz0CoC0F/L3LKJuDCAKDXJJg==", - "requires": { - "fs-extra": "^7.0.0", - "got": "^10.7.0", - "json5": "^2.1.0", - "lodash": "^4.17.14", - "nan": "^2.14.1", - "node-pre-gyp": "^0.13.0", - "ramda": "^0.25.0", - "tar-fs": "^1.16.3" - }, - "dependencies": { - "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - } - } - }, "@szmarczak/http-timer": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", @@ -1365,32 +13490,38 @@ "@tsconfig/node10": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", - "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==" + "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", + "dev": true }, "@tsconfig/node12": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", - "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==" + "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", + "dev": true }, "@tsconfig/node14": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", - "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==" + "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", + "dev": true }, "@tsconfig/node16": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", - "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==" + "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", + "dev": true }, "@types/argparse": { "version": "1.0.38", "resolved": "https://registry.npmjs.org/@types/argparse/-/argparse-1.0.38.tgz", - "integrity": "sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==" + "integrity": "sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==", + "dev": true }, "@types/async-lock": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/@types/async-lock/-/async-lock-1.1.3.tgz", - "integrity": "sha512-UpeDcjGKsYEQMeqEbfESm8OWJI305I7b9KE4ji3aBjoKWyN5CTdn8izcA1FM1DVDne30R5fNEnIy89vZw5LXJQ==" + "integrity": "sha512-UpeDcjGKsYEQMeqEbfESm8OWJI305I7b9KE4ji3aBjoKWyN5CTdn8izcA1FM1DVDne30R5fNEnIy89vZw5LXJQ==", + "dev": true }, "@types/cacheable-request": { "version": "6.0.2", @@ -1403,18 +13534,11 @@ "@types/responselike": "*" } }, - "@types/expect": { - "version": "24.3.0", - "resolved": "https://registry.npmjs.org/@types/expect/-/expect-24.3.0.tgz", - "integrity": "sha512-aq5Z+YFBz5o2b6Sp1jigx5nsmoZMK5Ceurjwy6PZmRv7dEi1jLtkARfvB1ME+OXJUG+7TZUDcv3WoCr/aor6dQ==", - "requires": { - "expect": "*" - } - }, "@types/fs-extra": { "version": "9.0.12", "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.12.tgz", "integrity": "sha512-I+bsBr67CurCGnSenZZ7v94gd3tc3+Aj2taxMT4yu4ABLuOgOjeFxX3dokG24ztSRg5tnT00sL8BszO7gSMoIw==", + "dev": true, "requires": { "@types/node": "*" } @@ -1423,6 +13547,7 @@ "version": "7.1.4", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.4.tgz", "integrity": "sha512-w+LsMxKyYQm347Otw+IfBXOv9UWVjpHpCDdbBMt8Kz/xbvCYNjP+0qPh91Km3iKfSRLBB0P7fAMf0KHrPu+MyA==", + "dev": true, "requires": { "@types/minimatch": "*", "@types/node": "*" @@ -1436,12 +13561,14 @@ "@types/istanbul-lib-coverage": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", - "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==" + "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", + "dev": true }, "@types/istanbul-lib-report": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, "requires": { "@types/istanbul-lib-coverage": "*" } @@ -1450,6 +13577,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, "requires": { "@types/istanbul-lib-report": "*" } @@ -1458,7 +13586,7 @@ "version": "7.0.8", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.8.tgz", "integrity": "sha512-YSBPTLTVm2e2OoQIDYx8HaeWJ5tTToLH67kXR7zYNGupXMEHa2++G8k+DczX2cFVgalypqtyZIcU19AFcmOpmg==", - "optional": true + "dev": true }, "@types/keyv": { "version": "3.1.2", @@ -1471,12 +13599,14 @@ "@types/minimatch": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", - "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==" + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "dev": true }, "@types/mocha": { "version": "8.2.3", "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.3.tgz", - "integrity": "sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw==" + "integrity": "sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw==", + "dev": true }, "@types/node": { "version": "14.17.5", @@ -1486,17 +13616,20 @@ "@types/normalize-package-data": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", - "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==" + "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", + "dev": true }, "@types/parse-git-config": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@types/parse-git-config/-/parse-git-config-3.0.1.tgz", - "integrity": "sha512-cBVLXlpIpP23p+jQm8d2TrTfxyub3aiqfqgd0TWRnMqwCJMskYiveNJT11YwN+gbo3+0ZFFmtaepKzN7pxExlA==" + "integrity": "sha512-cBVLXlpIpP23p+jQm8d2TrTfxyub3aiqfqgd0TWRnMqwCJMskYiveNJT11YwN+gbo3+0ZFFmtaepKzN7pxExlA==", + "dev": true }, "@types/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", + "dev": true }, "@types/responselike": { "version": "1.0.0", @@ -1510,6 +13643,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-3.0.1.tgz", "integrity": "sha512-CAoSlbco40aKZ0CkelBF2g3JeN6aioRaTVnqSX5pWsn/WApm6IDxI4e4tD9D0dY/meCkyyleP1IQDVN13F4maA==", + "dev": true, "requires": { "@types/glob": "*", "@types/node": "*" @@ -1519,6 +13653,7 @@ "version": "9.0.11", "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-9.0.11.tgz", "integrity": "sha512-PwP4UY33SeeVKodNE37ZlOsR9cReypbMJOhZ7BVE0lB+Hix3efCOxiJWiE5Ia+yL9Cn2Ch72EjFTRze8RZsNtg==", + "dev": true, "requires": { "@types/sinonjs__fake-timers": "*" } @@ -1526,22 +13661,26 @@ "@types/sinonjs__fake-timers": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.3.tgz", - "integrity": "sha512-E1dU4fzC9wN2QK2Cr1MLCfyHM8BoNnRFvuf45LYMPNDA+WqbNzC45S4UzPxvp1fFJ1rvSGU0bPvdd35VLmXG8g==" + "integrity": "sha512-E1dU4fzC9wN2QK2Cr1MLCfyHM8BoNnRFvuf45LYMPNDA+WqbNzC45S4UzPxvp1fFJ1rvSGU0bPvdd35VLmXG8g==", + "dev": true }, "@types/stack-utils": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", - "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==" + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", + "dev": true }, "@types/unist": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.5.tgz", - "integrity": "sha512-wnra4Vw9dopnuybR6HBywJ/URYpYrKLoepBTEtgfJup8Ahoi2zJECPP2cwiXp7btTvOT2CULv87aQRA4eZSP6g==" + "integrity": "sha512-wnra4Vw9dopnuybR6HBywJ/URYpYrKLoepBTEtgfJup8Ahoi2zJECPP2cwiXp7btTvOT2CULv87aQRA4eZSP6g==", + "dev": true }, "@types/yargs": { "version": "16.0.4", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "dev": true, "requires": { "@types/yargs-parser": "*" } @@ -1549,13 +13688,14 @@ "@types/yargs-parser": { "version": "20.2.1", "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", - "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==" + "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", + "dev": true }, "@typescript-eslint/eslint-plugin": { "version": "4.28.2", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.28.2.tgz", "integrity": "sha512-PGqpLLzHSxq956rzNGasO3GsAPf2lY9lDUBXhS++SKonglUmJypaUtcKzRtUte8CV7nruwnDxtLUKpVxs0wQBw==", - "optional": true, + "dev": true, "requires": { "@typescript-eslint/experimental-utils": "4.28.2", "@typescript-eslint/scope-manager": "4.28.2", @@ -1570,7 +13710,7 @@ "version": "4.3.2", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "optional": true, + "dev": true, "requires": { "ms": "2.1.2" } @@ -1579,13 +13719,13 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "optional": true + "dev": true }, "semver": { "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "optional": true, + "dev": true, "requires": { "lru-cache": "^6.0.0" } @@ -1596,7 +13736,7 @@ "version": "4.28.2", "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.28.2.tgz", "integrity": "sha512-MwHPsL6qo98RC55IoWWP8/opTykjTp4JzfPu1VfO2Z0MshNP0UZ1GEV5rYSSnZSUI8VD7iHvtIPVGW5Nfh7klQ==", - "optional": true, + "dev": true, "requires": { "@types/json-schema": "^7.0.7", "@typescript-eslint/scope-manager": "4.28.2", @@ -1610,7 +13750,7 @@ "version": "4.28.2", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.28.2.tgz", "integrity": "sha512-Q0gSCN51eikAgFGY+gnd5p9bhhCUAl0ERMiDKrTzpSoMYRubdB8MJrTTR/BBii8z+iFwz8oihxd0RAdP4l8w8w==", - "optional": true, + "dev": true, "requires": { "@typescript-eslint/scope-manager": "4.28.2", "@typescript-eslint/types": "4.28.2", @@ -1622,7 +13762,7 @@ "version": "4.3.2", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "optional": true, + "dev": true, "requires": { "ms": "2.1.2" } @@ -1631,7 +13771,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "optional": true + "dev": true } } }, @@ -1639,7 +13779,7 @@ "version": "4.28.2", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.28.2.tgz", "integrity": "sha512-MqbypNjIkJFEFuOwPWNDjq0nqXAKZvDNNs9yNseoGBB1wYfz1G0WHC2AVOy4XD7di3KCcW3+nhZyN6zruqmp2A==", - "optional": true, + "dev": true, "requires": { "@typescript-eslint/types": "4.28.2", "@typescript-eslint/visitor-keys": "4.28.2" @@ -1649,13 +13789,13 @@ "version": "4.28.2", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.28.2.tgz", "integrity": "sha512-Gr15fuQVd93uD9zzxbApz3wf7ua3yk4ZujABZlZhaxxKY8ojo448u7XTm/+ETpy0V0dlMtj6t4VdDvdc0JmUhA==", - "optional": true + "dev": true }, "@typescript-eslint/typescript-estree": { "version": "4.28.2", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.2.tgz", "integrity": "sha512-86lLstLvK6QjNZjMoYUBMMsULFw0hPHJlk1fzhAVoNjDBuPVxiwvGuPQq3fsBMCxuDJwmX87tM/AXoadhHRljg==", - "optional": true, + "dev": true, "requires": { "@typescript-eslint/types": "4.28.2", "@typescript-eslint/visitor-keys": "4.28.2", @@ -1670,7 +13810,7 @@ "version": "4.3.2", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "optional": true, + "dev": true, "requires": { "ms": "2.1.2" } @@ -1679,13 +13819,13 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "optional": true + "dev": true }, "semver": { "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "optional": true, + "dev": true, "requires": { "lru-cache": "^6.0.0" } @@ -1696,7 +13836,7 @@ "version": "4.28.2", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.2.tgz", "integrity": "sha512-aT2B4PLyyRDUVUafXzpZFoc0C9t0za4BJAKP5sgWIhG+jHECQZUEjuQSCIwZdiJJ4w4cgu5r3Kh20SOdtEBl0w==", - "optional": true, + "dev": true, "requires": { "@typescript-eslint/types": "4.28.2", "eslint-visitor-keys": "^2.0.0" @@ -1705,7 +13845,8 @@ "@ungap/promise-all-settled": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==" + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true }, "abbrev": { "version": "1.1.1", @@ -1715,17 +13856,21 @@ "acorn": { "version": "7.4.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true }, "acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==" + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "requires": {} }, "aggregate-error": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, "requires": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" @@ -1746,6 +13891,7 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/angular-estree-parser/-/angular-estree-parser-1.3.1.tgz", "integrity": "sha512-jvlnNk4aoEmA6EKK12OnsOkCSdsWleBsYB+aWyH8kpfTB6Li1kxWVbHKVldH9zDCwVVi1hXfqPi/gbSv49tkbQ==", + "dev": true, "requires": { "lines-and-columns": "^1.1.6", "tslib": "^1.9.3" @@ -1755,6 +13901,7 @@ "version": "1.7.0", "resolved": "https://registry.npmjs.org/angular-html-parser/-/angular-html-parser-1.7.0.tgz", "integrity": "sha512-/yjeqDQXGblZuFMI6vpDgiIDuv816QpIqa/mCotc0I4R0F5t5sfX1ntZ8VsBVQOUYRjPw8ggYlPZto76gHtf7Q==", + "dev": true, "requires": { "tslib": "^1.9.3" } @@ -1762,7 +13909,8 @@ "ansi-colors": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==" + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true }, "ansi-regex": { "version": "2.1.1", @@ -1781,6 +13929,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -1790,6 +13939,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", + "dev": true, "requires": { "default-require-extensions": "^3.0.0" } @@ -1802,7 +13952,8 @@ "archy": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=" + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", + "dev": true }, "are-we-there-yet": { "version": "1.1.5", @@ -1816,7 +13967,8 @@ "arg": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true }, "argparse": { "version": "1.0.10", @@ -1830,6 +13982,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==", + "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", @@ -1841,12 +13994,14 @@ "array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==" + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true }, "array.prototype.flat": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz", "integrity": "sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==", + "dev": true, "requires": { "call-bind": "^1.0.0", "define-properties": "^1.1.3", @@ -1857,6 +14012,7 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.4.tgz", "integrity": "sha512-r9Z0zYoxqHz60vvQbWEdXIEtCwHF0yxaWfno9qzXeNHvfyl3BZqygmGzb84dsubyaXLH4husF+NFgMSdpZhk2Q==", + "dev": true, "requires": { "call-bind": "^1.0.0", "define-properties": "^1.1.3", @@ -1880,7 +14036,8 @@ "astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==" + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true }, "async-lock": { "version": "1.3.0", @@ -1910,7 +14067,8 @@ "bail": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", - "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==" + "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==", + "dev": true }, "balanced-match": { "version": "1.0.2", @@ -1933,7 +14091,8 @@ "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true }, "bl": { "version": "1.2.3", @@ -1962,6 +14121,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, "requires": { "fill-range": "^7.0.1" } @@ -1969,12 +14129,14 @@ "browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true }, "browserslist": { "version": "4.16.6", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", + "dev": true, "requires": { "caniuse-lite": "^1.0.30001219", "colorette": "^1.2.2", @@ -2034,6 +14196,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", + "dev": true, "requires": { "hasha": "^5.0.0", "make-dir": "^3.0.0", @@ -2045,6 +14208,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, "requires": { "function-bind": "^1.1.1", "get-intrinsic": "^1.0.2" @@ -2053,17 +14217,20 @@ "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true }, "camelcase": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==" + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true }, "caniuse-lite": { "version": "1.0.30001243", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001243.tgz", - "integrity": "sha512-vNxw9mkTBtkmLFnJRv/2rhs1yufpDfCkBZexG3Y0xdOH2Z/eE/85E4Dl5j1YUN34nZVsSp6vVRFQRrez9wJMRA==" + "integrity": "sha512-vNxw9mkTBtkmLFnJRv/2rhs1yufpDfCkBZexG3Y0xdOH2Z/eE/85E4Dl5j1YUN34nZVsSp6vVRFQRrez9wJMRA==", + "dev": true }, "caseless": { "version": "0.12.0", @@ -2083,25 +14250,30 @@ "character-entities": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", - "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==" + "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", + "dev": true }, "character-entities-legacy": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", - "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==" + "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", + "dev": true }, "character-reference-invalid": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", - "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==" + "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", + "dev": true }, "chokidar": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "dev": true, "requires": { "anymatch": "~3.1.1", "braces": "~3.0.2", + "fsevents": "~2.3.1", "glob-parent": "~5.1.0", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", @@ -2117,12 +14289,14 @@ "ci-info": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true }, "cjk-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/cjk-regex/-/cjk-regex-2.0.0.tgz", "integrity": "sha512-E4gFi2f3jC0zFVHpaAcupW+gv9OejZ2aV3DP/LlSO0dDcZJAXw7W0ivn+vN17edN/PhU4HCgs1bfx7lPK7FpdA==", + "dev": true, "requires": { "regexp-util": "^1.2.1", "unicode-regex": "^2.0.0" @@ -2132,6 +14306,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-regex/-/unicode-regex-2.0.0.tgz", "integrity": "sha512-5nbEG2YU7loyTvPABaKb+8B0u8L7vWCsVmCSsiaO249ZdMKlvrXlxR2ex4TUVAdzv/Cne/TdoXSSaJArGXaleQ==", + "dev": true, "requires": { "regexp-util": "^1.2.0" } @@ -2147,6 +14322,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", "integrity": "sha1-jffHquUf02h06PjQW5GAvBGj/tc=", + "dev": true, "requires": { "escape-string-regexp": "^1.0.5" } @@ -2154,12 +14330,14 @@ "clean-stack": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==" + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true }, "cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, "requires": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", @@ -2169,17 +14347,20 @@ "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true }, "string-width": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -2190,6 +14371,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, "requires": { "ansi-regex": "^5.0.0" } @@ -2219,7 +14401,8 @@ "collapse-white-space": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz", - "integrity": "sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==" + "integrity": "sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==", + "dev": true }, "color-convert": { "version": "1.9.3", @@ -2237,12 +14420,14 @@ "colorette": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", - "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==" + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", + "dev": true }, "colors": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz", - "integrity": "sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==" + "integrity": "sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==", + "dev": true }, "combined-stream": { "version": "1.0.8", @@ -2255,12 +14440,14 @@ "commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true }, "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true }, "concat-map": { "version": "0.0.1", @@ -2270,7 +14457,8 @@ "confusing-browser-globals": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.10.tgz", - "integrity": "sha512-gNld/3lySHwuhaVluJUKLePYirM3QNCKzVxqAdhJII9/WXKVX5PURzMVJspS1jTslSqjeuG4KMVTSouit5YPHA==" + "integrity": "sha512-gNld/3lySHwuhaVluJUKLePYirM3QNCKzVxqAdhJII9/WXKVX5PURzMVJspS1jTslSqjeuG4KMVTSouit5YPHA==", + "dev": true }, "console-control-strings": { "version": "1.1.0", @@ -2280,12 +14468,14 @@ "contains-path": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", - "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=" + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true }, "convert-source-map": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "dev": true, "requires": { "safe-buffer": "~5.1.1" } @@ -2299,6 +14489,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.0.tgz", "integrity": "sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==", + "dev": true, "requires": { "@types/parse-json": "^4.0.0", "import-fresh": "^3.2.1", @@ -2311,6 +14502,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -2324,6 +14516,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.1.1.tgz", "integrity": "sha512-+dxnG2NHncSD1NrqbSM3dn/lE57O6Qf/koe9+I7c+wzkqRmEvcp0kgJdxKInzYzkICKkFMZsX3Vct3++tsF9ww==", + "dev": true, "requires": { "js-yaml": "^3.13.1", "lcov-parse": "^1.0.0", @@ -2344,12 +14537,14 @@ "create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true }, "crlf": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/crlf/-/crlf-1.1.1.tgz", "integrity": "sha1-JBcoQbTINSmmqkSJ337tlYsu0W8=", + "dev": true, "requires": { "glub": "^1.0.0", "transform-file": "^1.0.1" @@ -2368,6 +14563,7 @@ "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "dev": true, "requires": { "cross-spawn": "^7.0.1" } @@ -2376,6 +14572,7 @@ "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, "requires": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -2386,6 +14583,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, "requires": { "isexe": "^2.0.0" } @@ -2403,7 +14601,8 @@ "dashify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/dashify/-/dashify-2.0.0.tgz", - "integrity": "sha512-hpA5C/YrPjucXypHPPc0oJ1l9Hf6wWbiOL7Ik42cxnsUOhWiCB/fylKbKqqJalW9FgkNQCw16YO8uW9Hs0Iy1A==" + "integrity": "sha512-hpA5C/YrPjucXypHPPc0oJ1l9Hf6wWbiOL7Ik42cxnsUOhWiCB/fylKbKqqJalW9FgkNQCw16YO8uW9Hs0Iy1A==", + "dev": true }, "debug": { "version": "3.2.7", @@ -2416,7 +14615,8 @@ "decamelize": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==" + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true }, "decompress-response": { "version": "5.0.0", @@ -2429,7 +14629,8 @@ "dedent": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=" + "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", + "dev": true }, "deep-extend": { "version": "0.6.0", @@ -2439,17 +14640,20 @@ "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true }, "deepmerge": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==" + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true }, "default-require-extensions": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz", "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==", + "dev": true, "requires": { "strip-bom": "^4.0.0" }, @@ -2457,7 +14661,8 @@ "strip-bom": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true } } }, @@ -2470,6 +14675,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, "requires": { "object-keys": "^1.0.12" } @@ -2497,12 +14703,14 @@ "detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==" + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true }, "diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true }, "diff-match-patch": { "version": "1.0.5", @@ -2512,7 +14720,8 @@ "diff-sequences": { "version": "27.0.6", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz", - "integrity": "sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==" + "integrity": "sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==", + "dev": true }, "diff3": { "version": "0.0.3", @@ -2523,6 +14732,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, "requires": { "path-type": "^4.0.0" } @@ -2531,6 +14741,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, "requires": { "esutils": "^2.0.2" } @@ -2553,6 +14764,7 @@ "version": "0.15.3", "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", + "dev": true, "requires": { "commander": "^2.19.0", "lru-cache": "^4.1.5", @@ -2564,6 +14776,7 @@ "version": "4.1.5", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, "requires": { "pseudomap": "^1.0.2", "yallist": "^2.1.2" @@ -2572,29 +14785,34 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true }, "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true } } }, "editorconfig-to-prettier": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/editorconfig-to-prettier/-/editorconfig-to-prettier-0.1.1.tgz", - "integrity": "sha512-MMadSSVRDb4uKdxV6bCXXN4cTsxIsXYtV4XdPu6FOCSAw6zsCIDA+QEktEU+u6h+c/mTrul5NR+pwFpPxwetiQ==" + "integrity": "sha512-MMadSSVRDb4uKdxV6bCXXN4cTsxIsXYtV4XdPu6FOCSAw6zsCIDA+QEktEU+u6h+c/mTrul5NR+pwFpPxwetiQ==", + "dev": true }, "electron-to-chromium": { "version": "1.3.772", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.772.tgz", - "integrity": "sha512-X/6VRCXWALzdX+RjCtBU6cyg8WZgoxm9YA02COmDOiNJEZ59WkQggDbWZ4t/giHi/3GS+cvdrP6gbLISANAGYA==" + "integrity": "sha512-X/6VRCXWALzdX+RjCtBU6cyg8WZgoxm9YA02COmDOiNJEZ59WkQggDbWZ4t/giHi/3GS+cvdrP6gbLISANAGYA==", + "dev": true }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true }, "end-of-stream": { "version": "1.4.4", @@ -2608,19 +14826,16 @@ "version": "2.3.6", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, "requires": { "ansi-colors": "^4.1.1" } }, - "env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==" - }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, "requires": { "is-arrayish": "^0.2.1" } @@ -2629,6 +14844,7 @@ "version": "1.18.3", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz", "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==", + "dev": true, "requires": { "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", @@ -2652,6 +14868,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, "requires": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", @@ -2661,12 +14878,14 @@ "es6-error": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==" + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true }, "escape-string-regexp": { "version": "1.0.5", @@ -2677,6 +14896,7 @@ "version": "7.30.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.30.0.tgz", "integrity": "sha512-VLqz80i3as3NdloY44BQSJpFw534L9Oh+6zJOUaViV4JPd+DaHwutqP7tcpkW3YiXbK6s05RZl7yl7cQn+lijg==", + "dev": true, "requires": { "@babel/code-frame": "7.12.11", "@eslint/eslintrc": "^0.4.2", @@ -2724,6 +14944,7 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, "requires": { "@babel/highlight": "^7.10.4" } @@ -2731,12 +14952,14 @@ "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "requires": { "color-convert": "^2.0.1" } @@ -2745,6 +14968,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -2754,6 +14978,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "requires": { "color-name": "~1.1.4" } @@ -2761,12 +14986,14 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "debug": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, "requires": { "ms": "2.1.2" } @@ -2774,12 +15001,14 @@ "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true }, "eslint-utils": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, "requires": { "eslint-visitor-keys": "^1.1.0" }, @@ -2787,29 +15016,34 @@ "eslint-visitor-keys": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==" + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true } } }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true }, "ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true }, "semver": { "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, "requires": { "lru-cache": "^6.0.0" } @@ -2818,6 +15052,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, "requires": { "ansi-regex": "^5.0.0" } @@ -2825,12 +15060,14 @@ "strip-json-comments": { "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==" + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "requires": { "has-flag": "^4.0.0" } @@ -2841,6 +15078,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/eslint-ast-utils/-/eslint-ast-utils-1.1.0.tgz", "integrity": "sha512-otzzTim2/1+lVrlH19EfQQJEhVJSu0zOb9ygb3iapN6UlyaDtyRq4b5U1FuW0v1lRa9Fp/GJyHkSwm6NqABgCA==", + "dev": true, "requires": { "lodash.get": "^4.4.2", "lodash.zip": "^4.2.0" @@ -2850,6 +15088,7 @@ "version": "6.11.0", "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.11.0.tgz", "integrity": "sha512-oB8cpLWSAjOVFEJhhyMZh6NOEOtBVziaqdDQ86+qhDHFbZXoRTM7pNSvFRfW/W/L/LrQ38C99J5CGuRBBzBsdA==", + "dev": true, "requires": { "get-stdin": "^6.0.0" } @@ -2857,12 +15096,15 @@ "eslint-config-standard": { "version": "16.0.3", "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-16.0.3.tgz", - "integrity": "sha512-x4fmJL5hGqNJKGHSjnLdgA6U6h1YW/G2dW9fA+cyVur4SK6lyue8+UgNKWlZtUDTXvgKDD/Oa3GQjmB5kjtVvg==" + "integrity": "sha512-x4fmJL5hGqNJKGHSjnLdgA6U6h1YW/G2dW9fA+cyVur4SK6lyue8+UgNKWlZtUDTXvgKDD/Oa3GQjmB5kjtVvg==", + "dev": true, + "requires": {} }, "eslint-config-standardize": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/eslint-config-standardize/-/eslint-config-standardize-0.7.2.tgz", "integrity": "sha512-n2dt7la221Qig7FjQsrKn5NyK5jSEkkAy7xWSnY96XdG7H9FcUSDt5I1THyA6zHwEYcAtUFv8VOPBOK6oYEvfg==", + "dev": true, "requires": { "@jsbits/deep-clone": "~1.1.1", "@typescript-eslint/eslint-plugin": "^4.14.0", @@ -2882,6 +15124,7 @@ "version": "0.3.4", "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz", "integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==", + "dev": true, "requires": { "debug": "^2.6.9", "resolve": "^1.13.1" @@ -2891,6 +15134,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, "requires": { "ms": "2.0.0" } @@ -2898,7 +15142,8 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true } } }, @@ -2906,6 +15151,7 @@ "version": "2.6.1", "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.1.tgz", "integrity": "sha512-ZXI9B8cxAJIH4nfkhTwcRTEAnrVfobYqwjWy/QMCZ8rHkZHFjf9yO4BzpiF9kCSfNlMG54eKigISHpX0+AaT4A==", + "dev": true, "requires": { "debug": "^3.2.7", "pkg-dir": "^2.0.0" @@ -2915,6 +15161,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "dev": true, "requires": { "eslint-utils": "^2.0.0", "regexpp": "^3.0.0" @@ -2924,6 +15171,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, "requires": { "eslint-visitor-keys": "^1.1.0" } @@ -2931,7 +15179,8 @@ "eslint-visitor-keys": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==" + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true } } }, @@ -2939,6 +15188,7 @@ "version": "2.22.1", "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz", "integrity": "sha512-8K7JjINHOpH64ozkAhpT3sd+FswIZTfMZTjdx052pnWrgRCVfp8op9tbjpAk3DdUeI/Ba4C8OjdC0r90erHEOw==", + "dev": true, "requires": { "array-includes": "^3.1.1", "array.prototype.flat": "^1.2.3", @@ -2959,6 +15209,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, "requires": { "ms": "2.0.0" } @@ -2967,6 +15218,7 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, "requires": { "esutils": "^2.0.2", "isarray": "^1.0.0" @@ -2975,7 +15227,8 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true } } }, @@ -2983,6 +15236,7 @@ "version": "11.1.0", "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", + "dev": true, "requires": { "eslint-plugin-es": "^3.0.0", "eslint-utils": "^2.0.0", @@ -2996,6 +15250,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, "requires": { "eslint-visitor-keys": "^1.1.0" } @@ -3003,12 +15258,14 @@ "eslint-visitor-keys": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==" + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true } } }, @@ -3016,6 +15273,7 @@ "version": "0.14.0", "resolved": "https://registry.npmjs.org/eslint-plugin-prettierx/-/eslint-plugin-prettierx-0.14.0.tgz", "integrity": "sha512-Ak/sI2LO0B73qEFjepPNUplxLadqpT3BU/I16ExZ0mY1CjpjoJxiyKe7Nbb0VEH4XO4SbjhngGPSsod+S3/HPA==", + "dev": true, "requires": { "eslint-config-prettier": "~6.11.0", "prettier-linter-helpers": "~1.0.0", @@ -3025,12 +15283,14 @@ "eslint-plugin-promise": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz", - "integrity": "sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw==" + "integrity": "sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw==", + "dev": true }, "eslint-plugin-react": { "version": "7.22.0", "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.22.0.tgz", "integrity": "sha512-p30tuX3VS+NWv9nQot9xIGAHBXR0+xJVaZriEsHoJrASGCJZDJ8JLNM0YqKqI0AKm6Uxaa1VUHoNEibxRCMQHA==", + "dev": true, "requires": { "array-includes": "^3.1.1", "array.prototype.flatmap": "^1.2.3", @@ -3049,6 +15309,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, "requires": { "esutils": "^2.0.2" } @@ -3057,6 +15318,7 @@ "version": "1.20.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dev": true, "requires": { "is-core-module": "^2.2.0", "path-parse": "^1.0.6" @@ -3067,12 +15329,15 @@ "eslint-plugin-react-hooks": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.2.0.tgz", - "integrity": "sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ==" + "integrity": "sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ==", + "dev": true, + "requires": {} }, "eslint-plugin-unicorn": { "version": "26.0.1", "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-26.0.1.tgz", "integrity": "sha512-SWgF9sIVY74zqkkSN2dclSCqRfocWSUGD0haC0NX2oRfmdp9p8dQvJYkYSQePaCyssPUE/pqpsIEEZNTh8crUA==", + "dev": true, "requires": { "ci-info": "^2.0.0", "clean-regexp": "^1.0.0", @@ -3093,6 +15358,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, "requires": { "eslint-visitor-keys": "^1.1.0" } @@ -3100,12 +15366,14 @@ "eslint-visitor-keys": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==" + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true }, "find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, "requires": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -3115,6 +15383,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, "requires": { "p-locate": "^4.1.0" } @@ -3123,6 +15392,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, "requires": { "p-try": "^2.0.0" } @@ -3131,6 +15401,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, "requires": { "p-limit": "^2.2.0" } @@ -3138,12 +15409,14 @@ "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true }, "parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -3154,12 +15427,14 @@ "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true }, "read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, "requires": { "@types/normalize-package-data": "^2.4.0", "normalize-package-data": "^2.5.0", @@ -3170,7 +15445,8 @@ "type-fest": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==" + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true } } }, @@ -3178,6 +15454,7 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, "requires": { "find-up": "^4.1.0", "read-pkg": "^5.2.0", @@ -3188,6 +15465,7 @@ "version": "7.3.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, "requires": { "lru-cache": "^6.0.0" } @@ -3195,7 +15473,8 @@ "type-fest": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true } } }, @@ -3203,6 +15482,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, "requires": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -3212,6 +15492,7 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/eslint-template-visitor/-/eslint-template-visitor-2.3.2.tgz", "integrity": "sha512-3ydhqFpuV7x1M9EK52BPNj6V0Kwu0KKkcIAfpUhwHbR8ocRln/oUHgfxQupY8O1h4Qv/POHDumb/BwwNfxbtnA==", + "dev": true, "requires": { "@babel/core": "^7.12.16", "@babel/eslint-parser": "^7.12.16", @@ -3224,7 +15505,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "optional": true, + "dev": true, "requires": { "eslint-visitor-keys": "^2.0.0" } @@ -3232,12 +15513,14 @@ "eslint-visitor-keys": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==" + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true }, "espree": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "dev": true, "requires": { "acorn": "^7.4.0", "acorn-jsx": "^5.3.1", @@ -3247,7 +15530,8 @@ "eslint-visitor-keys": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==" + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true } } }, @@ -3260,6 +15544,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, "requires": { "estraverse": "^5.1.0" }, @@ -3267,7 +15552,8 @@ "estraverse": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==" + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true } } }, @@ -3275,6 +15561,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, "requires": { "estraverse": "^5.2.0" }, @@ -3282,19 +15569,22 @@ "estraverse": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==" + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true } } }, "estraverse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true }, "esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true }, "exit-on-epipe": { "version": "1.0.1", @@ -3305,6 +15595,7 @@ "version": "27.0.6", "resolved": "https://registry.npmjs.org/expect/-/expect-27.0.6.tgz", "integrity": "sha512-psNLt8j2kwg42jGBDSfAlU49CEZxejN1f1PlANWDZqIhBOVU/c2Pm888FcjWJzFewhIsNWfZJeLjUjtKGiPuSw==", + "dev": true, "requires": { "@jest/types": "^27.0.6", "ansi-styles": "^5.0.0", @@ -3317,7 +15608,8 @@ "ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==" + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true } } }, @@ -3339,13 +15631,14 @@ "fast-diff": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==" + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true }, "fast-glob": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", - "optional": true, + "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -3362,12 +15655,14 @@ "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true }, "fastq": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.1.tgz", "integrity": "sha512-HOnr8Mc60eNYl1gzwp6r5RoUyAn5/glBolUzP/Ez6IFVPMPirxn/9phgL6zhOtaTy7ISwPvQ+wT+hfcRZh/bzw==", + "dev": true, "requires": { "reusify": "^1.0.4" } @@ -3381,6 +15676,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, "requires": { "flat-cache": "^3.0.4" } @@ -3389,6 +15685,7 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, "requires": { "to-regex-range": "^5.0.1" } @@ -3397,6 +15694,7 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", + "dev": true, "requires": { "commondir": "^1.0.1", "make-dir": "^3.0.2", @@ -3407,6 +15705,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, "requires": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -3416,6 +15715,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, "requires": { "p-locate": "^4.1.0" } @@ -3424,6 +15724,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, "requires": { "p-try": "^2.0.0" } @@ -3432,6 +15733,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, "requires": { "p-limit": "^2.2.0" } @@ -3439,17 +15741,20 @@ "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true }, "pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, "requires": { "find-up": "^4.0.0" } @@ -3459,17 +15764,20 @@ "find-parent-dir": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/find-parent-dir/-/find-parent-dir-0.3.0.tgz", - "integrity": "sha1-M8RLQpqysvBkYpnF+fcY83b/jVQ=" + "integrity": "sha1-M8RLQpqysvBkYpnF+fcY83b/jVQ=", + "dev": true }, "find-project-root": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/find-project-root/-/find-project-root-1.1.1.tgz", - "integrity": "sha1-0kJyei2QRyXfVxTyPf3N7doLbvg=" + "integrity": "sha1-0kJyei2QRyXfVxTyPf3N7doLbvg=", + "dev": true }, "find-up": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, "requires": { "locate-path": "^2.0.0" } @@ -3477,12 +15785,14 @@ "flat": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==" + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true }, "flat-cache": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, "requires": { "flatted": "^3.1.0", "rimraf": "^3.0.2" @@ -3491,17 +15801,20 @@ "flatted": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.1.tgz", - "integrity": "sha512-OMQjaErSFHmHqZe+PSidH5n8j3O0F2DdnVh8JB4j4eUQ2k6KvB0qGfrKIhapvez5JerBbmWkaLYUYWISaESoXg==" + "integrity": "sha512-OMQjaErSFHmHqZe+PSidH5n8j3O0F2DdnVh8JB4j4eUQ2k6KvB0qGfrKIhapvez5JerBbmWkaLYUYWISaESoXg==", + "dev": true }, "flatten": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.3.tgz", - "integrity": "sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg==" + "integrity": "sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg==", + "dev": true }, "foreground-child": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "dev": true, "requires": { "cross-spawn": "^7.0.0", "signal-exit": "^3.0.2" @@ -3525,7 +15838,8 @@ "fromentries": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", - "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==" + "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", + "dev": true }, "fs-constants": { "version": "1.0.0", @@ -3575,12 +15889,14 @@ "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true }, "functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true }, "gauge": { "version": "2.7.4", @@ -3600,17 +15916,20 @@ "gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true }, "get-intrinsic": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, "requires": { "function-bind": "^1.1.1", "has": "^1.0.3", @@ -3620,12 +15939,14 @@ "get-package-type": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==" + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true }, "get-stdin": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", - "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==" + "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", + "dev": true }, "get-stream": { "version": "5.2.0", @@ -3646,11 +15967,11 @@ "git-config-path": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/git-config-path/-/git-config-path-2.0.0.tgz", - "integrity": "sha512-qc8h1KIQbJpp+241id3GuAtkdyJ+IK+LIVtkiFTRKRrmddDzs3SI9CvP1QYmWBFvm1I/PWRwj//of8bgAc0ltA==" + "integrity": "sha512-qc8h1KIQbJpp+241id3GuAtkdyJ+IK+LIVtkiFTRKRrmddDzs3SI9CvP1QYmWBFvm1I/PWRwj//of8bgAc0ltA==", + "dev": true }, "git-documentdb-plugin-remote-nodegit": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.3.tgz", + "version": "https://registry.npmjs.org/git-documentdb-plugin-remote-nodegit/-/git-documentdb-plugin-remote-nodegit-1.0.3.tgz", "integrity": "sha512-80cxPE+jIjDpECCXAmNtjZxMFVNc38yFkZmEd3hRp6EvSQhX6nky0kmEFWZ1aeFnTq0oATEJvEJg9yO8zYkyng==", "requires": { "git-documentdb-remote-errors": "^1.0.3", @@ -3680,6 +16001,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, "requires": { "is-glob": "^4.0.1" } @@ -3688,6 +16010,7 @@ "version": "13.10.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.10.0.tgz", "integrity": "sha512-piHC3blgLGFjvOuMmWZX60f+na1lXFDhQXBf1UYp2fXPXqvEUbOhNwi6BsQ0bQishwedgnjkwv1d9zKf+MWw3g==", + "dev": true, "requires": { "type-fest": "^0.20.2" }, @@ -3695,7 +16018,8 @@ "type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==" + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true } } }, @@ -3703,7 +16027,7 @@ "version": "11.0.4", "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", - "optional": true, + "dev": true, "requires": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -3717,6 +16041,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/glub/-/glub-1.0.3.tgz", "integrity": "sha1-VsFkMpiuJQZcYxUAMze7pp0vuGY=", + "dev": true, "requires": { "glob": "^5.0.5", "minimist": "^1.1.1" @@ -3726,6 +16051,7 @@ "version": "5.0.15", "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dev": true, "requires": { "inflight": "^1.0.4", "inherits": "2", @@ -3766,17 +16092,20 @@ "graphql": { "version": "15.3.0", "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.3.0.tgz", - "integrity": "sha512-GTCJtzJmkFLWRfFJuoo9RWWa/FfamUHgiFosxi/X1Ani4AVWbeyBenZTNX6dM+7WSbbFfTo/25eh0LLkwHMw2w==" + "integrity": "sha512-GTCJtzJmkFLWRfFJuoo9RWWa/FfamUHgiFosxi/X1Ani4AVWbeyBenZTNX6dM+7WSbbFfTo/25eh0LLkwHMw2w==", + "dev": true }, "growl": { "version": "1.10.5", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==" + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true }, "handlebars": { "version": "4.7.7", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "dev": true, "requires": { "minimist": "^1.2.5", "neo-async": "^2.6.0", @@ -3803,6 +16132,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, "requires": { "function-bind": "^1.1.1" } @@ -3810,7 +16140,8 @@ "has-bigints": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==" + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "dev": true }, "has-flag": { "version": "3.0.0", @@ -3820,7 +16151,8 @@ "has-symbols": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true }, "has-unicode": { "version": "2.0.1", @@ -3831,6 +16163,7 @@ "version": "5.2.2", "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", + "dev": true, "requires": { "is-stream": "^2.0.0", "type-fest": "^0.8.0" @@ -3839,39 +16172,46 @@ "type-fest": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true } } }, "he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true }, "hosted-git-info": { "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==" + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true }, "html-element-attributes": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/html-element-attributes/-/html-element-attributes-2.2.1.tgz", - "integrity": "sha512-gGTgCeQu+g1OFExZKWQ1LwbFXxLJ6cGdCGj64ByEaxatr/EPVc23D6Gxngb37ao+SNInP/sGu8FXxRsSxMm7aQ==" + "integrity": "sha512-gGTgCeQu+g1OFExZKWQ1LwbFXxLJ6cGdCGj64ByEaxatr/EPVc23D6Gxngb37ao+SNInP/sGu8FXxRsSxMm7aQ==", + "dev": true }, "html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true }, "html-styles": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/html-styles/-/html-styles-1.0.0.tgz", - "integrity": "sha1-oYBh/WUfmca3XEXI4FSaO8PgGnU=" + "integrity": "sha1-oYBh/WUfmca3XEXI4FSaO8PgGnU=", + "dev": true }, "html-tag-names": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/html-tag-names/-/html-tag-names-1.1.5.tgz", - "integrity": "sha512-aI5tKwNTBzOZApHIynaAwecLBv8TlZTEy/P4Sj2SzzAhBrGuI8yGZ0UIXVPQzOHGS+to2mjb04iy6VWt/8+d8A==" + "integrity": "sha512-aI5tKwNTBzOZApHIynaAwecLBv8TlZTEy/P4Sj2SzzAhBrGuI8yGZ0UIXVPQzOHGS+to2mjb04iy6VWt/8+d8A==", + "dev": true }, "http-cache-semantics": { "version": "4.1.0", @@ -3913,6 +16253,7 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, "requires": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -3921,27 +16262,32 @@ "import-lazy": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", - "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==" + "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", + "dev": true }, "import-modules": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/import-modules/-/import-modules-2.1.0.tgz", - "integrity": "sha512-8HEWcnkbGpovH9yInoisxaSoIg9Brbul+Ju3Kqe2UsYDUBJD/iQjSgEj0zPcTDPKfPp2fs5xlv1i+JSye/m1/A==" + "integrity": "sha512-8HEWcnkbGpovH9yInoisxaSoIg9Brbul+Ju3Kqe2UsYDUBJD/iQjSgEj0zPcTDPKfPp2fs5xlv1i+JSye/m1/A==", + "dev": true }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true }, "indent-string": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==" + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true }, "indexes-of": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", - "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=" + "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", + "dev": true }, "inflight": { "version": "1.0.6", @@ -3966,6 +16312,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dev": true, "requires": { "get-intrinsic": "^1.1.0", "has": "^1.0.3", @@ -3975,12 +16322,14 @@ "is-alphabetical": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", - "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==" + "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", + "dev": true }, "is-alphanumerical": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", + "dev": true, "requires": { "is-alphabetical": "^1.0.0", "is-decimal": "^1.0.0" @@ -3989,17 +16338,20 @@ "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true }, "is-bigint": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz", - "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==" + "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==", + "dev": true }, "is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, "requires": { "binary-extensions": "^2.0.0" } @@ -4008,6 +16360,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz", "integrity": "sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng==", + "dev": true, "requires": { "call-bind": "^1.0.2" } @@ -4015,17 +16368,20 @@ "is-buffer": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==" + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "dev": true }, "is-callable": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", - "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==" + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", + "dev": true }, "is-core-module": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", + "dev": true, "requires": { "has": "^1.0.3" } @@ -4033,17 +16389,20 @@ "is-date-object": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz", - "integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==" + "integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==", + "dev": true }, "is-decimal": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", - "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==" + "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", + "dev": true }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true }, "is-fullwidth-code-point": { "version": "1.0.0", @@ -4057,6 +16416,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, "requires": { "is-extglob": "^2.1.1" } @@ -4064,27 +16424,32 @@ "is-hexadecimal": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", - "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==" + "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", + "dev": true }, "is-negative-zero": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==" + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "dev": true }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true }, "is-number-object": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz", - "integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==" + "integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==", + "dev": true }, "is-plain-obj": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==" + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true }, "is-plain-object": { "version": "5.0.0", @@ -4095,6 +16460,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", + "dev": true, "requires": { "call-bind": "^1.0.2", "has-symbols": "^1.0.2" @@ -4103,17 +16469,20 @@ "is-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true }, "is-string": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz", - "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==" + "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==", + "dev": true }, "is-symbol": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, "requires": { "has-symbols": "^1.0.2" } @@ -4126,17 +16495,20 @@ "is-whitespace-character": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz", - "integrity": "sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==" + "integrity": "sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==", + "dev": true }, "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true }, "is-word-character": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.4.tgz", - "integrity": "sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA==" + "integrity": "sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA==", + "dev": true }, "isarray": { "version": "1.0.0", @@ -4149,8 +16521,7 @@ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, "isomorphic-git": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/isomorphic-git/-/isomorphic-git-1.9.1.tgz", + "version": "https://registry.npmjs.org/isomorphic-git/-/isomorphic-git-1.9.1.tgz", "integrity": "sha512-vzceJaiBdaJI5aT1di4dxWWf6sao3WQFQJ6UTi1tXO4zyDfsuyIadVOA4YQzdwKhLilV9msgM8HIvpOE94kmQg==", "requires": { "async-lock": "^1.1.0", @@ -4186,12 +16557,14 @@ "istanbul-lib-coverage": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", - "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==" + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", + "dev": true }, "istanbul-lib-hook": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", + "dev": true, "requires": { "append-transform": "^2.0.0" } @@ -4200,6 +16573,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, "requires": { "@babel/core": "^7.7.5", "@istanbuljs/schema": "^0.1.2", @@ -4210,7 +16584,8 @@ "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true } } }, @@ -4218,6 +16593,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz", "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==", + "dev": true, "requires": { "archy": "^1.0.0", "cross-spawn": "^7.0.0", @@ -4232,6 +16608,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, "requires": { "istanbul-lib-coverage": "^3.0.0", "make-dir": "^3.0.0", @@ -4241,12 +16618,14 @@ "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "requires": { "has-flag": "^4.0.0" } @@ -4257,6 +16636,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "dev": true, "requires": { "debug": "^4.1.1", "istanbul-lib-coverage": "^3.0.0", @@ -4267,6 +16647,7 @@ "version": "4.3.2", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, "requires": { "ms": "2.1.2" } @@ -4274,7 +16655,8 @@ "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true } } }, @@ -4282,6 +16664,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "dev": true, "requires": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" @@ -4291,6 +16674,7 @@ "version": "27.0.6", "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.0.6.tgz", "integrity": "sha512-Z1mqgkTCSYaFgwTlP/NUiRzdqgxmmhzHY1Tq17zL94morOHfHu3K4bgSgl+CR4GLhpV8VxkuOYuIWnQ9LnFqmg==", + "dev": true, "requires": { "chalk": "^4.0.0", "diff-sequences": "^27.0.6", @@ -4302,6 +16686,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "requires": { "color-convert": "^2.0.1" } @@ -4310,6 +16695,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -4319,6 +16705,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "requires": { "color-name": "~1.1.4" } @@ -4326,17 +16713,20 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "requires": { "has-flag": "^4.0.0" } @@ -4347,6 +16737,7 @@ "version": "26.0.0", "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==", + "dev": true, "requires": { "detect-newline": "^3.0.0" } @@ -4354,12 +16745,14 @@ "jest-get-type": { "version": "27.0.6", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", - "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==" + "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", + "dev": true }, "jest-matcher-utils": { "version": "27.0.6", "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.0.6.tgz", "integrity": "sha512-OFgF2VCQx9vdPSYTHWJ9MzFCehs20TsyFi6bIHbk5V1u52zJOnvF0Y/65z3GLZHKRuTgVPY4Z6LVePNahaQ+tA==", + "dev": true, "requires": { "chalk": "^4.0.0", "jest-diff": "^27.0.6", @@ -4371,6 +16764,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "requires": { "color-convert": "^2.0.1" } @@ -4379,6 +16773,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -4388,6 +16783,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "requires": { "color-name": "~1.1.4" } @@ -4395,17 +16791,20 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "requires": { "has-flag": "^4.0.0" } @@ -4416,6 +16815,7 @@ "version": "27.0.6", "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.0.6.tgz", "integrity": "sha512-rBxIs2XK7rGy+zGxgi+UJKP6WqQ+KrBbD1YMj517HYN3v2BG66t3Xan3FWqYHKZwjdB700KiAJ+iES9a0M+ixw==", + "dev": true, "requires": { "@babel/code-frame": "^7.12.13", "@jest/types": "^27.0.6", @@ -4432,6 +16832,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "requires": { "color-convert": "^2.0.1" } @@ -4440,6 +16841,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -4449,6 +16851,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "requires": { "color-name": "~1.1.4" } @@ -4456,17 +16859,20 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "requires": { "has-flag": "^4.0.0" } @@ -4476,17 +16882,20 @@ "jest-regex-util": { "version": "27.0.6", "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.0.6.tgz", - "integrity": "sha512-SUhPzBsGa1IKm8hx2F4NfTGGp+r7BXJ4CulsZ1k2kI+mGLG+lxGrs76veN2LF/aUdGosJBzKgXmNCw+BzFqBDQ==" + "integrity": "sha512-SUhPzBsGa1IKm8hx2F4NfTGGp+r7BXJ4CulsZ1k2kI+mGLG+lxGrs76veN2LF/aUdGosJBzKgXmNCw+BzFqBDQ==", + "dev": true }, "jju": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", - "integrity": "sha1-o6vicYryQaKykE+EpiWXDzia4yo=" + "integrity": "sha1-o6vicYryQaKykE+EpiWXDzia4yo=", + "dev": true }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true }, "js-yaml": { "version": "3.13.1", @@ -4505,7 +16914,8 @@ "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true }, "json-buffer": { "version": "3.0.1", @@ -4515,7 +16925,8 @@ "json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true }, "json-schema": { "version": "0.2.3", @@ -4531,6 +16942,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "dev": true, "requires": { "jsonify": "~0.0.0" } @@ -4538,7 +16950,8 @@ "json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=" + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true }, "json-stringify-safe": { "version": "5.0.1", @@ -4564,7 +16977,8 @@ "jsonify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=" + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true }, "jsprim": { "version": "1.4.1", @@ -4581,6 +16995,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz", "integrity": "sha512-EIsmt3O3ljsU6sot/J4E1zDRxfBNrhjyf/OKjlydwgEimQuznlM4Wv7U+ueONJMyEn1WRE0K8dhi3dVAXYT24Q==", + "dev": true, "requires": { "array-includes": "^3.1.2", "object.assign": "^4.1.2" @@ -4589,7 +17004,8 @@ "just-extend": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", - "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==" + "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", + "dev": true }, "keyv": { "version": "4.0.3", @@ -4602,17 +17018,20 @@ "lcov-parse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-1.0.0.tgz", - "integrity": "sha1-6w1GtUER68VhrLTECO+TY73I9+A=" + "integrity": "sha1-6w1GtUER68VhrLTECO+TY73I9+A=", + "dev": true }, "leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==" + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true }, "levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, "requires": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -4621,17 +17040,20 @@ "lines-and-columns": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=" + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true }, "linguist-languages": { "version": "7.10.0", "resolved": "https://registry.npmjs.org/linguist-languages/-/linguist-languages-7.10.0.tgz", - "integrity": "sha512-Uqt94P4iAznscZtccnNE1IBi105U+fmQKEUlDJv54JDdFZDInomkepEIRpZLOQcPyGdcNu3JO9Tvo5wpQVbfKw==" + "integrity": "sha512-Uqt94P4iAznscZtccnNE1IBi105U+fmQKEUlDJv54JDdFZDInomkepEIRpZLOQcPyGdcNu3JO9Tvo5wpQVbfKw==", + "dev": true }, "load-json-file": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, "requires": { "graceful-fs": "^4.1.2", "parse-json": "^2.2.0", @@ -4642,7 +17064,8 @@ "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true } } }, @@ -4650,6 +17073,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, "requires": { "p-locate": "^2.0.0", "path-exists": "^3.0.0" @@ -4663,47 +17087,56 @@ "lodash.clonedeep": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true }, "lodash.flattendeep": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=" + "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", + "dev": true }, "lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "dev": true }, "lodash.isequal": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", - "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" + "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=", + "dev": true }, "lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true }, "lodash.truncate": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=" + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true }, "lodash.zip": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.zip/-/lodash.zip-4.2.0.tgz", - "integrity": "sha1-7GZi5IlkCO1KtsVCo5kLcswIACA=" + "integrity": "sha1-7GZi5IlkCO1KtsVCo5kLcswIACA=", + "dev": true }, "log-driver": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", - "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==" + "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", + "dev": true }, "log-symbols": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "dev": true, "requires": { "chalk": "^4.0.0" }, @@ -4712,6 +17145,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "requires": { "color-convert": "^2.0.1" } @@ -4720,6 +17154,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -4729,6 +17164,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "requires": { "color-name": "~1.1.4" } @@ -4736,17 +17172,20 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "requires": { "has-flag": "^4.0.0" } @@ -4757,6 +17196,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, "requires": { "js-tokens": "^3.0.0 || ^4.0.0" } @@ -4785,6 +17225,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, "requires": { "semver": "^6.0.0" }, @@ -4792,19 +17233,22 @@ "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true } } }, "make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true }, "map-age-cleaner": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "dev": true, "requires": { "p-defer": "^1.0.0" } @@ -4812,12 +17256,14 @@ "markdown-escapes": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.4.tgz", - "integrity": "sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==" + "integrity": "sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==", + "dev": true }, "mem": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/mem/-/mem-6.1.1.tgz", "integrity": "sha512-Ci6bIfq/UgcxPTYa8dQQ5FY3BzKkT894bwXWXxC/zqs0XgMO2cT20CGkOqda7gZNkmK5VP4x89IGZ6K7hfbn3Q==", + "dev": true, "requires": { "map-age-cleaner": "^0.1.3", "mimic-fn": "^3.0.0" @@ -4826,12 +17272,14 @@ "merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true }, "micromatch": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, "requires": { "braces": "^3.0.1", "picomatch": "^2.2.3" @@ -4853,7 +17301,8 @@ "mimic-fn": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz", - "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==" + "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==", + "dev": true }, "mimic-response": { "version": "2.1.0", @@ -4910,6 +17359,7 @@ "version": "8.4.0", "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.4.0.tgz", "integrity": "sha512-hJaO0mwDXmZS4ghXsvPVriOhsxQ7ofcpQdm8dE+jISUOKopitvnXFQmpRR7jd2K6VBG6E26gU3IAbXXGIbu4sQ==", + "dev": true, "requires": { "@ungap/promise-all-settled": "1.1.2", "ansi-colors": "4.1.1", @@ -4941,12 +17391,14 @@ "argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true }, "debug": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, "requires": { "ms": "2.1.2" }, @@ -4954,24 +17406,28 @@ "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true } } }, "diff": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==" + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true }, "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true }, "find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, "requires": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -4981,6 +17437,7 @@ "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -4993,12 +17450,14 @@ "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true }, "js-yaml": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", + "dev": true, "requires": { "argparse": "^2.0.1" } @@ -5007,6 +17466,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, "requires": { "p-locate": "^5.0.0" } @@ -5015,6 +17475,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, "requires": { "yocto-queue": "^0.1.0" } @@ -5023,6 +17484,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, "requires": { "p-limit": "^3.0.2" } @@ -5030,17 +17492,20 @@ "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true }, "strip-json-comments": { "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==" + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true }, "supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, "requires": { "has-flag": "^4.0.0" } @@ -5049,6 +17514,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, "requires": { "isexe": "^2.0.0" } @@ -5063,12 +17529,14 @@ "multimap": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/multimap/-/multimap-1.1.0.tgz", - "integrity": "sha512-0ZIR9PasPxGXmRsEF8jsDzndzHDj7tIav+JUmvIFB/WHswliFnquxECT/De7GR4yg99ky/NlRKJT82G1y271bw==" + "integrity": "sha512-0ZIR9PasPxGXmRsEF8jsDzndzHDj7tIav+JUmvIFB/WHswliFnquxECT/De7GR4yg99ky/NlRKJT82G1y271bw==", + "dev": true }, "n-readlines": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/n-readlines/-/n-readlines-1.0.1.tgz", - "integrity": "sha512-z4SyAIVgMy7CkgsoNw7YVz40v0g4+WWvvqy8+ZdHrCtgevcEO758WQyrYcw3XPxcLxF+//RszTz/rO48nzD0wQ==" + "integrity": "sha512-z4SyAIVgMy7CkgsoNw7YVz40v0g4+WWvvqy8+ZdHrCtgevcEO758WQyrYcw3XPxcLxF+//RszTz/rO48nzD0wQ==", + "dev": true }, "nan": { "version": "2.14.2", @@ -5078,12 +17546,14 @@ "nanoid": { "version": "3.1.20", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", - "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==" + "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==", + "dev": true }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true }, "needle": { "version": "2.8.0", @@ -5098,12 +17568,14 @@ "neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true }, "nise": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/nise/-/nise-4.1.0.tgz", "integrity": "sha512-eQMEmGN/8arp0xsvGoQ+B1qvSkR73B1nWSCh7nOt5neMCtwcQVYQGdzQMhcNscktTsWB54xnlSQFzOAPJD8nXA==", + "dev": true, "requires": { "@sinonjs/commons": "^1.7.0", "@sinonjs/fake-timers": "^6.0.0", @@ -5130,6 +17602,7 @@ "osenv": "0", "request": "^2.87.0", "rimraf": "2", + "semver": "~5.3.0", "tar": "^4.4.8", "which": "1" }, @@ -5143,8 +17616,7 @@ } }, "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "version": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "requires": { "lru-cache": "^6.0.0" @@ -5249,6 +17721,7 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", + "dev": true, "requires": { "process-on-spawn": "^1.0.0" } @@ -5256,7 +17729,8 @@ "node-releases": { "version": "1.1.73", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.73.tgz", - "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==" + "integrity": "sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==", + "dev": true }, "nodegit": { "version": "0.27.0", @@ -5298,6 +17772,7 @@ "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, "requires": { "hosted-git-info": "^2.1.4", "resolve": "^1.10.0", @@ -5308,7 +17783,8 @@ "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true }, "normalize-url": { "version": "6.1.0", @@ -5358,6 +17834,7 @@ "version": "15.1.0", "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", + "dev": true, "requires": { "@istanbuljs/load-nyc-config": "^1.0.0", "@istanbuljs/schema": "^0.1.2", @@ -5391,12 +17868,14 @@ "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "requires": { "color-convert": "^2.0.1" } @@ -5404,12 +17883,14 @@ "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true }, "cliui": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, "requires": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", @@ -5420,6 +17901,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "requires": { "color-name": "~1.1.4" } @@ -5427,17 +17909,20 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true }, "find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, "requires": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -5446,12 +17931,14 @@ "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, "requires": { "p-locate": "^4.1.0" } @@ -5460,6 +17947,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, "requires": { "p-try": "^2.0.0" } @@ -5468,6 +17956,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, "requires": { "p-limit": "^2.2.0" } @@ -5475,22 +17964,26 @@ "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true }, "resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true }, "string-width": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -5501,6 +17994,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, "requires": { "ansi-regex": "^5.0.0" } @@ -5509,6 +18003,7 @@ "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, "requires": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -5518,12 +18013,14 @@ "y18n": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==" + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true }, "yargs": { "version": "15.4.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, "requires": { "cliui": "^6.0.0", "decamelize": "^1.2.0", @@ -5542,6 +18039,7 @@ "version": "18.1.3", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, "requires": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" @@ -5562,17 +18060,20 @@ "object-inspect": { "version": "1.10.3", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz", - "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==" + "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==", + "dev": true }, "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true }, "object.assign": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, "requires": { "call-bind": "^1.0.0", "define-properties": "^1.1.3", @@ -5584,6 +18085,7 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.4.tgz", "integrity": "sha512-h4LWKWE+wKQGhtMjZEBud7uLGhqyLwj8fpHOarZhD2uY3C9cRtk57VQ89ke3moByLXMedqs3XCHzyb4AmA2DjA==", + "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", @@ -5594,6 +18096,7 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.4.tgz", "integrity": "sha512-EsFBshs5RUUpQEY1D4q/m59kMfz4YJvxuNCJcv/jWwOJr34EaVnG11ZrZa0UHB3wnzV1wx8m58T4hQL8IuNXlQ==", + "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", @@ -5605,6 +18108,7 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.4.tgz", "integrity": "sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg==", + "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", @@ -5623,6 +18127,7 @@ "version": "0.9.1", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, "requires": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", @@ -5682,7 +18187,8 @@ "p-defer": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", - "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=" + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", + "dev": true }, "p-event": { "version": "4.2.0", @@ -5701,6 +18207,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, "requires": { "p-try": "^1.0.0" } @@ -5709,6 +18216,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, "requires": { "p-limit": "^1.1.0" } @@ -5717,6 +18225,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, "requires": { "aggregate-error": "^3.0.0" } @@ -5732,12 +18241,14 @@ "p-try": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true }, "package-hash": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", + "dev": true, "requires": { "graceful-fs": "^4.1.15", "hasha": "^5.0.0", @@ -5754,6 +18265,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, "requires": { "callsites": "^3.0.0" } @@ -5762,6 +18274,7 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.2.2.tgz", "integrity": "sha512-NzfpbxW/NPrzZ/yYSoQxyqUZMZXIdCfE0OIN4ESsnptHJECoUk3FZktxNuzQf4tjt5UEopnxpYJbvYuxIFDdsg==", + "dev": true, "requires": { "character-entities": "^1.0.0", "character-entities-legacy": "^1.0.0", @@ -5775,6 +18288,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/parse-git-config/-/parse-git-config-3.0.0.tgz", "integrity": "sha512-wXoQGL1D+2COYWCD35/xbiKma1Z15xvZL8cI25wvxzled58V51SJM04Urt/uznS900iQor7QO04SgdfT/XlbuA==", + "dev": true, "requires": { "git-config-path": "^2.0.0", "ini": "^1.3.5" @@ -5784,6 +18298,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, "requires": { "error-ex": "^1.2.0" } @@ -5791,7 +18306,8 @@ "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true }, "path-is-absolute": { "version": "1.0.1", @@ -5801,17 +18317,20 @@ "path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true }, "path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true }, "path-to-regexp": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "dev": true, "requires": { "isarray": "0.0.1" }, @@ -5819,14 +18338,16 @@ "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true } } }, "path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true }, "performance-now": { "version": "2.1.0", @@ -5836,7 +18357,8 @@ "picomatch": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==" + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true }, "pify": { "version": "4.0.1", @@ -5847,6 +18369,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, "requires": { "find-up": "^2.1.0" } @@ -5855,6 +18378,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", + "dev": true, "requires": { "semver-compare": "^1.0.0" } @@ -5862,12 +18386,14 @@ "pluralize": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", - "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==" + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true }, "postcss": { "version": "7.0.36", "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.36.tgz", "integrity": "sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw==", + "dev": true, "requires": { "chalk": "^2.4.2", "source-map": "^0.6.1", @@ -5878,6 +18404,7 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, "requires": { "has-flag": "^3.0.0" } @@ -5888,6 +18415,7 @@ "version": "3.1.4", "resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-3.1.4.tgz", "integrity": "sha512-7TvleQWNM2QLcHqvudt3VYjULVB49uiW6XzEUFmvwHzvsOEF5MwBrIXZDJQvJNFGjJQTzSzZnDoCJ8h/ljyGXA==", + "dev": true, "requires": { "postcss": "^7.0.14" } @@ -5895,12 +18423,14 @@ "postcss-media-query-parser": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", - "integrity": "sha1-J7Ocb02U+Bsac7j3Y1HGCeXO8kQ=" + "integrity": "sha1-J7Ocb02U+Bsac7j3Y1HGCeXO8kQ=", + "dev": true }, "postcss-scss": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-2.1.1.tgz", "integrity": "sha512-jQmGnj0hSGLd9RscFw9LyuSVAa5Bl1/KBPqG1NQw9w8ND55nY4ZEsdlVuYJvLPpV+y0nwTV5v/4rHPzZRihQbA==", + "dev": true, "requires": { "postcss": "^7.0.6" } @@ -5909,6 +18439,7 @@ "version": "2.2.3", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz", "integrity": "sha1-+UN3iGBsPJrO4W/+jYsWKX8nu5A=", + "dev": true, "requires": { "flatten": "^1.0.2", "indexes-of": "^1.0.1", @@ -5919,6 +18450,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/postcss-values-parser/-/postcss-values-parser-2.0.1.tgz", "integrity": "sha512-2tLuBsA6P4rYTNKCXYG/71C7j1pU6pK503suYOmn4xYrQIzW+opD+7FAFNuGSdZC/3Qfy334QbeMu7MEb8gOxg==", + "dev": true, "requires": { "flatten": "^1.0.2", "indexes-of": "^1.0.1", @@ -5928,12 +18460,14 @@ "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true }, "prettier-linter-helpers": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, "requires": { "fast-diff": "^1.1.2" } @@ -5942,6 +18476,7 @@ "version": "0.14.3", "resolved": "https://registry.npmjs.org/prettierx/-/prettierx-0.14.3.tgz", "integrity": "sha512-0VT3GgDAU6rvemeklrRzqVkILrGC1TSo/4STnsBqkreLx5Ck43W05lO60pMKWbG7SWM3DcUZZIR4FZ5pvvDwyQ==", + "dev": true, "requires": { "@angular/compiler": "9.0.5", "@babel/code-frame": "7.12.11", @@ -6007,6 +18542,7 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, "requires": { "@babel/highlight": "^7.10.4" } @@ -6014,12 +18550,14 @@ "@babel/parser": { "version": "7.12.0", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.0.tgz", - "integrity": "sha512-dYmySMYnlus2jwl7JnnajAj11obRStZoW9cG04wh4ZuhozDn11tDUrhHcUZ9iuNHqALAhh60XqNaYXpvuuE/Gg==" + "integrity": "sha512-dYmySMYnlus2jwl7JnnajAj11obRStZoW9cG04wh4ZuhozDn11tDUrhHcUZ9iuNHqALAhh60XqNaYXpvuuE/Gg==", + "dev": true }, "@typescript-eslint/typescript-estree": { "version": "2.34.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz", "integrity": "sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg==", + "dev": true, "requires": { "debug": "^4.1.1", "eslint-visitor-keys": "^1.1.0", @@ -6033,12 +18571,14 @@ "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "requires": { "color-convert": "^2.0.1" } @@ -6047,6 +18587,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -6056,6 +18597,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "requires": { "color-name": "~1.1.4" } @@ -6063,12 +18605,14 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "debug": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, "requires": { "ms": "2.1.2" } @@ -6076,17 +18620,20 @@ "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true }, "eslint-visitor-keys": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==" + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true }, "fast-glob": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", + "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -6099,12 +18646,14 @@ "get-stream": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.0.tgz", - "integrity": "sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg==" + "integrity": "sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg==", + "dev": true }, "globby": { "version": "11.0.1", "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", + "dev": true, "requires": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -6117,39 +18666,46 @@ "ignore": { "version": "5.1.8", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==" + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true } } }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true }, "ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true }, "lodash": { "version": "4.17.20", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", + "dev": true }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true }, "resolve": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "dev": true, "requires": { "is-core-module": "^2.1.0", "path-parse": "^1.0.6" @@ -6159,6 +18715,7 @@ "version": "7.3.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, "requires": { "lru-cache": "^6.0.0" } @@ -6167,6 +18724,7 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -6177,6 +18735,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, "requires": { "ansi-regex": "^5.0.0" } @@ -6185,6 +18744,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "requires": { "has-flag": "^4.0.0" } @@ -6195,6 +18755,7 @@ "version": "27.0.6", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.6.tgz", "integrity": "sha512-8tGD7gBIENgzqA+UBzObyWqQ5B778VIFZA/S66cclyd5YkFLYs2Js7gxDKf0MXtTc9zcS7t1xhdfcElJ3YIvkQ==", + "dev": true, "requires": { "@jest/types": "^27.0.6", "ansi-regex": "^5.0.0", @@ -6205,12 +18766,14 @@ "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true }, "ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==" + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true } } }, @@ -6228,6 +18791,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", + "dev": true, "requires": { "fromentries": "^1.2.0" } @@ -6235,12 +18799,14 @@ "progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true }, "prop-types": { "version": "15.7.2", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "dev": true, "requires": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -6250,14 +18816,16 @@ "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true } } }, "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true }, "psl": { "version": "1.8.0", @@ -6286,7 +18854,8 @@ "queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true }, "ramda": { "version": "0.25.0", @@ -6297,6 +18866,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, "requires": { "safe-buffer": "^5.1.0" } @@ -6315,12 +18885,14 @@ "react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true }, "read-pkg": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, "requires": { "load-json-file": "^2.0.0", "normalize-package-data": "^2.3.2", @@ -6331,6 +18903,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, "requires": { "pify": "^2.0.0" } @@ -6338,7 +18911,8 @@ "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true } } }, @@ -6346,6 +18920,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, "requires": { "find-up": "^2.0.0", "read-pkg": "^2.0.0" @@ -6369,6 +18944,7 @@ "version": "3.5.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "dev": true, "requires": { "picomatch": "^2.2.1" } @@ -6376,12 +18952,14 @@ "regexp-tree": { "version": "0.1.23", "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.23.tgz", - "integrity": "sha512-+7HWfb4Bvu8Rs2eQTUIpX9I/PlQkYOuTNbRpKLJlQpSgwSkzFYh+pUj0gtvglnOZLKB6YgnIgRuJ2/IlpL48qw==" + "integrity": "sha512-+7HWfb4Bvu8Rs2eQTUIpX9I/PlQkYOuTNbRpKLJlQpSgwSkzFYh+pUj0gtvglnOZLKB6YgnIgRuJ2/IlpL48qw==", + "dev": true }, "regexp-util": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/regexp-util/-/regexp-util-1.2.2.tgz", "integrity": "sha512-5/rl2UD18oAlLQEIuKBeiSIOp1hb5wCXcakl5yvHxlY1wyWI4D5cUKKzCibBeu741PA9JKvZhMqbkDQqPusX3w==", + "dev": true, "requires": { "tslib": "^1.9.0" } @@ -6390,6 +18968,7 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz", "integrity": "sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA==", + "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3" @@ -6398,12 +18977,14 @@ "regexpp": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==" + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true }, "release-zalgo": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", + "dev": true, "requires": { "es6-error": "^4.0.1" } @@ -6412,6 +18993,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/remark-math/-/remark-math-1.0.6.tgz", "integrity": "sha512-I43wU/QOQpXvVFXKjA4FHp5xptK65+5F6yolm8+69/JV0EqSOB64wURUZ3JK50JtnTL8FvwLiH2PZ+fvsBxviA==", + "dev": true, "requires": { "trim-trailing-lines": "^1.1.0" } @@ -6420,6 +19002,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-5.0.0.tgz", "integrity": "sha512-b3iXszZLH1TLoyUzrATcTQUZrwNl1rE70rVdSruJFlDaJ9z5aMkhrG43Pp68OgfHndL/ADz6V69Zow8cTQu+JA==", + "dev": true, "requires": { "collapse-white-space": "^1.0.2", "is-alphabetical": "^1.0.0", @@ -6441,7 +19024,8 @@ "repeat-string": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true }, "request": { "version": "2.88.2", @@ -6473,27 +19057,32 @@ "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true }, "require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true }, "require-main-filename": { "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==" + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true }, "reserved-words": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/reserved-words/-/reserved-words-0.1.2.tgz", - "integrity": "sha1-AKCUD5jNUBrqqsMWQR2a3FKzGrE=" + "integrity": "sha1-AKCUD5jNUBrqqsMWQR2a3FKzGrE=", + "dev": true }, "resolve": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, "requires": { "path-parse": "^1.0.6" } @@ -6501,7 +19090,8 @@ "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true }, "responselike": { "version": "2.0.0", @@ -6514,7 +19104,8 @@ "reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true }, "rimraf": { "version": "3.0.2", @@ -6528,6 +19119,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, "requires": { "queue-microtask": "^1.2.2" } @@ -6541,6 +19133,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz", "integrity": "sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==", + "dev": true, "requires": { "regexp-tree": "~0.1.1" } @@ -6563,12 +19156,14 @@ "semver-compare": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=" + "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", + "dev": true }, "serialize-javascript": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "dev": true, "requires": { "randombytes": "^2.1.0" } @@ -6591,6 +19186,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, "requires": { "shebang-regex": "^3.0.0" } @@ -6598,12 +19194,14 @@ "shebang-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true }, "side-channel": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, "requires": { "call-bind": "^1.0.0", "get-intrinsic": "^1.0.2", @@ -6613,7 +19211,8 @@ "sigmund": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", - "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=" + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", + "dev": true }, "signal-exit": { "version": "3.0.3", @@ -6648,12 +19247,14 @@ "simple-html-tokenizer": { "version": "0.5.11", "resolved": "https://registry.npmjs.org/simple-html-tokenizer/-/simple-html-tokenizer-0.5.11.tgz", - "integrity": "sha512-C2WEK/Z3HoSFbYq8tI7ni3eOo/NneSPRoPpcM7WdLjFOArFuyXEjAoCdOC3DgMfRyziZQ1hCNR4mrNdWEvD0og==" + "integrity": "sha512-C2WEK/Z3HoSFbYq8tI7ni3eOo/NneSPRoPpcM7WdLjFOArFuyXEjAoCdOC3DgMfRyziZQ1hCNR4mrNdWEvD0og==", + "dev": true }, "sinon": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/sinon/-/sinon-10.0.0.tgz", "integrity": "sha512-XAn5DxtGVJBlBWYrcYKEhWCz7FLwZGdyvANRyK06419hyEpdT0dMc5A8Vcxg5SCGHc40CsqoKsc1bt1CbJPfNw==", + "dev": true, "requires": { "@sinonjs/commons": "^1.8.1", "@sinonjs/fake-timers": "^6.0.1", @@ -6666,12 +19267,14 @@ "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "requires": { "has-flag": "^4.0.0" } @@ -6681,12 +19284,14 @@ "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true }, "slice-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, "requires": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", @@ -6697,6 +19302,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "requires": { "color-convert": "^2.0.1" } @@ -6705,6 +19311,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "requires": { "color-name": "~1.1.4" } @@ -6712,12 +19319,14 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true } } }, @@ -6739,6 +19348,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", + "dev": true, "requires": { "foreground-child": "^2.0.0", "is-windows": "^1.0.2", @@ -6752,6 +19362,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, "requires": { "isexe": "^2.0.0" } @@ -6762,6 +19373,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, "requires": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" @@ -6770,12 +19382,14 @@ "spdx-exceptions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==" + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true }, "spdx-expression-parse": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, "requires": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" @@ -6784,7 +19398,8 @@ "spdx-license-ids": { "version": "3.0.9", "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz", - "integrity": "sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ==" + "integrity": "sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ==", + "dev": true }, "sprintf-js": { "version": "1.0.3", @@ -6794,7 +19409,8 @@ "srcset": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/srcset/-/srcset-3.0.0.tgz", - "integrity": "sha512-D59vF08Qzu/C4GAOXVgMTLfgryt5fyWo93FZyhEWANo0PokFz/iWdDe13mX3O5TRf6l8vMTqckAfR4zPiaH0yQ==" + "integrity": "sha512-D59vF08Qzu/C4GAOXVgMTLfgryt5fyWo93FZyhEWANo0PokFz/iWdDe13mX3O5TRf6l8vMTqckAfR4zPiaH0yQ==", + "dev": true }, "sshpk": { "version": "1.16.1", @@ -6816,6 +19432,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", + "dev": true, "requires": { "escape-string-regexp": "^2.0.0" }, @@ -6823,19 +19440,30 @@ "escape-string-regexp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==" + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true } } }, "state-toggle": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.3.tgz", - "integrity": "sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ==" + "integrity": "sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ==", + "dev": true + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } }, "string-argv": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", - "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==" + "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", + "dev": true }, "string-width": { "version": "1.0.2", @@ -6851,6 +19479,7 @@ "version": "4.0.5", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.5.tgz", "integrity": "sha512-Z5ZaXO0svs0M2xd/6By3qpeKpLKd9mO4v4q3oMEQrk8Ck4xOD5d5XeBOOjGrmVZZ/AHB1S0CgG4N5r1G9N3E2Q==", + "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", @@ -6866,6 +19495,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3" @@ -6875,19 +19505,12 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3" } }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", @@ -6899,7 +19522,8 @@ "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true }, "strip-json-comments": { "version": "2.0.1", @@ -6918,6 +19542,7 @@ "version": "6.7.1", "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz", "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==", + "dev": true, "requires": { "ajv": "^8.0.1", "lodash.clonedeep": "^4.5.0", @@ -6931,6 +19556,7 @@ "version": "8.6.1", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.1.tgz", "integrity": "sha512-42VLtQUOLefAvKFAQIxIZDaThq6om/PrfP0CYk3/vn+y4BMNkKnbli8ON2QCiHov4KkzOSJ/xSoBJdayiiYvVQ==", + "dev": true, "requires": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -6941,22 +19567,26 @@ "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true }, "json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true }, "string-width": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -6967,6 +19597,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, "requires": { "ansi-regex": "^5.0.0" } @@ -7040,6 +19671,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, "requires": { "@istanbuljs/schema": "^0.1.2", "glob": "^7.1.4", @@ -7049,12 +19681,14 @@ "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true }, "timsort": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", - "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=" + "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=", + "dev": true }, "to-buffer": { "version": "1.1.1", @@ -7064,7 +19698,8 @@ "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true }, "to-readable-stream": { "version": "2.1.0", @@ -7075,6 +19710,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, "requires": { "is-number": "^7.0.0" } @@ -7092,6 +19728,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/transform-file/-/transform-file-1.0.1.tgz", "integrity": "sha1-f5WYSs0j1Ov4q7R+6dg74WbRJoc=", + "dev": true, "requires": { "os-tmpdir": "^1.0.0" } @@ -7099,22 +19736,26 @@ "trim": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", - "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=" + "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=", + "dev": true }, "trim-trailing-lines": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.4.tgz", - "integrity": "sha512-rjUWSqnfTNrjbB9NQWfPMH/xRK1deHeGsHoVfpxJ++XeYXE0d6B1En37AHfw3jtfTU7dzMzZL2jjpe8Qb5gLIQ==" + "integrity": "sha512-rjUWSqnfTNrjbB9NQWfPMH/xRK1deHeGsHoVfpxJ++XeYXE0d6B1En37AHfw3jtfTU7dzMzZL2jjpe8Qb5gLIQ==", + "dev": true }, "trough": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", - "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==" + "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==", + "dev": true }, "ts-node": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.1.0.tgz", "integrity": "sha512-6szn3+J9WyG2hE+5W8e0ruZrzyk1uFLYye6IGMBadnOzDh8aP7t8CbFpsfCiEx2+wMixAhjFt7lOZC4+l+WbEA==", + "dev": true, "requires": { "@tsconfig/node10": "^1.0.7", "@tsconfig/node12": "^1.0.7", @@ -7132,6 +19773,7 @@ "version": "3.10.1", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.10.1.tgz", "integrity": "sha512-rETidPDgCpltxF7MjBZlAFPUHv5aHH2MymyPvh+vEyWAED4Eb/WeMbsnD/JDr4OKPOA1TssDHgIcpTN5Kh0p6Q==", + "dev": true, "requires": { "json5": "^2.2.0", "minimist": "^1.2.0", @@ -7141,7 +19783,8 @@ "tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true }, "tslog": { "version": "3.2.0", @@ -7155,6 +19798,7 @@ "version": "3.21.0", "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, "requires": { "tslib": "^1.8.1" } @@ -7176,6 +19820,7 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, "requires": { "prelude-ls": "^1.2.1" } @@ -7183,7 +19828,8 @@ "type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true }, "type-fest": { "version": "0.10.0", @@ -7194,6 +19840,7 @@ "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, "requires": { "is-typedarray": "^1.0.0" } @@ -7201,12 +19848,14 @@ "typescript": { "version": "4.3.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz", - "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==" + "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==", + "dev": true }, "uglify-js": { "version": "3.13.10", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.10.tgz", "integrity": "sha512-57H3ACYFXeo1IaZ1w02sfA71wI60MGco/IQFjOqK+WtKoprh7Go2/yvd2HPtoJILO2Or84ncLccI4xoHMTSbGg==", + "dev": true, "optional": true }, "ulid": { @@ -7218,6 +19867,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "dev": true, "requires": { "function-bind": "^1.1.1", "has-bigints": "^1.0.1", @@ -7229,6 +19879,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.3.tgz", "integrity": "sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ==", + "dev": true, "requires": { "inherits": "^2.0.0", "xtend": "^4.0.0" @@ -7238,6 +19889,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/unicode-regex/-/unicode-regex-3.0.0.tgz", "integrity": "sha512-WiDJdORsqgxkZrjC8WsIP573130HNn7KsB0IDnUccW2BG2b19QQNloNhVe6DKk3Aef0UcoIHhNVj7IkkcYWrNw==", + "dev": true, "requires": { "regexp-util": "^1.2.0" } @@ -7251,6 +19903,7 @@ "version": "9.2.0", "resolved": "https://registry.npmjs.org/unified/-/unified-9.2.0.tgz", "integrity": "sha512-vx2Z0vY+a3YoTj8+pttM3tiJHCwY5UFbYdiWrwBEbHmK8pvsPj2rtAX2BFfgXen8T39CJWblWRDT4L5WGXtDdg==", + "dev": true, "requires": { "bail": "^1.0.0", "extend": "^3.0.0", @@ -7263,17 +19916,20 @@ "uniq": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", - "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=" + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", + "dev": true }, "unist-util-is": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz", - "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==" + "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==", + "dev": true }, "unist-util-remove-position": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-1.1.4.tgz", "integrity": "sha512-tLqd653ArxJIPnKII6LMZwH+mb5q+n/GtXQZo6S6csPRs5zB0u79Yw8ouR3wTw8wxvdJFhpP6Y7jorWdCgLO0A==", + "dev": true, "requires": { "unist-util-visit": "^1.1.0" } @@ -7282,6 +19938,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", + "dev": true, "requires": { "@types/unist": "^2.0.2" } @@ -7290,6 +19947,7 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz", "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==", + "dev": true, "requires": { "unist-util-visit-parents": "^2.0.0" } @@ -7298,6 +19956,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz", "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==", + "dev": true, "requires": { "unist-util-is": "^3.0.0" } @@ -7333,12 +19992,14 @@ "v8-compile-cache": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==" + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true }, "validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, "requires": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" @@ -7347,7 +20008,8 @@ "validator": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/validator/-/validator-8.2.0.tgz", - "integrity": "sha512-Yw5wW34fSv5spzTXNkokD6S6/Oq92d8q/t14TqsS3fAiA1RYnxSFSIZ+CY3n6PGGRCq5HhJTSepQvFUS2QUDxA==" + "integrity": "sha512-Yw5wW34fSv5spzTXNkokD6S6/Oq92d8q/t14TqsS3fAiA1RYnxSFSIZ+CY3n6PGGRCq5HhJTSepQvFUS2QUDxA==", + "dev": true }, "verror": { "version": "1.10.0", @@ -7363,6 +20025,7 @@ "version": "4.2.1", "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", + "dev": true, "requires": { "@types/unist": "^2.0.0", "is-buffer": "^2.0.0", @@ -7373,12 +20036,14 @@ "vfile-location": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.6.tgz", - "integrity": "sha512-sSFdyCP3G6Ka0CEmN83A2YCMKIieHx0EDaj5IDP4g1pa5ZJ4FJDvpO0WODLxo4LUX4oe52gmSCK7Jw4SBghqxA==" + "integrity": "sha512-sSFdyCP3G6Ka0CEmN83A2YCMKIieHx0EDaj5IDP4g1pa5ZJ4FJDvpO0WODLxo4LUX4oe52gmSCK7Jw4SBghqxA==", + "dev": true }, "vfile-message": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", + "dev": true, "requires": { "@types/unist": "^2.0.0", "unist-util-stringify-position": "^2.0.0" @@ -7388,6 +20053,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/vnopts/-/vnopts-1.0.2.tgz", "integrity": "sha512-d2rr2EFhAGHnTlURu49G7GWmiJV80HbAnkYdD9IFAtfhmxC+kSWEaZ6ZF064DJFTv9lQZQV1vuLTntyQpoanGQ==", + "dev": true, "requires": { "chalk": "^2.4.1", "leven": "^2.1.0", @@ -7397,7 +20063,8 @@ "leven": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", - "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=" + "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=", + "dev": true } } }, @@ -7413,6 +20080,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, "requires": { "is-bigint": "^1.0.1", "is-boolean-object": "^1.1.0", @@ -7424,7 +20092,8 @@ "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true }, "wide-align": { "version": "1.1.3", @@ -7437,22 +20106,26 @@ "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true }, "wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true }, "workerpool": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz", - "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==" + "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==", + "dev": true }, "wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, "requires": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -7462,12 +20135,14 @@ "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "requires": { "color-convert": "^2.0.1" } @@ -7476,6 +20151,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "requires": { "color-name": "~1.1.4" } @@ -7483,17 +20159,20 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true }, "string-width": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -7504,6 +20183,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, "requires": { "ansi-regex": "^5.0.0" } @@ -7519,6 +20199,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, "requires": { "imurmurhash": "^0.1.4", "is-typedarray": "^1.0.0", @@ -7534,7 +20215,8 @@ "y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true }, "yallist": { "version": "3.1.1", @@ -7544,12 +20226,14 @@ "yaml": { "version": "1.10.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true }, "yaml-unist-parser": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/yaml-unist-parser/-/yaml-unist-parser-1.3.1.tgz", "integrity": "sha512-4aHBMpYcnByF8l2OKj5hlBJlxSYIMON8Z1Hm57ymbBL4omXMlGgY+pEf4Di6h2qNT8ZG8seTVvAQYNOa7CZ9eA==", + "dev": true, "requires": { "lines-and-columns": "^1.1.6", "tslib": "^1.10.0", @@ -7560,6 +20244,7 @@ "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, "requires": { "cliui": "^7.0.2", "escalade": "^3.1.1", @@ -7573,17 +20258,20 @@ "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true }, "string-width": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -7594,6 +20282,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, "requires": { "ansi-regex": "^5.0.0" } @@ -7603,12 +20292,14 @@ "yargs-parser": { "version": "20.2.4", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==" + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true }, "yargs-unparser": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, "requires": { "camelcase": "^6.0.0", "decamelize": "^4.0.0", @@ -7619,17 +20310,20 @@ "yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true }, "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true }, "z-schema": { "version": "3.18.4", "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-3.18.4.tgz", "integrity": "sha512-DUOKC/IhbkdLKKiV89gw9DUauTV8U/8yJl1sjf6MtDmzevLKOF2duNJ495S3MFVjqZarr+qNGCPbkg4mu4PpLw==", + "dev": true, "requires": { "commander": "^2.7.1", "lodash.get": "^4.0.0", @@ -8347,6 +21041,14 @@ "tweetnacl": "~0.14.0" } }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, "string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", @@ -8357,14 +21059,6 @@ "strip-ansi": "^3.0.0" } }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", diff --git a/examples/package.json b/examples/package.json index 78f27f92..711830d8 100644 --- a/examples/package.json +++ b/examples/package.json @@ -8,13 +8,14 @@ "start": "npm run build && node dist/index.js", "collection": "npm run build && node dist/collection.js", "sync": "rm -rf ./git-documentdb/ && npm run build && node dist/sync.js", - "plugin": "npm run build && node dist/plugin.js" + "plugin": "npm run build && node dist/plugin.js", + "clear": "npx rimraf node_modules" }, "author": "", "license": "MPL-2.0", "dependencies": { "git-documentdb": "file:..", - "git-documentdb-plugin-remote-nodegit": "^1.0.5-alpha.0" + "git-documentdb-plugin-remote-nodegit": "^1.0.4" }, "devDependencies": { "typescript": "^4.1.3" From b362e9e09a11e933650b99b4c555d141f03256e1 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 10 May 2022 12:42:28 +0900 Subject: [PATCH 284/297] fix: update document --- src/git_documentdb.ts | 6 ++++++ src/types.ts | 15 +++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/git_documentdb.ts b/src/git_documentdb.ts index b9253260..55c76084 100644 --- a/src/git_documentdb.ts +++ b/src/git_documentdb.ts @@ -198,6 +198,12 @@ export class GitDocumentDB } private _tsLogger!: Logger; + /** + * Get logger + * + * @readonly + * @public + */ get tsLogger (): Logger { return this._tsLogger; } diff --git a/src/types.ts b/src/types.ts index f55e2e94..2b2d0269 100644 --- a/src/types.ts +++ b/src/types.ts @@ -91,7 +91,9 @@ export type Schema = { * * @remarks * - plainTextProperties: Only property whose key matches plainTextProperties uses text-diff-and-patch algorithm (google-diff-match-patch). + * * - keyInArrayedObject: To diff between arrays that contain objects as elements, you must specify a key in the object. See https://github.com/benjamine/jsondiffpatch/blob/master/docs/arrays.md#an-object-hash + * * - keyOfUniqueArray: Set a key of a unique array. Unique array never include duplicated members after JSON patch. * * @example @@ -142,6 +144,8 @@ export type DatabaseOpenResult = DatabaseInfo & { * * - version: A version of the GitDocumentDB specification. The version can be used for database migration. * + * - serialize: Serialize format of the database. + * * @public */ export type DatabaseInfo = { @@ -306,11 +310,15 @@ export type FatDoc = FatJsonDoc | FatTextDoc | FatBinaryDoc; /** * Format for serialization + * + * @public */ export type SerializeFormatLabel = 'json' | 'front-matter'; /** * Interface for serialize format classes + * + * @internal */ export interface SerializeFormat { format: SerializeFormatLabel; @@ -1226,12 +1234,19 @@ export interface IJsonPatch { /** * Colored log + * + * @internal */ export type ColoredLog = ( mes: string, colorTag?: () => (literals: TemplateStringsArray, ...placeholders: any[]) => string ) => void; +/** + * Colored logger + * + * @internal + */ export type ColoredLogger = { silly: ColoredLog; debug: ColoredLog; From d853fd13e4ea3d815793a855c16ef6f6e5843dc2 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 10 May 2022 12:42:48 +0900 Subject: [PATCH 285/297] fix: update README --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9ab4175a..b4c87765 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ Use GitDocumentDB to ... :arrows_counterclockwise: Integrate CI/CD pipelines through GitHub. -:dromedary_camel: Get revision history of a document. +:dromedary_camel: Get the revision history of a document. [(More...)](https://gitddb.com/) @@ -230,6 +230,7 @@ https://github.com/sosuisen/inventory-manager - Remove native module (NodeGit) from default install :feet: - Add plugin system for remote connection (isomorphic-git or NodeGit) :feet: - Connect with SSH key pair :feet: + - Add Front-Matter-Markdown format :feet: - Connect to GitHub with OAuth :dog2:(Next) - Work on browser From 0050089bae5f246b59581ab12e9da76660f7bfe8 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 10 May 2022 12:43:09 +0900 Subject: [PATCH 286/297] build: bump to v0.4.7 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 047ee4b9..fbf942c5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "git-documentdb", - "version": "0.4.7-beta.1", + "version": "0.4.7", "description": "Offline-first database that syncs with Git", "main": "dist/main.js", "types": "dist/main.d.ts", @@ -9,7 +9,7 @@ }, "scripts": { "build": "rm -rf dist/* && npm run lint && tsc --project src/tsconfig.json", - "doc": "npm run build && npm run api-extractor && npm run crlf", + "doc": "npm run build && rm -rf docs-api/* && npm run api-extractor && npm run crlf", "mocha-parallel": "npm run rm-test-db && npx cross-env TS_NODE_FILES=true TS_NODE_PROJECT=tsconfig.mocha.json mocha", "mocha-no-parallel": "npm run rm-test-db && npx cross-env TS_NODE_FILES=true TS_NODE_PROJECT=tsconfig.mocha.json mocha --retries 0 --no-parallel", "mocha-unit-parallel": "npm run rm-test-db && npx cross-env TS_NODE_FILES=true TS_NODE_PROJECT=tsconfig.mocha.json mocha --retries 0", From 10d350129dd33f1dc1112395bc9cbd075b052a91 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 10 May 2022 12:58:08 +0900 Subject: [PATCH 287/297] build: update package-lock --- package-lock.json | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/package-lock.json b/package-lock.json index 05efc33b..9ab20ebe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "git-documentdb", - "version": "0.4.7-beta.1", + "version": "0.4.7", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "git-documentdb", - "version": "0.4.7-beta.1", + "version": "0.4.7", "license": "MPL-2.0", "dependencies": { "@octokit/rest": "^18.3.5", @@ -2209,14 +2209,20 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001265", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001265.tgz", - "integrity": "sha512-YzBnspggWV5hep1m9Z6sZVLOt7vrju8xWooFAgN6BA5qvy98qPAPb7vNUzypFaoh2pb3vlfzbDO8tB57UPGbtw==", + "version": "1.0.30001338", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001338.tgz", + "integrity": "sha512-1gLHWyfVoRDsHieO+CaeYe7jSo/MT7D7lhaXUiwwbuR5BwQxORs0f1tAwUSQr3YbxRXJvxHM/PA5FfPQRnsPeQ==", "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - } + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + } + ] }, "node_modules/caseless": { "version": "0.12.0", @@ -12337,9 +12343,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001265", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001265.tgz", - "integrity": "sha512-YzBnspggWV5hep1m9Z6sZVLOt7vrju8xWooFAgN6BA5qvy98qPAPb7vNUzypFaoh2pb3vlfzbDO8tB57UPGbtw==", + "version": "1.0.30001338", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001338.tgz", + "integrity": "sha512-1gLHWyfVoRDsHieO+CaeYe7jSo/MT7D7lhaXUiwwbuR5BwQxORs0f1tAwUSQr3YbxRXJvxHM/PA5FfPQRnsPeQ==", "dev": true }, "caseless": { From 1735a1a1f5f08c14c2a6ccb3329c20853cb3cbbc Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 11 May 2022 10:34:49 +0900 Subject: [PATCH 288/297] fix: make YAML lineWidth to be unlimited --- src/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils.ts b/src/utils.ts index 4d1e44ef..1be53ab2 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -85,7 +85,7 @@ export function toSortedJSONString (obj: Record) { } export function toYAML (obj: Record) { - return yaml.dump(obj, { sortKeys: true }); + return yaml.dump(obj, { sortKeys: true, lineWidth: -1 }); } export function toFrontMatterMarkdown (obj: Record) { From 0e2982a9d440bea5dfcc22f8cac51917a27e7970 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Wed, 11 May 2022 10:37:38 +0900 Subject: [PATCH 289/297] build: bump to 0.4.8-alpha.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fbf942c5..6e76317f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "git-documentdb", - "version": "0.4.7", + "version": "0.4.8-alpha.1", "description": "Offline-first database that syncs with Git", "main": "dist/main.js", "types": "dist/main.d.ts", From 64f9cf65eca3baa93aefe2d3df826ec892f3f5bc Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 11 Apr 2023 15:06:35 +0900 Subject: [PATCH 290/297] fix: make YAML in front matter lineWidth to be unlimited --- src/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils.ts b/src/utils.ts index 1be53ab2..06d72df6 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -103,7 +103,7 @@ export function toFrontMatterMarkdown (obj: Record) { return body; } - const frontMatter = '---\n' + yaml.dump(clone, { sortKeys: true }) + '---\n'; + const frontMatter = '---\n' + yaml.dump(clone, { sortKeys: true, lineWidth: -1 }) + '---\n'; return frontMatter + body; } From 067d5f62ef467e6345d0dfb04cac2b20c0e18a2a Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 11 Apr 2023 15:10:21 +0900 Subject: [PATCH 291/297] build: bump to 0.4.8-alpha.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6e76317f..38a5ddec 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "git-documentdb", - "version": "0.4.8-alpha.1", + "version": "0.4.8-alpha.2", "description": "Offline-first database that syncs with Git", "main": "dist/main.js", "types": "dist/main.d.ts", From bf62a39c7ae9bba12ae535f9a57723a3c72158ff Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 11 Apr 2023 15:42:35 +0900 Subject: [PATCH 292/297] style --- src/utils.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/utils.ts b/src/utils.ts index 06d72df6..f1eedad1 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -103,7 +103,8 @@ export function toFrontMatterMarkdown (obj: Record) { return body; } - const frontMatter = '---\n' + yaml.dump(clone, { sortKeys: true, lineWidth: -1 }) + '---\n'; + const frontMatter = + '---\n' + yaml.dump(clone, { sortKeys: true, lineWidth: -1 }) + '---\n'; return frontMatter + body; } From 830d99ead578afc800928b3429ff783aea1e8bcf Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 11 Apr 2023 15:44:31 +0900 Subject: [PATCH 293/297] fix: 401 Unauthorized message can be handled --- src/plugin/remote-isomorphic-git.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugin/remote-isomorphic-git.ts b/src/plugin/remote-isomorphic-git.ts index 3dfecc3e..b96143bc 100644 --- a/src/plugin/remote-isomorphic-git.ts +++ b/src/plugin/remote-isomorphic-git.ts @@ -166,7 +166,7 @@ export async function clone ( } break; - case error.startsWith('HttpError: HTTP Error: 401 Authorization Required'): + case error.startsWith('HttpError: HTTP Error: 401'): throw new HTTPError401AuthorizationRequired(error); case error.startsWith('HttpError: HTTP Error: 404 Not Found'): @@ -280,7 +280,7 @@ export async function checkFetch ( } break; - case error.startsWith('HttpError: HTTP Error: 401 Authorization Required'): + case error.startsWith('HttpError: HTTP Error: 401'): throw new HTTPError401AuthorizationRequired(error); case error.startsWith('HttpError: HTTP Error: 404 Not Found'): @@ -393,7 +393,7 @@ export async function fetch ( } break; - case error.startsWith('HttpError: HTTP Error: 401 Authorization Required'): + case error.startsWith('HttpError: HTTP Error: 401'): throw new HTTPError401AuthorizationRequired(error); case error.startsWith('HttpError: HTTP Error: 404 Not Found'): @@ -511,7 +511,7 @@ export async function push ( } break; - case error.startsWith('HttpError: HTTP Error: 401 Authorization Required'): + case error.startsWith('HttpError: HTTP Error: 401'): throw new HTTPError401AuthorizationRequired(error); case error.startsWith('HttpError: HTTP Error: 404 Not Found'): From 2efe51e8e0ca2c3522226ef5eae97315cf5452cf Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 11 Apr 2023 16:15:52 +0900 Subject: [PATCH 294/297] build: bump isomorphic-git to 1.23.0 --- package-lock.json | 18 +++++++++--------- package.json | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9ab20ebe..f852c19c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "git-documentdb", - "version": "0.4.7", + "version": "0.4.8-alpha.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "git-documentdb", - "version": "0.4.7", + "version": "0.4.8-alpha.2", "license": "MPL-2.0", "dependencies": { "@octokit/rest": "^18.3.5", @@ -16,7 +16,7 @@ "fs-extra": "^9.1.0", "git-documentdb-plugin-remote-nodegit": "^1.0.4", "git-documentdb-remote-errors": "^1.0.3", - "isomorphic-git": "^1.17.1", + "isomorphic-git": "^1.23.0", "js-yaml": "^4.1.0", "ot-json1": "^1.0.2", "rimraf": "^3.0.2", @@ -5405,9 +5405,9 @@ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, "node_modules/isomorphic-git": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/isomorphic-git/-/isomorphic-git-1.17.1.tgz", - "integrity": "sha512-JLZzAmc78yELH6+bZgMzqV0KGEi2duo+URWmyEnSbhhibHwDsMIlUw5tr1ZVHjC2CUQtU0X/5EY9Sbzsyx7nug==", + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/isomorphic-git/-/isomorphic-git-1.23.0.tgz", + "integrity": "sha512-7mQlnZivFwrU6B3CswvmoNtVN8jqF9BcLf80uk7yh4fNA8PhFjAfQigi2Hu/Io0cmIvpOc7vn0/Rq3KtL5Ph8g==", "dependencies": { "async-lock": "^1.1.0", "clean-git-ref": "^2.0.1", @@ -14687,9 +14687,9 @@ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, "isomorphic-git": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/isomorphic-git/-/isomorphic-git-1.17.1.tgz", - "integrity": "sha512-JLZzAmc78yELH6+bZgMzqV0KGEi2duo+URWmyEnSbhhibHwDsMIlUw5tr1ZVHjC2CUQtU0X/5EY9Sbzsyx7nug==", + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/isomorphic-git/-/isomorphic-git-1.23.0.tgz", + "integrity": "sha512-7mQlnZivFwrU6B3CswvmoNtVN8jqF9BcLf80uk7yh4fNA8PhFjAfQigi2Hu/Io0cmIvpOc7vn0/Rq3KtL5Ph8g==", "requires": { "async-lock": "^1.1.0", "clean-git-ref": "^2.0.1", diff --git a/package.json b/package.json index 38a5ddec..935076c0 100644 --- a/package.json +++ b/package.json @@ -84,7 +84,7 @@ "fs-extra": "^9.1.0", "git-documentdb-plugin-remote-nodegit": "^1.0.4", "git-documentdb-remote-errors": "^1.0.3", - "isomorphic-git": "^1.17.1", + "isomorphic-git": "^1.23.0", "js-yaml": "^4.1.0", "ot-json1": "^1.0.2", "rimraf": "^3.0.2", From a346a0b60b67c5648afda30b6f0234dc4b345bfa Mon Sep 17 00:00:00 2001 From: sosuisen Date: Tue, 11 Apr 2023 16:16:18 +0900 Subject: [PATCH 295/297] build: bump to 0.4.8.alpha.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 935076c0..16f84a78 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "git-documentdb", - "version": "0.4.8-alpha.2", + "version": "0.4.8-alpha.3", "description": "Offline-first database that syncs with Git", "main": "dist/main.js", "types": "dist/main.d.ts", From 1196229f6e7bc4f0036bb62ec2a9c64eb81e17c7 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Thu, 13 Apr 2023 21:35:07 +0900 Subject: [PATCH 296/297] fix: plan changed --- README.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index b4c87765..7f971c19 100644 --- a/README.md +++ b/README.md @@ -225,22 +225,21 @@ https://github.com/sosuisen/inventory-manager - Automated conflict resolution :feet: - Automated JSON diff and patch :feet: - Automated combining of inconsistent repositories :feet: -- v0.4 Work on both Node.js and browser +- v0.4 Many data types and connection methods - API renewal to manage any data types :feet: - Remove native module (NodeGit) from default install :feet: - Add plugin system for remote connection (isomorphic-git or NodeGit) :feet: - Connect with SSH key pair :feet: - Add Front-Matter-Markdown format :feet: - - Connect to GitHub with OAuth :dog2:(Next) - - Work on browser - +- v0.5 Search + - Indexed Search :dog2:(Next) - Until v1.0 + - Connect to GitHub with OAuth + - Work on browser - Sync any data types - Replication - - Grep - Transaction (bulk) - - Tag - - Indexed Search + - GitLab and Bitbucket - Push server - Migration From 814442b00da0e0180142ea727c74f8a6ba5a62c8 Mon Sep 17 00:00:00 2001 From: sosuisen Date: Thu, 13 Apr 2023 21:45:18 +0900 Subject: [PATCH 297/297] build: bump up to v0.4.8 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 16f84a78..c91a863a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "git-documentdb", - "version": "0.4.8-alpha.3", + "version": "0.4.8", "description": "Offline-first database that syncs with Git", "main": "dist/main.js", "types": "dist/main.d.ts",