[apollo-mock-client] Rename and support query, mutation, and subscription operations
This commit is contained in:
Родитель
809be86745
Коммит
e3082322c6
|
@ -0,0 +1,3 @@
|
|||
# ApolloMockClient
|
||||
|
||||
An Apollo Client that allows mocking of payloads in response to operations, rather providing them all upfront. It is API-wise a port of [Relay’s RelayMocEnvironment](https://relay.dev/docs/guides/testing-relay-components/#relaymockenvironment-api-overview).
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "@graphitation/apollo-mock-provider",
|
||||
"name": "@graphitation/apollo-mock-client",
|
||||
"version": "0.1.0",
|
||||
"main": "./src/index.ts",
|
||||
"scripts": {
|
||||
|
@ -11,10 +11,15 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@apollo/client": "^3.3.15",
|
||||
"@graphitation/graphql-js-tag": "^0.1.0",
|
||||
"@graphitation/graphql-js-operation-payload-generator": "^0.1.0",
|
||||
"@types/jest": "^26.0.22",
|
||||
"@types/react": "^17.0.3",
|
||||
"@types/react-test-renderer": "^17.0.1",
|
||||
"graphql": "^15.5.0",
|
||||
"monorepo-scripts": "*"
|
||||
"monorepo-scripts": "*",
|
||||
"react": "^17.0.2",
|
||||
"react-test-renderer": "^17.0.2"
|
||||
},
|
||||
"publishConfig": {
|
||||
"main": "./lib/index.js",
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,213 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`ReactRelayTestMocker with Containers Basic Resolve/Reject Operations should resolve query 1`] = `"My id <mock-id-1> and name is <mock-value-for-field-\\"name\\">"`;
|
||||
|
||||
exports[`ReactRelayTestMocker with Containers Multiple Query Renderers should resolve both queries 1`] = `
|
||||
Array [
|
||||
<div
|
||||
testID="user"
|
||||
>
|
||||
Alice
|
||||
</div>,
|
||||
<div
|
||||
testID="page"
|
||||
>
|
||||
My Page
|
||||
</div>,
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`ReactRelayTestMocker with Containers Subscription Tests should resolve subscription 1`] = `
|
||||
<div>
|
||||
Feedback:
|
||||
<mock-value-for-field-"text">
|
||||
<span
|
||||
reactionType="Viewer does not like it"
|
||||
testID="reaction"
|
||||
/>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`ReactRelayTestMocker with Containers Test Mutations should reject mutation: Should render error message 1`] = `
|
||||
<div>
|
||||
<span
|
||||
testID="errorMessage"
|
||||
>
|
||||
Uh-oh
|
||||
</span>
|
||||
Feedback:
|
||||
<mock-value-for-field-"text">
|
||||
<button
|
||||
disabled={false}
|
||||
onClick={[Function]}
|
||||
testID="likeButton"
|
||||
>
|
||||
Like
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`ReactRelayTestMocker with Containers Test Mutations should resolve mutation: Button should be enabled. Text should be "Like". 1`] = `
|
||||
<div>
|
||||
Feedback:
|
||||
<mock-value-for-field-"text">
|
||||
<button
|
||||
disabled={false}
|
||||
onClick={[Function]}
|
||||
testID="likeButton"
|
||||
>
|
||||
Like
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`ReactRelayTestMocker with Containers Test Mutations should resolve mutation: Should apply optimistic update. Button should says "Unlike". And it should be disabled 1`] = `
|
||||
<div>
|
||||
Feedback:
|
||||
<mock-value-for-field-"text">
|
||||
<button
|
||||
disabled={true}
|
||||
onClick={[Function]}
|
||||
testID="likeButton"
|
||||
>
|
||||
Unlike
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`ReactRelayTestMocker with Containers Test Mutations should resolve mutation: Should render response from the server. Button should be enabled. And text still "Unlike" 1`] = `
|
||||
<div>
|
||||
Feedback:
|
||||
<mock-value-for-field-"text">
|
||||
<button
|
||||
disabled={false}
|
||||
onClick={[Function]}
|
||||
testID="likeButton"
|
||||
>
|
||||
Unlike
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`ReactRelayTestMocker with Containers Test Query Renderer with Fragment Container should render data 1`] = `
|
||||
<div>
|
||||
My id $
|
||||
<mock-id-1>
|
||||
and name is $
|
||||
<mock-value-for-field-"name">
|
||||
.
|
||||
<hr />
|
||||
<img
|
||||
alt="<mock-value-for-field-\\"name\\">"
|
||||
src="<mock-value-for-field-\\"uri\\">"
|
||||
testID="profile_picture"
|
||||
/>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`ReactRelayTestMocker with Containers Test Query Renderer with Pagination Container should load more data for pagination container: It should render a list of users with Alice and Bob, button "loadMore" should be disabled 1`] = `
|
||||
<div>
|
||||
My id $
|
||||
my-pagination-test-user-id
|
||||
and name is $
|
||||
<mock-value-for-field-"name">
|
||||
.
|
||||
<hr />
|
||||
<ul
|
||||
testID="list"
|
||||
>
|
||||
<li>
|
||||
Friend:
|
||||
Alice
|
||||
<img
|
||||
alt="Alice"
|
||||
src="<mock-value-for-field-\\"uri\\">"
|
||||
/>
|
||||
</li>
|
||||
<li>
|
||||
Friend:
|
||||
Bob
|
||||
<img
|
||||
alt="Bob"
|
||||
src="<mock-value-for-field-\\"uri\\">"
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
<button
|
||||
disabled={true}
|
||||
onClick={[Function]}
|
||||
testID="loadMore"
|
||||
/>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`ReactRelayTestMocker with Containers Test Query Renderer with Pagination Container should render data: It should render list of users with just Alice and \`button\` loadMore should be enabled. 1`] = `
|
||||
<div>
|
||||
My id $
|
||||
my-pagination-test-user-id
|
||||
and name is $
|
||||
<mock-value-for-field-"name">
|
||||
.
|
||||
<hr />
|
||||
<ul
|
||||
testID="list"
|
||||
>
|
||||
<li>
|
||||
Friend:
|
||||
Alice
|
||||
<img
|
||||
alt="Alice"
|
||||
src="<mock-value-for-field-\\"uri\\">"
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
<button
|
||||
disabled={false}
|
||||
onClick={[Function]}
|
||||
testID="loadMore"
|
||||
/>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`ReactRelayTestMocker with Containers Test Query Renderer with Refetch Container should refetch query: Should render hometown with SFO 1`] = `
|
||||
<div>
|
||||
My id $
|
||||
<mock-id-1>
|
||||
and name is $
|
||||
<mock-value-for-field-"name">
|
||||
.
|
||||
<hr />
|
||||
<div
|
||||
testID="hometown"
|
||||
>
|
||||
SFO
|
||||
</div>
|
||||
<div>
|
||||
Websites:
|
||||
<mock-value-for-field-"websites">
|
||||
</div>
|
||||
<button
|
||||
disabled={false}
|
||||
onClick={[Function]}
|
||||
testID="refetch"
|
||||
>
|
||||
Refetch
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`ReactRelayTestMocker with Containers resolve/reject next with components should reject next operation: should render component with the error 1`] = `
|
||||
<div
|
||||
testID="error"
|
||||
>
|
||||
Uh-oh
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`ReactRelayTestMocker with Containers resolve/reject next with components should resolve next operation: should render component with the data 1`] = `
|
||||
<div
|
||||
testID="user"
|
||||
>
|
||||
<mock-value-for-field-"name">
|
||||
</div>
|
||||
`;
|
|
@ -0,0 +1,230 @@
|
|||
import * as React from "react";
|
||||
import {
|
||||
ApolloLink,
|
||||
Observable,
|
||||
Operation,
|
||||
FetchResult,
|
||||
ApolloClient,
|
||||
InMemoryCache,
|
||||
ApolloProvider,
|
||||
NormalizedCacheObject,
|
||||
} from "@apollo/client";
|
||||
import invariant from "invariant";
|
||||
import { assertType, GraphQLSchema, isAbstractType } from "graphql";
|
||||
|
||||
type MockData = Record<string, unknown>;
|
||||
|
||||
interface MockFunctions {
|
||||
getAllOperations(): Operation[];
|
||||
getMostRecentOperation(): Operation;
|
||||
findOperation(findFn: (operation: Operation) => boolean): Operation;
|
||||
nextValue(operation: Operation, data: MockData): void;
|
||||
complete(operation: Operation): void;
|
||||
resolve(operation: Operation, data: MockData): void;
|
||||
reject(operation: Operation, error: Error): void;
|
||||
resolveMostRecentOperation(
|
||||
resolver: (operation: Operation) => MockData
|
||||
): void;
|
||||
rejectMostRecentOperation(
|
||||
error: Error | ((operation: Operation) => Error)
|
||||
): void;
|
||||
}
|
||||
|
||||
interface ApolloClientExtension {
|
||||
mock: MockFunctions;
|
||||
mockClear: () => void;
|
||||
}
|
||||
|
||||
export interface ApolloMockClient
|
||||
extends ApolloClient<NormalizedCacheObject>,
|
||||
ApolloClientExtension {}
|
||||
|
||||
class MockLink extends ApolloLink {
|
||||
public schema: GraphQLSchema;
|
||||
public mock: _MockEnvironment;
|
||||
|
||||
constructor(schema: GraphQLSchema) {
|
||||
super();
|
||||
this.schema = schema;
|
||||
this.mock = new _MockEnvironment();
|
||||
}
|
||||
|
||||
public mockClear() {
|
||||
this.mock = new _MockEnvironment();
|
||||
}
|
||||
|
||||
public request(operation: Operation): Observable<FetchResult> | null {
|
||||
operation.setContext({ schema: this.schema });
|
||||
return new Observable<FetchResult>((observer) => {
|
||||
this.mock.addOperation(operation, observer);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class _MockEnvironment implements MockFunctions {
|
||||
private operations: [
|
||||
operation: Operation,
|
||||
observer: ZenObservable.SubscriptionObserver<FetchResult>
|
||||
][];
|
||||
|
||||
constructor() {
|
||||
this.operations = [];
|
||||
}
|
||||
|
||||
// TODO: This should remain file private
|
||||
public addOperation(
|
||||
operation: Operation,
|
||||
observer: ZenObservable.SubscriptionObserver<FetchResult>
|
||||
) {
|
||||
this.operations.push([operation, observer]);
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
public getAllOperations(): Operation[] {
|
||||
return this.operations.map(([op, _]) => op);
|
||||
}
|
||||
|
||||
public getMostRecentOperation(): Operation {
|
||||
invariant(
|
||||
this.operations.length > 0,
|
||||
"Expected at least one operation to have been started"
|
||||
);
|
||||
const [op, _] = this.operations[this.operations.length - 1];
|
||||
return op;
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
public nextValue(operation: Operation, data: MockData): void {
|
||||
const [_, observer] = this.operations[this.findOperationIndex(operation)];
|
||||
observer.next(data);
|
||||
}
|
||||
|
||||
public complete(operation: Operation): void {
|
||||
const index = this.findOperationIndex(operation);
|
||||
const [_, observer] = this.operations[index];
|
||||
observer.complete();
|
||||
this.operations.splice(index, 1);
|
||||
}
|
||||
|
||||
public resolve(operation: Operation, data: MockData): void {
|
||||
this.nextValue(operation, data);
|
||||
this.complete(operation);
|
||||
}
|
||||
|
||||
public reject(operation: Operation, error: Error): void {
|
||||
const [_, observer] = this.operations[this.findOperationIndex(operation)];
|
||||
observer.error(error);
|
||||
this.complete(operation);
|
||||
}
|
||||
|
||||
public resolveMostRecentOperation(
|
||||
resolver: (operation: Operation) => MockData
|
||||
): void {
|
||||
const operation = this.getMostRecentOperation();
|
||||
this.resolve(operation, resolver(operation));
|
||||
}
|
||||
|
||||
public rejectMostRecentOperation(
|
||||
error: Error | ((operation: Operation) => Error)
|
||||
): void {
|
||||
const operation = this.getMostRecentOperation();
|
||||
this.reject(
|
||||
operation,
|
||||
typeof error === "function" ? error(operation) : error
|
||||
);
|
||||
}
|
||||
|
||||
public findOperation(findFn: (operation: Operation) => boolean): Operation {
|
||||
const operation = this.operations.find(([op, _]) => findFn(op));
|
||||
invariant(
|
||||
operation,
|
||||
"Operation was not found in the list of pending operations"
|
||||
);
|
||||
return operation[0];
|
||||
}
|
||||
|
||||
// ----
|
||||
|
||||
private findOperationIndex(operation: Operation) {
|
||||
const index = this.operations.findIndex(([op, _]) => op === operation);
|
||||
invariant(index >= 0, "Expected to find operation");
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
export function createMockClient(schema: GraphQLSchema): ApolloMockClient {
|
||||
// Build a list of abstract types and their possible types.
|
||||
// TODO: Cache this on the schema?
|
||||
const possibleTypes: Record<string, string[]> = {};
|
||||
Object.keys(schema.getTypeMap()).forEach((typeName) => {
|
||||
const type = schema.getType(typeName);
|
||||
assertType(type);
|
||||
if (isAbstractType(type)) {
|
||||
possibleTypes[typeName] = schema
|
||||
.getPossibleTypes(type)
|
||||
.map((possibleType) => possibleType.name);
|
||||
}
|
||||
});
|
||||
|
||||
const link = new MockLink(schema);
|
||||
|
||||
const ext: ApolloClientExtension = {
|
||||
get mock() {
|
||||
return link.mock;
|
||||
},
|
||||
mockClear() {
|
||||
link.mockClear();
|
||||
},
|
||||
};
|
||||
|
||||
const client = new ApolloClient({
|
||||
cache: new InMemoryCache({
|
||||
possibleTypes,
|
||||
addTypename: false,
|
||||
}),
|
||||
link,
|
||||
}) as ApolloMockClient;
|
||||
|
||||
// Object.defineProperties(client, {
|
||||
// mock: {
|
||||
// get() {
|
||||
// return link.mock;
|
||||
// },
|
||||
// },
|
||||
// mockClear: {
|
||||
// value: () => link.mockClear(),
|
||||
// },
|
||||
// });
|
||||
|
||||
return Object.assign(client, ext);
|
||||
}
|
||||
|
||||
// export const ApolloMockProvider: React.FC<{
|
||||
// environment: MockEnvironment;
|
||||
// }> = ({ children, environment }) => {
|
||||
// // Build a list of abstract types and their possible types.
|
||||
// // TODO: Cache this on the schema?
|
||||
// const schema = (environment as _MockEnvironment).schema;
|
||||
// const possibleTypes: Record<string, string[]> = {};
|
||||
// Object.keys(schema.getTypeMap()).forEach((typeName) => {
|
||||
// const type = schema.getType(typeName);
|
||||
// assertType(type);
|
||||
// if (isAbstractType(type)) {
|
||||
// possibleTypes[typeName] = schema
|
||||
// .getPossibleTypes(type)
|
||||
// .map((possibleType) => possibleType.name);
|
||||
// }
|
||||
// });
|
||||
|
||||
// const client = new ApolloClient({
|
||||
// cache: new InMemoryCache({
|
||||
// possibleTypes,
|
||||
// addTypename: false,
|
||||
// }),
|
||||
// link: new MockLink(environment as _MockEnvironment),
|
||||
// });
|
||||
|
||||
// return <ApolloProvider client={client}>{children}</ApolloProvider>;
|
||||
// };
|
|
@ -8,5 +8,8 @@
|
|||
"jsx": "react"
|
||||
},
|
||||
"include": ["src"],
|
||||
"references": []
|
||||
"references": [
|
||||
{ "path": "../graphql-js-tag" },
|
||||
{ "path": "../graphql-js-operation-payload-generator" }
|
||||
]
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
# ApolloMockProvider
|
||||
|
||||
An Apollo Client provider that allows mocking of payloads in response to operations, rather providing them all upfront. It is API-wise a port of [Relay’s RelayMocEnvironment](https://relay.dev/docs/guides/testing-relay-components/#relaymockenvironment-api-overview).
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,7 +0,0 @@
|
|||
import { bar } from "..";
|
||||
|
||||
describe("bar", () => {
|
||||
it("returns a string", () => {
|
||||
expect(typeof bar("test")).toBe("string");
|
||||
});
|
||||
});
|
|
@ -1,146 +0,0 @@
|
|||
/* eslint-disable max-classes-per-file */
|
||||
import * as React from "react";
|
||||
import {
|
||||
ApolloLink,
|
||||
Observable,
|
||||
Operation,
|
||||
NextLink,
|
||||
FetchResult,
|
||||
ApolloClient,
|
||||
InMemoryCache,
|
||||
ApolloProvider,
|
||||
} from "@apollo/client";
|
||||
import invariant from "invariant";
|
||||
import { assertType, GraphQLSchema, isAbstractType } from "graphql";
|
||||
|
||||
class MockLink extends ApolloLink {
|
||||
constructor(private environment: MockEnvironment) {
|
||||
super();
|
||||
}
|
||||
|
||||
public request(operation: Operation): Observable<FetchResult> | null {
|
||||
operation.setContext({ schema: this.environment.schema });
|
||||
return new Observable<FetchResult>((observer) => {
|
||||
this.environment.addOperation(operation, observer);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// interface MockOperation {
|
||||
// resolve();
|
||||
// }
|
||||
|
||||
// An opaque type that internally holds an Apollo Client Operation, but that should not be exposed to the user.
|
||||
type OperationDescriptor = { __brand: "OperationDescriptor" };
|
||||
|
||||
type MockData = Record<string, unknown>;
|
||||
|
||||
class MockEnvironment {
|
||||
private operations: [
|
||||
operation: Operation,
|
||||
observer: ZenObservable.SubscriptionObserver<FetchResult>
|
||||
][];
|
||||
|
||||
// TODO: This should remain file private
|
||||
public schema: GraphQLSchema;
|
||||
|
||||
constructor(schema: GraphQLSchema) {
|
||||
this.operations = [];
|
||||
this.schema = schema;
|
||||
}
|
||||
|
||||
// TODO: This should remain file private
|
||||
public addOperation(
|
||||
operation: Operation,
|
||||
observer: ZenObservable.SubscriptionObserver<FetchResult>
|
||||
) {
|
||||
this.operations.push([operation, observer]);
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
public getMostRecentOperation(): OperationDescriptor {
|
||||
invariant(
|
||||
this.operations.length > 0,
|
||||
"Expected at least one operation to have been started"
|
||||
);
|
||||
const [op, _] = this.operations[this.operations.length - 1];
|
||||
return (op as unknown) as OperationDescriptor;
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
public nextValue(operation: OperationDescriptor, data: MockData): void {
|
||||
const [_, observer] = this.operations[this.findOperationIndex(operation)];
|
||||
observer.next(data);
|
||||
}
|
||||
|
||||
// TODO: Does this need to do more work, such as finish the observable?
|
||||
public complete(operation: OperationDescriptor): void {
|
||||
const index = this.findOperationIndex(operation);
|
||||
const [_, observer] = this.operations[index];
|
||||
observer.complete();
|
||||
this.operations.splice(index, 1);
|
||||
}
|
||||
|
||||
public resolve(operation: OperationDescriptor, data: MockData): void {
|
||||
this.nextValue(operation, data);
|
||||
this.complete(operation);
|
||||
}
|
||||
|
||||
public reject(operation: OperationDescriptor, error: Error): void {}
|
||||
|
||||
public resolveMostRecentOperation(
|
||||
resolver: (operation: OperationDescriptor) => MockData
|
||||
): void {
|
||||
const operation = this.getMostRecentOperation();
|
||||
this.resolve(operation, resolver(operation));
|
||||
}
|
||||
|
||||
public rejectMostRecentOperation(
|
||||
resolve: (operation: OperationDescriptor) => Error
|
||||
): void {}
|
||||
|
||||
// ----
|
||||
|
||||
private findOperationIndex(operation: OperationDescriptor) {
|
||||
const index = this.operations.findIndex(
|
||||
([op, _]) => op === ((operation as unknown) as Operation)
|
||||
);
|
||||
invariant(index >= 0, "Expected to find operation");
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
export function createMockEnvironment(schema: GraphQLSchema) {
|
||||
const env = new MockEnvironment(schema);
|
||||
return env;
|
||||
}
|
||||
|
||||
export const ApolloMockProvider: React.FC<{
|
||||
environment: MockEnvironment;
|
||||
}> = ({ children, environment }) => {
|
||||
// Build a list of abstract types and their possible types.
|
||||
// TODO: Cache this on the schema?
|
||||
const schema = environment.schema;
|
||||
const possibleTypes: Record<string, string[]> = {};
|
||||
Object.keys(schema.getTypeMap()).forEach((typeName) => {
|
||||
const type = schema.getType(typeName);
|
||||
assertType(type);
|
||||
if (isAbstractType(type)) {
|
||||
possibleTypes[typeName] = schema
|
||||
.getPossibleTypes(type)
|
||||
.map((possibleType) => possibleType.name);
|
||||
}
|
||||
});
|
||||
|
||||
const client = new ApolloClient({
|
||||
cache: new InMemoryCache({
|
||||
possibleTypes,
|
||||
addTypename: false,
|
||||
}),
|
||||
link: new MockLink(environment),
|
||||
});
|
||||
|
||||
return <ApolloProvider client={client}>{children}</ApolloProvider>;
|
||||
};
|
51
yarn.lock
51
yarn.lock
|
@ -1176,7 +1176,14 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7"
|
||||
integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==
|
||||
|
||||
"@types/react@^17.0.3":
|
||||
"@types/react-test-renderer@^17.0.1":
|
||||
version "17.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-test-renderer/-/react-test-renderer-17.0.1.tgz#3120f7d1c157fba9df0118dae20cb0297ee0e06b"
|
||||
integrity sha512-3Fi2O6Zzq/f3QR9dRnlnHso9bMl7weKCviFmfF6B4LS1Uat6Hkm15k0ZAQuDz+UBq6B3+g+NM6IT2nr5QgPzCw==
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react@*", "@types/react@^17.0.3":
|
||||
version "17.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.3.tgz#ba6e215368501ac3826951eef2904574c262cc79"
|
||||
integrity sha512-wYOUxIgs2HZZ0ACNiIayItyluADNbONl7kt8lkLjVK8IitMH5QMyAh75Fwhmo37r1m7L2JaFj03sIfxBVDvRAg==
|
||||
|
@ -4523,7 +4530,7 @@ lodash@4.x, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21, lodash@^4.7.0:
|
|||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||
|
||||
loose-envify@^1.0.0, loose-envify@^1.4.0:
|
||||
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
|
||||
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
|
||||
|
@ -5308,15 +5315,41 @@ ramda@^0.27.1:
|
|||
resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.27.1.tgz#66fc2df3ef873874ffc2da6aa8984658abacf5c9"
|
||||
integrity sha512-PgIdVpn5y5Yns8vqb8FzBUEYn98V3xcPgawAkkgj0YJ0qDsnHCiNmZYfOGMgOvoB0eWFLpYbhxUR3mxfDIMvpw==
|
||||
|
||||
"react-is@^16.12.0 || ^17.0.0", react-is@^17.0.1, react-is@^17.0.2:
|
||||
version "17.0.2"
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
|
||||
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
|
||||
|
||||
react-is@^16.7.0, react-is@^16.8.1:
|
||||
version "16.13.1"
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
|
||||
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
||||
|
||||
react-is@^17.0.1:
|
||||
react-shallow-renderer@^16.13.1:
|
||||
version "16.14.1"
|
||||
resolved "https://registry.yarnpkg.com/react-shallow-renderer/-/react-shallow-renderer-16.14.1.tgz#bf0d02df8a519a558fd9b8215442efa5c840e124"
|
||||
integrity sha512-rkIMcQi01/+kxiTE9D3fdS959U1g7gs+/rborw++42m1O9FAQiNI/UNRZExVUoAOprn4umcXf+pFRou8i4zuBg==
|
||||
dependencies:
|
||||
object-assign "^4.1.1"
|
||||
react-is "^16.12.0 || ^17.0.0"
|
||||
|
||||
react-test-renderer@^17.0.2:
|
||||
version "17.0.2"
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
|
||||
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
|
||||
resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-17.0.2.tgz#4cd4ae5ef1ad5670fc0ef776e8cc7e1231d9866c"
|
||||
integrity sha512-yaQ9cB89c17PUb0x6UfWRs7kQCorVdHlutU1boVPEsB8IDZH6n9tHxMacc3y0JoXOJUsZb/t/Mb8FUWMKaM7iQ==
|
||||
dependencies:
|
||||
object-assign "^4.1.1"
|
||||
react-is "^17.0.2"
|
||||
react-shallow-renderer "^16.13.1"
|
||||
scheduler "^0.20.2"
|
||||
|
||||
react@^17.0.2:
|
||||
version "17.0.2"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037"
|
||||
integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==
|
||||
dependencies:
|
||||
loose-envify "^1.1.0"
|
||||
object-assign "^4.1.1"
|
||||
|
||||
read-pkg-up@^7.0.1:
|
||||
version "7.0.1"
|
||||
|
@ -5654,6 +5687,14 @@ saxes@^5.0.1:
|
|||
dependencies:
|
||||
xmlchars "^2.2.0"
|
||||
|
||||
scheduler@^0.20.2:
|
||||
version "0.20.2"
|
||||
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91"
|
||||
integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==
|
||||
dependencies:
|
||||
loose-envify "^1.1.0"
|
||||
object-assign "^4.1.1"
|
||||
|
||||
"semver@2 || 3 || 4 || 5", semver@^5.5.0:
|
||||
version "5.7.1"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
|
||||
|
|
Загрузка…
Ссылка в новой задаче