From 5c73453d1e33852b0fc55913005a905df953687c Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Wed, 20 May 2020 12:26:11 -0400 Subject: [PATCH 01/56] Revert "Remove experimental cache.modify method. (#6289)" This reverts commit 61a799b2cd5e1657eab4ea97485828671ce35286. --- CHANGELOG.md | 19 +- src/__tests__/client.ts | 14 + src/__tests__/local-state/resolvers.ts | 59 +-- src/cache/core/cache.ts | 9 + src/cache/core/types/common.ts | 25 ++ src/cache/inmemory/__tests__/cache.ts | 443 ++++++++++++++++---- src/cache/inmemory/__tests__/entityStore.ts | 46 ++ src/cache/inmemory/entityStore.ts | 166 +++++--- src/cache/inmemory/helpers.ts | 2 - src/cache/inmemory/inMemoryCache.ts | 20 + src/cache/inmemory/types.ts | 5 +- 11 files changed, 614 insertions(+), 194 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1feb41c7ee4..e9f8ecbee4e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,7 +41,7 @@ - **[BREAKING]** `InMemoryCache` now _throws_ when data with missing or undefined query fields is written into the cache, rather than just warning in development.
[@benjamn](https://github.com/benjamn) in [#6055](https://github.com/apollographql/apollo-client/pull/6055) -- **[BREAKING]** The `client|cache.writeData` methods have been fully removed, as `writeData` is one of the easiest ways to turn faulty assumptions about how the cache represents data internally into cache inconsistency and corruption. Instead, use `client|cache.writeQuery` or `client|cache.writeFragment` to update the cache.
+- **[BREAKING]** `client|cache.writeData` have been fully removed. `writeData` usage is one of the easiest ways to turn faulty assumptions about how the cache represents data internally, into cache inconsistency and corruption. `client|cache.writeQuery`, `client|cache.writeFragment`, and/or `cache.modify` can be used to update the cache.
[@benjamn](https://github.com/benjamn) in [#5923](https://github.com/apollographql/apollo-client/pull/5923) - **[BREAKING]** Apollo Client will no longer deliver "stale" results to `ObservableQuery` consumers, but will instead log more helpful errors about which cache fields were missing.
@@ -56,9 +56,6 @@ - **[BREAKING?]** Refactor `QueryManager` to make better use of observables and enforce `fetchPolicy` more reliably.
[@benjamn](https://github.com/benjamn) in [#6221](https://github.com/apollographql/apollo-client/pull/6221) -- **[beta-BREAKING]** The experimental `cache.modify` method, first introduced in [PR #5909](https://github.com/apollographql/apollo-client/pull/5909), has been removed.
- [@benjamn](https://github.com/benjamn) in [#6289](https://github.com/apollographql/apollo-client/pull/6289) - - `InMemoryCache` now supports tracing garbage collection and eviction. Note that the signature of the `evict` method has been simplified in a potentially backwards-incompatible way.
[@benjamn](https://github.com/benjamn) in [#5310](https://github.com/apollographql/apollo-client/pull/5310) @@ -89,6 +86,18 @@ - The result caching system (introduced in [#3394](https://github.com/apollographql/apollo-client/pull/3394)) now tracks dependencies at the field level, rather than at the level of whole entity objects, allowing the cache to return identical (`===`) results much more often than before.
[@benjamn](https://github.com/benjamn) in [#5617](https://github.com/apollographql/apollo-client/pull/5617) +- `InMemoryCache` now has a method called `modify` which can be used to update the value of a specific field within a specific entity object: + ```ts + cache.modify({ + comments(comments: Reference[], { readField }) { + return comments.filter(comment => idToRemove !== readField("id", comment)); + }, + }, cache.identify(post)); + ``` + This API gracefully handles cases where multiple field values are associated with a single field name, and also removes the need for updating the cache by reading a query or fragment, modifying the result, and writing the modified result back into the cache. Behind the scenes, the `cache.evict` method is now implemented in terms of `cache.modify`.
+ [@benjamn](https://github.com/benjamn) in [#5909](https://github.com/apollographql/apollo-client/pull/5909) + and [#6178](https://github.com/apollographql/apollo-client/pull/6178) + - `InMemoryCache` provides a new API for storing client state that can be updated from anywhere: ```ts const v = cache.makeVar(123) @@ -141,7 +150,7 @@ - Make sure `ApolloContext` plays nicely with IE11 when storing the shared context.
[@ms](https://github.com/ms) in [#5840](https://github.com/apollographql/apollo-client/pull/5840) -- Expose `cache.identify` to the mutation `update` function.
+- Expose cache `modify` and `identify` to the mutate `update` function.
[@hwillson](https://github.com/hwillson) in [#5956](https://github.com/apollographql/apollo-client/pull/5956) - Add a default `gc` implementation to `ApolloCache`.
diff --git a/src/__tests__/client.ts b/src/__tests__/client.ts index 9b08248bae8..c5898b979fa 100644 --- a/src/__tests__/client.ts +++ b/src/__tests__/client.ts @@ -2942,6 +2942,19 @@ describe('@connection', () => { checkLastResult(abResults, a456bOyez); checkLastResult(cResults, { c: "see" }); + cache.modify({ + c(value) { + expect(value).toBe("see"); + return "saw"; + }, + }); + await wait(); + + checkLastResult(aResults, a456); + checkLastResult(bResults, bOyez); + checkLastResult(abResults, a456bOyez); + checkLastResult(cResults, { c: "saw" }); + client.cache.evict("ROOT_QUERY", "c"); await wait(); @@ -2978,6 +2991,7 @@ describe('@connection', () => { expect(cResults).toEqual([ {}, { c: "see" }, + { c: "saw" }, {}, ]); diff --git a/src/__tests__/local-state/resolvers.ts b/src/__tests__/local-state/resolvers.ts index 0f7a94b243c..e7ba416fe1b 100644 --- a/src/__tests__/local-state/resolvers.ts +++ b/src/__tests__/local-state/resolvers.ts @@ -546,22 +546,19 @@ describe('Writing cache data from resolvers', () => { resolvers: { Mutation: { start() { - const obj = { - __typename: 'Object', - id: 'uniqueId', - field: 1, - }; - cache.writeQuery({ query, - data: { obj }, + data: { + obj: { field: 1, id: 'uniqueId', __typename: 'Object' }, + }, }); - cache.writeFragment({ - id: cache.identify(obj)!, - fragment: gql`fragment Field on Object { field }`, - data: { field: 2 }, - }); + cache.modify({ + field(value) { + expect(value).toBe(1); + return 2; + }, + }, 'Object:uniqueId'); return { start: true }; }, @@ -577,7 +574,7 @@ describe('Writing cache data from resolvers', () => { }); }); - itAsync('should not overwrite __typename when writing to the cache with an id', (resolve, reject) => { + it('should not overwrite __typename when writing to the cache with an id', () => { const query = gql` { obj @client { @@ -603,35 +600,22 @@ describe('Writing cache data from resolvers', () => { resolvers: { Mutation: { start() { - const obj = { - __typename: 'Object', - id: 'uniqueId', - field: { - __typename: 'Field', - field2: 1, - }, - }; - cache.writeQuery({ query, - data: { obj }, - }); - - cache.writeFragment({ - id: cache.identify(obj)!, - fragment: gql`fragment FieldField2 on Object { - field { - field2 - } - }`, data: { - field: { - __typename: 'Field', - field2: 2, + obj: { + field: { field2: 1, __typename: 'Field' }, + id: 'uniqueId', + __typename: 'Object', }, }, }); - + cache.modify({ + field(value: { field2: number }) { + expect(value.field2).toBe(1); + return { ...value, field2: 2 }; + }, + }, 'Object:uniqueId'); return { start: true }; }, }, @@ -644,7 +628,8 @@ describe('Writing cache data from resolvers', () => { .then(({ data }: any) => { expect(data.obj.__typename).toEqual('Object'); expect(data.obj.field.__typename).toEqual('Field'); - }).then(resolve, reject); + }) + .catch(e => console.log(e)); }); }); diff --git a/src/cache/core/cache.ts b/src/cache/core/cache.ts index 759bf9f7ebd..ff0415d9b73 100644 --- a/src/cache/core/cache.ts +++ b/src/cache/core/cache.ts @@ -5,6 +5,7 @@ import { getFragmentQueryDocument } from '../../utilities/graphql/fragments'; import { StoreObject } from '../../utilities/graphql/storeUtils'; import { DataProxy } from './types/DataProxy'; import { Cache } from './types/Cache'; +import { Modifier, Modifiers } from './types/common'; export type Transaction = (c: ApolloCache) => void; @@ -77,6 +78,14 @@ export abstract class ApolloCache implements DataProxy { public identify(object: StoreObject): string | undefined { return; } + + public modify( + modifiers: Modifier | Modifiers, + dataId?: string, + optimistic?: boolean, + ): boolean { + return false; + } public gc(): string[] { return []; diff --git a/src/cache/core/types/common.ts b/src/cache/core/types/common.ts index 4c80af791a6..e685837374a 100644 --- a/src/cache/core/types/common.ts +++ b/src/cache/core/types/common.ts @@ -1,5 +1,14 @@ import { DocumentNode } from 'graphql'; +import { + isReference, + StoreValue, + StoreObject, + Reference +} from '../../../utilities/graphql/storeUtils'; + +import { ToReferenceFunction } from '../../inmemory/entityStore'; + // The Readonly type only really works for object types, since it marks // all of the object's properties as readonly, but there are many cases when // a generic type parameter like TExisting might be a string or some other @@ -9,6 +18,22 @@ import { DocumentNode } from 'graphql'; // Readonly, somewhat surprisingly. export type SafeReadonly = T extends object ? Readonly : T; +export type Modifier = (value: T, details: { + DELETE: any; + fieldName: string; + storeFieldName: string; + isReference: typeof isReference; + toReference: ToReferenceFunction; + readField( + fieldName: string, + objOrRef?: StoreObject | Reference, + ): SafeReadonly; +}) => T; + +export type Modifiers = { + [fieldName: string]: Modifier; +} + export class MissingFieldError { constructor( public readonly message: string, diff --git a/src/cache/inmemory/__tests__/cache.ts b/src/cache/inmemory/__tests__/cache.ts index c2296308847..824539e5440 100644 --- a/src/cache/inmemory/__tests__/cache.ts +++ b/src/cache/inmemory/__tests__/cache.ts @@ -4,7 +4,6 @@ import { stripSymbols } from '../../../utilities/testing/stripSymbols'; import { cloneDeep } from '../../../utilities/common/cloneDeep'; import { makeReference, Reference } from '../../../core'; import { InMemoryCache, InMemoryCacheConfig } from '../inMemoryCache'; -import { fieldNameFromStoreName } from '../helpers'; disableFragmentWarnings(); @@ -1539,6 +1538,268 @@ describe("InMemoryCache#broadcastWatches", function () { }); describe("InMemoryCache#modify", () => { + it("should work with single modifier function", () => { + const cache = new InMemoryCache; + const query = gql` + query { + a + b + c + } + `; + + cache.writeQuery({ + query, + data: { + a: 0, + b: 0, + c: 0, + }, + }); + + const resultBeforeModify = cache.readQuery({ query }); + expect(resultBeforeModify).toEqual({ a: 0, b: 0, c: 0 }); + + cache.modify((value, { fieldName }) => { + switch (fieldName) { + case "a": return value + 1; + case "b": return value - 1; + default: return value; + } + }); + + expect(cache.extract()).toEqual({ + ROOT_QUERY: { + __typename: "Query", + a: 1, + b: -1, + c: 0, + }, + }); + + const resultAfterModify = cache.readQuery({ query }); + expect(resultAfterModify).toEqual({ a: 1, b: -1, c: 0 }); + }); + + it("should work with multiple modifier functions", () => { + const cache = new InMemoryCache; + const query = gql` + query { + a + b + c + } + `; + + cache.writeQuery({ + query, + data: { + a: 0, + b: 0, + c: 0, + }, + }); + + const resultBeforeModify = cache.readQuery({ query }); + expect(resultBeforeModify).toEqual({ a: 0, b: 0, c: 0 }); + + let checkedTypename = false; + cache.modify({ + a(value) { return value + 1 }, + b(value) { return value - 1 }, + __typename(t: string, { readField }) { + expect(t).toBe("Query"); + expect(readField("c")).toBe(0); + checkedTypename = true; + return t; + }, + }); + expect(checkedTypename).toBe(true); + + expect(cache.extract()).toEqual({ + ROOT_QUERY: { + __typename: "Query", + a: 1, + b: -1, + c: 0, + }, + }); + + const resultAfterModify = cache.readQuery({ query }); + expect(resultAfterModify).toEqual({ a: 1, b: -1, c: 0 }); + }); + + it("should allow deletion using details.DELETE", () => { + const cache = new InMemoryCache({ + typePolicies: { + Book: { + keyFields: ["isbn"], + }, + Author: { + keyFields: ["name"], + }, + }, + }); + + const query = gql` + query { + currentlyReading { + title + isbn + author { + name + yearOfBirth + } + } + } + `; + + const currentlyReading = { + __typename: "Book", + isbn: "147670032X", + title: "Why We're Polarized", + author: { + __typename: "Author", + name: "Ezra Klein", + yearOfBirth: 1983, + }, + }; + + cache.writeQuery({ + query, + data: { + currentlyReading, + } + }); + + expect(cache.extract()).toEqual({ + ROOT_QUERY: { + __typename: "Query", + currentlyReading: { + __ref: 'Book:{"isbn":"147670032X"}', + }, + }, + 'Book:{"isbn":"147670032X"}': { + __typename: "Book", + isbn: "147670032X", + author: { + __ref: 'Author:{"name":"Ezra Klein"}', + }, + title: "Why We're Polarized", + }, + 'Author:{"name":"Ezra Klein"}': { + __typename: "Author", + name: "Ezra Klein", + yearOfBirth: 1983, + }, + }); + + const authorId = cache.identify(currentlyReading.author)!; + expect(authorId).toBe('Author:{"name":"Ezra Klein"}'); + + cache.modify({ + yearOfBirth(yob) { + return yob + 1; + }, + }, authorId); + + const yobResult = cache.readFragment({ + id: authorId, + fragment: gql`fragment YOB on Author { yearOfBirth }`, + }); + + expect(yobResult).toEqual({ + __typename: "Author", + yearOfBirth: 1984, + }); + + const bookId = cache.identify(currentlyReading)!; + + // Modifying the Book in order to modify the Author is fancier than + // necessary, but we want fancy use cases to work, too. + cache.modify({ + author(author: Reference, { readField }) { + expect(readField("title")).toBe("Why We're Polarized"); + expect(readField("name", author)).toBe("Ezra Klein"); + cache.modify({ + yearOfBirth(yob, { DELETE }) { + expect(yob).toBe(1984); + return DELETE; + }, + }, cache.identify({ + __typename: readField("__typename", author), + name: readField("name", author), + })); + return author; + } + }, bookId); + + const snapshotWithoutYOB = cache.extract(); + expect(snapshotWithoutYOB[authorId]!.yearOfBirth).toBeUndefined(); + expect("yearOfBirth" in snapshotWithoutYOB[authorId]!).toBe(false); + expect(snapshotWithoutYOB).toEqual({ + ROOT_QUERY: { + __typename: "Query", + currentlyReading: { + __ref: 'Book:{"isbn":"147670032X"}', + }, + }, + 'Book:{"isbn":"147670032X"}': { + __typename: "Book", + isbn: "147670032X", + author: { + __ref: 'Author:{"name":"Ezra Klein"}', + }, + title: "Why We're Polarized", + }, + 'Author:{"name":"Ezra Klein"}': { + __typename: "Author", + name: "Ezra Klein", + // yearOfBirth is gone now + }, + }); + + // Delete the whole Book. + cache.modify((_, { DELETE }) => DELETE, bookId); + + const snapshotWithoutBook = cache.extract(); + expect(snapshotWithoutBook[bookId]).toBeUndefined(); + expect(bookId in snapshotWithoutBook).toBe(false); + expect(snapshotWithoutBook).toEqual({ + ROOT_QUERY: { + __typename: "Query", + currentlyReading: { + __ref: 'Book:{"isbn":"147670032X"}', + }, + }, + 'Author:{"name":"Ezra Klein"}': { + __typename: "Author", + name: "Ezra Klein", + }, + }); + + // Delete all fields of the Author, which also removes the object. + cache.modify({ + __typename(_, { DELETE }) { return DELETE }, + name(_, { DELETE }) { return DELETE }, + }, authorId); + + const snapshotWithoutAuthor = cache.extract(); + expect(snapshotWithoutAuthor[authorId]).toBeUndefined(); + expect(authorId in snapshotWithoutAuthor).toBe(false); + expect(snapshotWithoutAuthor).toEqual({ + ROOT_QUERY: { + __typename: "Query", + currentlyReading: { + __ref: 'Book:{"isbn":"147670032X"}', + }, + }, + }); + + cache.modify((_, { DELETE }) => DELETE); + expect(cache.extract()).toEqual({}); + }); + it("can remove specific items from paginated lists", () => { const cache = new InMemoryCache({ typePolicies: { @@ -1647,59 +1908,21 @@ describe("InMemoryCache#modify", () => { }, }); - const threadId = cache.identify({ + cache.modify({ + comments(comments: Reference[], { readField }) { + debugger; + expect(Object.isFrozen(comments)).toBe(true); + expect(comments.length).toBe(3); + const filtered = comments.filter(comment => { + return readField("id", comment) !== "c1"; + }); + expect(filtered.length).toBe(2); + return filtered; + }, + }, cache.identify({ __typename: "Thread", tid: 123, - })!; - - const threadCommentsFragment = gql` - fragment Comments on Thread { - comments(offset: $offset, limit: $limit) { - id - text - } - } - `; - - const threadWithComments = cache.readFragment<{ - comments: any[], - }>({ - id: threadId, - fragment: threadCommentsFragment, - variables: { - offset: 0, - // There are only three comments at this point, but let's pretend - // we don't know that. - limit: 10, - }, - })!; - - // First evict the comments field, so the Thread.comments merge - // function does not try to combine the existing (unfiltered) comments - // list with the incoming (filtered) comments list when we call - // writeFragment below. - expect(cache.evict({ - id: threadId, - fieldName: "comments", - broadcast: false, - })).toBe(true); - - const commentsWithoutC1 = - threadWithComments.comments.filter(comment => { - return comment.id !== "c1"; - }); - - cache.writeFragment({ - id: threadId, - fragment: threadCommentsFragment, - data: { - comments: commentsWithoutC1, - }, - variables: { - offset: 0, - limit: commentsWithoutC1.length, - }, - }); + })); expect(cache.gc()).toEqual(['Comment:{"id":"c1"}']); @@ -1731,6 +1954,47 @@ describe("InMemoryCache#modify", () => { }); }); + it("should not revisit deleted fields", () => { + const cache = new InMemoryCache; + const query = gql`query { a b c }`; + + cache.recordOptimisticTransaction(cache => { + cache.writeQuery({ + query, + data: { + a: 1, + b: 2, + c: 3, + }, + }) + }, "transaction"); + + cache.modify({ + b(value, { DELETE }) { + expect(value).toBe(2); + return DELETE; + }, + }, "ROOT_QUERY", true); + + expect(cache.extract(true)).toEqual({ + ROOT_QUERY: { + __typename: "Query", + a: 1, + c: 3, + }, + }); + + cache.modify((value, { fieldName }) => { + expect(fieldName).not.toBe("b"); + if (fieldName === "a") expect(value).toBe(1); + if (fieldName === "c") expect(value).toBe(3); + }, "ROOT_QUERY", true); + + cache.removeOptimistic("transaction"); + + expect(cache.extract(true)).toEqual({}); + }); + it("should broadcast watches for queries with changed fields", () => { const cache = new InMemoryCache; const queryA = gql`{ a { value } }`; @@ -1818,28 +2082,25 @@ describe("InMemoryCache#modify", () => { expect(aResults).toEqual([a123]); expect(bResults).toEqual([b321]); - const aId = cache.identify({ __typename: "A", id: 1 })!; - expect(aId).toBe("A:1"); + const aId = cache.identify({ __typename: "A", id: 1 }); + const bId = cache.identify({ __typename: "B", id: 1 }); - const bId = cache.identify({ __typename: "B", id: 1 })!; - expect(bId).toBe("B:1"); - - cache.writeFragment({ - id: aId, - fragment: gql`fragment AValue on A { value }`, - data: { value: a123.result.a.value + 1 }, - }); + cache.modify({ + value(x: number) { + return x + 1; + }, + }, aId); const a124 = makeResult("A", 124); expect(aResults).toEqual([a123, a124]); expect(bResults).toEqual([b321]); - cache.writeFragment({ - id: bId, - fragment: gql`fragment BValue on B { value }`, - data: { value: b321.result.b.value + 1 }, - }); + cache.modify({ + value(x: number) { + return x + 1; + }, + }, bId); const b322 = makeResult("B", 322); @@ -1923,22 +2184,40 @@ describe("InMemoryCache#modify", () => { expect(cache.extract()).toEqual(fullSnapshot); function check(isbnToDelete?: string) { - if (isbnToDelete) { - cache.evict({ - id: "ROOT_QUERY", - fieldName: "book", - args: { isbn: isbnToDelete }, - }); - } + let bookCount = 0; + + cache.modify({ + book(book: Reference, { + fieldName, + storeFieldName, + isReference, + readField, + DELETE, + }) { + expect(fieldName).toBe("book"); + expect(isReference(book)).toBe(true); + expect(typeof readField("title", book)).toBe("string"); + expect(readField("__typename", book)).toBe("Book"); + + const parts = storeFieldName.split(":"); + expect(parts.shift()).toBe("book"); + const keyArgs = JSON.parse(parts.join(":")); + expect(typeof keyArgs.isbn).toBe("string"); + expect(Object.keys(keyArgs)).toEqual(["isbn"]); + + expect(readField("isbn", book)).toBe(keyArgs.isbn); + + if (isbnToDelete === keyArgs.isbn) { + return DELETE; + } - return Object.keys( - cache.extract().ROOT_QUERY! - ).reduce((count: number, storeFieldName: string) => { - if ("book" === fieldNameFromStoreName(storeFieldName)) { - ++count; - } - return count; - }, 0); + ++bookCount; + + return book; + }, + }); + + return bookCount; } // No change from repeatedly calling check(). diff --git a/src/cache/inmemory/__tests__/entityStore.ts b/src/cache/inmemory/__tests__/entityStore.ts index 089a68b3e54..4e20c5bda6d 100644 --- a/src/cache/inmemory/__tests__/entityStore.ts +++ b/src/cache/inmemory/__tests__/entityStore.ts @@ -1917,5 +1917,51 @@ describe('EntityStore', () => { title: "The Cuckoo's Calling", }, }); + + cache.modify({ + title(title: string, { + isReference, + toReference, + readField, + }) { + const book = { + __typename: "Book", + isbn: readField("isbn"), + author: "J.K. Rowling", + }; + + // By not passing true as the second argument to toReference, we + // get back a Reference object, but the book.author field is not + // persisted into the store. + const refWithoutAuthor = toReference(book); + expect(isReference(refWithoutAuthor)).toBe(true); + expect(readField("author", refWithoutAuthor as Reference)).toBeUndefined(); + + // Update this very Book entity before we modify its title. + // Passing true for the second argument causes the extra + // book.author field to be persisted into the store. + const ref = toReference(book, true); + expect(isReference(ref)).toBe(true); + expect(readField("author", ref as Reference)).toBe("J.K. Rowling"); + + // In fact, readField doesn't need the ref if we're reading from + // the same entity that we're modifying. + expect(readField("author")).toBe("J.K. Rowling"); + + // Typography matters! + return title.split("'").join("’"); + }, + }, cuckoosCallingId); + + expect(cache.extract()).toEqual({ + ...threeBookSnapshot, + // This book was added as a side effect of the read function. + 'Book:{"isbn":"031648637X"}': { + __typename: "Book", + isbn: "031648637X", + title: "The Cuckoo’s Calling", + author: "J.K. Rowling", + }, + }); }); }); diff --git a/src/cache/inmemory/entityStore.ts b/src/cache/inmemory/entityStore.ts index 2b94b7361dc..e7ac5564aa9 100644 --- a/src/cache/inmemory/entityStore.ts +++ b/src/cache/inmemory/entityStore.ts @@ -12,11 +12,16 @@ import { DeepMerger } from '../../utilities/common/mergeDeep'; import { maybeDeepFreeze } from '../../utilities/common/maybeDeepFreeze'; import { canUseWeakMap } from '../../utilities/common/canUse'; import { NormalizedCache, NormalizedCacheObject } from './types'; -import { hasOwn, fieldNameFromStoreName } from './helpers'; +import { fieldNameFromStoreName } from './helpers'; import { Policies } from './policies'; -import { SafeReadonly } from '../core/types/common'; +import { Modifier, Modifiers, SafeReadonly } from '../core/types/common'; import { Cache } from '../core/types/Cache'; +const hasOwn = Object.prototype.hasOwnProperty; + +const DELETE: any = Object.create(null); +const delModifier: Modifier = () => DELETE; + export abstract class EntityStore implements NormalizedCache { protected data: NormalizedCacheObject = Object.create(null); @@ -72,43 +77,101 @@ export abstract class EntityStore implements NormalizedCache { this instanceof Layer ? this.parent.lookup(dataId, dependOnExistence) : void 0; } - public merge(dataId: string, incoming: StoreObject): StoreObject { + public merge(dataId: string, incoming: StoreObject): void { const existing = this.lookup(dataId); - const merged: StoreObject = - new DeepMerger(storeObjectReconciler).merge(existing, incoming); - + const merged = new DeepMerger(storeObjectReconciler).merge(existing, incoming); // Even if merged === existing, existing may have come from a lower // layer, so we always need to set this.data[dataId] on this level. this.data[dataId] = merged; - if (merged !== existing) { delete this.refs[dataId]; - const fieldsToDirty: Record = Object.create(null); - - // If we added a new StoreObject where there was previously none, - // dirty anything that depended on the existence of this dataId, - // such as the EntityStore#has method. - if (!existing) fieldsToDirty.__exists = 1; - - // Now invalidate dependents who called getFieldValue for any fields - // that are changing as a result of this merge. - Object.keys(incoming).forEach(storeFieldName => { - if (!existing || existing[storeFieldName] !== merged[storeFieldName]) { - fieldsToDirty[fieldNameFromStoreName(storeFieldName)] = 1; - - // If merged[storeFieldName] has become undefined, and this is the - // Root layer, actually delete the property from the merged object, - // which is guaranteed to have been created fresh in this method. - if (merged[storeFieldName] === void 0 && !(this instanceof Layer)) { - delete merged[storeFieldName]; + if (this.group.caching) { + const fieldsToDirty: Record = Object.create(null); + // If we added a new StoreObject where there was previously none, dirty + // anything that depended on the existence of this dataId, such as the + // EntityStore#has method. + if (!existing) fieldsToDirty.__exists = 1; + // Now invalidate dependents who called getFieldValue for any fields + // that are changing as a result of this merge. + Object.keys(incoming).forEach(storeFieldName => { + if (!existing || existing[storeFieldName] !== merged[storeFieldName]) { + fieldsToDirty[fieldNameFromStoreName(storeFieldName)] = 1; + // If merged[storeFieldName] has become undefined, and this is the + // Root layer, actually delete the property from the merged object, + // which is guaranteed to have been created fresh in this method. + if (merged[storeFieldName] === void 0 && !(this instanceof Layer)) { + delete merged[storeFieldName]; + } + } + }); + Object.keys(fieldsToDirty).forEach( + fieldName => this.group.dirty(dataId, fieldName)); + } + } + } + + public modify( + dataId: string, + modifiers: Modifier | Modifiers, + ): boolean { + const storeObject = this.lookup(dataId); + + if (storeObject) { + const changedFields: Record = Object.create(null); + let needToMerge = false; + let allDeleted = true; + + const readField = ( + fieldName: string, + objOrRef?: StoreObject | Reference, + ) => this.getFieldValue(objOrRef || makeReference(dataId), fieldName); + + Object.keys(storeObject).forEach(storeFieldName => { + const fieldName = fieldNameFromStoreName(storeFieldName); + let fieldValue = storeObject[storeFieldName]; + if (fieldValue === void 0) return; + const modify: Modifier = typeof modifiers === "function" + ? modifiers + : modifiers[storeFieldName] || modifiers[fieldName]; + if (modify) { + let newValue = modify === delModifier ? DELETE : + modify(maybeDeepFreeze(fieldValue), { + DELETE, + fieldName, + storeFieldName, + isReference, + toReference: this.toReference, + readField, + }); + if (newValue === DELETE) newValue = void 0; + if (newValue !== fieldValue) { + changedFields[storeFieldName] = newValue; + needToMerge = true; + fieldValue = newValue; } } + if (fieldValue !== void 0) { + allDeleted = false; + } }); - Object.keys(fieldsToDirty).forEach( - fieldName => this.group.dirty(dataId, fieldName)); + if (needToMerge) { + this.merge(dataId, changedFields); + + if (allDeleted) { + if (this instanceof Layer) { + this.data[dataId] = void 0; + } else { + delete this.data[dataId]; + } + this.group.dirty(dataId, "__exists"); + } + + return true; + } } - return merged; + + return false; } // If called with only one argument, removes the entire entity @@ -123,46 +186,15 @@ export abstract class EntityStore implements NormalizedCache { args?: Record, ) { const storeObject = this.lookup(dataId); - if (!storeObject) return false; - - const changedFields: Record = Object.create(null); - - if (fieldName && args) { - // Since we have args, we can compute the specific storeFieldName to - // be deleted (if it exists). - const storeFieldName = this.policies.getStoreFieldName({ - typename: this.getFieldValue(storeObject, "__typename"), - fieldName, - args, - }); - if (storeObject[storeFieldName] !== void 0) { - changedFields[storeFieldName] = void 0; - } - } else { - // Since we don't have specific args, loop over all the keys of - // storeObject and delete the ones that match fieldName. - Object.keys(storeObject).forEach(storeFieldName => { - if (storeObject[storeFieldName] !== void 0 && - (!fieldName || // If no fieldName, all fields match. - fieldName === fieldNameFromStoreName(storeFieldName))) { - changedFields[storeFieldName] = void 0; - } - }); + if (storeObject) { + const typename = this.getFieldValue(storeObject, "__typename"); + const storeFieldName = fieldName && args + ? this.policies.getStoreFieldName({ typename, fieldName, args }) + : fieldName; + return this.modify(dataId, storeFieldName ? { + [storeFieldName]: delModifier, + } : delModifier); } - - if (Object.keys(changedFields).length) { - const merged = this.merge(dataId, changedFields); - if (Object.keys(merged).every(key => merged[key] === void 0)) { - if (this instanceof Layer) { - this.data[dataId] = void 0; - } else { - delete this.data[dataId]; - } - this.group.dirty(dataId, "__exists"); - } - return true; - } - return false; } diff --git a/src/cache/inmemory/helpers.ts b/src/cache/inmemory/helpers.ts index d41568f26db..b01e18d8ff4 100644 --- a/src/cache/inmemory/helpers.ts +++ b/src/cache/inmemory/helpers.ts @@ -10,8 +10,6 @@ import { } from '../../utilities/graphql/storeUtils'; import { DeepMerger, ReconcilerFunction } from '../../utilities/common/mergeDeep'; -export const hasOwn = Object.prototype.hasOwnProperty; - export function getTypenameFromStoreObject( store: NormalizedCache, objectOrReference: StoreObject | Reference, diff --git a/src/cache/inmemory/inMemoryCache.ts b/src/cache/inmemory/inMemoryCache.ts index b1a35ba8d1c..22d797c924c 100644 --- a/src/cache/inmemory/inMemoryCache.ts +++ b/src/cache/inmemory/inMemoryCache.ts @@ -6,6 +6,7 @@ import { dep, wrap } from 'optimism'; import { ApolloCache, Transaction } from '../core/cache'; import { Cache } from '../core/types/Cache'; +import { Modifier, Modifiers } from '../core/types/common'; import { addTypenameToDocument } from '../../utilities/graphql/transform'; import { StoreObject } from '../../utilities/graphql/storeUtils'; import { @@ -150,6 +151,25 @@ export class InMemoryCache extends ApolloCache { } } + public modify( + modifiers: Modifier | Modifiers, + dataId = "ROOT_QUERY", + optimistic = false, + ): boolean { + if (typeof modifiers === "string") { + // In beta testing of Apollo Client 3, the dataId parameter used to + // come before the modifiers. The type system should complain about + // this, but it doesn't have to be fatal if we fix it here. + [modifiers, dataId] = [dataId as any, modifiers]; + } + const store = optimistic ? this.optimisticData : this.data; + if (store.modify(dataId, modifiers)) { + this.broadcastWatches(); + return true; + } + return false; + } + public diff(options: Cache.DiffOptions): Cache.DiffResult { return this.storeReader.diffQueryAgainstStore({ store: options.optimistic ? this.optimisticData : this.data, diff --git a/src/cache/inmemory/types.ts b/src/cache/inmemory/types.ts index 36cda0747ef..0a43223be6d 100644 --- a/src/cache/inmemory/types.ts +++ b/src/cache/inmemory/types.ts @@ -1,6 +1,7 @@ import { DocumentNode } from 'graphql'; import { Transaction } from '../core/cache'; +import { Modifier, Modifiers } from '../core/types/common'; import { StoreValue, StoreObject } from '../../utilities/graphql/storeUtils'; import { FieldValueGetter, ToReferenceFunction } from './entityStore'; import { KeyFieldsFunction } from './policies'; @@ -23,7 +24,9 @@ export declare type IdGetter = ( export interface NormalizedCache { has(dataId: string): boolean; get(dataId: string, fieldName: string): StoreValue; - merge(dataId: string, incoming: StoreObject): StoreObject; + merge(dataId: string, incoming: StoreObject): void; + modify(dataId: string, modifiers: Modifier | Modifiers): boolean; + delete(dataId: string, fieldName?: string): boolean; clear(): void; // non-Map elements: From df94cb3300525d38cea258fac6fdd4e95ca123d7 Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Wed, 20 May 2020 15:39:16 -0400 Subject: [PATCH 02/56] Make cache.modify readField helper work like read/merge readField. --- src/cache/core/cache.ts | 9 ------ src/cache/core/types/common.ts | 31 ++------------------ src/cache/inmemory/entityStore.ts | 21 ++++++++++---- src/cache/inmemory/inMemoryCache.ts | 3 +- src/cache/inmemory/policies.ts | 29 ++++++------------- src/cache/inmemory/readFromStore.ts | 3 +- src/cache/inmemory/types.ts | 44 +++++++++++++++++++++++++++-- src/cache/inmemory/writeToStore.ts | 2 ++ 8 files changed, 72 insertions(+), 70 deletions(-) diff --git a/src/cache/core/cache.ts b/src/cache/core/cache.ts index ff0415d9b73..759bf9f7ebd 100644 --- a/src/cache/core/cache.ts +++ b/src/cache/core/cache.ts @@ -5,7 +5,6 @@ import { getFragmentQueryDocument } from '../../utilities/graphql/fragments'; import { StoreObject } from '../../utilities/graphql/storeUtils'; import { DataProxy } from './types/DataProxy'; import { Cache } from './types/Cache'; -import { Modifier, Modifiers } from './types/common'; export type Transaction = (c: ApolloCache) => void; @@ -78,14 +77,6 @@ export abstract class ApolloCache implements DataProxy { public identify(object: StoreObject): string | undefined { return; } - - public modify( - modifiers: Modifier | Modifiers, - dataId?: string, - optimistic?: boolean, - ): boolean { - return false; - } public gc(): string[] { return []; diff --git a/src/cache/core/types/common.ts b/src/cache/core/types/common.ts index e685837374a..2bc7442afa2 100644 --- a/src/cache/core/types/common.ts +++ b/src/cache/core/types/common.ts @@ -1,14 +1,3 @@ -import { DocumentNode } from 'graphql'; - -import { - isReference, - StoreValue, - StoreObject, - Reference -} from '../../../utilities/graphql/storeUtils'; - -import { ToReferenceFunction } from '../../inmemory/entityStore'; - // The Readonly type only really works for object types, since it marks // all of the object's properties as readonly, but there are many cases when // a generic type parameter like TExisting might be a string or some other @@ -18,27 +7,11 @@ import { ToReferenceFunction } from '../../inmemory/entityStore'; // Readonly, somewhat surprisingly. export type SafeReadonly = T extends object ? Readonly : T; -export type Modifier = (value: T, details: { - DELETE: any; - fieldName: string; - storeFieldName: string; - isReference: typeof isReference; - toReference: ToReferenceFunction; - readField( - fieldName: string, - objOrRef?: StoreObject | Reference, - ): SafeReadonly; -}) => T; - -export type Modifiers = { - [fieldName: string]: Modifier; -} - export class MissingFieldError { constructor( public readonly message: string, public readonly path: (string | number)[], - public readonly query: DocumentNode, - public readonly variables: Record, + public readonly query: import('graphql').DocumentNode, + public readonly variables?: Record, ) {} } diff --git a/src/cache/inmemory/entityStore.ts b/src/cache/inmemory/entityStore.ts index e7ac5564aa9..e31a69cd980 100644 --- a/src/cache/inmemory/entityStore.ts +++ b/src/cache/inmemory/entityStore.ts @@ -11,10 +11,10 @@ import { import { DeepMerger } from '../../utilities/common/mergeDeep'; import { maybeDeepFreeze } from '../../utilities/common/maybeDeepFreeze'; import { canUseWeakMap } from '../../utilities/common/canUse'; -import { NormalizedCache, NormalizedCacheObject } from './types'; +import { NormalizedCache, NormalizedCacheObject, Modifiers, Modifier, ReadFieldFunction, ReadFieldOptions } from './types'; import { fieldNameFromStoreName } from './helpers'; import { Policies } from './policies'; -import { Modifier, Modifiers, SafeReadonly } from '../core/types/common'; +import { SafeReadonly } from '../core/types/common'; import { Cache } from '../core/types/Cache'; const hasOwn = Object.prototype.hasOwnProperty; @@ -121,10 +121,19 @@ export abstract class EntityStore implements NormalizedCache { let needToMerge = false; let allDeleted = true; - const readField = ( - fieldName: string, - objOrRef?: StoreObject | Reference, - ) => this.getFieldValue(objOrRef || makeReference(dataId), fieldName); + const readField: ReadFieldFunction = ( + fieldNameOrOptions: string | ReadFieldOptions, + from?: StoreObject | Reference, + ) => this.policies.readField( + typeof fieldNameOrOptions === "string" ? { + fieldName: fieldNameOrOptions, + from: from || makeReference(dataId), + } : fieldNameOrOptions, + { + toReference: this.toReference, + getFieldValue: this.getFieldValue, + }, + ); Object.keys(storeObject).forEach(storeFieldName => { const fieldName = fieldNameFromStoreName(storeFieldName); diff --git a/src/cache/inmemory/inMemoryCache.ts b/src/cache/inmemory/inMemoryCache.ts index 22d797c924c..7adc88bc274 100644 --- a/src/cache/inmemory/inMemoryCache.ts +++ b/src/cache/inmemory/inMemoryCache.ts @@ -6,12 +6,13 @@ import { dep, wrap } from 'optimism'; import { ApolloCache, Transaction } from '../core/cache'; import { Cache } from '../core/types/Cache'; -import { Modifier, Modifiers } from '../core/types/common'; import { addTypenameToDocument } from '../../utilities/graphql/transform'; import { StoreObject } from '../../utilities/graphql/storeUtils'; import { ApolloReducerConfig, NormalizedCacheObject, + Modifiers, + Modifier, } from './types'; import { StoreReader } from './readFromStore'; import { StoreWriter } from './writeToStore'; diff --git a/src/cache/inmemory/policies.ts b/src/cache/inmemory/policies.ts index 2cf61abaeb9..d6ca07a4096 100644 --- a/src/cache/inmemory/policies.ts +++ b/src/cache/inmemory/policies.ts @@ -24,7 +24,12 @@ import { getStoreKeyName, } from '../../utilities/graphql/storeUtils'; import { canUseWeakMap } from '../../utilities/common/canUse'; -import { IdGetter } from "./types"; +import { + IdGetter, + FieldSpecifier, + ReadFieldOptions, + ReadFieldFunction, +} from "./types"; import { fieldNameFromStoreName, FieldValueToBeMerged, @@ -98,23 +103,11 @@ export type FieldPolicy< type StorageType = Record; -interface FieldSpecifier { - typename?: string; - fieldName: string; - field?: FieldNode; - args?: Record; - variables?: Record; -} - function argsFromFieldSpecifier(spec: FieldSpecifier) { return spec.args !== void 0 ? spec.args : spec.field ? argumentsObjectFromField(spec.field, spec.variables) : null; } -export interface ReadFieldOptions extends FieldSpecifier { - from?: StoreObject | Reference; -} - export interface FieldFunctionOptions< TArgs = Record, TVars = Record, @@ -150,11 +143,7 @@ export interface FieldFunctionOptions< // to compute the argument values. Note that this function will invoke // custom read functions for other fields, if defined. Always returns // immutable data (enforced with Object.freeze in development). - readField(options: ReadFieldOptions): SafeReadonly | undefined; - readField( - fieldName: string, - from?: StoreObject | Reference, - ): SafeReadonly | undefined; + readField: ReadFieldFunction; // A handy place to put field-specific data that you want to survive // across multiple read function calls. Useful for field-level caching, @@ -653,9 +642,7 @@ export class Policies { } export interface ReadMergeContext { - variables: Record; - // A JSON.stringify-serialized version of context.variables. - varString: string; + variables?: Record; toReference: ToReferenceFunction; getFieldValue: FieldValueGetter; } diff --git a/src/cache/inmemory/readFromStore.ts b/src/cache/inmemory/readFromStore.ts index 33cf095f4dc..454b3a5fbdb 100644 --- a/src/cache/inmemory/readFromStore.ts +++ b/src/cache/inmemory/readFromStore.ts @@ -45,8 +45,9 @@ interface ExecContext extends ReadMergeContext { query: DocumentNode; store: NormalizedCache; policies: Policies; + // A JSON.stringify-serialized version of context.variables. + varString: string; fragmentMap: FragmentMap; - variables: VariableMap; path: (string | number)[]; }; diff --git a/src/cache/inmemory/types.ts b/src/cache/inmemory/types.ts index 0a43223be6d..7b23b799e76 100644 --- a/src/cache/inmemory/types.ts +++ b/src/cache/inmemory/types.ts @@ -1,10 +1,15 @@ -import { DocumentNode } from 'graphql'; +import { DocumentNode, FieldNode } from 'graphql'; import { Transaction } from '../core/cache'; -import { Modifier, Modifiers } from '../core/types/common'; -import { StoreValue, StoreObject } from '../../utilities/graphql/storeUtils'; +import { + StoreObject, + StoreValue, + isReference, + Reference, +} from '../../utilities/graphql/storeUtils'; import { FieldValueGetter, ToReferenceFunction } from './entityStore'; import { KeyFieldsFunction } from './policies'; +import { SafeReadonly } from '../core/types/common'; export { StoreObject, StoreValue } export interface IdGetterObj extends Object { @@ -101,3 +106,36 @@ export type CacheResolverMap = { // backwards compat export type CustomResolver = CacheResolver; export type CustomResolverMap = CacheResolverMap; + +export interface FieldSpecifier { + typename?: string; + fieldName: string; + field?: FieldNode; + args?: Record; + variables?: Record; +} + +export interface ReadFieldOptions extends FieldSpecifier { + from?: StoreObject | Reference; +} + +export interface ReadFieldFunction { + (options: ReadFieldOptions): SafeReadonly | undefined; + ( + fieldName: string, + from?: StoreObject | Reference, + ): SafeReadonly | undefined; +} + +export type Modifier = (value: T, details: { + DELETE: any; + fieldName: string; + storeFieldName: string; + isReference: typeof isReference; + toReference: ToReferenceFunction; + readField: ReadFieldFunction; +}) => T; + +export type Modifiers = { + [fieldName: string]: Modifier; +} diff --git a/src/cache/inmemory/writeToStore.ts b/src/cache/inmemory/writeToStore.ts index a58dfaccfba..448a580b227 100644 --- a/src/cache/inmemory/writeToStore.ts +++ b/src/cache/inmemory/writeToStore.ts @@ -40,6 +40,8 @@ export interface WriteContext extends ReadMergeContext { readonly fragmentMap?: FragmentMap; // General-purpose deep-merge function for use during writes. merge(existing: T, incoming: T): T; + // A JSON.stringify-serialized version of context.variables. + varString: string; }; interface ProcessSelectionSetOptions { From 09280f4001df316f0337a706c008780412ada257 Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Thu, 21 May 2020 17:44:53 -0400 Subject: [PATCH 03/56] Treat every cache.write as a transaction. This way, if a merge function happens to call cache.write recursively, it will not be broadcast in the middle of another write. --- src/cache/inmemory/inMemoryCache.ts | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/cache/inmemory/inMemoryCache.ts b/src/cache/inmemory/inMemoryCache.ts index 7adc88bc274..4778f672773 100644 --- a/src/cache/inmemory/inMemoryCache.ts +++ b/src/cache/inmemory/inMemoryCache.ts @@ -139,16 +139,19 @@ export class InMemoryCache extends ApolloCache { } public write(options: Cache.WriteOptions): void { - this.storeWriter.writeQueryToStore({ - store: this.data, - query: options.query, - result: options.result, - dataId: options.dataId, - variables: options.variables, - }); - - if (options.broadcast !== false) { - this.broadcastWatches(); + try { + ++this.txCount; + this.storeWriter.writeQueryToStore({ + store: this.data, + query: options.query, + result: options.result, + dataId: options.dataId, + variables: options.variables, + }); + } finally { + if (!--this.txCount && options.broadcast !== false) { + this.broadcastWatches(); + } } } From e584273bd869d0f9c433d11b181f087a4672722f Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Thu, 28 May 2020 13:54:23 -0400 Subject: [PATCH 04/56] Treat every cache.evict as a transaction. It's unlikely that the eviction will end up invoking any other cache update operations while it's running, but {in,de}crementing this.txCount still seems like a good/safe idea, if only for uniformity with the other update methods. --- src/cache/inmemory/inMemoryCache.ts | 30 ++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/src/cache/inmemory/inMemoryCache.ts b/src/cache/inmemory/inMemoryCache.ts index 4778f672773..112f53511d4 100644 --- a/src/cache/inmemory/inMemoryCache.ts +++ b/src/cache/inmemory/inMemoryCache.ts @@ -234,18 +234,26 @@ export class InMemoryCache extends ApolloCache { fieldName?: string, args?: Record, ): boolean { - const evicted = this.optimisticData.evict( - typeof idOrOptions === "string" ? { - id: idOrOptions, - fieldName, - args, - } : idOrOptions, - ); - if (typeof idOrOptions === "string" || - idOrOptions.broadcast !== false) { - this.broadcastWatches(); + try { + // It's unlikely that the eviction will end up invoking any other + // cache update operations while it's running, but {in,de}crementing + // this.txCount still seems like a good idea, for uniformity with + // the other update methods. + ++this.txCount; + return this.optimisticData.evict( + typeof idOrOptions === "string" ? { + id: idOrOptions, + fieldName, + args, + } : idOrOptions, + ); + } finally { + if (!--this.txCount && + (typeof idOrOptions === "string" || + idOrOptions.broadcast !== false)) { + this.broadcastWatches(); + } } - return evicted; } public reset(): Promise { From f125a343636c37078c2a1e1cf5254322d4f95098 Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Thu, 21 May 2020 17:47:24 -0400 Subject: [PATCH 05/56] Treat every cache.modify as a transaction. --- src/cache/inmemory/inMemoryCache.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/cache/inmemory/inMemoryCache.ts b/src/cache/inmemory/inMemoryCache.ts index 112f53511d4..55768de26b0 100644 --- a/src/cache/inmemory/inMemoryCache.ts +++ b/src/cache/inmemory/inMemoryCache.ts @@ -167,11 +167,13 @@ export class InMemoryCache extends ApolloCache { [modifiers, dataId] = [dataId as any, modifiers]; } const store = optimistic ? this.optimisticData : this.data; - if (store.modify(dataId, modifiers)) { + try { + ++this.txCount; + return store.modify(dataId, modifiers); + } finally { + --this.txCount; this.broadcastWatches(); - return true; } - return false; } public diff(options: Cache.DiffOptions): Cache.DiffResult { From f999af1fcf8e88ed6250b88bd924fb9f97c5e6f9 Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Thu, 21 May 2020 18:57:10 -0400 Subject: [PATCH 06/56] Stop passing options.typename to processSelectionSet. --- src/cache/inmemory/writeToStore.ts | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/cache/inmemory/writeToStore.ts b/src/cache/inmemory/writeToStore.ts index 448a580b227..c42152f5828 100644 --- a/src/cache/inmemory/writeToStore.ts +++ b/src/cache/inmemory/writeToStore.ts @@ -49,7 +49,6 @@ interface ProcessSelectionSetOptions { result: Record; selectionSet: SelectionSetNode; context: WriteContext; - typename?: string; out?: { shouldApplyMerges: boolean; }; @@ -111,10 +110,6 @@ export class StoreWriter { // unnecessarily. dataId, selectionSet: operationDefinition.selectionSet, - // If dataId is a well-known root ID such as ROOT_QUERY, we can - // infer its __typename immediately here. Otherwise, the __typename - // will be determined in processSelectionSet, as usual. - typename: this.config.policies.rootTypenamesById[dataId], context: { store, written: Object.create(null), @@ -137,7 +132,6 @@ export class StoreWriter { result, selectionSet, context, - typename, // This object allows processSelectionSet to report useful information // to its callers without explicitly returning that information. out = { @@ -195,7 +189,8 @@ export class StoreWriter { // If typename was not passed in, infer it. Note that typename is // always passed in for tricky-to-infer cases such as "Query" for // ROOT_QUERY. - typename = typename || + const typename = + (dataId && this.config.policies.rootTypenamesById[dataId]) || getTypenameFromResult(result, selectionSet, context.fragmentMap) || (dataId && context.store.get(dataId, "__typename") as string); From 25400d0da87211cdc43799a297506cb2ebce4929 Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Tue, 26 May 2020 19:44:12 -0400 Subject: [PATCH 07/56] Don't declare mergedFields earlier than necessary. --- src/cache/inmemory/writeToStore.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/cache/inmemory/writeToStore.ts b/src/cache/inmemory/writeToStore.ts index c42152f5828..c1b5a335450 100644 --- a/src/cache/inmemory/writeToStore.ts +++ b/src/cache/inmemory/writeToStore.ts @@ -140,10 +140,6 @@ export class StoreWriter { }: ProcessSelectionSetOptions): StoreObject | Reference { const { policies, reader } = this.config; - // This mergedFields variable will be repeatedly updated using context.merge - // to accumulate all fields that need to be written into the store. - let mergedFields: StoreObject = Object.create(null); - // Identify the result object, even if dataId was already provided, // since we always need keyObject below. const [id, keyObject] = @@ -153,12 +149,6 @@ export class StoreWriter { // policies.identify. dataId = dataId || id; - // Write any key fields that were used during identification, even if - // they were not mentioned in the original query. - if (keyObject) { - mergedFields = context.merge(mergedFields, keyObject); - } - if ("string" === typeof dataId) { // Avoid processing the same entity object using the same selection // set more than once. We use an array instead of a Set since most @@ -186,6 +176,16 @@ export class StoreWriter { } } + // This mergedFields variable will be repeatedly updated using context.merge + // to accumulate all fields that need to be written into the store. + let mergedFields: StoreObject = Object.create(null); + + // Write any key fields that were used during identification, even if + // they were not mentioned in the original query. + if (keyObject) { + mergedFields = context.merge(mergedFields, keyObject); + } + // If typename was not passed in, infer it. Note that typename is // always passed in for tricky-to-infer cases such as "Query" for // ROOT_QUERY. From 7202b78574f9fddd2a513a7f5ebd9212e989f825 Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Thu, 21 May 2020 18:59:37 -0400 Subject: [PATCH 08/56] Return Reference from cache.write. Apollo Client does not currently use this result internally, so alternate ApolloCache implementations are free to continue returning undefined. --- src/ApolloClient.ts | 6 +-- src/cache/core/__tests__/cache.ts | 6 ++- src/cache/core/cache.ts | 12 +++--- src/cache/core/types/Cache.ts | 2 +- src/cache/core/types/DataProxy.ts | 2 +- src/cache/inmemory/inMemoryCache.ts | 6 +-- src/cache/inmemory/writeToStore.ts | 65 +++++++++++++++++++---------- 7 files changed, 60 insertions(+), 39 deletions(-) diff --git a/src/ApolloClient.ts b/src/ApolloClient.ts index cf7badf7dcf..736db198415 100644 --- a/src/ApolloClient.ts +++ b/src/ApolloClient.ts @@ -403,9 +403,8 @@ export class ApolloClient implements DataProxy { public writeQuery( options: DataProxy.WriteQueryOptions, ): void { - const result = this.cache.writeQuery(options); + this.cache.writeQuery(options); this.queryManager.broadcastQueries(); - return result; } /** @@ -422,9 +421,8 @@ export class ApolloClient implements DataProxy { public writeFragment( options: DataProxy.WriteFragmentOptions, ): void { - const result = this.cache.writeFragment(options); + this.cache.writeFragment(options); this.queryManager.broadcastQueries(); - return result; } public __actionHookForDevTools(cb: () => any) { diff --git a/src/cache/core/__tests__/cache.ts b/src/cache/core/__tests__/cache.ts index 04b3cdb6bfe..f1417add255 100644 --- a/src/cache/core/__tests__/cache.ts +++ b/src/cache/core/__tests__/cache.ts @@ -1,6 +1,7 @@ import gql from 'graphql-tag'; import { ApolloCache } from '../cache'; import { Cache, DataProxy } from '../..'; +import { Reference } from '../../../utilities/graphql/storeUtils'; class TestCache extends ApolloCache { constructor() { @@ -45,7 +46,10 @@ class TestCache extends ApolloCache { }; } - public write(write: Cache.WriteOptions): void { + public write( + _: Cache.WriteOptions, + ): Reference | undefined { + return; } } const query = gql`{ a }`; diff --git a/src/cache/core/cache.ts b/src/cache/core/cache.ts index 759bf9f7ebd..acd20c2288a 100644 --- a/src/cache/core/cache.ts +++ b/src/cache/core/cache.ts @@ -2,7 +2,7 @@ import { DocumentNode } from 'graphql'; import { wrap } from 'optimism'; import { getFragmentQueryDocument } from '../../utilities/graphql/fragments'; -import { StoreObject } from '../../utilities/graphql/storeUtils'; +import { StoreObject, Reference } from '../../utilities/graphql/storeUtils'; import { DataProxy } from './types/DataProxy'; import { Cache } from './types/Cache'; @@ -16,7 +16,7 @@ export abstract class ApolloCache implements DataProxy { ): T | null; public abstract write( write: Cache.WriteOptions, - ): void; + ): Reference | undefined; public abstract diff(query: Cache.DiffOptions): Cache.DiffResult; public abstract watch(watch: Cache.WatchOptions): () => void; public abstract reset(): Promise; @@ -124,8 +124,8 @@ export abstract class ApolloCache implements DataProxy { public writeQuery( options: Cache.WriteQueryOptions, - ): void { - this.write({ + ): Reference | undefined { + return this.write({ dataId: options.id || 'ROOT_QUERY', result: options.data, query: options.query, @@ -136,8 +136,8 @@ export abstract class ApolloCache implements DataProxy { public writeFragment( options: Cache.WriteFragmentOptions, - ): void { - this.write({ + ): Reference | undefined { + return this.write({ dataId: options.id, result: options.data, variables: options.variables, diff --git a/src/cache/core/types/Cache.ts b/src/cache/core/types/Cache.ts index 55d7e4279c8..ea18b2ab627 100644 --- a/src/cache/core/types/Cache.ts +++ b/src/cache/core/types/Cache.ts @@ -12,7 +12,7 @@ export namespace Cache { export interface WriteOptions extends DataProxy.Query { - dataId: string; + dataId?: string; result: TResult; broadcast?: boolean; } diff --git a/src/cache/core/types/DataProxy.ts b/src/cache/core/types/DataProxy.ts index d9da863b13c..2e02ae6c42e 100644 --- a/src/cache/core/types/DataProxy.ts +++ b/src/cache/core/types/DataProxy.ts @@ -30,7 +30,7 @@ export namespace DataProxy { * value returned by your `dataIdFromObject` function. If a value with your * id does not exist in the store, `null` will be returned. */ - id: string; + id?: string; /** * A GraphQL document created using the `gql` template string tag from diff --git a/src/cache/inmemory/inMemoryCache.ts b/src/cache/inmemory/inMemoryCache.ts index 55768de26b0..2dc7c8b17e3 100644 --- a/src/cache/inmemory/inMemoryCache.ts +++ b/src/cache/inmemory/inMemoryCache.ts @@ -7,7 +7,7 @@ import { dep, wrap } from 'optimism'; import { ApolloCache, Transaction } from '../core/cache'; import { Cache } from '../core/types/Cache'; import { addTypenameToDocument } from '../../utilities/graphql/transform'; -import { StoreObject } from '../../utilities/graphql/storeUtils'; +import { StoreObject, Reference } from '../../utilities/graphql/storeUtils'; import { ApolloReducerConfig, NormalizedCacheObject, @@ -138,10 +138,10 @@ export class InMemoryCache extends ApolloCache { }) || null; } - public write(options: Cache.WriteOptions): void { + public write(options: Cache.WriteOptions): Reference | undefined { try { ++this.txCount; - this.storeWriter.writeQueryToStore({ + return this.storeWriter.writeToStore({ store: this.data, query: options.query, result: options.result, diff --git a/src/cache/inmemory/writeToStore.ts b/src/cache/inmemory/writeToStore.ts index c1b5a335450..a8cacfdc882 100644 --- a/src/cache/inmemory/writeToStore.ts +++ b/src/cache/inmemory/writeToStore.ts @@ -21,6 +21,7 @@ import { StoreValue, StoreObject, Reference, + isReference, } from '../../utilities/graphql/storeUtils'; import { shouldInclude, hasDirectives } from '../../utilities/graphql/directives'; @@ -54,6 +55,19 @@ interface ProcessSelectionSetOptions { }; } +interface WriteToStoreOptions { + query: DocumentNode; + result: Object; + dataId?: string; + store: NormalizedCache; + variables?: Object; +} + +interface WriteQueryToStoreOptions +extends Omit { + store?: NormalizedCache; +} + export interface StoreWriterConfig { reader?: StoreReader; policies: Policies; @@ -74,28 +88,27 @@ export class StoreWriter { * @param variables A map from the name of a variable to its value. These variables can be * referenced by the query document. */ - public writeQueryToStore({ + public writeQueryToStore( + options: WriteQueryToStoreOptions, + ): NormalizedCache { + const { + dataId = "ROOT_QUERY", + store = new EntityStore.Root({ + policies: this.config.policies, + }), + } = options; + this.writeToStore({ ...options, dataId, store }); + return store; + } + + public writeToStore({ query, result, - dataId = 'ROOT_QUERY', - store = new EntityStore.Root({ - policies: this.config.policies, - }), + dataId, + store, variables, - }: { - query: DocumentNode; - result: Object; - dataId?: string; - store?: NormalizedCache; - variables?: Object; - }): NormalizedCache { + }: WriteToStoreOptions): Reference | undefined { const operationDefinition = getOperationDefinition(query)!; - - // Any IDs written explicitly to the cache (including ROOT_QUERY, most - // frequently) will be retained as reachable root IDs on behalf of their - // owner DocumentNode objects, until/unless evicted for all owners. - store.retain(dataId); - const merger = makeProcessedFieldsMerger(); variables = { @@ -103,11 +116,8 @@ export class StoreWriter { ...variables, }; - this.processSelectionSet({ + const objOrRef = this.processSelectionSet({ result: result || Object.create(null), - // Since we already know the dataId here, pass it to - // processSelectionSet to skip calling policies.identify - // unnecessarily. dataId, selectionSet: operationDefinition.selectionSet, context: { @@ -124,7 +134,16 @@ export class StoreWriter { }, }); - return store; + const ref = isReference(objOrRef) ? objOrRef : + dataId && makeReference(dataId) || void 0; + + if (ref) { + // Any IDs written explicitly to the cache (including ROOT_QUERY, + // most frequently) will be retained as reachable root IDs. + store.retain(ref.__ref); + } + + return ref; } private processSelectionSet({ From 9ade23c78058fa7ca7ad57d9416def62f0020498 Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Tue, 26 May 2020 19:10:21 -0400 Subject: [PATCH 09/56] Use ModifyOptions for cache.modify method. --- src/__tests__/client.ts | 8 +- src/__tests__/local-state/resolvers.ts | 22 +- src/cache/inmemory/__tests__/cache.ts | 222 ++++++++++++-------- src/cache/inmemory/__tests__/entityStore.ts | 69 +++--- src/cache/inmemory/inMemoryCache.ts | 26 +-- src/cache/inmemory/types.ts | 7 + 6 files changed, 204 insertions(+), 150 deletions(-) diff --git a/src/__tests__/client.ts b/src/__tests__/client.ts index c5898b979fa..97f26ac558a 100644 --- a/src/__tests__/client.ts +++ b/src/__tests__/client.ts @@ -2943,9 +2943,11 @@ describe('@connection', () => { checkLastResult(cResults, { c: "see" }); cache.modify({ - c(value) { - expect(value).toBe("see"); - return "saw"; + modifiers: { + c(value) { + expect(value).toBe("see"); + return "saw"; + }, }, }); await wait(); diff --git a/src/__tests__/local-state/resolvers.ts b/src/__tests__/local-state/resolvers.ts index e7ba416fe1b..1b8128db541 100644 --- a/src/__tests__/local-state/resolvers.ts +++ b/src/__tests__/local-state/resolvers.ts @@ -554,11 +554,14 @@ describe('Writing cache data from resolvers', () => { }); cache.modify({ - field(value) { - expect(value).toBe(1); - return 2; + id: 'Object:uniqueId', + modifiers: { + field(value) { + expect(value).toBe(1); + return 2; + }, }, - }, 'Object:uniqueId'); + }); return { start: true }; }, @@ -611,11 +614,14 @@ describe('Writing cache data from resolvers', () => { }, }); cache.modify({ - field(value: { field2: number }) { - expect(value.field2).toBe(1); - return { ...value, field2: 2 }; + id: 'Object:uniqueId', + modifiers: { + field(value: { field2: number }) { + expect(value.field2).toBe(1); + return { ...value, field2: 2 }; + }, }, - }, 'Object:uniqueId'); + }) return { start: true }; }, }, diff --git a/src/cache/inmemory/__tests__/cache.ts b/src/cache/inmemory/__tests__/cache.ts index 824539e5440..d3b5b09bf5e 100644 --- a/src/cache/inmemory/__tests__/cache.ts +++ b/src/cache/inmemory/__tests__/cache.ts @@ -1560,12 +1560,14 @@ describe("InMemoryCache#modify", () => { const resultBeforeModify = cache.readQuery({ query }); expect(resultBeforeModify).toEqual({ a: 0, b: 0, c: 0 }); - cache.modify((value, { fieldName }) => { - switch (fieldName) { - case "a": return value + 1; - case "b": return value - 1; - default: return value; - } + cache.modify({ + modifiers(value, { fieldName }) { + switch (fieldName) { + case "a": return value + 1; + case "b": return value - 1; + default: return value; + } + }, }); expect(cache.extract()).toEqual({ @@ -1605,13 +1607,15 @@ describe("InMemoryCache#modify", () => { let checkedTypename = false; cache.modify({ - a(value) { return value + 1 }, - b(value) { return value - 1 }, - __typename(t: string, { readField }) { - expect(t).toBe("Query"); - expect(readField("c")).toBe(0); - checkedTypename = true; - return t; + modifiers: { + a(value) { return value + 1 }, + b(value) { return value - 1 }, + __typename(t: string, { readField }) { + expect(t).toBe("Query"); + expect(readField("c")).toBe(0); + checkedTypename = true; + return t; + }, }, }); expect(checkedTypename).toBe(true); @@ -1698,10 +1702,13 @@ describe("InMemoryCache#modify", () => { expect(authorId).toBe('Author:{"name":"Ezra Klein"}'); cache.modify({ - yearOfBirth(yob) { - return yob + 1; + id: authorId, + modifiers: { + yearOfBirth(yob) { + return yob + 1; + }, }, - }, authorId); + }); const yobResult = cache.readFragment({ id: authorId, @@ -1718,21 +1725,27 @@ describe("InMemoryCache#modify", () => { // Modifying the Book in order to modify the Author is fancier than // necessary, but we want fancy use cases to work, too. cache.modify({ - author(author: Reference, { readField }) { - expect(readField("title")).toBe("Why We're Polarized"); - expect(readField("name", author)).toBe("Ezra Klein"); - cache.modify({ - yearOfBirth(yob, { DELETE }) { - expect(yob).toBe(1984); - return DELETE; - }, - }, cache.identify({ - __typename: readField("__typename", author), - name: readField("name", author), - })); - return author; - } - }, bookId); + id: bookId, + modifiers: { + author(author: Reference, { readField }) { + expect(readField("title")).toBe("Why We're Polarized"); + expect(readField("name", author)).toBe("Ezra Klein"); + cache.modify({ + modifiers: { + yearOfBirth(yob, { DELETE }) { + expect(yob).toBe(1984); + return DELETE; + }, + }, + id: cache.identify({ + __typename: readField("__typename", author), + name: readField("name", author), + }), + }); + return author; + }, + }, + }); const snapshotWithoutYOB = cache.extract(); expect(snapshotWithoutYOB[authorId]!.yearOfBirth).toBeUndefined(); @@ -1760,7 +1773,10 @@ describe("InMemoryCache#modify", () => { }); // Delete the whole Book. - cache.modify((_, { DELETE }) => DELETE, bookId); + cache.modify({ + id: bookId, + modifiers: (_, { DELETE }) => DELETE, + }); const snapshotWithoutBook = cache.extract(); expect(snapshotWithoutBook[bookId]).toBeUndefined(); @@ -1780,9 +1796,12 @@ describe("InMemoryCache#modify", () => { // Delete all fields of the Author, which also removes the object. cache.modify({ - __typename(_, { DELETE }) { return DELETE }, - name(_, { DELETE }) { return DELETE }, - }, authorId); + id: authorId, + modifiers: { + __typename(_, { DELETE }) { return DELETE }, + name(_, { DELETE }) { return DELETE }, + }, + }); const snapshotWithoutAuthor = cache.extract(); expect(snapshotWithoutAuthor[authorId]).toBeUndefined(); @@ -1796,7 +1815,10 @@ describe("InMemoryCache#modify", () => { }, }); - cache.modify((_, { DELETE }) => DELETE); + cache.modify({ + modifiers: (_, { DELETE }) => DELETE, + }); + expect(cache.extract()).toEqual({}); }); @@ -1909,20 +1931,24 @@ describe("InMemoryCache#modify", () => { }); cache.modify({ - comments(comments: Reference[], { readField }) { - debugger; - expect(Object.isFrozen(comments)).toBe(true); - expect(comments.length).toBe(3); - const filtered = comments.filter(comment => { - return readField("id", comment) !== "c1"; - }); - expect(filtered.length).toBe(2); - return filtered; + modifiers: { + comments(comments: Reference[], { readField }) { + debugger; + expect(Object.isFrozen(comments)).toBe(true); + expect(comments.length).toBe(3); + const filtered = comments.filter(comment => { + return readField("id", comment) !== "c1"; + }); + expect(filtered.length).toBe(2); + return filtered; + }, }, - }, cache.identify({ - __typename: "Thread", - tid: 123, - })); + + id: cache.identify({ + __typename: "Thread", + tid: 123, + }), + }); expect(cache.gc()).toEqual(['Comment:{"id":"c1"}']); @@ -1970,11 +1996,14 @@ describe("InMemoryCache#modify", () => { }, "transaction"); cache.modify({ - b(value, { DELETE }) { - expect(value).toBe(2); - return DELETE; + modifiers: { + b(value, { DELETE }) { + expect(value).toBe(2); + return DELETE; + }, }, - }, "ROOT_QUERY", true); + optimistic: true, + }); expect(cache.extract(true)).toEqual({ ROOT_QUERY: { @@ -1984,11 +2013,14 @@ describe("InMemoryCache#modify", () => { }, }); - cache.modify((value, { fieldName }) => { - expect(fieldName).not.toBe("b"); - if (fieldName === "a") expect(value).toBe(1); - if (fieldName === "c") expect(value).toBe(3); - }, "ROOT_QUERY", true); + cache.modify({ + modifiers(value, { fieldName }) { + expect(fieldName).not.toBe("b"); + if (fieldName === "a") expect(value).toBe(1); + if (fieldName === "c") expect(value).toBe(3); + }, + optimistic: true, + }); cache.removeOptimistic("transaction"); @@ -2086,10 +2118,13 @@ describe("InMemoryCache#modify", () => { const bId = cache.identify({ __typename: "B", id: 1 }); cache.modify({ - value(x: number) { - return x + 1; + id: aId, + modifiers: { + value(x: number) { + return x + 1; + }, }, - }, aId); + }); const a124 = makeResult("A", 124); @@ -2097,10 +2132,13 @@ describe("InMemoryCache#modify", () => { expect(bResults).toEqual([b321]); cache.modify({ - value(x: number) { - return x + 1; + id: bId, + modifiers: { + value(x: number) { + return x + 1; + }, }, - }, bId); + }); const b322 = makeResult("B", 322); @@ -2187,33 +2225,39 @@ describe("InMemoryCache#modify", () => { let bookCount = 0; cache.modify({ - book(book: Reference, { - fieldName, - storeFieldName, - isReference, - readField, - DELETE, - }) { - expect(fieldName).toBe("book"); - expect(isReference(book)).toBe(true); - expect(typeof readField("title", book)).toBe("string"); - expect(readField("__typename", book)).toBe("Book"); - - const parts = storeFieldName.split(":"); - expect(parts.shift()).toBe("book"); - const keyArgs = JSON.parse(parts.join(":")); - expect(typeof keyArgs.isbn).toBe("string"); - expect(Object.keys(keyArgs)).toEqual(["isbn"]); - - expect(readField("isbn", book)).toBe(keyArgs.isbn); - - if (isbnToDelete === keyArgs.isbn) { - return DELETE; - } + modifiers: { + book(book: Reference, { + fieldName, + storeFieldName, + isReference, + readField, + DELETE, + }) { + expect(fieldName).toBe("book"); + expect(isReference(book)).toBe(true); + expect(typeof readField("title", book)).toBe("string"); + expect(readField("__typename", book)).toBe("Book"); + expect(readField({ + fieldName: "__typename", + from: book, + })).toBe("Book"); + + const parts = storeFieldName.split(":"); + expect(parts.shift()).toBe("book"); + const keyArgs = JSON.parse(parts.join(":")); + expect(typeof keyArgs.isbn).toBe("string"); + expect(Object.keys(keyArgs)).toEqual(["isbn"]); + + expect(readField("isbn", book)).toBe(keyArgs.isbn); + + if (isbnToDelete === keyArgs.isbn) { + return DELETE; + } - ++bookCount; + ++bookCount; - return book; + return book; + }, }, }); diff --git a/src/cache/inmemory/__tests__/entityStore.ts b/src/cache/inmemory/__tests__/entityStore.ts index 4e20c5bda6d..5700c5878f4 100644 --- a/src/cache/inmemory/__tests__/entityStore.ts +++ b/src/cache/inmemory/__tests__/entityStore.ts @@ -1919,39 +1919,42 @@ describe('EntityStore', () => { }); cache.modify({ - title(title: string, { - isReference, - toReference, - readField, - }) { - const book = { - __typename: "Book", - isbn: readField("isbn"), - author: "J.K. Rowling", - }; - - // By not passing true as the second argument to toReference, we - // get back a Reference object, but the book.author field is not - // persisted into the store. - const refWithoutAuthor = toReference(book); - expect(isReference(refWithoutAuthor)).toBe(true); - expect(readField("author", refWithoutAuthor as Reference)).toBeUndefined(); - - // Update this very Book entity before we modify its title. - // Passing true for the second argument causes the extra - // book.author field to be persisted into the store. - const ref = toReference(book, true); - expect(isReference(ref)).toBe(true); - expect(readField("author", ref as Reference)).toBe("J.K. Rowling"); - - // In fact, readField doesn't need the ref if we're reading from - // the same entity that we're modifying. - expect(readField("author")).toBe("J.K. Rowling"); - - // Typography matters! - return title.split("'").join("’"); - }, - }, cuckoosCallingId); + id: cuckoosCallingId, + modifiers: { + title(title: string, { + isReference, + toReference, + readField, + }) { + const book = { + __typename: "Book", + isbn: readField("isbn"), + author: "J.K. Rowling", + }; + + // By not passing true as the second argument to toReference, we + // get back a Reference object, but the book.author field is not + // persisted into the store. + const refWithoutAuthor = toReference(book); + expect(isReference(refWithoutAuthor)).toBe(true); + expect(readField("author", refWithoutAuthor as Reference)).toBeUndefined(); + + // Update this very Book entity before we modify its title. + // Passing true for the second argument causes the extra + // book.author field to be persisted into the store. + const ref = toReference(book, true); + expect(isReference(ref)).toBe(true); + expect(readField("author", ref as Reference)).toBe("J.K. Rowling"); + + // In fact, readField doesn't need the ref if we're reading from + // the same entity that we're modifying. + expect(readField("author")).toBe("J.K. Rowling"); + + // Typography matters! + return title.split("'").join("’"); + }, + }, + }); expect(cache.extract()).toEqual({ ...threeBookSnapshot, diff --git a/src/cache/inmemory/inMemoryCache.ts b/src/cache/inmemory/inMemoryCache.ts index 2dc7c8b17e3..8340478e206 100644 --- a/src/cache/inmemory/inMemoryCache.ts +++ b/src/cache/inmemory/inMemoryCache.ts @@ -11,8 +11,7 @@ import { StoreObject, Reference } from '../../utilities/graphql/storeUtils'; import { ApolloReducerConfig, NormalizedCacheObject, - Modifiers, - Modifier, + ModifyOptions, } from './types'; import { StoreReader } from './readFromStore'; import { StoreWriter } from './writeToStore'; @@ -155,24 +154,17 @@ export class InMemoryCache extends ApolloCache { } } - public modify( - modifiers: Modifier | Modifiers, - dataId = "ROOT_QUERY", - optimistic = false, - ): boolean { - if (typeof modifiers === "string") { - // In beta testing of Apollo Client 3, the dataId parameter used to - // come before the modifiers. The type system should complain about - // this, but it doesn't have to be fatal if we fix it here. - [modifiers, dataId] = [dataId as any, modifiers]; - } - const store = optimistic ? this.optimisticData : this.data; + public modify(options: ModifyOptions): boolean { + const store = options.optimistic // Defaults to false. + ? this.optimisticData + : this.data; try { ++this.txCount; - return store.modify(dataId, modifiers); + return store.modify(options.id || "ROOT_QUERY", options.modifiers); } finally { - --this.txCount; - this.broadcastWatches(); + if (!--this.txCount && options.broadcast !== false) { + this.broadcastWatches(); + } } } diff --git a/src/cache/inmemory/types.ts b/src/cache/inmemory/types.ts index 7b23b799e76..9618f43f090 100644 --- a/src/cache/inmemory/types.ts +++ b/src/cache/inmemory/types.ts @@ -127,6 +127,13 @@ export interface ReadFieldFunction { ): SafeReadonly | undefined; } +export interface ModifyOptions { + id?: string; + modifiers: Modifiers | Modifier; + optimistic?: boolean; + broadcast?: boolean; +} + export type Modifier = (value: T, details: { DELETE: any; fieldName: string; From df712287646144006f78604158c6d94c34716600 Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Wed, 27 May 2020 19:50:37 -0400 Subject: [PATCH 10/56] Pass options.cache to read, merge, and cache.modify functions. --- .../inmemory/__tests__/diffAgainstStore.ts | 63 +++++----- src/cache/inmemory/__tests__/entityStore.ts | 7 +- src/cache/inmemory/__tests__/helpers.ts | 22 ++++ src/cache/inmemory/__tests__/readFromStore.ts | 9 +- .../inmemory/__tests__/recordingCache.ts | 15 ++- src/cache/inmemory/__tests__/roundtrip.ts | 8 +- src/cache/inmemory/__tests__/writeToStore.ts | 111 +++++++++--------- src/cache/inmemory/entityStore.ts | 12 +- src/cache/inmemory/inMemoryCache.ts | 16 ++- src/cache/inmemory/policies.ts | 21 +++- src/cache/inmemory/readFromStore.ts | 5 +- src/cache/inmemory/types.ts | 2 +- src/cache/inmemory/writeToStore.ts | 25 ++-- 13 files changed, 175 insertions(+), 141 deletions(-) create mode 100644 src/cache/inmemory/__tests__/helpers.ts diff --git a/src/cache/inmemory/__tests__/diffAgainstStore.ts b/src/cache/inmemory/__tests__/diffAgainstStore.ts index e2b768d91fb..6b69157583e 100644 --- a/src/cache/inmemory/__tests__/diffAgainstStore.ts +++ b/src/cache/inmemory/__tests__/diffAgainstStore.ts @@ -1,12 +1,11 @@ import gql, { disableFragmentWarnings } from 'graphql-tag'; -import { Reference } from '../../../core'; -import { defaultNormalizedCacheFactory } from '../entityStore'; +import { defaultNormalizedCacheFactory } from './helpers'; import { StoreReader } from '../readFromStore'; import { StoreWriter } from '../writeToStore'; import { defaultDataIdFromObject } from '../policies'; -import { NormalizedCache } from '../types'; -import { Policies } from '../policies'; +import { NormalizedCache, Reference } from '../types'; +import { InMemoryCache } from '../inMemoryCache'; disableFragmentWarnings(); @@ -29,11 +28,11 @@ export function withError(func: Function, regex?: RegExp) { } describe('diffing queries against the store', () => { - const policies = new Policies({ + const cache = new InMemoryCache({ dataIdFromObject: defaultDataIdFromObject, }) - const reader = new StoreReader({ policies }); - const writer = new StoreWriter({ policies }); + const reader = new StoreReader({ cache }); + const writer = new StoreWriter(cache); it( 'expects named fragments to return complete as true when diffd against ' + @@ -134,15 +133,15 @@ describe('diffing queries against the store', () => { }); it('caches root queries both under the ID of the node and the query name', () => { - const writer = new StoreWriter({ - policies: new Policies({ + const writer = new StoreWriter( + new InMemoryCache({ typePolicies: { Person: { keyFields: ["id"], }, }, }), - }); + ); const store = writer.writeQueryToStore({ query: gql` @@ -496,13 +495,13 @@ describe('diffing queries against the store', () => { }, }; - const policies = new Policies({ + const cache = new InMemoryCache({ dataIdFromObject({ id }: { id: string }) { return id; }, }); - const writer = new StoreWriter({ policies }); + const writer = new StoreWriter(cache); const store = writer.writeQueryToStore({ query, @@ -515,14 +514,14 @@ describe('diffing queries against the store', () => { }); expect(result).toEqual(queryResult); - expect(policies.identify(result.a[0])).toEqual(['a:1']); - expect(policies.identify(result.a[1])).toEqual(['a:2']); - expect(policies.identify(result.a[2])).toEqual(['a:3']); - expect(policies.identify(result.c.e[0])).toEqual(['e:1']); - expect(policies.identify(result.c.e[1])).toEqual(['e:2']); - expect(policies.identify(result.c.e[2])).toEqual(['e:3']); - expect(policies.identify(result.c.e[3])).toEqual(['e:4']); - expect(policies.identify(result.c.e[4])).toEqual(['e:5']); + expect(cache.identify(result.a[0])).toEqual('a:1'); + expect(cache.identify(result.a[1])).toEqual('a:2'); + expect(cache.identify(result.a[2])).toEqual('a:3'); + expect(cache.identify(result.c.e[0])).toEqual('e:1'); + expect(cache.identify(result.c.e[1])).toEqual('e:2'); + expect(cache.identify(result.c.e[2])).toEqual('e:3'); + expect(cache.identify(result.c.e[3])).toEqual('e:4'); + expect(cache.identify(result.c.e[4])).toEqual('e:5'); }); describe('referential equality preservation', () => { @@ -830,11 +829,11 @@ describe('diffing queries against the store', () => { }, }; - const writer = new StoreWriter({ - policies: new Policies({ + const writer = new StoreWriter( + new InMemoryCache({ dataIdFromObject: ({ id }: { id: string }) => id, }), - }); + ); const store = writer.writeQueryToStore({ query, @@ -955,7 +954,7 @@ describe('diffing queries against the store', () => { } `; - const policies = new Policies({ + const cache = new InMemoryCache({ typePolicies: { Query: { fields: { @@ -979,8 +978,8 @@ describe('diffing queries against the store', () => { }, }); - const writer = new StoreWriter({ policies }); - const reader = new StoreReader({ policies }); + const reader = new StoreReader({ cache }); + const writer = new StoreWriter(cache, reader); const store = writer.writeQueryToStore({ query: listQuery, @@ -1155,11 +1154,11 @@ describe('diffing queries against the store', () => { // Check first using generated IDs. check( - new StoreWriter({ - policies: new Policies({ + new StoreWriter( + new InMemoryCache({ dataIdFromObject: void 0, }) - }).writeQueryToStore({ + ).writeQueryToStore({ query, result: { user: company.users[0], @@ -1169,11 +1168,11 @@ describe('diffing queries against the store', () => { // Now check with __typename-specific IDs. check( - new StoreWriter({ - policies: new Policies({ + new StoreWriter( + new InMemoryCache({ dataIdFromObject: defaultDataIdFromObject, }), - }).writeQueryToStore({ + ).writeQueryToStore({ query, result: { user: company.users[0], diff --git a/src/cache/inmemory/__tests__/entityStore.ts b/src/cache/inmemory/__tests__/entityStore.ts index 5700c5878f4..d8634576a99 100644 --- a/src/cache/inmemory/__tests__/entityStore.ts +++ b/src/cache/inmemory/__tests__/entityStore.ts @@ -2,7 +2,6 @@ import gql from 'graphql-tag'; import { EntityStore, supportsResultCaching } from '../entityStore'; import { InMemoryCache } from '../inMemoryCache'; import { DocumentNode } from 'graphql'; -import { Policies } from '../policies'; import { StoreObject } from '../types'; import { ApolloCache } from '../../core/cache'; import { Reference } from '../../../utilities/graphql/storeUtils'; @@ -10,13 +9,15 @@ import { MissingFieldError } from '../..'; describe('EntityStore', () => { it('should support result caching if so configured', () => { + const cache = new InMemoryCache(); + const storeWithResultCaching = new EntityStore.Root({ - policies: new Policies, + policies: cache.policies, resultCaching: true, }); const storeWithoutResultCaching = new EntityStore.Root({ - policies: new Policies, + policies: cache.policies, resultCaching: false, }); diff --git a/src/cache/inmemory/__tests__/helpers.ts b/src/cache/inmemory/__tests__/helpers.ts new file mode 100644 index 00000000000..6052ef2f3c4 --- /dev/null +++ b/src/cache/inmemory/__tests__/helpers.ts @@ -0,0 +1,22 @@ +import { NormalizedCache, NormalizedCacheObject } from "../types"; +import { EntityStore } from "../entityStore"; +import { InMemoryCache } from "../inMemoryCache"; + +export function defaultNormalizedCacheFactory( + seed?: NormalizedCacheObject, +): NormalizedCache { + const cache = new InMemoryCache(); + return new EntityStore.Root({ + policies: cache.policies, + resultCaching: true, + seed, + }); +} + +describe("defaultNormalizedCacheFactory", function () { + it("should return an EntityStore", function () { + const store = defaultNormalizedCacheFactory(); + expect(store).toBeInstanceOf(EntityStore); + expect(store).toBeInstanceOf(EntityStore.Root); + }); +}); diff --git a/src/cache/inmemory/__tests__/readFromStore.ts b/src/cache/inmemory/__tests__/readFromStore.ts index 91c09d38fc9..107d8f496ec 100644 --- a/src/cache/inmemory/__tests__/readFromStore.ts +++ b/src/cache/inmemory/__tests__/readFromStore.ts @@ -4,14 +4,13 @@ import gql from 'graphql-tag'; import { stripSymbols } from '../../../utilities/testing/stripSymbols'; import { StoreObject } from '../types'; import { StoreReader } from '../readFromStore'; -import { makeReference } from '../../../core'; -import { defaultNormalizedCacheFactory } from '../entityStore'; +import { makeReference, InMemoryCache } from '../../../core'; +import { defaultNormalizedCacheFactory } from './helpers'; import { withError } from './diffAgainstStore'; -import { Policies } from '../policies'; describe('reading from the store', () => { const reader = new StoreReader({ - policies: new Policies(), + cache: new InMemoryCache(), }); it('runs a nested query with proper fragment fields in arrays', () => { @@ -773,7 +772,7 @@ describe('reading from the store', () => { it('can use keyArgs function instead of @connection directive', () => { const reader = new StoreReader({ - policies: new Policies({ + cache: new InMemoryCache({ typePolicies: { Query: { fields: { diff --git a/src/cache/inmemory/__tests__/recordingCache.ts b/src/cache/inmemory/__tests__/recordingCache.ts index 02aef723340..26a6fd20901 100644 --- a/src/cache/inmemory/__tests__/recordingCache.ts +++ b/src/cache/inmemory/__tests__/recordingCache.ts @@ -1,6 +1,7 @@ import { NormalizedCacheObject, StoreObject } from '../types'; import { EntityStore } from '../entityStore'; import { Policies } from '../policies'; +import { InMemoryCache } from '../inMemoryCache'; describe('Optimistic EntityStore layering', () => { function makeLayer(root: EntityStore) { @@ -21,7 +22,12 @@ describe('Optimistic EntityStore layering', () => { Human: { __typename: 'Human', name: 'John' }, }; - const underlyingStore = new EntityStore.Root({ seed: data, policies: new Policies() }); + const underlyingStore = new EntityStore.Root({ + seed: data, + policies: new Policies({ + cache: new InMemoryCache(), + }), + }); let store = makeLayer(underlyingStore); beforeEach(() => { @@ -59,7 +65,12 @@ describe('Optimistic EntityStore layering', () => { Human: { __typename: 'Human', name: 'John' }, }; - const underlyingStore = new EntityStore.Root({ seed: data, policies: new Policies() }); + const underlyingStore = new EntityStore.Root({ + seed: data, + policies: new Policies({ + cache: new InMemoryCache(), + }), + }); let store = makeLayer(underlyingStore); let recording: NormalizedCacheObject; diff --git a/src/cache/inmemory/__tests__/roundtrip.ts b/src/cache/inmemory/__tests__/roundtrip.ts index 4d1c256f73c..215b5cc02d9 100644 --- a/src/cache/inmemory/__tests__/roundtrip.ts +++ b/src/cache/inmemory/__tests__/roundtrip.ts @@ -5,7 +5,7 @@ import { withError } from './diffAgainstStore'; import { EntityStore } from '../entityStore'; import { StoreReader } from '../readFromStore'; import { StoreWriter } from '../writeToStore'; -import { Policies } from '../policies'; +import { InMemoryCache } from '../inMemoryCache'; function assertDeeplyFrozen(value: any, stack: any[] = []) { if (value !== null && typeof value === 'object' && stack.indexOf(value) < 0) { @@ -20,14 +20,14 @@ function assertDeeplyFrozen(value: any, stack: any[] = []) { } function storeRoundtrip(query: DocumentNode, result: any, variables = {}) { - const policies = new Policies({ + const cache = new InMemoryCache({ possibleTypes: { Character: ["Jedi", "Droid"], }, }); - const reader = new StoreReader({ policies }); - const writer = new StoreWriter({ policies }); + const reader = new StoreReader({ cache }); + const writer = new StoreWriter(cache); const store = writer.writeQueryToStore({ result, diff --git a/src/cache/inmemory/__tests__/writeToStore.ts b/src/cache/inmemory/__tests__/writeToStore.ts index 1dbbef8d0d9..9344fc234fe 100644 --- a/src/cache/inmemory/__tests__/writeToStore.ts +++ b/src/cache/inmemory/__tests__/writeToStore.ts @@ -17,14 +17,13 @@ import { addTypenameToDocument } from '../../../utilities/graphql/transform'; import { cloneDeep } from '../../../utilities/common/cloneDeep'; import { itAsync } from '../../../utilities/testing/itAsync'; import { StoreWriter } from '../writeToStore'; -import { defaultNormalizedCacheFactory } from '../entityStore'; +import { defaultNormalizedCacheFactory } from './helpers'; import { InMemoryCache } from '../inMemoryCache'; -import { Policies } from '../policies'; const getIdField = ({ id }: { id: string }) => id; describe('writing to the store', () => { - const policies = new Policies({ + const cache = new InMemoryCache({ dataIdFromObject(object: any) { if (object.__typename && object.id) { return object.__typename + '__' + object.id; @@ -32,7 +31,7 @@ describe('writing to the store', () => { }, }); - const writer = new StoreWriter({ policies }); + const writer = new StoreWriter(cache); it('properly normalizes a trivial item', () => { const query = gql` @@ -280,11 +279,11 @@ describe('writing to the store', () => { }, }; - const writer = new StoreWriter({ - policies: new Policies({ + const writer = new StoreWriter( + new InMemoryCache({ dataIdFromObject: getIdField, }), - }); + ); expect( writer @@ -424,11 +423,11 @@ describe('writing to the store', () => { ], }; - const writer = new StoreWriter({ - policies: new Policies({ + const writer = new StoreWriter( + new InMemoryCache({ dataIdFromObject: getIdField, }), - }); + ); expect( writer @@ -481,11 +480,11 @@ describe('writing to the store', () => { ], }; - const writer = new StoreWriter({ - policies: new Policies({ + const writer = new StoreWriter( + new InMemoryCache({ dataIdFromObject: getIdField, }), - }); + ); expect( writer @@ -612,11 +611,11 @@ describe('writing to the store', () => { simpleArray: ['one', 'two', 'three'], }; - const writer = new StoreWriter({ - policies: new Policies({ + const writer = new StoreWriter( + new InMemoryCache({ dataIdFromObject: getIdField, }), - }); + ); const normalized = writer.writeQueryToStore({ query, @@ -690,11 +689,11 @@ describe('writing to the store', () => { }, }; - const writer = new StoreWriter({ - policies: new Policies({ + const writer = new StoreWriter( + new InMemoryCache({ dataIdFromObject: getIdField, }), - }); + ); const normalized = writer.writeQueryToStore({ query, @@ -763,11 +762,11 @@ describe('writing to the store', () => { ], }; - const writer = new StoreWriter({ - policies: new Policies({ + const writer = new StoreWriter( + new InMemoryCache({ dataIdFromObject: getIdField, }), - }); + ); const normalized = writer.writeQueryToStore({ query, @@ -839,11 +838,11 @@ describe('writing to the store', () => { ], }; - const writer = new StoreWriter({ - policies: new Policies({ + const writer = new StoreWriter( + new InMemoryCache({ dataIdFromObject: getIdField, }), - }); + ); const normalized = writer.writeQueryToStore({ query, @@ -889,11 +888,11 @@ describe('writing to the store', () => { nullField: null, }; - const writer = new StoreWriter({ - policies: new Policies({ + const writer = new StoreWriter( + new InMemoryCache({ dataIdFromObject: getIdField, }), - }); + ); const store = writer.writeQueryToStore({ query, @@ -1151,13 +1150,13 @@ describe('writing to the store', () => { mutation.definitions.map((def: OperationDefinitionNode) => { if (isOperationDefinition(def)) { - const writer = new StoreWriter({ - policies: new Policies({ + const writer = new StoreWriter( + new InMemoryCache({ dataIdFromObject() { return '5'; }, }), - }); + ); expect( writer.writeQueryToStore({ @@ -1234,9 +1233,9 @@ describe('writing to the store', () => { const expStore = defaultNormalizedCacheFactory({ ROOT_QUERY: { __typename: 'Query', - author: makeReference(policies.identify(data.author)[0]!), + author: makeReference(cache.identify(data.author)!), }, - [policies.identify(data.author)[0]!]: { + [cache.identify(data.author)!]: { firstName: data.author.firstName, id: data.author.id, __typename: data.author.__typename, @@ -1274,9 +1273,9 @@ describe('writing to the store', () => { const expStore = defaultNormalizedCacheFactory({ ROOT_QUERY: { __typename: 'Query', - author: makeReference(policies.identify(data.author)[0]!), + author: makeReference(cache.identify(data.author)!), }, - [policies.identify(data.author)[0]!]: { + [cache.identify(data.author)!]: { __typename: data.author.__typename, id: data.author.id, info: data.author.info, @@ -1518,11 +1517,11 @@ describe('writing to the store', () => { ], }; - const writer = new StoreWriter({ - policies: new Policies({ + const writer = new StoreWriter( + new InMemoryCache({ dataIdFromObject: getIdField, }), - }); + ); const newStore = writer.writeQueryToStore({ query, @@ -1542,12 +1541,12 @@ describe('writing to the store', () => { ], }; - const writer = new StoreWriter({ - policies: new Policies({ + const writer = new StoreWriter( + new InMemoryCache({ dataIdFromObject: getIdField, possibleTypes: {}, }), - }); + ); expect(() => { writer.writeQueryToStore({ @@ -1592,14 +1591,14 @@ describe('writing to the store', () => { ], }; - const writer = new StoreWriter({ - policies: new Policies({ + const writer = new StoreWriter( + new InMemoryCache({ dataIdFromObject: getIdField, possibleTypes: { Todo: ["ShoppingCartItem", "TaskItem"], }, }), - }); + ); expect(() => { writer.writeQueryToStore({ @@ -1620,12 +1619,12 @@ describe('writing to the store', () => { ], }; - const writer = new StoreWriter({ - policies: new Policies({ + const writer = new StoreWriter( + new InMemoryCache({ dataIdFromObject: getIdField, possibleTypes: {}, }), - }); + ); expect(() => { writer.writeQueryToStore({ @@ -1640,11 +1639,11 @@ describe('writing to the store', () => { todos: null, }; - const writer = new StoreWriter({ - policies: new Policies({ + const writer = new StoreWriter( + new InMemoryCache({ dataIdFromObject: getIdField, }), - }); + ); const newStore = writer.writeQueryToStore({ query, @@ -1669,11 +1668,11 @@ describe('writing to the store', () => { id: 1, }; - const writer = new StoreWriter({ - policies: new Policies({ + const writer = new StoreWriter( + new InMemoryCache({ dataIdFromObject: getIdField, }), - }); + ); const newStore = writer.writeQueryToStore({ query: defered, @@ -1739,8 +1738,8 @@ describe('writing to the store', () => { it('can use keyArgs function instead of @connection directive', () => { const store = defaultNormalizedCacheFactory(); - const writer = new StoreWriter({ - policies: new Policies({ + const writer = new StoreWriter( + new InMemoryCache({ typePolicies: { Query: { fields: { @@ -1751,7 +1750,7 @@ describe('writing to the store', () => { }, }, }), - }); + ); writer.writeQueryToStore({ query: gql` diff --git a/src/cache/inmemory/entityStore.ts b/src/cache/inmemory/entityStore.ts index e31a69cd980..4b91c1ea0de 100644 --- a/src/cache/inmemory/entityStore.ts +++ b/src/cache/inmemory/entityStore.ts @@ -436,7 +436,7 @@ export namespace EntityStore { return new Layer(layerId, this, replay, this.sharedLayerGroup); } - public removeLayer(layerId: string): Root { + public removeLayer(): Root { // Never remove the root layer. return this; } @@ -525,13 +525,3 @@ export function supportsResultCaching(store: any): store is EntityStore { // When result caching is disabled, store.depend will be null. return !!(store instanceof EntityStore && store.group.caching); } - -export function defaultNormalizedCacheFactory( - seed?: NormalizedCacheObject, -): NormalizedCache { - return new EntityStore.Root({ - policies: new Policies, - resultCaching: true, - seed, - }); -} diff --git a/src/cache/inmemory/inMemoryCache.ts b/src/cache/inmemory/inMemoryCache.ts index 8340478e206..c7976c9db9d 100644 --- a/src/cache/inmemory/inMemoryCache.ts +++ b/src/cache/inmemory/inMemoryCache.ts @@ -59,6 +59,7 @@ export class InMemoryCache extends ApolloCache { this.addTypename = !!this.config.addTypename; this.policies = new Policies({ + cache: this, dataIdFromObject: this.config.dataIdFromObject, possibleTypes: this.config.possibleTypes, typePolicies: this.config.typePolicies, @@ -79,13 +80,13 @@ export class InMemoryCache extends ApolloCache { // original this.data cache object. this.optimisticData = this.data; - this.storeWriter = new StoreWriter({ - policies: this.policies, - reader: this.storeReader = new StoreReader({ + this.storeWriter = new StoreWriter( + this, + this.storeReader = new StoreReader({ + cache: this, addTypename: this.addTypename, - policies: this.policies, }), - }); + ); const cache = this; const { maybeBroadcastWatch } = cache; @@ -160,7 +161,10 @@ export class InMemoryCache extends ApolloCache { : this.data; try { ++this.txCount; - return store.modify(options.id || "ROOT_QUERY", options.modifiers); + return store.modify( + options.id || "ROOT_QUERY", + options.modifiers, + ); } finally { if (!--this.txCount && options.broadcast !== false) { this.broadcastWatches(); diff --git a/src/cache/inmemory/policies.ts b/src/cache/inmemory/policies.ts index d6ca07a4096..39a6d1b3032 100644 --- a/src/cache/inmemory/policies.ts +++ b/src/cache/inmemory/policies.ts @@ -37,6 +37,7 @@ import { storeValueIsStoreObject, } from './helpers'; import { FieldValueGetter, ToReferenceFunction } from './entityStore'; +import { InMemoryCache } from './inMemoryCache'; import { SafeReadonly } from '../core/types/common'; const hasOwn = Object.prototype.hasOwnProperty; @@ -134,6 +135,13 @@ export interface FieldFunctionOptions< isReference: typeof isReference; toReference: ToReferenceFunction; + // A handy place to put field-specific data that you want to survive + // across multiple read function calls. Useful for field-level caching, + // if your read function does any expensive work. + storage: StorageType | null; + + cache: InMemoryCache; + // Helper function for reading other fields within the current object. // If a foreign object or reference is provided, the field will be read // from that object instead of the current object, so this function can @@ -145,11 +153,6 @@ export interface FieldFunctionOptions< // immutable data (enforced with Object.freeze in development). readField: ReadFieldFunction; - // A handy place to put field-specific data that you want to survive - // across multiple read function calls. Useful for field-level caching, - // if your read function does any expensive work. - storage: StorageType | null; - // Instead of just merging objects with { ...existing, ...incoming }, this // helper function can be used to merge objects in a way that respects any // custom merge functions defined for their fields. @@ -223,21 +226,26 @@ export class Policies { }; } = Object.create(null); + public readonly cache: InMemoryCache; + public readonly rootIdsByTypename: Record = Object.create(null); public readonly rootTypenamesById: Record = Object.create(null); public readonly usingPossibleTypes = false; constructor(private config: { + cache: InMemoryCache; dataIdFromObject?: KeyFieldsFunction; possibleTypes?: PossibleTypesMap; typePolicies?: TypePolicies; - } = {}) { + }) { this.config = { dataIdFromObject: defaultDataIdFromObject, ...config, }; + this.cache = this.config.cache; + this.setRootTypename("Query"); this.setRootTypename("Mutation"); this.setRootTypename("Subscription"); @@ -666,6 +674,7 @@ function makeFieldFunctionOptions( isReference, toReference, storage, + cache: policies.cache, readField( fieldNameOrOptions: string | ReadFieldOptions, diff --git a/src/cache/inmemory/readFromStore.ts b/src/cache/inmemory/readFromStore.ts index 454b3a5fbdb..5951ee9a580 100644 --- a/src/cache/inmemory/readFromStore.ts +++ b/src/cache/inmemory/readFromStore.ts @@ -37,6 +37,7 @@ import { import { supportsResultCaching } from './entityStore'; import { getTypenameFromStoreObject } from './helpers'; import { Policies, ReadMergeContext } from './policies'; +import { InMemoryCache } from './inMemoryCache'; import { MissingFieldError } from '../core/types/common'; export type VariableMap = { [name: string]: any }; @@ -81,8 +82,8 @@ type ExecSubSelectedArrayOptions = { }; export interface StoreReaderConfig { + cache: InMemoryCache, addTypename?: boolean; - policies: Policies; } export class StoreReader { @@ -124,7 +125,7 @@ export class StoreReader { variables, returnPartialData = true, }: DiffQueryAgainstStoreOptions): Cache.DiffResult { - const { policies } = this.config; + const policies = this.config.cache.policies; variables = { ...getDefaultValues(getQueryDefinition(query)), diff --git a/src/cache/inmemory/types.ts b/src/cache/inmemory/types.ts index 9618f43f090..35f9252cc8d 100644 --- a/src/cache/inmemory/types.ts +++ b/src/cache/inmemory/types.ts @@ -10,7 +10,7 @@ import { import { FieldValueGetter, ToReferenceFunction } from './entityStore'; import { KeyFieldsFunction } from './policies'; import { SafeReadonly } from '../core/types/common'; -export { StoreObject, StoreValue } +export { StoreObject, StoreValue, Reference } export interface IdGetterObj extends Object { __typename?: string; diff --git a/src/cache/inmemory/writeToStore.ts b/src/cache/inmemory/writeToStore.ts index a8cacfdc882..f8e0b2199eb 100644 --- a/src/cache/inmemory/writeToStore.ts +++ b/src/cache/inmemory/writeToStore.ts @@ -27,11 +27,12 @@ import { import { shouldInclude, hasDirectives } from '../../utilities/graphql/directives'; import { cloneDeep } from '../../utilities/common/cloneDeep'; -import { Policies, ReadMergeContext } from './policies'; +import { ReadMergeContext } from './policies'; import { EntityStore } from './entityStore'; import { NormalizedCache } from './types'; import { makeProcessedFieldsMerger, FieldValueToBeMerged } from './helpers'; import { StoreReader } from './readFromStore'; +import { InMemoryCache } from './inMemoryCache'; export interface WriteContext extends ReadMergeContext { readonly store: NormalizedCache; @@ -68,13 +69,11 @@ extends Omit { store?: NormalizedCache; } -export interface StoreWriterConfig { - reader?: StoreReader; - policies: Policies; -}; - export class StoreWriter { - constructor(private config: StoreWriterConfig) {} + constructor( + public readonly cache: InMemoryCache, + private reader?: StoreReader, + ) {} /** * Writes the result of a query to the store. @@ -94,7 +93,7 @@ export class StoreWriter { const { dataId = "ROOT_QUERY", store = new EntityStore.Root({ - policies: this.config.policies, + policies: this.cache.policies, }), } = options; this.writeToStore({ ...options, dataId, store }); @@ -157,12 +156,12 @@ export class StoreWriter { shouldApplyMerges: false, }, }: ProcessSelectionSetOptions): StoreObject | Reference { - const { policies, reader } = this.config; + const { policies } = this.cache; // Identify the result object, even if dataId was already provided, // since we always need keyObject below. - const [id, keyObject] = - policies.identify(result, selectionSet, context.fragmentMap); + const [id, keyObject] = policies.identify( + result, selectionSet, context.fragmentMap); // If dataId was not provided, fall back to the id just generated by // policies.identify. @@ -184,7 +183,7 @@ export class StoreWriter { // returned if we were to reread the result with the same inputs, // then we can skip the rest of the processSelectionSet work for // this object, and immediately return a Reference to it. - if (reader && reader.isFresh( + if (this.reader && this.reader.isFresh( result, context.store, ref, @@ -209,7 +208,7 @@ export class StoreWriter { // always passed in for tricky-to-infer cases such as "Query" for // ROOT_QUERY. const typename = - (dataId && this.config.policies.rootTypenamesById[dataId]) || + (dataId && policies.rootTypenamesById[dataId]) || getTypenameFromResult(result, selectionSet, context.fragmentMap) || (dataId && context.store.get(dataId, "__typename") as string); From 07f2af9ac516eb1bedce067a9b2a1e61b6157f70 Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Wed, 27 May 2020 21:32:43 -0400 Subject: [PATCH 11/56] Move StoreWriter#writeToStore into test helpers module. --- .../inmemory/__tests__/diffAgainstStore.ts | 78 +++--- src/cache/inmemory/__tests__/helpers.ts | 20 ++ src/cache/inmemory/__tests__/roundtrip.ts | 7 +- src/cache/inmemory/__tests__/writeToStore.ts | 234 ++++++++++-------- src/cache/inmemory/writeToStore.ts | 23 +- 5 files changed, 207 insertions(+), 155 deletions(-) diff --git a/src/cache/inmemory/__tests__/diffAgainstStore.ts b/src/cache/inmemory/__tests__/diffAgainstStore.ts index 6b69157583e..cf52a593d70 100644 --- a/src/cache/inmemory/__tests__/diffAgainstStore.ts +++ b/src/cache/inmemory/__tests__/diffAgainstStore.ts @@ -1,6 +1,6 @@ import gql, { disableFragmentWarnings } from 'graphql-tag'; -import { defaultNormalizedCacheFactory } from './helpers'; +import { defaultNormalizedCacheFactory, writeQueryToStore } from './helpers'; import { StoreReader } from '../readFromStore'; import { StoreWriter } from '../writeToStore'; import { defaultDataIdFromObject } from '../policies'; @@ -119,7 +119,8 @@ describe('diffing queries against the store', () => { }, }; - const store = writer.writeQueryToStore({ + const store = writeQueryToStore({ + writer, result, query, }); @@ -143,7 +144,8 @@ describe('diffing queries against the store', () => { }), ); - const store = writer.writeQueryToStore({ + const store = writeQueryToStore({ + writer, query: gql` { people_one(id: "1") { @@ -198,7 +200,8 @@ describe('diffing queries against the store', () => { powers: 'the force', }, }; - const store = writer.writeQueryToStore({ + const store = writeQueryToStore({ + writer, result: firstResult, query: firstQuery, }); @@ -233,7 +236,8 @@ describe('diffing queries against the store', () => { lastName: 'Smith', }, }; - const store = writer.writeQueryToStore({ + const store = writeQueryToStore({ + writer, result: firstResult, query: firstQuery, }); @@ -278,7 +282,8 @@ describe('diffing queries against the store', () => { lastName: 'Smith', }, }; - const store = writer.writeQueryToStore({ + const store = writeQueryToStore({ + writer, result: firstResult, query: firstQuery, }); @@ -325,7 +330,8 @@ describe('diffing queries against the store', () => { lastName: 'Smith', }, }; - const store = writer.writeQueryToStore({ + const store = writeQueryToStore({ + writer, result: firstResult, query: firstQuery, }); @@ -375,7 +381,8 @@ describe('diffing queries against the store', () => { }, }; - const store = writer.writeQueryToStore({ + const store = writeQueryToStore({ + writer, result: firstResult, query: firstQuery, }); @@ -503,7 +510,8 @@ describe('diffing queries against the store', () => { const writer = new StoreWriter(cache); - const store = writer.writeQueryToStore({ + const store = writeQueryToStore({ + writer, query, result: queryResult, }); @@ -545,7 +553,8 @@ describe('diffing queries against the store', () => { c: { d: 2, e: { f: 3 } }, }; - const store = writer.writeQueryToStore({ + const store = writeQueryToStore({ + writer, query, result: queryResult, }); @@ -585,7 +594,8 @@ describe('diffing queries against the store', () => { c: { d: 2, e: { f: 3 } }, }; - const store = writer.writeQueryToStore({ + const store = writeQueryToStore({ + writer, query, result: queryResult, }); @@ -631,7 +641,8 @@ describe('diffing queries against the store', () => { }, }; - const store = writer.writeQueryToStore({ + const store = writeQueryToStore({ + writer, query, result: queryResult, }); @@ -667,7 +678,8 @@ describe('diffing queries against the store', () => { a: [{ b: 1.1 }, { b: 1.2 }], }; - const store = writer.writeQueryToStore({ + const store = writeQueryToStore({ + writer, query, result: queryResult, }); @@ -710,7 +722,8 @@ describe('diffing queries against the store', () => { }, }; - const store = writer.writeQueryToStore({ + const store = writeQueryToStore({ + writer, query, result: queryResult, }); @@ -756,7 +769,8 @@ describe('diffing queries against the store', () => { }, }; - const store = writer.writeQueryToStore({ + const store = writeQueryToStore({ + writer, query, result: queryResult, }); @@ -835,7 +849,8 @@ describe('diffing queries against the store', () => { }), ); - const store = writer.writeQueryToStore({ + const store = writeQueryToStore({ + writer, query, result: queryResult, }); @@ -900,7 +915,8 @@ describe('diffing queries against the store', () => { d: { e: 5, f: { x: 6, y: 7, z: 8 } }, }; - const store = writer.writeQueryToStore({ + const store = writeQueryToStore({ + writer, query, result: queryResult, }); @@ -981,7 +997,8 @@ describe('diffing queries against the store', () => { const reader = new StoreReader({ cache }); const writer = new StoreWriter(cache, reader); - const store = writer.writeQueryToStore({ + const store = writeQueryToStore({ + writer, query: listQuery, result: listResult, }); @@ -1022,7 +1039,8 @@ describe('diffing queries against the store', () => { } `; - const store = writer.writeQueryToStore({ + const store = writeQueryToStore({ + writer, query: validQuery, result: { messageList: [ @@ -1154,11 +1172,12 @@ describe('diffing queries against the store', () => { // Check first using generated IDs. check( - new StoreWriter( - new InMemoryCache({ - dataIdFromObject: void 0, - }) - ).writeQueryToStore({ + writeQueryToStore({ + writer: new StoreWriter( + new InMemoryCache({ + dataIdFromObject: void 0, + }) + ), query, result: { user: company.users[0], @@ -1168,11 +1187,12 @@ describe('diffing queries against the store', () => { // Now check with __typename-specific IDs. check( - new StoreWriter( - new InMemoryCache({ - dataIdFromObject: defaultDataIdFromObject, - }), - ).writeQueryToStore({ + writeQueryToStore({ + writer: new StoreWriter( + new InMemoryCache({ + dataIdFromObject: defaultDataIdFromObject, + }), + ), query, result: { user: company.users[0], diff --git a/src/cache/inmemory/__tests__/helpers.ts b/src/cache/inmemory/__tests__/helpers.ts index 6052ef2f3c4..98c428b89be 100644 --- a/src/cache/inmemory/__tests__/helpers.ts +++ b/src/cache/inmemory/__tests__/helpers.ts @@ -1,6 +1,7 @@ import { NormalizedCache, NormalizedCacheObject } from "../types"; import { EntityStore } from "../entityStore"; import { InMemoryCache } from "../inMemoryCache"; +import { StoreWriter, WriteToStoreOptions } from "../writeToStore"; export function defaultNormalizedCacheFactory( seed?: NormalizedCacheObject, @@ -13,6 +14,25 @@ export function defaultNormalizedCacheFactory( }); } +interface WriteQueryToStoreOptions +extends Omit { + writer: StoreWriter; + store?: NormalizedCache; +} + +export function writeQueryToStore( + options: WriteQueryToStoreOptions, +): NormalizedCache { + const { + dataId = "ROOT_QUERY", + store = new EntityStore.Root({ + policies: options.writer.cache.policies, + }), + } = options; + options.writer.writeToStore({ ...options, dataId, store }); + return store; +} + describe("defaultNormalizedCacheFactory", function () { it("should return an EntityStore", function () { const store = defaultNormalizedCacheFactory(); diff --git a/src/cache/inmemory/__tests__/roundtrip.ts b/src/cache/inmemory/__tests__/roundtrip.ts index 215b5cc02d9..bce2ff62c45 100644 --- a/src/cache/inmemory/__tests__/roundtrip.ts +++ b/src/cache/inmemory/__tests__/roundtrip.ts @@ -6,6 +6,7 @@ import { EntityStore } from '../entityStore'; import { StoreReader } from '../readFromStore'; import { StoreWriter } from '../writeToStore'; import { InMemoryCache } from '../inMemoryCache'; +import { writeQueryToStore } from './helpers'; function assertDeeplyFrozen(value: any, stack: any[] = []) { if (value !== null && typeof value === 'object' && stack.indexOf(value) < 0) { @@ -29,7 +30,8 @@ function storeRoundtrip(query: DocumentNode, result: any, variables = {}) { const reader = new StoreReader({ cache }); const writer = new StoreWriter(cache); - const store = writer.writeQueryToStore({ + const store = writeQueryToStore({ + writer, result, query, variables, @@ -67,7 +69,8 @@ function storeRoundtrip(query: DocumentNode, result: any, variables = {}) { // Now make sure subtrees of the result are identical even after we write // an additional bogus field to the store. - writer.writeQueryToStore({ + writeQueryToStore({ + writer, store, result: { oyez: 1234 }, query: gql` diff --git a/src/cache/inmemory/__tests__/writeToStore.ts b/src/cache/inmemory/__tests__/writeToStore.ts index 9344fc234fe..2f1fb476212 100644 --- a/src/cache/inmemory/__tests__/writeToStore.ts +++ b/src/cache/inmemory/__tests__/writeToStore.ts @@ -17,7 +17,7 @@ import { addTypenameToDocument } from '../../../utilities/graphql/transform'; import { cloneDeep } from '../../../utilities/common/cloneDeep'; import { itAsync } from '../../../utilities/testing/itAsync'; import { StoreWriter } from '../writeToStore'; -import { defaultNormalizedCacheFactory } from './helpers'; +import { defaultNormalizedCacheFactory, writeQueryToStore } from './helpers'; import { InMemoryCache } from '../inMemoryCache'; const getIdField = ({ id }: { id: string }) => id; @@ -51,12 +51,11 @@ describe('writing to the store', () => { }; expect( - writer - .writeQueryToStore({ - query, - result: cloneDeep(result), - }) - .toObject(), + writeQueryToStore({ + writer, + query, + result: cloneDeep(result), + }).toObject(), ).toEqual({ ROOT_QUERY: { __typename: 'Query', @@ -82,7 +81,8 @@ describe('writing to the store', () => { nullField: null, }; - const normalized = writer.writeQueryToStore({ + const normalized = writeQueryToStore({ + writer, result, query, }); @@ -117,7 +117,8 @@ describe('writing to the store', () => { nullField: null, }; - const normalized = writer.writeQueryToStore({ + const normalized = writeQueryToStore({ + writer, result, query, }); @@ -157,7 +158,8 @@ describe('writing to the store', () => { nullField: null, }; - const normalized = writer.writeQueryToStore({ + const normalized = writeQueryToStore({ + writer, result, query, variables, @@ -200,7 +202,8 @@ describe('writing to the store', () => { nullField: null, }; - const normalized = writer.writeQueryToStore({ + const normalized = writeQueryToStore({ + writer, result, query, variables, @@ -234,7 +237,8 @@ describe('writing to the store', () => { birthDate: '20-05-1940', }; - const normalized = writer.writeQueryToStore({ + const normalized = writeQueryToStore({ + writer, result, query, }); @@ -286,12 +290,11 @@ describe('writing to the store', () => { ); expect( - writer - .writeQueryToStore({ - query, - result: cloneDeep(result), - }) - .toObject(), + writeQueryToStore({ + writer, + query, + result: cloneDeep(result), + }).toObject(), ).toEqual({ ROOT_QUERY: { __typename: 'Query', @@ -330,12 +333,11 @@ describe('writing to the store', () => { }; expect( - writer - .writeQueryToStore({ - query, - result: cloneDeep(result), - }) - .toObject(), + writeQueryToStore({ + writer, + query, + result: cloneDeep(result), + }).toObject(), ).toEqual({ ROOT_QUERY: { __typename: 'Query', @@ -372,12 +374,11 @@ describe('writing to the store', () => { }; expect( - writer - .writeQueryToStore({ - query, - result: cloneDeep(result), - }) - .toObject(), + writeQueryToStore({ + writer, + query, + result: cloneDeep(result), + }).toObject(), ).toEqual({ ROOT_QUERY: assign(omit(result, 'nestedObj'), { __typename: "Query", @@ -430,12 +431,11 @@ describe('writing to the store', () => { ); expect( - writer - .writeQueryToStore({ - query, - result: cloneDeep(result), - }) - .toObject(), + writeQueryToStore({ + writer, + query, + result: cloneDeep(result), + }).toObject(), ).toEqual({ ROOT_QUERY: assign({}, assign({}, omit(result, 'nestedArray')), { __typename: "Query", @@ -487,12 +487,11 @@ describe('writing to the store', () => { ); expect( - writer - .writeQueryToStore({ - query, - result: cloneDeep(result), - }) - .toObject(), + writeQueryToStore({ + writer, + query, + result: cloneDeep(result), + }).toObject(), ).toEqual({ ROOT_QUERY: assign({}, assign({}, omit(result, 'nestedArray')), { __typename: "Query", @@ -536,7 +535,8 @@ describe('writing to the store', () => { ], }; - const normalized = writer.writeQueryToStore({ + const normalized = writeQueryToStore({ + writer, query, result: cloneDeep(result), }); @@ -579,7 +579,8 @@ describe('writing to the store', () => { ], }; - const normalized = writer.writeQueryToStore({ + const normalized = writeQueryToStore({ + writer, query, result: cloneDeep(result), }); @@ -617,7 +618,8 @@ describe('writing to the store', () => { }), ); - const normalized = writer.writeQueryToStore({ + const normalized = writeQueryToStore({ + writer, query, result: cloneDeep(result), }); @@ -649,7 +651,8 @@ describe('writing to the store', () => { simpleArray: [null, 'two', 'three'], }; - const normalized = writer.writeQueryToStore({ + const normalized = writeQueryToStore({ + writer, query, result: cloneDeep(result), }); @@ -695,7 +698,8 @@ describe('writing to the store', () => { }), ); - const normalized = writer.writeQueryToStore({ + const normalized = writeQueryToStore({ + writer, query, result: cloneDeep(result), }); @@ -768,7 +772,8 @@ describe('writing to the store', () => { }), ); - const normalized = writer.writeQueryToStore({ + const normalized = writeQueryToStore({ + writer, query, result: cloneDeep(result), }); @@ -844,7 +849,8 @@ describe('writing to the store', () => { }), ); - const normalized = writer.writeQueryToStore({ + const normalized = writeQueryToStore({ + writer, query, result: cloneDeep(result), }); @@ -894,7 +900,8 @@ describe('writing to the store', () => { }), ); - const store = writer.writeQueryToStore({ + const store = writeQueryToStore({ + writer, query, result: cloneDeep(result), }); @@ -913,7 +920,8 @@ describe('writing to the store', () => { nullField: null, }; - const store2 = writer.writeQueryToStore({ + const store2 = writeQueryToStore({ + writer, store, query: query2, result: result2, @@ -953,12 +961,11 @@ describe('writing to the store', () => { }; expect( - writer - .writeQueryToStore({ - query, - result: cloneDeep(result), - }) - .toObject(), + writeQueryToStore({ + writer, + query, + result: cloneDeep(result), + }).toObject(), ).toEqual({ ROOT_QUERY: { __typename: 'Query', @@ -986,12 +993,11 @@ describe('writing to the store', () => { }; expect( - writer - .writeQueryToStore({ - query, - result: cloneDeep(result), - }) - .toObject(), + writeQueryToStore({ + writer, + query, + result: cloneDeep(result), + }).toObject(), ).toEqual({ ROOT_QUERY: { __typename: "Query", @@ -1159,7 +1165,8 @@ describe('writing to the store', () => { ); expect( - writer.writeQueryToStore({ + writeQueryToStore({ + writer, query: { kind: 'Document', definitions: [def], @@ -1204,12 +1211,11 @@ describe('writing to the store', () => { }, }); expect( - writer - .writeQueryToStore({ - result: data, - query, - }) - .toObject(), + writeQueryToStore({ + writer, + result: data, + query, + }).toObject(), ).toEqual(expStore.toObject()); }); @@ -1242,12 +1248,11 @@ describe('writing to the store', () => { }, }); expect( - writer - .writeQueryToStore({ - result: data, - query, - }) - .toObject(), + writeQueryToStore({ + writer, + result: data, + query, + }).toObject(), ).toEqual(expStore.toObject()); }); @@ -1282,12 +1287,11 @@ describe('writing to the store', () => { }, }); expect( - writer - .writeQueryToStore({ - result: data, - query, - }) - .toObject(), + writeQueryToStore({ + writer, + result: data, + query, + }).toObject(), ).toEqual(expStore.toObject()); }); }); @@ -1349,13 +1353,15 @@ describe('writing to the store', () => { }, }); - const storeWithoutId = writer.writeQueryToStore({ + const storeWithoutId = writeQueryToStore({ + writer, result: dataWithoutId, query: queryWithoutId, }); expect(storeWithoutId.toObject()).toEqual(expectedStoreWithoutId.toObject()); - const storeWithId = writer.writeQueryToStore({ + const storeWithId = writeQueryToStore({ + writer, result: dataWithId, query: queryWithId, store: storeWithoutId, @@ -1417,14 +1423,16 @@ describe('writing to the store', () => { }); // write the first object, without an ID, placeholder - const store = writer.writeQueryToStore({ + const store = writeQueryToStore({ + writer, result: dataWithPlaceholder, query, }); expect(store.toObject()).toEqual(expStoreWithPlaceholder.toObject()); // replace with another one of different type with ID - writer.writeQueryToStore({ + writeQueryToStore({ + writer, result: dataWithAuthor, query, store, @@ -1432,7 +1440,8 @@ describe('writing to the store', () => { expect(store.toObject()).toEqual(expStoreWithAuthor.toObject()); // and go back to the original: - writer.writeQueryToStore({ + writeQueryToStore({ + writer, result: dataWithPlaceholder, query, store, @@ -1457,7 +1466,8 @@ describe('writing to the store', () => { fortuneCookie: 'Star Wars unit tests are boring', }; expect(() => { - writer.writeQueryToStore({ + writeQueryToStore({ + writer, result, query, }); @@ -1480,12 +1490,14 @@ describe('writing to the store', () => { numberField: 5, nullField: null, }; - const store = writer.writeQueryToStore({ + const store = writeQueryToStore({ + writer, query, result: cloneDeep(result), }); - const newStore = writer.writeQueryToStore({ + const newStore = writeQueryToStore({ + writer, query, result: cloneDeep(result), store: defaultNormalizedCacheFactory(store.toObject()), @@ -1523,7 +1535,8 @@ describe('writing to the store', () => { }), ); - const newStore = writer.writeQueryToStore({ + const newStore = writeQueryToStore({ + writer, query, result, }); @@ -1549,7 +1562,8 @@ describe('writing to the store', () => { ); expect(() => { - writer.writeQueryToStore({ + writeQueryToStore({ + writer, query, result, }); @@ -1601,7 +1615,8 @@ describe('writing to the store', () => { ); expect(() => { - writer.writeQueryToStore({ + writeQueryToStore({ + writer, query: queryWithInterface, result, }); @@ -1627,7 +1642,8 @@ describe('writing to the store', () => { ); expect(() => { - writer.writeQueryToStore({ + writeQueryToStore({ + writer, query: addTypenameToDocument(query), result, }); @@ -1645,7 +1661,8 @@ describe('writing to the store', () => { }), ); - const newStore = writer.writeQueryToStore({ + const newStore = writeQueryToStore({ + writer, query, result, }); @@ -1674,7 +1691,8 @@ describe('writing to the store', () => { }), ); - const newStore = writer.writeQueryToStore({ + const newStore = writeQueryToStore({ + writer, query: defered, result, }); @@ -1688,7 +1706,8 @@ describe('writing to the store', () => { it('properly handles the @connection directive', () => { const store = defaultNormalizedCacheFactory(); - writer.writeQueryToStore({ + writeQueryToStore({ + writer, query: gql` { books(skip: 0, limit: 2) @connection(key: "abc") { @@ -1706,7 +1725,8 @@ describe('writing to the store', () => { store, }); - writer.writeQueryToStore({ + writeQueryToStore({ + writer, query: gql` { books(skip: 2, limit: 4) @connection(key: "abc") { @@ -1752,7 +1772,8 @@ describe('writing to the store', () => { }), ); - writer.writeQueryToStore({ + writeQueryToStore({ + writer, query: gql` { books(skip: 0, limit: 2) { @@ -1781,7 +1802,8 @@ describe('writing to the store', () => { }, }); - writer.writeQueryToStore({ + writeQueryToStore({ + writer, query: gql` { books(skip: 2, limit: 4) { @@ -1824,7 +1846,8 @@ describe('writing to the store', () => { } `; - writer.writeQueryToStore({ + writeQueryToStore({ + writer, query, result: { animals: [ @@ -1855,7 +1878,8 @@ describe('writing to the store', () => { }, }); - writer.writeQueryToStore({ + writeQueryToStore({ + writer, query, result: { animals: [ @@ -1901,7 +1925,8 @@ describe('writing to the store', () => { } `; - writer.writeQueryToStore({ + writeQueryToStore({ + writer, query, result: { animals: [ @@ -1932,7 +1957,8 @@ describe('writing to the store', () => { }, }); - writer.writeQueryToStore({ + writeQueryToStore({ + writer, query, result: { animals: [ diff --git a/src/cache/inmemory/writeToStore.ts b/src/cache/inmemory/writeToStore.ts index f8e0b2199eb..774f53bb480 100644 --- a/src/cache/inmemory/writeToStore.ts +++ b/src/cache/inmemory/writeToStore.ts @@ -28,7 +28,6 @@ import { shouldInclude, hasDirectives } from '../../utilities/graphql/directives import { cloneDeep } from '../../utilities/common/cloneDeep'; import { ReadMergeContext } from './policies'; -import { EntityStore } from './entityStore'; import { NormalizedCache } from './types'; import { makeProcessedFieldsMerger, FieldValueToBeMerged } from './helpers'; import { StoreReader } from './readFromStore'; @@ -56,7 +55,7 @@ interface ProcessSelectionSetOptions { }; } -interface WriteToStoreOptions { +export interface WriteToStoreOptions { query: DocumentNode; result: Object; dataId?: string; @@ -64,11 +63,6 @@ interface WriteToStoreOptions { variables?: Object; } -interface WriteQueryToStoreOptions -extends Omit { - store?: NormalizedCache; -} - export class StoreWriter { constructor( public readonly cache: InMemoryCache, @@ -86,20 +80,9 @@ export class StoreWriter { * * @param variables A map from the name of a variable to its value. These variables can be * referenced by the query document. + * + * @return A `Reference` to the written object. */ - public writeQueryToStore( - options: WriteQueryToStoreOptions, - ): NormalizedCache { - const { - dataId = "ROOT_QUERY", - store = new EntityStore.Root({ - policies: this.cache.policies, - }), - } = options; - this.writeToStore({ ...options, dataId, store }); - return store; - } - public writeToStore({ query, result, From bc0c50cca7c7f0eb775829b990514dedd0596b08 Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Thu, 28 May 2020 12:18:31 -0400 Subject: [PATCH 12/56] Update existing mentions of cache.modify in docs. We will definitely need more documentation about cache.modify after reverting PR #6289, but in the meantime the existing documentation should not be blatantly incorrect. --- docs/source/data/local-state.mdx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/source/data/local-state.mdx b/docs/source/data/local-state.mdx index 37c2046231c..3ec0b492a8f 100644 --- a/docs/source/data/local-state.mdx +++ b/docs/source/data/local-state.mdx @@ -176,13 +176,13 @@ const client = new ApolloClient({ resolvers: { Mutation: { toggleTodo: (_root, variables, { cache }) => { - const id = cache.identify({ - __typename: 'TodoItem', - id: variables.id, - }); - cache.modify(id, { - completed(value) { - return !value; + cache.modify({ + id: cache.identify({ + __typename: 'TodoItem', + id: variables.id, + }), + modifiers: { + completed: value => !value, }, }); return null; @@ -1095,7 +1095,7 @@ const client = new ApolloClient({ }; ``` -The `cache.writeQuery` and `cache.writeFragment` methods should cover most of your needs; however, there are some cases where the data you're writing to the cache depends on the data that's already there. In that scenario, you should use `cache.modify(id, modifiers)` to update specific fields within the entity object identified by `id`. +The `cache.writeQuery` and `cache.writeFragment` methods should cover most of your needs; however, there are some cases where the data you're writing to the cache depends on the data that's already there. In that scenario, you can either use a combination of `cache.read{Query,Fragment}` followed by `cache.write{Query,Fragment}`, or use `cache.modify({ id, modifiers })` to update specific fields within the entity object identified by `id`. ### writeQuery and readQuery From cc503beab8e8f7c4a43ff4391b4e9d117ead1ce7 Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Thu, 28 May 2020 12:41:30 -0400 Subject: [PATCH 13/56] Never assume ROOT_QUERY when cache.modify options.id exists. This distinction is a noteworthy benefit of using ModifyOptions rather than positional parameters for cache.modify. --- src/cache/inmemory/__tests__/cache.ts | 39 +++++++++++++++++++++++++++ src/cache/inmemory/entityStore.ts | 4 +-- src/cache/inmemory/helpers.ts | 2 ++ src/cache/inmemory/inMemoryCache.ts | 18 ++++++++++--- src/cache/inmemory/policies.ts | 3 +-- 5 files changed, 57 insertions(+), 9 deletions(-) diff --git a/src/cache/inmemory/__tests__/cache.ts b/src/cache/inmemory/__tests__/cache.ts index d3b5b09bf5e..d45671f6cbc 100644 --- a/src/cache/inmemory/__tests__/cache.ts +++ b/src/cache/inmemory/__tests__/cache.ts @@ -2341,6 +2341,45 @@ describe("InMemoryCache#modify", () => { }, }); }); + + it("should modify ROOT_QUERY only when options.id absent", function () { + const cache = new InMemoryCache(); + + cache.writeQuery({ + query: gql`query { field }`, + data: { + field: "oyez", + }, + }); + + const snapshot = { + ROOT_QUERY: { + __typename: "Query", + field: "oyez", + }, + }; + + expect(cache.extract()).toEqual(snapshot); + + function check(id: any) { + expect(cache.modify({ + id, + modifiers: { + field(value) { + throw new Error(`unexpected value: ${value}`); + }, + }, + })).toBe(false); + } + + check(void 0); + check(false); + check(null); + check(""); + check("bogus:id"); + + expect(cache.extract()).toEqual(snapshot); + }); }); describe("cache.makeVar", () => { diff --git a/src/cache/inmemory/entityStore.ts b/src/cache/inmemory/entityStore.ts index 4b91c1ea0de..5c8f0b06403 100644 --- a/src/cache/inmemory/entityStore.ts +++ b/src/cache/inmemory/entityStore.ts @@ -12,13 +12,11 @@ import { DeepMerger } from '../../utilities/common/mergeDeep'; import { maybeDeepFreeze } from '../../utilities/common/maybeDeepFreeze'; import { canUseWeakMap } from '../../utilities/common/canUse'; import { NormalizedCache, NormalizedCacheObject, Modifiers, Modifier, ReadFieldFunction, ReadFieldOptions } from './types'; -import { fieldNameFromStoreName } from './helpers'; +import { hasOwn, fieldNameFromStoreName } from './helpers'; import { Policies } from './policies'; import { SafeReadonly } from '../core/types/common'; import { Cache } from '../core/types/Cache'; -const hasOwn = Object.prototype.hasOwnProperty; - const DELETE: any = Object.create(null); const delModifier: Modifier = () => DELETE; diff --git a/src/cache/inmemory/helpers.ts b/src/cache/inmemory/helpers.ts index b01e18d8ff4..d41568f26db 100644 --- a/src/cache/inmemory/helpers.ts +++ b/src/cache/inmemory/helpers.ts @@ -10,6 +10,8 @@ import { } from '../../utilities/graphql/storeUtils'; import { DeepMerger, ReconcilerFunction } from '../../utilities/common/mergeDeep'; +export const hasOwn = Object.prototype.hasOwnProperty; + export function getTypenameFromStoreObject( store: NormalizedCache, objectOrReference: StoreObject | Reference, diff --git a/src/cache/inmemory/inMemoryCache.ts b/src/cache/inmemory/inMemoryCache.ts index c7976c9db9d..7061a84b81e 100644 --- a/src/cache/inmemory/inMemoryCache.ts +++ b/src/cache/inmemory/inMemoryCache.ts @@ -22,6 +22,7 @@ import { Policies, TypePolicies, } from './policies'; +import { hasOwn } from './helpers'; export interface InMemoryCacheConfig extends ApolloReducerConfig { resultCaching?: boolean; @@ -156,15 +157,24 @@ export class InMemoryCache extends ApolloCache { } public modify(options: ModifyOptions): boolean { + if (hasOwn.call(options, "id") && !options.id) { + // To my knowledge, TypeScript does not currently provide a way to + // enforce that an optional property must *not* be undefined when + // present. That ability would be useful here, because we want + // options.id to default to ROOT_QUERY only when no options.id was + // provided. If the caller attempts to pass options.id with a + // falsy/undefined value (perhaps because cache.identify failed to + // identity the object), we definitely should not assume they want + // to modify the ROOT_QUERY object. We could throw, but it seems + // natural to return false to indicate that nothing was modified. + return false; + } const store = options.optimistic // Defaults to false. ? this.optimisticData : this.data; try { ++this.txCount; - return store.modify( - options.id || "ROOT_QUERY", - options.modifiers, - ); + return store.modify(options.id || "ROOT_QUERY", options.modifiers); } finally { if (!--this.txCount && options.broadcast !== false) { this.broadcastWatches(); diff --git a/src/cache/inmemory/policies.ts b/src/cache/inmemory/policies.ts index 39a6d1b3032..9eadbed30de 100644 --- a/src/cache/inmemory/policies.ts +++ b/src/cache/inmemory/policies.ts @@ -31,6 +31,7 @@ import { ReadFieldFunction, } from "./types"; import { + hasOwn, fieldNameFromStoreName, FieldValueToBeMerged, isFieldValueToBeMerged, @@ -40,8 +41,6 @@ import { FieldValueGetter, ToReferenceFunction } from './entityStore'; import { InMemoryCache } from './inMemoryCache'; import { SafeReadonly } from '../core/types/common'; -const hasOwn = Object.prototype.hasOwnProperty; - export type TypePolicies = { [__typename: string]: TypePolicy; } From 4e1eabee0088ef2224fade818a5bbd8d62c5a81f Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Thu, 28 May 2020 14:15:57 -0400 Subject: [PATCH 14/56] Update cache.modify example in CHANGELOG.md. --- CHANGELOG.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e9f8ecbee4e..129cef8236a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -89,10 +89,13 @@ - `InMemoryCache` now has a method called `modify` which can be used to update the value of a specific field within a specific entity object: ```ts cache.modify({ - comments(comments: Reference[], { readField }) { - return comments.filter(comment => idToRemove !== readField("id", comment)); + id: cache.identify(post), + modifiers: { + comments(comments: Reference[], { readField }) { + return comments.filter(comment => idToRemove !== readField("id", comment)); + }, }, - }, cache.identify(post)); + }); ``` This API gracefully handles cases where multiple field values are associated with a single field name, and also removes the need for updating the cache by reading a query or fragment, modifying the result, and writing the modified result back into the cache. Behind the scenes, the `cache.evict` method is now implemented in terms of `cache.modify`.
[@benjamn](https://github.com/benjamn) in [#5909](https://github.com/apollographql/apollo-client/pull/5909) From 806b077a65179b8d06b70295ba50bd4cf69a562e Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Thu, 28 May 2020 14:22:10 -0400 Subject: [PATCH 15/56] Rename ModifyOptions.modifiers to .fields. To my subjective taste, using a key called `fields` rather than `modifiers` makes it much easier to tell that "something" and "anything" are the names of fields: cache.modify({ id: cache.identify(...), fields: { something(value) { ... }, anything(value) { ... }, }, }) Since ModifyOptions is a new type introduced by PR #6350, we still have total freedom to improve the names of its fields. --- CHANGELOG.md | 2 +- src/__tests__/client.ts | 2 +- src/__tests__/local-state/resolvers.ts | 4 +-- src/cache/inmemory/__tests__/cache.ts | 36 ++++++++++----------- src/cache/inmemory/__tests__/entityStore.ts | 2 +- src/cache/inmemory/inMemoryCache.ts | 2 +- src/cache/inmemory/types.ts | 2 +- 7 files changed, 25 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 129cef8236a..ae299f2fbd6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -90,7 +90,7 @@ ```ts cache.modify({ id: cache.identify(post), - modifiers: { + fields: { comments(comments: Reference[], { readField }) { return comments.filter(comment => idToRemove !== readField("id", comment)); }, diff --git a/src/__tests__/client.ts b/src/__tests__/client.ts index 97f26ac558a..8be5e5b6796 100644 --- a/src/__tests__/client.ts +++ b/src/__tests__/client.ts @@ -2943,7 +2943,7 @@ describe('@connection', () => { checkLastResult(cResults, { c: "see" }); cache.modify({ - modifiers: { + fields: { c(value) { expect(value).toBe("see"); return "saw"; diff --git a/src/__tests__/local-state/resolvers.ts b/src/__tests__/local-state/resolvers.ts index 1b8128db541..77f06c7b856 100644 --- a/src/__tests__/local-state/resolvers.ts +++ b/src/__tests__/local-state/resolvers.ts @@ -555,7 +555,7 @@ describe('Writing cache data from resolvers', () => { cache.modify({ id: 'Object:uniqueId', - modifiers: { + fields: { field(value) { expect(value).toBe(1); return 2; @@ -615,7 +615,7 @@ describe('Writing cache data from resolvers', () => { }); cache.modify({ id: 'Object:uniqueId', - modifiers: { + fields: { field(value: { field2: number }) { expect(value.field2).toBe(1); return { ...value, field2: 2 }; diff --git a/src/cache/inmemory/__tests__/cache.ts b/src/cache/inmemory/__tests__/cache.ts index d45671f6cbc..1de403b5ae4 100644 --- a/src/cache/inmemory/__tests__/cache.ts +++ b/src/cache/inmemory/__tests__/cache.ts @@ -1561,7 +1561,9 @@ describe("InMemoryCache#modify", () => { expect(resultBeforeModify).toEqual({ a: 0, b: 0, c: 0 }); cache.modify({ - modifiers(value, { fieldName }) { + // Passing a function for options.fields is equivalent to invoking + // that function for all fields within the object. + fields(value, { fieldName }) { switch (fieldName) { case "a": return value + 1; case "b": return value - 1; @@ -1607,7 +1609,7 @@ describe("InMemoryCache#modify", () => { let checkedTypename = false; cache.modify({ - modifiers: { + fields: { a(value) { return value + 1 }, b(value) { return value - 1 }, __typename(t: string, { readField }) { @@ -1703,7 +1705,7 @@ describe("InMemoryCache#modify", () => { cache.modify({ id: authorId, - modifiers: { + fields: { yearOfBirth(yob) { return yob + 1; }, @@ -1726,12 +1728,12 @@ describe("InMemoryCache#modify", () => { // necessary, but we want fancy use cases to work, too. cache.modify({ id: bookId, - modifiers: { + fields: { author(author: Reference, { readField }) { expect(readField("title")).toBe("Why We're Polarized"); expect(readField("name", author)).toBe("Ezra Klein"); cache.modify({ - modifiers: { + fields: { yearOfBirth(yob, { DELETE }) { expect(yob).toBe(1984); return DELETE; @@ -1775,7 +1777,7 @@ describe("InMemoryCache#modify", () => { // Delete the whole Book. cache.modify({ id: bookId, - modifiers: (_, { DELETE }) => DELETE, + fields: (_, { DELETE }) => DELETE, }); const snapshotWithoutBook = cache.extract(); @@ -1797,7 +1799,7 @@ describe("InMemoryCache#modify", () => { // Delete all fields of the Author, which also removes the object. cache.modify({ id: authorId, - modifiers: { + fields: { __typename(_, { DELETE }) { return DELETE }, name(_, { DELETE }) { return DELETE }, }, @@ -1816,7 +1818,7 @@ describe("InMemoryCache#modify", () => { }); cache.modify({ - modifiers: (_, { DELETE }) => DELETE, + fields: (_, { DELETE }) => DELETE, }); expect(cache.extract()).toEqual({}); @@ -1931,7 +1933,7 @@ describe("InMemoryCache#modify", () => { }); cache.modify({ - modifiers: { + fields: { comments(comments: Reference[], { readField }) { debugger; expect(Object.isFrozen(comments)).toBe(true); @@ -1996,7 +1998,7 @@ describe("InMemoryCache#modify", () => { }, "transaction"); cache.modify({ - modifiers: { + fields: { b(value, { DELETE }) { expect(value).toBe(2); return DELETE; @@ -2014,7 +2016,7 @@ describe("InMemoryCache#modify", () => { }); cache.modify({ - modifiers(value, { fieldName }) { + fields(value, { fieldName }) { expect(fieldName).not.toBe("b"); if (fieldName === "a") expect(value).toBe(1); if (fieldName === "c") expect(value).toBe(3); @@ -2119,7 +2121,7 @@ describe("InMemoryCache#modify", () => { cache.modify({ id: aId, - modifiers: { + fields: { value(x: number) { return x + 1; }, @@ -2133,7 +2135,7 @@ describe("InMemoryCache#modify", () => { cache.modify({ id: bId, - modifiers: { + fields: { value(x: number) { return x + 1; }, @@ -2225,7 +2227,7 @@ describe("InMemoryCache#modify", () => { let bookCount = 0; cache.modify({ - modifiers: { + fields: { book(book: Reference, { fieldName, storeFieldName, @@ -2364,10 +2366,8 @@ describe("InMemoryCache#modify", () => { function check(id: any) { expect(cache.modify({ id, - modifiers: { - field(value) { - throw new Error(`unexpected value: ${value}`); - }, + fields(value) { + throw new Error(`unexpected value: ${value}`); }, })).toBe(false); } diff --git a/src/cache/inmemory/__tests__/entityStore.ts b/src/cache/inmemory/__tests__/entityStore.ts index d8634576a99..99fad8e91de 100644 --- a/src/cache/inmemory/__tests__/entityStore.ts +++ b/src/cache/inmemory/__tests__/entityStore.ts @@ -1921,7 +1921,7 @@ describe('EntityStore', () => { cache.modify({ id: cuckoosCallingId, - modifiers: { + fields: { title(title: string, { isReference, toReference, diff --git a/src/cache/inmemory/inMemoryCache.ts b/src/cache/inmemory/inMemoryCache.ts index 7061a84b81e..625af42506c 100644 --- a/src/cache/inmemory/inMemoryCache.ts +++ b/src/cache/inmemory/inMemoryCache.ts @@ -174,7 +174,7 @@ export class InMemoryCache extends ApolloCache { : this.data; try { ++this.txCount; - return store.modify(options.id || "ROOT_QUERY", options.modifiers); + return store.modify(options.id || "ROOT_QUERY", options.fields); } finally { if (!--this.txCount && options.broadcast !== false) { this.broadcastWatches(); diff --git a/src/cache/inmemory/types.ts b/src/cache/inmemory/types.ts index 35f9252cc8d..4163ae1bf4a 100644 --- a/src/cache/inmemory/types.ts +++ b/src/cache/inmemory/types.ts @@ -129,7 +129,7 @@ export interface ReadFieldFunction { export interface ModifyOptions { id?: string; - modifiers: Modifiers | Modifier; + fields: Modifiers | Modifier; optimistic?: boolean; broadcast?: boolean; } From b5e04beadae73486731757cd3ea8c921176f428b Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Thu, 28 May 2020 14:33:08 -0400 Subject: [PATCH 16/56] Tweak comment about cache.modify and options.id. --- src/cache/inmemory/inMemoryCache.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/cache/inmemory/inMemoryCache.ts b/src/cache/inmemory/inMemoryCache.ts index 625af42506c..e1c2693b194 100644 --- a/src/cache/inmemory/inMemoryCache.ts +++ b/src/cache/inmemory/inMemoryCache.ts @@ -159,14 +159,14 @@ export class InMemoryCache extends ApolloCache { public modify(options: ModifyOptions): boolean { if (hasOwn.call(options, "id") && !options.id) { // To my knowledge, TypeScript does not currently provide a way to - // enforce that an optional property must *not* be undefined when - // present. That ability would be useful here, because we want + // enforce that an optional property?:type must *not* be undefined + // when present. That ability would be useful here, because we want // options.id to default to ROOT_QUERY only when no options.id was // provided. If the caller attempts to pass options.id with a - // falsy/undefined value (perhaps because cache.identify failed to - // identity the object), we definitely should not assume they want - // to modify the ROOT_QUERY object. We could throw, but it seems - // natural to return false to indicate that nothing was modified. + // falsy/undefined value (perhaps because cache.identify failed), we + // should not assume the goal was to modify the ROOT_QUERY object. + // We could throw, but it seems natural to return false to indicate + // that nothing was modified. return false; } const store = options.optimistic // Defaults to false. From 1b9af3771a6c5b15c0052c71cc6a26e1e13a6c45 Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Thu, 28 May 2020 17:17:08 -0400 Subject: [PATCH 17/56] Bump @apollo/client npm version to 3.0.0-beta.51. --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8536c62b612..07439dac7d2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@apollo/client", - "version": "3.0.0-beta.50", + "version": "3.0.0-beta.51", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 333aca2e153..01e1958a1bd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@apollo/client", - "version": "3.0.0-beta.50", + "version": "3.0.0-beta.51", "description": "A fully-featured caching GraphQL client.", "private": true, "keywords": [ From a60534110e326f2a9de62ba0c5729d243e49b407 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 28 May 2020 17:32:20 -0400 Subject: [PATCH 18/56] chore(deps): update dependency typescript to v3.9.3 (#6339) Co-authored-by: Renovate Bot --- docs/package-lock.json | 14 +++++++++++--- docs/package.json | 2 +- package-lock.json | 6 +++--- package.json | 2 +- 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/docs/package-lock.json b/docs/package-lock.json index 04ea2bf0b46..dc173bea42e 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -21771,6 +21771,14 @@ "shelljs": "^0.8.3", "typedoc-default-themes": "^0.6.3", "typescript": "3.7.x" + }, + "dependencies": { + "typescript": { + "version": "3.7.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.5.tgz", + "integrity": "sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw==", + "dev": true + } } }, "typedoc-default-themes": { @@ -21786,9 +21794,9 @@ } }, "typescript": { - "version": "3.7.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.4.tgz", - "integrity": "sha512-A25xv5XCtarLwXpcDNZzCGvW2D1S3/bACratYBx2sax8PefsFhlYmkQicKHvpYflFS8if4zne5zT5kpJ7pzuvw==", + "version": "3.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.3.tgz", + "integrity": "sha512-D/wqnB2xzNFIcoBG9FG8cXRDjiqSTbG2wd8DMZeQyJlP1vfTkIxH4GKveWaEBYySKIg+USu+E+EDIR47SqnaMQ==", "dev": true }, "ua-parser-js": { diff --git a/docs/package.json b/docs/package.json index 0acb2003812..1b2efadeeb0 100644 --- a/docs/package.json +++ b/docs/package.json @@ -14,6 +14,6 @@ }, "devDependencies": { "typedoc": "0.15.6", - "typescript": "3.7.4" + "typescript": "3.9.3" } } diff --git a/package-lock.json b/package-lock.json index 07439dac7d2..74fb14b6ca1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6822,9 +6822,9 @@ } }, "typescript": { - "version": "3.9.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.2.tgz", - "integrity": "sha512-q2ktq4n/uLuNNShyayit+DTobV2ApPEo/6so68JaD5ojvc/6GClBipedB9zNWYxRSAlZXAe405Rlijzl6qDiSw==", + "version": "3.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.3.tgz", + "integrity": "sha512-D/wqnB2xzNFIcoBG9FG8cXRDjiqSTbG2wd8DMZeQyJlP1vfTkIxH4GKveWaEBYySKIg+USu+E+EDIR47SqnaMQ==", "dev": true }, "union-value": { diff --git a/package.json b/package.json index 01e1958a1bd..bebedc22094 100644 --- a/package.json +++ b/package.json @@ -102,7 +102,7 @@ "rxjs": "6.5.3", "ts-jest": "26.0.0", "tsc-watch": "3.0.1", - "typescript": "3.9.2" + "typescript": "3.9.3" }, "publishConfig": { "access": "public" From d564262dbbeeb06f7d9ca881fb7b05500b80308f Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Thu, 28 May 2020 17:34:45 -0400 Subject: [PATCH 19/56] Update jest to latest version, 26.0.1. Closes #6264. --- package-lock.json | 8583 ++++++++++++++++++++++++++------------------- package.json | 2 +- 2 files changed, 5055 insertions(+), 3530 deletions(-) diff --git a/package-lock.json b/package-lock.json index 74fb14b6ca1..e5cf8db5f7e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,28 +14,60 @@ } }, "@babel/core": { - "version": "7.8.7", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.8.7.tgz", - "integrity": "sha512-rBlqF3Yko9cynC5CCFy6+K/w2N+Sq/ff2BPy+Krp7rHlABIr5epbA7OxVeKoMHB39LZOp1UY5SuLjy6uWi35yA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.8.7", - "@babel/helpers": "^7.8.4", - "@babel/parser": "^7.8.7", - "@babel/template": "^7.8.6", - "@babel/traverse": "^7.8.6", - "@babel/types": "^7.8.7", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.10.1.tgz", + "integrity": "sha512-u8XiZ6sMXW/gPmoP5ijonSUln4unazG291X0XAQ5h0s8qnAFr6BRRZGUEK+jtRWdmB0NTJQt7Uga25q8GetIIg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.1", + "@babel/generator": "^7.10.1", + "@babel/helper-module-transforms": "^7.10.1", + "@babel/helpers": "^7.10.1", + "@babel/parser": "^7.10.1", + "@babel/template": "^7.10.1", + "@babel/traverse": "^7.10.1", + "@babel/types": "^7.10.1", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.1", - "json5": "^2.1.0", + "json5": "^2.1.2", "lodash": "^4.17.13", "resolve": "^1.3.2", "semver": "^5.4.1", "source-map": "^0.5.0" }, "dependencies": { + "@babel/code-frame": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz", + "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.1" + } + }, + "@babel/highlight": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz", + "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.1", + "chalk": "^2.0.0", + "js-tokens": "^4.0.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" + } + }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", @@ -45,6 +77,12 @@ "ms": "^2.1.1" } }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -56,16 +94,25 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "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/generator": { - "version": "7.8.8", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.8.tgz", - "integrity": "sha512-HKyUVu69cZoclptr8t8U5b6sx6zoWjh8jiUhnuj3MpZuKT2dJ8zPTuiy31luq32swhI0SpwItCIlU8XW7BZeJg==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.1.tgz", + "integrity": "sha512-AT0YPLQw9DI21tliuJIdplVfLHya6mcGa8ctkv7n4Qv+hYacJrKmNWIteAK1P9iyLikFIAkwqJ7HAOqIDLFfgA==", "dev": true, "requires": { - "@babel/types": "^7.8.7", + "@babel/types": "^7.10.1", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" @@ -80,49 +127,119 @@ } }, "@babel/helper-function-name": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", - "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.1.tgz", + "integrity": "sha512-fcpumwhs3YyZ/ttd5Rz0xn0TpIwVkN7X0V38B9TWNfVF42KEkhkAAuPCQ3oXmtTRtiPJrmZ0TrfS0GKF0eMaRQ==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.8.3" + "@babel/helper-get-function-arity": "^7.10.1", + "@babel/template": "^7.10.1", + "@babel/types": "^7.10.1" } }, "@babel/helper-get-function-arity": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", - "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.1.tgz", + "integrity": "sha512-F5qdXkYGOQUb0hpRaPoetF9AnsXknKjWMZ+wmsIRsp5ge5sFh4c3h1eH2pRTTuy9KKAA2+TTYomGXAtEL2fQEw==", + "dev": true, + "requires": { + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.1.tgz", + "integrity": "sha512-u7XLXeM2n50gb6PWJ9hoO5oO7JFPaZtrh35t8RqKLT1jFKj9IWeD1zrcrYp1q1qiZTdEarfDWfTIP8nGsu0h5g==", + "dev": true, + "requires": { + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-module-imports": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.1.tgz", + "integrity": "sha512-SFxgwYmZ3HZPyZwJRiVNLRHWuW2OgE5k2nrVs6D9Iv4PPnXVffuEHy83Sfx/l4SqF+5kyJXjAyUmrG7tNm+qVg==", + "dev": true, + "requires": { + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-module-transforms": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.10.1.tgz", + "integrity": "sha512-RLHRCAzyJe7Q7sF4oy2cB+kRnU4wDZY/H2xJFGof+M+SJEGhZsb+GFj5j1AD8NiSaVBJ+Pf0/WObiXu/zxWpFg==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.10.1", + "@babel/helper-replace-supers": "^7.10.1", + "@babel/helper-simple-access": "^7.10.1", + "@babel/helper-split-export-declaration": "^7.10.1", + "@babel/template": "^7.10.1", + "@babel/types": "^7.10.1", + "lodash": "^4.17.13" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.1.tgz", + "integrity": "sha512-a0DjNS1prnBsoKx83dP2falChcs7p3i8VMzdrSbfLhuQra/2ENC4sbri34dz/rWmDADsmF1q5GbfaXydh0Jbjg==", "dev": true, "requires": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.10.1" } }, "@babel/helper-plugin-utils": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", - "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.1.tgz", + "integrity": "sha512-fvoGeXt0bJc7VMWZGCAEBEMo/HAjW2mP8apF5eXK0wSqwLAVHAISCWRoLMBMUs2kqeaG77jltVqu4Hn8Egl3nA==", "dev": true }, + "@babel/helper-replace-supers": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.1.tgz", + "integrity": "sha512-SOwJzEfpuQwInzzQJGjGaiG578UYmyi2Xw668klPWV5n07B73S0a9btjLk/52Mlcxa+5AdIYqws1KyXRfMoB7A==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.10.1", + "@babel/helper-optimise-call-expression": "^7.10.1", + "@babel/traverse": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-simple-access": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.1.tgz", + "integrity": "sha512-VSWpWzRzn9VtgMJBIWTZ+GP107kZdQ4YplJlCmIrjoLVSi/0upixezHCDG8kpPVTBJpKfxTH01wDhh+jS2zKbw==", + "dev": true, + "requires": { + "@babel/template": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, "@babel/helper-split-export-declaration": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", - "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.1.tgz", + "integrity": "sha512-UQ1LVBPrYdbchNhLwj6fetj46BcFwfS4NllJo/1aJsT+1dLTEnXJL0qHqtY7gPzF8S2fXBJamf1biAXV3X077g==", "dev": true, "requires": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.10.1" } }, + "@babel/helper-validator-identifier": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.1.tgz", + "integrity": "sha512-5vW/JXLALhczRCWP0PnFDMCJAchlBvM7f4uk/jXritBnIa6E1KmqmtrS3yn1LAnxFBypQ3eneLuXjsnfQsgILw==", + "dev": true + }, "@babel/helpers": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.8.4.tgz", - "integrity": "sha512-VPbe7wcQ4chu4TDQjimHv/5tj73qz88o12EPkO2ValS2QiQS/1F2SsjyIGNnAD0vF/nZS6Cf9i+vW6HIlnaR8w==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.1.tgz", + "integrity": "sha512-muQNHF+IdU6wGgkaJyhhEmI54MOZBKsFfsXFhboz1ybwJ1Kl7IHlbm2a++4jwrmY5UYsgitt5lfqo1wMFcHmyw==", "dev": true, "requires": { - "@babel/template": "^7.8.3", - "@babel/traverse": "^7.8.4", - "@babel/types": "^7.8.3" + "@babel/template": "^7.10.1", + "@babel/traverse": "^7.10.1", + "@babel/types": "^7.10.1" } }, "@babel/highlight": { @@ -165,11 +282,74 @@ } }, "@babel/parser": { - "version": "7.8.8", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.8.tgz", - "integrity": "sha512-mO5GWzBPsPf6865iIbzNE0AvkKF3NE+2S3eRUpE+FE07BOAkXh6G+GW/Pj01hhXjve1WScbaIO4UlY1JKeqCcA==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.1.tgz", + "integrity": "sha512-AUTksaz3FqugBkbTZ1i+lDLG5qy8hIzCaAxEtttU6C0BtZZU9pkNZtWSVAht4EW9kl46YBiyTGMp9xTTGqViNg==", "dev": true }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.1.tgz", + "integrity": "sha512-Gf2Yx/iRs1JREDtVZ56OrjjgFHCaldpTnuy9BHla10qyVT3YkIIGEtoDWhyop0ksu1GvNjHIoYRBqm3zoR1jyQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.1.tgz", + "integrity": "sha512-XyHIFa9kdrgJS91CUH+ccPVTnJShr8nLGc5bG2IhGXv5p1Rd+8BleGE5yzIg2Nc1QZAdHDa0Qp4m6066OL96Iw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.1.tgz", + "integrity": "sha512-uTd0OsHrpe3tH5gRPTxG8Voh99/WCU78vIm5NMRYPAqC8lR4vajt6KkCAknCHrx24vkPdd/05yfdGSB4EIY2mg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, "@babel/plugin-syntax-object-rest-spread": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", @@ -179,6 +359,24 @@ "@babel/helper-plugin-utils": "^7.8.0" } }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, "@babel/runtime": { "version": "7.8.7", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.8.7.tgz", @@ -199,82 +397,36 @@ } }, "@babel/template": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", - "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/parser": "^7.8.6", - "@babel/types": "^7.8.6" - } - }, - "@babel/traverse": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.6.tgz", - "integrity": "sha512-2B8l0db/DPi8iinITKuo7cbPznLCEk0kCxDoB9/N6gGNg/gxOXiR/IcymAFPiBwk5w6TtQ27w4wpElgp9btR9A==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.1.tgz", + "integrity": "sha512-OQDg6SqvFSsc9A0ej6SKINWrpJiNonRIniYondK2ViKhB06i3c0s+76XUft71iqBEe9S1OKsHwPAjfHnuvnCig==", "dev": true, "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.8.6", - "@babel/helper-function-name": "^7.8.3", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.8.6", - "@babel/types": "^7.8.6", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" + "@babel/code-frame": "^7.10.1", + "@babel/parser": "^7.10.1", + "@babel/types": "^7.10.1" }, "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "@babel/code-frame": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz", + "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==", "dev": true, "requires": { - "ms": "^2.1.1" + "@babel/highlight": "^7.10.1" + } + }, + "@babel/highlight": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz", + "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.1", + "chalk": "^2.0.0", + "js-tokens": "^4.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 - } - } - }, - "@babel/types": { - "version": "7.8.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.7.tgz", - "integrity": "sha512-k2TreEHxFA4CjGkL+GYjRyx35W0Mr7DP5+9q6WMkyKXB+904bYmG40syjMFV0oLlhhFCwWl0vA0DyzTDkwAiJw==", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "@cnakazawa/watch": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", - "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", - "dev": true, - "requires": { - "exec-sh": "^0.3.2", - "minimist": "^1.2.0" - } - }, - "@jest/console": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.9.0.tgz", - "integrity": "sha512-Zuj6b8TnKXi3q4ymac8EQfc3ea/uhLeCGThFqXeC8H9/raaH8ARPUTdId+XyGd03Z4In0/VjD2OYFcBF09fNLQ==", - "dev": true, - "requires": { - "@jest/source-map": "^24.9.0", - "chalk": "^2.0.1", - "slash": "^2.0.0" - }, - "dependencies": { "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -303,42 +455,43 @@ } } }, - "@jest/core": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-24.9.0.tgz", - "integrity": "sha512-Fogg3s4wlAr1VX7q+rhV9RVnUv5tD7VuWfYy1+whMiWUrvl7U3QJSJyWcDio9Lq2prqYsZaeTv2Rz24pWGkJ2A==", + "@babel/traverse": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.1.tgz", + "integrity": "sha512-C/cTuXeKt85K+p08jN6vMDz8vSV0vZcI0wmQ36o6mjbuo++kPMdpOYw23W2XH04dbRt9/nMEfA4W3eR21CD+TQ==", "dev": true, "requires": { - "@jest/console": "^24.7.1", - "@jest/reporters": "^24.9.0", - "@jest/test-result": "^24.9.0", - "@jest/transform": "^24.9.0", - "@jest/types": "^24.9.0", - "ansi-escapes": "^3.0.0", - "chalk": "^2.0.1", - "exit": "^0.1.2", - "graceful-fs": "^4.1.15", - "jest-changed-files": "^24.9.0", - "jest-config": "^24.9.0", - "jest-haste-map": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-regex-util": "^24.3.0", - "jest-resolve": "^24.9.0", - "jest-resolve-dependencies": "^24.9.0", - "jest-runner": "^24.9.0", - "jest-runtime": "^24.9.0", - "jest-snapshot": "^24.9.0", - "jest-util": "^24.9.0", - "jest-validate": "^24.9.0", - "jest-watcher": "^24.9.0", - "micromatch": "^3.1.10", - "p-each-series": "^1.0.0", - "realpath-native": "^1.1.0", - "rimraf": "^2.5.4", - "slash": "^2.0.0", - "strip-ansi": "^5.0.0" + "@babel/code-frame": "^7.10.1", + "@babel/generator": "^7.10.1", + "@babel/helper-function-name": "^7.10.1", + "@babel/helper-split-export-declaration": "^7.10.1", + "@babel/parser": "^7.10.1", + "@babel/types": "^7.10.1", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" }, "dependencies": { + "@babel/code-frame": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz", + "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.1" + } + }, + "@babel/highlight": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz", + "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.1", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -350,29 +503,26 @@ "supports-color": "^5.3.0" } }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, - "rimraf": { - "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" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.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 }, "supports-color": { "version": "5.5.0", @@ -385,1079 +535,1329 @@ } } }, - "@jest/environment": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-24.9.0.tgz", - "integrity": "sha512-5A1QluTPhvdIPFYnO3sZC3smkNeXPVELz7ikPbhUj0bQjB07EoE9qtLrem14ZUYWdVayYbsjVwIiL4WBIMV4aQ==", + "@babel/types": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.1.tgz", + "integrity": "sha512-L2yqUOpf3tzlW9GVuipgLEcZxnO+96SzR6fjXMuxxNkIgFJ5+07mHCZ+HkHqaeZu8+3LKnNJJ1bKbjBETQAsrA==", "dev": true, "requires": { - "@jest/fake-timers": "^24.9.0", - "@jest/transform": "^24.9.0", - "@jest/types": "^24.9.0", - "jest-mock": "^24.9.0" + "@babel/helper-validator-identifier": "^7.10.1", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" } }, - "@jest/fake-timers": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.9.0.tgz", - "integrity": "sha512-eWQcNa2YSwzXWIMC5KufBh3oWRIijrQFROsIqt6v/NS9Io/gknw1jsAC9c+ih/RQX4A3O7SeWAhQeN0goKhT9A==", + "@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "@cnakazawa/watch": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", + "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", "dev": true, "requires": { - "@jest/types": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-mock": "^24.9.0" + "exec-sh": "^0.3.2", + "minimist": "^1.2.0" } }, - "@jest/reporters": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-24.9.0.tgz", - "integrity": "sha512-mu4X0yjaHrffOsWmVLzitKmmmWSQ3GGuefgNscUSWNiUNcEOSEQk9k3pERKEQVBb0Cnn88+UESIsZEMH3o88Gw==", + "@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": { - "@jest/environment": "^24.9.0", - "@jest/test-result": "^24.9.0", - "@jest/transform": "^24.9.0", - "@jest/types": "^24.9.0", - "chalk": "^2.0.1", - "exit": "^0.1.2", - "glob": "^7.1.2", - "istanbul-lib-coverage": "^2.0.2", - "istanbul-lib-instrument": "^3.0.1", - "istanbul-lib-report": "^2.0.4", - "istanbul-lib-source-maps": "^3.0.1", - "istanbul-reports": "^2.2.6", - "jest-haste-map": "^24.9.0", - "jest-resolve": "^24.9.0", - "jest-runtime": "^24.9.0", - "jest-util": "^24.9.0", - "jest-worker": "^24.6.0", - "node-notifier": "^5.4.2", - "slash": "^2.0.0", - "source-map": "^0.6.0", - "string-length": "^2.0.0" + "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" }, "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==", + "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==", + "dev": true + }, + "@jest/console": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", + "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "jest-message-util": "^26.0.1", + "jest-util": "^26.0.1", + "slash": "^3.0.0" + }, + "dependencies": { + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" } }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "@types/yargs": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz", + "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "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 } } }, - "@jest/source-map": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-24.9.0.tgz", - "integrity": "sha512-/Xw7xGlsZb4MJzNDgB7PW5crou5JqWiBQaz6xyPd3ArOg2nfn/PunV8+olXbbEZzNl591o5rWKE9BRDaFAuIBg==", - "dev": true, - "requires": { - "callsites": "^3.0.0", - "graceful-fs": "^4.1.15", - "source-map": "^0.6.0" + "@jest/core": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.0.1.tgz", + "integrity": "sha512-Xq3eqYnxsG9SjDC+WLeIgf7/8KU6rddBxH+SCt18gEpOhAGYC/Mq+YbtlNcIdwjnnT+wDseXSbU0e5X84Y4jTQ==", + "dev": true, + "requires": { + "@jest/console": "^26.0.1", + "@jest/reporters": "^26.0.1", + "@jest/test-result": "^26.0.1", + "@jest/transform": "^26.0.1", + "@jest/types": "^26.0.1", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-changed-files": "^26.0.1", + "jest-config": "^26.0.1", + "jest-haste-map": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.0.1", + "jest-resolve-dependencies": "^26.0.1", + "jest-runner": "^26.0.1", + "jest-runtime": "^26.0.1", + "jest-snapshot": "^26.0.1", + "jest-util": "^26.0.1", + "jest-validate": "^26.0.1", + "jest-watcher": "^26.0.1", + "micromatch": "^4.0.2", + "p-each-series": "^2.1.0", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" }, "dependencies": { - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz", + "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "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.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "camelcase": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.0.0.tgz", + "integrity": "sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==", + "dev": true + }, + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "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 + }, + "jest-get-type": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", "dev": true + }, + "jest-validate": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.0.1.tgz", + "integrity": "sha512-u0xRc+rbmov/VqXnX3DlkxD74rHI/CfS5xaV2VpeaVySjbb1JioNVOyly5b56q2l9ZKe7bVG5qWmjfctkQb0bA==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "camelcase": "^6.0.0", + "chalk": "^4.0.0", + "jest-get-type": "^26.0.0", + "leven": "^3.1.0", + "pretty-format": "^26.0.1" + } + }, + "pretty-format": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", + "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.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" + } } } }, - "@jest/test-result": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.9.0.tgz", - "integrity": "sha512-XEFrHbBonBJ8dGp2JmF8kP/nQI/ImPpygKHwQ/SY+es59Z3L5PI4Qb9TQQMAEeYsThG1xF0k6tmG0tIKATNiiA==", - "dev": true, - "requires": { - "@jest/console": "^24.9.0", - "@jest/types": "^24.9.0", - "@types/istanbul-lib-coverage": "^2.0.0" - } - }, - "@jest/test-sequencer": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-24.9.0.tgz", - "integrity": "sha512-6qqsU4o0kW1dvA95qfNog8v8gkRN9ph6Lz7r96IvZpHdNipP2cBcb07J1Z45mz/VIS01OHJ3pY8T5fUY38tg4A==", + "@jest/environment": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", + "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", "dev": true, "requires": { - "@jest/test-result": "^24.9.0", - "jest-haste-map": "^24.9.0", - "jest-runner": "^24.9.0", - "jest-runtime": "^24.9.0" + "@jest/fake-timers": "^26.0.1", + "@jest/types": "^26.0.1", + "jest-mock": "^26.0.1" + }, + "dependencies": { + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz", + "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "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 + } } }, - "@jest/transform": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.9.0.tgz", - "integrity": "sha512-TcQUmyNRxV94S0QpMOnZl0++6RMiqpbH/ZMccFB/amku6Uwvyb1cjYX7xkp5nGNkbX4QPH/FcB6q1HBTHynLmQ==", + "@jest/fake-timers": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", + "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", "dev": true, "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^24.9.0", - "babel-plugin-istanbul": "^5.1.0", - "chalk": "^2.0.1", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.1.15", - "jest-haste-map": "^24.9.0", - "jest-regex-util": "^24.9.0", - "jest-util": "^24.9.0", - "micromatch": "^3.1.10", - "pirates": "^4.0.1", - "realpath-native": "^1.1.0", - "slash": "^2.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "2.4.1" + "@jest/types": "^26.0.1", + "@sinonjs/fake-timers": "^6.0.1", + "jest-message-util": "^26.0.1", + "jest-mock": "^26.0.1", + "jest-util": "^26.0.1" }, "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==", + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" } }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "@types/yargs": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz", + "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" } + }, + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "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 } } }, - "@jest/types": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", - "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "@jest/globals": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.0.1.tgz", + "integrity": "sha512-iuucxOYB7BRCvT+TYBzUqUNuxFX1hqaR6G6IcGgEqkJ5x4htNKo1r7jk1ji9Zj8ZMiMw0oB5NaA7k5Tx6MVssA==", "dev": true, "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^13.0.0" - } - }, - "@sheerun/mutationobserver-shim": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@sheerun/mutationobserver-shim/-/mutationobserver-shim-0.3.3.tgz", - "integrity": "sha512-DetpxZw1fzPD5xUBrIAoplLChO2VB8DlL5Gg+I1IR9b2wPqYIca2WSUxL5g1vLeR4MsQq1NeWriXAVffV+U1Fw==", - "dev": true - }, - "@testing-library/dom": { - "version": "6.16.0", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-6.16.0.tgz", - "integrity": "sha512-lBD88ssxqEfz0wFL6MeUyyWZfV/2cjEZZV3YRpb2IoJRej/4f1jB0TzqIOznTpfR1r34CNesrubxwIlAQ8zgPA==", - "dev": true, - "requires": { - "@babel/runtime": "^7.8.4", - "@sheerun/mutationobserver-shim": "^0.3.2", - "@types/testing-library__dom": "^6.12.1", - "aria-query": "^4.0.2", - "dom-accessibility-api": "^0.3.0", - "pretty-format": "^25.1.0", - "wait-for-expect": "^3.0.2" - } - }, - "@testing-library/react": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-9.4.1.tgz", - "integrity": "sha512-sta3ui24HPgW92quHyQj6gpOkNgLNx8BX/QOU4k1bddo43ZdqlGwmzCYwL93bExfhergwiau+IzBGl7TCsSFeA==", - "dev": true, - "requires": { - "@babel/runtime": "^7.8.3", - "@testing-library/dom": "^6.11.0", - "@types/testing-library__react": "^9.1.2" - } - }, - "@types/babel__core": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.6.tgz", - "integrity": "sha512-tTnhWszAqvXnhW7m5jQU9PomXSiKXk2sFxpahXvI20SZKu9ylPi8WtIxueZ6ehDWikPT0jeFujMj3X4ZHuf3Tg==", - "dev": true, - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "@types/babel__generator": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.1.tgz", - "integrity": "sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@types/babel__template": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.0.2.tgz", - "integrity": "sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg==", - "dev": true, - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@types/babel__traverse": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.9.tgz", - "integrity": "sha512-jEFQ8L1tuvPjOI8lnpaf73oCJe+aoxL6ygqSy6c8LcW98zaC+4mzWuQIRCEvKeCOu+lbqdXcg4Uqmm1S8AP1tw==", - "dev": true, - "requires": { - "@babel/types": "^7.3.0" - } - }, - "@types/color-name": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", - "dev": true - }, - "@types/estree": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.42.tgz", - "integrity": "sha512-K1DPVvnBCPxzD+G51/cxVIoc2X8uUVl1zpJeE6iKcgHMj4+tbat5Xu4TjV7v2QSDbIeAfLi2hIk+u2+s0MlpUQ==", - "dev": true - }, - "@types/fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha512-mky/O83TXmGY39P1H9YbUpjV6l6voRYlufqfFCvel8l1phuy8HRjdWc1rrPuN53ITBJlbyMSV6z3niOySO5pgQ==", - "dev": true - }, - "@types/fetch-mock": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@types/fetch-mock/-/fetch-mock-7.3.2.tgz", - "integrity": "sha512-NCEfv49jmDsBAixjMjEHKVgmVQlJ+uK56FOc+2roYPExnXCZDpi6mJOHQ3v23BiO84hBDStND9R2itJr7PNoow==", - "dev": true - }, - "@types/istanbul-lib-coverage": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", - "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", - "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": "*" - } - }, - "@types/istanbul-reports": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.1.tgz", - "integrity": "sha512-UpYjBi8xefVChsCoBpKShdxTllC9pwISirfoZsUa2AAdQg/Jd2KQGtSbw+ya7GPo7x/wAPlH6JBhKhAsXUEZNA==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "*", - "@types/istanbul-lib-report": "*" - } - }, - "@types/jest": { - "version": "24.0.25", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-24.0.25.tgz", - "integrity": "sha512-hnP1WpjN4KbGEK4dLayul6lgtys6FPz0UfxMeMQCv0M+sTnzN3ConfiO72jHgLxl119guHgI8gLqDOrRLsyp2g==", - "dev": true, - "requires": { - "jest-diff": "^24.3.0" - } - }, - "@types/lodash": { - "version": "4.14.149", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.149.tgz", - "integrity": "sha512-ijGqzZt/b7BfzcK9vTrS6MFljQRPn5BFWOx8oE0GYxribu6uV+aA9zZuXI1zc/etK9E8nrgdoF2+LgUw7+9tJQ==", - "dev": true - }, - "@types/node": { - "version": "14.0.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.1.tgz", - "integrity": "sha512-FAYBGwC+W6F9+huFIDtn43cpy7+SzG+atzRiTfdp3inUKL2hXnd4rG8hylJLIh4+hqrQy1P17kvJByE/z825hA==", - "dev": true - }, - "@types/prop-types": { - "version": "15.7.3", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz", - "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==", - "dev": true - }, - "@types/react": { - "version": "16.9.32", - "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.32.tgz", - "integrity": "sha512-fmejdp0CTH00mOJmxUPPbWCEBWPvRIL4m8r0qD+BSDUqmutPyGQCHifzMpMzdvZwROdEdL78IuZItntFWgPXHQ==", - "dev": true, - "requires": { - "@types/prop-types": "*", - "csstype": "^2.2.0" + "@jest/environment": "^26.0.1", + "@jest/types": "^26.0.1", + "expect": "^26.0.1" + }, + "dependencies": { + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz", + "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "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 + } } }, - "@types/react-dom": { - "version": "16.9.6", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-16.9.6.tgz", - "integrity": "sha512-S6ihtlPMDotrlCJE9ST1fRmYrQNNwfgL61UB4I1W7M6kPulUKx9fXAleW5zpdIjUQ4fTaaog8uERezjsGUj9HQ==", - "dev": true, - "requires": { - "@types/react": "*" + "@jest/reporters": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.0.1.tgz", + "integrity": "sha512-NWWy9KwRtE1iyG/m7huiFVF9YsYv/e+mbflKRV84WDoJfBqUrNRyDbL/vFxQcYLl8IRqI4P3MgPn386x76Gf2g==", + "dev": true, + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^26.0.1", + "@jest/test-result": "^26.0.1", + "@jest/transform": "^26.0.1", + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.4", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "jest-haste-map": "^26.0.1", + "jest-resolve": "^26.0.1", + "jest-util": "^26.0.1", + "jest-worker": "^26.0.0", + "node-notifier": "^7.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^4.1.3" + }, + "dependencies": { + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz", + "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "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 + }, + "jest-worker": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.0.0.tgz", + "integrity": "sha512-pPaYa2+JnwmiZjK9x7p9BoZht+47ecFCDFA/CJxspHzeDvQcfVBLWzCiWyo+EGrSiQMWZtCFo9iSvMZnAAo8vw==", + "dev": true, + "requires": { + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + } + } } }, - "@types/resolve": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", - "integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==", + "@jest/source-map": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.0.0.tgz", + "integrity": "sha512-S2Z+Aj/7KOSU2TfW0dyzBze7xr95bkm5YXNUqqCek+HE0VbNNSNzrRwfIi5lf7wvzDTSS0/ib8XQ1krFNyYgbQ==", "dev": true, "requires": { - "@types/node": "*" + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" + }, + "dependencies": { + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + } } }, - "@types/stack-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", - "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", - "dev": true - }, - "@types/testing-library__dom": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@types/testing-library__dom/-/testing-library__dom-6.14.0.tgz", - "integrity": "sha512-sMl7OSv0AvMOqn1UJ6j1unPMIHRXen0Ita1ujnMX912rrOcawe4f7wu0Zt9GIQhBhJvH2BaibqFgQ3lP+Pj2hA==", + "@jest/test-result": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", + "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", "dev": true, "requires": { - "pretty-format": "^24.3.0" + "@jest/console": "^26.0.1", + "@jest/types": "^26.0.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" }, "dependencies": { - "pretty-format": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz", - "integrity": "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==", + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", "dev": true, "requires": { - "@jest/types": "^24.9.0", - "ansi-regex": "^4.0.0", - "ansi-styles": "^3.2.0", - "react-is": "^16.8.4" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz", + "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "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 } } }, - "@types/testing-library__react": { - "version": "9.1.3", - "resolved": "https://registry.npmjs.org/@types/testing-library__react/-/testing-library__react-9.1.3.tgz", - "integrity": "sha512-iCdNPKU3IsYwRK9JieSYAiX0+aYDXOGAmrC/3/M7AqqSDKnWWVv07X+Zk1uFSL7cMTUYzv4lQRfohucEocn5/w==", + "@jest/test-sequencer": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.0.1.tgz", + "integrity": "sha512-ssga8XlwfP8YjbDcmVhwNlrmblddMfgUeAkWIXts1V22equp2GMIHxm7cyeD5Q/B0ZgKPK/tngt45sH99yLLGg==", "dev": true, "requires": { - "@types/react-dom": "*", - "@types/testing-library__dom": "*", - "pretty-format": "^25.1.0" + "@jest/test-result": "^26.0.1", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.0.1", + "jest-runner": "^26.0.1", + "jest-runtime": "^26.0.1" } }, - "@types/yargs": { - "version": "13.0.8", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.8.tgz", - "integrity": "sha512-XAvHLwG7UQ+8M4caKIH0ZozIOYay5fQkAgyIXegXT9jPtdIGdhga+sUEdAr1CiG46aB+c64xQEYyEzlwWVTNzA==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "@types/yargs-parser": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz", - "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==", - "dev": true - }, - "@types/zen-observable": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@types/zen-observable/-/zen-observable-0.8.0.tgz", - "integrity": "sha512-te5lMAWii1uEJ4FwLjzdlbw3+n0FZNOvFXHxQDKeT0dilh7HOzdMzV2TrJVUzq8ep7J4Na8OUYPRLSQkJHAlrg==" - }, - "@wry/context": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@wry/context/-/context-0.5.2.tgz", - "integrity": "sha512-B/JLuRZ/vbEKHRUiGj6xiMojST1kHhu4WcreLfNN7q9DqQFrb97cWgf/kiYsPSUCAMVN0HzfFc8XjJdzgZzfjw==", - "requires": { - "tslib": "^1.9.3" - } - }, - "@wry/equality": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/@wry/equality/-/equality-0.1.9.tgz", - "integrity": "sha512-mB6ceGjpMGz1ZTza8HYnrPGos2mC6So4NhS1PtZ8s4Qt0K7fBiIGhpSxUbQmhwcSWE3no+bYxmI2OL6KuXYmoQ==", - "requires": { - "tslib": "^1.9.3" - } - }, - "abab": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz", - "integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==", - "dev": true - }, - "acorn": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", - "dev": true - }, - "acorn-globals": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", - "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", + "@jest/transform": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.0.1.tgz", + "integrity": "sha512-pPRkVkAQ91drKGbzCfDOoHN838+FSbYaEAvBXvKuWeeRRUD8FjwXkqfUNUZL6Ke48aA/1cqq/Ni7kVMCoqagWA==", "dev": true, "requires": { - "acorn": "^6.0.1", - "acorn-walk": "^6.0.1" + "@babel/core": "^7.1.0", + "@jest/types": "^26.0.1", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.0.1", + "jest-regex-util": "^26.0.0", + "jest-util": "^26.0.1", + "micromatch": "^4.0.2", + "pirates": "^4.0.1", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" }, "dependencies": { - "acorn": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", - "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz", + "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "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 } } }, - "acorn-walk": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", - "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==", - "dev": true - }, - "ajv": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz", - "integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==", + "@jest/types": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", + "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", "dev": true, "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" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^13.0.0" } }, - "ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", - "dev": true - }, - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "@sheerun/mutationobserver-shim": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@sheerun/mutationobserver-shim/-/mutationobserver-shim-0.3.3.tgz", + "integrity": "sha512-DetpxZw1fzPD5xUBrIAoplLChO2VB8DlL5Gg+I1IR9b2wPqYIca2WSUxL5g1vLeR4MsQq1NeWriXAVffV+U1Fw==", "dev": true }, - "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==", + "@sinonjs/commons": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.0.tgz", + "integrity": "sha512-wEj54PfsZ5jGSwMX68G8ZXFawcSglQSXqCftWX3ec8MDUzQdHgcKvw97awHbY0efQEL5iKUOAmmVtoYgmrSG4Q==", "dev": true, "requires": { - "color-convert": "^1.9.0" + "type-detect": "4.0.8" } }, - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "@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, "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" + "@sinonjs/commons": "^1.7.0" } }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "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==", + "@testing-library/dom": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-6.16.0.tgz", + "integrity": "sha512-lBD88ssxqEfz0wFL6MeUyyWZfV/2cjEZZV3YRpb2IoJRej/4f1jB0TzqIOznTpfR1r34CNesrubxwIlAQ8zgPA==", "dev": true, "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" + "@babel/runtime": "^7.8.4", + "@sheerun/mutationobserver-shim": "^0.3.2", + "@types/testing-library__dom": "^6.12.1", + "aria-query": "^4.0.2", + "dom-accessibility-api": "^0.3.0", + "pretty-format": "^25.1.0", + "wait-for-expect": "^3.0.2" } }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "@testing-library/react": { + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-9.4.1.tgz", + "integrity": "sha512-sta3ui24HPgW92quHyQj6gpOkNgLNx8BX/QOU4k1bddo43ZdqlGwmzCYwL93bExfhergwiau+IzBGl7TCsSFeA==", "dev": true, "requires": { - "sprintf-js": "~1.0.2" + "@babel/runtime": "^7.8.3", + "@testing-library/dom": "^6.11.0", + "@types/testing-library__react": "^9.1.2" } }, - "aria-query": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.0.2.tgz", - "integrity": "sha512-S1G1V790fTaigUSM/Gd0NngzEfiMy9uTUfMyHhKhVyy4cH5O/eTuR01ydhGL0z4Za1PXFTRGH3qL8VhUQuEO5w==", + "@types/babel__core": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.7.tgz", + "integrity": "sha512-RL62NqSFPCDK2FM1pSDH0scHpJvsXtZNiYlMB73DgPBaG1E38ZYVL+ei5EkWRbr+KC4YNiAUNBnRj+bgwpgjMw==", "dev": true, "requires": { - "@babel/runtime": "^7.7.4", - "@babel/runtime-corejs3": "^7.7.4" + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" } }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", - "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "@types/babel__generator": { + "version": "7.6.1", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.1.tgz", + "integrity": "sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew==", "dev": true, "requires": { - "safer-buffer": "~2.1.0" + "@babel/types": "^7.0.0" } }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "ast-types": { - "version": "0.13.3", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.3.tgz", - "integrity": "sha512-XTZ7xGML849LkQP86sWdQzfhwbt3YwIO6MqbX9mUNYY98VKaaVZP7YNNm70IpwecbkkxmfC5IYAzOQ/2p29zRA==", - "dev": true - }, - "astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", - "dev": true - }, - "async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", - "dev": true - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "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 - }, - "aws4": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz", - "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==", - "dev": true - }, - "axios": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", - "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", + "@types/babel__template": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.0.2.tgz", + "integrity": "sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg==", "dev": true, "requires": { - "follow-redirects": "1.5.10" + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" } }, - "babel-jest": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-24.9.0.tgz", - "integrity": "sha512-ntuddfyiN+EhMw58PTNL1ph4C9rECiQXjI4nMMBKBaNjXvqLdkXpPRcMSr4iyBrJg/+wz9brFUD6RhOAT6r4Iw==", + "@types/babel__traverse": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.11.tgz", + "integrity": "sha512-ddHK5icION5U6q11+tV2f9Mo6CZVuT8GJKld2q9LqHSZbvLbH34Kcu2yFGckZut453+eQU6btIA3RihmnRgI+Q==", "dev": true, "requires": { - "@jest/transform": "^24.9.0", - "@jest/types": "^24.9.0", - "@types/babel__core": "^7.1.0", - "babel-plugin-istanbul": "^5.1.0", - "babel-preset-jest": "^24.9.0", - "chalk": "^2.4.2", - "slash": "^2.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" - } - }, - "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/types": "^7.3.0" } }, - "babel-plugin-istanbul": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz", - "integrity": "sha512-5LphC0USA8t4i1zCtjbbNb6jJj/9+X6P37Qfirc/70EQ34xKlMW+a1RHGwxGI+SwWpNwZ27HqvzAobeqaXwiZw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "find-up": "^3.0.0", - "istanbul-lib-instrument": "^3.3.0", - "test-exclude": "^5.2.3" - } + "@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", + "dev": true + }, + "@types/estree": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.42.tgz", + "integrity": "sha512-K1DPVvnBCPxzD+G51/cxVIoc2X8uUVl1zpJeE6iKcgHMj4+tbat5Xu4TjV7v2QSDbIeAfLi2hIk+u2+s0MlpUQ==", + "dev": true + }, + "@types/fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha512-mky/O83TXmGY39P1H9YbUpjV6l6voRYlufqfFCvel8l1phuy8HRjdWc1rrPuN53ITBJlbyMSV6z3niOySO5pgQ==", + "dev": true }, - "babel-plugin-jest-hoist": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.9.0.tgz", - "integrity": "sha512-2EMA2P8Vp7lG0RAzr4HXqtYwacfMErOuv1U3wrvxHX6rD1sV6xS3WXG3r8TRQ2r6w8OhvSdWt+z41hQNwNm3Xw==", + "@types/fetch-mock": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@types/fetch-mock/-/fetch-mock-7.3.2.tgz", + "integrity": "sha512-NCEfv49jmDsBAixjMjEHKVgmVQlJ+uK56FOc+2roYPExnXCZDpi6mJOHQ3v23BiO84hBDStND9R2itJr7PNoow==", + "dev": true + }, + "@types/graceful-fs": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.3.tgz", + "integrity": "sha512-AiHRaEB50LQg0pZmm659vNBb9f4SJ0qrAnteuzhSeAUcJKxoYgEnprg/83kppCnc2zvtCKbdZry1a5pVY3lOTQ==", "dev": true, "requires": { - "@types/babel__traverse": "^7.0.6" + "@types/node": "*" } }, - "babel-polyfill": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", - "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=", + "@types/istanbul-lib-coverage": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", + "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", + "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": { - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "regenerator-runtime": "^0.10.5" - }, - "dependencies": { - "regenerator-runtime": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", - "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=", - "dev": true - } + "@types/istanbul-lib-coverage": "*" } }, - "babel-preset-jest": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-24.9.0.tgz", - "integrity": "sha512-izTUuhE4TMfTRPF92fFwD2QfdXaZW08qvWTFCI51V8rW5x00UuPgc3ajRoWofXOuxjfcOM5zzSYsQS3H8KGCAg==", + "@types/istanbul-reports": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.1.tgz", + "integrity": "sha512-UpYjBi8xefVChsCoBpKShdxTllC9pwISirfoZsUa2AAdQg/Jd2KQGtSbw+ya7GPo7x/wAPlH6JBhKhAsXUEZNA==", "dev": true, "requires": { - "@babel/plugin-syntax-object-rest-spread": "^7.0.0", - "babel-plugin-jest-hoist": "^24.9.0" + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" } }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "@types/jest": { + "version": "24.0.25", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-24.0.25.tgz", + "integrity": "sha512-hnP1WpjN4KbGEK4dLayul6lgtys6FPz0UfxMeMQCv0M+sTnzN3ConfiO72jHgLxl119guHgI8gLqDOrRLsyp2g==", "dev": true, "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - }, - "dependencies": { - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - } + "jest-diff": "^24.3.0" } }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "@types/lodash": { + "version": "4.14.149", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.149.tgz", + "integrity": "sha512-ijGqzZt/b7BfzcK9vTrS6MFljQRPn5BFWOx8oE0GYxribu6uV+aA9zZuXI1zc/etK9E8nrgdoF2+LgUw7+9tJQ==", "dev": true }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "@types/node": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.1.tgz", + "integrity": "sha512-FAYBGwC+W6F9+huFIDtn43cpy7+SzG+atzRiTfdp3inUKL2hXnd4rG8hylJLIh4+hqrQy1P17kvJByE/z825hA==", + "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==", + "dev": true + }, + "@types/prettier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.1.tgz", + "integrity": "sha512-boy4xPNEtiw6N3abRhBi/e7hNvy3Tt8E9ZRAQrwAGzoCGZS/1wjo9KY7JHhnfnEsG5wSjDbymCozUM9a3ea7OQ==", + "dev": true + }, + "@types/prop-types": { + "version": "15.7.3", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz", + "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==", + "dev": true + }, + "@types/react": { + "version": "16.9.32", + "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.32.tgz", + "integrity": "sha512-fmejdp0CTH00mOJmxUPPbWCEBWPvRIL4m8r0qD+BSDUqmutPyGQCHifzMpMzdvZwROdEdL78IuZItntFWgPXHQ==", "dev": true, "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } + "@types/prop-types": "*", + "csstype": "^2.2.0" } }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "@types/react-dom": { + "version": "16.9.6", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-16.9.6.tgz", + "integrity": "sha512-S6ihtlPMDotrlCJE9ST1fRmYrQNNwfgL61UB4I1W7M6kPulUKx9fXAleW5zpdIjUQ4fTaaog8uERezjsGUj9HQ==", "dev": true, "requires": { - "tweetnacl": "^0.14.3" + "@types/react": "*" } }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "@types/resolve": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", + "integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==", "dev": true, - "optional": true, "requires": { - "file-uri-to-path": "1.0.0" + "@types/node": "*" } }, - "bl": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.1.tgz", - "integrity": "sha512-FL/TdvchukRCuWVxT0YMO/7+L5TNeNrVFvRU2IY63aUyv9mpt8splf2NEr6qXtPo5fya5a66YohQKvGNmLrWNA==", + "@types/stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", + "dev": true + }, + "@types/testing-library__dom": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@types/testing-library__dom/-/testing-library__dom-6.14.0.tgz", + "integrity": "sha512-sMl7OSv0AvMOqn1UJ6j1unPMIHRXen0Ita1ujnMX912rrOcawe4f7wu0Zt9GIQhBhJvH2BaibqFgQ3lP+Pj2hA==", "dev": true, "requires": { - "readable-stream": "^3.4.0" + "pretty-format": "^24.3.0" }, "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==", + "pretty-format": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz", + "integrity": "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==", "dev": true, "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "@jest/types": "^24.9.0", + "ansi-regex": "^4.0.0", + "ansi-styles": "^3.2.0", + "react-is": "^16.8.4" } } } }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "@types/testing-library__react": { + "version": "9.1.3", + "resolved": "https://registry.npmjs.org/@types/testing-library__react/-/testing-library__react-9.1.3.tgz", + "integrity": "sha512-iCdNPKU3IsYwRK9JieSYAiX0+aYDXOGAmrC/3/M7AqqSDKnWWVv07X+Zk1uFSL7cMTUYzv4lQRfohucEocn5/w==", "dev": true, "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "@types/react-dom": "*", + "@types/testing-library__dom": "*", + "pretty-format": "^25.1.0" } }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "@types/yargs": { + "version": "13.0.8", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.8.tgz", + "integrity": "sha512-XAvHLwG7UQ+8M4caKIH0ZozIOYay5fQkAgyIXegXT9jPtdIGdhga+sUEdAr1CiG46aB+c64xQEYyEzlwWVTNzA==", "dev": true, "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz", + "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==", + "dev": true + }, + "@types/zen-observable": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@types/zen-observable/-/zen-observable-0.8.0.tgz", + "integrity": "sha512-te5lMAWii1uEJ4FwLjzdlbw3+n0FZNOvFXHxQDKeT0dilh7HOzdMzV2TrJVUzq8ep7J4Na8OUYPRLSQkJHAlrg==" + }, + "@wry/context": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@wry/context/-/context-0.5.2.tgz", + "integrity": "sha512-B/JLuRZ/vbEKHRUiGj6xiMojST1kHhu4WcreLfNN7q9DqQFrb97cWgf/kiYsPSUCAMVN0HzfFc8XjJdzgZzfjw==", + "requires": { + "tslib": "^1.9.3" } }, - "brotli-size": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/brotli-size/-/brotli-size-0.1.0.tgz", - "integrity": "sha512-5ny7BNvpe2TSmdafF1T9dnFYp3AIrJ8qJt29K0DQJzORlK38LBim/CmlY26JtreV6SWmXza7Oa+9m61SzvxR0Q==", - "dev": true, + "@wry/equality": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/@wry/equality/-/equality-0.1.9.tgz", + "integrity": "sha512-mB6ceGjpMGz1ZTza8HYnrPGos2mC6So4NhS1PtZ8s4Qt0K7fBiIGhpSxUbQmhwcSWE3no+bYxmI2OL6KuXYmoQ==", "requires": { - "duplexer": "^0.1.1", - "iltorb": "^2.4.3" + "tslib": "^1.9.3" } }, - "browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", + "abab": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz", + "integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==", + "dev": true + }, + "acorn": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.2.0.tgz", + "integrity": "sha512-apwXVmYVpQ34m/i71vrApRrRKCWQnZZF1+npOD0WV5xZFfwWOmKGQ2RWlfdy9vWITsenisM8M0Qeq8agcFHNiQ==", "dev": true }, - "browser-resolve": { - "version": "1.11.3", - "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", - "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", + "acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", "dev": true, "requires": { - "resolve": "1.1.7" - }, - "dependencies": { - "resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", - "dev": true - } + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" } }, - "bs-logger": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", - "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "acorn-walk": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.1.1.tgz", + "integrity": "sha512-wdlPY2tm/9XBr7QkKlq0WQVgiuGTX6YWPyRyBviSoScBuLfTVQhvwg6wJ369GJ/1nPfTLMfnrFIfjqVg6d+jQQ==", + "dev": true + }, + "ajv": { + "version": "6.12.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz", + "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==", "dev": true, "requires": { - "fast-json-stable-stringify": "2.x" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" } }, - "bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "ansi-escapes": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", + "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", "dev": true, "requires": { - "node-int64": "^0.4.0" + "type-fest": "^0.11.0" + }, + "dependencies": { + "type-fest": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", + "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==", + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, - "builtin-modules": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.1.0.tgz", - "integrity": "sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw==", - "dev": true + "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" + } }, - "bundlesize": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/bundlesize/-/bundlesize-0.18.0.tgz", - "integrity": "sha512-GZURr25umfYxZYZUyOlOtJRbYjAn0VfbjbnS0NBcOiF8VcjmhoEhmx8Gw4va8HeQb8j7Ra0ZltY/IeHgSHFXFw==", + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", "dev": true, "requires": { - "axios": "^0.19.0", - "brotli-size": "0.1.0", - "bytes": "^3.1.0", - "ci-env": "^1.4.0", - "commander": "^2.20.0", - "cosmiconfig": "^5.2.1", - "github-build": "^1.2.0", - "glob": "^7.1.4", - "gzip-size": "^4.0.0", - "prettycli": "^1.4.3" + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" } }, - "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", "dev": true }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "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==", "dev": true, "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" } }, - "caller-callsite": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", - "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "requires": { - "callsites": "^2.0.0" + "sprintf-js": "~1.0.2" } }, - "caller-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", - "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", + "aria-query": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.0.2.tgz", + "integrity": "sha512-S1G1V790fTaigUSM/Gd0NngzEfiMy9uTUfMyHhKhVyy4cH5O/eTuR01ydhGL0z4Za1PXFTRGH3qL8VhUQuEO5w==", "dev": true, "requires": { - "caller-callsite": "^2.0.0" + "@babel/runtime": "^7.7.4", + "@babel/runtime-corejs3": "^7.7.4" } }, - "callsites": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", "dev": true }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", "dev": true }, - "capture-exit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", - "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", "dev": true, "requires": { - "rsvp": "^4.8.4" + "safer-buffer": "~2.1.0" } }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "dev": true }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "ast-types": { + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.3.tgz", + "integrity": "sha512-XTZ7xGML849LkQP86sWdQzfhwbt3YwIO6MqbX9mUNYY98VKaaVZP7YNNm70IpwecbkkxmfC5IYAzOQ/2p29zRA==", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "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 + }, + "aws4": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz", + "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==", + "dev": true + }, + "axios": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", + "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", "dev": true, "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "follow-redirects": "1.5.10" + } + }, + "babel-jest": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.0.1.tgz", + "integrity": "sha512-Z4GGmSNQ8pX3WS1O+6v3fo41YItJJZsVxG5gIQ+HuB/iuAQBJxMTHTwz292vuYws1LnHfwSRgoqI+nxdy/pcvw==", + "dev": true, + "requires": { + "@jest/transform": "^26.0.1", + "@jest/types": "^26.0.1", + "@types/babel__core": "^7.1.7", + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^26.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "slash": "^3.0.0" }, "dependencies": { + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz", + "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, "color-convert": { @@ -1477,695 +1877,752 @@ } } }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, - "ci-env": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/ci-env/-/ci-env-1.12.0.tgz", - "integrity": "sha512-4dS9YjX4kpaFmkJWZPuDPK3WlPKdMjx/3JH39vyHj+G4/ED2DCgHQLbh9tKBQjwAwR/sGHOqIVMTlMUZcfJPWw==", - "dev": true + "babel-plugin-istanbul": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", + "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^4.0.0", + "test-exclude": "^6.0.0" + } }, - "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 + "babel-plugin-jest-hoist": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.0.0.tgz", + "integrity": "sha512-+AuoehOrjt9irZL7DOt2+4ZaTM6dlu1s5TTS46JBa0/qem4dy7VNW3tMb96qeEqcIh20LD73TVNtmVEeymTG7w==", + "dev": true, + "requires": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__traverse": "^7.0.6" + } }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "babel-polyfill": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", + "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=", "dev": true, "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "regenerator-runtime": "^0.10.5" }, "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } + "regenerator-runtime": { + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", + "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=", + "dev": true } } }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "babel-preset-current-node-syntax": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.2.tgz", + "integrity": "sha512-u/8cS+dEiK1SFILbOC8/rUI3ml9lboKuuMvZ/4aQnQmhecQAgPw5ew066C1ObnEAUmlx7dv/s2z52psWEtLNiw==", + "dev": true, + "requires": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + } + }, + "babel-preset-jest": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.0.0.tgz", + "integrity": "sha512-9ce+DatAa31DpR4Uir8g4Ahxs5K4W4L8refzt+qHWQANb6LhGcAEfIFgLUwk67oya2cCUd6t4eUMtO/z64ocNw==", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^26.0.0", + "babel-preset-current-node-syntax": "^0.1.2" + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" }, "dependencies": { - "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=", + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", "dev": true + } + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "kind-of": "^6.0.0" } }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "ansi-regex": "^4.1.0" + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } } } }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "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=", - "dev": true - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "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, "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" + "tweetnacl": "^0.14.3" } }, - "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==", + "bl": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.1.tgz", + "integrity": "sha512-FL/TdvchukRCuWVxT0YMO/7+L5TNeNrVFvRU2IY63aUyv9mpt8splf2NEr6qXtPo5fya5a66YohQKvGNmLrWNA==", "dev": true, "requires": { - "color-name": "1.1.3" + "readable-stream": "^3.4.0" + }, + "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==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } } }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "requires": { - "delayed-stream": "~1.0.0" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "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 + "braces": { + "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" + } }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true + "brotli-size": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/brotli-size/-/brotli-size-0.1.0.tgz", + "integrity": "sha512-5ny7BNvpe2TSmdafF1T9dnFYp3AIrJ8qJt29K0DQJzORlK38LBim/CmlY26JtreV6SWmXza7Oa+9m61SzvxR0Q==", + "dev": true, + "requires": { + "duplexer": "^0.1.1", + "iltorb": "^2.4.3" + } }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", "dev": true }, - "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 + "bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "requires": { + "fast-json-stable-stringify": "2.x" + } }, - "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==", + "bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", "dev": true, "requires": { - "safe-buffer": "~5.1.1" + "node-int64": "^0.4.0" } }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "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==", "dev": true }, - "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", + "builtin-modules": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.1.0.tgz", + "integrity": "sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw==", "dev": true }, - "core-js-pure": { - "version": "3.6.4", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.6.4.tgz", - "integrity": "sha512-epIhRLkXdgv32xIUFaaAry2wdxZYBi6bgM7cB136dzzXXa+dFyRLTZeLUJxnd8ShrmyVXBub63n2NHo2JAt8Cw==", - "dev": true + "bundlesize": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/bundlesize/-/bundlesize-0.18.0.tgz", + "integrity": "sha512-GZURr25umfYxZYZUyOlOtJRbYjAn0VfbjbnS0NBcOiF8VcjmhoEhmx8Gw4va8HeQb8j7Ra0ZltY/IeHgSHFXFw==", + "dev": true, + "requires": { + "axios": "^0.19.0", + "brotli-size": "0.1.0", + "bytes": "^3.1.0", + "ci-env": "^1.4.0", + "commander": "^2.20.0", + "cosmiconfig": "^5.2.1", + "github-build": "^1.2.0", + "glob": "^7.1.4", + "gzip-size": "^4.0.0", + "prettycli": "^1.4.3" + } }, - "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=", + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", "dev": true }, - "cosmiconfig": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", - "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", "dev": true, "requires": { - "import-fresh": "^2.0.0", - "is-directory": "^0.3.1", - "js-yaml": "^3.13.1", - "parse-json": "^4.0.0" + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" } }, - "cross-fetch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.0.4.tgz", - "integrity": "sha512-MSHgpjQqgbT/94D4CyADeNoYh52zMkCX4pcJvPP5WqPsLFMKjr2TCMg381ox5qI0ii2dPwaLx/00477knXqXVw==", + "caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", "dev": true, "requires": { - "node-fetch": "2.6.0", - "whatwg-fetch": "3.0.0" + "callsites": "^2.0.0" } }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", "dev": true, "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "caller-callsite": "^2.0.0" } }, - "cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", "dev": true }, - "cssstyle": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.4.0.tgz", - "integrity": "sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==", - "dev": true, - "requires": { - "cssom": "0.3.x" - } - }, - "csstype": { - "version": "2.6.10", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.10.tgz", - "integrity": "sha512-D34BqZU4cIlMCY93rZHbrq9pjTAQJ3U8S8rfBqjwHxkGPThWFjzZDQpgMJY0QViLxth6ZKYiwFBo14RdN44U/w==", + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "capture-exit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", + "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", "dev": true, "requires": { - "assert-plus": "^1.0.0" + "rsvp": "^4.8.4" } }, - "data-urls": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", - "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, "requires": { - "abab": "^2.0.0", - "whatwg-mimetype": "^2.2.0", - "whatwg-url": "^7.0.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "dependencies": { - "whatwg-url": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", - "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", "dev": true, "requires": { - "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" + "@types/color-name": "^1.1.1", + "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 } } }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", "dev": true }, - "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==", - "dev": true, - "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==", + "ci-env": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/ci-env/-/ci-env-1.12.0.tgz", + "integrity": "sha512-4dS9YjX4kpaFmkJWZPuDPK3WlPKdMjx/3JH39vyHj+G4/ED2DCgHQLbh9tKBQjwAwR/sGHOqIVMTlMUZcfJPWw==", "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=", + "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 }, - "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==", + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", "dev": true, "requires": { - "object-keys": "^1.0.12" + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } } }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", "dev": true, "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" }, "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } + "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-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "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.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", "dev": true, "requires": { - "kind-of": "^6.0.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" } }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "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": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "ansi-regex": "^5.0.0" } } } }, - "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 - }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true - }, - "detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", - "dev": true - }, - "detect-newline": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", - "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=", + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", "dev": true }, - "diff-sequences": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-24.9.0.tgz", - "integrity": "sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew==", + "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 }, - "dom-accessibility-api": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.3.0.tgz", - "integrity": "sha512-PzwHEmsRP3IGY4gv/Ug+rMeaTIyTJvadCb+ujYXYeIylbHJezIyNToe8KfEgHTCEYyC+/bUghYOGg8yMGlZ6vA==", + "collect-v8-coverage": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", "dev": true }, - "domexception": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", - "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", "dev": true, "requires": { - "webidl-conversions": "^4.0.2" + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" } }, - "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", - "dev": true - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "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": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" + "color-name": "1.1.3" } }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, - "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==", + "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, "requires": { - "once": "^1.4.0" + "delayed-stream": "~1.0.0" } }, - "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" - } + "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 }, - "es-abstract": { - "version": "1.17.4", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz", - "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==", - "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.1.5", - "is-regex": "^1.0.5", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimleft": "^2.1.1", - "string.prototype.trimright": "^2.1.1" - } + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true }, - "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, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true }, - "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=", + "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 }, - "escodegen": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.1.tgz", - "integrity": "sha512-Bmt7NcRySdIfNPfU2ZoXDrrXsG9ZjvDxcAlMfDUgRBjLOWTuIACXPBFJH7Z+cLb40JeQco5toikyc9t9P8E9SQ==", + "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==", "dev": true, "requires": { - "esprima": "^4.0.1", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" + "safe-buffer": "~5.1.1" } }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", "dev": true }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "core-js": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", + "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", "dev": true }, - "estree-walker": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", - "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", + "core-js-pure": { + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.6.4.tgz", + "integrity": "sha512-epIhRLkXdgv32xIUFaaAry2wdxZYBi6bgM7cB136dzzXXa+dFyRLTZeLUJxnd8ShrmyVXBub63n2NHo2JAt8Cw==", "dev": true }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "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 }, - "event-stream": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", - "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", + "cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", "dev": true, "requires": { - "duplexer": "~0.1.1", - "from": "~0", - "map-stream": "~0.1.0", - "pause-stream": "0.0.11", - "split": "0.3", - "stream-combiner": "~0.0.4", - "through": "~2.3.1" + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" } }, - "exec-sh": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz", - "integrity": "sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A==", + "cross-fetch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.0.4.tgz", + "integrity": "sha512-MSHgpjQqgbT/94D4CyADeNoYh52zMkCX4pcJvPP5WqPsLFMKjr2TCMg381ox5qI0ii2dPwaLx/00477knXqXVw==", + "dev": true, + "requires": { + "node-fetch": "2.6.0", + "whatwg-fetch": "3.0.0" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", "dev": true }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", "dev": true, "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" + "cssom": "~0.3.6" + }, + "dependencies": { + "cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + } } }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "csstype": { + "version": "2.6.10", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.10.tgz", + "integrity": "sha512-D34BqZU4cIlMCY93rZHbrq9pjTAQJ3U8S8rfBqjwHxkGPThWFjzZDQpgMJY0QViLxth6ZKYiwFBo14RdN44U/w==", "dev": true }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dashdash": { + "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" + } + }, + "data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", "dev": true, "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" }, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "tr46": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.0.2.tgz", + "integrity": "sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg==", "dev": true, "requires": { - "ms": "2.0.0" + "punycode": "^2.1.1" } }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } + "webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "dev": true }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "whatwg-url": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.1.0.tgz", + "integrity": "sha512-vEIkwNi9Hqt4TV9RdnaBPNt+E2Sgmo3gePebCRgZ1R7g6d23+53zCTnuB0amKI4AXq6VM8jj2DUAa0S1vjJxkw==", "dev": true, "requires": { - "is-extendable": "^0.1.0" + "lodash.sortby": "^4.7.0", + "tr46": "^2.0.2", + "webidl-conversions": "^5.0.0" } } } }, - "expand-template": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", - "dev": true - }, - "expect": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-24.9.0.tgz", - "integrity": "sha512-wvVAx8XIol3Z5m9zvZXiyZOQ+sRJqNTIm6sGjdWlaZIeupQGO3WbYI+15D/AmEwZywL6wtJkbAbJtzkOfBuR0Q==", + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "requires": { - "@jest/types": "^24.9.0", - "ansi-styles": "^3.2.0", - "jest-get-type": "^24.9.0", - "jest-matcher-utils": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-regex-util": "^24.9.0" + "ms": "2.0.0" } }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "decimal.js": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.0.tgz", + "integrity": "sha512-vDPw+rDgn3bZe1+F/pyEwb1oMG2XTlRVgAa6B4KccTEpYgF8w6eQllVbQcfIJnZyvzFtFpxnpGtx8dd7DJp/Rw==", + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "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==", "dev": true, "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } + "mimic-response": "^2.0.0" } }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "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 + }, + "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 + }, + "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 + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", "dev": true, "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" }, "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, "is-accessor-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", @@ -2197,781 +2654,535 @@ } } }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "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 }, - "fast-deep-equal": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", - "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", "dev": true }, - "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==" + "detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", + "dev": true }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "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 }, - "fb-watchman": { + "diff-sequences": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-24.9.0.tgz", + "integrity": "sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew==", + "dev": true + }, + "dom-accessibility-api": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.3.0.tgz", + "integrity": "sha512-PzwHEmsRP3IGY4gv/Ug+rMeaTIyTJvadCb+ujYXYeIylbHJezIyNToe8KfEgHTCEYyC+/bUghYOGg8yMGlZ6vA==", + "dev": true + }, + "domexception": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", - "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", "dev": true, "requires": { - "bser": "2.1.1" + "webidl-conversions": "^5.0.0" + }, + "dependencies": { + "webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "dev": true + } } }, - "fetch-mock": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/fetch-mock/-/fetch-mock-7.7.3.tgz", - "integrity": "sha512-I4OkK90JFQnjH8/n3HDtWxH/I6D1wrxoAM2ri+nb444jpuH3RTcgvXx2el+G20KO873W727/66T7QhOvFxNHPg==", + "duplexer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", + "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", + "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": { - "babel-polyfill": "^6.26.0", - "core-js": "^2.6.9", - "glob-to-regexp": "^0.4.0", - "lodash.isequal": "^4.5.0", - "path-to-regexp": "^2.2.1", - "whatwg-url": "^6.5.0" + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" } }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": 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==", + "dev": true }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "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, "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } + "once": "^1.4.0" } }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "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": { - "locate-path": "^3.0.0" + "is-arrayish": "^0.2.1" } }, - "follow-redirects": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", - "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", + "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=", + "dev": true + }, + "escodegen": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.1.tgz", + "integrity": "sha512-Bmt7NcRySdIfNPfU2ZoXDrrXsG9ZjvDxcAlMfDUgRBjLOWTuIACXPBFJH7Z+cLb40JeQco5toikyc9t9P8E9SQ==", "dev": true, "requires": { - "debug": "=3.1.0" + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" } }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "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 }, - "forever-agent": { + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "estree-walker": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", + "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", "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", - "mime-types": "^2.1.12" - } + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "event-stream": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", + "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", "dev": true, "requires": { - "map-cache": "^0.2.2" + "duplexer": "~0.1.1", + "from": "~0", + "map-stream": "~0.1.0", + "pause-stream": "0.0.11", + "split": "0.3", + "stream-combiner": "~0.0.4", + "through": "~2.3.1" } }, - "from": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", - "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=", + "exec-sh": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz", + "integrity": "sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A==", "dev": true }, - "fs-constants": { + "execa": { "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 + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", "dev": true }, - "fsevents": { - "version": "1.2.11", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.11.tgz", - "integrity": "sha512-+ux3lx6peh0BpvY0JebGyZoiR4D+oYzdPZMKJwkZ+sFkNJzpL7tXc/wehS49gUAxg3tmMHPHZkA8JU2rhhgDHw==", + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", "dev": true, - "optional": true, "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1", - "node-pre-gyp": "*" + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" }, "dependencies": { - "abbrev": { - "version": "1.1.1", - "resolved": false, - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": false, - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, - "optional": true - }, - "aproba": { - "version": "1.2.0", - "resolved": false, - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "resolved": false, - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", - "dev": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": false, - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true, - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": false, - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "optional": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.1.3", - "resolved": false, - "integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==", - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "resolved": false, - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true, - "optional": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": false, - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true, - "optional": true - }, - "console-control-strings": { - "version": "1.1.0", - "resolved": false, - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true, - "optional": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": false, - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true, - "optional": true - }, - "debug": { - "version": "3.2.6", - "resolved": false, - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "optional": true, - "requires": { - "ms": "^2.1.1" - } - }, - "deep-extend": { - "version": "0.6.0", - "resolved": false, - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "resolved": false, - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "resolved": false, - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", - "dev": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.7", - "resolved": false, - "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.6.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": false, - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "resolved": false, - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "dev": true, - "optional": true, - "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" - } - }, - "glob": { - "version": "7.1.6", - "resolved": false, - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "optional": 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-unicode": { - "version": "2.0.1", - "resolved": false, - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "dev": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": false, - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore-walk": { - "version": "3.0.3", - "resolved": false, - "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==", - "dev": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "resolved": false, - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": false, - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true, - "optional": true - }, - "ini": { - "version": "1.3.5", - "resolved": false, - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": false, - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "optional": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": false, - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": false, - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "optional": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": false, - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true, - "optional": true - }, - "minipass": { - "version": "2.9.0", - "resolved": false, - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.3.3", - "resolved": false, - "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.9.0" - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": false, - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "optional": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.1.2", - "resolved": false, - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true, - "optional": true - }, - "needle": { - "version": "2.4.0", - "resolved": false, - "integrity": "sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg==", - "dev": true, - "optional": true, - "requires": { - "debug": "^3.2.6", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.14.0", - "resolved": false, - "integrity": "sha512-+CvDC7ZttU/sSt9rFjix/P05iS43qHCOOGzcr3Ry99bXG7VX953+vFyEuph/tfqoYu8dttBkE86JSKBO2OzcxA==", + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, - "optional": true, "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.4.2" + "ms": "2.0.0" } }, - "nopt": { - "version": "4.0.1", - "resolved": false, - "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, - "optional": true, "requires": { - "abbrev": "1", - "osenv": "^0.1.4" + "is-descriptor": "^0.1.0" } }, - "npm-bundled": { - "version": "1.1.1", - "resolved": false, - "integrity": "sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==", + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, - "optional": true, "requires": { - "npm-normalize-package-bin": "^1.0.1" + "is-extendable": "^0.1.0" } - }, - "npm-normalize-package-bin": { - "version": "1.0.1", - "resolved": false, - "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==", - "dev": true, - "optional": true - }, - "npm-packlist": { - "version": "1.4.7", - "resolved": false, - "integrity": "sha512-vAj7dIkp5NhieaGZxBJB8fF4R0078rqsmhJcAfXZ6O7JJhjhPK96n5Ry1oZcfLXgfun0GWTZPOxaEyqv8GBykQ==", + } + } + }, + "expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "dev": true + }, + "expect": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz", + "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.0.0", + "jest-matcher-utils": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-regex-util": "^26.0.0" + }, + "dependencies": { + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", "dev": true, - "optional": true, "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" } }, - "npmlog": { - "version": "4.1.2", - "resolved": false, - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "@types/yargs": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz", + "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==", "dev": true, - "optional": true, "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" + "@types/yargs-parser": "*" } }, - "number-is-nan": { - "version": "1.0.1", - "resolved": false, - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true, - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": false, - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "resolved": false, - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", "dev": true, - "optional": true, "requires": { - "wrappy": "1" + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" } }, - "os-homedir": { - "version": "1.0.2", - "resolved": false, - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": false, - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "resolved": false, - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", "dev": true, - "optional": true, "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": false, - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true, - "optional": true - }, - "process-nextick-args": { + "color-convert": { "version": "2.0.1", - "resolved": false, - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.8", - "resolved": false, - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "optional": true, "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": false, - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true, - "optional": true - } + "color-name": "~1.1.4" } }, - "readable-stream": { - "version": "2.3.6", - "resolved": false, - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "optional": 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" - } + "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 }, - "rimraf": { - "version": "2.7.1", - "resolved": false, - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "jest-get-type": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "dev": true + } + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, - "optional": true, "requires": { - "glob": "^7.1.3" + "is-plain-object": "^2.0.4" } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": false, - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "optional": true - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": false, - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "resolved": false, - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true, - "optional": true - }, - "semver": { - "version": "5.7.1", - "resolved": false, - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": false, - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "resolved": false, - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "resolved": false, - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, - "optional": true, "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" + "is-descriptor": "^1.0.0" } }, - "string_decoder": { - "version": "1.1.1", - "resolved": false, - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, - "optional": true, "requires": { - "safe-buffer": "~5.1.0" + "is-extendable": "^0.1.0" } }, - "strip-ansi": { - "version": "3.0.1", - "resolved": false, - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, - "optional": true, "requires": { - "ansi-regex": "^2.0.0" + "kind-of": "^6.0.0" } }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": false, - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true, - "optional": true - }, - "tar": { - "version": "4.4.13", - "resolved": false, - "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, - "optional": 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" + "kind-of": "^6.0.0" } }, - "util-deprecate": { + "is-descriptor": { "version": "1.0.2", - "resolved": false, - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true, - "optional": true - }, - "wide-align": { - "version": "1.1.3", - "resolved": false, - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, - "optional": true, "requires": { - "string-width": "^1.0.2 || 2" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } - }, - "wrappy": { - "version": "1.0.2", - "resolved": false, - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true, - "optional": true - }, - "yallist": { - "version": "3.1.1", - "resolved": false, - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true, - "optional": true } } }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", + "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", + "dev": true + }, + "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==" + }, + "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 + }, + "fb-watchman": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", + "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "dev": true, + "requires": { + "bser": "2.1.1" + } + }, + "fetch-mock": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/fetch-mock/-/fetch-mock-7.7.3.tgz", + "integrity": "sha512-I4OkK90JFQnjH8/n3HDtWxH/I6D1wrxoAM2ri+nb444jpuH3RTcgvXx2el+G20KO873W727/66T7QhOvFxNHPg==", + "dev": true, + "requires": { + "babel-polyfill": "^6.26.0", + "core-js": "^2.6.9", + "glob-to-regexp": "^0.4.0", + "lodash.isequal": "^4.5.0", + "path-to-regexp": "^2.2.1", + "whatwg-url": "^6.5.0" + } + }, + "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, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "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" + } + }, + "follow-redirects": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", + "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", + "dev": true, + "requires": { + "debug": "=3.1.0" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "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", + "mime-types": "^2.1.12" + } + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "from": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", + "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=", + "dev": true + }, + "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 + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, "gauge": { "version": "2.7.4", "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", @@ -3000,6 +3211,12 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, + "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 + }, "get-stream": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", @@ -3078,9 +3295,9 @@ "dev": true }, "graceful-fs": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", - "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", "dev": true }, "graphql": { @@ -3101,7 +3318,8 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", - "dev": true + "dev": true, + "optional": true }, "gzip-size": { "version": "4.1.0", @@ -3119,62 +3337,254 @@ "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", "dev": true }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "dev": true, - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "dev": true, + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.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 + }, + "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 + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "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==", + "dev": true + }, + "html-encoding-sniffer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "dev": true, + "requires": { + "whatwg-encoding": "^1.0.5" + } + }, + "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 + }, + "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", + "sshpk": "^1.7.0" + } + }, + "human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true + }, + "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, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "iltorb": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/iltorb/-/iltorb-2.4.5.tgz", + "integrity": "sha512-EMCMl3LnnNSZJS5QrxyZmMTaAC4+TJkM5woD+xbpm9RB+mFYCr7C05GFE3TEGCsVQSVHmjX+3sf5AiwsylNInQ==", + "dev": true, + "requires": { + "detect-libc": "^1.0.3", + "nan": "^2.14.0", + "npmlog": "^4.1.2", + "prebuild-install": "^5.3.3", + "which-pm-runs": "^1.0.0" + } + }, + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + } + }, + "import-local": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", + "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", + "dev": true, + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "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==", + "dev": true + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + }, + "ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", + "dev": true + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "requires": { - "function-bind": "^1.1.1" + "kind-of": "^3.0.2" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } } }, - "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 - }, - "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==", + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, - "has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "is-buffer": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", + "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", "dev": true }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", "dev": true, "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" + "ci-info": "^2.0.0" } }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" + "kind-of": "^3.0.2" }, "dependencies": { "is-buffer": { @@ -3184,9 +3594,9 @@ "dev": true }, "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { "is-buffer": "^1.1.5" @@ -3194,990 +3604,1510 @@ } } }, - "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==", - "dev": true - }, - "html-encoding-sniffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", - "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, "requires": { - "whatwg-encoding": "^1.0.1" + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } } }, - "html-escaper": { + "is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", + "dev": true + }, + "is-docker": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.0.tgz", - "integrity": "sha512-a4u9BeERWGu/S8JiWEAQcdrg9v4QArtP9keViQjGMdff20fBdd8waotXaNmODqBe6uZ3Nafi7K/ho4gCQHV3Ig==", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.0.0.tgz", + "integrity": "sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ==", + "dev": true, + "optional": true + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", "dev": true }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "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, "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" + "number-is-nan": "^1.0.0" } }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true + }, + "is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", + "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==", + "dev": true + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, "requires": { - "safer-buffer": ">= 2.1.2 < 3" + "isobject": "^3.0.1" } }, - "iltorb": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/iltorb/-/iltorb-2.4.5.tgz", - "integrity": "sha512-EMCMl3LnnNSZJS5QrxyZmMTaAC4+TJkM5woD+xbpm9RB+mFYCr7C05GFE3TEGCsVQSVHmjX+3sf5AiwsylNInQ==", + "is-potential-custom-element-name": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz", + "integrity": "sha1-DFLlS8yjkbssSUsh6GJtczbG45c=", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "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==", + "dev": true + }, + "is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", "dev": true, + "optional": true, "requires": { - "detect-libc": "^1.0.3", - "nan": "^2.14.0", - "npmlog": "^4.1.2", - "prebuild-install": "^5.3.3", - "which-pm-runs": "^1.0.0" + "is-docker": "^2.0.0" } }, - "import-fresh": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "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 + }, + "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 + }, + "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, "requires": { - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.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 + } } }, - "import-local": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", - "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", + "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, + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + } + }, + "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, "requires": { - "pkg-dir": "^3.0.0", - "resolve-cwd": "^2.0.0" + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "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 + } } }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "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, "requires": { - "once": "^1.3.0", - "wrappy": "1" + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" } }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "iterall": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.3.0.tgz", + "integrity": "sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg==", "dev": true }, - "invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "dev": true, - "requires": { - "loose-envify": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "jest": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest/-/jest-26.0.1.tgz", + "integrity": "sha512-29Q54kn5Bm7ZGKIuH2JRmnKl85YRigp0o0asTc6Sb6l2ch1DCXIeZTLLFy9ultJvhkTqbswF5DEx4+RlkmCxWg==", "dev": true, "requires": { - "kind-of": "^3.0.2" + "@jest/core": "^26.0.1", + "import-local": "^3.0.2", + "jest-cli": "^26.0.1" }, "dependencies": { - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz", + "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "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 }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", "dev": true, "requires": { - "is-buffer": "^1.1.5" + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "camelcase": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.0.0.tgz", + "integrity": "sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==", + "dev": true + }, + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "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 + }, + "jest-cli": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.0.1.tgz", + "integrity": "sha512-pFLfSOBcbG9iOZWaMK4Een+tTxi/Wcm34geqZEqrst9cZDkTQ1LZ2CnBrTlHWuYAiTMFr0EQeK52ScyFU8wK+w==", + "dev": true, + "requires": { + "@jest/core": "^26.0.1", + "@jest/test-result": "^26.0.1", + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "import-local": "^3.0.2", + "is-ci": "^2.0.0", + "jest-config": "^26.0.1", + "jest-util": "^26.0.1", + "jest-validate": "^26.0.1", + "prompts": "^2.0.1", + "yargs": "^15.3.1" + } + }, + "jest-get-type": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "dev": true + }, + "jest-validate": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.0.1.tgz", + "integrity": "sha512-u0xRc+rbmov/VqXnX3DlkxD74rHI/CfS5xaV2VpeaVySjbb1JioNVOyly5b56q2l9ZKe7bVG5qWmjfctkQb0bA==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "camelcase": "^6.0.0", + "chalk": "^4.0.0", + "jest-get-type": "^26.0.0", + "leven": "^3.1.0", + "pretty-format": "^26.0.1" + } + }, + "pretty-format": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", + "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" } } } }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true - }, - "is-callable": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", - "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", - "dev": true - }, - "is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "jest-changed-files": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.0.1.tgz", + "integrity": "sha512-q8LP9Sint17HaE2LjxQXL+oYWW/WeeXMPE2+Op9X3mY8IEGFVc14xRxFjUuXUbcPAlDLhtWdIEt59GdQbn76Hw==", "dev": true, "requires": { - "ci-info": "^2.0.0" + "@jest/types": "^26.0.1", + "execa": "^4.0.0", + "throat": "^5.0.0" + }, + "dependencies": { + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz", + "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "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 + }, + "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" + } + }, + "execa": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.2.tgz", + "integrity": "sha512-QI2zLa6CjGWdiQsmSkZoGtDx2N+cQIGb3yNolGTdjSQzydzLgYYf8LRuagp7S7fPimjcrzUDSUFd/MgzELMi4Q==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + } + }, + "get-stream": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", + "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "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 + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "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" + } + } } }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "jest-config": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.0.1.tgz", + "integrity": "sha512-9mWKx2L1LFgOXlDsC4YSeavnblN6A4CPfXFiobq+YYLaBMymA/SczN7xYTSmLaEYHZOcB98UdoN4m5uNt6tztg==", "dev": true, "requires": { - "kind-of": "^3.0.2" + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^26.0.1", + "@jest/types": "^26.0.1", + "babel-jest": "^26.0.1", + "chalk": "^4.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "jest-environment-jsdom": "^26.0.1", + "jest-environment-node": "^26.0.1", + "jest-get-type": "^26.0.0", + "jest-jasmine2": "^26.0.1", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.0.1", + "jest-util": "^26.0.1", + "jest-validate": "^26.0.1", + "micromatch": "^4.0.2", + "pretty-format": "^26.0.1" }, "dependencies": { - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz", + "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "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.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "camelcase": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.0.0.tgz", + "integrity": "sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==", "dev": true }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", "dev": true, "requires": { - "is-buffer": "^1.1.5" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } - } - } - }, - "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==", - "dev": true - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + }, + "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 + }, + "jest-get-type": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", "dev": true + }, + "jest-validate": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.0.1.tgz", + "integrity": "sha512-u0xRc+rbmov/VqXnX3DlkxD74rHI/CfS5xaV2VpeaVySjbb1JioNVOyly5b56q2l9ZKe7bVG5qWmjfctkQb0bA==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "camelcase": "^6.0.0", + "chalk": "^4.0.0", + "jest-get-type": "^26.0.0", + "leven": "^3.1.0", + "pretty-format": "^26.0.1" + } + }, + "pretty-format": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", + "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } } } }, - "is-directory": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", - "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", - "dev": true - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "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, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "dev": true - }, - "is-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", - "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", - "dev": true - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "jest-diff": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-24.9.0.tgz", + "integrity": "sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ==", "dev": true, "requires": { - "kind-of": "^3.0.2" + "chalk": "^2.0.1", + "diff-sequences": "^24.9.0", + "jest-get-type": "^24.9.0", + "pretty-format": "^24.9.0" }, "dependencies": { - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "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" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "pretty-format": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz", + "integrity": "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==", "dev": true, "requires": { - "is-buffer": "^1.1.5" + "@jest/types": "^24.9.0", + "ansi-regex": "^4.0.0", + "ansi-styles": "^3.2.0", + "react-is": "^16.8.4" + } + }, + "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" } } } }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "is-regex": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", - "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "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==", + "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, "requires": { - "has-symbols": "^1.0.1" + "detect-newline": "^3.0.0" } }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "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==", - "dev": true - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "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=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "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 - }, - "istanbul-lib-coverage": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", - "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", - "dev": true - }, - "istanbul-lib-instrument": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", - "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", + "jest-each": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.0.1.tgz", + "integrity": "sha512-OTgJlwXCAR8NIWaXFL5DBbeS4QIYPuNASkzSwMCJO+ywo9BEa6TqkaSWsfR7VdbMLdgYJqSfQcIyjJCNwl5n4Q==", "dev": true, "requires": { - "@babel/generator": "^7.4.0", - "@babel/parser": "^7.4.3", - "@babel/template": "^7.4.0", - "@babel/traverse": "^7.4.3", - "@babel/types": "^7.4.0", - "istanbul-lib-coverage": "^2.0.5", - "semver": "^6.0.0" + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "jest-get-type": "^26.0.0", + "jest-util": "^26.0.1", + "pretty-format": "^26.0.1" }, "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz", + "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "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.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "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 + }, + "jest-get-type": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", "dev": true + }, + "pretty-format": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", + "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } } } }, - "istanbul-lib-report": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", - "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", + "jest-environment-jsdom": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.0.1.tgz", + "integrity": "sha512-u88NJa3aptz2Xix2pFhihRBAatwZHWwSiRLBDBQE1cdJvDjPvv7ZGA0NQBxWwDDn7D0g1uHqxM8aGgfA9Bx49g==", "dev": true, "requires": { - "istanbul-lib-coverage": "^2.0.5", - "make-dir": "^2.1.0", - "supports-color": "^6.1.0" + "@jest/environment": "^26.0.1", + "@jest/fake-timers": "^26.0.1", + "@jest/types": "^26.0.1", + "jest-mock": "^26.0.1", + "jest-util": "^26.0.1", + "jsdom": "^16.2.2" }, "dependencies": { - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } }, - "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==", + "@types/yargs": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz", + "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "@types/yargs-parser": "*" + } + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "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 } } }, - "istanbul-lib-source-maps": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", - "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", + "jest-environment-node": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.0.1.tgz", + "integrity": "sha512-4FRBWcSn5yVo0KtNav7+5NH5Z/tEgDLp7VRQVS5tCouWORxj+nI+1tOLutM07Zb2Qi7ja+HEDoOUkjBSWZg/IQ==", "dev": true, "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^2.0.5", - "make-dir": "^2.1.0", - "rimraf": "^2.6.3", - "source-map": "^0.6.1" + "@jest/environment": "^26.0.1", + "@jest/fake-timers": "^26.0.1", + "@jest/types": "^26.0.1", + "jest-mock": "^26.0.1", + "jest-util": "^26.0.1" }, "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", "dev": true, "requires": { - "ms": "^2.1.1" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.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 + "@types/yargs": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz", + "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "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": { - "glob": "^7.1.3" + "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 } } }, - "istanbul-reports": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.7.tgz", - "integrity": "sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg==", - "dev": true, - "requires": { - "html-escaper": "^2.0.0" - } - }, - "iterall": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.3.0.tgz", - "integrity": "sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg==", + "jest-get-type": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.9.0.tgz", + "integrity": "sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q==", "dev": true }, - "jest": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-24.9.0.tgz", - "integrity": "sha512-YvkBL1Zm7d2B1+h5fHEOdyjCG+sGMz4f8D86/0HiqJ6MB4MnDc8FgP5vdWsGnemOQro7lnYo8UakZ3+5A0jxGw==", + "jest-haste-map": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.0.1.tgz", + "integrity": "sha512-J9kBl/EdjmDsvyv7CiyKY5+DsTvVOScenprz/fGqfLg/pm1gdjbwwQ98nW0t+OIt+f+5nAVaElvn/6wP5KO7KA==", "dev": true, "requires": { - "import-local": "^2.0.0", - "jest-cli": "^24.9.0" + "@jest/types": "^26.0.1", + "@types/graceful-fs": "^4.1.2", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", + "graceful-fs": "^4.2.4", + "jest-serializer": "^26.0.0", + "jest-util": "^26.0.1", + "jest-worker": "^26.0.0", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7", + "which": "^2.0.2" }, "dependencies": { + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz", + "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "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 }, - "jest-cli": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-24.9.0.tgz", - "integrity": "sha512-+VLRKyitT3BWoMeSUIHRxV/2g8y9gw91Jh5z2UmXZzkZKpbC08CSehVxgHUwTpy+HwGcns/tqafQDJW7imYvGg==", + "jest-worker": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.0.0.tgz", + "integrity": "sha512-pPaYa2+JnwmiZjK9x7p9BoZht+47ecFCDFA/CJxspHzeDvQcfVBLWzCiWyo+EGrSiQMWZtCFo9iSvMZnAAo8vw==", "dev": true, "requires": { - "@jest/core": "^24.9.0", - "@jest/test-result": "^24.9.0", - "@jest/types": "^24.9.0", - "chalk": "^2.0.1", - "exit": "^0.1.2", - "import-local": "^2.0.0", - "is-ci": "^2.0.0", - "jest-config": "^24.9.0", - "jest-util": "^24.9.0", - "jest-validate": "^24.9.0", - "prompts": "^2.0.1", - "realpath-native": "^1.1.0", - "yargs": "^13.3.0" + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" } }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "isexe": "^2.0.0" } } } }, - "jest-changed-files": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-24.9.0.tgz", - "integrity": "sha512-6aTWpe2mHF0DhL28WjdkO8LyGjs3zItPET4bMSeXU6T3ub4FPMw+mcOcbdGXQOAfmLcxofD23/5Bl9Z4AkFwqg==", - "dev": true, - "requires": { - "@jest/types": "^24.9.0", - "execa": "^1.0.0", - "throat": "^4.0.0" - } - }, - "jest-config": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-24.9.0.tgz", - "integrity": "sha512-RATtQJtVYQrp7fvWg6f5y3pEFj9I+H8sWw4aKxnDZ96mob5i5SD6ZEGWgMLXQ4LE8UurrjbdlLWdUeo+28QpfQ==", + "jest-jasmine2": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.0.1.tgz", + "integrity": "sha512-ILaRyiWxiXOJ+RWTKupzQWwnPaeXPIoLS5uW41h18varJzd9/7I0QJGqg69fhTT1ev9JpSSo9QtalriUN0oqOg==", "dev": true, "requires": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^24.9.0", - "@jest/types": "^24.9.0", - "babel-jest": "^24.9.0", - "chalk": "^2.0.1", - "glob": "^7.1.1", - "jest-environment-jsdom": "^24.9.0", - "jest-environment-node": "^24.9.0", - "jest-get-type": "^24.9.0", - "jest-jasmine2": "^24.9.0", - "jest-regex-util": "^24.3.0", - "jest-resolve": "^24.9.0", - "jest-util": "^24.9.0", - "jest-validate": "^24.9.0", - "micromatch": "^3.1.10", - "pretty-format": "^24.9.0", - "realpath-native": "^1.1.0" + "@babel/traverse": "^7.1.0", + "@jest/environment": "^26.0.1", + "@jest/source-map": "^26.0.0", + "@jest/test-result": "^26.0.1", + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "co": "^4.6.0", + "expect": "^26.0.1", + "is-generator-fn": "^2.0.0", + "jest-each": "^26.0.1", + "jest-matcher-utils": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-runtime": "^26.0.1", + "jest-snapshot": "^26.0.1", + "jest-util": "^26.0.1", + "pretty-format": "^26.0.1", + "throat": "^5.0.0" }, "dependencies": { + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz", + "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "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.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "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": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "color-name": "~1.1.4" } }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "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 }, "pretty-format": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz", - "integrity": "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==", + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", + "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", "dev": true, "requires": { - "@jest/types": "^24.9.0", - "ansi-regex": "^4.0.0", - "ansi-styles": "^3.2.0", - "react-is": "^16.8.4" + "@jest/types": "^26.0.1", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" } + } + } + }, + "jest-junit": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/jest-junit/-/jest-junit-8.0.0.tgz", + "integrity": "sha512-cuD2XM2youMjrOxOu/7H2pLfsO8LfAG4D3WsBxd9fFyI9U0uPpmr/CORH64kbIyZ47X5x1Rbzb9ovUkAEvhEEA==", + "dev": true, + "requires": { + "jest-validate": "^24.0.0", + "mkdirp": "^0.5.1", + "strip-ansi": "^4.0.0", + "xml": "^1.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "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==", + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { - "has-flag": "^3.0.0" + "ansi-regex": "^3.0.0" } } } }, - "jest-diff": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-24.9.0.tgz", - "integrity": "sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ==", + "jest-leak-detector": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.0.1.tgz", + "integrity": "sha512-93FR8tJhaYIWrWsbmVN1pQ9ZNlbgRpfvrnw5LmgLRX0ckOJ8ut/I35CL7awi2ecq6Ca4lL59bEK9hr7nqoHWPA==", "dev": true, "requires": { - "chalk": "^2.0.1", - "diff-sequences": "^24.9.0", - "jest-get-type": "^24.9.0", - "pretty-format": "^24.9.0" + "jest-get-type": "^26.0.0", + "pretty-format": "^26.0.1" }, "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==", + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" } }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "@types/yargs": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz", + "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "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 }, - "pretty-format": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz", - "integrity": "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==", + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", "dev": true, "requires": { - "@jest/types": "^24.9.0", - "ansi-regex": "^4.0.0", - "ansi-styles": "^3.2.0", - "react-is": "^16.8.4" + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" } }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "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 + }, + "jest-get-type": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "dev": true + }, + "pretty-format": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", + "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" } } } }, - "jest-docblock": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-24.9.0.tgz", - "integrity": "sha512-F1DjdpDMJMA1cN6He0FNYNZlo3yYmOtRUnktrT9Q37njYzC5WEaDdmbynIgy0L/IvXvvgsG8OsqhLPXTpfmZAA==", - "dev": true, - "requires": { - "detect-newline": "^2.1.0" - } - }, - "jest-each": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-24.9.0.tgz", - "integrity": "sha512-ONi0R4BvW45cw8s2Lrx8YgbeXL1oCQ/wIDwmsM3CqM/nlblNCPmnC3IPQlMbRFZu3wKdQ2U8BqM6lh3LJ5Bsog==", + "jest-matcher-utils": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz", + "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==", "dev": true, "requires": { - "@jest/types": "^24.9.0", - "chalk": "^2.0.1", - "jest-get-type": "^24.9.0", - "jest-util": "^24.9.0", - "pretty-format": "^24.9.0" + "chalk": "^4.0.0", + "jest-diff": "^26.0.1", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.0.1" }, "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==", + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" } }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "@types/yargs": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz", + "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "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 }, - "pretty-format": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz", - "integrity": "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==", + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", "dev": true, "requires": { - "@jest/types": "^24.9.0", - "ansi-regex": "^4.0.0", - "ansi-styles": "^3.2.0", - "react-is": "^16.8.4" + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" } }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } - } - } - }, - "jest-environment-jsdom": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-24.9.0.tgz", - "integrity": "sha512-Zv9FV9NBRzLuALXjvRijO2351DRQeLYXtpD4xNvfoVFw21IOKNhZAEUKcbiEtjTkm2GsJ3boMVgkaR7rN8qetA==", - "dev": true, - "requires": { - "@jest/environment": "^24.9.0", - "@jest/fake-timers": "^24.9.0", - "@jest/types": "^24.9.0", - "jest-mock": "^24.9.0", - "jest-util": "^24.9.0", - "jsdom": "^11.5.1" - } - }, - "jest-environment-node": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-24.9.0.tgz", - "integrity": "sha512-6d4V2f4nxzIzwendo27Tr0aFm+IXWa0XEUnaH6nU0FMaozxovt+sfRvh4J47wL1OvF83I3SSTu0XK+i4Bqe7uA==", - "dev": true, - "requires": { - "@jest/environment": "^24.9.0", - "@jest/fake-timers": "^24.9.0", - "@jest/types": "^24.9.0", - "jest-mock": "^24.9.0", - "jest-util": "^24.9.0" - } - }, - "jest-get-type": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.9.0.tgz", - "integrity": "sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q==", - "dev": true - }, - "jest-haste-map": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.9.0.tgz", - "integrity": "sha512-kfVFmsuWui2Sj1Rp1AJ4D9HqJwE4uwTlS/vO+eRUaMmd54BFpli2XhMQnPC2k4cHFVbB2Q2C+jtI1AGLgEnCjQ==", - "dev": true, - "requires": { - "@jest/types": "^24.9.0", - "anymatch": "^2.0.0", - "fb-watchman": "^2.0.0", - "fsevents": "^1.2.7", - "graceful-fs": "^4.1.15", - "invariant": "^2.2.4", - "jest-serializer": "^24.9.0", - "jest-util": "^24.9.0", - "jest-worker": "^24.9.0", - "micromatch": "^3.1.10", - "sane": "^4.0.3", - "walker": "^1.0.7" - } - }, - "jest-jasmine2": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-24.9.0.tgz", - "integrity": "sha512-Cq7vkAgaYKp+PsX+2/JbTarrk0DmNhsEtqBXNwUHkdlbrTBLtMJINADf2mf5FkowNsq8evbPc07/qFO0AdKTzw==", - "dev": true, - "requires": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^24.9.0", - "@jest/test-result": "^24.9.0", - "@jest/types": "^24.9.0", - "chalk": "^2.0.1", - "co": "^4.6.0", - "expect": "^24.9.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^24.9.0", - "jest-matcher-utils": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-runtime": "^24.9.0", - "jest-snapshot": "^24.9.0", - "jest-util": "^24.9.0", - "pretty-format": "^24.9.0", - "throat": "^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==", + }, + "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": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "color-name": "~1.1.4" } }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "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 + }, + "diff-sequences": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", + "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", "dev": true }, - "pretty-format": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz", - "integrity": "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==", + "jest-diff": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", + "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", "dev": true, "requires": { - "@jest/types": "^24.9.0", - "ansi-regex": "^4.0.0", - "ansi-styles": "^3.2.0", - "react-is": "^16.8.4" + "chalk": "^4.0.0", + "diff-sequences": "^26.0.0", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.0.1" } }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "jest-get-type": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "dev": true + }, + "pretty-format": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", + "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "@jest/types": "^26.0.1", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" } } } }, - "jest-junit": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/jest-junit/-/jest-junit-8.0.0.tgz", - "integrity": "sha512-cuD2XM2youMjrOxOu/7H2pLfsO8LfAG4D3WsBxd9fFyI9U0uPpmr/CORH64kbIyZ47X5x1Rbzb9ovUkAEvhEEA==", + "jest-message-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", + "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", "dev": true, "requires": { - "jest-validate": "^24.0.0", - "mkdirp": "^0.5.1", - "strip-ansi": "^4.0.0", - "xml": "^1.0.1" + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/stack-utils": "^1.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" }, "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } }, - "strip-ansi": { + "@types/yargs": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz", + "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", "dev": true, "requires": { - "ansi-regex": "^3.0.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } - } - } - }, - "jest-leak-detector": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-24.9.0.tgz", - "integrity": "sha512-tYkFIDsiKTGwb2FG1w8hX9V0aUb2ot8zY/2nFg087dUageonw1zrLMP4W6zsRO59dPkTSKie+D4rhMuP9nRmrA==", - "dev": true, - "requires": { - "jest-get-type": "^24.9.0", - "pretty-format": "^24.9.0" - }, - "dependencies": { - "pretty-format": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz", - "integrity": "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==", + }, + "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": { - "@jest/types": "^24.9.0", - "ansi-regex": "^4.0.0", - "ansi-styles": "^3.2.0", - "react-is": "^16.8.4" + "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 } } }, - "jest-matcher-utils": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-24.9.0.tgz", - "integrity": "sha512-OZz2IXsu6eaiMAwe67c1T+5tUAtQyQx27/EMEkbFAGiw52tB9em+uGbzpcgYVpA8wl0hlxKPZxrly4CXU/GjHA==", + "jest-mock": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", + "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", "dev": true, "requires": { - "chalk": "^2.0.1", - "jest-diff": "^24.9.0", - "jest-get-type": "^24.9.0", - "pretty-format": "^24.9.0" + "@jest/types": "^26.0.1" }, "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==", + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" } }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "pretty-format": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz", - "integrity": "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==", + "@types/yargs": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz", + "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==", "dev": true, "requires": { - "@jest/types": "^24.9.0", - "ansi-regex": "^4.0.0", - "ansi-styles": "^3.2.0", - "react-is": "^16.8.4" + "@types/yargs-parser": "*" } }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" } - } - } - }, - "jest-message-util": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.9.0.tgz", - "integrity": "sha512-oCj8FiZ3U0hTP4aSui87P4L4jC37BtQwUMqk+zk/b11FR19BJDeZsZAvIHutWnmtw7r85UmR3CEWZ0HWU2mAlw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/test-result": "^24.9.0", - "@jest/types": "^24.9.0", - "@types/stack-utils": "^1.0.1", - "chalk": "^2.0.1", - "micromatch": "^3.1.10", - "slash": "^2.0.0", - "stack-utils": "^1.0.1" - }, - "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==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, - "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==", + "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": { - "has-flag": "^3.0.0" + "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 } } }, - "jest-mock": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.9.0.tgz", - "integrity": "sha512-3BEYN5WbSq9wd+SyLDES7AHnjH9A/ROBwmz7l2y+ol+NtSFO8DYiEBzoO1CeFc9a8DYy10EO4dDFVv/wN3zl1w==", - "dev": true, - "requires": { - "@jest/types": "^24.9.0" - } - }, "jest-pnp-resolver": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz", @@ -4185,301 +5115,600 @@ "dev": true }, "jest-regex-util": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-24.9.0.tgz", - "integrity": "sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA==", + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", "dev": true }, "jest-resolve": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.9.0.tgz", - "integrity": "sha512-TaLeLVL1l08YFZAt3zaPtjiVvyy4oSA6CRe+0AFPPVX3Q/VI0giIWWoAvoS5L96vj9Dqxj4fB5p2qrHCmTU/MQ==", + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", + "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", "dev": true, "requires": { - "@jest/types": "^24.9.0", - "browser-resolve": "^1.11.3", - "chalk": "^2.0.1", + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", "jest-pnp-resolver": "^1.2.1", - "realpath-native": "^1.1.0" + "jest-util": "^26.0.1", + "read-pkg-up": "^7.0.1", + "resolve": "^1.17.0", + "slash": "^3.0.0" }, "dependencies": { + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz", + "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "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 + }, + "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" + } + } + } + }, + "jest-resolve-dependencies": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.0.1.tgz", + "integrity": "sha512-9d5/RS/ft0vB/qy7jct/qAhzJsr6fRQJyGAFigK3XD4hf9kIbEH5gks4t4Z7kyMRhowU6HWm/o8ILqhaHdSqLw==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "jest-regex-util": "^26.0.0", + "jest-snapshot": "^26.0.1" + }, + "dependencies": { + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz", + "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "@types/yargs-parser": "*" } }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "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 } } }, - "jest-resolve-dependencies": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-24.9.0.tgz", - "integrity": "sha512-Fm7b6AlWnYhT0BXy4hXpactHIqER7erNgIsIozDXWl5dVm+k8XdGVe1oTg1JyaFnOxarMEbax3wyRJqGP2Pq+g==", - "dev": true, - "requires": { - "@jest/types": "^24.9.0", - "jest-regex-util": "^24.3.0", - "jest-snapshot": "^24.9.0" - } - }, "jest-runner": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-24.9.0.tgz", - "integrity": "sha512-KksJQyI3/0mhcfspnxxEOBueGrd5E4vV7ADQLT9ESaCzz02WnbdbKWIf5Mkaucoaj7obQckYPVX6JJhgUcoWWg==", + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.0.1.tgz", + "integrity": "sha512-CApm0g81b49Znm4cZekYQK67zY7kkB4umOlI2Dx5CwKAzdgw75EN+ozBHRvxBzwo1ZLYZ07TFxkaPm+1t4d8jA==", "dev": true, "requires": { - "@jest/console": "^24.7.1", - "@jest/environment": "^24.9.0", - "@jest/test-result": "^24.9.0", - "@jest/types": "^24.9.0", - "chalk": "^2.4.2", + "@jest/console": "^26.0.1", + "@jest/environment": "^26.0.1", + "@jest/test-result": "^26.0.1", + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", "exit": "^0.1.2", - "graceful-fs": "^4.1.15", - "jest-config": "^24.9.0", - "jest-docblock": "^24.3.0", - "jest-haste-map": "^24.9.0", - "jest-jasmine2": "^24.9.0", - "jest-leak-detector": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-resolve": "^24.9.0", - "jest-runtime": "^24.9.0", - "jest-util": "^24.9.0", - "jest-worker": "^24.6.0", + "graceful-fs": "^4.2.4", + "jest-config": "^26.0.1", + "jest-docblock": "^26.0.0", + "jest-haste-map": "^26.0.1", + "jest-jasmine2": "^26.0.1", + "jest-leak-detector": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-resolve": "^26.0.1", + "jest-runtime": "^26.0.1", + "jest-util": "^26.0.1", + "jest-worker": "^26.0.0", "source-map-support": "^0.5.6", - "throat": "^4.0.0" + "throat": "^5.0.0" }, "dependencies": { + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz", + "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "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 }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "jest-worker": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.0.0.tgz", + "integrity": "sha512-pPaYa2+JnwmiZjK9x7p9BoZht+47ecFCDFA/CJxspHzeDvQcfVBLWzCiWyo+EGrSiQMWZtCFo9iSvMZnAAo8vw==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" } } } }, "jest-runtime": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-24.9.0.tgz", - "integrity": "sha512-8oNqgnmF3v2J6PVRM2Jfuj8oX3syKmaynlDMMKQ4iyzbQzIG6th5ub/lM2bCMTmoTKM3ykcUYI2Pw9xwNtjMnw==", - "dev": true, - "requires": { - "@jest/console": "^24.7.1", - "@jest/environment": "^24.9.0", - "@jest/source-map": "^24.3.0", - "@jest/transform": "^24.9.0", - "@jest/types": "^24.9.0", - "@types/yargs": "^13.0.0", - "chalk": "^2.0.1", + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.0.1.tgz", + "integrity": "sha512-Ci2QhYFmANg5qaXWf78T2Pfo6GtmIBn2rRaLnklRyEucmPccmCKvS9JPljcmtVamsdMmkyNkVFb9pBTD6si9Lw==", + "dev": true, + "requires": { + "@jest/console": "^26.0.1", + "@jest/environment": "^26.0.1", + "@jest/fake-timers": "^26.0.1", + "@jest/globals": "^26.0.1", + "@jest/source-map": "^26.0.0", + "@jest/test-result": "^26.0.1", + "@jest/transform": "^26.0.1", + "@jest/types": "^26.0.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", "exit": "^0.1.2", "glob": "^7.1.3", - "graceful-fs": "^4.1.15", - "jest-config": "^24.9.0", - "jest-haste-map": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-mock": "^24.9.0", - "jest-regex-util": "^24.3.0", - "jest-resolve": "^24.9.0", - "jest-snapshot": "^24.9.0", - "jest-util": "^24.9.0", - "jest-validate": "^24.9.0", - "realpath-native": "^1.1.0", - "slash": "^2.0.0", - "strip-bom": "^3.0.0", - "yargs": "^13.3.0" + "graceful-fs": "^4.2.4", + "jest-config": "^26.0.1", + "jest-haste-map": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-mock": "^26.0.1", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.0.1", + "jest-snapshot": "^26.0.1", + "jest-util": "^26.0.1", + "jest-validate": "^26.0.1", + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^15.3.1" }, "dependencies": { + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/yargs": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz", + "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "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.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "camelcase": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.0.0.tgz", + "integrity": "sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==", + "dev": true + }, "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "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 }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "jest-get-type": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "dev": true + }, + "jest-validate": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.0.1.tgz", + "integrity": "sha512-u0xRc+rbmov/VqXnX3DlkxD74rHI/CfS5xaV2VpeaVySjbb1JioNVOyly5b56q2l9ZKe7bVG5qWmjfctkQb0bA==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "@jest/types": "^26.0.1", + "camelcase": "^6.0.0", + "chalk": "^4.0.0", + "jest-get-type": "^26.0.0", + "leven": "^3.1.0", + "pretty-format": "^26.0.1" + } + }, + "pretty-format": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", + "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" } } } }, "jest-serializer": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-24.9.0.tgz", - "integrity": "sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ==", - "dev": true + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.0.0.tgz", + "integrity": "sha512-sQGXLdEGWFAE4wIJ2ZaIDb+ikETlUirEOBsLXdoBbeLhTHkZUJwgk3+M8eyFizhM6le43PDCCKPA1hzkSDo4cQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.4" + } }, "jest-snapshot": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-24.9.0.tgz", - "integrity": "sha512-uI/rszGSs73xCM0l+up7O7a40o90cnrk429LOiK3aeTvfC0HHmldbd81/B7Ix81KSFe1lwkbl7GnBGG4UfuDew==", + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.0.1.tgz", + "integrity": "sha512-jxd+cF7+LL+a80qh6TAnTLUZHyQoWwEHSUFJjkw35u3Gx+BZUNuXhYvDqHXr62UQPnWo2P6fvQlLjsU93UKyxA==", "dev": true, "requires": { "@babel/types": "^7.0.0", - "@jest/types": "^24.9.0", - "chalk": "^2.0.1", - "expect": "^24.9.0", - "jest-diff": "^24.9.0", - "jest-get-type": "^24.9.0", - "jest-matcher-utils": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-resolve": "^24.9.0", - "mkdirp": "^0.5.1", + "@jest/types": "^26.0.1", + "@types/prettier": "^2.0.0", + "chalk": "^4.0.0", + "expect": "^26.0.1", + "graceful-fs": "^4.2.4", + "jest-diff": "^26.0.1", + "jest-get-type": "^26.0.0", + "jest-matcher-utils": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-resolve": "^26.0.1", + "make-dir": "^3.0.0", "natural-compare": "^1.4.0", - "pretty-format": "^24.9.0", - "semver": "^6.2.0" + "pretty-format": "^26.0.1", + "semver": "^7.3.2" }, "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==", + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" } }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "@types/yargs": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz", + "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "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 }, - "pretty-format": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz", - "integrity": "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==", + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", "dev": true, "requires": { - "@jest/types": "^24.9.0", - "ansi-regex": "^4.0.0", - "ansi-styles": "^3.2.0", - "react-is": "^16.8.4" + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" } }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "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 + }, + "diff-sequences": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", + "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "dev": true + }, + "jest-diff": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", + "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^26.0.0", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.0.1" + } + }, + "jest-get-type": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", "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==", + "pretty-format": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", + "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "@jest/types": "^26.0.1", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" } + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true } } }, "jest-util": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.9.0.tgz", - "integrity": "sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg==", + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", "dev": true, "requires": { - "@jest/console": "^24.9.0", - "@jest/fake-timers": "^24.9.0", - "@jest/source-map": "^24.9.0", - "@jest/test-result": "^24.9.0", - "@jest/types": "^24.9.0", - "callsites": "^3.0.0", - "chalk": "^2.0.1", - "graceful-fs": "^4.1.15", + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "mkdirp": "^0.5.1", - "slash": "^2.0.0", - "source-map": "^0.6.0" + "make-dir": "^3.0.0" }, "dependencies": { - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.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==", + "@types/yargs": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz", + "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "@types/yargs-parser": "*" } }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "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 } } }, @@ -4538,45 +5767,74 @@ } }, "jest-watcher": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-24.9.0.tgz", - "integrity": "sha512-+/fLOfKPXXYJDYlks62/4R4GoT+GU1tYZed99JSCOsmzkkF7727RqKrjNAxtfO4YpGv11wybgRvCjR73lK2GZw==", + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.0.1.tgz", + "integrity": "sha512-pdZPydsS8475f89kGswaNsN3rhP6lnC3/QDCppP7bg1L9JQz7oU9Mb/5xPETk1RHDCWeqmVC47M4K5RR7ejxFw==", "dev": true, "requires": { - "@jest/test-result": "^24.9.0", - "@jest/types": "^24.9.0", - "@types/yargs": "^13.0.0", - "ansi-escapes": "^3.0.0", - "chalk": "^2.0.1", - "jest-util": "^24.9.0", - "string-length": "^2.0.0" + "@jest/test-result": "^26.0.1", + "@jest/types": "^26.0.1", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "jest-util": "^26.0.1", + "string-length": "^4.0.1" }, "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==", + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" } }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "@types/yargs": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz", + "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "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 } } }, @@ -4630,37 +5888,73 @@ "dev": true }, "jsdom": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.12.0.tgz", - "integrity": "sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw==", - "dev": true, - "requires": { - "abab": "^2.0.0", - "acorn": "^5.5.3", - "acorn-globals": "^4.1.0", - "array-equal": "^1.0.0", - "cssom": ">= 0.3.2 < 0.4.0", - "cssstyle": "^1.0.0", - "data-urls": "^1.0.0", - "domexception": "^1.0.1", - "escodegen": "^1.9.1", - "html-encoding-sniffer": "^1.0.2", - "left-pad": "^1.3.0", - "nwsapi": "^2.0.7", - "parse5": "4.0.0", - "pn": "^1.1.0", - "request": "^2.87.0", - "request-promise-native": "^1.0.5", - "sax": "^1.2.4", - "symbol-tree": "^3.2.2", - "tough-cookie": "^2.3.4", - "w3c-hr-time": "^1.0.1", - "webidl-conversions": "^4.0.2", - "whatwg-encoding": "^1.0.3", - "whatwg-mimetype": "^2.1.0", - "whatwg-url": "^6.4.1", - "ws": "^5.2.0", + "version": "16.2.2", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.2.2.tgz", + "integrity": "sha512-pDFQbcYtKBHxRaP55zGXCJWgFHkDAYbKcsXEK/3Icu9nKYZkutUXfLBwbD+09XDutkYSHcgfQLZ0qvpAAm9mvg==", + "dev": true, + "requires": { + "abab": "^2.0.3", + "acorn": "^7.1.1", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.2.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.0", + "domexception": "^2.0.1", + "escodegen": "^1.14.1", + "html-encoding-sniffer": "^2.0.1", + "is-potential-custom-element-name": "^1.0.0", + "nwsapi": "^2.2.0", + "parse5": "5.1.1", + "request": "^2.88.2", + "request-promise-native": "^1.0.8", + "saxes": "^5.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^3.0.1", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.0.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0", + "ws": "^7.2.3", "xml-name-validator": "^3.0.0" + }, + "dependencies": { + "tr46": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.0.2.tgz", + "integrity": "sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg==", + "dev": true, + "requires": { + "punycode": "^2.1.1" + } + }, + "webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", + "dev": true + }, + "whatwg-url": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.1.0.tgz", + "integrity": "sha512-vEIkwNi9Hqt4TV9RdnaBPNt+E2Sgmo3gePebCRgZ1R7g6d23+53zCTnuB0amKI4AXq6VM8jj2DUAa0S1vjJxkw==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^2.0.2", + "webidl-conversions": "^5.0.0" + }, + "dependencies": { + "webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "dev": true + } + } + } } }, "jsesc": { @@ -4726,12 +6020,6 @@ "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", "dev": true }, - "left-pad": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz", - "integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==", - "dev": true - }, "leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -4748,26 +6036,19 @@ "type-check": "~0.3.2" } }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - } + "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 }, "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "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": "^3.0.0", - "path-exists": "^3.0.0" + "p-locate": "^4.1.0" } }, "lodash": { @@ -4814,19 +6095,18 @@ } }, "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "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": { - "pify": "^4.0.1", - "semver": "^5.6.0" + "semver": "^6.0.0" }, "dependencies": { - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true } } @@ -4874,41 +6154,36 @@ "dev": true }, "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", "dev": true, "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" + "braces": "^3.0.1", + "picomatch": "^2.0.5" } }, "mime-db": { - "version": "1.43.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz", - "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==", + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", "dev": true }, "mime-types": { - "version": "2.1.26", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz", - "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==", + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", "dev": true, "requires": { - "mime-db": "1.43.0" + "mime-db": "1.44.0" } }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, "mimic-response": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", @@ -5043,16 +6318,37 @@ "dev": true }, "node-notifier": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.3.tgz", - "integrity": "sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-7.0.1.tgz", + "integrity": "sha512-VkzhierE7DBmQEElhTGJIoiZa1oqRijOtgOlsXg32KrJRXsPy0NXFBqWGW/wTswnJlDCs5viRYaqWguqzsKcmg==", "dev": true, + "optional": true, "requires": { "growly": "^1.3.0", - "is-wsl": "^1.1.0", - "semver": "^5.5.0", + "is-wsl": "^2.1.1", + "semver": "^7.2.1", "shellwords": "^0.1.1", - "which": "^1.3.0" + "uuid": "^7.0.3", + "which": "^2.0.2" + }, + "dependencies": { + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true, + "optional": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "optional": true, + "requires": { + "isexe": "^2.0.0" + } + } } }, "noop-logger": { @@ -5074,13 +6370,10 @@ } }, "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true }, "npm-run-path": { "version": "2.0.2", @@ -5164,18 +6457,6 @@ } } }, - "object-inspect": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", - "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", - "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==", - "dev": true - }, "object-visit": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", @@ -5185,28 +6466,6 @@ "isobject": "^3.0.0" } }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, "object.pick": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", @@ -5225,6 +6484,15 @@ "wrappy": "1" } }, + "onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, "optimism": { "version": "0.12.1", "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.12.1.tgz", @@ -5248,13 +6516,10 @@ } }, "p-each-series": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-1.0.0.tgz", - "integrity": "sha1-kw89Et0fUOdDRFeiLNbwSsatf3E=", - "dev": true, - "requires": { - "p-reduce": "^1.0.0" - } + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.1.0.tgz", + "integrity": "sha512-ZuRs1miPT4HrjFa+9fRfOFXxGJfORgelKV9f9nNOWw2gl6gVsRaVDOQP0+MI0G0wGKns1Yacsu0GjOFbTK0JFQ==", + "dev": true }, "p-finally": { "version": "1.0.0", @@ -5263,29 +6528,23 @@ "dev": true }, "p-limit": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", - "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", + "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": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "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.0.0" + "p-limit": "^2.2.0" } }, - "p-reduce": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-1.0.0.tgz", - "integrity": "sha1-GMKw3ZNqRpClKfgjH1ig/bakffo=", - "dev": true - }, "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", @@ -5303,9 +6562,9 @@ } }, "parse5": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", - "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", "dev": true }, "pascalcase": { @@ -5315,9 +6574,9 @@ "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=", + "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": { @@ -5344,15 +6603,6 @@ "integrity": "sha512-G6zHoVqC6GGTQkZwF4lkuEyMbVOjoBKAEybQUypI1WTkqinCOrq2x6U2+phkJ1XsEMTy4LjtwPI7HW+NVrRR2w==", "dev": true }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - } - }, "pause-stream": { "version": "0.0.11", "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", @@ -5390,20 +6640,14 @@ } }, "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "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": "^3.0.0" + "find-up": "^4.0.0" } }, - "pn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", - "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==", - "dev": true - }, "posix-character-classes": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", @@ -5555,9 +6799,9 @@ "dev": true }, "prompts": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.3.1.tgz", - "integrity": "sha512-qIP2lQyCwYbdzcqHIUi2HAxiWixhoM9OdLCWf8txXsapC/X9YdsCoeyRIXE/GP+Q0J37Q7+XN/MFqbUa7IzXNA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.3.2.tgz", + "integrity": "sha512-Q06uKs2CkNYVID0VqwfAl9mipo99zkBv/n2JtWY89Yxa3ZabWSrs0e2KTudKVa3peLUvYXMefDqIleLPVUBZMA==", "dev": true, "requires": { "kleur": "^3.0.3", @@ -5591,9 +6835,9 @@ "dev": true }, "psl": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.7.0.tgz", - "integrity": "sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", "dev": true }, "pump": { @@ -5660,24 +6904,46 @@ "dev": true }, "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", "dev": true, "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + } + }, + "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": "4.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", - "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", + "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": "^3.0.0", - "read-pkg": "^3.0.0" + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" } }, "readable-stream": { @@ -5695,15 +6961,6 @@ "util-deprecate": "~1.0.1" } }, - "realpath-native": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-1.1.0.tgz", - "integrity": "sha512-wlgPA6cCIIg9gKz0fgAPjnzh4yR/LnXovwuo9hvyGvx3h8nX4+/iLZplfUWasXpqD8BdnGnP5njOFjkUwPzvjA==", - "dev": true, - "requires": { - "util.promisify": "^1.0.0" - } - }, "recast": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/recast/-/recast-0.19.1.tgz", @@ -5776,6 +7033,24 @@ "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==", + "dev": true, + "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==", + "dev": true + } } }, "request-promise-core": { @@ -5796,6 +7071,18 @@ "request-promise-core": "1.1.3", "stealthy-require": "^1.1.1", "tough-cookie": "^2.3.3" + }, + "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==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + } } }, "require-directory": { @@ -5820,12 +7107,20 @@ } }, "resolve-cwd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", - "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", "dev": true, "requires": { - "resolve-from": "^3.0.0" + "resolve-from": "^5.0.0" + }, + "dependencies": { + "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 + } } }, "resolve-from": { @@ -5985,13 +7280,146 @@ "micromatch": "^3.1.4", "minimist": "^1.1.1", "walker": "~1.0.5" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } } }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true + "saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "dev": true, + "requires": { + "xmlchars": "^2.2.0" + } }, "scheduler": { "version": "0.19.1", @@ -6063,7 +7491,8 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", - "dev": true + "dev": true, + "optional": true }, "signal-exit": { "version": "3.0.2", @@ -6089,15 +7518,15 @@ } }, "sisteransi": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.4.tgz", - "integrity": "sha512-/ekMoM4NJ59ivGSfKapeG+FWtrmWvA1p6FBZwXrqojw90vJu8lBmrTxCMuBCydKtkaUe2zt4PlxeTKpjwMbyig==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", "dev": true }, "slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, "snapdragon": { @@ -6264,9 +7693,9 @@ "dev": true }, "spdx-correct": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", - "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "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", @@ -6274,15 +7703,15 @@ } }, "spdx-exceptions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", - "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", + "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 }, "spdx-expression-parse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "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", @@ -6337,10 +7766,21 @@ } }, "stack-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz", - "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==", - "dev": true + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "dev": true, + "requires": { + "escape-string-regexp": "^2.0.0" + }, + "dependencies": { + "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 + } + } }, "static-extend": { "version": "0.1.2", @@ -6385,28 +7825,28 @@ "dev": true }, "string-length": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-2.0.0.tgz", - "integrity": "sha1-1A27aGo6zpYMHP/KVivyxF+DY+0=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.1.tgz", + "integrity": "sha512-PKyXUd0LK0ePjSOnWn34V2uD6acUWev9uy0Ft05k0E8xRW+SKcA0F7eMr7h5xlzfn+4O3N+55rduYyet3Jk+jw==", "dev": true, "requires": { - "astral-regex": "^1.0.0", - "strip-ansi": "^4.0.0" + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" }, "dependencies": { "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "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": "^3.0.0" + "ansi-regex": "^5.0.0" } } } @@ -6422,26 +7862,6 @@ "strip-ansi": "^3.0.0" } }, - "string.prototype.trimleft": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz", - "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "function-bind": "^1.1.1" - } - }, - "string.prototype.trimright": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz", - "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "function-bind": "^1.1.1" - } - }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -6469,9 +7889,9 @@ } }, "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-eof": { @@ -6480,6 +7900,12 @@ "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", "dev": true }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + }, "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", @@ -6495,6 +7921,16 @@ "has-flag": "^4.0.0" } }, + "supports-hyperlinks": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz", + "integrity": "sha512-zoE5/e+dnEijk6ASB6/qrK+oYdm2do1hjoLWrqUC/8WEIW1gbxFcKuBof7sW8ArN6e+AYvsE8HBGiVRWL/F5CA==", + "dev": true, + "requires": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + } + }, "symbol-observable": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", @@ -6544,6 +7980,16 @@ } } }, + "terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + } + }, "terser": { "version": "4.6.7", "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.7.tgz", @@ -6556,21 +8002,20 @@ } }, "test-exclude": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", - "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==", + "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": { - "glob": "^7.1.3", - "minimatch": "^3.0.4", - "read-pkg-up": "^4.0.0", - "require-main-filename": "^2.0.0" + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" } }, "throat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/throat/-/throat-4.1.0.tgz", - "integrity": "sha1-iQN8vJLFarGJJua6TLsgDhVnKmo=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", + "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", "dev": true }, "through": { @@ -6630,21 +8075,21 @@ } }, "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "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": "^3.0.0", - "repeat-string": "^1.6.1" + "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==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", + "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", "dev": true, "requires": { + "ip-regex": "^2.1.0", "psl": "^1.1.28", "punycode": "^2.1.1" } @@ -6821,6 +8266,27 @@ "prelude-ls": "~1.1.2" } }, + "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 + }, + "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 + }, + "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, + "requires": { + "is-typedarray": "^1.0.0" + } + }, "typescript": { "version": "3.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.3.tgz", @@ -6906,24 +8372,32 @@ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, - "util.promisify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", - "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", + "uuid": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz", + "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==", + "dev": true, + "optional": true + }, + "v8-to-istanbul": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-4.1.4.tgz", + "integrity": "sha512-Rw6vJHj1mbdK8edjR7+zuJrpDtKIgNdAvTSAcpYfgMIw+u2dPDntD3dgN4XQFLU2/fvFQdzj+EeSGfd/jnY5fQ==", "dev": true, "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.2", - "has-symbols": "^1.0.1", - "object.getownpropertydescriptors": "^2.1.0" + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "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 - }, "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", @@ -6954,6 +8428,15 @@ "browser-process-hrtime": "^1.0.0" } }, + "w3c-xmlserializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "dev": true, + "requires": { + "xml-name-validator": "^3.0.0" + } + }, "wait-for-expect": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/wait-for-expect/-/wait-for-expect-3.0.2.tgz", @@ -7044,40 +8527,71 @@ "dev": true }, "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "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": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" + "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.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "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": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "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": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "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": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" } }, "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "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": "^4.1.0" + "ansi-regex": "^5.0.0" } } } @@ -7089,24 +8603,22 @@ "dev": true }, "write-file-atomic": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.1.tgz", - "integrity": "sha512-TGHFeZEZMnv+gBFRfjAcxL5bPHrsGKtnb4qsFAws7/vlh+QfwAaySIw4AXP9ZskTTh5GWu3FLuJhsWVdiJPGvg==", + "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": { - "graceful-fs": "^4.1.11", "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" } }, "ws": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", - "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0" - } + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.0.tgz", + "integrity": "sha512-iFtXzngZVXPGgpTlP1rBqsUK82p9tKqsWRPg5L56egiljujJT3vGAYnHANvFxBieXrTFavhzhxW52jnaWV+w2w==", + "dev": true }, "xml": { "version": "1.0.1", @@ -7120,6 +8632,12 @@ "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", "dev": true }, + "xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, "y18n": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", @@ -7133,55 +8651,62 @@ "dev": true }, "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz", + "integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==", "dev": true, "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", + "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": "^3.0.0", + "string-width": "^4.2.0", "which-module": "^2.0.0", "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" + "yargs-parser": "^18.1.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 + }, "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=", + "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": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "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": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" } }, "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "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": "^4.1.0" + "ansi-regex": "^5.0.0" } } } }, "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "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", diff --git a/package.json b/package.json index bebedc22094..44f71e394e0 100644 --- a/package.json +++ b/package.json @@ -87,7 +87,7 @@ "cross-fetch": "3.0.4", "fetch-mock": "7.7.3", "graphql": "14.6.0", - "jest": "24.9.0", + "jest": "26.0.1", "jest-junit": "8.0.0", "lodash": "4.17.15", "prop-types": "15.7.2", From 75caa44265a540eaef844fdff41a3c4075842d97 Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Thu, 28 May 2020 17:39:35 -0400 Subject: [PATCH 20/56] Temporarily increase bundlesize limit to 24.1kB. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 44f71e394e0..f4bf2b6a8bc 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ { "name": "apollo-client", "path": "./dist/apollo-client.cjs.min.js", - "maxSize": "24 kB" + "maxSize": "24.1 kB" } ], "peerDependencies": { From 8ce2b4f7c8e631a46ed41cd205c34ede38f202c9 Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Thu, 28 May 2020 20:14:45 -0400 Subject: [PATCH 21/56] Fall back to cache-first after cache-and-network or network-only. (#6353) When someone chooses cache-and-network or network-only as their initial FetchPolicy, they almost certainly do not want future cache updates to trigger unconditional network requests, which is what repeatedly applying the cache-and-network or network-only policies would seem to require. Instead, when the cache reports an update after the initial network request, subsequent network requests should be triggered only if the cache result is incomplete. This behavior corresponds exactly to switching to a cache-first FetchPolicy, which we can achieve by modifying options.fetchPolicy in QueryManager#fetchQueryObservable for the next fetchQueryObservable call, using the same options object that the Reobserver always passes to fetchQueryObservable. Note: if these FetchPolicy transitions get much more complicated, we might consider using some sort of state machine to capture the transition rules. Should fix #6305, and a few other related issues (TBD). --- src/core/QueryManager.ts | 18 ++++ src/core/__tests__/ObservableQuery.ts | 127 ++++++++++++++++---------- 2 files changed, 98 insertions(+), 47 deletions(-) diff --git a/src/core/QueryManager.ts b/src/core/QueryManager.ts index 3af192b809f..60a34b7878d 100644 --- a/src/core/QueryManager.ts +++ b/src/core/QueryManager.ts @@ -836,6 +836,24 @@ export class QueryManager { context = {}, } = options; + if (fetchPolicy === "cache-and-network" || + fetchPolicy === "network-only") { + // When someone chooses cache-and-network or network-only as their + // initial FetchPolicy, they almost certainly do not want future cache + // updates to trigger unconditional network requests, which is what + // repeatedly applying the cache-and-network or network-only policies + // would seem to require. Instead, when the cache reports an update + // after the initial network request, subsequent network requests should + // be triggered only if the cache result is incomplete. This behavior + // corresponds exactly to switching to a cache-first FetchPolicy, so we + // modify options.fetchPolicy here for the next fetchQueryObservable + // call, using the same options object that the Reobserver always passes + // to fetchQueryObservable. Note: if these FetchPolicy transitions get + // much more complicated, we might consider using some sort of state + // machine to capture the transition rules. + options.fetchPolicy = "cache-first"; + } + const mightUseNetwork = fetchPolicy === "cache-first" || fetchPolicy === "cache-and-network" || diff --git a/src/core/__tests__/ObservableQuery.ts b/src/core/__tests__/ObservableQuery.ts index 941dacb657f..c48419558d4 100644 --- a/src/core/__tests__/ObservableQuery.ts +++ b/src/core/__tests__/ObservableQuery.ts @@ -933,15 +933,29 @@ describe('ObservableQuery', () => { }); describe('refetch', () => { - type TFQO = QueryManager["fetchQueryObservable"]; function mockFetchQuery(queryManager: QueryManager) { - const origFetchQuery: TFQO = (queryManager as any).fetchQueryObservable; - return (queryManager as any).fetchQueryObservable = jest.fn< - ReturnType, - Parameters + const fetchQueryObservable = queryManager.fetchQueryObservable; + const fetchQueryByPolicy: QueryManager["fetchQueryByPolicy"] = + (queryManager as any).fetchQueryByPolicy; + + const mock = (original: T) => jest.fn< + ReturnType, + Parameters >(function () { - return origFetchQuery.apply(queryManager, arguments); + return original.apply(queryManager, arguments); }); + + const mocks = { + fetchQueryObservable: mock(fetchQueryObservable), + fetchQueryByPolicy: mock(fetchQueryByPolicy), + }; + + Object.assign(queryManager, mocks); + + return mocks; } itAsync('calls fetchRequest with fetchPolicy `network-only` when using a non-networked fetch policy', (resolve, reject) => { @@ -964,15 +978,24 @@ describe('ObservableQuery', () => { fetchPolicy: 'cache-first', }); - const mocked = mockFetchQuery(queryManager); + const mocks = mockFetchQuery(queryManager); subscribeAndCount(reject, observable, handleCount => { if (handleCount === 1) { observable.refetch(differentVariables); } else if (handleCount === 2) { - expect(mocked.mock.calls[1][1].fetchPolicy).toEqual( - 'network-only', - ); + const fqbpCalls = mocks.fetchQueryByPolicy.mock.calls; + expect(fqbpCalls.length).toBe(2); + expect(fqbpCalls[1][1].fetchPolicy).toEqual('network-only'); + // Although the options.fetchPolicy we passed just now to + // fetchQueryByPolicy should have been network-only, + // observable.options.fetchPolicy should now be updated to + // cache-first, since network-only (and cache-and-network) fetch + // policies fall back to cache-first after the first request. + expect(observable.options.fetchPolicy).toBe('cache-first'); + const fqoCalls = mocks.fetchQueryObservable.mock.calls; + expect(fqoCalls.length).toBe(2); + expect(fqoCalls[1][1].fetchPolicy).toEqual('cache-first'); resolve(); } }); @@ -1000,15 +1023,24 @@ describe('ObservableQuery', () => { fetchPolicy: 'no-cache', }); - const mocked = mockFetchQuery(queryManager); + const mocks = mockFetchQuery(queryManager); subscribeAndCount(reject, observable, handleCount => { if (handleCount === 1) { observable.refetch(differentVariables); } else if (handleCount === 2) { - expect( - mocked.mock.calls[1][1].fetchPolicy, - ).toEqual('no-cache'); + const fqbpCalls = mocks.fetchQueryByPolicy.mock.calls; + expect(fqbpCalls.length).toBe(2); + expect(fqbpCalls[1][1].fetchPolicy).toBe('no-cache'); + + // Unlike network-only or cache-and-network, the no-cache + // FetchPolicy does not switch to cache-first after the first + // network request. + expect(observable.options.fetchPolicy).toBe('no-cache'); + const fqoCalls = mocks.fetchQueryObservable.mock.calls; + expect(fqoCalls.length).toBe(2); + expect(fqoCalls[1][1].fetchPolicy).toBe('no-cache'); + resolve(); } }); @@ -1159,34 +1191,35 @@ describe('ObservableQuery', () => { networkStatus: NetworkStatus.ready, }); + const oldLinkObs = linkObservable; // Make the next network request fail. linkObservable = errorObservable; observable.refetch().then( - result => { - expect(result).toEqual({ - data: { - counter: 3, - name: 'Ben', - }, - }); + () => { + reject(new Error('should have gotten an error')); }, + error => { expect(error).toBe(intentionalNetworkFailure); + + // Switch back from errorObservable. + linkObservable = oldLinkObs; + + observable.refetch().then(result => { + expect(result).toEqual({ + data: { + counter: 3, + name: 'Ben', + }, + loading: false, + networkStatus: NetworkStatus.ready, + }); + resolve(); + }, reject); }, ); - } else if (handleCount === 3) { - expect(result).toEqual({ - data: { - counter: 3, - name: 'Ben', - }, - loading: true, - networkStatus: NetworkStatus.refetch, - }); - - resolve(); - } else if (handleCount > 4) { + } else if (handleCount > 2) { reject(new Error('should not get here')); } }, @@ -1545,38 +1578,38 @@ describe('ObservableQuery', () => { }, ); - queryManager.query({ query, variables }).then(() => { + queryManager.query({ query, variables }).then(result => { + expect(result).toEqual({ + data: dataOne, + loading: false, + networkStatus: NetworkStatus.ready, + }); + const observable = queryManager.watchQuery({ query, variables, fetchPolicy: 'network-only', }); - expect(stripSymbols(observable.getCurrentResult())).toEqual({ - data: undefined, + + expect(observable.getCurrentResult()).toEqual({ + data: void 0, loading: true, networkStatus: 1, partial: false, }); subscribeAndCount(reject, observable, (handleCount, subResult) => { - const { - data, - loading, - networkStatus, - } = observable.getCurrentResult(); - if (handleCount === 1) { expect(subResult).toEqual({ - data, - loading, - networkStatus, + loading: true, + networkStatus: NetworkStatus.loading, partial: false, }); } else if (handleCount === 2) { - expect(stripSymbols(subResult)).toEqual({ + expect(subResult).toEqual({ data: dataTwo, loading: false, - networkStatus: 7, + networkStatus: NetworkStatus.ready, }); resolve(); } From f820f8046780e75c1f8568a96d1b7c7ef556b392 Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Thu, 28 May 2020 20:26:05 -0400 Subject: [PATCH 22/56] Bump @apollo/client npm version to 3.0.0-beta.52. --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index e5cf8db5f7e..9153d0c6985 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@apollo/client", - "version": "3.0.0-beta.51", + "version": "3.0.0-beta.52", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index f4bf2b6a8bc..3bca664b930 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@apollo/client", - "version": "3.0.0-beta.51", + "version": "3.0.0-beta.52", "description": "A fully-featured caching GraphQL client.", "private": true, "keywords": [ From 597dc878e6e20f0a5bfc4a545f6ef3a922bed632 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Witek?= Date: Fri, 29 May 2020 16:44:11 +0200 Subject: [PATCH 23/56] Document .modifiers renaming for local-state (#6356) --- docs/source/data/local-state.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/source/data/local-state.mdx b/docs/source/data/local-state.mdx index 3ec0b492a8f..d5569d060c9 100644 --- a/docs/source/data/local-state.mdx +++ b/docs/source/data/local-state.mdx @@ -181,7 +181,7 @@ const client = new ApolloClient({ __typename: 'TodoItem', id: variables.id, }), - modifiers: { + fields: { completed: value => !value, }, }); @@ -1095,7 +1095,7 @@ const client = new ApolloClient({ }; ``` -The `cache.writeQuery` and `cache.writeFragment` methods should cover most of your needs; however, there are some cases where the data you're writing to the cache depends on the data that's already there. In that scenario, you can either use a combination of `cache.read{Query,Fragment}` followed by `cache.write{Query,Fragment}`, or use `cache.modify({ id, modifiers })` to update specific fields within the entity object identified by `id`. +The `cache.writeQuery` and `cache.writeFragment` methods should cover most of your needs; however, there are some cases where the data you're writing to the cache depends on the data that's already there. In that scenario, you can either use a combination of `cache.read{Query,Fragment}` followed by `cache.write{Query,Fragment}`, or use `cache.modify({ id, fields })` to update specific fields within the entity object identified by `id`. ### writeQuery and readQuery From 4b1fe835660b8c3009e3ada3f94205f3a7bc9d21 Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Fri, 29 May 2020 11:39:43 -0400 Subject: [PATCH 24/56] Avoid empty string as possible toReference return type. https://github.com/apollographql/apollo-client/pull/6350#issuecomment-636042196 --- src/cache/inmemory/entityStore.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/cache/inmemory/entityStore.ts b/src/cache/inmemory/entityStore.ts index 5c8f0b06403..1c9909e51f0 100644 --- a/src/cache/inmemory/entityStore.ts +++ b/src/cache/inmemory/entityStore.ts @@ -344,13 +344,15 @@ export abstract class EntityStore implements NormalizedCache { public toReference = ( object: StoreObject, mergeIntoStore?: boolean, - ) => { + ): Reference | undefined => { const [id] = this.policies.identify(object); - const ref = id && makeReference(id); - if (ref && mergeIntoStore) { - this.merge(id!, object); + if (id) { + const ref = makeReference(id); + if (mergeIntoStore) { + this.merge(id, object); + } + return ref; } - return ref; } } From a7232bf7d93085cd820f6db1a7688393aca68581 Mon Sep 17 00:00:00 2001 From: hwillson Date: Fri, 29 May 2020 15:43:21 -0400 Subject: [PATCH 25/56] Replace requireReactLazily with CJS bundle manipulation PR #5577 introduced a new way of lazily loading React to help prevent modern bundlers from requiring React when used with `@apollo/client/core` (in other words, without any of Apollo Client's React components). While this approach works well for applications that aren't using React, it introduces problems for bundlers and applications that are using React (as outlined in #6035 and #6352). There are several different ways we can address this, and we might do something more substantial in the future, but for now this commit manipulates Apollo Client's core CJS bundle at build time, to make the React require optional. Fixes #6035. Fixes #6352. --- config/rollup.config.js | 31 ++++ .../rollup-ac3-no-react/package-lock.json | 16 +- .../rollup-ac3/package-lock.json | 16 +- .../rollup-ac3-no-react/package-lock.json | 16 +- .../tree-shaking/rollup-ac3/package-lock.json | 147 +++++++++++------- .../tree-shaking/rollup-ac3/package.json | 4 +- src/react/context/ApolloConsumer.tsx | 3 +- src/react/context/ApolloContext.ts | 4 +- src/react/context/ApolloProvider.tsx | 3 +- .../context/__tests__/ApolloConsumer.test.tsx | 4 +- .../context/__tests__/ApolloProvider.test.tsx | 5 +- .../hooks/__tests__/useApolloClient.test.tsx | 4 +- .../hooks/__tests__/useLazyQuery.test.tsx | 4 +- .../hooks/__tests__/useMutation.test.tsx | 5 +- src/react/hooks/__tests__/useQuery.test.tsx | 5 +- .../hooks/__tests__/useSubscription.test.tsx | 4 +- src/react/hooks/useApolloClient.ts | 3 +- src/react/hooks/useMutation.ts | 3 +- src/react/hooks/useSubscription.ts | 4 +- src/react/hooks/utils/useBaseQuery.ts | 4 +- src/react/hooks/utils/useDeepMemo.ts | 5 +- src/react/react.ts | 9 -- 22 files changed, 166 insertions(+), 133 deletions(-) delete mode 100644 src/react/react.ts diff --git a/config/rollup.config.js b/config/rollup.config.js index 5c88d7a551b..429b891d76c 100644 --- a/config/rollup.config.js +++ b/config/rollup.config.js @@ -63,6 +63,37 @@ function prepareCJS(input, output) { }, plugins: [ nodeResolve(), + // When generating the `dist/core/core.cjs.js` entry point (in + // `config/prepareDist.js`), we filter and re-export the exports we + // need from the main Apollo Client CJS bundle (to exclude React related + // code). This means that consumers of `core.cjs.js` attempt to load the + // full AC CJS bundle first (before filtering exports), which then means + // the React require in the AC CJS bundle is attempted and not found + // (since people using `core.cjs.js` want to use Apollo Client without + // React). To address this, we make React an optional require in the CJS + // bundle. + (() => { + const cjsBundle = output.replace(`${distDir}/`, ''); + return { + generateBundle(_option, bundle) { + const { code } = bundle[cjsBundle]; + const regex = /var React = require\('react'\);/; + const matches = code.match(regex); + if (matches && matches.length === 1) { + bundle[cjsBundle].code = + code.replace( + regex, + "try { var React = require('react'); } catch (error) {}" + ); + } else { + throw new Error( + 'The CJS bundle could not prepared as a single React ' + + 'require could not be found.' + ); + } + } + } + })() ], }; } diff --git a/examples/bundling/no-tree-shaking/rollup-ac3-no-react/package-lock.json b/examples/bundling/no-tree-shaking/rollup-ac3-no-react/package-lock.json index 9a08b660d75..057a95dfbda 100644 --- a/examples/bundling/no-tree-shaking/rollup-ac3-no-react/package-lock.json +++ b/examples/bundling/no-tree-shaking/rollup-ac3-no-react/package-lock.json @@ -11,7 +11,7 @@ "@wry/equality": "^0.1.9", "fast-json-stable-stringify": "^2.0.0", "graphql-tag": "^2.10.2", - "optimism": "^0.11.5", + "optimism": "^0.12.1", "symbol-observable": "^1.2.0", "ts-invariant": "^0.4.4", "tslib": "^1.10.0", @@ -1172,9 +1172,9 @@ "integrity": "sha512-te5lMAWii1uEJ4FwLjzdlbw3+n0FZNOvFXHxQDKeT0dilh7HOzdMzV2TrJVUzq8ep7J4Na8OUYPRLSQkJHAlrg==" }, "@wry/context": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@wry/context/-/context-0.5.0.tgz", - "integrity": "sha512-yW5XFrWbRvv2/f86+g0YAfko7671SQg7Epn8lYjux4MZmIvtPvK2ts+vG1QAPu2w6GuBioEJknRa7K2LFj2kQw==", + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@wry/context/-/context-0.5.2.tgz", + "integrity": "sha512-B/JLuRZ/vbEKHRUiGj6xiMojST1kHhu4WcreLfNN7q9DqQFrb97cWgf/kiYsPSUCAMVN0HzfFc8XjJdzgZzfjw==", "requires": { "tslib": "^1.9.3" } @@ -5827,11 +5827,11 @@ } }, "optimism": { - "version": "0.11.5", - "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.11.5.tgz", - "integrity": "sha512-twCHmBb64DYzEZ8A3O+TLCuF/RmZPBhXPQYv4agoiALRLlW9SidMzd7lwUP9mL0jOZhzhnBmb8ajqA00ECo/7g==", + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.12.1.tgz", + "integrity": "sha512-t8I7HM1dw0SECitBYAqFOVHoBAHEQBTeKjIL9y9ImHzAVkdyPK4ifTgM4VJRDtTUY4r/u5Eqxs4XcGPHaoPkeQ==", "requires": { - "@wry/context": "^0.5.0" + "@wry/context": "^0.5.2" } }, "optimist": { diff --git a/examples/bundling/no-tree-shaking/rollup-ac3/package-lock.json b/examples/bundling/no-tree-shaking/rollup-ac3/package-lock.json index b1f7526df6a..8ee6c17dabf 100644 --- a/examples/bundling/no-tree-shaking/rollup-ac3/package-lock.json +++ b/examples/bundling/no-tree-shaking/rollup-ac3/package-lock.json @@ -11,7 +11,7 @@ "@wry/equality": "^0.1.9", "fast-json-stable-stringify": "^2.0.0", "graphql-tag": "^2.10.2", - "optimism": "^0.11.5", + "optimism": "^0.12.1", "symbol-observable": "^1.2.0", "ts-invariant": "^0.4.4", "tslib": "^1.10.0", @@ -744,9 +744,9 @@ "integrity": "sha512-te5lMAWii1uEJ4FwLjzdlbw3+n0FZNOvFXHxQDKeT0dilh7HOzdMzV2TrJVUzq8ep7J4Na8OUYPRLSQkJHAlrg==" }, "@wry/context": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@wry/context/-/context-0.5.0.tgz", - "integrity": "sha512-yW5XFrWbRvv2/f86+g0YAfko7671SQg7Epn8lYjux4MZmIvtPvK2ts+vG1QAPu2w6GuBioEJknRa7K2LFj2kQw==", + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@wry/context/-/context-0.5.2.tgz", + "integrity": "sha512-B/JLuRZ/vbEKHRUiGj6xiMojST1kHhu4WcreLfNN7q9DqQFrb97cWgf/kiYsPSUCAMVN0HzfFc8XjJdzgZzfjw==", "requires": { "tslib": "^1.9.3" } @@ -4765,11 +4765,11 @@ } }, "optimism": { - "version": "0.11.5", - "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.11.5.tgz", - "integrity": "sha512-twCHmBb64DYzEZ8A3O+TLCuF/RmZPBhXPQYv4agoiALRLlW9SidMzd7lwUP9mL0jOZhzhnBmb8ajqA00ECo/7g==", + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.12.1.tgz", + "integrity": "sha512-t8I7HM1dw0SECitBYAqFOVHoBAHEQBTeKjIL9y9ImHzAVkdyPK4ifTgM4VJRDtTUY4r/u5Eqxs4XcGPHaoPkeQ==", "requires": { - "@wry/context": "^0.5.0" + "@wry/context": "^0.5.2" } }, "optionator": { diff --git a/examples/bundling/tree-shaking/rollup-ac3-no-react/package-lock.json b/examples/bundling/tree-shaking/rollup-ac3-no-react/package-lock.json index cbb615a0ba3..2bcb85fad08 100644 --- a/examples/bundling/tree-shaking/rollup-ac3-no-react/package-lock.json +++ b/examples/bundling/tree-shaking/rollup-ac3-no-react/package-lock.json @@ -11,7 +11,7 @@ "@wry/equality": "^0.1.9", "fast-json-stable-stringify": "^2.0.0", "graphql-tag": "^2.10.2", - "optimism": "^0.11.5", + "optimism": "^0.12.1", "symbol-observable": "^1.2.0", "ts-invariant": "^0.4.4", "tslib": "^1.10.0", @@ -24,9 +24,9 @@ "integrity": "sha512-te5lMAWii1uEJ4FwLjzdlbw3+n0FZNOvFXHxQDKeT0dilh7HOzdMzV2TrJVUzq8ep7J4Na8OUYPRLSQkJHAlrg==" }, "@wry/context": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@wry/context/-/context-0.5.0.tgz", - "integrity": "sha512-yW5XFrWbRvv2/f86+g0YAfko7671SQg7Epn8lYjux4MZmIvtPvK2ts+vG1QAPu2w6GuBioEJknRa7K2LFj2kQw==", + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@wry/context/-/context-0.5.2.tgz", + "integrity": "sha512-B/JLuRZ/vbEKHRUiGj6xiMojST1kHhu4WcreLfNN7q9DqQFrb97cWgf/kiYsPSUCAMVN0HzfFc8XjJdzgZzfjw==", "requires": { "tslib": "^1.9.3" } @@ -50,11 +50,11 @@ "integrity": "sha512-4FOv3ZKfA4WdOKJeHdz6B3F/vxBLSgmBcGeAFPf4n1F64ltJUvOOerNj0rsJxONQGdhUMynQIvd6LzB+1J5oKA==" }, "optimism": { - "version": "0.11.5", - "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.11.5.tgz", - "integrity": "sha512-twCHmBb64DYzEZ8A3O+TLCuF/RmZPBhXPQYv4agoiALRLlW9SidMzd7lwUP9mL0jOZhzhnBmb8ajqA00ECo/7g==", + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.12.1.tgz", + "integrity": "sha512-t8I7HM1dw0SECitBYAqFOVHoBAHEQBTeKjIL9y9ImHzAVkdyPK4ifTgM4VJRDtTUY4r/u5Eqxs4XcGPHaoPkeQ==", "requires": { - "@wry/context": "^0.5.0" + "@wry/context": "^0.5.2" } }, "symbol-observable": { diff --git a/examples/bundling/tree-shaking/rollup-ac3/package-lock.json b/examples/bundling/tree-shaking/rollup-ac3/package-lock.json index 7ba5b57222e..0a3a6bfc57d 100644 --- a/examples/bundling/tree-shaking/rollup-ac3/package-lock.json +++ b/examples/bundling/tree-shaking/rollup-ac3/package-lock.json @@ -11,7 +11,7 @@ "@wry/equality": "^0.1.9", "fast-json-stable-stringify": "^2.0.0", "graphql-tag": "^2.10.2", - "optimism": "^0.11.5", + "optimism": "^0.12.1", "symbol-observable": "^1.2.0", "ts-invariant": "^0.4.4", "tslib": "^1.10.0", @@ -24,9 +24,9 @@ "integrity": "sha512-te5lMAWii1uEJ4FwLjzdlbw3+n0FZNOvFXHxQDKeT0dilh7HOzdMzV2TrJVUzq8ep7J4Na8OUYPRLSQkJHAlrg==" }, "@wry/context": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@wry/context/-/context-0.5.0.tgz", - "integrity": "sha512-yW5XFrWbRvv2/f86+g0YAfko7671SQg7Epn8lYjux4MZmIvtPvK2ts+vG1QAPu2w6GuBioEJknRa7K2LFj2kQw==", + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@wry/context/-/context-0.5.2.tgz", + "integrity": "sha512-B/JLuRZ/vbEKHRUiGj6xiMojST1kHhu4WcreLfNN7q9DqQFrb97cWgf/kiYsPSUCAMVN0HzfFc8XjJdzgZzfjw==", "requires": { "tslib": "^1.9.3" } @@ -50,11 +50,11 @@ "integrity": "sha512-4FOv3ZKfA4WdOKJeHdz6B3F/vxBLSgmBcGeAFPf4n1F64ltJUvOOerNj0rsJxONQGdhUMynQIvd6LzB+1J5oKA==" }, "optimism": { - "version": "0.11.5", - "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.11.5.tgz", - "integrity": "sha512-twCHmBb64DYzEZ8A3O+TLCuF/RmZPBhXPQYv4agoiALRLlW9SidMzd7lwUP9mL0jOZhzhnBmb8ajqA00ECo/7g==", + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.12.1.tgz", + "integrity": "sha512-t8I7HM1dw0SECitBYAqFOVHoBAHEQBTeKjIL9y9ImHzAVkdyPK4ifTgM4VJRDtTUY4r/u5Eqxs4XcGPHaoPkeQ==", "requires": { - "@wry/context": "^0.5.0" + "@wry/context": "^0.5.2" } }, "symbol-observable": { @@ -908,7 +908,8 @@ "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 }, "json-schema-traverse": { "version": "0.4.1", @@ -969,14 +970,6 @@ "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", "dev": true }, - "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==", - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, "lru-cache": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", @@ -1062,11 +1055,6 @@ "path-key": "^2.0.0" } }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, "on-headers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", @@ -1176,16 +1164,6 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "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==", - "requires": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.8.1" - } - }, "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", @@ -1223,31 +1201,103 @@ } }, "react": { - "version": "16.13.0", - "resolved": "https://registry.npmjs.org/react/-/react-16.13.0.tgz", - "integrity": "sha512-TSavZz2iSLkq5/oiE7gnFzmURKZMltmi193rm5HEoUDAXpzT9Kzw6oNZnGoai/4+fUnm7FqS5dwgUL34TujcWQ==", + "version": "file:../../../../node_modules/react", + "integrity": "sha512-+7LQnFBwkiw+BobzOF6N//BdoNw0ouwmSJTEm9cglOOmsg/TMiFHZLe2sEoN5M7LgJTj9oHH0gxklfnQe66S1w==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", "prop-types": "^15.6.2" + }, + "dependencies": { + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "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==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + }, + "react-is": { + "version": "16.13.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.0.tgz", + "integrity": "sha512-GFMtL0vHkiBv9HluwNZTggSn/sCyEt9n02aM0dSAjGGyqyNlAyftYm4phPxdvCigG15JreC5biwxCgTAJZ7yAA==" + } } }, "react-dom": { - "version": "16.13.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.13.0.tgz", - "integrity": "sha512-y09d2c4cG220DzdlFkPTnVvGTszVvNpC73v+AaLGLHbkpy3SSgvYq8x0rNwPJ/Rk/CicTNgk0hbHNw1gMEZAXg==", + "version": "file:../../../../node_modules/react-dom", + "integrity": "sha512-YFT2rxO9hM70ewk9jq0y6sQk8cL02xm4+IzYBz75CQGlClQQ1Bxq0nhHF6OtSbit+AIahujJgb/CPRibFkMNJQ==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", "prop-types": "^15.6.2", - "scheduler": "^0.19.0" + "scheduler": "^0.15.0" + }, + "dependencies": { + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "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==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + }, + "react-is": { + "version": "16.13.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.0.tgz", + "integrity": "sha512-GFMtL0vHkiBv9HluwNZTggSn/sCyEt9n02aM0dSAjGGyqyNlAyftYm4phPxdvCigG15JreC5biwxCgTAJZ7yAA==" + }, + "scheduler": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.15.0.tgz", + "integrity": "sha512-xAefmSfN6jqAa7Kuq7LIJY0bwAPG3xlCj0HMEBQk1lxYiDKZscY2xJ5U/61ZTrYbmNQbXa+gc7czPkVo11tnCg==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + } } }, - "react-is": { - "version": "16.13.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.0.tgz", - "integrity": "sha512-GFMtL0vHkiBv9HluwNZTggSn/sCyEt9n02aM0dSAjGGyqyNlAyftYm4phPxdvCigG15JreC5biwxCgTAJZ7yAA==" - }, "readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", @@ -1473,15 +1523,6 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, - "scheduler": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.0.tgz", - "integrity": "sha512-xowbVaTPe9r7y7RUejcK73/j8tt2jfiyTednOvHbA8JoClvMYCp+r8QegLwK/n8zWQAtZb1fFnER4XLBZXrCxA==", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - }, "serialize-javascript": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", diff --git a/examples/bundling/tree-shaking/rollup-ac3/package.json b/examples/bundling/tree-shaking/rollup-ac3/package.json index fce2fbe1cbf..8df3816e528 100644 --- a/examples/bundling/tree-shaking/rollup-ac3/package.json +++ b/examples/bundling/tree-shaking/rollup-ac3/package.json @@ -30,8 +30,8 @@ "dependencies": { "@apollo/client": "file:../../../../dist", "graphql": "^14.5.8", - "react": "^16.13.0", - "react-dom": "^16.13.0" + "react": "file:../../../../node_modules/react", + "react-dom": "file:../../../../node_modules/react-dom" }, "devDependencies": { "@babel/preset-react": "^7.0.0", diff --git a/src/react/context/ApolloConsumer.tsx b/src/react/context/ApolloConsumer.tsx index 6014d6e42b0..8c5c1d7f1fe 100644 --- a/src/react/context/ApolloConsumer.tsx +++ b/src/react/context/ApolloConsumer.tsx @@ -1,15 +1,14 @@ +import React from 'react'; import { invariant } from 'ts-invariant'; import { ApolloClient } from '../../ApolloClient'; import { getApolloContext } from './ApolloContext'; -import { requireReactLazily } from '../react'; export interface ApolloConsumerProps { children: (client: ApolloClient) => React.ReactChild | null; } export const ApolloConsumer: React.FC = props => { - const React = requireReactLazily(); const ApolloContext = getApolloContext(); return ( diff --git a/src/react/context/ApolloContext.ts b/src/react/context/ApolloContext.ts index 230881975e8..e9fa0911796 100644 --- a/src/react/context/ApolloContext.ts +++ b/src/react/context/ApolloContext.ts @@ -1,5 +1,5 @@ +import React from 'react'; import { ApolloClient } from '../../ApolloClient'; -import { requireReactLazily } from '../react'; export interface ApolloContextValue { client?: ApolloClient; @@ -20,7 +20,6 @@ const contextSymbol = typeof Symbol === 'function' && Symbol.for ? '__APOLLO_CONTEXT__'; export function resetApolloContext() { - const React = requireReactLazily(); Object.defineProperty(React, contextSymbol, { value: React.createContext({}), enumerable: false, @@ -30,7 +29,6 @@ export function resetApolloContext() { } export function getApolloContext() { - const React = requireReactLazily(); if (!(React as any)[contextSymbol]) { resetApolloContext(); } diff --git a/src/react/context/ApolloProvider.tsx b/src/react/context/ApolloProvider.tsx index 1667c451072..42fa65d1b2f 100644 --- a/src/react/context/ApolloProvider.tsx +++ b/src/react/context/ApolloProvider.tsx @@ -1,8 +1,8 @@ +import React from 'react'; import { invariant } from 'ts-invariant'; import { ApolloClient } from '../../ApolloClient'; import { getApolloContext } from './ApolloContext'; -import { requireReactLazily } from '../react'; export interface ApolloProviderProps { client: ApolloClient; @@ -13,7 +13,6 @@ export const ApolloProvider: React.FC> = ({ client, children }) => { - const React = requireReactLazily(); const ApolloContext = getApolloContext(); return ( diff --git a/src/react/context/__tests__/ApolloConsumer.test.tsx b/src/react/context/__tests__/ApolloConsumer.test.tsx index 811f4dd349a..27d3d96320b 100644 --- a/src/react/context/__tests__/ApolloConsumer.test.tsx +++ b/src/react/context/__tests__/ApolloConsumer.test.tsx @@ -1,3 +1,4 @@ +import React from 'react'; import { render, cleanup } from '@testing-library/react'; import { ApolloLink } from '../../../link/core/ApolloLink'; @@ -6,9 +7,6 @@ import { InMemoryCache as Cache } from '../../../cache/inmemory/inMemoryCache'; import { ApolloProvider } from '../ApolloProvider'; import { ApolloConsumer } from '../ApolloConsumer'; import { getApolloContext } from '../ApolloContext'; -import { requireReactLazily } from '../../react'; - -const React = requireReactLazily(); const client = new ApolloClient({ cache: new Cache(), diff --git a/src/react/context/__tests__/ApolloProvider.test.tsx b/src/react/context/__tests__/ApolloProvider.test.tsx index d2c18befb85..9ef9d72ba09 100644 --- a/src/react/context/__tests__/ApolloProvider.test.tsx +++ b/src/react/context/__tests__/ApolloProvider.test.tsx @@ -1,3 +1,4 @@ +import React, { useContext } from 'react'; import { render, cleanup } from '@testing-library/react'; import { ApolloLink } from '../../../link/core/ApolloLink'; @@ -5,10 +6,6 @@ import { ApolloClient } from '../../../ApolloClient'; import { InMemoryCache as Cache } from '../../../cache/inmemory/inMemoryCache'; import { ApolloProvider } from '../ApolloProvider'; import { getApolloContext } from '../ApolloContext'; -import { requireReactLazily } from '../../react'; - -const React = requireReactLazily(); -const { useContext } = React; describe(' Component', () => { afterEach(cleanup); diff --git a/src/react/hooks/__tests__/useApolloClient.test.tsx b/src/react/hooks/__tests__/useApolloClient.test.tsx index 54b08714478..1a1490efbb7 100644 --- a/src/react/hooks/__tests__/useApolloClient.test.tsx +++ b/src/react/hooks/__tests__/useApolloClient.test.tsx @@ -1,3 +1,4 @@ +import React from 'react'; import { render, cleanup } from '@testing-library/react'; import { InvariantError } from 'ts-invariant'; @@ -7,9 +8,6 @@ import { ApolloClient } from '../../../ApolloClient'; import { InMemoryCache } from '../../../cache/inmemory/inMemoryCache'; import { useApolloClient } from '../useApolloClient'; import { resetApolloContext } from '../../context/ApolloContext'; -import { requireReactLazily } from '../../react'; - -const React = requireReactLazily(); describe('useApolloClient Hook', () => { afterEach(() => { diff --git a/src/react/hooks/__tests__/useLazyQuery.test.tsx b/src/react/hooks/__tests__/useLazyQuery.test.tsx index a3fc9beb3f1..4f26803c37e 100644 --- a/src/react/hooks/__tests__/useLazyQuery.test.tsx +++ b/src/react/hooks/__tests__/useLazyQuery.test.tsx @@ -1,3 +1,4 @@ +import React from 'react'; import { DocumentNode } from 'graphql'; import gql from 'graphql-tag'; import { render, wait } from '@testing-library/react'; @@ -7,9 +8,6 @@ import { ApolloClient } from '../../../ApolloClient'; import { InMemoryCache } from '../../../cache/inmemory/inMemoryCache'; import { ApolloProvider } from '../../context/ApolloProvider'; import { useLazyQuery } from '../useLazyQuery'; -import { requireReactLazily } from '../../react'; - -const React = requireReactLazily(); describe('useLazyQuery Hook', () => { const CAR_QUERY: DocumentNode = gql` diff --git a/src/react/hooks/__tests__/useMutation.test.tsx b/src/react/hooks/__tests__/useMutation.test.tsx index 45d935de725..4afa79add91 100644 --- a/src/react/hooks/__tests__/useMutation.test.tsx +++ b/src/react/hooks/__tests__/useMutation.test.tsx @@ -1,3 +1,4 @@ +import React, { useEffect } from 'react'; import { DocumentNode, GraphQLError } from 'graphql'; import gql from 'graphql-tag'; import { render, cleanup, wait } from '@testing-library/react'; @@ -8,10 +9,6 @@ import { ApolloClient } from '../../../ApolloClient'; import { InMemoryCache } from '../../../cache/inmemory/inMemoryCache'; import { ApolloProvider } from '../../context/ApolloProvider'; import { useMutation } from '../useMutation'; -import { requireReactLazily } from '../../react'; - -const React = requireReactLazily(); -const { useEffect } = React; describe('useMutation Hook', () => { interface Todo { diff --git a/src/react/hooks/__tests__/useQuery.test.tsx b/src/react/hooks/__tests__/useQuery.test.tsx index 9ba5c3b44c5..db21a681c01 100644 --- a/src/react/hooks/__tests__/useQuery.test.tsx +++ b/src/react/hooks/__tests__/useQuery.test.tsx @@ -1,3 +1,4 @@ +import React, { useState, useReducer, Fragment } from 'react'; import { DocumentNode, GraphQLError } from 'graphql'; import gql from 'graphql-tag'; import { render, cleanup, wait } from '@testing-library/react'; @@ -11,13 +12,9 @@ import { ApolloClient } from '../../../ApolloClient'; import { InMemoryCache } from '../../../cache/inmemory/inMemoryCache'; import { ApolloProvider } from '../../context/ApolloProvider'; import { useQuery } from '../useQuery'; -import { requireReactLazily } from '../../react'; import { QueryFunctionOptions } from '../..'; import { NetworkStatus } from '../../../core/networkStatus'; -const React = requireReactLazily(); -const { useState, useReducer, Fragment } = React; - describe('useQuery Hook', () => { const CAR_QUERY: DocumentNode = gql` query { diff --git a/src/react/hooks/__tests__/useSubscription.test.tsx b/src/react/hooks/__tests__/useSubscription.test.tsx index 9211b411aba..c5d66c826a0 100644 --- a/src/react/hooks/__tests__/useSubscription.test.tsx +++ b/src/react/hooks/__tests__/useSubscription.test.tsx @@ -1,3 +1,4 @@ +import React from 'react'; import { render, cleanup, wait } from '@testing-library/react'; import gql from 'graphql-tag'; @@ -6,9 +7,6 @@ import { ApolloClient } from '../../../ApolloClient'; import { InMemoryCache as Cache } from '../../../cache/inmemory/inMemoryCache'; import { ApolloProvider } from '../../context/ApolloProvider'; import { useSubscription } from '../useSubscription'; -import { requireReactLazily } from '../../react'; - -const React = requireReactLazily(); describe('useSubscription Hook', () => { afterEach(cleanup); diff --git a/src/react/hooks/useApolloClient.ts b/src/react/hooks/useApolloClient.ts index 7507ae65adc..c7b4deb4d3d 100644 --- a/src/react/hooks/useApolloClient.ts +++ b/src/react/hooks/useApolloClient.ts @@ -1,11 +1,10 @@ +import React from 'react'; import { invariant } from 'ts-invariant'; import { ApolloClient } from '../../ApolloClient'; import { getApolloContext } from '../context/ApolloContext'; -import { requireReactLazily } from '../react'; export function useApolloClient(): ApolloClient { - const React = requireReactLazily(); const { client } = React.useContext(getApolloContext()); invariant( client, diff --git a/src/react/hooks/useMutation.ts b/src/react/hooks/useMutation.ts index 4b2ef906742..902ebe85101 100644 --- a/src/react/hooks/useMutation.ts +++ b/src/react/hooks/useMutation.ts @@ -1,16 +1,15 @@ +import { useContext, useState, useRef, useEffect } from 'react'; import { DocumentNode } from 'graphql'; import { MutationHookOptions, MutationTuple } from '../types/types'; import { MutationData } from '../data/MutationData'; import { OperationVariables } from '../../core/types'; import { getApolloContext } from '../context/ApolloContext'; -import { requireReactLazily } from '../react'; export function useMutation( mutation: DocumentNode, options?: MutationHookOptions ): MutationTuple { - const { useContext, useState, useRef, useEffect } = requireReactLazily(); const context = useContext(getApolloContext()); const [result, setResult] = useState({ called: false, loading: false }); const updatedOptions = options ? { ...options, mutation } : { mutation }; diff --git a/src/react/hooks/useSubscription.ts b/src/react/hooks/useSubscription.ts index a583554925a..a5dad16bc61 100644 --- a/src/react/hooks/useSubscription.ts +++ b/src/react/hooks/useSubscription.ts @@ -1,17 +1,15 @@ +import { useContext, useState, useRef, useEffect } from 'react'; import { DocumentNode } from 'graphql'; import { SubscriptionHookOptions } from '../types/types'; import { SubscriptionData } from '../data/SubscriptionData'; import { OperationVariables } from '../../core/types'; import { getApolloContext } from '../context/ApolloContext'; -import { requireReactLazily } from '../react'; export function useSubscription( subscription: DocumentNode, options?: SubscriptionHookOptions ) { - const React = requireReactLazily(); - const { useContext, useState, useRef, useEffect } = React; const context = useContext(getApolloContext()); const updatedOptions = options ? { ...options, subscription } diff --git a/src/react/hooks/utils/useBaseQuery.ts b/src/react/hooks/utils/useBaseQuery.ts index ff315a5830d..18cc63bd324 100644 --- a/src/react/hooks/utils/useBaseQuery.ts +++ b/src/react/hooks/utils/useBaseQuery.ts @@ -1,3 +1,4 @@ +import { useContext, useEffect, useReducer, useRef } from 'react'; import { DocumentNode } from 'graphql'; import { @@ -10,15 +11,12 @@ import { QueryData } from '../../data/QueryData'; import { useDeepMemo } from './useDeepMemo'; import { OperationVariables } from '../../../core/types'; import { getApolloContext } from '../../context/ApolloContext'; -import { requireReactLazily } from '../../react'; export function useBaseQuery( query: DocumentNode, options?: QueryHookOptions, lazy = false ) { - const React = requireReactLazily(); - const { useContext, useEffect, useReducer, useRef } = React; const context = useContext(getApolloContext()); const [tick, forceUpdate] = useReducer(x => x + 1, 0); const updatedOptions = options ? { ...options, query } : { query }; diff --git a/src/react/hooks/utils/useDeepMemo.ts b/src/react/hooks/utils/useDeepMemo.ts index a1f4882952a..868804e1bd4 100644 --- a/src/react/hooks/utils/useDeepMemo.ts +++ b/src/react/hooks/utils/useDeepMemo.ts @@ -1,7 +1,6 @@ +import { useRef } from 'react'; import { equal } from '@wry/equality'; -import { requireReactLazily } from '../../react'; - /** * Memoize a result using deep equality. This hook has two advantages over * React.useMemo: it uses deep equality to compare memo keys, and it guarantees @@ -13,8 +12,6 @@ export function useDeepMemo( memoFn: () => TValue, key: TKey ): TValue { - const React = requireReactLazily(); - const { useRef } = React; const ref = useRef<{ key: TKey; value: TValue }>(); if (!ref.current || !equal(key, ref.current.key)) { diff --git a/src/react/react.ts b/src/react/react.ts deleted file mode 100644 index 872f9f2ddf7..00000000000 --- a/src/react/react.ts +++ /dev/null @@ -1,9 +0,0 @@ -let React: typeof import('react'); - -// Apollo Client can be used without React, which means we want to make sure -// `react` is only imported/required if actually needed. To help with this -// the `react` module is lazy loaded using `requireReactLazily` when used by -// Apollo Client's React integration layer. -export function requireReactLazily(): typeof import('react') { - return React || (React = require('react')); -} From 0b8845b048630fbd8d16a7a28fd6d85582ea9ded Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Fri, 29 May 2020 16:51:43 -0400 Subject: [PATCH 26/56] Use String.prototype.split for CJS React munging. --- config/rollup.config.js | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/config/rollup.config.js b/config/rollup.config.js index 429b891d76c..264a9acbd19 100644 --- a/config/rollup.config.js +++ b/config/rollup.config.js @@ -76,18 +76,20 @@ function prepareCJS(input, output) { const cjsBundle = output.replace(`${distDir}/`, ''); return { generateBundle(_option, bundle) { - const { code } = bundle[cjsBundle]; - const regex = /var React = require\('react'\);/; - const matches = code.match(regex); - if (matches && matches.length === 1) { - bundle[cjsBundle].code = - code.replace( - regex, - "try { var React = require('react'); } catch (error) {}" - ); + const parts = bundle[cjsBundle].code.split( + /var React = require\('react'\);/); + // The React import should appear only once in the CJS bundle, + // since we build the CJS bundle using Rollup, which (hopefully!) + // deduplicates all external imports. + if (parts && parts.length === 2) { + bundle[cjsBundle].code = [ + parts[0], + "try { var React = require('react'); } catch (error) {}", + parts[1], + ].join("\n"); } else { throw new Error( - 'The CJS bundle could not prepared as a single React ' + + 'The CJS bundle could not be prepared as a single React ' + 'require could not be found.' ); } From dae6b6f3d9d8c578f30244db7df1c4c96c99f6fc Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Fri, 29 May 2020 19:33:12 -0400 Subject: [PATCH 27/56] Hoist cache.modify method declaration to ApolloCache. (#6362) Background: https://github.com/apollographql/apollo-client/pull/6350#issuecomment-635666826 The modify method and its related types are fairly InMemoryCache-specific, which is why it felt safest to confine cache.modify to InMemoryCache when I brought it back in #6350. In practice, however, that confinement just makes cache.modify harder to use (annoyingly, not helpfully) in cases where an ApolloCache is all that's available. You could also argue that cache.modify has roughly the same standing (in terms of InMemoryCache-specificity) as cache.identify or cache.gc, which are also part of the "Optional API" of the ApolloCache base class. In that sense, cache.modify is simply joining those other AC3 APIs in ApolloCache (and thus also InMemoryCache). --- src/cache/core/cache.ts | 4 +++ src/cache/core/types/Cache.ts | 8 +++++ src/cache/core/types/common.ts | 47 +++++++++++++++++++++++++++ src/cache/inmemory/entityStore.ts | 26 ++++++++------- src/cache/inmemory/inMemoryCache.ts | 3 +- src/cache/inmemory/policies.ts | 17 +++++----- src/cache/inmemory/types.ts | 49 +++-------------------------- 7 files changed, 87 insertions(+), 67 deletions(-) diff --git a/src/cache/core/cache.ts b/src/cache/core/cache.ts index acd20c2288a..f35942a1882 100644 --- a/src/cache/core/cache.ts +++ b/src/cache/core/cache.ts @@ -82,6 +82,10 @@ export abstract class ApolloCache implements DataProxy { return []; } + public modify(options: Cache.ModifyOptions): boolean { + return false; + } + // Experimental API public transformForLink(document: DocumentNode): DocumentNode { diff --git a/src/cache/core/types/Cache.ts b/src/cache/core/types/Cache.ts index ea18b2ab627..60aad9ea380 100644 --- a/src/cache/core/types/Cache.ts +++ b/src/cache/core/types/Cache.ts @@ -1,4 +1,5 @@ import { DataProxy } from './DataProxy'; +import { Modifier, Modifiers } from './common'; export namespace Cache { export type WatchCallback = (diff: Cache.DiffResult) => void; @@ -33,6 +34,13 @@ export namespace Cache { broadcast?: boolean; } + export interface ModifyOptions { + id?: string; + fields: Modifiers | Modifier; + optimistic?: boolean; + broadcast?: boolean; + } + export import DiffResult = DataProxy.DiffResult; export import WriteQueryOptions = DataProxy.WriteQueryOptions; export import WriteFragmentOptions = DataProxy.WriteFragmentOptions; diff --git a/src/cache/core/types/common.ts b/src/cache/core/types/common.ts index 2bc7442afa2..51cc7ae7f2b 100644 --- a/src/cache/core/types/common.ts +++ b/src/cache/core/types/common.ts @@ -1,3 +1,12 @@ +import { FieldNode } from 'graphql'; + +import { + Reference, + StoreObject, + StoreValue, + isReference, +} from '../../../core'; + // The Readonly type only really works for object types, since it marks // all of the object's properties as readonly, but there are many cases when // a generic type parameter like TExisting might be a string or some other @@ -15,3 +24,41 @@ export class MissingFieldError { public readonly variables?: Record, ) {} } + +export interface FieldSpecifier { + typename?: string; + fieldName: string; + field?: FieldNode; + args?: Record; + variables?: Record; +} + +export interface ReadFieldOptions extends FieldSpecifier { + from?: StoreObject | Reference; +} + +export interface ReadFieldFunction { + (options: ReadFieldOptions): SafeReadonly | undefined; + ( + fieldName: string, + from?: StoreObject | Reference, + ): SafeReadonly | undefined; +} + +export type ToReferenceFunction = ( + object: StoreObject, + mergeIntoStore?: boolean, +) => Reference | undefined; + +export type Modifier = (value: T, details: { + DELETE: any; + fieldName: string; + storeFieldName: string; + readField: ReadFieldFunction; + isReference: typeof isReference; + toReference: ToReferenceFunction; +}) => T; + +export type Modifiers = { + [fieldName: string]: Modifier; +}; diff --git a/src/cache/inmemory/entityStore.ts b/src/cache/inmemory/entityStore.ts index 1c9909e51f0..6b155ae67b2 100644 --- a/src/cache/inmemory/entityStore.ts +++ b/src/cache/inmemory/entityStore.ts @@ -11,11 +11,18 @@ import { import { DeepMerger } from '../../utilities/common/mergeDeep'; import { maybeDeepFreeze } from '../../utilities/common/maybeDeepFreeze'; import { canUseWeakMap } from '../../utilities/common/canUse'; -import { NormalizedCache, NormalizedCacheObject, Modifiers, Modifier, ReadFieldFunction, ReadFieldOptions } from './types'; +import { NormalizedCache, NormalizedCacheObject } from './types'; import { hasOwn, fieldNameFromStoreName } from './helpers'; import { Policies } from './policies'; -import { SafeReadonly } from '../core/types/common'; import { Cache } from '../core/types/Cache'; +import { + SafeReadonly, + Modifier, + Modifiers, + ReadFieldFunction, + ReadFieldOptions, + ToReferenceFunction, +} from '../core/types/common'; const DELETE: any = Object.create(null); const delModifier: Modifier = () => DELETE; @@ -110,7 +117,7 @@ export abstract class EntityStore implements NormalizedCache { public modify( dataId: string, - modifiers: Modifier | Modifiers, + fields: Modifier | Modifiers, ): boolean { const storeObject = this.lookup(dataId); @@ -137,9 +144,9 @@ export abstract class EntityStore implements NormalizedCache { const fieldName = fieldNameFromStoreName(storeFieldName); let fieldValue = storeObject[storeFieldName]; if (fieldValue === void 0) return; - const modify: Modifier = typeof modifiers === "function" - ? modifiers - : modifiers[storeFieldName] || modifiers[fieldName]; + const modify: Modifier = typeof fields === "function" + ? fields + : fields[storeFieldName] || fields[fieldName]; if (modify) { let newValue = modify === delModifier ? DELETE : modify(maybeDeepFreeze(fieldValue), { @@ -341,10 +348,7 @@ export abstract class EntityStore implements NormalizedCache { // Bound function that converts an object with a __typename and primary // key fields to a Reference object. Pass true for mergeIntoStore if you // would also like this object to be persisted into the store. - public toReference = ( - object: StoreObject, - mergeIntoStore?: boolean, - ): Reference | undefined => { + public toReference: ToReferenceFunction = (object, mergeIntoStore) => { const [id] = this.policies.identify(object); if (id) { const ref = makeReference(id); @@ -356,8 +360,6 @@ export abstract class EntityStore implements NormalizedCache { } } -export type ToReferenceFunction = EntityStore["toReference"]; - export type FieldValueGetter = EntityStore["getFieldValue"]; // A single CacheGroup represents a set of one or more EntityStore objects, diff --git a/src/cache/inmemory/inMemoryCache.ts b/src/cache/inmemory/inMemoryCache.ts index e1c2693b194..71d3a283bf8 100644 --- a/src/cache/inmemory/inMemoryCache.ts +++ b/src/cache/inmemory/inMemoryCache.ts @@ -11,7 +11,6 @@ import { StoreObject, Reference } from '../../utilities/graphql/storeUtils'; import { ApolloReducerConfig, NormalizedCacheObject, - ModifyOptions, } from './types'; import { StoreReader } from './readFromStore'; import { StoreWriter } from './writeToStore'; @@ -156,7 +155,7 @@ export class InMemoryCache extends ApolloCache { } } - public modify(options: ModifyOptions): boolean { + public modify(options: Cache.ModifyOptions): boolean { if (hasOwn.call(options, "id") && !options.id) { // To my knowledge, TypeScript does not currently provide a way to // enforce that an optional property?:type must *not* be undefined diff --git a/src/cache/inmemory/policies.ts b/src/cache/inmemory/policies.ts index 9eadbed30de..61b8f54f702 100644 --- a/src/cache/inmemory/policies.ts +++ b/src/cache/inmemory/policies.ts @@ -24,12 +24,7 @@ import { getStoreKeyName, } from '../../utilities/graphql/storeUtils'; import { canUseWeakMap } from '../../utilities/common/canUse'; -import { - IdGetter, - FieldSpecifier, - ReadFieldOptions, - ReadFieldFunction, -} from "./types"; +import { IdGetter } from "./types"; import { hasOwn, fieldNameFromStoreName, @@ -37,9 +32,15 @@ import { isFieldValueToBeMerged, storeValueIsStoreObject, } from './helpers'; -import { FieldValueGetter, ToReferenceFunction } from './entityStore'; +import { FieldValueGetter } from './entityStore'; import { InMemoryCache } from './inMemoryCache'; -import { SafeReadonly } from '../core/types/common'; +import { + SafeReadonly, + FieldSpecifier, + ToReferenceFunction, + ReadFieldFunction, + ReadFieldOptions, +} from '../core/types/common'; export type TypePolicies = { [__typename: string]: TypePolicy; diff --git a/src/cache/inmemory/types.ts b/src/cache/inmemory/types.ts index 4163ae1bf4a..597bc7e4562 100644 --- a/src/cache/inmemory/types.ts +++ b/src/cache/inmemory/types.ts @@ -1,15 +1,14 @@ -import { DocumentNode, FieldNode } from 'graphql'; +import { DocumentNode } from 'graphql'; import { Transaction } from '../core/cache'; import { StoreObject, StoreValue, - isReference, Reference, } from '../../utilities/graphql/storeUtils'; -import { FieldValueGetter, ToReferenceFunction } from './entityStore'; +import { FieldValueGetter } from './entityStore'; import { KeyFieldsFunction } from './policies'; -import { SafeReadonly } from '../core/types/common'; +import { ToReferenceFunction, Modifier, Modifiers } from '../core/types/common'; export { StoreObject, StoreValue, Reference } export interface IdGetterObj extends Object { @@ -30,7 +29,7 @@ export interface NormalizedCache { has(dataId: string): boolean; get(dataId: string, fieldName: string): StoreValue; merge(dataId: string, incoming: StoreObject): void; - modify(dataId: string, modifiers: Modifier | Modifiers): boolean; + modify(dataId: string, fields: Modifiers | Modifier): boolean; delete(dataId: string, fieldName?: string): boolean; clear(): void; @@ -106,43 +105,3 @@ export type CacheResolverMap = { // backwards compat export type CustomResolver = CacheResolver; export type CustomResolverMap = CacheResolverMap; - -export interface FieldSpecifier { - typename?: string; - fieldName: string; - field?: FieldNode; - args?: Record; - variables?: Record; -} - -export interface ReadFieldOptions extends FieldSpecifier { - from?: StoreObject | Reference; -} - -export interface ReadFieldFunction { - (options: ReadFieldOptions): SafeReadonly | undefined; - ( - fieldName: string, - from?: StoreObject | Reference, - ): SafeReadonly | undefined; -} - -export interface ModifyOptions { - id?: string; - fields: Modifiers | Modifier; - optimistic?: boolean; - broadcast?: boolean; -} - -export type Modifier = (value: T, details: { - DELETE: any; - fieldName: string; - storeFieldName: string; - isReference: typeof isReference; - toReference: ToReferenceFunction; - readField: ReadFieldFunction; -}) => T; - -export type Modifiers = { - [fieldName: string]: Modifier; -} From 13ad552d355f640e4b5b2530810e9f4b1df836bd Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Fri, 29 May 2020 19:35:18 -0400 Subject: [PATCH 28/56] Require Cache.EvictOptions when calling cache.evict. (#6364) We've been finding lately that named options APIs are much easier to work with (and later to extend), because you can think about the different options independently, and future additions of new named options tend to be much less disruptive for existing code. Since we're approaching a major new version of Apollo Client (3.0), and the `cache.evict` method did nothing in AC2 anyway, there's no sense preserving the alternate API with positional arguments, now that we support `Cache.EvictOptions`. In other words, this is definitely a breaking change, but only for those who have been using using the `@apollo/client` betas. Thank you for your patience and understanding; we know changes like this can be annoying if you were using `cache.evict` heavily, but we think the uniformity of always requiring `Cache.EvictOptions` will be simpler and more flexible in the long run. --- CHANGELOG.md | 3 +- src/__tests__/client.ts | 4 +- src/cache/core/cache.ts | 8 --- src/cache/core/types/Cache.ts | 2 +- src/cache/inmemory/__tests__/entityStore.ts | 65 +++++++++++++++------ src/cache/inmemory/__tests__/policies.ts | 4 +- src/cache/inmemory/entityStore.ts | 22 +++---- src/cache/inmemory/inMemoryCache.ts | 26 ++++----- 8 files changed, 79 insertions(+), 55 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ae299f2fbd6..d3c316a6e3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,8 +59,9 @@ - `InMemoryCache` now supports tracing garbage collection and eviction. Note that the signature of the `evict` method has been simplified in a potentially backwards-incompatible way.
[@benjamn](https://github.com/benjamn) in [#5310](https://github.com/apollographql/apollo-client/pull/5310) -- The `cache.evict` method can optionally take an arguments object as its third parameter (following the entity ID and field name), to delete only those field values with specific arguments.
+- **[beta-BREAKING]** Please note that the `cache.evict` method now requires `Cache.EvictOptions`, though it previously supported positional arguments as well.
[@danReynolds](https://github.com/danReynolds) in [#6141](https://github.com/apollographql/apollo-client/pull/6141) + [@benjamn](https://github.com/benjamn) in [#6364](https://github.com/apollographql/apollo-client/pull/6364) - Cache methods that would normally trigger a broadcast, like `cache.evict`, `cache.writeQuery`, and `cache.writeFragment`, can now be called with a named options object, which supports a `broadcast: boolean` property that can be used to silence the broadcast, for situations where you want to update the cache multiple times without triggering a broadcast each time.
[@benjamn](https://github.com/benjamn) in [#6288](https://github.com/apollographql/apollo-client/pull/6288) diff --git a/src/__tests__/client.ts b/src/__tests__/client.ts index 8be5e5b6796..26b69a2b5b6 100644 --- a/src/__tests__/client.ts +++ b/src/__tests__/client.ts @@ -2913,7 +2913,7 @@ describe('@connection', () => { expect(checkLastResult(abResults, a456bOyez)).toBe(a456bOyez); // Now invalidate the ROOT_QUERY.a field. - client.cache.evict("ROOT_QUERY", "a"); + client.cache.evict({ fieldName: "a" }); await wait(); // The results are structurally the same, but the result objects have @@ -2957,7 +2957,7 @@ describe('@connection', () => { checkLastResult(abResults, a456bOyez); checkLastResult(cResults, { c: "saw" }); - client.cache.evict("ROOT_QUERY", "c"); + client.cache.evict({ fieldName: "c" }); await wait(); checkLastResult(aResults, a456); diff --git a/src/cache/core/cache.ts b/src/cache/core/cache.ts index f35942a1882..ff7e0764f7c 100644 --- a/src/cache/core/cache.ts +++ b/src/cache/core/cache.ts @@ -28,14 +28,6 @@ export abstract class ApolloCache implements DataProxy { // removed from the cache. public abstract evict(options: Cache.EvictOptions): boolean; - // For backwards compatibility, evict can also take positional - // arguments. Please prefer the Cache.EvictOptions style (above). - public abstract evict( - id: string, - field?: string, - args?: Record, - ): boolean; - // intializer / offline / ssr API /** * Replaces existing state in the cache (if any) with the values expressed by diff --git a/src/cache/core/types/Cache.ts b/src/cache/core/types/Cache.ts index 60aad9ea380..21c2535538e 100644 --- a/src/cache/core/types/Cache.ts +++ b/src/cache/core/types/Cache.ts @@ -28,7 +28,7 @@ export namespace Cache { } export interface EvictOptions { - id: string; + id?: string; fieldName?: string; args?: Record; broadcast?: boolean; diff --git a/src/cache/inmemory/__tests__/entityStore.ts b/src/cache/inmemory/__tests__/entityStore.ts index 99fad8e91de..75130b44a06 100644 --- a/src/cache/inmemory/__tests__/entityStore.ts +++ b/src/cache/inmemory/__tests__/entityStore.ts @@ -620,7 +620,7 @@ describe('EntityStore', () => { }, }); - expect(cache.evict("Author:J.K. Rowling")).toBe(false); + expect(cache.evict({ id: "Author:J.K. Rowling" })).toBe(false); const bookAuthorFragment = gql` fragment BookAuthor on Book { @@ -689,7 +689,7 @@ describe('EntityStore', () => { expect(cache.gc()).toEqual([]); - expect(cache.evict("Author:Robert Galbraith")).toBe(true); + expect(cache.evict({ id: "Author:Robert Galbraith" })).toBe(true); expect(cache.gc()).toEqual([]); @@ -754,9 +754,27 @@ describe('EntityStore', () => { expect(cache.gc()).toEqual([]); - // If you're ever tempted to do this, you probably want to use cache.clear() - // instead, but evicting the ROOT_QUERY should work at least. - expect(cache.evict("ROOT_QUERY")).toBe(true); + function checkFalsyEvictId(id: any) { + expect(id).toBeFalsy(); + expect(cache.evict({ + // Accidentally passing a falsy/undefined options.id to + // cache.evict (perhaps because cache.identify failed) should + // *not* cause the ROOT_QUERY object to be evicted! In order for + // cache.evict to default to ROOT_QUERY, the options.id property + // must be *absent* (not just undefined). + id, + })).toBe(false); + } + checkFalsyEvictId(void 0); + checkFalsyEvictId(null); + checkFalsyEvictId(false); + checkFalsyEvictId(0); + checkFalsyEvictId(""); + + // In other words, this is how you evict the entire ROOT_QUERY + // object. If you're ever tempted to do this, you probably want to use + // cache.clear() instead, but evicting the ROOT_QUERY should work. + expect(cache.evict({})).toBe(true); expect(cache.extract(true)).toEqual({ "Book:031648637X": { @@ -1177,7 +1195,10 @@ describe('EntityStore', () => { }, }); - cache.evict('ROOT_QUERY', 'authorOfBook', { isbn: "1" }); + cache.evict({ + fieldName: 'authorOfBook', + args: { isbn: "1" }, + }); expect(cache.extract()).toEqual({ ROOT_QUERY: { @@ -1195,7 +1216,10 @@ describe('EntityStore', () => { }, }); - cache.evict('ROOT_QUERY', 'authorOfBook', { isbn: '3' }); + cache.evict({ + fieldName: 'authorOfBook', + args: { isbn: '3' }, + }); expect(cache.extract()).toEqual({ ROOT_QUERY: { @@ -1213,7 +1237,10 @@ describe('EntityStore', () => { }, }); - cache.evict('ROOT_QUERY', 'authorOfBook', {}); + cache.evict({ + fieldName: 'authorOfBook', + args: {}, + }); expect(cache.extract()).toEqual({ ROOT_QUERY: { @@ -1226,7 +1253,9 @@ describe('EntityStore', () => { }, }); - cache.evict('ROOT_QUERY', 'authorOfBook');; + cache.evict({ + fieldName: 'authorOfBook', + }); expect(cache.extract()).toEqual({ ROOT_QUERY: { @@ -1506,12 +1535,14 @@ describe('EntityStore', () => { query: queryWithoutAliases, })).toBe(resultWithoutAliases); - cache.evict(cache.identify({ - __typename: "ABCs", - a: "ay", - b: "bee", - c: "see", - })!); + cache.evict({ + id: cache.identify({ + __typename: "ABCs", + a: "ay", + b: "bee", + c: "see", + }), + }); expect(cache.extract()).toEqual({ ROOT_QUERY: { @@ -1590,7 +1621,7 @@ describe('EntityStore', () => { id: 2, })!; - expect(cache.evict(authorId)).toBe(true); + expect(cache.evict({ id: authorId })).toBe(true); expect(cache.extract(true)).toEqual({ "Book:1": { @@ -1604,7 +1635,7 @@ describe('EntityStore', () => { }, }); - expect(cache.evict(authorId)).toBe(false); + expect(cache.evict({ id: authorId })).toBe(false); const missing = [ new MissingFieldError( diff --git a/src/cache/inmemory/__tests__/policies.ts b/src/cache/inmemory/__tests__/policies.ts index 89ac93e61e6..c2a7b7b8c2f 100644 --- a/src/cache/inmemory/__tests__/policies.ts +++ b/src/cache/inmemory/__tests__/policies.ts @@ -2513,7 +2513,9 @@ describe("type policies", function () { expect(cache.gc()).toEqual([]); - expect(cache.evict("ROOT_QUERY", "book")).toBe(true); + expect(cache.evict({ + fieldName: "book", + })).toBe(true); expect(cache.gc().sort()).toEqual([ 'Book:{"isbn":"0393354326"}', diff --git a/src/cache/inmemory/entityStore.ts b/src/cache/inmemory/entityStore.ts index 6b155ae67b2..847afd04e7b 100644 --- a/src/cache/inmemory/entityStore.ts +++ b/src/cache/inmemory/entityStore.ts @@ -214,17 +214,19 @@ export abstract class EntityStore implements NormalizedCache { public evict(options: Cache.EvictOptions): boolean { let evicted = false; - if (hasOwn.call(this.data, options.id)) { - evicted = this.delete(options.id, options.fieldName, options.args); - } - if (this instanceof Layer) { - evicted = this.parent.evict(options) || evicted; + if (options.id) { + if (hasOwn.call(this.data, options.id)) { + evicted = this.delete(options.id, options.fieldName, options.args); + } + if (this instanceof Layer) { + evicted = this.parent.evict(options) || evicted; + } + // Always invalidate the field to trigger rereading of watched + // queries, even if no cache data was modified by the eviction, + // because queries may depend on computed fields with custom read + // functions, whose values are not stored in the EntityStore. + this.group.dirty(options.id, options.fieldName || "__exists"); } - // Always invalidate the field to trigger rereading of watched - // queries, even if no cache data was modified by the eviction, - // because queries may depend on computed fields with custom read - // functions, whose values are not stored in the EntityStore. - this.group.dirty(options.id, options.fieldName || "__exists"); return evicted; } diff --git a/src/cache/inmemory/inMemoryCache.ts b/src/cache/inmemory/inMemoryCache.ts index 71d3a283bf8..1ad6d3bf461 100644 --- a/src/cache/inmemory/inMemoryCache.ts +++ b/src/cache/inmemory/inMemoryCache.ts @@ -236,28 +236,24 @@ export class InMemoryCache extends ApolloCache { return this.policies.identify(object)[0]; } - public evict( - idOrOptions: string | Cache.EvictOptions, - fieldName?: string, - args?: Record, - ): boolean { + public evict(options: Cache.EvictOptions): boolean { + if (!options.id) { + if (hasOwn.call(options, "id")) { + // See comment in modify method about why we return false when + // options.id exists but is falsy/undefined. + return false; + } + options = { ...options, id: "ROOT_QUERY" }; + } try { // It's unlikely that the eviction will end up invoking any other // cache update operations while it's running, but {in,de}crementing // this.txCount still seems like a good idea, for uniformity with // the other update methods. ++this.txCount; - return this.optimisticData.evict( - typeof idOrOptions === "string" ? { - id: idOrOptions, - fieldName, - args, - } : idOrOptions, - ); + return this.optimisticData.evict(options); } finally { - if (!--this.txCount && - (typeof idOrOptions === "string" || - idOrOptions.broadcast !== false)) { + if (!--this.txCount && options.broadcast !== false) { this.broadcastWatches(); } } From c81071374225a2f94e86a6f0693fe99f17b1724f Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Fri, 29 May 2020 20:07:32 -0400 Subject: [PATCH 29/56] Stop treating dangling references differently from empty objects. (#6365) Question: When cache.read{Query,Fragment} encounters a dangling reference (one that does not currently refer to any normalized entity object in the cache), should the cache behave as if the (nonexistent) target of the reference was an empty object, and report any requested fields as missing, or should the cache generate some other kind of error that reflects the the absence of the whole object? I think we could answer this question either way, but I'm leaning towards the first option. Note: it's normal for the cache to end up with dangling references when whole entity objects are evicted, or when a reference is created (e.g. by toReference) without writing any data into the cache. Cleaning up dangling references is a tricky problem, requiring application-level reasoning, and not even always desirable, since the data could always come back into the cache later, restoring the validity of the reference. Previously, I thought it would be helpful to distinguish between the absence of an entity object and the object simply being empty, but I no longer think this distinction (which only affected the wording of the MissingFieldError description) matters very much, and we can simplify everything by adopting the following policy: > During cache reads, a dangling Reference should behave as much as possible like a Reference to an entity object that happens to contain zero fields. I'm optimistic this policy may help with issues like #6325. At the very least, this policy means there's now only one flavor of MissingFieldError, which should reduce confusion. --- src/cache/inmemory/__tests__/entityStore.ts | 8 ++++---- src/cache/inmemory/__tests__/policies.ts | 6 +++--- src/cache/inmemory/readFromStore.ts | 14 -------------- 3 files changed, 7 insertions(+), 21 deletions(-) diff --git a/src/cache/inmemory/__tests__/entityStore.ts b/src/cache/inmemory/__tests__/entityStore.ts index 75130b44a06..0cc51a1f411 100644 --- a/src/cache/inmemory/__tests__/entityStore.ts +++ b/src/cache/inmemory/__tests__/entityStore.ts @@ -1555,11 +1555,11 @@ describe('EntityStore', () => { expect(() => cache.readQuery({ query: queryWithAliases, - })).toThrow(/Dangling reference to missing ABCs:.* object/); + })).toThrow(/Can't find field 'a' on ABCs:.* object/); expect(() => cache.readQuery({ query: queryWithoutAliases, - })).toThrow(/Dangling reference to missing ABCs:.* object/); + })).toThrow(/Can't find field 'a' on ABCs:.* object/); }); it("gracefully handles eviction amid optimistic updates", () => { @@ -1639,8 +1639,8 @@ describe('EntityStore', () => { const missing = [ new MissingFieldError( - "Dangling reference to missing Author:2 object", - ["book", "author"], + "Can't find field 'name' on Author:2 object", + ["book", "author", "name"], expect.anything(), expect.anything(), ), diff --git a/src/cache/inmemory/__tests__/policies.ts b/src/cache/inmemory/__tests__/policies.ts index c2a7b7b8c2f..156b5a5ea8a 100644 --- a/src/cache/inmemory/__tests__/policies.ts +++ b/src/cache/inmemory/__tests__/policies.ts @@ -2397,7 +2397,7 @@ describe("type policies", function () { }); expect(read).toThrow( - /Dangling reference to missing Book:{"isbn":"156858217X"} object/ + /Can't find field 'title' on Book:{"isbn":"156858217X"} object/ ); const stealThisData = { @@ -2529,11 +2529,11 @@ describe("type policies", function () { }); expect(() => read("0393354326")).toThrow( - /Dangling reference to missing Book:{"isbn":"0393354326"} object/ + /Can't find field 'title' on Book:{"isbn":"0393354326"} object/ ); expect(() => read("156858217X")).toThrow( - /Dangling reference to missing Book:{"isbn":"156858217X"} object/ + /Can't find field 'title' on Book:{"isbn":"156858217X"} object/ ); }); diff --git a/src/cache/inmemory/readFromStore.ts b/src/cache/inmemory/readFromStore.ts index 5951ee9a580..b02e507f2c8 100644 --- a/src/cache/inmemory/readFromStore.ts +++ b/src/cache/inmemory/readFromStore.ts @@ -213,20 +213,6 @@ export class StoreReader { objectOrReference, context, }: ExecSelectionSetOptions): ExecResult { - if (isReference(objectOrReference) && - !context.policies.rootTypenamesById[objectOrReference.__ref] && - !context.store.has(objectOrReference.__ref)) { - return { - result: {}, - missing: [missingFromInvariant( - new InvariantError( - `Dangling reference to missing ${objectOrReference.__ref} object` - ), - context, - )], - }; - } - const { fragmentMap, variables, policies, store } = context; const objectsToMerge: { [key: string]: any }[] = []; const finalResult: ExecResult = { result: null }; From 7dbbc710df1d8be1e5a39ede9a0809014e9b15d8 Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Fri, 29 May 2020 20:23:01 -0400 Subject: [PATCH 30/56] Bump @apollo/client npm version to 3.0.0-beta.53. --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9153d0c6985..345f37b938d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@apollo/client", - "version": "3.0.0-beta.52", + "version": "3.0.0-beta.53", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 3bca664b930..9ecbf3bc34a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@apollo/client", - "version": "3.0.0-beta.52", + "version": "3.0.0-beta.53", "description": "A fully-featured caching GraphQL client.", "private": true, "keywords": [ From 518660bbadb8f85272a1e093746865343060112d Mon Sep 17 00:00:00 2001 From: Renovate Bot Date: Sat, 30 May 2020 19:44:16 +0000 Subject: [PATCH 31/56] chore(deps): update dependency ts-jest to v26.1.0 --- package-lock.json | 59 +++-------------------------------------------- package.json | 2 +- 2 files changed, 4 insertions(+), 57 deletions(-) diff --git a/package-lock.json b/package-lock.json index 345f37b938d..4662425db08 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8112,9 +8112,9 @@ } }, "ts-jest": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-26.0.0.tgz", - "integrity": "sha512-eBpWH65mGgzobuw7UZy+uPP9lwu+tPp60o324ASRX4Ijg8UC5dl2zcge4kkmqr2Zeuk9FwIjvCTOPuNMEyGWWw==", + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-26.1.0.tgz", + "integrity": "sha512-JbhQdyDMYN5nfKXaAwCIyaWLGwevcT2/dbqRPsQeh6NZPUuXjZQZEfeLb75tz0ubCIgEELNm6xAzTe5NXs5Y4Q==", "dev": true, "requires": { "bs-logger": "0.x", @@ -8129,40 +8129,6 @@ "yargs-parser": "18.x" }, "dependencies": { - "braces": { - "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" - } - }, - "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, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "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 - }, - "micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.0.5" - } - }, "mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", @@ -8174,25 +8140,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", "dev": true - }, - "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, - "requires": { - "is-number": "^7.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" - } } } }, diff --git a/package.json b/package.json index 9ecbf3bc34a..e8317126341 100644 --- a/package.json +++ b/package.json @@ -100,7 +100,7 @@ "rollup-plugin-node-resolve": "5.2.0", "rollup-plugin-terser": "5.1.3", "rxjs": "6.5.3", - "ts-jest": "26.0.0", + "ts-jest": "26.1.0", "tsc-watch": "3.0.1", "typescript": "3.9.3" }, From 5e74226077b88237d1f8e2cf898cf97e8ae1250e Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Mon, 1 Jun 2020 11:12:42 -0400 Subject: [PATCH 32/56] Revert "Stop treating dangling references differently from empty objects" (#6371) This reverts commit c81071374225a2f94e86a6f0693fe99f17b1724f, introduced recently in PR #6365. My optimism that #6365 was an improvement seems to have been misplaced, since it caused the regression reported in #6368. We're too close to the AC3 RC/release to be floating risky changes like these without compelling justifications. --- src/cache/inmemory/__tests__/entityStore.ts | 8 ++++---- src/cache/inmemory/__tests__/policies.ts | 6 +++--- src/cache/inmemory/readFromStore.ts | 14 ++++++++++++++ 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/cache/inmemory/__tests__/entityStore.ts b/src/cache/inmemory/__tests__/entityStore.ts index 0cc51a1f411..75130b44a06 100644 --- a/src/cache/inmemory/__tests__/entityStore.ts +++ b/src/cache/inmemory/__tests__/entityStore.ts @@ -1555,11 +1555,11 @@ describe('EntityStore', () => { expect(() => cache.readQuery({ query: queryWithAliases, - })).toThrow(/Can't find field 'a' on ABCs:.* object/); + })).toThrow(/Dangling reference to missing ABCs:.* object/); expect(() => cache.readQuery({ query: queryWithoutAliases, - })).toThrow(/Can't find field 'a' on ABCs:.* object/); + })).toThrow(/Dangling reference to missing ABCs:.* object/); }); it("gracefully handles eviction amid optimistic updates", () => { @@ -1639,8 +1639,8 @@ describe('EntityStore', () => { const missing = [ new MissingFieldError( - "Can't find field 'name' on Author:2 object", - ["book", "author", "name"], + "Dangling reference to missing Author:2 object", + ["book", "author"], expect.anything(), expect.anything(), ), diff --git a/src/cache/inmemory/__tests__/policies.ts b/src/cache/inmemory/__tests__/policies.ts index 156b5a5ea8a..c2a7b7b8c2f 100644 --- a/src/cache/inmemory/__tests__/policies.ts +++ b/src/cache/inmemory/__tests__/policies.ts @@ -2397,7 +2397,7 @@ describe("type policies", function () { }); expect(read).toThrow( - /Can't find field 'title' on Book:{"isbn":"156858217X"} object/ + /Dangling reference to missing Book:{"isbn":"156858217X"} object/ ); const stealThisData = { @@ -2529,11 +2529,11 @@ describe("type policies", function () { }); expect(() => read("0393354326")).toThrow( - /Can't find field 'title' on Book:{"isbn":"0393354326"} object/ + /Dangling reference to missing Book:{"isbn":"0393354326"} object/ ); expect(() => read("156858217X")).toThrow( - /Can't find field 'title' on Book:{"isbn":"156858217X"} object/ + /Dangling reference to missing Book:{"isbn":"156858217X"} object/ ); }); diff --git a/src/cache/inmemory/readFromStore.ts b/src/cache/inmemory/readFromStore.ts index b02e507f2c8..5951ee9a580 100644 --- a/src/cache/inmemory/readFromStore.ts +++ b/src/cache/inmemory/readFromStore.ts @@ -213,6 +213,20 @@ export class StoreReader { objectOrReference, context, }: ExecSelectionSetOptions): ExecResult { + if (isReference(objectOrReference) && + !context.policies.rootTypenamesById[objectOrReference.__ref] && + !context.store.has(objectOrReference.__ref)) { + return { + result: {}, + missing: [missingFromInvariant( + new InvariantError( + `Dangling reference to missing ${objectOrReference.__ref} object` + ), + context, + )], + }; + } + const { fragmentMap, variables, policies, store } = context; const objectsToMerge: { [key: string]: any }[] = []; const finalResult: ExecResult = { result: null }; From 06a89480554ffc8b54a336402de41ce9bd171405 Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Mon, 1 Jun 2020 12:00:47 -0400 Subject: [PATCH 33/56] Warn when clobbering non-normalized data in the cache. > This is a revival of PR #5833, which has accumulated too many merge conflicts over the last few months to be worth rebasing. One consequence of #5603 is that replacing non-normalized data in the cache can result in loss of useful data, which is preferable to mistakenly merging unrelated objects, but not ideal. In almost every case, the right solution is to make sure the data can be normalized, or (if that isn't possible) to define a custom `merge` function for the field in question, within the parent type policy. It turns out we can give a very detailed warning about such situations in development, and that's what this commit does. For example: Cache data may be lost when replacing the d field of a Query object. To address this problem (which is not a bug in Apollo Client), either ensure all objects of type D have IDs, or define a custom merge function for the Query.d field, so InMemoryCache can safely merge these objects: existing: {"__typename":"D","e":4} incoming: {"__typename":"D","h":{"__typename":"H","i":7}} For more information about these options, please refer to the documentation: * Ensuring entity objects have IDs: https://go.apollo.dev/c/generating-unique-identifiers * Defining custom merge functions: https://go.apollo.dev/c/merging-non-normalized-objects Looking at the output for our test suite, every warning seems legitimate and worth fixing. I will resolve the warnings in subsequent commits. --- src/cache/inmemory/entityStore.ts | 100 +++++++++++++++++++++++++++++- 1 file changed, 97 insertions(+), 3 deletions(-) diff --git a/src/cache/inmemory/entityStore.ts b/src/cache/inmemory/entityStore.ts index 847afd04e7b..4b7f7e9394d 100644 --- a/src/cache/inmemory/entityStore.ts +++ b/src/cache/inmemory/entityStore.ts @@ -1,5 +1,6 @@ import { dep, OptimisticDependencyFunction, KeyTrie } from 'optimism'; import { equal } from '@wry/equality'; +import { invariant } from 'ts-invariant'; import { isReference, @@ -84,7 +85,11 @@ export abstract class EntityStore implements NormalizedCache { public merge(dataId: string, incoming: StoreObject): void { const existing = this.lookup(dataId); - const merged = new DeepMerger(storeObjectReconciler).merge(existing, incoming); + const merged = new DeepMerger(storeObjectReconciler).merge( + existing, + incoming, + this.getFieldValue, + ); // Even if merged === existing, existing may have come from a lower // layer, so we always need to set this.data[dataId] on this level. this.data[dataId] = merged; @@ -513,16 +518,105 @@ class Layer extends EntityStore { function storeObjectReconciler( existingObject: StoreObject, incomingObject: StoreObject, - property: string | number, + property: string, + getFieldValue: FieldValueGetter, ): StoreValue { const existingValue = existingObject[property]; const incomingValue = incomingObject[property]; + // Wherever there is a key collision, prefer the incoming value, unless // it is deeply equal to the existing value. It's worth checking deep // equality here (even though blindly returning incoming would be // logically correct) because preserving the referential identity of // existing data can prevent needless rereading and rerendering. - return equal(existingValue, incomingValue) ? existingValue : incomingValue; + if (equal(existingValue, incomingValue)) { + return existingValue; + } + + if (process.env.NODE_ENV !== "production") { + warnAboutDataLoss(existingObject, incomingObject, property, getFieldValue); + } + + return incomingValue; +} + +const warnings = new Set(); + +// Note that this function is unused in production, and thus should be +// pruned by any well-configured minifier. +function warnAboutDataLoss( + existingObject: StoreObject | Reference, + incomingObject: StoreObject | Reference, + storeFieldName: string, + getFieldValue: FieldValueGetter, +) { + const getChild = (objOrRef: StoreObject | Reference): StoreObject | false => { + const child = getFieldValue(objOrRef, storeFieldName); + return typeof child === "object" && child; + }; + + const existing = getChild(existingObject); + if (!existing) return; + + const incoming = getChild(incomingObject); + if (!incoming) return; + + // It's always safe to replace a reference, since it refers to data + // safely stored elsewhere. + if (isReference(existing)) return; + + // If we're replacing every key of the existing object, then the + // existing data would be overwritten even if the objects were + // normalized, so warning would not be helpful here. + if (Object.keys(existing).every( + key => getFieldValue(incoming, key) !== void 0)) { + return; + } + + const parentType = + getFieldValue(existingObject, "__typename") || + getFieldValue(incomingObject, "__typename"); + + const fieldName = fieldNameFromStoreName(storeFieldName); + const typeDotName = `${parentType}.${fieldName}`; + + if (warnings.has(typeDotName)) return; + warnings.add(typeDotName); + + const childTypenames: string[] = []; + // Arrays do not have __typename fields, and always need a custom merge + // function, even if their elements are normalized entities. + if (!Array.isArray(existing) && + !Array.isArray(incoming)) { + [existing, incoming].forEach(child => { + const typename = getFieldValue(child, "__typename"); + if (typeof typename === "string" && + !childTypenames.includes(typename)) { + childTypenames.push(typename); + } + }); + } + + invariant.warn( +`Cache data may be lost when replacing the ${fieldName} field of a ${parentType} object. + +To address this problem (which is not a bug in Apollo Client), ${ + childTypenames.length + ? "either ensure all objects of type " + + childTypenames.join(" and ") + " have IDs, or " + : "" +}define a custom merge function for the ${ + typeDotName +} field, so InMemoryCache can safely merge these objects: + + existing: ${JSON.stringify(existing).slice(0, 1000)} + incoming: ${JSON.stringify(incoming).slice(0, 1000)} + +For more information about these options, please refer to the documentation: + + * Ensuring entity objects have IDs: https://go.apollo.dev/c/generating-unique-identifiers + * Defining custom merge functions: https://go.apollo.dev/c/merging-non-normalized-objects +`); } export function supportsResultCaching(store: any): store is EntityStore { From ca710a2bb28e98d61122542777355f6ed6063318 Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Mon, 1 Jun 2020 17:00:25 -0400 Subject: [PATCH 34/56] Ensure isReference always returns boolean value. --- src/utilities/graphql/storeUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utilities/graphql/storeUtils.ts b/src/utilities/graphql/storeUtils.ts index 7076017e08d..31c9513fb8d 100644 --- a/src/utilities/graphql/storeUtils.ts +++ b/src/utilities/graphql/storeUtils.ts @@ -30,7 +30,7 @@ export function makeReference(id: string): Reference { } export function isReference(obj: any): obj is Reference { - return obj && typeof obj === 'object' && typeof obj.__ref === 'string'; + return Boolean(obj && typeof obj === 'object' && typeof obj.__ref === 'string'); } export type StoreValue = From 7b8c8ea0808610937aff4fc5cd4e0413b84448c8 Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Mon, 1 Jun 2020 16:47:42 -0400 Subject: [PATCH 35/56] Avoid warning about fields that have custom merge functions. --- src/cache/inmemory/entityStore.ts | 38 ++++++++++++++++++------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/src/cache/inmemory/entityStore.ts b/src/cache/inmemory/entityStore.ts index 4b7f7e9394d..7235edd23bb 100644 --- a/src/cache/inmemory/entityStore.ts +++ b/src/cache/inmemory/entityStore.ts @@ -85,11 +85,8 @@ export abstract class EntityStore implements NormalizedCache { public merge(dataId: string, incoming: StoreObject): void { const existing = this.lookup(dataId); - const merged = new DeepMerger(storeObjectReconciler).merge( - existing, - incoming, - this.getFieldValue, - ); + const merged = new DeepMerger(storeObjectReconciler) + .merge(existing, incoming, this); // Even if merged === existing, existing may have come from a lower // layer, so we always need to set this.data[dataId] on this level. this.data[dataId] = merged; @@ -519,7 +516,7 @@ function storeObjectReconciler( existingObject: StoreObject, incomingObject: StoreObject, property: string, - getFieldValue: FieldValueGetter, + store: EntityStore, ): StoreValue { const existingValue = existingObject[property]; const incomingValue = incomingObject[property]; @@ -534,7 +531,7 @@ function storeObjectReconciler( } if (process.env.NODE_ENV !== "production") { - warnAboutDataLoss(existingObject, incomingObject, property, getFieldValue); + warnAboutDataLoss(existingObject, incomingObject, property, store); } return incomingValue; @@ -548,10 +545,10 @@ function warnAboutDataLoss( existingObject: StoreObject | Reference, incomingObject: StoreObject | Reference, storeFieldName: string, - getFieldValue: FieldValueGetter, + store: EntityStore, ) { const getChild = (objOrRef: StoreObject | Reference): StoreObject | false => { - const child = getFieldValue(objOrRef, storeFieldName); + const child = store.getFieldValue(objOrRef, storeFieldName); return typeof child === "object" && child; }; @@ -565,19 +562,28 @@ function warnAboutDataLoss( // safely stored elsewhere. if (isReference(existing)) return; + const parentType = + store.getFieldValue(existingObject, "__typename") || + store.getFieldValue(incomingObject, "__typename"); + + const fieldName = fieldNameFromStoreName(storeFieldName); + + if (parentType && + fieldName && + store.policies.hasMergeFunction(parentType, fieldName)) { + // If a merge function is defined for this field within this type, + // trust it to do the right thing about (not) clobbering data. + return; + } + // If we're replacing every key of the existing object, then the // existing data would be overwritten even if the objects were // normalized, so warning would not be helpful here. if (Object.keys(existing).every( - key => getFieldValue(incoming, key) !== void 0)) { + key => store.getFieldValue(incoming, key) !== void 0)) { return; } - const parentType = - getFieldValue(existingObject, "__typename") || - getFieldValue(incomingObject, "__typename"); - - const fieldName = fieldNameFromStoreName(storeFieldName); const typeDotName = `${parentType}.${fieldName}`; if (warnings.has(typeDotName)) return; @@ -589,7 +595,7 @@ function warnAboutDataLoss( if (!Array.isArray(existing) && !Array.isArray(incoming)) { [existing, incoming].forEach(child => { - const typename = getFieldValue(child, "__typename"); + const typename = store.getFieldValue(child, "__typename"); if (typeof typename === "string" && !childTypenames.includes(typename)) { childTypenames.push(typename); From 9ef581f665d878aa820350a22b49c62a8c47c3a6 Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Mon, 1 Jun 2020 16:37:37 -0400 Subject: [PATCH 36/56] Fix tests that display data-clobbering warnings. --- src/__tests__/ApolloClient.ts | 30 ++- src/__tests__/optimistic.ts | 14 ++ src/cache/inmemory/__tests__/cache.ts | 187 ++++++++++--------- src/cache/inmemory/__tests__/writeToStore.ts | 163 +++++++++++----- src/core/__tests__/QueryManager/index.ts | 33 +++- 5 files changed, 291 insertions(+), 136 deletions(-) diff --git a/src/__tests__/ApolloClient.ts b/src/__tests__/ApolloClient.ts index 8268ec5d0b3..44ce8ff0c10 100644 --- a/src/__tests__/ApolloClient.ts +++ b/src/__tests__/ApolloClient.ts @@ -668,7 +668,21 @@ describe('ApolloClient', () => { it('will write some deeply nested data to the store', () => { const client = new ApolloClient({ link: ApolloLink.empty(), - cache: new InMemoryCache(), + cache: new InMemoryCache({ + typePolicies: { + Query: { + fields: { + d: { + // Silence "Cache data may be lost..." warnings by + // unconditionally favoring the incoming data. + merge(_, incoming) { + return incoming; + }, + }, + }, + }, + }, + }), }); client.writeQuery({ @@ -1171,6 +1185,20 @@ describe('ApolloClient', () => { return new ApolloClient({ link, cache: new InMemoryCache({ + typePolicies: { + Person: { + fields: { + friends: { + // Deliberately silence "Cache data may be lost..." + // warnings by preferring the incoming data, rather + // than (say) concatenating the arrays together. + merge(_, incoming) { + return incoming; + }, + }, + }, + }, + }, dataIdFromObject: result => { if (result.id && result.__typename) { return result.__typename + result.id; diff --git a/src/__tests__/optimistic.ts b/src/__tests__/optimistic.ts index 283450789d4..360f0c81913 100644 --- a/src/__tests__/optimistic.ts +++ b/src/__tests__/optimistic.ts @@ -110,6 +110,20 @@ describe('optimistic mutation results', () => { const client = new ApolloClient({ link, cache: new InMemoryCache({ + typePolicies: { + TodoList: { + fields: { + todos: { + // Deliberately silence "Cache data may be lost..." + // warnings by favoring the incoming data, rather than + // (say) concatenating the arrays together. + merge(_, incoming) { + return incoming; + }, + }, + }, + }, + }, dataIdFromObject: (obj: any) => { if (obj.id && obj.__typename) { return obj.__typename + obj.id; diff --git a/src/cache/inmemory/__tests__/cache.ts b/src/cache/inmemory/__tests__/cache.ts index 1de403b5ae4..d4451c3f62d 100644 --- a/src/cache/inmemory/__tests__/cache.ts +++ b/src/cache/inmemory/__tests__/cache.ts @@ -28,9 +28,8 @@ describe('Cache', () => { ]; cachesList.forEach((caches, i) => { - it(message + ` (${i + 1}/${cachesList.length})`, () => - callback(...caches), - ); + it(`${message} (${i + 1}/${cachesList.length})`, + () => callback(...caches)); }); } @@ -869,106 +868,118 @@ describe('Cache', () => { }); }); - itWithInitialData( - 'will write some deeply nested data to the store', - [{}], - proxy => { - proxy.writeQuery({ - data: { a: 1, d: { e: 4 } }, - query: gql` - { - a - d { - e - } + it('will write some deeply nested data to the store', () => { + const cache = new InMemoryCache({ + typePolicies: { + Query: { + fields: { + d: { + // Deliberately silence "Cache data may be lost..." + // warnings by unconditionally favoring the incoming data. + merge(_, incoming) { + return incoming; + }, + }, + }, + }, + }, + }); + + cache.writeQuery({ + data: { a: 1, d: { e: 4 } }, + query: gql` + { + a + d { + e } - `, - }); + } + `, + }); - expect((proxy as InMemoryCache).extract()).toEqual({ - ROOT_QUERY: { - __typename: "Query", - a: 1, - d: { - e: 4, - }, + expect((cache as InMemoryCache).extract()).toEqual({ + ROOT_QUERY: { + __typename: "Query", + a: 1, + d: { + e: 4, }, - }); + }, + }); - proxy.writeQuery({ - data: { a: 1, d: { h: { i: 7 } } }, - query: gql` - { - a - d { - h { - i - } + cache.writeQuery({ + data: { a: 1, d: { h: { i: 7 } } }, + query: gql` + { + a + d { + h { + i } } - `, - }); + } + `, + }); - expect((proxy as InMemoryCache).extract()).toEqual({ - ROOT_QUERY: { - __typename: "Query", - a: 1, - // The new value for d overwrites the old value, since there - // is no custom merge function defined for Query.d. - d: { - h: { - i: 7, - }, + expect((cache as InMemoryCache).extract()).toEqual({ + ROOT_QUERY: { + __typename: "Query", + a: 1, + // The new value for d overwrites the old value, since there + // is no custom merge function defined for Query.d. + d: { + h: { + i: 7, }, }, - }); + }, + }); - proxy.writeQuery({ - data: { - a: 1, - b: 2, - c: 3, - d: { e: 4, f: 5, g: 6, h: { i: 7, j: 8, k: 9 } }, - }, - query: gql` - { - a - b - c - d { - e - f - g - h { - i - j - k - } + cache.writeQuery({ + data: { + a: 1, + b: 2, + c: 3, + d: { e: 4, f: 5, g: 6, h: { i: 7, j: 8, k: 9 } }, + }, + query: gql` + { + a + b + c + d { + e + f + g + h { + i + j + k } } - `, - }); + } + `, + }); - expect((proxy as InMemoryCache).extract()).toEqual({ - ROOT_QUERY: { - __typename: "Query", - a: 1, - b: 2, - c: 3, - d: { - e: 4, - f: 5, - g: 6, - h: { - i: 7, - j: 8, - k: 9, - }, + expect((cache as InMemoryCache).extract()).toEqual({ + ROOT_QUERY: { + __typename: "Query", + a: 1, + b: 2, + c: 3, + d: { + e: 4, + f: 5, + g: 6, + h: { + i: 7, + j: 8, + k: 9, }, }, - }); - }, - ); + }, + }); + }); itWithInitialData( 'will write some data to the store with variables', diff --git a/src/cache/inmemory/__tests__/writeToStore.ts b/src/cache/inmemory/__tests__/writeToStore.ts index 2f1fb476212..45464c376fc 100644 --- a/src/cache/inmemory/__tests__/writeToStore.ts +++ b/src/cache/inmemory/__tests__/writeToStore.ts @@ -1331,7 +1331,48 @@ describe('writing to the store', () => { } } `; - const expectedStoreWithoutId = defaultNormalizedCacheFactory({ + + const cache = new InMemoryCache({ + typePolicies: { + Query: { + fields: { + author: { + // Silence "Cache data may be lost..." warnings by always + // preferring the incoming value. + merge(existing, incoming, { readField, isReference }) { + if (existing) { + expect(isReference(existing)).toBe(false); + expect(readField({ + fieldName: "__typename", + from: existing, + })).toBe("Author"); + + expect(isReference(incoming)).toBe(true); + expect(readField({ + fieldName: "__typename", + from: incoming, + })).toBe("Author"); + } + + return incoming; + }, + }, + }, + }, + }, + dataIdFromObject(object: any) { + if (object.__typename && object.id) { + return object.__typename + '__' + object.id; + } + }, + }); + + cache.writeQuery({ + query: queryWithoutId, + data: dataWithoutId, + }); + + expect(cache.extract()).toEqual({ ROOT_QUERY: { __typename: 'Query', author: { @@ -1341,7 +1382,13 @@ describe('writing to the store', () => { }, }, }); - const expectedStoreWithId = defaultNormalizedCacheFactory({ + + cache.writeQuery({ + query: queryWithId, + data: dataWithId, + }); + + expect(cache.extract()).toEqual({ Author__129: { firstName: 'John', id: '129', @@ -1352,21 +1399,6 @@ describe('writing to the store', () => { author: makeReference('Author__129'), }, }); - - const storeWithoutId = writeQueryToStore({ - writer, - result: dataWithoutId, - query: queryWithoutId, - }); - expect(storeWithoutId.toObject()).toEqual(expectedStoreWithoutId.toObject()); - - const storeWithId = writeQueryToStore({ - writer, - result: dataWithId, - query: queryWithId, - store: storeWithoutId, - }); - expect(storeWithId.toObject()).toEqual(expectedStoreWithId.toObject()); }); it('should allow a union of objects of a different type, when overwriting a generated id with a real id', () => { @@ -1400,7 +1432,48 @@ describe('writing to the store', () => { } } `; - const expStoreWithPlaceholder = defaultNormalizedCacheFactory({ + + let mergeCount = 0; + const cache = new InMemoryCache({ + typePolicies: { + Query: { + fields: { + author: { + merge(existing, incoming, { isReference, readField }) { + switch (++mergeCount) { + case 1: + expect(existing).toBeUndefined(); + expect(isReference(incoming)).toBe(false); + expect(incoming).toEqual(dataWithPlaceholder.author); + break; + case 2: + expect(existing).toEqual(dataWithPlaceholder.author); + expect(isReference(incoming)).toBe(true); + expect(readField("__typename", incoming)).toBe("Author"); + break; + case 3: + expect(isReference(existing)).toBe(true); + expect(readField("__typename", existing)).toBe("Author"); + expect(incoming).toEqual(dataWithPlaceholder.author); + break; + default: + fail("unreached"); + } + return incoming; + }, + }, + }, + }, + }, + }); + + // write the first object, without an ID, placeholder + cache.writeQuery({ + query, + data: dataWithPlaceholder, + }); + + expect(cache.extract()).toEqual({ ROOT_QUERY: { __typename: 'Query', author: { @@ -1409,8 +1482,15 @@ describe('writing to the store', () => { }, }, }); - const expStoreWithAuthor = defaultNormalizedCacheFactory({ - Author__129: { + + // replace with another one of different type with ID + cache.writeQuery({ + query, + data: dataWithAuthor, + }); + + expect(cache.extract()).toEqual({ + "Author:129": { firstName: 'John', lastName: 'Smith', id: '129', @@ -1418,40 +1498,33 @@ describe('writing to the store', () => { }, ROOT_QUERY: { __typename: 'Query', - author: makeReference('Author__129'), + author: makeReference('Author:129'), }, }); - // write the first object, without an ID, placeholder - const store = writeQueryToStore({ - writer, - result: dataWithPlaceholder, - query, - }); - expect(store.toObject()).toEqual(expStoreWithPlaceholder.toObject()); - - // replace with another one of different type with ID - writeQueryToStore({ - writer, - result: dataWithAuthor, - query, - store, - }); - expect(store.toObject()).toEqual(expStoreWithAuthor.toObject()); - // and go back to the original: - writeQueryToStore({ - writer, - result: dataWithPlaceholder, + cache.writeQuery({ query, - store, + data: dataWithPlaceholder, }); + // Author__129 will remain in the store, // but will not be referenced by any of the fields, // hence we combine, and in that very order - expect(store.toObject()).toEqual({ - ...expStoreWithAuthor.toObject(), - ...expStoreWithPlaceholder.toObject(), + expect(cache.extract()).toEqual({ + "Author:129": { + firstName: 'John', + lastName: 'Smith', + id: '129', + __typename: 'Author', + }, + ROOT_QUERY: { + __typename: 'Query', + author: { + hello: 'Foo', + __typename: 'Placeholder', + }, + }, }); }); diff --git a/src/core/__tests__/QueryManager/index.ts b/src/core/__tests__/QueryManager/index.ts index 53994f1aff7..e407fd6d700 100644 --- a/src/core/__tests__/QueryManager/index.ts +++ b/src/core/__tests__/QueryManager/index.ts @@ -8,7 +8,7 @@ import { DocumentNode, GraphQLError } from 'graphql'; import { Observable, Observer } from '../../../utilities/observables/Observable'; import { ApolloLink } from '../../../link/core/ApolloLink'; import { GraphQLRequest, FetchResult } from '../../../link/core/types'; -import { InMemoryCache } from '../../../cache/inmemory/inMemoryCache'; +import { InMemoryCache, InMemoryCacheConfig } from '../../../cache/inmemory/inMemoryCache'; import { ApolloReducerConfig, NormalizedCacheObject @@ -64,7 +64,7 @@ describe('QueryManager', () => { clientAwareness = {}, }: { link: ApolloLink; - config?: ApolloReducerConfig; + config?: Partial; clientAwareness?: { [key: string]: string }; }) => { return new QueryManager({ @@ -2210,6 +2210,7 @@ describe('QueryManager', () => { }, }; + let mergeCount = 0; const queryManager = createQueryManager({ link: mockSingleLink({ request: { query: queryWithoutId }, @@ -2218,6 +2219,34 @@ describe('QueryManager', () => { request: { query: queryWithId }, result: { data: dataWithId }, }).setOnError(reject), + config: { + typePolicies: { + Query: { + fields: { + author: { + merge(existing, incoming, { isReference, readField }) { + switch (++mergeCount) { + case 1: + expect(existing).toBeUndefined(); + expect(isReference(incoming)).toBe(false); + expect(incoming).toEqual(dataWithoutId.author); + break; + case 2: + expect(existing).toEqual(dataWithoutId.author); + expect(isReference(incoming)).toBe(true); + expect(readField("id", incoming)).toBe("129"); + expect(readField("name", incoming)).toEqual(dataWithId.author.name); + break; + default: + fail("unreached"); + } + return incoming; + }, + }, + }, + }, + }, + }, }); const observableWithId = queryManager.watchQuery({ From c0c13b811a44546d5a60bb5622930ec180191d16 Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Mon, 1 Jun 2020 18:11:11 -0400 Subject: [PATCH 37/56] Move warnAboutDataLoss call into StoreWriter#processSelectionSet. Since cache.modify calls cache.merge, and we don't want cache.modify ever to trigger "Cache data may be lost..." warnings, it's more convenient if the StoreWriter is responsible for calling warnAboutDataLoss, rather than always performing that check in cache.merge. --- src/cache/inmemory/entityStore.ts | 104 +---------------------------- src/cache/inmemory/writeToStore.ts | 98 ++++++++++++++++++++++++++- 2 files changed, 98 insertions(+), 104 deletions(-) diff --git a/src/cache/inmemory/entityStore.ts b/src/cache/inmemory/entityStore.ts index 7235edd23bb..763d77d5f2f 100644 --- a/src/cache/inmemory/entityStore.ts +++ b/src/cache/inmemory/entityStore.ts @@ -1,6 +1,5 @@ import { dep, OptimisticDependencyFunction, KeyTrie } from 'optimism'; import { equal } from '@wry/equality'; -import { invariant } from 'ts-invariant'; import { isReference, @@ -85,8 +84,7 @@ export abstract class EntityStore implements NormalizedCache { public merge(dataId: string, incoming: StoreObject): void { const existing = this.lookup(dataId); - const merged = new DeepMerger(storeObjectReconciler) - .merge(existing, incoming, this); + const merged = new DeepMerger(storeObjectReconciler).merge(existing, incoming); // Even if merged === existing, existing may have come from a lower // layer, so we always need to set this.data[dataId] on this level. this.data[dataId] = merged; @@ -516,113 +514,15 @@ function storeObjectReconciler( existingObject: StoreObject, incomingObject: StoreObject, property: string, - store: EntityStore, ): StoreValue { const existingValue = existingObject[property]; const incomingValue = incomingObject[property]; - // Wherever there is a key collision, prefer the incoming value, unless // it is deeply equal to the existing value. It's worth checking deep // equality here (even though blindly returning incoming would be // logically correct) because preserving the referential identity of // existing data can prevent needless rereading and rerendering. - if (equal(existingValue, incomingValue)) { - return existingValue; - } - - if (process.env.NODE_ENV !== "production") { - warnAboutDataLoss(existingObject, incomingObject, property, store); - } - - return incomingValue; -} - -const warnings = new Set(); - -// Note that this function is unused in production, and thus should be -// pruned by any well-configured minifier. -function warnAboutDataLoss( - existingObject: StoreObject | Reference, - incomingObject: StoreObject | Reference, - storeFieldName: string, - store: EntityStore, -) { - const getChild = (objOrRef: StoreObject | Reference): StoreObject | false => { - const child = store.getFieldValue(objOrRef, storeFieldName); - return typeof child === "object" && child; - }; - - const existing = getChild(existingObject); - if (!existing) return; - - const incoming = getChild(incomingObject); - if (!incoming) return; - - // It's always safe to replace a reference, since it refers to data - // safely stored elsewhere. - if (isReference(existing)) return; - - const parentType = - store.getFieldValue(existingObject, "__typename") || - store.getFieldValue(incomingObject, "__typename"); - - const fieldName = fieldNameFromStoreName(storeFieldName); - - if (parentType && - fieldName && - store.policies.hasMergeFunction(parentType, fieldName)) { - // If a merge function is defined for this field within this type, - // trust it to do the right thing about (not) clobbering data. - return; - } - - // If we're replacing every key of the existing object, then the - // existing data would be overwritten even if the objects were - // normalized, so warning would not be helpful here. - if (Object.keys(existing).every( - key => store.getFieldValue(incoming, key) !== void 0)) { - return; - } - - const typeDotName = `${parentType}.${fieldName}`; - - if (warnings.has(typeDotName)) return; - warnings.add(typeDotName); - - const childTypenames: string[] = []; - // Arrays do not have __typename fields, and always need a custom merge - // function, even if their elements are normalized entities. - if (!Array.isArray(existing) && - !Array.isArray(incoming)) { - [existing, incoming].forEach(child => { - const typename = store.getFieldValue(child, "__typename"); - if (typeof typename === "string" && - !childTypenames.includes(typename)) { - childTypenames.push(typename); - } - }); - } - - invariant.warn( -`Cache data may be lost when replacing the ${fieldName} field of a ${parentType} object. - -To address this problem (which is not a bug in Apollo Client), ${ - childTypenames.length - ? "either ensure all objects of type " + - childTypenames.join(" and ") + " have IDs, or " - : "" -}define a custom merge function for the ${ - typeDotName -} field, so InMemoryCache can safely merge these objects: - - existing: ${JSON.stringify(existing).slice(0, 1000)} - incoming: ${JSON.stringify(incoming).slice(0, 1000)} - -For more information about these options, please refer to the documentation: - - * Ensuring entity objects have IDs: https://go.apollo.dev/c/generating-unique-identifiers - * Defining custom merge functions: https://go.apollo.dev/c/merging-non-normalized-objects -`); + return equal(existingValue, incomingValue) ? existingValue : incomingValue; } export function supportsResultCaching(store: any): store is EntityStore { diff --git a/src/cache/inmemory/writeToStore.ts b/src/cache/inmemory/writeToStore.ts index 774f53bb480..e0238d15272 100644 --- a/src/cache/inmemory/writeToStore.ts +++ b/src/cache/inmemory/writeToStore.ts @@ -1,5 +1,5 @@ import { SelectionSetNode, FieldNode, DocumentNode } from 'graphql'; -import { InvariantError } from 'ts-invariant'; +import { invariant, InvariantError } from 'ts-invariant'; import { createFragmentMap, @@ -29,7 +29,7 @@ import { cloneDeep } from '../../utilities/common/cloneDeep'; import { ReadMergeContext } from './policies'; import { NormalizedCache } from './types'; -import { makeProcessedFieldsMerger, FieldValueToBeMerged } from './helpers'; +import { makeProcessedFieldsMerger, FieldValueToBeMerged, fieldNameFromStoreName } from './helpers'; import { StoreReader } from './readFromStore'; import { InMemoryCache } from './inMemoryCache'; @@ -271,6 +271,22 @@ export class StoreWriter { mergedFields = policies.applyMerges(entityRef, mergedFields, context); } + if (process.env.NODE_ENV !== "production") { + Object.keys(mergedFields).forEach(storeFieldName => { + const fieldName = fieldNameFromStoreName(storeFieldName); + // If a merge function was defined for this field, trust that it + // did the right thing about (not) clobbering data. + if (!policies.hasMergeFunction(typename, fieldName)) { + warnAboutDataLoss( + entityRef, + mergedFields, + storeFieldName, + context.store, + ); + } + }); + } + context.store.merge(dataId, mergedFields); return entityRef; @@ -304,3 +320,81 @@ export class StoreWriter { }); } } + +const warnings = new Set(); + +// Note that this function is unused in production, and thus should be +// pruned by any well-configured minifier. +function warnAboutDataLoss( + existingRef: Reference, + incomingObj: StoreObject, + storeFieldName: string, + store: NormalizedCache, +) { + const getChild = (objOrRef: StoreObject | Reference): StoreObject | false => { + const child = store.getFieldValue(objOrRef, storeFieldName); + return typeof child === "object" && child; + }; + + const existing = getChild(existingRef); + if (!existing) return; + + const incoming = getChild(incomingObj); + if (!incoming) return; + + // It's always safe to replace a reference, since it refers to data + // safely stored elsewhere. + if (isReference(existing)) return; + + // If we're replacing every key of the existing object, then the + // existing data would be overwritten even if the objects were + // normalized, so warning would not be helpful here. + if (Object.keys(existing).every( + key => store.getFieldValue(incoming, key) !== void 0)) { + return; + } + + const parentType = + store.getFieldValue(existingRef, "__typename") || + store.getFieldValue(incomingObj, "__typename"); + const fieldName = fieldNameFromStoreName(storeFieldName); + const typeDotName = `${parentType}.${fieldName}`; + // Avoid warning more than once for the same type and field name. + if (warnings.has(typeDotName)) return; + warnings.add(typeDotName); + + const childTypenames: string[] = []; + // Arrays do not have __typename fields, and always need a custom merge + // function, even if their elements are normalized entities. + if (!Array.isArray(existing) && + !Array.isArray(incoming)) { + [existing, incoming].forEach(child => { + const typename = store.getFieldValue(child, "__typename"); + if (typeof typename === "string" && + !childTypenames.includes(typename)) { + childTypenames.push(typename); + } + }); + } + + invariant.warn( +`Cache data may be lost when replacing the ${fieldName} field of a ${parentType} object. + +To address this problem (which is not a bug in Apollo Client), ${ + childTypenames.length + ? "either ensure all objects of type " + + childTypenames.join(" and ") + " have IDs, or " + : "" +}define a custom merge function for the ${ + typeDotName +} field, so InMemoryCache can safely merge these objects: + + existing: ${JSON.stringify(existing).slice(0, 1000)} + incoming: ${JSON.stringify(incoming).slice(0, 1000)} + +For more information about these options, please refer to the documentation: + + * Ensuring entity objects have IDs: https://go.apollo.dev/c/generating-unique-identifiers + * Defining custom merge functions: https://go.apollo.dev/c/merging-non-normalized-objects +`); +} From cd6df79a1a890a4d26e470d66c177b51b020df9d Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Mon, 1 Jun 2020 18:33:00 -0400 Subject: [PATCH 38/56] Mention PR #6372 in CHANGELOG.md. --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d3c316a6e3f..00c2cd8bd6e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -66,6 +66,9 @@ - Cache methods that would normally trigger a broadcast, like `cache.evict`, `cache.writeQuery`, and `cache.writeFragment`, can now be called with a named options object, which supports a `broadcast: boolean` property that can be used to silence the broadcast, for situations where you want to update the cache multiple times without triggering a broadcast each time.
[@benjamn](https://github.com/benjamn) in [#6288](https://github.com/apollographql/apollo-client/pull/6288) +- `InMemoryCache` now `console.warn`s in development whenever non-normalized data is dangerously overwritten, with helpful links to documentation about normalization and custom `merge` functions.
+ [@benjamn](https://github.com/benjamn) in [#6372](https://github.com/apollographql/apollo-client/pull/6372) + - The contents of the `@apollo/react-hooks` package have been merged into `@apollo/client`, enabling the following all-in-one `import`: ```ts import { ApolloClient, ApolloProvider, useQuery } from '@apollo/client'; From 96a591aafd2016b879227b9f8c365149d05589d7 Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Mon, 1 Jun 2020 19:02:15 -0400 Subject: [PATCH 39/56] Skip warning about clobbering deeply equal data. This should have been part of #6372 (just merged). --- src/cache/inmemory/writeToStore.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/cache/inmemory/writeToStore.ts b/src/cache/inmemory/writeToStore.ts index e0238d15272..e511e694980 100644 --- a/src/cache/inmemory/writeToStore.ts +++ b/src/cache/inmemory/writeToStore.ts @@ -1,5 +1,6 @@ import { SelectionSetNode, FieldNode, DocumentNode } from 'graphql'; import { invariant, InvariantError } from 'ts-invariant'; +import { equal } from '@wry/equality'; import { createFragmentMap, @@ -346,6 +347,10 @@ function warnAboutDataLoss( // safely stored elsewhere. if (isReference(existing)) return; + // If the values are structurally equivalent, we do not need to worry + // about incoming replacing existing. + if (equal(existing, incoming)) return; + // If we're replacing every key of the existing object, then the // existing data would be overwritten even if the objects were // normalized, so warning would not be helpful here. From 2b798bcde7d842b4aa051f5454a3e10494635ddf Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Mon, 1 Jun 2020 19:06:31 -0400 Subject: [PATCH 40/56] Bump @apollo/client npm version to 3.0.0-beta.54. --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4662425db08..4ae6716e07a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@apollo/client", - "version": "3.0.0-beta.53", + "version": "3.0.0-beta.54", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index e8317126341..bf872377b18 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@apollo/client", - "version": "3.0.0-beta.53", + "version": "3.0.0-beta.54", "description": "A fully-featured caching GraphQL client.", "private": true, "keywords": [ From 8f3e2e7e0d8c859d61ec2ddb57a7e40f70f46326 Mon Sep 17 00:00:00 2001 From: Davy Hausser Date: Tue, 2 Jun 2020 17:15:02 +0200 Subject: [PATCH 41/56] Fixed typo in testing.mdx (#6337) Typo in second paragraph, changed "functoinality" to "functionality". --- docs/source/development-testing/testing.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/development-testing/testing.mdx b/docs/source/development-testing/testing.mdx index a69b56e4ce5..17cba509314 100644 --- a/docs/source/development-testing/testing.mdx +++ b/docs/source/development-testing/testing.mdx @@ -7,7 +7,7 @@ import { MultiCodeBlock } from 'gatsby-theme-apollo-docs'; Running tests against code meant for production has long been a best practice. It provides additional security for the code that's already written, and prevents accidental regressions in the future. Components utilizing React with Apollo Client are no exception. -Although Apollo Client's React integration has a lot going on under the hood, the library provides multiple tools for testing that simplify those abstractions, and allows complete focus on the component logic. These testing utilities have long been used to test React functoinality with Apollo Client itself, so they will be supported long-term. +Although Apollo Client's React integration has a lot going on under the hood, the library provides multiple tools for testing that simplify those abstractions, and allows complete focus on the component logic. These testing utilities have long been used to test React functionality with Apollo Client itself, so they will be supported long-term. ## An introduction From ad1a0a81149295d897a3cf5dc76abef460ba35da Mon Sep 17 00:00:00 2001 From: Fumiaki MATSUSHIMA Date: Wed, 3 Jun 2020 00:21:52 +0900 Subject: [PATCH 42/56] Update .vscode/launch.json to match official recipe (#6323) --- .vscode/launch.json | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index c68c3827db4..da88fd670e3 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -2,17 +2,21 @@ "version": "0.2.0", "configurations": [ { - "name": "Test", - "request": "launch", "type": "node", - "program": - "${workspaceRoot}/packages/apollo-client/node_modules/jest/bin/jest.js", - "internalConsoleOptions": "openOnSessionStart", - "stopOnEntry": false, - "args": ["-i"], - "cwd": "${workspaceRoot}/packages/apollo-client", - "sourceMaps": true, - "outFiles": ["${workspaceRoot}/lib/**/*"] + "request": "launch", + "name": "Jest Current File", + "program": "${workspaceFolder}/node_modules/.bin/jest", + "args": [ + "${fileBasenameNoExtension}", + "--config", + "./config/jest.config.js" + ], + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen", + "disableOptimisticBPs": true, + "windows": { + "program": "${workspaceFolder}/node_modules/jest/bin/jest", + } } ] } From 89546db82d15e64b54314ea3a2253cf793f8952e Mon Sep 17 00:00:00 2001 From: Michael Haglund Date: Tue, 2 Jun 2020 10:37:53 -0500 Subject: [PATCH 43/56] Update graphql dependencies to accommodate 15.0.0 (#6328) Update graphql dependencies to accommodate 15.0.0. Co-authored-by: hwillson --- CHANGELOG.md | 3 ++- package-lock.json | 67 ++++++++++++++++++++--------------------------- package.json | 4 +-- 3 files changed, 33 insertions(+), 41 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 00c2cd8bd6e..55dc17080f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -164,7 +164,8 @@ [@justinwaite](https://github.com/justinwaite) in [#5974](https://github.com/apollographql/apollo-client/pull/5974) - Updated to work with `graphql@15`.
- [@durchanek](https://github.com/durchanek) in [#6194](https://github.com/apollographql/apollo-client/pull/6194) and [#6279](https://github.com/apollographql/apollo-client/pull/6279) + [@durchanek](https://github.com/durchanek) in [#6194](https://github.com/apollographql/apollo-client/pull/6194) and [#6279](https://github.com/apollographql/apollo-client/pull/6279)
+ [@hagmic](https://github.com/hagmic) in [#6328](https://github.com/apollographql/apollo-client/pull/6328) ### Bug Fixes diff --git a/package-lock.json b/package-lock.json index 4ae6716e07a..c28f8ea3bc0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,19 +14,19 @@ } }, "@babel/core": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.10.1.tgz", - "integrity": "sha512-u8XiZ6sMXW/gPmoP5ijonSUln4unazG291X0XAQ5h0s8qnAFr6BRRZGUEK+jtRWdmB0NTJQt7Uga25q8GetIIg==", + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.10.2.tgz", + "integrity": "sha512-KQmV9yguEjQsXqyOUGKjS4+3K8/DlOCE2pZcq4augdQmtTy5iv5EHtmMSJ7V4c1BIPjuwtZYqYLCq9Ga+hGBRQ==", "dev": true, "requires": { "@babel/code-frame": "^7.10.1", - "@babel/generator": "^7.10.1", + "@babel/generator": "^7.10.2", "@babel/helper-module-transforms": "^7.10.1", "@babel/helpers": "^7.10.1", - "@babel/parser": "^7.10.1", + "@babel/parser": "^7.10.2", "@babel/template": "^7.10.1", "@babel/traverse": "^7.10.1", - "@babel/types": "^7.10.1", + "@babel/types": "^7.10.2", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.1", @@ -107,12 +107,12 @@ } }, "@babel/generator": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.1.tgz", - "integrity": "sha512-AT0YPLQw9DI21tliuJIdplVfLHya6mcGa8ctkv7n4Qv+hYacJrKmNWIteAK1P9iyLikFIAkwqJ7HAOqIDLFfgA==", + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.2.tgz", + "integrity": "sha512-AxfBNHNu99DTMvlUPlt1h2+Hn7knPpH5ayJ8OqDWSeLld+Fi2AYBTC/IejWDM9Edcii4UzZRCsbUt0WlSDsDsA==", "dev": true, "requires": { - "@babel/types": "^7.10.1", + "@babel/types": "^7.10.2", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" @@ -282,9 +282,9 @@ } }, "@babel/parser": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.1.tgz", - "integrity": "sha512-AUTksaz3FqugBkbTZ1i+lDLG5qy8hIzCaAxEtttU6C0BtZZU9pkNZtWSVAht4EW9kl46YBiyTGMp9xTTGqViNg==", + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.2.tgz", + "integrity": "sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==", "dev": true }, "@babel/plugin-syntax-async-generators": { @@ -536,9 +536,9 @@ } }, "@babel/types": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.1.tgz", - "integrity": "sha512-L2yqUOpf3tzlW9GVuipgLEcZxnO+96SzR6fjXMuxxNkIgFJ5+07mHCZ+HkHqaeZu8+3LKnNJJ1bKbjBETQAsrA==", + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", + "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.1", @@ -1361,9 +1361,9 @@ } }, "@types/babel__core": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.7.tgz", - "integrity": "sha512-RL62NqSFPCDK2FM1pSDH0scHpJvsXtZNiYlMB73DgPBaG1E38ZYVL+ei5EkWRbr+KC4YNiAUNBnRj+bgwpgjMw==", + "version": "7.1.8", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.8.tgz", + "integrity": "sha512-KXBiQG2OXvaPWFPDS1rD8yV9vO0OuWIqAEqLsbfX0oU2REN5KuoMnZ1gClWcBhO5I3n6oTVAmrMufOvRqdmFTQ==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -1393,9 +1393,9 @@ } }, "@types/babel__traverse": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.11.tgz", - "integrity": "sha512-ddHK5icION5U6q11+tV2f9Mo6CZVuT8GJKld2q9LqHSZbvLbH34Kcu2yFGckZut453+eQU6btIA3RihmnRgI+Q==", + "version": "7.0.12", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.12.tgz", + "integrity": "sha512-t4CoEokHTfcyfb4hUaF9oOHu9RmmNWnm1CP0YmMqOOfClKascOmvlEM736vlqeScuGvBDsHkf8R2INd4DWreQA==", "dev": true, "requires": { "@babel/types": "^7.3.0" @@ -3301,13 +3301,10 @@ "dev": true }, "graphql": { - "version": "14.6.0", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-14.6.0.tgz", - "integrity": "sha512-VKzfvHEKybTKjQVpTFrA5yUq2S9ihcZvfJAtsDBBCuV6wauPu1xl/f9ehgVf0FcEJJs4vz6ysb/ZMkGigQZseg==", - "dev": true, - "requires": { - "iterall": "^1.2.2" - } + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.0.0.tgz", + "integrity": "sha512-ZyVO1xIF9F+4cxfkdhOJINM+51B06Friuv4M66W7HzUOeFd+vNzUn4vtswYINPi6sysjf1M2Ri/rwZALqgwbaQ==", + "dev": true }, "graphql-tag": { "version": "2.10.3", @@ -3811,12 +3808,6 @@ "istanbul-lib-report": "^3.0.0" } }, - "iterall": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.3.0.tgz", - "integrity": "sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg==", - "dev": true - }, "jest": { "version": "26.0.1", "resolved": "https://registry.npmjs.org/jest/-/jest-26.0.1.tgz", @@ -5988,9 +5979,9 @@ "dev": true }, "json5": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.2.tgz", - "integrity": "sha512-MoUOQ4WdiN3yxhm7NEVJSJrieAo5hNSLQ5sj05OTRHPL9HOBy8u4Bu88jsC1jvqAdN+E1bJmsUcZH+1HQxliqQ==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", "dev": true, "requires": { "minimist": "^1.2.5" diff --git a/package.json b/package.json index bf872377b18..2fefd6ec329 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ } ], "peerDependencies": { - "graphql": "^14.5.4", + "graphql": "^14.0.0 || ^15.0.0", "react": "^16.8.0" }, "peerDependenciesMeta": { @@ -86,7 +86,7 @@ "bundlesize": "0.18.0", "cross-fetch": "3.0.4", "fetch-mock": "7.7.3", - "graphql": "14.6.0", + "graphql": "15.0.0", "jest": "26.0.1", "jest-junit": "8.0.0", "lodash": "4.17.15", From 045a0afa587e7697fe2ded7967614cf2e700a858 Mon Sep 17 00:00:00 2001 From: 0xflotus <0xflotus@gmail.com> Date: Tue, 2 Jun 2020 17:38:38 +0200 Subject: [PATCH 44/56] Fix typo in react/hoc.mdx (#6223) --- docs/source/api/react/hoc.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/api/react/hoc.mdx b/docs/source/api/react/hoc.mdx index 0fcd07fbd9c..b2ab4f4df16 100644 --- a/docs/source/api/react/hoc.mdx +++ b/docs/source/api/react/hoc.mdx @@ -727,7 +727,7 @@ export default graphql(gql`query MyQuery { ... }`, { ### `options.context` -With the flexiblity and power of [Apollo Link](../../networking/advanced-http-networking/) being part of Apollo Client, you may want to send information from your operation straight to a link in your network chain! This can be used to do things like set `headers` on HTTP requests from props, control which endpoint you send a query to, and so much more depending on what links your app is using. Everything under the `context` object gets passed directly to your network chain. For more information about using context, check out the [`HttpLink` context docs](../../networking/advanced-http-networking/) +With the flexibility and power of [Apollo Link](../../networking/advanced-http-networking/) being part of Apollo Client, you may want to send information from your operation straight to a link in your network chain! This can be used to do things like set `headers` on HTTP requests from props, control which endpoint you send a query to, and so much more depending on what links your app is using. Everything under the `context` object gets passed directly to your network chain. For more information about using context, check out the [`HttpLink` context docs](../../networking/advanced-http-networking/) ### `partialRefetch` From c76804eea2afcd3df4e01d5a8db3ae2c4c553aee Mon Sep 17 00:00:00 2001 From: Grex Date: Tue, 2 Jun 2020 09:45:10 -0600 Subject: [PATCH 45/56] Avoid React StrictMode error when query resolves after unmount (#6216) --- src/react/data/QueryData.ts | 6 +-- src/react/hooks/__tests__/useQuery.test.tsx | 43 +++++++++++++++++++++ 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/src/react/data/QueryData.ts b/src/react/data/QueryData.ts index 6f1cf91aeed..2fc8fdf14b2 100644 --- a/src/react/data/QueryData.ts +++ b/src/react/data/QueryData.ts @@ -133,7 +133,7 @@ export class QueryData extends OperationData { this.cleanup(); this.runLazy = true; this.lazyOptions = options; - this.onNewData(); + if (this.isMounted) this.onNewData(); }; private getExecuteResult(): QueryResult { @@ -291,7 +291,7 @@ export class QueryData extends OperationData { return; } - onNewData(); + if (this.isMounted) onNewData(); }, error: error => { this.resubscribeToQuery(); @@ -303,7 +303,7 @@ export class QueryData extends OperationData { !equal(error, this.previousData.error) ) { this.previousData.error = error; - onNewData(); + if (this.isMounted) onNewData(); } } }); diff --git a/src/react/hooks/__tests__/useQuery.test.tsx b/src/react/hooks/__tests__/useQuery.test.tsx index db21a681c01..d3381fe02bb 100644 --- a/src/react/hooks/__tests__/useQuery.test.tsx +++ b/src/react/hooks/__tests__/useQuery.test.tsx @@ -14,6 +14,7 @@ import { ApolloProvider } from '../../context/ApolloProvider'; import { useQuery } from '../useQuery'; import { QueryFunctionOptions } from '../..'; import { NetworkStatus } from '../../../core/networkStatus'; +import { FetchResult } from '../../../link/core/types'; describe('useQuery Hook', () => { const CAR_QUERY: DocumentNode = gql` @@ -378,6 +379,48 @@ describe('useQuery Hook', () => { console.error = consoleError; }).then(resolve, reject); }); + + itAsync('should not log a React warning in StrictMode when unmounted before a query is resolved', async (resolve, reject) => { + jest.spyOn(console, 'error'); + + const Component = () => { + useQuery(CAR_QUERY); + + return null; + }; + + const observable = new Observable((observer) => { + const timer = setTimeout(() => { + observer.next({ data: CAR_RESULT_DATA }); + observer.complete(); + }, 0); + + // On unsubscription, cancel the timer + return () => clearTimeout(timer); + }); + + const link = new ApolloLink(() => observable) + + const client = new ApolloClient({ + cache: new InMemoryCache(), + link, + }); + + const { unmount } = render( + + + + + + ); + + unmount(); + await wait() + + expect(console.error).not.toHaveBeenCalled(); + + resolve() + }); }); describe('Polling', () => { From e572f4ce36c2729f9fc31a66b7439c6d9f7684fe Mon Sep 17 00:00:00 2001 From: Hugh Willson Date: Tue, 2 Jun 2020 11:50:52 -0400 Subject: [PATCH 46/56] Allow setting new ApolloLink after ApolloClient instantiation (#6193) Provides support for setting a new `ApolloLink` (or link chain) after `new ApolloClient()` has been called, using a public `ApolloClient.setLink()` method. --- CHANGELOG.md | 3 +++ src/ApolloClient.ts | 7 +++++++ src/__tests__/ApolloClient.ts | 29 +++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 55dc17080f5..3e95d6a1730 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -167,6 +167,9 @@ [@durchanek](https://github.com/durchanek) in [#6194](https://github.com/apollographql/apollo-client/pull/6194) and [#6279](https://github.com/apollographql/apollo-client/pull/6279)
[@hagmic](https://github.com/hagmic) in [#6328](https://github.com/apollographql/apollo-client/pull/6328) +- Apollo Client now supports setting a new `ApolloLink` (or link chain) after `new ApolloClient()` has been called, using the `ApolloClient#setLink` method.
+ [@hwillson](https://github.com/hwillson) in [#6193](https://github.com/apollographql/apollo-client/pull/6193) + ### Bug Fixes - `useMutation` adjustments to help avoid an infinite loop / too many renders issue, caused by unintentionally modifying the `useState` based mutation result directly.
diff --git a/src/ApolloClient.ts b/src/ApolloClient.ts index 736db198415..709bca67651 100644 --- a/src/ApolloClient.ts +++ b/src/ApolloClient.ts @@ -553,4 +553,11 @@ export class ApolloClient implements DataProxy { public setLocalStateFragmentMatcher(fragmentMatcher: FragmentMatcher) { this.localState.setFragmentMatcher(fragmentMatcher); } + + /** + * Define a new ApolloLink (or link chain) that Apollo Client will use. + */ + public setLink(newLink: ApolloLink) { + this.link = this.queryManager.link = newLink; + } } diff --git a/src/__tests__/ApolloClient.ts b/src/__tests__/ApolloClient.ts index 44ce8ff0c10..d1ad5e409a7 100644 --- a/src/__tests__/ApolloClient.ts +++ b/src/__tests__/ApolloClient.ts @@ -2301,4 +2301,33 @@ describe('ApolloClient', () => { expect((client.cache as any).data.data).toEqual({}); }); }); + + describe('setLink', () => { + it('should override default link with newly set link', async () => { + const client = new ApolloClient({ + cache: new InMemoryCache() + }); + expect(client.link).toBeDefined(); + + const newLink = new ApolloLink(operation => { + return new Observable(observer => { + observer.next({ + data: { + widgets: [ + { name: 'Widget 1'}, + { name: 'Widget 2' } + ] + } + }); + observer.complete(); + }); + }); + + client.setLink(newLink); + + const { data } = await client.query({ query: gql`{ widgets }` }); + expect(data.widgets).toBeDefined(); + expect(data.widgets.length).toBe(2); + }); + }); }); From 480611e6744e0e8cc4b4be58496441274829b5f1 Mon Sep 17 00:00:00 2001 From: sammychinedu2ky Date: Tue, 2 Jun 2020 16:52:14 +0100 Subject: [PATCH 47/56] Update GET_TODOS query in mutations.mdx (#6316) The mutation needs to return the id for the cache to be updated. --- docs/source/data/mutations.mdx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/source/data/mutations.mdx b/docs/source/data/mutations.mdx index 46d0b042c61..1f6bddccae4 100644 --- a/docs/source/data/mutations.mdx +++ b/docs/source/data/mutations.mdx @@ -298,7 +298,9 @@ The following sample illustrates defining an update function in a call to `useMu ```jsx const GET_TODOS = gql` query GetTodos { - todos + todos { + id + } } `; From e42d16d4b858f3614b9c582821cb6bd8ae4f28ed Mon Sep 17 00:00:00 2001 From: Josh Kramer Date: Tue, 2 Jun 2020 11:53:17 -0400 Subject: [PATCH 48/56] Describe what `keyFields: false` does (#6270) Co-authored-by: Ben Newman --- docs/source/caching/cache-configuration.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/source/caching/cache-configuration.md b/docs/source/caching/cache-configuration.md index cb34dad6c8d..af6cd91e654 100644 --- a/docs/source/caching/cache-configuration.md +++ b/docs/source/caching/cache-configuration.md @@ -148,7 +148,8 @@ A `TypePolicy` object can include the following fields: ```ts type TypePolicy = { // Allows defining the primary key fields for this type, either using an - // array of field names or a function that returns an arbitrary string. + // array of field names, a function that returns an arbitrary string, or + // false to disable normalization for objects of this type. keyFields?: KeySpecifier | KeyFieldsFunction | false; // If your schema uses a custom __typename for any of the root Query, From f5353d67c99cc3c23e3d4cff1d23a63ad69beeda Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Tue, 2 Jun 2020 11:58:04 -0400 Subject: [PATCH 49/56] Bump @apollo/client npm version to 3.0.0-rc.0. Now that the release candidate phase of testing has begun, we will do our very best to avoid introducing any new features or breaking API changes, unless those changes are absolutely necessary to fix bugs. We are very much aware of a number of outstanding bugs, and we fully intend to fix all known bugs before the final AC3 release, in addition to continuing to write and edit the documentation for new AC3 features: https://github.com/apollographql/apollo-client/milestone/14 If you have been waiting for a signal that the AC3 API is stable/frozen, this is it. However, if you are not interested in helping to identify and fix (or at least work around) the remaining issues, then you should wait for the final release before updating. --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index c28f8ea3bc0..1aad9309d97 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@apollo/client", - "version": "3.0.0-beta.54", + "version": "3.0.0-rc.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 2fefd6ec329..c906ce5637a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@apollo/client", - "version": "3.0.0-beta.54", + "version": "3.0.0-rc.0", "description": "A fully-featured caching GraphQL client.", "private": true, "keywords": [ From 2d61e5c936c2bcb2aa62f4eb7c6f82b773b962ab Mon Sep 17 00:00:00 2001 From: luukvnes <34107188+luukvnes@users.noreply.github.com> Date: Wed, 3 Jun 2020 15:49:17 +0200 Subject: [PATCH 50/56] Fixed a edges -> an edges type in docs (#6028) Fixed a edges -> an edges type in docs (#6028) Co-authored-by: Hugh Willson --- docs/source/data/local-state.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/data/local-state.mdx b/docs/source/data/local-state.mdx index d5569d060c9..c3873f95349 100644 --- a/docs/source/data/local-state.mdx +++ b/docs/source/data/local-state.mdx @@ -621,7 +621,7 @@ const client = new ApolloClient({ }); ``` -[`CameraRoll.getPhotos()`](https://facebook.github.io/react-native/docs/cameraroll.html#getphotos) returns a `Promise` resolving to an object with a `edges` property, which is an array of camera node objects, and a `page_info` property, which is an object with pagination information. This is a great use case for GraphQL, since we can filter down the return value to only the data that our components consume. +[`CameraRoll.getPhotos()`](https://facebook.github.io/react-native/docs/cameraroll.html#getphotos) returns a `Promise` resolving to an object with an `edges` property, which is an array of camera node objects, and a `page_info` property, which is an object with pagination information. This is a great use case for GraphQL, since we can filter down the return value to only the data that our components consume. ```js import { gql } from "@apollo/client"; From adc9c82c6725722bbd30e1af4e66d432113a232a Mon Sep 17 00:00:00 2001 From: Hugh Willson Date: Thu, 4 Jun 2020 14:41:35 -0400 Subject: [PATCH 51/56] Let maybeBroadcastWatch broadcast older results, even if unchanged. (#6387) * Failing test for issue #5790 This is a failing test for issue #5790 that demonstrates an optimistic rollback issue when an error is received. * Move maybeBroadcastWatch wrapping closer to actual method. Analogous to how executeSelectionSet and executeSubSelectedArray were moved out of the constructor in ce6dece53ca50b4bd17a45b8cab25532fd5f91c3. * Dirty any past maybeBroadcastWatch(c) calls when c.callback called. Co-authored-by: Ben Newman --- src/cache/inmemory/inMemoryCache.ts | 91 +++++++----- src/react/hooks/__tests__/useQuery.test.tsx | 156 ++++++++++++++++++++ 2 files changed, 211 insertions(+), 36 deletions(-) diff --git a/src/cache/inmemory/inMemoryCache.ts b/src/cache/inmemory/inMemoryCache.ts index 1ad6d3bf461..e586a9736f2 100644 --- a/src/cache/inmemory/inMemoryCache.ts +++ b/src/cache/inmemory/inMemoryCache.ts @@ -87,32 +87,6 @@ export class InMemoryCache extends ApolloCache { addTypename: this.addTypename, }), ); - - const cache = this; - const { maybeBroadcastWatch } = cache; - this.maybeBroadcastWatch = wrap((c: Cache.WatchOptions) => { - return maybeBroadcastWatch.call(this, c); - }, { - makeCacheKey(c: Cache.WatchOptions) { - // Return a cache key (thus enabling result caching) only if we're - // currently using a data store that can track cache dependencies. - const store = c.optimistic ? cache.optimisticData : cache.data; - if (supportsResultCaching(store)) { - const { optimistic, rootId, variables } = c; - return store.makeCacheKey( - c.query, - // Different watches can have the same query, optimistic - // status, rootId, and variables, but if their callbacks are - // different, the (identical) result needs to be delivered to - // each distinct callback. The easiest way to achieve that - // separation is to include c.callback in the cache key for - // maybeBroadcastWatch calls. See issue #5733. - c.callback, - JSON.stringify({ optimistic, rootId, variables }), - ); - } - } - }); } public restore(data: NormalizedCacheObject): this { @@ -342,16 +316,61 @@ export class InMemoryCache extends ApolloCache { } } - // This method is wrapped in the constructor so that it will be called only - // if the data that would be broadcast has changed. - private maybeBroadcastWatch(c: Cache.WatchOptions) { - c.callback( - this.diff({ - query: c.query, - variables: c.variables, - optimistic: c.optimistic, - }), - ); + private maybeBroadcastWatch = wrap((c: Cache.WatchOptions) => { + return this.broadcastWatch.call(this, c); + }, { + makeCacheKey: (c: Cache.WatchOptions) => { + // Return a cache key (thus enabling result caching) only if we're + // currently using a data store that can track cache dependencies. + const store = c.optimistic ? this.optimisticData : this.data; + if (supportsResultCaching(store)) { + const { optimistic, rootId, variables } = c; + return store.makeCacheKey( + c.query, + // Different watches can have the same query, optimistic + // status, rootId, and variables, but if their callbacks are + // different, the (identical) result needs to be delivered to + // each distinct callback. The easiest way to achieve that + // separation is to include c.callback in the cache key for + // maybeBroadcastWatch calls. See issue #5733. + c.callback, + JSON.stringify({ optimistic, rootId, variables }), + ); + } + } + }); + + private watchDep = dep(); + + // This method is wrapped by maybeBroadcastWatch, which is called by + // broadcastWatches, so that we compute and broadcast results only when + // the data that would be broadcast might have changed. It would be + // simpler to check for changes after recomputing a result but before + // broadcasting it, but this wrapping approach allows us to skip both + // the recomputation and the broadcast, in most cases. + private broadcastWatch(c: Cache.WatchOptions) { + // First, invalidate any other maybeBroadcastWatch wrapper functions + // currently depending on this Cache.WatchOptions object (including + // the one currently calling broadcastWatch), so they will be included + // in the next broadcast, even if the result they receive is the same + // as the previous result they received. This is important because we + // are about to deliver a different result to c.callback, so any + // previous results should have a chance to be redelivered. + this.watchDep.dirty(c); + + // Next, re-depend on this.watchDep for just this invocation of + // maybeBroadcastWatch (this is a no-op if broadcastWatch was not + // called by maybeBroadcastWatch). This allows only the most recent + // maybeBroadcastWatch invocation for this watcher to remain cached, + // enabling re-broadcast of previous results even if they have not + // changed since they were previously delivered. + this.watchDep(c); + + c.callback(this.diff({ + query: c.query, + variables: c.variables, + optimistic: c.optimistic, + })); } private varDep = dep>(); diff --git a/src/react/hooks/__tests__/useQuery.test.tsx b/src/react/hooks/__tests__/useQuery.test.tsx index d3381fe02bb..d99a69c8dbd 100644 --- a/src/react/hooks/__tests__/useQuery.test.tsx +++ b/src/react/hooks/__tests__/useQuery.test.tsx @@ -12,9 +12,11 @@ import { ApolloClient } from '../../../ApolloClient'; import { InMemoryCache } from '../../../cache/inmemory/inMemoryCache'; import { ApolloProvider } from '../../context/ApolloProvider'; import { useQuery } from '../useQuery'; +import { useMutation } from '../useMutation'; import { QueryFunctionOptions } from '../..'; import { NetworkStatus } from '../../../core/networkStatus'; import { FetchResult } from '../../../link/core/types'; +import { Reference } from '../../../utilities/graphql/storeUtils'; describe('useQuery Hook', () => { const CAR_QUERY: DocumentNode = gql` @@ -1563,4 +1565,158 @@ describe('useQuery Hook', () => { }).then(resolve, reject); }); }); + + describe('Optimistic data', () => { + itAsync('should display rolled back optimistic data when an error occurs', (resolve, reject) => { + const query = gql` + query AllCars { + cars { + id + make + model + } + } + `; + + const carsData = { + cars: [ + { + id: 1, + make: 'Audi', + model: 'RS8', + __typename: 'Car' + } + ] + }; + + const mutation = gql` + mutation AddCar { + addCar { + id + make + model + } + } + `; + + const carData = { + id: 2, + make: 'Ford', + model: 'Pinto', + __typename: 'Car' + }; + + const allCarsData = { + cars: [ + carsData.cars[0], + carData + ] + }; + + const mocks = [ + { + request: { + query + }, + result: { data: carsData } + }, + { + request: { + query: mutation + }, + error: new Error('Oh no!') + } + ]; + + let renderCount = 0; + const Component = () => { + const [mutate, { loading: mutationLoading }] = useMutation(mutation, { + optimisticResponse: carData, + update: (cache, { data }) => { + cache.modify({ + fields: { + cars(existing, { readField }) { + const newCarRef = cache.writeFragment({ + data, + fragment: gql`fragment NewCar on Car { + id + make + model + }`, + }); + if (existing.some( + (ref: Reference) => readField('id', ref) === data!.id + )) { + return existing; + } + return [...existing, newCarRef]; + } + } + }); + }, + onError() { + // Swallow error + } + }); + + const { data, loading: queryLoading } = useQuery(query); + switch(++renderCount) { + case 1: + // The query ran and is loading the result. + expect(queryLoading).toBeTruthy(); + break; + case 2: + // The query has completed. + expect(queryLoading).toBeFalsy(); + expect(data).toEqual(carsData); + // Trigger a mutation (with optimisticResponse data). + mutate(); + break; + case 3: + // The mutation ran and is loading the result. The query stays at + // not loading as nothing has changed for the query. + expect(mutationLoading).toBeTruthy(); + expect(queryLoading).toBeFalsy(); + break; + case 4: + // The first part of the mutation has completed using the defined + // optimisticResponse data. This means that while the mutation + // stays in a loading state, it has made its optimistic data + // available to the query. New optimistic data doesn't trigger a + // query loading state. + expect(mutationLoading).toBeTruthy(); + expect(queryLoading).toBeFalsy(); + expect(data).toEqual(allCarsData); + break; + case 5: + // The mutation wasn't able to fulfill its network request so it + // errors, which means the initially returned optimistic data is + // rolled back, and the query no longer has access to it. + expect(mutationLoading).toBeTruthy(); + expect(queryLoading).toBeFalsy(); + expect(data).toEqual(carsData); + break; + case 6: + // The mutation has completely finished, leaving the query + // with access to the original cache data. + expect(mutationLoading).toBeFalsy(); + expect(queryLoading).toBeFalsy(); + expect(data).toEqual(carsData); + break; + default: + } + return null; + }; + + render( + + + + ); + + return wait(() => { + expect(renderCount).toBe(6); + }).then(resolve, reject); + }); + }); }); From a0844d71a344c03cb3c9972ffaa6a0619a4cc926 Mon Sep 17 00:00:00 2001 From: Tom Picton Date: Thu, 4 Jun 2020 11:43:19 -0700 Subject: [PATCH 52/56] Improve defaultDataIdFromObject type declaration (#6382) --- src/cache/inmemory/policies.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cache/inmemory/policies.ts b/src/cache/inmemory/policies.ts index 61b8f54f702..1433b04d6a0 100644 --- a/src/cache/inmemory/policies.ts +++ b/src/cache/inmemory/policies.ts @@ -183,9 +183,9 @@ export type FieldMergeFunction = ( options: FieldFunctionOptions, ) => TExisting; -export const defaultDataIdFromObject: KeyFieldsFunction = ( - { __typename, id, _id }, - context, +export const defaultDataIdFromObject = ( + { __typename, id, _id }: Readonly, + context?: KeyFieldsContext, ) => { if (typeof __typename === "string") { if (context) { From b6da9c89a9e6f75dc6799e7bf2668bbbcbab7e9d Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Thu, 4 Jun 2020 17:48:58 -0400 Subject: [PATCH 53/56] Allow onNewData to be called when unmounted, during SSR. (#6388) PR #6216 introduced these isMounted guards, and was merged just before the v3.0.0-rc.0 release. It appears (see #6386) that requiring the component to be mounted is too restrictive, specifically when doing server-side rendering, since the concept of mounting doesn't make sense without a DOM. --- src/react/data/QueryData.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/react/data/QueryData.ts b/src/react/data/QueryData.ts index 2fc8fdf14b2..64374f1d2a5 100644 --- a/src/react/data/QueryData.ts +++ b/src/react/data/QueryData.ts @@ -133,7 +133,9 @@ export class QueryData extends OperationData { this.cleanup(); this.runLazy = true; this.lazyOptions = options; - if (this.isMounted) this.onNewData(); + if (this.isMounted || this.ssrInitiated()) { + this.onNewData(); + } }; private getExecuteResult(): QueryResult { @@ -291,7 +293,9 @@ export class QueryData extends OperationData { return; } - if (this.isMounted) onNewData(); + if (this.isMounted || this.ssrInitiated()) { + onNewData(); + } }, error: error => { this.resubscribeToQuery(); @@ -303,7 +307,9 @@ export class QueryData extends OperationData { !equal(error, this.previousData.error) ) { this.previousData.error = error; - if (this.isMounted) onNewData(); + if (this.isMounted || this.ssrInitiated()) { + onNewData(); + } } } }); From 37b0bfdfc9c2a0d0a559a5423d1cbcc11d0ca630 Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Thu, 4 Jun 2020 17:50:17 -0400 Subject: [PATCH 54/56] Bump @apollo/client npm version to 3.0.0-rc.1. --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1aad9309d97..2dcdc25cfad 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@apollo/client", - "version": "3.0.0-rc.0", + "version": "3.0.0-rc.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index c906ce5637a..883584fb441 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@apollo/client", - "version": "3.0.0-rc.0", + "version": "3.0.0-rc.1", "description": "A fully-featured caching GraphQL client.", "private": true, "keywords": [ From 41fb5fee3b72ef6f0e6b44768c13728795407804 Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Fri, 5 Jun 2020 10:51:10 -0400 Subject: [PATCH 55/56] Revert #6388 and #6216, fixing #6386 and #6385. (#6395) This reverts commits b6da9c89a9e6f75dc6799e7bf2668bbbcbab7e9d (#6388) and c76804eea2afcd3df4e01d5a8db3ae2c4c553aee (#6216). Preventing StrictMode warnings in React is not worth introducing bugs that break applications. We will need to reconsider how best to prevent warnings for unmounted components. --- src/react/data/QueryData.ts | 12 ++---- src/react/hooks/__tests__/useQuery.test.tsx | 43 --------------------- 2 files changed, 3 insertions(+), 52 deletions(-) diff --git a/src/react/data/QueryData.ts b/src/react/data/QueryData.ts index 64374f1d2a5..6f1cf91aeed 100644 --- a/src/react/data/QueryData.ts +++ b/src/react/data/QueryData.ts @@ -133,9 +133,7 @@ export class QueryData extends OperationData { this.cleanup(); this.runLazy = true; this.lazyOptions = options; - if (this.isMounted || this.ssrInitiated()) { - this.onNewData(); - } + this.onNewData(); }; private getExecuteResult(): QueryResult { @@ -293,9 +291,7 @@ export class QueryData extends OperationData { return; } - if (this.isMounted || this.ssrInitiated()) { - onNewData(); - } + onNewData(); }, error: error => { this.resubscribeToQuery(); @@ -307,9 +303,7 @@ export class QueryData extends OperationData { !equal(error, this.previousData.error) ) { this.previousData.error = error; - if (this.isMounted || this.ssrInitiated()) { - onNewData(); - } + onNewData(); } } }); diff --git a/src/react/hooks/__tests__/useQuery.test.tsx b/src/react/hooks/__tests__/useQuery.test.tsx index d99a69c8dbd..c6777d881ed 100644 --- a/src/react/hooks/__tests__/useQuery.test.tsx +++ b/src/react/hooks/__tests__/useQuery.test.tsx @@ -15,7 +15,6 @@ import { useQuery } from '../useQuery'; import { useMutation } from '../useMutation'; import { QueryFunctionOptions } from '../..'; import { NetworkStatus } from '../../../core/networkStatus'; -import { FetchResult } from '../../../link/core/types'; import { Reference } from '../../../utilities/graphql/storeUtils'; describe('useQuery Hook', () => { @@ -381,48 +380,6 @@ describe('useQuery Hook', () => { console.error = consoleError; }).then(resolve, reject); }); - - itAsync('should not log a React warning in StrictMode when unmounted before a query is resolved', async (resolve, reject) => { - jest.spyOn(console, 'error'); - - const Component = () => { - useQuery(CAR_QUERY); - - return null; - }; - - const observable = new Observable((observer) => { - const timer = setTimeout(() => { - observer.next({ data: CAR_RESULT_DATA }); - observer.complete(); - }, 0); - - // On unsubscription, cancel the timer - return () => clearTimeout(timer); - }); - - const link = new ApolloLink(() => observable) - - const client = new ApolloClient({ - cache: new InMemoryCache(), - link, - }); - - const { unmount } = render( - - - - - - ); - - unmount(); - await wait() - - expect(console.error).not.toHaveBeenCalled(); - - resolve() - }); }); describe('Polling', () => { From 39942881567ff9825a0f17bbf114ec441590f8bb Mon Sep 17 00:00:00 2001 From: Ben Newman Date: Fri, 5 Jun 2020 10:53:23 -0400 Subject: [PATCH 56/56] Bump @apollo/client npm version to 3.0.0-rc.2. Deliberately putting as little as possible into this release, so that we can validate the impact of these specific changes (PR #6395). --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2dcdc25cfad..1642cf6c385 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@apollo/client", - "version": "3.0.0-rc.1", + "version": "3.0.0-rc.2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 883584fb441..4d11fb0fdcd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@apollo/client", - "version": "3.0.0-rc.1", + "version": "3.0.0-rc.2", "description": "A fully-featured caching GraphQL client.", "private": true, "keywords": [