diff --git a/.changeset/big-crews-suffer.md b/.changeset/big-crews-suffer.md new file mode 100644 index 00000000000..0fafe342653 --- /dev/null +++ b/.changeset/big-crews-suffer.md @@ -0,0 +1,5 @@ +--- +'@graphql-tools/webpack-loader': minor +--- + +feat(webpack-loader): export Options diff --git a/.changeset/blue-phones-kick.md b/.changeset/blue-phones-kick.md new file mode 100644 index 00000000000..6b45b64a001 --- /dev/null +++ b/.changeset/blue-phones-kick.md @@ -0,0 +1,8 @@ +--- +'@graphql-tools/delegate': major +--- + +BREAKING CHANGE +- Remove `rootValue` from subschemaConfig +- - Pass it through `ExecutionParams` or delegation options +- Do not pass `info.rootValue` if `rootValue` is falsy diff --git a/.changeset/brave-rats-march.md b/.changeset/brave-rats-march.md new file mode 100644 index 00000000000..52e68849001 --- /dev/null +++ b/.changeset/brave-rats-march.md @@ -0,0 +1,7 @@ +--- +'@graphql-tools/wrap': major +--- + +BREAKING CHANGE +- `makeRemoteExecutableSchema` has been removed. +- - You can use [`wrapSchema`](https://www.graphql-tools.com/docs/remote-schemas#creating-an-executor) instead diff --git a/.changeset/cuddly-horses-prove.md b/.changeset/cuddly-horses-prove.md new file mode 100644 index 00000000000..69d10c9951d --- /dev/null +++ b/.changeset/cuddly-horses-prove.md @@ -0,0 +1,5 @@ +--- +'@graphql-tools/utils': major +--- + +BREAKING - Remove fieldToFieldConfig, fieldToFieldConfig, argsToFieldConfigArgument and argumentToArgumentConfig diff --git a/.changeset/eighty-books-develop.md b/.changeset/eighty-books-develop.md new file mode 100644 index 00000000000..33afdd5d08f --- /dev/null +++ b/.changeset/eighty-books-develop.md @@ -0,0 +1,5 @@ +--- +'@graphql-tools/graphql-file-loader': patch +--- + +fix(file-loader): location path must be normalized diff --git a/.changeset/fifty-carrots-pretend.md b/.changeset/fifty-carrots-pretend.md new file mode 100644 index 00000000000..5001357f28e --- /dev/null +++ b/.changeset/fifty-carrots-pretend.md @@ -0,0 +1,11 @@ +--- +'@graphql-tools/url-loader': major +--- + +BREAKING CHANGE +- Remove `handleSDLAsync` and `handleSDLSync`; use `handleSDL` instead +- Remove `useSSEForSubscription` and `useWebSocketLegacyProtocol`; use `subscriptionProtocol` instead +- If introspection source is different than endpoint, use `endpoint` for remote execution source +- Default HTTP Executor is renamed to `buildHTTPExecutor` with a new signature +- `build*Subscriber` methods are renamed to `buildWSLegacyExecutor`, `buildWSExecutor` and `buildSSEExecutor` with new signatures +- `getFetch` no longer takes `async` flag diff --git a/.changeset/fifty-wombats-help.md b/.changeset/fifty-wombats-help.md new file mode 100644 index 00000000000..54780e5be09 --- /dev/null +++ b/.changeset/fifty-wombats-help.md @@ -0,0 +1,5 @@ +--- +'@graphql-tools/mock': patch +--- + +Safer use of Object.prototype.hasOwnProperty #3069 diff --git a/.changeset/forty-ducks-drum.md b/.changeset/forty-ducks-drum.md new file mode 100644 index 00000000000..b1726137568 --- /dev/null +++ b/.changeset/forty-ducks-drum.md @@ -0,0 +1,7 @@ +--- +'@graphql-tools/schema': major +'@graphql-tools/stitch': major +'@graphql-tools/utils': major +--- + +BREAKING - deprecate legacy schema directives and directive resolvers diff --git a/.changeset/grumpy-months-nail.md b/.changeset/grumpy-months-nail.md new file mode 100644 index 00000000000..3eccbc4bcf6 --- /dev/null +++ b/.changeset/grumpy-months-nail.md @@ -0,0 +1,5 @@ +--- +'@graphql-tools/resolvers-composition': patch +--- + +BugFix: Handle parsing endpoints when there are no mutations #3076 diff --git a/.changeset/heavy-vans-whisper.md b/.changeset/heavy-vans-whisper.md new file mode 100644 index 00000000000..99d1fd03470 --- /dev/null +++ b/.changeset/heavy-vans-whisper.md @@ -0,0 +1,5 @@ +--- +'@graphql-tools/schema': major +--- + +breaking - remove logger and addErrorLoggingToSchema - use envelop instead diff --git a/.changeset/long-rings-happen.md b/.changeset/long-rings-happen.md new file mode 100644 index 00000000000..60494b41d0f --- /dev/null +++ b/.changeset/long-rings-happen.md @@ -0,0 +1,5 @@ +--- +'graphql-tools': major +--- + +Add deprecation notice and export makeExecutableSchema only diff --git a/.changeset/mean-news-return.md b/.changeset/mean-news-return.md new file mode 100644 index 00000000000..57f962b5bf1 --- /dev/null +++ b/.changeset/mean-news-return.md @@ -0,0 +1,8 @@ +--- +'@graphql-tools/delegate': major +'@graphql-tools/apollo-engine-loader': major +'@graphql-tools/utils': major +'@graphql-tools/wrap': major +--- + +BREAKING - Use native AggregateError if possible. Native AggregateError doesn't have iterator but errors prop diff --git a/.changeset/new-balloons-reply.md b/.changeset/new-balloons-reply.md new file mode 100644 index 00000000000..9ea808648e4 --- /dev/null +++ b/.changeset/new-balloons-reply.md @@ -0,0 +1,5 @@ +--- +'@graphql-tools/schema': major +--- + +BREAKING - enhance(schema): remove schema level resolvers and addSchemaLevelResolver diff --git a/.changeset/nine-ducks-burn.md b/.changeset/nine-ducks-burn.md new file mode 100644 index 00000000000..0f2eaa561fd --- /dev/null +++ b/.changeset/nine-ducks-burn.md @@ -0,0 +1,6 @@ +--- +'@graphql-tools/wrap': major +--- + +BREAKING CHANGE +- Remove unnecessary `introspectSchemaSync`, `introspectSchema` already handles sync execution diff --git a/.changeset/ninety-shirts-crash.md b/.changeset/ninety-shirts-crash.md new file mode 100644 index 00000000000..9767056e056 --- /dev/null +++ b/.changeset/ninety-shirts-crash.md @@ -0,0 +1,5 @@ +--- +'@graphql-tools/utils': major +--- + +BREAKING - remove debugLog diff --git a/.changeset/pink-glasses-move.md b/.changeset/pink-glasses-move.md new file mode 100644 index 00000000000..c725407a8de --- /dev/null +++ b/.changeset/pink-glasses-move.md @@ -0,0 +1,5 @@ +--- +'@graphql-tools/delegate': major +--- + +BREAKING CHANGE: validations are skipped by default, use validateRequest: true to reenable diff --git a/.changeset/pink-zoos-fold.md b/.changeset/pink-zoos-fold.md new file mode 100644 index 00000000000..cd3565a1f8b --- /dev/null +++ b/.changeset/pink-zoos-fold.md @@ -0,0 +1,5 @@ +--- +'@graphql-tools/links': minor +--- + +feat(links): Respect operationName diff --git a/.changeset/polite-yaks-drive.md b/.changeset/polite-yaks-drive.md new file mode 100644 index 00000000000..e4d486c2dd7 --- /dev/null +++ b/.changeset/polite-yaks-drive.md @@ -0,0 +1,5 @@ +--- +'@graphql-tools/utils': major +--- + +BREAKING - do not apply camelCase naming convention in buildOperationNodeForField diff --git a/.changeset/sharp-wombats-perform.md b/.changeset/sharp-wombats-perform.md new file mode 100644 index 00000000000..f347c5699df --- /dev/null +++ b/.changeset/sharp-wombats-perform.md @@ -0,0 +1,15 @@ +--- +'@graphql-tools/batch-execute': major +'@graphql-tools/delegate': major +'@graphql-tools/links': major +'@graphql-tools/url-loader': major +'@graphql-tools/stitch': major +'@graphql-tools/utils': major +'@graphql-tools/wrap': major +--- + +BREAKING CHANGE +- Remove Subscriber and use only Executor +- - Now `Executor` can receive `AsyncIterable` and subscriptions will also be handled by `Executor`. This is a future-proof change for defer, stream and live queries + + diff --git a/.changeset/silent-comics-tell.md b/.changeset/silent-comics-tell.md new file mode 100644 index 00000000000..b015049e75b --- /dev/null +++ b/.changeset/silent-comics-tell.md @@ -0,0 +1,5 @@ +--- +'@graphql-tools/schema': major +--- + +BREAKING(schema) - remove allowUndefinedResolve option, buildSchemaFromTypeDefinitions and use buildSchema instead diff --git a/.changeset/silver-comics-check.md b/.changeset/silver-comics-check.md new file mode 100644 index 00000000000..06bc791cdd6 --- /dev/null +++ b/.changeset/silver-comics-check.md @@ -0,0 +1,5 @@ +--- +'@graphql-tools/resolvers-composition': minor +--- + +Added glob pattern support for composeResolver method diff --git a/.changeset/slimy-rice-exercise.md b/.changeset/slimy-rice-exercise.md new file mode 100644 index 00000000000..9c469de133e --- /dev/null +++ b/.changeset/slimy-rice-exercise.md @@ -0,0 +1,6 @@ +--- +'@graphql-tools/graphql-tag-pluck': major +--- + +BREAKING CHANGE +- feat(graphql-tag-pluck): keep locationOffset and return graphql-js Source instead of string diff --git a/.changeset/smooth-tips-know.md b/.changeset/smooth-tips-know.md new file mode 100644 index 00000000000..6f8013bc4da --- /dev/null +++ b/.changeset/smooth-tips-know.md @@ -0,0 +1,5 @@ +--- +'@graphql-tools/utils': major +--- + +BREAKING - Remove SchemaVisitor, visitSchema and VisitSchemaKind diff --git a/.changeset/twelve-suns-run.md b/.changeset/twelve-suns-run.md new file mode 100644 index 00000000000..7c816992aa7 --- /dev/null +++ b/.changeset/twelve-suns-run.md @@ -0,0 +1,5 @@ +--- +'@graphql-tools/schema': patch +--- + +enhance(schema): use merge package to handle typeDefs and resolvers merging diff --git a/.changeset/unlucky-kangaroos-tan.md b/.changeset/unlucky-kangaroos-tan.md new file mode 100644 index 00000000000..1ea9d5164c5 --- /dev/null +++ b/.changeset/unlucky-kangaroos-tan.md @@ -0,0 +1,5 @@ +--- +'@graphql-tools/url-loader': patch +--- + +fix(url-loader): fix node support for EventSource diff --git a/.changeset/wicked-tables-beg.md b/.changeset/wicked-tables-beg.md new file mode 100644 index 00000000000..3d44830de3a --- /dev/null +++ b/.changeset/wicked-tables-beg.md @@ -0,0 +1,5 @@ +--- +'@graphql-tools/utils': minor +--- + +feat(utils): Respect operationName and rootValue in ExecutionParams diff --git a/.changeset/yellow-pumas-impress.md b/.changeset/yellow-pumas-impress.md new file mode 100644 index 00000000000..57504e100ce --- /dev/null +++ b/.changeset/yellow-pumas-impress.md @@ -0,0 +1,5 @@ +--- +'@graphql-tools/jest-transform': major +--- + +new jest transform diff --git a/.changeset/young-beans-fail.md b/.changeset/young-beans-fail.md new file mode 100644 index 00000000000..ce34942cdba --- /dev/null +++ b/.changeset/young-beans-fail.md @@ -0,0 +1,10 @@ +--- +'@graphql-tools/url-loader': major +--- + +BREAKING CHANGE +- No more accept arrays or functions for `headers` + +NEW FEATURES +- Respect `operationName` and `extensions` +- Ability to get headers from `extensions.headers` diff --git a/.eslintrc.json b/.eslintrc.json index 12787662740..fd8fff382e9 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -61,7 +61,8 @@ "packages/load/tests/loaders/schema", "website", "scripts", - "packages/loaders/code-file/tests/test-files" + "packages/loaders/code-file/tests/test-files", + "packages/loaders/git/tests/test-files" ], "globals":{ "BigInt": true diff --git a/.github/workflows/canary.yml b/.github/workflows/canary.yml index 2dc25753ff5..058d1b6564c 100644 --- a/.github/workflows/canary.yml +++ b/.github/workflows/canary.yml @@ -4,12 +4,24 @@ on: pull_request: branches: - master - + workflow_dispatch: + inputs: + onDemand: + description: 'Are you sure?' + required: true + default: 'yes' + npmTag: + description: 'NPM Tag' + required: true + default: 'alpha' + npmVersionSuffix: + description: 'Custom NPM Version Suffix' + required: false jobs: publish-canary: name: Publish Canary runs-on: ubuntu-latest - if: github.event.pull_request.head.repo.full_name == github.repository + if: github.event.pull_request.head.repo.full_name == github.repository || github.event.inputs.onDemand == 'yes' steps: - name: Checkout Master uses: actions/checkout@v2 @@ -44,6 +56,10 @@ jobs: npm-token: ${{ secrets.NODE_AUTH_TOKEN }} npm-script: 'yarn release:canary' changesets: true + env: + ON_DEMAND: ${{github.event.inputs.onDemand}} + NPM_TAG: ${{github.event.inputs.npmTag || 'alpha'}} + NPM_VERSION_SUFFIX: ${{github.event.inputs.npmVersionSuffix}} - name: Publish a message if: steps.canary.outputs.released uses: 'kamilkisiela/pr-comment@master' diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index bcd0e515c36..c7c4f90c05c 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -31,7 +31,7 @@ jobs: - name: Lint run: yarn lint build: - name: Build on ${{matrix.os}} GraphQL v${{matrix.graphql_version}} + name: Type Check on GraphQL v${{matrix.graphql_version}} runs-on: ubuntu-latest strategy: matrix: @@ -55,14 +55,13 @@ jobs: - name: Install Dependencies using Yarn run: yarn install --ignore-engines && git checkout yarn.lock - name: Build - run: yarn ts:transpile + run: yarn ts:check test: - name: Test on ${{matrix.os}}, Node ${{matrix.node_version}} and GraphQL v${{matrix.graphql_version}} - runs-on: ${{matrix.os}} + name: Test, Node ${{matrix.node_version}} and GraphQL v${{matrix.graphql_version}} + runs-on: ubuntu-latest strategy: matrix: - os: [ubuntu-latest] # remove windows to speed up the tests - node_version: [10, 16] + node_version: [12, 16] graphql_version: [14, 15] steps: - name: Checkout Master diff --git a/.github/workflows/website.yml b/.github/workflows/website.yml index be451470b8d..58e422f91b3 100644 --- a/.github/workflows/website.yml +++ b/.github/workflows/website.yml @@ -35,6 +35,8 @@ jobs: key: ${{ runner.os }}-16-16-yarn-${{ hashFiles('yarn.lock') }} restore-keys: | ${{ runner.os }}-16-16-yarn- + - name: Align TypeScript version with typedoc + run: node scripts/install-typedocs-typescript-version.js - name: Install Dependencies using Yarn run: yarn install --ignore-engines && git checkout yarn.lock - name: Deploy 🚀 diff --git a/.gitignore b/.gitignore index c48856fce81..a121041328d 100644 --- a/.gitignore +++ b/.gitignore @@ -77,3 +77,5 @@ junit.xml package-lock.json website/yarn.lock +website/api-sidebar.json +website/docs/api diff --git a/package.json b/package.json index 30253190792..0fdea9dc06e 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,8 @@ "postinstall": "patch-package && husky install", "predeploy:website": "yarn build:api-docs", "deploy:website": "cd website && yarn deploy", - "ts:transpile": "concurrently \"tsc --project tsconfig.build.json\" \"tsc --project tsconfig.build.es5.json\"", + "ts:check": "tsc --noEmit --incremental", + "ts:transpile": "concurrently \"tsc --project tsconfig.build.json --incremental\" \"tsc --project tsconfig.build.es5.json --incremental\"", "clean-dist": "rimraf \"packages/**/dist\" && rimraf \"packages/**/dist-es5\" && rimraf \".bob\"", "build": "yarn ts:transpile && bob build", "build:api-docs": "node scripts/build-api-docs.js", @@ -18,7 +19,7 @@ "prerelease": "yarn build", "prerelease-canary": "yarn build", "release": "changeset publish", - "release:canary": "(node scripts/canary-release.js && yarn build && yarn changeset publish --tag alpha) || echo Skipping Canary..." + "release:canary": "(node scripts/canary-release.js && yarn build && yarn changeset publish --tag $NPM_TAG) || echo Skipping Canary..." }, "repository": { "type": "git", @@ -43,37 +44,37 @@ }, "devDependencies": { "bob-the-bundler": "1.4.1", - "@babel/core": "7.14.5", + "@babel/core": "7.14.6", "@babel/plugin-proposal-class-properties": "7.14.5", - "@babel/preset-env": "7.14.5", + "@babel/preset-env": "7.14.7", "@babel/preset-typescript": "7.14.5", "@changesets/cli": "2.16.0", "@types/jest": "26.0.23", "@types/node": "14.17.3", - "@typescript-eslint/eslint-plugin": "4.26.1", - "@typescript-eslint/parser": "4.26.1", - "babel-jest": "27.0.2", + "@typescript-eslint/eslint-plugin": "4.28.0", + "@typescript-eslint/parser": "4.28.0", + "babel-jest": "27.0.6", "concurrently": "6.2.0", - "eslint": "7.28.0", + "eslint": "7.30.0", "eslint-config-prettier": "8.3.0", "eslint-config-standard": "16.0.3", "eslint-plugin-import": "2.23.4", "eslint-plugin-node": "11.1.0", "eslint-plugin-promise": "5.1.0", "eslint-plugin-standard": "5.0.0", - "graphql": "15.5.0", + "graphql": "15.5.1", "graphql-helix": "1.6.1", "graphql-subscriptions": "1.2.1", - "husky": "6.0.0", - "jest": "27.0.4", + "husky": "7.0.0", + "jest": "27.0.6", "lint-staged": "11.0.0", - "nock": "13.1.0", + "nock": "13.1.1", "patch-package": "6.4.7", - "prettier": "2.3.1", + "prettier": "2.3.2", "ts-jest": "27.0.3", - "typedoc": "0.20.36", - "typedoc-plugin-markdown": "3.9.0", - "typescript": "4.3.2" + "typedoc": "0.21.2", + "typedoc-plugin-markdown": "3.10.2", + "typescript": "4.3.5" }, "lint-staged": { "packages/**/src/**/*.{ts,tsx}": [ @@ -94,7 +95,8 @@ ] }, "resolutions": { - "graphql": "15.5.0", + "graphql": "15.5.1", + "esbuild": "^0.12.8", "@changesets/apply-release-plan": "5.0.0" } } diff --git a/packages/batch-delegate/package.json b/packages/batch-delegate/package.json index b2aa808c521..d8957e3712c 100644 --- a/packages/batch-delegate/package.json +++ b/packages/batch-delegate/package.json @@ -35,7 +35,7 @@ "@graphql-tools/delegate": "^7.1.4", "@graphql-tools/utils": "^7.8.1", "dataloader": "2.0.0", - "tslib": "~2.2.0" + "tslib": "~2.3.0" }, "devDependencies": { "@graphql-tools/schema": "^7.1.4", diff --git a/packages/batch-delegate/src/batchDelegateToSchema.ts b/packages/batch-delegate/src/batchDelegateToSchema.ts index ee5057522b8..ba12dd310fb 100644 --- a/packages/batch-delegate/src/batchDelegateToSchema.ts +++ b/packages/batch-delegate/src/batchDelegateToSchema.ts @@ -2,7 +2,7 @@ import { BatchDelegateOptions } from './types'; import { getLoader } from './getLoader'; -export function batchDelegateToSchema(options: BatchDelegateOptions): any { +export function batchDelegateToSchema(options: BatchDelegateOptions): any { const key = options.key; if (key == null) { return null; diff --git a/packages/batch-delegate/src/getLoader.ts b/packages/batch-delegate/src/getLoader.ts index 03d2d1b2742..5b62f0d0ff0 100644 --- a/packages/batch-delegate/src/getLoader.ts +++ b/packages/batch-delegate/src/getLoader.ts @@ -9,18 +9,34 @@ import { BatchDelegateOptions } from './types'; const cache1: WeakMap< ReadonlyArray, - WeakMap>> + WeakMap, Record>> > = new WeakMap(); function createBatchFn(options: BatchDelegateOptions) { const argsFromKeys = options.argsFromKeys ?? ((keys: ReadonlyArray) => ({ ids: keys })); + const fieldName = options.fieldName ?? options.info.fieldName; const { valuesFromResults, lazyOptionsFn } = options; return async (keys: ReadonlyArray) => { const results = await delegateToSchema({ returnType: new GraphQLList(getNamedType(options.info.returnType) as GraphQLOutputType), - onLocatedError: originalError => - relocatedError(originalError, originalError.path.slice(0, 0).concat(originalError.path.slice(2))), + onLocatedError: originalError => { + if (originalError.path == null) { + return originalError; + } + + const [pathFieldName, pathNumber] = originalError.path; + + if (pathFieldName !== fieldName) { + return originalError; + } + const pathNumberType = typeof pathNumber; + if (pathNumberType !== 'number') { + return originalError; + } + + return relocatedError(originalError, originalError.path.slice(0, 0).concat(originalError.path.slice(2))); + }, args: argsFromKeys(keys), ...(lazyOptionsFn == null ? options : lazyOptionsFn(options)), }); @@ -35,10 +51,10 @@ function createBatchFn(options: BatchDelegateOptions) { }; } -export function getLoader(options: BatchDelegateOptions): DataLoader { +export function getLoader(options: BatchDelegateOptions): DataLoader { const fieldName = options.fieldName ?? options.info.fieldName; - let cache2: WeakMap>> = cache1.get( + let cache2: WeakMap>> | undefined = cache1.get( options.info.fieldNodes ); @@ -56,7 +72,7 @@ export function getLoader(options: BatchDelegateOptions let loaders = cache2.get(options.schema); if (loaders === undefined) { - loaders = Object.create(null); + loaders = Object.create(null) as Record>; cache2.set(options.schema, loaders); const batchFn = createBatchFn(options); const loader = new DataLoader(keys => batchFn(keys), options.dataLoaderOptions); diff --git a/packages/batch-delegate/tests/basic.example.test.ts b/packages/batch-delegate/tests/basic.example.test.ts index 042a693567a..9f6ed75d6f3 100644 --- a/packages/batch-delegate/tests/basic.example.test.ts +++ b/packages/batch-delegate/tests/basic.example.test.ts @@ -89,7 +89,7 @@ describe('batch delegation within basic stitching example', () => { expect(numCalls).toEqual(1); expect(result.errors).toBeUndefined(); - expect(result.data.trendingChirps[0].chirpedAtUser.email).not.toBe(null); + expect(result.data!['trendingChirps'][0].chirpedAtUser.email).not.toBe(null); }); test('works with key arrays', async () => { @@ -108,9 +108,9 @@ describe('batch delegation within basic stitching example', () => { `, resolvers: { Query: { - posts: (obj, args) => { + posts: (_, args) => { numCalls += 1; - return args.ids.map(id => ({ id, title: `Post ${id}` })); + return args.ids.map((id: unknown) => ({ id, title: `Post ${id}` })); } } } @@ -129,8 +129,8 @@ describe('batch delegation within basic stitching example', () => { `, resolvers: { Query: { - users: (obj, args) => { - return args.ids.map(id => { + users: (_, args) => { + return args.ids.map((id: unknown) => { return { id, postIds: [Number(id)+1, Number(id)+2] }; }); } diff --git a/packages/batch-delegate/tests/typeMerging.example.test.ts b/packages/batch-delegate/tests/typeMerging.example.test.ts index 171afd9bdf0..e8e000341bc 100644 --- a/packages/batch-delegate/tests/typeMerging.example.test.ts +++ b/packages/batch-delegate/tests/typeMerging.example.test.ts @@ -84,7 +84,7 @@ describe('merging using type merging', () => { Query: { mostStockedProduct: () => inventory.find(i => i.upc === '3'), _products: (_root, { representations }) => { - return representations.map((rep: Record) => ({ ...rep, ...inventory.find(i => i.upc === rep.upc) })); + return representations.map((rep: Record) => ({ ...rep, ...inventory.find(i => i.upc === rep['upc']) })); }, }, }, diff --git a/packages/batch-delegate/tests/withTransforms.test.ts b/packages/batch-delegate/tests/withTransforms.test.ts index e204dcf8db6..66f64086a8e 100644 --- a/packages/batch-delegate/tests/withTransforms.test.ts +++ b/packages/batch-delegate/tests/withTransforms.test.ts @@ -73,7 +73,7 @@ describe('works with complex transforms', () => { ] }), resultTransformer: (results, delegationContext) => { - const userIds = delegationContext.args.userIds; + const userIds = delegationContext.args['userIds']; const booksByUserIds = results.reduce( (acc: any, { userId, books }: { userId: string, books: any[] }) => { acc[userId] = books @@ -100,7 +100,7 @@ describe('works with complex transforms', () => { context, info, transforms: [queryTransform], - returnType: new GraphQLList(new GraphQLList(info.schema.getType('Book'))) + returnType: new GraphQLList(new GraphQLList(info.schema.getType('Book')!)) }), }, }, diff --git a/packages/batch-execute/package.json b/packages/batch-execute/package.json index bd9d2800d47..e06cc9a1aa7 100644 --- a/packages/batch-execute/package.json +++ b/packages/batch-execute/package.json @@ -34,7 +34,7 @@ "dependencies": { "@graphql-tools/utils": "^7.7.0", "dataloader": "2.0.0", - "tslib": "~2.2.0", + "tslib": "~2.3.0", "value-or-promise": "1.0.10" }, "publishConfig": { diff --git a/packages/batch-execute/src/createBatchingExecutor.ts b/packages/batch-execute/src/createBatchingExecutor.ts index b3ccbe1381c..5f1bd306872 100644 --- a/packages/batch-execute/src/createBatchingExecutor.ts +++ b/packages/batch-execute/src/createBatchingExecutor.ts @@ -12,28 +12,40 @@ import { splitResult } from './splitResult'; export function createBatchingExecutor( executor: Executor, dataLoaderOptions?: DataLoader.Options, - extensionsReducer?: (mergedExtensions: Record, executionParams: ExecutionParams) => Record + extensionsReducer: ( + mergedExtensions: Record, + executionParams: ExecutionParams + ) => Record = defaultExtensionsReducer ): Executor { - const loader = new DataLoader( - createLoadFn(executor, extensionsReducer ?? defaultExtensionsReducer), - dataLoaderOptions - ); - return (executionParams: ExecutionParams) => loader.load(executionParams); + const loader = new DataLoader(createLoadFn(executor, extensionsReducer), dataLoaderOptions); + return (executionParams: ExecutionParams) => + executionParams.info?.operation.operation === 'subscription' + ? executor(executionParams) + : loader.load(executionParams); } function createLoadFn( - executor: ({ document, context, variables, info }: ExecutionParams) => ExecutionResult | Promise, + executor: Executor, extensionsReducer: (mergedExtensions: Record, executionParams: ExecutionParams) => Record ) { - return async (execs: Array): Promise> => { + return async (execs: ReadonlyArray): Promise> => { const execBatches: Array> = []; let index = 0; const exec = execs[index]; let currentBatch: Array = [exec]; execBatches.push(currentBatch); - const operationType = getOperationAST(exec.document, undefined).operation; + + const operationType = getOperationAST(exec.document, undefined)?.operation; + if (operationType == null) { + throw new Error('Could not identify operation type of document.'); + } + while (++index < execs.length) { - const currentOperationType = getOperationAST(execs[index].document, undefined).operation; + const currentOperationType = getOperationAST(execs[index].document, undefined)?.operation; + if (operationType == null) { + throw new Error('Could not identify operation type of document.'); + } + if (operationType === currentOperationType) { currentBatch.push(execs[index]); } else { @@ -42,19 +54,19 @@ function createLoadFn( } } - const executionResults: Array> = []; - execBatches.forEach(execBatch => { + const executionResults: Array> = execBatches.map(execBatch => { const mergedExecutionParams = mergeExecutionParams(execBatch, extensionsReducer); - executionResults.push(new ValueOrPromise(() => executor(mergedExecutionParams))); + return new ValueOrPromise(() => executor(mergedExecutionParams) as ExecutionResult); }); - return ValueOrPromise.all(executionResults).then(resultBatches => { - let results: Array = []; - resultBatches.forEach((resultBatch, index) => { - results = results.concat(splitResult(resultBatch, execBatches[index].length)); - }); - return results; - }).resolve(); + return ValueOrPromise.all(executionResults) + .then(resultBatches => + resultBatches.reduce( + (results, resultBatch, index) => results.concat(splitResult(resultBatch, execBatches[index].length)), + new Array>>() + ) + ) + .resolve(); }; } diff --git a/packages/batch-execute/src/getBatchingExecutor.ts b/packages/batch-execute/src/getBatchingExecutor.ts index ba267b0fd0c..6d5e5de32cc 100644 --- a/packages/batch-execute/src/getBatchingExecutor.ts +++ b/packages/batch-execute/src/getBatchingExecutor.ts @@ -5,10 +5,12 @@ import { createBatchingExecutor } from './createBatchingExecutor'; import { memoize2of4 } from './memoize'; export const getBatchingExecutor = memoize2of4(function ( - _context: Record = self ?? window ?? global, + _context: Record, executor: Executor, - dataLoaderOptions?: DataLoader.Options, - extensionsReducer?: (mergedExtensions: Record, executionParams: ExecutionParams) => Record + dataLoaderOptions?: DataLoader.Options | undefined, + extensionsReducer?: + | undefined + | ((mergedExtensions: Record, executionParams: ExecutionParams) => Record) ): Executor { return createBatchingExecutor(executor, dataLoaderOptions, extensionsReducer); }); diff --git a/packages/batch-execute/src/mergeExecutionParams.ts b/packages/batch-execute/src/mergeExecutionParams.ts index 61b4184a634..80e2fce52fc 100644 --- a/packages/batch-execute/src/mergeExecutionParams.ts +++ b/packages/batch-execute/src/mergeExecutionParams.ts @@ -18,7 +18,7 @@ import { OperationTypeNode, } from 'graphql'; -import { ExecutionParams } from '@graphql-tools/utils'; +import { ExecutionParams, Maybe } from '@graphql-tools/utils'; import { createPrefix } from './prefix'; @@ -66,24 +66,31 @@ export function mergeExecutionParams( const mergedFragmentDefinitions: Array = []; let mergedExtensions: Record = Object.create(null); - let operation: OperationTypeNode; + let operation: Maybe; - execs.forEach((executionParams, index) => { + for (const index in execs) { + const executionParams = execs[index]; const prefixedExecutionParams = prefixExecutionParams(createPrefix(index), executionParams); - prefixedExecutionParams.document.definitions.forEach(def => { + for (const def of prefixedExecutionParams.document.definitions) { if (isOperationDefinition(def)) { operation = def.operation; mergedSelections.push(...def.selectionSet.selections); - mergedVariableDefinitions.push(...(def.variableDefinitions ?? [])); + if (def.variableDefinitions) { + mergedVariableDefinitions.push(...def.variableDefinitions); + } } if (isFragmentDefinition(def)) { mergedFragmentDefinitions.push(def); } - }); + } Object.assign(mergedVariables, prefixedExecutionParams.variables); mergedExtensions = extensionsReducer(mergedExtensions, executionParams); - }); + } + + if (operation == null) { + throw new Error('Could not identify operation type. Did the document only include fragment definitions?'); + } const mergedOperationDefinition: OperationDefinitionNode = { kind: Kind.OPERATION_DEFINITION, @@ -109,7 +116,8 @@ export function mergeExecutionParams( function prefixExecutionParams(prefix: string, executionParams: ExecutionParams): ExecutionParams { let document = aliasTopLevelFields(prefix, executionParams.document); - const variableNames = Object.keys(executionParams.variables); + const executionVariables = executionParams.variables ?? {}; + const variableNames = Object.keys(executionVariables); if (variableNames.length === 0) { return { ...executionParams, document }; @@ -122,7 +130,7 @@ function prefixExecutionParams(prefix: string, executionParams: ExecutionParams) }); const prefixedVariables = variableNames.reduce((acc, name) => { - acc[prefix + name] = executionParams.variables[name]; + acc[prefix + name] = executionVariables[name]; return acc; }, Object.create(null)); @@ -150,9 +158,9 @@ function aliasTopLevelFields(prefix: string, document: DocumentNode): DocumentNo }; }, }; - return visit(document, transformer, ({ + return visit(document, transformer, { [Kind.DOCUMENT]: [`definitions`], - } as unknown) as VisitorKeyMap); + } as unknown as VisitorKeyMap); } /** diff --git a/packages/batch-execute/src/prefix.ts b/packages/batch-execute/src/prefix.ts index 73cb9d52323..97460d521c8 100644 --- a/packages/batch-execute/src/prefix.ts +++ b/packages/batch-execute/src/prefix.ts @@ -1,10 +1,10 @@ // adapted from https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-source-graphql/src/batching/merge-queries.js -export function createPrefix(index: number): string { +export function createPrefix(index: string): string { return `graphqlTools${index}_`; } -export function parseKey(prefixedKey: string): { index: number; originalKey: string } { +export function parseKey(prefixedKey: string): null | { index: number; originalKey: string } { const match = /^graphqlTools([\d]+)_(.*)$/.exec(prefixedKey); if (match && match.length === 3 && !isNaN(Number(match[1])) && match[2]) { return { index: Number(match[1]), originalKey: match[2] }; diff --git a/packages/batch-execute/src/splitResult.ts b/packages/batch-execute/src/splitResult.ts index fd2682a8e60..1626a77186e 100644 --- a/packages/batch-execute/src/splitResult.ts +++ b/packages/batch-execute/src/splitResult.ts @@ -2,61 +2,48 @@ import { ExecutionResult, GraphQLError } from 'graphql'; -import { relocatedError } from '@graphql-tools/utils'; +import { assertSome, relocatedError } from '@graphql-tools/utils'; import { parseKey } from './prefix'; /** * Split and transform result of the query produced by the `merge` function */ -export function splitResult(mergedResult: ExecutionResult, numResults: number): Array { +export function splitResult({ data, errors }: ExecutionResult, numResults: number): Array { const splitResults: Array = []; for (let i = 0; i < numResults; i++) { splitResults.push({}); } - const data = mergedResult.data; if (data) { - Object.keys(data).forEach(prefixedKey => { - const { index, originalKey } = parseKey(prefixedKey); - if (!splitResults[index].data) { - splitResults[index].data = { [originalKey]: data[prefixedKey] }; + for (const prefixedKey in data) { + const parsedKey = parseKey(prefixedKey); + assertSome(parsedKey, "'parsedKey' should not be null."); + const { index, originalKey } = parsedKey; + const result = splitResults[index]; + if (result == null) { + continue; + } + if (result.data == null) { + result.data = { [originalKey]: data[prefixedKey] }; } else { - splitResults[index].data[originalKey] = data[prefixedKey]; + result.data[originalKey] = data[prefixedKey]; } - }); + } } - const errors = mergedResult.errors; if (errors) { - const newErrors: Record> = Object.create(null); - errors.forEach(error => { + for (const error of errors) { if (error.path) { const parsedKey = parseKey(error.path[0] as string); if (parsedKey) { const { index, originalKey } = parsedKey; const newError = relocatedError(error, [originalKey, ...error.path.slice(1)]); - if (!newErrors[index]) { - newErrors[index] = [newError]; - } else { - newErrors[index].push(newError); - } - return; + const errors = (splitResults[index].errors = (splitResults[index].errors || []) as GraphQLError[]); + errors.push(newError); } } - - splitResults.forEach((_splitResult, index) => { - if (!newErrors[index]) { - newErrors[index] = [error]; - } else { - newErrors[index].push(error); - } - }); - }); - - Object.keys(newErrors).forEach(index => { - splitResults[index].errors = newErrors[index]; - }); + } } return splitResults; diff --git a/packages/delegate/package.json b/packages/delegate/package.json index 52ed29ad471..663562b2253 100644 --- a/packages/delegate/package.json +++ b/packages/delegate/package.json @@ -35,9 +35,8 @@ "@graphql-tools/batch-execute": "^7.1.2", "@graphql-tools/schema": "^7.1.5", "@graphql-tools/utils": "^7.7.1", - "@ardatan/aggregate-error": "0.0.6", "dataloader": "2.0.0", - "tslib": "~2.2.0", + "tslib": "~2.3.0", "value-or-promise": "1.0.10" }, "publishConfig": { diff --git a/packages/delegate/src/Subschema.ts b/packages/delegate/src/Subschema.ts index 01754e00e43..668d68f82e6 100644 --- a/packages/delegate/src/Subschema.ts +++ b/packages/delegate/src/Subschema.ts @@ -3,7 +3,7 @@ import { GraphQLSchema } from 'graphql'; import { SubschemaConfig, Transform, MergedTypeConfig, CreateProxyingResolverFn, BatchingOptions } from './types'; import { applySchemaTransforms } from './applySchemaTransforms'; -import { Executor, Subscriber } from '@graphql-tools/utils'; +import { Executor } from '@graphql-tools/utils'; export function isSubschema(value: any): value is Subschema { return Boolean(value.transformedSchema); @@ -15,17 +15,16 @@ interface ISubschema> } export class Subschema> - implements ISubschema { + implements ISubschema +{ public schema: GraphQLSchema; - public rootValue?: Record; public executor?: Executor; - public subscriber?: Subscriber; public batch?: boolean; public batchingOptions?: BatchingOptions; public createProxyingResolver?: CreateProxyingResolverFn; - public transforms: Array; + public transforms: Array>; public transformedSchema: GraphQLSchema; public merge?: Record>; @@ -33,9 +32,7 @@ export class Subschema> constructor(config: SubschemaConfig) { this.schema = config.schema; - this.rootValue = config.rootValue; this.executor = config.executor; - this.subscriber = config.subscriber; this.batch = config.batch; this.batchingOptions = config.batchingOptions; diff --git a/packages/delegate/src/Transformer.ts b/packages/delegate/src/Transformer.ts index 59bf49a83ec..376cb24015c 100644 --- a/packages/delegate/src/Transformer.ts +++ b/packages/delegate/src/Transformer.ts @@ -9,14 +9,16 @@ interface Transformation { context: Record; } -export class Transformer { +export class Transformer> { private transformations: Array = []; - private delegationContext: DelegationContext; + private delegationContext: DelegationContext; - constructor(context: DelegationContext, binding: DelegationBinding = defaultDelegationBinding) { + constructor(context: DelegationContext, binding: DelegationBinding = defaultDelegationBinding) { this.delegationContext = context; const delegationTransforms: Array = binding(this.delegationContext); - delegationTransforms.forEach(transform => this.addTransform(transform, {})); + for (const transform of delegationTransforms) { + this.addTransform(transform, {}); + } } private addTransform(transform: Transform, context = {}) { diff --git a/packages/delegate/src/applySchemaTransforms.ts b/packages/delegate/src/applySchemaTransforms.ts index 4f6dbd84713..225cb59920b 100644 --- a/packages/delegate/src/applySchemaTransforms.ts +++ b/packages/delegate/src/applySchemaTransforms.ts @@ -2,11 +2,11 @@ import { GraphQLSchema } from 'graphql'; import { cloneSchema } from '@graphql-tools/utils'; -import { SubschemaConfig, Transform } from './types'; +import { SubschemaConfig } from './types'; export function applySchemaTransforms( originalWrappingSchema: GraphQLSchema, - subschemaConfig: SubschemaConfig, + subschemaConfig: SubschemaConfig, transformedSchema?: GraphQLSchema ): GraphQLSchema { const schemaTransforms = subschemaConfig.transforms; @@ -16,7 +16,7 @@ export function applySchemaTransforms( } return schemaTransforms.reduce( - (schema: GraphQLSchema, transform: Transform) => + (schema: GraphQLSchema, transform) => transform.transformSchema != null ? transform.transformSchema(cloneSchema(schema), subschemaConfig, transformedSchema) : schema, diff --git a/packages/delegate/src/createRequest.ts b/packages/delegate/src/createRequest.ts index 9c2b053cb5d..f5bde01de0c 100644 --- a/packages/delegate/src/createRequest.ts +++ b/packages/delegate/src/createRequest.ts @@ -10,7 +10,6 @@ import { typeFromAST, NamedTypeNode, GraphQLInputType, - GraphQLArgument, VariableDefinitionNode, SelectionSetNode, DefinitionNode, @@ -53,6 +52,10 @@ export function createRequestFromInfo({ }); } +const raiseError = (message: string) => { + throw new Error(message); +}; + export function createRequest({ sourceSchema, sourceParentType, @@ -66,16 +69,16 @@ export function createRequest({ selectionSet, fieldNodes, }: ICreateRequest): Request { - let newSelectionSet: SelectionSetNode; + let newSelectionSet: SelectionSetNode | undefined; let argumentNodeMap: Record; if (selectionSet != null) { newSelectionSet = selectionSet; argumentNodeMap = Object.create(null); } else { - const selections: Array = fieldNodes.reduce( + const selections: Array = (fieldNodes ?? []).reduce( (acc, fieldNode) => (fieldNode.selectionSet != null ? acc.concat(fieldNode.selectionSet.selections) : acc), - [] + [] as Array ); newSelectionSet = selections.length @@ -87,7 +90,7 @@ export function createRequest({ argumentNodeMap = {}; - const args = fieldNodes[0]?.arguments; + const args = fieldNodes?.[0]?.arguments; if (args) { argumentNodeMap = args.reduce( (prev, curr) => ({ @@ -103,18 +106,18 @@ export function createRequest({ const variableDefinitionMap = Object.create(null); if (sourceSchema != null && variableDefinitions != null) { - variableDefinitions.forEach(def => { + for (const def of variableDefinitions) { const varName = def.variable.name.value; variableDefinitionMap[varName] = def; const varType = typeFromAST(sourceSchema, def.type as NamedTypeNode) as GraphQLInputType; - const serializedValue = serializeInputValue(varType, variableValues[varName]); + const serializedValue = serializeInputValue(varType, variableValues?.[varName]); if (serializedValue !== undefined) { newVariables[varName] = serializedValue; } - }); + } } - if (sourceParentType != null) { + if (sourceParentType != null && sourceFieldName != null) { updateArgumentsWithDefaults( sourceParentType, sourceFieldName, @@ -126,10 +129,13 @@ export function createRequest({ const rootfieldNode: FieldNode = { kind: Kind.FIELD, - arguments: Object.keys(argumentNodeMap).map(argName => argumentNodeMap[argName]), + arguments: Object.values(argumentNodeMap), name: { kind: Kind.NAME, - value: targetFieldName || fieldNodes[0].name.value, + value: + targetFieldName ?? + fieldNodes?.[0]?.name.value ?? + raiseError("Either 'targetFieldName' or a non empty 'fieldNodes' array must be provided."), }, selectionSet: newSelectionSet, }; @@ -145,17 +151,17 @@ export function createRequest({ kind: Kind.OPERATION_DEFINITION, name: operationName, operation: targetOperation, - variableDefinitions: Object.keys(variableDefinitionMap).map(varName => variableDefinitionMap[varName]), + variableDefinitions: Object.values(variableDefinitionMap), selectionSet: { kind: Kind.SELECTION_SET, selections: [rootfieldNode], }, }; - let definitions: Array = [operationDefinition]; + const definitions: Array = [operationDefinition]; if (fragments != null) { - definitions = definitions.concat(Object.keys(fragments).map(fragmentName => fragments[fragmentName])); + definitions.push(...Object.values(fragments)); } const document: DocumentNode = { @@ -166,6 +172,7 @@ export function createRequest({ return { document, variables: newVariables, + operationName: targetOperationName, }; } @@ -177,7 +184,7 @@ function updateArgumentsWithDefaults( variableValues: Record ): void { const sourceField = sourceParentType.getFields()[sourceFieldName]; - sourceField.args.forEach((argument: GraphQLArgument) => { + for (const argument of sourceField.args) { const argName = argument.name; const sourceArgType = argument.type; @@ -195,5 +202,5 @@ function updateArgumentsWithDefaults( ); } } - }); + } } diff --git a/packages/delegate/src/delegateToSchema.ts b/packages/delegate/src/delegateToSchema.ts index a120ae46db1..2c1d4896f80 100644 --- a/packages/delegate/src/delegateToSchema.ts +++ b/packages/delegate/src/delegateToSchema.ts @@ -14,19 +14,30 @@ import { import { ValueOrPromise } from 'value-or-promise'; -import AggregateError from '@ardatan/aggregate-error'; - import { getBatchingExecutor } from '@graphql-tools/batch-execute'; -import { mapAsyncIterator, ExecutionResult, Executor, ExecutionParams, Subscriber } from '@graphql-tools/utils'; +import { + mapAsyncIterator, + Executor, + ExecutionParams, + Maybe, + assertSome, + AggregateError, + isAsyncIterable, +} from '@graphql-tools/utils'; -import { IDelegateToSchemaOptions, IDelegateRequestOptions, StitchingInfo, DelegationContext } from './types'; +import { + IDelegateToSchemaOptions, + IDelegateRequestOptions, + StitchingInfo, + DelegationContext, + SubschemaConfig, +} from './types'; import { isSubschemaConfig } from './subschemaConfig'; import { Subschema } from './Subschema'; import { createRequestFromInfo, getDelegatingOperation } from './createRequest'; import { Transformer } from './Transformer'; -import { memoize2 } from './memoize'; export function delegateToSchema, TArgs = any>( options: IDelegateToSchemaOptions @@ -64,7 +75,7 @@ function getDelegationReturnType( operation: OperationTypeNode, fieldName: string ): GraphQLOutputType { - let rootType: GraphQLObjectType; + let rootType: Maybe>; if (operation === 'query') { rootType = targetSchema.getQueryType(); } else if (operation === 'mutation') { @@ -72,91 +83,98 @@ function getDelegationReturnType( } else { rootType = targetSchema.getSubscriptionType(); } + assertSome(rootType); return rootType.getFields()[fieldName].type; } -export function delegateRequest, TArgs = any>(options: IDelegateRequestOptions) { +export function delegateRequest, TArgs = any>( + options: IDelegateRequestOptions +) { const delegationContext = getDelegationContext(options); - const transformer = new Transformer(delegationContext, options.binding); + const transformer = new Transformer(delegationContext, options.binding); const processedRequest = transformer.transformRequest(options.request); - if (!options.skipValidation) { + if (options.validateRequest) { validateRequest(delegationContext, processedRequest.document); } - const { operation, context, info } = delegationContext; + const { context, info } = delegationContext; - if (operation === 'query' || operation === 'mutation') { - const executor = getExecutor(delegationContext); + const executor = getExecutor(delegationContext); - return new ValueOrPromise(() => executor({ + return new ValueOrPromise(() => + executor({ ...processedRequest, context, info, - })).then(originalResult => transformer.transformResult(originalResult)).resolve(); - } - - const subscriber = getSubscriber(delegationContext); - - return subscriber({ - ...processedRequest, - context, - info, - }).then((subscriptionResult: AsyncIterableIterator | ExecutionResult) => { - if (Symbol.asyncIterator in subscriptionResult) { - // "subscribe" to the subscription result and map the result through the transforms - return mapAsyncIterator( - subscriptionResult as AsyncIterableIterator, - originalResult => ({ + }) + ) + .then(originalResult => { + if (isAsyncIterable(originalResult)) { + // "subscribe" to the subscription result and map the result through the transforms + return mapAsyncIterator(originalResult, originalResult => ({ [delegationContext.fieldName]: transformer.transformResult(originalResult), - }) - ); - } - - return transformer.transformResult(subscriptionResult as ExecutionResult); - }); + })); + } + return transformer.transformResult(originalResult); + }) + .resolve(); } const emptyObject = {}; -function getDelegationContext({ +function getDelegationContext({ request, schema, operation, fieldName, returnType, - args, + args = {}, context, info, - rootValue, + rootValue = emptyObject, transforms = [], transformedSchema, - skipTypeMerging, -}: IDelegateRequestOptions): DelegationContext { - let operationDefinition: OperationDefinitionNode; - let targetOperation: OperationTypeNode; + skipTypeMerging = false, + operationName, +}: IDelegateRequestOptions): DelegationContext { + let operationDefinition: Maybe; + let targetOperation: Maybe; let targetFieldName: string; + let targetOperationName: string | undefined; if (operation == null) { - operationDefinition = getOperationAST(request.document, undefined); + operationDefinition = getOperationAST(request.document, request.operationName); + assertSome(operationDefinition, 'Could not identify the main operation of the document.'); targetOperation = operationDefinition.operation; } else { targetOperation = operation; } if (fieldName == null) { - operationDefinition = operationDefinition ?? getOperationAST(request.document, undefined); - targetFieldName = ((operationDefinition.selectionSet.selections[0] as unknown) as FieldDefinitionNode).name.value; + operationDefinition = operationDefinition ?? getOperationAST(request.document, request.operationName); + targetFieldName = (operationDefinition?.selectionSet.selections[0] as unknown as FieldDefinitionNode).name.value; } else { targetFieldName = fieldName; } - const stitchingInfo: StitchingInfo = info?.schema.extensions?.stitchingInfo; + if (operationName == null) { + if (request.operationName) { + targetOperationName = request.operationName; + } else if (operationDefinition?.name?.value) { + targetOperationName = operationDefinition.name.value; + } + } else { + targetOperationName = operationName; + } + + const stitchingInfo: Maybe> = info?.schema.extensions?.['stitchingInfo']; - const subschemaOrSubschemaConfig = stitchingInfo?.subschemaMap.get(schema) ?? schema; + const subschemaOrSubschemaConfig: GraphQLSchema | SubschemaConfig = + stitchingInfo?.subschemaMap.get(schema) ?? schema; if (isSubschemaConfig(subschemaOrSubschemaConfig)) { const targetSchema = subschemaOrSubschemaConfig.schema; @@ -165,17 +183,21 @@ function getDelegationContext({ subschemaConfig: subschemaOrSubschemaConfig, targetSchema, operation: targetOperation, + operationName: targetOperationName, fieldName: targetFieldName, args, context, info, - rootValue: rootValue ?? subschemaOrSubschemaConfig?.rootValue ?? info?.rootValue ?? emptyObject, - returnType: returnType ?? info?.returnType ?? getDelegationReturnType(targetSchema, targetOperation, targetFieldName), + rootValue: rootValue ?? emptyObject, + returnType: + returnType ?? info?.returnType ?? getDelegationReturnType(targetSchema, targetOperation, targetFieldName), transforms: subschemaOrSubschemaConfig.transforms != null ? subschemaOrSubschemaConfig.transforms.concat(transforms) : transforms, - transformedSchema: transformedSchema ?? (subschemaOrSubschemaConfig as Subschema)?.transformedSchema ?? targetSchema, + transformedSchema: + transformedSchema ?? + (subschemaOrSubschemaConfig instanceof Subschema ? subschemaOrSubschemaConfig.transformedSchema : targetSchema), skipTypeMerging, }; } @@ -189,15 +211,18 @@ function getDelegationContext({ args, context, info, - rootValue: rootValue ?? info?.rootValue ?? emptyObject, - returnType: returnType ?? info?.returnType ?? getDelegationReturnType(subschemaOrSubschemaConfig, targetOperation, targetFieldName), + rootValue: rootValue, + returnType: + returnType ?? + info?.returnType ?? + getDelegationReturnType(subschemaOrSubschemaConfig, targetOperation, targetFieldName), transforms, transformedSchema: transformedSchema ?? subschemaOrSubschemaConfig, skipTypeMerging, }; } -function validateRequest(delegationContext: DelegationContext, document: DocumentNode) { +function validateRequest(delegationContext: DelegationContext, document: DocumentNode) { const errors = validate(delegationContext.targetSchema, document); if (errors.length > 0) { if (errors.length > 1) { @@ -209,16 +234,15 @@ function validateRequest(delegationContext: DelegationContext, document: Documen } } -function getExecutor(delegationContext: DelegationContext): Executor { - const { subschemaConfig, targetSchema, context, rootValue } = delegationContext; +function getExecutor(delegationContext: DelegationContext): Executor { + const { subschemaConfig, targetSchema, context, operation } = delegationContext; - let executor: Executor = - subschemaConfig?.executor || createDefaultExecutor(targetSchema, subschemaConfig?.rootValue || rootValue); + let executor: Executor = subschemaConfig?.executor || createDefaultExecutor(targetSchema, operation); if (subschemaConfig?.batch) { const batchingOptions = subschemaConfig?.batchingOptions; executor = getBatchingExecutor( - context, + context ?? globalThis ?? window ?? global, executor, batchingOptions?.dataLoaderOptions, batchingOptions?.extensionsReducer @@ -228,29 +252,17 @@ function getExecutor(delegationContext: DelegationContext): Executor { return executor; } -function getSubscriber(delegationContext: DelegationContext): Subscriber { - const { subschemaConfig, targetSchema, rootValue } = delegationContext; - return subschemaConfig?.subscriber || createDefaultSubscriber(targetSchema, subschemaConfig?.rootValue || rootValue); -} - -const createDefaultExecutor = memoize2(function (schema: GraphQLSchema, rootValue: Record): Executor { - return (({ document, context, variables, info }: ExecutionParams) => - execute({ +const createDefaultExecutor = (schema: GraphQLSchema, operation: OperationTypeNode) => + (({ document, context, variables, rootValue }: ExecutionParams) => { + const executionParams = { schema, document, contextValue: context, variableValues: variables, - rootValue: rootValue ?? info?.rootValue, - })) as Executor; -}); - -function createDefaultSubscriber(schema: GraphQLSchema, rootValue: Record) { - return ({ document, context, variables, info }: ExecutionParams) => - subscribe({ - schema, - document, - contextValue: context, - variableValues: variables, - rootValue: rootValue ?? info?.rootValue, - }) as any; -} + rootValue, + }; + if (operation === 'subscription') { + return subscribe(executionParams); + } + return execute(executionParams); + }) as Executor; diff --git a/packages/delegate/src/delegationBindings.ts b/packages/delegate/src/delegationBindings.ts index d5946f1f94f..1eb05edc5a9 100644 --- a/packages/delegate/src/delegationBindings.ts +++ b/packages/delegate/src/delegationBindings.ts @@ -1,3 +1,4 @@ +import { Maybe } from '@graphql-tools/utils'; import { Transform, StitchingInfo, DelegationContext } from './types'; import AddSelectionSets from './transforms/AddSelectionSets'; @@ -8,11 +9,13 @@ import AddTypenameToAbstract from './transforms/AddTypenameToAbstract'; import CheckResultAndHandleErrors from './transforms/CheckResultAndHandleErrors'; import AddArgumentsAsVariables from './transforms/AddArgumentsAsVariables'; -export function defaultDelegationBinding(delegationContext: DelegationContext): Array { - let delegationTransforms: Array = [new CheckResultAndHandleErrors()]; +export function defaultDelegationBinding( + delegationContext: DelegationContext +): Array> { + let delegationTransforms: Array> = [new CheckResultAndHandleErrors()]; const info = delegationContext.info; - const stitchingInfo: StitchingInfo = info?.schema.extensions?.stitchingInfo; + const stitchingInfo: Maybe = info?.schema.extensions?.['stitchingInfo']; if (stitchingInfo != null) { delegationTransforms = delegationTransforms.concat([ diff --git a/packages/delegate/src/externalObjects.ts b/packages/delegate/src/externalObjects.ts index 631afc45114..daee3d8035d 100644 --- a/packages/delegate/src/externalObjects.ts +++ b/packages/delegate/src/externalObjects.ts @@ -12,7 +12,7 @@ export function isExternalObject(data: any): data is ExternalObject { export function annotateExternalObject( object: any, errors: Array, - subschema: GraphQLSchema | SubschemaConfig + subschema: GraphQLSchema | SubschemaConfig | undefined ): ExternalObject { Object.defineProperties(object, { [OBJECT_SUBSCHEMA_SYMBOL]: { value: subschema }, @@ -41,7 +41,8 @@ export function mergeExternalObjects( const results: Array = []; let errors: Array = []; - sources.forEach((source, index) => { + for (const index in sources) { + const source = sources[index]; if (source instanceof Error || source === null) { const selectionSet = selectionSets[index]; const fieldNodes = collectFields( @@ -56,7 +57,7 @@ export function mergeExternalObjects( Object.create(null) ); const nullResult = {}; - Object.keys(fieldNodes).forEach(responseKey => { + for (const responseKey in fieldNodes) { if (source instanceof GraphQLError) { nullResult[responseKey] = relocatedError(source, path.concat([responseKey])); } else if (source instanceof Error) { @@ -64,31 +65,24 @@ export function mergeExternalObjects( } else { nullResult[responseKey] = null; } - }); + } results.push(nullResult); } else { errors = errors.concat(source[UNPATHED_ERRORS_SYMBOL]); results.push(source); } - }); + } const combinedResult: ExternalObject = results.reduce(mergeDeep, target); - const newFieldSubschemaMap = target[FIELD_SUBSCHEMA_MAP_SYMBOL] ?? Object.create(null); - - results.forEach((source: ExternalObject) => { + const newFieldSubschemaMap = results.reduce((newFieldSubschemaMap, source) => { const objectSubschema = source[OBJECT_SUBSCHEMA_SYMBOL]; const fieldSubschemaMap = source[FIELD_SUBSCHEMA_MAP_SYMBOL]; - if (fieldSubschemaMap === undefined) { - Object.keys(source).forEach(responseKey => { - newFieldSubschemaMap[responseKey] = objectSubschema; - }); - } else { - Object.keys(source).forEach(responseKey => { - newFieldSubschemaMap[responseKey] = fieldSubschemaMap[responseKey] ?? objectSubschema; - }); + for (const responseKey in source) { + newFieldSubschemaMap[responseKey] = fieldSubschemaMap?.[responseKey] ?? objectSubschema; } - }); + return newFieldSubschemaMap; + }, target[FIELD_SUBSCHEMA_MAP_SYMBOL] ?? Object.create(null)); combinedResult[FIELD_SUBSCHEMA_MAP_SYMBOL] = newFieldSubschemaMap; combinedResult[OBJECT_SUBSCHEMA_SYMBOL] = target[OBJECT_SUBSCHEMA_SYMBOL]; diff --git a/packages/delegate/src/getFieldsNotInSubschema.ts b/packages/delegate/src/getFieldsNotInSubschema.ts index c3a2249304a..92b01eec8bc 100644 --- a/packages/delegate/src/getFieldsNotInSubschema.ts +++ b/packages/delegate/src/getFieldsNotInSubschema.ts @@ -1,6 +1,6 @@ import { GraphQLSchema, FieldNode, GraphQLObjectType, GraphQLResolveInfo } from 'graphql'; -import { collectFields, GraphQLExecutionContext } from '@graphql-tools/utils'; +import { collectFields, GraphQLExecutionContext, Maybe } from '@graphql-tools/utils'; import { isSubschemaConfig } from './subschemaConfig'; import { MergedTypeInfo, SubschemaConfig, StitchingInfo } from './types'; @@ -11,26 +11,29 @@ function collectSubFields(info: GraphQLResolveInfo, typeName: string): Record { - subFieldNodes = collectFields( - partialExecutionContext, - type, - fieldNode.selectionSet, - subFieldNodes, - visitedFragmentNames - ); - }); + for (const fieldNode of info.fieldNodes) { + if (fieldNode.selectionSet) { + subFieldNodes = collectFields( + partialExecutionContext, + type, + fieldNode.selectionSet, + subFieldNodes, + visitedFragmentNames + ); + } + } - const stitchingInfo = info.schema.extensions.stitchingInfo as StitchingInfo; - const selectionSetsByField = stitchingInfo.selectionSetsByField; + // TODO: Verify whether it is safe that extensions always exists. + const stitchingInfo: Maybe = info.schema.extensions?.['stitchingInfo']; + const selectionSetsByField = stitchingInfo?.selectionSetsByField; - Object.keys(subFieldNodes).forEach(responseName => { + for (const responseName in subFieldNodes) { const fieldName = subFieldNodes[responseName][0].name.value; const fieldSelectionSet = selectionSetsByField?.[typeName]?.[fieldName]; if (fieldSelectionSet != null) { @@ -42,29 +45,32 @@ function collectSubFields(info: GraphQLResolveInfo, typeName: string): Record, mergedTypeInfo: MergedTypeInfo ): Array { const typeMap = isSubschemaConfig(subschema) ? mergedTypeInfo.typeMaps.get(subschema) : subschema.getTypeMap(); + if (!typeMap) { + return []; + } const typeName = mergedTypeInfo.typeName; const fields = (typeMap[typeName] as GraphQLObjectType).getFields(); const subFieldNodes = collectSubFields(info, typeName); let fieldsNotInSchema: Array = []; - Object.keys(subFieldNodes).forEach(responseName => { + for (const responseName in subFieldNodes) { const fieldName = subFieldNodes[responseName][0].name.value; if (!(fieldName in fields)) { fieldsNotInSchema = fieldsNotInSchema.concat(subFieldNodes[responseName]); } - }); + } return fieldsNotInSchema; }); diff --git a/packages/delegate/src/index.ts b/packages/delegate/src/index.ts index 93b3a21b408..030fed028b0 100644 --- a/packages/delegate/src/index.ts +++ b/packages/delegate/src/index.ts @@ -9,4 +9,4 @@ export * from './resolveExternalValue'; export * from './subschemaConfig'; export * from './transforms'; export * from './types'; -export { Executor, Subscriber, AsyncExecutor, SyncExecutor, ExecutionParams } from '@graphql-tools/utils'; +export { Executor, AsyncExecutor, SyncExecutor, ExecutionParams } from '@graphql-tools/utils'; diff --git a/packages/delegate/src/mergeFields.ts b/packages/delegate/src/mergeFields.ts index 3b44f3fb867..e15ae559756 100644 --- a/packages/delegate/src/mergeFields.ts +++ b/packages/delegate/src/mergeFields.ts @@ -30,7 +30,7 @@ const sortSubschemasByProxiability = memoize4(function ( const proxiableSubschemas: Array = []; const nonProxiableSubschemas: Array = []; - targetSubschemas.forEach(t => { + for (const t of targetSubschemas) { const selectionSet = mergedTypeInfo.selectionSets.get(t); const fieldSelectionSets = mergedTypeInfo.fieldSelectionSets.get(t); if ( @@ -55,7 +55,7 @@ const sortSubschemasByProxiability = memoize4(function ( nonProxiableSubschemas.push(t); } } - }); + } return { proxiableSubschemas, @@ -77,9 +77,9 @@ const buildDelegationPlan = memoize3(function ( // 2. for each selection: const delegationMap: Map> = new Map(); - fieldNodes.forEach(fieldNode => { + for (const fieldNode of fieldNodes) { if (fieldNode.name.value === '__typename') { - return; + continue; } // 2a. use uniqueFields map to assign fields to subschema if one of possible subschemas @@ -88,7 +88,7 @@ const buildDelegationPlan = memoize3(function ( if (uniqueSubschema != null) { if (!proxiableSubschemas.includes(uniqueSubschema)) { unproxiableFieldNodes.push(fieldNode); - return; + continue; } const existingSubschema = delegationMap.get(uniqueSubschema); @@ -98,7 +98,7 @@ const buildDelegationPlan = memoize3(function ( delegationMap.set(uniqueSubschema, [fieldNode]); } - return; + continue; } // 2b. use nonUniqueFields to assign to a possible subschema, @@ -107,31 +107,32 @@ const buildDelegationPlan = memoize3(function ( let nonUniqueSubschemas: Array = nonUniqueFields[fieldNode.name.value]; if (nonUniqueSubschemas == null) { unproxiableFieldNodes.push(fieldNode); - return; + continue; } nonUniqueSubschemas = nonUniqueSubschemas.filter(s => proxiableSubschemas.includes(s)); if (!nonUniqueSubschemas.length) { unproxiableFieldNodes.push(fieldNode); - return; + continue; } const existingSubschema = nonUniqueSubschemas.find(s => delegationMap.has(s)); if (existingSubschema != null) { - delegationMap.get(existingSubschema).push(fieldNode); + // It is okay we previously explicitly check whether the map has the element. + delegationMap.get(existingSubschema)!.push(fieldNode); } else { delegationMap.set(nonUniqueSubschemas[0], [fieldNode]); } - }); + } const finalDelegationMap: Map = new Map(); - delegationMap.forEach((selections, subschema) => { + for (const [subschema, selections] of delegationMap) { finalDelegationMap.set(subschema, { kind: Kind.SELECTION_SET, selections, }); - }); + } return { delegationMap: finalDelegationMap, @@ -153,9 +154,9 @@ export function mergeFields( typeName: string, object: any, fieldNodes: Array, - sourceSubschemaOrSourceSubschemas: Subschema | Array, - targetSubschemas: Array, - context: Record, + sourceSubschemaOrSourceSubschemas: Subschema | Array>, + targetSubschemas: Array>, + context: any, info: GraphQLResolveInfo ): any { if (!fieldNodes.length) { @@ -176,31 +177,37 @@ export function mergeFields( } const resultMap: Map, SelectionSetNode> = new Map(); - delegationMap.forEach((selectionSet: SelectionSetNode, s: Subschema) => { + for (const [s, selectionSet] of delegationMap) { const resolver = mergedTypeInfo.resolvers.get(s); - const valueOrPromise = new ValueOrPromise(() => resolver(object, context, info, s, selectionSet)).catch(error => error); - resultMap.set(valueOrPromise, selectionSet); - }); - - return ValueOrPromise.all(Array.from(resultMap.keys())).then(results => - mergeFields( - mergedTypeInfo, - typeName, - mergeExternalObjects( - info.schema, - responsePathAsArray(info.path), - object.__typename, - object, - results, - Array.from(resultMap.values()) - ), - unproxiableFieldNodes, - combineSubschemas(sourceSubschemaOrSourceSubschemas, proxiableSubschemas), - nonProxiableSubschemas, - context, - info + if (resolver) { + const valueOrPromise = new ValueOrPromise(() => resolver(object, context, info, s, selectionSet)).catch( + error => error + ); + resultMap.set(valueOrPromise, selectionSet); + } + } + + return ValueOrPromise.all(Array.from(resultMap.keys())) + .then(results => + mergeFields( + mergedTypeInfo, + typeName, + mergeExternalObjects( + info.schema, + responsePathAsArray(info.path), + object.__typename, + object, + results, + Array.from(resultMap.values()) + ), + unproxiableFieldNodes, + combineSubschemas(sourceSubschemaOrSourceSubschemas, proxiableSubschemas), + nonProxiableSubschemas, + context, + info + ) ) - ).resolve(); + .resolve(); } const subschemaTypesContainSelectionSet = memoize3(function ( @@ -239,7 +246,7 @@ function typesContainSelectionSet(types: Array, selectionSet: selection.selectionSet ); } - } else if (selection.kind === Kind.INLINE_FRAGMENT && selection.typeCondition.name.value === types[0].name) { + } else if (selection.kind === Kind.INLINE_FRAGMENT && selection.typeCondition?.name.value === types[0].name) { return typesContainSelectionSet(types, selection.selectionSet); } } diff --git a/packages/delegate/src/resolveExternalValue.ts b/packages/delegate/src/resolveExternalValue.ts index 73495d174ce..66a2e768ee8 100644 --- a/packages/delegate/src/resolveExternalValue.ts +++ b/packages/delegate/src/resolveExternalValue.ts @@ -13,7 +13,7 @@ import { locatedError, } from 'graphql'; -import AggregateError from '@ardatan/aggregate-error'; +import { AggregateError, Maybe } from '@graphql-tools/utils'; import { StitchingInfo, SubschemaConfig } from './types'; import { annotateExternalObject, isExternalObject } from './externalObjects'; @@ -66,8 +66,8 @@ function resolveExternalObject( annotateExternalObject(object, unpathedErrors, subschema); - const stitchingInfo: StitchingInfo = info?.schema.extensions?.stitchingInfo; - if (skipTypeMerging || !stitchingInfo) { + const stitchingInfo: Maybe = info?.schema.extensions?.['stitchingInfo']; + if (skipTypeMerging || stitchingInfo == null) { return object; } @@ -86,7 +86,7 @@ function resolveExternalObject( } const mergedTypeInfo = stitchingInfo.mergedTypes[typeName]; - let targetSubschemas: Array; + let targetSubschemas: undefined | Array; // Within the stitching context, delegation to a stitched GraphQLSchema or SubschemaConfig // will be redirected to the appropriate Subschema object, from which merge targets can be queried. @@ -106,7 +106,7 @@ function resolveExternalObject( typeName, object, fieldNodes, - subschema as Subschema, + subschema as Subschema | Array, targetSubschemas, context, info @@ -161,17 +161,17 @@ function resolveExternalListMember( } } -const reportedErrors: WeakMap = new Map(); +const reportedErrors = new WeakMap(); function reportUnpathedErrorsViaNull(unpathedErrors: Array) { if (unpathedErrors.length) { const unreportedErrors: Array = []; - unpathedErrors.forEach(error => { + for (const error of unpathedErrors) { if (!reportedErrors.has(error)) { unreportedErrors.push(error); reportedErrors.set(error, true); } - }); + } if (unreportedErrors.length) { if (unreportedErrors.length === 1) { @@ -179,7 +179,11 @@ function reportUnpathedErrorsViaNull(unpathedErrors: Array) { } const combinedError = new AggregateError(unreportedErrors); - return locatedError(combinedError, undefined, unreportedErrors[0].path); + // We cast path as any for GraphQL.js 14 compat + // locatedError path argument must be defined, but it is just forwarded to a constructor that allows a undefined value + // https://github.com/graphql/graphql-js/blob/b4bff0ba9c15c9d7245dd68556e754c41f263289/src/error/locatedError.js#L25 + // https://github.com/graphql/graphql-js/blob/b4bff0ba9c15c9d7245dd68556e754c41f263289/src/error/GraphQLError.js#L19 + return locatedError(combinedError, undefined as any, unreportedErrors[0].path as any); } } diff --git a/packages/delegate/src/subschemaConfig.ts b/packages/delegate/src/subschemaConfig.ts index e4efb5a14b7..55c85c9d407 100644 --- a/packages/delegate/src/subschemaConfig.ts +++ b/packages/delegate/src/subschemaConfig.ts @@ -1,6 +1,6 @@ import { SubschemaConfig } from './types'; -export function isSubschemaConfig(value: any): value is SubschemaConfig { +export function isSubschemaConfig(value: any): value is SubschemaConfig { return Boolean(value?.schema); } @@ -12,8 +12,8 @@ export function cloneSubschemaConfig(subschemaConfig: SubschemaConfig): Subschem if (newSubschemaConfig.merge != null) { newSubschemaConfig.merge = { ...subschemaConfig.merge }; - Object.keys(newSubschemaConfig.merge).forEach(typeName => { - const mergedTypeConfig = (newSubschemaConfig.merge[typeName] = { ...subschemaConfig.merge[typeName] }); + for (const typeName in newSubschemaConfig.merge) { + const mergedTypeConfig = (newSubschemaConfig.merge[typeName] = { ...(subschemaConfig.merge?.[typeName] ?? {}) }); if (mergedTypeConfig.entryPoints != null) { mergedTypeConfig.entryPoints = mergedTypeConfig.entryPoints.map(entryPoint => ({ ...entryPoint })); @@ -21,11 +21,11 @@ export function cloneSubschemaConfig(subschemaConfig: SubschemaConfig): Subschem if (mergedTypeConfig.fields != null) { const fields = (mergedTypeConfig.fields = { ...mergedTypeConfig.fields }); - Object.keys(fields).forEach(fieldName => { + for (const fieldName in fields) { fields[fieldName] = { ...fields[fieldName] }; - }); + } } - }); + } } return newSubschemaConfig; diff --git a/packages/delegate/src/transforms/AddArgumentsAsVariables.ts b/packages/delegate/src/transforms/AddArgumentsAsVariables.ts index 53a576a42a8..05d96eeddef 100644 --- a/packages/delegate/src/transforms/AddArgumentsAsVariables.ts +++ b/packages/delegate/src/transforms/AddArgumentsAsVariables.ts @@ -2,7 +2,6 @@ import { ArgumentNode, DocumentNode, FragmentDefinitionNode, - GraphQLArgument, GraphQLField, GraphQLObjectType, GraphQLSchema, @@ -12,7 +11,7 @@ import { VariableDefinitionNode, } from 'graphql'; -import { Request, serializeInputValue, updateArgument } from '@graphql-tools/utils'; +import { Maybe, Request, serializeInputValue, updateArgument, assertSome } from '@graphql-tools/utils'; import { Transform, DelegationContext } from '../types'; @@ -63,7 +62,7 @@ function addVariablesToRootField( ) as Array; const newOperations = operations.map((operation: OperationDefinitionNode) => { - const variableDefinitionMap: Record = operation.variableDefinitions.reduce( + const variableDefinitionMap: Record = (operation.variableDefinitions ?? []).reduce( (prev, def) => ({ ...prev, [def.variable.name.value]: def, @@ -71,7 +70,7 @@ function addVariablesToRootField( {} ); - let type: GraphQLObjectType | null | undefined; + let type: Maybe; if (operation.operation === 'subscription') { type = targetSchema.getSubscriptionType(); } else if (operation.operation === 'mutation') { @@ -79,9 +78,12 @@ function addVariablesToRootField( } else { type = targetSchema.getQueryType(); } + + assertSome(type); + const newSelectionSet: Array = []; - operation.selectionSet.selections.forEach((selection: SelectionNode) => { + for (const selection of operation.selectionSet.selections) { if (selection.kind === Kind.FIELD) { const argumentNodes = selection.arguments ?? []; const argumentNodeMap: Record = argumentNodes.reduce( @@ -101,16 +103,16 @@ function addVariablesToRootField( newSelectionSet.push({ ...selection, - arguments: Object.keys(argumentNodeMap).map(argName => argumentNodeMap[argName]), + arguments: Object.values(argumentNodeMap), }); } else { newSelectionSet.push(selection); } - }); + } return { ...operation, - variableDefinitions: Object.keys(variableDefinitionMap).map(varName => variableDefinitionMap[varName]), + variableDefinitions: Object.values(variableDefinitionMap), selectionSet: { kind: Kind.SELECTION_SET, selections: newSelectionSet, @@ -134,7 +136,7 @@ function updateArguments( variableValues: Record, newArgs: Record ): void { - targetField.args.forEach((argument: GraphQLArgument) => { + for (const argument of targetField.args) { const argName = argument.name; const argType = argument.type; @@ -148,5 +150,5 @@ function updateArguments( serializeInputValue(argType, newArgs[argName]) ); } - }); + } } diff --git a/packages/delegate/src/transforms/AddSelectionSets.ts b/packages/delegate/src/transforms/AddSelectionSets.ts index d725fd1c364..3ffad61e54a 100644 --- a/packages/delegate/src/transforms/AddSelectionSets.ts +++ b/packages/delegate/src/transforms/AddSelectionSets.ts @@ -1,6 +1,6 @@ import { SelectionSetNode, TypeInfo, Kind, FieldNode, SelectionNode, print } from 'graphql'; -import { Request } from '@graphql-tools/utils'; +import { Maybe, Request } from '@graphql-tools/utils'; import { Transform, DelegationContext } from '../types'; import { memoize2 } from '../memoize'; @@ -35,7 +35,7 @@ function visitSelectionSet( selectionSetsByType: Record, selectionSetsByField: Record>, dynamicSelectionSetsByField: Record SelectionSetNode>>> -): SelectionSetNode { +): Maybe { const parentType = typeInfo.getParentType(); const newSelections: Map = new Map(); @@ -50,7 +50,7 @@ function visitSelectionSet( } if (parentTypeName in selectionSetsByField) { - node.selections.forEach(selection => { + for (const selection of node.selections) { if (selection.kind === Kind.FIELD) { const name = selection.name.value; const selectionSet = selectionSetsByField[parentTypeName][name]; @@ -58,35 +58,35 @@ function visitSelectionSet( addSelectionsToMap(newSelections, selectionSet); } } - }); + } } if (parentTypeName in dynamicSelectionSetsByField) { - node.selections.forEach(selection => { + for (const selection of node.selections) { if (selection.kind === Kind.FIELD) { const name = selection.name.value; const dynamicSelectionSets = dynamicSelectionSetsByField[parentTypeName][name]; if (dynamicSelectionSets != null) { - dynamicSelectionSets.forEach(selectionSetFn => { + for (const selectionSetFn of dynamicSelectionSets) { const selectionSet = selectionSetFn(selection); if (selectionSet != null) { addSelectionsToMap(newSelections, selectionSet); } - }); + } } } - }); + } } return { ...node, - selections: Array.from(newSelections.values()), + selections: [...newSelections.values()], }; } } const addSelectionsToMap = memoize2(function (map: Map, selectionSet: SelectionSetNode): void { - selectionSet.selections.forEach(selection => { + for (const selection of selectionSet.selections) { map.set(print(selection), selection); - }); + } }); diff --git a/packages/delegate/src/transforms/AddTypenameToAbstract.ts b/packages/delegate/src/transforms/AddTypenameToAbstract.ts index 4ffb31f57a7..0eb25a2416c 100644 --- a/packages/delegate/src/transforms/AddTypenameToAbstract.ts +++ b/packages/delegate/src/transforms/AddTypenameToAbstract.ts @@ -10,7 +10,7 @@ import { isAbstractType, } from 'graphql'; -import { Request } from '@graphql-tools/utils'; +import { Maybe, Request } from '@graphql-tools/utils'; import { Transform, DelegationContext } from '../types'; @@ -34,7 +34,7 @@ function addTypenameToAbstract(targetSchema: GraphQLSchema, document: DocumentNo document, visitWithTypeInfo(typeInfo, { [Kind.SELECTION_SET](node: SelectionSetNode): SelectionSetNode | null | undefined { - const parentType: GraphQLType = typeInfo.getParentType(); + const parentType: Maybe = typeInfo.getParentType(); let selections = node.selections; if (parentType != null && isAbstractType(parentType)) { selections = selections.concat({ diff --git a/packages/delegate/src/transforms/CheckResultAndHandleErrors.ts b/packages/delegate/src/transforms/CheckResultAndHandleErrors.ts index 264541de177..bb1de4a5cdc 100644 --- a/packages/delegate/src/transforms/CheckResultAndHandleErrors.ts +++ b/packages/delegate/src/transforms/CheckResultAndHandleErrors.ts @@ -7,9 +7,7 @@ import { locatedError, } from 'graphql'; -import AggregateError from '@ardatan/aggregate-error'; - -import { getResponseKeyFromInfo, ExecutionResult, relocatedError } from '@graphql-tools/utils'; +import { AggregateError, getResponseKeyFromInfo, ExecutionResult, relocatedError } from '@graphql-tools/utils'; import { SubschemaConfig, Transform, DelegationContext } from '../types'; import { resolveExternalValue } from '../resolveExternalValue'; @@ -38,7 +36,7 @@ export function checkResultAndHandleErrors( context: Record, info: GraphQLResolveInfo, responseKey: string = getResponseKeyFromInfo(info), - subschema?: GraphQLSchema | SubschemaConfig, + subschema: GraphQLSchema | SubschemaConfig, returnType: GraphQLOutputType = info.returnType, skipTypeMerging?: boolean, onLocatedError?: (originalError: GraphQLError) => GraphQLError @@ -46,7 +44,7 @@ export function checkResultAndHandleErrors( const { data, unpathedErrors } = mergeDataAndErrors( result.data == null ? undefined : result.data[responseKey], result.errors == null ? [] : result.errors, - info ? responsePathAsArray(info.path) : undefined, + info != null && info.path ? responsePathAsArray(info.path) : undefined, onLocatedError ); @@ -56,8 +54,8 @@ export function checkResultAndHandleErrors( export function mergeDataAndErrors( data: any, errors: ReadonlyArray, - path: Array, - onLocatedError: (originalError: GraphQLError) => GraphQLError, + path: Array | undefined, + onLocatedError?: (originalError: GraphQLError) => GraphQLError, index = 1 ): { data: any; unpathedErrors: Array } { if (data == null) { @@ -73,7 +71,11 @@ export function mergeDataAndErrors( return { data: relocatedError(errors[0], newPath), unpathedErrors: [] }; } - const newError = locatedError(new AggregateError(errors), undefined, path); + // We cast path as any for GraphQL.js 14 compat + // locatedError path argument must be defined, but it is just forwarded to a constructor that allows a undefined value + // https://github.com/graphql/graphql-js/blob/b4bff0ba9c15c9d7245dd68556e754c41f263289/src/error/locatedError.js#L25 + // https://github.com/graphql/graphql-js/blob/b4bff0ba9c15c9d7245dd68556e754c41f263289/src/error/GraphQLError.js#L19 + const newError = locatedError(new AggregateError(errors), undefined as any, path as any); return { data: newError, unpathedErrors: [] }; } @@ -82,38 +84,39 @@ export function mergeDataAndErrors( return { data, unpathedErrors: [] }; } - let unpathedErrors: Array = []; + const unpathedErrors: Array = []; - const errorMap: Record> = Object.create(null); - errors.forEach(error => { + const errorMap = new Map>(); + for (const error of errors) { const pathSegment = error.path?.[index]; if (pathSegment != null) { - const pathSegmentErrors = errorMap[pathSegment]; + let pathSegmentErrors = errorMap.get(pathSegment); if (pathSegmentErrors === undefined) { - errorMap[pathSegment] = [error]; + pathSegmentErrors = [error]; + errorMap.set(pathSegment, pathSegmentErrors); } else { pathSegmentErrors.push(error); } } else { unpathedErrors.push(error); } - }); + } - Object.keys(errorMap).forEach(pathSegment => { + for (const [pathSegment, pathSegmentErrors] of errorMap) { if (data[pathSegment] !== undefined) { const { data: newData, unpathedErrors: newErrors } = mergeDataAndErrors( data[pathSegment], - errorMap[pathSegment], + pathSegmentErrors, path, onLocatedError, index + 1 ); data[pathSegment] = newData; - unpathedErrors = unpathedErrors.concat(newErrors); + unpathedErrors.push(...newErrors); } else { - unpathedErrors = unpathedErrors.concat(errorMap[pathSegment]); + unpathedErrors.push(...pathSegmentErrors); } - }); + } return { data, unpathedErrors }; } diff --git a/packages/delegate/src/transforms/ExpandAbstractTypes.ts b/packages/delegate/src/transforms/ExpandAbstractTypes.ts index a2ba8d2abfa..f320397c209 100644 --- a/packages/delegate/src/transforms/ExpandAbstractTypes.ts +++ b/packages/delegate/src/transforms/ExpandAbstractTypes.ts @@ -50,7 +50,7 @@ function extractPossibleTypes(sourceSchema: GraphQLSchema, targetSchema: GraphQL const typeMap = sourceSchema.getTypeMap(); const possibleTypesMap: Record> = Object.create(null); const interfaceExtensionsMap: Record> = Object.create(null); - Object.keys(typeMap).forEach(typeName => { + for (const typeName in typeMap) { const type = typeMap[typeName]; if (isAbstractType(type)) { const targetType = targetSchema.getType(typeName); @@ -58,12 +58,14 @@ function extractPossibleTypes(sourceSchema: GraphQLSchema, targetSchema: GraphQL if (isInterfaceType(type) && isInterfaceType(targetType)) { const targetTypeFields = targetType.getFields(); const extensionFields: Record = Object.create(null); - Object.keys(type.getFields()).forEach((fieldName: string) => { + let isExtensionFieldsEmpty = true; + for (const fieldName in type.getFields()) { if (!targetTypeFields[fieldName]) { extensionFields[fieldName] = true; + isExtensionFieldsEmpty = false; } - }); - if (Object.keys(extensionFields).length) { + } + if (!isExtensionFieldsEmpty) { interfaceExtensionsMap[typeName] = extensionFields; } } @@ -75,21 +77,21 @@ function extractPossibleTypes(sourceSchema: GraphQLSchema, targetSchema: GraphQL .map(impl => impl.name); } } - }); + } return { possibleTypesMap, interfaceExtensionsMap }; } function flipMapping(mapping: Record>): Record> { const result: Record> = Object.create(null); - Object.keys(mapping).forEach(typeName => { + for (const typeName in mapping) { const toTypeNames = mapping[typeName]; - toTypeNames.forEach(toTypeName => { + for (const toTypeName of toTypeNames) { if (!(toTypeName in result)) { result[toTypeName] = []; } result[toTypeName].push(typeName); - }); - }); + } + } return result; } @@ -135,12 +137,12 @@ function expandAbstractTypes( const newFragments: Array = []; const fragmentReplacements: Record> = Object.create(null); - fragments.forEach((fragment: FragmentDefinitionNode) => { + for (const fragment of fragments) { newFragments.push(fragment); const possibleTypes = possibleTypesMap[fragment.typeCondition.name.value]; if (possibleTypes != null) { fragmentReplacements[fragment.name.value] = []; - possibleTypes.forEach(possibleTypeName => { + for (const possibleTypeName of possibleTypes) { const name = generateFragmentName(possibleTypeName); existingFragmentNames.push(name); const newFragment: FragmentDefinitionNode = { @@ -164,9 +166,9 @@ function expandAbstractTypes( fragmentName: name, typeName: possibleTypeName, }); - }); + } } - }); + } const newDocument = { ...document, @@ -184,12 +186,12 @@ function expandAbstractTypes( const parentType: GraphQLNamedType = getNamedType(maybeType); const interfaceExtension = interfaceExtensionsMap[parentType.name]; const interfaceExtensionFields = [] as Array; - node.selections.forEach((selection: SelectionNode) => { + for (const selection of node.selections) { if (selection.kind === Kind.INLINE_FRAGMENT) { if (selection.typeCondition != null) { const possibleTypes = possibleTypesMap[selection.typeCondition.name.value]; if (possibleTypes != null) { - possibleTypes.forEach(possibleType => { + for (const possibleType of possibleTypes) { const maybePossibleType = targetSchema.getType(possibleType); if ( maybePossibleType != null && @@ -197,13 +199,13 @@ function expandAbstractTypes( ) { addedSelections.push(generateInlineFragment(possibleType, selection.selectionSet)); } - }); + } } } } else if (selection.kind === Kind.FRAGMENT_SPREAD) { const fragmentName = selection.name.value; if (fragmentName in fragmentReplacements) { - fragmentReplacements[fragmentName].forEach(replacement => { + for (const replacement of fragmentReplacements[fragmentName]) { const typeName = replacement.typeName; const maybeReplacementType = targetSchema.getType(typeName); if (maybeReplacementType != null && implementsAbstractType(targetSchema, parentType, maybeType)) { @@ -215,7 +217,7 @@ function expandAbstractTypes( }, }); } - }); + } } } else if ( interfaceExtension != null && @@ -224,7 +226,7 @@ function expandAbstractTypes( ) { interfaceExtensionFields.push(selection); } - }); + } if (parentType.name in reversePossibleTypesMap) { addedSelections.push({ @@ -239,14 +241,14 @@ function expandAbstractTypes( if (interfaceExtensionFields.length) { const possibleTypes = possibleTypesMap[parentType.name]; if (possibleTypes != null) { - possibleTypes.forEach(possibleType => { + for (const possibleType of possibleTypes) { addedSelections.push( generateInlineFragment(possibleType, { kind: Kind.SELECTION_SET, selections: interfaceExtensionFields, }) ); - }); + } newSelections = newSelections.filter( (selection: SelectionNode) => diff --git a/packages/delegate/src/transforms/FilterToSchema.ts b/packages/delegate/src/transforms/FilterToSchema.ts index 6f236ddcb05..3c703ed9141 100644 --- a/packages/delegate/src/transforms/FilterToSchema.ts +++ b/packages/delegate/src/transforms/FilterToSchema.ts @@ -19,9 +19,10 @@ import { getNamedType, isObjectType, isInterfaceType, + GraphQLObjectType, } from 'graphql'; -import { Request, implementsAbstractType, TypeMap } from '@graphql-tools/utils'; +import { Request, implementsAbstractType, TypeMap, assertSome, Maybe } from '@graphql-tools/utils'; import { Transform, DelegationContext } from '../types'; @@ -70,8 +71,8 @@ function filterToSchema( let fragmentSet = Object.create(null); - operations.forEach((operation: OperationDefinitionNode) => { - let type; + for (const operation of operations) { + let type: Maybe>; if (operation.operation === 'subscription') { type = targetSchema.getSubscriptionType(); } else if (operation.operation === 'mutation') { @@ -79,6 +80,7 @@ function filterToSchema( } else { type = targetSchema.getQueryType(); } + assertSome(type); const { selectionSet, @@ -98,7 +100,7 @@ function filterToSchema( newFragments = collectedNewFragments; fragmentSet = collectedFragmentSet; - const variableDefinitions = operation.variableDefinitions.filter( + const variableDefinitions = (operation.variableDefinitions ?? []).filter( (variable: VariableDefinitionNode) => operationOrFragmentVariables.indexOf(variable.variable.name.value) !== -1 ); @@ -110,7 +112,7 @@ function filterToSchema( variableDefinitions, selectionSet, }); - }); + } const newVariables = usedVariables.reduce((acc, variableName) => { const variableValue = variables[variableName]; @@ -148,6 +150,7 @@ function collectFragmentVariables( const name = nextFragmentName; const typeName = fragment.typeCondition.name.value; const type = targetSchema.getType(typeName); + assertSome(type); const { selectionSet, usedFragments: fragmentUsedFragments, @@ -156,7 +159,7 @@ function collectFragmentVariables( remainingFragments = union(remainingFragments, fragmentUsedFragments); usedVariables = union(usedVariables, fragmentUsedVariables); - if (!(name in fragmentSet)) { + if (name && !(name in fragmentSet)) { fragmentSet[name] = true; newFragments.push({ kind: Kind.FRAGMENT_DEFINITION, @@ -214,7 +217,9 @@ function filterSelectionSet( } }, leave(node: FieldNode): null | undefined | FieldNode { - const resolvedType = getNamedType(typeInfo.getType()); + const type = typeInfo.getType(); + assertSome(type); + const resolvedType = getNamedType(type); if (isObjectType(resolvedType) || isInterfaceType(resolvedType)) { const selections = node.selectionSet != null ? node.selectionSet.selections : null; if (selections == null || selections.length === 0) { @@ -273,13 +278,13 @@ function filterSelectionSet( function union(...arrays: Array>): Array { const cache: Record = Object.create(null); const result: Array = []; - arrays.forEach(array => { - array.forEach(item => { + for (const array of arrays) { + for (const item of array) { if (!(item in cache)) { cache[item] = true; result.push(item); } - }); - }); + } + } return result; } diff --git a/packages/delegate/src/transforms/VisitSelectionSets.ts b/packages/delegate/src/transforms/VisitSelectionSets.ts index 3f807241b0c..d0021378bc3 100644 --- a/packages/delegate/src/transforms/VisitSelectionSets.ts +++ b/packages/delegate/src/transforms/VisitSelectionSets.ts @@ -13,14 +13,16 @@ import { DefinitionNode, } from 'graphql'; -import { Request, collectFields, GraphQLExecutionContext } from '@graphql-tools/utils'; +import { Request, collectFields, GraphQLExecutionContext, assertSome, Maybe } from '@graphql-tools/utils'; import { Transform, DelegationContext } from '../types'; +type VisitSelectionSetsVisitor = (node: SelectionSetNode, typeInfo: TypeInfo) => Maybe; + export default class VisitSelectionSets implements Transform { - private readonly visitor: (node: SelectionSetNode, typeInfo: TypeInfo) => SelectionSetNode; + private readonly visitor: VisitSelectionSetsVisitor; - constructor(visitor: (node: SelectionSetNode, typeInfo: TypeInfo) => SelectionSetNode) { + constructor(visitor: VisitSelectionSetsVisitor) { this.visitor = visitor; } @@ -46,19 +48,19 @@ function visitSelectionSets( request: Request, schema: GraphQLSchema, initialType: GraphQLOutputType, - visitor: (node: SelectionSetNode, typeInfo: TypeInfo) => SelectionSetNode + visitor: VisitSelectionSetsVisitor ): DocumentNode { const { document, variables } = request; const operations: Array = []; const fragments: Record = Object.create(null); - document.definitions.forEach(def => { + for (const def of document.definitions) { if (def.kind === Kind.OPERATION_DEFINITION) { operations.push(def); } else if (def.kind === Kind.FRAGMENT_DEFINITION) { fragments[def.name.value] = def; } - }); + } const partialExecutionContext = { schema, @@ -74,6 +76,7 @@ function visitSelectionSets( : operation.operation === 'mutation' ? schema.getMutationType() : schema.getSubscriptionType(); + assertSome(type); const fields = collectFields( partialExecutionContext, @@ -84,14 +87,14 @@ function visitSelectionSets( ); const newSelections: Array = []; - Object.keys(fields).forEach(responseKey => { + for (const responseKey in fields) { const fieldNodes = fields[responseKey]; - fieldNodes.forEach(fieldNode => { + for (const fieldNode of fieldNodes) { const selectionSet = fieldNode.selectionSet; if (selectionSet == null) { newSelections.push(fieldNode); - return; + continue; } const newSelectionSet = visit( @@ -103,15 +106,15 @@ function visitSelectionSets( if (newSelectionSet === selectionSet) { newSelections.push(fieldNode); - return; + continue; } newSelections.push({ ...fieldNode, selectionSet: newSelectionSet, }); - }); - }); + } + } return { ...operation, @@ -122,7 +125,8 @@ function visitSelectionSets( }; }); - Object.values(fragments).forEach(fragment => { + for (const fragmentIndex in fragments) { + const fragment = fragments[fragmentIndex]; newDefinitions.push( visit( fragment, @@ -131,7 +135,7 @@ function visitSelectionSets( }) ) ); - }); + } return { ...document, diff --git a/packages/delegate/src/transforms/WrapConcreteTypes.ts b/packages/delegate/src/transforms/WrapConcreteTypes.ts index 069aa81e868..7c7bb5b0352 100644 --- a/packages/delegate/src/transforms/WrapConcreteTypes.ts +++ b/packages/delegate/src/transforms/WrapConcreteTypes.ts @@ -63,7 +63,8 @@ function wrapConcreteTypes( } }, [Kind.FIELD]: (node: FieldNode) => { - if (isAbstractType(getNamedType(typeInfo.getType()))) { + const type = typeInfo.getType(); + if (type != null && isAbstractType(getNamedType(type))) { return { ...node, selectionSet: { diff --git a/packages/delegate/src/types.ts b/packages/delegate/src/types.ts index 419f11bd075..1e12ddd9592 100644 --- a/packages/delegate/src/types.ts +++ b/packages/delegate/src/types.ts @@ -14,14 +14,14 @@ import { import DataLoader from 'dataloader'; -import { ExecutionParams, ExecutionResult, Executor, Request, Subscriber, TypeMap } from '@graphql-tools/utils'; +import { ExecutionParams, ExecutionResult, Executor, Request, TypeMap } from '@graphql-tools/utils'; import { Subschema } from './Subschema'; import { OBJECT_SUBSCHEMA_SYMBOL, FIELD_SUBSCHEMA_MAP_SYMBOL, UNPATHED_ERRORS_SYMBOL } from './symbols'; -export type SchemaTransform = ( +export type SchemaTransform> = ( originalWrappingSchema: GraphQLSchema, - subschemaConfig: SubschemaConfig, + subschemaConfig: SubschemaConfig, transformedSchema?: GraphQLSchema ) => GraphQLSchema; export type RequestTransform> = ( @@ -35,30 +35,33 @@ export type ResultTransform> = ( transformationContext: T ) => ExecutionResult; -export interface Transform> { - transformSchema?: SchemaTransform; +export interface Transform> { + transformSchema?: SchemaTransform; transformRequest?: RequestTransform; transformResult?: ResultTransform; } -export interface DelegationContext { - subschema: GraphQLSchema | SubschemaConfig; - subschemaConfig: SubschemaConfig; +export interface DelegationContext> { + subschema: GraphQLSchema | SubschemaConfig; + subschemaConfig?: SubschemaConfig; targetSchema: GraphQLSchema; operation: OperationTypeNode; fieldName: string; args: Record; - context: Record; + context?: TContext; info: GraphQLResolveInfo; - rootValue?: Record, + rootValue?: Record; returnType: GraphQLOutputType; onLocatedError?: (originalError: GraphQLError) => GraphQLError; - transforms: Array; + transforms: Array>; transformedSchema: GraphQLSchema; skipTypeMerging: boolean; + operationName?: string; } -export type DelegationBinding = (delegationContext: DelegationContext) => Array; +export type DelegationBinding> = ( + delegationContext: DelegationContext +) => Array>; export interface IDelegateToSchemaOptions, TArgs = Record> { schema: GraphQLSchema | SubschemaConfig; @@ -73,17 +76,16 @@ export interface IDelegateToSchemaOptions, TArgs context?: TContext; info: GraphQLResolveInfo; rootValue?: Record; - transforms?: Array; + transforms?: Array>; transformedSchema?: GraphQLSchema; - skipValidation?: boolean; + validateRequest?: boolean; skipTypeMerging?: boolean; - binding?: DelegationBinding; + binding?: DelegationBinding; } export interface IDelegateRequestOptions, TArgs = Record> - extends Omit, 'info'> { + extends IDelegateToSchemaOptions { request: Request; - info?: GraphQLResolveInfo; } export interface ICreateRequestFromInfo { @@ -112,13 +114,13 @@ export interface ICreateRequest { export interface MergedTypeInfo> { typeName: string; selectionSet?: SelectionSetNode; - targetSubschemas: Map>; - uniqueFields: Record; - nonUniqueFields: Record>; - typeMaps: Map; - selectionSets: Map; - fieldSelectionSets: Map>; - resolvers: Map>; + targetSubschemas: Map, Array>>; + uniqueFields: Record>; + nonUniqueFields: Record>>; + typeMaps: Map, TypeMap>; + selectionSets: Map, SelectionSetNode>; + fieldSelectionSets: Map, Record>; + resolvers: Map, MergedTypeResolver>; } export interface ICreateProxyingResolverOptions> { @@ -140,23 +142,23 @@ export interface BatchingOptions { export interface SubschemaConfig> { schema: GraphQLSchema; createProxyingResolver?: CreateProxyingResolverFn; - transforms?: Array; + transforms?: Array>; merge?: Record>; - rootValue?: Record; executor?: Executor; - subscriber?: Subscriber; batch?: boolean; batchingOptions?: BatchingOptions; } -export interface MergedTypeConfig> extends MergedTypeEntryPoint { +export interface MergedTypeConfig> + extends MergedTypeEntryPoint { entryPoints?: Array; fields?: Record; computedFields?: Record; canonical?: boolean; } -export interface MergedTypeEntryPoint> extends MergedTypeResolverOptions { +export interface MergedTypeEntryPoint> + extends MergedTypeResolverOptions { selectionSet?: string; key?: (originalResult: any) => K; resolve?: MergedTypeResolver; diff --git a/packages/delegate/tests/createRequest.test.ts b/packages/delegate/tests/createRequest.test.ts index d5f4431a001..36e0348be05 100644 --- a/packages/delegate/tests/createRequest.test.ts +++ b/packages/delegate/tests/createRequest.test.ts @@ -36,7 +36,7 @@ describe('bare requests', () => { `, resolvers: { Query: { - delegate: (_root, args) => { + delegate: (_root, args, _context, info) => { const request = createRequest({ fieldNodes: [{ kind: Kind.FIELD, @@ -72,6 +72,7 @@ describe('bare requests', () => { return delegateRequest({ request, schema: innerSchema, + info }); }, }, @@ -129,7 +130,7 @@ describe('bare requests', () => { `, resolvers: { Query: { - delegate: (_root, args) => { + delegate: (_root, args, _context, info) => { const request = createRequest({ fieldNodes: [{ kind: Kind.FIELD, @@ -155,6 +156,7 @@ describe('bare requests', () => { request, schema: innerSchema, args, + info, }); }, }, @@ -203,7 +205,7 @@ describe('bare requests', () => { `, resolvers: { Query: { - delegate: () => { + delegate: (_source, _args, _context, info) => { const request = createRequest({ fieldNodes: [{ kind: Kind.FIELD, @@ -218,6 +220,7 @@ describe('bare requests', () => { return delegateRequest({ request, schema: innerSchema, + info }); }, }, diff --git a/packages/delegate/tests/delegateToSchema.test..ts b/packages/delegate/tests/delegateToSchema.test.ts similarity index 87% rename from packages/delegate/tests/delegateToSchema.test..ts rename to packages/delegate/tests/delegateToSchema.test.ts index 11b54026171..4f4c23ce2f0 100644 --- a/packages/delegate/tests/delegateToSchema.test..ts +++ b/packages/delegate/tests/delegateToSchema.test.ts @@ -3,6 +3,12 @@ import { graphql } from 'graphql'; import { delegateToSchema } from '../src/delegateToSchema'; import { makeExecutableSchema } from '@graphql-tools/schema'; +function assertSome(input: T): asserts input is Exclude{ + if (input == null) { + throw new Error("Value should be neither null nor undefined.") + } +} + describe('delegateToSchema', () => { test('should work', async () => { const innerSchema = makeExecutableSchema({ @@ -47,7 +53,8 @@ describe('delegateToSchema', () => { `, ); - expect(result.data.delegateToSchema).toEqual('test'); + assertSome(result.data) + expect(result.data['delegateToSchema']).toEqual('test'); }); test('should work even where there are default fields', async () => { @@ -93,7 +100,8 @@ describe('delegateToSchema', () => { `, ); - expect(result.data.delegateToSchema).toEqual('test'); + assertSome(result.data) + expect(result.data['delegateToSchema']).toEqual('test'); }); test('should work even when there are variables', async () => { @@ -144,6 +152,7 @@ describe('delegateToSchema', () => { }, ); - expect(result.data.delegateToSchema).toEqual('test'); + assertSome(result.data) + expect(result.data['delegateToSchema']).toEqual('test'); }); }); diff --git a/packages/delegate/tests/errors.test.ts b/packages/delegate/tests/errors.test.ts index faf8d5b2ff0..a78982697a4 100644 --- a/packages/delegate/tests/errors.test.ts +++ b/packages/delegate/tests/errors.test.ts @@ -11,7 +11,7 @@ import { delegateToSchema, defaultMergedResolver } from '../src'; class ErrorWithExtensions extends GraphQLError { constructor(message: string, code: string) { - super(message, null, null, null, null, null, { code }); + super(message, null as any, null, null, null, null, { code }); } } @@ -33,6 +33,19 @@ describe('Errors', () => { }); describe('checkResultAndHandleErrors', () => { + const fakeInfo: GraphQLResolveInfo = { + fieldName: "foo", + fieldNodes: [], + returnType: {} as any, + parentType: {} as any, + path: {prev: undefined, key: "foo", typename: undefined } as any, + schema: {} as any, + fragments: {}, + rootValue: {}, + operation: {} as any, + variableValues: {} + } + test('persists single error', () => { const result = { errors: [new GraphQLError('Test error')], @@ -41,8 +54,9 @@ describe('Errors', () => { checkResultAndHandleErrors( result, {}, - ({} as unknown) as GraphQLResolveInfo, + fakeInfo, 'responseKey', + {} as any, ); } catch (e) { expect(e.message).toEqual('Test error'); @@ -58,8 +72,9 @@ describe('Errors', () => { checkResultAndHandleErrors( result, {}, - ({} as unknown) as GraphQLResolveInfo, + fakeInfo, 'responseKey', + {} as any ); } catch (e) { expect(e.message).toEqual('Test error'); @@ -76,17 +91,19 @@ describe('Errors', () => { checkResultAndHandleErrors( result, {}, - ({} as unknown) as GraphQLResolveInfo, + fakeInfo, 'responseKey', + {} as any ); } catch (e) { expect(e.message).toEqual('Error1\nError2'); expect(e.originalError).toBeDefined(); expect(e.originalError.errors).toBeDefined(); expect(e.originalError.errors).toHaveLength(result.errors.length); - result.errors.forEach((error, i) => { + for (const i in result.errors) { + const error = result.errors[i]; expect(e.originalError.errors[i]).toEqual(error); - }); + } } }); @@ -103,7 +120,7 @@ describe('Errors', () => { } `; - const unpathedError = locatedError(new Error('TestError'), undefined, ["_entities", 7, "name"]); + const unpathedError = locatedError(new Error('TestError'), undefined as any, ["_entities", 7, "name"]); const remoteSchema = makeExecutableSchema({ typeDefs, @@ -168,7 +185,7 @@ describe('Errors', () => { } `; - const unpathedError = locatedError(new Error('TestError'), undefined, ["_entities", 7, "name"]); + const unpathedError = locatedError(new Error('TestError'), undefined as any, ["_entities", 7, "name"]); const remoteSchema = makeExecutableSchema({ typeDefs, diff --git a/packages/graphql-tag-pluck/package.json b/packages/graphql-tag-pluck/package.json index 217a85d60e1..4b7f706e36c 100644 --- a/packages/graphql-tag-pluck/package.json +++ b/packages/graphql-tag-pluck/package.json @@ -29,15 +29,15 @@ "graphql": "^14.0.0 || ^15.0.0" }, "dependencies": { - "@babel/parser": "7.14.5", - "@babel/traverse": "7.14.5", + "@babel/parser": "7.14.7", + "@babel/traverse": "7.14.7", "@babel/types": "7.14.5", "@graphql-tools/utils": "^7.0.0", - "tslib": "~2.2.0" + "tslib": "~2.3.0" }, "devDependencies": { - "@types/babel__traverse": "7.11.1", - "@vue/compiler-sfc": "3.1.1" + "@types/babel__traverse": "7.14.0", + "@vue/compiler-sfc": "3.1.4" }, "buildOptions": { "external": [ diff --git a/packages/graphql-tag-pluck/src/index.ts b/packages/graphql-tag-pluck/src/index.ts index 6dc84251358..2c1857ada4d 100644 --- a/packages/graphql-tag-pluck/src/index.ts +++ b/packages/graphql-tag-pluck/src/index.ts @@ -4,6 +4,7 @@ import { getExtNameFromFilePath } from './libs/extname'; import createVisitor, { PluckedContent } from './visitor'; import traverse from '@babel/traverse'; import { freeText } from './utils'; +import { Source } from 'graphql'; /** * Additional options for determining how a file is parsed. @@ -128,7 +129,7 @@ export const gqlPluckFromCodeString = async ( filePath: string, code: string, options: GraphQLTagPluckOptions = {} -): Promise => { +): Promise => { validate({ code, options }); const fileExt = extractExtension(filePath); @@ -137,9 +138,7 @@ export const gqlPluckFromCodeString = async ( code = await pluckVueFileScript(code); } - return parseCode({ code, filePath, options }) - .map(t => t.content) - .join('\n\n'); + return parseCode({ code, filePath, options }).map(t => new Source(t.content, filePath, t.loc.start)); }; /** @@ -155,7 +154,7 @@ export const gqlPluckFromCodeStringSync = ( filePath: string, code: string, options: GraphQLTagPluckOptions = {} -): string => { +): Source[] => { validate({ code, options }); const fileExt = extractExtension(filePath); @@ -164,9 +163,7 @@ export const gqlPluckFromCodeStringSync = ( code = pluckVueFileScriptSync(code); } - return parseCode({ code, filePath, options }) - .map(t => t.content) - .join('\n\n'); + return parseCode({ code, filePath, options }).map(t => new Source(t.content, filePath, t.loc.start)); }; export function parseCode({ diff --git a/packages/graphql-tag-pluck/src/utils.ts b/packages/graphql-tag-pluck/src/utils.ts index 47c7163d2cb..c302045182f 100644 --- a/packages/graphql-tag-pluck/src/utils.ts +++ b/packages/graphql-tag-pluck/src/utils.ts @@ -22,7 +22,10 @@ export const freeText = (text: string | string[], skipIndentation = false) => { const minIndent = lines .filter(line => line.trim()) .reduce((minIndent, line) => { - const currIndent = line.match(/^ */)[0].length; + const currIndent = line.match(/^ */)?.[0].length; + if (currIndent == null) { + return minIndent; + } return currIndent < minIndent ? currIndent : minIndent; }, Infinity); @@ -47,7 +50,7 @@ export const toUpperFirst = (str: string) => { // foo-bar-baz -> fooBarBaz export const toCamelCase = (str: string) => { const words = splitWords(str); - const first = words.shift().toLowerCase(); + const first = words.shift()?.toLowerCase() ?? ''; const rest = words.map(toUpperFirst); return [first, ...rest].join(''); diff --git a/packages/graphql-tag-pluck/src/visitor.ts b/packages/graphql-tag-pluck/src/visitor.ts index e4e8537a7f4..d3e722c0611 100644 --- a/packages/graphql-tag-pluck/src/visitor.ts +++ b/packages/graphql-tag-pluck/src/visitor.ts @@ -8,6 +8,7 @@ import { isImportSpecifier, } from '@babel/types'; import { asArray } from '@graphql-tools/utils'; +import { Visitor } from '@babel/traverse'; const defaults: GraphQLTagPluckOptions = { modules: [ @@ -140,13 +141,17 @@ export type PluckedContent = { export default (code: string, out: any, options: GraphQLTagPluckOptions = {}) => { // Apply defaults to options - let { modules, globalGqlIdentifierName, gqlMagicComment } = { + let { + modules = [], + globalGqlIdentifierName, + gqlMagicComment, + } = { ...defaults, ...options, }; // Prevent case related potential errors - gqlMagicComment = gqlMagicComment.toLowerCase(); + gqlMagicComment = gqlMagicComment!.toLowerCase(); // normalize `name` and `identifier` values modules = modules.map(mod => { return { @@ -154,7 +159,7 @@ export default (code: string, out: any, options: GraphQLTagPluckOptions = {}) => identifier: mod.identifier && mod.identifier.toLowerCase(), }; }); - globalGqlIdentifierName = asArray(globalGqlIdentifierName).map(s => s.toLowerCase()); + globalGqlIdentifierName = asArray(globalGqlIdentifierName).map(s => s!.toLowerCase()); // Keep imported identifiers // import gql from 'graphql-tag' -> gql @@ -167,12 +172,12 @@ export default (code: string, out: any, options: GraphQLTagPluckOptions = {}) => // Check if package is registered function isValidPackage(name: string) { - return modules.some(pkg => pkg.name && name && pkg.name.toLowerCase() === name.toLowerCase()); + return modules!.some(pkg => pkg.name && name && pkg.name.toLowerCase() === name.toLowerCase()); } // Check if identifier is defined and imported from registered packages function isValidIdentifier(name: string) { - return definedIdentifierNames.some(id => id === name) || globalGqlIdentifierName.includes(name); + return definedIdentifierNames.some(id => id === name) || globalGqlIdentifierName!.includes(name); } const pluckStringFromFile = ({ start, end }: { start: number; end: number }) => { @@ -221,12 +226,20 @@ export default (code: string, out: any, options: GraphQLTagPluckOptions = {}) => } }; - return { + const visitor: Visitor = { CallExpression: { - enter(path: any) { + enter(path) { // Find the identifier name used from graphql-tag, commonJS // e.g. import gql from 'graphql-tag' -> gql - if (path.node.callee.name === 'require' && isValidPackage(path.node.arguments[0].value)) { + const arg0 = path.node.arguments[0]; + + if ( + 'name' in path.node.callee && + path.node.callee.name === 'require' && + 'value' in arg0 && + typeof arg0.value === 'string' && + isValidPackage(arg0.value) + ) { if (!isVariableDeclarator(path.parent)) { return; } @@ -239,29 +252,30 @@ export default (code: string, out: any, options: GraphQLTagPluckOptions = {}) => return; } - const arg0 = path.node.arguments[0]; - // Push strings template literals to gql calls // e.g. gql(`query myQuery {}`) -> query myQuery {} if (isIdentifier(path.node.callee) && isValidIdentifier(path.node.callee.name) && isTemplateLiteral(arg0)) { - const gqlTemplateLiteral = pluckStringFromFile(arg0); - - // If the entire template was made out of interpolations it should be an empty - // string by now and thus should be ignored - if (gqlTemplateLiteral) { - gqlTemplateLiterals.push({ - content: gqlTemplateLiteral, - loc: arg0.loc, - end: arg0.end, - start: arg0.start, - }); + const { start, end, loc } = arg0; + if (start != null && end != null && start != null && loc != null) { + const gqlTemplateLiteral = pluckStringFromFile({ start, end }); + + // If the entire template was made out of interpolations it should be an empty + // string by now and thus should be ignored + if (gqlTemplateLiteral) { + gqlTemplateLiterals.push({ + content: gqlTemplateLiteral, + loc, + end, + start, + }); + } } } }, }, ImportDeclaration: { - enter(path: any) { + enter(path) { // Find the identifier name used from graphql-tag, es6 // e.g. import gql from 'graphql-tag' -> gql if (!isValidPackage(path.node.source.value)) { @@ -270,6 +284,10 @@ export default (code: string, out: any, options: GraphQLTagPluckOptions = {}) => const moduleNode = modules.find(pkg => pkg.name.toLowerCase() === path.node.source.value.toLowerCase()); + if (moduleNode == null) { + return; + } + const gqlImportSpecifier = path.node.specifiers.find((importSpecifier: any) => { // When it's a default import and registered package has no named identifier if (isImportDefaultSpecifier(importSpecifier) && !moduleNode.identifier) { @@ -340,4 +358,6 @@ export default (code: string, out: any, options: GraphQLTagPluckOptions = {}) => out.returnValue = gqlTemplateLiterals; }, }; + + return visitor; }; diff --git a/packages/graphql-tag-pluck/tests/graphql-tag-pluck.test.ts b/packages/graphql-tag-pluck/tests/graphql-tag-pluck.test.ts index ef4d3ef8a2e..cd092de10f5 100644 --- a/packages/graphql-tag-pluck/tests/graphql-tag-pluck.test.ts +++ b/packages/graphql-tag-pluck/tests/graphql-tag-pluck.test.ts @@ -8,7 +8,7 @@ describe('graphql-tag-pluck', () => { sync: gqlPluckFromCodeStringSync })(pluck => { it('should allow to pluck without indentation changes', async () => { - const gqlString = await pluck('tmp-XXXXXX.js', freeText(` + const sources = await pluck('tmp-XXXXXX.js', freeText(` import gql from 'graphql-tag' const fragment = gql(\` @@ -30,11 +30,11 @@ describe('graphql-tag-pluck', () => { skipIndent: true }); - expect(gqlString).toMatchSnapshot(); + expect(sources.map(source => source.body).join('\n\n')).toMatchSnapshot(); }); it('should pluck graphql-tag template literals from .js file', async () => { - const gqlString = await pluck('tmp-XXXXXX.js', freeText(` + const sources = await pluck('tmp-XXXXXX.js', freeText(` import gql from 'graphql-tag' const fragment = gql(\` @@ -54,7 +54,7 @@ describe('graphql-tag-pluck', () => { \` `)); - expect(gqlString).toEqual(freeText(` + expect(sources.map(source => source.body).join('\n\n')).toEqual(freeText(` fragment Foo on FooType { id } @@ -68,7 +68,7 @@ describe('graphql-tag-pluck', () => { }); it('should pluck graphql-tag template literals from .js file when it has alias', async () => { - const gqlString = await pluck('tmp-XXXXXX.ts', freeText(` + const sources = await pluck('tmp-XXXXXX.ts', freeText(` import { default as foo } from 'graphql-tag' const fragment = foo(\` @@ -95,7 +95,7 @@ describe('graphql-tag-pluck', () => { ] }); - expect(gqlString).toEqual(freeText(` + expect(sources.map(source => source.body).join('\n\n')).toEqual(freeText(` fragment Foo on FooType { id } @@ -109,7 +109,7 @@ describe('graphql-tag-pluck', () => { }); it('should pluck graphql-tag template literals from .js file and remove replacements', async () => { - const gqlString = await pluck('tmp-XXXXXX.js', freeText(` + const sources = await pluck('tmp-XXXXXX.js', freeText(` import gql from 'graphql-tag' const fragment = gql(\` @@ -136,7 +136,7 @@ describe('graphql-tag-pluck', () => { \` `)); - expect(gqlString).toEqual(freeText(` + expect(sources.map(source => source.body).join('\n\n')).toEqual(freeText(` fragment Foo on FooType { id } @@ -155,7 +155,7 @@ describe('graphql-tag-pluck', () => { }); it('should pluck graphql-tag template literals from .ts file', async () => { - const gqlString = await pluck('tmp-XXXXXX.ts', freeText(` + const sources = await pluck('tmp-XXXXXX.ts', freeText(` import gql from 'graphql-tag' import { Document } from 'graphql' @@ -182,7 +182,7 @@ describe('graphql-tag-pluck', () => { } `)); - expect(gqlString).toEqual(freeText(` + expect(sources.map(source => source.body).join('\n\n')).toEqual(freeText(` fragment Foo on FooType { id } @@ -196,7 +196,7 @@ describe('graphql-tag-pluck', () => { }); it('should pluck graphql-tag template literals from .tsx file', async () => { - const gqlString = await pluck('tmp-XXXXXX.tsx', freeText(` + const sources = await pluck('tmp-XXXXXX.tsx', freeText(` import * as React from 'react'; import gql from 'graphql-tag'; @@ -227,7 +227,7 @@ describe('graphql-tag-pluck', () => { // \`; `)); - expect(gqlString).toEqual(freeText(` + expect(sources.map(source => source.body).join('\n\n')).toEqual(freeText(` query IndexQuery { site { siteMetadata { @@ -239,7 +239,7 @@ describe('graphql-tag-pluck', () => { }); it('should pluck graphql-tag template literals from .vue JavaScript file', async () => { - const gqlString = await pluck('tmp-XXXXXX.vue', freeText(` + const sources = await pluck('tmp-XXXXXX.vue', freeText(` @@ -278,7 +278,7 @@ describe('graphql-tag-pluck', () => { `)); - expect(gqlString).toEqual(freeText(` + expect(sources.map(source => source.body).join('\n\n')).toEqual(freeText(` query IndexQuery { site { siteMetadata { @@ -290,7 +290,7 @@ describe('graphql-tag-pluck', () => { }); it('should pluck graphql-tag template literals from .vue TS/Pug/SCSS file', async () => { - const gqlString = await pluck('tmp-XXXXXX.vue', freeText(` + const sources = await pluck('tmp-XXXXXX.vue', freeText(` @@ -329,7 +329,7 @@ describe('graphql-tag-pluck', () => { `)); - expect(gqlString).toEqual(freeText(` + expect(sources.map(source => source.body).join('\n\n')).toEqual(freeText(` query IndexQuery { site { siteMetadata { @@ -340,7 +340,7 @@ describe('graphql-tag-pluck', () => { `)); }); it('should pluck graphql-tag template literals from .vue 3 JavaScript file', async () => { - const gqlString = await pluck('tmp-XXXXXX.vue', freeText(` + const sources = await pluck('tmp-XXXXXX.vue', freeText(` @@ -379,7 +379,7 @@ describe('graphql-tag-pluck', () => { `)); - expect(gqlString).toEqual(freeText(` + expect(sources.map(source => source.body).join('\n\n')).toEqual(freeText(` query IndexQuery { site { siteMetadata { @@ -391,7 +391,7 @@ describe('graphql-tag-pluck', () => { }); it('should pluck graphql-tag template literals from .vue 3 TS/Pug/SCSS file', async () => { - const gqlString = await pluck('tmp-XXXXXX.vue', freeText(` + const sources = await pluck('tmp-XXXXXX.vue', freeText(` @@ -430,7 +430,7 @@ describe('graphql-tag-pluck', () => { `)); - expect(gqlString).toEqual(freeText(` + expect(sources.map(source => source.body).join('\n\n')).toEqual(freeText(` query IndexQuery { site { siteMetadata { @@ -442,7 +442,7 @@ describe('graphql-tag-pluck', () => { }); it('should pluck graphql-tag template literals from .vue 3 setup sugar JavaScript file', async () => { - const gqlString = await pluck('tmp-XXXXXX.vue', freeText(` + const sources = await pluck('tmp-XXXXXX.vue', freeText(` @@ -483,7 +483,7 @@ describe('graphql-tag-pluck', () => { `)); - expect(gqlString).toEqual(freeText(` + expect(sources.map(source => source.body).join('\n\n')).toEqual(freeText(` query IndexQuery { site { siteMetadata { @@ -495,7 +495,7 @@ describe('graphql-tag-pluck', () => { }); it('should pluck graphql-tag template literals from .vue 3 setup sugar TS/Pug/SCSS file', async () => { - const gqlString = await pluck('tmp-XXXXXX.vue', freeText(` + const sources = await pluck('tmp-XXXXXX.vue', freeText(` @@ -535,7 +535,7 @@ describe('graphql-tag-pluck', () => { `)); - expect(gqlString).toEqual(freeText(` + expect(sources.map(source => source.body).join('\n\n')).toEqual(freeText(` query IndexQuery { site { siteMetadata { @@ -546,7 +546,7 @@ describe('graphql-tag-pluck', () => { `)); }); it('should pluck graphql-tag template literals from .vue 3 outside setup sugar JavaScript file', async () => { - const gqlString = await pluck('tmp-XXXXXX.vue', freeText(` + const sources = await pluck('tmp-XXXXXX.vue', freeText(` @@ -585,7 +585,7 @@ describe('graphql-tag-pluck', () => { `)); - expect(gqlString).toEqual(freeText(` + expect(sources.map(source => source.body).join('\n\n')).toEqual(freeText(` query IndexQuery { site { siteMetadata { @@ -597,7 +597,7 @@ describe('graphql-tag-pluck', () => { }); it('should pluck graphql-tag template literals from .vue 3 outside setup sugar TS/Pug/SCSS file', async () => { - const gqlString = await pluck('tmp-XXXXXX.vue', freeText(` + const sources = await pluck('tmp-XXXXXX.vue', freeText(` @@ -636,7 +636,7 @@ describe('graphql-tag-pluck', () => { `)); - expect(gqlString).toEqual(freeText(` + expect(sources.map(source => source.body).join('\n\n')).toEqual(freeText(` query IndexQuery { site { siteMetadata { @@ -648,7 +648,7 @@ describe('graphql-tag-pluck', () => { }); it('should pluck graphql-tag template literals from .vue 3 setup JavaScript file', async () => { - const gqlString = await pluck('tmp-XXXXXX.vue', freeText(` + const sources = await pluck('tmp-XXXXXX.vue', freeText(` @@ -690,7 +690,7 @@ describe('graphql-tag-pluck', () => { `)); - expect(gqlString).toEqual(freeText(` + expect(sources.map(source => source.body).join('\n\n')).toEqual(freeText(` query IndexQuery { site { siteMetadata { @@ -702,7 +702,7 @@ describe('graphql-tag-pluck', () => { }); it('should pluck graphql-tag template literals from .vue 3 setup TS/Pug/SCSS file', async () => { - const gqlString = await pluck('tmp-XXXXXX.vue', freeText(` + const sources = await pluck('tmp-XXXXXX.vue', freeText(` @@ -744,7 +744,7 @@ describe('graphql-tag-pluck', () => { `)); - expect(gqlString).toEqual(freeText(` + expect(sources.map(source => source.body).join('\n\n')).toEqual(freeText(` query IndexQuery { site { siteMetadata { @@ -756,7 +756,7 @@ describe('graphql-tag-pluck', () => { }); it('should pluck graphql-tag template literals from .tsx file with generic jsx elements', async () => { - const gqlString = await pluck('tmp-XXXXXX.tsx', freeText(` + const sources = await pluck('tmp-XXXXXX.tsx', freeText(` import * as React from 'react'; import gql from 'graphql-tag'; import Generic from './Generic' @@ -784,7 +784,7 @@ describe('graphql-tag-pluck', () => { \`; `)); - expect(gqlString).toEqual(freeText(` + expect(sources.map(source => source.body).join('\n\n')).toEqual(freeText(` query IndexQuery { site { siteMetadata { @@ -796,7 +796,7 @@ describe('graphql-tag-pluck', () => { }); it('should pluck graphql-tag template literals from .ts file with the same const inside namespace and outside namespace', async () => { - const gqlString = await pluck('tmp-XXXXXX.ts', freeText(` + const sources = await pluck('tmp-XXXXXX.ts', freeText(` import gql from 'graphql-tag'; namespace Foo { @@ -829,7 +829,7 @@ describe('graphql-tag-pluck', () => { \`; `)); - expect(gqlString).toEqual(freeText(` + expect(sources.map(source => source.body).join('\n\n')).toEqual(freeText(` query myQueryInNamespace { fieldA } @@ -841,7 +841,7 @@ describe('graphql-tag-pluck', () => { }); it('should pluck graphql-tag template literals from .flow file', async () => { - const gqlString = await pluck('tmp-XXXXXX.flow', freeText(` + const sources = await pluck('tmp-XXXXXX.flow', freeText(` import gql from 'graphql-tag' import { Document } from 'graphql' @@ -862,7 +862,7 @@ describe('graphql-tag-pluck', () => { \` `)); - expect(gqlString).toEqual(freeText(` + expect(sources.map(source => source.body).join('\n\n')).toEqual(freeText(` fragment Foo on FooType { id } @@ -876,7 +876,7 @@ describe('graphql-tag-pluck', () => { }); it('should pluck graphql-tag template literals from .js file with @flow header', async () => { - const gqlString = await pluck('tmp-XXXXXX.js', freeText(` + const sources = await pluck('tmp-XXXXXX.js', freeText(` // @flow import gql from 'graphql-tag' @@ -899,7 +899,7 @@ describe('graphql-tag-pluck', () => { \` `)); - expect(gqlString).toEqual(freeText(` + expect(sources.map(source => source.body).join('\n\n')).toEqual(freeText(` fragment Foo on FooType { id } @@ -913,7 +913,7 @@ describe('graphql-tag-pluck', () => { }); it('should pluck graphql-tag template literals from .js file with @flow strict-local', async () => { - const gqlString = await pluck('tmp-XXXXXX.js', freeText(` + const sources = await pluck('tmp-XXXXXX.js', freeText(` // @flow strict-local import gql from 'graphql-tag' @@ -936,7 +936,7 @@ describe('graphql-tag-pluck', () => { \` `)); - expect(gqlString).toEqual(freeText(` + expect(sources.map(source => source.body).join('\n\n')).toEqual(freeText(` fragment Foo on FooType { id } @@ -982,7 +982,7 @@ describe('graphql-tag-pluck', () => { }); it('should pluck graphql-tag template literals from .flow.jsx file', async () => { - const gqlString = await pluck('tmp-XXXXXX.flow.jsx', freeText(` + const sources = await pluck('tmp-XXXXXX.flow.jsx', freeText(` import gql from 'graphql-tag' import { Document } from 'graphql' @@ -1003,7 +1003,7 @@ describe('graphql-tag-pluck', () => { \` `)); - expect(gqlString).toEqual(freeText(` + expect(sources.map(source => source.body).join('\n\n')).toEqual(freeText(` fragment Foo on FooType { id } @@ -1017,7 +1017,7 @@ describe('graphql-tag-pluck', () => { }); it('should pluck graphql-tag template literals from .*.jsx file', async () => { - const gqlString = await pluck('tmp-XXXXXX.mutation.jsx', freeText(` + const sources = await pluck('tmp-XXXXXX.mutation.jsx', freeText(` import gql from 'graphql-tag' const fragment = gql\` @@ -1037,7 +1037,7 @@ describe('graphql-tag-pluck', () => { \` `)); - expect(gqlString).toEqual(freeText(` + expect(sources.map(source => source.body).join('\n\n')).toEqual(freeText(` fragment Foo on FooType { id } @@ -1051,7 +1051,7 @@ describe('graphql-tag-pluck', () => { }); it('should pluck graphql-tag template literals leaded by a magic comment from .js file', async () => { - const gqlString = await pluck('tmp-XXXXXX.js', freeText(` + const sources = await pluck('tmp-XXXXXX.js', freeText(` const Message = /* GraphQL */ \` enum MessageTypes { text @@ -1060,7 +1060,7 @@ describe('graphql-tag-pluck', () => { }\` `)); - expect(gqlString).toEqual(freeText(` + expect(sources.map(source => source.body).join('\n\n')).toEqual(freeText(` enum MessageTypes { text media @@ -1070,7 +1070,7 @@ describe('graphql-tag-pluck', () => { }); it('should pluck graphql-tag expression statements leaded by a magic comment from .js file', async () => { - const gqlString = await pluck('tmp-XXXXXX.js', freeText(` + const sources = await pluck('tmp-XXXXXX.js', freeText(` /* GraphQL */ \` enum MessageTypes { text @@ -1079,7 +1079,7 @@ describe('graphql-tag-pluck', () => { }\` `)); - expect(gqlString).toEqual(freeText(` + expect(sources.map(source => source.body).join('\n\n')).toEqual(freeText(` enum MessageTypes { text media @@ -1089,7 +1089,7 @@ describe('graphql-tag-pluck', () => { }); it(`should NOT pluck other template literals from a .js file`, async () => { - const gqlString = await pluck(`tmp-XXXXXX.js`, freeText(` + const sources = await pluck(`tmp-XXXXXX.js`, freeText(` test( \`test1\` ) @@ -1104,11 +1104,11 @@ describe('graphql-tag-pluck', () => { \` `)); - expect(gqlString).toEqual(''); + expect(sources.map(source => source.body).join('\n\n')).toEqual(''); }); it('should pluck template literals when graphql-tag is imported differently', async () => { - const gqlString = await pluck('tmp-XXXXXX.js', freeText(` + const sources = await pluck('tmp-XXXXXX.js', freeText(` import graphqltag from 'graphql-tag' const fragment = graphqltag(\` @@ -1128,7 +1128,7 @@ describe('graphql-tag-pluck', () => { \` `)); - expect(gqlString).toEqual(freeText(` + expect(sources.map(source => source.body).join('\n\n')).toEqual(freeText(` fragment Foo on FooType { id } @@ -1142,7 +1142,7 @@ describe('graphql-tag-pluck', () => { }); it('should pluck template literals from gql by default even if not imported from graphql-tag', async () => { - const gqlString = await pluck('tmp-XXXXXX.js', freeText(` + const sources = await pluck('tmp-XXXXXX.js', freeText(` const fragment = gql(\` fragment Foo on FooType { id @@ -1160,7 +1160,7 @@ describe('graphql-tag-pluck', () => { \` `)); - expect(gqlString).toEqual(freeText(` + expect(sources.map(source => source.body).join('\n\n')).toEqual(freeText(` fragment Foo on FooType { id } @@ -1174,7 +1174,7 @@ describe('graphql-tag-pluck', () => { }); it('should pluck graphql-tag template literals from code string', async () => { - const gqlString = await pluck('test.js', freeText(` + const sources = await pluck('test.js', freeText(` import gql from 'graphql-tag' const fragment = gql(\` @@ -1194,7 +1194,7 @@ describe('graphql-tag-pluck', () => { \` `)); - expect(gqlString).toEqual(freeText(` + expect(sources.map(source => source.body).join('\n\n')).toEqual(freeText(` fragment Foo on FooType { id } @@ -1208,7 +1208,7 @@ describe('graphql-tag-pluck', () => { }); it('should pluck graphql-tag template literals from a .js file', async () => { - const gqlString = await pluck('tmp-XXXXXX.js', freeText(` + const sources = await pluck('tmp-XXXXXX.js', freeText(` import gql from 'graphql-tag' const fragment = gql(\` @@ -1228,7 +1228,7 @@ describe('graphql-tag-pluck', () => { \` `)); - expect(gqlString).toEqual(freeText(` + expect(sources.map(source => source.body).join('\n\n')).toEqual(freeText(` fragment Foo on FooType { id } @@ -1242,7 +1242,7 @@ describe('graphql-tag-pluck', () => { }); it('should be able to specify the global GraphQL identifier name', async () => { - const gqlString = await pluck('tmp-XXXXXX.js', freeText(` + const sources = await pluck('tmp-XXXXXX.js', freeText(` const fragment = anothergql(\` fragment Foo on FooType { id @@ -1262,7 +1262,7 @@ describe('graphql-tag-pluck', () => { globalGqlIdentifierName: 'anothergql' }); - expect(gqlString).toEqual(freeText(` + expect(sources.map(source => source.body).join('\n\n')).toEqual(freeText(` fragment Foo on FooType { id } @@ -1276,7 +1276,7 @@ describe('graphql-tag-pluck', () => { }); it('should be able to specify the GraphQL magic comment to look for', async () => { - const gqlString = await pluck('tmp-XXXXXX.js', freeText(` + const sources = await pluck('tmp-XXXXXX.js', freeText(` const Message = /* GQL */ \` enum MessageTypes { text @@ -1287,7 +1287,7 @@ describe('graphql-tag-pluck', () => { gqlMagicComment: 'GQL' }); - expect(gqlString).toEqual(freeText(` + expect(sources.map(source => source.body).join('\n\n')).toEqual(freeText(` enum MessageTypes { text media @@ -1297,7 +1297,7 @@ describe('graphql-tag-pluck', () => { }); it('should be able to specify the package name of which the GraphQL identifier should be imported from', async () => { - const gqlString = await pluck('tmp-XXXXXX.js', freeText(` + const sources = await pluck('tmp-XXXXXX.js', freeText(` import mygql from 'my-graphql-tag' const fragment = mygql(\` @@ -1321,7 +1321,7 @@ describe('graphql-tag-pluck', () => { ] }); - expect(gqlString).toEqual(freeText(` + expect(sources.map(source => source.body).join('\n\n')).toEqual(freeText(` fragment Foo on FooType { id } @@ -1335,7 +1335,7 @@ describe('graphql-tag-pluck', () => { }); it('should pluck graphql template literal from gatsby package', async () => { - const gqlString = await pluck('tmp-XXXXXX.js', freeText(` + const sources = await pluck('tmp-XXXXXX.js', freeText(` import {graphql} from 'gatsby' const fragment = graphql(\` @@ -1355,7 +1355,7 @@ describe('graphql-tag-pluck', () => { \` `)); - expect(gqlString).toEqual(freeText(` + expect(sources.map(source => source.body).join('\n\n')).toEqual(freeText(` fragment Foo on FooType { id } @@ -1369,7 +1369,7 @@ describe('graphql-tag-pluck', () => { }); it('should pluck gql template literal from apollo-server-express package', async () => { - const gqlString = await pluck('tmp-XXXXXX.js', freeText(` + const sources = await pluck('tmp-XXXXXX.js', freeText(` import { gql } from 'apollo-server-express' const fragment = gql(\` @@ -1389,7 +1389,7 @@ describe('graphql-tag-pluck', () => { \` `)); - expect(gqlString).toEqual(freeText(` + expect(sources.map(source => source.body).join('\n\n')).toEqual(freeText(` fragment Foo on FooType { id } @@ -1403,7 +1403,7 @@ describe('graphql-tag-pluck', () => { }); it('should pluck gql template literal from @apollo/client package', async () => { - const gqlString = await pluck('tmp-XXXXXX.js', freeText(` + const sources = await pluck('tmp-XXXXXX.js', freeText(` import { gql } from '@apollo/client' const fragment = gql(\` @@ -1423,7 +1423,7 @@ describe('graphql-tag-pluck', () => { \` `)); - expect(gqlString).toEqual(freeText(` + expect(sources.map(source => source.body).join('\n\n')).toEqual(freeText(` fragment Foo on FooType { id } @@ -1437,12 +1437,12 @@ describe('graphql-tag-pluck', () => { }); it('should pluck magic comment template literals with a trailing semicolon', async () => { - const gqlString = await pluck('test.js', '/* GraphQL */ `{}`;'); - expect(gqlString).toEqual('{}'); + const sources = await pluck('test.js', '/* GraphQL */ `{}`;'); + expect(sources.map(source => source.body).join('\n\n')).toEqual('{}'); }); it('should pluck with comments having escaped backticks', async () => { - const gqlString = await pluck('tmp-XXXXXX.js', freeText(` + const sources = await pluck('tmp-XXXXXX.js', freeText(` import gql from 'graphql-tag'; export default gql\` @@ -1455,7 +1455,7 @@ describe('graphql-tag-pluck', () => { \` `)); - expect(gqlString).toEqual(freeText(` + expect(sources.map(source => source.body).join('\n\n')).toEqual(freeText(` type User { id: ID! "Choose a nice username, so users can \`@mention\` you." @@ -1466,7 +1466,7 @@ describe('graphql-tag-pluck', () => { }); it('should pluck graphql template literal imported lazily', async () => { - const gqlString = await pluck('tmp-XXXXXX.js', freeText(` + const sources = await pluck('tmp-XXXXXX.js', freeText(` async function getUserType() { const graphql = await import('graphql-tag'); @@ -1481,7 +1481,7 @@ describe('graphql-tag-pluck', () => { } `)); - expect(gqlString).toEqual(freeText(` + expect(sources.map(source => source.body).join('\n\n')).toEqual(freeText(` type User { id: ID! "Choose a nice username, so users can \`@mention\` you." @@ -1492,7 +1492,7 @@ describe('graphql-tag-pluck', () => { }); it('should pluck graphql template literal in a code file that has decorators', async () => { - const gqlString = await pluck('tmp-XXXXXX.ts', freeText(` + const sources = await pluck('tmp-XXXXXX.ts', freeText(` const CurrentUserForProfile = gql\` query CurrentUserForProfile { currentUser { @@ -1523,7 +1523,7 @@ describe('graphql-tag-pluck', () => { `)); - expect(gqlString).toEqual(freeText(/* GraphQL */` + expect(sources.map(source => source.body).join('\n\n')).toEqual(freeText(/* GraphQL */` query CurrentUserForProfile { currentUser { login diff --git a/packages/graphql-tools/package.json b/packages/graphql-tools/package.json index 5e8f8b782b9..431ff3299be 100644 --- a/packages/graphql-tools/package.json +++ b/packages/graphql-tools/package.json @@ -36,30 +36,7 @@ "directory": "dist" }, "dependencies": { - "@graphql-tools/optimize": "1.0.1", - "@graphql-tools/batch-delegate": "^7.0.0", - "@graphql-tools/batch-execute": "^7.0.0", - "@graphql-tools/delegate": "^7.0.10", - "@graphql-tools/graphql-tag-pluck": "^6.2.6", - "@graphql-tools/import": "^6.2.4", - "@graphql-tools/links": "^7.0.4", - "@graphql-tools/load": "^6.2.5", - "@graphql-tools/code-file-loader": "^6.2.5", - "@graphql-tools/git-loader": "^6.2.5", - "@graphql-tools/github-loader": "^6.2.5", - "@graphql-tools/graphql-file-loader": "^6.2.5", - "@graphql-tools/json-file-loader": "^6.2.5", - "@graphql-tools/module-loader": "^6.2.5", - "@graphql-tools/url-loader": "^6.3.2", - "@graphql-tools/load-files": "^6.2.4", - "@graphql-tools/merge": "^6.2.14", - "@graphql-tools/mock": "^7.0.0", - "@graphql-tools/relay-operation-optimizer": "^6.2.5", - "@graphql-tools/resolvers-composition": "^6.2.5", "@graphql-tools/schema": "^7.0.0", - "@graphql-tools/stitch": "^7.3.0", - "@graphql-tools/utils": "^7.0.1", - "@graphql-tools/wrap": "^7.0.0", - "tslib": "~2.2.0" + "tslib": "~2.3.0" } } diff --git a/packages/graphql-tools/src/index.ts b/packages/graphql-tools/src/index.ts index dbd653e5d01..b214057bd3d 100644 --- a/packages/graphql-tools/src/index.ts +++ b/packages/graphql-tools/src/index.ts @@ -1,23 +1,5 @@ -export * from '@graphql-tools/batch-delegate'; -export * from '@graphql-tools/batch-execute'; -export * from '@graphql-tools/delegate'; -export * from '@graphql-tools/graphql-tag-pluck'; -export * from '@graphql-tools/import'; -export * from '@graphql-tools/links'; -export * from '@graphql-tools/load'; -export * from '@graphql-tools/code-file-loader'; -export * from '@graphql-tools/git-loader'; -export * from '@graphql-tools/github-loader'; -export * from '@graphql-tools/graphql-file-loader'; -export * from '@graphql-tools/module-loader'; -export * from '@graphql-tools/url-loader'; -export * from '@graphql-tools/load-files'; -export * from '@graphql-tools/merge'; -export * from '@graphql-tools/mock'; -export * from '@graphql-tools/relay-operation-optimizer'; -export * from '@graphql-tools/resolvers-composition'; -export * from '@graphql-tools/schema'; -export * from '@graphql-tools/stitch'; -export * from '@graphql-tools/utils'; -export * from '@graphql-tools/wrap'; -export * from '@graphql-tools/optimize'; +export { makeExecutableSchema } from '@graphql-tools/schema'; + +console.warn(`This package has been deprecated and now it only exports makeExecutableSchema. +We recommend you to migrate to scoped packages. +Check out https://www.graphql-tools.com for more information!`); diff --git a/packages/import/package.json b/packages/import/package.json index 82e01692566..8fdcda48f04 100644 --- a/packages/import/package.json +++ b/packages/import/package.json @@ -35,6 +35,6 @@ }, "dependencies": { "resolve-from": "5.0.0", - "tslib": "~2.2.0" + "tslib": "~2.3.0" } } diff --git a/packages/import/src/index.ts b/packages/import/src/index.ts index d69a20e4735..a00455b846d 100644 --- a/packages/import/src/index.ts +++ b/packages/import/src/index.ts @@ -70,12 +70,14 @@ export function processImport( const set = visitFile(filePath, join(cwd + '/root.graphql'), visitedFiles, predefinedImports); const definitionStrSet = new Set(); let definitionsStr = ''; - for (const defs of set.values()) { - for (const def of defs) { - const defStr = print(def); - if (!definitionStrSet.has(defStr)) { - definitionStrSet.add(defStr); - definitionsStr += defStr + '\n'; + if (set != null) { + for (const defs of set.values()) { + for (const def of defs) { + const defStr = print(def); + if (!definitionStrSet.has(defStr)) { + definitionStrSet.add(defStr); + definitionsStr += defStr + '\n'; + } } } } @@ -120,16 +122,18 @@ function visitFile( }); for (const definition of document.definitions) { if ('name' in definition || definition.kind === Kind.SCHEMA_DEFINITION) { - const definitionName = 'name' in definition ? definition.name.value : 'schema'; + const definitionName = 'name' in definition && definition.name ? definition.name.value : 'schema'; if (!definitionsByName.has(definitionName)) { definitionsByName.set(definitionName, new Set()); } const definitionsSet = definitionsByName.get(definitionName); - definitionsSet.add(definition); - if (!dependenciesByDefinitionName.has(definitionName)) { - dependenciesByDefinitionName.set(definitionName, new Set()); + definitionsSet?.add(definition); + + let dependencySet = dependenciesByDefinitionName.get(definitionName); + if (!dependencySet) { + dependencySet = new Set(); + dependenciesByDefinitionName.set(definitionName, dependencySet); } - const dependencySet = dependenciesByDefinitionName.get(definitionName); switch (definition.kind) { case Kind.OPERATION_DEFINITION: visitOperationDefinitionNode(definition, dependencySet); @@ -180,21 +184,22 @@ function visitFile( visitScalarExtensionNode(definition, dependencySet); break; } - if ('fields' in definition) { + if ('fields' in definition && definition.fields) { for (const field of definition.fields) { const definitionName = definition.name.value + '.' + field.name.value; if (!definitionsByName.has(definitionName)) { definitionsByName.set(definitionName, new Set()); } - const definitionsSet = definitionsByName.get(definitionName); - definitionsSet.add({ + definitionsByName.get(definitionName)?.add({ ...definition, fields: [field as any], }); - if (!dependenciesByDefinitionName.has(definitionName)) { - dependenciesByDefinitionName.set(definitionName, new Set()); + + let dependencySet = dependenciesByDefinitionName.get(definitionName); + if (!dependencySet) { + dependencySet = new Set(); + dependenciesByDefinitionName.set(definitionName, dependencySet); } - const dependencySet = dependenciesByDefinitionName.get(definitionName); switch (field.kind) { case Kind.FIELD_DEFINITION: visitFieldDefinitionNode(field, dependencySet, dependenciesByDefinitionName); @@ -208,19 +213,24 @@ function visitFile( } } for (const [definitionName, definitions] of definitionsByName) { - if (!fileDefinitionMap.has(definitionName)) { - fileDefinitionMap.set(definitionName, new Set()); + let definitionsWithDependencies = fileDefinitionMap.get(definitionName); + if (definitionsWithDependencies == null) { + definitionsWithDependencies = new Set(); + fileDefinitionMap.set(definitionName, definitionsWithDependencies); } - const definitionsWithDependencies = fileDefinitionMap.get(definitionName); for (const definition of definitions) { definitionsWithDependencies.add(definition); } const dependenciesOfDefinition = dependenciesByDefinitionName.get(definitionName); - for (const dependencyName of dependenciesOfDefinition) { - const dependencyDefinitions = definitionsByName.get(dependencyName); - dependencyDefinitions?.forEach(dependencyDefinition => { - definitionsWithDependencies.add(dependencyDefinition); - }); + if (dependenciesOfDefinition) { + for (const dependencyName of dependenciesOfDefinition) { + const dependencyDefinitions = definitionsByName.get(dependencyName); + if (dependencyDefinitions != null) { + for (const dependencyDefinition of dependencyDefinitions) { + definitionsWithDependencies.add(dependencyDefinition); + } + } + } } } } @@ -228,34 +238,40 @@ function visitFile( for (const line of importLines) { const { imports, from } = parseImportLine(line.replace('#', '').trim()); const importFileDefinitionMap = visitFile(from, filePath, visitedFiles, predefinedImports); - if (imports.includes('*')) { - for (const [importedDefinitionName, importedDefinitions] of importFileDefinitionMap) { - const [importedDefinitionTypeName] = importedDefinitionName.split('.'); - if (!allImportedDefinitionsMap.has(importedDefinitionTypeName)) { - allImportedDefinitionsMap.set(importedDefinitionTypeName, new Set()); - } - const allImportedDefinitions = allImportedDefinitionsMap.get(importedDefinitionTypeName); - for (const importedDefinition of importedDefinitions) { - allImportedDefinitions.add(importedDefinition); - } - } - } else { - for (let importedDefinitionName of imports) { - if (importedDefinitionName.endsWith('.*')) { - // Adding whole type means the same thing with adding every single field - importedDefinitionName = importedDefinitionName.replace('.*', ''); - } - const [importedDefinitionTypeName] = importedDefinitionName.split('.'); - if (!allImportedDefinitionsMap.has(importedDefinitionTypeName)) { - allImportedDefinitionsMap.set(importedDefinitionTypeName, new Set()); - } - const allImportedDefinitions = allImportedDefinitionsMap.get(importedDefinitionTypeName); - const importedDefinitions = importFileDefinitionMap.get(importedDefinitionName); - if (!importedDefinitions) { - throw new Error(`${importedDefinitionName} is not exported by ${from} imported by ${filePath}`); + if (importFileDefinitionMap != null) { + if (imports.includes('*')) { + for (const [importedDefinitionName, importedDefinitions] of importFileDefinitionMap) { + const [importedDefinitionTypeName] = importedDefinitionName.split('.'); + if (!allImportedDefinitionsMap.has(importedDefinitionTypeName)) { + allImportedDefinitionsMap.set(importedDefinitionTypeName, new Set()); + } + const allImportedDefinitions = allImportedDefinitionsMap.get(importedDefinitionTypeName); + if (allImportedDefinitions) { + for (const importedDefinition of importedDefinitions) { + allImportedDefinitions.add(importedDefinition); + } + } } - for (const importedDefinition of importedDefinitions) { - allImportedDefinitions.add(importedDefinition); + } else { + for (let importedDefinitionName of imports) { + if (importedDefinitionName.endsWith('.*')) { + // Adding whole type means the same thing with adding every single field + importedDefinitionName = importedDefinitionName.replace('.*', ''); + } + const [importedDefinitionTypeName] = importedDefinitionName.split('.'); + if (!allImportedDefinitionsMap.has(importedDefinitionTypeName)) { + allImportedDefinitionsMap.set(importedDefinitionTypeName, new Set()); + } + const allImportedDefinitions = allImportedDefinitionsMap.get(importedDefinitionTypeName); + const importedDefinitions = importFileDefinitionMap.get(importedDefinitionName); + if (!importedDefinitions) { + throw new Error(`${importedDefinitionName} is not exported by ${from} imported by ${filePath}`); + } + if (allImportedDefinitions != null) { + for (const importedDefinition of importedDefinitions) { + allImportedDefinitions.add(importedDefinition); + } + } } } } @@ -264,61 +280,69 @@ function visitFile( visitedFiles.set(filePath, allImportedDefinitionsMap); } else { const fileDefinitionMap = visitedFiles.get(filePath); - const addDefinition = ( - definition: DefinitionNode, - definitionName: string, - definitionSet: Set - ) => { - if (!definitionSet.has(definition)) { - definitionSet.add(definition); - // Regenerate field exports if some fields are imported after visitor - if ('fields' in definition) { - for (const field of definition.fields) { - const fieldName = field.name.value; - const fieldDefinitionName = definition.name.value + '.' + fieldName; + if (fileDefinitionMap) { + const addDefinition = ( + definition: DefinitionNode, + definitionName: string, + definitionSet: Set + ) => { + if (!definitionSet.has(definition)) { + definitionSet.add(definition); + // Regenerate field exports if some fields are imported after visitor + if ('fields' in definition && definition.fields) { + for (const field of definition.fields) { + const fieldName = field.name.value; + const fieldDefinitionName = definition.name.value + '.' + fieldName; + const allImportedDefinitions = allImportedDefinitionsMap.get(definitionName); + allImportedDefinitions?.forEach(importedDefinition => { + if (!fileDefinitionMap.has(fieldDefinitionName)) { + fileDefinitionMap.set(fieldDefinitionName, new Set()); + } + const definitionsWithDeps = fileDefinitionMap.get(fieldDefinitionName); + if (definitionsWithDeps) { + addDefinition(importedDefinition, fieldDefinitionName, definitionsWithDeps); + } + }); + const newDependencySet = new Set(); + switch (field.kind) { + case Kind.FIELD_DEFINITION: + visitFieldDefinitionNode(field, newDependencySet, dependenciesByDefinitionName); + break; + case Kind.INPUT_VALUE_DEFINITION: + visitInputValueDefinitionNode(field, newDependencySet, dependenciesByDefinitionName); + break; + } + newDependencySet.forEach(dependencyName => { + const definitionsInCurrentFile = fileDefinitionMap.get(dependencyName); + definitionsInCurrentFile?.forEach(def => addDefinition(def, definitionName, definitionSet)); + const definitionsFromImports = allImportedDefinitionsMap.get(dependencyName); + definitionsFromImports?.forEach(def => addDefinition(def, definitionName, definitionSet)); + }); + } + } + } + }; + for (const [definitionName] of definitionsByName) { + const definitionsWithDependencies = fileDefinitionMap.get(definitionName); + if (definitionsWithDependencies) { const allImportedDefinitions = allImportedDefinitionsMap.get(definitionName); allImportedDefinitions?.forEach(importedDefinition => { - if (!fileDefinitionMap.has(fieldDefinitionName)) { - fileDefinitionMap.set(fieldDefinitionName, new Set()); - } - const definitionsWithDeps = fileDefinitionMap.get(fieldDefinitionName); - addDefinition(importedDefinition, fieldDefinitionName, definitionsWithDeps); + addDefinition(importedDefinition, definitionName, definitionsWithDependencies); }); - const newDependencySet = new Set(); - switch (field.kind) { - case Kind.FIELD_DEFINITION: - visitFieldDefinitionNode(field, newDependencySet, dependenciesByDefinitionName); - break; - case Kind.INPUT_VALUE_DEFINITION: - visitInputValueDefinitionNode(field, newDependencySet, dependenciesByDefinitionName); - break; + const dependenciesOfDefinition = dependenciesByDefinitionName.get(definitionName); + if (dependenciesOfDefinition) { + for (const dependencyName of dependenciesOfDefinition) { + // If that dependency cannot be found both in imports and this file, throw an error + if (!allImportedDefinitionsMap.has(dependencyName) && !definitionsByName.has(dependencyName)) { + throw new Error(`Couldn't find type ${dependencyName} in any of the schemas.`); + } + const dependencyDefinitionsFromImports = allImportedDefinitionsMap.get(dependencyName); + dependencyDefinitionsFromImports?.forEach(dependencyDefinition => { + addDefinition(dependencyDefinition, definitionName, definitionsWithDependencies); + }); + } } - newDependencySet.forEach(dependencyName => { - const definitionsInCurrentFile = fileDefinitionMap.get(dependencyName); - definitionsInCurrentFile?.forEach(def => addDefinition(def, definitionName, definitionSet)); - const definitionsFromImports = allImportedDefinitionsMap.get(dependencyName); - definitionsFromImports?.forEach(def => addDefinition(def, definitionName, definitionSet)); - }); - } - } - } - }; - for (const [definitionName] of definitionsByName) { - const definitionsWithDependencies = fileDefinitionMap.get(definitionName); - const allImportedDefinitions = allImportedDefinitionsMap.get(definitionName); - allImportedDefinitions?.forEach(importedDefinition => { - addDefinition(importedDefinition, definitionName, definitionsWithDependencies); - }); - const dependenciesOfDefinition = dependenciesByDefinitionName.get(definitionName); - for (const dependencyName of dependenciesOfDefinition) { - // If that dependency cannot be found both in imports and this file, throw an error - if (!allImportedDefinitionsMap.has(dependencyName) && !definitionsByName.has(dependencyName)) { - throw new Error(`Couldn't find type ${dependencyName} in any of the schemas.`); } - const dependencyDefinitionsFromImports = allImportedDefinitionsMap.get(dependencyName); - dependencyDefinitionsFromImports?.forEach(dependencyDefinition => { - addDefinition(dependencyDefinition, definitionName, definitionsWithDependencies); - }); } } } @@ -327,10 +351,11 @@ function visitFile( } export function parseImportLine(importLine: string): { imports: string[]; from: string } { - if (IMPORT_FROM_REGEX.test(importLine)) { + let regexMatch = importLine.match(IMPORT_FROM_REGEX); + if (regexMatch != null) { // Apply regex to import line // Extract matches into named variables - const [, wildcard, importsString, , from] = importLine.match(IMPORT_FROM_REGEX); + const [, wildcard, importsString, , from] = regexMatch; if (from) { // Extract imported types @@ -339,12 +364,16 @@ export function parseImportLine(importLine: string): { imports: string[]; from: // Return information about the import line return { imports, from }; } - } else if (IMPORT_DEFAULT_REGEX.test(importLine)) { - const [, , from] = importLine.match(IMPORT_DEFAULT_REGEX); + } + + regexMatch = importLine.match(IMPORT_DEFAULT_REGEX); + if (regexMatch != null) { + const [, , from] = regexMatch; if (from) { return { imports: ['*'], from }; } } + throw new Error(` Import statement is not valid: > ${importLine} @@ -354,7 +383,7 @@ export function parseImportLine(importLine: string): { imports: string[]; from: `); } -function resolveFilePath(filePath: string, importFrom: string) { +function resolveFilePath(filePath: string, importFrom: string): string { const dirName = dirname(filePath); try { const fullPath = join(dirName, importFrom); @@ -363,11 +392,14 @@ function resolveFilePath(filePath: string, importFrom: string) { if (e.code === 'ENOENT') { return resolveFrom(dirName, importFrom); } + throw e; } } function visitOperationDefinitionNode(node: OperationDefinitionNode, dependencySet: Set) { - dependencySet.add(node.name.value); + if (node.name?.value) { + dependencySet.add(node.name.value); + } node.selectionSet.selections.forEach(selectionNode => visitSelectionNode(selectionNode, dependencySet)); } @@ -416,11 +448,13 @@ function visitObjectTypeDefinitionNode( node.interfaces?.forEach(namedTypeNode => { visitNamedTypeNode(namedTypeNode, dependencySet); const interfaceName = namedTypeNode.name.value; + let set = dependenciesByDefinitionName.get(interfaceName); // interface should be dependent to the type as well - if (!dependenciesByDefinitionName.has(interfaceName)) { - dependenciesByDefinitionName.set(interfaceName, new Set()); + if (set == null) { + set = new Set(); + dependenciesByDefinitionName.set(interfaceName, set); } - dependenciesByDefinitionName.get(interfaceName).add(typeName); + set.add(typeName); }); } @@ -507,18 +541,20 @@ function visitInterfaceTypeDefinitionNode( (node as any).interfaces?.forEach((namedTypeNode: NamedTypeNode) => { visitNamedTypeNode(namedTypeNode, dependencySet); const interfaceName = namedTypeNode.name.value; + let set = dependenciesByDefinitionName.get(interfaceName); // interface should be dependent to the type as well - if (!dependenciesByDefinitionName.has(interfaceName)) { - dependenciesByDefinitionName.set(interfaceName, new Set()); + if (set == null) { + set = new Set(); + dependenciesByDefinitionName.set(interfaceName, set); } - dependenciesByDefinitionName.get(interfaceName).add(typeName); + set.add(typeName); }); } function visitUnionTypeDefinitionNode(node: UnionTypeDefinitionNode, dependencySet: Set) { dependencySet.add(node.name.value); node.directives?.forEach(directiveNode => visitDirectiveNode(directiveNode, dependencySet)); - node.types.forEach(namedTypeNode => visitNamedTypeNode(namedTypeNode, dependencySet)); + node.types?.forEach(namedTypeNode => visitNamedTypeNode(namedTypeNode, dependencySet)); } function visitEnumTypeDefinitionNode(node: EnumTypeDefinitionNode, dependencySet: Set) { @@ -563,11 +599,13 @@ function visitObjectTypeExtensionNode( node.interfaces?.forEach(namedTypeNode => { visitNamedTypeNode(namedTypeNode, dependencySet); const interfaceName = namedTypeNode.name.value; + let set = dependenciesByDefinitionName.get(interfaceName); // interface should be dependent to the type as well - if (!dependenciesByDefinitionName.has(interfaceName)) { - dependenciesByDefinitionName.set(interfaceName, new Set()); + if (set == null) { + set = new Set(); + dependenciesByDefinitionName.set(interfaceName, set); } - dependenciesByDefinitionName.get(interfaceName).add(typeName); + set.add(typeName); }); } @@ -585,18 +623,20 @@ function visitInterfaceTypeExtensionNode( (node as any).interfaces?.forEach((namedTypeNode: NamedTypeNode) => { visitNamedTypeNode(namedTypeNode, dependencySet); const interfaceName = namedTypeNode.name.value; + let set = dependenciesByDefinitionName.get(interfaceName); // interface should be dependent to the type as well - if (!dependenciesByDefinitionName.has(interfaceName)) { - dependenciesByDefinitionName.set(interfaceName, new Set()); + if (set == null) { + set = new Set(); + dependenciesByDefinitionName.set(interfaceName, set); } - dependenciesByDefinitionName.get(interfaceName).add(typeName); + set.add(typeName); }); } function visitUnionTypeExtensionNode(node: UnionTypeExtensionNode, dependencySet: Set) { dependencySet.add(node.name.value); node.directives?.forEach(directiveNode => visitDirectiveNode(directiveNode, dependencySet)); - node.types.forEach(namedTypeNode => visitNamedTypeNode(namedTypeNode, dependencySet)); + node.types?.forEach(namedTypeNode => visitNamedTypeNode(namedTypeNode, dependencySet)); } function visitEnumTypeExtensionNode(node: EnumTypeExtensionNode, dependencySet: Set) { diff --git a/packages/jest-transform/README.md b/packages/jest-transform/README.md new file mode 100644 index 00000000000..fa1826ce1b4 --- /dev/null +++ b/packages/jest-transform/README.md @@ -0,0 +1,45 @@ +# GraphQL Jest Transform + +A Jest transformer to preprocess GraphQL Documents (operations, fragments and SDL) + + yarn add @graphql-tools/jest-transform + +In your `package.json`: + +```json +{ + "jest": { + "transform": { + "\\.(gql|graphql)$": "@graphql-tools/jest-transform" + } + } +} +``` + +or `jest.config.js`: + +```javascript +module.exports = { + // ... + transform: { + '\\.(gql|graphql)$': '@graphql-tools/jest-transform', + }, +}; +``` + +> How is it different from `jest-transform-graphql`? It doesn't use `graphql-tag/loader` under the hood but our own, more optimized and customisable `@graphql-tools/webpack-loader`. + +## Options + +- noDescription (_default: false_) - removes descriptions +- esModule (_default: false_) - uses import and export statements instead of CommonJS + +```json +{ + "globals": { + "graphql": { + "noDescription": true + } + } +} +``` diff --git a/packages/jest-transform/package.json b/packages/jest-transform/package.json new file mode 100644 index 00000000000..196f1023329 --- /dev/null +++ b/packages/jest-transform/package.json @@ -0,0 +1,44 @@ +{ + "name": "@graphql-tools/jest-transform", + "version": "0.0.0", + "description": "Jest Plugin to load and parse imported GraphQL files", + "repository": { + "type": "git", + "url": "git@github.com:ardatan/graphql-tools.git", + "directory": "packages/jest-transform" + }, + "license": "MIT", + "sideEffects": false, + "main": "dist/index.js", + "module": "dist/index.mjs", + "exports": { + ".": { + "require": "./dist/index.js", + "import": "./dist/index.mjs" + }, + "./*": { + "require": "./dist/*.js", + "import": "./dist/*.mjs" + } + }, + "typings": "dist/index.d.ts", + "typescript": { + "definition": "dist/index.d.ts" + }, + "peerDependencies": { + "graphql": "^14.0.0 || ^15.0.0" + }, + "buildOptions": { + "input": "./src/index.ts" + }, + "dependencies": { + "@graphql-tools/webpack-loader": "^6.4.0", + "@jest/transform": "^27.0.2", + "@jest/types": "^27.0.2", + "tslib": "~2.3.0" + }, + "publishConfig": { + "access": "public", + "directory": "dist" + } +} diff --git a/packages/jest-transform/src/index.ts b/packages/jest-transform/src/index.ts new file mode 100644 index 00000000000..0c071c1a648 --- /dev/null +++ b/packages/jest-transform/src/index.ts @@ -0,0 +1,37 @@ +import loader from '@graphql-tools/webpack-loader'; +import { SyncTransformer, TransformOptions } from '@jest/transform'; +import { Config } from '@jest/types'; + +export type GraphQLGlobalOptions = ThisParameterType['query']; + +declare module '@jest/types' { + namespace Config { + interface ConfigGlobals { + graphql: GraphQLGlobalOptions; + } + } +} + +class GraphQLTransformer implements SyncTransformer { + process(input: string, _filePath: Config.Path, jestConfig: TransformOptions): string { + const config = jestConfig.config.globals?.['graphql'] || {}; + // call directly the webpack loader with a mocked context + // as the loader leverages `this.cacheable()` + return loader.call( + { + cacheable() {}, + query: config, + } as any, + input + ); + } +} + +let transformer!: GraphQLTransformer; +function defaultTransformer(): GraphQLTransformer { + return transformer || (transformer = new GraphQLTransformer()); +} + +export function process(...args: any[]): any { + return (defaultTransformer().process as any)(...args); +} diff --git a/packages/links/package.json b/packages/links/package.json index 04b4679a5e6..11324265f35 100644 --- a/packages/links/package.json +++ b/packages/links/package.json @@ -10,8 +10,8 @@ "license": "MIT", "sideEffects": false, "main": "dist/index.js", - "module": "dist/index.mjs", - "exports": { + "module": "dist/index.mjs", + "exports": { ".": { "require": "./dist/index.js", "import": "./dist/index.mjs" @@ -42,16 +42,17 @@ "@types/apollo-upload-client": "14.1.0", "@types/graphql-upload": "8.0.5", "express-graphql": "0.12.0", - "graphql-upload": "12.0.0" + "graphql-upload": "12.0.0", + "express": "4.17.1" }, "dependencies": { "@graphql-tools/delegate": "^7.1.0", "@graphql-tools/utils": "^7.7.0", - "apollo-upload-client": "15.0.0", + "apollo-upload-client": "16.0.0", "cross-fetch": "3.1.4", "form-data": "4.0.0", "is-promise": "4.0.0", - "tslib": "~2.2.0" + "tslib": "~2.3.0" }, "publishConfig": { "access": "public", diff --git a/packages/links/src/index.ts b/packages/links/src/index.ts index 17fdfb74273..2b2a329a4d9 100644 --- a/packages/links/src/index.ts +++ b/packages/links/src/index.ts @@ -1,5 +1,4 @@ export { createServerHttpLink } from './createServerHttpLink'; export { AwaitVariablesLink } from './AwaitVariablesLink'; export { linkToExecutor } from './linkToExecutor'; -export { linkToSubscriber } from './linkToSubscriber'; export { GraphQLUpload } from './GraphQLUpload'; diff --git a/packages/links/src/linkToExecutor.ts b/packages/links/src/linkToExecutor.ts index f885406aa49..1f8e579da6b 100644 --- a/packages/links/src/linkToExecutor.ts +++ b/packages/links/src/linkToExecutor.ts @@ -1,23 +1,26 @@ +import { toPromise } from '@apollo/client/core'; import { ApolloLink, execute } from '@apollo/client/link/core'; import { Observable } from '@apollo/client/utilities'; -import { toPromise } from '@apollo/client/link/utils'; -import { AsyncExecutor, ExecutionParams, ExecutionResult } from '@graphql-tools/utils'; +import { Executor, ExecutionParams, ExecutionResult, observableToAsyncIterable } from '@graphql-tools/utils'; -export const linkToExecutor = (link: ApolloLink): AsyncExecutor => ( - params: ExecutionParams -): Promise> => { - const { document, variables, extensions, context, info } = params; - return toPromise( - execute(link, { +export const linkToExecutor = + (link: ApolloLink): Executor => + async (params: ExecutionParams) => { + const { document, variables, extensions, context, info, operationName } = params; + const observable = execute(link, { query: document, - variables: variables, + variables, context: { graphqlContext: context, graphqlResolveInfo: info, clientAwareness: {}, }, extensions, - }) as Observable> - ); -}; + operationName, + }) as Observable>; + if (info?.operation.operation === 'subscription') { + return observableToAsyncIterable>(observable)[Symbol.asyncIterator](); + } + return toPromise(observable); + }; diff --git a/packages/links/src/linkToSubscriber.ts b/packages/links/src/linkToSubscriber.ts deleted file mode 100644 index 0b66c661b1c..00000000000 --- a/packages/links/src/linkToSubscriber.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { ApolloLink, execute } from '@apollo/client/link/core'; -import { Observable } from '@apollo/client/utilities'; - -import { Subscriber, ExecutionParams, ExecutionResult, observableToAsyncIterable } from '@graphql-tools/utils'; - -export const linkToSubscriber = (link: ApolloLink): Subscriber => async ( - params: ExecutionParams -): Promise | AsyncIterator>> => { - const { document, variables, extensions, context, info } = params; - return observableToAsyncIterable>( - execute(link, { - query: document, - variables, - context: { - graphqlContext: context, - graphqlResolveInfo: info, - clientAwareness: {}, - }, - extensions, - }) as Observable> - )[Symbol.asyncIterator](); -}; diff --git a/packages/links/tests/upload.test.ts b/packages/links/tests/upload.test.ts index f41b9eb424a..1b8b6d76066 100644 --- a/packages/links/tests/upload.test.ts +++ b/packages/links/tests/upload.test.ts @@ -25,7 +25,7 @@ function streamToString(stream: Readable) { function startServer(e: Express): Promise { return new Promise((resolve, reject) => { - e.listen(undefined, 'localhost', function (error: Error) { + e.listen(undefined as any, 'localhost', function (this: any, error: Error) { if (error) { reject(error); } else { diff --git a/packages/load-files/package.json b/packages/load-files/package.json index 31292bd6296..9fa8c8c4497 100644 --- a/packages/load-files/package.json +++ b/packages/load-files/package.json @@ -30,9 +30,9 @@ "graphql": "^14.0.0 || ^15.0.0" }, "dependencies": { - "globby": "11.0.3", + "globby": "11.0.4", "unixify": "1.0.0", - "tslib": "~2.2.0" + "tslib": "~2.3.0" }, "publishConfig": { "access": "public", diff --git a/packages/load-files/src/index.ts b/packages/load-files/src/index.ts index 51086ee71bc..d6ea2da95e0 100644 --- a/packages/load-files/src/index.ts +++ b/packages/load-files/src/index.ts @@ -8,29 +8,31 @@ const { readFile, stat } = fsPromises; const DEFAULT_IGNORED_EXTENSIONS = ['spec', 'test', 'd', 'map']; const DEFAULT_EXTENSIONS = ['gql', 'graphql', 'graphqls', 'ts', 'js']; const DEFAULT_EXPORT_NAMES = ['schema', 'typeDef', 'typeDefs', 'resolver', 'resolvers']; -const DEFAULT_EXTRACT_EXPORTS_FACTORY = (exportNames: string[]) => (fileExport: any): any | null => { - if (!fileExport) { - return null; - } +const DEFAULT_EXTRACT_EXPORTS_FACTORY = + (exportNames: string[]) => + (fileExport: any): any | null => { + if (!fileExport) { + return null; + } - if (fileExport.default) { - for (const exportName of exportNames) { - if (fileExport.default[exportName]) { - return fileExport.default[exportName]; + if (fileExport.default) { + for (const exportName of exportNames) { + if (fileExport.default[exportName]) { + return fileExport.default[exportName]; + } } - } - return fileExport.default; - } + return fileExport.default; + } - for (const exportName of exportNames) { - if (fileExport[exportName]) { - return fileExport[exportName]; + for (const exportName of exportNames) { + if (fileExport[exportName]) { + return fileExport[exportName]; + } } - } - return fileExport; -}; + return fileExport; + }; function asArray(obj: T | T[]): T[] { if (obj instanceof Array) { @@ -68,9 +70,9 @@ function formatExtension(extension: string): string { function buildGlob( basePath: string, - extensions: string[], + extensions: string[] = [], ignoredExtensions: string[] = [], - recursive: boolean + recursive?: boolean ): string { const ignored = ignoredExtensions.length > 0 ? `!(${ignoredExtensions.map(e => `*${formatExtension(e)}`).join('|')})` : '*'; @@ -135,7 +137,7 @@ export function loadFilesSync( options.globOptions ); - const extractExports = execOptions.extractExports || DEFAULT_EXTRACT_EXPORTS_FACTORY(execOptions.exportNames); + const extractExports = execOptions.extractExports || DEFAULT_EXTRACT_EXPORTS_FACTORY(execOptions.exportNames ?? []); const requireMethod = execOptions.requireMethod || require; return relevantPaths @@ -220,7 +222,7 @@ export async function loadFiles( options.globOptions ); - const extractExports = execOptions.extractExports || DEFAULT_EXTRACT_EXPORTS_FACTORY(execOptions.exportNames); + const extractExports = execOptions.extractExports || DEFAULT_EXTRACT_EXPORTS_FACTORY(execOptions.exportNames ?? []); const defaultRequireMethod = (path: string) => import(path).catch(async () => require(path)); const requireMethod = execOptions.requireMethod || defaultRequireMethod; diff --git a/packages/load-files/tests/file-scanner.spec.ts b/packages/load-files/tests/file-scanner.spec.ts index 4d7616709ef..da1e1454c60 100644 --- a/packages/load-files/tests/file-scanner.spec.ts +++ b/packages/load-files/tests/file-scanner.spec.ts @@ -19,7 +19,7 @@ function testSchemaDir({ path, expected, note, extensions, ignoreIndex }: TestDi }; }); - syncAndAsync.forEach(([type, loadFiles]) => { + for (const [type, loadFiles] of syncAndAsync) { describe(type, () => { it(`should return the correct schema results for path: ${path} (${note})`, async () => { const result = await loadFiles(path, options); @@ -33,7 +33,7 @@ function testSchemaDir({ path, expected, note, extensions, ignoreIndex }: TestDi })).toEqual(expected.map(stripWhitespaces)); }); }); - }) + } } @@ -55,7 +55,7 @@ function testResolversDir({ path, expected, note, extensions, compareValue, igno }; }); - syncAndAsync.forEach(([type, loadFiles]) => { + for (const [type, loadFiles] of syncAndAsync) { describe(type, () => { it(`should return the correct resolvers results for path: ${path} (${note})`, async () => { const result = await loadFiles(path, options); @@ -67,7 +67,7 @@ function testResolversDir({ path, expected, note, extensions, compareValue, igno } }); }) - }); + } } function stripWhitespaces(str: any): string { @@ -219,7 +219,7 @@ describe('file scanner', function() { note: 'extensions and ignored extensions works with a trailing dot', }); }); - syncAndAsync.forEach(([type, loadFiles]) => { + for (const [type, loadFiles] of syncAndAsync) { it(`${type}: should process custom extractExports properly`, async () => { const customQueryTypeName = 'root_query'; const customExtractExports = (fileExport: any) => { @@ -254,7 +254,7 @@ describe('file scanner', function() { expect(typeof resolvers.Query.foo).toBe('function'); expect(resolvers.Query.foo()).toBe('FOO'); }); - }) + } }); interface TestDirOptions { diff --git a/packages/load-files/tests/test-assets/11/1.spec.ts b/packages/load-files/tests/test-assets/11/1.spec.ts index d3cbba3204d..dcbb9a5413e 100644 --- a/packages/load-files/tests/test-assets/11/1.spec.ts +++ b/packages/load-files/tests/test-assets/11/1.spec.ts @@ -1,3 +1,3 @@ -function foo() {} +function bar(..._args: any[]) {} -foo('dummy', () => {}); +bar('dummy', () => {}); diff --git a/packages/load-files/tests/test-assets/11/2.test.ts b/packages/load-files/tests/test-assets/11/2.test.ts index d3cbba3204d..d23eadd8239 100644 --- a/packages/load-files/tests/test-assets/11/2.test.ts +++ b/packages/load-files/tests/test-assets/11/2.test.ts @@ -1,3 +1,3 @@ -function foo() {} +function foo(..._args: any[]) {} foo('dummy', () => {}); diff --git a/packages/load/package.json b/packages/load/package.json index 7814b65af1c..e1dc1f4bd99 100644 --- a/packages/load/package.json +++ b/packages/load/package.json @@ -32,7 +32,7 @@ "devDependencies": { "@types/is-glob": "4.0.1", "@types/valid-url": "1.0.3", - "graphql-tag": "2.12.4", + "graphql-tag": "2.12.5", "graphql-type-json": "0.3.2" }, "dependencies": { @@ -41,7 +41,7 @@ "import-from": "4.0.0", "is-glob": "4.0.1", "p-limit": "3.1.0", - "tslib": "~2.2.0", + "tslib": "~2.3.0", "valid-url": "1.0.9" }, "publishConfig": { diff --git a/packages/load/src/documents.ts b/packages/load/src/documents.ts index d30e508d939..46b9f88e402 100644 --- a/packages/load/src/documents.ts +++ b/packages/load/src/documents.ts @@ -2,16 +2,18 @@ import { Source } from '@graphql-tools/utils'; import { Kind } from 'graphql'; import { LoadTypedefsOptions, loadTypedefs, loadTypedefsSync, UnnormalizedTypeDefPointer } from './load-typedefs'; +type KindList = Array; + /** * Kinds of AST nodes that are included in executable documents */ -export const OPERATION_KINDS = [Kind.OPERATION_DEFINITION, Kind.FRAGMENT_DEFINITION]; +export const OPERATION_KINDS: KindList = [Kind.OPERATION_DEFINITION, Kind.FRAGMENT_DEFINITION]; /** * Kinds of AST nodes that are included in type system definition documents */ export const NON_OPERATION_KINDS = Object.keys(Kind) - .reduce((prev, v) => [...prev, Kind[v]], []) + .reduce((prev, v) => [...prev, Kind[v]], [] as KindList) .filter(v => !OPERATION_KINDS.includes(v)); /** diff --git a/packages/load/src/filter-document-kind.ts b/packages/load/src/filter-document-kind.ts index 21fd1f715a3..aa49a3e155f 100644 --- a/packages/load/src/filter-document-kind.ts +++ b/packages/load/src/filter-document-kind.ts @@ -1,10 +1,10 @@ -import { debugLog } from '@graphql-tools/utils'; import { DocumentNode, DefinitionNode, Kind } from 'graphql'; +import { env } from 'process'; /** * @internal */ -export const filterKind = (content: DocumentNode, filterKinds: null | string[]) => { +export const filterKind = (content: DocumentNode | undefined, filterKinds: null | string[]) => { if (content && content.definitions && content.definitions.length && filterKinds && filterKinds.length > 0) { const invalidDefinitions: DefinitionNode[] = []; const validDefinitions: DefinitionNode[] = []; @@ -18,7 +18,9 @@ export const filterKind = (content: DocumentNode, filterKinds: null | string[]) if (invalidDefinitions.length > 0) { invalidDefinitions.forEach(d => { - debugLog(`Filtered document of kind ${d.kind} due to filter policy (${filterKinds.join(', ')})`); + if (env['DEBUG']) { + console.error(`Filtered document of kind ${d.kind} due to filter policy (${filterKinds.join(', ')})`); + } }); } diff --git a/packages/load/src/load-typedefs.ts b/packages/load/src/load-typedefs.ts index 255e86e179a..defb838b0af 100644 --- a/packages/load/src/load-typedefs.ts +++ b/packages/load/src/load-typedefs.ts @@ -86,7 +86,7 @@ export function loadTypedefsSync>( const validSources: Source[] = []; - sources.forEach(partialSource => { + for (const partialSource of sources) { parseSource({ partialSource, options, @@ -96,7 +96,7 @@ export function loadTypedefsSync>( validSources.push(source); }, }); - }); + } return prepareResult({ options, pointerOptionMap, validSources }); } diff --git a/packages/load/src/load-typedefs/collect-sources.ts b/packages/load/src/load-typedefs/collect-sources.ts index ebdba0b69b8..1bdd8e02d6e 100644 --- a/packages/load/src/load-typedefs/collect-sources.ts +++ b/packages/load/src/load-typedefs/collect-sources.ts @@ -6,6 +6,7 @@ import { getDocumentNodeFromSchema, Loader, ResolverGlobs, + isSome, } from '@graphql-tools/utils'; import { isSchema, Kind } from 'graphql'; import isGlob from 'is-glob'; @@ -53,7 +54,7 @@ export async function collectSources({ options, addSource, addGlob, - queue: queue.add, + queue: queue.add as AddToQueue, }); } @@ -67,7 +68,7 @@ export async function collectSources({ globOptions, pointerOptionMap, addSource, - queue: queue.add, + queue: queue.add as AddToQueue, }); } @@ -154,7 +155,7 @@ function createHelpers({ }) => { sources.push(source); - if (!noCache) { + if (!noCache && options.cache) { options.cache[pointer] = source; } }; @@ -195,10 +196,12 @@ async function addGlobsToLoaders({ if (!loader) { throw new Error(`unable to find loader for glob "${glob}"`); } - if (!loadersForGlobs.has(loader)) { - loadersForGlobs.set(loader, { globs: [], ignores: [] }); + let resolverGlobs = loadersForGlobs.get(loader); + if (!isSome(resolverGlobs)) { + resolverGlobs = { globs: [], ignores: [] }; + loadersForGlobs.set(loader, resolverGlobs); } - loadersForGlobs.get(loader)[type].push(glob); + resolverGlobs[type].push(glob); } } @@ -216,7 +219,11 @@ function addGlobsToLoadersSync({ for (const glob of globs) { let loader; for (const candidateLoader of options.loaders) { - if (candidateLoader.resolveGlobs && candidateLoader.canLoadSync(glob, options)) { + if ( + isSome(candidateLoader.resolveGlobsSync) && + isSome(candidateLoader.canLoadSync) && + candidateLoader.canLoadSync(glob, options) + ) { loader = candidateLoader; break; } @@ -224,10 +231,12 @@ function addGlobsToLoadersSync({ if (!loader) { throw new Error(`unable to find loader for glob "${glob}"`); } - if (!loadersForGlobs.has(loader)) { - loadersForGlobs.set(loader, { globs: [], ignores: [] }); + let resolverGlobs = loadersForGlobs.get(loader); + if (!isSome(resolverGlobs)) { + resolverGlobs = { globs: [], ignores: [] }; + loadersForGlobs.set(loader, resolverGlobs); } - loadersForGlobs.get(loader)[type].push(glob); + resolverGlobs[type].push(glob); } } @@ -237,12 +246,19 @@ async function collectPathsFromGlobs(globs: string[], options: LoadTypedefsOptio const loadersForGlobs: Map = new Map(); await addGlobsToLoaders({ options, loadersForGlobs, globs, type: 'globs' }); - await addGlobsToLoaders({ options, loadersForGlobs, globs: asArray(options.ignore), type: 'ignores' }); + await addGlobsToLoaders({ + options, + loadersForGlobs, + globs: isSome(options.ignore) ? asArray(options.ignore) : [], + type: 'ignores', + }); for await (const [loader, globsAndIgnores] of loadersForGlobs.entries()) { - const resolvedPaths = await loader.resolveGlobs(globsAndIgnores, options); - if (resolvedPaths) { - paths.push(...resolvedPaths); + if (isSome(loader.resolveGlobs)) { + const resolvedPaths = await loader.resolveGlobs(globsAndIgnores, options); + if (resolvedPaths) { + paths.push(...resolvedPaths); + } } } @@ -255,12 +271,19 @@ function collectPathsFromGlobsSync(globs: string[], options: LoadTypedefsOptions const loadersForGlobs: Map = new Map(); addGlobsToLoadersSync({ options, loadersForGlobs, globs, type: 'globs' }); - addGlobsToLoadersSync({ options, loadersForGlobs, globs: asArray(options.ignore), type: 'ignores' }); + addGlobsToLoadersSync({ + options, + loadersForGlobs, + globs: isSome(options.ignore) ? asArray(options.ignore) : [], + type: 'ignores', + }); for (const [loader, globsAndIgnores] of loadersForGlobs.entries()) { - const resolvedPaths = loader.resolveGlobsSync(globsAndIgnores, options); - if (resolvedPaths) { - paths.push(...resolvedPaths); + if (isSome(loader.resolveGlobsSync)) { + const resolvedPaths = loader.resolveGlobsSync(globsAndIgnores, options); + if (resolvedPaths) { + paths.push(...resolvedPaths); + } } } @@ -421,6 +444,8 @@ function collectCustomLoader( ) { if (pointerOptions.loader) { return queue(async () => { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore TODO options.cwd is possibly undefined, but it seems like no test covers this path const loader = await useCustomLoader(pointerOptions.loader, options.cwd); const result = await loader(pointer, { ...options, ...pointerOptions }, pointerOptionMap); @@ -441,6 +466,8 @@ function collectCustomLoaderSync( ) { if (pointerOptions.loader) { return queue(() => { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore TODO options.cwd is possibly undefined, but it seems like no test covers this path const loader = useCustomLoaderSync(pointerOptions.loader, options.cwd); const result = loader(pointer, { ...options, ...pointerOptions }, pointerOptionMap); diff --git a/packages/load/src/load-typedefs/load-file.ts b/packages/load/src/load-typedefs/load-file.ts index 9bca990a6d5..7f6acf067e8 100644 --- a/packages/load/src/load-typedefs/load-file.ts +++ b/packages/load/src/load-typedefs/load-file.ts @@ -1,7 +1,8 @@ -import { Source, debugLog } from '@graphql-tools/utils'; +import { Source, Maybe } from '@graphql-tools/utils'; +import { env } from 'process'; import { LoadTypedefsOptions } from '../load-typedefs'; -export async function loadFile(pointer: string, options: LoadTypedefsOptions): Promise { +export async function loadFile(pointer: string, options: LoadTypedefsOptions): Promise> { const cached = useCache({ pointer, options }); if (cached) { @@ -17,7 +18,9 @@ export async function loadFile(pointer: string, options: LoadTypedefsOptions): P return loadedValue; } } catch (error) { - debugLog(`Failed to find any GraphQL type definitions in: ${pointer} - ${error.message}`); + if (env['DEBUG']) { + console.error(`Failed to find any GraphQL type definitions in: ${pointer} - ${error.message}`); + } throw error; } } @@ -25,7 +28,7 @@ export async function loadFile(pointer: string, options: LoadTypedefsOptions): P return undefined; } -export function loadFileSync(pointer: string, options: LoadTypedefsOptions): Source { +export function loadFileSync(pointer: string, options: LoadTypedefsOptions): Maybe { const cached = useCache({ pointer, options }); if (cached) { @@ -37,10 +40,13 @@ export function loadFileSync(pointer: string, options: LoadTypedefsOptions): Sou const canLoad = loader.canLoadSync && loader.loadSync && loader.canLoadSync(pointer, options); if (canLoad) { - return loader.loadSync(pointer, options); + // We check for the existence so it is okay to force non null + return loader.loadSync!(pointer, options); } } catch (error) { - debugLog(`Failed to find any GraphQL type definitions in: ${pointer} - ${error.message}`); + if (env['DEBUG']) { + console.error(`Failed to find any GraphQL type definitions in: ${pointer} - ${error.message}`); + } throw error; } } diff --git a/packages/load/src/load-typedefs/parse.ts b/packages/load/src/load-typedefs/parse.ts index 3bbf431a0c7..87ae377be06 100644 --- a/packages/load/src/load-typedefs/parse.ts +++ b/packages/load/src/load-typedefs/parse.ts @@ -9,7 +9,7 @@ type Input = { }; type AddValidSource = (source: Source) => void; type ParseOptions = { - partialSource: Partial; + partialSource: Source; options: any; globOptions: any; pointerOptionMap: any; @@ -44,16 +44,22 @@ function prepareInput({ globOptions, pointerOptionMap, }: { - source: Partial; + source: Source; options: any; globOptions: any; pointerOptionMap: any; }): Input { - const specificOptions = { + let specificOptions = { ...options, - ...(source.location in pointerOptionMap ? globOptions : pointerOptionMap[source.location]), }; + if (source.location) { + specificOptions = { + ...specificOptions, + ...(source.location in pointerOptionMap ? globOptions : pointerOptionMap[source.location]), + }; + } + return { source: { ...source }, options: specificOptions }; } @@ -77,14 +83,14 @@ function useKindsFilter(input: Input) { } function useComments(input: Input) { - if (!input.source.rawSDL) { + if (!input.source.rawSDL && input.source.document) { input.source.rawSDL = printWithComments(input.source.document); resetComments(); } } function collectValidSources(input: Input, addValidSource: AddValidSource) { - if (input.source.document.definitions && input.source.document.definitions.length > 0) { + if (input.source.document?.definitions && input.source.document.definitions.length > 0) { addValidSource(input.source); } } diff --git a/packages/load/src/schema.ts b/packages/load/src/schema.ts index cdc9d61f5eb..f18a3ea340b 100644 --- a/packages/load/src/schema.ts +++ b/packages/load/src/schema.ts @@ -76,11 +76,17 @@ export function loadSchemaSync( } function includeSources(schema: GraphQLSchema, sources: Source[]) { + const finalSources: Array = []; + for (const source of sources) { + if (source.rawSDL) { + finalSources.push(new GraphQLSource(source.rawSDL, source.location)); + } else if (source.document) { + finalSources.push(new GraphQLSource(print(source.document), source.location)); + } + } schema.extensions = { ...schema.extensions, - sources: sources - .filter(source => source.rawSDL || source.document) - .map(source => new GraphQLSource(source.rawSDL || print(source.document), source.location)), + sources: finalSources, }; } @@ -88,13 +94,13 @@ function collectSchemasAndTypeDefs(sources: Source[]) { const schemas: GraphQLSchema[] = []; const typeDefs: DocumentNode[] = []; - sources.forEach(source => { + for (const source of sources) { if (source.schema) { schemas.push(source.schema); - } else { + } else if (source.document) { typeDefs.push(source.document); } - }); + } return { schemas, diff --git a/packages/load/src/utils/queue.ts b/packages/load/src/utils/queue.ts index 89188845b71..1a396be83e7 100644 --- a/packages/load/src/utils/queue.ts +++ b/packages/load/src/utils/queue.ts @@ -22,7 +22,9 @@ export function useSyncQueue() { queue.push(fn); }, runAll() { - queue.forEach(fn => fn()); + for (const fn of queue) { + fn(); + } }, }; } diff --git a/packages/load/tests/loaders/documents/documents-from-glob.spec.ts b/packages/load/tests/loaders/documents/documents-from-glob.spec.ts index 39424514293..f7fe2ce3532 100644 --- a/packages/load/tests/loaders/documents/documents-from-glob.spec.ts +++ b/packages/load/tests/loaders/documents/documents-from-glob.spec.ts @@ -34,9 +34,10 @@ describe('documentsFromGlob', () => { const result = await load(glob, { loaders: [new CodeFileLoader()] }); - const operations = separateOperations(result[0].document); + const { document } = result[0]; + const operations = document && separateOperations(document); - expect(Object.keys(operations)).toHaveLength(2); + expect(operations && Object.keys(operations)).toHaveLength(2); }); test(`Should load GraphQL documents that match custom settings`, async () => { @@ -57,9 +58,10 @@ describe('documentsFromGlob', () => { ] }); - const operations = separateOperations(result[0].document); + const { document } = result[0]; + const operations = document && separateOperations(document); - expect(Object.keys(operations)).toHaveLength(1); + expect(operations && Object.keys(operations)).toHaveLength(1); }); test(`Should throw on syntax errors`, async () => { diff --git a/packages/load/tests/loaders/schema/integration.spec.ts b/packages/load/tests/loaders/schema/integration.spec.ts index aedfd07a2c8..b913ffae1c6 100644 --- a/packages/load/tests/loaders/schema/integration.spec.ts +++ b/packages/load/tests/loaders/schema/integration.spec.ts @@ -33,8 +33,8 @@ describe('loadSchema', () => { const schema = await load(schemaPath, { loaders: [new CodeFileLoader()] }); - expect(schema.getTypeMap().User).toBeDefined(); - expect(schema.getTypeMap().Query).toBeDefined(); + expect(schema.getTypeMap()['User']).toBeDefined(); + expect(schema.getTypeMap()['Query']).toBeDefined(); }); test('should work with graphql single file', async () => { @@ -43,7 +43,7 @@ describe('loadSchema', () => { loaders: [new GraphQLFileLoader()] }); - expect(schema.getTypeMap().User).toBeDefined(); + expect(schema.getTypeMap()['User']).toBeDefined(); }); test('import and merge Query types from few different files', async () => { diff --git a/packages/load/tests/loaders/schema/schema-from-export.spec.ts b/packages/load/tests/loaders/schema/schema-from-export.spec.ts index 80ca06e9bbf..2e8cce1aeaf 100644 --- a/packages/load/tests/loaders/schema/schema-from-export.spec.ts +++ b/packages/load/tests/loaders/schema/schema-from-export.spec.ts @@ -7,6 +7,13 @@ const monorepo = useMonorepo({ dirname: __dirname }); +function assertNonMaybe(input: T): asserts input is Exclude{ + if (input == null) { + throw new Error("Value should be neither null nor undefined.") + } +} + + describe('Schema From Export', () => { monorepo.correctCWD(); @@ -26,7 +33,9 @@ describe('Schema From Export', () => { loaders: [new CodeFileLoader()] }); expect(isSchema(result)).toBeTruthy(); - expect(result.getQueryType().getFields().hello).toBeDefined(); + const QueryType = result.getQueryType() + assertNonMaybe(QueryType) + expect(QueryType.getFields()['hello']).toBeDefined(); }); test('should load the schema correctly from variable export', async () => { @@ -64,7 +73,9 @@ describe('Schema From Export', () => { const schema = await load(schemaPath, { loaders: [new CodeFileLoader()] }); - const queryFields = Object.keys(schema.getQueryType().getFields()); + const QueryType = schema.getQueryType() + assertNonMaybe(QueryType) + const queryFields = Object.keys(QueryType.getFields()); expect(queryFields).toContain('foo'); expect(queryFields).toContain('bar'); @@ -75,7 +86,9 @@ describe('Schema From Export', () => { const schema = await load(schemaPath, { loaders: [new CodeFileLoader()] }); - const queryFields = Object.keys(schema.getQueryType().getFields()); + const QueryType = schema.getQueryType() + assertNonMaybe(QueryType) + const queryFields = Object.keys(QueryType.getFields()); expect(queryFields).toContain('foo'); expect(queryFields).toContain('bar'); diff --git a/packages/load/tests/loaders/schema/schema-from-json.spec.ts b/packages/load/tests/loaders/schema/schema-from-json.spec.ts index 6785c6576c3..55ecbc63278 100644 --- a/packages/load/tests/loaders/schema/schema-from-json.spec.ts +++ b/packages/load/tests/loaders/schema/schema-from-json.spec.ts @@ -7,6 +7,12 @@ const monorepo = useMonorepo({ dirname: __dirname, }); +function assertNonMaybe(input: T): asserts input is Exclude{ + if (input == null) { + throw new Error("Value should be neither null nor undefined.") + } +} + describe('Schema From Export', () => { monorepo.correctCWD(); @@ -29,6 +35,7 @@ describe('Schema From Export', () => { for (const typeName in schema.getTypeMap()) { if (!typeName.startsWith('__')) { const type = schema.getType(typeName); + assertNonMaybe(type) const introspectionType = introspectionSchema.types.find((t: { name: string; }) => t.name === typeName); if (type.description || introspectionType.description) { expect(type.description).toBe(introspectionType.description); @@ -39,6 +46,7 @@ describe('Schema From Export', () => { const field = fieldMap[fieldName]; const introspectionField = introspectionType.fields.find((f: { name: string; }) => f.name === fieldName); if (field.description || introspectionField.description) { + assertNonMaybe(field.description) expect(field.description.trim()).toBe(introspectionField.description.trim()); } } diff --git a/packages/load/tests/loaders/schema/schema-from-typedefs.spec.ts b/packages/load/tests/loaders/schema/schema-from-typedefs.spec.ts index 54a5ce7227f..0199d4178a3 100644 --- a/packages/load/tests/loaders/schema/schema-from-typedefs.spec.ts +++ b/packages/load/tests/loaders/schema/schema-from-typedefs.spec.ts @@ -7,6 +7,12 @@ const monorepo = useMonorepo({ dirname: __dirname }); +function assertNonMaybe(input: T): asserts input is Exclude{ + if (input == null) { + throw new Error("Value should be neither null nor undefined.") + } +} + describe('schema from typedefs', () => { monorepo.correctCWD(); @@ -20,8 +26,8 @@ describe('schema from typedefs', () => { loaders: [new GraphQLFileLoader()] }); - expect(schema.getTypeMap().User).toBeDefined(); - expect(schema.getTypeMap().Query).toBeDefined(); + expect(schema.getTypeMap()['User']).toBeDefined(); + expect(schema.getTypeMap()['Query']).toBeDefined(); }); it('should ignore empty files when using glob expressions', async () => { @@ -72,8 +78,8 @@ describe('schema from typedefs', () => { loaders: [new CodeFileLoader()] }); - expect(schema.getTypeMap().User).toBeDefined(); - expect(schema.getTypeMap().Query).toBeDefined(); + expect(schema.getTypeMap()['User']).toBeDefined(); + expect(schema.getTypeMap()['Query']).toBeDefined(); }); it('should work without globs correctly', async () => { @@ -82,8 +88,8 @@ describe('schema from typedefs', () => { loaders: [new CodeFileLoader()] }); - expect(schema.getTypeMap().User).toBeDefined(); - expect(schema.getTypeMap().Query).toBeDefined(); + expect(schema.getTypeMap()['User']).toBeDefined(); + expect(schema.getTypeMap()['Query']).toBeDefined(); }); it('should work with import notations', async () => { @@ -92,8 +98,8 @@ describe('schema from typedefs', () => { loaders: [new GraphQLFileLoader()] }); - expect(schema.getTypeMap().User).toBeDefined(); - expect(schema.getTypeMap().Query).toBeDefined(); + expect(schema.getTypeMap()['User']).toBeDefined(); + expect(schema.getTypeMap()['Query']).toBeDefined(); }); it('should work with extensions (static graphql file)', async () => { @@ -101,7 +107,9 @@ describe('schema from typedefs', () => { const schema = await load(schemaPath, { loaders: [new GraphQLFileLoader()] }); - const queryFields = Object.keys(schema.getQueryType().getFields()); + const QueryType = schema.getQueryType() + assertNonMaybe(QueryType) + const queryFields = Object.keys(QueryType.getFields()); expect(queryFields).toContain('foo'); expect(queryFields).toContain('bar'); @@ -112,7 +120,9 @@ describe('schema from typedefs', () => { const schema = await load(schemaPath, { loaders: [new GraphQLFileLoader()] }); - const queryFields = Object.keys(schema.getQueryType().getFields()); + const QueryType = schema.getQueryType() + assertNonMaybe(QueryType) + const queryFields = Object.keys(QueryType.getFields()); expect(queryFields).toContain('foo'); expect(queryFields).toContain('bar'); @@ -124,7 +134,9 @@ describe('schema from typedefs', () => { const schema = await load(schemaPath, { loaders: [new CodeFileLoader()] }); - const queryFields = Object.keys(schema.getQueryType().getFields()); + const QueryType = schema.getQueryType() + assertNonMaybe(QueryType) + const queryFields = Object.keys(QueryType.getFields()); expect(queryFields).toContain('foo'); expect(queryFields).toContain('bar'); @@ -136,18 +148,18 @@ describe('schema from typedefs', () => { loaders: [new GraphQLFileLoader()], includeSources: true, }); - - expect(schemaWithSources.extensions.sources).toBeDefined(); - expect(schemaWithSources.extensions.sources).toHaveLength(1); - expect(schemaWithSources.extensions.sources[0]).toMatchObject(expect.objectContaining({ - name: glob + assertNonMaybe(schemaWithSources.extensions) + expect(schemaWithSources.extensions['sources']).toBeDefined(); + expect(schemaWithSources.extensions['sources']).toHaveLength(1); + expect(schemaWithSources.extensions['sources'][0]).toMatchObject(expect.objectContaining({ + name: glob.replace('.', process.cwd()) })) const schemaWithoutSources = await load(glob, { loaders: [new GraphQLFileLoader()] }); - - expect(schemaWithoutSources.extensions.sources).not.toBeDefined(); + assertNonMaybe(schemaWithoutSources.extensions) + expect(schemaWithoutSources.extensions['sources']).not.toBeDefined(); }); }) }); diff --git a/packages/loaders/apollo-engine/package.json b/packages/loaders/apollo-engine/package.json index ee4231d6c0f..3382d69b11d 100644 --- a/packages/loaders/apollo-engine/package.json +++ b/packages/loaders/apollo-engine/package.json @@ -30,10 +30,9 @@ "graphql": "^14.0.0 || ^15.0.0" }, "dependencies": { - "@ardatan/aggregate-error": "0.0.6", - "@graphql-tools/utils": "^7.0.0", + "@graphql-tools/utils": "^7.10.0", "cross-fetch": "3.1.4", - "tslib": "~2.2.0", + "tslib": "~2.3.0", "sync-fetch": "0.3.0" }, "publishConfig": { diff --git a/packages/loaders/apollo-engine/src/index.ts b/packages/loaders/apollo-engine/src/index.ts index 3015ce125b1..2c1c4b47ba5 100644 --- a/packages/loaders/apollo-engine/src/index.ts +++ b/packages/loaders/apollo-engine/src/index.ts @@ -1,6 +1,5 @@ -import { SchemaLoader, Source, SingleFileOptions, parseGraphQLSDL } from '@graphql-tools/utils'; +import { SchemaLoader, Source, SingleFileOptions, parseGraphQLSDL, AggregateError } from '@graphql-tools/utils'; import { fetch } from 'cross-fetch'; -import AggregateError from '@ardatan/aggregate-error'; import syncFetch from 'sync-fetch'; /** @@ -66,7 +65,7 @@ export class ApolloEngineLoader implements SchemaLoader { const { data, errors } = await response.json(); if (errors) { - throw new AggregateError(errors); + throw new AggregateError(errors, 'Introspection from Apollo Engine failed'); } return parseGraphQLSDL(pointer, data.service.schema.document, options); @@ -79,7 +78,7 @@ export class ApolloEngineLoader implements SchemaLoader { const { data, errors } = response.json(); if (errors) { - throw new AggregateError(errors); + throw new AggregateError(errors, 'Introspection from Apollo Engine failed'); } return parseGraphQLSDL(pointer, data.service.schema.document, options); diff --git a/packages/loaders/code-file/package.json b/packages/loaders/code-file/package.json index aed02b52d4a..8cb1f297bd4 100644 --- a/packages/loaders/code-file/package.json +++ b/packages/loaders/code-file/package.json @@ -37,7 +37,7 @@ "@graphql-tools/graphql-tag-pluck": "^6.5.1", "globby": "^11.0.3", "is-glob": "^4.0.1", - "tslib": "~2.2.0", + "tslib": "~2.3.0", "unixify": "^1.0.0" }, "publishConfig": { diff --git a/packages/loaders/code-file/src/index.ts b/packages/loaders/code-file/src/index.ts index 9ac6f0c9845..1299c2c61f7 100644 --- a/packages/loaders/code-file/src/index.ts +++ b/packages/loaders/code-file/src/index.ts @@ -1,10 +1,9 @@ import type { GlobbyOptions } from 'globby'; -import { isSchema, GraphQLSchema, DocumentNode } from 'graphql'; +import { isSchema, GraphQLSchema, DocumentNode, concatAST, parse } from 'graphql'; import { SchemaPointerSingle, DocumentPointerSingle, - debugLog, SingleFileOptions, Source, UniversalLoader, @@ -24,8 +23,9 @@ import isGlob from 'is-glob'; import unixify from 'unixify'; import { tryToLoadFromExport, tryToLoadFromExportSync } from './load-from-module'; import { isAbsolute, resolve } from 'path'; -import { cwd } from 'process'; +import { cwd, env } from 'process'; import { readFileSync, promises as fsPromises, existsSync } from 'fs'; +import { createRequire } from 'module'; const { readFile, access } = fsPromises; @@ -118,7 +118,10 @@ export class CodeFileLoader implements UniversalLoader { ); } - async load(pointer: SchemaPointerSingle | DocumentPointerSingle, options: CodeFileLoaderOptions): Promise { + async load( + pointer: SchemaPointerSingle | DocumentPointerSingle, + options: CodeFileLoaderOptions + ): Promise { const normalizedFilePath = ensureAbsolutePath(pointer, options); const errors: Error[] = []; @@ -126,13 +129,18 @@ export class CodeFileLoader implements UniversalLoader { if (!options.noPluck) { try { const content = await readFile(normalizedFilePath, { encoding: 'utf-8' }); - const sdl = await gqlPluckFromCodeString(normalizedFilePath, content, options.pluckConfig); + const sources = await gqlPluckFromCodeString(normalizedFilePath, content, options.pluckConfig); - if (sdl) { - return parseGraphQLSDL(pointer, sdl, options); + if (sources.length) { + return { + document: concatAST(sources.map(source => parse(source, options))), + location: pointer, + }; } } catch (e) { - debugLog(`Failed to load schema from code file "${normalizedFilePath}": ${e.message}`); + if (env['DEBUG']) { + console.error(`Failed to load schema from code file "${normalizedFilePath}": ${e.message}`); + } errors.push(e); } } @@ -161,7 +169,7 @@ export class CodeFileLoader implements UniversalLoader { return null; } - loadSync(pointer: SchemaPointerSingle | DocumentPointerSingle, options: CodeFileLoaderOptions): Source { + loadSync(pointer: SchemaPointerSingle | DocumentPointerSingle, options: CodeFileLoaderOptions): Source | null { const normalizedFilePath = ensureAbsolutePath(pointer, options); const errors: Error[] = []; @@ -169,13 +177,18 @@ export class CodeFileLoader implements UniversalLoader { if (!options.noPluck) { try { const content = readFileSync(normalizedFilePath, { encoding: 'utf-8' }); - const sdl = gqlPluckFromCodeStringSync(normalizedFilePath, content, options.pluckConfig); + const sources = gqlPluckFromCodeStringSync(normalizedFilePath, content, options.pluckConfig); - if (sdl) { - return parseGraphQLSDL(pointer, sdl, options); + if (sources.length) { + return { + document: concatAST(sources.map(source => parse(source, options))), + location: pointer, + }; } } catch (e) { - debugLog(`Failed to load schema from code file "${normalizedFilePath}": ${e.message}`); + if (env['DEBUG']) { + console.error(`Failed to load schema from code file "${normalizedFilePath}": ${e.message}`); + } errors.push(e); } } @@ -183,7 +196,10 @@ export class CodeFileLoader implements UniversalLoader { if (!options.noRequire) { try { if (options && options.require) { - asArray(options.require).forEach(m => require(m)); + const cwdRequire = createRequire(options.cwd || cwd()); + for (const m of asArray(options.require)) { + cwdRequire(m); + } } const loaded = tryToLoadFromExportSync(normalizedFilePath); @@ -207,7 +223,7 @@ export class CodeFileLoader implements UniversalLoader { function resolveSource( pointer: string, - value: GraphQLSchema | DocumentNode | string, + value: GraphQLSchema | DocumentNode | string | null, options: CodeFileLoaderOptions ): Source | null { if (typeof value === 'string') { diff --git a/packages/loaders/code-file/src/load-from-module.ts b/packages/loaders/code-file/src/load-from-module.ts index b5707f6cae3..b38ccca00e1 100644 --- a/packages/loaders/code-file/src/load-from-module.ts +++ b/packages/loaders/code-file/src/load-from-module.ts @@ -4,7 +4,7 @@ import { pickExportFromModule, pickExportFromModuleSync } from './exports'; /** * @internal */ -export async function tryToLoadFromExport(rawFilePath: string): Promise { +export async function tryToLoadFromExport(rawFilePath: string): Promise { try { const filepath = ensureFilepath(rawFilePath); @@ -19,7 +19,7 @@ export async function tryToLoadFromExport(rawFilePath: string): Promise { noRequire: true, cwd: __dirname }); - const doc = loaded.document ? loaded.document : parse(loaded.rawSDL); + const doc = loaded?.document ? loaded?.document : parse(loaded?.rawSDL!); expect(doc).toBeFalsy(); } catch (e) { @@ -24,9 +25,9 @@ describe('loadFromCodeFile', () => { noRequire: true, cwd: __dirname }); - const doc = loaded.document ? loaded.document : parse(loaded.rawSDL); + const doc = loaded?.document ? loaded?.document : parse(loaded?.rawSDL!); - expect(doc.kind).toEqual('Document'); + expect(doc?.kind).toEqual('Document'); }); it('should consider options.cwd', async () => { @@ -34,9 +35,9 @@ describe('loadFromCodeFile', () => { cwd: path.resolve(__dirname, 'test-files'), noRequire: true, }); - const doc = loaded.document ? loaded.document : parse(loaded.rawSDL); + const doc = loaded?.document ? loaded?.document : parse(loaded?.rawSDL!); - expect(doc.kind).toEqual('Document'); + expect(doc?.kind).toEqual('Document'); }); it('should load a TypeScript file using decorator', async () => { @@ -44,18 +45,18 @@ describe('loadFromCodeFile', () => { noRequire: true, cwd: __dirname }); - const doc = loaded.document ? loaded.document : parse(loaded.rawSDL); + const doc = loaded?.document ? loaded?.document : parse(loaded?.rawSDL!); - expect(doc.kind).toEqual('Document'); + expect(doc?.kind).toEqual('Document'); }); it('should support string interpolation', async () => { const loaded = await loader.load('./test-files/string-interpolation.js', { cwd: __dirname }); - const doc = loaded.document ? loaded.document : parse(loaded.rawSDL); + const doc = loaded?.document ? loaded?.document : parse(loaded?.rawSDL!); - expect(doc.kind).toEqual('Document'); + expect(doc?.kind).toEqual('Document'); }); }); @@ -68,9 +69,9 @@ describe('loadFromCodeFileSync', () => { noRequire: true, cwd: __dirname }); - const doc = loaded.document ? loaded.document : parse(loaded.rawSDL); + const doc = loaded?.document ? loaded?.document : parse(loaded?.rawSDL!); - expect(doc.kind).toEqual('Document'); + expect(doc?.kind).toEqual('Document'); }).toThrowError('Syntax Error: Unexpected Name "InvalidGetUser"') }); @@ -79,9 +80,9 @@ describe('loadFromCodeFileSync', () => { noRequire: true, cwd: __dirname }); - const doc = loaded.document; + const doc = loaded?.document; - expect(doc.kind).toEqual('Document'); + expect(doc?.kind).toEqual('Document'); }); it('should consider options.cwd', () => { @@ -89,9 +90,9 @@ describe('loadFromCodeFileSync', () => { cwd: path.resolve(__dirname, 'test-files'), noRequire: true, }); - const doc = loaded.document; + const doc = loaded?.document; - expect(doc.kind).toEqual('Document'); + expect(doc?.kind).toEqual('Document'); }); it('should support string interpolation', () => { @@ -99,8 +100,8 @@ describe('loadFromCodeFileSync', () => { cwd: __dirname }); - const doc = loaded.document; + const doc = loaded?.document; - expect(doc.kind).toEqual('Document'); + expect(doc?.kind).toEqual('Document'); }); }); diff --git a/packages/loaders/git/package.json b/packages/loaders/git/package.json index 37b72191218..146ee3b7402 100644 --- a/packages/loaders/git/package.json +++ b/packages/loaders/git/package.json @@ -33,7 +33,7 @@ "@graphql-tools/graphql-tag-pluck": "^6.2.6", "@graphql-tools/utils": "^7.0.0", "micromatch": "^4.0.4", - "tslib": "~2.2.0", + "tslib": "~2.3.0", "unixify": "^1.0.0" }, "devDependencies": { diff --git a/packages/loaders/git/src/index.ts b/packages/loaders/git/src/index.ts index c6d4384eced..f5b3af9ee35 100644 --- a/packages/loaders/git/src/index.ts +++ b/packages/loaders/git/src/index.ts @@ -8,7 +8,8 @@ import micromatch from 'micromatch'; import unixify from 'unixify'; import { loadFromGit, loadFromGitSync, readTreeAtRef, readTreeAtRefSync } from './load-git'; -import { parse } from './parse'; +import { parse as handleStuff } from './parse'; +import { concatAST, parse } from 'graphql'; // git:branch:path/to/file function extractData(pointer: string): { @@ -114,34 +115,38 @@ export class GitLoader implements UniversalLoader { async load(pointer: string, options: GitLoaderOptions) { const { ref, path } = extractData(pointer); const content = await loadFromGit({ ref, path }); - const parsed = parse({ path, options, pointer, content }); + const parsed = handleStuff({ path, options, pointer, content }); if (parsed) { return parsed; } - const rawSDL = await gqlPluckFromCodeString(pointer, content, options.pluckConfig); + const sources = await gqlPluckFromCodeString(pointer, content, options.pluckConfig); + + const documents = sources.map(source => parse(source, options)); return { location: pointer, - rawSDL, + document: concatAST(documents), }; } loadSync(pointer: string, options: GitLoaderOptions) { const { ref, path } = extractData(pointer); const content = loadFromGitSync({ ref, path }); - const parsed = parse({ path, options, pointer, content }); + const parsed = handleStuff({ path, options, pointer, content }); if (parsed) { return parsed; } - const rawSDL = gqlPluckFromCodeStringSync(pointer, content, options.pluckConfig); + const sources = gqlPluckFromCodeStringSync(pointer, content, options.pluckConfig); + + const documents = sources.map(source => parse(source, options)); return { location: pointer, - rawSDL, + document: concatAST(documents), }; } } diff --git a/packages/loaders/git/tests/__snapshots__/loader.spec.ts.snap b/packages/loaders/git/tests/__snapshots__/loader.spec.ts.snap new file mode 100644 index 00000000000..f196ba19681 --- /dev/null +++ b/packages/loaders/git/tests/__snapshots__/loader.spec.ts.snap @@ -0,0 +1,123 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`GitLoader load async should load type definitions from a pluckable file 1`] = ` +Object { + "definitions": Array [ + Object { + "description": undefined, + "directives": Array [], + "fields": Array [ + Object { + "arguments": Array [], + "description": undefined, + "directives": Array [], + "kind": "FieldDefinition", + "loc": Object { + "end": 28, + "start": 15, + }, + "name": Object { + "kind": "Name", + "loc": Object { + "end": 20, + "start": 15, + }, + "value": "hello", + }, + "type": Object { + "kind": "NamedType", + "loc": Object { + "end": 28, + "start": 22, + }, + "name": Object { + "kind": "Name", + "loc": Object { + "end": 28, + "start": 22, + }, + "value": "String", + }, + }, + }, + ], + "interfaces": Array [], + "kind": "ObjectTypeDefinition", + "loc": Object { + "end": 30, + "start": 0, + }, + "name": Object { + "kind": "Name", + "loc": Object { + "end": 10, + "start": 5, + }, + "value": "Query", + }, + }, + ], + "kind": "Document", +} +`; + +exports[`GitLoader load sync should load type definitions from a pluckable file 1`] = ` +Object { + "definitions": Array [ + Object { + "description": undefined, + "directives": Array [], + "fields": Array [ + Object { + "arguments": Array [], + "description": undefined, + "directives": Array [], + "kind": "FieldDefinition", + "loc": Object { + "end": 28, + "start": 15, + }, + "name": Object { + "kind": "Name", + "loc": Object { + "end": 20, + "start": 15, + }, + "value": "hello", + }, + "type": Object { + "kind": "NamedType", + "loc": Object { + "end": 28, + "start": 22, + }, + "name": Object { + "kind": "Name", + "loc": Object { + "end": 28, + "start": 22, + }, + "value": "String", + }, + }, + }, + ], + "interfaces": Array [], + "kind": "ObjectTypeDefinition", + "loc": Object { + "end": 30, + "start": 0, + }, + "name": Object { + "kind": "Name", + "loc": Object { + "end": 10, + "start": 5, + }, + "value": "Query", + }, + }, + ], + "kind": "Document", +} +`; diff --git a/packages/loaders/git/tests/loader.spec.ts b/packages/loaders/git/tests/loader.spec.ts index c1e3f9bb9ff..ba4969380ef 100644 --- a/packages/loaders/git/tests/loader.spec.ts +++ b/packages/loaders/git/tests/loader.spec.ts @@ -59,7 +59,7 @@ describe('GitLoader', () => { it('should load type definitions from a pluckable file', async () => { const result: Source = await load(getPointer('pluckable.ts'), {}); - expect(result.rawSDL).toBeDefined(); + expect(result.document).toMatchSnapshot(); }); it('should throw when pointer is malformed', async () => { diff --git a/packages/loaders/github/package.json b/packages/loaders/github/package.json index 2df4c4810f9..5fc93033e48 100644 --- a/packages/loaders/github/package.json +++ b/packages/loaders/github/package.json @@ -33,7 +33,7 @@ "@graphql-tools/utils": "^7.0.0", "@graphql-tools/graphql-tag-pluck": "^6.2.6", "cross-fetch": "3.1.4", - "tslib": "~2.2.0" + "tslib": "~2.3.0" }, "publishConfig": { "access": "public", diff --git a/packages/loaders/github/src/index.ts b/packages/loaders/github/src/index.ts index 007b14c90fa..983f972b8b9 100644 --- a/packages/loaders/github/src/index.ts +++ b/packages/loaders/github/src/index.ts @@ -1,11 +1,10 @@ import { UniversalLoader, parseGraphQLSDL, parseGraphQLJSON, SingleFileOptions } from '@graphql-tools/utils'; import { fetch } from 'cross-fetch'; import { GraphQLTagPluckOptions, gqlPluckFromCodeString } from '@graphql-tools/graphql-tag-pluck'; +import { concatAST, parse } from 'graphql'; // github:owner/name#ref:path/to/file -function extractData( - pointer: string -): { +function extractData(pointer: string): { owner: string; name: string; ref: string; @@ -113,8 +112,11 @@ export class GithubLoader implements UniversalLoader { } if (path.endsWith('.tsx') || path.endsWith('.ts') || path.endsWith('.js') || path.endsWith('.jsx')) { - const rawSDL = await gqlPluckFromCodeString(pointer, content, options.pluckConfig); - return parseGraphQLSDL(path, rawSDL, options); + const sources = await gqlPluckFromCodeString(pointer, content, options.pluckConfig); + return { + location: path, + document: concatAST(sources.map(source => parse(source, options))), + }; } throw new Error(`Invalid file extension: ${path}`); diff --git a/packages/loaders/github/tests/schema-from-github.spec.ts b/packages/loaders/github/tests/schema-from-github.spec.ts index c462e0937db..5c9e150ebb1 100644 --- a/packages/loaders/github/tests/schema-from-github.spec.ts +++ b/packages/loaders/github/tests/schema-from-github.spec.ts @@ -27,17 +27,22 @@ function normalize(doc: string): string { return print(parse(doc)); } +function assertNonMaybe(input: T): asserts input is Exclude{ + if (input == null) { + throw new Error("Value should be neither null nor undefined.") + } +} + test('load schema from GitHub', async () => { - let headers: Record = {}; - let query: string; - let variables: any; - let operationName: string; + let params: any = null; const server = nock('https://api.github.com').post('/graphql').reply(function reply(_, body: any) { - headers = this.req.headers; - query = body.query; - variables = body.variables; - operationName = body.operationName; + params = { + headers: this.req.headers, + query: body.query, + variables: body.variables, + operationName: body.operationName + } return [200, { data: { @@ -58,13 +63,15 @@ test('load schema from GitHub', async () => { server.done(); + assertNonMaybe(params); + // headers - expect(headers['content-type']).toContain('application/json; charset=utf-8'); - expect(headers.authorization).toContain(`bearer ${token}`); + expect(params.headers['content-type']).toContain('application/json; charset=utf-8'); + expect(params.headers.authorization).toContain(`bearer ${token}`); // query - expect(normalize(query)).toEqual( - normalize(` + expect(normalize(params.query)).toEqual( + normalize(/* GraphQL */` query GetGraphQLSchemaForGraphQLtools($owner: String!, $name: String!, $expression: String!) { repository(owner: $owner, name: $name) { object(expression: $expression) { @@ -78,15 +85,16 @@ test('load schema from GitHub', async () => { ); // variables - expect(variables).toEqual({ + expect(params.variables).toEqual({ owner, name, expression: ref + ':' + path, }); - + assertNonMaybe(params.operationName) // name - expect(operationName).toEqual('GetGraphQLSchemaForGraphQLtools'); + expect(params.operationName).toEqual('GetGraphQLSchemaForGraphQLtools'); + assertNonMaybe(schema.document) // schema expect(print(schema.document)).toEqual(printSchema(buildSchema(typeDefs))); }); diff --git a/packages/loaders/graphql-file/package.json b/packages/loaders/graphql-file/package.json index a5a0d88a92a..aea17e2cb30 100644 --- a/packages/loaders/graphql-file/package.json +++ b/packages/loaders/graphql-file/package.json @@ -41,7 +41,7 @@ "globby": "^11.0.3", "is-glob": "^4.0.1", "unixify": "^1.0.0", - "tslib": "~2.2.0" + "tslib": "~2.3.0" }, "publishConfig": { "access": "public", diff --git a/packages/loaders/graphql-file/src/index.ts b/packages/loaders/graphql-file/src/index.ts index c6d5ebe67e4..6a036156527 100644 --- a/packages/loaders/graphql-file/src/index.ts +++ b/packages/loaders/graphql-file/src/index.ts @@ -127,13 +127,13 @@ export class GraphQLFileLoader implements UniversalLoader { sync: loader.canLoadSync.bind(loader), })(canLoad => { it('should return true for a valid pointer', async () => { - await expect(canLoad(getPointer('schema'), {})).resolves.toBe(true); + await expect(canLoad(getPointer('schema'))).resolves.toBe(true); }); it('should return false if missing prefix', async () => { - await expect(canLoad(getPointer('schema').substring(7), {})).resolves.toBe(false); + await expect(canLoad(getPointer('schema').substring(7))).resolves.toBe(false); }); it('should return false if pointer is not a string', async () => { - await expect(canLoad(42 as any, {})).resolves.toBe(false); + await expect(canLoad(42 as any)).resolves.toBe(false); }); }); }); @@ -43,39 +43,39 @@ describe('ModuleLoader', () => { sync: loader.loadSync.bind(loader), })(load => { it('should load GraphQLSchema object from a file', async () => { - const result: Source = await load(getPointer('schema'), {}); + const result: Source = await load(getPointer('schema')); expect(result.schema).toBeDefined(); }); it('should load DocumentNode object from a file', async () => { - const result: Source = await load(getPointer('type-defs'), {}); + const result: Source = await load(getPointer('type-defs')); expect(result.document).toBeDefined(); }); it('should load string from a file', async () => { - const result: Source = await load(getPointer('type-defs-string'), {}); + const result: Source = await load(getPointer('type-defs-string')); expect(result.rawSDL).toBeDefined(); }); it('should load using a named export', async () => { - const result: Source = await load(getPointer('type-defs-named-export', 'typeDefs'), {}); + const result: Source = await load(getPointer('type-defs-named-export', 'typeDefs')); expect(result.document).toBeDefined(); }); it('should throw error when using a bad pointer', async () => { - await expect(load(getPointer('type-defs-named-export', 'tooMany#'), {})).rejects.toThrowError( + await expect(load(getPointer('type-defs-named-export', 'tooMany#'))).rejects.toThrowError( 'Schema pointer should match' ); }); it('should throw error when using a bad identifier', async () => { - await expect(load(getPointer('type-defs-named-export', 'badIdentifier'), {})).rejects.toThrowError( + await expect(load(getPointer('type-defs-named-export', 'badIdentifier'))).rejects.toThrowError( 'Unable to load schema from module' ); }); it('should throw error when loaded object is not GraphQLSchema, DocumentNode or string', async () => { - await expect(load(getPointer('type-defs-named-export', 'favoriteNumber'), {})).rejects.toThrowError( + await expect(load(getPointer('type-defs-named-export', 'favoriteNumber'))).rejects.toThrowError( 'Imported object was not a string, DocumentNode or GraphQLSchema' ); }); diff --git a/packages/loaders/prisma/package.json b/packages/loaders/prisma/package.json index c45d9841476..47fc5c5e654 100644 --- a/packages/loaders/prisma/package.json +++ b/packages/loaders/prisma/package.json @@ -32,7 +32,6 @@ "dependencies": { "@graphql-tools/url-loader": "^6.8.2", "@graphql-tools/utils": "^7.0.0", - "@types/http-proxy-agent": "^4.0.0", "@types/js-yaml": "^4.0.0", "@types/json-stable-stringify": "^1.0.32", "@types/jsonwebtoken": "^8.5.0", @@ -49,7 +48,7 @@ "lodash": "^4.17.20", "replaceall": "^0.1.6", "scuid": "^1.1.0", - "tslib": "~2.2.0", + "tslib": "~2.3.0", "yaml-ast-parser": "^0.0.43" }, "publishConfig": { diff --git a/packages/loaders/prisma/src/prisma-yml/Cluster.ts b/packages/loaders/prisma/src/prisma-yml/Cluster.ts index f74bf8ce058..626cb9b734b 100644 --- a/packages/loaders/prisma/src/prisma-yml/Cluster.ts +++ b/packages/loaders/prisma/src/prisma-yml/Cluster.ts @@ -13,7 +13,7 @@ export class Cluster { local: boolean; shared: boolean; clusterSecret?: string; - requiresAuth: boolean; + requiresAuth: boolean | undefined; out: IOutput; isPrivate: boolean; workspaceSlug?: string; @@ -58,10 +58,10 @@ export class Cluster { if (this.name === 'shared-public-demo') { return ''; } - if (this.isPrivate && process.env.PRISMA_MANAGEMENT_API_SECRET) { + if (this.isPrivate && process.env['PRISMA_MANAGEMENT_API_SECRET']) { return this.getLocalToken(); } - if (this.shared || (this.isPrivate && !process.env.PRISMA_MANAGEMENT_API_SECRET)) { + if (this.shared || (this.isPrivate && !process.env['PRISMA_MANAGEMENT_API_SECRET'])) { return this.generateClusterToken(serviceName, workspaceSlug, stageName); } else { return this.getLocalToken(); @@ -69,24 +69,30 @@ export class Cluster { } getLocalToken(): string | null { - if (!this.clusterSecret && !process.env.PRISMA_MANAGEMENT_API_SECRET) { + if (!this.clusterSecret && !process.env['PRISMA_MANAGEMENT_API_SECRET']) { return null; } if (!this.cachedToken) { const grants = [{ target: `*/*`, action: '*' }]; - const secret = process.env.PRISMA_MANAGEMENT_API_SECRET || this.clusterSecret; + const secret = process.env['PRISMA_MANAGEMENT_API_SECRET'] || this.clusterSecret; + + if (!secret) { + throw new Error( + `Could not generate token for cluster ${chalk.bold( + this.getDeployEndpoint() + )}. Did you provide the env var PRISMA_MANAGEMENT_API_SECRET?` + ); + } try { - const algorithm = process.env.PRISMA_MANAGEMENT_API_SECRET ? 'HS256' : 'RS256'; + const algorithm = process.env['PRISMA_MANAGEMENT_API_SECRET'] ? 'HS256' : 'RS256'; this.cachedToken = jwt.sign({ grants }, secret, { expiresIn: '5y', algorithm, }); } catch (e) { throw new Error( - `Could not generate token for cluster ${chalk.bold( - this.getDeployEndpoint() - )}. Did you provide the env var PRISMA_MANAGEMENT_API_SECRET? + `Could not generate token for cluster ${chalk.bold(this.getDeployEndpoint())}. Original error: ${e.message}` ); } diff --git a/packages/loaders/prisma/src/prisma-yml/Environment.test.ts b/packages/loaders/prisma/src/prisma-yml/Environment.test.ts index c9195bea387..7abb6fb1714 100644 --- a/packages/loaders/prisma/src/prisma-yml/Environment.test.ts +++ b/packages/loaders/prisma/src/prisma-yml/Environment.test.ts @@ -37,7 +37,7 @@ describe('Environment', () => { expect(env.clusters).toMatchSnapshot(); }); test('interpolates env vars', async () => { - process.env.SPECIAL_TEST_ENV_VAR = 'this-is-so-special'; + process.env['SPECIAL_TEST_ENV_VAR'] = 'this-is-so-special'; const env = makeEnv(`platformToken: \${env:SPECIAL_TEST_ENV_VAR}`); await env.load(); expect(env.clusters).toMatchSnapshot(); diff --git a/packages/loaders/prisma/src/prisma-yml/Environment.ts b/packages/loaders/prisma/src/prisma-yml/Environment.ts index a5dd773ee5a..e6bfb76c01e 100644 --- a/packages/loaders/prisma/src/prisma-yml/Environment.ts +++ b/packages/loaders/prisma/src/prisma-yml/Environment.ts @@ -14,15 +14,16 @@ import { getProxyAgent } from './utils/getProxyAgent'; // eslint-disable-next-line // @ts-ignore import * as jwt from 'jsonwebtoken'; +import { assertSome } from '@graphql-tools/utils'; const debug = require('debug')('Environment'); export class Environment { sharedClusters: string[] = ['prisma-eu1', 'prisma-us1']; clusterEndpointMap = clusterEndpointMap; - args: Args; - activeCluster: Cluster; + args: Args | undefined; + activeCluster: Cluster | undefined; globalRC: RC = {}; - clusters: Cluster[]; + clusters: Cluster[] | undefined; out: IOutput; home: string; rcPath: string; @@ -37,12 +38,17 @@ export class Environment { fs.mkdirSync(path.dirname(this.rcPath), { recursive: true }); } + private _getClusters() { + assertSome(this.clusters); + return this.clusters; + } + async load() { await this.loadGlobalRC(); } get cloudSessionKey(): string | undefined { - return process.env.PRISMA_CLOUD_SESSION_KEY || this.globalRC.cloudSessionKey; + return process.env['PRISMA_CLOUD_SESSION_KEY'] || this.globalRC.cloudSessionKey; } async renewToken() { @@ -105,10 +111,10 @@ export class Environment { } if (res.me && res.me.memberships && Array.isArray(res.me.memberships)) { // clean up all prisma-eu1 and prisma-us1 clusters if they already exist - this.clusters = this.clusters.filter(c => c.name !== 'prisma-eu1' && c.name !== 'prisma-us1'); + this.clusters = this._getClusters().filter(c => c.name !== 'prisma-eu1' && c.name !== 'prisma-us1'); - res.me.memberships.forEach((m: any) => { - m.workspace.clusters.forEach((cluster: any) => { + for (const m of res.me.memberships) { + for (const cluster of m.workspace.clusters) { const endpoint = cluster.connectInfo ? cluster.connectInfo.endpoint : cluster.customConnectionInfo @@ -126,8 +132,8 @@ export class Environment { m.workspace.slug ) ); - }); - }); + } + } } } catch (e) { debug(e); @@ -160,7 +166,8 @@ export class Environment { } addCluster(cluster: Cluster) { - const existingClusterIndex = this.clusters.findIndex(c => { + const clusters = this._getClusters(); + const existingClusterIndex = clusters.findIndex(c => { if (cluster.workspaceSlug) { return c.workspaceSlug === cluster.workspaceSlug && c.name === cluster.name; } else { @@ -168,13 +175,13 @@ export class Environment { } }); if (existingClusterIndex > -1) { - this.clusters.splice(existingClusterIndex, 1); + clusters.splice(existingClusterIndex, 1); } - this.clusters.push(cluster); + clusters.push(cluster); } removeCluster(name: string) { - this.clusters = this.clusters.filter(c => c.name !== name); + this.clusters = this._getClusters().filter(c => c.name !== name); } saveGlobalRC() { @@ -248,7 +255,7 @@ export class Environment { } private getLocalClusterConfig() { - return this.clusters + return this._getClusters() .filter(c => !c.shared && c.clusterSecret !== this.cloudSessionKey && !c.isPrivate) .reduce((acc, cluster) => { return { diff --git a/packages/loaders/prisma/src/prisma-yml/PrismaDefinition.test.ts b/packages/loaders/prisma/src/prisma-yml/PrismaDefinition.test.ts index e6a6db64c19..45ebc6f3c30 100644 --- a/packages/loaders/prisma/src/prisma-yml/PrismaDefinition.test.ts +++ b/packages/loaders/prisma/src/prisma-yml/PrismaDefinition.test.ts @@ -77,7 +77,7 @@ type User @model { }); test('load yml with secret and env var', async () => { const secret = 'this-is-a-long-secret'; - process.env.MY_TEST_SECRET = secret; + process.env['MY_TEST_SECRET'] = secret; const yml = `\ service: jj stage: dev @@ -127,7 +127,7 @@ type User @model { } `; const { definition, env } = makeDefinition(yml, datamodel, {}); - const envPath = path.join(definition.definitionDir, '.env'); + const envPath = path.join(definition.definitionDir!, '.env'); fs.mkdirSync(path.dirname(envPath), { recursive: true }); fs.writeFileSync(envPath, `MY_DOT_ENV_SECRET=this-is-very-secret,and-comma,seperated`); @@ -241,7 +241,7 @@ type User @model { } `; const { definition, env } = makeDefinition(yml, datamodel); - const envPath = path.join(definition.definitionDir, '.env'); + const envPath = path.join(definition.definitionDir!, '.env'); fs.mkdirSync(path.dirname(envPath), { recursive: true }); fs.writeFileSync(envPath, `MY_DOT_ENV_SECRET=this-is-very-secret,and-comma,seperated`); diff --git a/packages/loaders/prisma/src/prisma-yml/PrismaDefinition.ts b/packages/loaders/prisma/src/prisma-yml/PrismaDefinition.ts index f0ff636bf3b..4386064f280 100644 --- a/packages/loaders/prisma/src/prisma-yml/PrismaDefinition.ts +++ b/packages/loaders/prisma/src/prisma-yml/PrismaDefinition.ts @@ -27,12 +27,12 @@ export class PrismaDefinitionClass { typesString?: string; secrets: string[] | null; definitionPath?: string | null; - definitionDir: string; + definitionDir: string | undefined; env: Environment; out?: IOutput; envVars: any; rawEndpoint?: string; - private definitionString: string; + private definitionString: string | undefined; constructor(env: Environment, definitionPath?: string | null, envVars: EnvVars = process.env, out?: IOutput) { this.secrets = null; this.definitionPath = definitionPath; @@ -45,8 +45,8 @@ export class PrismaDefinitionClass { } async load(args: Args, envPath?: string, graceful?: boolean) { - if (args.project) { - const flagPath = path.resolve(args.project as string); + if (args['project']) { + const flagPath = path.resolve(String(args['project'])); try { fs.accessSync(flagPath); @@ -97,7 +97,7 @@ export class PrismaDefinitionClass { } get endpoint(): string | undefined { - return (this.definition && this.definition.endpoint) || process.env.PRISMA_MANAGEMENT_API_ENDPOINT; + return (this.definition && this.definition.endpoint) || process.env['PRISMA_MANAGEMENT_API_ENDPOINT']; } get clusterBaseUrl(): string | undefined { @@ -212,11 +212,11 @@ and execute ${chalk.bold.green('prisma deploy')} again, to get that value auto-f } findClusterByBaseUrl(baseUrl: string) { - return this.env.clusters.find(c => c.baseUrl.toLowerCase() === baseUrl); + return this.env.clusters?.find(c => c.baseUrl.toLowerCase() === baseUrl); } async getClusterByEndpoint(data: ParseEndpointResult) { - if (data.clusterBaseUrl && !process.env.PRISMA_MANAGEMENT_API_SECRET) { + if (data.clusterBaseUrl && !process.env['PRISMA_MANAGEMENT_API_SECRET']) { const cluster = this.findClusterByBaseUrl(data.clusterBaseUrl); if (cluster) { return cluster; @@ -255,8 +255,8 @@ and execute ${chalk.bold.green('prisma deploy')} again, to get that value auto-f : []; let allTypes = ''; - typesPaths.forEach(unresolvedTypesPath => { - const typesPath = path.join(this.definitionDir, unresolvedTypesPath!); + for (const unresolvedTypesPath of typesPaths) { + const typesPath = path.join(this.definitionDir!, unresolvedTypesPath!); try { fs.accessSync(typesPath); const types = fs.readFileSync(typesPath, 'utf-8'); @@ -264,7 +264,7 @@ and execute ${chalk.bold.green('prisma deploy')} again, to get that value auto-f } catch { throw new Error(`The types definition file "${typesPath}" could not be found.`); } - }); + } return allTypes; } @@ -297,7 +297,7 @@ and execute ${chalk.bold.green('prisma deploy')} again, to get that value auto-f let query = subscription.query; if (subscription.query.endsWith('.graphql')) { - const queryPath = path.join(this.definitionDir, subscription.query); + const queryPath = path.join(this.definitionDir!, subscription.query); try { fs.accessSync(queryPath); } catch { @@ -326,7 +326,7 @@ and execute ${chalk.bold.green('prisma deploy')} again, to get that value auto-f addDatamodel(datamodel: any) { this.definitionString += `\ndatamodel: ${datamodel}`; - fs.writeFileSync(this.definitionPath!, this.definitionString); + fs.writeFileSync(this.definitionPath!, this.definitionString!); this.definition!.datamodel = datamodel; } diff --git a/packages/loaders/prisma/src/prisma-yml/Variables.ts b/packages/loaders/prisma/src/prisma-yml/Variables.ts index 5eecd5e2819..6abb8d0bb5a 100644 --- a/packages/loaders/prisma/src/prisma-yml/Variables.ts +++ b/packages/loaders/prisma/src/prisma-yml/Variables.ts @@ -1,4 +1,4 @@ -import * as lodash from 'lodash'; +import _ from 'lodash'; // eslint-disable-next-line // @ts-ignore import replaceall from 'replaceall'; @@ -43,10 +43,10 @@ export class Variables { const deepMapValues = (object: any, callback: any, propertyPath?: string[]): any => { const deepMapValuesIteratee = (value: any, key: any) => deepMapValues(value, callback, propertyPath ? propertyPath.concat(key) : [key]); - if (lodash.isArray(object)) { - return lodash.map(object, deepMapValuesIteratee); - } else if (lodash.isObject(object) && !lodash.isDate(object) && !lodash.isFunction(object)) { - return lodash.extend({}, object, lodash.mapValues(object, deepMapValuesIteratee)); + if (_.isArray(object)) { + return _.map(object, deepMapValuesIteratee); + } else if (_.isObject(object) && !_.isDate(object) && !_.isFunction(object)) { + return _.extend({}, object, _.mapValues(object, deepMapValuesIteratee)); } return callback(object, propertyPath); }; @@ -54,7 +54,7 @@ export class Variables { deepMapValues(objectToPopulate, (property: any, propertyPath: any) => { if (typeof property === 'string') { const populateSingleProperty = this.populateProperty(property, true).then((newProperty: any) => - lodash.set(objectToPopulate, propertyPath, newProperty) + _.set(objectToPopulate, propertyPath, newProperty) ); populateAll.push(populateSingleProperty); } @@ -64,40 +64,43 @@ export class Variables { } populateProperty(propertyParam: any, populateInPlace?: boolean): any { - let property = populateInPlace ? propertyParam : lodash.cloneDeep(propertyParam); + let property = populateInPlace ? propertyParam : _.cloneDeep(propertyParam); const allValuesToPopulate: any[] = []; let warned = false; if (typeof property === 'string' && property.match(this.variableSyntax)) { - property.match(this.variableSyntax)!.forEach(matchedString => { - const variableString = matchedString - .replace(this.variableSyntax, (_, varName) => varName.trim()) - .replace(/\s/g, ''); - - let singleValueToPopulate: Promise | null = null; - if (variableString.match(this.overwriteSyntax)) { - singleValueToPopulate = this.overwrite(variableString); - } else { - singleValueToPopulate = this.getValueFromSource(variableString).then((valueToPopulate: any) => { - if (typeof valueToPopulate === 'object') { - return this.populateObject(valueToPopulate); - } - return valueToPopulate; - }); - } + const matchedStrings = property.match(this.variableSyntax); + if (matchedStrings) { + for (const matchedString of matchedStrings) { + const variableString = matchedString + .replace(this.variableSyntax, (_, varName) => varName.trim()) + .replace(/\s/g, ''); - singleValueToPopulate = singleValueToPopulate!.then(valueToPopulate => { - if (this.warnIfNotFound(variableString, valueToPopulate)) { - warned = true; + let singleValueToPopulate: Promise | null = null; + if (variableString.match(this.overwriteSyntax)) { + singleValueToPopulate = this.overwrite(variableString); + } else { + singleValueToPopulate = this.getValueFromSource(variableString).then((valueToPopulate: any) => { + if (typeof valueToPopulate === 'object') { + return this.populateObject(valueToPopulate); + } + return valueToPopulate; + }); } - return this.populateVariable(property, matchedString, valueToPopulate).then((newProperty: any) => { - property = newProperty; - return Promise.resolve(property); + + singleValueToPopulate = singleValueToPopulate!.then(valueToPopulate => { + if (this.warnIfNotFound(variableString, valueToPopulate)) { + warned = true; + } + return this.populateVariable(property, matchedString, valueToPopulate).then((newProperty: any) => { + property = newProperty; + return Promise.resolve(property); + }); }); - }); - allValuesToPopulate.push(singleValueToPopulate); - }); + allValuesToPopulate.push(singleValueToPopulate); + } + } return Promise.all(allValuesToPopulate).then(() => { if ((property as any) !== (this.json as any) && !warned) { return this.populateProperty(property); @@ -143,7 +146,7 @@ export class Variables { return ( finalValue !== null && typeof finalValue !== 'undefined' && - !(typeof finalValue === 'object' && lodash.isEmpty(finalValue)) + !(typeof finalValue === 'object' && _.isEmpty(finalValue)) ); }); return Promise.resolve(finalValue); @@ -166,6 +169,7 @@ export class Variables { ' You can check our docs for more info.', ].join(''); this.out.warn(this.out.getErrorPrefix(this.fileName, 'warning') + errorMessage); + return Promise.resolve(); } getValueFromEnv(variableString: any) { @@ -214,7 +218,7 @@ export class Variables { if ( valueToPopulate === null || typeof valueToPopulate === 'undefined' || - (typeof valueToPopulate === 'object' && lodash.isEmpty(valueToPopulate)) + (typeof valueToPopulate === 'object' && _.isEmpty(valueToPopulate)) ) { let varType; if (variableString.match(this.envRefSyntax)) { diff --git a/packages/loaders/prisma/src/prisma-yml/constants.ts b/packages/loaders/prisma/src/prisma-yml/constants.ts index 55640af751e..93832914b50 100644 --- a/packages/loaders/prisma/src/prisma-yml/constants.ts +++ b/packages/loaders/prisma/src/prisma-yml/constants.ts @@ -1,10 +1,10 @@ -import { invert } from 'lodash'; +import _ from 'lodash'; -export const cloudApiEndpoint = process.env.CLOUD_API_ENDPOINT || 'https://api.cloud.prisma.sh'; +export const cloudApiEndpoint = process.env['CLOUD_API_ENDPOINT'] || 'https://api.cloud.prisma.sh'; export const clusterEndpointMap: { [key: string]: string } = { 'prisma-eu1': 'https://eu1.prisma.sh', 'prisma-us1': 'https://us1.prisma.sh', }; -export const clusterEndpointMapReverse: { [key: string]: string } = invert(clusterEndpointMap); +export const clusterEndpointMapReverse: { [key: string]: string } = _.invert(clusterEndpointMap); diff --git a/packages/loaders/prisma/src/prisma-yml/utils/getProxyAgent.ts b/packages/loaders/prisma/src/prisma-yml/utils/getProxyAgent.ts index 63c16116788..f2d3c6ab89a 100644 --- a/packages/loaders/prisma/src/prisma-yml/utils/getProxyAgent.ts +++ b/packages/loaders/prisma/src/prisma-yml/utils/getProxyAgent.ts @@ -46,7 +46,7 @@ function getProxyFromURI(uri: any) { // environmental variables (NO_PROXY, HTTP_PROXY, etc.) // respect NO_PROXY environment variables (see: http://lynx.isc.org/current/breakout/lynx_help/keystrokes/environments.html) - const noProxy = process.env.NO_PROXY || process.env.no_proxy || ''; + const noProxy = process.env['NO_PROXY'] || process.env['no_proxy'] || ''; // if the noProxy is a wildcard then return null @@ -63,12 +63,16 @@ function getProxyFromURI(uri: any) { // Check for HTTP or HTTPS Proxy in environment Else default to null if (uri.protocol === 'http:') { - return process.env.HTTP_PROXY || process.env.http_proxy || null; + return process.env['HTTP_PROXY'] || process.env['http_proxy'] || null; } if (uri.protocol === 'https:') { return ( - process.env.HTTPS_PROXY || process.env.https_proxy || process.env.HTTP_PROXY || process.env.http_proxy || null + process.env['HTTPS_PROXY'] || + process.env['https_proxy'] || + process.env['HTTP_PROXY'] || + process.env['http_proxy'] || + null ); } diff --git a/packages/loaders/url/package.json b/packages/loaders/url/package.json index 7328e371f03..a238ad6db93 100644 --- a/packages/loaders/url/package.json +++ b/packages/loaders/url/package.json @@ -36,7 +36,7 @@ }, "devDependencies": { "@types/extract-files": "8.1.0", - "@types/ws": "7.4.4", + "@types/ws": "7.4.6", "graphql-upload": "12.0.0", "mock-http": "1.1.0", "mock-socket": "9.0.3" @@ -45,11 +45,12 @@ "@graphql-tools/delegate": "^7.0.1", "@graphql-tools/utils": "^7.9.0", "@graphql-tools/wrap": "^7.0.4", - "@microsoft/fetch-event-source": "2.0.1", - "@types/websocket": "1.0.2", + "@ardatan/fetch-event-source": "2.0.2", + "@n1ru4l/graphql-live-query": "0.7.1", + "@types/websocket": "1.0.3", "abort-controller": "3.0.0", "cross-fetch": "3.1.4", - "extract-files": "10.0.0", + "extract-files": "11.0.0", "form-data": "4.0.0", "graphql-ws": "^5.0.0", "lodash": "4.17.21", @@ -58,9 +59,10 @@ "isomorphic-ws": "4.0.1", "subscriptions-transport-ws": "^0.10.0", "sync-fetch": "0.3.0", - "tslib": "~2.2.0", + "tslib": "~2.3.0", "valid-url": "1.0.9", - "ws": "7.4.6" + "ws": "7.5.2", + "value-or-promise": "1.0.10" }, "publishConfig": { "access": "public", diff --git a/packages/loaders/url/src/index.ts b/packages/loaders/url/src/index.ts index c672328cc4a..f5cd4c9f5cf 100644 --- a/packages/loaders/url/src/index.ts +++ b/packages/loaders/url/src/index.ts @@ -1,10 +1,10 @@ /* eslint-disable no-case-declarations */ /// -import { print, IntrospectionOptions, DocumentNode, Kind, GraphQLError } from 'graphql'; +import { print, IntrospectionOptions, GraphQLError, buildASTSchema, buildSchema, getOperationAST } from 'graphql'; + import { AsyncExecutor, Executor, - Subscriber, SyncExecutor, SchemaPointerSingle, Source, @@ -19,7 +19,6 @@ import { } from '@graphql-tools/utils'; import { isWebUri } from 'valid-url'; import { fetch as crossFetch } from 'cross-fetch'; -import { SubschemaConfig } from '@graphql-tools/delegate'; import { introspectSchema, wrapSchema } from '@graphql-tools/wrap'; import { ClientOptions, createClient } from 'graphql-ws'; import WebSocket from 'isomorphic-ws'; @@ -27,11 +26,13 @@ import syncFetch from 'sync-fetch'; import isPromise from 'is-promise'; import { extractFiles, isExtractableFile } from 'extract-files'; import FormData from 'form-data'; -import { fetchEventSource, FetchEventSourceInit } from '@microsoft/fetch-event-source'; +import { fetchEventSource, FetchEventSourceInit } from '@ardatan/fetch-event-source'; import { ConnectionParamsOptions, SubscriptionClient as LegacySubscriptionClient } from 'subscriptions-transport-ws'; import AbortController from 'abort-controller'; import { meros } from 'meros'; import _ from 'lodash'; +import { ValueOrPromise } from 'value-or-promise'; +import { isLiveQueryOperationDefinitionNode } from '@n1ru4l/graphql-live-query'; export type AsyncFetchFn = typeof import('cross-fetch').fetch; export type SyncFetchFn = (input: RequestInfo, init?: RequestInit) => SyncResponse; @@ -41,21 +42,9 @@ export type SyncResponse = Omit & { }; export type FetchFn = AsyncFetchFn | SyncFetchFn; -type Headers = - | Record - | Array> - | ((executionParams: ExecutionParams) => Array> | Record); - -type BuildExecutorOptions = { - pointer: string; - fetch: TFetchFn; - extraHeaders: Headers; - defaultMethod: 'GET' | 'POST'; - useGETForQueries: boolean; - multipart?: boolean; -}; - +// TODO: Should the types here be changed to T extends Record ? export type AsyncImportFn = (moduleName: string) => PromiseLike; +// TODO: Should the types here be changed to T extends Record ? export type SyncImportFn = (moduleName: string) => T; const asyncImport: AsyncImportFn = (moduleName: string) => import(moduleName); @@ -63,19 +52,37 @@ const syncImport: SyncImportFn = (moduleName: string) => require(moduleName); interface ExecutionResult { errors?: ReadonlyArray; - data?: TData | null; + data?: TData; extensions?: TExtensions; } interface ExecutionPatchResult { errors?: ReadonlyArray; - data?: TData | null; + data?: TData; path?: ReadonlyArray; label?: string; hasNext: boolean; extensions?: TExtensions; } +type HeadersConfig = Record; + +interface ExecutionExtensions { + headers?: HeadersConfig; +} + +export enum SubscriptionProtocol { + WS = 'WS', + /** + * Use legacy web socket protocol `graphql-ws` instead of the more current standard `graphql-transport-ws` + */ + LEGACY_WS = 'LEGACY_WS', + /** + * Use SSE for subscription instead of WebSocket + */ + SSE = 'SSE', +} + /** * Additional options for loading from a URL */ @@ -83,7 +90,7 @@ export interface LoadFromUrlOptions extends SingleFileOptions, Partial { return !!isWebUri(pointer); } - async createFormDataFromVariables({ query, variables }: { query: string; variables: TVariables }) { + createFormDataFromVariables({ + query, + variables, + operationName, + extensions, + }: { + query: string; + variables: TVariables; + operationName?: string; + extensions?: any; + }) { const vars = Object.assign({}, variables); const { clone, files } = extractFiles( vars, @@ -164,41 +181,47 @@ export class UrlLoader implements DocumentLoader { prev[currIndex] = curr; return prev; }, {}); - const uploads: any = new Map(Array.from(files.keys()).map((u, i) => [i, u])); + const uploads: Map = new Map(Array.from(files.keys()).map((u, i) => [i, u])); const form = new FormData(); form.append( 'operations', JSON.stringify({ query, variables: clone, + operationName, + extensions, }) ); form.append('map', JSON.stringify(map)); - await Promise.all( - Array.from(uploads.entries()).map(async ([i, u]) => { - if (isPromise(u)) { - u = await u; - } - if (u?.promise) { - const upload = await u.promise; - const stream = upload.createReadStream(); - form.append(i.toString(), stream, { - filename: upload.filename, - contentType: upload.mimetype, - } as any); - } else { - form.append( - i.toString(), - u as any, - { - filename: 'name' in u ? u['name'] : i, - contentType: u.type, - } as any - ); - } - }) - ); - return form; + return ValueOrPromise.all( + Array.from(uploads.entries()).map(params => + new ValueOrPromise(() => { + const [i, u$] = params as any; + return new ValueOrPromise(() => u$).then(u => [i, u]).resolve(); + }).then(([i, u]) => { + if (u?.promise) { + return u.promise.then((upload: any) => { + const stream = upload.createReadStream(); + form.append(i.toString(), stream, { + filename: upload.filename, + contentType: upload.mimetype, + } as any); + }); + } else { + form.append( + i.toString(), + u as any, + { + filename: 'name' in u ? u['name'] : i, + contentType: u.type, + } as any + ); + } + }) + ) + ) + .then(() => form) + .resolve(); } prepareGETUrl({ @@ -206,11 +229,13 @@ export class UrlLoader implements DocumentLoader { query, variables, operationName, + extensions, }: { baseUrl: string; query: string; variables: any; operationName?: string; + extensions?: any; }) { const HTTP_URL = switchProtocols(baseUrl, { wss: 'https', @@ -230,137 +255,159 @@ export class UrlLoader implements DocumentLoader { if (operationName) { urlObj.searchParams.set('operationName', operationName); } + if (extensions) { + urlObj.searchParams.set('extensions', JSON.stringify(extensions)); + } const finalUrl = urlObj.toString().replace(dummyHostname, ''); return finalUrl; } - buildExecutor(options: BuildExecutorOptions): SyncExecutor; - buildExecutor(options: BuildExecutorOptions): AsyncExecutor; - buildExecutor({ - pointer, - fetch, - extraHeaders, - defaultMethod, - useGETForQueries, - multipart, - }: BuildExecutorOptions): Executor { - const HTTP_URL = switchProtocols(pointer, { + buildHTTPExecutor( + endpoint: string, + fetch: SyncFetchFn, + options?: LoadFromUrlOptions + ): SyncExecutor; + + buildHTTPExecutor( + endpoint: string, + fetch: AsyncFetchFn, + options?: LoadFromUrlOptions + ): AsyncExecutor; + + buildHTTPExecutor( + endpoint: string, + fetch: FetchFn, + options?: LoadFromUrlOptions + ): Executor { + const defaultMethod = this.getDefaultMethodFromOptions(options?.method, 'POST'); + const HTTP_URL = switchProtocols(endpoint, { wss: 'https', ws: 'http', }); - const executor = ({ document, variables, ...rest }: ExecutionParams) => { + const executor = ({ + document, + variables, + operationName, + extensions, + }: ExecutionParams) => { const controller = new AbortController(); let method = defaultMethod; - if (useGETForQueries) { - method = 'GET'; - for (const definition of document.definitions) { - if (definition.kind === Kind.OPERATION_DEFINITION) { - if (definition.operation !== 'query') { - method = defaultMethod; - } - } + if (options?.useGETForQueries) { + const operationAst = getOperationAST(document, operationName); + if (operationAst?.operation === 'query') { + method = 'GET'; + } else { + method = defaultMethod; } } - const headers = this.getHeadersFromOptions(extraHeaders, { - document, - variables, - ...rest, - }); + const headers = Object.assign({}, options?.headers, extensions?.headers || {}); - let fetchResult: SyncResponse | Promise; - const query = print(document); - switch (method) { - case 'GET': - const finalUrl = this.prepareGETUrl({ baseUrl: pointer, query, variables }); - fetchResult = fetch(finalUrl, { - method: 'GET', - credentials: 'include', - headers: { - accept: 'application/json', - ...headers, - }, - }); - break; - case 'POST': - if (multipart) { - fetchResult = this.createFormDataFromVariables({ query, variables }).then(form => - (fetch as AsyncFetchFn)(HTTP_URL, { + return new ValueOrPromise(() => { + const query = print(document); + switch (method) { + case 'GET': + const finalUrl = this.prepareGETUrl({ baseUrl: endpoint, query, variables, operationName, extensions }); + return fetch(finalUrl, { + method: 'GET', + credentials: 'include', + headers: { + accept: 'application/json', + ...headers, + }, + }); + case 'POST': + if (options?.multipart) { + return new ValueOrPromise(() => + this.createFormDataFromVariables({ query, variables, operationName, extensions }) + ) + .then( + form => + fetch(HTTP_URL, { + method: 'POST', + credentials: 'include', + body: form as any, + headers: { + accept: 'application/json', + ...headers, + }, + signal: controller.signal, + }) as any + ) + .resolve(); + } else { + return fetch(HTTP_URL, { method: 'POST', credentials: 'include', - body: form as any, + body: JSON.stringify({ + query, + variables, + operationName, + extensions, + }), headers: { - accept: 'application/json', + accept: 'application/json, multipart/mixed', + 'content-type': 'application/json', ...headers, }, signal: controller.signal, - }) - ); - } else { - fetchResult = fetch(HTTP_URL, { - method: 'POST', - credentials: 'include', - body: JSON.stringify({ - query, - variables, - }), - headers: { - accept: 'application/json, multipart/mixed', - 'content-type': 'application/json', - ...headers, - }, - signal: controller.signal, - }); - } - break; - } - if (isPromise(fetchResult)) { - return fetchResult.then(async res => { + }); + } + } + }) + .then((fetchResult: Response) => { const response: ExecutionResult = {}; - const maybeStream = await meros(res); - if (isAsyncIterable(maybeStream)) { - return withCancel( - mapAsyncIterator(maybeStream, part => { - if (part.json) { - const chunk = part.body; - if (chunk.path) { - if (chunk.data) { - const path: Array = ['data']; - _.merge(response, _.set({}, path.concat(chunk.path), chunk.data)); + const contentType = fetchResult.headers.get + ? fetchResult.headers.get('content-type') + : fetchResult['content-type']; + if (contentType?.includes('multipart/mixed')) { + return meros(fetchResult).then(maybeStream => { + if (isAsyncIterable(maybeStream)) { + return withCancel( + mapAsyncIterator(maybeStream, part => { + if (part.json) { + const chunk = part.body; + if (chunk.path) { + if (chunk.data) { + const path: Array = ['data']; + _.merge(response, _.set({}, path.concat(chunk.path), chunk.data)); + } + + if (chunk.errors) { + response.errors = (response.errors || []).concat(chunk.errors); + } + } else { + if (chunk.data) { + response.data = chunk.data; + } + if (chunk.errors) { + response.errors = chunk.errors; + } + } + return response; } - - if (chunk.errors) { - response.errors = (response.errors || []).concat(chunk.errors); - } - } else { - if (chunk.data) { - response.data = chunk.data; - } - if (chunk.errors) { - response.errors = chunk.errors; - } - } - return response; - } - }), - () => controller.abort() - ); - } else { - return maybeStream.json(); + }), + () => controller.abort() + ); + } else { + return maybeStream.json(); + } + }); } - }); - } - return fetchResult.json(); + + return fetchResult.json(); + }) + .resolve(); }; return executor; } - buildWSSubscriber( + buildWSExecutor( subscriptionsEndpoint: string, webSocketImpl: typeof WebSocket, connectionParams?: ClientOptions['connectionParams'] - ): Subscriber { + ): AsyncExecutor { const WS_URL = switchProtocols(subscriptionsEndpoint, { https: 'wss', http: 'ws', @@ -371,14 +418,16 @@ export class UrlLoader implements DocumentLoader { connectionParams, lazy: true, }); - return async ({ document, variables }: { document: DocumentNode; variables: any }) => { + return async ({ document, variables, operationName, extensions }) => { const query = print(document); return observableToAsyncIterable({ subscribe: observer => { const unsubscribe = subscriptionClient.subscribe( { query, - variables, + variables: variables as Record, + operationName, + extensions, }, observer ); @@ -390,11 +439,11 @@ export class UrlLoader implements DocumentLoader { }; } - buildWSLegacySubscriber( + buildWSLegacyExecutor( subscriptionsEndpoint: string, webSocketImpl: typeof WebSocket, connectionParams?: ConnectionParamsOptions - ): Subscriber { + ): AsyncExecutor { const WS_URL = switchProtocols(subscriptionsEndpoint, { https: 'wss', http: 'ws', @@ -408,33 +457,29 @@ export class UrlLoader implements DocumentLoader { webSocketImpl ); - return async ({ document, variables }: ExecutionParams) => { + return async ({ document, variables, operationName }: ExecutionParams) => { return observableToAsyncIterable( subscriptionClient.request({ query: document, variables, + operationName, }) - ) as AsyncIterator>; + ) as AsyncIterableIterator>; }; } - buildSSESubscriber( - pointer: string, - extraHeaders: Headers, + buildSSEExecutor( + endpoint: string, fetch: AsyncFetchFn, - options: FetchEventSourceInit - ): Subscriber { - return async ({ document, variables, ...rest }: { document: DocumentNode; variables: any }) => { + options?: Omit + ): AsyncExecutor { + return async ({ document, variables, extensions }) => { const controller = new AbortController(); const query = print(document); - const finalUrl = this.prepareGETUrl({ baseUrl: pointer, query, variables }); - const headers = this.getHeadersFromOptions(extraHeaders, { - document, - variables, - ...rest, - }); + const finalUrl = this.prepareGETUrl({ baseUrl: endpoint, query, variables }); return observableToAsyncIterable({ subscribe: observer => { + const headers = Object.assign({}, options?.headers || {}, extensions?.headers || {}); fetchEventSource(finalUrl, { credentials: 'include', headers, @@ -465,7 +510,7 @@ export class UrlLoader implements DocumentLoader { }, fetch, signal: controller.signal, - ...options, + ...(options?.eventSourceOptions || {}), }); return { unsubscribe: () => controller.abort(), @@ -475,48 +520,28 @@ export class UrlLoader implements DocumentLoader { }; } - getFetch( - customFetch: LoadFromUrlOptions['customFetch'], - importFn: AsyncImportFn, - async: true - ): PromiseLike; + getFetch(customFetch: LoadFromUrlOptions['customFetch'], importFn: AsyncImportFn): PromiseLike; - getFetch(customFetch: LoadFromUrlOptions['customFetch'], importFn: SyncImportFn, async: false): SyncFetchFn; + getFetch(customFetch: LoadFromUrlOptions['customFetch'], importFn: SyncImportFn): SyncFetchFn; getFetch( customFetch: LoadFromUrlOptions['customFetch'], - importFn: SyncImportFn | AsyncImportFn, - async: boolean + importFn: SyncImportFn | AsyncImportFn ): SyncFetchFn | PromiseLike { if (customFetch) { if (typeof customFetch === 'string') { const [moduleName, fetchFnName] = customFetch.split('#'); const moduleResult = importFn(moduleName); if (isPromise(moduleResult)) { - return moduleResult.then(module => (fetchFnName ? module[fetchFnName] : module)); + return moduleResult.then(module => (fetchFnName ? (module as Record)[fetchFnName] : module)); } else { - return fetchFnName ? moduleResult[fetchFnName] : moduleResult; + return fetchFnName ? (module as Record)[fetchFnName] : moduleResult; } } else { return customFetch as any; } } - return async ? (typeof fetch === 'undefined' ? crossFetch : fetch) : syncFetch; - } - - private getHeadersFromOptions(customHeaders: Headers, executionParams: ExecutionParams): Record { - let headers = {}; - if (customHeaders) { - if (typeof customHeaders === 'function') { - customHeaders = customHeaders(executionParams); - } - if (Array.isArray(customHeaders)) { - headers = customHeaders.reduce((prev: any, v: any) => ({ ...prev, ...v }), {}); - } else if (typeof customHeaders === 'object') { - headers = customHeaders; - } - } - return headers; + return importFn === asyncImport ? (typeof fetch === 'undefined' ? crossFetch : fetch) : syncFetch; } private getDefaultMethodFromOptions(method: LoadFromUrlOptions['method'], defaultMethod: 'GET' | 'POST') { @@ -526,13 +551,13 @@ export class UrlLoader implements DocumentLoader { return defaultMethod; } - getWebSocketImpl(options: LoadFromUrlOptions, importFn: AsyncImportFn): PromiseLike; + getWebSocketImpl(importFn: AsyncImportFn, options?: LoadFromUrlOptions): PromiseLike; - getWebSocketImpl(options: LoadFromUrlOptions, importFn: SyncImportFn): typeof WebSocket; + getWebSocketImpl(importFn: SyncImportFn, options?: LoadFromUrlOptions): typeof WebSocket; getWebSocketImpl( - options: LoadFromUrlOptions, - importFn: SyncImportFn | AsyncImportFn + importFn: SyncImportFn | AsyncImportFn, + options?: LoadFromUrlOptions ): typeof WebSocket | PromiseLike { if (typeof options?.webSocketImpl === 'string') { const [moduleName, webSocketImplName] = options.webSocketImpl.split('#'); @@ -540,169 +565,154 @@ export class UrlLoader implements DocumentLoader { if (isPromise(importedModule)) { return importedModule.then(webSocketImplName ? importedModule[webSocketImplName] : importedModule); } else { - return webSocketImplName ? importedModule[webSocketImplName] : importedModule; + return webSocketImplName ? (importedModule as Record)[webSocketImplName] : importedModule; } } else { - const websocketImpl = options.webSocketImpl || WebSocket; + const websocketImpl = options?.webSocketImpl || WebSocket; return websocketImpl; } } - async getExecutorAndSubscriberAsync( - pointer: SchemaPointerSingle, - options: LoadFromUrlOptions = {} - ): Promise<{ executor: AsyncExecutor; subscriber: Subscriber }> { - const fetch = await this.getFetch(options.customFetch, asyncImport, true); - const defaultMethod = this.getDefaultMethodFromOptions(options.method, 'POST'); - - const executor = this.buildExecutor({ - pointer, - fetch, - extraHeaders: options.headers, - defaultMethod, - useGETForQueries: options.useGETForQueries, - multipart: options.multipart, - }); - - let subscriber: Subscriber; - - const subscriptionsEndpoint = options.subscriptionsEndpoint || pointer; - if (options.useSSEForSubscription) { - subscriber = this.buildSSESubscriber(subscriptionsEndpoint, options.headers, fetch, options.eventSourceOptions); + async buildSubscriptionExecutor( + subscriptionsEndpoint: string, + fetch: AsyncFetchFn, + options?: Omit + ): Promise { + if (options?.subscriptionsProtocol === SubscriptionProtocol.SSE) { + return this.buildSSEExecutor(subscriptionsEndpoint, fetch, options); } else { - const webSocketImpl = await this.getWebSocketImpl(options, asyncImport); - const connectionParams = () => ({ headers: this.getHeadersFromOptions(options.headers, {} as any) }); - if (options.useWebSocketLegacyProtocol) { - subscriber = this.buildWSLegacySubscriber(subscriptionsEndpoint, webSocketImpl, connectionParams); + const webSocketImpl = await this.getWebSocketImpl(asyncImport, options); + const connectionParams = () => ({ headers: options?.headers }); + if (options?.subscriptionsProtocol === SubscriptionProtocol.LEGACY_WS) { + return this.buildWSLegacyExecutor(subscriptionsEndpoint, webSocketImpl, connectionParams); } else { - subscriber = this.buildWSSubscriber(subscriptionsEndpoint, webSocketImpl, connectionParams); + return this.buildWSExecutor(subscriptionsEndpoint, webSocketImpl, connectionParams); } } - - return { - executor, - subscriber, - }; } - getExecutorAndSubscriberSync( - pointer: SchemaPointerSingle, - options: LoadFromUrlOptions - ): { executor: SyncExecutor; subscriber: Subscriber } { - const fetch = this.getFetch(options?.customFetch, syncImport, false); - const defaultMethod = this.getDefaultMethodFromOptions(options?.method, 'POST'); + async getExecutorAsync(endpoint: string, options?: Omit): Promise { + const fetch = await this.getFetch(options?.customFetch, asyncImport); + const httpExecutor = this.buildHTTPExecutor(endpoint, fetch, options); + const subscriptionsEndpoint = options?.subscriptionsEndpoint || endpoint; + const subscriptionExecutor = await this.buildSubscriptionExecutor(subscriptionsEndpoint, fetch, options); - const executor = this.buildExecutor({ - pointer, - fetch, - extraHeaders: options.headers, - defaultMethod, - useGETForQueries: options.useGETForQueries, - }); - - const subscriptionsEndpoint = options.subscriptionsEndpoint || pointer; - let subscriber: Subscriber; - if (options.useSSEForSubscription) { - const asyncFetchFn: any = (...args: any[]) => - this.getFetch(options?.customFetch, asyncImport, true).then((asyncFetch: any) => asyncFetch(...args)); - subscriber = this.buildSSESubscriber( - subscriptionsEndpoint, - options.headers, - asyncFetchFn, - options.eventSourceOptions - ); - } else { - const webSocketImpl = this.getWebSocketImpl(options, syncImport); - const connectionParams = () => ({ headers: this.getHeadersFromOptions(options.headers, {} as any) }); - if (options.useWebSocketLegacyProtocol) { - subscriber = this.buildWSLegacySubscriber(subscriptionsEndpoint, webSocketImpl, connectionParams); - } else { - subscriber = this.buildWSSubscriber(subscriptionsEndpoint, webSocketImpl, connectionParams); + return params => { + const operationAst = getOperationAST(params.document, params.operationName); + if (!operationAst) { + throw new Error(`No valid operations found: ${params.operationName || ''}`); } - } - - return { - executor, - subscriber, - }; - } - - async getSubschemaConfigAsync(pointer: SchemaPointerSingle, options: LoadFromUrlOptions): Promise { - const { executor, subscriber } = await this.getExecutorAndSubscriberAsync(pointer, options); - return { - schema: await introspectSchema(executor, undefined, options as IntrospectionOptions), - executor, - subscriber, + if ( + operationAst.operation === 'subscription' || + isLiveQueryOperationDefinitionNode(operationAst, params.variables as Record) + ) { + return subscriptionExecutor(params); + } + return httpExecutor(params); }; } - getSubschemaConfigSync(pointer: SchemaPointerSingle, options: LoadFromUrlOptions): SubschemaConfig { - const { executor, subscriber } = this.getExecutorAndSubscriberSync(pointer, options); - return { - schema: introspectSchema(executor, undefined, options as IntrospectionOptions), - executor, - subscriber, - }; - } + getExecutorSync(endpoint: string, options: Omit): SyncExecutor { + const fetch = this.getFetch(options?.customFetch, syncImport); + const executor = this.buildHTTPExecutor(endpoint, fetch, options); - async handleSDLAsync(pointer: SchemaPointerSingle, options: LoadFromUrlOptions): Promise { - const fetch = await this.getFetch(options?.customFetch, asyncImport, true); - const headers = this.getHeadersFromOptions(options?.headers, {} as any); - const defaultMethod = this.getDefaultMethodFromOptions(options?.method, 'GET'); - const response = await fetch(pointer, { - method: defaultMethod, - headers, - }); - const schemaString = await response.text(); - return parseGraphQLSDL(pointer, schemaString, options); + return executor; } - handleSDLSync(pointer: SchemaPointerSingle, options: LoadFromUrlOptions): Source { - const fetch = this.getFetch(options?.customFetch, syncImport, false); - const headers = this.getHeadersFromOptions(options?.headers, {} as any); + handleSDL(pointer: SchemaPointerSingle, fetch: SyncFetchFn, options: LoadFromUrlOptions): Source; + handleSDL(pointer: SchemaPointerSingle, fetch: AsyncFetchFn, options: LoadFromUrlOptions): Promise; + handleSDL(pointer: SchemaPointerSingle, fetch: FetchFn, options: LoadFromUrlOptions): Source | Promise { const defaultMethod = this.getDefaultMethodFromOptions(options?.method, 'GET'); - const response = fetch(pointer, { - method: defaultMethod, - headers, - }); - const schemaString = response.text(); - return parseGraphQLSDL(pointer, schemaString, options); + return new ValueOrPromise(() => + fetch(pointer, { + method: defaultMethod, + headers: options.headers, + }) + ) + .then(response => response.text()) + .then(schemaString => parseGraphQLSDL(pointer, schemaString, options)) + .resolve(); } async load(pointer: SchemaPointerSingle, options: LoadFromUrlOptions): Promise { + let source: Source = { + location: pointer, + }; + const fetch = await this.getFetch(options?.customFetch, asyncImport); + let executor = await this.getExecutorAsync(pointer, options); if (options?.handleAsSDL || pointer.endsWith('.graphql')) { - return this.handleSDLAsync(pointer, options); + source = await this.handleSDL(pointer, fetch, options); + if (!source.schema && !source.document && !source.rawSDL) { + throw new Error(`Invalid SDL response`); + } + source.schema = + source.schema || + (source.document + ? buildASTSchema(source.document, options) + : source.rawSDL + ? buildSchema(source.rawSDL, options) + : undefined); + } else { + source.schema = await introspectSchema(executor, {}, options); } - const subschemaConfig = await this.getSubschemaConfigAsync(pointer, options); + if (!source.schema) { + throw new Error(`Invalid introspected schema`); + } - const remoteExecutableSchema = wrapSchema(subschemaConfig); + if (options?.endpoint) { + executor = await this.getExecutorAsync(options.endpoint, options); + } - return { - location: pointer, - schema: remoteExecutableSchema, - }; + source.schema = wrapSchema({ + schema: source.schema, + executor, + }); + + return source; } loadSync(pointer: SchemaPointerSingle, options: LoadFromUrlOptions): Source { + let source: Source = { + location: pointer, + }; + const fetch = this.getFetch(options?.customFetch, syncImport); + let executor = this.getExecutorSync(pointer, options); if (options?.handleAsSDL || pointer.endsWith('.graphql')) { - return this.handleSDLSync(pointer, options); + source = this.handleSDL(pointer, fetch, options); + if (!source.schema && !source.document && !source.rawSDL) { + throw new Error(`Invalid SDL response`); + } + source.schema = + source.schema || + (source.document + ? buildASTSchema(source.document, options) + : source.rawSDL + ? buildSchema(source.rawSDL, options) + : undefined); + } else { + source.schema = introspectSchema(executor, {}, options); } - const subschemaConfig = this.getSubschemaConfigSync(pointer, options); + if (!source.schema) { + throw new Error(`Invalid introspected schema`); + } - const remoteExecutableSchema = wrapSchema(subschemaConfig); + if (options?.endpoint) { + executor = this.getExecutorSync(options.endpoint, options); + } - return { - location: pointer, - schema: remoteExecutableSchema, - }; + source.schema = wrapSchema({ + schema: source.schema, + executor, + }); + + return source; } } function switchProtocols(pointer: string, protocolMap: Record): string { - const protocols: [string, string][] = Object.keys(protocolMap).map(source => [source, protocolMap[source]]); - return protocols.reduce( + return Object.entries(protocolMap).reduce( (prev, [source, target]) => prev.replace(`${source}://`, `${target}://`).replace(`${source}:\\`, `${target}:\\`), pointer ); diff --git a/packages/loaders/url/tests/url-loader.spec.ts b/packages/loaders/url/tests/url-loader.spec.ts index b5c72f6de3c..eb99a2e963e 100644 --- a/packages/loaders/url/tests/url-loader.spec.ts +++ b/packages/loaders/url/tests/url-loader.spec.ts @@ -1,6 +1,6 @@ import '../../../testing/to-be-similar-gql-doc'; import { makeExecutableSchema } from '@graphql-tools/schema'; -import { UrlLoader } from '../src'; +import { SubscriptionProtocol, UrlLoader } from '../src'; import { printSchemaWithDirectives } from '@graphql-tools/utils'; import nock from 'nock'; import { mockGraphQLServer } from '../../../testing/utils'; @@ -102,6 +102,12 @@ input TestInput { const testPathChecker = (path: string) => path.startsWith(testPath); const testUrl = `${testHost}${testPath}`; + function assertNonMaybe(input: T): asserts input is Exclude{ + if (input == null) { + throw new Error("Value should be neither null nor undefined.") + } + } + describe('handle', () => { let scope: nock.Scope; @@ -127,10 +133,9 @@ input TestInput { it('Should return a valid schema when request is valid', async () => { scope = mockGraphQLServer({ schema: testSchema, host: testHost, path: testPathChecker }); - const schema = await loader.load(testUrl, {}); - - expect(schema.schema).toBeDefined(); - expect(printSchemaWithDirectives(schema.schema)).toBeSimilarGqlDoc(testTypeDefs); + const source = await loader.load(testUrl, {}); + assertNonMaybe(source.schema) + expect(printSchemaWithDirectives(source.schema)).toBeSimilarGqlDoc(testTypeDefs); }); it('Should pass default headers', async () => { @@ -145,13 +150,13 @@ input TestInput { }, }); - const schema = await loader.load(testUrl, {}); + const source = await loader.load(testUrl, {}); - expect(schema).toBeDefined(); - expect(schema.schema).toBeDefined(); - expect(printSchemaWithDirectives(schema.schema)).toBeSimilarGqlDoc(testTypeDefs); + expect(source).toBeDefined(); + assertNonMaybe(source.schema) + expect(printSchemaWithDirectives(source.schema)).toBeSimilarGqlDoc(testTypeDefs); - expect(Array.isArray(headers.accept) ? headers.accept.join(',') : headers.accept).toContain(`application/json`); + expect(Array.isArray(headers['accept']) ? headers['accept'].join(',') : headers['accept']).toContain(`application/json`); expect(headers['content-type']).toContain(`application/json`); }); @@ -166,38 +171,15 @@ input TestInput { }, }); - const schema = await loader.load(testUrl, { headers: { Auth: '1' } }); - - expect(schema).toBeDefined(); - expect(schema.schema).toBeDefined(); - expect(printSchemaWithDirectives(schema.schema)).toBeSimilarGqlDoc(testTypeDefs); - - expect(Array.isArray(headers.accept) ? headers.accept.join(',') : headers.accept).toContain(`application/json`); - expect(headers['content-type']).toContain(`application/json`); - expect(headers.auth).toContain(`1`); - }); + const source = await loader.load(testUrl, { headers: { Auth: '1' } }); - it('Should pass extra headers when they are specified as array', async () => { - let headers: Record = {}; - scope = mockGraphQLServer({ - schema: testSchema, - host: testHost, - path: testPathChecker, - intercept(ctx) { - headers = ctx.req.headers; - }, - }); - const schema = await loader.load(testUrl, { headers: [{ A: '1' }, { B: '2', C: '3' }] }); - - expect(schema).toBeDefined(); - expect(schema.schema).toBeDefined(); - expect(printSchemaWithDirectives(schema.schema)).toBeSimilarGqlDoc(testTypeDefs); + expect(source).toBeDefined(); + assertNonMaybe(source.schema) + expect(printSchemaWithDirectives(source.schema)).toBeSimilarGqlDoc(testTypeDefs); - expect(Array.isArray(headers.accept) ? headers.accept.join(',') : headers.accept).toContain(`application/json`); + expect(Array.isArray(headers['accept']) ? headers['accept'].join(',') : headers['accept']).toContain(`application/json`); expect(headers['content-type']).toContain(`application/json`); - expect(headers.a).toContain(`1`); - expect(headers.b).toContain(`2`); - expect(headers.c).toContain(`3`); + expect(headers['auth']).toContain(`1`); }); it('Should utilize extra introspection options', async () => { @@ -205,7 +187,8 @@ input TestInput { const source = await loader.load(testUrl, { descriptions: false }); expect(source).toBeDefined(); - expect(source.schema.getQueryType().description).toBeUndefined(); + assertNonMaybe(source.schema) + expect(source.schema.getQueryType()!.description).toBeUndefined(); }); it('Absolute file path should not be accepted as URL', async () => { @@ -224,7 +207,7 @@ input TestInput { scope.done(); scope = mockGraphQLServer({ schema: testSchema, host: testHost, path: testPathChecker, method: 'GET' }); - + assertNonMaybe(source.schema) const result = await execute({ schema: source.schema, document: parse(/* GraphQL */ ` @@ -241,7 +224,7 @@ input TestInput { expect(result?.errors).toBeFalsy(); - expect(result?.data?.a).toBe(testVariableValue); + expect(result?.data?.['a']).toBe(testVariableValue); }); it('Should preserve "ws" and "http" in the middle of a pointer', async () => { @@ -253,7 +236,7 @@ input TestInput { scope = mockGraphQLServer({ schema: testSchema, host: address.host, path: address.path }); const result = await loader.load(url, {}); - expect(result.schema).toBeDefined(); + assertNonMaybe(result.schema) expect(printSchemaWithDirectives(result.schema)).toBeSimilarGqlDoc(testTypeDefs); }); @@ -270,7 +253,7 @@ input TestInput { }); const result = await loader.load(url, {}); - expect(result.schema).toBeDefined(); + assertNonMaybe(result.schema) expect(printSchemaWithDirectives(result.schema)).toBeSimilarGqlDoc(testTypeDefs); }); @@ -287,7 +270,7 @@ input TestInput { }); const result = await loader.load(url, {}); - expect(result.schema).toBeDefined(); + assertNonMaybe(result.schema) expect(printSchemaWithDirectives(result.schema)).toBeSimilarGqlDoc(testTypeDefs); }); it('should handle .graphql files', async () => { @@ -296,7 +279,7 @@ input TestInput { scope = nock(testHost).get(testPath).reply(200, testTypeDefs); const result = await loader.load(testHost + testPath, {}); - expect(result.document).toBeDefined(); + assertNonMaybe(result.document) expect(print(result.document)).toBeSimilarGqlDoc(testTypeDefs); }) it('should handle results with handleAsSDL option even if it doesn\'t end with .graphql', async () => { @@ -307,7 +290,7 @@ input TestInput { handleAsSDL: true, }); - expect(result.document).toBeDefined(); + assertNonMaybe(result.document) expect(print(result.document)).toBeSimilarGqlDoc(testTypeDefs); }) it('should handle subscriptions - new protocol', (done) => { @@ -322,6 +305,7 @@ input TestInput { data: introspectionFromSchema(testSchema), }) }) as any, + subscriptionsProtocol: SubscriptionProtocol.WS }); const httpServer = http.createServer(function weServeSocketsOnly(_, res) { @@ -344,7 +328,7 @@ input TestInput { ); httpServer.listen(8081); - + assertNonMaybe(schema) const asyncIterator = await subscribe({ schema, document: parse(/* GraphQL */` @@ -372,7 +356,7 @@ input TestInput { expect(await getNextResult()).toBe(1); expect(await getNextResult()).toBe(2); - await asyncIterator.return(); + await asyncIterator.return!(); await subscriptionServer.dispose(); wsServer.close(() => { httpServer.close(done); @@ -391,7 +375,7 @@ input TestInput { data: introspectionFromSchema(testSchema), }) }) as any, - useWebSocketLegacyProtocol: true, + subscriptionsProtocol: SubscriptionProtocol.LEGACY_WS }); const httpServer = http.createServer(function weServeSocketsOnly(_, res) { @@ -413,7 +397,7 @@ input TestInput { path: '/graphql', }, ); - + assertNonMaybe(schema) const asyncIterator = await subscribe({ schema, document: parse(/* GraphQL */` @@ -441,7 +425,7 @@ input TestInput { expect(await getNextResult()).toBe(1); expect(await getNextResult()).toBe(2); - await asyncIterator.return(); + await asyncIterator.return!(); subscriptionServer.close(); httpServer.close(done); }); @@ -460,7 +444,7 @@ input TestInput { const fileName = 'testfile.txt'; const absoluteFilePath = join(__dirname, fileName); - + assertNonMaybe(schema) const result = await execute({ schema, document: parse(/* GraphQL */` @@ -481,8 +465,9 @@ input TestInput { const content = readFileSync(absoluteFilePath, 'utf8') expect(result.errors).toBeFalsy(); - expect(result.data.uploadFile?.filename).toBe(fileName); - expect(result.data.uploadFile?.content).toBe(content); + assertNonMaybe(result.data) + expect(result.data['uploadFile']?.filename).toBe(fileName); + expect(result.data['uploadFile']?.content).toBe(content); }); }); }); diff --git a/packages/merge/package.json b/packages/merge/package.json index 6c8ad281119..861424fe5fb 100644 --- a/packages/merge/package.json +++ b/packages/merge/package.json @@ -35,7 +35,7 @@ "dependencies": { "@graphql-tools/schema": "^7.0.0", "@graphql-tools/utils": "^7.7.0", - "tslib": "~2.2.0" + "tslib": "~2.3.0" }, "publishConfig": { "access": "public", diff --git a/packages/merge/src/extensions.ts b/packages/merge/src/extensions.ts index 40cfbc83759..58118ab0225 100644 --- a/packages/merge/src/extensions.ts +++ b/packages/merge/src/extensions.ts @@ -146,7 +146,10 @@ export function mergeExtensions(extensions: SchemaExtensions[]): SchemaExtension ); } -function applyExtensionObject(obj: { extensions: Maybe>> }, extensions: ExtensionsObject) { +function applyExtensionObject( + obj: Maybe<{ extensions: Maybe>> }>, + extensions: ExtensionsObject +) { if (!obj) { return; } diff --git a/packages/merge/src/merge-resolvers.ts b/packages/merge/src/merge-resolvers.ts index ed8ed384c2d..4c66d5c7365 100644 --- a/packages/merge/src/merge-resolvers.ts +++ b/packages/merge/src/merge-resolvers.ts @@ -1,8 +1,5 @@ import { IResolvers, mergeDeep } from '@graphql-tools/utils'; -export type ResolversFactory = (...args: any[]) => IResolvers; -export type ResolversDefinition = IResolvers | ResolversFactory; - /** * Additional options for merging resolvers */ @@ -39,54 +36,41 @@ export interface MergeResolversOptions { * const resolvers = mergeResolvers(resolversArray) * ``` */ -export function mergeResolvers>( - resolversDefinitions: T[], +export function mergeResolvers( + resolversDefinitions: IResolvers | IResolvers[], options?: MergeResolversOptions -): T { - if (!resolversDefinitions || resolversDefinitions.length === 0) { - return {} as T; +): IResolvers { + if (!resolversDefinitions || (Array.isArray(resolversDefinitions) && resolversDefinitions.length === 0)) { + return {}; + } + + if (!Array.isArray(resolversDefinitions)) { + return resolversDefinitions; } if (resolversDefinitions.length === 1) { - const singleDefinition = resolversDefinitions[0]; - if (Array.isArray(singleDefinition)) { - return mergeResolvers(singleDefinition); - } - return singleDefinition; + return resolversDefinitions[0]; } - type TFactory = (...args: any[]) => T; - const resolversFactories = new Array(); - const resolvers = new Array(); + const resolvers = new Array>(); for (let resolversDefinition of resolversDefinitions) { if (Array.isArray(resolversDefinition)) { resolversDefinition = mergeResolvers(resolversDefinition); } - if (typeof resolversDefinition === 'function') { - resolversFactories.push(resolversDefinition as unknown as TFactory); - } else if (typeof resolversDefinition === 'object') { + if (typeof resolversDefinition === 'object') { resolvers.push(resolversDefinition); } } - let result: T = {} as T; - if (resolversFactories.length) { - result = ((...args: any[]) => { - const resultsOfFactories = resolversFactories.map(factory => factory(...args)); - return resolvers.concat(resultsOfFactories).reduce(mergeDeep, {}); - }) as any; - } else { - result = resolvers.reduce(mergeDeep, {} as T); - } - if (options && options.exclusions) { - for (const exclusion of options.exclusions) { - const [typeName, fieldName] = exclusion.split('.'); - if (!fieldName || fieldName === '*') { - delete result[typeName]; - } else if (result[typeName]) { - delete result[typeName][fieldName]; - } + const result = resolvers.reduce(mergeDeep, {}); + + options?.exclusions?.forEach(exclusion => { + const [typeName, fieldName] = exclusion.split('.'); + if (!fieldName || fieldName === '*') { + delete result[typeName]; + } else if (result[typeName]) { + delete result[typeName][fieldName]; } - } + }); return result; } diff --git a/packages/merge/src/merge-schemas.ts b/packages/merge/src/merge-schemas.ts index 5fd180946b6..b20181e3dba 100644 --- a/packages/merge/src/merge-schemas.ts +++ b/packages/merge/src/merge-schemas.ts @@ -1,13 +1,13 @@ import { GraphQLSchema, DocumentNode, buildASTSchema, BuildSchemaOptions, buildSchema } from 'graphql'; -import { addResolversToSchema, addErrorLoggingToSchema, ILogger } from '@graphql-tools/schema'; +import { addResolversToSchema } from '@graphql-tools/schema'; import { mergeTypeDefs, Config } from './typedefs-mergers/merge-typedefs'; import { mergeResolvers } from './merge-resolvers'; import { IResolvers, - SchemaDirectiveVisitor, IResolverValidationOptions, asArray, getResolversFromSchema, + TypeSource, } from '@graphql-tools/utils'; import { mergeExtensions, extractExtensionsFromSchema, applyExtensions, SchemaExtensions } from './extensions'; @@ -22,23 +22,15 @@ export interface MergeSchemasConfig e /** * Additional type definitions to also merge */ - typeDefs?: (DocumentNode | string)[] | DocumentNode | string; + typeDefs?: TypeSource; /** * Additional resolvers to also merge */ resolvers?: Resolvers | Resolvers[]; - /** - * Schema directives to apply to the type definitions being merged, if provided - */ - schemaDirectives?: { [directiveName: string]: typeof SchemaDirectiveVisitor }; /** * Options to validate the resolvers being merged, if provided */ resolverValidationOptions?: IResolverValidationOptions; - /** - * Custom logger instance - */ - logger?: ILogger; } const defaultResolverValidationOptions: Partial = { @@ -54,7 +46,7 @@ const defaultResolverValidationOptions: Partial = { * @param config Configuration object */ export function mergeSchemas(config: MergeSchemasConfig) { - const typeDefs = mergeTypes(config); + const typeDefs = mergeTypeDefs([config.schemas, config.typeDefs || []], config); const extractedResolvers: IResolvers[] = []; const extractedExtensions: SchemaExtensions[] = []; for (const schema of config.schemas) { @@ -75,7 +67,7 @@ export function mergeSchemas(config: MergeSchemasConfig) { */ export async function mergeSchemasAsync(config: MergeSchemasConfig) { const [typeDefs, resolvers, extensions] = await Promise.all([ - mergeTypes(config), + mergeTypeDefs([config.schemas, config.typeDefs || []], config), Promise.all(config.schemas.map(async schema => getResolversFromSchema(schema))).then(extractedResolvers => mergeResolvers([...extractedResolvers, ...ensureResolvers(config)], config) ), @@ -87,10 +79,6 @@ export async function mergeSchemasAsync(config: MergeSchemasConfig) { return makeSchema({ resolvers, typeDefs, extensions }, config); } -function mergeTypes({ schemas, typeDefs, ...config }: MergeSchemasConfig) { - return mergeTypeDefs([...schemas, ...(typeDefs ? asArray(typeDefs) : [])], config); -} - function ensureResolvers(config: MergeSchemasConfig) { return config.resolvers ? asArray(config.resolvers) : []; } @@ -117,16 +105,6 @@ function makeSchema( }); } - // use logger - if (config.logger) { - schema = addErrorLoggingToSchema(schema, config.logger); - } - - // use schema directives - if (config.schemaDirectives) { - SchemaDirectiveVisitor.visitSchemaDirectives(schema, config.schemaDirectives); - } - // extensions applyExtensions(schema, extensions); diff --git a/packages/merge/src/typedefs-mergers/arguments.ts b/packages/merge/src/typedefs-mergers/arguments.ts index 1916b275a9f..c1e13be5438 100644 --- a/packages/merge/src/typedefs-mergers/arguments.ts +++ b/packages/merge/src/typedefs-mergers/arguments.ts @@ -1,13 +1,13 @@ import { InputValueDefinitionNode } from 'graphql'; import { Config } from '.'; -import { compareNodes } from '@graphql-tools/utils'; +import { compareNodes, isSome } from '@graphql-tools/utils'; export function mergeArguments( args1: InputValueDefinitionNode[], args2: InputValueDefinitionNode[], - config: Config + config?: Config ): InputValueDefinitionNode[] { - const result = deduplicateArguments([].concat(args2, args1).filter(a => a)); + const result = deduplicateArguments([...args2, ...args1].filter(isSome)); if (config && config.sort) { result.sort(compareNodes); } diff --git a/packages/merge/src/typedefs-mergers/comments.ts b/packages/merge/src/typedefs-mergers/comments.ts index 3dd2294de4f..fdd80c9d54f 100644 --- a/packages/merge/src/typedefs-mergers/comments.ts +++ b/packages/merge/src/typedefs-mergers/comments.ts @@ -2,7 +2,6 @@ import { getDescription, StringValueNode, FieldDefinitionNode, - InputValueDefinitionNode, ASTNode, NameNode, TypeNode, @@ -20,29 +19,35 @@ export function resetComments(): void { } export function collectComment(node: NamedDefinitionNode): void { - const entityName = node.name.value; + const entityName = node.name?.value; + if (entityName == null) { + return; + } + pushComment(node, entityName); switch (node.kind) { case 'EnumTypeDefinition': - node.values.forEach(value => { - pushComment(value, entityName, value.name.value); - }); + if (node.values) { + for (const value of node.values) { + pushComment(value, entityName, value.name.value); + } + } break; case 'ObjectTypeDefinition': case 'InputObjectTypeDefinition': case 'InterfaceTypeDefinition': if (node.fields) { - node.fields.forEach((field: FieldDefinitionNode | InputValueDefinitionNode) => { + for (const field of node.fields) { pushComment(field, entityName, field.name.value); if (isFieldDefinitionNode(field) && field.arguments) { - field.arguments.forEach(arg => { + for (const arg of field.arguments) { pushComment(arg, entityName, field.name.value, arg.name.value); - }); + } } - }); + } } break; } diff --git a/packages/merge/src/typedefs-mergers/directives.ts b/packages/merge/src/typedefs-mergers/directives.ts index a247dc5df33..2808edbf62e 100644 --- a/packages/merge/src/typedefs-mergers/directives.ts +++ b/packages/merge/src/typedefs-mergers/directives.ts @@ -1,5 +1,6 @@ import { ArgumentNode, DirectiveNode, DirectiveDefinitionNode, ListValueNode, NameNode, print } from 'graphql'; import { Config } from './merge-typedefs'; +import { isSome } from '@graphql-tools/utils'; function directiveAlreadyExists(directivesArr: ReadonlyArray, otherDirective: DirectiveNode): boolean { return !!directivesArr.find(directive => directive.name.value === otherDirective.name.value); @@ -52,7 +53,7 @@ function deduplicateDirectives(directives: ReadonlyArray): Direct return directive; }) - .filter(d => d); + .filter(isSome); } export function mergeDirectives( @@ -60,7 +61,7 @@ export function mergeDirectives( d2: ReadonlyArray = [], config?: Config ): DirectiveNode[] { - const reverseOrder: boolean = config && config.reverseDirectives; + const reverseOrder: boolean | undefined = config && config.reverseDirectives; const asNext = reverseOrder ? d1 : d2; const asFirst = reverseOrder ? d2 : d1; const result = deduplicateDirectives([...asNext]); diff --git a/packages/merge/src/typedefs-mergers/enum-values.ts b/packages/merge/src/typedefs-mergers/enum-values.ts index 8ac31168f85..c4b81a49ffb 100644 --- a/packages/merge/src/typedefs-mergers/enum-values.ts +++ b/packages/merge/src/typedefs-mergers/enum-values.ts @@ -4,29 +4,37 @@ import { Config } from './merge-typedefs'; import { compareNodes } from '@graphql-tools/utils'; export function mergeEnumValues( - first: ReadonlyArray, - second: ReadonlyArray, + first: ReadonlyArray | undefined, + second: ReadonlyArray | undefined, config?: Config ): EnumValueDefinitionNode[] { if (config?.consistentEnumMerge) { - const reversed: ReadonlyArray = first; + const reversed: Array = []; + if (first) { + reversed.push(...first); + } first = second; second = reversed; } const enumValueMap = new Map(); - for (const firstValue of first) { - enumValueMap.set(firstValue.name.value, firstValue); + if (first) { + for (const firstValue of first) { + enumValueMap.set(firstValue.name.value, firstValue); + } } - for (const secondValue of second) { - const enumValue = secondValue.name.value; - if (enumValueMap.has(enumValue)) { - const firstValue: any = enumValueMap.get(enumValue); - firstValue.description = secondValue.description || firstValue.description; - firstValue.directives = mergeDirectives(secondValue.directives, firstValue.directives); - } else { - enumValueMap.set(enumValue, secondValue); + if (second) { + for (const secondValue of second) { + const enumValue = secondValue.name.value; + if (enumValueMap.has(enumValue)) { + const firstValue: any = enumValueMap.get(enumValue); + firstValue.description = secondValue.description || firstValue.description; + firstValue.directives = mergeDirectives(secondValue.directives, firstValue.directives); + } else { + enumValueMap.set(enumValue, secondValue); + } } } + const result = [...enumValueMap.values()]; if (config && config.sort) { result.sort(compareNodes); diff --git a/packages/merge/src/typedefs-mergers/fields.ts b/packages/merge/src/typedefs-mergers/fields.ts index 98146f90817..be3673c69b0 100644 --- a/packages/merge/src/typedefs-mergers/fields.ts +++ b/packages/merge/src/typedefs-mergers/fields.ts @@ -24,40 +24,45 @@ function fieldAlreadyExists(fieldsArr: ReadonlyArray, otherField: any, conf export function mergeFields( type: { name: NameNode }, - f1: ReadonlyArray, - f2: ReadonlyArray, + f1: ReadonlyArray | undefined, + f2: ReadonlyArray | undefined, config?: Config ): T[] { - const result: T[] = [...f2]; - - for (const field of f1) { - if (fieldAlreadyExists(result, field, config)) { - const existing: any = result.find((f: any) => f.name.value === (field as any).name.value); - - if (!config?.ignoreFieldConflicts) { - if (config?.throwOnConflict) { - preventConflicts(type, existing, field, false); - } else { - preventConflicts(type, existing, field, true); + const result: T[] = []; + if (f2 != null) { + result.push(...f2); + } + if (f1 != null) { + for (const field of f1) { + if (fieldAlreadyExists(result, field, config)) { + const existing: any = result.find((f: any) => f.name.value === (field as any).name.value); + + if (!config?.ignoreFieldConflicts) { + if (config?.throwOnConflict) { + preventConflicts(type, existing, field, false); + } else { + preventConflicts(type, existing, field, true); + } + + if (isNonNullTypeNode(field.type) && !isNonNullTypeNode(existing.type)) { + existing.type = field.type; + } } - if (isNonNullTypeNode(field.type) && !isNonNullTypeNode(existing.type)) { - existing.type = field.type; - } + existing.arguments = mergeArguments(field['arguments'] || [], existing.arguments || [], config); + existing.directives = mergeDirectives(field.directives, existing.directives, config); + existing.description = field.description || existing.description; + } else { + result.push(field); } - - existing.arguments = mergeArguments(field['arguments'] || [], existing.arguments || [], config); - existing.directives = mergeDirectives(field.directives, existing.directives, config); - existing.description = field.description || existing.description; - } else { - result.push(field); } } if (config && config.sort) { result.sort(compareNodes); } if (config && config.exclusions) { - return result.filter(field => !config.exclusions.includes(`${type.name.value}.${field.name.value}`)); + const exclusions = config.exclusions; + return result.filter(field => !exclusions.includes(`${type.name.value}.${field.name.value}`)); } return result; } diff --git a/packages/merge/src/typedefs-mergers/interface.ts b/packages/merge/src/typedefs-mergers/interface.ts index fb5a1d2d6a9..996299b1b65 100644 --- a/packages/merge/src/typedefs-mergers/interface.ts +++ b/packages/merge/src/typedefs-mergers/interface.ts @@ -6,7 +6,7 @@ import { mergeDirectives } from './directives'; export function mergeInterface( node: InterfaceTypeDefinitionNode | InterfaceTypeExtensionNode, existingNode: InterfaceTypeDefinitionNode | InterfaceTypeExtensionNode, - config: Config + config?: Config ): InterfaceTypeDefinitionNode | InterfaceTypeExtensionNode { if (existingNode) { try { diff --git a/packages/merge/src/typedefs-mergers/merge-nodes.ts b/packages/merge/src/typedefs-mergers/merge-nodes.ts index 8fceaa72eba..264323f70f3 100644 --- a/packages/merge/src/typedefs-mergers/merge-nodes.ts +++ b/packages/merge/src/typedefs-mergers/merge-nodes.ts @@ -10,6 +10,8 @@ import { mergeDirective } from './directives'; import { collectComment } from './comments'; import { mergeSchemaDefs } from './schema-def'; +export const schemaDefSymbol = 'SCHEMA_DEF_SYMBOL'; + export type MergedResultMap = Record & { [schemaDefSymbol]: SchemaDefinitionNode | SchemaExtensionNode; }; @@ -19,17 +21,19 @@ export function isNamedDefinitionNode(definitionNode: DefinitionNode): definitio return 'name' in definitionNode; } -export const schemaDefSymbol = 'SCHEMA_DEF_SYMBOL'; - export function mergeGraphQLNodes(nodes: ReadonlyArray, config?: Config): MergedResultMap { const mergedResultMap = {} as MergedResultMap; for (const nodeDefinition of nodes) { if (isNamedDefinitionNode(nodeDefinition)) { - const name = nodeDefinition.name.value; + const name = nodeDefinition.name?.value; if (config?.commentDescriptions) { collectComment(nodeDefinition); } + if (name == null) { + continue; + } + if (config?.exclusions?.includes(name + '.*') || config?.exclusions?.includes(name)) { delete mergedResultMap[name]; } else { diff --git a/packages/merge/src/typedefs-mergers/merge-typedefs.ts b/packages/merge/src/typedefs-mergers/merge-typedefs.ts index 0760a62aadf..02057f10f37 100644 --- a/packages/merge/src/typedefs-mergers/merge-typedefs.ts +++ b/packages/merge/src/typedefs-mergers/merge-typedefs.ts @@ -1,24 +1,28 @@ import { DefinitionNode, DocumentNode, - GraphQLSchema, parse, - Source, Kind, isSchema, OperationTypeDefinitionNode, OperationTypeNode, isDefinitionNode, + ParseOptions, } from 'graphql'; import { CompareFn, defaultStringComparator, isSourceTypes, isStringTypes } from './utils'; import { MergedResultMap, mergeGraphQLNodes, schemaDefSymbol } from './merge-nodes'; import { resetComments, printWithComments } from './comments'; -import { getDocumentNodeFromSchema } from '@graphql-tools/utils'; +import { + getDocumentNodeFromSchema, + GetDocumentNodeFromSchemaOptions, + isDocumentNode, + TypeSource, +} from '@graphql-tools/utils'; import { DEFAULT_OPERATION_TYPE_NAME_MAP } from './schema-def'; type Omit = Pick>; -export interface Config { +export interface Config extends ParseOptions, GetDocumentNodeFromSchemaOptions { /** * Produces `schema { query: ..., mutation: ..., subscription: ... }` * @@ -76,24 +80,18 @@ export interface Config { * Merges multiple type definitions into a single `DocumentNode` * @param types The type definitions to be merged */ -export function mergeTypeDefs(types: Array): DocumentNode; -export function mergeTypeDefs( - types: Array, - config?: Partial & { commentDescriptions: true } -): string; +export function mergeTypeDefs(typeSource: TypeSource): DocumentNode; +export function mergeTypeDefs(typeSource: TypeSource, config?: Partial & { commentDescriptions: true }): string; export function mergeTypeDefs( - types: Array, + typeSource: TypeSource, config?: Omit, 'commentDescriptions'> ): DocumentNode; -export function mergeTypeDefs( - types: Array, - config?: Partial -): DocumentNode | string { +export function mergeTypeDefs(typeSource: TypeSource, config?: Partial): DocumentNode | string { resetComments(); const doc = { kind: Kind.DOCUMENT, - definitions: mergeGraphQLTypes(types, { + definitions: mergeGraphQLTypes(typeSource, { useSchemaDefinition: true, forceSchemaDefinition: false, throwOnConflict: false, @@ -116,36 +114,38 @@ export function mergeTypeDefs( } function visitTypeSources( - types: Array, - allNodes: DefinitionNode[] = [] + typeSource: TypeSource, + options: ParseOptions & GetDocumentNodeFromSchemaOptions, + allNodes: DefinitionNode[] = [], + visitedTypeSources = new Set() ) { - for (const type of types) { - if (type) { - if (Array.isArray(type)) { - visitTypeSources(type, allNodes); - } else if (isSchema(type)) { - const documentNode = getDocumentNodeFromSchema(type); - visitTypeSources(documentNode.definitions as DefinitionNode[], allNodes); - } else if (isStringTypes(type) || isSourceTypes(type)) { - const documentNode = parse(type); - visitTypeSources(documentNode.definitions as DefinitionNode[], allNodes); - } else if (isDefinitionNode(type)) { - allNodes.push(type); - } else { - visitTypeSources(type.definitions as DefinitionNode[], allNodes); - } + if (typeSource && !visitedTypeSources.has(typeSource)) { + visitedTypeSources.add(typeSource); + if (typeof typeSource === 'function') { + visitTypeSources(typeSource(), options, allNodes, visitedTypeSources); + } else if (Array.isArray(typeSource)) { + typeSource.forEach(type => visitTypeSources(type, options, allNodes, visitedTypeSources)); + } else if (isSchema(typeSource)) { + const documentNode = getDocumentNodeFromSchema(typeSource, options); + visitTypeSources(documentNode.definitions as DefinitionNode[], options, allNodes, visitedTypeSources); + } else if (isStringTypes(typeSource) || isSourceTypes(typeSource)) { + const documentNode = parse(typeSource, options); + visitTypeSources(documentNode.definitions as DefinitionNode[], options, allNodes, visitedTypeSources); + } else if (typeof typeSource === 'object' && isDefinitionNode(typeSource)) { + allNodes.push(typeSource); + } else if (isDocumentNode(typeSource)) { + visitTypeSources(typeSource.definitions as DefinitionNode[], options, allNodes, visitedTypeSources); + } else { + throw new Error(`typeDefs must contain only strings, documents, schemas, or functions, got ${typeof typeSource}`); } } return allNodes; } -export function mergeGraphQLTypes( - types: Array, - config: Config -): DefinitionNode[] { +export function mergeGraphQLTypes(typeSource: TypeSource, config: Config): DefinitionNode[] { resetComments(); - const allNodes = visitTypeSources(types); + const allNodes = visitTypeSources(typeSource, config); const mergedNodes: MergedResultMap = mergeGraphQLNodes(allNodes, config); @@ -161,7 +161,7 @@ export function mergeGraphQLTypes( if (!opTypeDefNode) { const possibleRootTypeName = DEFAULT_OPERATION_TYPE_NAME_MAP[opTypeDefNodeType]; const existingPossibleRootType = mergedNodes[possibleRootTypeName]; - if (existingPossibleRootType) { + if (existingPossibleRootType != null && existingPossibleRootType.name != null) { operationTypes.push({ kind: Kind.OPERATION_TYPE_DEFINITION, type: { @@ -174,7 +174,7 @@ export function mergeGraphQLTypes( } } - if (schemaDef.operationTypes?.length > 0) { + if (schemaDef?.operationTypes?.length != null && schemaDef.operationTypes.length > 0) { mergedNodes[schemaDefSymbol] = schemaDef; } } diff --git a/packages/merge/src/typedefs-mergers/utils.ts b/packages/merge/src/typedefs-mergers/utils.ts index 9093afd243d..d072742da5f 100644 --- a/packages/merge/src/typedefs-mergers/utils.ts +++ b/packages/merge/src/typedefs-mergers/utils.ts @@ -45,9 +45,18 @@ export enum CompareVal { A_EQUALS_B = 0, A_GREATER_THAN_B = 1, } -export type CompareFn = (a: T, b: T) => -1 | 0 | 1; +export type CompareFn = (a: T | undefined, b: T | undefined) => -1 | 0 | 1; -export function defaultStringComparator(a: string, b: string): CompareVal { +export function defaultStringComparator(a: string | undefined, b: string | undefined): CompareVal { + if (a == null && b == null) { + return CompareVal.A_EQUALS_B; + } + if (a == null) { + return CompareVal.A_SMALLER_THAN_B; + } + if (b == null) { + return CompareVal.A_GREATER_THAN_B; + } if (a < b) return CompareVal.A_SMALLER_THAN_B; if (a > b) return CompareVal.A_GREATER_THAN_B; return CompareVal.A_EQUALS_B; diff --git a/packages/merge/tests/extract-extensions-from-schema.spec.ts b/packages/merge/tests/extract-extensions-from-schema.spec.ts index 354af4b653c..4e360fa3f12 100644 --- a/packages/merge/tests/extract-extensions-from-schema.spec.ts +++ b/packages/merge/tests/extract-extensions-from-schema.spec.ts @@ -1,4 +1,6 @@ -import { buildSchema, GraphQLEnumType, GraphQLSchema, printSchema, buildClientSchema, buildASTSchema, parse } from 'graphql'; +import { buildSchema, GraphQLSchema, printSchema, buildASTSchema, parse } from 'graphql'; +import { assertGraphQLEnumType, assertGraphQLInputObjectType, assertGraphQLObjectType, assertGraphQLInterfaceType, assertGraphQLUnionType, assertGraphQLScalerType } from '../../testing/assertion'; +import { assertSome } from '@graphql-tools/utils'; import { extractExtensionsFromSchema, mergeExtensions, applyExtensions } from '../src/extensions' describe('extensions', () => { @@ -47,103 +49,170 @@ describe('extensions', () => { }); it('Should extract extensions correctly for all possible types', () => { - schema.getType('MyInput').extensions = { input: true }; - schema.getType('MyType').extensions = { type: true }; - schema.getType('Node').extensions = { interface: true }; - schema.getType('MyEnum').extensions = { enum: true }; - schema.getType('MyUnion').extensions = { union: true }; - schema.getType('MyScalar').extensions = { scalar: true }; + const MyInput = schema.getType('MyInput') + assertSome(MyInput) + MyInput.extensions = { input: true }; + const MyType = schema.getType('MyType') + assertSome(MyType) + MyType.extensions = { type: true }; + const Node = schema.getType('Node') + assertSome(Node) + Node.extensions = { interface: true }; + const MyEnum = schema.getType('MyEnum') + assertSome(MyEnum) + MyEnum.extensions = { enum: true }; + const MyUnion = schema.getType('MyUnion') + assertSome(MyUnion) + MyUnion.extensions = { union: true }; + const MyScalar = schema.getType('MyScalar') + assertSome(MyScalar) + MyScalar.extensions = { scalar: true }; const { types: extensions } = extractExtensionsFromSchema(schema); - expect(extensions.MyInput.extensions).toEqual({ input: true }) - expect(extensions.MyType.extensions).toEqual({ type: true }) - expect(extensions.Node.extensions).toEqual({ interface: true }) - expect(extensions.MyEnum.extensions).toEqual({ enum: true }) - expect(extensions.MyUnion.extensions).toEqual({ union: true }) - expect(extensions.MyScalar.extensions).toEqual({ scalar: true }) + expect(extensions['MyInput'].extensions).toEqual({ input: true }) + expect(extensions['MyType'].extensions).toEqual({ type: true }) + expect(extensions['Node'].extensions).toEqual({ interface: true }) + expect(extensions['MyEnum'].extensions).toEqual({ enum: true }) + expect(extensions['MyUnion'].extensions).toEqual({ union: true }) + expect(extensions['MyScalar'].extensions).toEqual({ scalar: true }) }); it('Should extract extensions correctly for fields arguments', () => { - schema.getQueryType().getFields().t.args[0].extensions = { fieldArg: true }; + const queryType = schema.getQueryType() + assertSome(queryType) + queryType.getFields()['t'].args[0].extensions = { fieldArg: true }; - const { types: extensions } = extractExtensionsFromSchema(schema); - expect(extensions.Query.fields.t.arguments.i).toEqual({ fieldArg: true }) + const { types: extensions } = extractExtensionsFromSchema(schema); + if (extensions['Query'].type !== "object") { + throw new Error("Unexpected type.") + } + + expect(extensions['Query'].fields['t'].arguments['i']).toEqual({ fieldArg: true }) }); it('Should extract extensions correctly for enum values', () => { - (schema.getType('MyEnum') as GraphQLEnumType).getValues()[0].extensions = { enumValue: true }; + const MyEnum = schema.getType('MyEnum') + assertGraphQLEnumType(MyEnum) + MyEnum.getValues()[0].extensions = { enumValue: true }; - const { types: extensions } = extractExtensionsFromSchema(schema); - expect(extensions.MyEnum.values.A).toEqual({ enumValue: true }); - expect(extensions.MyEnum.values.B).toEqual({}); - expect(extensions.MyEnum.values.C).toEqual({}); + const { types: extensions } = extractExtensionsFromSchema(schema); + if (extensions['MyEnum'].type !== "enum") { + throw new Error("Unexpected type.") + } + expect(extensions['MyEnum'].values['A']).toEqual({ enumValue: true }); + expect(extensions['MyEnum'].values['B']).toEqual({}); + expect(extensions['MyEnum'].values['C']).toEqual({}); }); it('Should extract extensions correctly for fields', () => { - schema.getQueryType().getFields().t.extensions = { field: true }; + const queryType = schema.getQueryType() + assertSome(queryType) + queryType.getFields()['t'].extensions = { field: true }; - const { types: extensions } = extractExtensionsFromSchema(schema); - expect(extensions.Query.fields.t.extensions).toEqual({ field: true }) + const { types: extensions } = extractExtensionsFromSchema(schema); + if (extensions['Query'].type !== "object") { + throw new Error("Unexpected type.") + } + expect(extensions['Query'].fields['t'].extensions).toEqual({ field: true }) }); it('Should extract extensions correctly for input fields', () => { - (schema.getType('MyInput') as any).getFields().foo.extensions = { inputField: true }; + const MyInput = schema.getType('MyInput') + assertGraphQLInputObjectType(MyInput) + MyInput.getFields()['foo'].extensions = { inputField: true }; - const { types: extensions } = extractExtensionsFromSchema(schema); - expect(extensions.MyInput.fields.foo.extensions).toEqual({ inputField: true }) + const { types: extensions } = extractExtensionsFromSchema(schema); + if (extensions['MyInput'].type !== "input") { + throw new Error("Unexpected type.") + } + expect(extensions['MyInput'].fields['foo'].extensions).toEqual({ inputField: true }) }); }); describe('mergeExtensions', () => { it('Should merge all extensions from 2 schemas correctly', () => { - schema.getQueryType().extensions = { queryTest: true }; + const queryType = schema.getQueryType() + assertSome(queryType) + queryType.extensions = { queryTest: true }; const secondSchema = buildSchema(/* GraphQL */` type Query { foo: String! } `); - secondSchema.getQueryType().extensions = { querySecondTest: true }; + const secondQueryType = secondSchema.getQueryType() + assertSome(secondQueryType) + secondQueryType.extensions = { querySecondTest: true }; const extensions = extractExtensionsFromSchema(schema); const secondExtensions = extractExtensionsFromSchema(secondSchema); const mergedExtensions = mergeExtensions([extensions, secondExtensions]); - expect(mergedExtensions.types.Query.extensions).toEqual({ queryTest: true, querySecondTest: true }) + expect(mergedExtensions.types['Query'].extensions).toEqual({ queryTest: true, querySecondTest: true }) }) }); describe('applyExtensionsToSchema', () => { it('Should re apply extensions to schema and types correctly', () => { schema.extensions = { schema: true }; - schema.getType('MyInput').extensions = { input: true }; - schema.getType('MyType').extensions = { type: true }; - schema.getType('Node').extensions = { interface: true }; - schema.getType('MyEnum').extensions = { enum: true }; - schema.getType('MyUnion').extensions = { union: true }; - schema.getType('MyScalar').extensions = { scalar: true }; - (schema.getType('MyInput') as any).getFields().foo.extensions = { inputField: true }; - schema.getQueryType().getFields().t.extensions = { field: true }; - (schema.getType('MyEnum') as GraphQLEnumType).getValues()[0].extensions = { enumValue: true }; - schema.getQueryType().getFields().t.args[0].extensions = { fieldArg: true }; + let MyInput = schema.getType('MyInput') + assertGraphQLInputObjectType(MyInput) + MyInput.extensions = { input: true }; + let MyType = schema.getType("MyType") + assertGraphQLObjectType(MyType) + MyType.extensions = { type: true }; + let Node = schema.getType("Node") + assertGraphQLInterfaceType(Node) + Node.extensions = { interface: true }; + let MyEnum = schema.getType('MyEnum') + assertGraphQLEnumType(MyEnum) + MyEnum.extensions = { enum: true }; + let MyUnion = schema.getType('MyUnion') + assertGraphQLUnionType(MyUnion) + MyUnion.extensions = { union: true }; + let MyScalar = schema.getType('MyScalar') + assertGraphQLScalerType(MyScalar) + MyScalar.extensions = { scalar: true }; + MyInput.getFields()['foo'].extensions = { inputField: true }; + let QueryType = schema.getQueryType(); + assertSome(QueryType) + QueryType.getFields()['t'].extensions = { field: true }; + MyEnum.getValues()[0].extensions = { enumValue: true }; + QueryType.getFields()['t'].args[0].extensions = { fieldArg: true }; const result = extractExtensionsFromSchema(schema); const cleanSchema = buildASTSchema(parse(printSchema(schema))); + MyInput = cleanSchema.getType('MyInput') + assertGraphQLInputObjectType(MyInput) // To make sure it's stripped - expect(cleanSchema.getType('MyInput').extensions).toBeUndefined(); + expect(MyInput.extensions).toBeUndefined(); const modifiedSchema = applyExtensions(cleanSchema, result); - + expect(modifiedSchema.extensions).toEqual({ schema: true }) - expect(modifiedSchema.getType('MyInput').extensions).toEqual({ input: true }); - expect(modifiedSchema.getType('MyType').extensions).toEqual({ type: true }); - expect(modifiedSchema.getType('Node').extensions).toEqual({ interface: true }); - expect(modifiedSchema.getType('MyEnum').extensions).toEqual({ enum: true }); - expect(modifiedSchema.getType('MyUnion').extensions).toEqual({ union: true }); - expect(modifiedSchema.getType('MyScalar').extensions).toEqual({ scalar: true }); - expect((modifiedSchema.getType('MyInput') as any).getFields().foo.extensions).toEqual({ inputField: true }); - expect(modifiedSchema.getQueryType().getFields().t.extensions).toEqual({ field: true }); - expect((modifiedSchema.getType('MyEnum') as GraphQLEnumType).getValues()[0].extensions).toEqual({ enumValue: true }); - expect(modifiedSchema.getQueryType().getFields().t.args[0].extensions).toEqual({ fieldArg: true }); + MyInput = modifiedSchema.getType('MyInput') + assertGraphQLInputObjectType(MyInput) + expect(MyInput.extensions).toEqual({ input: true }); + MyType = modifiedSchema.getType("MyType") + assertGraphQLObjectType(MyType) + expect(MyType.extensions).toEqual({ type: true }); + Node = modifiedSchema.getType("Node") + assertGraphQLInterfaceType(Node) + expect(Node.extensions).toEqual({ interface: true }); + MyEnum = modifiedSchema.getType('MyEnum') + assertGraphQLEnumType(MyEnum) + expect(MyEnum.extensions).toEqual({ enum: true }); + MyUnion = modifiedSchema.getType('MyUnion') + assertGraphQLUnionType(MyUnion) + expect(MyUnion.extensions).toEqual({ union: true }); + MyScalar = modifiedSchema.getType('MyScalar') + assertGraphQLScalerType(MyScalar) + expect(MyScalar.extensions).toEqual({ scalar: true }); + expect(MyInput.getFields()['foo'].extensions).toEqual({ inputField: true }); + QueryType = modifiedSchema.getQueryType(); + assertSome(QueryType) + expect(QueryType.getFields()['t'].extensions).toEqual({ field: true }); + expect(MyEnum.getValues()[0].extensions).toEqual({ enumValue: true }); + expect(QueryType.getFields()['t'].args[0].extensions).toEqual({ fieldArg: true }); }); }) -}); \ No newline at end of file +}); diff --git a/packages/merge/tests/merge-nodes.spec.ts b/packages/merge/tests/merge-nodes.spec.ts index ac7fcd12fcb..2ca7fbaa83a 100644 --- a/packages/merge/tests/merge-nodes.spec.ts +++ b/packages/merge/tests/merge-nodes.spec.ts @@ -1,5 +1,7 @@ import { mergeGraphQLNodes } from '../src'; -import { parse, InputObjectTypeDefinitionNode, EnumTypeDefinitionNode } from 'graphql'; +import { parse } from 'graphql'; +import { assertEnumTypeDefinitionNode, assertInputObjectTypeDefinitionNode, assertNamedTypeNode, assertObjectTypeDefinitionNode, assertScalarTypeDefinitionNode, assertUnionTypeDefinitionNode } from '../../testing/assertion'; +import { assertSome } from '@graphql-tools/utils'; describe('Merge Nodes', () => { describe('type', () => { @@ -7,10 +9,12 @@ describe('Merge Nodes', () => { const type1 = parse(`type A { f1: String }`); const type2 = parse(`type A`); const merged = mergeGraphQLNodes([...type1.definitions, ...type2.definitions]); - const type: any = merged.A; - + const type = merged['A']; + assertObjectTypeDefinitionNode(type) + assertSome(type.fields) expect(type.fields.length).toBe(1); expect(type.fields[0].name.value).toBe('f1'); + assertNamedTypeNode(type.fields[0].type) expect(type.fields[0].type.name.value).toBe('String'); }); @@ -18,12 +22,16 @@ describe('Merge Nodes', () => { const type1 = parse(`type A { f1: String }`); const type2 = parse(`type A { f2: Int }`); const merged = mergeGraphQLNodes([...type1.definitions, ...type2.definitions]); - const type: any = merged.A; + const type = merged['A']; + assertObjectTypeDefinitionNode(type) + assertSome(type.fields) expect(type.fields.length).toBe(2); expect(type.fields[0].name.value).toBe('f1'); expect(type.fields[1].name.value).toBe('f2'); + assertNamedTypeNode(type.fields[0].type) expect(type.fields[0].type.name.value).toBe('String'); + assertNamedTypeNode(type.fields[1].type) expect(type.fields[1].type.name.value).toBe('Int'); }); @@ -31,12 +39,16 @@ describe('Merge Nodes', () => { const type1 = parse(`type A { f1: String }`); const type2 = parse(`type A { f1: String, f2: Int}`); const merged = mergeGraphQLNodes([...type1.definitions, ...type2.definitions]); - const type: any = merged.A; + const type = merged['A']; + assertObjectTypeDefinitionNode(type) + assertSome(type.fields) expect(type.fields.length).toBe(2); expect(type.fields[0].name.value).toBe('f1'); expect(type.fields[1].name.value).toBe('f2'); + assertNamedTypeNode(type.fields[0].type) expect(type.fields[0].type.name.value).toBe('String'); + assertNamedTypeNode(type.fields[1].type) expect(type.fields[1].type.name.value).toBe('Int'); }); @@ -44,7 +56,9 @@ describe('Merge Nodes', () => { const type1 = parse(`interface Base { f1: String } type A implements Base { f1: String }`); const type2 = parse(`interface Base { f1: String } type A implements Base { f2: Int}`); const merged = mergeGraphQLNodes([...type1.definitions, ...type2.definitions]); - const type: any = merged.A; + const type = merged['A']; + assertObjectTypeDefinitionNode(type) + assertSome(type.interfaces) expect(type.interfaces.length).toBe(1); expect(type.interfaces[0].name.value).toBe('Base'); @@ -54,7 +68,9 @@ describe('Merge Nodes', () => { const type1 = parse(`interface Base { f1: String } type A implements Base { f1: String }`); const type2 = parse(`type A { f2: Int}`); const merged = mergeGraphQLNodes([...type1.definitions, ...type2.definitions]); - const type: any = merged.A; + const type = merged['A']; + assertObjectTypeDefinitionNode(type) + assertSome(type.interfaces) expect(type.interfaces.length).toBe(1); expect(type.interfaces[0].name.value).toBe('Base'); @@ -64,7 +80,9 @@ describe('Merge Nodes', () => { const type1 = parse(`type A @test { f1: String }`); const type2 = parse(`type A { f2: Int}`); const merged = mergeGraphQLNodes([...type1.definitions, ...type2.definitions]); - const type: any = merged.A; + const type = merged['A']; + assertObjectTypeDefinitionNode(type) + assertSome(type.directives) expect(type.directives.length).toBe(1); expect(type.directives[0].name.value).toBe('test'); @@ -74,7 +92,9 @@ describe('Merge Nodes', () => { const type1 = parse(`type A @test { f1: String }`); const type2 = parse(`type A @other { f2: Int}`); const merged = mergeGraphQLNodes([...type1.definitions, ...type2.definitions]); - const type: any = merged.A; + const type = merged['A']; + assertObjectTypeDefinitionNode(type) + assertSome(type.directives) expect(type.directives.length).toBe(2); expect(type.directives[0].name.value).toBe('test'); @@ -85,7 +105,9 @@ describe('Merge Nodes', () => { const type1 = parse(`type A @test { f1: String }`); const type2 = parse(`type A @test { f2: Int}`); const merged = mergeGraphQLNodes([...type1.definitions, ...type2.definitions]); - const type: any = merged.A; + const type = merged['A']; + assertObjectTypeDefinitionNode(type) + assertSome(type.directives) expect(type.directives.length).toBe(1); expect(type.directives[0].name.value).toBe('test'); @@ -95,7 +117,9 @@ describe('Merge Nodes', () => { const type1 = parse(`type A @test { f1: String }`); const type2 = parse(`type A @test2 { f2: Int}`); const merged = mergeGraphQLNodes([...type1.definitions, ...type2.definitions]); - const type: any = merged.A; + const type = merged['A']; + assertObjectTypeDefinitionNode(type) + assertSome(type.directives) expect(type.directives.length).toBe(2); expect(type.directives[0].name.value).toBe('test'); @@ -108,7 +132,9 @@ describe('Merge Nodes', () => { const merged = mergeGraphQLNodes([...type1.definitions, ...type2.definitions], { reverseDirectives: true, }); - const type: any = merged.A; + const type = merged['A']; + assertObjectTypeDefinitionNode(type) + assertSome(type.directives) expect(type.directives.length).toBe(2); expect(type.directives[0].name.value).toBe('test2'); @@ -119,7 +145,9 @@ describe('Merge Nodes', () => { const type1 = parse(`interface Base1 { f1: String } type A implements Base1 { f1: String }`); const type2 = parse(`interface Base2 { f2: Int } type A implements Base2 { f2: Int}`); const merged = mergeGraphQLNodes([...type1.definitions, ...type2.definitions]); - const type: any = merged.A; + const type = merged['A']; + assertObjectTypeDefinitionNode(type) + assertSome(type.interfaces) expect(type.interfaces.length).toBe(2); expect(type.interfaces[0].name.value).toBe('Base1'); @@ -140,8 +168,9 @@ describe('Merge Nodes', () => { const type1 = parse(`enum A { T }`); const type2 = parse(`enum A { S }`); const merged = mergeGraphQLNodes([...type1.definitions, ...type2.definitions]); - const result = merged.A as EnumTypeDefinitionNode; - + const result = merged['A'] + assertEnumTypeDefinitionNode(result) + assertSome(result.values) expect(result.values.length).toBe(2); expect(result.values.findIndex(v => v.name.value === 'T')).not.toBe(-1); expect(result.values.findIndex(v => v.name.value === 'S')).not.toBe(-1); @@ -151,7 +180,9 @@ describe('Merge Nodes', () => { const type1 = parse(`enum A { T }`); const type2 = parse(`enum A { T }`); const merged = mergeGraphQLNodes([...type1.definitions, ...type2.definitions]); - const result: any = merged.A; + const result = merged['A']; + assertEnumTypeDefinitionNode(result) + assertSome(result.values) expect(result.values.length).toBe(1); expect(result.values[0].name.value).toBe('T'); @@ -161,7 +192,9 @@ describe('Merge Nodes', () => { const type1 = parse(`enum A @test { T }`); const type2 = parse(`enum A @test2 { T }`); const merged = mergeGraphQLNodes([...type1.definitions, ...type2.definitions]); - const result: any = merged.A; + const result = merged['A']; + assertEnumTypeDefinitionNode(result) + assertSome(result.directives) expect(result.directives.length).toBe(2); expect(result.directives[0].name.value).toBe('test'); @@ -172,7 +205,9 @@ describe('Merge Nodes', () => { const type1 = parse(`enum A @test { T }`); const type2 = parse(`enum A { S }`); const merged = mergeGraphQLNodes([...type1.definitions, ...type2.definitions]); - const result: any = merged.A; + const result = merged['A']; + assertEnumTypeDefinitionNode(result) + assertSome(result.directives) expect(result.directives.length).toBe(1); expect(result.directives[0].name.value).toBe('test'); @@ -184,7 +219,9 @@ describe('Merge Nodes', () => { const type1 = parse(`type A union C = A`); const type2 = parse(`type B union C = B`); const merged = mergeGraphQLNodes([...type1.definitions, ...type2.definitions]); - const result: any = merged.C; + const result = merged['C']; + assertUnionTypeDefinitionNode(result) + assertSome(result.types) expect(result.types.length).toBe(2); expect(result.types[0].name.value).toBe('A'); @@ -197,7 +234,8 @@ describe('Merge Nodes', () => { const type1 = parse(`scalar A`); const type2 = parse(`scalar A`); const merged = mergeGraphQLNodes([...type1.definitions, ...type2.definitions]); - const result: any = merged.A; + const result = merged['A']; + assertScalarTypeDefinitionNode(result) expect(result.name.value).toBe('A'); }); @@ -208,7 +246,9 @@ describe('Merge Nodes', () => { const type1 = parse(`input A { f1: String }`); const type2 = parse(`input A { f2: String }`); const merged = mergeGraphQLNodes([...type1.definitions, ...type2.definitions]); - const result: any = merged.A; + const result = merged['A']; + assertInputObjectTypeDefinitionNode(result) + assertSome(result.fields) expect(result.fields.length).toBe(2); expect(result.fields[0].name.value).toBe('f1'); @@ -219,7 +259,9 @@ describe('Merge Nodes', () => { const type1 = parse(`input A { f1: String }`); const type2 = parse(`input A { f1: String! }`); const merged = mergeGraphQLNodes([...type1.definitions, ...type2.definitions]); - const result: InputObjectTypeDefinitionNode = merged.A as any; + const result = merged['A']; + assertInputObjectTypeDefinitionNode(result) + assertSome(result.fields) expect(result.fields.length).toBe(1); expect(result.fields[0].name.value).toBe('f1'); @@ -232,12 +274,16 @@ describe('Merge Nodes', () => { const type1 = parse(`type Query { f1: String }`); const type2 = parse(`type Query { f2: String }`); const merged = mergeGraphQLNodes([...type1.definitions, ...type2.definitions]); - const type: any = merged.Query; + const type = merged['Query']; + assertObjectTypeDefinitionNode(type) + assertSome(type.fields) expect(type.fields.length).toBe(2); expect(type.fields[0].name.value).toBe('f1'); expect(type.fields[1].name.value).toBe('f2'); + assertNamedTypeNode(type.fields[0].type) expect(type.fields[0].type.name.value).toBe('String'); + assertNamedTypeNode(type.fields[1].type) expect(type.fields[1].type.name.value).toBe('String'); }); diff --git a/packages/merge/tests/merge-schemas.spec.ts b/packages/merge/tests/merge-schemas.spec.ts index 24aee3cd1ad..03d5da68988 100644 --- a/packages/merge/tests/merge-schemas.spec.ts +++ b/packages/merge/tests/merge-schemas.spec.ts @@ -1,7 +1,8 @@ import { makeExecutableSchema } from '@graphql-tools/schema'; -import { graphql, buildSchema, GraphQLScalarType, Kind, GraphQLSchema, ListValueNode, print } from 'graphql'; +import { graphql, buildSchema, GraphQLScalarType, Kind, GraphQLSchema, print } from 'graphql'; import { mergeSchemas, mergeSchemasAsync } from '../src/merge-schemas'; -import { printSchemaWithDirectives } from '@graphql-tools/utils'; +import { assertSome, printSchemaWithDirectives } from '@graphql-tools/utils'; +import { assertListValueNode } from '../../testing/assertion'; describe('Merge Schemas', () => { it('Should include extensions in merged schemas', () => { @@ -76,8 +77,9 @@ describe('Merge Schemas', () => { ` }); expect(errors).toBeFalsy(); - expect(data.foo).toBe('FOO'); - expect(data.bar).toBe('BAR'); + assertSome(data) + expect(data['foo']).toBe('FOO'); + expect(data['bar']).toBe('BAR'); }); it('should merge two valid executable schemas async', async () => { const fooSchema = makeExecutableSchema({ @@ -116,8 +118,9 @@ describe('Merge Schemas', () => { ` }); expect(errors).toBeFalsy(); - expect(data.foo).toBe('FOO'); - expect(data.bar).toBe('BAR'); + assertSome(data) + expect(data['foo']).toBe('FOO'); + expect(data['bar']).toBe('BAR'); }); it('should merge two valid executable schemas with extra resolvers', async () => { const fooSchema = makeExecutableSchema({ @@ -163,9 +166,10 @@ describe('Merge Schemas', () => { ` }); expect(errors).toBeFalsy(); - expect(data.foo).toBe('FOO'); - expect(data.bar).toBe('BAR'); - expect(data.qux).toBe('QUX'); + assertSome(data) + expect(data['foo']).toBe('FOO'); + expect(data['bar']).toBe('BAR'); + expect(data['qux']).toBe('QUX'); }); it('should merge two valid executable schemas with extra typeDefs and resolvers', async () => { const fooSchema = makeExecutableSchema({ @@ -215,9 +219,10 @@ describe('Merge Schemas', () => { ` }); expect(errors).toBeFalsy(); - expect(data.foo).toBe('FOO'); - expect(data.bar).toBe('BAR'); - expect(data.qux).toBe('QUX'); + assertSome(data) + expect(data['foo']).toBe('FOO'); + expect(data['bar']).toBe('BAR'); + expect(data['qux']).toBe('QUX'); }); it('should merge two valid schemas by keeping their directives to be used in extra typeDefs', async () => { const fooSchema = makeExecutableSchema({ @@ -268,9 +273,10 @@ describe('Merge Schemas', () => { ` }); expect(errors).toBeFalsy(); - expect(data.foo).toBe('FOO'); - expect(data.bar).toBe('BAR'); - expect(data.qux).toBe('QUX'); + assertSome(data) + expect(data['foo']).toBe('FOO'); + expect(data['bar']).toBe('BAR'); + expect(data['qux']).toBe('QUX'); }); it('should merge valid schemas with interfaces correctly', async () => { const fooSchema = makeExecutableSchema({ @@ -338,10 +344,11 @@ describe('Merge Schemas', () => { ` }); expect(errors).toBeFalsy(); - expect(data.bar.foo).toBe('foo'); - expect(data.bar.bar).toBe('bar'); - expect(data.qux.foo).toBe('foo'); - expect(data.qux.qux).toBe('qux'); + assertSome(data) + expect(data['bar'].foo).toBe('foo'); + expect(data['bar'].bar).toBe('bar'); + expect(data['qux'].foo).toBe('foo'); + expect(data['qux'].qux).toBe('qux'); }); it('should merge scalars (part of resolvers)', async () => { @@ -381,15 +388,16 @@ describe('Merge Schemas', () => { source: /* GraphQL */` { a } ` }); - expect(dataA.a).toEqual(now.toISOString()); + assertSome(dataA) + expect(dataA['a']).toEqual(now.toISOString()); // merged schema const { data } = await graphql({ schema, source: /* GraphQL */` { a } ` }); - - expect(data.a).toEqual(now.toISOString()); + assertSome(data) + expect(data['a']).toEqual(now.toISOString()); }); it.only('should not duplicate directives of scalars', () => { @@ -436,8 +444,16 @@ describe('Merge Schemas', () => { while (num--) { prev = mergeSchemas({schemas: [prev, base]}); } + const QueryType = prev.getQueryType() + assertSome(QueryType) + const fields = QueryType.getFields() + assertSome(fields['test'].astNode) + assertSome(fields['test'].astNode.directives) + assertSome(fields['test'].astNode.directives[0]) + assertSome(fields['test'].astNode.directives[0].arguments) + assertListValueNode(fields['test'].astNode.directives[0].arguments[0].value) - expect((prev.getQueryType().getFields().test.astNode.directives[0].arguments[0].value as ListValueNode).values).toHaveLength(1); + expect(fields['test'].astNode.directives[0].arguments[0].value.values).toHaveLength(1); }); it('should merge schemas with custom scalars', () => { const GraphQLUUID = new GraphQLScalarType({ diff --git a/packages/merge/tests/merge-typedefs.spec.ts b/packages/merge/tests/merge-typedefs.spec.ts index 7dfc1f55afd..eb3df437285 100644 --- a/packages/merge/tests/merge-typedefs.spec.ts +++ b/packages/merge/tests/merge-typedefs.spec.ts @@ -7,7 +7,7 @@ import { stripWhitespaces } from './utils'; import gql from 'graphql-tag'; import { readFileSync } from 'fs'; import { join } from 'path'; -import {jest} from '@jest/globals'; +import { assertSome } from '@graphql-tools/utils'; const introspectionSchema = JSON.parse(readFileSync(join(__dirname, './schema.json'), 'utf8')); @@ -202,7 +202,7 @@ describe('Merge TypeDefs', () => { const queryType = schema.getQueryType(); expect(queryType).toBeDefined(); - expect(queryType).not.toBeNull(); + assertSome(queryType) expect(queryType.name).toEqual('RootQuery'); }); @@ -656,7 +656,6 @@ describe('Merge TypeDefs', () => { const merged = mergeTypeDefs([ makeExecutableSchema({ typeDefs: ['type Query { f1: String }'], - allowUndefinedInResolve: true, }), 'type Query { f2: String }', ]); @@ -678,11 +677,9 @@ describe('Merge TypeDefs', () => { const merged = mergeTypeDefs([ makeExecutableSchema({ typeDefs: ['type RootQuery { f1: String }'], - allowUndefinedInResolve: true, }), makeExecutableSchema({ typeDefs: ['type RootQuery { f2: String }', 'schema { query: RootQuery }'], - allowUndefinedInResolve: true, }), ]); @@ -703,7 +700,6 @@ describe('Merge TypeDefs', () => { const merged = mergeTypeDefs([ makeExecutableSchema({ typeDefs: ['type Query { f1: String }'], - allowUndefinedInResolve: true, }), 'type Query { f2: String }', gql` @@ -731,7 +727,6 @@ describe('Merge TypeDefs', () => { const merged = mergeTypeDefs([ makeExecutableSchema({ typeDefs: ['type MyType { f1: String }'], - allowUndefinedInResolve: true, }), ]); @@ -746,11 +741,9 @@ describe('Merge TypeDefs', () => { const merged = mergeTypeDefs([ makeExecutableSchema({ typeDefs: ['type MyType { f1: String }'], - allowUndefinedInResolve: true, }), makeExecutableSchema({ typeDefs: ['type MyType { f2: String }'], - allowUndefinedInResolve: true, }), ]); diff --git a/packages/mock/package.json b/packages/mock/package.json index e76092de5b2..fa16db31983 100644 --- a/packages/mock/package.json +++ b/packages/mock/package.json @@ -33,10 +33,11 @@ }, "dependencies": { "@graphql-tools/schema": "^7.0.0", + "@graphql-tools/merge": "6.2.14", "@graphql-tools/utils": "^7.0.0", "fast-json-stable-stringify": "^2.1.0", "ts-is-defined": "^1.0.0", - "tslib": "~2.2.0" + "tslib": "~2.3.0" }, "devDependencies": { "casual": "1.6.2" diff --git a/packages/mock/src/MockList.ts b/packages/mock/src/MockList.ts index 7da5e7446ad..6af0f9f23f5 100644 --- a/packages/mock/src/MockList.ts +++ b/packages/mock/src/MockList.ts @@ -17,7 +17,7 @@ export function isMockList(obj: any): obj is MockList { */ export class MockList { private readonly len: number | Array; - private readonly wrappedFunction: () => unknown; + private readonly wrappedFunction: undefined | (() => unknown); /** * @param length Either the exact length of items to return or an inclusive diff --git a/packages/mock/src/MockStore.ts b/packages/mock/src/MockStore.ts index 14d982eda8c..69e4ea10cf7 100644 --- a/packages/mock/src/MockStore.ts +++ b/packages/mock/src/MockStore.ts @@ -237,7 +237,7 @@ export class MockStore implements IMockStore { if (!isRecord(value)) { throw new Error('When no `fieldName` is provided, `value` should be a record.'); } - for (const fieldName of Object.keys(value)) { + for (const fieldName in value) { this.setImpl({ typeName, key, @@ -333,7 +333,7 @@ export class MockStore implements IMockStore { return this.normalizeValueToStore( nullableFieldType.ofType, v, - currentValue && currentValue[index] ? currentValue : undefined, + typeof currentValue === 'object' && currentValue != null && currentValue[index] ? currentValue : undefined, onInsertType ); }); @@ -368,7 +368,7 @@ export class MockStore implements IMockStore { } const toInsert = { ...otherValues, ...values }; - for (const fieldName of Object.keys(toInsert)) { + for (const fieldName in toInsert) { if (fieldName === '$ref') continue; if (fieldName === '__typename') continue; this.set({ @@ -410,7 +410,7 @@ export class MockStore implements IMockStore { throw new Error(`Value returned by the mock for ${typeName} is not an object`); } - for (const otherFieldName of Object.keys(values)) { + for (const otherFieldName in values) { if (otherFieldName === fieldName) continue; if (typeof (values as any)[otherFieldName] === 'function') continue; onOtherFieldsGenerated && onOtherFieldsGenerated(otherFieldName, (values as any)[otherFieldName]); @@ -418,7 +418,7 @@ export class MockStore implements IMockStore { value = (values as any)[fieldName]; if (typeof value === 'function') value = value(); - } else if (typeof mock[fieldName] === 'function') { + } else if (typeof mock === 'object' && mock != null && typeof mock[fieldName] === 'function') { value = mock[fieldName](); } } @@ -488,7 +488,7 @@ export class MockStore implements IMockStore { throw new Error(`Please return a __typename in "${nullableType.name}"`); } typeName = values['__typename']; - } else if (typeof mock['__typename'] === 'function') { + } else if (typeof mock === 'object' && mock != null && typeof mock['__typename'] === 'function') { const mockRes = mock['__typename'](); if (typeof mockRes !== 'string') throw new Error(`'__typename' returned by the mock for abstract type ${nullableType.name} is not a string`); @@ -498,7 +498,7 @@ export class MockStore implements IMockStore { } const toInsert = {}; - for (const fieldName of Object.keys(values)) { + for (const fieldName in values) { if (fieldName === '__typename') continue; const fieldValue = (values as any)[fieldName]; toInsert[fieldName] = typeof fieldValue === 'function' ? fieldValue() : fieldValue; diff --git a/packages/mock/src/mockServer.ts b/packages/mock/src/mockServer.ts index 301e9ebcf55..bb3bc2a9123 100644 --- a/packages/mock/src/mockServer.ts +++ b/packages/mock/src/mockServer.ts @@ -1,6 +1,6 @@ -import { ITypeDefinitions } from '@graphql-tools/utils'; -import { GraphQLSchema, isSchema, graphql } from 'graphql'; -import { buildSchemaFromTypeDefinitions } from '@graphql-tools/schema'; +import { TypeSource } from '@graphql-tools/utils'; +import { GraphQLSchema, isSchema, graphql, buildASTSchema } from 'graphql'; +import { mergeTypeDefs } from '@graphql-tools/merge'; import { addMocksToSchema } from './addMocksToSchema'; import { IMockServer, IMocks } from './types'; @@ -16,15 +16,11 @@ import { IMockServer, IMocks } from './types'; * overwritten to provide mock data. This can be used to mock some parts of the * server and not others. */ -export function mockServer( - schema: GraphQLSchema | ITypeDefinitions, - mocks: IMocks, - preserveResolvers = false -): IMockServer { +export function mockServer(schema: TypeSource, mocks: IMocks, preserveResolvers = false): IMockServer { let mySchema: GraphQLSchema; if (!isSchema(schema)) { // TODO: provide useful error messages here if this fails - mySchema = buildSchemaFromTypeDefinitions(schema); + mySchema = buildASTSchema(mergeTypeDefs(schema)); } else { mySchema = schema; } diff --git a/packages/mock/src/types.ts b/packages/mock/src/types.ts index e9307bdaa55..92db067b0ba 100644 --- a/packages/mock/src/types.ts +++ b/packages/mock/src/types.ts @@ -190,7 +190,7 @@ export type Ref = { }; export function isRef(maybeRef: unknown): maybeRef is Ref { - return maybeRef && typeof maybeRef === 'object' && maybeRef.hasOwnProperty('$ref'); + return !!(maybeRef && typeof maybeRef === 'object' && '$ref' in maybeRef); } export function assertIsRef( diff --git a/packages/mock/src/utils.ts b/packages/mock/src/utils.ts index e36d784446b..76edccb11ba 100644 --- a/packages/mock/src/utils.ts +++ b/packages/mock/src/utils.ts @@ -26,21 +26,21 @@ export function isObject(thing: any) { } export function copyOwnPropsIfNotPresent(target: Record, source: Record) { - Object.getOwnPropertyNames(source).forEach(prop => { + for (const prop of Object.getOwnPropertyNames(source)) { if (!Object.getOwnPropertyDescriptor(target, prop)) { const propertyDescriptor = Object.getOwnPropertyDescriptor(source, prop); Object.defineProperty(target, prop, propertyDescriptor == null ? {} : propertyDescriptor); } - }); + } } export function copyOwnProps(target: Record, ...sources: Array>) { - sources.forEach(source => { + for (const source of sources) { let chain = source; while (chain != null) { copyOwnPropsIfNotPresent(target, chain); chain = Object.getPrototypeOf(chain); } - }); + } return target; } diff --git a/packages/mock/tests/addMocksToSchema.spec.ts b/packages/mock/tests/addMocksToSchema.spec.ts index 15bc84d82b9..24f46e010b7 100644 --- a/packages/mock/tests/addMocksToSchema.spec.ts +++ b/packages/mock/tests/addMocksToSchema.spec.ts @@ -1,5 +1,5 @@ import { buildSchema, graphql } from 'graphql'; -import { addMocksToSchema, assertIsRef, createMockStore } from '../src'; +import { addMocksToSchema, assertIsRef, createMockStore, isRef } from '../src'; const typeDefs = ` type User { @@ -267,8 +267,8 @@ describe('addMocksToSchema', () => { source: query }); - expect(data.foo.field1).toBe('text'); - expect(data.foo.field2).toBe(null); + expect(data?.['foo'].field1).toBe('text'); + expect(data?.['foo'].field2).toBe(null); }) it('should handle null fields correctly in nested fields', async () => { const schema = buildSchema(/* GraphQL */` @@ -309,7 +309,12 @@ describe('addMocksToSchema', () => { }); expect(errors).toBeFalsy(); - expect(data.foo.foo_field).toBe('text'); - expect(data.foo.boo).toBe(null); + expect(data?.['foo'].foo_field).toBe('text'); + expect(data?.['foo'].boo).toBe(null); + }); + it('handle objects without object prototype correctly', () => { + const maybeRef = Object.create(null); + maybeRef.$ref = {}; + expect(isRef(maybeRef)).toBeTruthy(); }); }); diff --git a/packages/mock/tests/mocking-compatibility.spec.ts b/packages/mock/tests/mocking-compatibility.spec.ts index c2c85745137..fd94b338287 100644 --- a/packages/mock/tests/mocking-compatibility.spec.ts +++ b/packages/mock/tests/mocking-compatibility.spec.ts @@ -11,7 +11,6 @@ import { sentence, first_name } from 'casual'; import { addMocksToSchema, MockList, mockServer, IMocks, IMockStore } from '../src'; import { addResolversToSchema, - buildSchemaFromTypeDefinitions, makeExecutableSchema, } from '@graphql-tools/schema'; @@ -100,7 +99,7 @@ describe('Mock retro-compatibility', () => { }); test('throws an error if second argument is not a Map', () => { - const jsSchema = buildSchemaFromTypeDefinitions(shorthand); + const jsSchema = buildSchema(shorthand); expect(() => addMocksToSchema({ schema: jsSchema, @@ -110,7 +109,7 @@ describe('Mock retro-compatibility', () => { }); test('mocks the default types for you', () => { - let jsSchema = buildSchemaFromTypeDefinitions(shorthand); + let jsSchema = buildSchema(shorthand); const mockMap = {}; jsSchema = addMocksToSchema({ schema: jsSchema, mocks: mockMap }); const testQuery = `{ @@ -121,13 +120,13 @@ describe('Mock retro-compatibility', () => { returnID }`; return graphql(jsSchema, testQuery).then((res) => { - expect(res.data.returnInt).toBeGreaterThanOrEqual(-1000); - expect(res.data.returnInt).toBeLessThanOrEqual(1000); - expect(res.data.returnFloat).toBeGreaterThanOrEqual(-1000); - expect(res.data.returnFloat).toBeLessThanOrEqual(1000); - expect(typeof res.data.returnBoolean).toBe('boolean'); - expect(typeof res.data.returnString).toBe('string'); - expect(typeof res.data.returnID).toBe('string'); + expect(res.data?.['returnInt']).toBeGreaterThanOrEqual(-1000); + expect(res.data?.['returnInt']).toBeLessThanOrEqual(1000); + expect(res.data?.['returnFloat']).toBeGreaterThanOrEqual(-1000); + expect(res.data?.['returnFloat']).toBeLessThanOrEqual(1000); + expect(typeof res.data?.['returnBoolean']).toBe('boolean'); + expect(typeof res.data?.['returnString']).toBe('string'); + expect(typeof res.data?.['returnID']).toBe('string'); }); }); @@ -171,7 +170,7 @@ describe('Mock retro-compatibility', () => { }); test('mockServer is able to preserveResolvers of a prebuilt schema', () => { - let jsSchema = buildSchemaFromTypeDefinitions(shorthand); + let jsSchema = buildSchema(shorthand); const resolvers = { RootQuery: { returnString: () => 'someString', @@ -208,7 +207,7 @@ describe('Mock retro-compatibility', () => { }); test('lets you use mockServer with prebuilt schema', () => { - const jsSchema = buildSchemaFromTypeDefinitions(shorthand); + const jsSchema = buildSchema(shorthand); const testQuery = `{ returnInt returnFloat @@ -248,7 +247,7 @@ describe('Mock retro-compatibility', () => { }); test('does not mask resolveType functions if you tell it not to', () => { - let jsSchema = buildSchemaFromTypeDefinitions(shorthand); + let jsSchema = buildSchema(shorthand); let spy = 0; const resolvers = { BirdsAndBees: { @@ -284,19 +283,19 @@ describe('Mock retro-compatibility', () => { // TODO test mockServer with precompiled schema test('can mock Enum', () => { - let jsSchema = buildSchemaFromTypeDefinitions(shorthand); + let jsSchema = buildSchema(shorthand); const mockMap = {}; jsSchema = addMocksToSchema({ schema: jsSchema, mocks: mockMap }); const testQuery = `{ returnEnum }`; return graphql(jsSchema, testQuery).then((res) => { - expect(['A', 'B', 'C']).toContain(res.data.returnEnum); + expect(['A', 'B', 'C']).toContain(res.data?.['returnEnum']); }); }); test('can mock Enum with a certain value', () => { - let jsSchema = buildSchemaFromTypeDefinitions(shorthand); + let jsSchema = buildSchema(shorthand); const mockMap = { SomeEnum: () => 'C', }; @@ -305,12 +304,12 @@ describe('Mock retro-compatibility', () => { returnEnum }`; return graphql(jsSchema, testQuery).then((res) => { - expect('C').toBe(res.data.returnEnum); + expect('C').toBe(res.data?.['returnEnum']); }); }); test('can mock Unions', () => { - let jsSchema = buildSchemaFromTypeDefinitions(shorthand); + let jsSchema = buildSchema(shorthand); const mockMap = { Int: () => 10, String: () => 'aha', @@ -334,13 +333,13 @@ describe('Mock retro-compatibility', () => { }`; return graphql(jsSchema, testQuery).then((res) => { // XXX this test is expected to fail once every 2^40 times ;-) - expect(res.data.returnBirdsAndBees).toContainEqual( + expect(res.data?.['returnBirdsAndBees']).toContainEqual( expect.objectContaining({ returnInt: 10, returnString: 'aha', }), ); - return expect(res.data.returnBirdsAndBees).toContainEqual( + return expect(res.data?.['returnBirdsAndBees']).toContainEqual( expect.objectContaining({ returnInt: 10, returnEnum: 'A', @@ -350,7 +349,7 @@ describe('Mock retro-compatibility', () => { }); test('can mock Interfaces by default', () => { - let jsSchema = buildSchemaFromTypeDefinitions(shorthand); + let jsSchema = buildSchema(shorthand); const mockMap = { Int: () => 10, String: () => 'aha', @@ -376,13 +375,13 @@ describe('Mock retro-compatibility', () => { } }`; return graphql(jsSchema, testQuery).then((res) => { - expect(res.data.returnFlying).toContainEqual( + expect(res.data?.['returnFlying']).toContainEqual( expect.objectContaining({ returnInt: 10, returnString: 'aha', }), ); - return expect(res.data.returnFlying).toContainEqual( + return expect(res.data?.['returnFlying']).toContainEqual( expect.objectContaining({ returnInt: 10, returnEnum: 'A', @@ -392,7 +391,7 @@ describe('Mock retro-compatibility', () => { }); it('can mock nullable Interfaces', () => { - let jsSchema = buildSchemaFromTypeDefinitions(shorthand); + let jsSchema = buildSchema(shorthand); const mockMap = { Bird: (): null => null, @@ -421,7 +420,7 @@ describe('Mock retro-compatibility', () => { }`; return graphql(jsSchema, testQuery).then((res) => { - expect(res.data.node).toEqual(null); + expect(res.data?.['node']).toEqual(null); }); }); @@ -449,7 +448,7 @@ describe('Mock retro-compatibility', () => { const res = await server.query(testQuery); - expect(res.data.node).toEqual({ + expect(res.data?.['node']).toEqual({ id: 'bee:hardcoded', returnAbility: { name: 'Hello World', @@ -458,7 +457,7 @@ describe('Mock retro-compatibility', () => { }); test('can support explicit Interface mock with resolver', () => { - let jsSchema = buildSchemaFromTypeDefinitions(shorthand); + let jsSchema = buildSchema(shorthand); let spy = 0; const mockMap = { Bird: () => ({ @@ -480,7 +479,7 @@ describe('Mock retro-compatibility', () => { const __typename = ['Bird', 'Bee'].find( (r) => r.toLowerCase() === type, ); - return store.get(__typename, id); + return __typename && store.get(__typename, id); } } }); @@ -499,7 +498,7 @@ describe('Mock retro-compatibility', () => { return graphql(jsSchema, testQuery).then((res) => { expect(spy).toBe(1); // to make sure that Flying possible types are not randomly selected - expect(res.data.node).toMatchObject({ + expect(res.data?.['node']).toMatchObject({ id: 'bee:123456', returnSong: 'I believe i can fly', returnInt: 200, @@ -508,7 +507,7 @@ describe('Mock retro-compatibility', () => { }); test('can support explicit UnionType mock', () => { - let jsSchema = buildSchemaFromTypeDefinitions(shorthand); + let jsSchema = buildSchema(shorthand); let spy = 0; const mockMap = { Bird: () => ({ @@ -541,7 +540,7 @@ describe('Mock retro-compatibility', () => { return graphql(jsSchema, testQuery).then((res) => { expect(spy).toBe(1); - expect(res.data.node2).toMatchObject({ + expect(res.data?.['node2']).toMatchObject({ id: 'bee:hardcoded', returnEnum: 'A', }); @@ -549,7 +548,7 @@ describe('Mock retro-compatibility', () => { }); test('throws an error when __typename is not returned within an explicit interface mock', () => { - let jsSchema = buildSchemaFromTypeDefinitions(shorthand); + let jsSchema = buildSchema(shorthand); const mockMap = { Bird: (_root: any, args: any) => ({ id: args.id, @@ -570,12 +569,12 @@ describe('Mock retro-compatibility', () => { }`; const expected = 'Please return a __typename in "Flying"'; return graphql(jsSchema, testQuery).then((res) => { - expect(res.errors[0].originalError.message).toBe(expected); + expect(res.errors?.[0].originalError?.message).toBe(expected); }); }); test('throws an error in resolve if mock type is not defined', () => { - let jsSchema = buildSchemaFromTypeDefinitions(shorthand); + let jsSchema = buildSchema(shorthand); const mockMap = {}; jsSchema = addMocksToSchema({ schema: jsSchema, mocks: mockMap }); const testQuery = `{ @@ -583,12 +582,12 @@ describe('Mock retro-compatibility', () => { }`; const expected = 'No mock defined for type "MissingMockType"'; return graphql(jsSchema, testQuery).then((res) => { - expect(res.errors[0].originalError.message).toBe(expected); + expect(res.errors?.[0].originalError?.message).toBe(expected); }); }); test('throws an error in resolve if mock type is not defined and resolver failed', () => { - let jsSchema = buildSchemaFromTypeDefinitions(shorthand); + let jsSchema = buildSchema(shorthand); const resolvers = { MissingMockType: { __serialize: (val: string) => val, @@ -596,7 +595,7 @@ describe('Mock retro-compatibility', () => { __parseLiteral: (val: string) => val, }, RootQuery: { - returnMockError: (): string => undefined, + returnMockError: () => undefined, }, }; jsSchema = addResolversToSchema(jsSchema, resolvers); @@ -612,12 +611,12 @@ describe('Mock retro-compatibility', () => { }`; const expected = 'No mock defined for type "MissingMockType"'; return graphql(jsSchema, testQuery).then((res) => { - expect(res.errors[0].originalError.message).toBe(expected); + expect(res.errors?.[0].originalError?.message).toBe(expected); }); }); test('can preserve scalar resolvers', () => { - let jsSchema = buildSchemaFromTypeDefinitions(shorthand); + let jsSchema = buildSchema(shorthand); const resolvers = { MissingMockType: { __serialize: (val: string) => val, @@ -649,85 +648,85 @@ describe('Mock retro-compatibility', () => { }); test('can mock an Int', () => { - let jsSchema = buildSchemaFromTypeDefinitions(shorthand); + let jsSchema = buildSchema(shorthand); const mockMap = { Int: () => 55 }; jsSchema = addMocksToSchema({ schema: jsSchema, mocks: mockMap }); const testQuery = `{ returnInt }`; return graphql(jsSchema, testQuery).then((res) => { - expect(res.data.returnInt).toBe(55); + expect(res.data?.['returnInt']).toBe(55); }); }); test('can mock a Float', () => { - let jsSchema = buildSchemaFromTypeDefinitions(shorthand); + let jsSchema = buildSchema(shorthand); const mockMap = { Float: () => 55.5 }; jsSchema = addMocksToSchema({ schema: jsSchema, mocks: mockMap }); const testQuery = `{ returnFloat }`; return graphql(jsSchema, testQuery).then((res) => { - expect(res.data.returnFloat).toBe(55.5); + expect(res.data?.['returnFloat']).toBe(55.5); }); }); test('can mock a String', () => { - let jsSchema = buildSchemaFromTypeDefinitions(shorthand); + let jsSchema = buildSchema(shorthand); const mockMap = { String: () => 'a string' }; jsSchema = addMocksToSchema({ schema: jsSchema, mocks: mockMap }); const testQuery = `{ returnString }`; return graphql(jsSchema, testQuery).then((res) => { - expect(res.data.returnString).toBe('a string'); + expect(res.data?.['returnString']).toBe('a string'); }); }); test('can mock a Boolean', () => { - let jsSchema = buildSchemaFromTypeDefinitions(shorthand); + let jsSchema = buildSchema(shorthand); const mockMap = { Boolean: () => true }; jsSchema = addMocksToSchema({ schema: jsSchema, mocks: mockMap }); const testQuery = `{ returnBoolean }`; return graphql(jsSchema, testQuery).then((res) => { - expect(res.data.returnBoolean).toBe(true); + expect(res.data?.['returnBoolean']).toBe(true); }); }); test('can mock an ID', () => { - let jsSchema = buildSchemaFromTypeDefinitions(shorthand); + let jsSchema = buildSchema(shorthand); const mockMap = { ID: () => 'ea5bdc19' }; jsSchema = addMocksToSchema({ schema: jsSchema, mocks: mockMap }); const testQuery = `{ returnID }`; return graphql(jsSchema, testQuery).then((res) => { - expect(res.data.returnID).toBe('ea5bdc19'); + expect(res.data?.['returnID']).toBe('ea5bdc19'); }); }); test('nullable type is nullable', () => { - let jsSchema = buildSchemaFromTypeDefinitions(shorthand); + let jsSchema = buildSchema(shorthand); const mockMap = { String: (): null => null }; jsSchema = addMocksToSchema({ schema: jsSchema, mocks: mockMap }); const testQuery = `{ returnNullableString }`; return graphql(jsSchema, testQuery).then((res) => { - expect(res.data.returnNullableString).toBe(null); + expect(res.data?.['returnNullableString']).toBe(null); }); }); test('can mock a nonNull type', () => { - let jsSchema = buildSchemaFromTypeDefinitions(shorthand); + let jsSchema = buildSchema(shorthand); const mockMap = { String: () => 'nonnull' }; jsSchema = addMocksToSchema({ schema: jsSchema, mocks: mockMap }); const testQuery = `{ returnNonNullString }`; return graphql(jsSchema, testQuery).then((res) => { - expect(res.data.returnNonNullString).toBe('nonnull'); + expect(res.data?.['returnNonNullString']).toBe('nonnull'); }); }); test('nonNull type is not nullable', () => { - let jsSchema = buildSchemaFromTypeDefinitions(shorthand); + let jsSchema = buildSchema(shorthand); const mockMap = { String: (): null => null }; jsSchema = addMocksToSchema({ schema: jsSchema, mocks: mockMap }); const testQuery = `{ @@ -735,11 +734,11 @@ describe('Mock retro-compatibility', () => { }`; return graphql(jsSchema, testQuery).then((res) => { expect(res.data).toBe(null); - expect(res.errors.length).toBe(1); + expect(res.errors?.length).toBe(1); }); }); test('can mock object types', () => { - let jsSchema = buildSchemaFromTypeDefinitions(shorthand); + let jsSchema = buildSchema(shorthand); const mockMap = { String: () => 'abc', Int: () => 123, @@ -757,7 +756,7 @@ describe('Mock retro-compatibility', () => { }); test('can mock a list of ints', () => { - let jsSchema = buildSchemaFromTypeDefinitions(shorthand); + let jsSchema = buildSchema(shorthand); const mockMap = { Int: () => 123 }; jsSchema = addMocksToSchema({ schema: jsSchema, mocks: mockMap }); const testQuery = `{ @@ -772,7 +771,7 @@ describe('Mock retro-compatibility', () => { }); test('can mock a list of lists of objects', () => { - let jsSchema = buildSchemaFromTypeDefinitions(shorthand); + let jsSchema = buildSchema(shorthand); const mockMap = { String: () => 'a', Int: () => 1, @@ -799,7 +798,7 @@ describe('Mock retro-compatibility', () => { }); test('does not mask resolvers if you tell it not to', () => { - let jsSchema = buildSchemaFromTypeDefinitions(shorthand); + let jsSchema = buildSchema(shorthand); const mockMap = { RootQuery: () => ({ returnInt: (_root: any, _args: Record) => 42, // a) in resolvers, will not be used @@ -836,7 +835,7 @@ describe('Mock retro-compatibility', () => { }); test('lets you mock non-leaf types conveniently', () => { - let jsSchema = buildSchemaFromTypeDefinitions(shorthand); + let jsSchema = buildSchema(shorthand); const mockMap = { Bird: () => ({ returnInt: 12, @@ -865,7 +864,7 @@ describe('Mock retro-compatibility', () => { }); test('lets you mock and resolve non-leaf types concurrently', () => { - let jsSchema = buildSchemaFromTypeDefinitions(shorthand); + let jsSchema = buildSchema(shorthand); const resolvers = { RootQuery: { returnListOfInt: () => [1, 2, 3], @@ -908,7 +907,7 @@ describe('Mock retro-compatibility', () => { }); test('lets you mock and resolve non-leaf types concurrently, support promises', () => { - let jsSchema = buildSchemaFromTypeDefinitions(shorthand); + let jsSchema = buildSchema(shorthand); const resolvers = { RootQuery: { returnObject: () => @@ -948,7 +947,7 @@ describe('Mock retro-compatibility', () => { }); test('lets you mock and resolve non-leaf types concurrently, support defineProperty', () => { - let jsSchema = buildSchemaFromTypeDefinitions(shorthand); + let jsSchema = buildSchema(shorthand); const objProxy = {}; Object.defineProperty( objProxy, @@ -989,7 +988,7 @@ describe('Mock retro-compatibility', () => { }); }); - test('let you mock with preserving resolvers, also when using logger', () => { + test('let you mock with preserving resolvers', () => { const resolvers = { RootQuery: { returnString: () => 'woot!?', // a) resolve of a string @@ -998,7 +997,6 @@ describe('Mock retro-compatibility', () => { let jsSchema = makeExecutableSchema({ typeDefs: [shorthand], resolvers, - logger: console, }); const mockMap = { Int: () => 123, // b) mock of Int. @@ -1028,10 +1026,10 @@ describe('Mock retro-compatibility', () => { }); test('let you resolve null with mocking and preserving resolvers', () => { - let jsSchema = buildSchemaFromTypeDefinitions(shorthand); + let jsSchema = buildSchema(shorthand); const resolvers = { RootQuery: { - returnString: (): string => null, // a) resolve of a string + returnString: () => null, // a) resolve of a string }, }; jsSchema = addResolversToSchema(jsSchema, resolvers); @@ -1055,7 +1053,7 @@ describe('Mock retro-compatibility', () => { returnInt: 666, // from the mock, see b) returnString: 'Hello World', // from mock default values. }, - returnString: null as string, // from the mock, see a) + returnString: null as unknown as string, // from the mock, see a) }; return graphql(jsSchema, testQuery, undefined, {}).then((res) => { expect(res.data).toEqual(expected); @@ -1063,10 +1061,10 @@ describe('Mock retro-compatibility', () => { }); test('lets you mock root query fields', () => { - let jsSchema = buildSchemaFromTypeDefinitions(shorthand); + let jsSchema = buildSchema(shorthand); const resolvers = { RootQuery: { - returnStringArgument: (_: void, a: Record) => a.s, + returnStringArgument: (_: void, a: Record) => a['s'], }, }; jsSchema = addMocksToSchema({ schema: jsSchema, resolvers }); @@ -1082,10 +1080,10 @@ describe('Mock retro-compatibility', () => { }); test('lets you mock root mutation fields', () => { - let jsSchema = buildSchemaFromTypeDefinitions(shorthand); + let jsSchema = buildSchema(shorthand); const resolvers = { RootMutation: { - returnStringArgument: (_: void, a: Record) => a.s, + returnStringArgument: (_: void, a: Record) => a['s'], }, }; jsSchema = addMocksToSchema({ schema: jsSchema, resolvers }); @@ -1101,7 +1099,7 @@ describe('Mock retro-compatibility', () => { }); test('lets you mock a list of a certain length', () => { - let jsSchema = buildSchemaFromTypeDefinitions(shorthand); + let jsSchema = buildSchema(shorthand); const mockMap = { RootQuery: () => ({ returnListOfInt: () => new MockList(3) }), Int: () => 12, @@ -1119,7 +1117,7 @@ describe('Mock retro-compatibility', () => { }); test('lets you mock a list of a random length', () => { - let jsSchema = buildSchemaFromTypeDefinitions(shorthand); + let jsSchema = buildSchema(shorthand); const mockMap = { RootQuery: () => ({ returnListOfInt: () => new MockList([10, 20]) }), Int: () => 12, @@ -1129,14 +1127,14 @@ describe('Mock retro-compatibility', () => { returnListOfInt }`; return graphql(jsSchema, testQuery).then((res) => { - expect(res.data.returnListOfInt.length).toBeGreaterThanOrEqual(10); - expect(res.data.returnListOfInt.length).toBeLessThanOrEqual(20); - expect(res.data.returnListOfInt[0]).toBe(12); + expect(res.data?.['returnListOfInt'].length).toBeGreaterThanOrEqual(10); + expect(res.data?.['returnListOfInt'].length).toBeLessThanOrEqual(20); + expect(res.data?.['returnListOfInt'][0]).toBe(12); }); }); test('lets you provide a function for your MockList', () => { - let jsSchema = buildSchemaFromTypeDefinitions(shorthand); + let jsSchema = buildSchema(shorthand); const mockMap = { RootQuery: () => ({ returnListOfInt: () => new MockList(2, () => 33), @@ -1165,7 +1163,7 @@ describe('Mock retro-compatibility', () => { }); test('lets you nest MockList in MockList', () => { - let jsSchema = buildSchemaFromTypeDefinitions(shorthand); + let jsSchema = buildSchema(shorthand); const mockMap = { RootQuery: () => ({ returnListOfListOfInt: () => new MockList(2, () => new MockList(3)), @@ -1368,9 +1366,9 @@ describe('Mock retro-compatibility', () => { `, }); - expect(result.data?.reviews?.length <= 4).toBeTruthy(); - expect(typeof result.data?.reviews[0]?.sentence).toBe('string'); - expect(typeof result.data?.reviews[0]?.user?.first_name).toBe('string'); + expect(result.data?.['reviews']?.length <= 4).toBeTruthy(); + expect(typeof result.data?.['reviews'][0]?.sentence).toBe('string'); + expect(typeof result.data?.['reviews'][0]?.user?.first_name).toBe('string'); }); it('resolves subscriptions only once', async () => { diff --git a/packages/mock/tests/store.spec.ts b/packages/mock/tests/store.spec.ts index 2d27062ffc1..869bd123359 100644 --- a/packages/mock/tests/store.spec.ts +++ b/packages/mock/tests/store.spec.ts @@ -250,7 +250,7 @@ describe('MockStore', () => { it('should be able to generate a list of Object type', () => { const store = createMockStore({ schema }); - const friends = store.get('User', '123', 'friends'); + const friends = store.get('User', '123', 'friends') as any[]; expect(friends).toBeInstanceOf(Array); expect(friends[0]).toHaveProperty('$ref'); diff --git a/packages/node-require/package.json b/packages/node-require/package.json index 17e7223f18e..b7c5ba56be8 100644 --- a/packages/node-require/package.json +++ b/packages/node-require/package.json @@ -34,7 +34,8 @@ "dependencies": { "@graphql-tools/load": "^6.2.4", "@graphql-tools/graphql-file-loader": "^6.2.4", - "tslib": "~2.2.0" + "@graphql-tools/utils": "^7.10.0", + "tslib": "~2.3.0" }, "publishConfig": { "access": "public", diff --git a/packages/node-require/src/index.ts b/packages/node-require/src/index.ts index 3b7ee84a928..43b801ac65e 100644 --- a/packages/node-require/src/index.ts +++ b/packages/node-require/src/index.ts @@ -7,24 +7,24 @@ import { loadTypedefsSync } from '@graphql-tools/load'; import { GraphQLFileLoader } from '@graphql-tools/graphql-file-loader'; import { concatAST } from 'graphql'; +import { isSome } from '@graphql-tools/utils'; const VALID_EXTENSIONS = ['graphql', 'graphqls', 'gql', 'gqls']; -function handleModule(m: NodeModule, filename: string) { - console.log(m, filename); +export function handleModule(m: NodeModule, filename: string) { const sources = loadTypedefsSync(filename, { loaders: [new GraphQLFileLoader()], }); - const documents = sources.map(source => source.document); + const documents = sources.map(source => source.document).filter(isSome); const mergedDoc = concatAST(documents); m.exports = mergedDoc; } -export function registerGraphQLExtensions(require: NodeRequire) { - VALID_EXTENSIONS.forEach(ext => { - require.extensions[`.${ext}`] = handleModule; - }); +export function registerGraphQLExtensions(nodeRequire: NodeRequire) { + for (const ext of VALID_EXTENSIONS) { + nodeRequire.extensions[`.${ext}`] = handleModule; + } } registerGraphQLExtensions(require); diff --git a/packages/node-require/test/node-require.spec.ts b/packages/node-require/test/node-require.spec.ts index febaac67b37..d2dac6d6f2e 100644 --- a/packages/node-require/test/node-require.spec.ts +++ b/packages/node-require/test/node-require.spec.ts @@ -1,12 +1,14 @@ -import '../src'; +import { handleModule } from '../src'; import { print } from 'graphql'; import { readFileSync } from 'fs'; +import { join } from 'path'; describe('GraphQL Node Import', () => { - it.skip('should import correct definitions', () => { - console.log(require.main); + it('should import correct definitions', () => { const filePath = './fixtures/test.graphql'; - const typeDefs = require(filePath); + const m: any = {}; + handleModule(m, join(__dirname, filePath)); + const typeDefs = m.exports; expect(print(typeDefs).replace(/\s\s+/g, ' ')).toBe( readFileSync(require.resolve(filePath), 'utf8').replace(/\s\s+/g, ' ') ); diff --git a/packages/optimize/package.json b/packages/optimize/package.json index a6fa01f37b5..d72ca52dfd8 100644 --- a/packages/optimize/package.json +++ b/packages/optimize/package.json @@ -32,7 +32,7 @@ "input": "./src/index.ts" }, "dependencies": { - "tslib": "~2.2.0" + "tslib": "~2.3.0" }, "publishConfig": { "access": "public", diff --git a/packages/relay-operation-optimizer/package.json b/packages/relay-operation-optimizer/package.json index 6207612c4a2..98c10b4adac 100644 --- a/packages/relay-operation-optimizer/package.json +++ b/packages/relay-operation-optimizer/package.json @@ -43,7 +43,7 @@ "dependencies": { "@graphql-tools/utils": "^7.1.0", "relay-compiler": "11.0.2", - "tslib": "~2.2.0" + "tslib": "~2.3.0" }, "devDependencies": { "@types/relay-compiler": "8.0.0" diff --git a/packages/relay-operation-optimizer/tests/relay-optimizer.spec.ts b/packages/relay-operation-optimizer/tests/relay-optimizer.spec.ts index 62a9c03a058..44d04ae4e84 100644 --- a/packages/relay-operation-optimizer/tests/relay-optimizer.spec.ts +++ b/packages/relay-operation-optimizer/tests/relay-optimizer.spec.ts @@ -68,7 +68,7 @@ it('can inline @argumentDefinitions/@arguments annotated fragments', async () => const queryDoc = output.find(doc => doc.definitions[0].kind === 'OperationDefinition'); expect(queryDoc).toBeDefined(); - expect(print(queryDoc)).toBeSimilarGqlDoc(/* GraphQL */ ` + expect(print(queryDoc!)).toBeSimilarGqlDoc(/* GraphQL */ ` query user { users { id @@ -127,7 +127,7 @@ it('handles unions with interfaces the correct way', async () => { const queryDoc = output.find(doc => doc.definitions[0].kind === 'OperationDefinition'); expect(queryDoc).toBeDefined(); - expect(print(queryDoc)).toBeSimilarGqlDoc(/* GraphQL */ ` + expect(print(queryDoc!)).toBeSimilarGqlDoc(/* GraphQL */ ` query user { user { ... on User { diff --git a/packages/resolvers-composition/package.json b/packages/resolvers-composition/package.json index d6fdf51c13c..ba6fc246eec 100644 --- a/packages/resolvers-composition/package.json +++ b/packages/resolvers-composition/package.json @@ -11,8 +11,8 @@ "license": "MIT", "sideEffects": false, "main": "dist/index.js", - "module": "dist/index.mjs", - "exports": { + "module": "dist/index.mjs", + "exports": { ".": { "require": "./dist/index.js", "import": "./dist/index.mjs" @@ -30,12 +30,14 @@ "graphql": "^14.0.0 || ^15.0.0" }, "devDependencies": { - "@types/lodash": "4.14.170" + "@types/lodash": "4.14.170", + "@types/micromatch": "4.0.1" }, "dependencies": { "@graphql-tools/utils": "^7.9.1", "lodash": "4.17.21", - "tslib": "~2.2.0" + "micromatch": "^4.0.4", + "tslib": "~2.3.0" }, "publishConfig": { "access": "public", diff --git a/packages/resolvers-composition/src/resolvers-composition.ts b/packages/resolvers-composition/src/resolvers-composition.ts index f087c8461cf..4c71412f78e 100644 --- a/packages/resolvers-composition/src/resolvers-composition.ts +++ b/packages/resolvers-composition/src/resolvers-composition.ts @@ -1,7 +1,8 @@ import { chainFunctions } from './chain-functions'; -import { get, set, flatten } from 'lodash'; +import _ from 'lodash'; import { GraphQLFieldResolver, GraphQLScalarTypeConfig } from 'graphql'; import { asArray } from '@graphql-tools/utils'; +import { matcher } from 'micromatch'; export type ResolversComposition< Resolver extends GraphQLFieldResolver = GraphQLFieldResolver @@ -27,34 +28,39 @@ function isScalarTypeConfiguration(config: any): config is GraphQLScalarTypeConf function resolveRelevantMappings = Record>( resolvers: Resolvers, - path: string, - allMappings: ResolversComposerMapping + path: string ): string[] { - const split = path.split('.'); + if (!resolvers) { + return []; + } - if (split.length === 2) { - const typeName = split[0]; + const [typeNameOrGlob, fieldNameOrGlob] = path.split('.'); + const isTypeMatch = matcher(typeNameOrGlob); - if (isScalarTypeConfiguration(resolvers[typeName])) { - return []; - } + let fixedFieldGlob = fieldNameOrGlob; + // convert single value OR `{singleField}` to `singleField` as matching will fail otherwise + if (fixedFieldGlob.includes('{') && !fixedFieldGlob.includes(',')) { + fixedFieldGlob = fieldNameOrGlob.replace('{', '').replace('}', ''); + } + fixedFieldGlob = fixedFieldGlob.replace(', ', ',').trim(); - const fieldName = split[1]; + const isFieldMatch = matcher(fixedFieldGlob); if (typeName === '*') { - return flatten( - Object.keys(resolvers).map(typeName => + if (!resolvers) { + return []; + } + return Object.keys(resolvers).map(typeName => resolveRelevantMappings(resolvers, `${typeName}.${fieldName}`, allMappings) - ) - ); + ).flat(); } if (fieldName === '*') { - return flatten( - Object.keys(resolvers[typeName]).map(field => - resolveRelevantMappings(resolvers, `${typeName}.${field}`, allMappings) - ) - ).filter(mapItem => !allMappings[mapItem]); + const fieldMap = resolvers[typeName]; + if (!fieldMap) { + return []; + } + return Object.keys(fieldMap).map(field => resolveRelevantMappings(resolvers, `${typeName}.${field}`, allMappings)).flat().filter(mapItem => !allMappings[mapItem]); } else { const paths = []; @@ -74,17 +80,18 @@ function resolveRelevantMappings = Record< return paths; } - } else if (split.length === 1) { - const typeName = split[0]; - return flatten( - Object.keys(resolvers[typeName]).map(fieldName => + const fieldMap = resolvers[typeName]; + if (!fieldMap) { + return []; + } + + return Object.keys(fieldMap).map(fieldName => resolveRelevantMappings(resolvers, `${typeName}.${fieldName}`, allMappings) - ) - ); + ).flat(); } - return []; + return mappings; } /** @@ -101,31 +108,32 @@ export function composeResolvers>( ): Resolvers { const mappingResult: { [path: string]: ((...args: any[]) => any)[] } = {}; - Object.keys(mapping).forEach((resolverPath: string) => { - if (mapping[resolverPath] instanceof Array || typeof mapping[resolverPath] === 'function') { - const composeFns = mapping[resolverPath] as ResolversComposition | ResolversComposition[]; - const relevantFields = resolveRelevantMappings(resolvers, resolverPath, mapping); + for (const resolverPath in mapping) { + const resolverPathMapping = mapping[resolverPath]; + if (resolverPathMapping instanceof Array || typeof resolverPathMapping === 'function') { + const composeFns = resolverPathMapping as ResolversComposition | ResolversComposition[]; + const relevantFields = resolveRelevantMappings(resolvers, resolverPath); - relevantFields.forEach((path: string) => { + for (const path of relevantFields) { mappingResult[path] = asArray(composeFns); - }); - } else { - Object.keys(mapping[resolverPath]).forEach(fieldName => { - const composeFns = mapping[resolverPath][fieldName]; - const relevantFields = resolveRelevantMappings(resolvers, resolverPath + '.' + fieldName, mapping); + } + } else if (resolverPathMapping) { + for (const fieldName in resolverPathMapping) { + const composeFns = resolverPathMapping[fieldName]; + const relevantFields = resolveRelevantMappings(resolvers, resolverPath + '.' + fieldName); - relevantFields.forEach((path: string) => { + for (const path of relevantFields) { mappingResult[path] = asArray(composeFns); - }); + } }); } - }); + } - Object.keys(mappingResult).forEach(path => { - const fns = chainFunctions([...asArray(mappingResult[path]), () => get(resolvers, path)]); + for (const path in mappingResult) { + const fns = chainFunctions([...asArray(mappingResult[path]), () => _.get(resolvers, path)]); - set(resolvers, path, fns()); - }); + _.set(resolvers, path, fns()); + } return resolvers; } diff --git a/packages/resolvers-composition/tests/resolvers-composition.spec.ts b/packages/resolvers-composition/tests/resolvers-composition.spec.ts index f0fd96c8697..908b88dc3d5 100644 --- a/packages/resolvers-composition/tests/resolvers-composition.spec.ts +++ b/packages/resolvers-composition/tests/resolvers-composition.spec.ts @@ -52,7 +52,7 @@ describe('Resolvers composition', () => { `, }); expect(result.errors).toBeFalsy(); - expect(result.data.foo).toBe('FOOFOO'); + expect(result.data!['foo']).toBe('FOOFOO'); }); it('should compose resolvers with resolve field', async () => { const getFoo = () => 'FOO'; @@ -90,7 +90,7 @@ describe('Resolvers composition', () => { `, }); expect(result.errors).toBeFalsy(); - expect(result.data.foo).toBe('FOOFOO'); + expect(result.data!['foo']).toBe('FOOFOO'); }); it('should compose subscription resolvers', async () => { const array1 = [1, 2]; @@ -169,7 +169,7 @@ describe('Resolvers composition', () => { `, }); expect(result.errors).toBeFalsy(); - expect(result.data.foo).toBe('FOOFOO'); + expect(result.data!['foo']).toBe('FOOFOO'); }); it('should be able to take nested composition objects for subscription resolvers', async () => { const array1 = [1, 2]; @@ -289,4 +289,80 @@ describe('Resolvers composition', () => { expect(functionsCalled).not.toContain('parseLiteral'); }); + + it('should support glob pattern for fields - Query.{foo, bar}', async () => { + const resolvers = { + Query: { + foo: async () => 0, + bar: async () => 1, + fooBar: async () => 2, + }, + Mutation: { + qux: async () => 3, + baz: async () => 4, + }, + }; + const resolversComposition = { + 'Query.{foo, bar}': [ + (next: any) => async (...args: any) => { + const result = await next(...args); + return result + 1; + } + ] + } + const composedResolvers = composeResolvers(resolvers, resolversComposition); + + expect(await composedResolvers.Query.foo()).toBe(1); + expect(await composedResolvers.Query.bar()).toBe(2); + expect(await composedResolvers.Query.fooBar()).toBe(2); + expect(await composedResolvers.Mutation.qux()).toBe(3); + expect(await composedResolvers.Mutation.baz()).toBe(4); + }); + + it('should support glob pattern for fields - Query.!{foo, bar}', async () => { + const resolvers = { + Query: { + foo: async () => 0, + bar: async () => 1, + fooBar: async () => 2, + }, + Mutation: { + qux: async () => 3, + baz: async () => 4, + }, + }; + const resolversComposition = { + 'Query.!{foo, bar}': [ + (next: any) => async (...args: any) => { + const result = await next(...args); + return result + 1; + } + ] + } + const composedResolvers = composeResolvers(resolvers, resolversComposition); + + expect(await composedResolvers.Query.foo()).toBe(0); + expect(await composedResolvers.Query.bar()).toBe(1); + expect(await composedResolvers.Query.fooBar()).toBe(3); + expect(await composedResolvers.Mutation.qux()).toBe(3); + expect(await composedResolvers.Mutation.baz()).toBe(4); + }); + it('should handle nullish properties correctly', async () => { + const getFoo = () => 'FOO'; + const resolvers = { + Query: { + foo: async () => getFoo(), + bar: undefined, + }, + Mutation: undefined + }; + const resolversComposition: any = { + 'Query.foo': (next: (arg0: any, arg1: any, arg2: any, arg3: any) => void) => async (root: any, args: any, context: any, info: any) => { + const prevResult = await next(root, args, context, info); + return getFoo() + prevResult; + }, + 'Query.bar': undefined + }; + expect(() => composeResolvers(resolvers, resolversComposition)).not.toThrow(); + }) }); diff --git a/packages/schema/package.json b/packages/schema/package.json index 22e0af0ff58..85efbcc0a70 100644 --- a/packages/schema/package.json +++ b/packages/schema/package.json @@ -35,8 +35,9 @@ "input": "./src/index.ts" }, "dependencies": { + "@graphql-tools/merge": "6.2.14", "@graphql-tools/utils": "^7.1.2", - "tslib": "~2.2.0", + "tslib": "~2.3.0", "value-or-promise": "1.0.10" }, "publishConfig": { diff --git a/packages/schema/src/addCatchUndefinedToSchema.ts b/packages/schema/src/addCatchUndefinedToSchema.ts deleted file mode 100644 index fc3444d9c65..00000000000 --- a/packages/schema/src/addCatchUndefinedToSchema.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { GraphQLFieldResolver, defaultFieldResolver, GraphQLSchema } from 'graphql'; -import { mapSchema, MapperKind } from '@graphql-tools/utils'; - -function decorateToCatchUndefined(fn: GraphQLFieldResolver, hint: string): GraphQLFieldResolver { - const resolve = fn == null ? defaultFieldResolver : fn; - return (root, args, ctx, info) => { - const result = resolve(root, args, ctx, info); - if (typeof result === 'undefined') { - throw new Error(`Resolver for "${hint}" returned undefined`); - } - return result; - }; -} - -export function addCatchUndefinedToSchema(schema: GraphQLSchema): GraphQLSchema { - return mapSchema(schema, { - [MapperKind.OBJECT_FIELD]: (fieldConfig, fieldName, typeName) => ({ - ...fieldConfig, - resolve: decorateToCatchUndefined(fieldConfig.resolve, `${typeName}.${fieldName}`), - }), - }); -} diff --git a/packages/schema/src/addErrorLoggingToSchema.ts b/packages/schema/src/addErrorLoggingToSchema.ts deleted file mode 100644 index ac42a375b48..00000000000 --- a/packages/schema/src/addErrorLoggingToSchema.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { GraphQLSchema } from 'graphql'; -import { mapSchema, MapperKind } from '@graphql-tools/utils'; -import { decorateWithLogger } from './decorateWithLogger'; -import { ILogger } from './types'; - -export function addErrorLoggingToSchema(schema: GraphQLSchema, logger?: ILogger): GraphQLSchema { - if (!logger) { - throw new Error('Must provide a logger'); - } - if (typeof logger.log !== 'function') { - throw new Error('Logger.log must be a function'); - } - return mapSchema(schema, { - [MapperKind.OBJECT_FIELD]: (fieldConfig, fieldName, typeName) => ({ - ...fieldConfig, - resolve: decorateWithLogger(fieldConfig.resolve, logger, `${typeName}.${fieldName}`), - }), - }); -} diff --git a/packages/schema/src/addResolversToSchema.ts b/packages/schema/src/addResolversToSchema.ts index 6e486382d37..756f4b1f34b 100644 --- a/packages/schema/src/addResolversToSchema.ts +++ b/packages/schema/src/addResolversToSchema.ts @@ -41,7 +41,7 @@ export function addResolversToSchema( const options: IAddResolversToSchemaOptions = isSchema(schemaOrOptions) ? { schema: schemaOrOptions, - resolvers: legacyInputResolvers, + resolvers: legacyInputResolvers ?? {}, resolverValidationOptions: legacyInputValidationOptions, } : schemaOrOptions; @@ -61,92 +61,82 @@ export function addResolversToSchema( ? extendResolversFromInterfaces(schema, inputResolvers) : inputResolvers; - Object.getOwnPropertyNames(resolvers).forEach(typeName => { + for (const typeName in resolvers) { const resolverValue = resolvers[typeName]; const resolverType = typeof resolverValue; - if (typeName === '__schema') { - if (resolverType !== 'function') { - throw new Error( - `"${typeName}" defined in resolvers, but has invalid value "${ - resolverValue as unknown as string - }". A schema resolver's value must be of type object or function.` - ); - } - } else { - if (resolverType !== 'object') { - throw new Error( - `"${typeName}" defined in resolvers, but has invalid value "${ - resolverValue as unknown as string - }". The resolver's value must be of type object.` - ); - } + if (resolverType !== 'object') { + throw new Error( + `"${typeName}" defined in resolvers, but has invalid value "${ + resolverValue as unknown as string + }". The resolver's value must be of type object.` + ); + } - const type = schema.getType(typeName); + const type = schema.getType(typeName); - if (type == null) { - if (requireResolversToMatchSchema === 'ignore') { - return; + if (type == null) { + if (requireResolversToMatchSchema === 'ignore') { + break; + } + + throw new Error(`"${typeName}" defined in resolvers, but not in schema`); + } else if (isSpecifiedScalarType(type)) { + // allow -- without recommending -- overriding of specified scalar types + for (const fieldName in resolverValue) { + if (fieldName.startsWith('__')) { + type[fieldName.substring(2)] = resolverValue[fieldName]; + } else { + type[fieldName] = resolverValue[fieldName]; + } + } + } else if (isEnumType(type)) { + const values = type.getValues(); + + for (const fieldName in resolverValue) { + if ( + !fieldName.startsWith('__') && + !values.some(value => value.name === fieldName) && + requireResolversToMatchSchema && + requireResolversToMatchSchema !== 'ignore' + ) { + throw new Error(`${type.name}.${fieldName} was defined in resolvers, but not present within ${type.name}`); } + } + } else if (isUnionType(type)) { + for (const fieldName in resolverValue) { + if ( + !fieldName.startsWith('__') && + requireResolversToMatchSchema && + requireResolversToMatchSchema !== 'ignore' + ) { + throw new Error( + `${type.name}.${fieldName} was defined in resolvers, but ${type.name} is not an object or interface type` + ); + } + } + } else if (isObjectType(type) || isInterfaceType(type)) { + for (const fieldName in resolverValue) { + if (!fieldName.startsWith('__')) { + const fields = type.getFields(); + const field = fields[fieldName]; - throw new Error(`"${typeName}" defined in resolvers, but not in schema`); - } else if (isSpecifiedScalarType(type)) { - // allow -- without recommending -- overriding of specified scalar types - Object.getOwnPropertyNames(resolverValue).forEach(fieldName => { - if (fieldName.startsWith('__')) { - type[fieldName.substring(2)] = resolverValue[fieldName]; + if (field == null) { + // Field present in resolver but not in schema + if (requireResolversToMatchSchema && requireResolversToMatchSchema !== 'ignore') { + throw new Error(`${typeName}.${fieldName} defined in resolvers, but not in schema`); + } } else { - type[fieldName] = resolverValue[fieldName]; - } - }); - } else if (isEnumType(type)) { - const values = type.getValues(); - - Object.getOwnPropertyNames(resolverValue).forEach(fieldName => { - if ( - !fieldName.startsWith('__') && - !values.some(value => value.name === fieldName) && - requireResolversToMatchSchema && - requireResolversToMatchSchema !== 'ignore' - ) { - throw new Error(`${type.name}.${fieldName} was defined in resolvers, but not present within ${type.name}`); - } - }); - } else if (isUnionType(type)) { - Object.getOwnPropertyNames(resolverValue).forEach(fieldName => { - if ( - !fieldName.startsWith('__') && - requireResolversToMatchSchema && - requireResolversToMatchSchema !== 'ignore' - ) { - throw new Error( - `${type.name}.${fieldName} was defined in resolvers, but ${type.name} is not an object or interface type` - ); - } - }); - } else if (isObjectType(type) || isInterfaceType(type)) { - Object.getOwnPropertyNames(resolverValue).forEach(fieldName => { - if (!fieldName.startsWith('__')) { - const fields = type.getFields(); - const field = fields[fieldName]; - - if (field == null) { - // Field present in resolver but not in schema - if (requireResolversToMatchSchema && requireResolversToMatchSchema !== 'ignore') { - throw new Error(`${typeName}.${fieldName} defined in resolvers, but not in schema`); - } - } else { - // Field present in both the resolver and schema - const fieldResolve = resolverValue[fieldName]; - if (typeof fieldResolve !== 'function' && typeof fieldResolve !== 'object') { - throw new Error(`Resolver ${typeName}.${fieldName} must be object or function`); - } + // Field present in both the resolver and schema + const fieldResolve = resolverValue[fieldName]; + if (typeof fieldResolve !== 'function' && typeof fieldResolve !== 'object') { + throw new Error(`Resolver ${typeName}.${fieldName} must be object or function`); } } - }); + } } } - }); + } schema = updateResolversInPlace ? addResolversToExistingSchema(schema, resolvers, defaultFieldResolver) @@ -162,101 +152,99 @@ export function addResolversToSchema( function addResolversToExistingSchema( schema: GraphQLSchema, resolvers: IResolvers, - defaultFieldResolver: GraphQLFieldResolver + defaultFieldResolver?: GraphQLFieldResolver ): GraphQLSchema { const typeMap = schema.getTypeMap(); - getAllPropertyNames(resolvers).forEach(typeName => { - if (typeName !== '__schema') { - const type = schema.getType(typeName); - const resolverValue = resolvers[typeName]; + for (const typeName in resolvers) { + const type = schema.getType(typeName); + const resolverValue = resolvers[typeName]; - if (isScalarType(type)) { - getAllPropertyNames(resolverValue).forEach(fieldName => { - if (fieldName.startsWith('__')) { - type[fieldName.substring(2)] = resolverValue[fieldName]; - } else if (fieldName === 'astNode' && type.astNode != null) { - type.astNode = { - ...type.astNode, - description: (resolverValue as GraphQLScalarType)?.astNode?.description ?? type.astNode.description, - directives: (type.astNode.directives ?? []).concat( - (resolverValue as GraphQLScalarType)?.astNode?.directives ?? [] - ), - }; - } else if (fieldName === 'extensionASTNodes' && type.extensionASTNodes != null) { - type.extensionASTNodes = ([] ?? type.extensionASTNodes).concat( - (resolverValue as GraphQLScalarType)?.extensionASTNodes ?? [] - ); - } else if ( - fieldName === 'extensions' && - type.extensions != null && - (resolverValue as GraphQLScalarType).extensions != null - ) { - type.extensions = Object.assign({}, type.extensions, (resolverValue as GraphQLScalarType).extensions); - } else { - type[fieldName] = resolverValue[fieldName]; - } - }); - } else if (isEnumType(type)) { - const config = type.toConfig(); - const enumValueConfigMap = config.values; + if (isScalarType(type)) { + for (const fieldName in resolverValue) { + if (fieldName.startsWith('__')) { + type[fieldName.substring(2)] = resolverValue[fieldName]; + } else if (fieldName === 'astNode' && type.astNode != null) { + type.astNode = { + ...type.astNode, + description: (resolverValue as GraphQLScalarType)?.astNode?.description ?? type.astNode.description, + directives: (type.astNode.directives ?? []).concat( + (resolverValue as GraphQLScalarType)?.astNode?.directives ?? [] + ), + }; + } else if (fieldName === 'extensionASTNodes' && type.extensionASTNodes != null) { + type.extensionASTNodes = type.extensionASTNodes.concat( + (resolverValue as GraphQLScalarType)?.extensionASTNodes ?? [] + ); + } else if ( + fieldName === 'extensions' && + type.extensions != null && + (resolverValue as GraphQLScalarType).extensions != null + ) { + type.extensions = Object.assign({}, type.extensions, (resolverValue as GraphQLScalarType).extensions); + } else { + type[fieldName] = resolverValue[fieldName]; + } + } + } else if (isEnumType(type)) { + const config = type.toConfig(); + const enumValueConfigMap = config.values; - getAllPropertyNames(resolverValue).forEach(fieldName => { - if (fieldName.startsWith('__')) { - config[fieldName.substring(2)] = resolverValue[fieldName]; - } else if (fieldName === 'astNode' && config.astNode != null) { - config.astNode = { - ...config.astNode, - description: (resolverValue as GraphQLScalarType)?.astNode?.description ?? config.astNode.description, - directives: (config.astNode.directives ?? []).concat( - (resolverValue as GraphQLEnumType)?.astNode?.directives ?? [] - ), - }; - } else if (fieldName === 'extensionASTNodes' && config.extensionASTNodes != null) { - config.extensionASTNodes = config.extensionASTNodes.concat( - (resolverValue as GraphQLEnumType)?.extensionASTNodes ?? [] - ); - } else if ( - fieldName === 'extensions' && - type.extensions != null && - (resolverValue as GraphQLEnumType).extensions != null - ) { - type.extensions = Object.assign({}, type.extensions, (resolverValue as GraphQLEnumType).extensions); - } else if (enumValueConfigMap[fieldName]) { - enumValueConfigMap[fieldName].value = resolverValue[fieldName]; - } - }); + for (const fieldName in resolverValue) { + if (fieldName.startsWith('__')) { + config[fieldName.substring(2)] = resolverValue[fieldName]; + } else if (fieldName === 'astNode' && config.astNode != null) { + config.astNode = { + ...config.astNode, + description: (resolverValue as GraphQLScalarType)?.astNode?.description ?? config.astNode.description, + directives: (config.astNode.directives ?? []).concat( + (resolverValue as GraphQLEnumType)?.astNode?.directives ?? [] + ), + }; + } else if (fieldName === 'extensionASTNodes' && config.extensionASTNodes != null) { + config.extensionASTNodes = config.extensionASTNodes.concat( + (resolverValue as GraphQLEnumType)?.extensionASTNodes ?? [] + ); + } else if ( + fieldName === 'extensions' && + type.extensions != null && + (resolverValue as GraphQLEnumType).extensions != null + ) { + type.extensions = Object.assign({}, type.extensions, (resolverValue as GraphQLEnumType).extensions); + } else if (enumValueConfigMap[fieldName]) { + enumValueConfigMap[fieldName].value = resolverValue[fieldName]; + } + } - typeMap[typeName] = new GraphQLEnumType(config); - } else if (isUnionType(type)) { - getAllPropertyNames(resolverValue).forEach(fieldName => { - if (fieldName.startsWith('__')) { - type[fieldName.substring(2)] = resolverValue[fieldName]; - } - }); - } else if (isObjectType(type) || isInterfaceType(type)) { - getAllPropertyNames(resolverValue).forEach(fieldName => { - if (fieldName.startsWith('__')) { - // this is for isTypeOf and resolveType and all the other stuff. - type[fieldName.substring(2)] = resolverValue[fieldName]; - return; - } + typeMap[typeName] = new GraphQLEnumType(config); + } else if (isUnionType(type)) { + for (const fieldName in resolverValue) { + if (fieldName.startsWith('__')) { + type[fieldName.substring(2)] = resolverValue[fieldName]; + } + } + } else if (isObjectType(type) || isInterfaceType(type)) { + for (const fieldName in resolverValue) { + if (fieldName.startsWith('__')) { + // this is for isTypeOf and resolveType and all the other stuff. + type[fieldName.substring(2)] = resolverValue[fieldName]; + break; + } - const fields = type.getFields(); - const field = fields[fieldName]; + const fields = type.getFields(); + const field = fields[fieldName]; - if (field != null) { - const fieldResolve = resolverValue[fieldName]; - if (typeof fieldResolve === 'function') { - // for convenience. Allows shorter syntax in resolver definition file - field.resolve = fieldResolve.bind(resolverValue); - } else { - setFieldProperties(field, fieldResolve); - } + if (field != null) { + const fieldResolve = resolverValue[fieldName]; + if (typeof fieldResolve === 'function') { + // for convenience. Allows shorter syntax in resolver definition file + field.resolve = fieldResolve.bind(resolverValue); + } else { + setFieldProperties(field, fieldResolve); } - }); + } } } - }); + } // serialize all default values prior to healing fields with new scalar/enum types. forEachDefaultValue(schema, serializeInputValue); @@ -279,14 +267,14 @@ function addResolversToExistingSchema( function createNewSchemaWithResolvers( schema: GraphQLSchema, resolvers: IResolvers, - defaultFieldResolver: GraphQLFieldResolver + defaultFieldResolver?: GraphQLFieldResolver ): GraphQLSchema { schema = mapSchema(schema, { [MapperKind.SCALAR_TYPE]: type => { const config = type.toConfig(); const resolverValue = resolvers[type.name]; if (!isSpecifiedScalarType(type) && resolverValue != null) { - getAllPropertyNames(resolverValue).forEach(fieldName => { + for (const fieldName in resolverValue) { if (fieldName.startsWith('__')) { config[fieldName.substring(2)] = resolverValue[fieldName]; } else if (fieldName === 'astNode' && config.astNode != null) { @@ -310,7 +298,7 @@ function createNewSchemaWithResolvers( } else { config[fieldName] = resolverValue[fieldName]; } - }); + } return new GraphQLScalarType(config); } @@ -322,7 +310,7 @@ function createNewSchemaWithResolvers( const enumValueConfigMap = config.values; if (resolverValue != null) { - getAllPropertyNames(resolverValue).forEach(fieldName => { + for (const fieldName in resolverValue) { if (fieldName.startsWith('__')) { config[fieldName.substring(2)] = resolverValue[fieldName]; } else if (fieldName === 'astNode' && config.astNode != null) { @@ -346,7 +334,7 @@ function createNewSchemaWithResolvers( } else if (enumValueConfigMap[fieldName]) { enumValueConfigMap[fieldName].value = resolverValue[fieldName]; } - }); + } return new GraphQLEnumType(config); } @@ -356,11 +344,10 @@ function createNewSchemaWithResolvers( if (resolverValue != null) { const config = type.toConfig(); - getAllPropertyNames(resolverValue).forEach(fieldName => { - if (fieldName.startsWith('__')) { - config[fieldName.substring(2)] = resolverValue[fieldName]; - } - }); + + if (resolverValue['__resolveType']) { + config.resolveType = resolverValue['__resolveType']; + } return new GraphQLUnionType(config); } @@ -370,11 +357,9 @@ function createNewSchemaWithResolvers( if (resolverValue != null) { const config = type.toConfig(); - getAllPropertyNames(resolverValue).forEach(fieldName => { - if (fieldName.startsWith('__')) { - config[fieldName.substring(2)] = resolverValue[fieldName]; - } - }); + if (resolverValue['__isTypeOf']) { + config.isTypeOf = resolverValue['__isTypeOf']; + } return new GraphQLObjectType(config); } @@ -384,11 +369,9 @@ function createNewSchemaWithResolvers( if (resolverValue != null) { const config = type.toConfig(); - getAllPropertyNames(resolverValue).forEach(fieldName => { - if (fieldName.startsWith('__')) { - config[fieldName.substring(2)] = resolverValue[fieldName]; - } - }); + if (resolverValue['__resolveType']) { + config.resolveType = resolverValue['__resolveType']; + } return new GraphQLInterfaceType(config); } @@ -428,14 +411,7 @@ function setFieldProperties( field: GraphQLField | GraphQLFieldConfig, propertiesObj: Record ) { - Object.keys(propertiesObj).forEach(propertyName => { + for (const propertyName in propertiesObj) { field[propertyName] = propertiesObj[propertyName]; - }); -} - -function getAllPropertyNames(obj: any): string[] { - const prototype = Object.getPrototypeOf(obj); - let inherited = prototype ? getAllPropertyNames(prototype) : []; - inherited = inherited.filter(property => property !== 'constructor'); - return [...new Set(Object.getOwnPropertyNames(obj).concat(inherited))]; + } } diff --git a/packages/schema/src/addSchemaLevelResolver.ts b/packages/schema/src/addSchemaLevelResolver.ts deleted file mode 100644 index c82ba97354e..00000000000 --- a/packages/schema/src/addSchemaLevelResolver.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { defaultFieldResolver, GraphQLSchema, GraphQLFieldResolver } from 'graphql'; - -import { ValueOrPromise } from 'value-or-promise'; - -import { mapSchema, MapperKind } from '@graphql-tools/utils'; - -// wraps all resolvers of query, mutation or subscription fields -// with the provided function to simulate a root schema level resolver -export function addSchemaLevelResolver(schema: GraphQLSchema, fn: GraphQLFieldResolver): GraphQLSchema { - // TODO test that schema is a schema, fn is a function - const fnToRunOnlyOnce = runAtMostOncePerRequest(fn); - return mapSchema(schema, { - [MapperKind.ROOT_FIELD]: (fieldConfig, _fieldName, typeName, schema) => { - // XXX this should run at most once per request to simulate a true root resolver - // for graphql-js this is an approximation that works with queries but not mutations - // XXX if the type is a subscription, a same query AST will be ran multiple times so we - // deactivate here the runOnce if it's a subscription. This may not be optimal though... - const subscription = schema.getSubscriptionType(); - if (subscription != null && subscription.name === typeName) { - return { - ...fieldConfig, - resolve: wrapResolver(fieldConfig.resolve, fn), - }; - } - - return { - ...fieldConfig, - resolve: wrapResolver(fieldConfig.resolve, fnToRunOnlyOnce), - }; - }, - }); -} - -// XXX badly named function. this doesn't really wrap, it just chains resolvers... -function wrapResolver( - innerResolver: GraphQLFieldResolver | undefined, - outerResolver: GraphQLFieldResolver -): GraphQLFieldResolver { - return (obj, args, ctx, info) => { - return new ValueOrPromise(() => outerResolver(obj, args, ctx, info)) - .then(root => { - if (innerResolver != null) { - return innerResolver(root, args, ctx, info); - } - return defaultFieldResolver(root, args, ctx, info); - }) - .resolve(); - } -} - -// XXX this function only works for resolvers -// XXX very hacky way to remember if the function -// already ran for this request. This will only work -// if people don't actually cache the operation. -// if they do cache the operation, they will have to -// manually remove the __runAtMostOnce before every request. -function runAtMostOncePerRequest(fn: GraphQLFieldResolver): GraphQLFieldResolver { - let value: any; - const randomNumber = Math.random(); - return (root, args, ctx, info) => { - if (!info.operation['__runAtMostOnce']) { - info.operation['__runAtMostOnce'] = {}; - } - if (!info.operation['__runAtMostOnce'][randomNumber]) { - info.operation['__runAtMostOnce'][randomNumber] = true; - value = fn(root, args, ctx, info); - } - return value; - }; -} diff --git a/packages/schema/src/assertResolversPresent.ts b/packages/schema/src/assertResolversPresent.ts index 9026b858a27..3bb4dcf0376 100644 --- a/packages/schema/src/assertResolversPresent.ts +++ b/packages/schema/src/assertResolversPresent.ts @@ -6,11 +6,8 @@ export function assertResolversPresent( schema: GraphQLSchema, resolverValidationOptions: IResolverValidationOptions = {} ): void { - const { - requireResolversForArgs, - requireResolversForNonScalar, - requireResolversForAllFields, - } = resolverValidationOptions; + const { requireResolversForArgs, requireResolversForNonScalar, requireResolversForAllFields } = + resolverValidationOptions; if (requireResolversForAllFields && (requireResolversForArgs || requireResolversForNonScalar)) { throw new TypeError( @@ -40,7 +37,7 @@ export function assertResolversPresent( function expectResolver( validator: string, - behavior: ValidatorBehavior, + behavior: ValidatorBehavior | undefined, field: GraphQLField, typeName: string, fieldName: string diff --git a/packages/schema/src/attachDirectiveResolvers.ts b/packages/schema/src/attachDirectiveResolvers.ts deleted file mode 100644 index 8ced8d0fc20..00000000000 --- a/packages/schema/src/attachDirectiveResolvers.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { GraphQLSchema, defaultFieldResolver } from 'graphql'; - -import { IDirectiveResolvers, mapSchema, MapperKind, getDirectives } from '@graphql-tools/utils'; - -export function attachDirectiveResolvers( - schema: GraphQLSchema, - directiveResolvers: IDirectiveResolvers -): GraphQLSchema { - if (typeof directiveResolvers !== 'object') { - throw new Error(`Expected directiveResolvers to be of type object, got ${typeof directiveResolvers}`); - } - - if (Array.isArray(directiveResolvers)) { - throw new Error('Expected directiveResolvers to be of type object, got Array'); - } - - return mapSchema(schema, { - [MapperKind.OBJECT_FIELD]: fieldConfig => { - const newFieldConfig = { ...fieldConfig }; - - const directives = getDirectives(schema, fieldConfig); - Object.keys(directives).forEach(directiveName => { - if (directiveResolvers[directiveName]) { - const resolver = directiveResolvers[directiveName]; - const originalResolver = newFieldConfig.resolve != null ? newFieldConfig.resolve : defaultFieldResolver; - const directiveArgs = directives[directiveName]; - newFieldConfig.resolve = (source, originalArgs, context, info) => { - return resolver( - () => - new Promise((resolve, reject) => { - const result = originalResolver(source, originalArgs, context, info); - if (result instanceof Error) { - reject(result); - } - resolve(result); - }), - source, - directiveArgs, - context, - info - ); - }; - } - }); - - return newFieldConfig; - }, - }); -} diff --git a/packages/schema/src/buildSchemaFromTypeDefinitions.ts b/packages/schema/src/buildSchemaFromTypeDefinitions.ts deleted file mode 100644 index 6836602caa9..00000000000 --- a/packages/schema/src/buildSchemaFromTypeDefinitions.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { extendSchema, buildASTSchema, GraphQLSchema, DocumentNode } from 'graphql'; - -import { ITypeDefinitions, GraphQLParseOptions, parseGraphQLSDL, isDocumentNode } from '@graphql-tools/utils'; - -import { filterAndExtractExtensionDefinitions } from './extensionDefinitions'; -import { concatenateTypeDefs } from './concatenateTypeDefs'; - -export function buildSchemaFromTypeDefinitions( - typeDefinitions: ITypeDefinitions, - parseOptions?: GraphQLParseOptions, - noExtensionExtraction?: boolean -): GraphQLSchema { - const document = buildDocumentFromTypeDefinitions(typeDefinitions, parseOptions); - - if (noExtensionExtraction) { - return buildASTSchema(document); - } - - const { typesAst, extensionsAst } = filterAndExtractExtensionDefinitions(document); - - const backcompatOptions = { commentDescriptions: true }; - let schema: GraphQLSchema = buildASTSchema(typesAst, backcompatOptions); - - if (extensionsAst.definitions.length > 0) { - schema = extendSchema(schema, extensionsAst, backcompatOptions); - } - - return schema; -} - -export function buildDocumentFromTypeDefinitions( - typeDefinitions: ITypeDefinitions, - parseOptions?: GraphQLParseOptions -): DocumentNode { - let document: DocumentNode; - if (typeof typeDefinitions === 'string') { - document = parseGraphQLSDL('', typeDefinitions, parseOptions).document; - } else if (Array.isArray(typeDefinitions)) { - document = parseGraphQLSDL('', concatenateTypeDefs(typeDefinitions), parseOptions).document; - } else if (isDocumentNode(typeDefinitions)) { - document = typeDefinitions; - } else { - const type = typeof typeDefinitions; - throw new Error(`typeDefs must be a string, array or schema AST, got ${type}`); - } - - return document; -} diff --git a/packages/schema/src/chainResolvers.ts b/packages/schema/src/chainResolvers.ts index 903382e6db4..8daf3e9fd14 100644 --- a/packages/schema/src/chainResolvers.ts +++ b/packages/schema/src/chainResolvers.ts @@ -1,7 +1,10 @@ import { defaultFieldResolver, GraphQLResolveInfo, GraphQLFieldResolver } from 'graphql'; +import { Maybe } from '@graphql-tools/utils'; -export function chainResolvers(resolvers: Array>) { - return (root: any, args: { [argName: string]: any }, ctx: any, info: GraphQLResolveInfo) => +export function chainResolvers( + resolvers: Array>> +) { + return (root: any, args: TArgs, ctx: any, info: GraphQLResolveInfo) => resolvers.reduce((prev, curResolver) => { if (curResolver != null) { return curResolver(prev, args, ctx, info); diff --git a/packages/schema/src/checkForResolveTypeResolver.ts b/packages/schema/src/checkForResolveTypeResolver.ts index 595776b1dfc..6dcf9508f7d 100644 --- a/packages/schema/src/checkForResolveTypeResolver.ts +++ b/packages/schema/src/checkForResolveTypeResolver.ts @@ -3,7 +3,7 @@ import { GraphQLSchema } from 'graphql'; import { MapperKind, mapSchema, ValidatorBehavior } from '@graphql-tools/utils'; // If we have any union or interface types throw if no there is no resolveType resolver -export function checkForResolveTypeResolver(schema: GraphQLSchema, requireResolversForResolveType: ValidatorBehavior) { +export function checkForResolveTypeResolver(schema: GraphQLSchema, requireResolversForResolveType?: ValidatorBehavior) { mapSchema(schema, { [MapperKind.ABSTRACT_TYPE]: type => { if (!type.resolveType) { diff --git a/packages/schema/src/concatenateTypeDefs.ts b/packages/schema/src/concatenateTypeDefs.ts deleted file mode 100644 index 546c60e3b04..00000000000 --- a/packages/schema/src/concatenateTypeDefs.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { print, ASTNode } from 'graphql'; - -import { ITypedef } from '@graphql-tools/utils'; - -export function concatenateTypeDefs( - typeDefinitionsAry: Array, - calledFunctionRefs = new Set() -): string { - const resolvedTypeDefinitions = new Set(); - typeDefinitionsAry.forEach((typeDef: ITypedef) => { - if (typeof typeDef === 'function') { - if (!calledFunctionRefs.has(typeDef)) { - calledFunctionRefs.add(typeDef); - resolvedTypeDefinitions.add(concatenateTypeDefs(typeDef(), calledFunctionRefs)); - } - } else if (typeof typeDef === 'string') { - resolvedTypeDefinitions.add(typeDef.trim()); - } else if ((typeDef as ASTNode).kind !== undefined) { - resolvedTypeDefinitions.add(print(typeDef).trim()); - } else { - const type = typeof typeDef; - throw new Error(`typeDef array must contain only strings, documents, or functions, got ${type}`); - } - }); - return [...resolvedTypeDefinitions].join('\n'); -} diff --git a/packages/schema/src/decorateWithLogger.ts b/packages/schema/src/decorateWithLogger.ts deleted file mode 100644 index 3d1be51cdce..00000000000 --- a/packages/schema/src/decorateWithLogger.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { defaultFieldResolver, GraphQLFieldResolver } from 'graphql'; -import { ILogger } from './types'; - -/* - * fn: The function to decorate with the logger - * logger: an object instance of type Logger - * hint: an optional hint to add to the error's message - */ -export function decorateWithLogger( - fn: GraphQLFieldResolver, - logger: ILogger, - hint: string -): GraphQLFieldResolver { - const resolver = fn != null ? fn : defaultFieldResolver; - - const logError = (e: Error) => { - // TODO: clone the error properly - const newE = new Error(); - newE.stack = e.stack; - /* istanbul ignore else: always get the hint from addErrorLoggingToSchema */ - if (hint) { - newE['originalMessage'] = e.message; - newE.message = `Error in resolver ${hint}\n${e.message}`; - } - logger.log(newE); - }; - - return (root, args, ctx, info) => { - try { - const result = resolver(root, args, ctx, info); - // If the resolver returns a Promise log any Promise rejects. - if (result && typeof result.then === 'function' && typeof result.catch === 'function') { - result.catch((reason: Error | string) => { - // make sure that it's an error we're logging. - const error = reason instanceof Error ? reason : new Error(reason); - logError(error); - - // We don't want to leave an unhandled exception so pass on error. - return reason; - }); - } - return result; - } catch (e) { - logError(e); - // we want to pass on the error, just in case. - throw e; - } - }; -} diff --git a/packages/schema/src/extendResolversFromInterfaces.ts b/packages/schema/src/extendResolversFromInterfaces.ts index b9233ef60ce..e5c9b1abea0 100644 --- a/packages/schema/src/extendResolversFromInterfaces.ts +++ b/packages/schema/src/extendResolversFromInterfaces.ts @@ -3,28 +3,21 @@ import { GraphQLSchema } from 'graphql'; import { IResolvers, IObjectTypeResolver } from '@graphql-tools/utils'; export function extendResolversFromInterfaces(schema: GraphQLSchema, resolvers: IResolvers): IResolvers { - const typeNames = Object.keys({ - ...schema.getTypeMap(), - ...resolvers, - }); - const extendedResolvers = {}; - typeNames.forEach(typeName => { - const type = schema.getType(typeName); - if (type && 'getInterfaces' in type) { - const allInterfaceResolvers = type - .getInterfaces() - .map(iFace => resolvers[iFace.name]) - .filter(interfaceResolvers => interfaceResolvers != null); - + const typeMap = schema.getTypeMap(); + for (const typeName in typeMap) { + const type = typeMap[typeName]; + if ('getInterfaces' in type) { extendedResolvers[typeName] = {}; - allInterfaceResolvers.forEach(interfaceResolvers => { - Object.keys(interfaceResolvers).forEach(fieldName => { - if (fieldName === '__isTypeOf' || !fieldName.startsWith('__')) { - extendedResolvers[typeName][fieldName] = interfaceResolvers[fieldName]; + for (const iFace of type.getInterfaces()) { + if (resolvers[iFace.name]) { + for (const fieldName in resolvers[iFace.name]) { + if (fieldName === '__isTypeOf' || !fieldName.startsWith('__')) { + extendedResolvers[typeName][fieldName] = resolvers[iFace.name][fieldName]; + } } - }); - }); + } + } const typeResolvers = resolvers[typeName] as Record; extendedResolvers[typeName] = { @@ -37,7 +30,7 @@ export function extendResolversFromInterfaces(schema: GraphQLSchema, resolvers: extendedResolvers[typeName] = typeResolvers; } } - }); + } return extendedResolvers; } diff --git a/packages/schema/src/extensionDefinitions.ts b/packages/schema/src/extensionDefinitions.ts deleted file mode 100644 index d509b1da691..00000000000 --- a/packages/schema/src/extensionDefinitions.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { DocumentNode, DefinitionNode, Kind } from 'graphql'; - -const isExtensionNode = (def: DefinitionNode) => - def.kind === Kind.OBJECT_TYPE_EXTENSION || - def.kind === Kind.INTERFACE_TYPE_EXTENSION || - def.kind === Kind.INPUT_OBJECT_TYPE_EXTENSION || - def.kind === Kind.UNION_TYPE_EXTENSION || - def.kind === Kind.ENUM_TYPE_EXTENSION || - def.kind === Kind.SCALAR_TYPE_EXTENSION || - def.kind === Kind.SCHEMA_EXTENSION; - -export function filterAndExtractExtensionDefinitions(ast: DocumentNode) { - const extensionDefs: DefinitionNode[] = []; - const typesDefs: DefinitionNode[] = []; - ast.definitions.forEach(def => { - if (isExtensionNode(def)) { - extensionDefs.push(def); - } else { - typesDefs.push(def); - } - }); - - return { - typesAst: { - ...ast, - definitions: typesDefs, - }, - extensionsAst: { - ...ast, - definitions: extensionDefs, - }, - }; -} - -export function filterExtensionDefinitions(ast: DocumentNode) { - const { typesAst } = filterAndExtractExtensionDefinitions(ast); - return typesAst; -} - -export function extractExtensionDefinitions(ast: DocumentNode) { - const { extensionsAst } = filterAndExtractExtensionDefinitions(ast); - return extensionsAst; -} diff --git a/packages/schema/src/index.ts b/packages/schema/src/index.ts index 15ad2b2fafd..4d090541b25 100644 --- a/packages/schema/src/index.ts +++ b/packages/schema/src/index.ts @@ -1,15 +1,7 @@ -export { addSchemaLevelResolver } from './addSchemaLevelResolver'; export { assertResolversPresent } from './assertResolversPresent'; -export { attachDirectiveResolvers } from './attachDirectiveResolvers'; -export { buildSchemaFromTypeDefinitions, buildDocumentFromTypeDefinitions } from './buildSchemaFromTypeDefinitions'; export { chainResolvers } from './chainResolvers'; -export { concatenateTypeDefs } from './concatenateTypeDefs'; -export { decorateWithLogger } from './decorateWithLogger'; -export * from './extensionDefinitions'; export { addResolversToSchema } from './addResolversToSchema'; export { checkForResolveTypeResolver } from './checkForResolveTypeResolver'; export { extendResolversFromInterfaces } from './extendResolversFromInterfaces'; -export { addErrorLoggingToSchema } from './addErrorLoggingToSchema'; -export { addCatchUndefinedToSchema } from './addCatchUndefinedToSchema'; export * from './makeExecutableSchema'; export * from './types'; diff --git a/packages/schema/src/makeExecutableSchema.ts b/packages/schema/src/makeExecutableSchema.ts index 552b47520cf..671afd9dff7 100644 --- a/packages/schema/src/makeExecutableSchema.ts +++ b/packages/schema/src/makeExecutableSchema.ts @@ -1,15 +1,11 @@ -import { GraphQLFieldResolver } from 'graphql'; +import { buildASTSchema } from 'graphql'; -import { mergeDeep, SchemaDirectiveVisitor, pruneSchema } from '@graphql-tools/utils'; +import { pruneSchema } from '@graphql-tools/utils'; import { addResolversToSchema } from './addResolversToSchema'; -import { attachDirectiveResolvers } from './attachDirectiveResolvers'; import { assertResolversPresent } from './assertResolversPresent'; -import { addSchemaLevelResolver } from './addSchemaLevelResolver'; -import { buildSchemaFromTypeDefinitions } from './buildSchemaFromTypeDefinitions'; -import { addErrorLoggingToSchema } from './addErrorLoggingToSchema'; -import { addCatchUndefinedToSchema } from './addCatchUndefinedToSchema'; import { ExecutableSchemaTransformation, IExecutableSchemaDefinition } from './types'; +import { mergeResolvers, mergeTypeDefs } from '@graphql-tools/merge'; /** * Builds a schema from the provided type definitions and resolvers. @@ -58,17 +54,12 @@ import { ExecutableSchemaTransformation, IExecutableSchemaDefinition } from './t export function makeExecutableSchema({ typeDefs, resolvers = {}, - logger, - allowUndefinedInResolve = true, resolverValidationOptions = {}, - directiveResolvers, - schemaDirectives, schemaTransforms: userProvidedSchemaTransforms, parseOptions = {}, inheritResolversFromInterfaces = false, pruningOptions, updateResolversInPlace = false, - noExtensionExtraction = false, }: IExecutableSchemaDefinition) { // Validate and clean up arguments if (typeof resolverValidationOptions !== 'object') { @@ -83,11 +74,10 @@ export function makeExecutableSchema({ const schemaTransforms: ExecutableSchemaTransformation[] = [ schema => { // We allow passing in an array of resolver maps, in which case we merge them - const resolverMap: any = Array.isArray(resolvers) ? resolvers.reduce(mergeDeep, {}) : resolvers; const schemaWithResolvers = addResolversToSchema({ schema, - resolvers: resolverMap, + resolvers: mergeResolvers(resolvers), resolverValidationOptions, inheritResolversFromInterfaces, updateResolversInPlace, @@ -101,46 +91,18 @@ export function makeExecutableSchema({ }, ]; - if (!allowUndefinedInResolve) { - schemaTransforms.push(addCatchUndefinedToSchema); - } - - if (logger != null) { - schemaTransforms.push(schema => addErrorLoggingToSchema(schema, logger)); - } - - if (typeof resolvers['__schema'] === 'function') { - // TODO a bit of a hack now, better rewrite generateSchema to attach it there. - // not doing that now, because I'd have to rewrite a lot of tests. - schemaTransforms.push(schema => - addSchemaLevelResolver(schema, resolvers['__schema'] as GraphQLFieldResolver) - ); - } - if (userProvidedSchemaTransforms) { schemaTransforms.push(schema => userProvidedSchemaTransforms.reduce((s, schemaTransform) => schemaTransform(s), schema) ); } - // directive resolvers are implemented using SchemaDirectiveVisitor.visitSchemaDirectives - // schema visiting modifies the schema in place - if (directiveResolvers != null) { - schemaTransforms.push(schema => attachDirectiveResolvers(schema, directiveResolvers)); - } - - if (schemaDirectives != null) { - schemaTransforms.push(schema => { - SchemaDirectiveVisitor.visitSchemaDirectives(schema, schemaDirectives); - return schema; - }); - } - if (pruningOptions) { schemaTransforms.push(pruneSchema); } - const schemaFromTypeDefs = buildSchemaFromTypeDefinitions(typeDefs, parseOptions, noExtensionExtraction); + const mergedTypeDefs = mergeTypeDefs(typeDefs, parseOptions); + const schemaFromTypeDefs = buildASTSchema(mergedTypeDefs, parseOptions); return schemaTransforms.reduce((schema, schemaTransform) => schemaTransform(schema), schemaFromTypeDefs); } diff --git a/packages/schema/src/types.ts b/packages/schema/src/types.ts index e263d1340c1..ed28779d686 100644 --- a/packages/schema/src/types.ts +++ b/packages/schema/src/types.ts @@ -1,19 +1,13 @@ import { GraphQLSchema } from 'graphql'; import { - ITypeDefinitions, + TypeSource, IResolvers, IResolverValidationOptions, - IDirectiveResolvers, - SchemaDirectiveVisitorClass, GraphQLParseOptions, PruneSchemaOptions, } from '@graphql-tools/utils'; -export interface ILogger { - log: (error: Error) => void; -} - /** * Configuration object for creating an executable schema */ @@ -21,34 +15,15 @@ export interface IExecutableSchemaDefinition { /** * The type definitions used to create the schema */ - typeDefs: ITypeDefinitions; + typeDefs: TypeSource; /** * Object describing the field resolvers for the provided type definitions */ resolvers?: IResolvers | Array>; - /** - * Logger instance used to print errors to the server console that are - * usually swallowed by GraphQL. - */ - logger?: ILogger; - /** - * Set to `false` to have resolvers throw an if they return undefined, which - * can help make debugging easier - */ - allowUndefinedInResolve?: boolean; /** * Additional options for validating the provided resolvers */ resolverValidationOptions?: IResolverValidationOptions; - /** - * Map of directive resolvers - */ - directiveResolvers?: IDirectiveResolvers; - /** - * A map of schema directives used with the legacy class-based implementation - * of schema directives - */ - schemaDirectives?: Record; /** * An array of schema transformation functions */ @@ -71,10 +46,6 @@ export interface IExecutableSchemaDefinition { * Do not create a schema again and use the one from `buildASTSchema` */ updateResolversInPlace?: boolean; - /** - * Do not extract and apply extensions separately and leave it to `buildASTSchema` - */ - noExtensionExtraction?: boolean; } export type ExecutableSchemaTransformation = (schema: GraphQLSchema) => GraphQLSchema; diff --git a/packages/schema/tests/Logger.ts b/packages/schema/tests/Logger.ts deleted file mode 100644 index 8495a16c371..00000000000 --- a/packages/schema/tests/Logger.ts +++ /dev/null @@ -1,36 +0,0 @@ -/* - * A very simple class for logging errors - */ - -import { ILogger } from '@graphql-tools/schema'; - -export class Logger implements ILogger { - public errors: Array; - public name: string | undefined; - private readonly callback: (...args: any[]) => any | undefined; - - constructor(name?: string, callback?: (...args: any[]) => any) { - this.name = name; - this.errors = []; - this.callback = callback; - // TODO: should assert that callback is a function - } - - public log(err: Error) { - this.errors.push(err); - if (typeof this.callback === 'function') { - this.callback(err); - } - } - - public printOneError(e: Error): string { - return e.stack ? e.stack : ''; - } - - public printAllErrors() { - return this.errors.reduce( - (agg: string, e: Error) => `${agg}\n${this.printOneError(e)}`, - '', - ); - } -} diff --git a/packages/schema/tests/extensionExtraction.test.ts b/packages/schema/tests/extensionExtraction.test.ts deleted file mode 100644 index b972530441d..00000000000 --- a/packages/schema/tests/extensionExtraction.test.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { parse } from 'graphql'; - -import { extractExtensionDefinitions } from '@graphql-tools/schema'; - -describe('Extension extraction', () => { - test('extracts extended inputs', () => { - const typeDefs = ` - input Input { - foo: String - } - - extend input Input { - bar: String - } - `; - - const astDocument = parse(typeDefs); - const extensionAst = extractExtensionDefinitions(astDocument); - - expect(extensionAst.definitions).toHaveLength(1); - expect(extensionAst.definitions[0].kind).toBe('InputObjectTypeExtension'); - }); - - test('extracts extended unions', () => { - const typeDefs = ` - type Person { - name: String! - } - type Location { - name: String! - } - union Searchable = Person | Location - - type Post { - name: String! - } - extend union Searchable = Post - `; - - const astDocument = parse(typeDefs); - const extensionAst = extractExtensionDefinitions(astDocument); - - expect(extensionAst.definitions).toHaveLength(1); - expect(extensionAst.definitions[0].kind).toBe('UnionTypeExtension'); - }); - - test('extracts extended enums', () => { - const typeDefs = ` - enum Color { - RED - GREEN - } - - extend enum Color { - BLUE - } - `; - - const astDocument = parse(typeDefs); - const extensionAst = extractExtensionDefinitions(astDocument); - - expect(extensionAst.definitions).toHaveLength(1); - expect(extensionAst.definitions[0].kind).toBe('EnumTypeExtension'); - }); -}); diff --git a/packages/schema/tests/logger.test.ts b/packages/schema/tests/logger.test.ts deleted file mode 100644 index 4171bce3533..00000000000 --- a/packages/schema/tests/logger.test.ts +++ /dev/null @@ -1,409 +0,0 @@ -/* eslint-disable promise/param-names */ -import { graphql } from 'graphql'; - -import { makeExecutableSchema } from '@graphql-tools/schema'; - -import { Logger } from './Logger'; - -describe('Logger', () => { - test('logs the errors', () => { - const shorthand = ` - type RootQuery { - just_a_field: Int - } - type RootMutation { - species(name: String): String - stuff: String - } - schema { - query: RootQuery - mutation: RootMutation - } - `; - const resolve = { - RootMutation: { - species: () => { - throw new Error('oops!'); - }, - stuff: () => { - throw new Error('oh noes!'); - }, - }, - }; - const logger = new Logger(); - const jsSchema = makeExecutableSchema({ - typeDefs: shorthand, - resolvers: resolve, - logger, - }); - // calling the mutation here so the errors will be ordered. - const testQuery = 'mutation { species, stuff }'; - const expected0 = 'Error in resolver RootMutation.species\noops!'; - const expected1 = 'Error in resolver RootMutation.stuff\noh noes!'; - return graphql(jsSchema, testQuery).then(() => { - expect(logger.errors.length).toEqual(2); - expect(logger.errors[0].message).toEqual(expected0); - expect(logger.errors[1].message).toEqual(expected1); - }); - }); - - test('also forwards the errors when you tell it to', () => { - const shorthand = ` - type RootQuery { - species(name: String): String - } - schema { - query: RootQuery - } - `; - const resolve = { - RootQuery: { - species: () => { - throw new Error('oops!'); - }, - }, - }; - let loggedErr: Error = null; - const logger = new Logger('LoggyMcLogface', (e: Error) => { - loggedErr = e; - }); - const jsSchema = makeExecutableSchema({ - typeDefs: shorthand, - resolvers: resolve, - logger, - }); - const testQuery = '{ species }'; - return graphql(jsSchema, testQuery).then(() => { - expect(loggedErr).toEqual(logger.errors[0]); - }); - }); - - test('prints the errors when you want it to', () => { - const shorthand = ` - type RootQuery { - species(name: String): String - } - schema { - query: RootQuery - } - `; - const resolve = { - RootQuery: { - species: (_root: any, { name }: { name: string }) => { - if (name) { - throw new Error(name); - } - throw new Error('oops!'); - }, - }, - }; - const logger = new Logger(); - const jsSchema = makeExecutableSchema({ - typeDefs: shorthand, - resolvers: resolve, - logger, - }); - const testQuery = '{ q: species, p: species(name: "Peter") }'; - return graphql(jsSchema, testQuery).then(() => { - const allErrors = logger.printAllErrors(); - expect(allErrors).toMatch(/oops/); - expect(allErrors).toMatch(/Peter/); - }); - }); - - test('logs any Promise reject errors', () => { - const shorthand = ` - type RootQuery { - just_a_field: Int - } - type RootMutation { - species(name: String): String - stuff: String - } - schema { - query: RootQuery - mutation: RootMutation - } - `; - const resolve = { - RootMutation: { - species: () => - new Promise((_, reject) => { - reject(new Error('oops!')); - }), - stuff: () => - new Promise((_, reject) => { - reject(new Error('oh noes!')); - }), - }, - }; - const logger = new Logger(); - const jsSchema = makeExecutableSchema({ - typeDefs: shorthand, - resolvers: resolve, - logger, - }); - - const testQuery = 'mutation { species, stuff }'; - const expected0 = 'Error in resolver RootMutation.species\noops!'; - const expected1 = 'Error in resolver RootMutation.stuff\noh noes!'; - return graphql(jsSchema, testQuery).then(() => { - expect(logger.errors.length).toEqual(2); - expect(logger.errors[0].message).toEqual(expected0); - expect(logger.errors[1].message).toEqual(expected1); - }); - }); - - test('all Promise rejects will log an Error', () => { - const shorthand = ` - type RootQuery { - species(name: String): String - } - schema { - query: RootQuery - } - `; - const resolve = { - RootQuery: { - species: () => - new Promise((_, reject) => { - reject(new Error('oops!')); - }), - }, - }; - - let loggedErr: Error = null; - const logger = new Logger('LoggyMcLogface', (e: Error) => { - loggedErr = e; - }); - const jsSchema = makeExecutableSchema({ - typeDefs: shorthand, - resolvers: resolve, - logger, - }); - - const testQuery = '{ species }'; - return graphql(jsSchema, testQuery).then(() => { - expect(loggedErr).toEqual(logger.errors[0]); - }); - }); -}); - - - -describe('providing useful errors from resolvers', () => { - test('logs an error if a resolver fails', () => { - const shorthand = ` - type RootQuery { - species(name: String): String - } - schema { - query: RootQuery - } - `; - const resolve = { - RootQuery: { - species: (): string => { - throw new Error('oops!'); - }, - }, - }; - - // TODO: Should use a spy here instead of logger class - // to make sure we don't duplicate tests from Logger. - const logger = new Logger(); - const jsSchema = makeExecutableSchema({ - typeDefs: shorthand, - resolvers: resolve, - logger, - }); - const testQuery = '{ species }'; - const expected = 'Error in resolver RootQuery.species\noops!'; - return graphql(jsSchema, testQuery).then((_res) => { - expect(logger.errors.length).toEqual(1); - expect(logger.errors[0].message).toEqual(expected); - }); - }); - - test('will throw errors on undefined if you tell it to', () => { - const shorthand = ` - type RootQuery { - species(name: String): String - stuff: String - } - schema { - query: RootQuery - } - `; - const resolve = { - RootQuery: { - species: (): string => undefined, - stuff: () => 'stuff', - }, - }; - - const logger = new Logger(); - const jsSchema = makeExecutableSchema({ - typeDefs: shorthand, - resolvers: resolve, - logger, - allowUndefinedInResolve: false, - }); - const testQuery = '{ species, stuff }'; - const expectedErr = /Resolver for "RootQuery.species" returned undefined/; - const expectedResData = { species: null as string, stuff: 'stuff' }; - return graphql(jsSchema, testQuery).then((res) => { - expect(logger.errors.length).toEqual(1); - expect(logger.errors[0].message).toMatch(expectedErr); - expect(res.data).toEqual(expectedResData); - }); - }); - - test('decorateToCatchUndefined preserves default resolvers', () => { - const shorthand = ` - type Thread { - name: String - } - type RootQuery { - thread(name: String): Thread - } - schema { - query: RootQuery - } - `; - const resolve = { - RootQuery: { - thread(_root: any, args: Record) { - return args; - }, - }, - }; - - const jsSchema = makeExecutableSchema({ - typeDefs: shorthand, - resolvers: resolve, - allowUndefinedInResolve: false, - }); - const testQuery = `{ - thread(name: "SomeThread") { - name - } - }`; - const expectedResData = { - thread: { - name: 'SomeThread', - }, - }; - return graphql(jsSchema, testQuery).then((res) => { - expect(res.data).toEqual(expectedResData); - }); - }); - - test('decorateToCatchUndefined throws even if default resolvers are preserved', () => { - const shorthand = ` - type Thread { - name: String - } - type RootQuery { - thread(name: String): Thread - } - schema { - query: RootQuery - } - `; - const resolve = { - RootQuery: { - thread(_root: any, _args: Record) { - return { name: (): any => undefined }; - }, - }, - }; - - const jsSchema = makeExecutableSchema({ - typeDefs: shorthand, - resolvers: resolve, - allowUndefinedInResolve: false, - }); - const testQuery = `{ - thread { - name - } - }`; - return graphql(jsSchema, testQuery).then((res) => { - expect(res.errors[0].originalError.message).toBe( - 'Resolver for "Thread.name" returned undefined', - ); - }); - }); - - test('will use default resolver when returning function properties ', () => { - const shorthand = ` - type Thread { - name: String - } - type RootQuery { - thread(name: String): Thread - } - schema { - query: RootQuery - } - `; - const resolve = { - RootQuery: { - thread(_root: any, args: Record) { - return { name: () => args.name }; - }, - }, - }; - - const jsSchema = makeExecutableSchema({ - typeDefs: shorthand, - resolvers: resolve, - allowUndefinedInResolve: false, - }); - const testQuery = `{ - thread(name: "SomeThread") { - name - } - }`; - const expectedResData = { - thread: { - name: 'SomeThread', - }, - }; - return graphql(jsSchema, testQuery).then((res) => { - expect(res.data).toEqual(expectedResData); - }); - }); - - test('will not throw errors on undefined by default', () => { - const shorthand = ` - type RootQuery { - species(name: String): String - stuff: String - } - schema { - query: RootQuery - } - `; - const resolve = { - RootQuery: { - species: (): string => undefined, - stuff: () => 'stuff', - }, - }; - - const logger = new Logger(); - const jsSchema = makeExecutableSchema({ - typeDefs: shorthand, - resolvers: resolve, - logger, - }); - const testQuery = '{ species, stuff }'; - const expectedResData = { species: null as string, stuff: 'stuff' }; - return graphql(jsSchema, testQuery).then((res) => { - expect(logger.errors.length).toEqual(0); - expect(res.data).toEqual(expectedResData); - }); - }); -}); diff --git a/packages/schema/tests/resolution.test.ts b/packages/schema/tests/resolution.test.ts deleted file mode 100644 index 9cc71a3c43c..00000000000 --- a/packages/schema/tests/resolution.test.ts +++ /dev/null @@ -1,148 +0,0 @@ -/* eslint-disable promise/param-names */ -import { - parse, - graphql, - subscribe, - graphqlSync, -} from 'graphql'; -import { PubSub } from 'graphql-subscriptions'; - -import { makeExecutableSchema, addSchemaLevelResolver } from '@graphql-tools/schema'; - -import { ExecutionResult } from '@graphql-tools/utils'; - -describe('Resolve', () => { - describe('addSchemaLevelResolver', () => { - const pubsub = new PubSub(); - const typeDefs = ` - type RootQuery { - printRoot: String! - printRootAgain: String! - } - - type RootMutation { - printRoot: String! - } - - type RootSubscription { - printRoot: String! - } - - schema { - query: RootQuery - mutation: RootMutation - subscription: RootSubscription - } - `; - const printRoot = (root: any) => root.toString(); - const resolvers = { - RootQuery: { - printRoot, - printRootAgain: printRoot, - }, - RootMutation: { - printRoot, - }, - RootSubscription: { - printRoot: { - subscribe: () => pubsub.asyncIterator('printRootChannel'), - }, - }, - }; - let schema = makeExecutableSchema({ typeDefs, resolvers }); - let schemaLevelResolverCalls = 0; - schema = addSchemaLevelResolver(schema, (root) => { - schemaLevelResolverCalls += 1; - return root; - }); - - test('should run the schema level resolver once in a same query', () => { - schemaLevelResolverCalls = 0; - const root = 'queryRoot'; - return graphql( - schema, - ` - query TestOnce { - printRoot - printRootAgain - } - `, - root, - ).then(({ data }) => { - expect(data).toEqual({ - printRoot: root, - printRootAgain: root, - }); - expect(schemaLevelResolverCalls).toEqual(1); - }); - }); - - test('should isolate roots from the different operation types', async () => { - schemaLevelResolverCalls = 0; - const queryRoot = 'queryRoot'; - const mutationRoot = 'mutationRoot'; - const subscriptionRoot = 'subscriptionRoot'; - const subscriptionRoot2 = 'subscriptionRoot2'; - - const sub = await subscribe( - schema, - parse(` - subscription TestSubscription { - printRoot - } - `), - ) as AsyncIterableIterator; - - const payload1 = sub.next(); - await pubsub.publish('printRootChannel', { printRoot: subscriptionRoot }); - - expect(await payload1).toEqual({ done: false, value: { data: { printRoot: subscriptionRoot } } }); - expect(schemaLevelResolverCalls).toEqual(1); - - const queryResult = await graphql( - schema, - ` - query TestQuery { - printRoot - } - `, - queryRoot, - ); - - expect(queryResult).toEqual({ data: { printRoot: queryRoot } }); - expect(schemaLevelResolverCalls).toEqual(2); - - const mutationResult = await graphql( - schema, - ` - mutation TestMutation { - printRoot - } - `, - mutationRoot, - ); - - expect(mutationResult).toEqual({ data: { printRoot: mutationRoot } }); - expect(schemaLevelResolverCalls).toEqual(3); - - await pubsub.publish('printRootChannel', { printRoot: subscriptionRoot2 }); - - expect(await sub.next()).toEqual({ done: false, value: { data: { printRoot: subscriptionRoot2 } } }); - expect(schemaLevelResolverCalls).toEqual(4); - }); - - it('should not force an otherwise synchronous operation to be asynchronous', () => { - const queryRoot = 'queryRoot'; - // This will throw an error if schema has any asynchronous resolvers - graphqlSync( - schema, - ` - query TestQuery { - printRoot - } - `, - queryRoot, - ); - }); - }); -}); diff --git a/packages/schema/tests/schemaGenerator.test.ts b/packages/schema/tests/schemaGenerator.test.ts index cf4295d2661..02a0034fea5 100644 --- a/packages/schema/tests/schemaGenerator.test.ts +++ b/packages/schema/tests/schemaGenerator.test.ts @@ -20,29 +20,19 @@ import { DocumentNode, GraphQLBoolean, graphqlSync, - GraphQLSchema, } from 'graphql'; import { makeExecutableSchema, - addErrorLoggingToSchema, - addSchemaLevelResolver, addResolversToSchema, - attachDirectiveResolvers, chainResolvers, - concatenateTypeDefs, - ILogger, } from '@graphql-tools/schema'; import { IResolverValidationOptions, IResolvers, - IDirectiveResolvers, - NextResolverFn, - VisitSchemaKind, - ITypeDefinitions, - visitSchema, - ExecutionResult + ExecutionResult, + TypeSource } from '@graphql-tools/utils'; import TypeA from './fixtures/circularSchemaA'; @@ -55,7 +45,7 @@ interface Bird { function expectWarning(fn: () => void, warnMatcher?: string) { // eslint-disable-next-line no-console const originalWarn = console.warn; - let warning: string = null; + let warning: string | null = null; try { // eslint-disable-next-line no-console @@ -87,7 +77,6 @@ const testSchema = ` } `; const testResolvers = { - __schema: () => ({ stuff: 'stuff', species: 'ROOT' }), RootQuery: { usecontext: (_r: any, _a: Record, ctx: any) => ctx.usecontext, species: (root: any, { name }: { name: string }) => @@ -97,11 +86,13 @@ const testResolvers = { describe('generating schema from shorthand', () => { test('throws an error if no schema is provided', () => { + // @ts-expect-error: we call it with invalid params expect(() => makeExecutableSchema(undefined)).toThrowError('undefined'); }); test('throws an error if typeDefinitionNodes are not provided', () => { expect(() => + // @ts-expect-error: we call it with invalid params makeExecutableSchema({ typeDefs: undefined, resolvers: {} }), ).toThrowError('Must provide typeDefs'); }); @@ -115,22 +106,22 @@ describe('generating schema from shorthand', () => { test('throws an error if typeDefinitionNodes is neither string nor array nor schema AST', () => { expect(() => makeExecutableSchema({ - typeDefs: ({} as unknown) as ITypeDefinitions, + typeDefs: ({} as unknown) as TypeSource, resolvers: {}, }), ).toThrowError( - 'typeDefs must be a string, array or schema AST, got object', + 'typeDefs must contain only strings, documents, schemas, or functions, got object', ); }); test('throws an error if typeDefinitionNode array contains not only functions and strings', () => { expect(() => makeExecutableSchema({ - typeDefs: ([17] as unknown) as ITypeDefinitions, + typeDefs: ([17] as unknown) as TypeSource, resolvers: {}, }), ).toThrowError( - 'typeDef array must contain only strings, documents, or functions, got number', + 'typeDefs must contain only strings, documents, schemas, or functions, got number', ); }); @@ -218,7 +209,7 @@ describe('generating schema from shorthand', () => { name: 'name', type: { kind: 'NON_NULL', - name: null as string, + name: null as string | null, ofType: { name: 'String', }, @@ -242,7 +233,7 @@ describe('generating schema from shorthand', () => { name: 'species', type: { kind: 'LIST', - name: null as string, + name: null as string | null, ofType: { name: 'BirdSpecies', }, @@ -251,7 +242,7 @@ describe('generating schema from shorthand', () => { { name: 'name', type: { - name: null as string, + name: null as string | null, kind: 'NON_NULL', ofType: { name: 'String', @@ -293,7 +284,7 @@ describe('generating schema from shorthand', () => { typeDefs: typeDefAry, resolvers: {}, }); - expect(jsSchema.getQueryType().name).toBe('Query'); + expect(jsSchema.getQueryType()?.name).toBe('Query'); }); test('can generate a schema from a parsed type definition', () => { @@ -310,7 +301,7 @@ describe('generating schema from shorthand', () => { typeDefs: typeDefSchema, resolvers: {}, }); - expect(jsSchema.getQueryType().name).toBe('Query'); + expect(jsSchema.getQueryType()?.name).toBe('Query'); }); test('can generate a schema from an array of parsed and none parsed type definitions', () => { @@ -330,7 +321,7 @@ describe('generating schema from shorthand', () => { typeDefs: typeDefSchema, resolvers: {}, }); - expect(jsSchema.getQueryType().name).toBe('Query'); + expect(jsSchema.getQueryType()?.name).toBe('Query'); }); test('can generate a schema from an array of types with extensions', () => { @@ -356,9 +347,9 @@ describe('generating schema from shorthand', () => { typeDefs: typeDefAry, resolvers: {}, }); - expect(jsSchema.getQueryType().name).toBe('Query'); - expect(jsSchema.getQueryType().getFields().foo).toBeDefined(); - expect(jsSchema.getQueryType().getFields().bar).toBeDefined(); + expect(jsSchema.getQueryType()?.name).toBe('Query'); + expect(jsSchema.getQueryType()?.getFields()['foo']).toBeDefined(); + expect(jsSchema.getQueryType()?.getFields()['bar']).toBeDefined(); }); test('allow for a map of extensions in field resolver', () => { @@ -381,33 +372,9 @@ describe('generating schema from shorthand', () => { }, }, }); - const extensions = jsSchema.getQueryType().getFields().foo.extensions; + const extensions = jsSchema.getQueryType()?.getFields()['foo'].extensions; expect(extensions).toHaveProperty('verbose'); - expect(extensions.verbose).toBe(true); - }); - - test('can concatenateTypeDefs created by a function inside a closure', () => { - const typeA = { typeDefs: () => ['type TypeA { foo: String }'] }; - const typeB = { typeDefs: () => ['type TypeB { bar: String }'] }; - const typeC = { typeDefs: () => ['type TypeC { foo: String }'] }; - const typeD = { typeDefs: () => ['type TypeD { bar: String }'] }; - - function combineTypeDefs(...args: Array): any { - return { typeDefs: () => args.map((o) => o.typeDefs) }; - } - - const combinedAandB = combineTypeDefs(typeA, typeB); - const combinedCandD = combineTypeDefs(typeC, typeD); - - const result = concatenateTypeDefs([ - combinedAandB.typeDefs, - combinedCandD.typeDefs, - ]); - - expect(result).toMatch('type TypeA'); - expect(result).toMatch('type TypeB'); - expect(result).toMatch('type TypeC'); - expect(result).toMatch('type TypeD'); + expect(extensions!.verbose).toBe(true); }); test('properly deduplicates the array of type DefinitionNodes', () => { @@ -433,7 +400,7 @@ describe('generating schema from shorthand', () => { typeDefs: typeDefAry, resolvers: {}, }); - expect(jsSchema.getQueryType().name).toBe('Query'); + expect(jsSchema.getQueryType()?.name).toBe('Query'); }); test('works with imports, even circular ones', () => { @@ -459,7 +426,7 @@ describe('generating schema from shorthand', () => { TypeB: { a: () => null }, }, }); - expect(jsSchema.getQueryType().name).toBe('Query'); + expect(jsSchema.getQueryType()?.name).toBe('Query'); }); test('can generate a schema with resolvers', () => { @@ -748,7 +715,7 @@ describe('generating schema from shorthand', () => { const QueryResolver = class QueryResolver { private internalVersion = 1 - version(root: any, args: any, context: any) { + version() { return this.internalVersion } } @@ -804,13 +771,13 @@ describe('generating schema from shorthand', () => { typeDefs: shorthand, resolvers: resolveFunctions, }); - expect(jsSchema.getQueryType().name).toBe('Query'); + expect(jsSchema.getQueryType()?.name).toBe('Query'); for (const scalarName of scalarNames) { expect(jsSchema.getType(scalarName)).toBeInstanceOf(GraphQLScalarType); expect(jsSchema.getType(scalarName)).toHaveProperty('description'); - expect(typeof jsSchema.getType(scalarName).description).toBe('string'); + expect(typeof jsSchema.getType(scalarName)?.description).toBe('string'); expect( - jsSchema.getType(scalarName).description.length, + jsSchema.getType(scalarName)?.description?.length, ).toBeGreaterThan(0); } }); @@ -832,7 +799,7 @@ describe('generating schema from shorthand', () => { typeDefs: shorthand, resolvers: resolveFunctions, }); - expect(jsSchema.getQueryType().name).toBe('Query'); + expect(jsSchema.getQueryType()?.name).toBe('Query'); expect(jsSchema.getType('Boolean')).toBe(GraphQLBoolean); }); @@ -868,7 +835,7 @@ describe('generating schema from shorthand', () => { } `; const result = graphqlSync(jsSchema, testQuery); - expect(result.data.foo.aField).toBe(false); + expect(result.data!['foo'].aField).toBe(false); jsSchema = addResolversToSchema({ schema: jsSchema, resolvers: { @@ -905,81 +872,7 @@ describe('generating schema from shorthand', () => { const testType = schema.getType('Test'); expect(testType).toBeInstanceOf(GraphQLScalarType); - expect(testType.astNode.directives.length).toBe(1); - }); - - test('retains scalars after walking/recreating the schema', () => { - const shorthand = ` - scalar Test - - type Foo { - testField: Test - } - - type Query { - test: Test - testIn(input: Test): Test - } - `; - const resolveFunctions = { - Test: new GraphQLScalarType({ - name: 'Test', - description: 'Test resolver', - serialize(value) { - if (typeof value !== 'string' || value.indexOf('scalar:') !== 0) { - return `scalar:${value as string}`; - } - return value; - }, - parseValue(value) { - return `scalar:${value as string}`; - }, - parseLiteral(ast: any) { - switch (ast.kind) { - case Kind.STRING: - case Kind.INT: - return `scalar:${ast.value as string}`; - default: - return null; - } - }, - }), - Query: { - testIn(_: any, { input }: any) { - expect(input).toMatch('scalar:'); - return input; - }, - test() { - return 42; - }, - }, - }; - const walkedSchema = visitSchema( - makeExecutableSchema({ - typeDefs: shorthand, - resolvers: resolveFunctions, - }), - { - [VisitSchemaKind.ENUM_TYPE](type: GraphQLEnumType) { - return type; - }, - }, - ); - expect(walkedSchema.getType('Test')).toBeInstanceOf(GraphQLScalarType); - expect(walkedSchema.getType('Test')).toHaveProperty('description'); - expect(walkedSchema.getType('Test').description).toBe('Test resolver'); - const testQuery = ` - { - test - testIn(input: 1) - }`; - const resultPromise = graphql(walkedSchema, testQuery); - return resultPromise.then((result) => - expect(result.data).toEqual({ - test: 'scalar:42', - testIn: 'scalar:1', - }), - ); + expect(testType!.astNode!.directives!.length).toBe(1); }); test('should support custom scalar usage on client-side query execution', () => { @@ -1096,7 +989,7 @@ describe('generating schema from shorthand', () => { `; const resultPromise = graphql(jsSchema, testQuery); return resultPromise.then((result) => { - expect(result.data.post.something).toEqual(testValue); + expect(result.data!['post'].something).toEqual(testValue); expect(result.errors).toEqual(undefined); }); }); @@ -1166,7 +1059,7 @@ describe('generating schema from shorthand', () => { `; const resultPromise = graphql(jsSchema, testQuery); return resultPromise.then((result) => { - expect(result.data.post.something).toEqual(testDate.getTime()); + expect(result.data!['post'].something).toEqual(testDate.getTime()); expect(result.errors).toEqual(undefined); }); }); @@ -1207,7 +1100,7 @@ describe('generating schema from shorthand', () => { resolvers: resolveFunctions, }); - expect(jsSchema.getQueryType().name).toBe('Query'); + expect(jsSchema.getQueryType()!.name).toBe('Query'); expect(jsSchema.getType('Color')).toBeInstanceOf(GraphQLEnumType); expect(jsSchema.getType('NumericEnum')).toBeInstanceOf(GraphQLEnumType); }); @@ -1268,9 +1161,9 @@ describe('generating schema from shorthand', () => { const resultPromise = graphql(jsSchema, testQuery); return resultPromise.then((result) => { - expect(result.data.redColor).toEqual('RED'); - expect(result.data.blueColor).toEqual('BLUE'); - expect(result.data.numericEnum).toEqual('TEST'); + expect(result.data!['redColor']).toEqual('RED'); + expect(result.data!['blueColor']).toEqual('BLUE'); + expect(result.data!['numericEnum']).toEqual('TEST'); expect(result.errors).toEqual(undefined); }); }); @@ -1327,9 +1220,9 @@ describe('generating schema from shorthand', () => { const resultPromise = graphql(jsSchema, testQuery); return resultPromise.then((result) => { - expect(result.data.red).toEqual(resolveFunctions.Color.RED); - expect(result.data.blue).toEqual(resolveFunctions.Color.BLUE); - expect(result.data.num).toEqual(resolveFunctions.NumericEnum.TEST); + expect(result.data!['red']).toEqual(resolveFunctions.Color.RED); + expect(result.data!['blue']).toEqual(resolveFunctions.Color.BLUE); + expect(result.data!['num']).toEqual(resolveFunctions.NumericEnum.TEST); expect(result.errors).toEqual(undefined); }); }); @@ -1373,7 +1266,7 @@ describe('generating schema from shorthand', () => { const resultPromise = graphql(jsSchema, testQuery); return resultPromise.then((result) => { - expect(result.data.red).toEqual(resolveFunctions.Color.RED); + expect(result.data!['red']).toEqual(resolveFunctions.Color.RED); expect(result.errors).toEqual(undefined); }); }); @@ -1424,7 +1317,7 @@ describe('generating schema from shorthand', () => { const resultPromise = graphql(jsSchema, testQuery); return resultPromise.then((result) => { - expect(result.data.red).toEqual('override'); + expect(result.data!['red']).toEqual('override'); expect(result.errors).toEqual(undefined); }); }); @@ -1472,7 +1365,7 @@ describe('generating schema from shorthand', () => { const resultPromise = graphql(jsSchema, testQuery); return resultPromise.then((result) => { - expect(result.data.red).toEqual('#EA3232'); + expect(result.data!['red']).toEqual('#EA3232'); expect(result.errors).toEqual(undefined); }); }); @@ -1648,7 +1541,7 @@ To disable this validator, use: makeExecutableSchema.bind(null, { typeDefs: short, resolvers: rf, - resolverValidationOptions: { requireResolversForNonScalar: false }, + resolverValidationOptions: { requireResolversForNonScalar: 'ignore' }, }), ).not.toThrow(); }); @@ -2009,157 +1902,6 @@ To disable this validator, use: }); }); -describe('Add error logging to schema', () => { - test('throws an error if no logger is provided', () => { - expect(() => - addErrorLoggingToSchema(({} as unknown) as GraphQLSchema), - ).toThrow('Must provide a logger'); - }); - test('throws an error if logger.log is not a function', () => { - expect(() => - addErrorLoggingToSchema( - ({} as unknown) as GraphQLSchema, - ({ log: '1' } as unknown) as ILogger, - ), - ).toThrow('Logger.log must be a function'); - }); -}); - -describe('Attaching external data fetchers to schema', () => { - describe('Schema level resolver', () => { - test('actually runs', () => { - let jsSchema = makeExecutableSchema({ - typeDefs: testSchema, - resolvers: testResolvers, - }); - const rootResolver = () => ({ species: 'ROOT' }); - jsSchema = addSchemaLevelResolver(jsSchema, rootResolver); - const query = `{ - species(name: "strix") - }`; - return graphql(jsSchema, query).then((res) => { - expect(res.data.species).toBe('ROOTstrix'); - }); - }); - - test('can wrap fields that do not have a resolver defined', () => { - let jsSchema = makeExecutableSchema({ - typeDefs: testSchema, - resolvers: testResolvers, - }); - const rootResolver = () => ({ stuff: 'stuff' }); - jsSchema = addSchemaLevelResolver(jsSchema, rootResolver); - const query = `{ - stuff - }`; - return graphql(jsSchema, query).then((res) => { - expect(res.data.stuff).toBe('stuff'); - }); - }); - - test('runs only once per query', () => { - const simpleResolvers = { - RootQuery: { - usecontext: (_r: any, _a: Record, ctx: any) => - ctx.usecontext, - species: (root: any, { name }: { name: string }) => - (root.species as string) + name, - }, - }; - let jsSchema = makeExecutableSchema({ - typeDefs: testSchema, - resolvers: simpleResolvers, - }); - let count = 0; - const rootResolver = () => { - if (count === 0) { - count += 1; - return { stuff: 'stuff', species: 'some ' }; - } - return { stuff: 'EEE', species: 'EEE' }; - }; - jsSchema = addSchemaLevelResolver(jsSchema, rootResolver); - const query = `{ - species(name: "strix") - stuff - }`; - const expected = { - species: 'some strix', - stuff: 'stuff', - }; - return graphql(jsSchema, query).then((res) => { - expect(res.data).toEqual(expected); - }); - }); - - test('runs twice for two queries', () => { - const simpleResolvers = { - RootQuery: { - usecontext: (_r: any, _a: Record, ctx: any) => - ctx.usecontext, - species: (root: any, { name }: { name: string }) => - (root.species as string) + name, - }, - }; - let jsSchema = makeExecutableSchema({ - typeDefs: testSchema, - resolvers: simpleResolvers, - }); - let count = 0; - const rootResolver = () => { - if (count === 0) { - count += 1; - return { stuff: 'stuff', species: 'some ' }; - } - if (count === 1) { - count += 1; - return { stuff: 'stuff2', species: 'species2 ' }; - } - return { stuff: 'EEE', species: 'EEE' }; - }; - jsSchema = addSchemaLevelResolver(jsSchema, rootResolver); - const query = `{ - species(name: "strix") - stuff - }`; - const expected = { - species: 'some strix', - stuff: 'stuff', - }; - const expected2 = { - species: 'species2 strix', - stuff: 'stuff2', - }; - return graphql(jsSchema, query).then((res) => { - expect(res.data).toEqual(expected); - return graphql(jsSchema, query).then((res2) => - expect(res2.data).toEqual(expected2), - ); - }); - }); - - test('can attach things to context', () => { - let jsSchema = makeExecutableSchema({ - typeDefs: testSchema, - resolvers: testResolvers, - }); - const rootResolver = (_o: any, _a: Record, ctx: any) => { - ctx.usecontext = 'ABC'; - }; - jsSchema = addSchemaLevelResolver(jsSchema, rootResolver); - const query = `{ - usecontext - }`; - const expected = { - usecontext: 'ABC', - }; - return graphql(jsSchema, query, {}, {}).then((res) => { - expect(res.data).toEqual(expected); - }); - }); - }); -}); - describe('Generating a full graphQL schema with resolvers and connectors', () => { test('outputs a working GraphQL schema', () => { const schema = makeExecutableSchema({ @@ -2176,7 +1918,7 @@ describe('Generating a full graphQL schema with resolvers and connectors', () => stuff: 'stuff', usecontext: 'ABC', }; - return graphql(schema, query, {}, { usecontext: 'ABC' }).then((res) => { + return graphql(schema, query, { stuff: 'stuff', species: 'ROOT' }, { usecontext: 'ABC' }).then((res) => { expect(res.data).toEqual(expected); }); }); @@ -2184,11 +1926,15 @@ describe('Generating a full graphQL schema with resolvers and connectors', () => describe('chainResolvers', () => { test('can chain two resolvers', () => { - const r1 = (root: number) => root + 1; - const r2 = (root: number, { addend }: { addend: number }) => root + addend; + const r1: GraphQLFieldResolver = (root: number) => root + 1; + const r2: GraphQLFieldResolver = (root: number, { addend }) => root + addend; + + const info: GraphQLResolveInfo = ({ + fieldName: 'addend', + } as unknown) as GraphQLResolveInfo; const rChained = chainResolvers([r1, r2]); - expect(rChained(0, { addend: 2 }, null, null)).toBe(3); + expect(rChained(0, { addend: 2 }, null, info)).toBe(3); }); test('uses default resolver when a resolver is undefined', () => { @@ -2205,248 +1951,6 @@ describe('chainResolvers', () => { }); }); -describe('attachDirectiveResolvers on field', () => { - const testSchemaWithDirectives = ` - directive @upper on FIELD_DEFINITION - directive @lower on FIELD_DEFINITION - directive @default(value: String!) on FIELD_DEFINITION - directive @catchError on FIELD_DEFINITION - - type TestObject { - hello: String @upper - } - type RootQuery { - hello: String @upper - withDefault: String @default(value: "some default_value") - object: TestObject - asyncResolver: String @upper - multiDirectives: String @upper @lower - throwError: String @catchError - } - schema { - query: RootQuery - } - `; - - const testObject = { - hello: 'giau. tran minh', - }; - - const testResolversDirectives = { - RootQuery: { - hello: () => 'giau. tran minh', - object: () => testObject, - asyncResolver: async () => Promise.resolve('giau. tran minh'), - multiDirectives: () => 'Giau. Tran Minh', - throwError: () => { - throw new Error('This error for testing'); - }, - }, - }; - - const directiveResolvers: IDirectiveResolvers = { - lower( - next: NextResolverFn, - _src: any, - _args: { [argName: string]: any }, - _context: any, - ) { - return next().then((str) => { - if (typeof str === 'string') { - return str.toLowerCase(); - } - return str; - }); - }, - upper( - next: NextResolverFn, - _src: any, - _args: { [argName: string]: any }, - _context: any, - ) { - return next().then((str) => { - if (typeof str === 'string') { - return str.toUpperCase(); - } - return str; - }); - }, - default( - next: NextResolverFn, - _src: any, - args: { [argName: string]: any }, - _context: any, - ) { - return next().then((res) => { - if (undefined === res) { - return args.value; - } - return res; - }); - }, - catchError( - next: NextResolverFn, - _src: any, - _args: { [argName: string]: any }, - _context: any, - ) { - return next().catch((error) => error.message); - }, - }; - - test('throws error if directiveResolvers argument is an array', () => { - const jsSchema = makeExecutableSchema({ - typeDefs: testSchema, - resolvers: testResolvers, - }); - expect(() => - attachDirectiveResolvers(jsSchema, ([ - 1, - ] as unknown) as IDirectiveResolvers), - ).toThrowError( - 'Expected directiveResolvers to be of type object, got Array', - ); - }); - - test('throws error if directiveResolvers argument is not an object', () => { - const jsSchema = makeExecutableSchema({ - typeDefs: testSchema, - resolvers: testResolvers, - }); - return expect(() => - attachDirectiveResolvers( - jsSchema, - ('a' as unknown) as IDirectiveResolvers, - ), - ).toThrowError( - 'Expected directiveResolvers to be of type object, got string', - ); - }); - - test('upper String from resolvers', () => { - const schema = makeExecutableSchema({ - typeDefs: testSchemaWithDirectives, - resolvers: testResolversDirectives, - directiveResolvers, - }); - const query = `{ - hello - }`; - const expected = { - hello: 'GIAU. TRAN MINH', - }; - return graphql(schema, query, {}, {}).then((res) => { - expect(res.data).toEqual(expected); - }); - }); - - test('using default resolver for object property', () => { - const schema = makeExecutableSchema({ - typeDefs: testSchemaWithDirectives, - resolvers: testResolversDirectives, - directiveResolvers, - }); - const query = `{ - object { - hello - } - }`; - const expected = { - object: { - hello: 'GIAU. TRAN MINH', - }, - }; - return graphql(schema, query, {}, {}).then((res) => { - expect(res.data).toEqual(expected); - }); - }); - - test('passes in directive arguments to the directive resolver', () => { - const schema = makeExecutableSchema({ - typeDefs: testSchemaWithDirectives, - resolvers: testResolversDirectives, - directiveResolvers, - }); - const query = `{ - withDefault - }`; - const expected = { - withDefault: 'some default_value', - }; - return graphql(schema, query, {}, {}).then((res) => { - expect(res.data).toEqual(expected); - }); - }); - - test('No effect if missing directive resolvers', () => { - const schema = makeExecutableSchema({ - typeDefs: testSchemaWithDirectives, - resolvers: testResolversDirectives, - directiveResolvers: {}, // Empty resolver - }); - const query = `{ - hello - }`; - const expected = { - hello: 'giau. tran minh', - }; - return graphql(schema, query, {}, {}).then((res) => { - expect(res.data).toEqual(expected); - }); - }); - - test('If resolver return Promise, keep using it', () => { - const schema = makeExecutableSchema({ - typeDefs: testSchemaWithDirectives, - resolvers: testResolversDirectives, - directiveResolvers, - }); - const query = `{ - asyncResolver - }`; - const expected = { - asyncResolver: 'GIAU. TRAN MINH', - }; - return graphql(schema, query, {}, {}).then((res) => { - expect(res.data).toEqual(expected); - }); - }); - - test('Multi directives apply with LTR order', () => { - const schema = makeExecutableSchema({ - typeDefs: testSchemaWithDirectives, - resolvers: testResolversDirectives, - directiveResolvers, - }); - const query = `{ - multiDirectives - }`; - const expected = { - multiDirectives: 'giau. tran minh', - }; - return graphql(schema, query, {}, {}).then((res) => { - expect(res.data).toEqual(expected); - }); - }); - - test('Allow to catch error from next resolver', () => { - const schema = makeExecutableSchema({ - typeDefs: testSchemaWithDirectives, - resolvers: testResolversDirectives, - directiveResolvers, - }); - const query = `{ - throwError - }`; - const expected = { - throwError: 'This error for testing', - }; - return graphql(schema, query, {}, {}).then((res) => { - expect(res.data).toEqual(expected); - }); - }); -}); - describe('can specify lexical parser options', () => { test("can specify 'noLocation' option", () => { const schema = makeExecutableSchema({ @@ -2464,7 +1968,7 @@ describe('can specify lexical parser options', () => { }, }); - expect(schema.astNode.loc).toBeUndefined(); + expect(schema.astNode!.loc).toBeUndefined(); }); test("can specify 'experimentalFragmentVariables' option", () => { @@ -2524,13 +2028,13 @@ describe('can specify lexical parser options', () => { const parsedQuery = parse(query, { experimentalFragmentVariables: true }); const hoist = (document: DocumentNode) => { - let variableDefs: Array = []; + const variableDefs: Array = []; - document.definitions.forEach((def) => { - if (def.kind === Kind.FRAGMENT_DEFINITION) { - variableDefs = variableDefs.concat(def.variableDefinitions); + for (const def of document.definitions) { + if (def.kind === Kind.FRAGMENT_DEFINITION && def.variableDefinitions) { + variableDefs.push(...def.variableDefinitions); } - }); + } return { kind: Kind.DOCUMENT, diff --git a/packages/stitch/package.json b/packages/stitch/package.json index 11b91448d17..a6c87b7908e 100644 --- a/packages/stitch/package.json +++ b/packages/stitch/package.json @@ -43,7 +43,7 @@ "@graphql-tools/schema": "^7.1.4", "@graphql-tools/utils": "^7.7.0", "@graphql-tools/wrap": "^7.0.6", - "tslib": "~2.2.0" + "tslib": "~2.3.0" }, "publishConfig": { "access": "public", diff --git a/packages/stitch/src/createMergedTypeResolver.ts b/packages/stitch/src/createMergedTypeResolver.ts index 21bb0dbc1ed..3ceec4b3162 100644 --- a/packages/stitch/src/createMergedTypeResolver.ts +++ b/packages/stitch/src/createMergedTypeResolver.ts @@ -2,7 +2,9 @@ import { getNamedType, GraphQLOutputType, GraphQLList } from 'graphql'; import { delegateToSchema, MergedTypeResolver, MergedTypeResolverOptions } from '@graphql-tools/delegate'; import { batchDelegateToSchema } from '@graphql-tools/batch-delegate'; -export function createMergedTypeResolver(mergedTypeResolverOptions: MergedTypeResolverOptions): MergedTypeResolver { +export function createMergedTypeResolver( + mergedTypeResolverOptions: MergedTypeResolverOptions +): MergedTypeResolver | undefined { const { fieldName, argsFromKeys, valuesFromResults, args } = mergedTypeResolverOptions; if (argsFromKeys != null) { diff --git a/packages/stitch/src/definitions.ts b/packages/stitch/src/definitions.ts index f11648113df..bf683125027 100644 --- a/packages/stitch/src/definitions.ts +++ b/packages/stitch/src/definitions.ts @@ -14,7 +14,7 @@ export function extractDefinitions(ast: DocumentNode) { const schemaDefs: SchemaDefinitionNode[] = []; const schemaExtensions: SchemaExtensionNode[] = []; const extensionDefs: TypeExtensionNode[] = []; - ast.definitions.forEach(def => { + for (const def of ast.definitions) { switch (def.kind) { case Kind.OBJECT_TYPE_DEFINITION: case Kind.INTERFACE_TYPE_DEFINITION: @@ -42,7 +42,7 @@ export function extractDefinitions(ast: DocumentNode) { extensionDefs.push(def); break; } - }); + } return { typeDefinitions, diff --git a/packages/stitch/src/mergeCandidates.ts b/packages/stitch/src/mergeCandidates.ts index 9d4173b8c85..72f1cf0565b 100644 --- a/packages/stitch/src/mergeCandidates.ts +++ b/packages/stitch/src/mergeCandidates.ts @@ -26,6 +26,12 @@ import { GraphQLScalarSerializer, GraphQLScalarValueParser, GraphQLScalarLiteralParser, + ObjectTypeExtensionNode, + InputObjectTypeExtensionNode, + InterfaceTypeExtensionNode, + UnionTypeExtensionNode, + EnumTypeExtensionNode, + ScalarTypeExtensionNode, } from 'graphql'; import { mergeType, mergeInputType, mergeInterface, mergeUnion, mergeEnum, mergeScalar } from '@graphql-tools/merge'; @@ -44,13 +50,13 @@ import { validateInputObjectConsistency, } from './mergeValidations'; -import { fieldToFieldConfig, inputFieldToFieldConfig } from '@graphql-tools/utils'; import { isSubschemaConfig } from '@graphql-tools/delegate'; +import { Maybe } from '@graphql-tools/utils'; -export function mergeCandidates( +export function mergeCandidates>( typeName: string, - candidates: Array, - typeMergingOptions: TypeMergingOptions + candidates: Array>, + typeMergingOptions?: TypeMergingOptions ): GraphQLNamedType { const initialCandidateType = candidates[0].type; if (candidates.some(candidate => candidate.type.constructor !== initialCandidateType.constructor)) { @@ -74,10 +80,10 @@ export function mergeCandidates( } } -function mergeObjectTypeCandidates( +function mergeObjectTypeCandidates>( typeName: string, - candidates: Array, - typeMergingOptions: TypeMergingOptions + candidates: Array>, + typeMergingOptions?: TypeMergingOptions ): GraphQLObjectType { candidates = orderedTypeCandidates(candidates, typeMergingOptions); @@ -86,15 +92,15 @@ function mergeObjectTypeCandidates( const typeConfigs = candidates.map(candidate => (candidate.type as GraphQLObjectType).toConfig()); const interfaceMap = typeConfigs .map(typeConfig => typeConfig.interfaces) - .reduce((acc, interfaces) => { + .reduce>((acc, interfaces) => { if (interfaces != null) { - interfaces.forEach(iface => { + for (const iface of interfaces) { acc[iface.name] = iface; - }); + } } return acc; }, Object.create(null)); - const interfaces = Object.keys(interfaceMap).map(interfaceName => interfaceMap[interfaceName]); + const interfaces = Object.values(interfaceMap); const astNodes = pluck('astNode', candidates); const fieldAstNodes = canonicalFieldNamesForType(candidates) @@ -116,7 +122,7 @@ function mergeObjectTypeCandidates( astNodes[0] ); - const extensionASTNodes = [].concat(pluck>('extensionASTNodes', candidates)); + const extensionASTNodes = pluck('extensionASTNodes', candidates); const extensions = Object.assign({}, ...pluck>('extensions', candidates)); @@ -133,10 +139,10 @@ function mergeObjectTypeCandidates( return new GraphQLObjectType(typeConfig); } -function mergeInputObjectTypeCandidates( +function mergeInputObjectTypeCandidates>( typeName: string, - candidates: Array, - typeMergingOptions: TypeMergingOptions + candidates: Array>, + typeMergingOptions?: TypeMergingOptions ): GraphQLInputObjectType { candidates = orderedTypeCandidates(candidates, typeMergingOptions); @@ -163,7 +169,7 @@ function mergeInputObjectTypeCandidates( astNodes[0] ); - const extensionASTNodes = [].concat(pluck>('extensionASTNodes', candidates)); + const extensionASTNodes = pluck('extensionASTNodes', candidates); const extensions = Object.assign({}, ...pluck>('extensions', candidates)); @@ -179,31 +185,31 @@ function mergeInputObjectTypeCandidates( return new GraphQLInputObjectType(typeConfig); } -function pluck(typeProperty: string, candidates: Array): Array { +function pluck(typeProperty: string, candidates: Array>): Array { return candidates.map(candidate => candidate.type[typeProperty]).filter(value => value != null) as Array; } -function mergeInterfaceTypeCandidates( +function mergeInterfaceTypeCandidates>( typeName: string, - candidates: Array, - typeMergingOptions: TypeMergingOptions + candidates: Array>, + typeMergingOptions?: TypeMergingOptions ): GraphQLInterfaceType { candidates = orderedTypeCandidates(candidates, typeMergingOptions); const description = mergeTypeDescriptions(candidates, typeMergingOptions); const fields = fieldConfigMapFromTypeCandidates(candidates, typeMergingOptions); - const typeConfigs = candidates.map(candidate => (candidate.type as GraphQLInterfaceType).toConfig()); + const typeConfigs = candidates.map(candidate => candidate.type.toConfig()); const interfaceMap = typeConfigs - .map(typeConfig => ((typeConfig as unknown) as { interfaces: Array }).interfaces) - .reduce((acc, interfaces) => { + .map(typeConfig => ('interfaces' in typeConfig ? typeConfig.interfaces : [])) + .reduce>((acc, interfaces) => { if (interfaces != null) { - interfaces.forEach(iface => { + for (const iface of interfaces) { acc[iface.name] = iface; - }); + } } return acc; }, Object.create(null)); - const interfaces = Object.keys(interfaceMap).map(interfaceName => interfaceMap[interfaceName]); + const interfaces = Object.values(interfaceMap); const astNodes = pluck('astNode', candidates); const fieldAstNodes = canonicalFieldNamesForType(candidates) @@ -225,7 +231,7 @@ function mergeInterfaceTypeCandidates( astNodes[0] ); - const extensionASTNodes = [].concat(pluck>('extensionASTNodes', candidates)); + const extensionASTNodes = pluck('extensionASTNodes', candidates); const extensions = Object.assign({}, ...pluck>('extensions', candidates)); @@ -242,22 +248,27 @@ function mergeInterfaceTypeCandidates( return new GraphQLInterfaceType(typeConfig); } -function mergeUnionTypeCandidates( +function mergeUnionTypeCandidates>( typeName: string, - candidates: Array, - typeMergingOptions: TypeMergingOptions + candidates: Array>, + typeMergingOptions?: TypeMergingOptions ): GraphQLUnionType { candidates = orderedTypeCandidates(candidates, typeMergingOptions); const description = mergeTypeDescriptions(candidates, typeMergingOptions); - const typeConfigs = candidates.map(candidate => (candidate.type as GraphQLUnionType).toConfig()); - const typeMap = typeConfigs.reduce((acc, typeConfig) => { - typeConfig.types.forEach(type => { + const typeConfigs = candidates.map(candidate => { + if (!isUnionType(candidate.type)) { + throw new Error(`Expected ${candidate.type} to be a union type!`); + } + return candidate.type.toConfig(); + }); + const typeMap = typeConfigs.reduce>((acc, typeConfig) => { + for (const type of typeConfig.types) { acc[type.name] = type; - }); + } return acc; }, Object.create(null)); - const types = Object.keys(typeMap).map(typeName => typeMap[typeName]); + const types = Object.values(typeMap); const astNodes = pluck('astNode', candidates); const astNode = astNodes @@ -267,7 +278,7 @@ function mergeUnionTypeCandidates( astNodes[0] ); - const extensionASTNodes = [].concat(pluck>('extensionASTNodes', candidates)); + const extensionASTNodes = pluck('extensionASTNodes', candidates); const extensions = Object.assign({}, ...pluck>('extensions', candidates)); @@ -283,10 +294,10 @@ function mergeUnionTypeCandidates( return new GraphQLUnionType(typeConfig); } -function mergeEnumTypeCandidates( +function mergeEnumTypeCandidates>( typeName: string, - candidates: Array, - typeMergingOptions: TypeMergingOptions + candidates: Array>, + typeMergingOptions?: TypeMergingOptions ): GraphQLEnumType { candidates = orderedTypeCandidates(candidates, typeMergingOptions); @@ -302,7 +313,7 @@ function mergeEnumTypeCandidates( astNodes[0] ); - const extensionASTNodes = [].concat(pluck>('extensionASTNodes', candidates)); + const extensionASTNodes = pluck('extensionASTNodes', candidates); const extensions = Object.assign({}, ...pluck>('extensions', candidates)); @@ -319,14 +330,14 @@ function mergeEnumTypeCandidates( } function enumValueConfigMapFromTypeCandidates( - candidates: Array, - typeMergingOptions: TypeMergingOptions + candidates: Array>, + typeMergingOptions?: TypeMergingOptions ): GraphQLEnumValueConfigMap { const enumValueConfigCandidatesMap: Record> = Object.create(null); - candidates.forEach(candidate => { + for (const candidate of candidates) { const valueMap = (candidate.type as GraphQLEnumType).toConfig().values; - Object.keys(valueMap).forEach(enumValue => { + for (const enumValue in valueMap) { const enumValueConfigCandidate = { enumValueConfig: valueMap[enumValue], enumValue, @@ -340,15 +351,15 @@ function enumValueConfigMapFromTypeCandidates( } else { enumValueConfigCandidatesMap[enumValue] = [enumValueConfigCandidate]; } - }); - }); + } + } const enumValueConfigMap = Object.create(null); - Object.keys(enumValueConfigCandidatesMap).forEach(enumValue => { + for (const enumValue in enumValueConfigCandidatesMap) { const enumValueConfigMerger = typeMergingOptions?.enumValueConfigMerger ?? defaultEnumValueConfigMerger; enumValueConfigMap[enumValue] = enumValueConfigMerger(enumValueConfigCandidatesMap[enumValue]); - }); + } return enumValueConfigMap; } @@ -361,10 +372,10 @@ function defaultEnumValueConfigMerger(candidates: Array>( typeName: string, - candidates: Array, - typeMergingOptions: TypeMergingOptions + candidates: Array>, + typeMergingOptions?: TypeMergingOptions ): GraphQLScalarType { candidates = orderedTypeCandidates(candidates, typeMergingOptions); @@ -386,7 +397,7 @@ function mergeScalarTypeCandidates( astNodes[0] ); - const extensionASTNodes = [].concat(pluck>('extensionASTNodes', candidates)); + const extensionASTNodes = pluck('extensionASTNodes', candidates); const extensions = Object.assign({}, ...pluck>('extensions', candidates)); @@ -404,17 +415,19 @@ function mergeScalarTypeCandidates( return new GraphQLScalarType(typeConfig); } -function orderedTypeCandidates( - candidates: Array, - typeMergingOptions: TypeMergingOptions -): Array { +function orderedTypeCandidates>( + candidates: Array>, + typeMergingOptions?: TypeMergingOptions +): Array> { const typeCandidateMerger = typeMergingOptions?.typeCandidateMerger ?? defaultTypeCandidateMerger; const candidate = typeCandidateMerger(candidates); return candidates.filter(c => c !== candidate).concat([candidate]); } -function defaultTypeCandidateMerger(candidates: Array): MergeTypeCandidate { - const canonical: Array = candidates.filter(({ type, transformedSubschema }) => +function defaultTypeCandidateMerger>( + candidates: Array> +): MergeTypeCandidate { + const canonical: Array> = candidates.filter(({ type, transformedSubschema }) => isSubschemaConfig(transformedSubschema) ? transformedSubschema.merge?.[type.name]?.canonical : false ); @@ -427,26 +440,32 @@ function defaultTypeCandidateMerger(candidates: Array): Merg return candidates[candidates.length - 1]; } -function mergeTypeDescriptions(candidates: Array, typeMergingOptions: TypeMergingOptions): string { +function mergeTypeDescriptions>( + candidates: Array>, + typeMergingOptions?: TypeMergingOptions +): Maybe { const typeDescriptionsMerger = typeMergingOptions?.typeDescriptionsMerger ?? defaultTypeDescriptionMerger; return typeDescriptionsMerger(candidates); } -function defaultTypeDescriptionMerger(candidates: Array): string { +function defaultTypeDescriptionMerger>( + candidates: Array> +): Maybe { return candidates[candidates.length - 1].type.description; } -function fieldConfigMapFromTypeCandidates( - candidates: Array, - typeMergingOptions: TypeMergingOptions +function fieldConfigMapFromTypeCandidates>( + candidates: Array>, + typeMergingOptions?: TypeMergingOptions ): GraphQLFieldConfigMap { - const fieldConfigCandidatesMap: Record> = Object.create(null); + const fieldConfigCandidatesMap: Record>> = Object.create(null); candidates.forEach(candidate => { - const fieldMap = (candidate.type as GraphQLObjectType | GraphQLInterfaceType).getFields(); - Object.keys(fieldMap).forEach(fieldName => { + const typeConfig = (candidate.type as GraphQLObjectType | GraphQLInterfaceType).toConfig(); + const fieldConfigMap = typeConfig.fields; + Object.entries(fieldConfigMap).forEach(([fieldName, fieldConfig]) => { const fieldConfigCandidate = { - fieldConfig: fieldToFieldConfig(fieldMap[fieldName]), + fieldConfig, fieldName, type: candidate.type as GraphQLObjectType | GraphQLInterfaceType, subschema: candidate.subschema, @@ -458,37 +477,42 @@ function fieldConfigMapFromTypeCandidates( } else { fieldConfigCandidatesMap[fieldName] = [fieldConfigCandidate]; } - }); - }); + } + } const fieldConfigMap = Object.create(null); - Object.keys(fieldConfigCandidatesMap).forEach(fieldName => { + for (const fieldName in fieldConfigCandidatesMap) { fieldConfigMap[fieldName] = mergeFieldConfigs(fieldConfigCandidatesMap[fieldName], typeMergingOptions); - }); + } return fieldConfigMap; } -function mergeFieldConfigs(candidates: Array, typeMergingOptions: TypeMergingOptions) { +function mergeFieldConfigs>( + candidates: Array>, + typeMergingOptions?: TypeMergingOptions +) { const fieldConfigMerger = typeMergingOptions?.fieldConfigMerger ?? defaultFieldConfigMerger; const finalFieldConfig = fieldConfigMerger(candidates); validateFieldConsistency(finalFieldConfig, candidates, typeMergingOptions); return finalFieldConfig; } -function defaultFieldConfigMerger(candidates: Array) { +function defaultFieldConfigMerger>( + candidates: Array> +) { const canonicalByField: Array> = []; const canonicalByType: Array> = []; - candidates.forEach(({ type, fieldName, fieldConfig, transformedSubschema }) => { - if (!isSubschemaConfig(transformedSubschema)) return; + for (const { type, fieldName, fieldConfig, transformedSubschema } of candidates) { + if (!isSubschemaConfig(transformedSubschema)) continue; if (transformedSubschema.merge?.[type.name]?.fields?.[fieldName]?.canonical) { canonicalByField.push(fieldConfig); } else if (transformedSubschema.merge?.[type.name]?.canonical) { canonicalByType.push(fieldConfig); } - }); + } if (canonicalByField.length > 1) { throw new Error(`Multiple canonical definitions for "${candidates[0].type.name}.${candidates[0].fieldName}"`); @@ -501,21 +525,24 @@ function defaultFieldConfigMerger(candidates: Array) return candidates[candidates.length - 1].fieldConfig; } -function inputFieldConfigMapFromTypeCandidates( - candidates: Array, - typeMergingOptions: TypeMergingOptions +function inputFieldConfigMapFromTypeCandidates>( + candidates: Array>, + typeMergingOptions?: TypeMergingOptions ): GraphQLInputFieldConfigMap { - const inputFieldConfigCandidatesMap: Record> = Object.create(null); + const inputFieldConfigCandidatesMap: Record>> = Object.create( + null + ); const fieldInclusionMap: Record = Object.create(null); candidates.forEach(candidate => { - const inputFieldMap = (candidate.type as GraphQLInputObjectType).getFields(); - Object.keys(inputFieldMap).forEach(fieldName => { + const typeConfig = (candidate.type as GraphQLInputObjectType).toConfig(); + const inputFieldConfigMap = typeConfig.fields; + Object.entries(inputFieldConfigMap).forEach(([fieldName, inputFieldConfig]) => { fieldInclusionMap[fieldName] = fieldInclusionMap[fieldName] || 0; fieldInclusionMap[fieldName] += 1; const inputFieldConfigCandidate = { - inputFieldConfig: inputFieldToFieldConfig(inputFieldMap[fieldName]), + inputFieldConfig, fieldName, type: candidate.type as GraphQLInputObjectType, subschema: candidate.subschema, @@ -527,14 +554,14 @@ function inputFieldConfigMapFromTypeCandidates( } else { inputFieldConfigCandidatesMap[fieldName] = [inputFieldConfigCandidate]; } - }); - }); + } + } validateInputObjectConsistency(fieldInclusionMap, candidates, typeMergingOptions); const inputFieldConfigMap = Object.create(null); - Object.keys(inputFieldConfigCandidatesMap).forEach(fieldName => { + for (const fieldName in inputFieldConfigCandidatesMap) { const inputFieldConfigMerger = typeMergingOptions?.inputFieldConfigMerger ?? defaultInputFieldConfigMerger; inputFieldConfigMap[fieldName] = inputFieldConfigMerger(inputFieldConfigCandidatesMap[fieldName]); validateInputFieldConsistency( @@ -542,23 +569,25 @@ function inputFieldConfigMapFromTypeCandidates( inputFieldConfigCandidatesMap[fieldName], typeMergingOptions ); - }); + } return inputFieldConfigMap; } -function defaultInputFieldConfigMerger(candidates: Array) { +function defaultInputFieldConfigMerger>( + candidates: Array> +) { const canonicalByField: Array = []; const canonicalByType: Array = []; - candidates.forEach(({ type, fieldName, inputFieldConfig, transformedSubschema }) => { - if (!isSubschemaConfig(transformedSubschema)) return; + for (const { type, fieldName, inputFieldConfig, transformedSubschema } of candidates) { + if (!isSubschemaConfig(transformedSubschema)) continue; if (transformedSubschema.merge?.[type.name]?.fields?.[fieldName]?.canonical) { canonicalByField.push(inputFieldConfig); } else if (transformedSubschema.merge?.[type.name]?.canonical) { canonicalByType.push(inputFieldConfig); } - }); + } if (canonicalByField.length > 1) { throw new Error(`Multiple canonical definitions for "${candidates[0].type.name}.${candidates[0].fieldName}"`); @@ -571,22 +600,21 @@ function defaultInputFieldConfigMerger(candidates: Array): Array { +function canonicalFieldNamesForType(candidates: Array>): Array { const canonicalFieldNames: Record = Object.create(null); - candidates.forEach(({ type, transformedSubschema }) => { - if ( - isSubschemaConfig(transformedSubschema) && - transformedSubschema.merge?.[type.name]?.fields && - !transformedSubschema.merge[type.name].canonical - ) { - Object.entries(transformedSubschema.merge[type.name].fields).forEach(([fieldName, mergedFieldConfig]) => { + for (const { type, transformedSubschema } of candidates) { + if (!isSubschemaConfig(transformedSubschema)) continue; + const mergeConfig = transformedSubschema.merge?.[type.name]; + if (mergeConfig != null && mergeConfig.fields != null && !mergeConfig.canonical) { + for (const fieldName in mergeConfig.fields) { + const mergedFieldConfig = mergeConfig.fields[fieldName]; if (mergedFieldConfig.canonical) { canonicalFieldNames[fieldName] = true; } - }); + } } - }); + } return Object.keys(canonicalFieldNames); } diff --git a/packages/stitch/src/mergeValidations.ts b/packages/stitch/src/mergeValidations.ts index 862ef8fa000..4ed13197d4e 100644 --- a/packages/stitch/src/mergeValidations.ts +++ b/packages/stitch/src/mergeValidations.ts @@ -21,10 +21,10 @@ import { ValidationLevel, } from './types'; -export function validateFieldConsistency( +export function validateFieldConsistency>( finalFieldConfig: GraphQLFieldConfig, - candidates: Array, - typeMergingOptions: TypeMergingOptions + candidates: Array>, + typeMergingOptions?: TypeMergingOptions ): void { const fieldNamespace = `${candidates[0].type.name}.${candidates[0].fieldName}`; const finalFieldNull = isNonNullType(finalFieldConfig.type); @@ -55,12 +55,16 @@ export function validateFieldConsistency( } const argCandidatesMap: Record> = Object.create(null); - candidates.forEach(({ fieldConfig }) => { - Object.entries(fieldConfig.args).forEach(([argName, arg]) => { + for (const { fieldConfig } of candidates) { + if (fieldConfig.args == null) { + continue; + } + for (const argName in fieldConfig.args) { + const arg = fieldConfig.args[argName]; argCandidatesMap[argName] = argCandidatesMap[argName] || []; argCandidatesMap[argName].push(arg); - }); - }); + } + } if (Object.values(argCandidatesMap).some(argCandidates => candidates.length !== argCandidates.length)) { validationMessage( @@ -70,7 +74,11 @@ export function validateFieldConsistency( ); } - Object.entries(argCandidatesMap).forEach(([argName, argCandidates]) => { + for (const argName in argCandidatesMap) { + if (finalFieldConfig.args == null) { + continue; + } + const argCandidates = argCandidatesMap[argName]; const argNamespace = `${fieldNamespace}.${argName}`; const finalArgConfig = finalFieldConfig.args[argName] || argCandidates[argCandidates.length - 1]; const finalArgType = getNamedType(finalArgConfig.type); @@ -98,15 +106,16 @@ export function validateFieldConsistency( if (isEnumType(finalArgType)) { validateInputEnumConsistency(finalArgType, argCandidates, typeMergingOptions); } - }); + } } -export function validateInputObjectConsistency( +export function validateInputObjectConsistency>( fieldInclusionMap: Record, - candidates: Array, - typeMergingOptions: TypeMergingOptions + candidates: Array>, + typeMergingOptions?: TypeMergingOptions ): void { - Object.entries(fieldInclusionMap).forEach(([fieldName, count]) => { + for (const fieldName in fieldInclusionMap) { + const count = fieldInclusionMap[fieldName]; if (candidates.length !== count) { const namespace = `${candidates[0].type.name}.${fieldName}`; validationMessage( @@ -115,13 +124,13 @@ export function validateInputObjectConsistency( typeMergingOptions ); } - }); + } } -export function validateInputFieldConsistency( +export function validateInputFieldConsistency>( finalInputFieldConfig: GraphQLInputFieldConfig, - candidates: Array, - typeMergingOptions: TypeMergingOptions + candidates: Array>, + typeMergingOptions?: TypeMergingOptions ): void { const inputFieldNamespace = `${candidates[0].type.name}.${candidates[0].fieldName}`; const inputFieldConfigs = candidates.map(c => c.inputFieldConfig); @@ -158,18 +167,18 @@ export function validateInputFieldConsistency( } } -export function validateTypeConsistency( +export function validateTypeConsistency>( finalElementConfig: GraphQLFieldConfig | GraphQLArgumentConfig | GraphQLInputFieldConfig, candidates: Array | GraphQLArgumentConfig | GraphQLInputFieldConfig>, definitionType: string, settingNamespace: string, - typeMergingOptions: TypeMergingOptions + typeMergingOptions?: TypeMergingOptions ): void { const finalNamedType = getNamedType(finalElementConfig.type); const finalIsScalar = isScalarType(finalNamedType); const finalIsList = hasListType(finalElementConfig.type); - candidates.forEach(c => { + for (const c of candidates) { if (finalIsList !== hasListType(c.type)) { throw new Error( `Definitions of ${definitionType} "${settingNamespace}" implement inconsistent list types across subschemas and cannot be merged.` @@ -195,29 +204,29 @@ export function validateTypeConsistency( ); } } - }); + } } function hasListType(type: GraphQLType): boolean { return isListType(getNullableType(type)); } -export function validateInputEnumConsistency( +export function validateInputEnumConsistency>( inputEnumType: GraphQLEnumType, candidates: Array, - typeMergingOptions: TypeMergingOptions + typeMergingOptions?: TypeMergingOptions ): void { const enumValueInclusionMap: Record = Object.create(null); - candidates.forEach(candidate => { + for (const candidate of candidates) { const enumType = getNamedType(candidate.type) as GraphQLEnumType; if (isEnumType(enumType)) { - enumType.getValues().forEach(({ value }) => { + for (const { value } of enumType.getValues()) { enumValueInclusionMap[value] = enumValueInclusionMap[value] || 0; enumValueInclusionMap[value] += 1; - }); + } } - }); + } if (Object.values(enumValueInclusionMap).some(count => candidates.length !== count)) { validationMessage( @@ -228,7 +237,11 @@ export function validateInputEnumConsistency( } } -function validationMessage(message: string, settingNamespace: string, typeMergingOptions: TypeMergingOptions): void { +function validationMessage>( + message: string, + settingNamespace: string, + typeMergingOptions?: TypeMergingOptions +): void { const override = `typeMergingOptions.validationScopes['${settingNamespace}'].validationLevel`; const settings = getValidationSettings(settingNamespace, typeMergingOptions); @@ -244,7 +257,10 @@ function validationMessage(message: string, settingNamespace: string, typeMergin } } -function getValidationSettings(settingNamespace: string, typeMergingOptions: TypeMergingOptions): ValidationSettings { +function getValidationSettings>( + settingNamespace: string, + typeMergingOptions?: TypeMergingOptions +): ValidationSettings { return { ...(typeMergingOptions?.validationSettings ?? {}), ...(typeMergingOptions?.validationScopes?.[settingNamespace] ?? {}), diff --git a/packages/stitch/src/selectionSetArgs.ts b/packages/stitch/src/selectionSetArgs.ts index 4dbc164d5b2..ab011e9b7de 100644 --- a/packages/stitch/src/selectionSetArgs.ts +++ b/packages/stitch/src/selectionSetArgs.ts @@ -7,22 +7,20 @@ export const forwardArgsToSelectionSet: ( ) => (field: FieldNode) => SelectionSetNode = (selectionSet: string, mapping?: Record) => { const selectionSetDef = parseSelectionSet(selectionSet, { noLocation: true }); return (field: FieldNode): SelectionSetNode => { - const selections = selectionSetDef.selections.map( - (selectionNode): SelectionNode => { - if (selectionNode.kind === Kind.FIELD) { - if (!mapping) { - return { ...selectionNode, arguments: field.arguments.slice() }; - } else if (selectionNode.name.value in mapping) { - const selectionArgs = mapping[selectionNode.name.value]; - return { - ...selectionNode, - arguments: field.arguments.filter((arg): boolean => selectionArgs.includes(arg.name.value)), - }; - } + const selections = selectionSetDef.selections.map((selectionNode): SelectionNode => { + if (selectionNode.kind === Kind.FIELD) { + if (!mapping) { + return { ...selectionNode, arguments: field.arguments?.slice() }; + } else if (selectionNode.name.value in mapping) { + const selectionArgs = mapping[selectionNode.name.value]; + return { + ...selectionNode, + arguments: field.arguments?.filter((arg): boolean => selectionArgs.includes(arg.name.value)), + }; } - return selectionNode; } - ); + return selectionNode; + }); return { ...selectionSetDef, selections }; }; diff --git a/packages/stitch/src/stitchSchemas.ts b/packages/stitch/src/stitchSchemas.ts index 40d63a88da6..d95e1837141 100644 --- a/packages/stitch/src/stitchSchemas.ts +++ b/packages/stitch/src/stitchSchemas.ts @@ -7,17 +7,9 @@ import { extendSchema, } from 'graphql'; -import { SchemaDirectiveVisitor, mergeDeep, IResolvers, pruneSchema } from '@graphql-tools/utils'; +import { IResolvers, pruneSchema } from '@graphql-tools/utils'; -import { - addResolversToSchema, - addSchemaLevelResolver, - addErrorLoggingToSchema, - addCatchUndefinedToSchema, - assertResolversPresent, - attachDirectiveResolvers, - extendResolversFromInterfaces, -} from '@graphql-tools/schema'; +import { addResolversToSchema, assertResolversPresent, extendResolversFromInterfaces } from '@graphql-tools/schema'; import { SubschemaConfig, isSubschemaConfig, Subschema, defaultMergedResolver } from '@graphql-tools/delegate'; @@ -30,6 +22,7 @@ import { isolateComputedFieldsTransformer, splitMergedTypeEntryPointsTransformer, } from './subschemaConfigTransforms'; +import { mergeResolvers } from '@graphql-tools/merge'; export function stitchSchemas>({ subschemas = [], @@ -41,12 +34,8 @@ export function stitchSchemas>({ typeMergingOptions, subschemaConfigTransforms = defaultSubschemaConfigTransforms, resolvers = {}, - schemaDirectives, inheritResolversFromInterfaces = false, - logger, - allowUndefinedInResolve = true, resolverValidationOptions = {}, - directiveResolvers, schemaTransforms = [], parseOptions = {}, pruningOptions, @@ -56,28 +45,39 @@ export function stitchSchemas>({ throw new Error('Expected `resolverValidationOptions` to be an object'); } - let transformedSubschemas: Array = []; - const subschemaMap: Map, Subschema> = new Map(); - const originalSubschemaMap: Map> = new Map(); - - subschemas.forEach(subschemaOrSubschemaArray => { + const transformedSubschemas: Array> = []; + const subschemaMap: Map< + GraphQLSchema | SubschemaConfig, + Subschema + > = new Map(); + const originalSubschemaMap: Map< + Subschema, + GraphQLSchema | SubschemaConfig + > = new Map(); + + for (const subschemaOrSubschemaArray of subschemas) { if (Array.isArray(subschemaOrSubschemaArray)) { - subschemaOrSubschemaArray.forEach(s => { - transformedSubschemas = transformedSubschemas.concat( - applySubschemaConfigTransforms(subschemaConfigTransforms, s, subschemaMap, originalSubschemaMap) - ); - }); - } else { - transformedSubschemas = transformedSubschemas.concat( - applySubschemaConfigTransforms( + for (const s of subschemaOrSubschemaArray) { + for (const transformedSubschemaConfig of applySubschemaConfigTransforms( subschemaConfigTransforms, - subschemaOrSubschemaArray, + s, subschemaMap, originalSubschemaMap - ) - ); + )) { + transformedSubschemas.push(transformedSubschemaConfig); + } + } + } else { + for (const transformedSubschemaConfig of applySubschemaConfigTransforms( + subschemaConfigTransforms, + subschemaOrSubschemaArray, + subschemaMap, + originalSubschemaMap + )) { + transformedSubschemas.push(transformedSubschemaConfig); + } } - }); + } const extensions: Array = []; const directives: Array = []; @@ -96,7 +96,7 @@ export function stitchSchemas>({ subschemas: transformedSubschemas, originalSubschemaMap, types, - typeDefs, + typeDefs: typeDefs || [], parseOptions, extensions, directiveMap, @@ -105,9 +105,9 @@ export function stitchSchemas>({ mergeDirectives, }); - Object.keys(directiveMap).forEach(directiveName => { + for (const directiveName in directiveMap) { directives.push(directiveMap[directiveName]); - }); + } let stitchingInfo = createStitchingInfo(subschemaMap, typeCandidates, mergeTypes); @@ -132,14 +132,14 @@ export function stitchSchemas>({ extensions: null, }); - extensions.forEach(extension => { + for (const extension of extensions) { schema = extendSchema(schema, extension, { commentDescriptions: true, }); - }); + } // We allow passing in an array of resolver maps, in which case we merge them - const resolverMap: IResolvers = Array.isArray(resolvers) ? resolvers.reduce(mergeDeep, {}) : resolvers; + const resolverMap: IResolvers = mergeResolvers(resolvers); const finalResolvers = inheritResolversFromInterfaces ? extendResolversFromInterfaces(schema, resolverMap) @@ -162,32 +162,10 @@ export function stitchSchemas>({ schema = addStitchingInfo(schema, stitchingInfo); - if (!allowUndefinedInResolve) { - schema = addCatchUndefinedToSchema(schema); - } - - if (logger != null) { - schema = addErrorLoggingToSchema(schema, logger); - } - - if (typeof finalResolvers['__schema'] === 'function') { - // TODO a bit of a hack now, better rewrite generateSchema to attach it there. - // not doing that now, because I'd have to rewrite a lot of tests. - schema = addSchemaLevelResolver(schema, finalResolvers['__schema']); - } - schemaTransforms.forEach(schemaTransform => { schema = schemaTransform(schema); }); - if (directiveResolvers != null) { - schema = attachDirectiveResolvers(schema, directiveResolvers); - } - - if (schemaDirectives != null) { - SchemaDirectiveVisitor.visitSchemaDirectives(schema, schemaDirectives); - } - if (pruningOptions) { schema = pruneSchema(schema, pruningOptions); } @@ -195,43 +173,48 @@ export function stitchSchemas>({ return schema; } -const subschemaConfigTransformerPresets = [isolateComputedFieldsTransformer, splitMergedTypeEntryPointsTransformer]; +const subschemaConfigTransformerPresets: Array> = [ + isolateComputedFieldsTransformer, + splitMergedTypeEntryPointsTransformer, +]; function applySubschemaConfigTransforms>( subschemaConfigTransforms: Array>, subschemaOrSubschemaConfig: GraphQLSchema | SubschemaConfig, - subschemaMap: Map, - originalSubschemaMap: Map> -): Array { - const subschemaConfig = isSubschemaConfig(subschemaOrSubschemaConfig) - ? subschemaOrSubschemaConfig - : { schema: subschemaOrSubschemaConfig }; - - let transformedSubschemaConfigs: Array = [subschemaConfig]; - subschemaConfigTransforms.concat(subschemaConfigTransformerPresets).forEach(subschemaConfigTransform => { - const mapped: Array> = transformedSubschemaConfigs.map(ssConfig => - subschemaConfigTransform(ssConfig) - ); + subschemaMap: Map, Subschema>, + originalSubschemaMap: Map< + Subschema, + GraphQLSchema | SubschemaConfig + > +): Array> { + let subschemaConfig: SubschemaConfig; + if (isSubschemaConfig(subschemaOrSubschemaConfig)) { + subschemaConfig = subschemaOrSubschemaConfig; + } else if (subschemaOrSubschemaConfig instanceof GraphQLSchema) { + subschemaConfig = { schema: subschemaOrSubschemaConfig }; + } else { + throw new TypeError('Received invalid input.'); + } - transformedSubschemaConfigs = mapped.reduce( - (acc: Array, configOrList: SubschemaConfig | Array) => { - if (Array.isArray(configOrList)) { - return acc.concat(configOrList as Array); - } - acc.push(configOrList as SubschemaConfig); - return acc; - }, - [] - ) as Array; - }); + const transformedSubschemaConfigs = subschemaConfigTransforms + .concat(subschemaConfigTransformerPresets) + .reduce( + (transformedSubschemaConfigs, subschemaConfigTransform) => + transformedSubschemaConfigs.map(ssConfig => subschemaConfigTransform(ssConfig)).flat(), + [subschemaConfig] + ); - const transformedSubschemas = transformedSubschemaConfigs.map(ssConfig => new Subschema(ssConfig)); + const transformedSubschemas = transformedSubschemaConfigs.map( + ssConfig => new Subschema(ssConfig) + ); const baseSubschema = transformedSubschemas[0]; subschemaMap.set(subschemaOrSubschemaConfig, baseSubschema); - transformedSubschemas.forEach(subschema => originalSubschemaMap.set(subschema, subschemaOrSubschemaConfig)); + for (const subschema of transformedSubschemas) { + originalSubschemaMap.set(subschema, subschemaOrSubschemaConfig); + } return transformedSubschemas; } diff --git a/packages/stitch/src/stitchingInfo.ts b/packages/stitch/src/stitchingInfo.ts index d34ebcd4e46..da5ace90a1c 100644 --- a/packages/stitch/src/stitchingInfo.ts +++ b/packages/stitch/src/stitchingInfo.ts @@ -13,7 +13,7 @@ import { isLeafType, } from 'graphql'; -import { parseSelectionSet, TypeMap, IResolvers, IFieldResolverOptions } from '@graphql-tools/utils'; +import { parseSelectionSet, TypeMap, IResolvers, IFieldResolverOptions, isSome } from '@graphql-tools/utils'; import { MergedTypeResolver, Subschema, SubschemaConfig, MergedTypeInfo, StitchingInfo } from '@graphql-tools/delegate'; @@ -21,30 +21,31 @@ import { MergeTypeCandidate, MergeTypeFilter } from './types'; import { createMergedTypeResolver } from './createMergedTypeResolver'; -export function createStitchingInfo( - subschemaMap: Map, - typeCandidates: Record>, - mergeTypes?: boolean | Array | MergeTypeFilter -): StitchingInfo { +export function createStitchingInfo>( + subschemaMap: Map, Subschema>, + typeCandidates: Record>>, + mergeTypes?: boolean | Array | MergeTypeFilter +): StitchingInfo { const mergedTypes = createMergedTypes(typeCandidates, mergeTypes); const selectionSetsByField: Record> = Object.create(null); - Object.entries(mergedTypes).forEach(([typeName, mergedTypeInfo]) => { + for (const typeName in mergedTypes) { + const mergedTypeInfo = mergedTypes[typeName]; if (mergedTypeInfo.selectionSets == null && mergedTypeInfo.fieldSelectionSets == null) { - return; + continue; } selectionSetsByField[typeName] = Object.create(null); - mergedTypeInfo.selectionSets.forEach((selectionSet, subschemaConfig) => { + for (const [subschemaConfig, selectionSet] of mergedTypeInfo.selectionSets) { const schema = subschemaConfig.transformedSchema; const type = schema.getType(typeName) as GraphQLObjectType; const fields = type.getFields(); - Object.keys(fields).forEach(fieldName => { + for (const fieldName in fields) { const field = fields[fieldName]; const fieldType = getNamedType(field.type); if (selectionSet && isLeafType(fieldType) && selectionSetContainsTopLevelField(selectionSet, fieldName)) { - return; + continue; } if (selectionSetsByField[typeName][fieldName] == null) { selectionSetsByField[typeName][fieldName] = { @@ -55,11 +56,11 @@ export function createStitchingInfo( selectionSetsByField[typeName][fieldName].selections = selectionSetsByField[typeName][ fieldName ].selections.concat(selectionSet.selections); - }); - }); + } + } - mergedTypeInfo.fieldSelectionSets.forEach(selectionSetFieldMap => { - Object.keys(selectionSetFieldMap).forEach(fieldName => { + for (const [, selectionSetFieldMap] of mergedTypeInfo.fieldSelectionSets) { + for (const fieldName in selectionSetFieldMap) { if (selectionSetsByField[typeName][fieldName] == null) { selectionSetsByField[typeName][fieldName] = { kind: Kind.SELECTION_SET, @@ -69,26 +70,26 @@ export function createStitchingInfo( selectionSetsByField[typeName][fieldName].selections = selectionSetsByField[typeName][ fieldName ].selections.concat(selectionSetFieldMap[fieldName].selections); - }); - }); - }); + } + } + } return { subschemaMap, - selectionSetsByType: undefined, + selectionSetsByType: Object.create(null), selectionSetsByField, - dynamicSelectionSetsByField: undefined, + dynamicSelectionSetsByField: Object.create(null), mergedTypes, }; } -function createMergedTypes( - typeCandidates: Record>, - mergeTypes?: boolean | Array | MergeTypeFilter -): Record { - const mergedTypes: Record = Object.create(null); +function createMergedTypes>( + typeCandidates: Record>>, + mergeTypes?: boolean | Array | MergeTypeFilter +): Record> { + const mergedTypes: Record> = Object.create(null); - Object.keys(typeCandidates).forEach(typeName => { + for (const typeName in typeCandidates) { if ( typeCandidates[typeName].length > 1 && (isObjectType(typeCandidates[typeName][0].type) || isInterfaceType(typeCandidates[typeName][0].type)) @@ -106,19 +107,19 @@ function createMergedTypes( (Array.isArray(mergeTypes) && mergeTypes.includes(typeName)) || typeCandidatesWithMergedTypeConfig.length ) { - const targetSubschemas: Array = []; + const targetSubschemas: Array> = []; - const typeMaps: Map = new Map(); - const supportedBySubschemas: Record> = Object.create({}); - const selectionSets: Map = new Map(); - const fieldSelectionSets: Map> = new Map(); - const resolvers: Map = new Map(); + const typeMaps: Map, TypeMap> = new Map(); + const supportedBySubschemas: Record>> = Object.create({}); + const selectionSets: Map, SelectionSetNode> = new Map(); + const fieldSelectionSets: Map, Record> = new Map(); + const resolvers: Map, MergedTypeResolver> = new Map(); - typeCandidates[typeName].forEach(typeCandidate => { + for (const typeCandidate of typeCandidates[typeName]) { const subschema = typeCandidate.transformedSubschema; if (subschema == null) { - return; + continue; } typeMaps.set(subschema, subschema.transformedSchema.getTypeMap()); @@ -126,7 +127,7 @@ function createMergedTypes( const mergedTypeConfig = subschema?.merge?.[typeName]; if (mergedTypeConfig == null) { - return; + continue; } if (mergedTypeConfig.selectionSet) { @@ -136,19 +137,21 @@ function createMergedTypes( if (mergedTypeConfig.fields) { const parsedFieldSelectionSets = Object.create(null); - Object.keys(mergedTypeConfig.fields).forEach(fieldName => { + for (const fieldName in mergedTypeConfig.fields) { if (mergedTypeConfig.fields[fieldName].selectionSet) { const rawFieldSelectionSet = mergedTypeConfig.fields[fieldName].selectionSet; - parsedFieldSelectionSets[fieldName] = parseSelectionSet(rawFieldSelectionSet, { noLocation: true }); + parsedFieldSelectionSets[fieldName] = rawFieldSelectionSet + ? parseSelectionSet(rawFieldSelectionSet, { noLocation: true }) + : undefined; } - }); + } fieldSelectionSets.set(subschema, parsedFieldSelectionSets); } const resolver = mergedTypeConfig.resolve ?? createMergedTypeResolver(mergedTypeConfig); if (resolver == null) { - return; + continue; } const keyFn = mergedTypeConfig.key; @@ -167,29 +170,32 @@ function createMergedTypes( const type = subschema.transformedSchema.getType(typeName) as GraphQLObjectType | GraphQLInterfaceType; const fieldMap = type.getFields(); const selectionSet = selectionSets.get(subschema); - Object.keys(fieldMap).forEach(fieldName => { + for (const fieldName in fieldMap) { const field = fieldMap[fieldName]; const fieldType = getNamedType(field.type); if (selectionSet && isLeafType(fieldType) && selectionSetContainsTopLevelField(selectionSet, fieldName)) { - return; + continue; } if (!(fieldName in supportedBySubschemas)) { supportedBySubschemas[fieldName] = []; } supportedBySubschemas[fieldName].push(subschema); - }); - }); + } + } const sourceSubschemas = typeCandidates[typeName] - .filter(typeCandidate => typeCandidate.transformedSubschema != null) - .map(typeCandidate => typeCandidate.transformedSubschema); - const targetSubschemasBySubschema: Map> = new Map(); - sourceSubschemas.forEach(subschema => { + .map(typeCandidate => typeCandidate?.transformedSubschema) + .filter(isSome); + const targetSubschemasBySubschema: Map< + Subschema, + Array> + > = new Map(); + for (const subschema of sourceSubschemas) { const filteredSubschemas = targetSubschemas.filter(s => s !== subschema); if (filteredSubschemas.length) { targetSubschemasBySubschema.set(subschema, filteredSubschemas); } - }); + } mergedTypes[typeName] = { typeName, @@ -202,41 +208,40 @@ function createMergedTypes( resolvers, }; - Object.keys(supportedBySubschemas).forEach(fieldName => { + for (const fieldName in supportedBySubschemas) { if (supportedBySubschemas[fieldName].length === 1) { mergedTypes[typeName].uniqueFields[fieldName] = supportedBySubschemas[fieldName][0]; } else { mergedTypes[typeName].nonUniqueFields[fieldName] = supportedBySubschemas[fieldName]; } - }); + } } } - }); + } return mergedTypes; } -export function completeStitchingInfo( - stitchingInfo: StitchingInfo, +export function completeStitchingInfo>( + stitchingInfo: StitchingInfo, resolvers: IResolvers, schema: GraphQLSchema -): StitchingInfo { - const selectionSetsByType = Object.create(null); - [schema.getQueryType(), schema.getMutationType()].forEach(rootType => { +): StitchingInfo { + const { selectionSetsByType, selectionSetsByField, dynamicSelectionSetsByField } = stitchingInfo; + + const rootTypes = [schema.getQueryType(), schema.getMutationType()]; + for (const rootType of rootTypes) { if (rootType) { selectionSetsByType[rootType.name] = parseSelectionSet('{ __typename }', { noLocation: true }); } - }); + } - const selectionSetsByField = stitchingInfo.selectionSetsByField; - const dynamicSelectionSetsByField = Object.create(null); - - Object.keys(resolvers).forEach(typeName => { + for (const typeName in resolvers) { const type = resolvers[typeName]; if (isScalarType(type)) { - return; + continue; } - Object.keys(type).forEach(fieldName => { + for (const fieldName in type) { const field = type[fieldName] as IFieldResolverOptions; if (field.selectionSet) { if (typeof field.selectionSet === 'function') { @@ -266,29 +271,28 @@ export function completeStitchingInfo( ].selections.concat(selectionSet.selections); } } - }); - }); + } + } - Object.keys(selectionSetsByField).forEach(typeName => { + for (const typeName in selectionSetsByField) { const typeSelectionSets = selectionSetsByField[typeName]; - Object.keys(typeSelectionSets).forEach(fieldName => { + for (const fieldName in typeSelectionSets) { const consolidatedSelections: Map = new Map(); const selectionSet = typeSelectionSets[fieldName]; - selectionSet.selections.forEach(selection => { + for (const selection of selectionSet.selections) { consolidatedSelections.set(print(selection), selection); - }); + } selectionSet.selections = Array.from(consolidatedSelections.values()); - }); - }); - - stitchingInfo.selectionSetsByType = selectionSetsByType; - stitchingInfo.selectionSetsByField = selectionSetsByField; - stitchingInfo.dynamicSelectionSetsByField = dynamicSelectionSetsByField; + } + } return stitchingInfo; } -export function addStitchingInfo(stitchedSchema: GraphQLSchema, stitchingInfo: StitchingInfo): GraphQLSchema { +export function addStitchingInfo>( + stitchedSchema: GraphQLSchema, + stitchingInfo: StitchingInfo +): GraphQLSchema { return new GraphQLSchema({ ...stitchedSchema.toConfig(), extensions: { diff --git a/packages/stitch/src/subschemaConfigTransforms/index.ts b/packages/stitch/src/subschemaConfigTransforms/index.ts index ebc854cc46d..f9ea965783e 100644 --- a/packages/stitch/src/subschemaConfigTransforms/index.ts +++ b/packages/stitch/src/subschemaConfigTransforms/index.ts @@ -1,7 +1,10 @@ +import { SubschemaConfigTransform } from '../types'; import { computedDirectiveTransformer } from './computedDirectiveTransformer'; export { computedDirectiveTransformer } from './computedDirectiveTransformer'; export { isolateComputedFieldsTransformer } from './isolateComputedFieldsTransformer'; export { splitMergedTypeEntryPointsTransformer } from './splitMergedTypeEntryPointsTransformer'; -export const defaultSubschemaConfigTransforms = [computedDirectiveTransformer('computed')]; +export const defaultSubschemaConfigTransforms: Array> = [ + computedDirectiveTransformer('computed'), +]; diff --git a/packages/stitch/src/subschemaConfigTransforms/isolateComputedFieldsTransformer.ts b/packages/stitch/src/subschemaConfigTransforms/isolateComputedFieldsTransformer.ts index c39e5126b2d..1b128d87a9d 100644 --- a/packages/stitch/src/subschemaConfigTransforms/isolateComputedFieldsTransformer.ts +++ b/packages/stitch/src/subschemaConfigTransforms/isolateComputedFieldsTransformer.ts @@ -1,4 +1,4 @@ -import { GraphQLObjectType, GraphQLInterfaceType, isObjectType, isInterfaceType } from 'graphql'; +import { GraphQLObjectType, isObjectType, isInterfaceType } from 'graphql'; import { SubschemaConfig, MergedTypeConfig, MergedFieldConfig } from '@graphql-tools/delegate'; @@ -14,29 +14,34 @@ export function isolateComputedFieldsTransformer(subschemaConfig: SubschemaConfi const baseSchemaTypes: Record = Object.create(null); const isolatedSchemaTypes: Record = Object.create(null); - Object.entries(subschemaConfig.merge).forEach(([typeName, mergedTypeConfig]) => { + for (const typeName in subschemaConfig.merge) { + const mergedTypeConfig = subschemaConfig.merge[typeName]; + baseSchemaTypes[typeName] = mergedTypeConfig; if (mergedTypeConfig.computedFields) { - mergedTypeConfig.fields = mergedTypeConfig.fields ?? Object.create(null); - Object.entries(mergedTypeConfig.computedFields).forEach(([fieldName, mergedFieldConfig]) => { + const mergeConfigFields = mergedTypeConfig.fields ?? Object.create(null); + for (const fieldName in mergedTypeConfig.computedFields) { + const mergedFieldConfig = mergedTypeConfig.computedFields[fieldName]; console.warn( `The "computedFields" setting is deprecated. Update your @graphql-tools/stitching-directives package, and/or update static merged type config to "${typeName}.fields.${fieldName} = { selectionSet: '${mergedFieldConfig.selectionSet}', computed: true }"` ); - mergedTypeConfig.fields[fieldName] = { - ...(mergedTypeConfig.fields[fieldName] ?? {}), + mergeConfigFields[fieldName] = { + ...(mergeConfigFields[fieldName] ?? {}), ...mergedFieldConfig, computed: true, }; - }); + } delete mergedTypeConfig.computedFields; + mergedTypeConfig.fields = mergeConfigFields; } if (mergedTypeConfig.fields) { const baseFields: Record = Object.create(null); const isolatedFields: Record = Object.create(null); - Object.entries(mergedTypeConfig.fields).forEach(([fieldName, mergedFieldConfig]) => { + for (const fieldName in mergedTypeConfig.fields) { + const mergedFieldConfig = mergedTypeConfig.fields[fieldName]; if (mergedFieldConfig.computed && mergedFieldConfig.selectionSet) { isolatedFields[fieldName] = mergedFieldConfig; } else if (mergedFieldConfig.computed) { @@ -44,7 +49,7 @@ export function isolateComputedFieldsTransformer(subschemaConfig: SubschemaConfi } else { baseFields[fieldName] = mergedFieldConfig; } - }); + } const isolatedFieldCount = Object.keys(isolatedFields).length; const objectType = subschemaConfig.schema.getType(typeName) as GraphQLObjectType; @@ -61,7 +66,7 @@ export function isolateComputedFieldsTransformer(subschemaConfig: SubschemaConfi }; } } - }); + } if (Object.keys(isolatedSchemaTypes).length) { return [ @@ -82,29 +87,29 @@ function filterBaseSubschema( const filteredSchema = pruneSchema( filterSchema({ schema, - objectFieldFilter: (typeName, fieldName) => !isolatedSchemaTypes[typeName]?.fields[fieldName], + objectFieldFilter: (typeName, fieldName) => !isolatedSchemaTypes[typeName]?.fields?.[fieldName], interfaceFieldFilter: (typeName, fieldName) => { if (!typesForInterface[typeName]) { typesForInterface[typeName] = getImplementingTypes(typeName, schema); } return !typesForInterface[typeName].some( - implementingTypeName => isolatedSchemaTypes[implementingTypeName]?.fields[fieldName] + implementingTypeName => isolatedSchemaTypes[implementingTypeName]?.fields?.[fieldName] ); }, }) ); const filteredFields: Record> = {}; - Object.keys(filteredSchema.getTypeMap()).forEach(typeName => { + for (const typeName in filteredSchema.getTypeMap()) { const type = filteredSchema.getType(typeName); if (isObjectType(type) || isInterfaceType(type)) { filteredFields[typeName] = { __typename: true }; const fieldMap = type.getFields(); - Object.keys(fieldMap).forEach(fieldName => { + for (const fieldName in fieldMap) { filteredFields[typeName][fieldName] = true; - }); + } } - }); + } const filteredSubschema = { ...subschemaConfig, @@ -122,63 +127,79 @@ function filterBaseSubschema( }; const remainingTypes = filteredSchema.getTypeMap(); - Object.keys(filteredSubschema.merge).forEach(mergeType => { - if (!remainingTypes[mergeType]) { - delete filteredSubschema.merge[mergeType]; + const mergeConfig = filteredSubschema.merge; + if (mergeConfig) { + for (const mergeType in mergeConfig) { + if (!remainingTypes[mergeType]) { + delete mergeConfig[mergeType]; + } } - }); - if (!Object.keys(filteredSubschema.merge).length) { - delete filteredSubschema.merge; + if (!Object.keys(mergeConfig).length) { + delete filteredSubschema.merge; + } } return filteredSubschema; } -function filterIsolatedSubschema(subschemaConfig: SubschemaConfig): SubschemaConfig { +type IsolatedSubschemaInput = Exclude & { + merge: Exclude; +}; + +function filterIsolatedSubschema(subschemaConfig: IsolatedSubschemaInput): SubschemaConfig { const rootFields: Record = {}; - Object.values(subschemaConfig.merge).forEach(mergedTypeConfig => { + for (const typeName in subschemaConfig.merge) { + const mergedTypeConfig = subschemaConfig.merge[typeName]; const entryPoints = mergedTypeConfig.entryPoints ?? [mergedTypeConfig]; - entryPoints.forEach(entryPoint => { - rootFields[entryPoint.fieldName] = true; - }); - }); + for (const entryPoint of entryPoints) { + if (entryPoint.fieldName != null) { + rootFields[entryPoint.fieldName] = true; + } + } + } const interfaceFields: Record> = {}; - Object.keys(subschemaConfig.merge).forEach(typeName => { - (subschemaConfig.schema.getType(typeName) as GraphQLObjectType).getInterfaces().forEach(int => { - Object.keys((subschemaConfig.schema.getType(int.name) as GraphQLInterfaceType).getFields()).forEach( - intFieldName => { - if (subschemaConfig.merge[typeName].fields[intFieldName]) { - interfaceFields[int.name] = interfaceFields[int.name] || {}; - interfaceFields[int.name][intFieldName] = true; - } + for (const typeName in subschemaConfig.merge) { + const type = subschemaConfig.schema.getType(typeName); + if (!type || !('getInterfaces' in type)) { + throw new Error(`${typeName} expected to have 'getInterfaces' method`); + } + for (const int of type.getInterfaces()) { + const intType = subschemaConfig.schema.getType(int.name); + if (!intType || !('getFields' in intType)) { + throw new Error(`${int.name} expected to have 'getFields' method`); + } + for (const intFieldName in intType.getFields()) { + if (subschemaConfig.merge[typeName].fields?.[intFieldName]) { + interfaceFields[int.name] = interfaceFields[int.name] || {}; + interfaceFields[int.name][intFieldName] = true; } - ); - }); - }); + } + } + } const filteredSchema = pruneSchema( filterSchema({ schema: subschemaConfig.schema, rootFieldFilter: (operation, fieldName) => operation === 'Query' && rootFields[fieldName] != null, - objectFieldFilter: (typeName, fieldName) => subschemaConfig.merge[typeName]?.fields[fieldName] != null, + objectFieldFilter: (typeName, fieldName) => subschemaConfig.merge[typeName]?.fields?.[fieldName] != null, interfaceFieldFilter: (typeName, fieldName) => interfaceFields[typeName]?.[fieldName] != null, }) ); const filteredFields: Record> = {}; - Object.keys(filteredSchema.getTypeMap()).forEach(typeName => { + for (const typeName in filteredSchema.getTypeMap()) { const type = filteredSchema.getType(typeName); if (isObjectType(type) || isInterfaceType(type)) { filteredFields[typeName] = { __typename: true }; const fieldMap = type.getFields(); - Object.keys(fieldMap).forEach(fieldName => { + for (const fieldName in fieldMap) { filteredFields[typeName][fieldName] = true; - }); + } } - }); + } return { ...subschemaConfig, diff --git a/packages/stitch/src/subschemaConfigTransforms/splitMergedTypeEntryPointsTransformer.ts b/packages/stitch/src/subschemaConfigTransforms/splitMergedTypeEntryPointsTransformer.ts index b655fc9f135..493772bbfc9 100644 --- a/packages/stitch/src/subschemaConfigTransforms/splitMergedTypeEntryPointsTransformer.ts +++ b/packages/stitch/src/subschemaConfigTransforms/splitMergedTypeEntryPointsTransformer.ts @@ -1,4 +1,4 @@ -import { cloneSubschemaConfig, SubschemaConfig } from '@graphql-tools/delegate'; +import { cloneSubschemaConfig, MergedTypeConfig, SubschemaConfig } from '@graphql-tools/delegate'; export function splitMergedTypeEntryPointsTransformer(subschemaConfig: SubschemaConfig): Array { if (!subschemaConfig.merge) return [subschemaConfig]; @@ -13,19 +13,23 @@ export function splitMergedTypeEntryPointsTransformer(subschemaConfig: Subschema for (let i = 0; i < maxEntryPoints; i += 1) { const subschemaPermutation = cloneSubschemaConfig(subschemaConfig); - const mergedTypesCopy = subschemaPermutation.merge; + const mergedTypesCopy: Record> = subschemaPermutation.merge ?? + Object.create(null); + let currentMerge = mergedTypesCopy; if (i > 0) { - subschemaPermutation.merge = Object.create(null); + subschemaPermutation.merge = currentMerge = Object.create(null); } - Object.keys(mergedTypesCopy).forEach(typeName => { + for (const typeName in mergedTypesCopy) { const mergedTypeConfig = mergedTypesCopy[typeName]; const mergedTypeEntryPoint = mergedTypeConfig?.entryPoints?.[i]; if (mergedTypeEntryPoint) { if (mergedTypeConfig.selectionSet ?? mergedTypeConfig.fieldName ?? mergedTypeConfig.resolve) { - throw new Error(`Merged type ${typeName} may not define entryPoints in addition to selectionSet, fieldName, or resolve`); + throw new Error( + `Merged type ${typeName} may not define entryPoints in addition to selectionSet, fieldName, or resolve` + ); } Object.assign(mergedTypeConfig, mergedTypeEntryPoint); @@ -34,15 +38,16 @@ export function splitMergedTypeEntryPointsTransformer(subschemaConfig: Subschema if (i > 0) { delete mergedTypeConfig.canonical; if (mergedTypeConfig.fields != null) { - Object.values(mergedTypeConfig.fields).forEach(mergedFieldConfig => { + for (const mergedFieldName in mergedTypeConfig.fields) { + const mergedFieldConfig = mergedTypeConfig.fields[mergedFieldName]; delete mergedFieldConfig.canonical; - }); + } } } - subschemaPermutation.merge[typeName] = mergedTypeConfig; + currentMerge[typeName] = mergedTypeConfig; } - }); + } subschemaPermutations.push(subschemaPermutation); } diff --git a/packages/stitch/src/typeCandidates.ts b/packages/stitch/src/typeCandidates.ts index e681149ca92..7d356cdc535 100644 --- a/packages/stitch/src/typeCandidates.ts +++ b/packages/stitch/src/typeCandidates.ts @@ -8,21 +8,24 @@ import { SchemaExtensionNode, isSpecifiedScalarType, GraphQLSchema, + isDirective, } from 'graphql'; import { wrapSchema } from '@graphql-tools/wrap'; import { Subschema, SubschemaConfig, StitchingInfo } from '@graphql-tools/delegate'; -import { GraphQLParseOptions, ITypeDefinitions, rewireTypes, TypeMap } from '@graphql-tools/utils'; -import { buildDocumentFromTypeDefinitions } from '@graphql-tools/schema'; +import { GraphQLParseOptions, TypeSource, rewireTypes, TypeMap } from '@graphql-tools/utils'; import typeFromAST from './typeFromAST'; import { MergeTypeCandidate, MergeTypeFilter, OnTypeConflict, TypeMergingOptions } from './types'; import { mergeCandidates } from './mergeCandidates'; import { extractDefinitions } from './definitions'; +import { mergeTypeDefs } from '@graphql-tools/merge'; -type CandidateSelector = (candidates: Array) => MergeTypeCandidate; +type CandidateSelector> = ( + candidates: Array> +) => MergeTypeCandidate; -export function buildTypeCandidates({ +export function buildTypeCandidates>({ subschemas, originalSubschemaMap, types, @@ -34,10 +37,13 @@ export function buildTypeCandidates({ operationTypeNames, mergeDirectives, }: { - subschemas: Array; - originalSubschemaMap: Map; + subschemas: Array>; + originalSubschemaMap: Map< + Subschema, + GraphQLSchema | SubschemaConfig + >; types: Array; - typeDefs: ITypeDefinitions; + typeDefs: TypeSource; parseOptions: GraphQLParseOptions; extensions: Array; directiveMap: Record; @@ -46,28 +52,28 @@ export function buildTypeCandidates({ schemaExtensions: Array; }; operationTypeNames: Record; - mergeDirectives: boolean; -}): Record> { - const typeCandidates: Record> = Object.create(null); + mergeDirectives?: boolean | undefined; +}): Record>> { + const typeCandidates: Record>> = Object.create(null); - let schemaDef: SchemaDefinitionNode; + let schemaDef: SchemaDefinitionNode | undefined; let schemaExtensions: Array = []; - let document: DocumentNode; - let extraction: ReturnType; + let document: DocumentNode | undefined; + let extraction: ReturnType | undefined; if ((typeDefs && !Array.isArray(typeDefs)) || (Array.isArray(typeDefs) && typeDefs.length)) { - document = buildDocumentFromTypeDefinitions(typeDefs, parseOptions); + document = mergeTypeDefs(typeDefs, parseOptions); extraction = extractDefinitions(document); schemaDef = extraction.schemaDefs[0]; schemaExtensions = schemaExtensions.concat(extraction.schemaExtensions); } - schemaDefs.schemaDef = schemaDef; + schemaDefs.schemaDef = schemaDef ?? schemaDefs.schemaDef; schemaDefs.schemaExtensions = schemaExtensions; setOperationTypeNames(schemaDefs, operationTypeNames); - subschemas.forEach(subschema => { + for (const subschema of subschemas) { const schema = wrapSchema(subschema); const operationTypes = { @@ -76,7 +82,7 @@ export function buildTypeCandidates({ subscription: schema.getSubscriptionType(), }; - Object.keys(operationTypes).forEach(operationType => { + for (const operationType in operationTypes) { if (operationTypes[operationType] != null) { addTypeCandidate(typeCandidates, operationTypeNames[operationType], { type: operationTypes[operationType], @@ -84,16 +90,16 @@ export function buildTypeCandidates({ transformedSubschema: subschema, }); } - }); + } - if (mergeDirectives) { - schema.getDirectives().forEach(directive => { + if (mergeDirectives === true) { + for (const directive of schema.getDirectives()) { directiveMap[directive.name] = directive; - }); + } } const originalTypeMap = schema.getTypeMap(); - Object.keys(originalTypeMap).forEach(typeName => { + for (const typeName in originalTypeMap) { const type: GraphQLNamedType = originalTypeMap[typeName]; if ( isNamedType(type) && @@ -108,21 +114,27 @@ export function buildTypeCandidates({ transformedSubschema: subschema, }); } - }); - }); + } + } - if (document !== undefined) { - extraction.typeDefinitions.forEach(def => { - const type = typeFromAST(def) as GraphQLNamedType; + if (document != null && extraction != null) { + for (const def of extraction.typeDefinitions) { + const type = typeFromAST(def); + if (!isNamedType(type)) { + throw new Error(`Expected to get named typed but got ${JSON.stringify(def)}`); + } if (type != null) { addTypeCandidate(typeCandidates, type.name, { type }); } - }); + } - extraction.directiveDefs.forEach(def => { - const directive = typeFromAST(def) as GraphQLDirective; + for (const def of extraction.directiveDefs) { + const directive = typeFromAST(def); + if (!isDirective(directive)) { + throw new Error(`Expected to get directive type but got ${JSON.stringify(def)}`); + } directiveMap[directive.name] = directive; - }); + } if (extraction.extensionDefs.length > 0) { extensions.push({ @@ -132,7 +144,9 @@ export function buildTypeCandidates({ } } - types.forEach(type => addTypeCandidate(typeCandidates, type.name, { type })); + for (const type of types) { + addTypeCandidate(typeCandidates, type.name, { type }); + } return typeCandidates; } @@ -152,19 +166,19 @@ function setOperationTypeNames( allNodes.unshift(schemaDef); } - allNodes.forEach(node => { + for (const node of allNodes) { if (node.operationTypes != null) { - node.operationTypes.forEach(operationType => { + for (const operationType of node.operationTypes) { operationTypeNames[operationType.operation] = operationType.type.name.value; - }); + } } - }); + } } -function addTypeCandidate( - typeCandidates: Record>, +function addTypeCandidate>( + typeCandidates: Record>>, name: string, - typeCandidate: MergeTypeCandidate + typeCandidate: MergeTypeCandidate ) { if (!(name in typeCandidates)) { typeCandidates[name] = []; @@ -172,7 +186,7 @@ function addTypeCandidate( typeCandidates[name].push(typeCandidate); } -export function buildTypes({ +export function buildTypes>({ typeCandidates, directives, stitchingInfo, @@ -181,21 +195,21 @@ export function buildTypes({ mergeTypes, typeMergingOptions, }: { - typeCandidates: Record>; + typeCandidates: Record>>; directives: Array; - stitchingInfo: StitchingInfo; + stitchingInfo: StitchingInfo; operationTypeNames: Record; - onTypeConflict: OnTypeConflict; - mergeTypes: boolean | Array | MergeTypeFilter; - typeMergingOptions: TypeMergingOptions; + onTypeConflict?: OnTypeConflict; + mergeTypes: boolean | Array | MergeTypeFilter; + typeMergingOptions?: TypeMergingOptions; }): { typeMap: TypeMap; directives: Array } { const typeMap: TypeMap = Object.create(null); - Object.keys(typeCandidates).forEach(typeName => { + for (const typeName in typeCandidates) { if ( - typeName === operationTypeNames.query || - typeName === operationTypeNames.mutation || - typeName === operationTypeNames.subscription || + typeName === operationTypeNames['query'] || + typeName === operationTypeNames['mutation'] || + typeName === operationTypeNames['subscription'] || (mergeTypes === true && !typeCandidates[typeName].some(candidate => isSpecifiedScalarType(candidate.type))) || (typeof mergeTypes === 'function' && mergeTypes(typeCandidates[typeName], typeName)) || (Array.isArray(mergeTypes) && mergeTypes.includes(typeName)) || @@ -206,15 +220,17 @@ export function buildTypes({ const candidateSelector = onTypeConflict != null ? onTypeConflictToCandidateSelector(onTypeConflict) - : (cands: Array) => cands[cands.length - 1]; + : (cands: Array>) => cands[cands.length - 1]; typeMap[typeName] = candidateSelector(typeCandidates[typeName]).type; } - }); + } return rewireTypes(typeMap, directives); } -function onTypeConflictToCandidateSelector(onTypeConflict: OnTypeConflict): CandidateSelector { +function onTypeConflictToCandidateSelector>( + onTypeConflict: OnTypeConflict +): CandidateSelector { return cands => cands.reduce((prev, next) => { const type = onTypeConflict(prev.type, next.type, { diff --git a/packages/stitch/src/typeFromAST.ts b/packages/stitch/src/typeFromAST.ts index 7178f324a6e..f72355dc1cd 100644 --- a/packages/stitch/src/typeFromAST.ts +++ b/packages/stitch/src/typeFromAST.ts @@ -32,7 +32,7 @@ import { GraphQLDeprecatedDirective, } from 'graphql'; -import { createStub, createNamedStub } from '@graphql-tools/utils'; +import { createStub, createNamedStub, Maybe } from '@graphql-tools/utils'; const backcompatOptions = { commentDescriptions: true }; @@ -61,8 +61,8 @@ function makeObjectType(node: ObjectTypeDefinitionNode): GraphQLObjectType { const config = { name: node.name.value, description: getDescription(node, backcompatOptions), - interfaces: () => node.interfaces.map(iface => createNamedStub(iface.name.value, 'interface')), - fields: () => makeFields(node.fields), + interfaces: () => node.interfaces?.map(iface => createNamedStub(iface.name.value, 'interface')), + fields: () => (node.fields != null ? makeFields(node.fields) : {}), astNode: node, }; return new GraphQLObjectType(config); @@ -72,27 +72,28 @@ function makeInterfaceType(node: InterfaceTypeDefinitionNode): GraphQLInterfaceT const config = { name: node.name.value, description: getDescription(node, backcompatOptions), - interfaces: ((node as unknown) as ObjectTypeDefinitionNode).interfaces?.map(iface => + interfaces: (node as unknown as ObjectTypeDefinitionNode).interfaces?.map(iface => createNamedStub(iface.name.value, 'interface') ), - fields: () => makeFields(node.fields), + fields: () => (node.fields != null ? makeFields(node.fields) : {}), astNode: node, }; return new GraphQLInterfaceType(config); } function makeEnumType(node: EnumTypeDefinitionNode): GraphQLEnumType { - const values = node.values.reduce( - (prev, value) => ({ - ...prev, - [value.name.value]: { - description: getDescription(value, backcompatOptions), - deprecationReason: getDeprecationReason(value), - astNode: value, - }, - }), - {} - ); + const values = + node.values?.reduce( + (prev, value) => ({ + ...prev, + [value.name.value]: { + description: getDescription(value, backcompatOptions), + deprecationReason: getDeprecationReason(value), + astNode: value, + }, + }), + {} + ) ?? {}; return new GraphQLEnumType({ name: node.name.value, @@ -106,7 +107,7 @@ function makeUnionType(node: UnionTypeDefinitionNode): GraphQLUnionType { return new GraphQLUnionType({ name: node.name.value, description: getDescription(node, backcompatOptions), - types: () => node.types.map(type => createNamedStub(type.name.value, 'object')), + types: () => node.types?.map(type => createNamedStub(type.name.value, 'object')) ?? [], astNode: node, }); } @@ -126,7 +127,7 @@ function makeInputObjectType(node: InputObjectTypeDefinitionNode): GraphQLInputO return new GraphQLInputObjectType({ name: node.name.value, description: getDescription(node, backcompatOptions), - fields: () => makeValues(node.fields), + fields: () => (node.fields ? makeValues(node.fields) : {}), astNode: node, }); } @@ -138,7 +139,7 @@ function makeFields(nodes: ReadonlyArray): Record): GraphQLFiel function makeDirective(node: DirectiveDefinitionNode): GraphQLDirective { const locations: Array = []; - node.locations.forEach(location => { + for (const location of node.locations) { if (location.value in DirectiveLocation) { locations.push(location.value as DirectiveLocationEnum); } - }); + } return new GraphQLDirective({ name: node.name.value, description: node.description != null ? node.description.value : null, locations, isRepeatable: node.repeatable, - args: makeValues(node.arguments), + args: makeValues(node.arguments ?? []), astNode: node, }); } @@ -184,11 +185,11 @@ function makeDirective(node: DirectiveDefinitionNode): GraphQLDirective { function getDescription( node: { description?: StringValueNode; loc?: Location }, options?: { commentDescriptions?: boolean } -): string { +): string | undefined { if (node.description != null) { return node.description.value; } - if (options.commentDescriptions) { + if (options?.commentDescriptions) { const rawValue = getLeadingCommentBlock(node); if (rawValue !== undefined) { return dedentBlockStringValue(`\n${rawValue as string}`); @@ -278,7 +279,7 @@ function isBlank(str: string) { return leadingWhitespace(str) === str.length; } -function getDeprecationReason(node: EnumValueDefinitionNode | FieldDefinitionNode): string { +function getDeprecationReason(node: EnumValueDefinitionNode | FieldDefinitionNode): Maybe { const deprecated = getDirectiveValues(GraphQLDeprecatedDirective, node); - return deprecated?.reason; + return deprecated?.['reason']; } diff --git a/packages/stitch/src/types.ts b/packages/stitch/src/types.ts index 1251afdd843..f7ebed4bcc7 100644 --- a/packages/stitch/src/types.ts +++ b/packages/stitch/src/types.ts @@ -11,7 +11,7 @@ import { GraphQLEnumValueConfig, GraphQLEnumType, } from 'graphql'; -import { ITypeDefinitions } from '@graphql-tools/utils'; +import { Maybe, TypeSource } from '@graphql-tools/utils'; import { Subschema, SubschemaConfig } from '@graphql-tools/delegate'; import { IExecutableSchemaDefinition } from '@graphql-tools/schema'; @@ -55,10 +55,10 @@ export interface IStitchSchemasOptions> subschemas?: Array< GraphQLSchema | SubschemaConfig | Array> >; - typeDefs?: ITypeDefinitions; + typeDefs?: TypeSource; types?: Array; - onTypeConflict?: OnTypeConflict; - mergeDirectives?: boolean; + onTypeConflict?: OnTypeConflict; + mergeDirectives?: boolean | undefined; mergeTypes?: boolean | Array | MergeTypeFilter; typeMergingOptions?: TypeMergingOptions; subschemaConfigTransforms?: Array>; @@ -72,8 +72,8 @@ export interface TypeMergingOptions> { validationSettings?: ValidationSettings; validationScopes?: Record; typeCandidateMerger?: (candidates: Array>) => MergeTypeCandidate; - typeDescriptionsMerger?: (candidates: Array>) => string; - fieldConfigMerger?: (candidates: Array>) => GraphQLFieldConfig; + typeDescriptionsMerger?: (candidates: Array>) => Maybe; + fieldConfigMerger?: (candidates: Array>) => GraphQLFieldConfig; inputFieldConfigMerger?: (candidates: Array>) => GraphQLInputFieldConfig; enumValueConfigMerger?: (candidates: Array>) => GraphQLEnumValueConfig; } diff --git a/packages/stitch/tests/alternateStitchSchemas.test.ts b/packages/stitch/tests/alternateStitchSchemas.test.ts index 3ae5cb889f1..28621405339 100644 --- a/packages/stitch/tests/alternateStitchSchemas.test.ts +++ b/packages/stitch/tests/alternateStitchSchemas.test.ts @@ -33,7 +33,7 @@ import { import { delegateToSchema, SubschemaConfig } from '@graphql-tools/delegate'; import { makeExecutableSchema } from '@graphql-tools/schema'; import { addMocksToSchema } from '@graphql-tools/mock'; -import { filterSchema, ExecutionResult } from '@graphql-tools/utils'; +import { filterSchema, ExecutionResult, assertSome } from '@graphql-tools/utils'; import { stitchSchemas } from '../src/stitchSchemas'; @@ -440,10 +440,12 @@ describe('optional arguments', () => { `; const originalResult = await graphql(schema, query); - expect(originalResult.data.test).toEqual(true); + assertSome(originalResult.data) + expect(originalResult.data['test']).toEqual(true); const stitchedResult = await graphql(stitchedSchema, query); - expect(stitchedResult.data.test).toEqual(true); + assertSome(stitchedResult.data) + expect(stitchedResult.data['test']).toEqual(true); }); it('work with schema stitching when using variables', async () => { @@ -454,10 +456,12 @@ describe('optional arguments', () => { `; const originalResult = await graphql(schema, query); - expect(originalResult.data.test).toEqual(true); + assertSome(originalResult.data) + expect(originalResult.data['test']).toEqual(true); const stitchedResult = await graphql(stitchedSchema, query); - expect(stitchedResult.data.test).toEqual(true); + assertSome(stitchedResult.data) + expect(stitchedResult.data['test']).toEqual(true); }); // See https://github.com/graphql/graphql-js/issues/2533 @@ -475,7 +479,8 @@ describe('optional arguments', () => { {}, { arg: undefined }, ); - expect(originalResult.data.test).toEqual(false); + assertSome(originalResult.data) + expect(originalResult.data['test']).toEqual(false); const stitchedResult = await graphql( stitchedSchema, @@ -484,7 +489,8 @@ describe('optional arguments', () => { {}, { arg: undefined }, ); - expect(stitchedResult.data.test).toEqual(false); + assertSome(stitchedResult.data) + expect(stitchedResult.data['test']).toEqual(false); }); }); @@ -495,11 +501,12 @@ describe('default values', () => { transforms: [ new TransformRootFields( ( - typeName: string, - fieldName: string, - fieldConfig: GraphQLFieldConfig, + typeName, + fieldName, + fieldConfig, ) => { if (typeName === 'Query' && fieldName === 'jsonTest') { + assertSome(fieldConfig.args) return [ 'renamedJsonTest', { @@ -508,7 +515,7 @@ describe('default values', () => { args: { ...fieldConfig.args, input: { - ...fieldConfig.args.input, + ...fieldConfig.args['input'], defaultValue: { test: 'test' } } } @@ -1508,7 +1515,8 @@ describe('schema transformation with wrapping of object fields', () => { const query = '{ wrapped { user { dummy } } }'; const result = await graphql(stitchedSchema, query); - expect(result.data.wrapped.user.dummy).not.toEqual(null); + assertSome(result.data) + expect(result.data['wrapped'].user.dummy).not.toEqual(null); }); }); }); @@ -1579,6 +1587,7 @@ describe('interface resolver inheritance', () => { }); const query = '{ user { id name } }'; const response = await graphql(stitchedSchema, query); + assertSome(response.errors) expect(response.errors.length).toBe(1); expect(response.errors[0].message).toBe( 'Cannot return null for non-nullable field User.id.', @@ -1598,6 +1607,7 @@ describe('interface resolver inheritance', () => { }); const query = '{ user { id name } }'; const response = await graphql(stitchedSchema, query); + assertSome(response.errors) expect(response.errors.length).toBe(1); expect(response.errors[0].message).toBe( 'Cannot return null for non-nullable field User.id.', @@ -1629,7 +1639,8 @@ describe('stitchSchemas', () => { const query = '{ test { field } }'; const response = await graphql(stitchedSchema, query); - expect(response.data.test).toBe(null); + assertSome(response.data) + expect(response.data['test']).toBe(null); expect(response.errors).toBeUndefined(); }); @@ -1671,7 +1682,7 @@ type Query { } `.trim(), ); - expect(response.data?.getInput).toBe('test'); + expect(response.data?.['getInput']).toBe('test'); }); test('can override scalars with new internal values', async () => { @@ -1711,7 +1722,7 @@ type Query { const query = '{ getTestScalar }'; const response = await graphql(stitchedSchema, query); - expect(response.data?.getTestScalar).toBe('test'); + expect(response.data?.['getTestScalar']).toBe('test'); }); test('can override scalars with new internal values when using default input types', async () => { @@ -1751,7 +1762,7 @@ type Query { const query = '{ getTestScalar }'; const response = await graphql(stitchedSchema, query); - expect(response.data?.getTestScalar).toBe('test'); + expect(response.data?.['getTestScalar']).toBe('test'); }); test('can use @include directives', async () => { @@ -1799,7 +1810,7 @@ type Query { } `; const response = await graphql(stitchedSchema, query); - expect(response.data?.get2.subfield).toBe('test'); + expect(response.data?.['get2'].subfield).toBe('test'); }); test('can use functions in subfields', async () => { @@ -1827,7 +1838,7 @@ type Query { const query = '{ wrappingObject { functionField } }'; const response = await graphql(stitchedSchema, query); - expect(response.data?.wrappingObject.functionField).toBe(8); + expect(response.data?.['wrappingObject'].functionField).toBe(8); }); }); @@ -1891,7 +1902,7 @@ describe('onTypeConflict', () => { mergeTypes: false, }); const result1 = await graphql(stitchedSchema, '{ test2 { fieldC } }'); - expect(result1.data?.test2.fieldC).toBe('C'); + expect(result1.data?.['test2'].fieldC).toBe('C'); const result2 = await graphql(stitchedSchema, '{ test2 { fieldB } }'); expect(result2.data).toBeUndefined(); }); @@ -1903,7 +1914,7 @@ describe('onTypeConflict', () => { onTypeConflict: (_left, right) => right, }); const result1 = await graphql(stitchedSchema, '{ test2 { fieldC } }'); - expect(result1.data?.test2.fieldC).toBe('C'); + expect(result1.data?.['test2'].fieldC).toBe('C'); const result2 = await graphql(stitchedSchema, '{ test2 { fieldB } }'); expect(result2.data).toBeUndefined(); }); @@ -1915,7 +1926,7 @@ describe('onTypeConflict', () => { onTypeConflict: (left) => left, }); const result1 = await graphql(stitchedSchema, '{ test1 { fieldB } }'); - expect(result1.data?.test1.fieldB).toBe('B'); + expect(result1.data?.['test1'].fieldB).toBe('B'); const result2 = await graphql(stitchedSchema, '{ test1 { fieldC } }'); expect(result2.data).toBeUndefined(); }); diff --git a/packages/stitch/tests/dataloader.test.ts b/packages/stitch/tests/dataloader.test.ts index f7692b3dbbe..4dcacf27d7e 100644 --- a/packages/stitch/tests/dataloader.test.ts +++ b/packages/stitch/tests/dataloader.test.ts @@ -60,7 +60,7 @@ describe('dataloader', () => { user: { selectionSet: '{ userId }', resolve(task, _args, context, info) { - return context.usersLoader.load({ id: task.userId, info }); + return context['usersLoader'].load({ id: task.userId, info }); }, }, }, @@ -68,7 +68,7 @@ describe('dataloader', () => { }); const usersLoader = new DataLoader( - async (keys: Array<{ id: any; info: GraphQLResolveInfo }>) => { + async (keys: ReadonlyArray<{ id: any; info: GraphQLResolveInfo }>) => { const users = await delegateToSchema({ schema: userSchema, operation: 'query', diff --git a/packages/stitch/tests/errors.test.ts b/packages/stitch/tests/errors.test.ts index aba766bce8c..b9571d460df 100644 --- a/packages/stitch/tests/errors.test.ts +++ b/packages/stitch/tests/errors.test.ts @@ -3,7 +3,7 @@ import { graphql, GraphQLError, buildSchema } from 'graphql'; import { Executor } from '@graphql-tools/delegate'; import { makeExecutableSchema } from '@graphql-tools/schema'; import { stitchSchemas } from '@graphql-tools/stitch'; -import { ExecutionResult } from '@graphql-tools/utils'; +import { assertSome, ExecutionResult } from '@graphql-tools/utils'; describe('passes along errors for missing fields on list', () => { test('if non-null', async () => { @@ -38,6 +38,8 @@ describe('passes along errors for missing fields on list', () => { const originalResult = await graphql(schema, query); const stitchedResult = await graphql(stitchedSchema, query); expect(stitchedResult).toEqual(originalResult); + assertSome(stitchedResult.errors) + assertSome(originalResult.errors) expect(stitchedResult.errors[0].path).toEqual(originalResult.errors[0].path); }); @@ -73,6 +75,8 @@ describe('passes along errors for missing fields on list', () => { const originalResult = await graphql(schema, query); const stitchedResult = await graphql(stitchedSchema, query); expect(stitchedResult).toEqual(originalResult); + assertSome(originalResult.errors) + assertSome(stitchedResult.errors) expect(stitchedResult.errors[0].path).toEqual(originalResult.errors[0].path); }); }); @@ -110,6 +114,8 @@ describe('passes along errors when list field errors', () => { const originalResult = await graphql(schema, query); const stitchedResult = await graphql(stitchedSchema, query); expect(stitchedResult).toEqual(originalResult); + assertSome(stitchedResult.errors) + assertSome(originalResult.errors) expect(stitchedResult.errors[0].path).toEqual(originalResult.errors[0].path); }); @@ -145,6 +151,8 @@ describe('passes along errors when list field errors', () => { const originalResult = await graphql(schema, query); const stitchedResult = await graphql(stitchedSchema, query); expect(stitchedResult).toEqual(originalResult); + assertSome(stitchedResult.errors) + assertSome(originalResult.errors) expect(stitchedResult.errors[0].path).toEqual(originalResult.errors[0].path); }); @@ -175,6 +183,8 @@ describe('passes along errors when list field errors', () => { const originalResult = await graphql(schema, query); const stitchedResult = await graphql(stitchedSchema, query); expect(stitchedResult).toEqual(originalResult); + assertSome(stitchedResult.errors) + assertSome(originalResult.errors) expect(stitchedResult.errors[0].path).toEqual(originalResult.errors[0].path); }); }); diff --git a/packages/stitch/tests/example.test.ts b/packages/stitch/tests/example.test.ts index 8d2b48cc46d..9e20c76a278 100644 --- a/packages/stitch/tests/example.test.ts +++ b/packages/stitch/tests/example.test.ts @@ -4,6 +4,7 @@ import { makeExecutableSchema } from '@graphql-tools/schema'; import { delegateToSchema } from '@graphql-tools/delegate'; import { addMocksToSchema } from '@graphql-tools/mock'; import { stitchSchemas } from '@graphql-tools/stitch'; +import { assertSome } from '@graphql-tools/utils'; describe('basic stitching example', () => { test('works', async () => { @@ -107,9 +108,10 @@ describe('basic stitching example', () => { const result = await graphql(stitchedSchema, query); expect(result.errors).toBeUndefined(); - expect(result.data.userById.chirps[1].id).not.toBe(null); - expect(result.data.userById.chirps[1].text).not.toBe(null); - expect(result.data.userById.chirps[1].author.email).not.toBe(null); + assertSome(result.data) + expect(result.data['userById'].chirps[1].id).not.toBe(null); + expect(result.data['userById'].chirps[1].text).not.toBe(null); + expect(result.data['userById'].chirps[1].author.email).not.toBe(null); }); }); @@ -229,9 +231,10 @@ describe('stitching to interfaces', () => { const resultWithFragments = await graphql(stitchedSchema, queryWithFragments); expect(resultWithFragments.errors).toBeUndefined(); - expect(resultWithFragments.data.node.chirps[1].id).not.toBe(null); - expect(resultWithFragments.data.node.chirps[1].text).not.toBe(null); - expect(resultWithFragments.data.node.chirps[1].author.email).not.toBe(null); + assertSome(resultWithFragments.data) + expect(resultWithFragments.data['node'].chirps[1].id).not.toBe(null); + expect(resultWithFragments.data['node'].chirps[1].text).not.toBe(null); + expect(resultWithFragments.data['node'].chirps[1].author.email).not.toBe(null); }); test('it works without fragments', async () => { @@ -253,9 +256,10 @@ describe('stitching to interfaces', () => { const resultWithoutFragments = await graphql(stitchedSchema, queryWithoutFragments); expect(resultWithoutFragments.errors).toBeUndefined(); - expect(resultWithoutFragments.data.node.chirps[1].id).not.toBe(null); - expect(resultWithoutFragments.data.node.chirps[1].text).not.toBe(null); - expect(resultWithoutFragments.data.node.chirps[1].author.email).not.toBe(null); + assertSome(resultWithoutFragments.data) + expect(resultWithoutFragments.data['node'].chirps[1].id).not.toBe(null); + expect(resultWithoutFragments.data['node'].chirps[1].text).not.toBe(null); + expect(resultWithoutFragments.data['node'].chirps[1].author.email).not.toBe(null); }); }); diff --git a/packages/stitch/tests/extendedInterface.test.ts b/packages/stitch/tests/extendedInterface.test.ts index 28ce3e7bfa7..4e855c11433 100644 --- a/packages/stitch/tests/extendedInterface.test.ts +++ b/packages/stitch/tests/extendedInterface.test.ts @@ -1,6 +1,7 @@ import { graphql } from 'graphql'; import { makeExecutableSchema } from '@graphql-tools/schema'; import { stitchSchemas } from '../src/stitchSchemas'; +import { assertSome } from '@graphql-tools/utils'; describe('extended interfaces', () => { test('expands extended interface types for subservices', async () => { @@ -19,7 +20,7 @@ describe('extended interfaces', () => { `, resolvers: { Query: { - slot(obj, args, context, info) { + slot() { return { __typename: 'Item', id: '23', name: 'The Item' }; } } @@ -45,8 +46,8 @@ describe('extended interfaces', () => { } } `); - - expect(data.slot).toEqual({ id: '23', name: 'The Item' }); + assertSome(data) + expect(data['slot']).toEqual({ id: '23', name: 'The Item' }); }); test('merges types behind gateway interface extension', async () => { @@ -62,7 +63,7 @@ describe('extended interfaces', () => { `, resolvers: { Query: { - itemById(obj, args, context, info) { + itemById(_obj, args, _context, _info) { return { id: args.id, name: `Item ${args.id}` }; } } @@ -83,7 +84,7 @@ describe('extended interfaces', () => { `, resolvers: { Query: { - placementById(obj, args, context, info) { + placementById(_obj, args, _context, _info) { return { __typename: 'Item', id: args.id }; } } @@ -119,7 +120,7 @@ describe('extended interfaces', () => { } } `); - - expect(result.data.placement).toEqual({ id: '23', name: 'Item 23' }); + assertSome(result.data) + expect(result.data['placement']).toEqual({ id: '23', name: 'Item 23' }); }); }); diff --git a/packages/stitch/tests/fixtures/schemas.ts b/packages/stitch/tests/fixtures/schemas.ts index 191fb01c2ae..bab2fb0b1b5 100644 --- a/packages/stitch/tests/fixtures/schemas.ts +++ b/packages/stitch/tests/fixtures/schemas.ts @@ -21,6 +21,7 @@ import { IResolvers, ExecutionResult, mapAsyncIterator, + isAsyncIterable, } from '@graphql-tools/utils'; import { makeExecutableSchema } from '@graphql-tools/schema'; @@ -189,10 +190,6 @@ export const sampleData: { }, }; -function values(o: { [s: string]: T }): Array { - return Object.keys(o).map((k) => o[k]); -} - function coerceString(value: any): string { if (Array.isArray(value)) { throw new TypeError( @@ -226,9 +223,9 @@ function parseLiteral(ast: ValueNode): any { return parseFloat(ast.value); case Kind.OBJECT: { const value = Object.create(null); - ast.fields.forEach((field) => { + for (const field of ast.fields) { value[field.name.value] = parseLiteral(field.value); - }); + } return value; } @@ -350,7 +347,7 @@ const propertyResolvers: IResolvers = { }, properties(_root, { limit }) { - const list = values(sampleData.Property); + const list = Object.values(sampleData.Property); return limit ? list.slice(0, limit) : list; }, @@ -465,7 +462,7 @@ const productTypeDefs = ` const productResolvers: IResolvers = { Query: { products(_root) { - const list = values(sampleData.Product); + const list = Object.values(sampleData.Product); return list; }, }, @@ -551,7 +548,7 @@ const bookingResolvers: IResolvers = { return sampleData.Booking[id]; }, bookingsByPropertyId(_parent, { propertyId, limit }) { - const list = values(sampleData.Booking).filter( + const list = Object.values(sampleData.Booking).filter( (booking: Booking) => booking.propertyId === propertyId, ); return limit ? list.slice(0, limit) : list; @@ -560,11 +557,11 @@ const bookingResolvers: IResolvers = { return sampleData.Customer[id]; }, bookings(_parent, { limit }) { - const list = values(sampleData.Booking); + const list = Object.values(sampleData.Booking); return limit ? list.slice(0, limit) : list; }, customers(_parent, { limit }) { - const list = values(sampleData.Customer); + const list = Object.values(sampleData.Customer); return limit ? list.slice(0, limit) : list; }, }, @@ -601,13 +598,13 @@ const bookingResolvers: IResolvers = { Customer: { bookings(parent: Customer, { limit }) { - const list = values(sampleData.Booking).filter( + const list = Object.values(sampleData.Booking).filter( (booking: Booking) => booking.customerId === parent.id, ); return limit ? list.slice(0, limit) : list; }, vehicle(parent: Customer) { - return sampleData.Vehicle[parent.vehicleId]; + return parent.vehicleId && sampleData.Vehicle[parent.vehicleId]; }, error() { throw new Error('Customer.error error'); @@ -685,7 +682,23 @@ export const subscriptionSchema: GraphQLSchema = makeExecutableSchema({ }); function makeExecutorFromSchema(schema: GraphQLSchema) { - return async ({ document, variables, context }: ExecutionParams) => { + return async ({ document, variables, context, info }: ExecutionParams) => { + if (info?.operation.operation === 'subscription') { + const result = subscribe( + schema, + document, + null, + context, + variables, + ) as Promise> | ExecutionResult>; + if (isPromise(result)) { + return result.then(asyncIterator => { + assertAsyncIterable(asyncIterator) + return mapAsyncIterator(asyncIterator, (originalResult: ExecutionResult) => JSON.parse(JSON.stringify(originalResult))) + }); + } + return JSON.parse(JSON.stringify(result)); + } return (new ValueOrPromise(() => graphql( schema, print(document), @@ -698,33 +711,20 @@ function makeExecutorFromSchema(schema: GraphQLSchema) { }; } -function makeSubscriberFromSchema(schema: GraphQLSchema) { - return async ({ document, variables, context }: ExecutionParams) => { - const result = subscribe( - schema, - document, - null, - context, - variables, - ) as Promise> | ExecutionResult>; - if (isPromise(result)) { - return result.then(asyncIterator => - mapAsyncIterator(asyncIterator as AsyncIterator, (originalResult: ExecutionResult) => JSON.parse(JSON.stringify(originalResult)))); - } - return JSON.parse(JSON.stringify(result)); - }; +function assertAsyncIterable(input: unknown): asserts input is AsyncIterableIterator { + if (isAsyncIterable(input) === false) { + throw new Error("Expected AsyncIterable.") + } } export async function makeSchemaRemote( schema: GraphQLSchema, ): Promise { const executor = makeExecutorFromSchema(schema); - const subscriber = makeSubscriberFromSchema(schema); const clientSchema = await introspectSchema(executor); return { schema: clientSchema, executor, - subscriber, batch: true, }; } diff --git a/packages/stitch/tests/isolateComputedFieldsTransformer.test.ts b/packages/stitch/tests/isolateComputedFieldsTransformer.test.ts index 49a6c2fe489..d8c3a043c73 100644 --- a/packages/stitch/tests/isolateComputedFieldsTransformer.test.ts +++ b/packages/stitch/tests/isolateComputedFieldsTransformer.test.ts @@ -2,6 +2,7 @@ import { makeExecutableSchema } from '@graphql-tools/schema'; import { isolateComputedFieldsTransformer } from '@graphql-tools/stitch'; import { Subschema } from '@graphql-tools/delegate'; import { GraphQLObjectType, GraphQLInterfaceType } from 'graphql'; +import { assertSome } from '@graphql-tools/utils'; describe('isolateComputedFieldsTransformer', () => { describe('basic isolation', () => { @@ -73,13 +74,14 @@ describe('isolateComputedFieldsTransformer', () => { expect(Object.keys((computedSubschema.transformedSchema.getType('Storefront') as GraphQLObjectType).getFields()).length).toEqual(0); expect(computedSubschema.transformedSchema.getType('ProductRepresentation')).toBeDefined(); - expect(baseSubschema.merge.Product.canonical).toEqual(true); - expect(baseSubschema.merge.Product.fields).toEqual({ + assertSome(baseSubschema.merge) + expect(baseSubschema.merge['Product'].canonical).toEqual(true); + expect(baseSubschema.merge['Product'].fields).toEqual({ deliveryService: { canonical: true }, }); - - expect(computedSubschema.merge.Product.canonical).toBeUndefined(); - expect(computedSubschema.merge.Product.fields).toEqual({ + assertSome(computedSubschema.merge) + expect(computedSubschema.merge['Product'].canonical).toBeUndefined(); + expect(computedSubschema.merge['Product'].fields).toEqual({ shippingEstimate: { selectionSet: '{ price }', computed: true, canonical: true }, }); }); @@ -195,15 +197,17 @@ describe('isolateComputedFieldsTransformer', () => { expect(Object.keys((baseSubschema.transformedSchema.getType('Query') as GraphQLObjectType).getFields())).toEqual(['storefront', '_products']); expect(Object.keys((baseSubschema.transformedSchema.getType('Product') as GraphQLObjectType).getFields())).toEqual(['base']); expect(Object.keys((baseSubschema.transformedSchema.getType('Storefront') as GraphQLObjectType).getFields())).toEqual(['base']); - expect(baseSubschema.merge.Storefront.fields).toEqual({}); + assertSome(baseSubschema.merge) + expect(baseSubschema.merge['Storefront'].fields).toEqual({}); expect(Object.keys((computedSubschema.transformedSchema.getType('Query') as GraphQLObjectType).getFields())).toEqual(['storefront', '_products']); expect(Object.keys((computedSubschema.transformedSchema.getType('Product') as GraphQLObjectType).getFields())).toEqual(['computeMe']); expect(Object.keys((computedSubschema.transformedSchema.getType('Storefront') as GraphQLObjectType).getFields())).toEqual(['computeMe']); - expect(computedSubschema.merge.Storefront.fields).toEqual({ + assertSome(computedSubschema.merge) + expect(computedSubschema.merge['Storefront'].fields).toEqual({ computeMe: { selectionSet: '{ availableProductIds }', computed: true }, }); - expect(computedSubschema.merge.Product.fields).toEqual({ + expect(computedSubschema.merge['Product'].fields).toEqual({ computeMe: { selectionSet: '{ price }', computed: true }, }); }); diff --git a/packages/stitch/tests/mergeAbstractTypes.test.ts b/packages/stitch/tests/mergeAbstractTypes.test.ts index 8f435e73192..a8f25bd8365 100644 --- a/packages/stitch/tests/mergeAbstractTypes.test.ts +++ b/packages/stitch/tests/mergeAbstractTypes.test.ts @@ -1,6 +1,7 @@ import { makeExecutableSchema } from '@graphql-tools/schema'; import { stitchSchemas } from '@graphql-tools/stitch'; import { graphql } from 'graphql'; +import { assertSome } from '@graphql-tools/utils'; describe('Abstract type merge', () => { it('merges with abstract type definitions', async () => { @@ -84,8 +85,8 @@ describe('Abstract type merge', () => { } } `); - - expect(data.post.leadArt).toEqual({ + assertSome(data) + expect(data['post'].leadArt).toEqual({ __typename: 'Image', url: '/path/to/23', id: '23', @@ -183,7 +184,8 @@ describe('Merged associations', () => { } `); - expect(data.slots).toEqual([{ + assertSome(data) + expect(data['slots']).toEqual([{ id: '55', network: { domain: 'network56.com' } }]); diff --git a/packages/stitch/tests/mergeComputedFields.test.ts b/packages/stitch/tests/mergeComputedFields.test.ts index 635c64a78df..c63c718b97d 100644 --- a/packages/stitch/tests/mergeComputedFields.test.ts +++ b/packages/stitch/tests/mergeComputedFields.test.ts @@ -1,6 +1,7 @@ import { makeExecutableSchema } from '@graphql-tools/schema'; import { stitchSchemas } from '@graphql-tools/stitch'; import { graphql } from 'graphql'; +import { assertSome } from '@graphql-tools/utils'; const productSchema = makeExecutableSchema({ typeDefs: ` @@ -108,7 +109,8 @@ describe('merge computed fields via config', () => { } `); - expect(data.product).toEqual({ + assertSome(data) + expect(data['product']).toEqual({ id: '77', price: 77.99, weight: 77, @@ -132,7 +134,8 @@ describe('merge computed fields via config', () => { } `); - expect(data.storefront.availableProducts).toEqual([ + assertSome(data) + expect(data['storefront'].availableProducts).toEqual([ { id: '23', price: 23.99, @@ -184,7 +187,8 @@ describe('merge computed fields via config', () => { } `); - expect(data.product).toEqual({ + assertSome(data) + expect(data['product']).toEqual({ id: '77', price: 77.99, weight: 77, @@ -271,7 +275,8 @@ describe('merge computed fields via SDL (Apollo Federation-style directive annot } `); - expect(data.storefront.availableProducts).toEqual([ + assertSome(data) + expect(data['storefront'].availableProducts).toEqual([ { id: '23', price: 23.99, diff --git a/packages/stitch/tests/mergeConflicts.test.ts b/packages/stitch/tests/mergeConflicts.test.ts index d2be75e291a..99a83a549ba 100644 --- a/packages/stitch/tests/mergeConflicts.test.ts +++ b/packages/stitch/tests/mergeConflicts.test.ts @@ -1,5 +1,25 @@ import { makeExecutableSchema } from '@graphql-tools/schema'; import { stitchSchemas } from '@graphql-tools/stitch'; +import { GraphQLInputObjectType, GraphQLObjectType, GraphQLInterfaceType, } from 'graphql'; + +function assertGraphQLObjectType(input: unknown): asserts input is GraphQLObjectType { + if (input instanceof GraphQLObjectType) { + return + } + throw new Error("Expected GraphQLObjectType.") +} +function assertGraphQLInterfaceType(input: unknown): asserts input is GraphQLInterfaceType { + if (input instanceof GraphQLInterfaceType) { + return + } + throw new Error("Expected GraphQLInterfaceType.") +} +function assertGraphQLInputObjectType(input: unknown): asserts input is GraphQLInputObjectType { + if (input instanceof GraphQLInputObjectType) { + return + } + throw new Error("Expected GraphQLInputObjectType.") +} describe('merge conflict handlers', () => { const listings1Schema = makeExecutableSchema({ @@ -69,12 +89,17 @@ describe('merge conflict handlers', () => { } }, }); - - expect(gatewaySchema.getType('Listing').description).toEqual('A type'); - expect(gatewaySchema.getType('IListing').description).toEqual('An interface'); - expect(gatewaySchema.getType('ListingInput').description).toEqual('An input'); - expect(gatewaySchema.getType('Listing').getFields().id.description).toEqual('type identifier'); - expect(gatewaySchema.getType('IListing').getFields().id.description).toEqual('interface identifier'); - expect(gatewaySchema.getType('ListingInput').getFields().id.description).toEqual('input identifier'); + const Listing = gatewaySchema.getType('Listing') + assertGraphQLObjectType(Listing) + const IListing = gatewaySchema.getType('IListing') + assertGraphQLInterfaceType(IListing) + const ListingInput = gatewaySchema.getType('ListingInput') + assertGraphQLInputObjectType(ListingInput) + expect(Listing.description).toEqual('A type'); + expect(IListing.description).toEqual('An interface'); + expect(ListingInput.description).toEqual('An input'); + expect(Listing.getFields()['id'].description).toEqual('type identifier'); + expect(IListing.getFields()['id'].description).toEqual('interface identifier'); + expect(ListingInput.getFields()['id'].description).toEqual('input identifier'); }); }); diff --git a/packages/stitch/tests/mergeDefinitions.test.ts b/packages/stitch/tests/mergeDefinitions.test.ts index cd70fc06da1..17af8555698 100644 --- a/packages/stitch/tests/mergeDefinitions.test.ts +++ b/packages/stitch/tests/mergeDefinitions.test.ts @@ -4,13 +4,9 @@ import { getDirectives } from '@graphql-tools/utils'; import { stitchingDirectives } from '@graphql-tools/stitching-directives'; import { GraphQLObjectType, - GraphQLInterfaceType, - GraphQLInputObjectType, - GraphQLEnumType, - GraphQLUnionType, - GraphQLScalarType, - graphql + graphql, } from 'graphql'; +import { assertGraphQLEnumType, assertGraphQLInputObjectType, assertGraphQLInterfaceType, assertGraphQLObjectType, assertGraphQLScalerType, assertGraphQLUnionType } from '../../testing/assertion'; describe('merge canonical types', () => { const firstSchema = makeExecutableSchema({ @@ -235,74 +231,86 @@ describe('merge canonical types', () => { }); it('merges prioritized descriptions', () => { - expect(gatewaySchema.getQueryType().description).toEqual('first'); - expect(gatewaySchema.getType('Product').description).toEqual('first'); - expect(gatewaySchema.getType('IProduct').description).toEqual('first'); - expect(gatewaySchema.getType('ProductInput').description).toEqual('first'); - expect(gatewaySchema.getType('ProductEnum').description).toEqual('first'); - expect(gatewaySchema.getType('ProductUnion').description).toEqual('first'); - expect(gatewaySchema.getType('ProductScalar').description).toEqual('first'); + expect(gatewaySchema.getQueryType()?.description).toEqual('first'); + expect(gatewaySchema.getType('Product')?.description).toEqual('first'); + expect(gatewaySchema.getType('IProduct')?.description).toEqual('first'); + expect(gatewaySchema.getType('ProductInput')?.description).toEqual('first'); + expect(gatewaySchema.getType('ProductEnum')?.description).toEqual('first'); + expect(gatewaySchema.getType('ProductUnion')?.description).toEqual('first'); + expect(gatewaySchema.getType('ProductScalar')?.description).toEqual('first'); const queryType = gatewaySchema.getQueryType(); - const objectType = gatewaySchema.getType('Product') as GraphQLObjectType; - const interfaceType = gatewaySchema.getType('IProduct') as GraphQLInterfaceType; - const inputType = gatewaySchema.getType('ProductInput') as GraphQLInputObjectType; - const enumType = gatewaySchema.getType('ProductEnum') as GraphQLEnumType; - - expect(queryType.getFields().field1.description).toEqual('first'); - expect(queryType.getFields().field2.description).toEqual('second'); - - expect(objectType.getFields().id.description).toEqual('first'); - expect(interfaceType.getFields().id.description).toEqual('first'); - expect(inputType.getFields().id.description).toEqual('first'); - - expect(objectType.getFields().url.description).toEqual('second'); - expect(interfaceType.getFields().url.description).toEqual('second'); - expect(inputType.getFields().url.description).toEqual('second'); - - expect(enumType.toConfig().values.YES.description).toEqual('first'); - expect(enumType.toConfig().values.NO.description).toEqual('first'); - expect(enumType.toConfig().values.MAYBE.description).toEqual('second'); + assertGraphQLObjectType(queryType) + const objectType = gatewaySchema.getType('Product') + assertGraphQLObjectType(objectType) + const interfaceType = gatewaySchema.getType('IProduct') + assertGraphQLInterfaceType(interfaceType) + const inputType = gatewaySchema.getType('ProductInput'); + assertGraphQLInputObjectType(inputType) + const enumType = gatewaySchema.getType('ProductEnum'); + assertGraphQLEnumType(enumType) + + expect(queryType.getFields()['field1'].description).toEqual('first'); + expect(queryType.getFields()['field2'].description).toEqual('second'); + + expect(objectType.getFields()['id'].description).toEqual('first'); + expect(interfaceType.getFields()['id'].description).toEqual('first'); + expect(inputType.getFields()['id'].description).toEqual('first'); + + expect(objectType.getFields()['url'].description).toEqual('second'); + expect(interfaceType.getFields()['url'].description).toEqual('second'); + expect(inputType.getFields()['url'].description).toEqual('second'); + + expect(enumType.toConfig().values['YES'].description).toEqual('first'); + expect(enumType.toConfig().values['NO'].description).toEqual('first'); + expect(enumType.toConfig().values['MAYBE'].description).toEqual('second'); }); it('merges prioritized ASTs', () => { const queryType = gatewaySchema.getQueryType(); - const objectType = gatewaySchema.getType('Product') as GraphQLObjectType; - const interfaceType = gatewaySchema.getType('IProduct') as GraphQLInterfaceType; - const inputType = gatewaySchema.getType('ProductInput') as GraphQLInputObjectType; - const enumType = gatewaySchema.getType('ProductEnum') as GraphQLEnumType; - const unionType = gatewaySchema.getType('ProductUnion') as GraphQLUnionType; - const scalarType = gatewaySchema.getType('ProductScalar') as GraphQLScalarType; - - expect(getDirectives(firstSchema, queryType.toConfig()).mydir.value).toEqual('first'); - expect(getDirectives(firstSchema, objectType.toConfig()).mydir.value).toEqual('first'); - expect(getDirectives(firstSchema, interfaceType.toConfig()).mydir.value).toEqual('first'); - expect(getDirectives(firstSchema, inputType.toConfig()).mydir.value).toEqual('first'); - expect(getDirectives(firstSchema, enumType.toConfig()).mydir.value).toEqual('first'); - expect(getDirectives(firstSchema, unionType.toConfig()).mydir.value).toEqual('first'); - expect(getDirectives(firstSchema, scalarType.toConfig()).mydir.value).toEqual('first'); - - expect(getDirectives(firstSchema, queryType.getFields().field1).mydir.value).toEqual('first'); - expect(getDirectives(firstSchema, queryType.getFields().field2).mydir.value).toEqual('second'); - expect(getDirectives(firstSchema, objectType.getFields().id).mydir.value).toEqual('first'); - expect(getDirectives(firstSchema, objectType.getFields().url).mydir.value).toEqual('second'); - expect(getDirectives(firstSchema, interfaceType.getFields().id).mydir.value).toEqual('first'); - expect(getDirectives(firstSchema, interfaceType.getFields().url).mydir.value).toEqual('second'); - expect(getDirectives(firstSchema, inputType.getFields().id).mydir.value).toEqual('first'); - expect(getDirectives(firstSchema, inputType.getFields().url).mydir.value).toEqual('second'); - - expect(enumType.toConfig().astNode.values.map(v => v.description.value)).toEqual(['first', 'first', 'second']); - expect(enumType.toConfig().values.YES.astNode.description.value).toEqual('first'); - expect(enumType.toConfig().values.NO.astNode.description.value).toEqual('first'); - expect(enumType.toConfig().values.MAYBE.astNode.description.value).toEqual('second'); + assertGraphQLObjectType(queryType) + const objectType = gatewaySchema.getType('Product'); + assertGraphQLObjectType(objectType) + const interfaceType = gatewaySchema.getType('IProduct') + assertGraphQLInterfaceType(interfaceType) + const inputType = gatewaySchema.getType('ProductInput'); + assertGraphQLInputObjectType(inputType) + const enumType = gatewaySchema.getType('ProductEnum'); + assertGraphQLEnumType(enumType) + const unionType = gatewaySchema.getType('ProductUnion'); + assertGraphQLUnionType(unionType) + const scalarType = gatewaySchema.getType('ProductScalar'); + assertGraphQLScalerType(scalarType) + + expect(getDirectives(firstSchema, queryType.toConfig())['mydir'].value).toEqual('first'); + expect(getDirectives(firstSchema, objectType.toConfig())['mydir'].value).toEqual('first'); + expect(getDirectives(firstSchema, interfaceType.toConfig())['mydir'].value).toEqual('first'); + expect(getDirectives(firstSchema, inputType.toConfig())['mydir'].value).toEqual('first'); + expect(getDirectives(firstSchema, enumType.toConfig())['mydir'].value).toEqual('first'); + expect(getDirectives(firstSchema, unionType.toConfig())['mydir'].value).toEqual('first'); + expect(getDirectives(firstSchema, scalarType.toConfig())['mydir'].value).toEqual('first'); + + expect(getDirectives(firstSchema, queryType.getFields()['field1'])['mydir'].value).toEqual('first'); + expect(getDirectives(firstSchema, queryType.getFields()['field2'])['mydir'].value).toEqual('second'); + expect(getDirectives(firstSchema, objectType.getFields()['id'])['mydir'].value).toEqual('first'); + expect(getDirectives(firstSchema, objectType.getFields()['url'])['mydir'].value).toEqual('second'); + expect(getDirectives(firstSchema, interfaceType.getFields()['id'])['mydir'].value).toEqual('first'); + expect(getDirectives(firstSchema, interfaceType.getFields()['url'])['mydir'].value).toEqual('second'); + expect(getDirectives(firstSchema, inputType.getFields()['id'])['mydir'].value).toEqual('first'); + expect(getDirectives(firstSchema, inputType.getFields()['url'])['mydir'].value).toEqual('second'); + + expect(enumType.toConfig().astNode?.values?.map(v => v.description?.value)).toEqual(['first', 'first', 'second']); + expect(enumType.toConfig().values['YES'].astNode?.description?.value).toEqual('first'); + expect(enumType.toConfig().values['NO'].astNode?.description?.value).toEqual('first'); + expect(enumType.toConfig().values['MAYBE'].astNode?.description?.value).toEqual('second'); }); it('merges prioritized deprecations', () => { const objectType = gatewaySchema.getType('Product') as GraphQLObjectType; - expect(objectType.getFields().id.deprecationReason).toEqual('first'); - expect(objectType.getFields().url.deprecationReason).toEqual('second'); - expect(getDirectives(firstSchema, objectType.getFields().id).deprecated.reason).toEqual('first'); - expect(getDirectives(firstSchema, objectType.getFields().url).deprecated.reason).toEqual('second'); + expect(objectType.getFields()['id'].deprecationReason).toEqual('first'); + expect(objectType.getFields()['url'].deprecationReason).toEqual('second'); + expect(getDirectives(firstSchema, objectType.getFields()['id'])['deprecated'].reason).toEqual('first'); + expect(getDirectives(firstSchema, objectType.getFields()['url'])['deprecated'].reason).toEqual('second'); }); it('promotes canonical root field definitions', async () => { @@ -377,15 +385,20 @@ describe('merge @canonical directives', () => { }); it('merges with directive', async () => { - const objectType = gatewaySchema.getType('Product') as GraphQLObjectType; - const inputType = gatewaySchema.getType('ProductInput') as GraphQLInputObjectType; - const enumType = gatewaySchema.getType('ProductEnum') as GraphQLEnumType; + const objectType = gatewaySchema.getType('Product') ; + assertGraphQLObjectType(objectType) + const inputType = gatewaySchema.getType('ProductInput'); + assertGraphQLInputObjectType(inputType) + const enumType = gatewaySchema.getType('ProductEnum'); + assertGraphQLEnumType(enumType) + const queryType = gatewaySchema.getQueryType() + assertGraphQLObjectType(queryType) expect(objectType.description).toEqual('first'); expect(inputType.description).toEqual('first'); expect(enumType.description).toEqual('first'); - expect(gatewaySchema.getQueryType().getFields().product.description).toEqual('first'); - expect(objectType.getFields().id.description).toEqual('first'); - expect(objectType.getFields().name.description).toEqual('second'); - expect(inputType.getFields().value.description).toEqual('second'); + expect(queryType.getFields()['product'].description).toEqual('first'); + expect(objectType.getFields()['id'].description).toEqual('first'); + expect(objectType.getFields()['name'].description).toEqual('second'); + expect(inputType.getFields()['value'].description).toEqual('second'); }); }); diff --git a/packages/stitch/tests/mergeFailures.test.ts b/packages/stitch/tests/mergeFailures.test.ts index 6deadd9c147..d7a1055d309 100644 --- a/packages/stitch/tests/mergeFailures.test.ts +++ b/packages/stitch/tests/mergeFailures.test.ts @@ -1,6 +1,6 @@ import { makeExecutableSchema } from '@graphql-tools/schema'; import { stitchSchemas } from '@graphql-tools/stitch'; -import { ExecutionResult } from '@graphql-tools/utils'; +import { assertSome, ExecutionResult } from '@graphql-tools/utils'; import { graphql, GraphQLError, GraphQLSchema } from 'graphql'; describe('merge failures', () => { @@ -139,6 +139,7 @@ describe('merge failures', () => { }); const stitchedResult = await graphql(stitchedSchema, '{ parent { thing { name desc id } } }'); + assertSome(stitchedResult.errors) expect(stitchedResult.errors[0].path).toEqual(['parent', 'thing', 'name']); }); diff --git a/packages/stitch/tests/mergeInterfaces.test.ts b/packages/stitch/tests/mergeInterfaces.test.ts index e8587630a7f..5555c525c51 100644 --- a/packages/stitch/tests/mergeInterfaces.test.ts +++ b/packages/stitch/tests/mergeInterfaces.test.ts @@ -1,6 +1,7 @@ import { graphql } from 'graphql'; import { makeExecutableSchema } from '@graphql-tools/schema'; import { stitchSchemas } from '../src/stitchSchemas'; +import { assertSome } from '@graphql-tools/utils'; describe('merged interfaces via concrete type', () => { const namedItemSchema = makeExecutableSchema({ @@ -77,7 +78,8 @@ describe('merged interfaces via concrete type', () => { } `); - expect(result.data.placement).toEqual({ id: '23', index: 23, name: 'Item 23' }); + assertSome(result.data) + expect(result.data['placement']).toEqual({ id: '23', index: 23, name: 'Item 23' }); }); test('works without selection set key', async () => { @@ -90,7 +92,8 @@ describe('merged interfaces via concrete type', () => { } `); - expect(result.data.placement).toEqual({ index: 23, name: 'Item 23' }); + assertSome(result.data) + expect(result.data['placement']).toEqual({ index: 23, name: 'Item 23' }); }); }); @@ -169,7 +172,9 @@ describe('merged interfaces via abstract type', () => { } `); - expect(result.data.placement).toEqual({ id: '23', index: 23, name: 'Item 23' }); + + assertSome(result.data) + expect(result.data['placement']).toEqual({ id: '23', index: 23, name: 'Item 23' }); }); test('works without selection set key', async () => { @@ -181,7 +186,7 @@ describe('merged interfaces via abstract type', () => { } } `); - - expect(result.data.placement).toEqual({ index: 23, name: 'Item 23' }); + assertSome(result.data) + expect(result.data['placement']).toEqual({ index: 23, name: 'Item 23' }); }); }); diff --git a/packages/stitch/tests/mergeMultipleEntryPoints.test.ts b/packages/stitch/tests/mergeMultipleEntryPoints.test.ts index 6711adaf2d8..b57e3e0dc98 100644 --- a/packages/stitch/tests/mergeMultipleEntryPoints.test.ts +++ b/packages/stitch/tests/mergeMultipleEntryPoints.test.ts @@ -1,5 +1,6 @@ import { graphql } from 'graphql'; import { makeExecutableSchema } from '@graphql-tools/schema'; +import { assertSome } from '@graphql-tools/utils'; import { stitchSchemas } from '../src/stitchSchemas'; describe('merge on multiple keys', () => { @@ -124,8 +125,8 @@ describe('merge on multiple keys', () => { } } `); - - expect(data.productsByKey).toEqual(result); + assertSome(data) + expect(data['productsByKey']).toEqual(result); }); test('works from upc -> join -> id', async () => { @@ -140,8 +141,8 @@ describe('merge on multiple keys', () => { } } `); - - expect(data.productsByUpc).toEqual(result); + assertSome(data) + expect(data['productsByUpc']).toEqual(result); }); test('works from id -> join -> upc', async () => { @@ -156,7 +157,7 @@ describe('merge on multiple keys', () => { } } `); - - expect(data.productsById).toEqual(result); + assertSome(data) + expect(data['productsById']).toEqual(result); }); }); diff --git a/packages/stitch/tests/mergeResolvers.test.ts b/packages/stitch/tests/mergeResolvers.test.ts index 6de2c84ec0f..c5d7e50e99b 100644 --- a/packages/stitch/tests/mergeResolvers.test.ts +++ b/packages/stitch/tests/mergeResolvers.test.ts @@ -2,6 +2,7 @@ import { makeExecutableSchema } from '@graphql-tools/schema'; import { stitchSchemas, createMergedTypeResolver } from '@graphql-tools/stitch'; import { MergedTypeResolver, MergedTypeResolverOptions } from '@graphql-tools/delegate'; import { graphql } from 'graphql'; +import { assertSome } from '@graphql-tools/utils'; describe('Merge resolvers', () => { const firstSchema = makeExecutableSchema({ @@ -91,6 +92,7 @@ describe('Merge resolvers', () => { it('works with wrapped resolvers', async () => { function wrapResolve(mergedTypeResolverOptions: MergedTypeResolverOptions): MergedTypeResolver { const defaultResolve = createMergedTypeResolver(mergedTypeResolverOptions); + assertSome(defaultResolve) return async (obj, ctx, inf, sch, sel, key) => { const result = await defaultResolve(obj, ctx, inf, sch, sel, key); result.source += '->resolve'; diff --git a/packages/stitch/tests/selectionSetArgs.test.ts b/packages/stitch/tests/selectionSetArgs.test.ts index 0397a21c0dc..69c70b92ee5 100644 --- a/packages/stitch/tests/selectionSetArgs.test.ts +++ b/packages/stitch/tests/selectionSetArgs.test.ts @@ -1,19 +1,36 @@ -import { parseSelectionSet } from '@graphql-tools/utils'; +import { assertSome, parseSelectionSet } from '@graphql-tools/utils'; +import { FieldNode, SelectionNode, IntValueNode, ValueNode, } from 'graphql'; import { forwardArgsToSelectionSet } from '../src'; -describe('forwardArgsToSelectionSet', () => { +function assertIntValueNode(input: ValueNode): asserts input is IntValueNode { + if (input.kind !== "IntValue"){ + throw new Error(`Expected "StringValue", got "${input.kind}".`) + } +} + +function assertFieldNode(input: SelectionNode): asserts input is FieldNode { + if (input.kind !== "Field"){ + throw new Error(`Expected "SelectionNode", got "${input.kind}".`) + } +} +describe('forwardArgsToSelectionSet', () => { + // TODO: assert this const GATEWAY_FIELD = parseSelectionSet('{ posts(pageNumber: 1, perPage: 7) }').selections[0]; + assertFieldNode(GATEWAY_FIELD) test('passes all arguments to a hint selection set', () => { const buildSelectionSet = forwardArgsToSelectionSet('{ postIds }'); const result = buildSelectionSet(GATEWAY_FIELD).selections[0]; - + assertFieldNode(result) expect(result.name.value).toEqual('postIds'); + assertSome(result.arguments) expect(result.arguments.length).toEqual(2); expect(result.arguments[0].name.value).toEqual('pageNumber'); + assertIntValueNode(result.arguments[0].value) expect(result.arguments[0].value.value).toEqual('1'); expect(result.arguments[1].name.value).toEqual('perPage'); + assertIntValueNode(result.arguments[1].value) expect(result.arguments[1].value.value).toEqual('7'); }); @@ -22,12 +39,16 @@ describe('forwardArgsToSelectionSet', () => { const result = buildSelectionSet(GATEWAY_FIELD); expect(result.selections.length).toEqual(2); + assertFieldNode(result.selections[0]) expect(result.selections[0].name.value).toEqual('id'); + assertSome(result.selections[0].arguments) expect(result.selections[0].arguments.length).toEqual(0); - + assertFieldNode(result.selections[1]) expect(result.selections[1].name.value).toEqual('postIds'); + assertSome(result.selections[1].arguments) expect(result.selections[1].arguments.length).toEqual(1); expect(result.selections[1].arguments[0].name.value).toEqual('pageNumber'); + assertIntValueNode(result.selections[1].arguments[0].value) expect(result.selections[1].arguments[0].value.value).toEqual('1'); }); }); diff --git a/packages/stitch/tests/selectionSets.test.ts b/packages/stitch/tests/selectionSets.test.ts index 45962680a32..efa300c5974 100644 --- a/packages/stitch/tests/selectionSets.test.ts +++ b/packages/stitch/tests/selectionSets.test.ts @@ -3,7 +3,7 @@ import { graphql } from 'graphql'; import { delegateToSchema } from '@graphql-tools/delegate'; import { batchDelegateToSchema } from '@graphql-tools/batch-delegate'; import { makeExecutableSchema } from '@graphql-tools/schema'; -import { IResolvers } from '@graphql-tools/utils'; +import { assertSome, IResolvers } from '@graphql-tools/utils'; import { stitchSchemas } from '../src/stitchSchemas'; @@ -20,7 +20,7 @@ describe('delegateToSchema ', () => { properties: Record, name: string, ): Property | undefined { - for (const key of Object.keys(properties)) { + for (const key in properties) { const property = properties[key]; if (property.location.name === name) { return property; @@ -61,7 +61,7 @@ describe('delegateToSchema ', () => { selectionSet: '{ name }', resolve: (location) => { const name = location.name; - return findPropertyByLocationName(sampleData.Property, name).location + return findPropertyByLocationName(sampleData.Property, name)?.location .coordinates; }, }, @@ -96,7 +96,7 @@ describe('delegateToSchema ', () => { bookingById: { property: { location: { - coordinates: sampleData.Property.p1.location.coordinates, + coordinates: sampleData.Property['p1'].location.coordinates, }, }, }, @@ -213,7 +213,8 @@ describe('delegateToSchema ', () => { `, ); - expect(data.posts).toEqual(expectedData); + assertSome(data) + expect(data['posts']).toEqual(expectedData); }); it('should resolve with a fragment', async () => { @@ -237,8 +238,8 @@ describe('delegateToSchema ', () => { } `, ); - - expect(data.posts).toEqual(expectedData); + assertSome(data) + expect(data['posts']).toEqual(expectedData); }); it('should resolve with deep fragment', async () => { @@ -262,8 +263,8 @@ describe('delegateToSchema ', () => { } `, ); - - expect(data.posts).toEqual(expectedData); + assertSome(data) + expect(data['posts']).toEqual(expectedData); }); it('should resolve with nested fragments', async () => { @@ -291,8 +292,8 @@ describe('delegateToSchema ', () => { } `, ) - - expect(data.posts).toEqual(expectedData); + assertSome(data) + expect(data['posts']).toEqual(expectedData); }); }); }); diff --git a/packages/stitch/tests/splitMergedTypeEntryPointsTransformer.test.ts b/packages/stitch/tests/splitMergedTypeEntryPointsTransformer.test.ts index e871178db9c..16f52ac6dba 100644 --- a/packages/stitch/tests/splitMergedTypeEntryPointsTransformer.test.ts +++ b/packages/stitch/tests/splitMergedTypeEntryPointsTransformer.test.ts @@ -1,5 +1,6 @@ import { makeExecutableSchema } from '@graphql-tools/schema'; import { splitMergedTypeEntryPointsTransformer } from '@graphql-tools/stitch'; +import { assertSome } from '@graphql-tools/utils'; const schema = makeExecutableSchema({ typeDefs: 'type Query { go:Int }' }); @@ -18,7 +19,8 @@ describe('splitMergedTypeEntryPointsTransformer', () => { }); expect(results.length).toEqual(1); - expect(results[0].merge.Product).toEqual({ + assertSome(results[0].merge) + expect(results[0].merge['Product']).toEqual({ selectionSet: '{ yep }', fieldName: 'yep', }); @@ -79,11 +81,13 @@ describe('splitMergedTypeEntryPointsTransformer', () => { }); expect(results.length).toEqual(2); - expect(results[0].merge.Product).toEqual({ + assertSome(results[0].merge) + expect(results[0].merge['Product']).toEqual({ selectionSet: '{ id }', fieldName: 'productById', }); - expect(results[1].merge.Product).toEqual({ + assertSome(results[1].merge) + expect(results[1].merge['Product']).toEqual({ selectionSet: '{ upc }', fieldName: 'productByUpc', }); diff --git a/packages/stitch/tests/stitchSchemas.test.ts b/packages/stitch/tests/stitchSchemas.test.ts index 9ca6140bdd0..91fec6016e9 100644 --- a/packages/stitch/tests/stitchSchemas.test.ts +++ b/packages/stitch/tests/stitchSchemas.test.ts @@ -1,12 +1,10 @@ import { graphql, GraphQLSchema, - GraphQLField, GraphQLObjectType, GraphQLScalarType, subscribe, parse, - defaultFieldResolver, findDeprecatedUsages, printSchema, GraphQLResolveInfo, @@ -18,9 +16,9 @@ import { stitchSchemas } from '../src/stitchSchemas'; import { cloneSchema, getResolversFromSchema, - SchemaDirectiveVisitor, IResolvers, ExecutionResult, + assertSome, } from '@graphql-tools/utils'; import { addMocksToSchema } from '@graphql-tools/mock'; @@ -327,7 +325,7 @@ const schemaDirectiveTypeDefs = ` } `; -testCombinations.forEach((combination) => { +for (const combination of testCombinations) { describe('merging ' + combination.name, () => { let stitchedSchema: GraphQLSchema; let propertySchema: GraphQLSchema | SubschemaConfig; @@ -355,20 +353,6 @@ testCombinations.forEach((combination) => { codeCoverageTypeDefs, schemaDirectiveTypeDefs, ], - schemaDirectives: { - upper: class extends SchemaDirectiveVisitor { - public visitFieldDefinition(field: GraphQLField) { - const { resolve = defaultFieldResolver } = field; - field.resolve = async function (...args) { - const result = await resolve.apply(this, args); - if (typeof result === 'string') { - return result.toUpperCase(); - } - return result; - }; - } - }, - }, mergeDirectives: true, resolvers: { Property: { @@ -2238,8 +2222,9 @@ fragment BookingFragment on Booking { expect(originalResult.errors).toBeUndefined(); expect(originalResult.data).toBeDefined(); - expect(originalResult.data.persona.transactions.items.length).toBe(2); - expect(originalResult.data.persona.transactions.items[1].debt).toBeDefined(); + assertSome(originalResult.data) + expect(originalResult.data['persona'].transactions.items.length).toBe(2); + expect(originalResult.data['persona'].transactions.items[1].debt).toBeDefined(); const mergedSchema = stitchSchemas({ subschemas: [remoteSchema], @@ -2337,8 +2322,9 @@ fragment BookingFragment on Booking { return ast; }, transformResult: (originalResult: ExecutionResult) => { - originalResult.data.persona = { - page: originalResult.data.persona.transactions.items, + assertSome(originalResult.data) + originalResult.data['persona'] = { + page: originalResult.data['persona'].transactions.items, }; return originalResult; }, @@ -2379,9 +2365,9 @@ fragment BookingFragment on Booking { }); expect(result.errors).toBeUndefined(); - expect(result.data).toBeDefined(); - expect(result.data.flattenedTransactions.page.length).toBe(2); - expect(result.data.flattenedTransactions.page[1].debt).toBeDefined(); + assertSome(result.data) + expect(result.data['flattenedTransactions'].page.length).toBe(2); + expect(result.data['flattenedTransactions'].page[1].debt).toBeDefined(); }); test('aliases', async () => { @@ -2558,6 +2544,8 @@ fragment BookingFragment on Booking { ...propertyResult.data, ...bookingResult.data, }); + assertSome(stitchedResult.errors) + assertSome(propertyResult.errors) expect(stitchedResult.errors.map(removeLocations)).toEqual( propertyResult.errors.map(removeLocations), ); @@ -2575,6 +2563,7 @@ fragment BookingFragment on Booking { ); expect(stitchedResult2.data).toBe(null); + assertSome(stitchedResult2.errors) expect(stitchedResult2.errors.map(removeLocations)).toEqual([ { message: 'Sample error non-null!', @@ -2627,6 +2616,7 @@ fragment BookingFragment on Booking { }, }); + assertSome(result.errors) const errorsWithoutLocations = result.errors.map(removeLocations); const expectedErrors: Array = [ @@ -2689,59 +2679,60 @@ fragment BookingFragment on Booking { const stitchedResult = await graphql(stitchedSchema, propertyQuery, undefined, {}); - [propertyResult, stitchedResult].forEach((result) => { - expect(result.errors).toBeDefined(); + for (const result of [propertyResult, stitchedResult]) { + assertSome(result.errors) expect(result.errors.length > 0).toBe(true); const error = result.errors[0]; - expect(error.extensions).toBeDefined(); - expect(error.extensions.code).toBe('SOME_CUSTOM_CODE'); - }); + assertSome(error.extensions) + expect(error.extensions['code']).toBe('SOME_CUSTOM_CODE'); + } }, ); }); describe('types in schema extensions', () => { test('should parse descriptions on new types', () => { - expect(stitchedSchema.getType('AnotherNewScalar').description).toBe( + expect(stitchedSchema.getType('AnotherNewScalar')?.description).toBe( 'Description of AnotherNewScalar.', ); - expect(stitchedSchema.getType('TestingScalar').description).toBe( + expect(stitchedSchema.getType('TestingScalar')?.description).toBe( 'A type that uses TestScalar.', ); - expect(stitchedSchema.getType('Color').description).toBe( + expect(stitchedSchema.getType('Color')?.description).toBe( 'A type that uses an Enum.', ); - expect(stitchedSchema.getType('NumericEnum').description).toBe( + expect(stitchedSchema.getType('NumericEnum')?.description).toBe( 'A type that uses an Enum with a numeric constant.', ); - expect(stitchedSchema.getType('LinkType').description).toBe( + expect(stitchedSchema.getType('LinkType')?.description).toBe( 'A new type linking the Property type.', ); - expect(stitchedSchema.getType('LinkType').description).toBe( + expect(stitchedSchema.getType('LinkType')?.description).toBe( 'A new type linking the Property type.', ); }); test('should parse descriptions on new fields', () => { const Query = stitchedSchema.getQueryType(); - expect(Query.getFields().linkTest.description).toBe( + assertSome(Query) + expect(Query.getFields()['linkTest'].description).toBe( 'A new field on the root query.', ); const Booking = stitchedSchema.getType('Booking') as GraphQLObjectType; - expect(Booking.getFields().property.description).toBe( + expect(Booking.getFields()['property'].description).toBe( 'The property of the booking.', ); const Property = stitchedSchema.getType( 'Property', ) as GraphQLObjectType; - const bookingsField = Property.getFields().bookings; + const bookingsField = Property.getFields()['bookings']; expect(bookingsField.description).toBe('A list of bookings.'); expect(bookingsField.args[0].description).toBe( 'The maximum number of bookings to retrieve.', @@ -3079,31 +3070,6 @@ fragment BookingFragment on Booking { }); }); - describe('schema directives', () => { - test('should work with schema directives', async () => { - const result = await graphql( - stitchedSchema, - ` - query { - propertyById(id: "p1") { - someField - } - } - `, - undefined, - {}, - ); - - expect(result).toEqual({ - data: { - propertyById: { - someField: 'SOMEFIELD', - }, - }, - }); - }); - }); - describe('regression', () => { test('should not pass extra arguments to delegates', async () => { const result = await graphql( @@ -3152,8 +3118,8 @@ fragment BookingFragment on Booking { }); const result = await graphql(schema, '{ book { cat: category } }'); - - expect(result.data.book.cat).toBe('Test'); +assertSome(result.data) + expect(result.data['book'].cat).toBe('Test'); }); }); @@ -3285,8 +3251,8 @@ fragment BookingFragment on Booking { }); const result = await graphql(schema, '{ book { cat: category } }'); - - expect(result.data.book.cat).toBe('Test'); +assertSome(result.data) + expect(result.data['book'].cat).toBe('Test'); }); }); @@ -3544,4 +3510,4 @@ fragment BookingFragment on Booking { }); }); }); -}); +} diff --git a/packages/stitch/tests/stitchingFromSubschemas.test.ts b/packages/stitch/tests/stitchingFromSubschemas.test.ts deleted file mode 100644 index e5a333d5e41..00000000000 --- a/packages/stitch/tests/stitchingFromSubschemas.test.ts +++ /dev/null @@ -1,146 +0,0 @@ -// The below is meant to be an alternative canonical schema stitching example -// which intermingles local (mocked) resolvers and stitched schemas and does -// not require use of the fragment field, because it follows best practices of -// always returning the necessary object fields: -// https://medium.com/paypal-engineering/graphql-resolvers-best-practices-cd36fdbcef55 - -// This is achieved at the considerable cost of moving all of the delegation -// logic from the gateway to each subschema so that each subschema imports all -// the required types and performs all delegation. - -// The fragment field is still necessary when working with a remote schema -// where this is not possible. - -import { graphql, GraphQLSchema } from 'graphql'; - -import { delegateToSchema } from '@graphql-tools/delegate'; -import { addMocksToSchema } from '@graphql-tools/mock'; - -import { stitchSchemas } from '../src/stitchSchemas'; - -const chirpTypeDefs = ` - type Chirp { - id: ID! - text: String - authorId: ID! - author: User - } -`; - -const authorTypeDefs = ` - type User { - id: ID! - email: String - chirps: [Chirp] - } -`; - -const schemas: Record = {}; -const getSchema = (name: string) => schemas[name]; - -let chirpSchema = stitchSchemas({ - typeDefs: [ - chirpTypeDefs, - authorTypeDefs, - ` - type Query { - chirpById(id: ID!): Chirp - chirpsByAuthorId(authorId: ID!): [Chirp] - } - `, - ], - resolvers: { - Chirp: { - author: (chirp, _args, context, info) => - delegateToSchema({ - schema: getSchema('authorSchema'), - operation: 'query', - fieldName: 'userById', - args: { - id: chirp.authorId, - }, - context, - info, - }), - }, - }, -}); - -chirpSchema = addMocksToSchema({ - schema: chirpSchema, - mocks: { - Chirp: () => ({ - authorId: '1', - }), - }, - preserveResolvers: true, -}); - -let authorSchema = stitchSchemas({ - typeDefs: [ - chirpTypeDefs, - authorTypeDefs, - ` - type Query { - userById(id: ID!): User - } - `, - ], - resolvers: { - User: { - chirps: (user, _args, context, info) => - delegateToSchema({ - schema: getSchema('chirpSchema'), - operation: 'query', - fieldName: 'chirpsByAuthorId', - args: { - authorId: user.id, - }, - context, - info, - }), - }, - }, -}); - -authorSchema = addMocksToSchema({ - schema: authorSchema, - mocks: { - User: () => ({ - id: '1', - }), - }, - preserveResolvers: true, -}); - -schemas.chirpSchema = chirpSchema; -schemas.authorSchema = authorSchema; - -const stitchedSchema = stitchSchemas({ - subschemas:Object.keys(schemas).map((schemaName) => schemas[schemaName]), -}); - -describe('merging without specifying fragments', () => { - test.skip('works', async () => { - const query = ` - query { - userById(id: 5) { - chirps { - id - textAlias: text - author { - email - } - } - } - } - `; - - const result = await graphql(stitchedSchema, query); - - expect(result.errors).toBeUndefined(); - expect(result.data.userById.chirps[1].id).not.toBe(null); - expect(result.data.userById.chirps[1].text).not.toBe(null); - expect(result.data.userById.chirps[1].author.email).not.toBe(null); - }); -}); diff --git a/packages/stitch/tests/typeMerging.test.ts b/packages/stitch/tests/typeMerging.test.ts index 6946d8020ab..284c1f8b0c0 100644 --- a/packages/stitch/tests/typeMerging.test.ts +++ b/packages/stitch/tests/typeMerging.test.ts @@ -10,6 +10,8 @@ import { addMocksToSchema } from '@graphql-tools/mock'; import { delegateToSchema } from '@graphql-tools/delegate'; import { RenameRootFields, RenameTypes } from '@graphql-tools/wrap'; +import { assertSome } from '@graphql-tools/utils'; + import { stitchSchemas } from '../src/stitchSchemas'; @@ -107,10 +109,11 @@ describe('merging using type merging', () => { ); expect(result.errors).toBeUndefined(); - expect(result.data.userById.__typename).toBe('User'); - expect(result.data.userById.chirps[1].id).not.toBe(null); - expect(result.data.userById.chirps[1].text).not.toBe(null); - expect(result.data.userById.chirps[1].author.email).not.toBe(null); + assertSome(result.data) + expect(result.data['userById'].__typename).toBe('User'); + expect(result.data['userById'].chirps[1].id).not.toBe(null); + expect(result.data['userById'].chirps[1].text).not.toBe(null); + expect(result.data['userById'].chirps[1].author.email).not.toBe(null); }); test("handle top level failures on subschema queries", async() => { @@ -422,8 +425,8 @@ describe('Merged associations', () => { } } `); - - expect(data.posts).toEqual([{ + assertSome(data) + expect(data['posts']).toEqual([{ title: 'Post 55', network: { domain: 'network57.com' }, sections: ['News'] @@ -527,10 +530,11 @@ describe('merging using type merging when renaming', () => { ); expect(result.errors).toBeUndefined(); - expect(result.data.User_userById.__typename).toBe('Gateway_User'); - expect(result.data.User_userById.chirps[1].id).not.toBe(null); - expect(result.data.User_userById.chirps[1].text).not.toBe(null); - expect(result.data.User_userById.chirps[1].author.email).not.toBe(null); + assertSome(result.data) + expect(result.data['User_userById'].__typename).toBe('Gateway_User'); + expect(result.data['User_userById'].chirps[1].id).not.toBe(null); + expect(result.data['User_userById'].chirps[1].text).not.toBe(null); + expect(result.data['User_userById'].chirps[1].author.email).not.toBe(null); }); }); @@ -552,7 +556,7 @@ describe('external object annotation with batchDelegateToSchema', () => { resolvers: { Query: { networks: (_root, { ids }) => - ids.map((id) => ({ id, domains: [{ id: Number(id) + 3, name: `network${id}.com` }] })), + ids.map((id: unknown) => ({ id, domains: [{ id: Number(id) + 3, name: `network${id}.com` }] })), }, }, }) @@ -573,7 +577,7 @@ describe('external object annotation with batchDelegateToSchema', () => { resolvers: { Query: { posts: (_root, { ids }) => - ids.map((id) => ({ + ids.map((id: unknown) => ({ id, network: { id: Number(id) + 2 }, })), @@ -617,8 +621,8 @@ describe('external object annotation with batchDelegateToSchema', () => { } `, ) - - expect(data.posts).toEqual([ + assertSome(data) + expect(data['posts']).toEqual([ { network: { id: '57', domains: [{ id: '60', name: 'network57.com' }] }, }, diff --git a/packages/stitch/tests/typeMergingWithDirectives.test.ts b/packages/stitch/tests/typeMergingWithDirectives.test.ts index 389ef1d8246..de32835db5d 100644 --- a/packages/stitch/tests/typeMergingWithDirectives.test.ts +++ b/packages/stitch/tests/typeMergingWithDirectives.test.ts @@ -56,7 +56,7 @@ describe('merging using type merging with directives', () => { resolvers: { Query: { me: () => users[0], - _users: (_root, { keys }) => keys.map((key: Record) => users.find(u => u.id === key.id)), + _users: (_root, { keys }) => keys.map((key: Record) => users.find(u => u.id === key['id'])), }, }, schemaTransforms: [stitchingDirectivesValidator], @@ -122,7 +122,7 @@ describe('merging using type merging with directives', () => { Query: { mostStockedProduct: () => inventory.find(i => i.upc === '3'), _products: (_root, { keys }) => { - return keys.map((key: Record) => ({ ...key, ...inventory.find(i => i.upc === key.upc) })); + return keys.map((key: Record) => ({ ...key, ...inventory.find(i => i.upc === key['upc']) })); }, }, }, diff --git a/packages/stitch/tests/typeMergingWithExtensions.test.ts b/packages/stitch/tests/typeMergingWithExtensions.test.ts index e47b7247b3a..a84c33d130d 100644 --- a/packages/stitch/tests/typeMergingWithExtensions.test.ts +++ b/packages/stitch/tests/typeMergingWithExtensions.test.ts @@ -35,7 +35,7 @@ describe('merging using type merging', () => { accountsSchemaTypes._Key = new GraphQLScalarType({ name: '_Key', - }); + } as any); accountsSchemaTypes.Query = new GraphQLObjectType({ name: 'Query', fields: () => ({ @@ -50,7 +50,7 @@ describe('merging using type merging', () => { type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(accountsSchemaTypes._Key))) }, }, - resolve: (_root, { keys }) => keys.map((key: Record) => users.find(u => u.id === key.id)), + resolve: (_root, { keys }) => keys.map((key: Record) => users.find(u => u.id === key['id'])), extensions: { directives: { merge: {}, @@ -138,7 +138,7 @@ describe('merging using type merging', () => { keys: { type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(inventorySchemaTypes.ProductKey))) } }, resolve: (_root, { keys }) => { - return keys.map((key: Record) => ({ ...key, ...inventory.find(i => i.upc === key.upc) })); + return keys.map((key: Record) => ({ ...key, ...inventory.find(i => i.upc === key['upc']) })); }, extensions: { directives: { @@ -204,7 +204,7 @@ describe('merging using type merging', () => { defaultValue: 2, }, }, - resolve: (_root, args) => products.slice(0, args.first), + resolve: (_root, args) => products.slice(0, args['first']), }, _productsByUpc: { type: new GraphQLList(productsSchemaTypes.Product), diff --git a/packages/stitch/tests/typeMergingWithInterfaces.test.ts b/packages/stitch/tests/typeMergingWithInterfaces.test.ts index d575cd20dc5..5b0fa9511a2 100644 --- a/packages/stitch/tests/typeMergingWithInterfaces.test.ts +++ b/packages/stitch/tests/typeMergingWithInterfaces.test.ts @@ -58,7 +58,7 @@ describe('merging using type merging', () => { Query: { me: () => users[0], _entities: (_root, { keys }) => { - return keys.map((key: Record) => ({ ...key, ...users.find(u => u.id === key.id) })); + return keys.map((key: Record) => ({ ...key, ...users.find(u => u.id === key['id']) })); }, }, }, @@ -122,7 +122,7 @@ describe('merging using type merging', () => { Query: { mostStockedProduct: () => inventory.find(i => i.upc === '3'), _entities: (_root, { keys }) => { - return keys.map((key: Record) => ({ ...key, ...inventory.find(i => i.upc === key.upc) })); + return keys.map((key: Record) => ({ ...key, ...inventory.find(i => i.upc === key['upc']) })); }, }, }, @@ -187,7 +187,7 @@ describe('merging using type merging', () => { Query: { topProducts: (_root, args) => products.slice(0, args.first), _entities: (_root, { keys }) => { - return keys.map((key: Record) => ({ ...key, ...products.find(product => product.upc === key.upc) })); + return keys.map((key: Record) => ({ ...key, ...products.find(product => product.upc === key['upc']) })); } } }, @@ -281,8 +281,8 @@ describe('merging using type merging', () => { Query: { _entities: (_root, { keys }) => { return keys.map((key: Record) => { - if (key.__typename === 'Review') { - return ({ ...key, ...reviews.find(review => review.id === key.id) }); + if (key['__typename'] === 'Review') { + return ({ ...key, ...reviews.find(review => review.id === key['id']) }); } return { ...key }; diff --git a/packages/stitching-directives/package.json b/packages/stitching-directives/package.json index c926822c0ce..f97bec08764 100644 --- a/packages/stitching-directives/package.json +++ b/packages/stitching-directives/package.json @@ -34,7 +34,7 @@ "dependencies": { "@graphql-tools/delegate": "^7.1.5", "@graphql-tools/utils": "^7.2.4", - "tslib": "~2.2.0" + "tslib": "~2.3.0" }, "devDependencies": { "@graphql-tools/schema": "7.1.5" diff --git a/packages/stitching-directives/src/defaultStitchingDirectiveOptions.ts b/packages/stitching-directives/src/defaultStitchingDirectiveOptions.ts index 59dbe7376b2..4a36846226e 100644 --- a/packages/stitching-directives/src/defaultStitchingDirectiveOptions.ts +++ b/packages/stitching-directives/src/defaultStitchingDirectiveOptions.ts @@ -1,6 +1,6 @@ -import { StitchingDirectivesOptions } from './types'; +import { StitchingDirectivesFinalOptions } from './types'; -export const defaultStitchingDirectiveOptions: StitchingDirectivesOptions = { +export const defaultStitchingDirectiveOptions: StitchingDirectivesFinalOptions = { keyDirectiveName: 'key', computedDirectiveName: 'computed', canonicalDirectiveName: 'canonical', diff --git a/packages/stitching-directives/src/extractVariables.ts b/packages/stitching-directives/src/extractVariables.ts index 7a81ce64c3e..9da1fac8bf4 100644 --- a/packages/stitching-directives/src/extractVariables.ts +++ b/packages/stitching-directives/src/extractVariables.ts @@ -7,12 +7,12 @@ export function extractVariables(inputValue: ValueNode): { inputValue: ValueNode const variablePaths = Object.create(null); const keyPathVisitor = { - enter: (_node: any, key: string | number) => { + enter: (_node: any, key: string | number | undefined) => { if (typeof key === 'number') { path.push(key); } }, - leave: (_node: any, key: string | number) => { + leave: (_node: any, key: string | number | undefined) => { if (typeof key === 'number') { path.pop(); } @@ -29,7 +29,7 @@ export function extractVariables(inputValue: ValueNode): { inputValue: ValueNode }; const variableVisitor = { - enter: (node: VariableNode, key: string | number) => { + enter: (node: VariableNode, key: string | number | undefined) => { if (typeof key === 'number') { variablePaths[node.name.value] = path.concat([key]); } else { diff --git a/packages/stitching-directives/src/getSourcePaths.ts b/packages/stitching-directives/src/getSourcePaths.ts index b361130d959..c5dbf7b6f9d 100644 --- a/packages/stitching-directives/src/getSourcePaths.ts +++ b/packages/stitching-directives/src/getSourcePaths.ts @@ -9,22 +9,24 @@ export function getSourcePaths( selectionSet?: SelectionSetNode ): Array> { const sourcePaths: Array> = []; - mappingInstructions.forEach(mappingInstruction => { + for (const mappingInstruction of mappingInstructions) { const { sourcePath } = mappingInstruction; if (sourcePath.length) { sourcePaths.push(sourcePath); - return; + continue; } if (selectionSet == null) { - return; + continue; } const paths = pathsFromSelectionSet(selectionSet); - paths.forEach(path => sourcePaths.push(path)); + for (const path of paths) { + sourcePaths.push(path); + } sourcePaths.push([TypeNameMetaFieldDef.name]); - }); + } return sourcePaths; } diff --git a/packages/stitching-directives/src/parseMergeArgsExpr.ts b/packages/stitching-directives/src/parseMergeArgsExpr.ts index c3cfd73c3ab..ae1fcb23f27 100644 --- a/packages/stitching-directives/src/parseMergeArgsExpr.ts +++ b/packages/stitching-directives/src/parseMergeArgsExpr.ts @@ -9,10 +9,7 @@ import { getSourcePaths } from './getSourcePaths'; type VariablePaths = Record>; -export function parseMergeArgsExpr( - mergeArgsExpr: string, - selectionSet?: SelectionSetNode, -): ParsedMergeArgsExpr { +export function parseMergeArgsExpr(mergeArgsExpr: string, selectionSet?: SelectionSetNode): ParsedMergeArgsExpr { const { mergeArgsExpr: newMergeArgsExpr, expansionExpressions } = preparseMergeArgsExpr(mergeArgsExpr); const inputValue = parseValue(`{ ${newMergeArgsExpr} }`, { noLocation: true }); @@ -32,15 +29,15 @@ export function parseMergeArgsExpr( } const expansionRegEx = new RegExp(`^${EXPANSION_PREFIX}[0-9]+$`); - Object.keys(variablePaths).forEach(variableName => { + for (const variableName in variablePaths) { if (!variableName.match(expansionRegEx)) { throw new Error('Expansions cannot be mixed with single key declarations.'); } - }); + } const expansions: Array = []; const sourcePaths: Array> = []; - Object.keys(expansionExpressions).forEach(variableName => { + for (const variableName in expansionExpressions) { const str = expansionExpressions[variableName]; const valuePath = variablePaths[variableName]; const { inputValue: expansionInputValue, variablePaths: expansionVariablePaths } = extractVariables( @@ -57,12 +54,13 @@ export function parseMergeArgsExpr( sourcePaths.push(...getSourcePaths(mappingInstructions, selectionSet)); + assertNotWithinList(valuePath); expansions.push({ - valuePath: assertNotWithinList(valuePath), + valuePath, value, mappingInstructions, }); - }); + } const usedProperties = propertyTreeFromPaths(sourcePaths); @@ -71,23 +69,24 @@ export function parseMergeArgsExpr( function getMappingInstructions(variablePaths: VariablePaths): Array { const mappingInstructions: Array = []; - Object.entries(variablePaths).forEach(([keyPath, valuePath]) => { + for (const keyPath in variablePaths) { + const valuePath = variablePaths[keyPath]; const splitKeyPath = keyPath.split(KEY_DELIMITER).slice(1); + assertNotWithinList(valuePath); mappingInstructions.push({ - destinationPath: assertNotWithinList(valuePath), + destinationPath: valuePath, sourcePath: splitKeyPath, }); - }); + } return mappingInstructions; } -function assertNotWithinList(path: Array): Array { - path.forEach(pathSegment => { +function assertNotWithinList(path: Array): asserts path is string[] { + for (const pathSegment of path) { if (typeof pathSegment === 'number') { throw new Error('Insertions cannot be made into a list.'); } - }); - return path as Array; + } } diff --git a/packages/stitching-directives/src/pathsFromSelectionSet.ts b/packages/stitching-directives/src/pathsFromSelectionSet.ts index 0bd077cc698..9d452734e49 100644 --- a/packages/stitching-directives/src/pathsFromSelectionSet.ts +++ b/packages/stitching-directives/src/pathsFromSelectionSet.ts @@ -1,14 +1,17 @@ import { Kind, SelectionNode, SelectionSetNode } from 'graphql'; export function pathsFromSelectionSet(selectionSet: SelectionSetNode, path: Array = []): Array> { - let paths: Array> = []; - selectionSet.selections.forEach(selection => { - paths = paths.concat(pathsFromSelection(selection, path)); - }); + const paths: Array> = []; + for (const selection of selectionSet.selections) { + const additions = pathsFromSelection(selection, path) ?? []; + for (const addition of additions) { + paths.push(addition); + } + } return paths; } -function pathsFromSelection(selection: SelectionNode, path: Array): Array> { +function pathsFromSelection(selection: SelectionNode, path: Array): Array> | undefined { if (selection.kind === Kind.FIELD) { const responseKey = selection.alias?.value ?? selection.name.value; if (selection.selectionSet) { diff --git a/packages/stitching-directives/src/properties.ts b/packages/stitching-directives/src/properties.ts index 6c74dd3230c..deca3896bef 100644 --- a/packages/stitching-directives/src/properties.ts +++ b/packages/stitching-directives/src/properties.ts @@ -29,6 +29,9 @@ export function getProperty(object: Record, path: Array): a const newPath = path.slice(); const key = newPath.shift(); + if (key == null) { + return; + } const prop = object[key]; return getProperty(prop, newPath); @@ -41,25 +44,27 @@ export function getProperties(object: Record, propertyTree: Propert const newObject = Object.create(null); - Object.entries(propertyTree).forEach(([key, subKey]) => { + for (const key in propertyTree) { + const subKey = propertyTree[key]; + if (subKey == null) { newObject[key] = object[key]; - return; + continue; } const prop = object[key]; - newObject[key] = deepMap(prop, (item) => getProperties(item, subKey)); - }); + newObject[key] = deepMap(prop, item => getProperties(item, subKey)); + } return newObject; } export function propertyTreeFromPaths(paths: Array>): PropertyTree { const propertyTree = Object.create(null); - paths.forEach(path => { + for (const path of paths) { addProperty(propertyTree, path, null); - }); + } return propertyTree; } diff --git a/packages/stitching-directives/src/stitchingDirectives.ts b/packages/stitching-directives/src/stitchingDirectives.ts index 19f72d9586b..c460c562bf2 100644 --- a/packages/stitching-directives/src/stitchingDirectives.ts +++ b/packages/stitching-directives/src/stitchingDirectives.ts @@ -2,15 +2,13 @@ import { GraphQLDirective, GraphQLList, GraphQLNonNull, GraphQLSchema, GraphQLSt import { SubschemaConfig } from '@graphql-tools/delegate'; -import { StitchingDirectivesOptions } from './types'; +import { StitchingDirectivesFinalOptions, StitchingDirectivesOptions } from './types'; import { defaultStitchingDirectiveOptions } from './defaultStitchingDirectiveOptions'; import { stitchingDirectivesValidator } from './stitchingDirectivesValidator'; import { stitchingDirectivesTransformer } from './stitchingDirectivesTransformer'; -export function stitchingDirectives( - options: StitchingDirectivesOptions = {} -): { +export function stitchingDirectives(options: StitchingDirectivesOptions = {}): { keyDirectiveTypeDefs: string; computedDirectiveTypeDefs: string; mergeDirectiveTypeDefs: string; @@ -25,7 +23,7 @@ export function stitchingDirectives( canonicalDirective: GraphQLDirective; allStitchingDirectives: Array; } { - const finalOptions = { + const finalOptions: StitchingDirectivesFinalOptions = { ...defaultStitchingDirectiveOptions, ...options, }; diff --git a/packages/stitching-directives/src/stitchingDirectivesTransformer.ts b/packages/stitching-directives/src/stitchingDirectivesTransformer.ts index 68284c1cb11..27691311b2b 100644 --- a/packages/stitching-directives/src/stitchingDirectivesTransformer.ts +++ b/packages/stitching-directives/src/stitchingDirectivesTransformer.ts @@ -15,8 +15,9 @@ import { valueFromASTUntyped, } from 'graphql'; -import { cloneSubschemaConfig, SubschemaConfig } from '@graphql-tools/delegate'; +import { cloneSubschemaConfig, SubschemaConfig, MergedTypeConfig, MergedFieldConfig } from '@graphql-tools/delegate'; import { + assertSome, getDirectives, getImplementingTypes, MapperKind, @@ -52,9 +53,8 @@ export function stitchingDirectivesTransformer( const selectionSetsByType: Record = Object.create(null); const computedFieldSelectionSets: Record> = Object.create(null); const mergedTypesResolversInfo: Record = Object.create(null); - const canonicalTypesInfo: Record }> = Object.create( - null - ); + const canonicalTypesInfo: Record }> = + Object.create(null); const schema = subschemaConfig.schema; @@ -64,8 +64,9 @@ export function stitchingDirectivesTransformer( function setCanonicalDefinition(typeName: string, fieldName?: string): void { canonicalTypesInfo[typeName] = canonicalTypesInfo[typeName] || Object.create(null); if (fieldName) { - canonicalTypesInfo[typeName].fields = canonicalTypesInfo[typeName].fields || Object.create(null); - canonicalTypesInfo[typeName].fields[fieldName] = true; + const fields: Record = canonicalTypesInfo[typeName].fields ?? Object.create(null); + canonicalTypesInfo[typeName].fields = fields; + fields[fieldName] = true; } else { canonicalTypesInfo[typeName].canonical = true; } @@ -75,13 +76,13 @@ export function stitchingDirectivesTransformer( [MapperKind.OBJECT_TYPE]: type => { const directives = getDirectives(schema, type, pathToDirectivesInExtensions); - const keyDirective = directives[keyDirectiveName]; - if (keyDirective) { + if (keyDirectiveName != null && directives[keyDirectiveName] != null) { + const keyDirective = directives[keyDirectiveName]; const selectionSet = parseSelectionSet(keyDirective.selectionSet, { noLocation: true }); selectionSetsByType[type.name] = selectionSet; } - if (directives[canonicalDirectiveName]) { + if (canonicalDirectiveName != null && directives[canonicalDirectiveName]) { setCanonicalDefinition(type.name); } @@ -90,8 +91,8 @@ export function stitchingDirectivesTransformer( [MapperKind.OBJECT_FIELD]: (fieldConfig, fieldName, typeName) => { const directives = getDirectives(schema, fieldConfig, pathToDirectivesInExtensions); - const computedDirective = directives[computedDirectiveName]; - if (computedDirective) { + if (computedDirectiveName != null && directives[computedDirectiveName] != null) { + const computedDirective = directives[computedDirectiveName]; const selectionSet = parseSelectionSet(computedDirective.selectionSet, { noLocation: true }); if (!computedFieldSelectionSets[typeName]) { computedFieldSelectionSets[typeName] = Object.create(null); @@ -99,11 +100,15 @@ export function stitchingDirectivesTransformer( computedFieldSelectionSets[typeName][fieldName] = selectionSet; } - const mergeDirectiveKeyField = directives[mergeDirectiveName]?.keyField; - if (mergeDirectiveKeyField) { + if ( + mergeDirectiveName != null && + directives[mergeDirectiveName] != null && + directives[mergeDirectiveName].keyField + ) { + const mergeDirectiveKeyField = directives[mergeDirectiveName].keyField; const selectionSet = parseSelectionSet(`{ ${mergeDirectiveKeyField}}`, { noLocation: true }); - const typeNames: Array = directives[mergeDirectiveName]?.types; + const typeNames: Array = directives[mergeDirectiveName].types; const returnType = getNamedType(fieldConfig.type); @@ -117,7 +122,7 @@ export function stitchingDirectivesTransformer( }); } - if (directives[canonicalDirectiveName]) { + if (canonicalDirectiveName != null && directives[canonicalDirectiveName] != null) { setCanonicalDefinition(typeName, fieldName); } @@ -126,7 +131,7 @@ export function stitchingDirectivesTransformer( [MapperKind.INTERFACE_TYPE]: type => { const directives = getDirectives(schema, type, pathToDirectivesInExtensions); - if (directives[canonicalDirectiveName]) { + if (canonicalDirectiveName != null && directives[canonicalDirectiveName] != null) { setCanonicalDefinition(type.name); } @@ -135,7 +140,7 @@ export function stitchingDirectivesTransformer( [MapperKind.INTERFACE_FIELD]: (fieldConfig, fieldName, typeName) => { const directives = getDirectives(schema, fieldConfig, pathToDirectivesInExtensions); - if (directives[canonicalDirectiveName]) { + if (canonicalDirectiveName != null && directives[canonicalDirectiveName]) { setCanonicalDefinition(typeName, fieldName); } @@ -144,7 +149,7 @@ export function stitchingDirectivesTransformer( [MapperKind.INPUT_OBJECT_TYPE]: type => { const directives = getDirectives(schema, type, pathToDirectivesInExtensions); - if (directives[canonicalDirectiveName]) { + if (canonicalDirectiveName != null && directives[canonicalDirectiveName] != null) { setCanonicalDefinition(type.name); } @@ -153,7 +158,7 @@ export function stitchingDirectivesTransformer( [MapperKind.INPUT_OBJECT_FIELD]: (inputFieldConfig, fieldName, typeName) => { const directives = getDirectives(schema, inputFieldConfig, pathToDirectivesInExtensions); - if (directives[canonicalDirectiveName]) { + if (canonicalDirectiveName != null && directives[canonicalDirectiveName] != null) { setCanonicalDefinition(typeName, fieldName); } @@ -162,7 +167,7 @@ export function stitchingDirectivesTransformer( [MapperKind.UNION_TYPE]: type => { const directives = getDirectives(schema, type, pathToDirectivesInExtensions); - if (directives[canonicalDirectiveName]) { + if (canonicalDirectiveName != null && directives[canonicalDirectiveName] != null) { setCanonicalDefinition(type.name); } @@ -171,7 +176,7 @@ export function stitchingDirectivesTransformer( [MapperKind.ENUM_TYPE]: type => { const directives = getDirectives(schema, type, pathToDirectivesInExtensions); - if (directives[canonicalDirectiveName]) { + if (canonicalDirectiveName != null && directives[canonicalDirectiveName] != null) { setCanonicalDefinition(type.name); } @@ -180,7 +185,7 @@ export function stitchingDirectivesTransformer( [MapperKind.SCALAR_TYPE]: type => { const directives = getDirectives(schema, type, pathToDirectivesInExtensions); - if (directives[canonicalDirectiveName]) { + if (canonicalDirectiveName != null && directives[canonicalDirectiveName] != null) { setCanonicalDefinition(type.name); } @@ -189,7 +194,8 @@ export function stitchingDirectivesTransformer( }); if (subschemaConfig.merge) { - Object.entries(subschemaConfig.merge).forEach(([typeName, mergedTypeConfig]) => { + for (const typeName in subschemaConfig.merge) { + const mergedTypeConfig = subschemaConfig.merge[typeName]; if (mergedTypeConfig.selectionSet) { const selectionSet = parseSelectionSet(mergedTypeConfig.selectionSet, { noLocation: true }); if (selectionSet) { @@ -201,8 +207,9 @@ export function stitchingDirectivesTransformer( } } if (mergedTypeConfig.fields) { - Object.entries(mergedTypeConfig.fields).forEach(([fieldName, fieldConfig]) => { - if (!fieldConfig.selectionSet) return; + for (const fieldName in mergedTypeConfig.fields) { + const fieldConfig = mergedTypeConfig.fields[fieldName]; + if (!fieldConfig.selectionSet) continue; const selectionSet = parseSelectionSet(fieldConfig.selectionSet, { noLocation: true }); if (selectionSet) { @@ -218,36 +225,33 @@ export function stitchingDirectivesTransformer( computedFieldSelectionSets[typeName][fieldName] = selectionSet; } } - }); + } } - }); + } } const allSelectionSetsByType: Record> = Object.create(null); - Object.entries(selectionSetsByType).forEach(([typeName, selectionSet]) => { - if (allSelectionSetsByType[typeName] == null) { - allSelectionSetsByType[typeName] = [selectionSet]; - } else { + for (const typeName in selectionSetsByType) { + allSelectionSetsByType[typeName] = allSelectionSetsByType[typeName] || []; + const selectionSet = selectionSetsByType[typeName]; + allSelectionSetsByType[typeName].push(selectionSet); + } + + for (const typeName in computedFieldSelectionSets) { + const selectionSets = computedFieldSelectionSets[typeName]; + for (const i in selectionSets) { + allSelectionSetsByType[typeName] = allSelectionSetsByType[typeName] || []; + const selectionSet = selectionSets[i]; allSelectionSetsByType[typeName].push(selectionSet); } - }); - - Object.entries(computedFieldSelectionSets).forEach(([typeName, selectionSets]) => { - Object.values(selectionSets).forEach(selectionSet => { - if (allSelectionSetsByType[typeName] == null) { - allSelectionSetsByType[typeName] = [selectionSet]; - } else { - allSelectionSetsByType[typeName].push(selectionSet); - } - }); - }); + } mapSchema(schema, { [MapperKind.OBJECT_FIELD]: (fieldConfig, fieldName) => { const directives = getDirectives(schema, fieldConfig, pathToDirectivesInExtensions); - if (directives[mergeDirectiveName]) { + if (mergeDirectiveName != null && directives[mergeDirectiveName] != null) { const directiveArgumentMap = directives[mergeDirectiveName]; const returnType = getNullableType(fieldConfig.type); @@ -262,14 +266,14 @@ export function stitchingDirectivesTransformer( const keyExpr = key != null ? buildKeyExpr(key) : keyField != null ? `$key.${keyField}` : '$key'; const keyArg: string = directiveArgumentMap.keyArg; - const argNames = keyArg == null ? [Object.keys(fieldConfig.args)[0]] : keyArg.split('.'); + const argNames = keyArg == null ? [Object.keys(fieldConfig.args ?? {})[0]] : keyArg.split('.'); const lastArgName = argNames.pop(); mergeArgsExpr = returnsList ? `${lastArgName}: [[${keyExpr}]]` : `${lastArgName}: ${keyExpr}`; - argNames.reverse().forEach(argName => { + for (const argName of argNames.reverse()) { mergeArgsExpr = `${argName}: { ${mergeArgsExpr} }`; - }); + } } const typeNames: Array = directiveArgumentMap.types; @@ -277,7 +281,9 @@ export function stitchingDirectivesTransformer( forEachConcreteTypeName(namedType, schema, typeNames, typeName => { const parsedMergeArgsExpr = parseMergeArgsExpr( mergeArgsExpr, - allSelectionSetsByType[typeName] == null ? undefined : mergeSelectionSets(...allSelectionSetsByType[typeName]), + allSelectionSetsByType[typeName] == null + ? undefined + : mergeSelectionSets(...allSelectionSetsByType[typeName]) ); const additionalArgs = directiveArgumentMap.additionalArgs; @@ -300,49 +306,51 @@ export function stitchingDirectivesTransformer( }, }); - Object.entries(selectionSetsByType).forEach(([typeName, selectionSet]) => { - if (newSubschemaConfig.merge == null) { - newSubschemaConfig.merge = Object.create(null); - } + for (const typeName in selectionSetsByType) { + const selectionSet = selectionSetsByType[typeName]; + const mergeConfig: Record> = newSubschemaConfig.merge ?? + Object.create(null); + newSubschemaConfig.merge = mergeConfig; - if (newSubschemaConfig.merge[typeName] == null) { + if (mergeConfig[typeName] == null) { newSubschemaConfig.merge[typeName] = Object.create(null); } - const mergeTypeConfig = newSubschemaConfig.merge[typeName]; + const mergeTypeConfig = mergeConfig[typeName]; mergeTypeConfig.selectionSet = print(selectionSet); - }); + } - Object.entries(computedFieldSelectionSets).forEach(([typeName, selectionSets]) => { - if (newSubschemaConfig.merge == null) { - newSubschemaConfig.merge = Object.create(null); - } + for (const typeName in computedFieldSelectionSets) { + const selectionSets = computedFieldSelectionSets[typeName]; + const mergeConfig: Record> = newSubschemaConfig.merge ?? + Object.create(null); + newSubschemaConfig.merge = mergeConfig; - if (newSubschemaConfig.merge[typeName] == null) { - newSubschemaConfig.merge[typeName] = Object.create(null); + if (mergeConfig[typeName] == null) { + mergeConfig[typeName] = Object.create(null); } const mergeTypeConfig = newSubschemaConfig.merge[typeName]; + const mergeTypeConfigFields: Record = mergeTypeConfig.fields ?? Object.create(null); + mergeTypeConfig.fields = mergeTypeConfigFields; - if (mergeTypeConfig.fields == null) { - mergeTypeConfig.fields = Object.create(null); - } + for (const fieldName in selectionSets) { + const selectionSet = selectionSets[fieldName]; + const fieldConfig: MergedFieldConfig = mergeTypeConfigFields[fieldName] ?? Object.create(null); + mergeTypeConfigFields[fieldName] = fieldConfig; - Object.entries(selectionSets).forEach(([fieldName, selectionSet]) => { - if (mergeTypeConfig.fields[fieldName] == null) { - mergeTypeConfig.fields[fieldName] = Object.create(null); - } + fieldConfig.selectionSet = print(selectionSet); + fieldConfig.computed = true; + } + } - mergeTypeConfig.fields[fieldName].selectionSet = print(selectionSet); - mergeTypeConfig.fields[fieldName].computed = true; - }); - }); + for (const typeName in mergedTypesResolversInfo) { + const mergedTypeResolverInfo = mergedTypesResolversInfo[typeName]; - Object.entries(mergedTypesResolversInfo).forEach(([typeName, mergedTypeResolverInfo]) => { - if (newSubschemaConfig.merge == null) { - newSubschemaConfig.merge = Object.create(null); - } + const mergeConfig: Record> = newSubschemaConfig.merge ?? + Object.create(null); + newSubschemaConfig.merge = mergeConfig; if (newSubschemaConfig.merge[typeName] == null) { newSubschemaConfig.merge[typeName] = Object.create(null); @@ -358,12 +366,13 @@ export function stitchingDirectivesTransformer( } else { mergeTypeConfig.args = generateArgsFn(mergedTypeResolverInfo); } - }); + } - Object.entries(canonicalTypesInfo).forEach(([typeName, canonicalTypeInfo]) => { - if (newSubschemaConfig.merge == null) { - newSubschemaConfig.merge = Object.create(null); - } + for (const typeName in canonicalTypesInfo) { + const canonicalTypeInfo = canonicalTypesInfo[typeName]; + const mergeConfig: Record> = newSubschemaConfig.merge ?? + Object.create(null); + newSubschemaConfig.merge = mergeConfig; if (newSubschemaConfig.merge[typeName] == null) { newSubschemaConfig.merge[typeName] = Object.create(null); @@ -376,17 +385,16 @@ export function stitchingDirectivesTransformer( } if (canonicalTypeInfo.fields) { - if (mergeTypeConfig.fields == null) { - mergeTypeConfig.fields = Object.create(null); - } - Object.keys(canonicalTypeInfo.fields).forEach(fieldName => { - if (mergeTypeConfig.fields[fieldName] == null) { - mergeTypeConfig.fields[fieldName] = Object.create(null); + const mergeTypeConfigFields: Record = mergeTypeConfig.fields ?? Object.create(null); + mergeTypeConfig.fields = mergeTypeConfigFields; + for (const fieldName in canonicalTypeInfo.fields) { + if (mergeTypeConfigFields[fieldName] == null) { + mergeTypeConfigFields[fieldName] = Object.create(null); } - mergeTypeConfig.fields[fieldName].canonical = true; - }); + mergeTypeConfigFields[fieldName].canonical = true; + } } - }); + } return newSubschemaConfig; }; @@ -399,17 +407,17 @@ function forEachConcreteType( fn: (typeName: string) => void ) { if (isInterfaceType(type)) { - getImplementingTypes(type.name, schema).forEach(typeName => { + for (const typeName of getImplementingTypes(type.name, schema)) { if (typeNames == null || typeNames.includes(typeName)) { fn(typeName); } - }); + } } else if (isUnionType(type)) { - type.getTypes().forEach(({ name: typeName }) => { + for (const { name: typeName } of type.getTypes()) { if (typeNames == null || typeNames.includes(typeName)) { fn(typeName); } - }); + } } else if (isObjectType(type)) { fn(type.name); } @@ -421,27 +429,28 @@ function generateKeyFn(mergedTypeResolverInfo: MergedTypeResolverInfo): (origina function generateArgsFromKeysFn( mergedTypeResolverInfo: MergedTypeResolverInfo -): (keys: Array) => Record { +): (keys: ReadonlyArray) => Record { const { expansions, args } = mergedTypeResolverInfo; - return (keys: Array): Record => { + return (keys: ReadonlyArray): Record => { const newArgs = mergeDeep({}, args); - expansions.forEach(expansion => { - const mappingInstructions = expansion.mappingInstructions; - const expanded: Array = []; - keys.forEach(key => { - let newValue = mergeDeep({}, expansion.valuePath); - mappingInstructions.forEach(mappingInstruction => { - const { destinationPath, sourcePath } = mappingInstruction; - if (destinationPath.length) { - addProperty(newValue, destinationPath, getProperty(key, sourcePath)); - } else { - newValue = getProperty(key, sourcePath); + if (expansions) { + for (const expansion of expansions) { + const mappingInstructions = expansion.mappingInstructions; + const expanded: Array = []; + for (const key of keys) { + let newValue = mergeDeep({}, expansion.valuePath); + for (const { destinationPath, sourcePath } of mappingInstructions) { + if (destinationPath.length) { + addProperty(newValue, destinationPath, getProperty(key, sourcePath)); + } else { + newValue = getProperty(key, sourcePath); + } } - }); - expanded.push(newValue); - }); - addProperty(newArgs, expansion.valuePath, expanded); - }); + expanded.push(newValue); + } + addProperty(newArgs, expansion.valuePath, expanded); + } + } return newArgs; }; } @@ -452,17 +461,19 @@ function generateArgsFn(mergedTypeResolverInfo: MergedTypeResolverInfo): (origin return (originalResult: any): Record => { const newArgs = mergeDeep({}, args); const filteredResult = getProperties(originalResult, usedProperties); - mappingInstructions.forEach(mappingInstruction => { - const { destinationPath, sourcePath } = mappingInstruction; - addProperty(newArgs, destinationPath, getProperty(filteredResult, sourcePath)); - }); + if (mappingInstructions) { + for (const mappingInstruction of mappingInstructions) { + const { destinationPath, sourcePath } = mappingInstruction; + addProperty(newArgs, destinationPath, getProperty(filteredResult, sourcePath)); + } + } return newArgs; }; } function buildKeyExpr(key: Array): string { let mergedObject = {}; - key.forEach(keyDef => { + for (const keyDef of key) { let [aliasOrKeyPath, keyPath] = keyDef.split(':'); let aliasPath: string; if (keyPath == null) { @@ -472,13 +483,14 @@ function buildKeyExpr(key: Array): string { } const aliasParts = aliasPath.split('.'); const lastAliasPart = aliasParts.pop(); - let object: any = { [lastAliasPart]: `$key.${keyPath}` }; + assertSome(lastAliasPart); + let object: Record = { [lastAliasPart]: `$key.${keyPath}` }; - aliasParts.reverse().forEach(aliasPart => { + for (const aliasPart of aliasParts.reverse()) { object = { [aliasPart]: object }; - }); + } mergedObject = mergeDeep(mergedObject, object); - }); + } return JSON.stringify(mergedObject).replace(/"/g, ''); } @@ -486,12 +498,12 @@ function buildKeyExpr(key: Array): string { function mergeSelectionSets(...selectionSets: Array): SelectionSetNode { const normalizedSelections: Record = Object.create(null); - selectionSets.forEach(selectionSet => { - selectionSet.selections.forEach(selection => { + for (const selectionSet of selectionSets) { + for (const selection of selectionSet.selections) { const normalizedSelection = print(selection); normalizedSelections[normalizedSelection] = selection; - }); - }); + } + } const newSelectionSet = { kind: Kind.SELECTION_SET, @@ -508,17 +520,17 @@ function forEachConcreteTypeName( fn: (typeName: string) => void ): void { if (isInterfaceType(returnType)) { - getImplementingTypes(returnType.name, schema).forEach(typeName => { + for (const typeName of getImplementingTypes(returnType.name, schema)) { if (typeNames == null || typeNames.includes(typeName)) { fn(typeName); } - }); + } } else if (isUnionType(returnType)) { - returnType.getTypes().forEach(type => { + for (const type of returnType.getTypes()) { if (typeNames == null || typeNames.includes(type.name)) { fn(type.name); } - }); + } } else if (isObjectType(returnType) && (typeNames == null || typeNames.includes(returnType.name))) { fn(returnType.name); } diff --git a/packages/stitching-directives/src/stitchingDirectivesValidator.ts b/packages/stitching-directives/src/stitchingDirectivesValidator.ts index 65e76784762..92ab3ddd9b5 100644 --- a/packages/stitching-directives/src/stitchingDirectivesValidator.ts +++ b/packages/stitching-directives/src/stitchingDirectivesValidator.ts @@ -10,7 +10,14 @@ import { parseValue, } from 'graphql'; -import { getDirectives, getImplementingTypes, MapperKind, mapSchema, parseSelectionSet } from '@graphql-tools/utils'; +import { + getDirectives, + getImplementingTypes, + isSome, + MapperKind, + mapSchema, + parseSelectionSet, +} from '@graphql-tools/utils'; import { StitchingDirectivesOptions } from './types'; @@ -34,7 +41,7 @@ export function stitchingDirectivesValidator( [MapperKind.OBJECT_TYPE]: type => { const directives = getDirectives(schema, type, pathToDirectivesInExtensions); - if (directives[keyDirectiveName]) { + if (keyDirectiveName != null && directives[keyDirectiveName]) { const directiveArgumentMap = directives[keyDirectiveName]; parseSelectionSet(directiveArgumentMap.selectionSet); } @@ -44,12 +51,12 @@ export function stitchingDirectivesValidator( [MapperKind.OBJECT_FIELD]: (fieldConfig, _fieldName, typeName) => { const directives = getDirectives(schema, fieldConfig, pathToDirectivesInExtensions); - if (directives[computedDirectiveName]) { + if (computedDirectiveName != null && directives[computedDirectiveName]) { const directiveArgumentMap = directives[computedDirectiveName]; parseSelectionSet(directiveArgumentMap.selectionSet); } - if (directives[mergeDirectiveName]) { + if (mergeDirectiveName != null && directives[mergeDirectiveName]) { const directiveArgumentMap = directives[mergeDirectiveName]; if (typeName !== queryTypeName) { @@ -71,7 +78,7 @@ export function stitchingDirectivesValidator( parseMergeArgsExpr(mergeArgsExpr); } - const args = Object.keys(fieldConfig.args); + const args = Object.keys(fieldConfig.args ?? {}); const keyArg = directiveArgumentMap.keyArg; if (keyArg == null) { @@ -101,7 +108,7 @@ export function stitchingDirectivesValidator( throw new Error('Cannot use @merge directive with both `keyField` and `key` arguments.'); } - key.forEach(keyDef => { + for (const keyDef of key) { let [aliasOrKeyPath, keyPath] = keyDef.split(':'); let aliasPath: string; if (keyPath == null) { @@ -122,7 +129,7 @@ export function stitchingDirectivesValidator( ); // TODO: ideally we should check that the arg exists within the resolver } - }); + } } const additionalArgs = directiveArgumentMap.additionalArgs; @@ -148,14 +155,14 @@ export function stitchingDirectivesValidator( const implementingTypes = isInterfaceType(returnType) ? getImplementingTypes(returnType.name, schema).map(typeName => schema.getType(typeName)) : returnType.getTypes(); - const implementingTypeNames = implementingTypes.map(type => type.name); - typeNames.forEach(typeName => { + const implementingTypeNames = implementingTypes.filter(isSome).map(type => type.name); + for (const typeName of typeNames) { if (!implementingTypeNames.includes(typeName)) { throw new Error( `Types argument can only include only type names that implement the field return type's abstract type.` ); } - }); + } } } diff --git a/packages/stitching-directives/src/types.ts b/packages/stitching-directives/src/types.ts index e549fce20f4..4bcf978eb72 100644 --- a/packages/stitching-directives/src/types.ts +++ b/packages/stitching-directives/src/types.ts @@ -30,6 +30,12 @@ export interface StitchingDirectivesOptions { pathToDirectivesInExtensions?: Array; } +type Complete = { + [P in keyof Required]: Exclude extends Required> ? T[P] : T[P] | undefined, undefined>; +}; + +export type StitchingDirectivesFinalOptions = Complete; + export interface MergedTypeResolverInfo extends ParsedMergeArgsExpr { fieldName: string; returnsList: boolean; diff --git a/packages/stitching-directives/tests/stitchingDirectivesTransformer.test.ts b/packages/stitching-directives/tests/stitchingDirectivesTransformer.test.ts index c15e5de5dfb..29bf970afbd 100644 --- a/packages/stitching-directives/tests/stitchingDirectivesTransformer.test.ts +++ b/packages/stitching-directives/tests/stitchingDirectivesTransformer.test.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-non-null-asserted-optional-chain */ import { print } from 'graphql'; import { makeExecutableSchema } from '@graphql-tools/schema'; @@ -31,8 +32,8 @@ describe('type merging directives', () => { const transformedSubschemaConfig = stitchingDirectivesTransformer(subschemaConfig); - expect(transformedSubschemaConfig.merge.User.selectionSet).toEqual(print(parseSelectionSet('{ id }'))); - expect(transformedSubschemaConfig.merge.User.fieldName).toEqual('_user'); + expect(transformedSubschemaConfig.merge?.['User'].selectionSet).toEqual(print(parseSelectionSet('{ id }'))); + expect(transformedSubschemaConfig.merge?.['User'].fieldName).toEqual('_user'); }); test('adds type selection sets when returns union', () => { @@ -60,8 +61,8 @@ describe('type merging directives', () => { const transformedSubschemaConfig = stitchingDirectivesTransformer(subschemaConfig); - expect(transformedSubschemaConfig.merge.User.selectionSet).toEqual(print(parseSelectionSet('{ id }'))); - expect(transformedSubschemaConfig.merge.User.fieldName).toEqual('_entity'); + expect(transformedSubschemaConfig.merge?.['User'].selectionSet).toEqual(print(parseSelectionSet('{ id }'))); + expect(transformedSubschemaConfig.merge?.['User'].fieldName).toEqual('_entity'); }); test('adds type selection sets when returns interface', () => { @@ -91,8 +92,8 @@ describe('type merging directives', () => { const transformedSubschemaConfig = stitchingDirectivesTransformer(subschemaConfig); - expect(transformedSubschemaConfig.merge.User.selectionSet).toEqual(print(parseSelectionSet('{ id }'))); - expect(transformedSubschemaConfig.merge.User.fieldName).toEqual('_entity'); + expect(transformedSubschemaConfig.merge?.['User'].selectionSet).toEqual(print(parseSelectionSet('{ id }'))); + expect(transformedSubschemaConfig.merge?.['User'].fieldName).toEqual('_entity'); }); test('adds type selection sets when returns list', () => { @@ -117,7 +118,7 @@ describe('type merging directives', () => { const transformedSubschemaConfig = stitchingDirectivesTransformer(subschemaConfig); - const argsFn = transformedSubschemaConfig.merge.User.args; + const argsFn = transformedSubschemaConfig.merge?.['User'].args!; const originalResult = { relations: [ @@ -168,7 +169,7 @@ describe('type merging directives', () => { const transformedSubschemaConfig = stitchingDirectivesTransformer(subschemaConfig); - const argsFn = transformedSubschemaConfig.merge.User.args; + const argsFn = transformedSubschemaConfig.merge?.['User'].args!; const originalResult = { relationSets: [ @@ -233,7 +234,7 @@ describe('type merging directives', () => { const transformedSubschemaConfig = stitchingDirectivesTransformer(subschemaConfig); - const argsFn = transformedSubschemaConfig.merge.User.args; + const argsFn = transformedSubschemaConfig.merge?.['User'].args!; const originalResult: { nestedField: null } = { nestedField: null @@ -271,9 +272,9 @@ describe('type merging directives', () => { const transformedSubschemaConfig = stitchingDirectivesTransformer(subschemaConfig); - expect(transformedSubschemaConfig.merge.User.fields.name.selectionSet).toEqual(print(parseSelectionSet('{ id }'))); - expect(transformedSubschemaConfig.merge.User.fields.name.computed).toEqual(true); - expect(transformedSubschemaConfig.merge.User.fieldName).toEqual('_user'); + expect(transformedSubschemaConfig.merge?.['User']?.fields?.['name']?.selectionSet).toEqual(print(parseSelectionSet('{ id }'))); + expect(transformedSubschemaConfig.merge?.['User']?.fields?.['name']?.computed).toEqual(true); + expect(transformedSubschemaConfig.merge?.['User'].fieldName).toEqual('_user'); }); test('adds args function when used without arguments', () => { @@ -299,7 +300,7 @@ describe('type merging directives', () => { const transformedSubschemaConfig = stitchingDirectivesTransformer(subschemaConfig); - const argsFn = transformedSubschemaConfig.merge.User.args; + const argsFn = transformedSubschemaConfig.merge?.['User'].args!; const originalResult = { id: '5', @@ -338,7 +339,7 @@ describe('type merging directives', () => { const transformedSubschemaConfig = stitchingDirectivesTransformer(subschemaConfig); - const argsFn = transformedSubschemaConfig.merge.User.args; + const argsFn = transformedSubschemaConfig.merge?.['User'].args!; const originalResult = { id: '5', @@ -377,7 +378,7 @@ describe('type merging directives', () => { const transformedSubschemaConfig = stitchingDirectivesTransformer(subschemaConfig); - const argsFn = transformedSubschemaConfig.merge.User.args; + const argsFn = transformedSubschemaConfig.merge?.['User'].args!; const originalResult = { id: '5', @@ -416,7 +417,7 @@ describe('type merging directives', () => { const transformedSubschemaConfig = stitchingDirectivesTransformer(subschemaConfig); - const argsFn = transformedSubschemaConfig.merge.User.args; + const argsFn = transformedSubschemaConfig.merge?.['User'].args!; const originalResult = { id: '5', @@ -459,7 +460,7 @@ describe('type merging directives', () => { const transformedSubschemaConfig = stitchingDirectivesTransformer(subschemaConfig); - const argsFn = transformedSubschemaConfig.merge.User.args; + const argsFn = transformedSubschemaConfig.merge?.['User'].args!; const originalResult = { id: '5', @@ -501,7 +502,7 @@ describe('type merging directives', () => { const transformedSubschemaConfig = stitchingDirectivesTransformer(subschemaConfig); - const argsFn = transformedSubschemaConfig.merge.User.args; + const argsFn = transformedSubschemaConfig.merge?.['User'].args!; const originalResult = { id: '5', @@ -539,9 +540,9 @@ describe('type merging directives', () => { const transformedSubschemaConfig = stitchingDirectivesTransformer(subschemaConfig); - expect(transformedSubschemaConfig.merge.User.selectionSet).toEqual(`{\n id\n}`); + expect(transformedSubschemaConfig.merge?.['User'].selectionSet).toEqual(`{\n id\n}`); - const argsFn = transformedSubschemaConfig.merge.User.args; + const argsFn = transformedSubschemaConfig.merge?.['User'].args!; const originalResult = { id: '5', @@ -578,7 +579,7 @@ describe('type merging directives', () => { const transformedSubschemaConfig = stitchingDirectivesTransformer(subschemaConfig); - const argsFn = transformedSubschemaConfig.merge.User.args; + const argsFn = transformedSubschemaConfig.merge?.['User'].args!; const originalResult = { id: '5', @@ -624,8 +625,8 @@ describe('type merging directives', () => { const transformedSubschemaConfig = stitchingDirectivesTransformer(subschemaConfig); - const keyFn = transformedSubschemaConfig.merge.User.key; - const argsFromKeysFn = transformedSubschemaConfig.merge.User.argsFromKeys; + const keyFn = transformedSubschemaConfig.merge?.['User'].key!; + const argsFromKeysFn = transformedSubschemaConfig.merge?.['User'].argsFromKeys!; const originalResult = { id: '5', @@ -670,8 +671,8 @@ describe('type merging directives', () => { const transformedSubschemaConfig = stitchingDirectivesTransformer(subschemaConfig); - const keyFn = transformedSubschemaConfig.merge.User.key; - const argsFromKeysFn = transformedSubschemaConfig.merge.User.argsFromKeys; + const keyFn = transformedSubschemaConfig.merge?.['User'].key!; + const argsFromKeysFn = transformedSubschemaConfig.merge?.['User'].argsFromKeys!; const originalResult = { __typename: 'User', @@ -721,8 +722,8 @@ describe('type merging directives', () => { const transformedSubschemaConfig = stitchingDirectivesTransformer(subschemaConfig); - const keyFn = transformedSubschemaConfig.merge.User.key; - const argsFromKeysFn = transformedSubschemaConfig.merge.User.argsFromKeys; + const keyFn = transformedSubschemaConfig.merge?.['User'].key!; + const argsFromKeysFn = transformedSubschemaConfig.merge?.['User'].argsFromKeys!; const originalResult = { __typename: 'User', @@ -768,8 +769,8 @@ describe('type merging directives', () => { const transformedSubschemaConfig = stitchingDirectivesTransformer(subschemaConfig); - const keyFn = transformedSubschemaConfig.merge.User.key; - const argsFromKeysFn = transformedSubschemaConfig.merge.User.argsFromKeys; + const keyFn = transformedSubschemaConfig.merge?.['User'].key!; + const argsFromKeysFn = transformedSubschemaConfig.merge?.['User'].argsFromKeys!; const originalResult = { id: '5', @@ -812,8 +813,8 @@ describe('type merging directives', () => { const transformedSubschemaConfig = stitchingDirectivesTransformer(subschemaConfig); - const keyFn = transformedSubschemaConfig.merge.User.key; - const argsFromKeysFn = transformedSubschemaConfig.merge.User.argsFromKeys; + const keyFn = transformedSubschemaConfig.merge?.['User'].key!; + const argsFromKeysFn = transformedSubschemaConfig.merge?.['User'].argsFromKeys!; const originalResult = { id: '5', diff --git a/packages/testing/assertion.ts b/packages/testing/assertion.ts new file mode 100644 index 00000000000..2055925abc4 --- /dev/null +++ b/packages/testing/assertion.ts @@ -0,0 +1,103 @@ +import { + ASTNode, + EnumTypeDefinitionNode, + GraphQLEnumType, + GraphQLInputObjectType, + GraphQLInterfaceType, + GraphQLObjectType, + GraphQLScalarType, + GraphQLUnionType, + InputObjectTypeDefinitionNode, + InterfaceTypeDefinitionNode, + ListValueNode, + NamedTypeNode, + ObjectTypeDefinitionNode, + ScalarTypeDefinitionNode, + UnionTypeDefinitionNode, +} from 'graphql'; + +export function assertGraphQLObjectType(input: unknown): asserts input is GraphQLObjectType { + if (input instanceof GraphQLObjectType) { + return; + } + throw new Error('Expected GraphQLObjectType.'); +} +export function assertGraphQLEnumType(input: unknown): asserts input is GraphQLEnumType { + if (input instanceof GraphQLEnumType) { + return; + } + throw new Error('Expected GraphQLObjectType.'); +} +export function assertGraphQLScalerType(input: unknown): asserts input is GraphQLScalarType { + if (input instanceof GraphQLScalarType) { + return; + } + throw new Error('Expected GraphQLScalerType.'); +} +export function assertGraphQLInterfaceType(input: unknown): asserts input is GraphQLInterfaceType { + if (input instanceof GraphQLInterfaceType) { + return; + } + throw new Error('Expected GraphQLInterfaceType.'); +} +export function assertGraphQLUnionType(input: unknown): asserts input is GraphQLUnionType { + if (input instanceof GraphQLUnionType) { + return; + } + throw new Error('Expected GraphQLUnionType.'); +} +export function assertGraphQLInputObjectType(input: unknown): asserts input is GraphQLInputObjectType { + if (input instanceof GraphQLInputObjectType) { + return; + } + throw new Error('Expected GraphQLInputObjectType.'); +} + +export function assertEnumTypeDefinitionNode(input: ASTNode): asserts input is EnumTypeDefinitionNode { + if (input.kind === 'EnumTypeDefinition') { + return; + } + throw new Error('Expected EnumTypeDefinitionNode.'); +} +export function assertObjectTypeDefinitionNode(input: ASTNode): asserts input is ObjectTypeDefinitionNode { + if (input.kind === 'ObjectTypeDefinition') { + return; + } + throw new Error(`Expected ObjectTypeDefinitionNode. Got ${input.kind}`); +} +export function assertInterfaceTypeDefinitionNode(input: ASTNode): asserts input is InterfaceTypeDefinitionNode { + if (input.kind === 'InterfaceTypeDefinition') { + return; + } + throw new Error(`Expected InterfaceTypeDefinitionNode. Got ${input.kind}`); +} +export function assertUnionTypeDefinitionNode(input: ASTNode): asserts input is UnionTypeDefinitionNode { + if (input.kind === 'UnionTypeDefinition') { + return; + } + throw new Error(`Expected InterfaceTypeDefinitionNode. Got ${input.kind}`); +} +export function assertNamedTypeNode(input: ASTNode): asserts input is NamedTypeNode { + if (input.kind === 'NamedType') { + return; + } + throw new Error(`Expected NamedTypeNode. Got ${input.kind}`); +} +export function assertScalarTypeDefinitionNode(input: ASTNode): asserts input is ScalarTypeDefinitionNode { + if (input.kind === 'ScalarTypeDefinition') { + return; + } + throw new Error(`Expected ScalarTypeDefinitionNode. Got ${input.kind}`); +} +export function assertInputObjectTypeDefinitionNode(input: ASTNode): asserts input is InputObjectTypeDefinitionNode { + if (input.kind === 'InputObjectTypeDefinition') { + return; + } + throw new Error(`Expected InputObjectTypeDefinitionNode. Got ${input.kind}`); +} +export function assertListValueNode(input: ASTNode): asserts input is ListValueNode { + if (input.kind === 'ListValue') { + return; + } + throw new Error(`Expected ListValueNode. Got ${input.kind}`); +} diff --git a/packages/testing/utils.ts b/packages/testing/utils.ts index 579de0a85e1..3f4172e4b17 100644 --- a/packages/testing/utils.ts +++ b/packages/testing/utils.ts @@ -16,9 +16,10 @@ export function normalizeString(str: string) { type PromiseOf any> = T extends (...args: any[]) => Promise ? R : ReturnType; export function runTests< - TSync extends (...args: any[]) => TResult, - TAsync extends (...args: any[]) => Promise, - TResult = ReturnType + TResult extends any, + TArgs extends Array, + TSync extends (...args: TArgs) => TResult, + TAsync extends (...args: TArgs) => Promise >({ sync: executeSync, async: executeAsync }: { sync?: TSync; async?: TAsync }) { return ( testRunner: ( @@ -29,7 +30,7 @@ export function runTests< if (executeSync) { // sync describe('sync', () => { - testRunner((...args: Parameters) => { + testRunner((...args: Parameters) => { return new Promise>((resolve, reject) => { try { const result: any = executeSync(...args); @@ -98,7 +99,7 @@ export function mockGraphQLServer({ path: string | RegExp | ((path: string) => boolean); intercept?: (obj: nock.ReplyFnContext) => void; method?: string; -}) { +}): nock.Scope { const handler = async function (this: nock.ReplyFnContext, uri: string, body: any) { if (intercept) { intercept(this); @@ -141,9 +142,9 @@ export function mockGraphQLServer({ // 2) MULTIPART RESPONSE: a multipart response (when @stream or @defer directives are used) // 3) PUSH: a stream of events to push back down the client for a subscription if (result.type === 'RESPONSE') { - const headers = {}; + const headers = new Map(); // We set the provided status and headers and just the send the payload back to the client - result.headers.forEach(({ name, value }) => (headers[name] = value)); + result.headers.forEach(({ name, value }) => headers.set(name, value)); return [result.status, result.payload, headers]; } else { return [500, 'Not implemented']; @@ -155,4 +156,5 @@ export function mockGraphQLServer({ case 'POST': return nock(host).post(path).reply(handler); } + throw new Error(`Unsupported method: ${method}`); } diff --git a/packages/utils/package.json b/packages/utils/package.json index f3718c96ee4..52c2341c81c 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -11,8 +11,8 @@ "license": "MIT", "sideEffects": false, "main": "dist/index.js", - "module": "dist/index.mjs", - "exports": { + "module": "dist/index.mjs", + "exports": { ".": { "require": "./dist/index.js", "import": "./dist/index.mjs" @@ -35,9 +35,7 @@ "graphql-scalars": "1.10.0" }, "dependencies": { - "@ardatan/aggregate-error": "0.0.6", - "camel-case": "4.1.2", - "tslib": "~2.2.0" + "tslib": "~2.3.0" }, "publishConfig": { "access": "public", diff --git a/packages/utils/src/AggregateError.ts b/packages/utils/src/AggregateError.ts new file mode 100644 index 00000000000..1300c199ade --- /dev/null +++ b/packages/utils/src/AggregateError.ts @@ -0,0 +1,20 @@ +let AggregateErrorImpl = globalThis.AggregateError; + +if (typeof AggregateErrorImpl === 'undefined') { + class AggregateErrorClass extends Error implements AggregateError { + errors: Error[]; + constructor(maybeErrors: Iterable, message = '') { + super(message); + this.name = 'AggregateError'; + Error.captureStackTrace(this, AggregateErrorClass); + this.errors = [...maybeErrors].map(maybeError => + maybeError instanceof Error ? maybeError : new Error(maybeError) + ); + } + } + AggregateErrorImpl = function (errors: Iterable, message?: string) { + return new AggregateErrorClass(errors, message); + } as AggregateErrorConstructor; +} + +export { AggregateErrorImpl as AggregateError }; diff --git a/packages/utils/src/Interfaces.ts b/packages/utils/src/Interfaces.ts index e8f0aade45b..23190a3c41a 100644 --- a/packages/utils/src/Interfaces.ts +++ b/packages/utils/src/Interfaces.ts @@ -46,10 +46,10 @@ import { InputObjectTypeExtensionNode, InputObjectTypeDefinitionNode, GraphQLType, + Source, + DefinitionNode, } from 'graphql'; -import { SchemaVisitor } from './SchemaVisitor'; - // graphql-js < v15 backwards compatible ExecutionResult // See: https://github.com/graphql/graphql-js/pull/2490 @@ -199,15 +199,21 @@ export type InputFieldFilter = ( ) => boolean; export type FieldFilter = ( - typeName?: string, - fieldName?: string, - fieldConfig?: GraphQLFieldConfig | GraphQLInputFieldConfig + typeName: string, + fieldName: string, + fieldConfig: GraphQLFieldConfig | GraphQLInputFieldConfig +) => boolean; + +export type ObjectFieldFilter = ( + typeName: string, + fieldName: string, + fieldConfig: GraphQLFieldConfig ) => boolean; export type RootFieldFilter = ( - operation?: 'Query' | 'Mutation' | 'Subscription', - rootFieldName?: string, - fieldConfig?: GraphQLFieldConfig + operation: 'Query' | 'Mutation' | 'Subscription', + rootFieldName: string, + fieldConfig: GraphQLFieldConfig ) => boolean; export type TypeFilter = (typeName: string, type: GraphQLType) => boolean; @@ -231,9 +237,14 @@ export type IFieldResolver, TRetu info: GraphQLResolveInfo ) => TReturn; -export type ITypedef = string | DocumentNode | (() => Array); - -export type ITypeDefinitions = string | DocumentNode | Array; +export type TypeSource = + | string + | Source + | DocumentNode + | GraphQLSchema + | DefinitionNode + | Array + | (() => TypeSource); export type IObjectTypeResolver = { [key: string]: IFieldResolver | IFieldResolverOptions; @@ -298,21 +309,10 @@ export type IDefaultValueIteratorFn = (type: GraphQLInputType, value: any) => vo export type NextResolverFn = () => Promise; -export type DirectiveResolverFn = ( - next: NextResolverFn, - source: TSource, - args: { [argName: string]: any }, - context: TContext, - info: GraphQLResolveInfo -) => any; - -export interface IDirectiveResolvers { - [directiveName: string]: DirectiveResolverFn; -} - export interface Request { document: DocumentNode; variables: Record; + operationName?: string; extensions?: Record; } @@ -330,79 +330,6 @@ export type VisitableSchemaType = | GraphQLEnumType | GraphQLEnumValue; -export type VisitorSelector = ( - type: VisitableSchemaType, - methodName: string -) => Array; - -export enum VisitSchemaKind { - TYPE = 'VisitSchemaKind.TYPE', - SCALAR_TYPE = 'VisitSchemaKind.SCALAR_TYPE', - ENUM_TYPE = 'VisitSchemaKind.ENUM_TYPE', - COMPOSITE_TYPE = 'VisitSchemaKind.COMPOSITE_TYPE', - OBJECT_TYPE = 'VisitSchemaKind.OBJECT_TYPE', - INPUT_OBJECT_TYPE = 'VisitSchemaKind.INPUT_OBJECT_TYPE', - ABSTRACT_TYPE = 'VisitSchemaKind.ABSTRACT_TYPE', - UNION_TYPE = 'VisitSchemaKind.UNION_TYPE', - INTERFACE_TYPE = 'VisitSchemaKind.INTERFACE_TYPE', - ROOT_OBJECT = 'VisitSchemaKind.ROOT_OBJECT', - QUERY = 'VisitSchemaKind.QUERY', - MUTATION = 'VisitSchemaKind.MUTATION', - SUBSCRIPTION = 'VisitSchemaKind.SUBSCRIPTION', -} - -export interface SchemaVisitorMap { - [VisitSchemaKind.TYPE]?: NamedTypeVisitor; - [VisitSchemaKind.SCALAR_TYPE]?: ScalarTypeVisitor; - [VisitSchemaKind.ENUM_TYPE]?: EnumTypeVisitor; - [VisitSchemaKind.COMPOSITE_TYPE]?: CompositeTypeVisitor; - [VisitSchemaKind.OBJECT_TYPE]?: ObjectTypeVisitor; - [VisitSchemaKind.INPUT_OBJECT_TYPE]?: InputObjectTypeVisitor; - [VisitSchemaKind.ABSTRACT_TYPE]?: AbstractTypeVisitor; - [VisitSchemaKind.UNION_TYPE]?: UnionTypeVisitor; - [VisitSchemaKind.INTERFACE_TYPE]?: InterfaceTypeVisitor; - [VisitSchemaKind.ROOT_OBJECT]?: ObjectTypeVisitor; - [VisitSchemaKind.QUERY]?: ObjectTypeVisitor; - [VisitSchemaKind.MUTATION]?: ObjectTypeVisitor; - [VisitSchemaKind.SUBSCRIPTION]?: ObjectTypeVisitor; -} - -export type NamedTypeVisitor = (type: GraphQLNamedType, schema: GraphQLSchema) => GraphQLNamedType | null | undefined; - -export type ScalarTypeVisitor = ( - type: GraphQLScalarType, - schema: GraphQLSchema -) => GraphQLScalarType | null | undefined; - -export type EnumTypeVisitor = (type: GraphQLEnumType, schema: GraphQLSchema) => GraphQLEnumType | null | undefined; - -export type CompositeTypeVisitor = ( - type: GraphQLObjectType | GraphQLInterfaceType | GraphQLUnionType, - schema: GraphQLSchema -) => GraphQLObjectType | GraphQLInterfaceType | GraphQLUnionType | null | undefined; - -export type ObjectTypeVisitor = ( - type: GraphQLObjectType, - schema: GraphQLSchema -) => GraphQLObjectType | null | undefined; - -export type InputObjectTypeVisitor = ( - type: GraphQLInputObjectType, - schema: GraphQLSchema -) => GraphQLInputObjectType | null | undefined; - -export type AbstractTypeVisitor = ( - type: GraphQLInterfaceType | GraphQLUnionType, - schema: GraphQLSchema -) => GraphQLInterfaceType | GraphQLUnionType | null | undefined; - -export type UnionTypeVisitor = (type: GraphQLUnionType, schema: GraphQLSchema) => GraphQLUnionType | null | undefined; - -export type InterfaceTypeVisitor = ( - type: GraphQLInterfaceType, - schema: GraphQLSchema -) => GraphQLInterfaceType | null | undefined; - export enum MapperKind { TYPE = 'MapperKind.TYPE', SCALAR_TYPE = 'MapperKind.SCALAR_TYPE', @@ -459,6 +386,18 @@ export interface SchemaMapper { [MapperKind.DIRECTIVE]?: DirectiveMapper; } +export type SchemaFieldMapperTypes = Array< + | MapperKind.FIELD + | MapperKind.COMPOSITE_FIELD + | MapperKind.OBJECT_FIELD + | MapperKind.ROOT_FIELD + | MapperKind.QUERY_ROOT_FIELD + | MapperKind.MUTATION_ROOT_FIELD + | MapperKind.SUBSCRIPTION_ROOT_FIELD + | MapperKind.INTERFACE_FIELD + | MapperKind.INPUT_OBJECT_FIELD +>; + export type NamedTypeMapper = (type: GraphQLNamedType, schema: GraphQLSchema) => GraphQLNamedType | null | undefined; export type ScalarTypeMapper = (type: GraphQLScalarType, schema: GraphQLSchema) => GraphQLScalarType | null | undefined; diff --git a/packages/utils/src/SchemaDirectiveVisitor.ts b/packages/utils/src/SchemaDirectiveVisitor.ts deleted file mode 100644 index 8ca764837c2..00000000000 --- a/packages/utils/src/SchemaDirectiveVisitor.ts +++ /dev/null @@ -1,321 +0,0 @@ -import { - GraphQLDirective, - GraphQLSchema, - DirectiveLocationEnum, - TypeSystemExtensionNode, - valueFromASTUntyped, -} from 'graphql'; - -import { VisitableSchemaType } from './Interfaces'; - -import { SchemaVisitor } from './SchemaVisitor'; -import { visitSchema } from './visitSchema'; -import { getArgumentValues } from './getArgumentValues'; - -// This class represents a reusable implementation of a @directive that may -// appear in a GraphQL schema written in Schema Definition Language. -// -// By overriding one or more visit{Object,Union,...} methods, a subclass -// registers interest in certain schema types, such as GraphQLObjectType, -// GraphQLUnionType, etc. When SchemaDirectiveVisitor.visitSchemaDirectives is -// called with a GraphQLSchema object and a map of visitor subclasses, the -// overridden methods of those subclasses allow the visitors to obtain -// references to any type objects that have @directives attached to them, -// enabling visitors to inspect or modify the schema as appropriate. -// -// For example, if a directive called @rest(url: "...") appears after a field -// definition, a SchemaDirectiveVisitor subclass could provide meaning to that -// directive by overriding the visitFieldDefinition method (which receives a -// GraphQLField parameter), and then the body of that visitor method could -// manipulate the field's resolver function to fetch data from a REST endpoint -// described by the url argument passed to the @rest directive: -// -// const typeDefs = ` -// type Query { -// people: [Person] @rest(url: "/api/v1/people") -// }`; -// -// const schema = makeExecutableSchema({ typeDefs }); -// -// SchemaDirectiveVisitor.visitSchemaDirectives(schema, { -// rest: class extends SchemaDirectiveVisitor { -// public visitFieldDefinition(field: GraphQLField) { -// const { url } = this.args; -// field.resolve = () => fetch(url); -// } -// } -// }); -// -// The subclass in this example is defined as an anonymous class expression, -// for brevity. A truly reusable SchemaDirectiveVisitor would most likely be -// defined in a library using a named class declaration, and then exported for -// consumption by other modules and packages. -// -// See below for a complete list of overridable visitor methods, their -// parameter types, and more details about the properties exposed by instances -// of the SchemaDirectiveVisitor class. - -export class SchemaDirectiveVisitor extends SchemaVisitor { - // The name of the directive this visitor is allowed to visit (that is, the - // identifier that appears after the @ character in the schema). Note that - // this property is per-instance rather than static because subclasses of - // SchemaDirectiveVisitor can be instantiated multiple times to visit - // directives of different names. In other words, SchemaDirectiveVisitor - // implementations are effectively anonymous, and it's up to the caller of - // SchemaDirectiveVisitor.visitSchemaDirectives to assign names to them. - public name: string; - - // A map from parameter names to argument values, as obtained from a - // specific occurrence of a @directive(arg1: value1, arg2: value2, ...) in - // the schema. Visitor methods may refer to this object via this.args. - public args: TArgs; - - // A reference to the type object that this visitor was created to visit. - public visitedType: VisitableSchemaType; - - // A shared object that will be available to all visitor instances via - // this.context. Callers of visitSchemaDirectives can provide their own - // object, or just use the default empty object. - public context: TContext; - - // Override this method to return a custom GraphQLDirective (or modify one - // already present in the schema) to enforce argument types, provide default - // argument values, or specify schema locations where this @directive may - // appear. By default, any declaration found in the schema will be returned. - public static getDirectiveDeclaration( - directiveName: string, - schema: GraphQLSchema - ): GraphQLDirective | null | undefined { - return schema.getDirective(directiveName); - } - - // Call SchemaDirectiveVisitor.visitSchemaDirectives to visit every - // @directive in the schema and create an appropriate SchemaDirectiveVisitor - // instance to visit the object decorated by the @directive. - public static visitSchemaDirectives( - schema: GraphQLSchema, - // The keys of this object correspond to directive names as they appear - // in the schema, and the values should be subclasses (not instances!) - // of the SchemaDirectiveVisitor class. This distinction is important - // because a new SchemaDirectiveVisitor instance will be created each - // time a matching directive is found in the schema AST, with arguments - // and other metadata specific to that occurrence. To help prevent the - // mistake of passing instances, the SchemaDirectiveVisitor constructor - // method is marked as protected. - directiveVisitors: Record, - // Optional context object that will be available to all visitor instances - // via this.context. Defaults to an empty null-prototype object. - context: Record = Object.create(null), - // The visitSchemaDirectives method returns a map from directive names to - // lists of SchemaDirectiveVisitors created while visiting the schema. - pathToDirectivesInExtensions = ['directives'] - ): Record> { - // If the schema declares any directives for public consumption, record - // them here so that we can properly coerce arguments when/if we encounter - // an occurrence of the directive while walking the schema below. - const declaredDirectives = this.getDeclaredDirectives(schema, directiveVisitors); - - // Map from directive names to lists of SchemaDirectiveVisitor instances - // created while visiting the schema. - const createdVisitors: Record> = Object.keys(directiveVisitors).reduce( - (prev, item) => ({ - ...prev, - [item]: [], - }), - {} - ); - - const directiveVisitorMap: Record = Object.entries(directiveVisitors).reduce( - (prev, [key, value]) => ({ - ...prev, - [key]: value, - }), - {} - ); - - function visitorSelector(type: VisitableSchemaType, methodName: string): Array { - const directivesInExtensions = pathToDirectivesInExtensions.reduce( - (acc, pathSegment) => (acc == null ? acc : acc[pathSegment]), - type?.extensions - ); - - const directives: Record> = Object.create(null); - - if (directivesInExtensions != null) { - Object.entries(directivesInExtensions).forEach(([directiveName, directiveValue]) => { - if (!directives[directiveName]) { - directives[directiveName] = [directiveValue]; - } else { - directives[directiveName].push([directiveValue]); - } - }); - } else { - let directiveNodes = type?.astNode?.directives ?? []; - - const extensionASTNodes: ReadonlyArray = (type as { - extensionASTNodes?: Array; - }).extensionASTNodes; - - if (extensionASTNodes != null) { - extensionASTNodes.forEach(extensionASTNode => { - if (extensionASTNode.directives != null) { - directiveNodes = directiveNodes.concat(extensionASTNode.directives); - } - }); - } - - directiveNodes.forEach(directiveNode => { - const directiveName = directiveNode.name.value; - - const decl = declaredDirectives[directiveName]; - let args: Record; - - if (decl != null) { - // If this directive was explicitly declared, use the declared - // argument types (and any default values) to check, coerce, and/or - // supply default values for the given arguments. - args = getArgumentValues(decl, directiveNode); - } else { - // If this directive was not explicitly declared, just convert the - // argument nodes to their corresponding JavaScript values. - args = Object.create(null); - if (directiveNode.arguments != null) { - directiveNode.arguments.forEach(arg => { - args[arg.name.value] = valueFromASTUntyped(arg.value); - }); - } - } - - if (!directives[directiveName]) { - directives[directiveName] = [args]; - } else { - directives[directiveName].push(args); - } - }); - } - - const visitors: Array = []; - - Object.entries(directives).forEach(([directiveName, directiveValues]) => { - if (!(directiveName in directiveVisitorMap)) { - return; - } - - const VisitorClass = directiveVisitorMap[directiveName]; - - // Avoid creating visitor objects if visitorClass does not override - // the visitor method named by methodName. - if (!VisitorClass.implementsVisitorMethod(methodName)) { - return; - } - - directiveValues.forEach(directiveValue => { - // As foretold in comments near the top of the visitSchemaDirectives - // method, this is where instances of the SchemaDirectiveVisitor class - // get created and assigned names. While subclasses could override the - // constructor method, the constructor is marked as protected, so - // these are the only arguments that will ever be passed. - visitors.push( - new VisitorClass({ - name: directiveName, - args: directiveValue, - visitedType: type, - schema, - context, - }) - ); - }); - }); - - if (visitors.length > 0) { - visitors.forEach(visitor => { - createdVisitors[visitor.name].push(visitor); - }); - } - - return visitors; - } - - visitSchema(schema, visitorSelector); - - return createdVisitors; - } - - protected static getDeclaredDirectives( - schema: GraphQLSchema, - directiveVisitors: Record - ): Record { - const declaredDirectives: Record = schema.getDirectives().reduce( - (prev, curr) => ({ - ...prev, - [curr.name]: curr, - }), - {} - ); - // If the visitor subclass overrides getDirectiveDeclaration, and it - // returns a non-null GraphQLDirective, use that instead of any directive - // declared in the schema itself. Reasoning: if a SchemaDirectiveVisitor - // goes to the trouble of implementing getDirectiveDeclaration, it should - // be able to rely on that implementation. - Object.entries(directiveVisitors).forEach(([directiveName, visitorClass]) => { - const decl = visitorClass.getDirectiveDeclaration(directiveName, schema); - if (decl != null) { - declaredDirectives[directiveName] = decl; - } - }); - - Object.entries(declaredDirectives).forEach(([name, decl]) => { - if (!(name in directiveVisitors)) { - // SchemaDirectiveVisitors.visitSchemaDirectives might be called - // multiple times with partial directiveVisitors maps, so it's not - // necessarily an error for directiveVisitors to be missing an - // implementation of a directive that was declared in the schema. - return; - } - const visitorClass = directiveVisitors[name]; - - decl.locations.forEach(loc => { - const visitorMethodName = directiveLocationToVisitorMethodName(loc); - if ( - SchemaVisitor.implementsVisitorMethod(visitorMethodName) && - !visitorClass.implementsVisitorMethod(visitorMethodName) - ) { - // While visitor subclasses may implement extra visitor methods, - // it's definitely a mistake if the GraphQLDirective declares itself - // applicable to certain schema locations, and the visitor subclass - // does not implement all the corresponding methods. - throw new Error(`SchemaDirectiveVisitor for @${name} must implement ${visitorMethodName} method`); - } - }); - }); - - return declaredDirectives; - } - - // Mark the constructor protected to enforce passing SchemaDirectiveVisitor - // subclasses (not instances) to visitSchemaDirectives. - protected constructor(config: { - name: string; - args: TArgs; - visitedType: VisitableSchemaType; - schema: GraphQLSchema; - context: TContext; - }) { - super(); - this.name = config.name; - this.args = config.args; - this.visitedType = config.visitedType; - this.schema = config.schema; - this.context = config.context; - } -} - -// Convert a string like "FIELD_DEFINITION" to "visitFieldDefinition". -function directiveLocationToVisitorMethodName(loc: DirectiveLocationEnum) { - return ( - 'visit' + - loc.replace(/([^_]*)_?/g, (_wholeMatch, part: string) => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase()) - ); -} - -export type SchemaDirectiveVisitorClass = typeof SchemaDirectiveVisitor; diff --git a/packages/utils/src/SchemaVisitor.ts b/packages/utils/src/SchemaVisitor.ts deleted file mode 100644 index 7f49ba0aa82..00000000000 --- a/packages/utils/src/SchemaVisitor.ts +++ /dev/null @@ -1,119 +0,0 @@ -import { - GraphQLArgument, - GraphQLEnumType, - GraphQLEnumValue, - GraphQLField, - GraphQLInputField, - GraphQLInputObjectType, - GraphQLInterfaceType, - GraphQLObjectType, - GraphQLScalarType, - GraphQLSchema, - GraphQLUnionType, -} from 'graphql'; - -// Abstract base class of any visitor implementation, defining the available -// visitor methods along with their parameter types, and providing a static -// helper function for determining whether a subclass implements a given -// visitor method, as opposed to inheriting one of the stubs defined here. -export abstract class SchemaVisitor { - // All SchemaVisitor instances are created while visiting a specific - // GraphQLSchema object, so this property holds a reference to that object, - // in case a visitor method needs to refer to this.schema. - public schema!: GraphQLSchema; - - // Determine if this SchemaVisitor (sub)class implements a particular - // visitor method. - public static implementsVisitorMethod(methodName: string): boolean { - if (!methodName.startsWith('visit')) { - return false; - } - - const method = this.prototype[methodName]; - if (typeof method !== 'function') { - return false; - } - - if (this.name === 'SchemaVisitor') { - // The SchemaVisitor class implements every visitor method. - return true; - } - - const stub = SchemaVisitor.prototype[methodName]; - if (method === stub) { - // If this.prototype[methodName] was just inherited from SchemaVisitor, - // then this class does not really implement the method. - return false; - } - - return true; - } - - // Concrete subclasses of SchemaVisitor should override one or more of these - // visitor methods, in order to express their interest in handling certain - // schema types/locations. Each method may return null to remove the given - // type from the schema, a non-null value of the same type to update the - // type in the schema, or nothing to leave the type as it was. - - // eslint-disable-next-line @typescript-eslint/no-empty-function - public visitSchema(_schema: GraphQLSchema): void {} - - public visitScalar( - _scalar: GraphQLScalarType - // eslint-disable-next-line @typescript-eslint/no-empty-function - ): GraphQLScalarType | void | null {} - - public visitObject( - _object: GraphQLObjectType - // eslint-disable-next-line @typescript-eslint/no-empty-function - ): GraphQLObjectType | void | null {} - - public visitFieldDefinition( - _field: GraphQLField, - _details: { - objectType: GraphQLObjectType | GraphQLInterfaceType; - } - // eslint-disable-next-line @typescript-eslint/no-empty-function - ): GraphQLField | void | null {} - - public visitArgumentDefinition( - _argument: GraphQLArgument, - _details: { - field: GraphQLField; - objectType: GraphQLObjectType | GraphQLInterfaceType; - } - // eslint-disable-next-line @typescript-eslint/no-empty-function - ): GraphQLArgument | void | null {} - - public visitInterface( - _iface: GraphQLInterfaceType - // eslint-disable-next-line @typescript-eslint/no-empty-function - ): GraphQLInterfaceType | void | null {} - - // eslint-disable-next-line @typescript-eslint/no-empty-function - public visitUnion(_union: GraphQLUnionType): GraphQLUnionType | void | null {} - - // eslint-disable-next-line @typescript-eslint/no-empty-function - public visitEnum(_type: GraphQLEnumType): GraphQLEnumType | void | null {} - - public visitEnumValue( - _value: GraphQLEnumValue, - _details: { - enumType: GraphQLEnumType; - } - // eslint-disable-next-line @typescript-eslint/no-empty-function - ): GraphQLEnumValue | void | null {} - - public visitInputObject( - _object: GraphQLInputObjectType - // eslint-disable-next-line @typescript-eslint/no-empty-function - ): GraphQLInputObjectType | void | null {} - - public visitInputFieldDefinition( - _field: GraphQLInputField, - _details: { - objectType: GraphQLInputObjectType; - } - // eslint-disable-next-line @typescript-eslint/no-empty-function - ): GraphQLInputField | void | null {} -} diff --git a/packages/utils/src/addTypes.ts b/packages/utils/src/addTypes.ts index 849b5f52681..ae4859c3c2d 100644 --- a/packages/utils/src/addTypes.ts +++ b/packages/utils/src/addTypes.ts @@ -33,6 +33,7 @@ import { GraphQLDirective, isNamedType, isDirective, + isObjectType, } from 'graphql'; import { rewireTypes } from './rewire'; @@ -50,35 +51,44 @@ export function addTypes( const config = schema.toConfig(); - const originalTypeMap = {}; - config.types.forEach(type => { + const originalTypeMap: Record = {}; + for (const type of config.types) { originalTypeMap[type.name] = type; - }); + } - const originalDirectiveMap = {}; - config.directives.forEach(directive => { + const originalDirectiveMap: Record = {}; + for (const directive of config.directives) { originalDirectiveMap[directive.name] = directive; - }); + } - newTypesOrDirectives.forEach(newTypeOrDirective => { + for (const newTypeOrDirective of newTypesOrDirectives) { if (isNamedType(newTypeOrDirective)) { originalTypeMap[newTypeOrDirective.name] = newTypeOrDirective; } else if (isDirective(newTypeOrDirective)) { originalDirectiveMap[newTypeOrDirective.name] = newTypeOrDirective; } - }); + } - const { typeMap, directives } = rewireTypes( - originalTypeMap, - Object.keys(originalDirectiveMap).map(directiveName => originalDirectiveMap[directiveName]) - ); + const { typeMap, directives } = rewireTypes(originalTypeMap, Object.values(originalDirectiveMap)); return new GraphQLSchema({ ...config, - query: queryTypeName ? (typeMap[queryTypeName] as GraphQLObjectType) : undefined, - mutation: mutationTypeName ? (typeMap[mutationTypeName] as GraphQLObjectType) : undefined, - subscription: subscriptionTypeName != null ? (typeMap[subscriptionTypeName] as GraphQLObjectType) : undefined, - types: Object.keys(typeMap).map(typeName => typeMap[typeName]), + query: getObjectTypeFromTypeMap(typeMap, queryTypeName), + mutation: getObjectTypeFromTypeMap(typeMap, mutationTypeName), + subscription: getObjectTypeFromTypeMap(typeMap, subscriptionTypeName), + types: Object.values(typeMap), directives, }); } + +export function getObjectTypeFromTypeMap( + typeMap: Record, + typeName?: string +): GraphQLObjectType | undefined { + if (typeName) { + const maybeObjectType = typeMap[typeName]; + if (isObjectType(maybeObjectType)) { + return maybeObjectType; + } + } +} diff --git a/packages/utils/src/astFromValueUntyped.ts b/packages/utils/src/astFromValueUntyped.ts index d11ed47ccd4..a7ed8213702 100644 --- a/packages/utils/src/astFromValueUntyped.ts +++ b/packages/utils/src/astFromValueUntyped.ts @@ -15,7 +15,7 @@ import { Kind, ObjectFieldNode, ValueNode } from 'graphql'; * | null | NullValue | * */ -export function astFromValueUntyped(value: any): ValueNode { +export function astFromValueUntyped(value: any): ValueNode | null { // only explicit null, not undefined, NaN if (value === null) { return { kind: Kind.NULL }; @@ -30,18 +30,19 @@ export function astFromValueUntyped(value: any): ValueNode { // the value is not an array, convert the value using the list's item type. if (Array.isArray(value)) { const valuesNodes: Array = []; - value.forEach(item => { + for (const item of value) { const itemNode = astFromValueUntyped(item); if (itemNode != null) { valuesNodes.push(itemNode); } - }); + } return { kind: Kind.LIST, values: valuesNodes }; } if (typeof value === 'object') { const fieldNodes: Array = []; - Object.entries(value).forEach(([fieldName, fieldValue]) => { + for (const fieldName in value) { + const fieldValue = value[fieldName]; const ast = astFromValueUntyped(fieldValue); if (ast) { fieldNodes.push({ @@ -50,7 +51,7 @@ export function astFromValueUntyped(value: any): ValueNode { value: ast, }); } - }); + } return { kind: Kind.OBJECT, fields: fieldNodes }; } diff --git a/packages/utils/src/build-operation-for-field.ts b/packages/utils/src/build-operation-for-field.ts index 3209968d150..87652876f51 100644 --- a/packages/utils/src/build-operation-for-field.ts +++ b/packages/utils/src/build-operation-for-field.ts @@ -27,7 +27,6 @@ import { isEnumType, Kind, } from 'graphql'; -import { camelCase } from 'camel-case'; let operationVariables: VariableDefinitionNode[] = []; let fieldTypeMap = new Map(); @@ -44,10 +43,6 @@ function resetFieldMap() { fieldTypeMap = new Map(); } -function buildOperationName(name: string) { - return camelCase(name); -} - export type Skip = string[]; export type Force = string[]; export type Ignore = string[]; @@ -131,15 +126,15 @@ function buildOperationAndCollectVariables({ }; const type = typeMap[kind]; const field = type.getFields()[fieldName]; - const operationName = buildOperationName(`${fieldName}_${kind}`); + const operationName = `${fieldName}_${kind}`; if (field.args) { - field.args.forEach(arg => { + for (const arg of field.args) { const argName = arg.name; if (!argNames || argNames.includes(argName)) { addOperationVariable(resolveVariable(arg, argName)); } - }); + } } return { @@ -340,15 +335,13 @@ function resolveSelectionSet({ } return null; }) - .filter(f => { - if (f) { - if ('selectionSet' in f) { - return f.selectionSet?.selections?.length; - } else { - return true; - } + .filter((f): f is SelectionNode => { + if (f == null) { + return false; + } else if ('selectionSet' in f) { + return !!f.selectionSet?.selections?.length; } - return false; + return true; }), }; } @@ -396,7 +389,7 @@ function resolveVariable(arg: GraphQLArgument, name?: string): VariableDefinitio } function getArgumentName(name: string, path: string[]): string { - return camelCase([...path, name].join('_')); + return [...path, name].join('_'); } function resolveField({ diff --git a/packages/utils/src/collectFields.ts b/packages/utils/src/collectFields.ts index aef6ab5d9b9..120121c3d32 100644 --- a/packages/utils/src/collectFields.ts +++ b/packages/utils/src/collectFields.ts @@ -83,13 +83,13 @@ function shouldIncludeNode( ): boolean { const skip = getDirectiveValues(GraphQLSkipDirective, node, exeContext.variableValues); - if (skip?.if === true) { + if (skip?.['if'] === true) { return false; } const include = getDirectiveValues(GraphQLIncludeDirective, node, exeContext.variableValues); - if (include?.if === false) { + if (include?.['if'] === false) { return false; } diff --git a/packages/utils/src/create-schema-definition.ts b/packages/utils/src/create-schema-definition.ts index dbb974c2338..a685aff021f 100644 --- a/packages/utils/src/create-schema-definition.ts +++ b/packages/utils/src/create-schema-definition.ts @@ -9,7 +9,7 @@ export function createSchemaDefinition( config?: { force?: boolean; } -): string { +): string | undefined { const schemaRoot: { query?: string; mutation?: string; diff --git a/packages/utils/src/debug-log.ts b/packages/utils/src/debug-log.ts deleted file mode 100644 index 8478cc07ea2..00000000000 --- a/packages/utils/src/debug-log.ts +++ /dev/null @@ -1,6 +0,0 @@ -export function debugLog(...args: any[]): void { - if (process && process.env && process.env.DEBUG && !process.env.GQL_tools_NODEBUG) { - // tslint:disable-next-line: no-console - console.log(...args); - } -} diff --git a/packages/utils/src/executor.ts b/packages/utils/src/executor.ts index 7ff1d6422a8..ac89baeb322 100644 --- a/packages/utils/src/executor.ts +++ b/packages/utils/src/executor.ts @@ -1,39 +1,50 @@ import { DocumentNode, GraphQLResolveInfo } from 'graphql'; import { ExecutionResult } from './Interfaces'; -export interface ExecutionParams, TContext = any> { +type MaybePromise = Promise | T; +type MaybeAsyncIterableIterator = AsyncIterableIterator | T; + +export interface ExecutionParams< + TArgs extends Record = Record, + TContext = any, + TRootValue = any, + TExtensions = Record +> { document: DocumentNode; variables?: TArgs; - extensions?: Record; + extensions?: TExtensions; context?: TContext; info?: GraphQLResolveInfo; + rootValue?: TRootValue; + operationName?: string; } -export type AsyncExecutor> = < - TReturn = Record, +export type AsyncExecutor, TBaseExtensions = Record> = < + TReturn = any, TArgs = Record, - TContext extends TBaseContext = TBaseContext + TContext extends TBaseContext = TBaseContext, + TRoot = any, + TExtensions extends TBaseExtensions = TBaseExtensions >( - params: ExecutionParams -) => Promise>; -export type SyncExecutor> = < - TReturn = Record, + params: ExecutionParams +) => Promise>>; + +export type SyncExecutor, TBaseExtensions = Record> = < + TReturn = any, TArgs = Record, - TContext extends TBaseContext = TBaseContext + TContext extends TBaseContext = TBaseContext, + TRoot = any, + TExtensions extends TBaseExtensions = TBaseExtensions >( - params: ExecutionParams + params: ExecutionParams ) => ExecutionResult; -export type Executor> = < - TReturn = Record, - TArgs = Record, - TContext extends TBaseContext = TBaseContext ->( - params: ExecutionParams -) => ExecutionResult | Promise>; -export type Subscriber> = < - TReturn = Record, + +export type Executor, TBaseExtensions = Record> = < + TReturn = any, TArgs = Record, - TContext extends TBaseContext = TBaseContext + TContext extends TBaseContext = TBaseContext, + TRoot = any, + TExtensions extends TBaseExtensions = TBaseExtensions >( - params: ExecutionParams -) => Promise> | ExecutionResult>; + params: ExecutionParams +) => MaybePromise>>; diff --git a/packages/utils/src/fields.ts b/packages/utils/src/fields.ts index 15a16eaca10..e33180753e6 100644 --- a/packages/utils/src/fields.ts +++ b/packages/utils/src/fields.ts @@ -24,12 +24,13 @@ export function appendObjectFields( const originalFieldConfigMap = config.fields; const newFieldConfigMap = {}; - Object.keys(originalFieldConfigMap).forEach(fieldName => { + + for (const fieldName in originalFieldConfigMap) { newFieldConfigMap[fieldName] = originalFieldConfigMap[fieldName]; - }); - Object.keys(additionalFields).forEach(fieldName => { + } + for (const fieldName in additionalFields) { newFieldConfigMap[fieldName] = additionalFields[fieldName]; - }); + } return correctASTNodes( new GraphQLObjectType({ @@ -55,14 +56,14 @@ export function removeObjectFields( const originalFieldConfigMap = config.fields; const newFieldConfigMap = {}; - Object.keys(originalFieldConfigMap).forEach(fieldName => { + for (const fieldName in originalFieldConfigMap) { const originalFieldConfig = originalFieldConfigMap[fieldName]; if (testFn(fieldName, originalFieldConfig)) { removedFields[fieldName] = originalFieldConfig; } else { newFieldConfigMap[fieldName] = originalFieldConfig; } - }); + } return correctASTNodes( new GraphQLObjectType({ @@ -89,12 +90,12 @@ export function selectObjectFields( const config = type.toConfig(); const originalFieldConfigMap = config.fields; - Object.keys(originalFieldConfigMap).forEach(fieldName => { + for (const fieldName in originalFieldConfigMap) { const originalFieldConfig = originalFieldConfigMap[fieldName]; if (testFn(fieldName, originalFieldConfig)) { selectedFields[fieldName] = originalFieldConfig; } - }); + } } return undefined; @@ -118,19 +119,19 @@ export function modifyObjectFields( const originalFieldConfigMap = config.fields; const newFieldConfigMap = {}; - Object.keys(originalFieldConfigMap).forEach(fieldName => { + for (const fieldName in originalFieldConfigMap) { const originalFieldConfig = originalFieldConfigMap[fieldName]; if (testFn(fieldName, originalFieldConfig)) { removedFields[fieldName] = originalFieldConfig; } else { newFieldConfigMap[fieldName] = originalFieldConfig; } - }); + } - Object.keys(newFields).forEach(fieldName => { + for (const fieldName in newFields) { const fieldConfig = newFields[fieldName]; newFieldConfigMap[fieldName] = fieldConfig; - }); + } return correctASTNodes( new GraphQLObjectType({ diff --git a/packages/utils/src/filterSchema.ts b/packages/utils/src/filterSchema.ts index 5941bd21d7b..74e04b06232 100644 --- a/packages/utils/src/filterSchema.ts +++ b/packages/utils/src/filterSchema.ts @@ -81,17 +81,18 @@ function filterRootFields( ): GraphQLObjectType { if (rootFieldFilter || argumentFilter) { const config = type.toConfig(); - Object.entries(config.fields).forEach(([fieldName, field]) => { + for (const fieldName in config.fields) { + const field = config.fields[fieldName]; if (rootFieldFilter && !rootFieldFilter(operation, fieldName, config.fields[fieldName])) { delete config.fields[fieldName]; - } else if (argumentFilter) { - for (const argName of Object.keys(field.args)) { + } else if (argumentFilter && field.args) { + for (const argName in field.args) { if (!argumentFilter(operation, fieldName, argName, field.args[argName])) { delete field.args[argName]; } } } - }); + } return new GraphQLObjectType(config); } return type; @@ -105,17 +106,18 @@ function filterElementFields( ): ElementType | undefined { if (fieldFilter || argumentFilter) { const config = type.toConfig(); - Object.entries(config.fields).forEach(([fieldName, field]) => { + for (const fieldName in config.fields) { + const field = config.fields[fieldName]; if (fieldFilter && !fieldFilter(type.name, fieldName, config.fields[fieldName])) { delete config.fields[fieldName]; } else if (argumentFilter && 'args' in field) { - for (const argName of Object.keys(field.args)) { + for (const argName in field.args) { if (!argumentFilter(type.name, fieldName, argName, field.args[argName])) { delete field.args[argName]; } } } - }); + } return new ElementConstructor(config); } } diff --git a/packages/utils/src/fix-schema-ast.ts b/packages/utils/src/fix-schema-ast.ts index efccdff9e74..acf7739a848 100644 --- a/packages/utils/src/fix-schema-ast.ts +++ b/packages/utils/src/fix-schema-ast.ts @@ -10,15 +10,16 @@ function buildFixedSchema(schema: GraphQLSchema, options: BuildSchemaOptions & S } export function fixSchemaAst(schema: GraphQLSchema, options: BuildSchemaOptions & SchemaPrintOptions) { - let schemaWithValidAst: GraphQLSchema; + // eslint-disable-next-line no-undef-init + let schemaWithValidAst: GraphQLSchema | undefined = undefined; if (!schema.astNode || !schema.extensionASTNodes) { schemaWithValidAst = buildFixedSchema(schema, options); } - if (!schema.astNode) { + if (!schema.astNode && schemaWithValidAst?.astNode) { schema.astNode = schemaWithValidAst.astNode; } - if (!schema.extensionASTNodes) { + if (!schema.extensionASTNodes && schemaWithValidAst?.astNode) { schema.extensionASTNodes = schemaWithValidAst.extensionASTNodes; } return schema; diff --git a/packages/utils/src/fix-windows-path.ts b/packages/utils/src/fix-windows-path.ts deleted file mode 100644 index 746bed0a8d0..00000000000 --- a/packages/utils/src/fix-windows-path.ts +++ /dev/null @@ -1 +0,0 @@ -export const fixWindowsPath = (path: string) => path.replace(/\\/g, '/'); diff --git a/packages/utils/src/flatten-array.ts b/packages/utils/src/flatten-array.ts deleted file mode 100644 index 094f04f4918..00000000000 --- a/packages/utils/src/flatten-array.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const flattenArray = (arr: any): any[] => - arr.reduce((acc: any, next: any) => acc.concat(Array.isArray(next) ? flattenArray(next) : next), []); diff --git a/packages/utils/src/forEachDefaultValue.ts b/packages/utils/src/forEachDefaultValue.ts index 4d15403c186..4ff70bc5a4c 100644 --- a/packages/utils/src/forEachDefaultValue.ts +++ b/packages/utils/src/forEachDefaultValue.ts @@ -4,26 +4,26 @@ import { IDefaultValueIteratorFn } from './Interfaces'; export function forEachDefaultValue(schema: GraphQLSchema, fn: IDefaultValueIteratorFn): void { const typeMap = schema.getTypeMap(); - Object.keys(typeMap).forEach(typeName => { + for (const typeName in typeMap) { const type = typeMap[typeName]; if (!getNamedType(type).name.startsWith('__')) { if (isObjectType(type)) { const fields = type.getFields(); - Object.keys(fields).forEach(fieldName => { + for (const fieldName in fields) { const field = fields[fieldName]; - field.args.forEach(arg => { + for (const arg of field.args) { arg.defaultValue = fn(arg.type, arg.defaultValue); - }); - }); + } + } } else if (isInputObjectType(type)) { const fields = type.getFields(); - Object.keys(fields).forEach(fieldName => { + for (const fieldName in fields) { const field = fields[fieldName]; field.defaultValue = fn(field.type, field.defaultValue); - }); + } } } - }); + } } diff --git a/packages/utils/src/forEachField.ts b/packages/utils/src/forEachField.ts index f6795c8d2c5..a59a9a969cb 100644 --- a/packages/utils/src/forEachField.ts +++ b/packages/utils/src/forEachField.ts @@ -4,16 +4,16 @@ import { IFieldIteratorFn } from './Interfaces'; export function forEachField(schema: GraphQLSchema, fn: IFieldIteratorFn): void { const typeMap = schema.getTypeMap(); - Object.keys(typeMap).forEach(typeName => { + for (const typeName in typeMap) { const type = typeMap[typeName]; // TODO: maybe have an option to include these? if (!getNamedType(type).name.startsWith('__') && isObjectType(type)) { const fields = type.getFields(); - Object.keys(fields).forEach(fieldName => { + for (const fieldName in fields) { const field = fields[fieldName]; fn(field, typeName, fieldName); - }); + } } - }); + } } diff --git a/packages/utils/src/get-directives.ts b/packages/utils/src/get-directives.ts index c96b0965602..d0afe8fb287 100644 --- a/packages/utils/src/get-directives.ts +++ b/packages/utils/src/get-directives.ts @@ -23,6 +23,7 @@ import { GraphQLEnumValueConfig, EnumValueDefinitionNode, } from 'graphql'; +import { Maybe } from '@graphql-tools/utils'; import { getArgumentValues } from './getArgumentValues'; @@ -57,7 +58,7 @@ type DirectableGraphQLObject = export function getDirectivesInExtensions( node: DirectableGraphQLObject, pathToDirectivesInExtensions = ['directives'] -): DirectiveUseMap { +): Maybe { const directivesInExtensions = pathToDirectivesInExtensions.reduce( (acc, pathSegment) => (acc == null ? acc : acc[pathSegment]), node?.extensions @@ -95,9 +96,9 @@ export function getDirectives( const result: DirectiveUseMap = {}; - astNodes.forEach(astNode => { + for (const astNode of astNodes) { if (astNode.directives) { - astNode.directives.forEach(directiveNode => { + for (const directiveNode of astNode.directives) { const schemaDirective = schemaDirectiveMap[directiveNode.name.value]; if (schemaDirective) { if (schemaDirective.isRepeatable) { @@ -107,9 +108,9 @@ export function getDirectives( result[schemaDirective.name] = getArgumentValues(schemaDirective, directiveNode); } } - }); + } } - }); + } return result; } diff --git a/packages/utils/src/get-fields-with-directives.ts b/packages/utils/src/get-fields-with-directives.ts index 19b3ca5f72c..5f6eeb9d311 100644 --- a/packages/utils/src/get-fields-with-directives.ts +++ b/packages/utils/src/get-fields-with-directives.ts @@ -60,6 +60,10 @@ export function getFieldsWithDirectives(documentNode: DocumentNode, options: Opt for (const type of allTypes) { const typeName = type.name.value; + if (type.fields == null) { + continue; + } + for (const field of type.fields) { if (field.directives && field.directives.length > 0) { const fieldName = field.name.value; diff --git a/packages/utils/src/get-user-types-from-schema.ts b/packages/utils/src/get-user-types-from-schema.ts index 9f3583740a1..d0b6f8e51c2 100644 --- a/packages/utils/src/get-user-types-from-schema.ts +++ b/packages/utils/src/get-user-types-from-schema.ts @@ -12,19 +12,22 @@ export function getUserTypesFromSchema(schema: GraphQLSchema): GraphQLObjectType const allTypesMap = schema.getTypeMap(); // tslint:disable-next-line: no-unnecessary-local-variable - const modelTypes = Object.values(allTypesMap).filter((graphqlType: GraphQLObjectType) => { + const modelTypes = Object.values(allTypesMap).filter((graphqlType): graphqlType is GraphQLObjectType => { if (isObjectType(graphqlType)) { // Filter out private types if (graphqlType.name.startsWith('__')) { return false; } - if (schema.getMutationType() && graphqlType.name === schema.getMutationType().name) { + const schemaMutationType = schema.getMutationType(); + if (schemaMutationType && graphqlType.name === schemaMutationType.name) { return false; } - if (schema.getQueryType() && graphqlType.name === schema.getQueryType().name) { + const schemaQueryType = schema.getMutationType(); + if (schemaQueryType && graphqlType.name === schemaQueryType.name) { return false; } - if (schema.getSubscriptionType() && graphqlType.name === schema.getSubscriptionType().name) { + const schemaSubscriptionType = schema.getMutationType(); + if (schemaSubscriptionType && graphqlType.name === schemaSubscriptionType.name) { return false; } @@ -34,5 +37,5 @@ export function getUserTypesFromSchema(schema: GraphQLSchema): GraphQLObjectType return false; }); - return modelTypes as GraphQLObjectType[]; + return modelTypes; } diff --git a/packages/utils/src/getArgumentValues.ts b/packages/utils/src/getArgumentValues.ts index f3e64b6afd4..1ad1003b6e6 100644 --- a/packages/utils/src/getArgumentValues.ts +++ b/packages/utils/src/getArgumentValues.ts @@ -11,7 +11,7 @@ import { ArgumentNode, } from 'graphql'; -import { inspect } from './inspect'; +import { inspect } from 'util'; /** * Prepares an object map of argument values given a list of argument diff --git a/packages/utils/src/getResolversFromSchema.ts b/packages/utils/src/getResolversFromSchema.ts index 2f0a1746e5d..deeb1814836 100644 --- a/packages/utils/src/getResolversFromSchema.ts +++ b/packages/utils/src/getResolversFromSchema.ts @@ -16,7 +16,7 @@ export function getResolversFromSchema(schema: GraphQLSchema): IResolvers { const typeMap = schema.getTypeMap(); - Object.keys(typeMap).forEach(typeName => { + for (const typeName in typeMap) { if (!typeName.startsWith('__')) { const type = typeMap[typeName]; @@ -30,9 +30,9 @@ export function getResolversFromSchema(schema: GraphQLSchema): IResolvers { resolvers[typeName] = {}; const values = type.getValues(); - values.forEach(value => { + for (const value of values) { resolvers[typeName][value.name] = value.value; - }); + } } else if (isInterfaceType(type)) { if (type.resolveType != null) { resolvers[typeName] = { @@ -53,20 +53,24 @@ export function getResolversFromSchema(schema: GraphQLSchema): IResolvers { } const fields = type.getFields(); - Object.keys(fields).forEach(fieldName => { + for (const fieldName in fields) { const field = fields[fieldName]; if (field.subscribe != null) { resolvers[typeName][fieldName] = resolvers[typeName][fieldName] || {}; resolvers[typeName][fieldName].subscribe = field.subscribe; } - if (field.resolve != null && field.resolve?.name !== 'defaultFieldResolver' && field.resolve?.name !== 'defaultMergedResolver') { + if ( + field.resolve != null && + field.resolve?.name !== 'defaultFieldResolver' && + field.resolve?.name !== 'defaultMergedResolver' + ) { resolvers[typeName][fieldName] = resolvers[typeName][fieldName] || {}; resolvers[typeName][fieldName].resolve = field.resolve; } - }); + } } } - }); + } return resolvers; } diff --git a/packages/utils/src/heal.ts b/packages/utils/src/heal.ts index 73a00cbf224..f0dd92fc8b3 100644 --- a/packages/utils/src/heal.ts +++ b/packages/utils/src/heal.ts @@ -66,14 +66,15 @@ export function healTypes( // schema.getTypeMap() have changed, the keys of the type map need to // be updated accordingly. - Object.entries(originalTypeMap).forEach(([typeName, namedType]) => { + for (const typeName in originalTypeMap) { + const namedType = originalTypeMap[typeName]; if (namedType == null || typeName.startsWith('__')) { - return; + continue; } const actualName = namedType.name; if (actualName.startsWith('__')) { - return; + continue; } if (actualName in actualNamedTypeMap) { @@ -85,31 +86,33 @@ export function healTypes( // Note: we are deliberately leaving namedType in the schema by its // original name (which might be different from actualName), so that // references by that name can be healed. - }); + } // Now add back every named type by its actual name. - Object.entries(actualNamedTypeMap).forEach(([typeName, namedType]) => { + for (const typeName in actualNamedTypeMap) { + const namedType = actualNamedTypeMap[typeName]; originalTypeMap[typeName] = namedType; - }); + } // Directive declaration argument types can refer to named types. - directives.forEach((decl: GraphQLDirective) => { + for (const decl of directives) { decl.args = decl.args.filter(arg => { arg.type = healType(arg.type) as GraphQLInputType; return arg.type !== null; }); - }); + } - Object.entries(originalTypeMap).forEach(([typeName, namedType]) => { + for (const typeName in originalTypeMap) { + const namedType = originalTypeMap[typeName]; // Heal all named types, except for dangling references, kept only to redirect. if (!typeName.startsWith('__') && typeName in actualNamedTypeMap) { if (namedType != null) { healNamedType(namedType); } } - }); + } - for (const typeName of Object.keys(originalTypeMap)) { + for (const typeName in originalTypeMap) { if (!typeName.startsWith('__') && !(typeName in actualNamedTypeMap)) { delete originalTypeMap[typeName]; } diff --git a/packages/utils/src/helpers.ts b/packages/utils/src/helpers.ts index 9bf75a42409..fbcdea600c5 100644 --- a/packages/utils/src/helpers.ts +++ b/packages/utils/src/helpers.ts @@ -48,27 +48,30 @@ export function isValidPath(str: string): boolean { } export function compareStrings(a: A, b: B) { - if (a.toString() < b.toString()) { + if (String(a) < String(b)) { return -1; } - if (a.toString() > b.toString()) { + if (String(a) > String(b)) { return 1; } return 0; } -export function nodeToString(a: ASTNode) { +export function nodeToString(a: ASTNode): string { + let name: string | undefined; if ('alias' in a) { - return a.alias.value; + name = a.alias?.value; } - - if ('name' in a) { - return a.name.value; + if (name == null && 'name' in a) { + name = a.name?.value; + } + if (name == null) { + name = a.kind; } - return a.kind; + return name; } export function compareNodes(a: ASTNode, b: ASTNode, customFn?: (a: any, b: any) => number) { @@ -81,3 +84,16 @@ export function compareNodes(a: ASTNode, b: ASTNode, customFn?: (a: any, b: any) return compareStrings(aStr, bStr); } + +export function isSome(input: T): input is Exclude { + return input != null; +} + +export function assertSome( + input: T, + message = 'Value should be something' +): asserts input is Exclude { + if (input == null) { + throw new Error(message); + } +} diff --git a/packages/utils/src/implementsAbstractType.ts b/packages/utils/src/implementsAbstractType.ts index f2b2630346e..c8554a8a59d 100644 --- a/packages/utils/src/implementsAbstractType.ts +++ b/packages/utils/src/implementsAbstractType.ts @@ -1,7 +1,10 @@ import { GraphQLType, GraphQLSchema, doTypesOverlap, isCompositeType } from 'graphql'; +import { Maybe } from '@graphql-tools/utils'; -export function implementsAbstractType(schema: GraphQLSchema, typeA: GraphQLType, typeB: GraphQLType) { - if (typeA === typeB) { +export function implementsAbstractType(schema: GraphQLSchema, typeA: Maybe, typeB: Maybe) { + if (typeB == null || typeA == null) { + return false; + } else if (typeA === typeB) { return true; } else if (isCompositeType(typeA) && isCompositeType(typeB)) { return doTypesOverlap(schema, typeA, typeB); diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index 531c3a96ea9..5fc559f2755 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -1,8 +1,5 @@ export * from './loaders'; export * from './helpers'; -export * from './debug-log'; -export * from './fix-windows-path'; -export * from './flatten-array'; export * from './get-directives'; export * from './get-fields-with-directives'; export * from './get-implementing-types'; @@ -19,9 +16,6 @@ export * from './types'; export * from './filterSchema'; export * from './clone'; export * from './heal'; -export * from './SchemaVisitor'; -export * from './SchemaDirectiveVisitor'; -export * from './visitSchema'; export * from './getResolversFromSchema'; export * from './forEachField'; export * from './forEachDefaultValue'; @@ -42,7 +36,6 @@ export * from './mapAsyncIterator'; export * from './updateArgument'; export * from './implementsAbstractType'; export * from './errors'; -export * from './toConfig'; export * from './observableToAsyncIterable'; export * from './visitResult'; export * from './getArgumentValues'; @@ -52,3 +45,4 @@ export * from './isDocumentNode'; export * from './astFromValueUntyped'; export * from './executor'; export * from './withCancel'; +export * from './AggregateError'; diff --git a/packages/utils/src/inspect.ts b/packages/utils/src/inspect.ts deleted file mode 100644 index 9f2f474e324..00000000000 --- a/packages/utils/src/inspect.ts +++ /dev/null @@ -1,113 +0,0 @@ -const MAX_ARRAY_LENGTH = 10; -const MAX_RECURSIVE_DEPTH = 2; - -/** - * Used to print values in error messages. - */ -export function inspect(value: any): string { - return formatValue(value, []); -} - -function formatValue(value: any, seenValues: Array): string { - switch (typeof value) { - case 'string': - return JSON.stringify(value); - case 'function': - return value.name ? `[function ${(value as (...args: any[]) => any).name}]` : '[function]'; - case 'object': - if (value === null) { - return 'null'; - } - return formatObjectValue(value, seenValues); - default: - return String(value); - } -} - -function formatObjectValue(value: any, previouslySeenValues: Array): string { - if (previouslySeenValues.indexOf(value) !== -1) { - return '[Circular]'; - } - - const seenValues = [...previouslySeenValues, value]; - const customInspectFn = getCustomFn(value); - - if (customInspectFn !== undefined) { - const customValue = customInspectFn.call(value); - - // check for infinite recursion - if (customValue !== value) { - return typeof customValue === 'string' ? customValue : formatValue(customValue, seenValues); - } - } else if (Array.isArray(value)) { - return formatArray(value, seenValues); - } - - return formatObject(value, seenValues); -} - -function formatObject(object: any, seenValues: Array) { - const keys = Object.keys(object); - if (keys.length === 0) { - return '{}'; - } - - if (seenValues.length > MAX_RECURSIVE_DEPTH) { - return '[' + getObjectTag(object) + ']'; - } - - const properties = keys.map(key => { - const value = formatValue(object[key], seenValues); - return key + ': ' + value; - }); - - return '{ ' + properties.join(', ') + ' }'; -} - -function formatArray(array: Array, seenValues: Array): string { - if (array.length === 0) { - return '[]'; - } - - if (seenValues.length > MAX_RECURSIVE_DEPTH) { - return '[Array]'; - } - - const len = Math.min(MAX_ARRAY_LENGTH, array.length); - const remaining = array.length - len; - const items = []; - - for (let i = 0; i < len; ++i) { - items.push(formatValue(array[i], seenValues)); - } - - if (remaining === 1) { - items.push('... 1 more item'); - } else if (remaining > 1) { - items.push(`... ${remaining.toString(10)} more items`); - } - - return '[' + items.join(', ') + ']'; -} - -function getCustomFn(obj: any) { - if (typeof obj.inspect === 'function') { - return obj.inspect; - } -} - -function getObjectTag(obj: any): string { - const tag = Object.prototype.toString - .call(obj) - .replace(/^\[object /, '') - .replace(/]$/, ''); - - if (tag === 'Object' && typeof obj.constructor === 'function') { - const name = obj.constructor.name; - if (typeof name === 'string' && name !== '') { - return name; - } - } - - return tag; -} diff --git a/packages/utils/src/loaders.ts b/packages/utils/src/loaders.ts index 21a1eb2b485..56efc329de4 100644 --- a/packages/utils/src/loaders.ts +++ b/packages/utils/src/loaders.ts @@ -27,8 +27,8 @@ export interface Loader; resolveGlobsSync?(globs: ResolverGlobs, options?: TOptions): TPointer[]; - load(pointer: TPointer, options?: TOptions): Promise; - loadSync?(pointer: TPointer, options?: TOptions): Source | never; + load(pointer: TPointer, options?: TOptions): Promise; + loadSync?(pointer: TPointer, options?: TOptions): Source | null | never; } export type SchemaLoader = Loader< diff --git a/packages/utils/src/mapSchema.ts b/packages/utils/src/mapSchema.ts index 656d8424127..d80b8e1284b 100644 --- a/packages/utils/src/mapSchema.ts +++ b/packages/utils/src/mapSchema.ts @@ -29,6 +29,7 @@ import { Kind, EnumValueDefinitionNode, } from 'graphql'; +import { getObjectTypeFromTypeMap } from './addTypes'; import { SchemaMapper, @@ -40,22 +41,37 @@ import { IDefaultValueIteratorFn, ArgumentMapper, EnumValueMapper, + SchemaFieldMapperTypes, } from './Interfaces'; import { rewireTypes } from './rewire'; import { serializeInputValue, parseInputValue } from './transformInputValue'; export function mapSchema(schema: GraphQLSchema, schemaMapper: SchemaMapper = {}): GraphQLSchema { - const originalTypeMap = schema.getTypeMap(); - - let newTypeMap = mapDefaultValues(originalTypeMap, schema, serializeInputValue); - newTypeMap = mapTypes(newTypeMap, schema, schemaMapper, type => isLeafType(type)); - newTypeMap = mapEnumValues(newTypeMap, schema, schemaMapper); - newTypeMap = mapDefaultValues(newTypeMap, schema, parseInputValue); - - newTypeMap = mapTypes(newTypeMap, schema, schemaMapper, type => !isLeafType(type)); - newTypeMap = mapFields(newTypeMap, schema, schemaMapper); - newTypeMap = mapArguments(newTypeMap, schema, schemaMapper); + const newTypeMap = mapArguments( + mapFields( + mapTypes( + mapDefaultValues( + mapEnumValues( + mapTypes(mapDefaultValues(schema.getTypeMap(), schema, serializeInputValue), schema, schemaMapper, type => + isLeafType(type) + ), + schema, + schemaMapper + ), + schema, + parseInputValue + ), + schema, + schemaMapper, + type => !isLeafType(type) + ), + schema, + schemaMapper + ), + schema, + schemaMapper + ); const originalDirectives = schema.getDirectives(); const newDirectives = mapDirectives(originalDirectives, schema, schemaMapper); @@ -64,29 +80,18 @@ export function mapSchema(schema: GraphQLSchema, schemaMapper: SchemaMapper = {} const mutationType = schema.getMutationType(); const subscriptionType = schema.getSubscriptionType(); - const newQueryTypeName = - queryType != null ? (newTypeMap[queryType.name] != null ? newTypeMap[queryType.name].name : undefined) : undefined; - const newMutationTypeName = - mutationType != null - ? newTypeMap[mutationType.name] != null - ? newTypeMap[mutationType.name].name - : undefined - : undefined; - const newSubscriptionTypeName = - subscriptionType != null - ? newTypeMap[subscriptionType.name] != null - ? newTypeMap[subscriptionType.name].name - : undefined - : undefined; + const newQueryTypeName = queryType?.name && newTypeMap?.[queryType?.name]?.name; + const newMutationTypeName = mutationType?.name && newTypeMap?.[mutationType?.name]?.name; + const newSubscriptionTypeName = subscriptionType?.name && newTypeMap?.[subscriptionType?.name]?.name; const { typeMap, directives } = rewireTypes(newTypeMap, newDirectives); return new GraphQLSchema({ ...schema.toConfig(), - query: newQueryTypeName ? (typeMap[newQueryTypeName] as GraphQLObjectType) : undefined, - mutation: newMutationTypeName ? (typeMap[newMutationTypeName] as GraphQLObjectType) : undefined, - subscription: newSubscriptionTypeName != null ? (typeMap[newSubscriptionTypeName] as GraphQLObjectType) : undefined, - types: Object.keys(typeMap).map(typeName => typeMap[typeName]), + query: getObjectTypeFromTypeMap(typeMap, newQueryTypeName), + mutation: getObjectTypeFromTypeMap(typeMap, newMutationTypeName), + subscription: getObjectTypeFromTypeMap(typeMap, newSubscriptionTypeName), + types: Object.values(typeMap), directives, }); } @@ -99,32 +104,32 @@ function mapTypes( ): TypeMap { const newTypeMap = {}; - Object.keys(originalTypeMap).forEach(typeName => { + for (const typeName in originalTypeMap) { if (!typeName.startsWith('__')) { const originalType = originalTypeMap[typeName]; if (originalType == null || !testFn(originalType)) { newTypeMap[typeName] = originalType; - return; + continue; } const typeMapper = getTypeMapper(schema, schemaMapper, typeName); if (typeMapper == null) { newTypeMap[typeName] = originalType; - return; + continue; } const maybeNewType = typeMapper(originalType, schema); if (maybeNewType === undefined) { newTypeMap[typeName] = originalType; - return; + continue; } newTypeMap[typeName] = maybeNewType; } - }); + } return newTypeMap; } @@ -143,7 +148,7 @@ function mapEnumValues(originalTypeMap: TypeMap, schema: GraphQLSchema, schemaMa const config = type.toConfig(); const originalEnumValueConfigMap = config.values; const newEnumValueConfigMap = {}; - Object.keys(originalEnumValueConfigMap).forEach(externalValue => { + for (const externalValue in originalEnumValueConfigMap) { const originalEnumValueConfig = originalEnumValueConfigMap[externalValue]; const mappedEnumValue = enumValueMapper(originalEnumValueConfig, type.name, schema, externalValue); if (mappedEnumValue === undefined) { @@ -155,7 +160,7 @@ function mapEnumValues(originalTypeMap: TypeMap, schema: GraphQLSchema, schemaMa } else if (mappedEnumValue !== null) { newEnumValueConfigMap[externalValue] = mappedEnumValue; } - }); + } return correctASTNodes( new GraphQLEnumType({ ...config, @@ -220,26 +225,26 @@ function getNewType(newTypeMap: TypeMap, type: T): T | nu function mapFields(originalTypeMap: TypeMap, schema: GraphQLSchema, schemaMapper: SchemaMapper): TypeMap { const newTypeMap = {}; - Object.keys(originalTypeMap).forEach(typeName => { + for (const typeName in originalTypeMap) { if (!typeName.startsWith('__')) { const originalType = originalTypeMap[typeName]; if (!isObjectType(originalType) && !isInterfaceType(originalType) && !isInputObjectType(originalType)) { newTypeMap[typeName] = originalType; - return; + continue; } const fieldMapper = getFieldMapper(schema, schemaMapper, typeName); if (fieldMapper == null) { newTypeMap[typeName] = originalType; - return; + continue; } const config = originalType.toConfig(); const originalFieldConfigMap = config.fields; const newFieldConfigMap = {}; - Object.keys(originalFieldConfigMap).forEach(fieldName => { + for (const fieldName in originalFieldConfigMap) { const originalFieldConfig = originalFieldConfigMap[fieldName]; const mappedField = fieldMapper(originalFieldConfig, fieldName, typeName, schema); if (mappedField === undefined) { @@ -259,7 +264,7 @@ function mapFields(originalTypeMap: TypeMap, schema: GraphQLSchema, schemaMapper } else if (mappedField !== null) { newFieldConfigMap[fieldName] = mappedField; } - }); + } if (isObjectType(originalType)) { newTypeMap[typeName] = correctASTNodes( @@ -284,7 +289,7 @@ function mapFields(originalTypeMap: TypeMap, schema: GraphQLSchema, schemaMapper ); } } - }); + } return newTypeMap; } @@ -292,44 +297,44 @@ function mapFields(originalTypeMap: TypeMap, schema: GraphQLSchema, schemaMapper function mapArguments(originalTypeMap: TypeMap, schema: GraphQLSchema, schemaMapper: SchemaMapper): TypeMap { const newTypeMap = {}; - Object.keys(originalTypeMap).forEach(typeName => { + for (const typeName in originalTypeMap) { if (!typeName.startsWith('__')) { const originalType = originalTypeMap[typeName]; if (!isObjectType(originalType) && !isInterfaceType(originalType)) { newTypeMap[typeName] = originalType; - return; + continue; } const argumentMapper = getArgumentMapper(schemaMapper); if (argumentMapper == null) { newTypeMap[typeName] = originalType; - return; + continue; } const config = originalType.toConfig(); const originalFieldConfigMap = config.fields; const newFieldConfigMap = {}; - Object.keys(originalFieldConfigMap).forEach(fieldName => { + for (const fieldName in originalFieldConfigMap) { const originalFieldConfig = originalFieldConfigMap[fieldName]; const originalArgumentConfigMap = originalFieldConfig.args; if (originalArgumentConfigMap == null) { newFieldConfigMap[fieldName] = originalFieldConfig; - return; + continue; } const argumentNames = Object.keys(originalArgumentConfigMap); if (!argumentNames.length) { newFieldConfigMap[fieldName] = originalFieldConfig; - return; + continue; } const newArgumentConfigMap = {}; - argumentNames.forEach(argumentName => { + for (const argumentName of argumentNames) { const originalArgumentConfig = originalArgumentConfigMap[argumentName]; const mappedArgument = argumentMapper(originalArgumentConfig, fieldName, typeName, schema); @@ -342,31 +347,32 @@ function mapArguments(originalTypeMap: TypeMap, schema: GraphQLSchema, schemaMap } else if (mappedArgument !== null) { newArgumentConfigMap[argumentName] = mappedArgument; } - }); + } + newFieldConfigMap[fieldName] = { ...originalFieldConfig, args: newArgumentConfigMap, }; - }); + } if (isObjectType(originalType)) { newTypeMap[typeName] = new GraphQLObjectType({ - ...((config as unknown) as GraphQLObjectTypeConfig), + ...(config as unknown as GraphQLObjectTypeConfig), fields: newFieldConfigMap, }); } else if (isInterfaceType(originalType)) { newTypeMap[typeName] = new GraphQLInterfaceType({ - ...((config as unknown) as GraphQLInterfaceTypeConfig), + ...(config as unknown as GraphQLInterfaceTypeConfig), fields: newFieldConfigMap, }); } else { newTypeMap[typeName] = new GraphQLInputObjectType({ - ...((config as unknown) as GraphQLInputObjectTypeConfig), + ...(config as unknown as GraphQLInputObjectTypeConfig), fields: newFieldConfigMap, }); } } - }); + } return newTypeMap; } @@ -383,14 +389,14 @@ function mapDirectives( const newDirectives: Array = []; - originalDirectives.forEach(directive => { + for (const directive of originalDirectives) { const mappedDirective = directiveMapper(directive, schema); if (mappedDirective === undefined) { newDirectives.push(directive); } else if (mappedDirective !== null) { newDirectives.push(mappedDirective); } - }); + } return newDirectives; } @@ -431,16 +437,17 @@ function getTypeMapper(schema: GraphQLSchema, schemaMapper: SchemaMapper, typeNa let typeMapper: NamedTypeMapper | undefined; const stack = [...specifiers]; while (!typeMapper && stack.length > 0) { - const next = stack.pop(); + // It is safe to use the ! operator here as we check the length. + const next = stack.pop()!; typeMapper = schemaMapper[next] as NamedTypeMapper; } return typeMapper != null ? typeMapper : null; } -function getFieldSpecifiers(schema: GraphQLSchema, typeName: string): Array { +function getFieldSpecifiers(schema: GraphQLSchema, typeName: string): SchemaFieldMapperTypes { const type = schema.getType(typeName); - const specifiers = [MapperKind.FIELD]; + const specifiers: SchemaFieldMapperTypes = [MapperKind.FIELD]; if (isObjectType(type)) { specifiers.push(MapperKind.COMPOSITE_FIELD, MapperKind.OBJECT_FIELD); @@ -472,11 +479,13 @@ function getFieldMapper | GraphQLInputFie let fieldMapper: GenericFieldMapper | undefined; const stack = [...specifiers]; while (!fieldMapper && stack.length > 0) { - const next = stack.pop(); - fieldMapper = schemaMapper[next] as GenericFieldMapper; + // It is safe to use the ! operator here as we check the length. + const next = stack.pop()!; + // TODO: fix this as unknown cast + fieldMapper = schemaMapper[next] as unknown as GenericFieldMapper; } - return fieldMapper != null ? fieldMapper : null; + return fieldMapper ?? null; } function getArgumentMapper(schemaMapper: SchemaMapper): ArgumentMapper | null { @@ -503,11 +512,14 @@ export function correctASTNodes(type: GraphQLNamedType): GraphQLNamedType { const config = (type as GraphQLObjectType).toConfig(); if (config.astNode != null) { const fields: Array = []; - Object.values(config.fields).forEach(fieldConfig => { + for (const fieldName in config.fields) { + const fieldConfig = config.fields[fieldName]; + if (fieldConfig.astNode != null) { fields.push(fieldConfig.astNode); } - }); + } + config.astNode = { ...config.astNode, kind: Kind.OBJECT_TYPE_DEFINITION, @@ -528,11 +540,13 @@ export function correctASTNodes(type: GraphQLNamedType): GraphQLNamedType { const config = (type as GraphQLInterfaceType).toConfig(); if (config.astNode != null) { const fields: Array = []; - Object.values(config.fields).forEach(fieldConfig => { + for (const fieldName in config.fields) { + const fieldConfig = config.fields[fieldName]; + if (fieldConfig.astNode != null) { fields.push(fieldConfig.astNode); } - }); + } config.astNode = { ...config.astNode, kind: Kind.INTERFACE_TYPE_DEFINITION, @@ -553,11 +567,13 @@ export function correctASTNodes(type: GraphQLNamedType): GraphQLNamedType { const config = (type as GraphQLInputObjectType).toConfig(); if (config.astNode != null) { const fields: Array = []; - Object.values(config.fields).forEach(fieldConfig => { + for (const fieldName in config.fields) { + const fieldConfig = config.fields[fieldName]; + if (fieldConfig.astNode != null) { fields.push(fieldConfig.astNode); } - }); + } config.astNode = { ...config.astNode, kind: Kind.INPUT_OBJECT_TYPE_DEFINITION, @@ -578,11 +594,12 @@ export function correctASTNodes(type: GraphQLNamedType): GraphQLNamedType { const config = (type as GraphQLEnumType).toConfig(); if (config.astNode != null) { const values: Array = []; - Object.values(config.values).forEach(enumValueConfig => { + for (const enumKey in config.values) { + const enumValueConfig = config.values[enumKey]; if (enumValueConfig.astNode != null) { values.push(enumValueConfig.astNode); } - }); + } config.astNode = { ...config.astNode, values, diff --git a/packages/utils/src/mergeDeep.ts b/packages/utils/src/mergeDeep.ts index 041a7ac1af8..79a7b3a241e 100644 --- a/packages/utils/src/mergeDeep.ts +++ b/packages/utils/src/mergeDeep.ts @@ -1,3 +1,4 @@ +import { isSome } from './helpers'; import { isScalarType } from 'graphql'; type BoxedTupleTypes = { [P in keyof T]: [T[P]] }[Exclude]; @@ -9,7 +10,7 @@ export function mergeDeep( ...sources: S ): T & UnboxIntersection>> & any { if (isScalarType(target)) { - return target as any; + return target; } const output = {}; Object.setPrototypeOf(output, Object.create(Object.getPrototypeOf(target))); @@ -18,10 +19,12 @@ export function mergeDeep( const outputPrototype = Object.getPrototypeOf(output); const sourcePrototype = Object.getPrototypeOf(source); if (sourcePrototype) { - Object.getOwnPropertyNames(sourcePrototype).forEach(key => { + for (const key of Object.getOwnPropertyNames(sourcePrototype)) { const descriptor = Object.getOwnPropertyDescriptor(sourcePrototype, key); - Object.defineProperty(outputPrototype, key, descriptor); - }); + if (isSome(descriptor)) { + Object.defineProperty(outputPrototype, key, descriptor); + } + } } for (const key in source) { diff --git a/packages/utils/src/observableToAsyncIterable.ts b/packages/utils/src/observableToAsyncIterable.ts index 09d5f00ca16..62c256c7559 100644 --- a/packages/utils/src/observableToAsyncIterable.ts +++ b/packages/utils/src/observableToAsyncIterable.ts @@ -5,9 +5,7 @@ export interface Observer { } export interface Observable { - subscribe( - observer: Observer - ): { + subscribe(observer: Observer): { unsubscribe: () => void; }; } @@ -22,7 +20,8 @@ export function observableToAsyncIterable(observable: Observable): AsyncIt const pushValue = (value: any) => { if (pullQueue.length !== 0) { - pullQueue.shift()({ value, done: false }); + // It is safe to use the ! operator here as we check the length. + pullQueue.shift()!({ value, done: false }); } else { pushQueue.push({ value, done: false }); } @@ -30,7 +29,8 @@ export function observableToAsyncIterable(observable: Observable): AsyncIt const pushError = (error: any) => { if (pullQueue.length !== 0) { - pullQueue.shift()({ value: { errors: [error] }, done: false }); + // It is safe to use the ! operator here as we check the length. + pullQueue.shift()!({ value: { errors: [error] }, done: false }); } else { pushQueue.push({ value: { errors: [error] }, done: false }); } @@ -38,14 +38,15 @@ export function observableToAsyncIterable(observable: Observable): AsyncIt const pushDone = () => { if (pullQueue.length !== 0) { - pullQueue.shift()({ done: true }); + // It is safe to use the ! operator here as we check the length. + pullQueue.shift()!({ done: true }); } else { pushQueue.push({ done: true }); } }; const pullValue = () => - new Promise(resolve => { + new Promise>(resolve => { if (pushQueue.length !== 0) { const element = pushQueue.shift(); // either {value: {errors: [...]}} or {value: ...} @@ -71,7 +72,9 @@ export function observableToAsyncIterable(observable: Observable): AsyncIt if (listening) { listening = false; subscription.unsubscribe(); - pullQueue.forEach(resolve => resolve({ value: undefined, done: true })); + for (const resolve of pullQueue) { + resolve({ value: undefined, done: true }); + } pullQueue.length = 0; pushQueue.length = 0; } @@ -79,7 +82,8 @@ export function observableToAsyncIterable(observable: Observable): AsyncIt return { next() { - return listening ? pullValue() : this.return(); + // return is a defined method, so it is safe to call it. + return listening ? pullValue() : this.return!(); }, return() { emptyQueue(); diff --git a/packages/utils/src/parse-graphql-sdl.ts b/packages/utils/src/parse-graphql-sdl.ts index f8fd4eb8378..6f22cf9ed55 100644 --- a/packages/utils/src/parse-graphql-sdl.ts +++ b/packages/utils/src/parse-graphql-sdl.ts @@ -13,12 +13,11 @@ import { import { dedentBlockStringValue } from 'graphql/language/blockString.js'; import { GraphQLParseOptions } from './Interfaces'; -export function parseGraphQLSDL(location: string, rawSDL: string, options: GraphQLParseOptions = {}) { +export function parseGraphQLSDL(location: string | undefined, rawSDL: string, options: GraphQLParseOptions = {}) { let document: DocumentNode; - const sdl: string = rawSDL; try { - if (options.commentDescriptions && sdl.includes('#')) { + if (options.commentDescriptions && rawSDL.includes('#')) { document = transformCommentsToDescriptions(rawSDL, options); // If noLocation=true, we need to make sure to print and parse it again, to remove locations, @@ -28,10 +27,10 @@ export function parseGraphQLSDL(location: string, rawSDL: string, options: Graph document = parse(print(document), options); } } else { - document = parse(new GraphQLSource(sdl, location), options); + document = parse(new GraphQLSource(rawSDL, location), options); } } catch (e) { - if (e.message.includes('EOF') && sdl.replace(/(\#[^*]*)/g, '').trim() === '') { + if (e.message.includes('EOF') && rawSDL.replace(/(\#[^*]*)/g, '').trim() === '') { document = { kind: Kind.DOCUMENT, definitions: [], @@ -42,6 +41,7 @@ export function parseGraphQLSDL(location: string, rawSDL: string, options: Graph } return { + rawSDL, location, document, }; @@ -73,10 +73,7 @@ export function getLeadingCommentBlock(node: ASTNode): void | string { return comments.length > 0 ? comments.reverse().join('\n') : undefined; } -export function transformCommentsToDescriptions( - sourceSdl: string, - options: GraphQLParseOptions = {} -): DocumentNode | null { +export function transformCommentsToDescriptions(sourceSdl: string, options: GraphQLParseOptions = {}): DocumentNode { const parsedDoc = parse(sourceSdl, { ...options, noLocation: false, diff --git a/packages/utils/src/print-schema-with-directives.ts b/packages/utils/src/print-schema-with-directives.ts index a7d98477b51..d89f09e1958 100644 --- a/packages/utils/src/print-schema-with-directives.ts +++ b/packages/utils/src/print-schema-with-directives.ts @@ -44,15 +44,16 @@ import { EnumTypeDefinitionNode, GraphQLScalarType, ScalarTypeDefinitionNode, - StringValueNode, DefinitionNode, DocumentNode, + StringValueNode, } from 'graphql'; -import { GetDocumentNodeFromSchemaOptions, PrintSchemaWithDirectivesOptions } from './types'; +import { GetDocumentNodeFromSchemaOptions, PrintSchemaWithDirectivesOptions, Maybe } from './types'; import { astFromType } from './astFromType'; import { getDirectivesInExtensions } from './get-directives'; import { astFromValueUntyped } from './astFromValueUntyped'; +import { isSome } from './helpers'; export function getDocumentNodeFromSchema( schema: GraphQLSchema, @@ -118,37 +119,39 @@ export function printSchemaWithDirectives( export function astFromSchema( schema: GraphQLSchema, - pathToDirectivesInExtensions: Array -): SchemaDefinitionNode | SchemaExtensionNode { - const operationTypeMap: Record = { + pathToDirectivesInExtensions?: Array +): SchemaDefinitionNode | SchemaExtensionNode | null { + const operationTypeMap: Record> = { query: undefined, mutation: undefined, subscription: undefined, }; - let nodes: Array = []; + const nodes: Array = []; if (schema.astNode != null) { nodes.push(schema.astNode); } if (schema.extensionASTNodes != null) { - nodes = nodes.concat(schema.extensionASTNodes); + for (const extensionASTNode of schema.extensionASTNodes) { + nodes.push(extensionASTNode); + } } - nodes.forEach(node => { + for (const node of nodes) { if (node.operationTypes) { - node.operationTypes.forEach(operationTypeDefinitionNode => { + for (const operationTypeDefinitionNode of node.operationTypes) { operationTypeMap[operationTypeDefinitionNode.operation] = operationTypeDefinitionNode; - }); + } } - }); + } - const rootTypeMap: Record = { + const rootTypeMap: Record> = { query: schema.getQueryType(), mutation: schema.getMutationType(), subscription: schema.getSubscriptionType(), }; - Object.keys(operationTypeMap).forEach(operationTypeNode => { + for (const operationTypeNode in operationTypeMap) { if (rootTypeMap[operationTypeNode] != null) { if (operationTypeMap[operationTypeNode] != null) { operationTypeMap[operationTypeNode].type = astFromType(rootTypeMap[operationTypeNode]); @@ -160,11 +163,9 @@ export function astFromSchema( }; } } - }); + } - const operationTypes = Object.values(operationTypeMap).filter( - operationTypeDefinitionNode => operationTypeDefinitionNode != null - ); + const operationTypes = Object.values(operationTypeMap).filter(isSome); const directives = getDirectiveNodes(schema, schema, pathToDirectivesInExtensions); @@ -178,12 +179,14 @@ export function astFromSchema( directives, }; - ((schemaNode as unknown) as { description: StringValueNode }).description = - ((schema.astNode as unknown) as { description: string })?.description ?? - ((schema as unknown) as { description: string }).description != null + // This code is so weird because it needs to support GraphQL.js 14 + // In GraphQL.js 14 there is no `description` value on schemaNode + (schemaNode as unknown as { description?: StringValueNode }).description = + (schema.astNode as unknown as { description: string })?.description ?? + (schema as unknown as { description: string }).description != null ? { kind: Kind.STRING, - value: ((schema as unknown) as { description: string }).description, + value: (schema as unknown as { description: string }).description, block: true, } : undefined; @@ -219,14 +222,14 @@ export function astFromDirective( kind: Kind.NAME, value: location, })) - : undefined, + : [], }; } export function getDirectiveNodes( entity: GraphQLSchema | GraphQLNamedType | GraphQLEnumValue, schema: GraphQLSchema, - pathToDirectivesInExtensions: Array + pathToDirectivesInExtensions?: Array ): Array { const directivesInExtensions = getDirectivesInExtensions(entity, pathToDirectivesInExtensions); @@ -244,7 +247,12 @@ export function getDirectiveNodes( if (directivesInExtensions != null) { directives = makeDirectiveNodes(schema, directivesInExtensions); } else { - directives = [].concat(...nodes.filter(node => node.directives != null).map(node => node.directives)); + directives = []; + for (const node of nodes) { + if (node.directives) { + directives.push(...node.directives); + } + } } return directives; @@ -252,15 +260,15 @@ export function getDirectiveNodes( export function getDeprecatableDirectiveNodes( entity: GraphQLArgument | GraphQLField | GraphQLInputField, - schema: GraphQLSchema, - pathToDirectivesInExtensions: Array + schema?: GraphQLSchema, + pathToDirectivesInExtensions?: Array ): Array { let directiveNodesBesidesDeprecated: Array = []; - let deprecatedDirectiveNode: DirectiveNode; + let deprecatedDirectiveNode: Maybe = null; const directivesInExtensions = getDirectivesInExtensions(entity, pathToDirectivesInExtensions); - let directives: ReadonlyArray; + let directives: Maybe>; if (directivesInExtensions != null) { directives = makeDirectiveNodes(schema, directivesInExtensions); } else { @@ -269,17 +277,17 @@ export function getDeprecatableDirectiveNodes( if (directives != null) { directiveNodesBesidesDeprecated = directives.filter(directive => directive.name.value !== 'deprecated'); - if (((entity as unknown) as { deprecationReason: string }).deprecationReason != null) { + if ((entity as unknown as { deprecationReason: string }).deprecationReason != null) { deprecatedDirectiveNode = directives.filter(directive => directive.name.value === 'deprecated')?.[0]; } } if ( - ((entity as unknown) as { deprecationReason: string }).deprecationReason != null && + (entity as unknown as { deprecationReason: string }).deprecationReason != null && deprecatedDirectiveNode == null ) { deprecatedDirectiveNode = makeDeprecatedDirective( - ((entity as unknown) as { deprecationReason: string }).deprecationReason + (entity as unknown as { deprecationReason: string }).deprecationReason ); } @@ -290,25 +298,26 @@ export function getDeprecatableDirectiveNodes( export function astFromArg( arg: GraphQLArgument, - schema: GraphQLSchema, - pathToDirectivesInExtensions: Array + schema?: GraphQLSchema, + pathToDirectivesInExtensions?: Array ): InputValueDefinitionNode { return { kind: Kind.INPUT_VALUE_DEFINITION, description: - arg.astNode?.description ?? arg.description + arg.astNode?.description ?? + (arg.description ? { kind: Kind.STRING, value: arg.description, block: true, } - : undefined, + : undefined), name: { kind: Kind.NAME, value: arg.name, }, type: astFromType(arg.type), - defaultValue: arg.defaultValue !== undefined ? astFromValue(arg.defaultValue, arg.type) : undefined, + defaultValue: arg.defaultValue !== undefined ? astFromValue(arg.defaultValue, arg.type) ?? undefined : undefined, directives: getDeprecatableDirectiveNodes(arg, schema, pathToDirectivesInExtensions), }; } @@ -316,18 +325,19 @@ export function astFromArg( export function astFromObjectType( type: GraphQLObjectType, schema: GraphQLSchema, - pathToDirectivesInExtensions: Array + pathToDirectivesInExtensions?: Array ): ObjectTypeDefinitionNode { return { kind: Kind.OBJECT_TYPE_DEFINITION, description: - type.astNode?.description ?? type.description + type.astNode?.description ?? + (type.description ? { kind: Kind.STRING, value: type.description, block: true, } - : undefined, + : undefined), name: { kind: Kind.NAME, value: type.name, @@ -341,18 +351,19 @@ export function astFromObjectType( export function astFromInterfaceType( type: GraphQLInterfaceType, schema: GraphQLSchema, - pathToDirectivesInExtensions: Array + pathToDirectivesInExtensions?: Array ): InterfaceTypeDefinitionNode { - const node = { + const node: InterfaceTypeDefinitionNode = { kind: Kind.INTERFACE_TYPE_DEFINITION, description: - type.astNode?.description ?? type.description + type.astNode?.description ?? + (type.description ? { kind: Kind.STRING, value: type.description, block: true, } - : undefined, + : undefined), name: { kind: Kind.NAME, value: type.name, @@ -362,8 +373,8 @@ export function astFromInterfaceType( }; if ('getInterfaces' in type) { - ((node as unknown) as { interfaces: Array }).interfaces = Object.values( - ((type as unknown) as GraphQLObjectType).getInterfaces() + (node as unknown as { interfaces: Array }).interfaces = Object.values( + (type as unknown as GraphQLObjectType).getInterfaces() ).map(iFace => astFromType(iFace) as NamedTypeNode); } @@ -373,18 +384,19 @@ export function astFromInterfaceType( export function astFromUnionType( type: GraphQLUnionType, schema: GraphQLSchema, - pathToDirectivesInExtensions: Array + pathToDirectivesInExtensions?: Array ): UnionTypeDefinitionNode { return { kind: Kind.UNION_TYPE_DEFINITION, description: - type.astNode?.description ?? type.description + type.astNode?.description ?? + (type.description ? { kind: Kind.STRING, value: type.description, block: true, } - : undefined, + : undefined), name: { kind: Kind.NAME, value: type.name, @@ -397,18 +409,19 @@ export function astFromUnionType( export function astFromInputObjectType( type: GraphQLInputObjectType, schema: GraphQLSchema, - pathToDirectivesInExtensions: Array + pathToDirectivesInExtensions?: Array ): InputObjectTypeDefinitionNode { return { kind: Kind.INPUT_OBJECT_TYPE_DEFINITION, description: - type.astNode?.description ?? type.description + type.astNode?.description ?? + (type.description ? { kind: Kind.STRING, value: type.description, block: true, } - : undefined, + : undefined), name: { kind: Kind.NAME, value: type.name, @@ -423,18 +436,19 @@ export function astFromInputObjectType( export function astFromEnumType( type: GraphQLEnumType, schema: GraphQLSchema, - pathToDirectivesInExtensions: Array + pathToDirectivesInExtensions?: Array ): EnumTypeDefinitionNode { return { kind: Kind.ENUM_TYPE_DEFINITION, description: - type.astNode?.description ?? type.description + type.astNode?.description ?? + (type.description ? { kind: Kind.STRING, value: type.description, block: true, } - : undefined, + : undefined), name: { kind: Kind.NAME, value: type.name, @@ -447,14 +461,14 @@ export function astFromEnumType( export function astFromScalarType( type: GraphQLScalarType, schema: GraphQLSchema, - pathToDirectivesInExtensions: Array + pathToDirectivesInExtensions?: Array ): ScalarTypeDefinitionNode { let directiveNodesBesidesSpecifiedBy: Array = []; - let specifiedByDirectiveNode: DirectiveNode; + let specifiedByDirectiveNode: Maybe = null; const directivesInExtensions = getDirectivesInExtensions(type, pathToDirectivesInExtensions); - let allDirectives: ReadonlyArray; + let allDirectives: Maybe>; if (directivesInExtensions != null) { allDirectives = makeDirectiveNodes(schema, directivesInExtensions); } else { @@ -463,14 +477,14 @@ export function astFromScalarType( if (allDirectives != null) { directiveNodesBesidesSpecifiedBy = allDirectives.filter(directive => directive.name.value !== 'specifiedBy'); - if (((type as unknown) as { specifiedByUrl: string }).specifiedByUrl != null) { + if ((type as unknown as { specifiedByUrl: string }).specifiedByUrl != null) { specifiedByDirectiveNode = allDirectives.filter(directive => directive.name.value === 'specifiedBy')?.[0]; } } - if (((type as unknown) as { specifiedByUrl: string }).specifiedByUrl != null && specifiedByDirectiveNode == null) { + if ((type as unknown as { specifiedByUrl: string }).specifiedByUrl != null && specifiedByDirectiveNode == null) { specifiedByDirectiveNode = makeDirectiveNode('specifiedBy', { - url: ((type as unknown) as { specifiedByUrl: string }).specifiedByUrl, + url: (type as unknown as { specifiedByUrl: string }).specifiedByUrl, }); } @@ -482,13 +496,14 @@ export function astFromScalarType( return { kind: Kind.SCALAR_TYPE_DEFINITION, description: - type.astNode?.description ?? type.description + type.astNode?.description ?? + (type.description ? { kind: Kind.STRING, value: type.description, block: true, } - : undefined, + : undefined), name: { kind: Kind.NAME, value: type.name, @@ -500,18 +515,19 @@ export function astFromScalarType( export function astFromField( field: GraphQLField, schema: GraphQLSchema, - pathToDirectivesInExtensions: Array + pathToDirectivesInExtensions?: Array ): FieldDefinitionNode { return { kind: Kind.FIELD_DEFINITION, description: - field.astNode?.description ?? field.description + field.astNode?.description ?? + (field.description ? { kind: Kind.STRING, value: field.description, block: true, } - : undefined, + : undefined), name: { kind: Kind.NAME, value: field.name, @@ -525,43 +541,45 @@ export function astFromField( export function astFromInputField( field: GraphQLInputField, schema: GraphQLSchema, - pathToDirectivesInExtensions: Array + pathToDirectivesInExtensions?: Array ): InputValueDefinitionNode { return { kind: Kind.INPUT_VALUE_DEFINITION, description: - field.astNode?.description ?? field.description + field.astNode?.description ?? + (field.description ? { kind: Kind.STRING, value: field.description, block: true, } - : undefined, + : undefined), name: { kind: Kind.NAME, value: field.name, }, type: astFromType(field.type), directives: getDeprecatableDirectiveNodes(field, schema, pathToDirectivesInExtensions), - defaultValue: astFromValue(field.defaultValue, field.type), + defaultValue: astFromValue(field.defaultValue, field.type) ?? undefined, }; } export function astFromEnumValue( value: GraphQLEnumValue, schema: GraphQLSchema, - pathToDirectivesInExtensions: Array + pathToDirectivesInExtensions?: Array ): EnumValueDefinitionNode { return { kind: Kind.ENUM_VALUE_DEFINITION, description: - value.astNode?.description ?? value.description + value.astNode?.description ?? + (value.description ? { kind: Kind.STRING, value: value.description, block: true, } - : undefined, + : undefined), name: { kind: Kind.NAME, value: value.name, @@ -577,36 +595,43 @@ export function makeDeprecatedDirective(deprecationReason: string): DirectiveNod export function makeDirectiveNode( name: string, args: Record, - directive?: GraphQLDirective + directive?: Maybe ): DirectiveNode { const directiveArguments: Array = []; if (directive != null) { - directive.args.forEach(arg => { + for (const arg of directive.args) { const argName = arg.name; const argValue = args[argName]; if (argValue !== undefined) { + const value = astFromValue(argValue, arg.type); + if (value) { + directiveArguments.push({ + kind: Kind.ARGUMENT, + name: { + kind: Kind.NAME, + value: argName, + }, + value, + }); + } + } + } + } else { + for (const argName in args) { + const argValue = args[argName]; + const value = astFromValueUntyped(argValue); + if (value) { directiveArguments.push({ kind: Kind.ARGUMENT, name: { kind: Kind.NAME, value: argName, }, - value: astFromValue(argValue, arg.type), + value, }); } - }); - } else { - Object.entries(args).forEach(([argName, argValue]) => { - directiveArguments.push({ - kind: Kind.ARGUMENT, - name: { - kind: Kind.NAME, - value: argName, - }, - value: astFromValueUntyped(argValue), - }); - }); + } } return { @@ -619,17 +644,21 @@ export function makeDirectiveNode( }; } -export function makeDirectiveNodes(schema: GraphQLSchema, directiveValues: Record): Array { +export function makeDirectiveNodes( + schema: Maybe, + directiveValues: Record +): Array { const directiveNodes: Array = []; - Object.entries(directiveValues).forEach(([directiveName, arrayOrSingleValue]) => { + for (const directiveName in directiveValues) { + const arrayOrSingleValue = directiveValues[directiveName]; const directive = schema?.getDirective(directiveName); if (Array.isArray(arrayOrSingleValue)) { - arrayOrSingleValue.forEach(value => { + for (const value of arrayOrSingleValue) { directiveNodes.push(makeDirectiveNode(directiveName, value, directive)); - }); + } } else { directiveNodes.push(makeDirectiveNode(directiveName, arrayOrSingleValue, directive)); } - }); + } return directiveNodes; } diff --git a/packages/utils/src/prune.ts b/packages/utils/src/prune.ts index 0bd5cff45f1..7be287cf9a8 100644 --- a/packages/utils/src/prune.ts +++ b/packages/utils/src/prune.ts @@ -18,6 +18,7 @@ import { PruneSchemaOptions } from './types'; import { mapSchema } from './mapSchema'; import { MapperKind } from './Interfaces'; +import { isSome } from './helpers'; type NamedOutputType = | GraphQLObjectType @@ -45,18 +46,18 @@ export function pruneSchema(schema: GraphQLSchema, options: PruneSchemaOptions = implementations: Object.create(null), }; - Object.keys(schema.getTypeMap()).forEach(typeName => { + for (const typeName in schema.getTypeMap()) { const type = schema.getType(typeName); - if ('getInterfaces' in type) { - type.getInterfaces().forEach(iface => { + if (type && 'getInterfaces' in type) { + for (const iface of type.getInterfaces()) { const implementations = getImplementations(pruningContext, iface); if (implementations == null) { pruningContext.implementations[iface.name] = Object.create(null); } pruningContext.implementations[iface.name][type.name] = true; - }); + } } - }); + } visitTypes(pruningContext, schema); @@ -114,35 +115,36 @@ function visitOutputType( if (isObjectType(type) || isInterfaceType(type)) { const fields = type.getFields(); - Object.keys(fields).forEach(fieldName => { + for (const fieldName in fields) { const field = fields[fieldName]; const namedType = getNamedType(field.type) as NamedOutputType; visitOutputType(visitedTypes, pruningContext, namedType); - const args = field.args; - args.forEach(arg => { + for (const arg of field.args) { const type = getNamedType(arg.type) as NamedInputType; visitInputType(visitedTypes, pruningContext, type); - }); - }); + } + } if (isInterfaceType(type)) { const implementations = getImplementations(pruningContext, type); if (implementations) { - Object.keys(implementations).forEach(typeName => { + for (const typeName in implementations) { visitOutputType(visitedTypes, pruningContext, pruningContext.schema.getType(typeName) as NamedOutputType); - }); + } } } if ('getInterfaces' in type) { - type.getInterfaces().forEach(type => { - visitOutputType(visitedTypes, pruningContext, type); - }); + for (const iFace of type.getInterfaces()) { + visitOutputType(visitedTypes, pruningContext, iFace); + } } } else if (isUnionType(type)) { const types = type.getTypes(); - types.forEach(type => visitOutputType(visitedTypes, pruningContext, type)); + for (const type of types) { + visitOutputType(visitedTypes, pruningContext, type); + } } } @@ -170,33 +172,33 @@ function visitInputType( if (isInputObjectType(type)) { const fields = type.getFields(); - Object.keys(fields).forEach(fieldName => { + for (const fieldName in fields) { const field = fields[fieldName]; const namedType = getNamedType(field.type) as NamedInputType; visitInputType(visitedTypes, pruningContext, namedType); - }); + } } } function visitTypes(pruningContext: PruningContext, schema: GraphQLSchema): void { - Object.keys(schema.getTypeMap()).forEach(typeName => { + for (const typeName in schema.getTypeMap()) { if (!typeName.startsWith('__')) { pruningContext.unusedTypes[typeName] = true; } - }); + } const visitedTypes: Record = Object.create(null); - const rootTypes = [schema.getQueryType(), schema.getMutationType(), schema.getSubscriptionType()].filter( - type => type != null - ); + const rootTypes = [schema.getQueryType(), schema.getMutationType(), schema.getSubscriptionType()].filter(isSome); - rootTypes.forEach(rootType => visitOutputType(visitedTypes, pruningContext, rootType)); + for (const rootType of rootTypes) { + visitOutputType(visitedTypes, pruningContext, rootType); + } - schema.getDirectives().forEach(directive => { - directive.args.forEach(arg => { + for (const directive of schema.getDirectives()) { + for (const arg of directive.args) { const type = getNamedType(arg.type) as NamedInputType; visitInputType(visitedTypes, pruningContext, type); - }); - }); + } + } } diff --git a/packages/utils/src/rewire.ts b/packages/utils/src/rewire.ts index 930a8ee701f..45e6639d688 100644 --- a/packages/utils/src/rewire.ts +++ b/packages/utils/src/rewire.ts @@ -37,21 +37,21 @@ export function rewireTypes( directives: Array; } { const referenceTypeMap = Object.create(null); - Object.keys(originalTypeMap).forEach(typeName => { + for (const typeName in originalTypeMap) { referenceTypeMap[typeName] = originalTypeMap[typeName]; - }); + } const newTypeMap: TypeMap = Object.create(null); - Object.keys(referenceTypeMap).forEach(typeName => { + for (const typeName in referenceTypeMap) { const namedType = referenceTypeMap[typeName]; if (namedType == null || typeName.startsWith('__')) { - return; + continue; } const newName = namedType.name; if (newName.startsWith('__')) { - return; + continue; } if (newTypeMap[newName] != null) { @@ -59,11 +59,11 @@ export function rewireTypes( } newTypeMap[newName] = namedType; - }); + } - Object.keys(newTypeMap).forEach(typeName => { + for (const typeName in newTypeMap) { newTypeMap[typeName] = rewireNamedType(newTypeMap[typeName]); - }); + } const newDirectives = directives.map(directive => rewireDirective(directive)); @@ -83,14 +83,14 @@ export function rewireTypes( function rewireArgs(args: GraphQLFieldConfigArgumentMap): GraphQLFieldConfigArgumentMap { const rewiredArgs = {}; - Object.keys(args).forEach(argName => { + for (const argName in args) { const arg = args[argName]; const rewiredArgType = rewireType(arg.type); if (rewiredArgType != null) { arg.type = rewiredArgType; rewiredArgs[argName] = arg; } - }); + } return rewiredArgs; } @@ -111,7 +111,7 @@ export function rewireTypes( }; if ('interfaces' in newConfig) { newConfig.interfaces = () => - rewireNamedTypes(((config as unknown) as { interfaces: Array }).interfaces); + rewireNamedTypes((config as unknown as { interfaces: Array }).interfaces); } return new GraphQLInterfaceType(newConfig); } else if (isUnionType(type)) { @@ -139,44 +139,44 @@ export function rewireTypes( return new GraphQLScalarType(scalarConfig); } - throw new Error(`Unexpected schema type: ${(type as unknown) as string}`); + throw new Error(`Unexpected schema type: ${type as unknown as string}`); } function rewireFields(fields: GraphQLFieldConfigMap): GraphQLFieldConfigMap { const rewiredFields = {}; - Object.keys(fields).forEach(fieldName => { + for (const fieldName in fields) { const field = fields[fieldName]; const rewiredFieldType = rewireType(field.type); - if (rewiredFieldType != null) { + if (rewiredFieldType != null && field.args) { field.type = rewiredFieldType; field.args = rewireArgs(field.args); rewiredFields[fieldName] = field; } - }); + } return rewiredFields; } function rewireInputFields(fields: GraphQLInputFieldConfigMap): GraphQLInputFieldConfigMap { const rewiredFields = {}; - Object.keys(fields).forEach(fieldName => { + for (const fieldName in fields) { const field = fields[fieldName]; const rewiredFieldType = rewireType(field.type); if (rewiredFieldType != null) { field.type = rewiredFieldType; rewiredFields[fieldName] = field; } - }); + } return rewiredFields; } function rewireNamedTypes(namedTypes: Array): Array { const rewiredTypes: Array = []; - namedTypes.forEach(namedType => { + for (const namedType of namedTypes) { const rewiredType = rewireType(namedType); if (rewiredType != null) { rewiredTypes.push(rewiredType); } - }); + } return rewiredTypes; } diff --git a/packages/utils/src/stub.ts b/packages/utils/src/stub.ts index 1d6cbdb2c13..de72bbfa995 100644 --- a/packages/utils/src/stub.ts +++ b/packages/utils/src/stub.ts @@ -8,9 +8,6 @@ import { GraphQLFloat, GraphQLBoolean, GraphQLID, - isObjectType, - isInterfaceType, - isInputObjectType, TypeNode, Kind, GraphQLType, @@ -64,10 +61,13 @@ export function createStub(node: TypeNode, type: any): any { } export function isNamedStub(type: GraphQLNamedType): boolean { - if (isObjectType(type) || isInterfaceType(type) || isInputObjectType(type)) { + if ('getFields' in type) { const fields = type.getFields(); - const fieldNames = Object.keys(fields); - return fieldNames.length === 1 && fields[fieldNames[0]].name === '_fake'; + // eslint-disable-next-line no-unreachable-loop + for (const fieldName in fields) { + const field = fields[fieldName]; + return field.name === '_fake'; + } } return false; diff --git a/packages/utils/src/toConfig.ts b/packages/utils/src/toConfig.ts deleted file mode 100644 index 623b68395db..00000000000 --- a/packages/utils/src/toConfig.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { - GraphQLArgument, - GraphQLFieldConfigArgumentMap, - GraphQLField, - GraphQLInputField, - GraphQLInputFieldConfig, - GraphQLArgumentConfig, - GraphQLFieldConfig, -} from 'graphql'; - -export function inputFieldToFieldConfig(field: GraphQLInputField): GraphQLInputFieldConfig { - return { - description: field.description, - type: field.type, - defaultValue: field.defaultValue, - extensions: field.extensions, - astNode: field.astNode, - }; -} - -export function fieldToFieldConfig(field: GraphQLField): GraphQLFieldConfig { - return { - description: field.description, - type: field.type, - args: argsToFieldConfigArgumentMap(field.args), - resolve: field.resolve, - subscribe: field.subscribe, - deprecationReason: field.deprecationReason, - extensions: field.extensions, - astNode: field.astNode, - }; -} - -export function argsToFieldConfigArgumentMap(args: ReadonlyArray): GraphQLFieldConfigArgumentMap { - const newArguments = {}; - args.forEach(arg => { - newArguments[arg.name] = argumentToArgumentConfig(arg); - }); - - return newArguments; -} - -export function argumentToArgumentConfig(arg: GraphQLArgument): GraphQLArgumentConfig { - return { - description: arg.description, - type: arg.type, - defaultValue: arg.defaultValue, - extensions: arg.extensions, - astNode: arg.astNode, - }; -} diff --git a/packages/utils/src/transformInputValue.ts b/packages/utils/src/transformInputValue.ts index 6fa15c00ce4..530a0a7be19 100644 --- a/packages/utils/src/transformInputValue.ts +++ b/packages/utils/src/transformInputValue.ts @@ -1,12 +1,12 @@ import { GraphQLInputType, getNullableType, isLeafType, isListType, isInputObjectType } from 'graphql'; -import { InputLeafValueTransformer, InputObjectValueTransformer } from './types'; +import { InputLeafValueTransformer, InputObjectValueTransformer, Maybe } from './types'; export function transformInputValue( type: GraphQLInputType, value: any, - inputLeafValueTransformer: InputLeafValueTransformer = null, - inputObjectValueTransformer: InputObjectValueTransformer = null + inputLeafValueTransformer: Maybe = null, + inputObjectValueTransformer: Maybe = null ): any { if (value == null) { return value; @@ -23,7 +23,7 @@ export function transformInputValue( } else if (isInputObjectType(nullableType)) { const fields = nullableType.getFields(); const newValue = {}; - Object.keys(value).forEach(key => { + for (const key in value) { const field = fields[key]; if (field != null) { newValue[key] = transformInputValue( @@ -33,7 +33,7 @@ export function transformInputValue( inputObjectValueTransformer ); } - }); + } return inputObjectValueTransformer != null ? inputObjectValueTransformer(nullableType, newValue) : newValue; } diff --git a/packages/utils/src/validate-documents.ts b/packages/utils/src/validate-documents.ts index b2d429c8266..58df7024689 100644 --- a/packages/utils/src/validate-documents.ts +++ b/packages/utils/src/validate-documents.ts @@ -7,14 +7,17 @@ import { FragmentDefinitionNode, ValidationContext, ASTVisitor, + DefinitionNode, + concatAST, + DocumentNode, } from 'graphql'; import { Source } from './loaders'; -import AggregateError from '@ardatan/aggregate-error'; +import { AggregateError } from './AggregateError'; export type ValidationRule = (context: ValidationContext) => ASTVisitor; export interface LoadDocumentError { - readonly filePath: string; + readonly filePath?: string; readonly errors: ReadonlyArray; } @@ -24,39 +27,42 @@ export async function validateGraphQlDocuments( effectiveRules?: ValidationRule[] ): Promise> { effectiveRules = effectiveRules || createDefaultRules(); - const allFragments: FragmentDefinitionNode[] = []; + const allFragmentMap = new Map(); + const documentFileObjectsToValidate: { + location?: string; + document: DocumentNode; + }[] = []; - documentFiles.forEach(documentFile => { + for (const documentFile of documentFiles) { if (documentFile.document) { + const definitionsToValidate: DefinitionNode[] = []; for (const definitionNode of documentFile.document.definitions) { if (definitionNode.kind === Kind.FRAGMENT_DEFINITION) { - allFragments.push(definitionNode); + allFragmentMap.set(definitionNode.name.value, definitionNode); + } else { + definitionsToValidate.push(definitionNode); } } + documentFileObjectsToValidate.push({ + location: documentFile.location, + document: { + kind: Kind.DOCUMENT, + definitions: definitionsToValidate, + }, + }); } - }); + } const allErrors: LoadDocumentError[] = []; - await Promise.all( - documentFiles.map(async documentFile => { - const documentToValidate = { - kind: Kind.DOCUMENT, - definitions: [...allFragments, ...documentFile.document.definitions].filter((definition, index, list) => { - if (definition.kind === Kind.FRAGMENT_DEFINITION) { - const firstIndex = list.findIndex( - def => def.kind === Kind.FRAGMENT_DEFINITION && def.name.value === definition.name.value - ); - const isDuplicated = firstIndex !== index; - - if (isDuplicated) { - return false; - } - } + const allFragmentsDocument: DocumentNode = { + kind: Kind.DOCUMENT, + definitions: [...allFragmentMap.values()], + }; - return true; - }), - }; + await Promise.all( + documentFileObjectsToValidate.map(async documentFile => { + const documentToValidate = concatAST([allFragmentsDocument, documentFile.document]); const errors = validate(schema, documentToValidate, effectiveRules); @@ -82,26 +88,25 @@ export function checkValidationErrors(loadDocumentErrors: ReadonlyArray (error.stack += `\n at ${loadDocumentError.filePath}:${location.line}:${location.column}`) - ); + if (graphQLError.locations) { + for (const location of graphQLError.locations) { + error.stack += `\n at ${loadDocumentError.filePath}:${location.line}:${location.column}`; + } + } errors.push(error); } } - throw new AggregateError(errors); + throw new AggregateError(errors, 'Validation failed'); } } function createDefaultRules() { const ignored = ['NoUnusedFragmentsRule', 'NoUnusedVariablesRule', 'KnownDirectivesRule']; + const v4ignored = ignored.map(rule => rule.replace(/Rule$/, '')); - // GraphQL v14 has no Rule suffix in function names - // Adding `*Rule` makes validation backwards compatible - ignored.forEach(rule => { - ignored.push(rule.replace(/Rule$/, '')); - }); - - return specifiedRules.filter((f: (...args: any[]) => any) => !ignored.includes(f.name)); + return specifiedRules.filter( + (f: (...args: any[]) => any) => !ignored.includes(f.name) && !v4ignored.includes(f.name) + ); } diff --git a/packages/utils/src/visitResult.ts b/packages/utils/src/visitResult.ts index 4c94956d7aa..f71725fd41f 100644 --- a/packages/utils/src/visitResult.ts +++ b/packages/utils/src/visitResult.ts @@ -17,6 +17,7 @@ import { import { Request, GraphQLExecutionContext, ExecutionResult } from './Interfaces'; import { collectFields } from './collectFields'; +import { Maybe } from '@graphql-tools/utils'; export type ValueVisitor = (value: any) => any; @@ -56,10 +57,10 @@ export function visitData(data: any, enter?: ValueVisitor, leave?: ValueVisitor) const newData = enter != null ? enter(data) : data; if (newData != null) { - Object.keys(newData).forEach(key => { + for (const key in newData) { const value = newData[key]; newData[key] = visitData(value, enter, leave); - }); + } } return leave != null ? leave(newData) : newData; @@ -101,10 +102,12 @@ export function visitResult( const errors = result.errors; const visitingErrors = errors != null && errorVisitorMap != null; - if (data != null) { + const operationDocumentNode = getOperationAST(request.document, undefined); + + if (data != null && operationDocumentNode != null) { result.data = visitRoot( data, - getOperationAST(request.document, undefined), + operationDocumentNode, partialExecutionContext, resultVisitorMap, visitingErrors ? errors : undefined, @@ -112,7 +115,7 @@ export function visitResult( ); } - if (visitingErrors) { + if (errors != null && errorVisitorMap) { result.errors = visitErrorsByType(errors, errorVisitorMap, errorInfo); } @@ -155,8 +158,8 @@ function visitRoot( root: any, operation: OperationDefinitionNode, exeContext: GraphQLExecutionContext, - resultVisitorMap: ResultVisitorMap, - errors: ReadonlyArray, + resultVisitorMap: Maybe, + errors: Maybe>, errorInfo: ErrorInfo ): any { const operationRootType = getOperationRootType(exeContext.schema, operation); @@ -176,9 +179,9 @@ function visitObjectValue( type: GraphQLObjectType, fieldNodeMap: Record>, exeContext: GraphQLExecutionContext, - resultVisitorMap: ResultVisitorMap, + resultVisitorMap: Maybe, pathIndex: number, - errors: ReadonlyArray, + errors: Maybe>, errorInfo: ErrorInfo ): Record { const fieldMap = type.getFields(); @@ -188,22 +191,24 @@ function visitObjectValue( const newObject = enterObject != null ? enterObject(object) : object; let sortedErrors: SortedErrors; - let errorMap: Record>; + let errorMap: Maybe>> = null; if (errors != null) { sortedErrors = sortErrorsByPathSegment(errors, pathIndex); errorMap = sortedErrors.errorMap; - sortedErrors.unpathedErrors.forEach(error => errorInfo.unpathedErrors.add(error)); + for (const error of sortedErrors.unpathedErrors) { + errorInfo.unpathedErrors.add(error); + } } - Object.keys(fieldNodeMap).forEach(responseKey => { + for (const responseKey in fieldNodeMap) { const subFieldNodes = fieldNodeMap[responseKey]; const fieldName = subFieldNodes[0].name.value; const fieldType = fieldName === '__typename' ? TypeNameMetaFieldDef.type : fieldMap[fieldName].type; const newPathIndex = pathIndex + 1; - let fieldErrors: Array; - if (errors != null) { + let fieldErrors: Array | undefined; + if (errorMap) { fieldErrors = errorMap[responseKey]; if (fieldErrors != null) { delete errorMap[responseKey]; @@ -223,17 +228,19 @@ function visitObjectValue( ); updateObject(newObject, responseKey, newValue, typeVisitorMap, fieldName); - }); + } const oldTypename = newObject.__typename; if (oldTypename != null) { updateObject(newObject, '__typename', oldTypename, typeVisitorMap, '__typename'); } - if (errors != null) { - Object.keys(errorMap).forEach(unknownResponseKey => { - errorMap[unknownResponseKey].forEach(error => errorInfo.unpathedErrors.add(error)); - }); + if (errorMap) { + for (const errors of Object.values(errorMap)) { + for (const error of errors) { + errorInfo.unpathedErrors.add(error); + } + } } const leaveObject = typeVisitorMap?.__leave as ValueVisitor; @@ -273,7 +280,7 @@ function visitListValue( returnType: GraphQLOutputType, fieldNodes: Array, exeContext: GraphQLExecutionContext, - resultVisitorMap: ResultVisitorMap, + resultVisitorMap: Maybe, pathIndex: number, errors: ReadonlyArray, errorInfo: ErrorInfo @@ -288,9 +295,9 @@ function visitFieldValue( returnType: GraphQLOutputType, fieldNodes: Array, exeContext: GraphQLExecutionContext, - resultVisitorMap: ResultVisitorMap, + resultVisitorMap: Maybe, pathIndex: number, - errors: ReadonlyArray = [], + errors: ReadonlyArray | undefined = [], errorInfo: ErrorInfo ): any { if (value == null) { @@ -348,11 +355,11 @@ function visitFieldValue( function sortErrorsByPathSegment(errors: ReadonlyArray, pathIndex: number): SortedErrors { const errorMap = Object.create(null); const unpathedErrors: Set = new Set(); - errors.forEach(error => { + for (const error of errors) { const pathSegment = error.path?.[pathIndex]; if (pathSegment == null) { unpathedErrors.add(error); - return; + continue; } if (pathSegment in errorMap) { @@ -360,7 +367,7 @@ function sortErrorsByPathSegment(errors: ReadonlyArray, pathIndex: } else { errorMap[pathSegment] = [error]; } - }); + } return { errorMap, @@ -375,7 +382,7 @@ function addPathSegmentInfo( errors: ReadonlyArray = [], errorInfo: ErrorInfo ) { - errors.forEach(error => { + for (const error of errors) { const segmentInfo = { type, fieldName, @@ -387,7 +394,7 @@ function addPathSegmentInfo( } else { pathSegmentsInfo.push(segmentInfo); } - }); + } } function collectSubFields( @@ -398,9 +405,11 @@ function collectSubFields( let subFieldNodes: Record> = Object.create(null); const visitedFragmentNames = Object.create(null); - fieldNodes.forEach(fieldNode => { - subFieldNodes = collectFields(exeContext, type, fieldNode.selectionSet, subFieldNodes, visitedFragmentNames); - }); + for (const fieldNode of fieldNodes) { + if (fieldNode.selectionSet) { + subFieldNodes = collectFields(exeContext, type, fieldNode.selectionSet, subFieldNodes, visitedFragmentNames); + } + } return subFieldNodes; } diff --git a/packages/utils/src/visitSchema.ts b/packages/utils/src/visitSchema.ts deleted file mode 100644 index 72d16aa6a28..00000000000 --- a/packages/utils/src/visitSchema.ts +++ /dev/null @@ -1,317 +0,0 @@ -import { - GraphQLInterfaceType, - GraphQLObjectType, - GraphQLSchema, - isNamedType, - GraphQLType, - GraphQLNamedType, - GraphQLInputField, - isSchema, - isObjectType, - isInterfaceType, - isInputObjectType, - isScalarType, - isUnionType, - isEnumType, - isInputType, - GraphQLEnumValue, - GraphQLEnumType, -} from 'graphql'; - -import { - VisitableSchemaType, - VisitorSelector, - VisitSchemaKind, - NamedTypeVisitor, - SchemaVisitorMap, -} from './Interfaces'; - -import { healSchema } from './heal'; -import { SchemaVisitor } from './SchemaVisitor'; - -function isSchemaVisitor(obj: any): obj is SchemaVisitor { - if ('schema' in obj && isSchema(obj.schema)) { - if ('visitSchema' in obj && typeof obj.visitSchema === 'function') { - return true; - } - } - return false; -} - -// Generic function for visiting GraphQLSchema objects. -export function visitSchema( - schema: GraphQLSchema, - // To accommodate as many different visitor patterns as possible, the - // visitSchema function does not simply accept a single instance of the - // SchemaVisitor class, but instead accepts a function that takes the - // current VisitableSchemaType object and the name of a visitor method and - // returns an array of SchemaVisitor instances that implement the visitor - // method and have an interest in handling the given VisitableSchemaType - // object. In the simplest case, this function can always return an array - // containing a single visitor object, without even looking at the type or - // methodName parameters. In other cases, this function might sometimes - // return an empty array to indicate there are no visitors that should be - // applied to the given VisitableSchemaType object. For an example of a - // visitor pattern that benefits from this abstraction, see the - // SchemaDirectiveVisitor class below. - visitorOrVisitorSelector: VisitorSelector | Array | SchemaVisitor | SchemaVisitorMap -): GraphQLSchema { - const visitorSelector = - typeof visitorOrVisitorSelector === 'function' ? visitorOrVisitorSelector : () => visitorOrVisitorSelector; - - // Helper function that calls visitorSelector and applies the resulting - // visitors to the given type, with arguments [type, ...args]. - function callMethod(methodName: string, type: T, ...args: Array): T | null { - let visitors = visitorSelector(type, methodName); - visitors = Array.isArray(visitors) ? visitors : [visitors]; - - let finalType: T | null = type; - visitors.every(visitorOrVisitorDef => { - let newType; - if (isSchemaVisitor(visitorOrVisitorDef)) { - newType = visitorOrVisitorDef[methodName](finalType, ...args); - } else if ( - isNamedType(finalType) && - (methodName === 'visitScalar' || - methodName === 'visitEnum' || - methodName === 'visitObject' || - methodName === 'visitInputObject' || - methodName === 'visitUnion' || - methodName === 'visitInterface') - ) { - const specifiers = getTypeSpecifiers(finalType, schema); - const typeVisitor = getVisitor(visitorOrVisitorDef, specifiers); - newType = typeVisitor != null ? typeVisitor(finalType, schema) : undefined; - } - - if (typeof newType === 'undefined') { - // Keep going without modifying type. - return true; - } - - if (methodName === 'visitSchema' || isSchema(finalType)) { - throw new Error(`Method ${methodName} cannot replace schema with ${newType as string}`); - } - - if (newType === null) { - // Stop the loop and return null form callMethod, which will cause - // the type to be removed from the schema. - finalType = null; - return false; - } - - // Update type to the new type returned by the visitor method, so that - // later directives will see the new type, and callMethod will return - // the final type. - finalType = newType; - return true; - }); - - // If there were no directives for this type object, or if all visitor - // methods returned nothing, type will be returned unmodified. - return finalType; - } - - // Recursive helper function that calls any appropriate visitor methods for - // each object in the schema, then traverses the object's children (if any). - function visit(type: T): T | null { - if (isSchema(type)) { - // Unlike the other types, the root GraphQLSchema object cannot be - // replaced by visitor methods, because that would make life very hard - // for SchemaVisitor subclasses that rely on the original schema object. - callMethod('visitSchema', type); - - const typeMap: Record = type.getTypeMap(); - Object.entries(typeMap).forEach(([typeName, namedType]) => { - if (!typeName.startsWith('__') && namedType != null) { - // Call visit recursively to let it determine which concrete - // subclass of GraphQLNamedType we found in the type map. - // We do not use updateEachKey because we want to preserve - // deleted types in the typeMap so that other types that reference - // the deleted types can be healed. - typeMap[typeName] = visit(namedType); - } - }); - - return type; - } - - if (isObjectType(type)) { - // Note that callMethod('visitObject', type) may not actually call any - // methods, if there are no @directive annotations associated with this - // type, or if this SchemaDirectiveVisitor subclass does not override - // the visitObject method. - const newObject = callMethod('visitObject', type); - if (newObject != null) { - visitFields(newObject); - } - return newObject; - } - - if (isInterfaceType(type)) { - const newInterface = callMethod('visitInterface', type); - if (newInterface != null) { - visitFields(newInterface); - } - return newInterface; - } - - if (isInputObjectType(type)) { - const newInputObject = callMethod('visitInputObject', type); - - if (newInputObject != null) { - const fieldMap = newInputObject.getFields() as Record; - for (const key of Object.keys(fieldMap)) { - fieldMap[key] = callMethod('visitInputFieldDefinition', fieldMap[key], { - // Since we call a different method for input object fields, we - // can't reuse the visitFields function here. - objectType: newInputObject, - }); - if (!fieldMap[key]) { - delete fieldMap[key]; - } - } - } - - return newInputObject; - } - - if (isScalarType(type)) { - return callMethod('visitScalar', type); - } - - if (isUnionType(type)) { - return callMethod('visitUnion', type); - } - - if (isEnumType(type)) { - let newEnum = callMethod('visitEnum', type); - - if (newEnum != null) { - const newValues: Array = newEnum - .getValues() - .map(value => - callMethod('visitEnumValue', value, { - enumType: newEnum, - }) - ) - .filter(Boolean); - - // Recreate the enum type if any of the values changed - const valuesUpdated = newValues.some((value, index) => value !== newEnum.getValues()[index]); - if (valuesUpdated) { - newEnum = new GraphQLEnumType({ - ...(newEnum as GraphQLEnumType).toConfig(), - values: newValues.reduce( - (prev, value) => ({ - ...prev, - [value.name]: { - value: value.value, - deprecationReason: value.deprecationReason, - description: value.description, - astNode: value.astNode, - }, - }), - {} - ), - }) as GraphQLEnumType & T; - } - } - - return newEnum; - } - - throw new Error(`Unexpected schema type: ${(type as unknown) as string}`); - } - - function visitFields(type: GraphQLObjectType | GraphQLInterfaceType) { - const fieldMap = type.getFields(); - for (const [key, field] of Object.entries(fieldMap)) { - // It would be nice if we could call visit(field) recursively here, but - // GraphQLField is merely a type, not a value that can be detected using - // an instanceof check, so we have to visit the fields in this lexical - // context, so that TypeScript can validate the call to - // visitFieldDefinition. - const newField = callMethod('visitFieldDefinition', field, { - // While any field visitor needs a reference to the field object, some - // field visitors may also need to know the enclosing (parent) type, - // perhaps to determine if the parent is a GraphQLObjectType or a - // GraphQLInterfaceType. To obtain a reference to the parent, a - // visitor method can have a second parameter, which will be an object - // with an .objectType property referring to the parent. - objectType: type, - }); - - if (newField?.args != null) { - newField.args = newField.args - .map(arg => - callMethod('visitArgumentDefinition', arg, { - // Like visitFieldDefinition, visitArgumentDefinition takes a - // second parameter that provides additional context, namely the - // parent .field and grandparent .objectType. Remember that the - // current GraphQLSchema is always available via this.schema. - field: newField, - objectType: type, - }) - ) - .filter(Boolean); - } - - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition - if (newField) { - fieldMap[key] = newField; - } else { - delete fieldMap[key]; - } - } - } - - visit(schema); - - // Automatically update any references to named schema types replaced - // during the traversal, so implementers don't have to worry about that. - healSchema(schema); - - // Return schema for convenience, even though schema parameter has all updated types. - return schema; -} - -function getTypeSpecifiers(type: GraphQLType, schema: GraphQLSchema): Array { - const specifiers = [VisitSchemaKind.TYPE]; - if (isObjectType(type)) { - specifiers.push(VisitSchemaKind.COMPOSITE_TYPE, VisitSchemaKind.OBJECT_TYPE); - const query = schema.getQueryType(); - const mutation = schema.getMutationType(); - const subscription = schema.getSubscriptionType(); - if (type === query) { - specifiers.push(VisitSchemaKind.ROOT_OBJECT, VisitSchemaKind.QUERY); - } else if (type === mutation) { - specifiers.push(VisitSchemaKind.ROOT_OBJECT, VisitSchemaKind.MUTATION); - } else if (type === subscription) { - specifiers.push(VisitSchemaKind.ROOT_OBJECT, VisitSchemaKind.SUBSCRIPTION); - } - } else if (isInputType(type)) { - specifiers.push(VisitSchemaKind.INPUT_OBJECT_TYPE); - } else if (isInterfaceType(type)) { - specifiers.push(VisitSchemaKind.COMPOSITE_TYPE, VisitSchemaKind.ABSTRACT_TYPE, VisitSchemaKind.INTERFACE_TYPE); - } else if (isUnionType(type)) { - specifiers.push(VisitSchemaKind.COMPOSITE_TYPE, VisitSchemaKind.ABSTRACT_TYPE, VisitSchemaKind.UNION_TYPE); - } else if (isEnumType(type)) { - specifiers.push(VisitSchemaKind.ENUM_TYPE); - } else if (isScalarType(type)) { - specifiers.push(VisitSchemaKind.SCALAR_TYPE); - } - - return specifiers; -} - -function getVisitor(visitorDef: SchemaVisitorMap, specifiers: Array): NamedTypeVisitor | null { - let typeVisitor: NamedTypeVisitor | undefined; - const stack = [...specifiers]; - while (!typeVisitor && stack.length > 0) { - const next = stack.pop(); - typeVisitor = visitorDef[next] as NamedTypeVisitor; - } - - return typeVisitor != null ? typeVisitor : null; -} diff --git a/packages/utils/tests/build-operation-node-for-field.spec.ts b/packages/utils/tests/build-operation-node-for-field.spec.ts index 01b3e506d1c..53e9612e24f 100644 --- a/packages/utils/tests/build-operation-node-for-field.spec.ts +++ b/packages/utils/tests/build-operation-node-for-field.spec.ts @@ -84,7 +84,7 @@ test('should work with Query', async () => { expect(clean(document)).toEqual( clean(/* GraphQL */ ` - query meQuery { + query me_query { me { id name @@ -131,7 +131,7 @@ test('should work with Query and variables', async () => { expect(clean(document)).toEqual( clean(/* GraphQL */ ` - query userQuery($id: ID!) { + query user_query($id: ID!) { user(id: $id) { id name @@ -178,7 +178,7 @@ test('should work with Query and complicated variable', async () => { expect(clean(document)).toEqual( clean(/* GraphQL */ ` - query menuByIngredientsQuery($ingredients: [String!]!) { + query menuByIngredients_query($ingredients: [String!]!) { menuByIngredients(ingredients: $ingredients) { ... on Pizza { dough @@ -211,7 +211,7 @@ test('should work with Union', async () => { expect(clean(document)).toEqual( clean(/* GraphQL */ ` - query menuQuery { + query menu_query { menu { ... on Pizza { dough @@ -244,7 +244,7 @@ test('should work with mutation', async () => { expect(clean(document)).toEqual( clean(/* GraphQL */ ` - mutation addSaladMutation($ingredients: [String!]!) { + mutation addSalad_mutation($ingredients: [String!]!) { addSalad(ingredients: $ingredients) { ... on CaeserSalad { ingredients @@ -271,7 +271,7 @@ test('should work with mutation and unions', async () => { expect(clean(document)).toEqual( clean(/* GraphQL */ ` - mutation addRandomFoodMutation { + mutation addRandomFood_mutation { addRandomFood { ... on Pizza { dough @@ -304,9 +304,9 @@ test('should work with Query and nested variables', async () => { expect(clean(document)).toEqual( clean(/* GraphQL */ ` - query feedQuery($feedCommentsFilter: String!) { + query feed_query($feed_comments_filter: String!) { feed { - comments(filter: $feedCommentsFilter) + comments(filter: $feed_comments_filter) } } `) @@ -324,7 +324,7 @@ test('should be able to ignore using models when requested', async () => { expect(clean(document)).toEqual( clean(/* GraphQL */ ` - query userQuery($id: ID!) { + query user_query($id: ID!) { user(id: $id) { id name @@ -373,7 +373,7 @@ test('should work with Subscription', async () => { expect(clean(document)).toEqual( clean(/* GraphQL */ ` - subscription onFoodSubscription { + subscription onFood_subscription { onFood { ... on Pizza { dough @@ -423,7 +423,7 @@ test('should work with circular ref (default depth limit === 1)', async () => { expect(clean(document)).toEqual( clean(/* GraphQL */ ` - query aQuery { + query a_query { a { b { c { @@ -465,7 +465,7 @@ test('should work with circular ref (custom depth limit)', async () => { expect(clean(document)).toEqual( clean(/* GraphQL */ ` - query aQuery { + query a_query { a { b { c { @@ -510,7 +510,7 @@ test('arguments', async () => { expect(clean(document)).toEqual( clean(/* GraphQL */ ` - query usersQuery($pageInfo: PageInfoInput!) { + query users_query($pageInfo: PageInfoInput!) { users(pageInfo: $pageInfo) { id name @@ -538,7 +538,7 @@ test('selectedFields', async () => { expect(clean(document)).toEqual( clean(/* GraphQL */ ` - query userQuery($id: ID!) { + query user_query($id: ID!) { user(id: $id) { favoriteFood { ... on Pizza { diff --git a/packages/utils/tests/directives.test.ts b/packages/utils/tests/directives.test.ts deleted file mode 100644 index 2b3094dbe50..00000000000 --- a/packages/utils/tests/directives.test.ts +++ /dev/null @@ -1,1582 +0,0 @@ -import '../../testing/to-be-similar-string'; -import { createHash } from 'crypto'; - -import { - GraphQLArgument, - GraphQLEnumType, - GraphQLEnumValue, - GraphQLField, - GraphQLID, - GraphQLInputField, - GraphQLInputObjectType, - GraphQLObjectType, - GraphQLScalarType, - GraphQLSchema, - GraphQLString, - StringValueNode, - defaultFieldResolver, - graphql, - GraphQLNonNull, - GraphQLList, - GraphQLUnionType, - GraphQLInt, - GraphQLOutputType, - isNonNullType, - isScalarType, - isListType, - TypeSystemExtensionNode, - GraphQLDirective, - DirectiveLocation, - print, -} from 'graphql'; -import formatDate from 'dateformat'; - -import { makeExecutableSchema } from '@graphql-tools/schema'; -import { - VisitableSchemaType, - SchemaDirectiveVisitor, - SchemaVisitor, - visitSchema, - ExecutionResult, - astFromDirective, -} from '@graphql-tools/utils'; - -const typeDefs = ` -directive @schemaDirective(role: String) on SCHEMA -directive @schemaExtensionDirective(role: String) on SCHEMA -directive @queryTypeDirective on OBJECT -directive @queryTypeExtensionDirective on OBJECT -directive @queryFieldDirective on FIELD_DEFINITION -directive @enumTypeDirective on ENUM -directive @enumTypeExtensionDirective on ENUM -directive @enumValueDirective on ENUM_VALUE -directive @dateDirective(tz: String) on SCALAR -directive @dateExtensionDirective(tz: String) on SCALAR -directive @interfaceDirective on INTERFACE -directive @interfaceExtensionDirective on INTERFACE -directive @interfaceFieldDirective on FIELD_DEFINITION -directive @inputTypeDirective on INPUT_OBJECT -directive @inputTypeExtensionDirective on INPUT_OBJECT -directive @inputFieldDirective on INPUT_FIELD_DEFINITION -directive @mutationTypeDirective on OBJECT -directive @mutationTypeExtensionDirective on OBJECT -directive @mutationArgumentDirective on ARGUMENT_DEFINITION -directive @mutationMethodDirective on FIELD_DEFINITION -directive @objectTypeDirective on OBJECT -directive @objectTypeExtensionDirective on OBJECT -directive @objectFieldDirective on FIELD_DEFINITION -directive @unionDirective on UNION -directive @unionExtensionDirective on UNION - -schema @schemaDirective(role: "admin") { - query: Query - mutation: Mutation -} - -extend schema @schemaExtensionDirective(role: "admin") - -type Query @queryTypeDirective { - people: [Person] @queryFieldDirective -} - -extend type Query @queryTypeExtensionDirective - -enum Gender @enumTypeDirective { - NONBINARY @enumValueDirective - FEMALE - MALE -} - -extend enum Gender @enumTypeExtensionDirective -scalar Date @dateDirective(tz: "utc") - -extend scalar Date @dateExtensionDirective(tz: "utc") -interface Named @interfaceDirective { - name: String! @interfaceFieldDirective -} - -extend interface Named @interfaceExtensionDirective -input PersonInput @inputTypeDirective { - name: String! @inputFieldDirective - gender: Gender -} - -extend input PersonInput @inputTypeExtensionDirective -type Mutation @mutationTypeDirective { - addPerson( - input: PersonInput @mutationArgumentDirective - ): Person @mutationMethodDirective -} - -extend type Mutation @mutationTypeExtensionDirective -type Person implements Named @objectTypeDirective { - id: ID! @objectFieldDirective - name: String! -} - -extend type Person @objectTypeExtensionDirective -union WhateverUnion @unionDirective = Person | Query | Mutation - -extend union WhateverUnion @unionExtensionDirective`; - -describe('@directives', () => { - test('are included in the schema AST', () => { - const schema = makeExecutableSchema({ - typeDefs, - resolvers: { - Gender: { - NONBINARY: 'NB', - FEMALE: 'F', - MALE: 'M', - }, - }, - }); - - function checkDirectives( - type: VisitableSchemaType, - typeDirectiveNames: Array, - fieldDirectiveMap: Record> = {}, - ) { - expect(getDirectiveNames(type)).toEqual(typeDirectiveNames); - - Object.keys(fieldDirectiveMap).forEach((key) => { - expect( - getDirectiveNames((type as GraphQLObjectType).getFields()[key]), - ).toEqual(fieldDirectiveMap[key]); - }); - } - - function getDirectiveNames(type: VisitableSchemaType): Array { - let directives = type.astNode.directives.map((d) => d.name.value); - const extensionASTNodes = (type as { - extensionASTNodes?: Array; - }).extensionASTNodes; - if (extensionASTNodes != null) { - extensionASTNodes.forEach((extensionASTNode) => { - directives = directives.concat( - extensionASTNode.directives.map((d) => d.name.value), - ); - }); - } - return directives; - } - - expect(getDirectiveNames(schema)).toEqual([ - 'schemaDirective', - 'schemaExtensionDirective', - ]); - - checkDirectives( - schema.getQueryType(), - ['queryTypeDirective', 'queryTypeExtensionDirective'], - { - people: ['queryFieldDirective'], - }, - ); - - expect(getDirectiveNames(schema.getType('Gender'))).toEqual([ - 'enumTypeDirective', - 'enumTypeExtensionDirective', - ]); - - const nonBinary = (schema.getType( - 'Gender', - ) as GraphQLEnumType).getValues()[0]; - expect(getDirectiveNames(nonBinary)).toEqual(['enumValueDirective']); - - checkDirectives(schema.getType('Date') as GraphQLObjectType, [ - 'dateDirective', - 'dateExtensionDirective', - ]); - - checkDirectives( - schema.getType('Named') as GraphQLObjectType, - ['interfaceDirective', 'interfaceExtensionDirective'], - { - name: ['interfaceFieldDirective'], - }, - ); - - checkDirectives( - schema.getType('PersonInput') as GraphQLObjectType, - ['inputTypeDirective', 'inputTypeExtensionDirective'], - { - name: ['inputFieldDirective'], - gender: [], - }, - ); - - checkDirectives( - schema.getMutationType(), - ['mutationTypeDirective', 'mutationTypeExtensionDirective'], - { - addPerson: ['mutationMethodDirective'], - }, - ); - expect( - getDirectiveNames(schema.getMutationType().getFields().addPerson.args[0]), - ).toEqual(['mutationArgumentDirective']); - - checkDirectives( - schema.getType('Person'), - ['objectTypeDirective', 'objectTypeExtensionDirective'], - { - id: ['objectFieldDirective'], - name: [], - }, - ); - - checkDirectives(schema.getType('WhateverUnion'), [ - 'unionDirective', - 'unionExtensionDirective', - ]); - }); - - test('works with enum and its resolvers', () => { - const schema = makeExecutableSchema({ - typeDefs: ` - enum DateFormat { - LOCAL - ISO - } - - directive @date(format: DateFormat) on FIELD_DEFINITION - - scalar Date - - type Query { - today: Date @date(format: LOCAL) - } - `, - resolvers: { - DateFormat: { - LOCAL: 'local', - ISO: 'iso', - }, - }, - }); - - expect(schema.getType('DateFormat')).toBeDefined(); - expect(schema.getDirective('date')).toBeDefined(); - }); - - test('can be implemented with SchemaDirectiveVisitor', () => { - const visited: Set = new Set(); - const schema = makeExecutableSchema({ typeDefs }); - - SchemaDirectiveVisitor.visitSchemaDirectives(schema, { - // The directive subclass can be defined anonymously inline! - queryTypeDirective: class extends SchemaDirectiveVisitor { - public static description = 'A @directive for query object types'; - public visitObject(object: GraphQLObjectType) { - expect(object).toBe(schema.getQueryType()); - visited.add(object); - } - }, - queryTypeExtensionDirective: class extends SchemaDirectiveVisitor { - public static description = 'A @directive for query object types'; - public visitObject(object: GraphQLObjectType) { - expect(object).toBe(schema.getQueryType()); - visited.add(object); - } - }, - }); - - expect(visited.size).toBe(1); - }); - - test('can visit the schema itself', () => { - const visited: Array = []; - const schema = makeExecutableSchema({ typeDefs }); - SchemaDirectiveVisitor.visitSchemaDirectives(schema, { - schemaDirective: class extends SchemaDirectiveVisitor { - public visitSchema(s: GraphQLSchema) { - visited.push(s); - } - }, - schemaExtensionDirective: class extends SchemaDirectiveVisitor { - public visitSchema(s: GraphQLSchema) { - visited.push(s); - } - }, - }); - expect(visited.length).toBe(2); - expect(visited[0]).toBe(schema); - expect(visited[1]).toBe(schema); - }); - - test('can visit fields within object types', () => { - const schema = makeExecutableSchema({ typeDefs }); - - let mutationObjectType: GraphQLObjectType; - let mutationField: GraphQLField; - let enumObjectType: GraphQLEnumType; - let inputObjectType: GraphQLInputObjectType; - - SchemaDirectiveVisitor.visitSchemaDirectives(schema, { - mutationTypeDirective: class extends SchemaDirectiveVisitor { - public visitObject(object: GraphQLObjectType) { - mutationObjectType = object; - expect(this.visitedType).toBe(object); - expect(object.name).toBe('Mutation'); - } - }, - - mutationTypeExtensionDirective: class extends SchemaDirectiveVisitor { - public visitObject(object: GraphQLObjectType) { - mutationObjectType = object; - expect(this.visitedType).toBe(object); - expect(object.name).toBe('Mutation'); - } - }, - - mutationMethodDirective: class extends SchemaDirectiveVisitor { - public visitFieldDefinition( - field: GraphQLField, - details: { - objectType: GraphQLObjectType; - }, - ) { - expect(this.visitedType).toBe(field); - expect(field.name).toBe('addPerson'); - expect(details.objectType).toBe(mutationObjectType); - expect(field.args.length).toBe(1); - mutationField = field; - } - }, - - mutationArgumentDirective: class extends SchemaDirectiveVisitor { - public visitArgumentDefinition( - arg: GraphQLArgument, - details: { - field: GraphQLField; - objectType: GraphQLObjectType; - }, - ) { - expect(this.visitedType).toBe(arg); - expect(arg.name).toBe('input'); - expect(details.field).toBe(mutationField); - expect(details.objectType).toBe(mutationObjectType); - expect(details.field.args[0]).toBe(arg); - } - }, - - enumTypeDirective: class extends SchemaDirectiveVisitor { - public visitEnum(enumType: GraphQLEnumType) { - expect(this.visitedType).toBe(enumType); - expect(enumType.name).toBe('Gender'); - enumObjectType = enumType; - } - }, - - enumTypeExtensionDirective: class extends SchemaDirectiveVisitor { - public visitEnum(enumType: GraphQLEnumType) { - expect(this.visitedType).toBe(enumType); - expect(enumType.name).toBe('Gender'); - enumObjectType = enumType; - } - }, - - enumValueDirective: class extends SchemaDirectiveVisitor { - public visitEnumValue( - value: GraphQLEnumValue, - details: { - enumType: GraphQLEnumType; - }, - ) { - expect(this.visitedType).toBe(value); - expect(value.name).toBe('NONBINARY'); - expect(value.value).toBe('NONBINARY'); - expect(details.enumType).toBe(enumObjectType); - } - }, - - inputTypeDirective: class extends SchemaDirectiveVisitor { - public visitInputObject(object: GraphQLInputObjectType) { - inputObjectType = object; - expect(this.visitedType).toBe(object); - expect(object.name).toBe('PersonInput'); - } - }, - - inputTypeExtensionDirective: class extends SchemaDirectiveVisitor { - public visitInputObject(object: GraphQLInputObjectType) { - inputObjectType = object; - expect(this.visitedType).toBe(object); - expect(object.name).toBe('PersonInput'); - } - }, - - inputFieldDirective: class extends SchemaDirectiveVisitor { - public visitInputFieldDefinition( - field: GraphQLInputField, - details: { - objectType: GraphQLInputObjectType; - }, - ) { - expect(this.visitedType).toBe(field); - expect(field.name).toBe('name'); - expect(details.objectType).toBe(inputObjectType); - } - }, - }); - }); - - test('can check if a visitor method is implemented', () => { - class Visitor extends SchemaVisitor { - // eslint-disable-next-line @typescript-eslint/no-empty-function - public notVisitorMethod() {} - - public visitObject(object: GraphQLObjectType) { - return object; - } - } - - expect(Visitor.implementsVisitorMethod('notVisitorMethod')).toBe(false); - - expect(Visitor.implementsVisitorMethod('visitObject')).toBe(true); - - expect(Visitor.implementsVisitorMethod('visitInputFieldDefinition')).toBe( - false, - ); - - expect(Visitor.implementsVisitorMethod('visitBogusType')).toBe(false); - }); - - test('can use visitSchema for simple visitor patterns', () => { - class SimpleVisitor extends SchemaVisitor { - public visitCount = 0; - public names: Array = []; - - constructor(s: GraphQLSchema) { - super(); - this.schema = s; - } - - public visit() { - // More complicated visitor implementations might use the - // visitorSelector function more selectively, but this SimpleVisitor - // class always volunteers itself to visit any schema type. - visitSchema(this.schema, () => [this]); - } - - public visitObject(object: GraphQLObjectType) { - expect(this.schema.getType(object.name)).toBe(object); - this.names.push(object.name); - } - } - - const schema = makeExecutableSchema({ typeDefs }); - const visitor = new SimpleVisitor(schema); - visitor.visit(); - expect(visitor.names.sort((a, b) => a.localeCompare(b))).toEqual([ - 'Mutation', - 'Person', - 'Query', - ]); - }); - - test('can use SchemaDirectiveVisitor as a no-op visitor', () => { - const schema = makeExecutableSchema({ typeDefs }); - const methodNamesEncountered = new Set(); - - class EnthusiasticVisitor extends SchemaDirectiveVisitor { - public static implementsVisitorMethod(name: string) { - // Pretend this class implements all visitor methods. This is safe - // because the SchemaVisitor base class provides empty stubs for all - // the visitor methods that might be called. - methodNamesEncountered.add(name); - return true; - } - } - - EnthusiasticVisitor.visitSchemaDirectives(schema, { - schemaDirective: EnthusiasticVisitor, - queryTypeDirective: EnthusiasticVisitor, - queryFieldDirective: EnthusiasticVisitor, - enumTypeDirective: EnthusiasticVisitor, - enumValueDirective: EnthusiasticVisitor, - dateDirective: EnthusiasticVisitor, - interfaceDirective: EnthusiasticVisitor, - interfaceFieldDirective: EnthusiasticVisitor, - inputTypeDirective: EnthusiasticVisitor, - inputFieldDirective: EnthusiasticVisitor, - mutationTypeDirective: EnthusiasticVisitor, - mutationArgumentDirective: EnthusiasticVisitor, - mutationMethodDirective: EnthusiasticVisitor, - objectTypeDirective: EnthusiasticVisitor, - objectFieldDirective: EnthusiasticVisitor, - unionDirective: EnthusiasticVisitor, - }); - - for (const methodName of methodNamesEncountered) { - expect(methodName in SchemaVisitor.prototype).toBeTruthy(); - } - }); - - test('can handle declared arguments', () => { - const schemaText = ` - directive @oyez( - times: Int = 5, - party: Party = IMPARTIAL, - ) on OBJECT | FIELD_DEFINITION - - schema { - query: Courtroom - } - - type Courtroom @oyez { - judge: String @oyez(times: 0) - marshall: String @oyez - } - - enum Party { - DEFENSE - PROSECUTION - IMPARTIAL - }`; - - const schema = makeExecutableSchema({ typeDefs: schemaText }); - const context = { - objectCount: 0, - fieldCount: 0, - }; - - const visitors = SchemaDirectiveVisitor.visitSchemaDirectives( - schema, - { - oyez: class extends SchemaDirectiveVisitor { - public static getDirectiveDeclaration( - name: string, - theSchema: GraphQLSchema, - ) { - expect(theSchema).toBe(schema); - const prev = schema.getDirective(name); - prev.args.some((arg) => { - if (arg.name === 'times') { - // Override the default value of the times argument to be 3 - // instead of 5. - arg.defaultValue = 3; - return true; - } - return false; - }); - return prev; - } - - public visitObject() { - ++this.context.objectCount; - expect(this.args.times).toBe(3); - } - - public visitFieldDefinition(field: GraphQLField) { - ++this.context.fieldCount; - if (field.name === 'judge') { - expect(this.args.times).toBe(0); - } else if (field.name === 'marshall') { - expect(this.args.times).toBe(3); - } - expect(this.args.party).toBe('IMPARTIAL'); - } - }, - }, - context, - ); - - expect(context.objectCount).toBe(1); - expect(context.fieldCount).toBe(2); - - expect(Object.keys(visitors)).toEqual(['oyez']); - expect( - visitors.oyez.map( - (v) => - (v.visitedType as GraphQLObjectType | GraphQLField).name, - ), - ).toEqual(['Courtroom', 'judge', 'marshall']); - }); - - test('can be used to implement the @upper example', () => { - const schema = makeExecutableSchema({ - typeDefs: ` - directive @upper on FIELD_DEFINITION - - type Query { - hello: String @upper - }`, - schemaDirectives: { - upper: class extends SchemaDirectiveVisitor { - public visitFieldDefinition(field: GraphQLField) { - const { resolve = defaultFieldResolver } = field; - field.resolve = async function (...args) { - const result = await resolve.apply(this, args); - if (typeof result === 'string') { - return result.toUpperCase(); - } - return result; - }; - } - }, - }, - resolvers: { - Query: { - hello() { - return 'hello world'; - }, - }, - }, - }); - - return graphql( - schema, - ` - query { - hello - } - `, - ).then(({ data }) => { - expect(data).toEqual({ - hello: 'HELLO WORLD', - }); - }); - }); - - test('can be used to implement the @date example', () => { - const schema = makeExecutableSchema({ - typeDefs: ` - directive @date(format: String) on FIELD_DEFINITION - - scalar Date - - type Query { - today: Date @date(format: "mmmm d, yyyy") - }`, - - schemaDirectives: { - date: class extends SchemaDirectiveVisitor { - public visitFieldDefinition(field: GraphQLField) { - const { resolve = defaultFieldResolver } = field; - const { format } = this.args; - field.type = GraphQLString; - field.resolve = async function (...args) { - const date = await resolve.apply(this, args); - return formatDate(date, format, true); - }; - } - }, - }, - - resolvers: { - Query: { - today() { - return new Date(1519688273858).toUTCString(); - }, - }, - }, - }); - - return graphql( - schema, - ` - query { - today - } - `, - ).then(({ data }) => { - expect(data).toEqual({ - today: 'February 26, 2018', - }); - }); - }); - - test('can be used to implement the @date by adding an argument', async () => { - class FormattableDateDirective extends SchemaDirectiveVisitor { - public visitFieldDefinition(field: GraphQLField) { - const { resolve = defaultFieldResolver } = field; - const { defaultFormat } = this.args; - - field.args.push( - Object.create({ - name: 'format', - type: GraphQLString, - }), - ); - - field.type = GraphQLString; - field.resolve = async function ( - source, - { format, ...args }, - context, - info, - ) { - const newFormat = format || defaultFormat; - const date = await resolve.call(this, source, args, context, info); - return formatDate(date, newFormat, true); - }; - } - } - - const schema = makeExecutableSchema({ - typeDefs: ` - directive @date( - defaultFormat: String = "mmmm d, yyyy" - ) on FIELD_DEFINITION - - scalar Date - - type Query { - today: Date @date - }`, - - schemaDirectives: { - date: FormattableDateDirective, - }, - - resolvers: { - Query: { - today() { - return new Date(1521131357195); - }, - }, - }, - }); - - const resultNoArg = await graphql(schema, 'query { today }'); - - if (resultNoArg.errors != null) { - expect(resultNoArg.errors).toEqual([]); - } - - expect(resultNoArg.data).toEqual({ today: 'March 15, 2018' }); - - const resultWithArg = await graphql( - schema, - ` - query { - today(format: "dd mmm yyyy") - } - `, - ); - - if (resultWithArg.errors != null) { - expect(resultWithArg.errors).toEqual([]); - } - - expect(resultWithArg.data).toEqual({ today: '15 Mar 2018' }); - }); - - test('can be used to implement the @intl example', () => { - function translate(text: string, path: Array, locale: string) { - expect(text).toBe('hello'); - expect(path).toEqual(['Query', 'greeting']); - expect(locale).toBe('fr'); - return 'bonjour'; - } - - const context = { - locale: 'fr', - }; - - const schema = makeExecutableSchema({ - typeDefs: ` - directive @intl on FIELD_DEFINITION - - type Query { - greeting: String @intl - }`, - - schemaDirectives: { - intl: class extends SchemaDirectiveVisitor { - public visitFieldDefinition( - field: GraphQLField, - details: { - objectType: GraphQLObjectType; - }, - ) { - const { resolve = defaultFieldResolver } = field; - field.resolve = async function (...args: Array) { - const defaultText = await resolve.apply(this, args); - // In this example, path would be ["Query", "greeting"]: - const path = [details.objectType.name, field.name]; - expect(args[2]).toBe(context); - return translate(defaultText, path, context.locale); - }; - } - }, - }, - - resolvers: { - Query: { - greeting() { - return 'hello'; - }, - }, - }, - }); - - return graphql( - schema, - ` - query { - greeting - } - `, - null, - context, - ).then(({ data }) => { - expect(data).toEqual({ - greeting: 'bonjour', - }); - }); - }); - - test('can be used to implement the @auth example', async () => { - const roles = ['UNKNOWN', 'USER', 'REVIEWER', 'ADMIN']; - - function getUser(token: string) { - return { - hasRole(role: string) { - const tokenIndex = roles.indexOf(token); - const roleIndex = roles.indexOf(role); - return roleIndex >= 0 && tokenIndex >= roleIndex; - }, - }; - } - - class AuthDirective extends SchemaDirectiveVisitor { - public visitObject(type: GraphQLObjectType) { - this.ensureFieldsWrapped(type); - (type as any)._requiredAuthRole = this.args.requires; - } - - // Visitor methods for nested types like fields and arguments - // also receive a details object that provides information about - // the parent and grandparent types. - public visitFieldDefinition( - field: GraphQLField, - details: { objectType: GraphQLObjectType }, - ) { - this.ensureFieldsWrapped(details.objectType); - (field as any)._requiredAuthRole = this.args.requires; - } - - public ensureFieldsWrapped(objectType: GraphQLObjectType) { - // Mark the GraphQLObjectType object to avoid re-wrapping: - if ((objectType as any)._authFieldsWrapped) { - return; - } - (objectType as any)._authFieldsWrapped = true; - - const fields = objectType.getFields(); - - Object.keys(fields).forEach((fieldName) => { - const field = fields[fieldName]; - const { resolve = defaultFieldResolver } = field; - field.resolve = function (...args: Array) { - // Get the required Role from the field first, falling back - // to the objectType if no Role is required by the field: - const requiredRole = - (field as any)._requiredAuthRole || - (objectType as any)._requiredAuthRole; - - if (!requiredRole) { - return resolve.apply(this, args); - } - - const context = args[2]; - const user = getUser(context.headers.authToken); - if (!user.hasRole(requiredRole)) { - throw new Error('not authorized'); - } - - return resolve.apply(this, args); - }; - }); - } - } - - const schema = makeExecutableSchema({ - typeDefs: ` - directive @auth( - requires: Role = ADMIN, - ) on OBJECT | FIELD_DEFINITION - - enum Role { - ADMIN - REVIEWER - USER - UNKNOWN - } - - type User @auth(requires: USER) { - name: String - banned: Boolean @auth(requires: ADMIN) - canPost: Boolean @auth(requires: REVIEWER) - } - - type Query { - users: [User] - }`, - - schemaDirectives: { - auth: AuthDirective, - }, - - resolvers: { - Query: { - users() { - return [ - { - banned: true, - canPost: false, - name: 'Ben', - }, - ]; - }, - }, - }, - }); - - function execWithRole(role: string): Promise { - return graphql( - schema, - ` - query { - users { - name - banned - canPost - } - } - `, - null, - { - headers: { - authToken: role, - }, - }, - ); - } - - function checkErrors( - expectedCount: number, - ...expectedNames: Array - ) { - return function ({ - errors = [], - data, - }: { - errors: Array; - data: any; - }) { - expect(errors.length).toBe(expectedCount); - expect( - errors.every((error) => error.message === 'not authorized'), - ).toBeTruthy(); - const actualNames = errors.map((error) => error.path.slice(-1)[0]); - expect(expectedNames.sort((a, b) => a.localeCompare(b))).toEqual( - actualNames.sort((a, b) => a.localeCompare(b)), - ); - return data; - }; - } - - return Promise.all([ - execWithRole('UNKNOWN').then(checkErrors(3, 'banned', 'canPost', 'name')), - execWithRole('USER').then(checkErrors(2, 'banned', 'canPost')), - execWithRole('REVIEWER').then(checkErrors(1, 'banned')), - execWithRole('ADMIN') - .then(checkErrors(0)) - .then((data) => { - expect(data.users.length).toBe(1); - expect(data.users[0].banned).toBe(true); - expect(data.users[0].canPost).toBe(false); - expect(data.users[0].name).toBe('Ben'); - }), - ]); - }); - - test('can be used to implement the @length example', async () => { - class LimitedLengthType extends GraphQLScalarType { - constructor(type: GraphQLScalarType, maxLength: number) { - super({ - name: `LengthAtMost${maxLength.toString()}`, - - serialize(value: string) { - const newValue: string = type.serialize(value); - expect(typeof newValue.length).toBe('number'); - if (newValue.length > maxLength) { - throw new Error( - `expected ${newValue.length.toString( - 10, - )} to be at most ${maxLength.toString(10)}`, - ); - } - return newValue; - }, - - parseValue(value: string) { - return type.parseValue(value); - }, - - parseLiteral(ast: StringValueNode) { - return type.parseLiteral(ast, {}); - }, - }); - } - } - - const schema = makeExecutableSchema({ - typeDefs: ` - directive @length(max: Int) on FIELD_DEFINITION | INPUT_FIELD_DEFINITION - - type Query { - books: [Book] - } - - type Book { - title: String @length(max: 10) - } - - type Mutation { - createBook(book: BookInput): Book - } - - input BookInput { - title: String! @length(max: 10) - }`, - - schemaDirectives: { - length: class extends SchemaDirectiveVisitor { - public visitInputFieldDefinition(field: GraphQLInputField) { - this.wrapType(field); - } - - public visitFieldDefinition(field: GraphQLField) { - this.wrapType(field); - } - - private wrapType(field: GraphQLInputField | GraphQLField) { - if (isNonNullType(field.type) && isScalarType(field.type.ofType)) { - field.type = new GraphQLNonNull( - new LimitedLengthType(field.type.ofType, this.args.max), - ); - } else if (isScalarType(field.type)) { - field.type = new LimitedLengthType(field.type, this.args.max); - } else { - throw new Error(`Not a scalar type: ${field.type.toString()}`); - } - } - }, - }, - - resolvers: { - Query: { - books() { - return [ - { - title: 'abcdefghijklmnopqrstuvwxyz', - }, - ]; - }, - }, - Mutation: { - createBook(_parent, args) { - return args.book; - }, - }, - }, - }); - - const { errors } = await graphql( - schema, - ` - query { - books { - title - } - } - `, - ); - expect(errors.length).toBe(1); - expect(errors[0].message).toBe('expected 26 to be at most 10'); - - const result = await graphql( - schema, - ` - mutation { - createBook(book: { title: "safe title" }) { - title - } - } - `, - ); - - if (result.errors != null) { - expect(result.errors).toEqual([]); - } - - expect(result.data).toEqual({ - createBook: { - title: 'safe title', - }, - }); - }); - - test('can be used to implement the @uniqueID example', () => { - const schema = makeExecutableSchema({ - typeDefs: ` - directive @uniqueID(name: String, from: [String]) on OBJECT - - type Query { - people: [Person] - locations: [Location] - } - - type Person @uniqueID(name: "uid", from: ["personID"]) { - personID: Int - name: String - } - - type Location @uniqueID(name: "uid", from: ["locationID"]) { - locationID: Int - address: String - }`, - - schemaDirectives: { - uniqueID: class extends SchemaDirectiveVisitor { - public visitObject(type: GraphQLObjectType) { - const { name, from } = this.args; - type.getFields()[name] = Object.create({ - name, - type: GraphQLID, - description: 'Unique ID', - args: [], - resolve(object: any) { - const hash = createHash('sha1'); - hash.update(type.name); - from.forEach((fieldName: string) => { - hash.update(String(object[fieldName])); - }); - return hash.digest('hex'); - }, - }); - } - }, - }, - - resolvers: { - Query: { - people() { - return [ - { - personID: 1, - name: 'Ben', - }, - ]; - }, - locations() { - return [ - { - locationID: 1, - address: '140 10th St', - }, - ]; - }, - }, - }, - }); - - return graphql( - schema, - ` - query { - people { - uid - personID - name - } - locations { - uid - locationID - address - } - } - `, - null, - {}, - ).then((result) => { - const { data } = result; - - expect(data.people).toEqual([ - { - uid: '580a207c8e94f03b93a2b01217c3cc218490571a', - personID: 1, - name: 'Ben', - }, - ]); - - expect(data.locations).toEqual([ - { - uid: 'c31b71e6e23a7ae527f94341da333590dd7cba96', - locationID: 1, - address: '140 10th St', - }, - ]); - }); - }); - - test('automatically updates references to changed types', () => { - const schema = makeExecutableSchema({ - typeDefs, - schemaDirectives: { - objectTypeDirective: class extends SchemaDirectiveVisitor { - public visitObject(object: GraphQLObjectType) { - return Object.create(object, { - name: { value: 'Human' }, - }); - } - }, - }, - }); - - const Query = schema.getType('Query') as GraphQLObjectType; - const peopleType = Query.getFields().people.type; - if (isListType(peopleType)) { - expect(peopleType.ofType).toBe(schema.getType('Human')); - } else { - throw new Error('Query.people not a GraphQLList type'); - } - - const Mutation = schema.getType('Mutation') as GraphQLObjectType; - const addPersonResultType = Mutation.getFields().addPerson.type; - expect(addPersonResultType).toBe( - schema.getType('Human') as GraphQLOutputType, - ); - - const WhateverUnion = schema.getType('WhateverUnion') as GraphQLUnionType; - const found = WhateverUnion.getTypes().some((type) => { - if (type.name === 'Human') { - expect(type).toBe(schema.getType('Human')); - return true; - } - return false; - }); - expect(found).toBe(true); - - // Make sure that the Person type was actually removed. - expect(typeof schema.getType('Person')).toBe('undefined'); - }); - - test('can remove enum values', () => { - const schema = makeExecutableSchema({ - typeDefs: ` - directive @remove(if: Boolean) on ENUM_VALUE - - type Query { - age(unit: AgeUnit): Int - } - - enum AgeUnit { - DOG_YEARS - TURTLE_YEARS @remove(if: true) - PERSON_YEARS @remove(if: false) - }`, - - schemaDirectives: { - remove: class extends SchemaDirectiveVisitor { - public visitEnumValue(): null { - if (this.args.if) { - return null; - } - } - }, - }, - }); - - const AgeUnit = schema.getType('AgeUnit') as GraphQLEnumType; - expect(AgeUnit.getValues().map((value) => value.name)).toEqual([ - 'DOG_YEARS', - 'PERSON_YEARS', - ]); - }); - - test("can modify enum value's value", () => { - const schema = makeExecutableSchema({ - typeDefs: ` - directive @value(new: String!) on ENUM_VALUE - - type Query { - device: Device - } - - enum Device { - PHONE - TABLET - LAPTOP @value(new: "COMPUTER") - }`, - - schemaDirectives: { - value: class extends SchemaDirectiveVisitor { - public visitEnumValue(value: GraphQLEnumValue): GraphQLEnumValue { - return { - ...value, - value: this.args.new, - }; - } - }, - }, - }); - - const Device = schema.getType('Device') as GraphQLEnumType; - expect(Device.getValues().map((value) => value.value)).toEqual([ - 'PHONE', - 'TABLET', - 'COMPUTER', - ]); - }); - - test('can swap names of GraphQLNamedType objects', () => { - const schema = makeExecutableSchema({ - typeDefs: ` - directive @rename(to: String) on OBJECT - - type Query { - people: [Person] - } - - type Person @rename(to: "Human") { - heightInInches: Int - } - - scalar Date - - type Human @rename(to: "Person") { - born: Date - }`, - - schemaDirectives: { - rename: class extends SchemaDirectiveVisitor { - public visitObject(object: GraphQLObjectType) { - object.name = this.args.to; - } - }, - }, - }); - - const Human = schema.getType('Human') as GraphQLObjectType; - expect(Human.name).toBe('Human'); - expect(Human.getFields().heightInInches.type).toBe(GraphQLInt); - - const Person = schema.getType('Person') as GraphQLObjectType; - expect(Person.name).toBe('Person'); - expect(Person.getFields().born.type).toBe( - schema.getType('Date') as GraphQLScalarType, - ); - - const Query = schema.getType('Query') as GraphQLObjectType; - const peopleType = Query.getFields().people.type as GraphQLList< - GraphQLObjectType - >; - expect(peopleType.ofType).toBe(Human); - }); - - test('does not enforce query directive locations (issue #680)', () => { - const visited = new Set(); - makeExecutableSchema({ - typeDefs: ` - directive @hasScope(scope: [String]) on QUERY | FIELD | OBJECT - - type Query @hasScope { - oyez: String - }`, - - schemaDirectives: { - hasScope: class extends SchemaDirectiveVisitor { - public visitObject(object: GraphQLObjectType) { - expect(object.name).toBe('Query'); - visited.add(object); - } - }, - }, - }); - - expect(visited.size).toBe(1); - }); - - test('allows multiple directives when first replaces type (issue #851)', () => { - const schema = makeExecutableSchema({ - typeDefs: ` - directive @upper on FIELD_DEFINITION - directive @reverse on FIELD_DEFINITION - - type Query { - hello: String @upper @reverse - }`, - schemaDirectives: { - upper: class extends SchemaDirectiveVisitor { - public visitFieldDefinition(field: GraphQLField) { - const { resolve = defaultFieldResolver } = field; - const newField = { ...field }; - - newField.resolve = async function (...args: Array) { - const result = await resolve.apply(this, args); - if (typeof result === 'string') { - return result.toUpperCase(); - } - return result; - }; - - return newField; - } - }, - reverse: class extends SchemaDirectiveVisitor { - public visitFieldDefinition(field: GraphQLField) { - const { resolve = defaultFieldResolver } = field; - field.resolve = async function (...args: Array) { - const result = await resolve.apply(this, args); - if (typeof result === 'string') { - return result.split('').reverse().join(''); - } - return result; - }; - } - }, - }, - resolvers: { - Query: { - hello() { - return 'hello world'; - }, - }, - }, - }); - - return graphql( - schema, - ` - query { - hello - } - `, - ).then(({ data }) => { - expect(data).toEqual({ - hello: 'DLROW OLLEH', - }); - }); - }); - - test('preserves ability to create fields of different types with same name (issue 1462)', () => { - function validateStr(value: any, { - min = null, - message = null, - } : { - min: number, - message: string, - }) { - if(min && value.length < min) { - throw new Error(message || `Please ensure the value is at least ${min} characters.`); - } - } - - class ConstraintType extends GraphQLScalarType { - constructor( - type: GraphQLScalarType, - args: { - min: number, - message: string, - }, - ) { - super({ - name: 'ConstraintType', - serialize: (value) => type.serialize(value), - parseValue: (value) => { - const trimmed = value.trim(); - validateStr(trimmed, args); - return type.parseValue(trimmed); - } - }); - } - } - - class ConstraintDirective extends SchemaDirectiveVisitor { - visitInputFieldDefinition(field: GraphQLInputField) { - if (isNonNullType(field.type) && isScalarType(field.type.ofType)) { - field.type = new GraphQLNonNull( - new ConstraintType(field.type.ofType, this.args) - ); - } else if (isScalarType(field.type)) { - field.type = new ConstraintType(field.type, this.args); - } else { - throw new Error(`Not a scalar type: ${field.type}`); - } - } - } - - const schema = makeExecutableSchema({ - typeDefs: ` - directive @constraint(min: Int, message: String) on INPUT_FIELD_DEFINITION - - input BookInput { - name: String! @constraint(min: 10, message: "Book input error!") - } - - input AuthorInput { - name: String! @constraint(min: 4, message: "Author input error") - } - - type Query { - getBookById(id: Int): String - } - - type Mutation { - createBook(input: BookInput!): String - createAuthor(input: AuthorInput!): String - } - `, - resolvers: { - Mutation: { - createBook() { - return 'yes'; - }, - createAuthor() { - return 'no'; - } - } - }, - schemaDirectives: { - constraint: ConstraintDirective - } - }); - - return graphql( - schema, - ` - mutation { - createAuthor(input: { - name: "M" - }) - } - `, - ).then(({ errors }) => { - expect(errors[0].originalError).toEqual(new Error('Author input error')); - }); - }); - it('should print a directive correctly from GraphQLDirective object using astFromDirective and print', () => { - const sampleDirective = new GraphQLDirective({ - name: 'sample', - args: { - foo: { - type: GraphQLString - } - }, - locations: [DirectiveLocation.FIELD_DEFINITION] - }); - expect( - print( - astFromDirective(sampleDirective) - ) - ).toBeSimilarString(/* GraphQL */` - directive @sample(foo: String) on FIELD_DEFINITION - `); - }) -}); diff --git a/packages/utils/tests/filterSchema.test.ts b/packages/utils/tests/filterSchema.test.ts index 8745a0dd61d..54c8781efd2 100644 --- a/packages/utils/tests/filterSchema.test.ts +++ b/packages/utils/tests/filterSchema.test.ts @@ -19,7 +19,7 @@ describe('filterSchema', () => { const filtered = filterSchema({ schema, - rootFieldFilter: (_opName, fieldName) => fieldName.startsWith('keep'), + rootFieldFilter: (_opName, fieldName) => fieldName?.startsWith('keep') ?? false, }); expect((filtered.getType('Query') as GraphQLObjectType).getFields()['keep']).toBeDefined(); @@ -97,7 +97,7 @@ describe('filterSchema', () => { const filtered = filterSchema({ schema, - objectFieldFilter: (_typeName, fieldName) => fieldName.startsWith('keep'), + objectFieldFilter: (_typeName, fieldName) => fieldName?.startsWith('keep') ?? false, }); expect((filtered.getType('Thing') as GraphQLObjectType).getFields()['keep']).toBeDefined(); @@ -120,7 +120,7 @@ describe('filterSchema', () => { const filtered = filterSchema({ schema, - interfaceFieldFilter: (_typeName, fieldName) => fieldName.startsWith('keep'), + interfaceFieldFilter: (_typeName, fieldName) => fieldName?.startsWith('keep') ?? false, }); expect((filtered.getType('IThing') as GraphQLInterfaceType).getFields()['keep']).toBeDefined(); @@ -143,7 +143,7 @@ describe('filterSchema', () => { const filtered = filterSchema({ schema, - inputObjectFieldFilter: (_typeName, fieldName) => fieldName.startsWith('keep'), + inputObjectFieldFilter: (_typeName, fieldName) => fieldName?.startsWith('keep') ?? false, }); expect((filtered.getType('ThingInput') as GraphQLInputObjectType).getFields()['keep']).toBeDefined(); @@ -171,7 +171,7 @@ describe('filterSchema', () => { const filtered = filterSchema({ schema, - fieldFilter: (_typeName, fieldName) => fieldName.startsWith('keep'), + fieldFilter: (_typeName, fieldName) => fieldName?.startsWith('keep') ?? false, }); expect((filtered.getType('Thing') as GraphQLObjectType).getFields()['keep']).toBeDefined(); @@ -199,7 +199,7 @@ describe('filterSchema', () => { const filtered = filterSchema({ schema, - argumentFilter: (_typeName, _fieldName, argName) => argName.startsWith('keep'), + argumentFilter: (_typeName, _fieldName, argName) => argName?.startsWith('keep') ?? false, }); expect((filtered.getType('Query') as GraphQLObjectType).getFields()['field'].args.map(arg => arg.name)).toEqual(['keep']); diff --git a/packages/utils/tests/get-directives.spec.ts b/packages/utils/tests/get-directives.spec.ts index 83facfd4238..05bdf4d882b 100644 --- a/packages/utils/tests/get-directives.spec.ts +++ b/packages/utils/tests/get-directives.spec.ts @@ -1,6 +1,7 @@ -import { GraphQLSchema } from 'graphql'; import { makeExecutableSchema } from '@graphql-tools/schema'; import { getDirectives } from '../src'; +import { assertGraphQLObjectType } from '../../testing/assertion'; +import { GraphQLSchema } from 'graphql'; describe('getDirectives', () => { it('should return the correct directives map when no directives specified', () => { @@ -9,7 +10,7 @@ describe('getDirectives', () => { test: String } `; - const schema = makeExecutableSchema({ typeDefs, resolvers: {}, allowUndefinedInResolve: true }) as GraphQLSchema; + const schema = makeExecutableSchema({ typeDefs, resolvers: {} }) as GraphQLSchema; const directivesMap = getDirectives(schema, schema.getQueryType()); expect(directivesMap).toEqual({}); @@ -22,7 +23,7 @@ describe('getDirectives', () => { } `; - const schema = makeExecutableSchema({ typeDefs, resolvers: {}, allowUndefinedInResolve: true }) as GraphQLSchema; + const schema = makeExecutableSchema({ typeDefs, resolvers: {} }) as GraphQLSchema; const directivesMap = getDirectives(schema, schema.getQueryType().getFields().test); expect(directivesMap).toEqual({ deprecated: { @@ -40,7 +41,7 @@ describe('getDirectives', () => { directive @mydir on FIELD_DEFINITION `; - const schema = makeExecutableSchema({ typeDefs, resolvers: {}, allowUndefinedInResolve: true }) as GraphQLSchema; + const schema = makeExecutableSchema({ typeDefs, resolvers: {} }) as GraphQLSchema; const directivesMap = getDirectives(schema, schema.getQueryType().getFields().test); expect(directivesMap).toEqual({ mydir: {}, @@ -56,7 +57,7 @@ describe('getDirectives', () => { directive @mydir(f1: String) on FIELD_DEFINITION `; - const schema = makeExecutableSchema({ typeDefs, resolvers: {}, allowUndefinedInResolve: true }) as GraphQLSchema; + const schema = makeExecutableSchema({ typeDefs, resolvers: {} }) as GraphQLSchema; const directivesMap = getDirectives(schema, schema.getQueryType().getFields().test); expect(directivesMap).toEqual({ mydir: { @@ -74,27 +75,28 @@ describe('getDirectives', () => { directive @mydir(f1: String) on FIELD_DEFINITION `; - const schema = makeExecutableSchema({ typeDefs, resolvers: {}, allowUndefinedInResolve: true }) as GraphQLSchema; + const schema = makeExecutableSchema({ typeDefs, resolvers: {} }) as GraphQLSchema; const directivesMap = getDirectives(schema, schema.getQueryType().getFields().test); expect(directivesMap).toEqual({ mydir: {}, }); }); - it('provides the extension definition over base', () => { + it('provides the extension definition', () => { const schema = makeExecutableSchema({ typeDefs: ` directive @mydir(arg: String) on OBJECT - extend type Query @mydir(arg: "ext1") { - second: String - } type Query @mydir(arg: "base") { first: String } + extend type Query @mydir(arg: "ext1") { + second: String + } ` }); - - expect(getDirectives(schema, schema.getQueryType())).toEqual({ mydir: { arg: 'ext1' } }); + const QueryType = schema.getQueryType() + assertGraphQLObjectType(QueryType) + expect(getDirectives(schema,QueryType)).toEqual({ mydir: { arg: 'ext1' } }); }); it('builds proper repeatable directives listing', () => { @@ -106,8 +108,9 @@ describe('getDirectives', () => { } ` }); - - expect(getDirectives(schema, schema.getQueryType())).toEqual({ + const QueryType = schema.getQueryType() + assertGraphQLObjectType(QueryType) + expect(getDirectives(schema, QueryType)).toEqual({ mydir: [{ arg: "first" }, { arg: "second" }] }); }); diff --git a/packages/utils/tests/mapSchema.test.ts b/packages/utils/tests/mapSchema.test.ts index 982bc5479cc..e2622760e3e 100644 --- a/packages/utils/tests/mapSchema.test.ts +++ b/packages/utils/tests/mapSchema.test.ts @@ -29,7 +29,7 @@ describe('mapSchema', () => { const newSchema = mapSchema(schema, { [MapperKind.QUERY]: (type) => { const queryConfig = type.toConfig(); - queryConfig.fields.version.resolve = () => 1; + queryConfig.fields['version'].resolve = () => 1; return new GraphQLObjectType(queryConfig); }, }); @@ -37,7 +37,7 @@ describe('mapSchema', () => { expect(newSchema).toBeInstanceOf(GraphQLSchema); const result = graphqlSync(newSchema, '{ version }'); - expect(result.data.version).toBe(1); + expect(result.data?.['version']).toBe(1); }); test('can change the root query name', () => { @@ -58,6 +58,6 @@ describe('mapSchema', () => { }); expect(newSchema).toBeInstanceOf(GraphQLSchema); - expect(newSchema.getQueryType().name).toBe('RootQuery'); + expect(newSchema.getQueryType()?.name).toBe('RootQuery'); }); }); diff --git a/packages/utils/tests/parse-graphql-sdl.spec.ts b/packages/utils/tests/parse-graphql-sdl.spec.ts index a00669b19ac..ecbe6526984 100644 --- a/packages/utils/tests/parse-graphql-sdl.spec.ts +++ b/packages/utils/tests/parse-graphql-sdl.spec.ts @@ -76,9 +76,9 @@ describe('parse sdl', () => { it('should transform comments to descriptions correctly on all available nodes with noLocation=true', () => { const transformed = parseGraphQLSDL('test.graphql', ast, { noLocation: true, commentDescriptions: true }); - const type = transformed.document.definitions.find(d => (d as any)?.name?.value === 'Type'); - expect((type as ObjectTypeDefinitionNode).description.value).toBe('test type comment'); - expect((type as ObjectTypeDefinitionNode).loc).not.toBeDefined(); + const type = transformed.document.definitions.find((d): d is ObjectTypeDefinitionNode => "name" in d && d.name?.value === 'Type'); + expect(type?.description?.value).toBe('test type comment'); + expect(type?.loc).not.toBeDefined(); const printed = print(transformed.document); expect(printed).toMatchSnapshot(); }); diff --git a/packages/utils/tests/print-schema-with-directives.spec.ts b/packages/utils/tests/print-schema-with-directives.spec.ts index 5eb8ec2a9c6..4108123390b 100644 --- a/packages/utils/tests/print-schema-with-directives.spec.ts +++ b/packages/utils/tests/print-schema-with-directives.spec.ts @@ -224,7 +224,7 @@ describe('printSchemaWithDirectives', () => { name: 'dummy', locations: ['QUERY'], })] - }); + } as any); const output = printSchemaWithDirectives(schema); diff --git a/packages/utils/tests/relocatedError.test.ts b/packages/utils/tests/relocatedError.test.ts index e5d5d427a02..9f4d3ab5204 100644 --- a/packages/utils/tests/relocatedError.test.ts +++ b/packages/utils/tests/relocatedError.test.ts @@ -4,11 +4,11 @@ import { relocatedError } from '../src/errors'; describe('Errors', () => { describe('relocatedError', () => { test('should adjust the path of a GraphqlError', () => { - const originalError = new GraphQLError('test', null, null, null, [ + const originalError = new GraphQLError('test', null as any, null, null, [ 'test', ]); const newError = relocatedError(originalError, ['test', 1]); - const expectedError = new GraphQLError('test', null, null, null, [ + const expectedError = new GraphQLError('test', null as any, null, null, [ 'test', 1, ]); diff --git a/packages/utils/tests/schemaTransforms.test.ts b/packages/utils/tests/schemaTransforms.test.ts index 9bf74b72774..451314b4a82 100644 --- a/packages/utils/tests/schemaTransforms.test.ts +++ b/packages/utils/tests/schemaTransforms.test.ts @@ -8,7 +8,6 @@ import { graphql, GraphQLString, GraphQLScalarType, - StringValueNode, GraphQLInputFieldConfig, GraphQLFieldConfig, isNonNullType, @@ -123,12 +122,12 @@ describe('@directives', () => { return schema => mapSchema(schema, { [MapperKind.OBJECT_TYPE]: type => { const directives = getDirectives(schema, type); - Object.keys(directives).forEach(directiveName => { + for (const directiveName in directives) { if (directiveNames.includes(directiveName)) { - expect(type.name).toBe(schema.getQueryType().name); + expect(type.name).toBe(schema.getQueryType()?.name); visited.add(type); } - }); + } return undefined; } }) @@ -150,11 +149,11 @@ describe('@directives', () => { function recordSchemaDirectiveUses(directiveNames: Array): (schema: GraphQLSchema) => GraphQLSchema { return schema => { const directives = getDirectives(schema, schema); - Object.keys(directives).forEach(directiveName => { + for (const directiveName in directives) { if (directiveNames.includes(directiveName)) { visited.push(schema); } - }); + } return schema; } } @@ -270,7 +269,7 @@ describe('@directives', () => { schemaTransforms: [deprecatedDirectiveTransformer], }); - expect((schema.getType('ExampleType') as GraphQLObjectType).getFields().oldField.deprecationReason).toBe('Use \`newField\`.') + expect((schema.getType('ExampleType') as GraphQLObjectType).getFields()['oldField'].deprecationReason).toBe('Use \`newField\`.') }); test('can be used to implement the @date example', () => { @@ -345,6 +344,10 @@ describe('@directives', () => { const { resolve = defaultFieldResolver } = fieldConfig; const { defaultFormat } = directiveArgumentMap; + if (!fieldConfig.args) { + throw new Error("Unexpected Error. args should be defined.") + } + fieldConfig.args['format'] = { type: GraphQLString, }; @@ -515,6 +518,12 @@ describe('@directives', () => { ); } + function assertStringArray(input: Array): asserts input is Array { + if (input.some(item => typeof item !== "string")) { + throw new Error("All items in array should be strings.") + } + } + function checkErrors( expectedCount: number, ...expectedNames: Array @@ -522,15 +531,13 @@ describe('@directives', () => { return function ({ errors = [], data, - }: { - errors: Array; - data: any; - }) { + }: ExecutionResult) { expect(errors.length).toBe(expectedCount); expect( errors.every((error) => error.message === 'not authorized'), ).toBeTruthy(); - const actualNames = errors.map((error) => error.path.slice(-1)[0]); + const actualNames = errors.map((error) => error.path!.slice(-1)[0]); + assertStringArray(actualNames) expect(expectedNames.sort((a, b) => a.localeCompare(b))).toEqual( actualNames.sort((a, b) => a.localeCompare(b)), ); @@ -545,10 +552,10 @@ describe('@directives', () => { execWithRole('ADMIN') .then(checkErrors(0)) .then((data) => { - expect(data.users.length).toBe(1); - expect(data.users[0].banned).toBe(true); - expect(data.users[0].canPost).toBe(false); - expect(data.users[0].name).toBe('Ben'); + expect(data?.['users'].length).toBe(1); + expect(data?.['users'][0].banned).toBe(true); + expect(data?.['users'][0].canPost).toBe(false); + expect(data?.['users'][0].name).toBe('Ben'); }), ]); }); @@ -577,7 +584,7 @@ describe('@directives', () => { return type.parseValue(value); }, - parseLiteral(ast: StringValueNode) { + parseLiteral(ast) { return type.parseLiteral(ast, {}); }, }); @@ -607,9 +614,9 @@ describe('@directives', () => { function wrapType | GraphQLInputFieldConfig>(fieldConfig: F, directiveArgumentMap: Record): void { if (isNonNullType(fieldConfig.type) && isScalarType(fieldConfig.type.ofType)) { - fieldConfig.type = getLimitedLengthType(fieldConfig.type.ofType, directiveArgumentMap.max); + fieldConfig.type = getLimitedLengthType(fieldConfig.type.ofType, directiveArgumentMap['max']); } else if (isScalarType(fieldConfig.type)) { - fieldConfig.type = getLimitedLengthType(fieldConfig.type, directiveArgumentMap.max); + fieldConfig.type = getLimitedLengthType(fieldConfig.type, directiveArgumentMap['max']); } else { throw new Error(`Not a scalar type: ${fieldConfig.type.toString()}`); } @@ -679,8 +686,8 @@ describe('@directives', () => { } `, ); - expect(errors.length).toBe(1); - expect(errors[0].message).toBe('expected 26 to be at most 10'); + expect(errors?.length).toBe(1); + expect(errors?.[0].message).toBe('expected 26 to be at most 10'); const result = await graphql( schema, @@ -722,9 +729,9 @@ describe('@directives', () => { resolve(object: any) { const hash = createHash('sha1'); hash.update(type.name); - from.forEach((fieldName: string) => { + for (const fieldName of from ){ hash.update(String(object[fieldName])); - }); + } return hash.digest('hex'); }, }; @@ -798,7 +805,7 @@ describe('@directives', () => { ).then((result) => { const { data } = result; - expect(data.people).toEqual([ + expect(data?.['people']).toEqual([ { uid: '580a207c8e94f03b93a2b01217c3cc218490571a', personID: 1, @@ -806,7 +813,7 @@ describe('@directives', () => { }, ]); - expect(data.locations).toEqual([ + expect(data?.['locations']).toEqual([ { uid: 'c31b71e6e23a7ae527f94341da333590dd7cba96', locationID: 1, @@ -837,7 +844,7 @@ describe('@directives', () => { }); const Query = schema.getType('Query') as GraphQLObjectType; - const peopleType = Query.getFields().people.type; + const peopleType = Query.getFields()['people'].type; if (isListType(peopleType)) { expect(peopleType.ofType).toBe(schema.getType('Human')); } else { @@ -845,7 +852,7 @@ describe('@directives', () => { } const Mutation = schema.getType('Mutation') as GraphQLObjectType; - const addPersonResultType = Mutation.getFields().addPerson.type; + const addPersonResultType = Mutation.getFields()['addPerson'].type; expect(addPersonResultType).toBe( schema.getType('Human') as GraphQLOutputType, ); @@ -1016,16 +1023,16 @@ describe('@directives', () => { const Human = schema.getType('Human') as GraphQLObjectType; expect(Human.name).toBe('Human'); - expect(Human.getFields().heightInInches.type).toBe(GraphQLInt); + expect(Human.getFields()['heightInInches'].type).toBe(GraphQLInt); const Person = schema.getType('Person') as GraphQLObjectType; expect(Person.name).toBe('Person'); - expect(Person.getFields().born.type).toBe( + expect(Person.getFields()['born'].type).toBe( schema.getType('Date') as GraphQLScalarType, ); const Query = schema.getType('Query') as GraphQLObjectType; - const peopleType = Query.getFields().people.type as GraphQLList< + const peopleType = Query.getFields()['people'].type as GraphQLList< GraphQLObjectType >; expect(peopleType.ofType).toBe(Human); @@ -1038,7 +1045,7 @@ describe('@directives', () => { const directives = getDirectives(schema, type); const directiveArgumentMap = directives[directiveName]; if (directiveArgumentMap) { - expect(type.name).toBe(schema.getQueryType().name); + expect(type.name).toBe(schema.getQueryType()?.name); visited.add(type); } return undefined; diff --git a/packages/utils/tests/validate-documents.spec.ts b/packages/utils/tests/validate-documents.spec.ts index 5f1b12e6169..62dff298b84 100644 --- a/packages/utils/tests/validate-documents.spec.ts +++ b/packages/utils/tests/validate-documents.spec.ts @@ -53,7 +53,8 @@ describe('validateGraphQlDocuments', () => { try { checkValidationErrors(result); expect(true).toBeFalsy(); - } catch (errors) { + } catch (aggregateError) { + const { errors } = aggregateError; expect(Symbol.iterator in errors).toBeTruthy(); const generator = errors[Symbol.iterator](); @@ -112,8 +113,8 @@ describe('checkValidationErrors', () => { let errors; try { checkValidationErrors(loadDocumentErrors as any); - } catch (_errors) { - errors = _errors; + } catch (aggregateError) { + errors = aggregateError.errors; } expect(Symbol.iterator in errors).toBeTruthy(); diff --git a/packages/utils/tests/visitResult.test.ts b/packages/utils/tests/visitResult.test.ts index ae6817a4f5d..e67ca1a38fd 100644 --- a/packages/utils/tests/visitResult.test.ts +++ b/packages/utils/tests/visitResult.test.ts @@ -389,7 +389,7 @@ describe('visiting errors', () => { const visitedResult = visitResult(result, request, schema, undefined, { Query: { test: (error, pathIndex) => { - const oldPath = error.path; + const oldPath = error.path ?? []; const newPath = [...oldPath.slice(0, pathIndex), 'inserted', ...oldPath.slice(pathIndex)]; return relocatedError(error, newPath); }, diff --git a/packages/webpack-loader/package.json b/packages/webpack-loader/package.json index d94f3e3ea39..e08f6187e84 100644 --- a/packages/webpack-loader/package.json +++ b/packages/webpack-loader/package.json @@ -34,7 +34,10 @@ "dependencies": { "@graphql-tools/optimize": "1.0.1", "@graphql-tools/webpack-loader-runtime": "^6.2.4", - "tslib": "~2.2.0" + "tslib": "~2.3.0" + }, + "devDependencies": { + "@types/webpack": "5.28.0" }, "publishConfig": { "access": "public", diff --git a/packages/webpack-loader/src/index.ts b/packages/webpack-loader/src/index.ts index b2fa17b9623..da45e5aa978 100644 --- a/packages/webpack-loader/src/index.ts +++ b/packages/webpack-loader/src/index.ts @@ -3,6 +3,7 @@ import { isExecutableDefinitionNode, Kind, DocumentNode } from 'graphql'; import { uniqueCode } from '@graphql-tools/webpack-loader-runtime'; import { parseDocument } from './parser'; import { optimizeDocumentNode, removeDescriptions, removeEmptyNodes } from '@graphql-tools/optimize'; +import type { LoaderContext } from 'webpack'; function isSDL(doc: DocumentNode) { return !doc.definitions.some(def => isExecutableDefinitionNode(def)); @@ -41,9 +42,10 @@ function expandImports(source: string, options: Options) { return outputCode; } -export default function graphqlLoader(source: string) { +export default function graphqlLoader(this: LoaderContext, source: string) { this.cacheable(); - const options: Options = this.query || {}; + // TODO: This should probably use this.getOptions() + const options = (this.query as Options) || {}; let doc = parseDocument(source); const optimizers = []; @@ -62,11 +64,10 @@ export default function graphqlLoader(source: string) { let stringifiedDoc = JSON.stringify(doc); if (options.replaceKinds) { - Object.keys(Kind).forEach((identifier: keyof typeof Kind) => { - const value = Kind[identifier]; - + for (const identifier in Kind) { + const value = Kind[identifier as keyof typeof Kind]; stringifiedDoc = stringifiedDoc.replace(new RegExp(`"kind":"${value}"`, 'g'), `"kind": Kind.${identifier}`); - }); + } } const headerCode = ` diff --git a/packages/webpack-loader/tests/loader.test.ts b/packages/webpack-loader/tests/loader.test.ts index eefd1c4f95a..1e719cf2c72 100644 --- a/packages/webpack-loader/tests/loader.test.ts +++ b/packages/webpack-loader/tests/loader.test.ts @@ -4,7 +4,7 @@ import {uniqueCode} from '@graphql-tools/webpack-loader-runtime'; import loader from '../src/index'; function useLoader(source: string, options: any): string { - return loader.call({cacheable() {}, query: options}, source) + return loader.call({cacheable() {}, query: options} as any, source) } test('basic query', () => { diff --git a/packages/wrap/package.json b/packages/wrap/package.json index 7a924058914..513c1df580e 100644 --- a/packages/wrap/package.json +++ b/packages/wrap/package.json @@ -38,7 +38,7 @@ "@graphql-tools/delegate": "^7.1.5", "@graphql-tools/schema": "^7.1.5", "@graphql-tools/utils": "^7.8.1", - "tslib": "~2.2.0", + "tslib": "~2.3.0", "value-or-promise": "1.0.10" }, "publishConfig": { diff --git a/packages/wrap/src/generateProxyingResolvers.ts b/packages/wrap/src/generateProxyingResolvers.ts index c2e07c0d6f7..e394509003d 100644 --- a/packages/wrap/src/generateProxyingResolvers.ts +++ b/packages/wrap/src/generateProxyingResolvers.ts @@ -1,6 +1,6 @@ import { GraphQLFieldResolver, GraphQLObjectType, GraphQLResolveInfo, OperationTypeNode } from 'graphql'; -import { getResponseKeyFromInfo } from '@graphql-tools/utils'; +import { Maybe, getResponseKeyFromInfo } from '@graphql-tools/utils'; import { delegateToSchema, getSubschema, @@ -12,29 +12,30 @@ import { getUnpathedErrors, } from '@graphql-tools/delegate'; -export function generateProxyingResolvers( - subschemaConfig: SubschemaConfig +export function generateProxyingResolvers( + subschemaConfig: SubschemaConfig ): Record>> { const targetSchema = subschemaConfig.schema; const createProxyingResolver = subschemaConfig.createProxyingResolver ?? defaultCreateProxyingResolver; const transformedSchema = applySchemaTransforms(targetSchema, subschemaConfig); - const operationTypes: Record = { + const operationTypes: Record> = { query: targetSchema.getQueryType(), mutation: targetSchema.getMutationType(), subscription: targetSchema.getSubscriptionType(), }; const resolvers = {}; - Object.keys(operationTypes).forEach((operation: OperationTypeNode) => { + for (const operationAsString in operationTypes) { + const operation = operationAsString as OperationTypeNode; const rootType = operationTypes[operation]; if (rootType != null) { const typeName = rootType.name; const fields = rootType.getFields(); resolvers[typeName] = {}; - Object.keys(fields).forEach(fieldName => { + for (const fieldName in fields) { const proxyingResolver = createProxyingResolver({ subschemaConfig, transformedSchema, @@ -55,17 +56,17 @@ export function generateProxyingResolvers( resolve: finalResolver, }; } - }); + } } - }); + } return resolvers; } -function createPossiblyNestedProxyingResolver( - subschemaConfig: SubschemaConfig, +function createPossiblyNestedProxyingResolver( + subschemaConfig: SubschemaConfig, proxyingResolver: GraphQLFieldResolver -): GraphQLFieldResolver { +): GraphQLFieldResolver { return (parent, args, context, info) => { if (parent != null) { const responseKey = getResponseKeyFromInfo(info); @@ -88,11 +89,11 @@ function createPossiblyNestedProxyingResolver( }; } -export function defaultCreateProxyingResolver({ +export function defaultCreateProxyingResolver({ subschemaConfig, operation, transformedSchema, -}: ICreateProxyingResolverOptions): GraphQLFieldResolver { +}: ICreateProxyingResolverOptions): GraphQLFieldResolver { return (_parent, _args, context, info) => delegateToSchema({ schema: subschemaConfig, diff --git a/packages/wrap/src/index.ts b/packages/wrap/src/index.ts index 7be4ebcc7bf..317d012e34c 100644 --- a/packages/wrap/src/index.ts +++ b/packages/wrap/src/index.ts @@ -3,6 +3,5 @@ export { defaultCreateProxyingResolver, generateProxyingResolvers } from './gene export * from './transforms/index'; -export { makeRemoteExecutableSchema, defaultCreateRemoteResolver } from './makeRemoteExecutableSchema'; export * from './types'; export * from './introspect'; diff --git a/packages/wrap/src/introspect.ts b/packages/wrap/src/introspect.ts index 08ef51fdf9c..6a11a74e545 100644 --- a/packages/wrap/src/introspect.ts +++ b/packages/wrap/src/introspect.ts @@ -1,24 +1,33 @@ import { GraphQLSchema, - DocumentNode, getIntrospectionQuery, buildClientSchema, parse, IntrospectionOptions, IntrospectionQuery, + ParseOptions, } from 'graphql'; import { ValueOrPromise } from 'value-or-promise'; -import { AsyncExecutor, Executor, SyncExecutor, ExecutionResult } from '@graphql-tools/utils'; -import AggregateError from '@ardatan/aggregate-error'; +import { + AsyncExecutor, + Executor, + ExecutionResult, + AggregateError, + isAsyncIterable, + SyncExecutor, +} from '@graphql-tools/utils'; -function getSchemaFromIntrospection(introspectionResult: ExecutionResult): GraphQLSchema { +function getSchemaFromIntrospection( + introspectionResult: ExecutionResult, + options?: Parameters[1] +): GraphQLSchema { if (introspectionResult?.data?.__schema) { - return buildClientSchema(introspectionResult.data); + return buildClientSchema(introspectionResult.data, options); } else if (introspectionResult?.errors?.length) { if (introspectionResult.errors.length > 1) { - const combinedError = new AggregateError(introspectionResult.errors); + const combinedError = new AggregateError(introspectionResult.errors, 'Could not obtain introspection result'); throw combinedError; } const error = introspectionResult.errors[0]; @@ -28,23 +37,34 @@ function getSchemaFromIntrospection(introspectionResult: ExecutionResult( - executor: TExecutor, - context?: Record, - options?: IntrospectionOptions -): TExecutor extends AsyncExecutor ? Promise : GraphQLSchema { - const parsedIntrospectionQuery: DocumentNode = parse(getIntrospectionQuery(options)); - return new ValueOrPromise(() => (executor as Executor)({ - document: parsedIntrospectionQuery, - context, - })).then(introspection => getSchemaFromIntrospection(introspection)).resolve() as any; -} - -// Keep for backwards compatibility. Will be removed on next release. -export function introspectSchemaSync( +export function introspectSchema( executor: SyncExecutor, context?: Record, - options?: IntrospectionOptions -) { - return introspectSchema(executor, context, options); + options?: Partial & Parameters[1] & ParseOptions +): GraphQLSchema; +export function introspectSchema( + executor: AsyncExecutor, + context?: Record, + options?: Partial & Parameters[1] & ParseOptions +): Promise; +export function introspectSchema( + executor: Executor, + context?: Record, + options?: Partial & Parameters[1] & ParseOptions +): Promise | GraphQLSchema { + const parsedIntrospectionQuery = parse(getIntrospectionQuery(options as any), options); + return new ValueOrPromise(() => + executor({ + document: parsedIntrospectionQuery, + context, + }) + ) + .then(introspection => { + if (isAsyncIterable(introspection)) { + return introspection.next().then(({ value }) => value); + } + return introspection; + }) + .then(introspection => getSchemaFromIntrospection(introspection, options)) + .resolve(); } diff --git a/packages/wrap/src/makeRemoteExecutableSchema.ts b/packages/wrap/src/makeRemoteExecutableSchema.ts deleted file mode 100644 index 0245e53ba6a..00000000000 --- a/packages/wrap/src/makeRemoteExecutableSchema.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { buildSchema, GraphQLFieldResolver, GraphQLSchema } from 'graphql'; - -import { IMakeRemoteExecutableSchemaOptions } from './types'; -import { delegateToSchema } from '@graphql-tools/delegate'; - -import { wrapSchema } from './wrapSchema'; -import { Executor, Subscriber } from '@graphql-tools/utils'; - -export function makeRemoteExecutableSchema({ - schema: schemaOrTypeDefs, - executor, - subscriber, - createResolver = defaultCreateRemoteResolver, - buildSchemaOptions, -}: IMakeRemoteExecutableSchemaOptions): GraphQLSchema { - const targetSchema = - typeof schemaOrTypeDefs === 'string' ? buildSchema(schemaOrTypeDefs, buildSchemaOptions) : schemaOrTypeDefs; - - return wrapSchema({ - schema: targetSchema, - createProxyingResolver: () => createResolver(executor, subscriber), - }); -} - -export function defaultCreateRemoteResolver( - executor: Executor, - subscriber: Subscriber -): GraphQLFieldResolver { - return (_parent, _args, context, info) => - delegateToSchema({ - schema: { schema: info.schema, executor, subscriber }, - context, - info, - }); -} diff --git a/packages/wrap/src/transforms/FilterObjectFieldDirectives.ts b/packages/wrap/src/transforms/FilterObjectFieldDirectives.ts index 4d471964613..74e7ec64be9 100644 --- a/packages/wrap/src/transforms/FilterObjectFieldDirectives.ts +++ b/packages/wrap/src/transforms/FilterObjectFieldDirectives.ts @@ -20,13 +20,17 @@ export default class FilterObjectFieldDirectives implements Transform { ): GraphQLSchema { const transformer = new TransformObjectFields( (_typeName: string, _fieldName: string, fieldConfig: GraphQLFieldConfig) => { - const keepDirectives = fieldConfig.astNode.directives.filter(dir => { - const directiveDef = originalWrappingSchema.getDirective(dir.name.value); - const directiveValue = directiveDef ? getArgumentValues(directiveDef, dir) : undefined; - return this.filter(dir.name.value, directiveValue); - }); - - if (keepDirectives.length !== fieldConfig.astNode.directives.length) { + const keepDirectives = + fieldConfig.astNode?.directives?.filter(dir => { + const directiveDef = originalWrappingSchema.getDirective(dir.name.value); + const directiveValue = directiveDef ? getArgumentValues(directiveDef, dir) : undefined; + return this.filter(dir.name.value, directiveValue); + }) ?? []; + + if ( + fieldConfig.astNode?.directives != null && + keepDirectives.length !== fieldConfig.astNode.directives.length + ) { fieldConfig = { ...fieldConfig, astNode: { diff --git a/packages/wrap/src/transforms/FilterObjectFields.ts b/packages/wrap/src/transforms/FilterObjectFields.ts index d02dc59d956..ca652937ffe 100644 --- a/packages/wrap/src/transforms/FilterObjectFields.ts +++ b/packages/wrap/src/transforms/FilterObjectFields.ts @@ -1,6 +1,6 @@ import { GraphQLSchema, GraphQLFieldConfig } from 'graphql'; -import { FieldFilter } from '@graphql-tools/utils'; +import { ObjectFieldFilter } from '@graphql-tools/utils'; import { SubschemaConfig, Transform } from '@graphql-tools/delegate'; @@ -9,7 +9,7 @@ import TransformObjectFields from './TransformObjectFields'; export default class FilterObjectFields implements Transform { private readonly transformer: TransformObjectFields; - constructor(filter: FieldFilter) { + constructor(filter: ObjectFieldFilter) { this.transformer = new TransformObjectFields( (typeName: string, fieldName: string, fieldConfig: GraphQLFieldConfig) => filter(typeName, fieldName, fieldConfig) ? undefined : null diff --git a/packages/wrap/src/transforms/HoistField.ts b/packages/wrap/src/transforms/HoistField.ts index fedb4735ec8..4c686613016 100644 --- a/packages/wrap/src/transforms/HoistField.ts +++ b/packages/wrap/src/transforms/HoistField.ts @@ -9,7 +9,14 @@ import { GraphQLFieldResolver, } from 'graphql'; -import { appendObjectFields, removeObjectFields, Request, ExecutionResult, relocatedError } from '@graphql-tools/utils'; +import { + appendObjectFields, + removeObjectFields, + Request, + ExecutionResult, + relocatedError, + assertSome, +} from '@graphql-tools/utils'; import { Transform, defaultMergedResolver, DelegationContext, SubschemaConfig } from '@graphql-tools/delegate'; @@ -24,7 +31,7 @@ export default class HoistField implements Transform { private readonly oldFieldName: string; private readonly argFilters: Array<(arg: GraphQLArgument) => boolean>; private readonly argLevels: Record; - private readonly transformer: Transform; + private readonly transformer: MapFields; constructor( typeName: string, @@ -45,6 +52,7 @@ export default class HoistField implements Transform { const pathToField = path.slice(); const oldFieldName = pathToField.pop(); + assertSome(oldFieldName); this.oldFieldName = oldFieldName; this.pathToField = pathToField; @@ -59,7 +67,7 @@ export default class HoistField implements Transform { { [typeName]: value => unwrapValue(value, alias), }, - errors => unwrapErrors(errors, alias) + errors => (errors != null ? unwrapErrors(errors, alias) : undefined) ); this.argLevels = argLevels; } @@ -72,12 +80,12 @@ export default class HoistField implements Transform { const argsMap: Record = Object.create(null); const innerType: GraphQLObjectType = this.pathToField.reduce((acc, pathSegment, index) => { const field = acc.getFields()[pathSegment]; - field.args.forEach(arg => { + for (const arg of field.args) { if (this.argFilters[index](arg)) { argsMap[arg.name] = arg; this.argLevels[arg.name] = index; } - }); + } return getNullableType(field.type) as GraphQLObjectType; }, originalWrappingSchema.getType(this.typeName) as GraphQLObjectType); @@ -97,7 +105,7 @@ export default class HoistField implements Transform { if (hoistingToRootField) { const targetSchema = subschemaConfig.schema; - const operation = this.typeName === targetSchema.getQueryType().name ? 'query' : 'mutation'; + const operation = this.typeName === targetSchema.getQueryType()?.name ? 'query' : 'mutation'; const createProxyingResolver = subschemaConfig.createProxyingResolver ?? defaultCreateProxyingResolver; resolve = createProxyingResolver({ subschemaConfig, @@ -112,26 +120,32 @@ export default class HoistField implements Transform { const newTargetField = { ...targetField, - resolve, + resolve: resolve!, }; const level = this.pathToField.length; - Object.keys(targetField.args).forEach(argName => { - const argConfig = targetField.args[argName]; - const arg = { - ...argConfig, - name: argName, - description: argConfig.description, - defaultValue: argConfig.defaultValue, - extensions: argConfig.extensions, - astNode: argConfig.astNode, - } as GraphQLArgument; - if (this.argFilters[level](arg)) { - argsMap[argName] = arg; - this.argLevels[arg.name] = level; + const args = targetField.args; + if (args != null) { + for (const argName in args) { + const argConfig = args[argName]; + if (argConfig == null) { + continue; + } + const arg = { + ...argConfig, + name: argName, + description: argConfig.description, + defaultValue: argConfig.defaultValue, + extensions: argConfig.extensions, + astNode: argConfig.astNode, + } as GraphQLArgument; + if (this.argFilters[level](arg)) { + argsMap[argName] = arg; + this.argLevels[arg.name] = level; + } } - }); + } newTargetField.args = argsMap; @@ -180,11 +194,17 @@ export function wrapFieldNode( kind: Kind.SELECTION_SET, selections: [acc], }, - arguments: fieldNode.arguments.filter(arg => argLevels[arg.name.value] === index), + arguments: + fieldNode.arguments != null + ? fieldNode.arguments.filter(arg => argLevels[arg.name.value] === index) + : undefined, }), { ...fieldNode, - arguments: fieldNode.arguments.filter(arg => argLevels[arg.name.value] === path.length), + arguments: + fieldNode.arguments != null + ? fieldNode.arguments.filter(arg => argLevels[arg.name.value] === path.length) + : undefined, } ); } @@ -218,7 +238,7 @@ export function unwrapValue(originalValue: any, alias: string): any { return originalValue; } -function unwrapErrors(errors: ReadonlyArray, alias: string): Array { +function unwrapErrors(errors: ReadonlyArray | undefined, alias: string): Array | undefined { if (errors === undefined) { return undefined; } diff --git a/packages/wrap/src/transforms/MapFields.ts b/packages/wrap/src/transforms/MapFields.ts index 638ec88eef9..d63af39f41e 100644 --- a/packages/wrap/src/transforms/MapFields.ts +++ b/packages/wrap/src/transforms/MapFields.ts @@ -1,6 +1,6 @@ import { GraphQLSchema } from 'graphql'; -import { Request, FieldNodeMappers, ExecutionResult } from '@graphql-tools/utils'; +import { Request, FieldNodeMappers, ExecutionResult, assertSome } from '@graphql-tools/utils'; import { Transform, DelegationContext, SubschemaConfig } from '@graphql-tools/delegate'; @@ -8,11 +8,11 @@ import { ObjectValueTransformerMap, ErrorsTransformer } from '../types'; import TransformCompositeFields from './TransformCompositeFields'; -export default class MapFields implements Transform { +export default class MapFields implements Transform { private fieldNodeTransformerMap: FieldNodeMappers; private objectValueTransformerMap?: ObjectValueTransformerMap; private errorsTransformer?: ErrorsTransformer; - private transformer: TransformCompositeFields; + private transformer: TransformCompositeFields | undefined; constructor( fieldNodeTransformerMap: FieldNodeMappers, @@ -24,12 +24,18 @@ export default class MapFields implements Transform { this.errorsTransformer = errorsTransformer; } + private _getTransformer() { + assertSome(this.transformer); + return this.transformer; + } + public transformSchema( originalWrappingSchema: GraphQLSchema, - subschemaConfig: SubschemaConfig, + subschemaConfig: SubschemaConfig, transformedSchema?: GraphQLSchema ): GraphQLSchema { const subscriptionTypeName = originalWrappingSchema.getSubscriptionType()?.name; + const objectValueTransformerMap = this.objectValueTransformerMap; this.transformer = new TransformCompositeFields( () => undefined, (typeName, fieldName, fieldNode, fragments, transformationContext) => { @@ -45,7 +51,7 @@ export default class MapFields implements Transform { return fieldNodeTransformer(fieldNode, fragments, transformationContext); }, - this.objectValueTransformerMap != null + objectValueTransformerMap != null ? (data, transformationContext) => { if (data == null) { return data; @@ -60,7 +66,7 @@ export default class MapFields implements Transform { } } - const transformer = this.objectValueTransformerMap[typeName]; + const transformer = objectValueTransformerMap[typeName]; if (transformer == null) { return data; } @@ -78,7 +84,7 @@ export default class MapFields implements Transform { delegationContext: DelegationContext, transformationContext: Record ): Request { - return this.transformer.transformRequest(originalRequest, delegationContext, transformationContext); + return this._getTransformer().transformRequest(originalRequest, delegationContext, transformationContext); } public transformResult( @@ -86,6 +92,6 @@ export default class MapFields implements Transform { delegationContext: DelegationContext, transformationContext: Record ): ExecutionResult { - return this.transformer.transformResult(originalResult, delegationContext, transformationContext); + return this._getTransformer().transformResult(originalResult, delegationContext, transformationContext); } } diff --git a/packages/wrap/src/transforms/MapLeafValues.ts b/packages/wrap/src/transforms/MapLeafValues.ts index a9f4cd402e1..cbd4c0141ea 100644 --- a/packages/wrap/src/transforms/MapLeafValues.ts +++ b/packages/wrap/src/transforms/MapLeafValues.ts @@ -8,7 +8,6 @@ import { FragmentDefinitionNode, VariableDefinitionNode, ArgumentNode, - GraphQLArgument, FieldNode, valueFromAST, isLeafType, @@ -21,6 +20,7 @@ import { ResultVisitorMap, updateArgument, transformInputValue, + assertSome, } from '@graphql-tools/utils'; import { Transform, DelegationContext, SubschemaConfig } from '@graphql-tools/delegate'; @@ -35,8 +35,8 @@ export default class MapLeafValues implements Transform { + for (const typeName in typeMap) { const type = typeMap[typeName]; if (!typeName.startsWith('__')) { if (isLeafType(type)) { this.resultVisitorMap[typeName] = (value: any) => this.outputValueTransformer(typeName, value); } } - }); + } this.typeInfo = new TypeInfo(originalWrappingSchema); return originalWrappingSchema; } @@ -66,7 +76,7 @@ export default class MapLeafValues implements Transform ): Array { return operations.map((operation: OperationDefinitionNode) => { - const variableDefinitionMap: Record = operation.variableDefinitions.reduce( + const variableDefinitionMap: Record = ( + operation.variableDefinitions ?? [] + ).reduce( (prev, def) => ({ ...prev, [def.variable.name.value]: def, @@ -122,14 +134,14 @@ export default class MapLeafValues implements Transform this.transformFieldNode(node, variableDefinitionMap, variableValues), }) ); return { ...newOperation, - variableDefinitions: Object.keys(variableDefinitionMap).map(varName => variableDefinitionMap[varName]), + variableDefinitions: Object.values(variableDefinitionMap), }; }); } @@ -138,8 +150,8 @@ export default class MapLeafValues implements Transform, variableValues: Record - ): FieldNode { - const targetField = this.typeInfo.getFieldDef(); + ): FieldNode | undefined { + const targetField = this._getTypeInfo().getFieldDef(); if (!targetField.name.startsWith('__')) { const argumentNodes = field.arguments; @@ -152,7 +164,7 @@ export default class MapLeafValues implements Transform { + for (const argument of targetField.args) { const argName = argument.name; const argType = argument.type; @@ -175,11 +187,11 @@ export default class MapLeafValues implements Transform argumentNodeMap[argName]), + arguments: Object.values(argumentNodeMap), }; } } diff --git a/packages/wrap/src/transforms/RemoveObjectFieldsWithDeprecation.ts b/packages/wrap/src/transforms/RemoveObjectFieldsWithDeprecation.ts index 958f32f3911..2e25ebb043a 100644 --- a/packages/wrap/src/transforms/RemoveObjectFieldsWithDeprecation.ts +++ b/packages/wrap/src/transforms/RemoveObjectFieldsWithDeprecation.ts @@ -1,4 +1,4 @@ -import { GraphQLSchema, GraphQLFieldConfig } from 'graphql'; +import { GraphQLSchema } from 'graphql'; import { valueMatchesCriteria } from '@graphql-tools/utils'; @@ -10,14 +10,12 @@ export default class RemoveObjectFieldsWithDeprecation implements Transform { private readonly transformer: FilterObjectFields; constructor(reason: string | RegExp) { - this.transformer = new FilterObjectFields( - (_typeName: string, _fieldName: string, fieldConfig: GraphQLFieldConfig) => { - if (fieldConfig.deprecationReason) { - return !valueMatchesCriteria(fieldConfig.deprecationReason, reason); - } - return true; + this.transformer = new FilterObjectFields((_typeName, _fieldName, fieldConfig) => { + if (fieldConfig.deprecationReason) { + return !valueMatchesCriteria(fieldConfig.deprecationReason, reason); } - ); + return true; + }); } public transformSchema( diff --git a/packages/wrap/src/transforms/RemoveObjectFieldsWithDirective.ts b/packages/wrap/src/transforms/RemoveObjectFieldsWithDirective.ts index d44aee5b7c1..2633df6e282 100644 --- a/packages/wrap/src/transforms/RemoveObjectFieldsWithDirective.ts +++ b/packages/wrap/src/transforms/RemoveObjectFieldsWithDirective.ts @@ -1,4 +1,4 @@ -import { GraphQLSchema, GraphQLFieldConfig } from 'graphql'; +import { GraphQLSchema } from 'graphql'; import { getDirectives, valueMatchesCriteria } from '@graphql-tools/utils'; @@ -20,18 +20,16 @@ export default class RemoveObjectFieldsWithDirective implements Transform { subschemaConfig: SubschemaConfig, transformedSchema?: GraphQLSchema ): GraphQLSchema { - const transformer = new FilterObjectFields( - (_typeName: string, _fieldName: string, fieldConfig: GraphQLFieldConfig) => { - const valueMap = getDirectives(originalWrappingSchema, fieldConfig); - return !Object.keys(valueMap).some( - directiveName => - valueMatchesCriteria(directiveName, this.directiveName) && - ((Array.isArray(valueMap[directiveName]) && - valueMap[directiveName].some((value: any) => valueMatchesCriteria(value, this.args))) || - valueMatchesCriteria(valueMap[directiveName], this.args)) - ); - } - ); + const transformer = new FilterObjectFields((_typeName, _fieldName, fieldConfig) => { + const valueMap = getDirectives(originalWrappingSchema, fieldConfig); + return !Object.keys(valueMap).some( + directiveName => + valueMatchesCriteria(directiveName, this.directiveName) && + ((Array.isArray(valueMap[directiveName]) && + valueMap[directiveName].some((value: any) => valueMatchesCriteria(value, this.args))) || + valueMatchesCriteria(valueMap[directiveName], this.args)) + ); + }); return transformer.transformSchema(originalWrappingSchema, subschemaConfig, transformedSchema); } diff --git a/packages/wrap/src/transforms/RenameInputObjectFields.ts b/packages/wrap/src/transforms/RenameInputObjectFields.ts index 6e2d80ecbc8..a7084ea3a15 100644 --- a/packages/wrap/src/transforms/RenameInputObjectFields.ts +++ b/packages/wrap/src/transforms/RenameInputObjectFields.ts @@ -6,18 +6,27 @@ import { Transform, DelegationContext, SubschemaConfig } from '@graphql-tools/de import TransformInputObjectFields from './TransformInputObjectFields'; +type RenamerFunction = ( + typeName: string, + fieldName: string, + inputFieldConfig: GraphQLInputFieldConfig +) => string | undefined; + export default class RenameInputObjectFields implements Transform { - private readonly renamer: (typeName: string, fieldName: string, inputFieldConfig: GraphQLInputFieldConfig) => string; + private readonly renamer: RenamerFunction; private readonly transformer: TransformInputObjectFields; private reverseMap: Record>; - constructor(renamer: (typeName: string, fieldName: string, inputFieldConfig: GraphQLInputFieldConfig) => string) { + constructor(renamer: RenamerFunction) { this.renamer = renamer; this.transformer = new TransformInputObjectFields( - (typeName: string, inputFieldName: string, inputFieldConfig: GraphQLInputFieldConfig) => { + (typeName, inputFieldName, inputFieldConfig) => { const newName = renamer(typeName, inputFieldName, inputFieldConfig); if (newName !== undefined && newName !== inputFieldName) { - return [renamer(typeName, inputFieldName, inputFieldConfig), inputFieldConfig]; + const value = renamer(typeName, inputFieldName, inputFieldConfig); + if (value != null) { + return [value, inputFieldConfig]; + } } }, (typeName: string, inputFieldName: string, inputFieldNode: ObjectFieldNode) => { diff --git a/packages/wrap/src/transforms/TransformCompositeFields.ts b/packages/wrap/src/transforms/TransformCompositeFields.ts index 537b3e20d92..127fa9db5e9 100644 --- a/packages/wrap/src/transforms/TransformCompositeFields.ts +++ b/packages/wrap/src/transforms/TransformCompositeFields.ts @@ -11,21 +11,21 @@ import { FragmentDefinitionNode, } from 'graphql'; -import { Request, MapperKind, mapSchema, visitData, ExecutionResult } from '@graphql-tools/utils'; +import { Request, MapperKind, mapSchema, visitData, ExecutionResult, Maybe, assertSome } from '@graphql-tools/utils'; import { Transform, DelegationContext, SubschemaConfig } from '@graphql-tools/delegate'; import { FieldTransformer, FieldNodeTransformer, DataTransformer, ErrorsTransformer } from '../types'; -export default class TransformCompositeFields implements Transform { +export default class TransformCompositeFields> implements Transform { private readonly fieldTransformer: FieldTransformer; - private readonly fieldNodeTransformer: FieldNodeTransformer; - private readonly dataTransformer: DataTransformer; - private readonly errorsTransformer: ErrorsTransformer; - private transformedSchema: GraphQLSchema; - private typeInfo: TypeInfo; + private readonly fieldNodeTransformer: FieldNodeTransformer | undefined; + private readonly dataTransformer: DataTransformer | undefined; + private readonly errorsTransformer: ErrorsTransformer | undefined; + private transformedSchema: GraphQLSchema | undefined; + private typeInfo: TypeInfo | undefined; private mapping: Record>; - private subscriptionTypeName: string; + private subscriptionTypeName: string | undefined; constructor( fieldTransformer: FieldTransformer, @@ -40,9 +40,14 @@ export default class TransformCompositeFields implements Transform { this.mapping = {}; } + private _getTypeInfo() { + assertSome(this.typeInfo); + return this.typeInfo; + } + public transformSchema( originalWrappingSchema: GraphQLSchema, - _subschemaConfig: SubschemaConfig, + _subschemaConfig: SubschemaConfig, _transformedSchema?: GraphQLSchema ): GraphQLSchema { this.transformedSchema = mapSchema(originalWrappingSchema, { @@ -74,11 +79,11 @@ export default class TransformCompositeFields implements Transform { ): Request { const document = originalRequest.document; const fragments = Object.create(null); - document.definitions.forEach(def => { + for (const def of document.definitions) { if (def.kind === Kind.FRAGMENT_DEFINITION) { fragments[def.name.value] = def; } - }); + } return { ...originalRequest, document: this.transformDocument(document, fragments, transformationContext), @@ -90,10 +95,11 @@ export default class TransformCompositeFields implements Transform { _delegationContext: DelegationContext, transformationContext: Record ): ExecutionResult { - if (this.dataTransformer != null) { - result.data = visitData(result.data, value => this.dataTransformer(value, transformationContext)); + const dataTransformer = this.dataTransformer; + if (dataTransformer != null) { + result.data = visitData(result.data, value => dataTransformer(value, transformationContext)); } - if (this.errorsTransformer != null) { + if (this.errorsTransformer != null && Array.isArray(result.errors)) { result.errors = this.errorsTransformer(result.errors, transformationContext); } return result; @@ -106,10 +112,10 @@ export default class TransformCompositeFields implements Transform { ): DocumentNode { return visit( document, - visitWithTypeInfo(this.typeInfo, { + visitWithTypeInfo(this._getTypeInfo(), { leave: { [Kind.SELECTION_SET]: node => - this.transformSelectionSet(node, this.typeInfo, fragments, transformationContext), + this.transformSelectionSet(node, this._getTypeInfo(), fragments, transformationContext), }, }) ); @@ -120,8 +126,8 @@ export default class TransformCompositeFields implements Transform { typeInfo: TypeInfo, fragments: Record, transformationContext: Record - ): SelectionSetNode { - const parentType: GraphQLType = typeInfo.getParentType(); + ): SelectionSetNode | undefined { + const parentType: Maybe = typeInfo.getParentType(); if (parentType == null) { return undefined; } @@ -129,10 +135,10 @@ export default class TransformCompositeFields implements Transform { const parentTypeName = parentType.name; let newSelections: Array = []; - node.selections.forEach(selection => { + for (const selection of node.selections) { if (selection.kind !== Kind.FIELD) { newSelections.push(selection); - return; + continue; } const newName = selection.name.value; @@ -151,7 +157,7 @@ export default class TransformCompositeFields implements Transform { }); } - let transformedSelection: SelectionNode | Array; + let transformedSelection: Maybe>; if (this.fieldNodeTransformer == null) { transformedSelection = selection; } else { @@ -166,25 +172,25 @@ export default class TransformCompositeFields implements Transform { } if (transformedSelection == null) { - return; + continue; } else if (Array.isArray(transformedSelection)) { newSelections = newSelections.concat(transformedSelection); - return; + continue; } else if (transformedSelection.kind !== Kind.FIELD) { newSelections.push(transformedSelection); - return; + continue; } const typeMapping = this.mapping[parentTypeName]; if (typeMapping == null) { newSelections.push(transformedSelection); - return; + continue; } const oldName = this.mapping[parentTypeName][newName]; if (oldName == null) { newSelections.push(transformedSelection); - return; + continue; } newSelections.push({ @@ -198,7 +204,7 @@ export default class TransformCompositeFields implements Transform { value: transformedSelection.alias?.value ?? newName, }, }); - }); + } return { ...node, diff --git a/packages/wrap/src/transforms/TransformEnumValues.ts b/packages/wrap/src/transforms/TransformEnumValues.ts index 009cf5e0d56..29a6fba90ce 100644 --- a/packages/wrap/src/transforms/TransformEnumValues.ts +++ b/packages/wrap/src/transforms/TransformEnumValues.ts @@ -1,6 +1,6 @@ import { GraphQLSchema, GraphQLEnumValueConfig, ExecutionResult } from 'graphql'; -import { Request, MapperKind, mapSchema } from '@graphql-tools/utils'; +import { Request, MapperKind, mapSchema, Maybe } from '@graphql-tools/utils'; import { Transform, DelegationContext, SubschemaConfig } from '@graphql-tools/delegate'; @@ -11,7 +11,7 @@ import MapLeafValues, { MapLeafValuesTransformationContext } from './MapLeafValu export default class TransformEnumValues implements Transform { private readonly enumValueTransformer: EnumValueTransformer; private readonly transformer: MapLeafValues; - private transformedSchema: GraphQLSchema; + private transformedSchema: GraphQLSchema | undefined; private mapping: Record>; private reverseMapping: Record>; @@ -62,7 +62,7 @@ export default class TransformEnumValues implements Transform { const transformedEnumValue = this.enumValueTransformer(typeName, externalValue, enumValueConfig); if (Array.isArray(transformedEnumValue)) { const newExternalValue = transformedEnumValue[0]; @@ -86,7 +86,7 @@ function mapEnumValues(typeName: string, value: string, mapping: Record, mapping: Record> ): LeafValueTransformer { if (valueTransformer == null) { diff --git a/packages/wrap/src/transforms/TransformInputObjectFields.ts b/packages/wrap/src/transforms/TransformInputObjectFields.ts index f823a511a33..8f15bc67dd2 100644 --- a/packages/wrap/src/transforms/TransformInputObjectFields.ts +++ b/packages/wrap/src/transforms/TransformInputObjectFields.ts @@ -1,6 +1,5 @@ import { GraphQLSchema, - GraphQLType, DocumentNode, typeFromAST, TypeInfo, @@ -9,14 +8,13 @@ import { Kind, FragmentDefinitionNode, GraphQLInputObjectType, - GraphQLInputType, ObjectValueNode, ObjectFieldNode, OperationDefinitionNode, - NamedTypeNode, + isInputType, } from 'graphql'; -import { Request, MapperKind, mapSchema, transformInputValue } from '@graphql-tools/utils'; +import { Maybe, Request, MapperKind, mapSchema, transformInputValue, assertSome } from '@graphql-tools/utils'; import { Transform, DelegationContext, SubschemaConfig } from '@graphql-tools/delegate'; @@ -24,9 +22,9 @@ import { InputFieldTransformer, InputFieldNodeTransformer, InputObjectNodeTransf export default class TransformInputObjectFields implements Transform { private readonly inputFieldTransformer: InputFieldTransformer; - private readonly inputFieldNodeTransformer: InputFieldNodeTransformer; - private readonly inputObjectNodeTransformer: InputObjectNodeTransformer; - private transformedSchema: GraphQLSchema; + private readonly inputFieldNodeTransformer: InputFieldNodeTransformer | undefined; + private readonly inputObjectNodeTransformer: InputObjectNodeTransformer | undefined; + private transformedSchema: GraphQLSchema | undefined; private mapping: Record>; constructor( @@ -40,6 +38,11 @@ export default class TransformInputObjectFields implements Transform { this.mapping = {}; } + private _getTransformedSchema() { + assertSome(this.transformedSchema); + return this.transformedSchema; + } + public transformSchema( originalWrappingSchema: GraphQLSchema, _subschemaConfig: SubschemaConfig, @@ -75,24 +78,27 @@ export default class TransformInputObjectFields implements Transform { const operations: Array = []; - originalRequest.document.definitions.forEach(def => { - if ((def as OperationDefinitionNode).kind === Kind.OPERATION_DEFINITION) { - operations.push(def as OperationDefinitionNode); - } else { - fragments[(def as FragmentDefinitionNode).name.value] = def; + for (const def of originalRequest.document.definitions) { + if (def.kind === Kind.OPERATION_DEFINITION) { + operations.push(def); + } else if (def.kind === Kind.FRAGMENT_DEFINITION) { + fragments[def.name.value] = def; } - }); + } - operations.forEach(def => { + for (const def of operations) { const variableDefs = def.variableDefinitions; if (variableDefs != null) { - variableDefs.forEach(variableDef => { + for (const variableDef of variableDefs) { const varName = variableDef.variable.name.value; + if (variableDef.type.kind !== Kind.NAMED_TYPE) { + throw new Error(`Expected ${variableDef.type} to be a named type`); + } // requirement for 'as NamedTypeNode' appears to be a bug within types, as function should take any TypeNode - const varType = typeFromAST( - delegationContext.transformedSchema, - variableDef.type as NamedTypeNode - ) as GraphQLInputType; + const varType = typeFromAST(delegationContext.transformedSchema, variableDef.type); + if (!isInputType(varType)) { + throw new Error(`Expected ${varType} to be an input type`); + } variableValues[varName] = transformInputValue( varType, variableValues[varName], @@ -100,7 +106,7 @@ export default class TransformInputObjectFields implements Transform { (type, originalValue) => { const newValue = Object.create(null); const fields = type.getFields(); - Object.keys(originalValue).forEach(key => { + for (const key in originalValue) { const field = fields[key]; if (field != null) { const newFieldName = this.mapping[type.name]?.[field.name]; @@ -110,19 +116,17 @@ export default class TransformInputObjectFields implements Transform { newValue[field.name] = originalValue[field.name]; } } - }); + } return newValue; } ); - }); + } } - }); + } - originalRequest.document.definitions - .filter(def => def.kind === Kind.FRAGMENT_DEFINITION) - .forEach(def => { - fragments[(def as FragmentDefinitionNode).name.value] = def; - }); + for (const def of originalRequest.document.definitions.filter(def => def.kind === Kind.FRAGMENT_DEFINITION)) { + fragments[(def as FragmentDefinitionNode).name.value] = def; + } const document = this.transformDocument( originalRequest.document, this.mapping, @@ -141,23 +145,24 @@ export default class TransformInputObjectFields implements Transform { private transformDocument( document: DocumentNode, mapping: Record>, - inputFieldNodeTransformer: InputFieldNodeTransformer, - inputObjectNodeTransformer: InputObjectNodeTransformer, + inputFieldNodeTransformer: InputFieldNodeTransformer | undefined, + inputObjectNodeTransformer: InputObjectNodeTransformer | undefined, request: Request, delegationContext?: DelegationContext ): DocumentNode { - const typeInfo = new TypeInfo(this.transformedSchema); + const typeInfo = new TypeInfo(this._getTransformedSchema()); const newDocument: DocumentNode = visit( document, visitWithTypeInfo(typeInfo, { leave: { - [Kind.OBJECT]: (node: ObjectValueNode): ObjectValueNode => { - const parentType: GraphQLType = typeInfo.getInputType() as GraphQLInputObjectType; + [Kind.OBJECT]: (node: ObjectValueNode): ObjectValueNode | undefined => { + // The casting is kind of legit here as we are in a visitor + const parentType = typeInfo.getInputType() as Maybe; if (parentType != null) { const parentTypeName = parentType.name; const newInputFields: Array = []; - node.fields.forEach(inputField => { + for (const inputField of node.fields) { const newName = inputField.name.value; const transformedInputField = @@ -166,17 +171,17 @@ export default class TransformInputObjectFields implements Transform { : inputField; if (Array.isArray(transformedInputField)) { - transformedInputField.forEach(individualTransformedInputField => { + for (const individualTransformedInputField of transformedInputField) { const typeMapping = mapping[parentTypeName]; if (typeMapping == null) { newInputFields.push(individualTransformedInputField); - return; + continue; } const oldName = typeMapping[newName]; if (oldName == null) { newInputFields.push(individualTransformedInputField); - return; + continue; } newInputFields.push({ @@ -186,20 +191,20 @@ export default class TransformInputObjectFields implements Transform { value: oldName, }, }); - }); - return; + } + continue; } const typeMapping = mapping[parentTypeName]; if (typeMapping == null) { newInputFields.push(transformedInputField); - return; + continue; } const oldName = typeMapping[newName]; if (oldName == null) { newInputFields.push(transformedInputField); - return; + continue; } newInputFields.push({ @@ -209,7 +214,7 @@ export default class TransformInputObjectFields implements Transform { value: oldName, }, }); - }); + } const newNode = { ...node, diff --git a/packages/wrap/src/transforms/TransformInterfaceFields.ts b/packages/wrap/src/transforms/TransformInterfaceFields.ts index 956ac4e5673..9af6ef85754 100644 --- a/packages/wrap/src/transforms/TransformInterfaceFields.ts +++ b/packages/wrap/src/transforms/TransformInterfaceFields.ts @@ -1,6 +1,6 @@ import { GraphQLSchema, isInterfaceType, GraphQLFieldConfig } from 'graphql'; -import { Request, ExecutionResult } from '@graphql-tools/utils'; +import { Request, ExecutionResult, assertSome } from '@graphql-tools/utils'; import { Transform, DelegationContext, SubschemaConfig } from '@graphql-tools/delegate'; @@ -10,14 +10,19 @@ import TransformCompositeFields from './TransformCompositeFields'; export default class TransformInterfaceFields implements Transform { private readonly interfaceFieldTransformer: FieldTransformer; - private readonly fieldNodeTransformer: FieldNodeTransformer; - private transformer: TransformCompositeFields; + private readonly fieldNodeTransformer: FieldNodeTransformer | undefined; + private transformer: TransformCompositeFields | undefined; constructor(interfaceFieldTransformer: FieldTransformer, fieldNodeTransformer?: FieldNodeTransformer) { this.interfaceFieldTransformer = interfaceFieldTransformer; this.fieldNodeTransformer = fieldNodeTransformer; } + private _getTransformer() { + assertSome(this.transformer); + return this.transformer; + } + public transformSchema( originalWrappingSchema: GraphQLSchema, subschemaConfig: SubschemaConfig, @@ -45,7 +50,7 @@ export default class TransformInterfaceFields implements Transform { delegationContext: DelegationContext, transformationContext: Record ): Request { - return this.transformer.transformRequest(originalRequest, delegationContext, transformationContext); + return this._getTransformer().transformRequest(originalRequest, delegationContext, transformationContext); } public transformResult( @@ -53,6 +58,6 @@ export default class TransformInterfaceFields implements Transform { delegationContext: DelegationContext, transformationContext: Record ): ExecutionResult { - return this.transformer.transformResult(originalResult, delegationContext, transformationContext); + return this._getTransformer().transformResult(originalResult, delegationContext, transformationContext); } } diff --git a/packages/wrap/src/transforms/TransformObjectFields.ts b/packages/wrap/src/transforms/TransformObjectFields.ts index 7ced6e12f2c..ac88e6e7103 100644 --- a/packages/wrap/src/transforms/TransformObjectFields.ts +++ b/packages/wrap/src/transforms/TransformObjectFields.ts @@ -1,6 +1,6 @@ import { GraphQLSchema, isObjectType, GraphQLFieldConfig } from 'graphql'; -import { Request, ExecutionResult } from '@graphql-tools/utils'; +import { Request, ExecutionResult, assertSome } from '@graphql-tools/utils'; import { Transform, DelegationContext, SubschemaConfig } from '@graphql-tools/delegate'; @@ -10,14 +10,19 @@ import TransformCompositeFields from './TransformCompositeFields'; export default class TransformObjectFields implements Transform { private readonly objectFieldTransformer: FieldTransformer; - private readonly fieldNodeTransformer: FieldNodeTransformer; - private transformer: TransformCompositeFields; + private readonly fieldNodeTransformer: FieldNodeTransformer | undefined; + private transformer: TransformCompositeFields | undefined; constructor(objectFieldTransformer: FieldTransformer, fieldNodeTransformer?: FieldNodeTransformer) { this.objectFieldTransformer = objectFieldTransformer; this.fieldNodeTransformer = fieldNodeTransformer; } + private _getTransformer() { + assertSome(this.transformer); + return this.transformer; + } + public transformSchema( originalWrappingSchema: GraphQLSchema, subschemaConfig: SubschemaConfig, @@ -45,7 +50,7 @@ export default class TransformObjectFields implements Transform { delegationContext: DelegationContext, transformationContext: Record ): Request { - return this.transformer.transformRequest(originalRequest, delegationContext, transformationContext); + return this._getTransformer().transformRequest(originalRequest, delegationContext, transformationContext); } public transformResult( @@ -53,6 +58,6 @@ export default class TransformObjectFields implements Transform { delegationContext: DelegationContext, transformationContext: Record ): ExecutionResult { - return this.transformer.transformResult(originalResult, delegationContext, transformationContext); + return this._getTransformer().transformResult(originalResult, delegationContext, transformationContext); } } diff --git a/packages/wrap/src/transforms/TransformQuery.ts b/packages/wrap/src/transforms/TransformQuery.ts index 06221726df6..6a1690a4b53 100644 --- a/packages/wrap/src/transforms/TransformQuery.ts +++ b/packages/wrap/src/transforms/TransformQuery.ts @@ -8,10 +8,14 @@ export type QueryTransformer = ( selectionSet: SelectionSetNode, fragments: Record, delegationContext: DelegationContext, - transformationContext: Record, + transformationContext: Record ) => SelectionSetNode; -export type ResultTransformer = (result: any, delegationContext: DelegationContext, transformationContext: Record) => any; +export type ResultTransformer = ( + result: any, + delegationContext: DelegationContext, + transformationContext: Record +) => any; export type ErrorPathTransformer = (path: ReadonlyArray) => Array; @@ -26,7 +30,7 @@ export default class TransformQuery implements Transform { path, queryTransformer, resultTransformer = result => result, - errorPathTransformer = errorPath => [].concat(errorPath), + errorPathTransformer = errorPath => [...errorPath], fragments = {}, }: { path: Array; @@ -52,14 +56,19 @@ export default class TransformQuery implements Transform { const document = visit(originalRequest.document, { [Kind.FIELD]: { enter: node => { - if (index === pathLength || node.name.value !== this.path[index]) { + if (index === pathLength || node.name.value !== this.path[index] || node.selectionSet == null) { return false; } index++; if (index === pathLength) { - const selectionSet = this.queryTransformer(node.selectionSet, this.fragments, delegationContext, transformationContext); + const selectionSet = this.queryTransformer( + node.selectionSet, + this.fragments, + delegationContext, + transformationContext + ); return { ...node, @@ -92,7 +101,11 @@ export default class TransformQuery implements Transform { }; } - private transformData(data: any, delegationContext: DelegationContext, transformationContext: Record): any { + private transformData( + data: any, + delegationContext: DelegationContext, + transformationContext: Record + ): any { const leafIndex = this.path.length - 1; let index = 0; let newData = data; @@ -114,7 +127,11 @@ export default class TransformQuery implements Transform { private transformErrors(errors: ReadonlyArray): ReadonlyArray { return errors.map(error => { - const path: ReadonlyArray = error.path; + const path: ReadonlyArray | undefined = error.path; + + if (path == null) { + return error; + } let match = true; let index = 0; diff --git a/packages/wrap/src/transforms/TransformRootFields.ts b/packages/wrap/src/transforms/TransformRootFields.ts index ba224efbf5c..bd0193108ea 100644 --- a/packages/wrap/src/transforms/TransformRootFields.ts +++ b/packages/wrap/src/transforms/TransformRootFields.ts @@ -1,6 +1,6 @@ import { GraphQLSchema, GraphQLFieldConfig } from 'graphql'; -import { Request, ExecutionResult } from '@graphql-tools/utils'; +import { Request, ExecutionResult, assertSome } from '@graphql-tools/utils'; import { Transform, DelegationContext, SubschemaConfig } from '@graphql-tools/delegate'; @@ -10,14 +10,19 @@ import TransformObjectFields from './TransformObjectFields'; export default class TransformRootFields implements Transform { private readonly rootFieldTransformer: RootFieldTransformer; - private readonly fieldNodeTransformer: FieldNodeTransformer; - private transformer: TransformObjectFields; + private readonly fieldNodeTransformer: FieldNodeTransformer | undefined; + private transformer: TransformObjectFields | undefined; constructor(rootFieldTransformer: RootFieldTransformer, fieldNodeTransformer?: FieldNodeTransformer) { this.rootFieldTransformer = rootFieldTransformer; this.fieldNodeTransformer = fieldNodeTransformer; } + private _getTransformer() { + assertSome(this.transformer); + return this.transformer; + } + public transformSchema( originalWrappingSchema: GraphQLSchema, subschemaConfig: SubschemaConfig, @@ -57,7 +62,7 @@ export default class TransformRootFields implements Transform { delegationContext: DelegationContext, transformationContext: Record ): Request { - return this.transformer.transformRequest(originalRequest, delegationContext, transformationContext); + return this._getTransformer().transformRequest(originalRequest, delegationContext, transformationContext); } public transformResult( @@ -65,6 +70,6 @@ export default class TransformRootFields implements Transform { delegationContext: DelegationContext, transformationContext: Record ): ExecutionResult { - return this.transformer.transformResult(originalResult, delegationContext, transformationContext); + return this._getTransformer().transformResult(originalResult, delegationContext, transformationContext); } } diff --git a/packages/wrap/src/transforms/WrapFields.ts b/packages/wrap/src/transforms/WrapFields.ts index ee989ae9b9d..2ae45201e1c 100644 --- a/packages/wrap/src/transforms/WrapFields.ts +++ b/packages/wrap/src/transforms/WrapFields.ts @@ -18,6 +18,7 @@ import { modifyObjectFields, ExecutionResult, relocatedError, + assertSome, } from '@graphql-tools/utils'; import { Transform, defaultMergedResolver, DelegationContext, SubschemaConfig } from '@graphql-tools/delegate'; @@ -30,13 +31,13 @@ interface WrapFieldsTransformationContext { paths: Record; alias: string }>; } -export default class WrapFields implements Transform { +export default class WrapFields implements Transform { private readonly outerTypeName: string; private readonly wrappingFieldNames: Array; private readonly wrappingTypeNames: Array; private readonly numWraps: number; - private readonly fieldNames: Array; - private readonly transformer: Transform; + private readonly fieldNames: Array | undefined; + private readonly transformer: MapFields; constructor( outerTypeName: string, @@ -53,51 +54,49 @@ export default class WrapFields implements Transform( { [outerTypeName]: { - [outerMostWrappingFieldName]: ( - fieldNode, - fragments, - transformationContext: WrapFieldsTransformationContext - ) => + [outerMostWrappingFieldName]: (fieldNode, fragments, transformationContext) => hoistFieldNodes({ fieldNode, path: remainingWrappingFieldNames, fieldNames, fragments, - transformationContext, + transformationContext: transformationContext as WrapFieldsTransformationContext, prefix, }), }, }, { - [outerTypeName]: (value, context: WrapFieldsTransformationContext) => dehoistValue(value, context), + [outerTypeName]: (value, context) => dehoistValue(value, context as WrapFieldsTransformationContext), }, - (errors, context: WrapFieldsTransformationContext) => dehoistErrors(errors, context) + (errors, context) => dehoistErrors(errors, context as WrapFieldsTransformationContext) ); } public transformSchema( originalWrappingSchema: GraphQLSchema, - subschemaConfig: SubschemaConfig, + subschemaConfig: SubschemaConfig, transformedSchema?: GraphQLSchema ): GraphQLSchema { + const fieldNames = this.fieldNames; const targetFieldConfigMap = selectObjectFields( originalWrappingSchema, this.outerTypeName, - !this.fieldNames ? () => true : fieldName => this.fieldNames.includes(fieldName) + !fieldNames ? () => true : fieldName => fieldNames.includes(fieldName) ); const newTargetFieldConfigMap: GraphQLFieldConfigMap = Object.create(null); - Object.keys(targetFieldConfigMap).forEach(fieldName => { + for (const fieldName in targetFieldConfigMap) { const field = targetFieldConfigMap[fieldName]; const newField: GraphQLFieldConfig = { ...field, resolve: defaultMergedResolver, }; newTargetFieldConfigMap[fieldName] = newField; - }); + } let wrapIndex = this.numWraps - 1; let wrappingTypeName = this.wrappingTypeNames[wrapIndex]; @@ -123,11 +122,11 @@ export default class WrapFields implements Transform; + let resolve: GraphQLFieldResolver | undefined; if (transformedSchema) { if (wrappingRootField) { const targetSchema = subschemaConfig.schema; - const operation = this.outerTypeName === targetSchema.getQueryType().name ? 'query' : 'mutation'; + const operation = this.outerTypeName === targetSchema.getQueryType()?.name ? 'query' : 'mutation'; const createProxyingResolver = subschemaConfig.createProxyingResolver ?? defaultCreateProxyingResolver; resolve = createProxyingResolver({ subschemaConfig, @@ -176,13 +175,13 @@ export default class WrapFields implements Transform, fields: Array = [], visitedFragmentNames = {} ): Array { if (selectionSet != null) { - selectionSet.selections.forEach(selection => { + for (const selection of selectionSet.selections) { switch (selection.kind) { case Kind.FIELD: fields.push(selection); @@ -202,7 +201,7 @@ function collectFields( // unreachable break; } - }); + } } return fields; @@ -243,7 +242,7 @@ function hoistFieldNodes({ if (index < path.length) { const pathSegment = path[index]; - collectFields(fieldNode.selectionSet, fragments).forEach((possibleFieldNode: FieldNode) => { + for (const possibleFieldNode of collectFields(fieldNode.selectionSet, fragments)) { if (possibleFieldNode.name.value === pathSegment) { const newWrappingPath = wrappingPath.concat([alias]); @@ -260,9 +259,9 @@ function hoistFieldNodes({ }) ); } - }); + } } else { - collectFields(fieldNode.selectionSet, fragments).forEach((possibleFieldNode: FieldNode) => { + for (const possibleFieldNode of collectFields(fieldNode.selectionSet, fragments)) { if (!fieldNames || fieldNames.includes(possibleFieldNode.name.value)) { const nextIndex = transformationContext.nextIndex; transformationContext.nextIndex++; @@ -273,7 +272,7 @@ function hoistFieldNodes({ }; newFieldNodes.push(aliasFieldNode(possibleFieldNode, indexingAlias)); } - }); + } } return newFieldNodes; @@ -286,30 +285,30 @@ export function dehoistValue(originalValue: any, context: WrapFieldsTransformati const newValue = Object.create(null); - Object.keys(originalValue).forEach(alias => { + for (const alias in originalValue) { let obj = newValue; const path = context.paths[alias]; if (path == null) { newValue[alias] = originalValue[alias]; - return; + continue; } const pathToField = path.pathToField; const fieldAlias = path.alias; - pathToField.forEach(key => { + for (const key of pathToField) { obj = obj[key] = obj[key] || Object.create(null); - }); + } obj[fieldAlias] = originalValue[alias]; - }); + } return newValue; } function dehoistErrors( - errors: ReadonlyArray, + errors: ReadonlyArray | undefined, context: WrapFieldsTransformationContext -): Array { +): Array | undefined { if (errors === undefined) { return undefined; } @@ -321,20 +320,20 @@ function dehoistErrors( } let newPath: Array = []; - originalPath.forEach(pathSegment => { + for (const pathSegment of originalPath) { if (typeof pathSegment !== 'string') { newPath.push(pathSegment); - return; + continue; } const path = context.paths[pathSegment]; if (path == null) { newPath.push(pathSegment); - return; + continue; } newPath = newPath.concat(path.pathToField, [path.alias]); - }); + } return relocatedError(error, newPath); }); diff --git a/packages/wrap/src/transforms/WrapQuery.ts b/packages/wrap/src/transforms/WrapQuery.ts index 04b7dbc84ba..978d2a68962 100644 --- a/packages/wrap/src/transforms/WrapQuery.ts +++ b/packages/wrap/src/transforms/WrapQuery.ts @@ -28,7 +28,7 @@ export default class WrapQuery implements Transform { [Kind.FIELD]: { enter: (node: FieldNode) => { fieldPath.push(node.name.value); - if (ourPath === JSON.stringify(fieldPath)) { + if (node.selectionSet != null && ourPath === JSON.stringify(fieldPath)) { const wrapResult = this.wrapper(node.selectionSet); // Selection can be either a single selection or a selection set. If it's just one selection, @@ -68,7 +68,7 @@ export default class WrapQuery implements Transform { let data = rootData; const path = [...this.path]; while (path.length > 1) { - const next = path.shift(); + const next = path.shift()!; if (data[next]) { data = data[next]; } diff --git a/packages/wrap/src/transforms/WrapType.ts b/packages/wrap/src/transforms/WrapType.ts index 83d99089e1a..8d32d768675 100644 --- a/packages/wrap/src/transforms/WrapType.ts +++ b/packages/wrap/src/transforms/WrapType.ts @@ -7,7 +7,7 @@ import { Transform, DelegationContext, SubschemaConfig } from '@graphql-tools/de import WrapFields from './WrapFields'; export default class WrapType implements Transform { - private readonly transformer: Transform; + private readonly transformer: WrapFields; constructor(outerTypeName: string, innerTypeName: string, fieldName: string) { this.transformer = new WrapFields(outerTypeName, [fieldName], [innerTypeName]); @@ -26,7 +26,7 @@ export default class WrapType implements Transform { delegationContext: DelegationContext, transformationContext: Record ): Request { - return this.transformer.transformRequest(originalRequest, delegationContext, transformationContext); + return this.transformer.transformRequest(originalRequest, delegationContext, transformationContext as any); } public transformResult( @@ -34,6 +34,6 @@ export default class WrapType implements Transform { delegationContext: DelegationContext, transformationContext: Record ): ExecutionResult { - return this.transformer.transformResult(originalResult, delegationContext, transformationContext); + return this.transformer.transformResult(originalResult, delegationContext, transformationContext as any); } } diff --git a/packages/wrap/src/types.ts b/packages/wrap/src/types.ts index 57bec411122..2ff018fd6c9 100644 --- a/packages/wrap/src/types.ts +++ b/packages/wrap/src/types.ts @@ -1,7 +1,4 @@ import { - GraphQLSchema, - GraphQLFieldResolver, - BuildSchemaOptions, GraphQLInputFieldConfig, GraphQLFieldConfig, FieldNode, @@ -13,18 +10,7 @@ import { GraphQLEnumValueConfig, } from 'graphql'; import { DelegationContext } from '@graphql-tools/delegate'; -import { Executor, Subscriber, Request } from '@graphql-tools/utils'; - -export interface IMakeRemoteExecutableSchemaOptions> { - schema: GraphQLSchema | string; - executor?: Executor; - subscriber?: Subscriber; - createResolver?: ( - executor: Executor, - subscriber: Subscriber - ) => GraphQLFieldResolver; - buildSchemaOptions?: BuildSchemaOptions; -} +import { Request, Maybe } from '@graphql-tools/utils'; export type InputFieldTransformer = ( typeName: string, @@ -45,25 +31,25 @@ export type InputObjectNodeTransformer = ( inputObjectNode: ObjectValueNode, request: Request, delegationContext?: DelegationContext -) => ObjectValueNode; +) => ObjectValueNode | undefined; export type FieldTransformer> = ( typeName: string, fieldName: string, fieldConfig: GraphQLFieldConfig -) => GraphQLFieldConfig | [string, GraphQLFieldConfig] | null | undefined; +) => Maybe | [string, GraphQLFieldConfig]>; export type RootFieldTransformer> = ( operation: 'Query' | 'Mutation' | 'Subscription', fieldName: string, fieldConfig: GraphQLFieldConfig -) => GraphQLFieldConfig | [string, GraphQLFieldConfig] | null | undefined; +) => Maybe | [string, GraphQLFieldConfig]>; export type EnumValueTransformer = ( typeName: string, externalValue: string, enumValueConfig: GraphQLEnumValueConfig -) => GraphQLEnumValueConfig | [string, GraphQLEnumValueConfig] | null | undefined; +) => Maybe; export type FieldNodeTransformer = ( typeName: string, @@ -71,7 +57,7 @@ export type FieldNodeTransformer = ( fieldNode: FieldNode, fragments: Record, transformationContext: Record -) => SelectionNode | Array; +) => Maybe>; export type LeafValueTransformer = (typeName: string, value: any) => any; @@ -80,6 +66,6 @@ export type DataTransformer = (value: any, transformationContext: Record; export type ErrorsTransformer = ( - errors: ReadonlyArray, + errors: ReadonlyArray | undefined, transformationContext: Record -) => Array; +) => Array | undefined; diff --git a/packages/wrap/src/wrapSchema.ts b/packages/wrap/src/wrapSchema.ts index 12f55f7bcde..2532cd8611c 100644 --- a/packages/wrap/src/wrapSchema.ts +++ b/packages/wrap/src/wrapSchema.ts @@ -11,7 +11,9 @@ import { MapperKind, mapSchema } from '@graphql-tools/utils'; import { SubschemaConfig, defaultMergedResolver, applySchemaTransforms } from '@graphql-tools/delegate'; import { generateProxyingResolvers } from './generateProxyingResolvers'; -export function wrapSchema(subschemaConfig: SubschemaConfig): GraphQLSchema { +export function wrapSchema>( + subschemaConfig: SubschemaConfig +): GraphQLSchema { const targetSchema = subschemaConfig.schema; const proxyingResolvers = generateProxyingResolvers(subschemaConfig); @@ -31,12 +33,16 @@ function createWrappingSchema( const config = type.toConfig(); const fieldConfigMap = config.fields; - Object.keys(fieldConfigMap).forEach(fieldName => { + for (const fieldName in fieldConfigMap) { + const field = fieldConfigMap[fieldName]; + if (field == null) { + continue; + } fieldConfigMap[fieldName] = { - ...fieldConfigMap[fieldName], - ...proxyingResolvers[type.name][fieldName], + ...field, + ...proxyingResolvers[type.name]?.[fieldName], }; - }); + } return new GraphQLObjectType(config); }, @@ -44,10 +50,14 @@ function createWrappingSchema( const config = type.toConfig(); config.isTypeOf = undefined; - Object.keys(config.fields).forEach(fieldName => { - config.fields[fieldName].resolve = defaultMergedResolver; - config.fields[fieldName].subscribe = null; - }); + for (const fieldName in config.fields) { + const field = config.fields[fieldName]; + if (field == null) { + continue; + } + field.resolve = defaultMergedResolver; + field.subscribe = undefined; + } return new GraphQLObjectType(config); }, diff --git a/packages/wrap/tests/fixtures/schemas.ts b/packages/wrap/tests/fixtures/schemas.ts index 8c405f4dfa0..22edcc4f7f4 100644 --- a/packages/wrap/tests/fixtures/schemas.ts +++ b/packages/wrap/tests/fixtures/schemas.ts @@ -12,8 +12,6 @@ import { GraphQLInterfaceType, } from 'graphql'; -import isPromise from 'is-promise'; - import { ValueOrPromise } from 'value-or-promise'; import { introspectSchema } from '../../src/introspect'; @@ -21,6 +19,7 @@ import { IResolvers, ExecutionResult, mapAsyncIterator, + isAsyncIterable, } from '@graphql-tools/utils'; import { makeExecutableSchema } from '@graphql-tools/schema'; import { SubschemaConfig, ExecutionParams } from '@graphql-tools/delegate'; @@ -188,10 +187,6 @@ export const sampleData: { }, }; -function values(o: { [s: string]: T }): Array { - return Object.keys(o).map((k) => o[k]); -} - function coerceString(value: any): string { if (Array.isArray(value)) { throw new TypeError( @@ -225,9 +220,9 @@ function parseLiteral(ast: ValueNode): any { return parseFloat(ast.value); case Kind.OBJECT: { const value = Object.create(null); - ast.fields.forEach((field) => { + for (const field of ast.fields) { value[field.name.value] = parseLiteral(field.value); - }); + } return value; } @@ -289,8 +284,7 @@ const propertyRootTypeDefs = ` foo: String } - ${ - 'getInterfaces' in GraphQLInterfaceType.prototype + ${'getInterfaces' in GraphQLInterfaceType.prototype ? `interface TestNestedInterface implements TestInterface { kind: TestInterfaceKind testString: String @@ -301,7 +295,7 @@ const propertyRootTypeDefs = ` testString: String bar: String }` - : `type TestImpl2 implements TestInterface { + : `type TestImpl2 implements TestInterface { kind: TestInterfaceKind testString: String bar: String @@ -349,7 +343,7 @@ const propertyResolvers: IResolvers = { }, properties(_root, { limit }) { - const list = values(sampleData.Property); + const list = Object.values(sampleData.Property); return limit ? list.slice(0, limit) : list; }, @@ -368,27 +362,27 @@ const propertyResolvers: IResolvers = { interfaceTest(_root, { kind }) { return kind === 'ONE' ? { - kind: 'ONE', - testString: 'test', - foo: 'foo', - } + kind: 'ONE', + testString: 'test', + foo: 'foo', + } : { - kind: 'TWO', - testString: 'test', - bar: 'bar', - }; + kind: 'TWO', + testString: 'test', + bar: 'bar', + }; }, unionTest(_root, { output }) { return output === 'Interface' ? { - kind: 'ONE', - testString: 'test', - foo: 'foo', - } + kind: 'ONE', + testString: 'test', + foo: 'foo', + } : { - someField: 'Bar', - }; + someField: 'Bar', + }; }, errorTest() { @@ -464,7 +458,7 @@ const productTypeDefs = ` const productResolvers: IResolvers = { Query: { products(_root) { - const list = values(sampleData.Product); + const list = Object.values(sampleData.Product); return list; }, }, @@ -550,7 +544,7 @@ const bookingResolvers: IResolvers = { return sampleData.Booking[id]; }, bookingsByPropertyId(_parent, { propertyId, limit }) { - const list = values(sampleData.Booking).filter( + const list = Object.values(sampleData.Booking).filter( (booking: Booking) => booking.propertyId === propertyId, ); return limit ? list.slice(0, limit) : list; @@ -559,11 +553,11 @@ const bookingResolvers: IResolvers = { return sampleData.Customer[id]; }, bookings(_parent, { limit }) { - const list = values(sampleData.Booking); + const list = Object.values(sampleData.Booking); return limit ? list.slice(0, limit) : list; }, customers(_parent, { limit }) { - const list = values(sampleData.Customer); + const list = Object.values(sampleData.Customer); return limit ? list.slice(0, limit) : list; }, }, @@ -600,13 +594,13 @@ const bookingResolvers: IResolvers = { Customer: { bookings(parent: Customer, { limit }) { - const list = values(sampleData.Booking).filter( + const list = Object.values(sampleData.Booking).filter( (booking: Booking) => booking.customerId === parent.id, ); return limit ? list.slice(0, limit) : list; }, vehicle(parent: Customer) { - return sampleData.Vehicle[parent.vehicleId]; + return parent.vehicleId && sampleData.Vehicle[parent.vehicleId]; }, error() { throw new Error('Customer.error error'); @@ -684,7 +678,20 @@ export const subscriptionSchema: GraphQLSchema = makeExecutableSchema({ }); function makeExecutorFromSchema(schema: GraphQLSchema) { - return async ({ document, variables, context }: ExecutionParams) => { + return async ({ document, variables, context, info }: ExecutionParams) => { + if (info?.operation.operation === 'subscription') { + const result = await subscribe( + schema, + document, + null, + context, + variables, + ); + if (isAsyncIterable>(result)) { + return mapAsyncIterator, TReturn>(result, (originalResult: ExecutionResult) => JSON.parse(JSON.stringify(originalResult))); + } + return JSON.parse(JSON.stringify(result)); + } return (new ValueOrPromise(() => graphql( schema, print(document), @@ -692,25 +699,8 @@ function makeExecutorFromSchema(schema: GraphQLSchema) { context, variables, )) - .then(originalResult => JSON.parse(JSON.stringify(originalResult))) - .resolve()) as Promise> | ExecutionResult; - }; -} - -function makeSubscriberFromSchema(schema: GraphQLSchema) { - return async ({ document, variables, context }: ExecutionParams) => { - const result = subscribe( - schema, - document, - null, - context, - variables, - ) as Promise> | ExecutionResult>; - if (isPromise(result)) { - return result.then(asyncIterator => - mapAsyncIterator(asyncIterator as AsyncIterator, (originalResult: ExecutionResult) => JSON.parse(JSON.stringify(originalResult)))); - } - return JSON.parse(JSON.stringify(result)); + .then(originalResult => JSON.parse(JSON.stringify(originalResult))) + .resolve()) as Promise> | ExecutionResult; }; } @@ -718,12 +708,10 @@ export async function makeSchemaRemote( schema: GraphQLSchema, ): Promise { const executor = makeExecutorFromSchema(schema); - const subscriber = makeSubscriberFromSchema(schema); const clientSchema = await introspectSchema(executor); return { schema: clientSchema, executor, - subscriber, }; } diff --git a/packages/wrap/tests/fragmentsAreNotDuplicated.test.ts b/packages/wrap/tests/fragmentsAreNotDuplicated.test.ts index 02df525b46a..7cc4a106df4 100644 --- a/packages/wrap/tests/fragmentsAreNotDuplicated.test.ts +++ b/packages/wrap/tests/fragmentsAreNotDuplicated.test.ts @@ -83,6 +83,8 @@ const variables = { function assertNoDuplicateFragmentErrors(result: ExecutionResult) { // Run assertion against each array element for better test failure output. if (result.errors != null) { - result.errors.forEach((error) => expect(error.message).toBe('')); + for (const error of result.errors) { + expect(error.message).toBe('') + } } } diff --git a/packages/wrap/tests/gatsbyTransforms.test.ts b/packages/wrap/tests/gatsbyTransforms.test.ts index 3831e37be25..9ebb579ef2e 100644 --- a/packages/wrap/tests/gatsbyTransforms.test.ts +++ b/packages/wrap/tests/gatsbyTransforms.test.ts @@ -7,7 +7,7 @@ import { GraphQLFieldConfigMap, } from 'graphql'; -import { mapSchema, MapperKind, addTypes, modifyObjectFields } from '@graphql-tools/utils'; +import { mapSchema, MapperKind, addTypes, modifyObjectFields, assertSome } from '@graphql-tools/utils'; import { wrapSchema, RenameTypes } from '../src'; import { makeExecutableSchema } from '@graphql-tools/schema'; import { addMocksToSchema } from '@graphql-tools/mock'; @@ -36,7 +36,9 @@ class NamespaceUnderFieldTransform { } transformSchema(schema: GraphQLSchema) { - const queryConfig = schema.getQueryType().toConfig(); + const QueryType = schema.getQueryType(); + assertSome(QueryType) + const queryConfig = QueryType.toConfig(); const nestedQuery = new GraphQLObjectType({ ...queryConfig, diff --git a/packages/wrap/tests/makeRemoteExecutableSchema.test.ts b/packages/wrap/tests/makeRemoteExecutableSchema.test.ts index 554d656108b..fbfeeb7669a 100644 --- a/packages/wrap/tests/makeRemoteExecutableSchema.test.ts +++ b/packages/wrap/tests/makeRemoteExecutableSchema.test.ts @@ -6,9 +6,10 @@ import { execute, print, ExecutionResult, + buildSchema, } from 'graphql'; -import { makeRemoteExecutableSchema } from '../src/index'; +import { wrapSchema } from '../src/index'; import { propertySchema, @@ -22,7 +23,7 @@ describe('remote queries', () => { let schema: GraphQLSchema; beforeAll(async () => { const remoteSubschemaConfig = await makeSchemaRemote(propertySchema); - schema = makeRemoteExecutableSchema(remoteSubschemaConfig); + schema = wrapSchema(remoteSubschemaConfig); }); test('should work', async () => { @@ -60,7 +61,7 @@ describe('remote subscriptions', () => { let schema: GraphQLSchema; beforeAll(async () => { const remoteSubschemaConfig = await makeSchemaRemote(subscriptionSchema); - schema = makeRemoteExecutableSchema(remoteSubschemaConfig); + schema = wrapSchema(remoteSubschemaConfig); }); test('should work', async () => { @@ -133,7 +134,7 @@ describe('remote subscriptions', () => { }); describe('respects buildSchema options', () => { - const schema = ` + const typeDefs = /* GraphQL */` type Query { # Field description custom: CustomScalar! @@ -144,26 +145,25 @@ describe('respects buildSchema options', () => { `; test('without comment descriptions', () => { - const remoteSchema = makeRemoteExecutableSchema({ schema }); + const remoteSchema = wrapSchema({ schema: buildSchema(typeDefs) }); const customScalar = remoteSchema.getType('CustomScalar'); - expect(customScalar.description).toBeUndefined(); + expect(customScalar?.description).toBeUndefined(); }); test('with comment descriptions', () => { - const remoteSchema = makeRemoteExecutableSchema({ - schema, - buildSchemaOptions: { commentDescriptions: true }, + const remoteSchema = wrapSchema({ + schema: buildSchema(typeDefs, { commentDescriptions: true }), }); - const field = remoteSchema.getQueryType().getFields()['custom']; + const field = remoteSchema.getQueryType()!.getFields()['custom']; expect(field.description).toBe('Field description'); const customScalar = remoteSchema.getType('CustomScalar'); - expect(customScalar.description).toBe('Scalar description'); + expect(customScalar?.description).toBe('Scalar description'); }); describe('when query for multiple fields', () => { - const schema = ` + const typeDefs = ` type Query { fieldA: Int! fieldB: Int! @@ -188,8 +188,8 @@ describe('respects buildSchema options', () => { }, }); }; - const remoteSchema = makeRemoteExecutableSchema({ - schema, + const remoteSchema = wrapSchema({ + schema: buildSchema(typeDefs), executor, }); diff --git a/packages/wrap/tests/requests.test.ts b/packages/wrap/tests/requests.test.ts index f38108cabba..a4f308c2116 100644 --- a/packages/wrap/tests/requests.test.ts +++ b/packages/wrap/tests/requests.test.ts @@ -12,11 +12,11 @@ function removeLocations(value: any): any { return value.map((v) => removeLocations(v)); } else if (typeof value === 'object') { const newValue = {}; - Object.keys(value).forEach((key) => { + for (const key in value) { if (key !== 'loc') { newValue[key] = removeLocations(value[key]); } - }); + } return newValue; } @@ -34,12 +34,13 @@ describe('requests', () => { minor patch }`), + targetOperationName: 'test' }), ); const expectedRequest = removeLocations({ document: parse(` - query { + query test { version { major minor @@ -48,6 +49,7 @@ describe('requests', () => { } `), variables: {}, + operationName: 'test' }); expect(expectedRequest).toMatchObject(request); diff --git a/packages/wrap/tests/transformFilterInputObjectFields.test.ts b/packages/wrap/tests/transformFilterInputObjectFields.test.ts index 44c050fe8bc..9bd1e99a415 100644 --- a/packages/wrap/tests/transformFilterInputObjectFields.test.ts +++ b/packages/wrap/tests/transformFilterInputObjectFields.test.ts @@ -1,6 +1,7 @@ import { wrapSchema, FilterInputObjectFields } from '@graphql-tools/wrap'; import { makeExecutableSchema } from '@graphql-tools/schema'; import { graphql, astFromValue, Kind, GraphQLString } from 'graphql'; +import { assertSome } from '@graphql-tools/utils'; describe('FilterInputObjectFields', () => { test('filtering works', async () => { @@ -36,6 +37,8 @@ describe('FilterInputObjectFields', () => { (typeName, fieldName) => (typeName !== 'InputObject' || fieldName !== 'field2'), (typeName, inputObjectNode) => { if (typeName === 'InputObject') { + const value = astFromValue('field2', GraphQLString) + assertSome(value) return { ...inputObjectNode, fields: [...inputObjectNode.fields, { @@ -44,7 +47,7 @@ describe('FilterInputObjectFields', () => { kind: Kind.NAME, value: 'field2', }, - value: astFromValue('field2', GraphQLString), + value, }], }; } @@ -63,7 +66,8 @@ describe('FilterInputObjectFields', () => { }`; const result = await graphql(transformedSchema, query); - expect(result.data.test.field1).toBe('field1'); - expect(result.data.test.field2).toBe('field2'); + assertSome(result.data) + expect(result.data['test'].field1).toBe('field1'); + expect(result.data['test'].field2).toBe('field2'); }); }); diff --git a/packages/wrap/tests/transformFilterObjectFieldDirectives.test.ts b/packages/wrap/tests/transformFilterObjectFieldDirectives.test.ts index 733cf13b34d..d122d815e32 100644 --- a/packages/wrap/tests/transformFilterObjectFieldDirectives.test.ts +++ b/packages/wrap/tests/transformFilterObjectFieldDirectives.test.ts @@ -23,10 +23,10 @@ describe('FilterObjectFieldDirectives', () => { ], }); - const fields = transformedSchema.getType('Query').getFields(); - expect(fields.alpha.astNode.directives.length).toEqual(0); - expect(fields.bravo.astNode.directives.length).toEqual(1); - expect(fields.charlie.astNode.directives.length).toEqual(0); - expect(fields.delta.astNode.directives.length).toEqual(1); + const fields = transformedSchema.getQueryType()?.getFields(); + expect(fields?.['alpha']?.astNode?.directives?.length).toEqual(0); + expect(fields?.['bravo']?.astNode?.directives?.length).toEqual(1); + expect(fields?.['charlie']?.astNode?.directives?.length).toEqual(0); + expect(fields?.['delta']?.astNode?.directives?.length).toEqual(1); }); }); diff --git a/packages/wrap/tests/transformFilterTypes.test.ts b/packages/wrap/tests/transformFilterTypes.test.ts index bfde574fd8d..931445475e7 100644 --- a/packages/wrap/tests/transformFilterTypes.test.ts +++ b/packages/wrap/tests/transformFilterTypes.test.ts @@ -1,5 +1,6 @@ import { wrapSchema, FilterTypes } from '@graphql-tools/wrap'; import { graphql, GraphQLSchema, GraphQLNamedType } from 'graphql'; +import { assertSome } from '@graphql-tools/utils'; import { bookingSchema } from './fixtures/schemas'; describe('FilterTypes', () => { @@ -62,6 +63,7 @@ describe('FilterTypes', () => { `, ); expect(result.errors).toBeDefined(); + assertSome(result.errors) expect(result.errors.length).toBe(1); expect(result.errors[0].message).toBe( 'Cannot query field "customer" on type "Booking".', diff --git a/packages/wrap/tests/transformMapLeafValues.test.ts b/packages/wrap/tests/transformMapLeafValues.test.ts index 9850a6ad21d..21712a5f4b8 100644 --- a/packages/wrap/tests/transformMapLeafValues.test.ts +++ b/packages/wrap/tests/transformMapLeafValues.test.ts @@ -1,6 +1,7 @@ import { wrapSchema, MapLeafValues } from '@graphql-tools/wrap'; import { makeExecutableSchema } from '@graphql-tools/schema'; import { graphql } from 'graphql'; +import { assertSome } from '@graphql-tools/utils'; describe('MapLeafValues', () => { test('works', async () => { @@ -48,7 +49,8 @@ describe('MapLeafValues', () => { }`; const result = await graphql(transformedSchema, query); - expect(result.data.testEnum).toBe('THREE'); - expect(result.data.testScalar).toBe(15); + assertSome(result.data) + expect(result.data['testEnum']).toBe('THREE'); + expect(result.data['testScalar']).toBe(15); }); }); diff --git a/packages/wrap/tests/transformRemoveObjectFieldDeprecations.test.ts b/packages/wrap/tests/transformRemoveObjectFieldDeprecations.test.ts index 8fd64f6b53a..888a87da065 100644 --- a/packages/wrap/tests/transformRemoveObjectFieldDeprecations.test.ts +++ b/packages/wrap/tests/transformRemoveObjectFieldDeprecations.test.ts @@ -1,5 +1,7 @@ import { wrapSchema, RemoveObjectFieldDeprecations } from '@graphql-tools/wrap'; import { makeExecutableSchema } from '@graphql-tools/schema'; +import { assertGraphQLObjectType } from '../../testing/assertion'; +import { assertSome } from '@graphql-tools/utils'; describe('RemoveObjectFieldDeprecations', () => { const originalSchema = makeExecutableSchema({ @@ -20,11 +22,15 @@ describe('RemoveObjectFieldDeprecations', () => { ], }); - const fields = transformedSchema.getType('Test').getFields(); - expect(fields.first.deprecationReason).toEqual('do not remove'); - expect(fields.second.deprecationReason).toBeUndefined(); - expect(fields.first.astNode.directives.length).toEqual(1); - expect(fields.second.astNode.directives.length).toEqual(0); + const Test = transformedSchema.getType('Test') + assertGraphQLObjectType(Test) + const fields = Test.getFields(); + assertSome(fields['first']) + expect(fields['first'].deprecationReason).toEqual('do not remove'); + assertSome(fields['second']) + expect(fields['second'].deprecationReason).toBeUndefined(); + expect(fields['first'].astNode?.directives?.length).toEqual(1); + expect(fields['second'].astNode?.directives?.length).toEqual(0); }); test('removes deprecations by reason regex', async () => { @@ -35,10 +41,14 @@ describe('RemoveObjectFieldDeprecations', () => { ], }); - const fields = transformedSchema.getType('Test').getFields(); - expect(fields.first.deprecationReason).toBeUndefined(); - expect(fields.second.deprecationReason).toBeUndefined(); - expect(fields.first.astNode.directives.length).toEqual(0); - expect(fields.second.astNode.directives.length).toEqual(0); + const Test = transformedSchema.getType('Test') + assertGraphQLObjectType(Test) + const fields = Test.getFields(); + assertSome(fields['first']) + expect(fields['first'].deprecationReason).toBeUndefined(); + assertSome(fields['second']) + expect(fields['second'].deprecationReason).toBeUndefined(); + expect(fields['first'].astNode?.directives?.length).toEqual(0); + expect(fields['second'].astNode?.directives?.length).toEqual(0); }); }); diff --git a/packages/wrap/tests/transformRemoveObjectFieldDirectives.test.ts b/packages/wrap/tests/transformRemoveObjectFieldDirectives.test.ts index 331c78eaa4a..745a885d748 100644 --- a/packages/wrap/tests/transformRemoveObjectFieldDirectives.test.ts +++ b/packages/wrap/tests/transformRemoveObjectFieldDirectives.test.ts @@ -1,5 +1,7 @@ import { wrapSchema, RemoveObjectFieldDirectives } from '@graphql-tools/wrap'; import { makeExecutableSchema } from '@graphql-tools/schema'; +import { assertGraphQLObjectType } from '../../testing/assertion'; +import { assertSome } from '@graphql-tools/utils'; describe('RemoveObjectFieldDirectives', () => { const originalSchema = makeExecutableSchema({ @@ -24,11 +26,17 @@ describe('RemoveObjectFieldDirectives', () => { ], }); - const fields = transformedSchema.getType('Test').getFields(); - expect(fields.id.astNode.directives.length).toEqual(1); - expect(fields.first.astNode.directives.length).toEqual(0); - expect(fields.second.astNode.directives.length).toEqual(0); - expect(fields.third.astNode.directives.length).toEqual(0); + const Test = transformedSchema.getType('Test') + assertGraphQLObjectType(Test) + const fields = Test.getFields(); + assertSome(fields['id']) + expect(fields['id'].astNode?.directives?.length).toEqual(1); + assertSome(fields['first']) + expect(fields['first'].astNode?.directives?.length).toEqual(0); + assertSome(fields['second']) + expect(fields['second'].astNode?.directives?.length).toEqual(0); + assertSome(fields['third']) + expect(fields['third'].astNode?.directives?.length).toEqual(0); }); test('removes directives by name regex', async () => { @@ -39,11 +47,17 @@ describe('RemoveObjectFieldDirectives', () => { ], }); - const fields = transformedSchema.getType('Test').getFields(); - expect(fields.id.astNode.directives.length).toEqual(1); - expect(fields.first.astNode.directives.length).toEqual(0); - expect(fields.second.astNode.directives.length).toEqual(0); - expect(fields.third.astNode.directives.length).toEqual(0); + const Test = transformedSchema.getType('Test') + assertGraphQLObjectType(Test) + const fields = Test.getFields(); + assertSome(fields['id']) + expect(fields['id'].astNode?.directives?.length).toEqual(1); + assertSome(fields['first']) + expect(fields['first'].astNode?.directives?.length).toEqual(0); + assertSome(fields['second']) + expect(fields['second'].astNode?.directives?.length).toEqual(0); + assertSome(fields['third']) + expect(fields['third'].astNode?.directives?.length).toEqual(0); }); test('removes directives by argument', async () => { @@ -54,11 +68,17 @@ describe('RemoveObjectFieldDirectives', () => { ], }); - const fields = transformedSchema.getType('Test').getFields(); - expect(fields.id.astNode.directives.length).toEqual(0); - expect(fields.first.astNode.directives.length).toEqual(1); - expect(fields.second.astNode.directives.length).toEqual(0); - expect(fields.third.astNode.directives.length).toEqual(0); + const Test = transformedSchema.getType('Test') + assertGraphQLObjectType(Test) + const fields = Test.getFields(); + assertSome(fields['id']) + expect(fields['id'].astNode?.directives?.length).toEqual(0); + assertSome(fields['first']) + expect(fields['first'].astNode?.directives?.length).toEqual(1); + assertSome(fields['second']) + expect(fields['second'].astNode?.directives?.length).toEqual(0); + assertSome(fields['third']) + expect(fields['third'].astNode?.directives?.length).toEqual(0); }); test('removes directives by argument regex', async () => { @@ -69,10 +89,16 @@ describe('RemoveObjectFieldDirectives', () => { ], }); - const fields = transformedSchema.getType('Test').getFields(); - expect(fields.id.astNode.directives.length).toEqual(0); - expect(fields.first.astNode.directives.length).toEqual(0); - expect(fields.second.astNode.directives.length).toEqual(0); - expect(fields.third.astNode.directives.length).toEqual(0); + const Test = transformedSchema.getType('Test') + assertGraphQLObjectType(Test) + const fields = Test.getFields(); + assertSome(fields['id']) + expect(fields['id'].astNode?.directives?.length).toEqual(0); + assertSome(fields['first']) + expect(fields['first'].astNode?.directives?.length).toEqual(0); + assertSome(fields['second']) + expect(fields['second'].astNode?.directives?.length).toEqual(0); + assertSome(fields['third']) + expect(fields['third'].astNode?.directives?.length).toEqual(0); }); }); diff --git a/packages/wrap/tests/transformRemoveObjectFieldsWithDeprecation.test.ts b/packages/wrap/tests/transformRemoveObjectFieldsWithDeprecation.test.ts index 27781011cfd..a60dabb5615 100644 --- a/packages/wrap/tests/transformRemoveObjectFieldsWithDeprecation.test.ts +++ b/packages/wrap/tests/transformRemoveObjectFieldsWithDeprecation.test.ts @@ -1,5 +1,6 @@ import { wrapSchema, RemoveObjectFieldsWithDeprecation } from '@graphql-tools/wrap'; import { makeExecutableSchema } from '@graphql-tools/schema'; +import { assertGraphQLObjectType } from '../../testing/assertion'; describe('RemoveObjectFieldsWithDeprecation', () => { const originalSchema = makeExecutableSchema({ @@ -20,9 +21,11 @@ describe('RemoveObjectFieldsWithDeprecation', () => { ], }); - const fields = transformedSchema.getType('Test').getFields(); - expect(fields.first).toBeDefined(); - expect(fields.second).toBeUndefined(); + const Test = transformedSchema.getType('Test') + assertGraphQLObjectType(Test) + const fields = Test.getFields(); + expect(fields['first']).toBeDefined(); + expect(fields['second']).toBeUndefined(); }); test('removes deprecated fields by reason regex', async () => { @@ -33,8 +36,10 @@ describe('RemoveObjectFieldsWithDeprecation', () => { ], }); - const fields = transformedSchema.getType('Test').getFields(); - expect(fields.first).toBeUndefined(); - expect(fields.second).toBeUndefined(); + const Test = transformedSchema.getType('Test') + assertGraphQLObjectType(Test) + const fields = Test.getFields(); + expect(fields['first']).toBeUndefined(); + expect(fields['second']).toBeUndefined(); }); }); diff --git a/packages/wrap/tests/transformRemoveObjectFieldsWithDirective.test.ts b/packages/wrap/tests/transformRemoveObjectFieldsWithDirective.test.ts index 6e661ea1b56..978bae84505 100644 --- a/packages/wrap/tests/transformRemoveObjectFieldsWithDirective.test.ts +++ b/packages/wrap/tests/transformRemoveObjectFieldsWithDirective.test.ts @@ -1,5 +1,6 @@ import { wrapSchema, RemoveObjectFieldsWithDirective } from '@graphql-tools/wrap'; import { makeExecutableSchema } from '@graphql-tools/schema'; +import { assertGraphQLObjectType } from '../../testing/assertion'; describe('RemoveObjectFieldsWithDirective', () => { const originalSchema = makeExecutableSchema({ @@ -25,11 +26,13 @@ describe('RemoveObjectFieldsWithDirective', () => { ], }); - const fields = transformedSchema.getType('Test').getFields(); - expect(fields.first).toBeUndefined(); - expect(fields.second).toBeUndefined(); - expect(fields.third).toBeUndefined(); - expect(fields.fourth).toBeDefined(); + const Test = transformedSchema.getType('Test') + assertGraphQLObjectType(Test) + const fields = Test.getFields(); + expect(fields['first']).toBeUndefined(); + expect(fields['second']).toBeUndefined(); + expect(fields['third']).toBeUndefined(); + expect(fields['fourth']).toBeDefined(); }); test('removes directive fields by name regex', async () => { @@ -40,11 +43,13 @@ describe('RemoveObjectFieldsWithDirective', () => { ], }); - const fields = transformedSchema.getType('Test').getFields(); - expect(fields.first).toBeUndefined(); - expect(fields.second).toBeUndefined(); - expect(fields.third).toBeUndefined(); - expect(fields.fourth).toBeDefined(); + const Test = transformedSchema.getType('Test') + assertGraphQLObjectType(Test) + const fields = Test.getFields(); + expect(fields['first']).toBeUndefined(); + expect(fields['second']).toBeUndefined(); + expect(fields['third']).toBeUndefined(); + expect(fields['fourth']).toBeDefined(); }); test('removes directive fields by argument', async () => { @@ -55,11 +60,13 @@ describe('RemoveObjectFieldsWithDirective', () => { ], }); - const fields = transformedSchema.getType('Test').getFields(); - expect(fields.first).toBeDefined(); - expect(fields.second).toBeUndefined(); - expect(fields.third).toBeUndefined(); - expect(fields.third).toBeUndefined(); + const Test = transformedSchema.getType('Test') + assertGraphQLObjectType(Test) + const fields = Test.getFields(); + expect(fields['first']).toBeDefined(); + expect(fields['second']).toBeUndefined(); + expect(fields['third']).toBeUndefined(); + expect(fields['third']).toBeUndefined(); }); test('removes directive fields by argument regex', async () => { @@ -70,10 +77,12 @@ describe('RemoveObjectFieldsWithDirective', () => { ], }); - const fields = transformedSchema.getType('Test').getFields(); - expect(fields.first).toBeUndefined(); - expect(fields.second).toBeUndefined(); - expect(fields.third).toBeUndefined(); - expect(fields.third).toBeUndefined(); + const Test = transformedSchema.getType('Test') + assertGraphQLObjectType(Test) + const fields = Test.getFields(); + expect(fields['first']).toBeUndefined(); + expect(fields['second']).toBeUndefined(); + expect(fields['third']).toBeUndefined(); + expect(fields['third']).toBeUndefined(); }); }); diff --git a/packages/wrap/tests/transformRenameInputObjectFields.test.ts b/packages/wrap/tests/transformRenameInputObjectFields.test.ts index 3ebbe735dc4..f40682d05d6 100644 --- a/packages/wrap/tests/transformRenameInputObjectFields.test.ts +++ b/packages/wrap/tests/transformRenameInputObjectFields.test.ts @@ -1,6 +1,7 @@ import { wrapSchema, RenameInputObjectFields } from '@graphql-tools/wrap'; import { makeExecutableSchema } from '@graphql-tools/schema'; import { graphql } from 'graphql'; +import { assertSome } from '@graphql-tools/utils'; describe('RenameInputObjectFields', () => { test('renaming with arguments works', async () => { @@ -33,7 +34,7 @@ describe('RenameInputObjectFields', () => { schema, transforms: [ new RenameInputObjectFields( - (typeName: string, fieldName: string) => { + (typeName, fieldName) => { if (typeName === 'InputObject' && fieldName === 'field2') { return 'field3'; } @@ -53,8 +54,9 @@ describe('RenameInputObjectFields', () => { }`; const result = await graphql(transformedSchema, query); - expect(result.data.test.field1).toBe('field1'); - expect(result.data.test.field2).toBe('field2'); + assertSome(result.data) + expect(result.data['test'].field1).toBe('field1'); + expect(result.data['test'].field2).toBe('field2'); }); test('renaming with variables works', async () => { @@ -115,7 +117,8 @@ describe('RenameInputObjectFields', () => { } } const result = await graphql(transformedSchema, query, {}, {}, variables); - expect(result.data.test.field1).toBe('field1'); - expect(result.data.test.field2).toBe('field2'); + assertSome(result.data) + expect(result.data['test'].field1).toBe('field1'); + expect(result.data['test'].field2).toBe('field2'); }); }); diff --git a/packages/wrap/tests/transformTransformEnumValues.test.ts b/packages/wrap/tests/transformTransformEnumValues.test.ts index d5b2a935a5c..164d6ee3025 100644 --- a/packages/wrap/tests/transformTransformEnumValues.test.ts +++ b/packages/wrap/tests/transformTransformEnumValues.test.ts @@ -2,6 +2,13 @@ import { wrapSchema, TransformEnumValues } from '@graphql-tools/wrap'; import { makeExecutableSchema } from '@graphql-tools/schema'; import { graphql, GraphQLEnumType } from 'graphql'; +function assertGraphQLEnumType(input: unknown): asserts input is GraphQLEnumType { + if (input instanceof GraphQLEnumType) { + return + } + throw new Error("Expected GraphQLEnumType.") +} + describe('TransformEnumValues', () => { test('works', async () => { const schema = makeExecutableSchema({ @@ -74,7 +81,9 @@ describe('TransformEnumValues', () => { const result = await graphql(transformedSchema, query); expect(result.errors).toBeUndefined(); - expect((transformedSchema.getType('TestEnum') as GraphQLEnumType).getValue('UNO').value).toBe('ONE'); + const TestEnum = transformedSchema.getType('TestEnum') + assertGraphQLEnumType(TestEnum) + expect(TestEnum.getValue('UNO')?.value).toBe('ONE'); }); test('works with variables', async () => { diff --git a/patches/bob-the-bundler+1.4.1.patch b/patches/bob-the-bundler+1.4.1.patch new file mode 100644 index 00000000000..ed97b313bda --- /dev/null +++ b/patches/bob-the-bundler+1.4.1.patch @@ -0,0 +1,22 @@ +diff --git a/node_modules/bob-the-bundler/dist/commands/build.js b/node_modules/bob-the-bundler/dist/commands/build.js +index e1c8d4e..cb9fa6a 100644 +--- a/node_modules/bob-the-bundler/dist/commands/build.js ++++ b/node_modules/bob-the-bundler/dist/commands/build.js +@@ -87,7 +87,7 @@ async function buildSingle({ distDir, distPath = '' }) { + // generates + const commonOutputOptions = { + preferConst: true, +- sourcemap: true, ++ sourcemap: false, + }; + const generates = [ + { +@@ -148,7 +148,7 @@ async function build({ packagePath, cwd, pkg, fullName, config, reporter, distDi + // generates + const commonOutputOptions = { + preferConst: true, +- sourcemap: true, ++ sourcemap: false, + }; + const generates = [ + { diff --git a/scripts/build-api-docs.js b/scripts/build-api-docs.js index a92c3b7f981..2a7700a270b 100644 --- a/scripts/build-api-docs.js +++ b/scripts/build-api-docs.js @@ -34,6 +34,7 @@ async function buildApiDocs() { const packageJsonContent = require(path.join(__dirname, '..', packageJsonPath)); // Do not include private and large npm package that contains rest if ( + !packageJsonPath.includes('./website/') && !packageJsonContent.private && packageJsonContent.name !== MONOREPO && !packageJsonContent.name.endsWith('/container') @@ -80,6 +81,13 @@ async function buildApiDocs() { // Escape angle brackets .replace(//g, '>') + // Fix title + .replace(/^# .+/g, function (match) { + return `--- +title: '${match.replace('# ', '')}' +--- +${match}`; + }) // Fix links .replace(/\[([^\]]+)\]\(([^)]+).md\)/g, '[$1]($2)') .replace(/\[([^\]]+)\]\((\.\.\/(classes|interfaces|enums)\/([^\)]+))\)/g, '[$1](/docs/api/$3/$4)'); @@ -109,8 +117,8 @@ async function buildApiDocs() { }) ); - // Remove the generated "index.md" file - // fs.unlinkSync(path.join(outputDir, 'index.md')); + // Remove the generated "README.md" file + fs.unlinkSync(path.join(outputDir, 'README.md')); // Update each module 's frontmatter and title await Promise.all( @@ -142,20 +150,27 @@ sidebar_label: "${id}" fs.writeFileSync( sidebarsPath, JSON.stringify( - [ - { - Modules: modules.map(([name]) => `api/modules/${convertNameToId(name)}`), - }, - { - Classes: getSidebarItemsByDirectory(path.join(outputDir, 'classes')), - }, - { - Interfaces: getSidebarItemsByDirectory(path.join(outputDir, 'interfaces')), - }, - { - Enums: getSidebarItemsByDirectory(path.join(outputDir, 'enums')), + { + $name: 'API Reference', + _: { + modules: { + $name: 'Modules', + $routes: getSidebarItemsByDirectory(path.join(outputDir, 'modules')), + }, + classes: { + $name: 'Classes', + $routes: getSidebarItemsByDirectory(path.join(outputDir, 'classes')), + }, + interfaces: { + $name: 'Interfaces', + $routes: getSidebarItemsByDirectory(path.join(outputDir, 'interfaces')), + }, + enums: { + $name: 'Enums', + $routes: getSidebarItemsByDirectory(path.join(outputDir, 'enums')), + }, }, - ], + }, null, 2 ) @@ -183,8 +198,7 @@ sidebar_label: "${id}" const absoluteFilePath = path.join(dirName, fileName); const fileLstat = fs.lstatSync(absoluteFilePath); if (fileLstat.isFile()) { - const relativeDirName = path.relative(outputDir, dirName); - return `api/${relativeDirName}/${path.parse(fileName).name}`; + return path.parse(fileName).name; } else { return getSidebarItemsByDirectory(absoluteFilePath); } diff --git a/scripts/canary-release.js b/scripts/canary-release.js index 978fac233d5..5a8ce567124 100644 --- a/scripts/canary-release.js +++ b/scripts/canary-release.js @@ -3,21 +3,31 @@ const semver = require('semver'); const cp = require('child_process'); const { basename } = require('path'); -const { read: readConfig } = require("@changesets/config"); -const readChangesets = require("@changesets/read").default; -const assembleReleasePlan = require("@changesets/assemble-release-plan").default; -const applyReleasePlan = require("@changesets/apply-release-plan").default; -const { getPackages } = require("@manypkg/get-packages"); +const { read: readConfig } = require('@changesets/config'); +const readChangesets = require('@changesets/read').default; +const assembleReleasePlan = require('@changesets/assemble-release-plan').default; +const applyReleasePlan = require('@changesets/apply-release-plan').default; +const { getPackages } = require('@manypkg/get-packages'); function getNewVersion(version, type) { - const gitHash = cp.spawnSync('git', ['rev-parse', '--short', 'HEAD']).stdout.toString().trim(); - - return semver.inc(version, `pre${type}`, true, 'alpha-' + gitHash); + let npmVersionSuffix = process.env.NPM_VERSION_SUFFIX; + if (!npmVersionSuffix) { + const gitHash = cp.spawnSync('git', ['rev-parse', '--short', 'HEAD']).stdout.toString().trim(); + npmVersionSuffix = `alpha-${gitHash}`; + } + return semver.inc(version, `pre${type}`, true, npmVersionSuffix); } function getRelevantChangesets(baseBranch) { - const comparePoint = cp.spawnSync('git', ['merge-base', `origin/${baseBranch}`, 'HEAD']).stdout.toString().trim(); - const listModifiedFiles = cp.spawnSync('git', ['diff', '--name-only', comparePoint]).stdout.toString().trim().split('\n'); + const comparePoint = cp + .spawnSync('git', ['merge-base', `origin/${baseBranch}`, 'HEAD']) + .stdout.toString() + .trim(); + const listModifiedFiles = cp + .spawnSync('git', ['diff', '--name-only', comparePoint]) + .stdout.toString() + .trim() + .split('\n'); return listModifiedFiles.filter(f => f.startsWith('.changeset')).map(f => basename(f, '.md')); } @@ -27,14 +37,18 @@ async function updateVersions() { const packages = await getPackages(cwd); const config = await readConfig(cwd, packages); const modifiedChangesets = getRelevantChangesets(config.baseBranch); - const changesets = (await readChangesets(cwd)).filter(change => modifiedChangesets.includes(change.id)); - + const allChangesets = await readChangesets(cwd); + const changesets = + process.env.ON_DEMAND === 'yes' + ? allChangesets + : allChangesets.filter(change => modifiedChangesets.includes(change.id)); + if (changesets.length === 0) { console.warn(`Unable to find any relevant package for canary publishing. Please make sure changesets exists!`); process.exit(1); } else { const releasePlan = assembleReleasePlan(changesets, packages, config, [], false); - + if (releasePlan.releases.length === 0) { console.warn(`Unable to find any relevant package for canary releasing. Please make sure changesets exists!`); process.exit(1); @@ -59,9 +73,11 @@ async function updateVersions() { } } -updateVersions().then(() => { - console.info(`Done!`) -}).catch(err => { - console.error(err); - process.exit(1); -}); +updateVersions() + .then(() => { + console.info(`Done!`); + }) + .catch(err => { + console.error(err); + process.exit(1); + }); diff --git a/scripts/install-typedocs-typescript-version.js b/scripts/install-typedocs-typescript-version.js new file mode 100644 index 00000000000..5246e012eca --- /dev/null +++ b/scripts/install-typedocs-typescript-version.js @@ -0,0 +1,16 @@ +const { writeFileSync } = require('fs'); +const { resolve } = require('path'); +const { argv, cwd } = require('process'); + +const typeDocsVersion = require('typedoc/package.json'); +const pkgPath = resolve(cwd(), './package.json'); + +const pkg = require(pkgPath); + +const version = argv[2]; + +pkg.resolutions = pkg.resolutions || {}; + +pkg.resolutions.typescript = typeDocsVersion.peerDependencies.typescript; + +writeFileSync(pkgPath, JSON.stringify(pkg, null, 2), 'utf8'); diff --git a/tsconfig.build.es5.json b/tsconfig.build.es5.json index c42f1e0d7d6..879594f93ff 100644 --- a/tsconfig.build.es5.json +++ b/tsconfig.build.es5.json @@ -2,6 +2,9 @@ "extends": "./tsconfig.build.json", "compilerOptions": { "outDir": "dist-es5", - "target": "es5" + "target": "es5", + "tsBuildInfoFile": "./node_modules/tsconfig.build.es5.tsbuildinfo", + "sourceMap": false, + "inlineSourceMap": false } } diff --git a/tsconfig.build.json b/tsconfig.build.json index 4abd5dd07b0..a4e8b33e761 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -1,5 +1,10 @@ { "extends": "./tsconfig.json", + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/tsconfig.build.tsbuildinfo", + "sourceMap": false, + "inlineSourceMap": false + }, "exclude": [ "**/test/*.ts", "*.spec.ts", diff --git a/tsconfig.json b/tsconfig.json index 60c649e1e58..3221d62b0b1 100755 --- a/tsconfig.json +++ b/tsconfig.json @@ -18,17 +18,22 @@ "downlevelIteration": true, "suppressImplicitAnyIndexErrors": true, - "noImplicitAny": true, - "alwaysStrict": true, + + "skipLibCheck": true, + + "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, - "skipLibCheck": true, + "noFallthroughCasesInSwitch": true, + "noPropertyAccessFromIndexSignature": true, "paths": { - "@graphql-tools/*-loader": ["packages/loaders/*/src/index.ts"], + "@graphql-tools/*-loader": ["packages/loaders/*/src/index.ts", "packages/*-loader/src/index.ts"], "@graphql-tools/*": ["packages/*/src/index.ts"] - } + }, + + "tsBuildInfoFile": "./node_modules/tsconfig.tsbuildinfo" }, "include": ["packages"], - "exclude": ["**/node_modules", "**/dist"] + "exclude": ["**/node_modules", "**/dist", "**/test-files"] } diff --git a/website/.gitignore b/website/.gitignore deleted file mode 100644 index e02eb3be181..00000000000 --- a/website/.gitignore +++ /dev/null @@ -1,26 +0,0 @@ -# Dependencies -/node_modules - -# Production -/build - -# Generated files -.docusaurus -.cache-loader - -# Misc -.DS_Store -.env.local -.env.development.local -.env.test.local -.env.production.local - -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# Generated API Docs -/docs/api - -api-sidebar.json - diff --git a/website/README.md b/website/README.md deleted file mode 100644 index 859abf8bd0f..00000000000 --- a/website/README.md +++ /dev/null @@ -1,42 +0,0 @@ -# Website - -This website is built using [Docusaurus 2](https://v2.docusaurus.io/), a modern static website generator. - -### Install Dependencies (on the root directory) - -``` -$ yarn -``` - -### Generate API Docs (on the root directory) - - -This command generates API Documentation and its sidebar configuration. - -``` -yarn build:api-docs -``` - -### Start Local Dev Server - -``` -$ yarn start -``` - -This command starts a local development server and open up a browser window. Most changes are reflected live without having to restart the server. - -### Build - -``` -$ yarn build -``` - -This command generates static content into the `build` directory and can be served using any static contents hosting service. - -### Deployment - -``` -$ GIT_USER= USE_SSH=true yarn deploy -``` - -If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch. diff --git a/website/docs/directive-resolvers.md b/website/docs/directive-resolvers.md deleted file mode 100644 index fcf91884492..00000000000 --- a/website/docs/directive-resolvers.md +++ /dev/null @@ -1,178 +0,0 @@ ---- -id: directive-resolvers -title: Directive resolvers -description: A set of utilities to build your JavaScript GraphQL schema in a concise and powerful way. ---- - -## Directive example - -Let's take a look at how we can create `@upper` Directive to upper-case a string returned from resolve on Field - -To start, let's grab the schema definition string from the `makeExecutableSchema` example [in the "Generating a schema" article](/docs/generate-schema/#example). - -```js -import { makeExecutableSchema } from '@graphql-tools/schema'; -import { graphql } from 'graphql'; - -// Construct a schema, using GraphQL schema language -const typeDefs = ` - directive @upper on FIELD_DEFINITION - - type Query { - hello: String @upper - } -`; - -// Implement resolvers for out custom Directive -const directiveResolvers = { - upper( - next, - src, - args, - context, - ) { - return next().then((str) => { - if (typeof(str) === 'string') { - return str.toUpperCase(); - } - return str; - }); - }, -} - -// Provide resolver functions for your schema fields -const resolvers = { - Query: { - hello: (root, args, context) => { - return 'Hello world!'; - }, - }, -}; - -export const schema = makeExecutableSchema({ - typeDefs, - resolvers, - directiveResolvers, -}); - -const query = ` -query UPPER_HELLO { - hello -} -`; - -graphql(schema, query).then((result) => console.log('Got result', result)); -``` - -> Note: next() always return a Promise for consistency, resolved with original resolver value or rejected with an error. - -## Multi-Directives example - -Multi-Directives on a field will be apply with LTR order. - -```js -// graphql-tools combines a schema string with resolvers. -import { makeExecutableSchema } from '@graphql-tools/schema'; - -// Construct a schema, using GraphQL schema language -const typeDefs = ` - directive @upper on FIELD_DEFINITION - directive @concat(value: String!) on FIELD_DEFINITION - - type Query { - foo: String @concat(value: "@gmail.com") @upper - } -`; - -// Customs directives, check https://github.com/ardatan/graphql-tools/pull/518 -// for more examples -const directiveResolvers = { - upper( - next, - src, - args, - context, - ) { - return next().then((str) => { - if (typeof(str) === 'string') { - return str.toUpperCase(); - } - return str; - }); - }, - concat( - next, - src, - args, - context, - ) { - return next().then((str) => { - if (typeof(str) !== 'undefined') { - return `${str}${args.value}`; - } - return str; - }); - }, -} - -// Provide resolver functions for your schema fields -const resolvers = { - Query: { - foo: (root, args, context) => { - return 'foo'; - }, - }, -}; - -// Required: Export the GraphQL.js schema object as "schema" -export const schema = makeExecutableSchema({ - typeDefs, - resolvers, - directiveResolvers, -}); -``` - -The result with query `{foo}` will be: -```json -{ - "data": { - "foo": "FOO@GMAIL.COM" - } -} -``` - -## API - -### directiveResolvers option - -```js -import { makeExecutableSchema } from '@graphql-tools/schema'; - -const directiveResolvers = { - // directive resolvers implement -}; - -const schema = makeExecutableSchema({ - // ... other options - directiveResolvers, -}) -``` - -`makeExecutableSchema` has new option field is `directiveResolvers`, a map object for custom Directive's resolvers. - -### attachDirectiveResolvers - -```js -import { attachDirectiveResolvers } from '@graphql-tools/schema'; - -const directiveResolvers = { - // directive resolvers implement -}; - -schemaWithDirectiveResolvers = attachDirectiveResolvers( - schema, - directiveResolvers, -); -``` - -Given an instance of GraphQLSchema and a `directiveResolvers` map object, `attachDirectiveResolvers` returns a new schema in which all fields' resolver have been wrapped with directive resolvers. diff --git a/website/docs/connectors.md b/website/docs/guides/connectors.mdx similarity index 100% rename from website/docs/connectors.md rename to website/docs/guides/connectors.mdx diff --git a/website/docs/documents-loading.md b/website/docs/guides/documents-loading.mdx similarity index 100% rename from website/docs/documents-loading.md rename to website/docs/guides/documents-loading.mdx diff --git a/website/docs/generate-schema.md b/website/docs/guides/generate-schema.mdx similarity index 82% rename from website/docs/generate-schema.md rename to website/docs/guides/generate-schema.mdx index 04f1ed2a040..679af9f224a 100644 --- a/website/docs/generate-schema.md +++ b/website/docs/guides/generate-schema.mdx @@ -105,10 +105,11 @@ This example has the entire type definition in one string and all resolvers in o ## Extending Types -It's easy to add additional fields to existing types using the `extend` keyword. Using `extend` is particularly useful in avoiding a large list of fields on root Queries and Mutations. You can use it like this: +It's easy to add additional fields to existing types using the `extend` keyword. Using `extend` is particularly useful in avoiding a large list of fields on root Queries and Mutations. You can use it like this: ```js -const typeDefs = [` +const typeDefs = [ + ` schema { query: Query } @@ -120,7 +121,8 @@ const typeDefs = [` type Bar { id } - `, ` + `, + ` type Foo { id: String! } @@ -128,7 +130,8 @@ const typeDefs = [` extend type Query { foos: [Foo]! } -`] +`, +]; ``` If one of the types extended needs a resolver you can use `makeExecutableSchema` like this: @@ -138,22 +141,22 @@ const barsResolver = { Query: { bars(parent, args, context, info) { // ... - } - } + }, + }, }; const foosResolver = { Query: { foos(parent, args, context, info) { // ... - } - } -} + }, + }, +}; const schema = makeExecutableSchema({ typeDefs, - resolvers: [barsResolver, foosResolver] -}) + resolvers: [barsResolver, foosResolver], +}); ``` ## Learning the GraphQL schema language @@ -161,8 +164,10 @@ const schema = makeExecutableSchema({ The official documentation on graphql.org now has [a section about GraphQL schemas](http://graphql.org/learn/schema/) which explains all of the different schema features and how to use them with the schema language. The type definitions must define a query type, which means a minimal schema would look something like this: + ```js -const typeDefs = [` +const typeDefs = [ + ` schema { query: RootQuery } @@ -170,7 +175,8 @@ const typeDefs = [` type RootQuery { aNumber: Int } -`]; +`, +]; ``` ## Descriptions & Deprecations @@ -219,32 +225,26 @@ const jsSchema = makeExecutableSchema({ typeDefs, resolvers, // optional logger, // optional - allowUndefinedInResolve: false, // optional resolverValidationOptions: {}, // optional - directiveResolvers: null, // optional - schemaDirectives: null, // optional schemaTransforms: [], // optional parseOptions: {}, // optional inheritResolversFromInterfaces: false // optional }); ``` -- `typeDefs` is a required argument and should be an GraphQL schema language string or array of GraphQL schema language strings or a function that takes no arguments and returns an array of GraphQL schema language strings. The order of the strings in the array is not important, but it must include a schema definition. +- `typeDefs` is a required argument and should be a GraphQL schema language string or an array of GraphQL schema language strings or a function that takes no arguments and returns an array of GraphQL schema language strings. The order of the strings in the array is not important, but it must include a schema definition. - `resolvers` is an optional argument _(empty object by default)_ and should be an object or an array of objects that follow the pattern explained in [article on resolvers](/docs/resolvers/) -- `logger` is an optional argument, which can be used to print errors to the server console that are usually swallowed by GraphQL. The `logger` argument should be an object with a `log` function, eg. `const logger = { log: e => console.log(e) }` - - `parseOptions` is an optional argument which allows customization of parse when specifying `typeDefs` as a string. -- `allowUndefinedInResolve` is an optional argument, which is `true` by default. When set to `false`, causes your resolver to throw errors if they return undefined, which can help make debugging easier. - - `resolverValidationOptions` is an optional argument with the following properties, each of which can be set to `error`, `warn`, or `ignore`: + - `requireResolversForArgs` will cause `makeExecutableSchema` to throw an error (`error`) or issue a warning (`warn`)unless a resolver is defined for every field with arguments. The default is `ignore`, causing this validator to be skipped. - `requireResolversForNonScalar` require a resolver for every non-scalar field. Default is `ignore`. - - `requireResolversForAllFields` asserts that *all* fields have valid resolvers. This option cannot be set in combination with the previous two validators. Default is `ignore`. + - `requireResolversForAllFields` asserts that _all_ fields have valid resolvers. This option cannot be set in combination with the previous two validators. Default is `ignore`. - `requireResolversForResolveType` will require a `resolveType()` method for Interface and Union types. This can be passed in with the field resolvers as `__resolveType()`. Default is `ignore`. @@ -253,5 +253,3 @@ const jsSchema = makeExecutableSchema({ - `inheritResolversFromInterfaces` GraphQL Objects that implement interfaces will inherit missing resolvers from their interface types defined in the `resolvers` object. - `schemaTransforms` is an optional argument _(empty array by default)_ and should be an array of schema transformation functions, essentially designed to enable the use of [directive-based functional schema transformation](/docs/schema-directives/) - -- `schemaDirectives` is an optional argument _(empty object by default)_ and can be used to specify the [earlier class-based implementation of schema directives](/docs/legacy-schema-directives/) diff --git a/website/docs/graphql-tag-pluck.md b/website/docs/guides/graphql-tag-pluck.mdx similarity index 100% rename from website/docs/graphql-tag-pluck.md rename to website/docs/guides/graphql-tag-pluck.mdx diff --git a/website/docs/loaders.md b/website/docs/guides/loaders.mdx similarity index 100% rename from website/docs/loaders.md rename to website/docs/guides/loaders.mdx diff --git a/website/docs/merge-resolvers.md b/website/docs/guides/merge-resolvers.mdx similarity index 100% rename from website/docs/merge-resolvers.md rename to website/docs/guides/merge-resolvers.mdx diff --git a/website/docs/merge-schemas.md b/website/docs/guides/merge-schemas.mdx similarity index 100% rename from website/docs/merge-schemas.md rename to website/docs/guides/merge-schemas.mdx diff --git a/website/docs/merge-typedefs.md b/website/docs/guides/merge-typedefs.mdx similarity index 100% rename from website/docs/merge-typedefs.md rename to website/docs/guides/merge-typedefs.mdx diff --git a/website/docs/migration-from-import.md b/website/docs/guides/migration/migration-from-import.mdx similarity index 100% rename from website/docs/migration-from-import.md rename to website/docs/guides/migration/migration-from-import.mdx diff --git a/website/docs/migration-from-merge-graphql-schemas.md b/website/docs/guides/migration/migration-from-merge-graphql-schemas.mdx similarity index 100% rename from website/docs/migration-from-merge-graphql-schemas.md rename to website/docs/guides/migration/migration-from-merge-graphql-schemas.mdx diff --git a/website/docs/migration-from-toolkit.md b/website/docs/guides/migration/migration-from-toolkit.mdx similarity index 100% rename from website/docs/migration-from-toolkit.md rename to website/docs/guides/migration/migration-from-toolkit.mdx diff --git a/website/docs/migration-from-tools.md b/website/docs/guides/migration/migration-from-tools.mdx similarity index 100% rename from website/docs/migration-from-tools.md rename to website/docs/guides/migration/migration-from-tools.mdx diff --git a/website/docs/mocking.md b/website/docs/guides/mocking.mdx similarity index 100% rename from website/docs/mocking.md rename to website/docs/guides/mocking.mdx diff --git a/website/docs/relay-operation-optimizer.md b/website/docs/guides/relay-operation-optimizer.mdx similarity index 100% rename from website/docs/relay-operation-optimizer.md rename to website/docs/guides/relay-operation-optimizer.mdx diff --git a/website/docs/remote-schemas.md b/website/docs/guides/remote-schemas.mdx similarity index 76% rename from website/docs/remote-schemas.md rename to website/docs/guides/remote-schemas.mdx index 08b774d0a42..a9fbbad9687 100644 --- a/website/docs/remote-schemas.md +++ b/website/docs/guides/remote-schemas.mdx @@ -10,9 +10,9 @@ There two ways to create remote schemas; ## Use Loaders to load schemas easily -Check out [Schema Loading](/docs/schema-loading) to load schemas from an URL and/or different sources easily without implementing an executor or subscriber. +Check out [Schema Loading](/docs/schema-loading) to load schemas from an URL and/or different sources easily without implementing an executor. -## Create a remote executable schema with custom executor and subscriber methods +## Create a remote executable schema with custom executor methods Generally, to create a remote schema, you generally need just three steps: @@ -20,8 +20,6 @@ Generally, to create a remote schema, you generally need just three steps: 2. Use [`introspectSchema`](#introspectschemaexecutor-context) to get the non-executable schema of the remote server 3. Use [`wrapSchema`](#wrapschemaschemaconfig) to create a schema that uses the executor to delegate requests to the underlying service -You can optionally also include a [subscriber](#creating-a-subscriber) that can retrieve real time subscription results from the remote schema (only if you are using GraphQL Subscriptions) - ### Creating an executor You can use an executor with an HTTP Client implementation (like cross-fetch). An executor is a function capable of retrieving GraphQL results. It is the same way that a GraphQL Client handles fetching data and is used by several `graphql-tools` features to do introspection or fetch results during execution. @@ -99,13 +97,9 @@ export default async () => { }; ``` -### Creating a subscriber - -For subscriptions, we need to define a subscriber that returns `AsyncIterator`. Other than that, it has the similar API with `executor`. +### Extending the executor for subscriptions -```ts -type Subscriber = (executionParams: ExecutionParams) => Promise>; -``` +For subscriptions, we need to extend our executor by returning `AsyncIterator`. #### Using `graphql-ws` @@ -113,7 +107,7 @@ For the following example to work, the server must implement the [library's tran ```ts import { wrapSchema, introspectSchema } from '@graphql-tools/wrap'; -import { Executor, Subscriber } from '@graphql-tools/delegate'; +import { Executor } from '@graphql-tools/delegate'; import { fetch } from 'cross-fetch'; import { print } from 'graphql'; import { observableToAsyncIterable } from '@graphql-tools/utils'; @@ -122,23 +116,11 @@ import { createClient } from 'graphql-ws'; const HTTP_GRAPHQL_ENDPOINT = 'http://localhost:3000/graphql'; const WS_GRAPHQL_ENDPOINT = 'ws://localhost:3000/graphql'; -const executor: Executor = async ({ document, variables }) => { - const query = print(document); - const fetchResult = await fetch(HTTP_GRAPHQL_ENDPOINT, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ query, variables }), - }); - return fetchResult.json(); -}; - const subscriptionClient = createClient({ url: WS_GRAPHQL_ENDPOINT, }); -const subscriber: Subscriber = ({ document, variables }) => +const executor: Executor = ({ document, variables }) => observableToAsyncIterable({ subscribe: observer => ({ unsubscribe: subscriptionClient.subscribe( @@ -169,7 +151,6 @@ export default async () => { const schema = wrapSchema({ schema: await introspectSchema(executor), executor, - subscriber, }); return schema; @@ -260,24 +241,4 @@ const schema = wrapSchema({ }); ``` -Note that within the `defaultCreateProxyingResolver` function, `delegateToSchema` receives `executor` and `subscriber` functions stored on the subschema config object originally passed to `wrapSchema`. As above, use of the the `createProxyingResolver` option is helpful when you want to customize additional functionality at resolver creation time. If you just want to customize how things are proxied at the time that they are proxied, you can make do just with custom executors and subscribers. - -### makeRemoteExecutableSchema(options) - -What about `makeRemoteExecutableSchema`, the function used in older versions to access remote schemas? It still works -- just now under the hood calling `wrapSchema`. There is essentially no longer any need to use `makeRemoteExecutableSchema` directly, but we've kept it around for backwards compatibility. - -You can still pass a `createResolver` function to `makeRemoteExecutableSchema` to override how the fetch resolvers are created and executed. The `createResolver` param accepts an `Executor` as its first argument (and a `Subscriber` as its second) and returns a resolver function. This opens up the possibility for users to create batching mechanisms for fetches. As above, it is likely easier to just customize the `executor` function itself. - -Given a GraphQL.js schema (can be a non-executable client schema made by `buildClientSchema`) and a [executor](#creating-an-executor), `makeRemoteExecutableSchema` produce a GraphQL Schema that routes all requests to the executor: - -```js -import { makeRemoteExecutableSchema } from '@graphql-tools/wrap'; - -const createResolver: (executor: Executor) => GraphQLFieldResolver = // . . . - -const schema = makeRemoteExecutableSchema({ - schema, - executor, - createResolver -}); -``` +Note that within the `defaultCreateProxyingResolver` function, `delegateToSchema` receives `executor` function stored on the subschema config object originally passed to `wrapSchema`. As above, use of the the `createProxyingResolver` option is helpful when you want to customize additional functionality at resolver creation time. If you just want to customize how things are proxied at the time that they are proxied, you can make do just with custom executors. diff --git a/website/docs/resolvers-composition.md b/website/docs/guides/resolvers-composition.mdx similarity index 50% rename from website/docs/resolvers-composition.md rename to website/docs/guides/resolvers-composition.mdx index 68513317ddc..427738cddc4 100644 --- a/website/docs/resolvers-composition.md +++ b/website/docs/guides/resolvers-composition.mdx @@ -13,27 +13,27 @@ The following is an example of a simple logged-in authorization logic: Instead of doing this, ```js -const resolvers ={ - Query: { - myQuery: (root, args, context) => { - // Make sure that the user is authenticated - if (!context.currentUser) { - throw new Error('You are not authenticated!'); - } - - // Make sure that the user has the correct roles - if (!context.currentUser.roles || context.currentUser.roles.includes('EDITOR')) { - throw new Error('You are not authorized!'); - } - - // Business logic - if (args.something === '1') { - return true; - } - - return false; - }, +const resolvers = { + Query: { + myQuery: (root, args, context) => { + // Make sure that the user is authenticated + if (!context.currentUser) { + throw new Error('You are not authenticated!'); + } + + // Make sure that the user has the correct roles + if (!context.currentUser.roles || context.currentUser.roles.includes('EDITOR')) { + throw new Error('You are not authorized!'); + } + + // Business logic + if (args.something === '1') { + return true; + } + + return false; }, + }, }; ``` @@ -42,39 +42,50 @@ You can do; ```js const { composeResolvers } = require('@graphql-tools/resolvers-composition'); -const resolvers ={ - Query: { - myQuery: (root, args, context) => { - if (args.something === '1') { - return true; - } +const resolvers = { + Query: { + myQuery: (root, args, context) => { + if (args.something === '1') { + return true; + } - return false; - }, + return false; }, + }, }; const isAuthenticated = () => next => async (root, args, context, info) => { - if (!context.currentUser) { - throw new Error('You are not authenticated!'); - } + if (!context.currentUser) { + throw new Error('You are not authenticated!'); + } - return next(root, args, context, info); + return next(root, args, context, info); }; const hasRole = (role: string) => next => async (root, args, context, info) => { - if (!context.currentUser.roles || context.currentUser.roles.includes(role)) { - throw new Error('You are not authorized!'); - } + if (!context.currentUser.roles || context.currentUser.roles.includes(role)) { + throw new Error('You are not authorized!'); + } - return next(root, args, context, info); + return next(root, args, context, info); }; const resolversComposition = { - 'Query.myQuery': [isAuthenticated(), hasRole('EDITOR')], + 'Query.myQuery': [isAuthenticated(), hasRole('EDITOR')], }; const composedResolvers = composeResolvers(resolvers, resolversComposition); ``` `composeResolvers` is a method in `@graphql-tools/resolvers-composition` package that accepts `IResolvers` object and mappings for composition functions that would be run before resolver itself. + +### Supported path matcher format + +The paths for resolvers support `*` wildcard for types and glob patters for fields, eg: + +- `*.*` - all types and all fields +- `Query.*` - all queries +- `Query.single` - only a single query +- `Query.{first, second}` - queries for first/second +- `Query.!first` - all queries but first +- `Query.!{first, second}` - all queries but first/second diff --git a/website/docs/resolvers.md b/website/docs/guides/resolvers.mdx similarity index 100% rename from website/docs/resolvers.md rename to website/docs/guides/resolvers.mdx diff --git a/website/docs/scalars.md b/website/docs/guides/scalars.mdx similarity index 100% rename from website/docs/scalars.md rename to website/docs/guides/scalars.mdx diff --git a/website/docs/schema-delegation.md b/website/docs/guides/schema-delegation.mdx similarity index 99% rename from website/docs/schema-delegation.md rename to website/docs/guides/schema-delegation.mdx index 1d315c3bf7e..be35c169d5b 100644 --- a/website/docs/schema-delegation.md +++ b/website/docs/guides/schema-delegation.mdx @@ -93,7 +93,7 @@ The resolver function for the `repositories` field of the `User` type would be r ```graphql # To the subschema -query($id: ID!) { +query ($id: ID!) { repositoriesByUserId(id: $id) { id url diff --git a/website/docs/schema-directives.md b/website/docs/guides/schema-directives.mdx similarity index 97% rename from website/docs/schema-directives.md rename to website/docs/guides/schema-directives.mdx index 36f3caed1f4..124bbfaaf07 100644 --- a/website/docs/schema-directives.md +++ b/website/docs/guides/schema-directives.mdx @@ -23,10 +23,6 @@ The possible applications of directive syntax are numerous: enforcing access per This document focuses on directives that appear in GraphQL _schemas_ (as opposed to queries) written in [Schema Definition Language](https://github.com/facebook/graphql/pull/90), or SDL for short. In the following sections, you will see how custom directives can be implemented and used to modify the structure and behavior of a GraphQL schema in ways that would not be possible using SDL syntax alone. -## (At least) two strategies - -Earlier versions of `graphql-tools` provides a class-based mechanism for directive-based schema modification. The documentation for the class-based version is [still available](/docs/legacy-schema-directives/), but the remainder of this document describes the newer functional mechanism. We believe the newer approach is easier to reason about, but older class-based schema directives are still supported. - ## Using schema directives Most of this document is concerned with _implementing_ schema directives, and some of the examples may seem quite complicated. No matter how many tools and best practices you have at your disposal, it can be difficult to implement a non-trivial schema directive in a reliable, reusable way. Exhaustive testing is essential, and using a typed language like TypeScript is recommended, because there are so many different schema types to worry about. @@ -619,9 +615,9 @@ function uniqueIDDirective(directiveName: string) { resolve(object: any) { const hash = createHash('sha1'); hash.update(type.name); - from.forEach((fieldName: string) => { + for (const fieldName of from) { hash.update(String(object[fieldName])); - }); + } return hash.digest('hex'); }, }; @@ -692,7 +688,7 @@ In theory, access to the query directives is available within the `info` resolve The `makeExecutableSchema` function also takes a `directiveResolvers` option that can be used for implementing certain kinds of `@directive`s on fields that have resolver functions. -The new abstraction is more general, since it can visit any kind of schema syntax, and do much more than just wrap resolver functions. However, the old `directiveResolvers` API has been [left in place](directive-resolvers) for backwards compatibility, though it is now implemented in terms of `mapSchema`: +The new abstraction is more general, since it can visit any kind of schema syntax, and do much more than just wrap resolver functions. However, the old `directiveResolvers` API has been left in place for backwards compatibility, though it is now implemented in terms of `mapSchema`: ```typescript export function attachDirectiveResolvers( @@ -706,7 +702,7 @@ export function attachDirectiveResolvers( const newFieldConfig = { ...fieldConfig }; const directives = getDirectives(schema, fieldConfig); - Object.keys(directives).forEach(directiveName => { + for (const directiveName in directives) { if (directiveResolvers[directiveName]) { const resolver = directiveResolvers[directiveName]; const originalResolver = newFieldConfig.resolve != null ? newFieldConfig.resolve : defaultFieldResolver; @@ -728,7 +724,7 @@ export function attachDirectiveResolvers( ); }; } - }); + } return newFieldConfig; }, diff --git a/website/docs/schema-loading.md b/website/docs/guides/schema-loading.mdx similarity index 100% rename from website/docs/schema-loading.md rename to website/docs/guides/schema-loading.mdx diff --git a/website/docs/schema-merging.md b/website/docs/guides/schema-merging.mdx similarity index 100% rename from website/docs/schema-merging.md rename to website/docs/guides/schema-merging.mdx diff --git a/website/docs/schema-stitching.md b/website/docs/guides/schema-stitching.mdx similarity index 99% rename from website/docs/schema-stitching.md rename to website/docs/guides/schema-stitching.mdx index 45dce7cee45..65e6cc2b89b 100644 --- a/website/docs/schema-stitching.md +++ b/website/docs/guides/schema-stitching.mdx @@ -44,7 +44,7 @@ const postsService = makeExecutableSchema({ `, resolvers: { // ... - } + }, }); const usersService = makeExecutableSchema({ @@ -61,7 +61,7 @@ const usersService = makeExecutableSchema({ `, resolvers: { // ... - } + }, }); const { stitchingDirectivesTransformer } = stitchingDirectives({ @@ -73,7 +73,7 @@ const gatewaySchema = stitchSchemas({ subschemas: [ { schema: postsSchema, batch: true }, { schema: usersSchema, batch: true }, - ] + ], }); ``` diff --git a/website/docs/stitch-api.md b/website/docs/guides/schema-stitching/stitch-api.mdx similarity index 100% rename from website/docs/stitch-api.md rename to website/docs/guides/schema-stitching/stitch-api.mdx diff --git a/website/docs/stitch-combining-schemas.md b/website/docs/guides/schema-stitching/stitch-combining-schemas.mdx similarity index 96% rename from website/docs/stitch-combining-schemas.md rename to website/docs/guides/schema-stitching/stitch-combining-schemas.mdx index 344026fc13a..405dcdaf480 100644 --- a/website/docs/stitch-combining-schemas.md +++ b/website/docs/guides/schema-stitching/stitch-combining-schemas.mdx @@ -12,7 +12,7 @@ Note that schema stitching is a superset of the [schema wrapping](/docs/schema-w One of the main benefits of GraphQL is that we can query for all data in a single request to one schema. As that schema grows though, it may become preferable to break it up into separate modules or microservices that can be developed independently. We may also want to integrate the schemas we own with third-party schemas, allowing mashups with external data. -![distributed service graph](../static/img/distributed-graph.png) +![distributed service graph](/assets/distributed-graph.png) In these cases, `stitchSchemas` is used to combine multiple GraphQL APIs into one unified gateway proxy schema that knows how to delegate parts of a request to the relevant underlying subschemas. These subschemas may be local GraphQL instances or APIs running on remote servers. @@ -88,7 +88,6 @@ export interface SubschemaConfig { schema: GraphQLSchema; rootValue?: Record; executor?: Executor; - subscriber?: Subscriber; createProxyingResolver?: CreateProxyingResolverFn; transforms?: Array; merge?: Record; @@ -109,7 +108,7 @@ Also note that these subschema config objects may need to be referenced again in ## Stitching remote schemas -To include a remote schema in the combined gateway, you must provide at least the `schema` and `executor` subschema config options, and an optional `subscriber` for subscriptions: +To include a remote schema in the combined gateway, you must provide at least the `schema` and `executor` subschema config options. ```js import { introspectSchema } from '@graphql-tools/wrap'; @@ -129,13 +128,11 @@ async function remoteExecutor({ document, variables }) { export const postsSubschema = { schema: await introspectSchema(remoteExecutor), executor: remoteExecutor, - // subscriber: remoteSubscriber }; ``` - `schema`: this is a non-executable schema representing the remote API. The remote schema may be obtained using [introspection](/docs/remote-schemas/#introspectschemaexecutor-context), or fetched as a flat SDL string (from a server or repo) and built into a schema using [`buildSchema`](https://graphql.org/graphql-js/utilities/#buildschema). Note that not all GraphQL servers enable introspection, and those that do will not include custom directives. - `executor`: is a generic method that performs requests to a remote schema. It's quite simple to [write your own](/docs/remote-schemas#creating-an-executor). Subschema config uses the executor for query and mutation operations. See [handbook example](https://github.com/gmac/schema-stitching-handbook/tree/master/combining-local-and-remote-schemas). -- `subscriber`: to enable subscription operations, include a [subscriber function](/docs/remote-schemas#creating-a-subscriber) that returns an AsyncIterator. See [handbook example](https://github.com/gmac/schema-stitching-handbook/tree/master/mutations-and-subscriptions). ## Duplicate types diff --git a/website/docs/stitch-directives-sdl.md b/website/docs/guides/schema-stitching/stitch-directives-sdl.mdx similarity index 100% rename from website/docs/stitch-directives-sdl.md rename to website/docs/guides/schema-stitching/stitch-directives-sdl.mdx diff --git a/website/docs/stitch-schema-extensions.md b/website/docs/guides/schema-stitching/stitch-schema-extensions.mdx similarity index 100% rename from website/docs/stitch-schema-extensions.md rename to website/docs/guides/schema-stitching/stitch-schema-extensions.mdx diff --git a/website/docs/stitch-type-merging.md b/website/docs/guides/schema-stitching/stitch-type-merging.mdx similarity index 99% rename from website/docs/stitch-type-merging.md rename to website/docs/guides/schema-stitching/stitch-type-merging.mdx index 9602a10f478..102368503b4 100644 --- a/website/docs/stitch-type-merging.md +++ b/website/docs/guides/schema-stitching/stitch-type-merging.mdx @@ -175,7 +175,7 @@ This fabricated record fulfills the not-null requirement of the `posts:[Post]!` To better understand the flow of merged object calls, let's break down the [basic example](#basic-example) above: -![Schema Stitching flow](../static/img/stitching-flow.png) +![Schema Stitching flow](/assets/stitching-flow.png) 1. A request is submitted to the gateway schema that selects fields from multiple subschemas. 2. The gateway fetches the resource that was **explicitly** requested (`userById`), known as the _original object_. This subquery is filtered to match its subschema, and adds the `selectionSet` of other subschemas that must **implicitly** provide data for the request. diff --git a/website/docs/schema-wrapping.md b/website/docs/guides/schema-wrapping.mdx similarity index 100% rename from website/docs/schema-wrapping.md rename to website/docs/guides/schema-wrapping.mdx diff --git a/website/docs/server-setup.md b/website/docs/guides/server-setup.mdx similarity index 100% rename from website/docs/server-setup.md rename to website/docs/guides/server-setup.mdx diff --git a/website/docs/introduction.md b/website/docs/introduction.mdx similarity index 100% rename from website/docs/introduction.md rename to website/docs/introduction.mdx diff --git a/website/docs/legacy-schema-directives.md b/website/docs/legacy-schema-directives.md deleted file mode 100644 index 0bd464b614c..00000000000 --- a/website/docs/legacy-schema-directives.md +++ /dev/null @@ -1,714 +0,0 @@ ---- -id: legacy-schema-directives -title: Schema directives -description: Using and implementing custom directives to transform schema types, fields, and arguments ---- - -A _directive_ is an identifier preceded by a `@` character, optionally followed by a list of named arguments, which can appear after almost any form of syntax in the GraphQL query or schema languages. Here's an example from the [GraphQL draft specification](http://facebook.github.io/graphql/draft/#sec-Type-System.Directives) that illustrates several of these possibilities: - -```typescript -directive @deprecated( - reason: String = "No longer supported" -) on FIELD_DEFINITION | ENUM_VALUE - -type ExampleType { - newField: String - oldField: String @deprecated(reason: "Use `newField`.") -} -``` - -As you can see, the usage of `@deprecated(reason: ...)` _follows_ the field that it pertains to (`oldField`), though the syntax might remind you of "decorators" in other languages, which usually appear on the line above. Directives are typically _declared_ once, using the `directive @deprecated ... on ...` syntax, and then _used_ zero or more times throughout the schema document, using the `@deprecated(reason: ...)` syntax. - -The possible applications of directive syntax are numerous: enforcing access permissions, formatting date strings, auto-generating resolver functions for a particular backend API, marking strings for internationalization, synthesizing globally unique object identifiers, specifying caching behavior, skipping or including or deprecating fields, and just about anything else you can imagine. - -This document focuses on directives that appear in GraphQL _schemas_ (as opposed to queries) written in [Schema Definition Language](https://github.com/facebook/graphql/pull/90), or SDL for short. In the following sections, you will see how custom directives can be implemented and used to modify the structure and behavior of a GraphQL schema in ways that would not be possible using SDL syntax alone. - -## (At least) two strategies - -`graphql-tools` provides [a newer functional approach](/docs/schema-directives/) for directive-based schema modification. The remainder of this document describes the earlier class-based mechanism. We believe the newer approach is easier to reason about, but older class-based schema directives are still supported, as long as the in-place schema modification techniques they employ do not yield an invalid schema. - -## Using schema directives - -Most of this document is concerned with _implementing_ schema directives, and some of the examples are quite complicated. No matter how many tools and best practices you have at your disposal, it can be difficult to implement a non-trivial class-based schema directive in a reliable, reusable way. Exhaustive testing is essential, and using a typed language like TypeScript is recommended, because there are so many different schema types to worry about. - -However, the API we provide for _using_ a schema directive is extremely simple. Just import the implementation of the directive, then pass it to `makeExecutableSchema` via the `schemaDirectives` argument, which is an object that maps directive names to directive implementations: - -```js -import { makeExecutableSchema } from '@graphql-tools/schema'; -import { RenameDirective } from 'fake-rename-directive-package'; - -const typeDefs = ` -type Person @rename(to: "Human") { - name: String! - currentDateMinusDateOfBirth: Int @rename(to: "age") -}`; - -const schema = makeExecutableSchema({ - typeDefs, - schemaDirectives: { - rename: RenameDirective, - }, -}); -``` - -That's it. The implementation of `RenameDirective` takes care of everything else. If you understand what the directive is supposed to do to your schema, then you do not have to worry about how it works. - -Everything you read below addresses some aspect of how a directive like `@rename(to: ...)` could be implemented. If that's not something you care about right now, feel free to skip the rest of this document. When you need it, it will be here. - -## Implementing schema directives - -Since the GraphQL specification does not discuss any specific implementation strategy for directives, it's up to each GraphQL server framework to expose an API for implementing new directives. - -GraphQL Tools provides a convenient yet powerful tool for implementing directive syntax: the [`SchemaDirectiveVisitor`](https://github.com/ardatan/graphql-tools/blob/master/src/utils/SchemaDirectiveVisitor.ts) class. - -To implement a schema directive using `SchemaDirectiveVisitor`, simply create a subclass of `SchemaDirectiveVisitor` that overrides one or more of the following visitor methods: - -- `visitSchema(schema: GraphQLSchema)` -- `visitScalar(scalar: GraphQLScalarType)` -- `visitObject(object: GraphQLObjectType)` -- `visitFieldDefinition(field: GraphQLField, details: { objectType: GraphQLObjectType | GraphQLInterfaceType })` -- `visitArgumentDefinition(argument: GraphQLArgument, objectType: GraphQLObjectType | GraphQLInterfaceType })` -- `visitInterface(iface: GraphQLInterfaceType)` -- `visitUnion(union: GraphQLUnionType)` -- `visitEnum(type: GraphQLEnumType)` -- `visitEnumValue(value: GraphQLEnumValue, details: { enumType: GraphQLEnumType })` -- `visitInputObject(object: GraphQLInputObjectType)` -- `visitInputFieldDefinition(field: GraphQLInputField, details: { objectType: GraphQLInputObjectType })` - -By overriding methods like `visitObject`, a subclass of `SchemaDirectiveVisitor` expresses interest in certain schema types such as `GraphQLObjectType` (the first parameter type of `visitObject`). - -These method names correspond to all possible [locations](https://github.com/graphql/graphql-js/blob/a62eea88d5844a3bd9725c0f3c30950a78727f3e/src/language/directiveLocation.js#L22-L33) where a directive may be used in a schema. For example, the location `INPUT_FIELD_DEFINITION` is handled by `visitInputFieldDefinition`. - -Here is one possible implementation of the `@deprecated` directive we saw above: - -```typescript -import { SchemaDirectiveVisitor } from '@graphql-tools/utils'; -import { GraphQLField, GraphQLEnumValue } from 'graphql'; - -class DeprecatedDirective extends SchemaDirectiveVisitor { - public visitFieldDefinition(field: GraphQLField) { - field.isDeprecated = true; - field.deprecationReason = this.args.reason; - } - - public visitEnumValue(value: GraphQLEnumValue) { - value.isDeprecated = true; - value.deprecationReason = this.args.reason; - } -} -``` - -In order to apply this implementation to a schema that contains `@deprecated` directives, simply pass the `DeprecatedDirective` class to the `makeExecutableSchema` function via the `schemaDirectives` option: - -```typescript -import { makeExecutableSchema } from '@graphql-tools/schema'; - -const typeDefs = ` -type ExampleType { - newField: String - oldField: String @deprecated(reason: "Use \`newField\`.") -}`; - -const schema = makeExecutableSchema({ - typeDefs, - schemaDirectives: { - deprecated: DeprecatedDirective, - }, -}); -``` - -Alternatively, if you want to modify an existing schema object, you can use the `SchemaDirectiveVisitor.visitSchemaDirectives` interface directly: - -```typescript -import { SchemaDirectiveVisitor } from '@graphql-tools/utils'; - -SchemaDirectiveVisitor.visitSchemaDirectives(schema, { - deprecated: DeprecatedDirective, -}); -``` - -This syntax is especially useful for code-first schemas that wish to make use of directive implementations. For code-first schemas, directives are read from the `directives` key within the `extensions` field for each GraphQL entity, unless a different path is provided, as per below: - -```typescript -import { SchemaDirectiveVisitor } from '@graphql-tools/utils'; - -SchemaDirectiveVisitor.visitSchemaDirectives( - schema, - { - deprecated: DeprecatedDirective, - }, - undefined, - ['custom', 'path', 'to', 'directives', 'within', 'the', 'extensions', 'object'] -); -``` - -The second argument to `visitSchemaDirectives` refers to a shared context object that may be passed to `SchemaDirectiveVisitor` classes -- it is not often used, and can usually be safely set to undefined. - -See [this `graphql-js` issue](https://github.com/graphql/graphql-js/issues/1343) for more information on directives with code-first schemas. We follow the [Gatsby and graphql-compose convention](https://github.com/graphql/graphql-js/issues/1343#issuecomment-479877640) of reading directives from the `extensions` field, but allow customization as above. - -Note that a subclass of `SchemaDirectiveVisitor` may be instantiated multiple times to visit multiple different occurrences of the `@deprecated` directive. That's why you provide a class rather than an instance of that class. - -If for some reason you have a schema that uses another name for the `@deprecated` directive, but you want to use the same implementation, you can! The same `DeprecatedDirective` class can be passed with a different name, simply by changing its key in the `schemaDirectives` object passed to `makeExecutableSchema`. In other words, `SchemaDirectiveVisitor` implementations are effectively anonymous, so it's up to whoever uses them to assign names to them. - -## Examples - -To appreciate the range of possibilities enabled by `SchemaDirectiveVisitor`, let's examine a variety of practical examples. - -### Uppercasing strings - -Suppose you want to ensure a string-valued field is converted to uppercase. Though this use case is simple, it's a good example of a directive implementation that works by wrapping a field's `resolve` function: - -```js -import { defaultFieldResolver } from 'graphql'; -import { SchemaDirectiveVisitor } from '@graphql-tools/utils'; -import { makeExecutableSchema } from '@graphql-tools/schema'; - -const typeDefs = ` -directive @upper on FIELD_DEFINITION - -type Query { - hello: String @upper -}`; - -class UpperCaseDirective extends SchemaDirectiveVisitor { - visitFieldDefinition(field) { - const { resolve = defaultFieldResolver } = field; - field.resolve = async function (...args) { - const result = await resolve.apply(this, args); - if (typeof result === 'string') { - return result.toUpperCase(); - } - return result; - }; - } -} - -const schema = makeExecutableSchema({ - typeDefs, - schemaDirectives: { - upper: UpperCaseDirective, - upperCase: UpperCaseDirective, - }, -}); -``` - -Notice how easy it is to handle both `@upper` and `@upperCase` with the same `UpperCaseDirective` implementation. - -### Fetching data from a REST API - -Suppose you've defined an object type that corresponds to a [REST](https://en.wikipedia.org/wiki/Representational_state_transfer) resource, and you want to avoid implementing resolver functions for every field: - -```js -import { SchemaDirectiveVisitor } from '@graphql-tools/utils'; -import { makeExecutableSchema } from '@graphql-tools/schema'; - -const typeDefs = ` -directive @rest(url: String) on FIELD_DEFINITION - -type Query { - people: [Person] @rest(url: "/api/v1/people") -}`; - -class RestDirective extends SchemaDirectiveVisitor { - public visitFieldDefinition(field) { - const { url } = this.args; - field.resolve = () => fetch(url); - } -} - -const schema = makeExecutableSchema({ - typeDefs, - schemaDirectives: { - rest: RestDirective - } -}); -``` - -There are many more issues to consider when implementing a real GraphQL wrapper over a REST endpoint (such as how to do caching or pagination), but this example demonstrates the basic structure. - -### Formatting date strings - -Suppose your resolver returns a `Date` object but you want to return a formatted string to the client: - -```js -import { SchemaDirectiveVisitor } from '@graphql-tools/utils'; -import { makeExecutableSchema } from '@graphql-tools/schema'; - -const typeDefs = ` -directive @date(format: String) on FIELD_DEFINITION - -scalar Date - -type Post { - published: Date @date(format: "mmmm d, yyyy") -}`; - -class DateFormatDirective extends SchemaDirectiveVisitor { - visitFieldDefinition(field) { - const { resolve = defaultFieldResolver } = field; - const { format } = this.args; - field.resolve = async function (...args) { - const date = await resolve.apply(this, args); - return require('dateformat')(date, format); - }; - // The formatted Date becomes a String, so the field type must change: - field.type = GraphQLString; - } -} - -const schema = makeExecutableSchema({ - typeDefs, - schemaDirectives: { - date: DateFormatDirective, - }, -}); -``` - -Of course, it would be even better if the schema author did not have to decide on a specific `Date` format, but could instead leave that decision to the client. To make this work, the directive just needs to add an additional argument to the field: - -```js -import { SchemaDirectiveVisitor } from '@graphql-tools/utils'; -import { makeExecutableSchema } from '@graphql-tools/schema'; -import formatDate from "dateformat"; -import { defaultFieldResolver, GraphQLString } from "graphql"; - -const typeDefs = ` -directive @date( - defaultFormat: String = "mmmm d, yyyy" -) on FIELD_DEFINITION - -scalar Date - -type Query { - today: Date @date -}`; - -class FormattableDateDirective extends SchemaDirectiveVisitor { - public visitFieldDefinition(field) { - const { resolve = defaultFieldResolver } = field; - const { defaultFormat } = this.args; - - field.args.push({ - name: 'format', - type: GraphQLString - }); - - field.resolve = async function ( - source, - { format, ...otherArgs }, - context, - info, - ) { - const date = await resolve.call(this, source, otherArgs, context, info); - // If a format argument was not provided, default to the optional - // defaultFormat argument taken by the @date directive: - return formatDate(date, format || defaultFormat); - }; - - field.type = GraphQLString; - } -} - -const schema = makeExecutableSchema({ - typeDefs, - schemaDirectives: { - date: FormattableDateDirective - } -}); -``` - -Now the client can specify a desired `format` argument when requesting the `Query.today` field, or omit the argument to use the `defaultFormat` string specified in the schema: - -```js -import { graphql } from 'graphql'; - -graphql( - schema, - ` - query { - today - } - ` -).then(result => { - // Logs with the default "mmmm d, yyyy" format: - console.log(result.data.today); -}); - -graphql( - schema, - ` - query { - today(format: "d mmm yyyy") - } - ` -).then(result => { - // Logs with the requested "d mmm yyyy" format: - console.log(result.data.today); -}); -``` - -### Marking strings for internationalization - -Suppose you have a function called `translate` that takes a string, a path identifying that string's role in your application, and a target locale for the translation. - -Here's how you might make sure `translate` is used to localize the `greeting` field of a `Query` type: - -```js -import { SchemaDirectiveVisitor } from '@graphql-tools/utils'; -import { makeExecutableSchema } from '@graphql-tools/schema'; - -const typeDefs = ` -directive @intl on FIELD_DEFINITION - -type Query { - greeting: String @intl -}`; - -class IntlDirective extends SchemaDirectiveVisitor { - visitFieldDefinition(field, details) { - const { resolve = defaultFieldResolver } = field; - field.resolve = async function (...args) { - const context = args[2]; - const defaultText = await resolve.apply(this, args); - // In this example, path would be ["Query", "greeting"]: - const path = [details.objectType.name, field.name]; - return translate(defaultText, path, context.locale); - }; - } -} - -const schema = makeExecutableSchema({ - typeDefs, - schemaDirectives: { - intl: IntlDirective, - }, -}); -``` - -GraphQL is great for internationalization, since a GraphQL server can access unlimited translation data, and clients can simply ask for the translations they need. - -### Enforcing access permissions - -Imagine a hypothetical `@auth` directive that takes an argument `requires` of type `Role`, which defaults to `ADMIN`. This `@auth` directive can appear on an `OBJECT` like `User` to set default access permissions for all `User` fields, as well as appearing on individual fields, to enforce field-specific `@auth` restrictions: - -```graphql -directive @auth(requires: Role = ADMIN) on OBJECT | FIELD_DEFINITION - -enum Role { - ADMIN - REVIEWER - USER - UNKNOWN -} - -type User @auth(requires: USER) { - name: String - banned: Boolean @auth(requires: ADMIN) - canPost: Boolean @auth(requires: REVIEWER) -} -``` - -What makes this example tricky is that the `OBJECT` version of the directive needs to wrap all fields of the object, even though some of those fields may be individually wrapped by `@auth` directives at the `FIELD_DEFINITION` level, and we would prefer not to rewrap resolvers if we can help it: - -```js -import { SchemaDirectiveVisitor } from '@graphql-tools/utils'; -import { makeExecutableSchema } from '@graphql-tools/schema'; - -class AuthDirective extends SchemaDirectiveVisitor { - visitObject(type) { - this.ensureFieldsWrapped(type); - type._requiredAuthRole = this.args.requires; - } - // Visitor methods for nested types like fields and arguments - // also receive a details object that provides information about - // the parent and grandparent types. - visitFieldDefinition(field, details) { - this.ensureFieldsWrapped(details.objectType); - field._requiredAuthRole = this.args.requires; - } - - ensureFieldsWrapped(objectType) { - // Mark the GraphQLObjectType object to avoid re-wrapping: - if (objectType._authFieldsWrapped) return; - objectType._authFieldsWrapped = true; - - const fields = objectType.getFields(); - - Object.keys(fields).forEach(fieldName => { - const field = fields[fieldName]; - const { resolve = defaultFieldResolver } = field; - field.resolve = async function (...args) { - // Get the required Role from the field first, falling back - // to the objectType if no Role is required by the field: - const requiredRole = field._requiredAuthRole || objectType._requiredAuthRole; - - if (!requiredRole) { - return resolve.apply(this, args); - } - - const context = args[2]; - const user = await getUser(context.headers.authToken); - if (!user.hasRole(requiredRole)) { - throw new Error('not authorized'); - } - - return resolve.apply(this, args); - }; - }); - } -} - -const schema = makeExecutableSchema({ - typeDefs, - schemaDirectives: { - auth: AuthDirective, - authorized: AuthDirective, - authenticated: AuthDirective, - }, -}); -``` - -One drawback of this approach is that it does not guarantee fields will be wrapped if they are added to the schema after `AuthDirective` is applied, and the whole `getUser(context.headers.authToken)` is a made-up API that would need to be fleshed out. In other words, we’ve glossed over some of the details that would be required for a production-ready implementation of this directive, though we hope the basic structure shown here inspires you to find clever solutions to the remaining problems. - -### Enforcing value restrictions - -Suppose you want to enforce a maximum length for a string-valued field: - -```js -import { SchemaDirectiveVisitor } from '@graphql-tools/utils'; -import { makeExecutableSchema } from '@graphql-tools/schema'; -import { GraphQLScalarType, isNonNullType, isScalarType, GraphQLNonNull } from 'graphql'; - -const typeDefs = ` -directive @length(max: Int) on FIELD_DEFINITION | INPUT_FIELD_DEFINITION - -type Query { - books: [Book] -} - -type Book { - title: String @length(max: 50) -} - -type Mutation { - createBook(book: BookInput): Book -} - -input BookInput { - title: String! @length(max: 50) -}`; - -class LengthDirective extends SchemaDirectiveVisitor { - visitInputFieldDefinition(field) { - this.wrapType(field); - } - - visitFieldDefinition(field) { - this.wrapType(field); - } - - // Replace field.type with a custom GraphQLScalarType that enforces the - // length restriction. - wrapType(field) { - if (isNonNullType(field.type) && isScalarType(field.type.ofType)) { - field.type = new GraphQLNonNull(new LimitedLengthType(field.type.ofType, this.args.max)); - } else if (isScalarType(field.type)) { - field.type = new LimitedLengthType(field.type, this.args.max); - } else { - throw new Error(`Not a scalar type: ${field.type}`); - } - } -} - -class LimitedLengthType extends GraphQLScalarType { - constructor(type, maxLength) { - super({ - name: `LengthAtMost${maxLength}`, - - // For more information about GraphQLScalar type (de)serialization, - // see the graphql-js implementation: - // https://github.com/graphql/graphql-js/blob/31ae8a8e8312/src/type/definition.js#L425-L446 - - serialize(value) { - value = type.serialize(value); - assert.isAtMost(value.length, maxLength); - return value; - }, - - parseValue(value) { - return type.parseValue(value); - }, - - parseLiteral(ast) { - return type.parseLiteral(ast); - }, - }); - } -} - -const schema = makeExecutableSchema({ - typeDefs, - schemaDirectives: { - length: LengthDirective, - }, -}); -``` - -### Synthesizing unique IDs - -Suppose your database uses incrementing IDs for each resource type, so IDs are not unique across all resource types. Here’s how you might synthesize a field called `uid` that combines the object type with various field values to produce an ID that’s unique across your schema: - -```js -import { GraphQLID } from 'graphql'; -import { createHash } from 'crypto'; -import { SchemaDirectiveVisitor } from '@graphql-tools/utils'; -import { makeExecutableSchema } from '@graphql-tools/schema'; - -const typeDefs = ` -directive @uniqueID( - # The name of the new ID field, "uid" by default: - name: String = "uid" - - # Which fields to include in the new ID: - from: [String] = ["id"] -) on OBJECT - -# Since this type just uses the default values of name and from, -# we don't have to pass any arguments to the directive: -type Location @uniqueID { - id: Int - address: String -} - -# This type uses both the person's name and the personID field, -# in addition to the "Person" type name, to construct the ID: -type Person @uniqueID(from: ["name", "personID"]) { - personID: Int - name: String -}`; - -class UniqueIdDirective extends SchemaDirectiveVisitor { - visitObject(type) { - const { name, from } = this.args; - const fields = type.getFields(); - if (name in fields) { - throw new Error(`Conflicting field name ${name}`); - } - fields[name] = { - name, - type: GraphQLID, - description: 'Unique ID', - args: [], - resolve(object) { - const hash = createHash('sha1'); - hash.update(type.name); - from.forEach(fieldName => { - hash.update(String(object[fieldName])); - }); - return hash.digest('hex'); - }, - }; - } -} - -const schema = makeExecutableSchema({ - typeDefs, - schemaDirectives: { - uniqueID: UniqueIdDirective, - }, -}); -``` - -## Declaring schema directives - -While the above examples should be sufficient to implement any `@directive` used in your schema, SDL syntax also supports declaring the names, argument types, default argument values, and permissible locations of any available directives: - -```js -directive @auth( - requires: Role = ADMIN, -) on OBJECT | FIELD_DEFINITION - -enum Role { - ADMIN - REVIEWER - USER - UNKNOWN -} - -type User @auth(requires: USER) { - name: String - banned: Boolean @auth(requires: ADMIN) - canPost: Boolean @auth(requires: REVIEWER) -} -``` - -This hypothetical `@auth` directive takes an argument named `requires` of type `Role`, which defaults to `ADMIN` if `@auth` is used without passing an explicit `requires` argument. The `@auth` directive can appear on an `OBJECT` like `User` to set a default access control for all `User` fields, and also on individual fields, to enforce field-specific `@auth` restrictions. - -Enforcing the requirements of the declaration is something a `SchemaDirectiveVisitor` implementation could do itself, in theory, but the SDL syntax is easier to read and write, and provides value even if you're not using the `SchemaDirectiveVisitor` abstraction. - -However, if you're implementing a reusable `SchemaDirectiveVisitor` for public consumption, you will probably not be the person writing the SDL syntax, so you may not have control over which directives the schema author decides to declare, and how. That's why a well-implemented, reusable `SchemaDirectiveVisitor` should consider overriding the `getDirectiveDeclaration` method: - -```typescript -import { SchemaDirectiveVisitor } from '@graphql-tools/utils'; -import { makeExecutableSchema } from '@graphql-tools/schema'; -import { - DirectiveLocation, - GraphQLDirective, - GraphQLEnumType, -} from "graphql"; - -class AuthDirective extends SchemaDirectiveVisitor { - public visitObject(object: GraphQLObjectType) {...} - public visitFieldDefinition(field: GraphQLField) {...} - - public static getDirectiveDeclaration( - directiveName: string, - schema: GraphQLSchema, - ): GraphQLDirective { - const previousDirective = schema.getDirective(directiveName); - if (previousDirective) { - // If a previous directive declaration exists in the schema, it may be - // better to modify it than to return a new GraphQLDirective object. - previousDirective.args.forEach(arg => { - if (arg.name === 'requires') { - // Lower the default minimum Role from ADMIN to REVIEWER. - arg.defaultValue = 'REVIEWER'; - } - }); - - return previousDirective; - } - - // If a previous directive with this name was not found in the schema, - // there are several options: - // - // 1. Construct a new GraphQLDirective (see below). - // 2. Throw an exception to force the client to declare the directive. - // 3. Return null, and forget about declaring this directive. - // - // All three are valid options, since the visitor will still work without - // any declared directives. In fact, unless you're publishing a directive - // implementation for public consumption, you can probably just ignore - // getDirectiveDeclaration altogether. - - return new GraphQLDirective({ - name: directiveName, - locations: [ - DirectiveLocation.OBJECT, - DirectiveLocation.FIELD_DEFINITION, - ], - args: { - requires: { - // Having the schema available here is important for obtaining - // references to existing type objects, such as the Role enum. - type: (schema.getType('Role') as GraphQLEnumType), - // Set the default minimum Role to REVIEWER. - defaultValue: 'REVIEWER', - } - }] - }); - } -} -``` - -Since the `getDirectiveDeclaration` method receives not only the name of the directive but also the `GraphQLSchema` object, it can modify and/or reuse previous declarations found in the schema, as an alternative to returning a totally new `GraphQLDirective` object. Either way, if the visitor returns a non-null `GraphQLDirective` from `getDirectiveDeclaration`, that declaration will be used to check arguments and permissible locations. diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js deleted file mode 100644 index 7b9f24322f0..00000000000 --- a/website/docusaurus.config.js +++ /dev/null @@ -1,106 +0,0 @@ -/* eslint-disable import/no-commonjs */ -/* eslint-disable import/unambiguous */ -module.exports = { - title: 'GraphQL Tools', - tagline: 'A set of utilities to build your GraphQL schema in a concise, faster and powerful way', - url: 'https://graphql-tools.com', - baseUrl: '/', - favicon: 'img/favicon.ico', - organizationName: 'ardatan', // Usually your GitHub org/user name. - projectName: 'graphql-tools', // Usually your repo name. - themeConfig: { - colorMode: { - defaultMode: 'dark', - disableSwitch: true, - }, - navbar: { - // title: 'GraphQL Tools', - logo: { - alt: 'GraphQL Tools Logo', - src: 'img/logo.png', - }, - items: [ - { - to: 'docs/introduction', - activeBasePath: 'docs', - label: 'API & Documentation', - position: 'right', - }, - { - href: 'https://github.com/ardatan/graphql-tools', - label: 'GitHub', - position: 'right', - }, - { - href: 'https://the-guild.dev/contact', - label: 'Contact Us', - position: 'right', - }, - ], - }, - footer: { - style: 'dark', - links: [ - /* { - title: 'Docs', - items: [ - { - label: 'Style Guide', - to: 'docs/doc1' - }, - { - label: 'Second Doc', - to: 'docs/doc2' - } - ] - }, */ - { - title: 'Community', - items: [ - { - label: 'Discord', - href: 'http://bit.ly/guild-chat', - }, - { - label: 'Stack Overflow', - href: 'https://stackoverflow.com/questions/tagged/graphql-tools', - }, - ], - }, - { - title: 'Social', - items: [ - { - label: 'GitHub', - href: 'https://github.com/Urigo/graphql-tools/', - }, - { - label: 'Twitter', - href: 'https://twitter.com/TheGuildDev', - }, - ], - }, - ], - copyright: `Copyright © ${new Date().getFullYear()} The Guild, Inc. Built with Docusaurus.`, - }, - }, - scripts: [ - 'https://the-guild.dev/static/crisp.js' - ], - presets: [ - [ - '@docusaurus/preset-classic', - { - docs: { - sidebarPath: require.resolve('./sidebars.js'), - editUrl: 'https://github.com/ardatan/graphql-tools/edit/master/website/', - }, - theme: { - customCss: require.resolve('./src/css/custom.css'), - }, - }, - ], - ], - onBrokenLinks: 'warn', - onBrokenMarkdownLinks: 'warn', -}; diff --git a/website/next-env.d.ts b/website/next-env.d.ts new file mode 100644 index 00000000000..c6643fda12f --- /dev/null +++ b/website/next-env.d.ts @@ -0,0 +1,3 @@ +/// +/// +/// diff --git a/website/next-i18next.config.js b/website/next-i18next.config.js new file mode 100644 index 00000000000..7c7e427740c --- /dev/null +++ b/website/next-i18next.config.js @@ -0,0 +1,6 @@ +module.exports = { + i18n: { + defaultLocale: 'en', + locales: ['en'], + }, +}; diff --git a/website/next.config.js b/website/next.config.js new file mode 100644 index 00000000000..d8f90fb3bdd --- /dev/null +++ b/website/next.config.js @@ -0,0 +1,25 @@ +const { register } = require('esbuild-register/dist/node'); + +register({ + extensions: ['.ts', '.tsx'], +}); + +const { i18n } = require('./next-i18next.config'); + +const { withGuildDocs } = require('@guild-docs/server'); + +const { getRoutes } = require('./routes.ts'); + +const withBundleAnalyzer = require('@next/bundle-analyzer')({ + enabled: process.env.ANALYZE === 'true', +}); + +module.exports = withBundleAnalyzer( + withGuildDocs({ + i18n, + getRoutes, + eslint: { + ignoreDuringBuilds: true, + }, + }) +); diff --git a/website/package.json b/website/package.json index fd79177780a..5b5d73f2653 100644 --- a/website/package.json +++ b/website/package.json @@ -3,30 +3,51 @@ "version": "6.2.3", "private": true, "scripts": { - "start": "docusaurus start", - "build": "docusaurus build", - "swizzle": "docusaurus swizzle", - "deploy": "docusaurus deploy" + "build": "next build", + "dev": "concurrently -r \"next-remote-watch ./docs ./src/pages/_app.tsx ./src/pages/_document.tsx\" \"wait-on -s 1 http://localhost:3000 && open-cli http://localhost:3000\"", + "next": "next", + "start": "next start", + "analyze": "cross-env ANALYZE=true next build" }, - "dependencies": { - "@docusaurus/core": "2.0.0-beta.ff31de0ff", - "@docusaurus/preset-classic": "2.0.0-beta.ff31de0ff", - "classnames": "2.3.1", - "react": "17.0.2", - "react-dom": "17.0.2", - "styled-components": "5.3.0", - "the-guild-components": "1.2.4" + "pnpm": { "overrides": { "esbuild": "^0.12.8" } }, + "resolutions": { "esbuild": "^0.12.8" }, + "devDependencies": { + "@next/bundle-analyzer": "^11.0.1", + "@types/concurrently": "^6.2.0", + "@types/mdx-js__react": "^1.5.3", + "@types/node": "^15.12.4", + "@types/react": "^17.0.11", + "@types/react-dom": "^17.0.8", + "concurrently": "^6.2.0", + "cross-env": "^7.0.3", + "esbuild": "^0.12.9", + "esbuild-register": "^2.6.0", + "next-remote-watch": "^1.0.0", + "open-cli": "^7.0.0", + "typescript": "^4.3.4", + "wait-on": "^5.3.0" }, - "browserslist": { - "production": [ - ">0.2%", - "not dead", - "not op_mini all" - ], - "development": [ - "last 1 chrome version", - "last 1 firefox version", - "last 1 safari version" - ] + "dependencies": { + "@chakra-ui/icons": "^1.0.13", + "@chakra-ui/react": "^1.6.4", + "@chakra-ui/theme-tools": "^1.1.7", + "@chakra-ui/utils": "^1.8.0", + "@emotion/react": "^11.4.0", + "@emotion/styled": "^11.3.0", + "@guild-docs/client": "^0.2.14", + "@guild-docs/server": "^0.2.13", + "@mdx-js/react": "^1.6.22", + "@theguild/components": "1.4.3", + "framer-motion": "^4.1.17", + "next": "^11.0.1", + "next-i18next": "^8.5.1", + "next-seo": "^4.26.0", + "prism-themes": "^1.7.0", + "react": "^17.0.2", + "react-dom": "^17.0.2", + "react-icons": "^4.2.0", + "react-use": "^17.2.4", + "remark-admonitions": "^1.2.1", + "remark-prism": "^1.3.6" } } diff --git a/website/static/CNAME b/website/public/CNAME similarity index 100% rename from website/static/CNAME rename to website/public/CNAME diff --git a/website/static/img/distributed-graph.png b/website/public/assets/distributed-graph.png similarity index 100% rename from website/static/img/distributed-graph.png rename to website/public/assets/distributed-graph.png diff --git a/website/static/img/graphiql-test.png b/website/public/assets/graphiql-test.png similarity index 100% rename from website/static/img/graphiql-test.png rename to website/public/assets/graphiql-test.png diff --git a/website/static/img/stitching-flow.png b/website/public/assets/stitching-flow.png similarity index 100% rename from website/static/img/stitching-flow.png rename to website/public/assets/stitching-flow.png diff --git a/website/static/img/favicon.ico b/website/public/favicon.ico similarity index 100% rename from website/static/img/favicon.ico rename to website/public/favicon.ico diff --git a/website/public/locales/en/common.json b/website/public/locales/en/common.json new file mode 100644 index 00000000000..1dd64c715b3 --- /dev/null +++ b/website/public/locales/en/common.json @@ -0,0 +1,3 @@ +{ + "greeting": "Hello!" +} diff --git a/website/public/style.css b/website/public/style.css new file mode 100644 index 00000000000..5afed553ead --- /dev/null +++ b/website/public/style.css @@ -0,0 +1,15 @@ +code[class*='language-'], +pre[class*='language-'] { + white-space: pre-wrap !important; + word-break: break-word !important; +} + +code, +code * { + font-family: 'SF Mono', 'Source Code Pro', Menlo, monospace; +} + +article { + width: 100%; + overflow-x: auto; +} diff --git a/website/routes.ts b/website/routes.ts new file mode 100644 index 00000000000..ea56013faac --- /dev/null +++ b/website/routes.ts @@ -0,0 +1,46 @@ +import { IRoutes, GenerateRoutes } from '@guild-docs/server'; +import apiSidebar from './api-sidebar.json'; + +export function getRoutes(): IRoutes { + const Routes: IRoutes = { + _: { + docs: { + $routes: ['introduction'], + _: { + guides: { + $name: 'Guides', + $routes: [ + 'generate-schema', + 'resolvers', + 'resolvers-composition', + 'scalars', + 'mocking', + 'connectors', + 'schema-directives', + 'schema-delegation', + 'remote-schemas', + 'schema-wrapping', + 'schema-merging', + '$schema-stitching', + 'server-setup', + 'schema-loading', + 'documents-loading', + 'graphql-tag-pluck', + 'relay-operation-optimizer', + '$migration', + ], + }, + api: apiSidebar, + }, + }, + }, + }; + GenerateRoutes({ + Routes, + folderPattern: 'docs', + basePath: 'docs', + basePathLabel: 'Documentation', + }); + + return Routes; +} diff --git a/website/sidebars.js b/website/sidebars.js deleted file mode 100644 index 10f25f94a8d..00000000000 --- a/website/sidebars.js +++ /dev/null @@ -1,46 +0,0 @@ -module.exports = { - "someSidebar": [ - "introduction", - { - "Guides": [ - "generate-schema", - "resolvers", - "resolvers-composition", - "scalars", - "mocking", - "connectors", - "schema-directives", - "directive-resolvers", - "schema-delegation", - "remote-schemas", - "schema-wrapping", - "schema-merging", - { - "Schema stitching": [ - "stitch-combining-schemas", - "stitch-type-merging", - "stitch-directives-sdl", - "stitch-schema-extensions", - "stitch-api" - ] - }, - "server-setup", - "schema-loading", - "documents-loading", - "graphql-tag-pluck", - "relay-operation-optimizer", - { - "Migration": [ - "migration-from-tools", - "migration-from-toolkit", - "migration-from-merge-graphql-schemas", - "migration-from-import" - ] - } - ] - }, - { - "API Reference": require('./api-sidebar.json') - } - ] -} diff --git a/website/src/css/custom.css b/website/src/css/custom.css deleted file mode 100644 index 99c169bb11e..00000000000 --- a/website/src/css/custom.css +++ /dev/null @@ -1,55 +0,0 @@ -/* stylelint-disable docusaurus/copyright-header */ -/** - * Any CSS included here will be global. The classic template - * bundles Infima by default. Infima is a CSS framework designed to - * work well for content-centric websites. - */ - -/* You can override the default Infima variables here. */ -:root { - --ifm-color-primary: #5e80f0; - --ifm-color-primary-dark: #3f68ed; - --ifm-color-primary-darker: #305cec; - --ifm-color-primary-darkest: #1441d6; - --ifm-color-primary-light: #7d98f3; - --ifm-color-primary-lighter: #8ca4f4; - --ifm-color-primary-lightest: #bac8f9; - --ifm-code-font-size: 95%; -} - -.docusaurus-highlight-code-line { - background-color: rgb(72, 77, 91); - display: block; - margin: 0 calc(-1 * var(--ifm-pre-padding)); - padding: 0 var(--ifm-pre-padding); -} - -.navbar__logo { - height: 64px !important; -} - -.menu button { - margin-bottom: 70px; -} - -.video-player { - position: relative; - max-width: 600px; - margin: 0 auto 2em; -} - -.video-player:before { - content: ''; - display: block; - height: 0; - padding-top: 56.25%; - width: 100%; -} - -.video-player iframe { - width: 100%; - height: 100%; - position: absolute; - left: 0; - top: 0; -} diff --git a/website/src/pages/_app.tsx b/website/src/pages/_app.tsx new file mode 100644 index 00000000000..f43d3f9b20c --- /dev/null +++ b/website/src/pages/_app.tsx @@ -0,0 +1,175 @@ +import 'remark-admonitions/styles/infima.css'; +import 'prism-themes/themes/prism-atom-dark.css'; +import '../../public/style.css'; + +import { appWithTranslation } from 'next-i18next'; + +import { extendTheme, theme as chakraTheme } from '@chakra-ui/react'; +import { mode } from '@chakra-ui/theme-tools'; +import { ExtendComponents, handlePushRoute, CombinedThemeProvider, DocsPage, AppSeoProps } from '@guild-docs/client'; +import { Header, Subheader, FooterExtended } from '@theguild/components'; + +import type { AppProps } from 'next/app'; + +ExtendComponents({ + HelloWorld() { + return

Hello World!

; + }, +}); + +const styles: typeof chakraTheme['styles'] = { + global: props => ({ + body: { + bg: mode('white', 'gray.850')(props), + }, + }), +}; + +const theme = extendTheme({ + colors: { + gray: { + 50: '#fafafa', + 100: '#f5f5f5', + 200: '#e5e5e5', + 300: '#d4d4d4', + 400: '#a3a3a3', + 500: '#737373', + 600: '#525252', + 700: '#404040', + 800: '#262626', + 850: '#1b1b1b', + 900: '#171717', + }, + }, + fonts: { + heading: '"Poppins", sans-serif', + body: '"Poppins", sans-serif', + }, + config: { + initialColorMode: 'light', + useSystemColorMode: false, + }, + styles, +}); + +const accentColor = '#184BE6'; + +const serializedMdx = process.env.SERIALIZED_MDX_ROUTES; +const mdxRoutes = { data: serializedMdx && JSON.parse(serializedMdx) }; + +function AppContent(appProps: AppProps) { + const { Component, pageProps, router } = appProps; + const isDocs = router.asPath.startsWith('/docs'); + + return ( + <> +
+ handlePushRoute('/', e), + }} + links={[ + { + children: 'Home', + title: 'Visit our Homepage', + href: '/', + onClick: e => handlePushRoute('/', e), + }, + { + children: 'API & Doc', + title: 'Learn more about GraphQL Tools', + href: '/docs', + onClick: e => handlePushRoute('/docs/introduction', e), + }, + { + children: 'Github', + title: 'See our Github profile', + href: 'https://github.com/ardatan/graphql-tools', + target: '_blank', + rel: 'noopener noreferrer', + }, + ]} + cta={{ + children: 'Get Started', + title: 'Begin your journey with GraphQL Tools', + href: '/docs/introduction', + onClick: e => handlePushRoute('/docs/introduction', e), + }} + /> + {isDocs ? ( + + ) : ( + + )} + handlePushRoute('/docs/introduction', e), + }, + { + children: 'Guides', + title: 'Read about the Guides', + href: '/docs/guides/generate-schema', + onClick: e => handlePushRoute('/docs/guides/generate-schema', e), + }, + { + children: 'Modules (API)', + title: 'Read about the Modules', + href: '/docs/api/modules/batch_delegate_src', + onClick: e => handlePushRoute('/docs/api/modules/batch_delegate_src', e), + }, + { + children: 'Classes (API)', + title: 'Read about the Classes', + href: '/docs/api/classes/delegate_src.addargumentsasvariables', + onClick: e => handlePushRoute('/docs/api/classes/delegate_src.addargumentsasvariables', e), + }, + { + children: 'Interfaces (API)', + title: 'Read about the Interfaces', + href: '/docs/api/interfaces/loaders_apollo_engine_src.apolloengineoptions', + onClick: e => handlePushRoute('/docs/api/interfaces/loaders_apollo_engine_src.apolloengineoptions', e), + }, + { + children: 'Enums (API)', + title: 'Read about the Enums', + href: '/docs/api/enums/merge_src.compareval', + onClick: e => handlePushRoute('/docs/api/enums/merge_src.compareval', e), + }, + ]} + /> + + ); +} + +const AppContentWrapper = appWithTranslation(function TranslatedApp(appProps) { + return ; +}); + +const defaultSeo: AppSeoProps = { + title: 'GraphQL Tools', + description: 'A set of utilities for faster GraphQL development', + logo: { + url: 'https://the-guild.dev/static/shared-logos/products/tools.svg', + width: 54, + height: 54, + }, +}; + +export default function App(appProps: AppProps) { + return ( + + + + ); +} diff --git a/website/src/pages/_document.tsx b/website/src/pages/_document.tsx new file mode 100644 index 00000000000..bf9578666dd --- /dev/null +++ b/website/src/pages/_document.tsx @@ -0,0 +1,22 @@ +import Document, { Head, Html, Main, NextScript } from 'next/document'; + +import { ColorModeScript } from '@chakra-ui/react'; + +export default class MyDocument extends Document { + render() { + return ( + + + + + + + + +
+ + + + ); + } +} diff --git a/website/src/pages/docs/[[...slug]].tsx b/website/src/pages/docs/[[...slug]].tsx new file mode 100644 index 00000000000..4a731c95554 --- /dev/null +++ b/website/src/pages/docs/[[...slug]].tsx @@ -0,0 +1,37 @@ +import Head from 'next/head'; + +import { DocsContent, DocsTOC, MDXPage } from '@guild-docs/client'; +import { MDXPaths, MDXProps } from '@guild-docs/server'; + +import { getRoutes } from '../../../routes'; + +import type { GetStaticPaths, GetStaticProps } from 'next'; + +export default MDXPage(function PostPage({ content, TOC, MetaHead, BottomNavigation }) { + return ( + <> + {MetaHead} + {content} + + + + + + ); +}); + +export const getStaticProps: GetStaticProps = ctx => { + return MDXProps( + ({ readMarkdownFile, getArrayParam }) => { + return readMarkdownFile('docs/', getArrayParam('slug')); + }, + ctx, + { + getRoutes, + } + ); +}; + +export const getStaticPaths: GetStaticPaths = ctx => { + return MDXPaths('docs', { ctx }); +}; diff --git a/website/src/pages/index.js b/website/src/pages/index.js deleted file mode 100644 index cc55088bcb8..00000000000 --- a/website/src/pages/index.js +++ /dev/null @@ -1,96 +0,0 @@ -import React from 'react'; -import classnames from 'classnames'; -import Layout from '@theme/Layout'; -import Link from '@docusaurus/Link'; -import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; -import useBaseUrl from '@docusaurus/useBaseUrl'; -import styles from './styles.module.css'; - -const features = [ - { - title: <>The GraphQL-first philosophy, - imageUrl: 'img/graphql.svg', - description: ( - <> - Use the GraphQL schema definition language to generate a schema with full support for resolvers, interfaces, unions, and custom scalars. The schema produced is completely compatible with GraphQL.js. - - ), - }, - { - title: <>Mock your GraphQL API, - imageUrl: 'img/flask.svg', - description: ( - <> - With GraphQL Tools, you can mock your GraphQL API with fine-grained per-type mocking for fast prototyping without any datasources. - - ), - }, - { - title: <>Stitch multiple GraphQL Schemas, - imageUrl: 'img/needle.svg', - description: ( - <> - Automatically stitch multiple schemas together into one larger API in a simple, fast and powerful way - - ), - }, -]; - -function Feature({imageUrl, title, description}) { - const imgUrl = useBaseUrl(imageUrl); - return ( -
- {imgUrl && ( -
- {title} -
- )} -

{title}

-

{description}

-
- ); -} - -function Home() { - const context = useDocusaurusContext(); - const {siteConfig = {}} = context; - return ( - -
- {/*

{siteConfig.title}

-

{siteConfig.tagline}

*/} - - - - -
- - Get Started - -
-
-
- {features && features.length && ( -
-
-
- {features.map((props, idx) => ( - - ))} -
-
-
- )} -
-
- ); -} - -export default Home; diff --git a/website/src/pages/index.tsx b/website/src/pages/index.tsx new file mode 100644 index 00000000000..91557e5df63 --- /dev/null +++ b/website/src/pages/index.tsx @@ -0,0 +1,43 @@ +import { HeroGradient, InfoList } from '@theguild/components'; + +import { handlePushRoute } from '@guild-docs/client'; + +export default function Index() { + return ( + <> + handlePushRoute('/docs/introduction', e), + }} + version="v 7.0.5" + colors={['#000246', '#184BE6']} + /> + + + + ); +} diff --git a/website/src/pages/styles.module.css b/website/src/pages/styles.module.css deleted file mode 100644 index d24690c20cc..00000000000 --- a/website/src/pages/styles.module.css +++ /dev/null @@ -1,89 +0,0 @@ -/* stylelint-disable docusaurus/copyright-header */ -/** - * CSS files with the .module.css suffix will be treated as CSS modules - * and scoped locally. - */ - -.heroBanner { - /*padding: 4rem 0;*/ - padding: 0; - padding-bottom: 1rem; - text-align: center; - position: relative; - overflow: hidden; - background-color: #030303 !important; - display: flex; - flex-direction: column; - justify-content: center; -} - -.heroImage { - width: 100%; - max-width: 1218px; - margin-bottom: -110px; - -webkit-box-reflect: right; -} - -@media screen and (max-width: 966px) { - .heroBanner { - padding: 2rem; - } - .heroImage { - margin-bottom: 1rem; - } -} - -.npmBadge { - margin-bottom: 6px !important; - z-index: 1; -} - -.buttons { - display: flex; - align-items: center; - justify-content: center; - z-index: 1; -} - -.features { - display: flex; - align-items: center; - padding: 2rem 0; - width: 100%; -} - -.featureImage { - height: 100px; - width: 100px; -} - -.featureTitle { - text-align: center; -} - -.featureContent { - text-align: center; -} - -.getStarted { - cursor: pointer; - border: 1px solid var(--ifm-link-color); - border-radius: 3px; - color: var(--ifm-link-color) !important; - display: inline-block; - font-size: 14px; - font-weight: 400; - line-height: 1.2em; - padding: 10px; - text-decoration: none !important; - text-transform: uppercase; - transition: background 0.3s, color 0.3s; - margin: 5px; - background: transparent; -} - -.getStarted:hover { - background: var(--ifm-link-color); - color: #fff !important; - text-decoration: none; -} diff --git a/website/src/theme/Root.js b/website/src/theme/Root.js deleted file mode 100644 index e5d8a904bb0..00000000000 --- a/website/src/theme/Root.js +++ /dev/null @@ -1,21 +0,0 @@ -import React from 'react'; -import BrowserOnly from '@docusaurus/BrowserOnly'; -import { ThemeProvider, Header } from 'the-guild-components'; - -// Default implementation, that you can customize -function Root({ children }) { - return ( - <> - - {() => ( - -
- - )} - - {children} - - ); -} - -export default Root; diff --git a/website/static/img/banner.gif b/website/static/img/banner.gif deleted file mode 100644 index b9f1bd936fc..00000000000 Binary files a/website/static/img/banner.gif and /dev/null differ diff --git a/website/static/img/flask.svg b/website/static/img/flask.svg deleted file mode 100644 index faa1fc5771e..00000000000 --- a/website/static/img/flask.svg +++ /dev/null @@ -1,105 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/website/static/img/graphql.svg b/website/static/img/graphql.svg deleted file mode 100644 index 58b2cc2877c..00000000000 --- a/website/static/img/graphql.svg +++ /dev/null @@ -1,71 +0,0 @@ - - - - diff --git a/website/static/img/logo.png b/website/static/img/logo.png deleted file mode 100644 index ccacc47abfa..00000000000 Binary files a/website/static/img/logo.png and /dev/null differ diff --git a/website/static/img/needle.svg b/website/static/img/needle.svg deleted file mode 100644 index d5d1500e187..00000000000 --- a/website/static/img/needle.svg +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/website/tsconfig.json b/website/tsconfig.json new file mode 100644 index 00000000000..9d27bcc417b --- /dev/null +++ b/website/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "target": "es2019", + "module": "commonjs", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "noEmit": true, + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve" + }, + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], + "exclude": ["node_modules"] +} diff --git a/yarn.lock b/yarn.lock index 6a0c32b990b..da9e0d72cc4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,128 +2,109 @@ # yarn lockfile v1 -"@algolia/autocomplete-core@1.0.0-alpha.44": - version "1.0.0-alpha.44" - resolved "https://registry.yarnpkg.com/@algolia/autocomplete-core/-/autocomplete-core-1.0.0-alpha.44.tgz#e626dba45f5f3950d6beb0ab055395ef0f7e8bb2" - integrity sha512-2iMXthldMIDXtlbg9omRKLgg1bLo2ZzINAEqwhNjUeyj1ceEyL1ck6FY0VnJpf2LsjmNthHCz2BuFk+nYUeDNA== - dependencies: - "@algolia/autocomplete-shared" "1.0.0-alpha.44" - -"@algolia/autocomplete-preset-algolia@1.0.0-alpha.44": - version "1.0.0-alpha.44" - resolved "https://registry.yarnpkg.com/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.0.0-alpha.44.tgz#0ea0b255d0be10fbe262e281472dd6e4619b62ba" - integrity sha512-DCHwo5ovzg9k2ejUolGNTLFnIA7GpsrkbNJTy1sFbMnYfBmeK8egZPZnEl7lBTr27OaZu7IkWpTepLVSztZyng== - dependencies: - "@algolia/autocomplete-shared" "1.0.0-alpha.44" - -"@algolia/autocomplete-shared@1.0.0-alpha.44": - version "1.0.0-alpha.44" - resolved "https://registry.yarnpkg.com/@algolia/autocomplete-shared/-/autocomplete-shared-1.0.0-alpha.44.tgz#db13902ad1667e455711b77d08cae1a0feafaa48" - integrity sha512-2oQZPERYV+yNx/yoVWYjZZdOqsitJ5dfxXJjL18yczOXH6ujnsq+DTczSrX+RjzjQdVeJ1UAG053EJQF/FOiMg== - -"@algolia/cache-browser-local-storage@4.9.1": - version "4.9.1" - resolved "https://registry.yarnpkg.com/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.9.1.tgz#784e91580dcca00a8280b0905197f5abbbdf4b48" - integrity sha512-bAUU9vKCy45uTTlzJw0LYu1IjoZsmzL6lgjaVFaW1crhX/4P+JD5ReQv3n/wpiXSFaHq1WEO3WyH2g3ymzeipQ== - dependencies: - "@algolia/cache-common" "4.9.1" - -"@algolia/cache-common@4.9.1": - version "4.9.1" - resolved "https://registry.yarnpkg.com/@algolia/cache-common/-/cache-common-4.9.1.tgz#2d5f37ba7aab7db76627c4a4fce51a7fd137fa65" - integrity sha512-tcvw4mOfFy44V4ZxDEy9wNGr6vFROZKRpXKTEBgdw/WBn6mX51H1ar4RWtceDEcDU4H5fIv5tsY3ip2hU+fTPg== - -"@algolia/cache-in-memory@4.9.1": - version "4.9.1" - resolved "https://registry.yarnpkg.com/@algolia/cache-in-memory/-/cache-in-memory-4.9.1.tgz#3fd1d67aec804b6cc8439015b8b9c712a45c7ae0" - integrity sha512-IEJrHonvdymW2CnRfJtsTVWyfAH05xPEFkGXGCw00+6JNCj8Dln3TeaRLiaaY1srlyGedkemekQm1/Xb46CGOQ== - dependencies: - "@algolia/cache-common" "4.9.1" - -"@algolia/client-account@4.9.1": - version "4.9.1" - resolved "https://registry.yarnpkg.com/@algolia/client-account/-/client-account-4.9.1.tgz#f2c1b3e49de2ee1fca44b8b5e64e1ce0dbdff0db" - integrity sha512-Shpjeuwb7i2LR5QuWREb6UbEQLGB+Pl/J5+wPgILJDP/uWp7jpl0ase9mYNQGKj7TjztpSpQCPZ3dSHPnzZPfw== - dependencies: - "@algolia/client-common" "4.9.1" - "@algolia/client-search" "4.9.1" - "@algolia/transporter" "4.9.1" - -"@algolia/client-analytics@4.9.1": - version "4.9.1" - resolved "https://registry.yarnpkg.com/@algolia/client-analytics/-/client-analytics-4.9.1.tgz#56972496526910c53c5ce7844f4571efba63eb5f" - integrity sha512-/g6OkOSIA+A0t/tjvbL6iG/zV4El4LPFgv/tcAYHTH27BmlNtnEXw+iFpGjeUlQoPily9WVB3QNLMJkaNwL3HA== - dependencies: - "@algolia/client-common" "4.9.1" - "@algolia/client-search" "4.9.1" - "@algolia/requester-common" "4.9.1" - "@algolia/transporter" "4.9.1" - -"@algolia/client-common@4.9.1": - version "4.9.1" - resolved "https://registry.yarnpkg.com/@algolia/client-common/-/client-common-4.9.1.tgz#ae313b65d3249efcb4fafd2e92ed1fa2fd075482" - integrity sha512-UziRTZ8km3qwoVPIyEre8TV6V+MX7UtbfVqPmSafZ0xu41UUZ+sL56YoKjOXkbKuybeIC9prXMGy/ID5bXkTqg== - dependencies: - "@algolia/requester-common" "4.9.1" - "@algolia/transporter" "4.9.1" - -"@algolia/client-recommendation@4.9.1": - version "4.9.1" - resolved "https://registry.yarnpkg.com/@algolia/client-recommendation/-/client-recommendation-4.9.1.tgz#217af2a38d37ab12cf23a419cc9a576af9d15b13" - integrity sha512-Drtvvm1PNIOpYf4HFlkPFstFQ3IsN+TRmxur2F7y6Faplb5ybISa8ithu1tmlTdyTf3A78hQUQjgJet6qD2XZw== - dependencies: - "@algolia/client-common" "4.9.1" - "@algolia/requester-common" "4.9.1" - "@algolia/transporter" "4.9.1" - -"@algolia/client-search@4.9.1": - version "4.9.1" - resolved "https://registry.yarnpkg.com/@algolia/client-search/-/client-search-4.9.1.tgz#a2fbc47a1b343dade9a8b06310231d51ff675b1b" - integrity sha512-r9Cw2r8kJr45iYncFDht6EshARghU265wuY8Q8oHrpFHjAziEYdsUOdNmQKbsSH5J3gLjDPx1EI5DzVd6ivn3w== - dependencies: - "@algolia/client-common" "4.9.1" - "@algolia/requester-common" "4.9.1" - "@algolia/transporter" "4.9.1" - -"@algolia/logger-common@4.9.1": - version "4.9.1" - resolved "https://registry.yarnpkg.com/@algolia/logger-common/-/logger-common-4.9.1.tgz#3323834095f2916338d2535d2df91c4723ac19f2" - integrity sha512-9mPrbFlFyPT7or/7PXTiJjyOewWB9QRkZKVXkt5zHAUiUzGxmmdpJIGpPv3YQnDur8lXrXaRI0MHXUuIDMY1ng== - -"@algolia/logger-console@4.9.1": - version "4.9.1" - resolved "https://registry.yarnpkg.com/@algolia/logger-console/-/logger-console-4.9.1.tgz#c324ef26843dbed06b44586309331dbb949744ad" - integrity sha512-74VUwjtFjFpjZpi3QoHIPv0kcr3vWUSHX/Vs8PJW3lPsD4CgyhFenQbG9v+ZnyH0JrJwiYTtzfmrVh7IMWZGrQ== - dependencies: - "@algolia/logger-common" "4.9.1" - -"@algolia/requester-browser-xhr@4.9.1": - version "4.9.1" - resolved "https://registry.yarnpkg.com/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.9.1.tgz#0812f3c7c4105a4646c0fba8429b172b2d0e01c5" - integrity sha512-zc46tk5o0ikOAz3uYiRAMxC2iVKAMFKT7nNZnLB5IzT0uqAh7pz/+D/UvIxP4bKmsllpBSnPcpfQF+OI4Ag/BA== - dependencies: - "@algolia/requester-common" "4.9.1" - -"@algolia/requester-common@4.9.1": - version "4.9.1" - resolved "https://registry.yarnpkg.com/@algolia/requester-common/-/requester-common-4.9.1.tgz#50fcf4c7c1ed7ae13159167ac1da2844d036a630" - integrity sha512-9hPgXnlCSbqJqF69M5x5WN3h51Dc+mk/iWNeJSVxExHGvCDfBBZd0v6S15i8q2a9cD1I2RnhMpbnX5BmGtabVA== - -"@algolia/requester-node-http@4.9.1": - version "4.9.1" - resolved "https://registry.yarnpkg.com/@algolia/requester-node-http/-/requester-node-http-4.9.1.tgz#70054a0aa5643072404fcb68042eec97c7abd1c8" - integrity sha512-vYNVbSCuyrCSCjHBQJk+tLZtWCjvvDf5tSbRJjyJYMqpnXuIuP7gZm24iHil4NPYBhbBj5NU2ZDAhc/gTn75Ag== - dependencies: - "@algolia/requester-common" "4.9.1" - -"@algolia/transporter@4.9.1": - version "4.9.1" - resolved "https://registry.yarnpkg.com/@algolia/transporter/-/transporter-4.9.1.tgz#63ef3d9ae3b6556fa1ff1e6265bbab482bd084b7" - integrity sha512-AbjFfGzX+cAuj7Qyc536OxIQzjFOA5FU2ANGStx8LBH+AKXScwfkx67C05riuaRR5adSCLMSEbVvUscH0nF+6A== - dependencies: - "@algolia/cache-common" "4.9.1" - "@algolia/logger-common" "4.9.1" - "@algolia/requester-common" "4.9.1" +"@algolia/cache-browser-local-storage@4.10.3": + version "4.10.3" + resolved "https://registry.yarnpkg.com/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.10.3.tgz#3bf81e0f66a4a1079a75914a987eb1ef432c7c68" + integrity sha512-TD1N7zg5lb56/PLjjD4bBl2eccEvVHhC7yfgFu2r9k5tf+gvbGxEZ3NhRZVKu2MObUIcEy2VR4LVLxOQu45Hlg== + dependencies: + "@algolia/cache-common" "4.10.3" + +"@algolia/cache-common@4.10.3": + version "4.10.3" + resolved "https://registry.yarnpkg.com/@algolia/cache-common/-/cache-common-4.10.3.tgz#311b2b5ae06d55300f4230944c99bc39ad15847d" + integrity sha512-q13cPPUmtf8a2suBC4kySSr97EyulSXuxUkn7l1tZUCX/k1y5KNheMp8npBy8Kc8gPPmHpacxddRSfOncjiKFw== + +"@algolia/cache-in-memory@4.10.3": + version "4.10.3" + resolved "https://registry.yarnpkg.com/@algolia/cache-in-memory/-/cache-in-memory-4.10.3.tgz#697e4994538426272ea29ccf2b32b46ea4c48862" + integrity sha512-JhPajhOXAjUP+TZrZTh6KJpF5VKTKyWK2aR1cD8NtrcVHwfGS7fTyfXfVm5BqBqkD9U0gVvufUt/mVyI80aZww== + dependencies: + "@algolia/cache-common" "4.10.3" + +"@algolia/client-account@4.10.3": + version "4.10.3" + resolved "https://registry.yarnpkg.com/@algolia/client-account/-/client-account-4.10.3.tgz#f2cbefb1abce74c341115607d6af199df1b056ae" + integrity sha512-S/IsJB4s+e1xYctdpW3nAbwrR2y3pjSo9X21fJGoiGeIpTRdvQG7nydgsLkhnhcgAdLnmqBapYyAqMGmlcyOkg== + dependencies: + "@algolia/client-common" "4.10.3" + "@algolia/client-search" "4.10.3" + "@algolia/transporter" "4.10.3" + +"@algolia/client-analytics@4.10.3": + version "4.10.3" + resolved "https://registry.yarnpkg.com/@algolia/client-analytics/-/client-analytics-4.10.3.tgz#43d934ef8df0cf551c78e6b2e9f2452e7fb27d93" + integrity sha512-vlHTbBqJktRgclh3v7bPQLfZvFIqY4erNFIZA5C7nisCj9oLeTgzefoUrr+R90+I+XjfoLxnmoeigS1Z1yg1vw== + dependencies: + "@algolia/client-common" "4.10.3" + "@algolia/client-search" "4.10.3" + "@algolia/requester-common" "4.10.3" + "@algolia/transporter" "4.10.3" + +"@algolia/client-common@4.10.3": + version "4.10.3" + resolved "https://registry.yarnpkg.com/@algolia/client-common/-/client-common-4.10.3.tgz#c4257dd5c57c5c8ec4bd48a7b1897573e372d403" + integrity sha512-uFyP2Z14jG2hsFRbAoavna6oJf4NTXaSDAZgouZUZlHlBp5elM38sjNeA5HR9/D9J/GjwaB1SgB7iUiIWYBB4w== + dependencies: + "@algolia/requester-common" "4.10.3" + "@algolia/transporter" "4.10.3" + +"@algolia/client-personalization@4.10.3": + version "4.10.3" + resolved "https://registry.yarnpkg.com/@algolia/client-personalization/-/client-personalization-4.10.3.tgz#58c800f90ab8ab4aa29abdf29a97e89e6bda419e" + integrity sha512-NS7Nx8EJ/nduGXT8CFo5z7kLF0jnFehTP3eC+z+GOEESH3rrs7uR12IZHxv5QhQswZa9vl925zCOZDcDVoENCg== + dependencies: + "@algolia/client-common" "4.10.3" + "@algolia/requester-common" "4.10.3" + "@algolia/transporter" "4.10.3" + +"@algolia/client-search@4.10.3": + version "4.10.3" + resolved "https://registry.yarnpkg.com/@algolia/client-search/-/client-search-4.10.3.tgz#aa6b02c2d528cb264830f276739b7f68b58988ef" + integrity sha512-Zwnp2G94IrNFKWCG/k7epI5UswRkPvL9FCt7/slXe2bkjP2y/HA37gzRn+9tXoLVRwd7gBzrtOA4jFKIyjrtVw== + dependencies: + "@algolia/client-common" "4.10.3" + "@algolia/requester-common" "4.10.3" + "@algolia/transporter" "4.10.3" + +"@algolia/logger-common@4.10.3": + version "4.10.3" + resolved "https://registry.yarnpkg.com/@algolia/logger-common/-/logger-common-4.10.3.tgz#6773d2e38581bf9ac57e2dda02f0c4f1bc72ce94" + integrity sha512-M6xi+qov2bkgg1H9e1Qtvq/E/eKsGcgz8RBbXNzqPIYoDGZNkv+b3b8YMo3dxd4Wd6M24HU1iqF3kmr1LaXndg== + +"@algolia/logger-console@4.10.3": + version "4.10.3" + resolved "https://registry.yarnpkg.com/@algolia/logger-console/-/logger-console-4.10.3.tgz#bd8bdc1f9dba89db37be25d673ac1f2e68de7913" + integrity sha512-vVgRI7b4PHjgBdRkv/cRz490twvkLoGdpC4VYzIouSrKj8SIVLRhey3qgXk7oQXi3xoxVAv6NrklHfpO8Bpx0w== + dependencies: + "@algolia/logger-common" "4.10.3" + +"@algolia/requester-browser-xhr@4.10.3": + version "4.10.3" + resolved "https://registry.yarnpkg.com/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.10.3.tgz#81ae8f6caf562a28f96102f03da7f4b19bba568c" + integrity sha512-4WIk1zreFbc1EF6+gsfBTQvwSNjWc20zJAAExRWql/Jq5yfVHmwOqi/CajA53/cXKFBqo80DAMRvOiwP+hOLYw== + dependencies: + "@algolia/requester-common" "4.10.3" + +"@algolia/requester-common@4.10.3": + version "4.10.3" + resolved "https://registry.yarnpkg.com/@algolia/requester-common/-/requester-common-4.10.3.tgz#c3112393cff97be79863bc28de76f9c69b2f5a95" + integrity sha512-PNfLHmg0Hujugs3rx55uz/ifv7b9HVdSFQDb2hj0O5xZaBEuQCNOXC6COrXR8+9VEfqp2swpg7zwgtqFxh+BtQ== + +"@algolia/requester-node-http@4.10.3": + version "4.10.3" + resolved "https://registry.yarnpkg.com/@algolia/requester-node-http/-/requester-node-http-4.10.3.tgz#75ea7805ac0ba25a1124989d8632ef39c31441c1" + integrity sha512-A9ZcGfEvgqf0luJApdNcIhsRh6MShn2zn2tbjwjGG1joF81w+HUY+BWuLZn56vGwAA9ZB9n00IoJJpxibbfofg== + dependencies: + "@algolia/requester-common" "4.10.3" + +"@algolia/transporter@4.10.3": + version "4.10.3" + resolved "https://registry.yarnpkg.com/@algolia/transporter/-/transporter-4.10.3.tgz#0aeee752923957cffe63e4cf1c7a22ca48d96dde" + integrity sha512-n1lRyKDbrckbMEgm7QXtj3nEWUuzA3aKLzVQ43/F/RCFib15j4IwtmYhXR6OIBRSc7+T0Hm48S0J6F+HeYCQkw== + dependencies: + "@algolia/cache-common" "4.10.3" + "@algolia/logger-common" "4.10.3" + "@algolia/requester-common" "4.10.3" "@apollo/client@3.3.20", "@apollo/client@^3.1.3", "@apollo/client@~3.2.5 || ~3.3.0": version "3.3.20" @@ -144,19 +125,10 @@ tslib "^1.10.0" zen-observable "^0.8.14" -"@ardatan/aggregate-error@0.0.6": - version "0.0.6" - resolved "https://registry.yarnpkg.com/@ardatan/aggregate-error/-/aggregate-error-0.0.6.tgz#fe6924771ea40fc98dc7a7045c2e872dc8527609" - integrity sha512-vyrkEHG1jrukmzTPtyWB4NLPauUw5bQeg4uhn8f+1SSynmrOcyvlb1GKQjjgoBzElLdfXCRYX8UnBlhklOHYRQ== - dependencies: - tslib "~2.0.1" - -"@babel/code-frame@7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a" - integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg== - dependencies: - "@babel/highlight" "^7.10.4" +"@ardatan/fetch-event-source@2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@ardatan/fetch-event-source/-/fetch-event-source-2.0.2.tgz#734aa3eaa0da456453d24d8dc7c14d5e366a8d21" + integrity sha512-mcpz/wJ7s50PJIVz4OQ1Yim3w/AAchtYtIg0QMWiMR2cZZoI9t23hRyqeumtD5EmyJu0fxtjmQ5WY8GI86V4rQ== "@babel/code-frame@7.12.11": version "7.12.11" @@ -165,17 +137,17 @@ dependencies: "@babel/highlight" "^7.10.4" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.14.5", "@babel/code-frame@^7.5.5": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.14.5.tgz#23b08d740e83f49c5e59945fbf1b43e80bbf4edb" integrity sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw== dependencies: "@babel/highlight" "^7.14.5" -"@babel/compat-data@^7.13.0", "@babel/compat-data@^7.13.11", "@babel/compat-data@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.14.5.tgz#8ef4c18e58e801c5c95d3c1c0f2874a2680fadea" - integrity sha512-kixrYn4JwfAVPa0f2yfzc2AWti6WRRyO3XjWW5PJAvtE11qhSayrrcrEnee05KAtNaPC+EwehE8Qt1UedEVB8w== +"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.14.5", "@babel/compat-data@^7.14.7": + version "7.14.7" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.14.7.tgz#7b047d7a3a89a67d2258dc61f604f098f1bc7e08" + integrity sha512-nS6dZaISCXJ3+518CWiBfEr//gHyMO02uDxBkXTKZDN5POruCnOZ1N4YBRZDCabwF8nZMWBpRxIicmXtBs+fvw== "@babel/core@7.12.9": version "7.12.9" @@ -199,17 +171,17 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/core@7.14.5", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.12.16", "@babel/core@^7.12.3", "@babel/core@^7.7.2", "@babel/core@^7.7.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.14.5.tgz#d281f46a9905f07d1b3bf71ead54d9c7d89cb1e3" - integrity sha512-RN/AwP2DJmQTZSfiDaD+JQQ/J99KsIpOCfBE5pL+5jJSt7nI3nYGoAXZu+ffYSQ029NLs2DstZb+eR81uuARgg== +"@babel/core@7.14.6", "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.7.2", "@babel/core@^7.7.5": + version "7.14.6" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.14.6.tgz#e0814ec1a950032ff16c13a2721de39a8416fcab" + integrity sha512-gJnOEWSqTk96qG5BoIrl5bVtc23DCycmIePPYnamY9RboYdI4nFy5vAQMSl81O5K/W0sLDWfGysnOECC+KUUCA== dependencies: "@babel/code-frame" "^7.14.5" "@babel/generator" "^7.14.5" "@babel/helper-compilation-targets" "^7.14.5" "@babel/helper-module-transforms" "^7.14.5" - "@babel/helpers" "^7.14.5" - "@babel/parser" "^7.14.5" + "@babel/helpers" "^7.14.6" + "@babel/parser" "^7.14.6" "@babel/template" "^7.14.5" "@babel/traverse" "^7.14.5" "@babel/types" "^7.14.5" @@ -220,7 +192,7 @@ semver "^6.3.0" source-map "^0.5.0" -"@babel/generator@^7.12.15", "@babel/generator@^7.12.5", "@babel/generator@^7.14.5", "@babel/generator@^7.5.0", "@babel/generator@^7.7.2": +"@babel/generator@^7.12.5", "@babel/generator@^7.14.5", "@babel/generator@^7.5.0", "@babel/generator@^7.7.2": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.14.5.tgz#848d7b9f031caca9d0cd0af01b063f226f52d785" integrity sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA== @@ -229,7 +201,16 @@ jsesc "^2.5.1" source-map "^0.5.0" -"@babel/helper-annotate-as-pure@^7.0.0", "@babel/helper-annotate-as-pure@^7.10.4", "@babel/helper-annotate-as-pure@^7.12.13", "@babel/helper-annotate-as-pure@^7.14.5": +"@babel/generator@^7.14.8": + version "7.14.8" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.14.8.tgz#bf86fd6af96cf3b74395a8ca409515f89423e070" + integrity sha512-cYDUpvIzhBVnMzRoY1fkSEhK/HmwEVwlyULYgn/tMQYd6Obag3ylCjONle3gdErfXBW61SVTlR9QR7uWlgeIkg== + dependencies: + "@babel/types" "^7.14.8" + jsesc "^2.5.1" + source-map "^0.5.0" + +"@babel/helper-annotate-as-pure@^7.12.13", "@babel/helper-annotate-as-pure@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.14.5.tgz#7bf478ec3b71726d56a8ca5775b046fc29879e61" integrity sha512-EivH9EgBIb+G8ij1B2jAwSH36WnGvkQSEC6CkX/6v6ZFlw5fVOHvsgGF4uiEHO2GzMvunZb6tDLQEQSdrdocrA== @@ -274,20 +255,6 @@ "@babel/helper-annotate-as-pure" "^7.14.5" regexpu-core "^4.7.1" -"@babel/helper-define-polyfill-provider@^0.1.5": - version "0.1.5" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.1.5.tgz#3c2f91b7971b9fc11fe779c945c014065dea340e" - integrity sha512-nXuzCSwlJ/WKr8qxzW816gwyT6VZgiJG17zR40fou70yfAcqjoNyTLl/DQ+FExw5Hx5KNqshmN8Ldl/r2N7cTg== - dependencies: - "@babel/helper-compilation-targets" "^7.13.0" - "@babel/helper-module-imports" "^7.12.13" - "@babel/helper-plugin-utils" "^7.13.0" - "@babel/traverse" "^7.13.0" - debug "^4.1.1" - lodash.debounce "^4.0.8" - resolve "^1.14.2" - semver "^6.1.2" - "@babel/helper-define-polyfill-provider@^0.2.2": version "0.2.3" resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.3.tgz#0525edec5094653a282688d34d846e4c75e9c0b6" @@ -339,7 +306,7 @@ dependencies: "@babel/types" "^7.14.5" -"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.14.5": +"@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz#6d1a44df6a38c957aa7c312da076429f11b422f3" integrity sha512-SwrNHu5QWS84XlHwGYPDtCxcA0hrSlL2yhWYLgeOc0w7ccOl2qv4s/nARI0aYZW+bSwAL5CukeXA47B/1NKcnQ== @@ -422,6 +389,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz#d0f0e277c512e0c938277faa85a3968c9a44c0e8" integrity sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg== +"@babel/helper-validator-identifier@^7.14.8": + version "7.14.8" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.8.tgz#32be33a756f29e278a0d644fa08a2c9e0f88a34c" + integrity sha512-ZGy6/XQjllhYQrNw/3zfWRwZCTVSiBLZ9DHVZxn9n2gip/7ab8mv2TWlKPIBk26RwedCBoWdjLmn+t9na2Gcow== + "@babel/helper-validator-option@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz#6e72a1fff18d5dfcb878e1e62f1a021c4b72d5a3" @@ -437,10 +409,19 @@ "@babel/traverse" "^7.14.5" "@babel/types" "^7.14.5" -"@babel/helpers@^7.12.5", "@babel/helpers@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.14.5.tgz#4870f8d9a6fdbbd65e5674a3558b4ff7fef0d9b2" - integrity sha512-xtcWOuN9VL6nApgVHtq3PPcQv5qFBJzoSZzJ/2c0QK/IP/gxVcoWSNQwFEGvmbQsuS9rhYqjILDGGXcTkA705Q== +"@babel/helpers@^7.12.5": + version "7.14.8" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.14.8.tgz#839f88f463025886cff7f85a35297007e2da1b77" + integrity sha512-ZRDmI56pnV+p1dH6d+UN6GINGz7Krps3+270qqI9UJ4wxYThfAIcI5i7j5vXC4FJ3Wap+S9qcebxeYiqn87DZw== + dependencies: + "@babel/template" "^7.14.5" + "@babel/traverse" "^7.14.8" + "@babel/types" "^7.14.8" + +"@babel/helpers@^7.14.6": + version "7.14.6" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.14.6.tgz#5b58306b95f1b47e2a0199434fa8658fa6c21635" + integrity sha512-yesp1ENQBiLI+iYHSJdoZKUtRpfTlL1grDIX9NRlAVppljLw/4tTyYupIB7uIYmC3stW/imAv8EqaKaS/ibmeA== dependencies: "@babel/template" "^7.14.5" "@babel/traverse" "^7.14.5" @@ -455,10 +436,15 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@7.14.5", "@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.12.0", "@babel/parser@^7.12.16", "@babel/parser@^7.12.5", "@babel/parser@^7.12.7", "@babel/parser@^7.13.9", "@babel/parser@^7.14.5", "@babel/parser@^7.7.2": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.5.tgz#4cd2f346261061b2518873ffecdf1612cb032829" - integrity sha512-TM8C+xtH/9n1qzX+JNHi7AN2zHMTiPUtspO0ZdHflW8KaskkALhMmuMHb4bCmNdv9VAPzJX3/bXqkVLnAvsPfg== +"@babel/parser@7.14.7", "@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.12.0", "@babel/parser@^7.12.5", "@babel/parser@^7.12.7", "@babel/parser@^7.13.9", "@babel/parser@^7.14.5", "@babel/parser@^7.14.6", "@babel/parser@^7.14.7", "@babel/parser@^7.7.2": + version "7.14.7" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.7.tgz#6099720c8839ca865a2637e6c85852ead0bdb595" + integrity sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA== + +"@babel/parser@^7.14.8": + version "7.14.8" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.8.tgz#66fd41666b2d7b840bd5ace7f7416d5ac60208d4" + integrity sha512-syoCQFOoo/fzkWDeM0dLEZi5xqurb5vuyzwIMNZRNun+N/9A4cUZeQaE7dTrB8jGaKuJRBtEOajtnmw0I5hvvA== "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.14.5": version "7.14.5" @@ -469,10 +455,10 @@ "@babel/helper-skip-transparent-expression-wrappers" "^7.14.5" "@babel/plugin-proposal-optional-chaining" "^7.14.5" -"@babel/plugin-proposal-async-generator-functions@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.14.5.tgz#4024990e3dd74181f4f426ea657769ff49a2df39" - integrity sha512-tbD/CG3l43FIXxmu4a7RBe4zH7MLJ+S/lFowPFO7HetS2hyOZ/0nnnznegDuzFzfkyQYTxqdTH/hKmuBngaDAA== +"@babel/plugin-proposal-async-generator-functions@^7.14.7": + version "7.14.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.14.7.tgz#784a48c3d8ed073f65adcf30b57bcbf6c8119ace" + integrity sha512-RK8Wj7lXLY3bqei69/cc25gwS5puEc3dknoFPFbqfy3XxYQBQFvu4ioWpafMBAB+L9NyptQK4nMOa5Xz16og8Q== dependencies: "@babel/helper-plugin-utils" "^7.14.5" "@babel/helper-remap-async-to-generator" "^7.14.5" @@ -552,12 +538,12 @@ "@babel/plugin-syntax-object-rest-spread" "^7.8.0" "@babel/plugin-transform-parameters" "^7.12.1" -"@babel/plugin-proposal-object-rest-spread@^7.0.0", "@babel/plugin-proposal-object-rest-spread@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.14.5.tgz#e581d5ccdfa187ea6ed73f56c6a21c1580b90fbf" - integrity sha512-VzMyY6PWNPPT3pxc5hi9LloKNr4SSrVCg7Yr6aZpW4Ym07r7KqSU/QXYwjXLVxqwSv0t/XSXkFoKBPUkZ8vb2A== +"@babel/plugin-proposal-object-rest-spread@^7.0.0", "@babel/plugin-proposal-object-rest-spread@^7.14.7": + version "7.14.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.14.7.tgz#5920a2b3df7f7901df0205974c0641b13fd9d363" + integrity sha512-082hsZz+sVabfmDWo1Oct1u1AgbKbUAyVgmX4otIc7bdsRgHBXwTwb3DpDmD4Eyyx6DNiuz5UAATT655k+kL5g== dependencies: - "@babel/compat-data" "^7.14.5" + "@babel/compat-data" "^7.14.7" "@babel/helper-compilation-targets" "^7.14.5" "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-object-rest-spread" "^7.8.3" @@ -796,10 +782,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-destructuring@^7.0.0", "@babel/plugin-transform-destructuring@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.14.5.tgz#d32ad19ff1a6da1e861dc62720d80d9776e3bf35" - integrity sha512-wU9tYisEbRMxqDezKUqC9GleLycCRoUsai9ddlsq54r8QRLaeEhc+d+9DqCG+kV9W2GgQjTZESPTpn5bAFMDww== +"@babel/plugin-transform-destructuring@^7.0.0", "@babel/plugin-transform-destructuring@^7.14.7": + version "7.14.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.14.7.tgz#0ad58ed37e23e22084d109f185260835e5557576" + integrity sha512-0mDE99nK+kVh3xlc5vKwB6wnP9ecuSj+zQCa/n0voENtP/zymdT4HH6QEb65wjjcbqr1Jb/7z9Qp7TF5FtwYGw== dependencies: "@babel/helper-plugin-utils" "^7.14.5" @@ -901,10 +887,10 @@ "@babel/helper-module-transforms" "^7.14.5" "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-named-capturing-groups-regex@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.14.5.tgz#d537e8ee083ee6f6aa4f4eef9d2081d555746e4c" - integrity sha512-+Xe5+6MWFo311U8SchgeX5c1+lJM+eZDBZgD+tvXu9VVQPXwwVzeManMMjYX6xw2HczngfOSZjoFYKwdeB/Jvw== +"@babel/plugin-transform-named-capturing-groups-regex@^7.14.7": + version "7.14.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.14.7.tgz#60c06892acf9df231e256c24464bfecb0908fd4e" + integrity sha512-DTNOTaS7TkW97xsDMrp7nycUVh6sn/eq22VaxWfEdzuEbRsiaOU0pqU7DlyUGHVsbQbSghvjKRpEl+nUCKGQSg== dependencies: "@babel/helper-create-regexp-features-plugin" "^7.14.5" @@ -937,28 +923,14 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-react-constant-elements@^7.12.1": - version "7.13.10" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.13.10.tgz#5d3de8a8ee53f4612e728f4f17b8c9125f8019e5" - integrity sha512-E+aCW9j7mLq01tOuGV08YzLBt+vSyr4bOPT75B6WrAlrUfmOYOZ/yWk847EH0dv0xXiCihWLEmlX//O30YhpIw== - dependencies: - "@babel/helper-plugin-utils" "^7.13.0" - -"@babel/plugin-transform-react-display-name@^7.0.0", "@babel/plugin-transform-react-display-name@^7.12.13": +"@babel/plugin-transform-react-display-name@^7.0.0": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.12.13.tgz#c28effd771b276f4647411c9733dbb2d2da954bd" integrity sha512-MprESJzI9O5VnJZrL7gg1MpdqmiFcUv41Jc7SahxYsNP2kDkFqClxxTZq+1Qv4AFCamm+GXMRDQINNn+qrxmiA== dependencies: "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-react-jsx-development@^7.12.12": - version "7.12.17" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.12.17.tgz#f510c0fa7cd7234153539f9a362ced41a5ca1447" - integrity sha512-BPjYV86SVuOaudFhsJR1zjgxxOhJDt6JHNoD48DxWEIxUCAMjV1ys6DYw4SDYZh0b1QsS2vfIA9t/ZsQGsDOUQ== - dependencies: - "@babel/plugin-transform-react-jsx" "^7.12.17" - -"@babel/plugin-transform-react-jsx@^7.0.0", "@babel/plugin-transform-react-jsx@^7.12.13", "@babel/plugin-transform-react-jsx@^7.12.17": +"@babel/plugin-transform-react-jsx@^7.0.0": version "7.12.17" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.12.17.tgz#dd2c1299f5e26de584939892de3cfc1807a38f24" integrity sha512-mwaVNcXV+l6qJOuRhpdTEj8sT/Z0owAVWf9QujTZ0d2ye9X/K+MTOTSizcgKOj18PGnTc/7g1I4+cIUjsKhBcw== @@ -969,14 +941,6 @@ "@babel/plugin-syntax-jsx" "^7.12.13" "@babel/types" "^7.12.17" -"@babel/plugin-transform-react-pure-annotations@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.12.1.tgz#05d46f0ab4d1339ac59adf20a1462c91b37a1a42" - integrity sha512-RqeaHiwZtphSIUZ5I85PEH19LOSzxfuEazoY7/pWASCAIBuATQzpSVD+eT6MebeeZT2F4eSL0u4vw6n4Nm0Mjg== - dependencies: - "@babel/helper-annotate-as-pure" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-transform-regenerator@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.14.5.tgz#9676fd5707ed28f522727c5b3c0aa8544440b04f" @@ -991,18 +955,6 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-runtime@^7.12.15": - version "7.13.10" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.13.10.tgz#a1e40d22e2bf570c591c9c7e5ab42d6bf1e419e1" - integrity sha512-Y5k8ipgfvz5d/76tx7JYbKQTcgFSU6VgJ3kKQv4zGTKr+a9T/KBvfRvGtSFgKDQGt/DBykQixV0vNWKIdzWErA== - dependencies: - "@babel/helper-module-imports" "^7.12.13" - "@babel/helper-plugin-utils" "^7.13.0" - babel-plugin-polyfill-corejs2 "^0.1.4" - babel-plugin-polyfill-corejs3 "^0.1.3" - babel-plugin-polyfill-regenerator "^0.1.2" - semver "^6.3.0" - "@babel/plugin-transform-shorthand-properties@^7.0.0", "@babel/plugin-transform-shorthand-properties@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.14.5.tgz#97f13855f1409338d8cadcbaca670ad79e091a58" @@ -1010,10 +962,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-spread@^7.0.0", "@babel/plugin-transform-spread@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.14.5.tgz#bd269fb4119754d2ce7f4cc39a96b4f71baae356" - integrity sha512-/3iqoQdiWergnShZYl0xACb4ADeYCJ7X/RgmwtXshn6cIvautRPAFzhd58frQlokLO6Jb4/3JXvmm6WNTPtiTw== +"@babel/plugin-transform-spread@^7.0.0", "@babel/plugin-transform-spread@^7.14.6": + version "7.14.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.14.6.tgz#6bd40e57fe7de94aa904851963b5616652f73144" + integrity sha512-Zr0x0YroFJku7n7+/HH3A2eIrGMjbmAIbJSVv0IZ+t3U2WUQUA64S/oeied2e+MaGSjmt4alzBCsK9E8gh+fag== dependencies: "@babel/helper-plugin-utils" "^7.14.5" "@babel/helper-skip-transparent-expression-wrappers" "^7.14.5" @@ -1063,17 +1015,17 @@ "@babel/helper-create-regexp-features-plugin" "^7.14.5" "@babel/helper-plugin-utils" "^7.14.5" -"@babel/preset-env@7.14.5", "@babel/preset-env@^7.12.1", "@babel/preset-env@^7.12.16": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.14.5.tgz#c0c84e763661fd0e74292c3d511cb33b0c668997" - integrity sha512-ci6TsS0bjrdPpWGnQ+m4f+JSSzDKlckqKIJJt9UZ/+g7Zz9k0N8lYU8IeLg/01o2h8LyNZDMLGgRLDTxpudLsA== +"@babel/preset-env@7.14.7": + version "7.14.7" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.14.7.tgz#5c70b22d4c2d893b03d8c886a5c17422502b932a" + integrity sha512-itOGqCKLsSUl0Y+1nSfhbuuOlTs0MJk2Iv7iSH+XT/mR8U1zRLO7NjWlYXB47yhK4J/7j+HYty/EhFZDYKa/VA== dependencies: - "@babel/compat-data" "^7.14.5" + "@babel/compat-data" "^7.14.7" "@babel/helper-compilation-targets" "^7.14.5" "@babel/helper-plugin-utils" "^7.14.5" "@babel/helper-validator-option" "^7.14.5" "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.14.5" - "@babel/plugin-proposal-async-generator-functions" "^7.14.5" + "@babel/plugin-proposal-async-generator-functions" "^7.14.7" "@babel/plugin-proposal-class-properties" "^7.14.5" "@babel/plugin-proposal-class-static-block" "^7.14.5" "@babel/plugin-proposal-dynamic-import" "^7.14.5" @@ -1082,7 +1034,7 @@ "@babel/plugin-proposal-logical-assignment-operators" "^7.14.5" "@babel/plugin-proposal-nullish-coalescing-operator" "^7.14.5" "@babel/plugin-proposal-numeric-separator" "^7.14.5" - "@babel/plugin-proposal-object-rest-spread" "^7.14.5" + "@babel/plugin-proposal-object-rest-spread" "^7.14.7" "@babel/plugin-proposal-optional-catch-binding" "^7.14.5" "@babel/plugin-proposal-optional-chaining" "^7.14.5" "@babel/plugin-proposal-private-methods" "^7.14.5" @@ -1108,7 +1060,7 @@ "@babel/plugin-transform-block-scoping" "^7.14.5" "@babel/plugin-transform-classes" "^7.14.5" "@babel/plugin-transform-computed-properties" "^7.14.5" - "@babel/plugin-transform-destructuring" "^7.14.5" + "@babel/plugin-transform-destructuring" "^7.14.7" "@babel/plugin-transform-dotall-regex" "^7.14.5" "@babel/plugin-transform-duplicate-keys" "^7.14.5" "@babel/plugin-transform-exponentiation-operator" "^7.14.5" @@ -1120,7 +1072,7 @@ "@babel/plugin-transform-modules-commonjs" "^7.14.5" "@babel/plugin-transform-modules-systemjs" "^7.14.5" "@babel/plugin-transform-modules-umd" "^7.14.5" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.14.5" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.14.7" "@babel/plugin-transform-new-target" "^7.14.5" "@babel/plugin-transform-object-super" "^7.14.5" "@babel/plugin-transform-parameters" "^7.14.5" @@ -1128,7 +1080,7 @@ "@babel/plugin-transform-regenerator" "^7.14.5" "@babel/plugin-transform-reserved-words" "^7.14.5" "@babel/plugin-transform-shorthand-properties" "^7.14.5" - "@babel/plugin-transform-spread" "^7.14.5" + "@babel/plugin-transform-spread" "^7.14.6" "@babel/plugin-transform-sticky-regex" "^7.14.5" "@babel/plugin-transform-template-literals" "^7.14.5" "@babel/plugin-transform-typeof-symbol" "^7.14.5" @@ -1139,7 +1091,7 @@ babel-plugin-polyfill-corejs2 "^0.2.2" babel-plugin-polyfill-corejs3 "^0.2.2" babel-plugin-polyfill-regenerator "^0.2.2" - core-js-compat "^3.14.0" + core-js-compat "^3.15.0" semver "^6.3.0" "@babel/preset-modules@^0.1.4": @@ -1153,18 +1105,7 @@ "@babel/types" "^7.4.4" esutils "^2.0.2" -"@babel/preset-react@^7.12.13", "@babel/preset-react@^7.12.5": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.12.13.tgz#5f911b2eb24277fa686820d5bd81cad9a0602a0a" - integrity sha512-TYM0V9z6Abb6dj1K7i5NrEhA13oS5ujUYQYDfqIBXYHOc2c2VkFgc+q9kyssIyUfy4/hEwqrgSlJ/Qgv8zJLsA== - dependencies: - "@babel/helper-plugin-utils" "^7.12.13" - "@babel/plugin-transform-react-display-name" "^7.12.13" - "@babel/plugin-transform-react-jsx" "^7.12.13" - "@babel/plugin-transform-react-jsx-development" "^7.12.12" - "@babel/plugin-transform-react-pure-annotations" "^7.12.1" - -"@babel/preset-typescript@7.14.5", "@babel/preset-typescript@^7.12.16": +"@babel/preset-typescript@7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.14.5.tgz#aa98de119cf9852b79511f19e7f44a2d379bcce0" integrity sha512-u4zO6CdbRKbS9TypMqrlGH7sd2TAJppZwn3c/ZRLeO/wGsbddxgbPDUZVNrie3JWYLQ9vpineKlsrWFvO6Pwkw== @@ -1173,21 +1114,27 @@ "@babel/helper-validator-option" "^7.14.5" "@babel/plugin-transform-typescript" "^7.14.5" -"@babel/runtime-corejs3@^7.12.13": - version "7.13.10" - resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.13.10.tgz#14c3f4c85de22ba88e8e86685d13e8861a82fe86" - integrity sha512-x/XYVQ1h684pp1mJwOV4CyvqZXqbc8CMsMGUnAbuc82ZCdv1U63w5RSUzgDSXQHG5Rps/kiksH6g2D5BuaKyXg== +"@babel/runtime@7.12.5": + version "7.12.5" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.5.tgz#410e7e487441e1b360c29be715d870d9b985882e" + integrity sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg== dependencies: - core-js-pure "^3.0.0" regenerator-runtime "^0.13.4" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.3", "@babel/runtime@^7.10.4", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.14.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4": +"@babel/runtime@^7.0.0", "@babel/runtime@^7.10.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.4": version "7.14.0" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.0.tgz#46794bc20b612c5f75e62dd071e24dfd95f1cbe6" integrity sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA== dependencies: regenerator-runtime "^0.13.4" +"@babel/runtime@^7.1.2", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.13", "@babel/runtime@^7.13.10", "@babel/runtime@^7.13.17", "@babel/runtime@^7.14.0", "@babel/runtime@^7.14.5", "@babel/runtime@^7.7.2": + version "7.14.6" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.6.tgz#535203bc0892efc7dec60bdc27b2ecf6e409062d" + integrity sha512-/PCB2uJ7oM44tz8YhC4Z/6PeOKXp4K588f+5M3clr1M4zbqztlo0XEfJ2LEzj/FgwfgGcIdl8n7YYjTCI0BYwg== + dependencies: + regenerator-runtime "^0.13.4" + "@babel/template@^7.12.7", "@babel/template@^7.14.5", "@babel/template@^7.3.3": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.14.5.tgz#a9bc9d8b33354ff6e55a9c60d1109200a68974f4" @@ -1197,22 +1144,37 @@ "@babel/parser" "^7.14.5" "@babel/types" "^7.14.5" -"@babel/traverse@7.14.5", "@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.12.13", "@babel/traverse@^7.12.9", "@babel/traverse@^7.13.0", "@babel/traverse@^7.14.5", "@babel/traverse@^7.4.5", "@babel/traverse@^7.7.2": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.14.5.tgz#c111b0f58afab4fea3d3385a406f692748c59870" - integrity sha512-G3BiS15vevepdmFqmUc9X+64y0viZYygubAMO8SvBmKARuF6CPSZtH4Ng9vi/lrWlZFGe3FWdXNy835akH8Glg== +"@babel/traverse@7.14.7", "@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.12.9", "@babel/traverse@^7.13.0", "@babel/traverse@^7.14.5", "@babel/traverse@^7.7.2": + version "7.14.7" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.14.7.tgz#64007c9774cfdc3abd23b0780bc18a3ce3631753" + integrity sha512-9vDr5NzHu27wgwejuKL7kIOm4bwEtaPQ4Z6cpCmjSuaRqpH/7xc4qcGEscwMqlkwgcXl6MvqoAjZkQ24uSdIZQ== dependencies: "@babel/code-frame" "^7.14.5" "@babel/generator" "^7.14.5" "@babel/helper-function-name" "^7.14.5" "@babel/helper-hoist-variables" "^7.14.5" "@babel/helper-split-export-declaration" "^7.14.5" - "@babel/parser" "^7.14.5" + "@babel/parser" "^7.14.7" "@babel/types" "^7.14.5" debug "^4.1.0" globals "^11.1.0" -"@babel/types@7.14.5", "@babel/types@^7.0.0", "@babel/types@^7.12.0", "@babel/types@^7.12.17", "@babel/types@^7.12.6", "@babel/types@^7.12.7", "@babel/types@^7.13.0", "@babel/types@^7.14.5", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": +"@babel/traverse@^7.14.8": + version "7.14.8" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.14.8.tgz#c0253f02677c5de1a8ff9df6b0aacbec7da1a8ce" + integrity sha512-kexHhzCljJcFNn1KYAQ6A5wxMRzq9ebYpEDV4+WdNyr3i7O44tanbDOR/xjiG2F3sllan+LgwK+7OMk0EmydHg== + dependencies: + "@babel/code-frame" "^7.14.5" + "@babel/generator" "^7.14.8" + "@babel/helper-function-name" "^7.14.5" + "@babel/helper-hoist-variables" "^7.14.5" + "@babel/helper-split-export-declaration" "^7.14.5" + "@babel/parser" "^7.14.8" + "@babel/types" "^7.14.8" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/types@7.14.5", "@babel/types@^7.0.0", "@babel/types@^7.12.0", "@babel/types@^7.12.17", "@babel/types@^7.12.7", "@babel/types@^7.13.0", "@babel/types@^7.14.5", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.14.5.tgz#3bb997ba829a2104cedb20689c4a5b8121d383ff" integrity sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg== @@ -1220,11 +1182,563 @@ "@babel/helper-validator-identifier" "^7.14.5" to-fast-properties "^2.0.0" +"@babel/types@7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.8.3.tgz#5a383dffa5416db1b73dedffd311ffd0788fb31c" + integrity sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg== + dependencies: + esutils "^2.0.2" + lodash "^4.17.13" + to-fast-properties "^2.0.0" + +"@babel/types@^7.14.8": + version "7.14.8" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.14.8.tgz#38109de8fcadc06415fbd9b74df0065d4d41c728" + integrity sha512-iob4soQa7dZw8nodR/KlOQkPh9S4I8RwCxwRIFuiMRYjOzH/KJzdUfDgz6cGi5dDaclXF4P2PAhCdrBJNIg68Q== + dependencies: + "@babel/helper-validator-identifier" "^7.14.8" + to-fast-properties "^2.0.0" + "@bcoe/v8-coverage@^0.2.3": version "0.2.3" resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== +"@chakra-ui/accordion@1.3.3": + version "1.3.3" + resolved "https://registry.yarnpkg.com/@chakra-ui/accordion/-/accordion-1.3.3.tgz#7e483759671c2c55e17aa79a637235808be79592" + integrity sha512-l0mtyChZxGlMfFRQhCS3yiucEXU4oV2k35W0OvYl5X1upzNlwD2o9JFCw/25PHJ+IbDo+bMAoQ/mPc4ZAy7s/Q== + dependencies: + "@chakra-ui/descendant" "2.0.1" + "@chakra-ui/hooks" "1.5.3" + "@chakra-ui/icon" "1.1.9" + "@chakra-ui/react-utils" "1.1.2" + "@chakra-ui/transition" "1.3.2" + "@chakra-ui/utils" "1.8.0" + +"@chakra-ui/alert@1.2.5": + version "1.2.5" + resolved "https://registry.yarnpkg.com/@chakra-ui/alert/-/alert-1.2.5.tgz#d8ab0fdf75fa61625c368bd1979d2989a9fa1907" + integrity sha512-S+YaqaACteSOhGlBFygOeYsQC2FYO6m37g6M+N23kbUHKtT7I4gYsxczLuUwKJ65u4T2Bt1qNSVokjmKCMhE9w== + dependencies: + "@chakra-ui/icon" "1.1.9" + "@chakra-ui/react-utils" "1.1.2" + "@chakra-ui/utils" "1.8.0" + +"@chakra-ui/avatar@1.2.6": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@chakra-ui/avatar/-/avatar-1.2.6.tgz#0f9c1d98aa401b0b6a758e16ceb4e44cb56947ea" + integrity sha512-Z07yd86nGYgrqFk1H/zyplpPRhQ04g3UioPWmufoqsGp6x/wysRO1ictF5O1duGQ1M5x4vrTqAS1ssAl5HmUzg== + dependencies: + "@chakra-ui/image" "1.0.16" + "@chakra-ui/react-utils" "1.1.2" + "@chakra-ui/utils" "1.8.0" + +"@chakra-ui/breadcrumb@1.2.6": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@chakra-ui/breadcrumb/-/breadcrumb-1.2.6.tgz#1c3d9069f421d1b431be8ff955e6193d6cf7d3de" + integrity sha512-dsISuwwqq46VcNUbeHJSE2kU939yPl6oSBo7RFQW/JNr+UN0wf9yGdB9BtETIhXZQDpnlEZgm3Gea78ubcDEKA== + dependencies: + "@chakra-ui/react-utils" "1.1.2" + "@chakra-ui/utils" "1.8.0" + +"@chakra-ui/button@1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/button/-/button-1.4.0.tgz#99a74ecb256def4b5d4d420dc6164a70c5492901" + integrity sha512-bkc5t2l3fBUm4yIllQAtoWBRvbElBWGEIzMEo9ABxWrB6bhXEeP513Mz1IoPFwHQmFhsQ1G+FpdH+X8TSN8cNw== + dependencies: + "@chakra-ui/react-utils" "1.1.2" + "@chakra-ui/spinner" "1.1.10" + "@chakra-ui/utils" "1.8.0" + +"@chakra-ui/checkbox@1.5.3": + version "1.5.3" + resolved "https://registry.yarnpkg.com/@chakra-ui/checkbox/-/checkbox-1.5.3.tgz#2f2c945d77997c8dc76b0be0cab99da90929bc53" + integrity sha512-0BXKci7D/dm0HxPBlFnZOtLy370dOYhOO11cMWnKGE+F3Zm2+vJKEU40O1wkWe7qnr6USsjFwXSHNLUkY9qH5A== + dependencies: + "@chakra-ui/hooks" "1.5.3" + "@chakra-ui/react-utils" "1.1.2" + "@chakra-ui/utils" "1.8.0" + "@chakra-ui/visually-hidden" "1.0.12" + +"@chakra-ui/clickable@1.1.5": + version "1.1.5" + resolved "https://registry.yarnpkg.com/@chakra-ui/clickable/-/clickable-1.1.5.tgz#21c439aee65880a133c91413c08dcf17095890ab" + integrity sha512-nC6vLxh7cYrYyuMdrotiq+CUqG+KGND+RLeE3WiWyP0JDivX6t7S1EtRENnskKyWaLvjMDFsLU0wDAZm18vQNA== + dependencies: + "@chakra-ui/react-utils" "1.1.2" + "@chakra-ui/utils" "1.8.0" + +"@chakra-ui/close-button@1.1.9": + version "1.1.9" + resolved "https://registry.yarnpkg.com/@chakra-ui/close-button/-/close-button-1.1.9.tgz#f6f0aba2de0e15881e4ec20dd1ba2e7d6cac4630" + integrity sha512-Wj1nuNUw93AkswwQM+ifOi0guJddRavu4mJS4F15+Vv8d30BQo/O6NOGPFutJK4Fm48WA9QjqydCMb1n8umDxA== + dependencies: + "@chakra-ui/icon" "1.1.9" + "@chakra-ui/utils" "1.8.0" + +"@chakra-ui/color-mode@1.1.9": + version "1.1.9" + resolved "https://registry.yarnpkg.com/@chakra-ui/color-mode/-/color-mode-1.1.9.tgz#7cda49574fb73f793c2b0816be803689a4f51b55" + integrity sha512-Bb8HpoJ4dzrYUIOHzIf0Ph+82ZphYEmRxc4Hd/ilCa5PGTHmOh7SSoFs6RToU4j/9Xmz32eKF6ioT6m6Fh8ycQ== + dependencies: + "@chakra-ui/hooks" "1.5.3" + "@chakra-ui/utils" "1.8.0" + +"@chakra-ui/control-box@1.0.13": + version "1.0.13" + resolved "https://registry.yarnpkg.com/@chakra-ui/control-box/-/control-box-1.0.13.tgz#d63df2294bfa4f29314c6e22a56229447cbe3c55" + integrity sha512-C64WLlVaTRaHDI+aeZpIDMXSZZMsXxbjXN7UCzUoNcG/5PzZQNJgvcJ3Y82pKF6S+4Sl7rRzxw+zIZLSCasGPw== + dependencies: + "@chakra-ui/utils" "1.8.0" + +"@chakra-ui/counter@1.1.6": + version "1.1.6" + resolved "https://registry.yarnpkg.com/@chakra-ui/counter/-/counter-1.1.6.tgz#b6db93717aa51956cb03cdcbacfcf43a5eb5f468" + integrity sha512-KwmkgI6Sp+NAsGEIFQOOUZMJ1ePPWNoUev3mArPrw7KcymPsMQK8KS95JdQXmRIYU34xdbeDavcsRJVLkFCfwg== + dependencies: + "@chakra-ui/hooks" "1.5.3" + "@chakra-ui/utils" "1.8.0" + +"@chakra-ui/css-reset@1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/css-reset/-/css-reset-1.0.0.tgz#8395921b35ef27bee0579a4d730c5ab7f7b39734" + integrity sha512-UaPsImGHvCgFO3ayp6Ugafu2/3/EG8wlW/8Y9Ihfk1UFv8cpV+3BfWKmuZ7IcmxcBL9dkP6E8p3/M1T0FB92hg== + +"@chakra-ui/descendant@2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@chakra-ui/descendant/-/descendant-2.0.1.tgz#fc3bc9081aa01503035b2c9296bc4b9f87ceaae0" + integrity sha512-TeYp94iOhu5Gs2oVzewJaep0qft/JKMKfmcf4PGgzJF+h6TWZm6NGohk6Jq7JOh+y0rExa1ulknIgnMzFx5xaA== + dependencies: + "@chakra-ui/react-utils" "^1.1.2" + +"@chakra-ui/editable@1.2.6": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@chakra-ui/editable/-/editable-1.2.6.tgz#638caf1633e05869a452c773b68025e780365200" + integrity sha512-Zbb68l/whuVkB5anPbrNLua14XhTGuqgmlrsadsaWnPzdBYCQFUR9+nXPhYLlHdzlWM5WLZCdffVkUl9UVgJwQ== + dependencies: + "@chakra-ui/hooks" "1.5.3" + "@chakra-ui/react-utils" "1.1.2" + "@chakra-ui/utils" "1.8.0" + +"@chakra-ui/focus-lock@1.1.8": + version "1.1.8" + resolved "https://registry.yarnpkg.com/@chakra-ui/focus-lock/-/focus-lock-1.1.8.tgz#30139cc8ccc68038e3c148a5f5e57eccfdfcb54e" + integrity sha512-y2aZGFv5O8vWL/oxt3FhhQSD6lQO5TEUdIFwaKFCh1qqHMoWrQMx0n7aGny1E8IMGvs2fKMKr1lIA3HovE/sCw== + dependencies: + "@chakra-ui/utils" "1.8.0" + react-focus-lock "2.5.0" + +"@chakra-ui/form-control@1.3.7": + version "1.3.7" + resolved "https://registry.yarnpkg.com/@chakra-ui/form-control/-/form-control-1.3.7.tgz#5a9c7da856f3b4b7eae39edafa2a41a0a0d1f01a" + integrity sha512-kXrnhI61SYbf+OL4XM+iMFS/OjdqfsIJo+BHNfTC8phY9xTbwnzTeA0kzEwcZa2n043ICzcD5O3QpPf9Z49Kig== + dependencies: + "@chakra-ui/hooks" "1.5.3" + "@chakra-ui/icon" "1.1.9" + "@chakra-ui/react-utils" "1.1.2" + "@chakra-ui/utils" "1.8.0" + +"@chakra-ui/hooks@1.5.3": + version "1.5.3" + resolved "https://registry.yarnpkg.com/@chakra-ui/hooks/-/hooks-1.5.3.tgz#d1988fc028ee04e61d625de2d33b991d4d1b8d8c" + integrity sha512-a8j87nnS5mGopsNkEPmvXPOuW+Ua4vS3sQh48esx8WXQ3v9V2/XcJ8+eTA4AMJGhxXCU63brU2BciyN9dkxYwA== + dependencies: + "@chakra-ui/react-utils" "1.1.2" + "@chakra-ui/utils" "1.8.0" + compute-scroll-into-view "1.0.14" + copy-to-clipboard "3.3.1" + +"@chakra-ui/icon@1.1.9": + version "1.1.9" + resolved "https://registry.yarnpkg.com/@chakra-ui/icon/-/icon-1.1.9.tgz#fbd6e82abf58b890f5bcc728bb75dda25d7b6c63" + integrity sha512-lmZHK4O+Wo7LwxRsQb0KmtOwq2iACESxwQgackuj7NPHbAsdF2/y3t2f7KCD+dTKGxoauEMgU2nVLePZWjtpTQ== + dependencies: + "@chakra-ui/utils" "1.8.0" + +"@chakra-ui/icons@^1.0.13": + version "1.0.13" + resolved "https://registry.yarnpkg.com/@chakra-ui/icons/-/icons-1.0.13.tgz#d8eb04479b048d8023ae90d76205cd4a0bf7dd79" + integrity sha512-twDpFz2uPVboMTEI4QA2y3EJND3G4+/9AVs730fgnnfhTw4EOJt0Lhfm4Spq1qi1LgHF16x4/Lao1E2imB5lWw== + dependencies: + "@chakra-ui/icon" "1.1.9" + "@types/react" "^17.0.0" + +"@chakra-ui/image@1.0.16": + version "1.0.16" + resolved "https://registry.yarnpkg.com/@chakra-ui/image/-/image-1.0.16.tgz#21758592ffd855562f1a91220f0d16c5b8f2e1dd" + integrity sha512-CrmT9HhnIawiQ4XiSz9O3tH1b0Hma2QQQzGyOQNrfiERxrG+m6pFaA1voCiK6e9RoDiRwcLeEPCg1tVus+AT2g== + dependencies: + "@chakra-ui/hooks" "1.5.3" + "@chakra-ui/utils" "1.8.0" + +"@chakra-ui/input@1.2.7": + version "1.2.7" + resolved "https://registry.yarnpkg.com/@chakra-ui/input/-/input-1.2.7.tgz#49221c5f6b13ca33e140b5aeb32ffd9b9a1032ea" + integrity sha512-PpcpFy9vYxU0DNEVpSDM4/400MDh2pS84MW+cF0SIepJSL+5DczUe+LO/+yoKx0Zh6ccmOfUSHUVDQLczwEFSg== + dependencies: + "@chakra-ui/form-control" "1.3.7" + "@chakra-ui/react-utils" "1.1.2" + "@chakra-ui/utils" "1.8.0" + +"@chakra-ui/layout@1.4.6": + version "1.4.6" + resolved "https://registry.yarnpkg.com/@chakra-ui/layout/-/layout-1.4.6.tgz#887bb65b58a63f37c6691cabda11edfc1967849f" + integrity sha512-dde/c0SNhFsSHwdgQY4m/JwBzcjY4gSCuODX90AcPJuDVd+CFm2mbRIicaJ9iFj3V83C3oIQUzn+LJlLLnmSig== + dependencies: + "@chakra-ui/icon" "1.1.9" + "@chakra-ui/react-utils" "1.1.2" + "@chakra-ui/utils" "1.8.0" + +"@chakra-ui/live-region@1.0.12": + version "1.0.12" + resolved "https://registry.yarnpkg.com/@chakra-ui/live-region/-/live-region-1.0.12.tgz#ff9806c27f955eab5492fa89f186a7fb09c78b4a" + integrity sha512-NgIZuCLAX7FCyLc7+7wxQ0WCmlFS+SHutHf2QXezU6NjkoUmiZ02yVoBHltGn9f0jBVkVBZ4LL1ng2ruwRsJog== + dependencies: + "@chakra-ui/utils" "1.8.0" + +"@chakra-ui/media-query@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/media-query/-/media-query-1.1.0.tgz#0902cf2171893583927ff6c4e86793116f083ff2" + integrity sha512-uito1LpqhO+xBgpXvnPcn4YZkeF905pAOgwNdudX88Wyn26Rcs81w/B4W90/MW0lAfPuUWqzYbGyUuiXyavQWQ== + dependencies: + "@chakra-ui/react-env" "1.0.4" + "@chakra-ui/utils" "1.8.0" + +"@chakra-ui/menu@1.7.0": + version "1.7.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/menu/-/menu-1.7.0.tgz#fea6a2a50bb6df216f35ab123c2c15f3ed8b5f79" + integrity sha512-zhT174hDwRyf9A4xbfFERPIH46hZFckFVy9BEBhTGeFAY2ohyqY0BEQoaJwQriN4ivFv2Wpr8j8yYAGR68x4XA== + dependencies: + "@chakra-ui/clickable" "1.1.5" + "@chakra-ui/descendant" "2.0.1" + "@chakra-ui/hooks" "1.5.3" + "@chakra-ui/popper" "2.2.1" + "@chakra-ui/react-utils" "1.1.2" + "@chakra-ui/transition" "1.3.2" + "@chakra-ui/utils" "1.8.0" + +"@chakra-ui/modal@1.8.8": + version "1.8.8" + resolved "https://registry.yarnpkg.com/@chakra-ui/modal/-/modal-1.8.8.tgz#990313c1a74c8a62d7db7f35fbdb36d74c0cd2da" + integrity sha512-E1fBHwGzmxjHv/+QK9jryiY4y544arRkR8gI6aBbXzpSmSZ2yke802NC6p2Xb22dnmrvzIT5G9MkJx2oV5jjCA== + dependencies: + "@chakra-ui/close-button" "1.1.9" + "@chakra-ui/focus-lock" "1.1.8" + "@chakra-ui/hooks" "1.5.3" + "@chakra-ui/portal" "1.2.6" + "@chakra-ui/react-utils" "1.1.2" + "@chakra-ui/transition" "1.3.2" + "@chakra-ui/utils" "1.8.0" + aria-hidden "^1.1.1" + react-remove-scroll "2.4.1" + +"@chakra-ui/number-input@1.2.7": + version "1.2.7" + resolved "https://registry.yarnpkg.com/@chakra-ui/number-input/-/number-input-1.2.7.tgz#0f1e7e32a83354520b4b4bbfc87a42143db0e876" + integrity sha512-k5TUjDfPHmv/pM9Rq3Dmo3S55Y/yTl76gX/en93+KF8kTamVP0oAhunbC82fYegyFIgpjPckJ3VOxR51JdX/eg== + dependencies: + "@chakra-ui/counter" "1.1.6" + "@chakra-ui/form-control" "1.3.7" + "@chakra-ui/hooks" "1.5.3" + "@chakra-ui/icon" "1.1.9" + "@chakra-ui/react-utils" "1.1.2" + "@chakra-ui/utils" "1.8.0" + +"@chakra-ui/pin-input@1.6.2": + version "1.6.2" + resolved "https://registry.yarnpkg.com/@chakra-ui/pin-input/-/pin-input-1.6.2.tgz#cc489cdb05ef5fe49d2cd361b3270b3a2bda886a" + integrity sha512-E3eRuYmLEiyRNUui6OTh5blXD8X0jvqFYl7Nc60g3Sqwux2myiBkFBSflNPl0CPFkdBg2OpzwPglHQsW/dXBHw== + dependencies: + "@chakra-ui/descendant" "2.0.1" + "@chakra-ui/hooks" "1.5.3" + "@chakra-ui/react-utils" "1.1.2" + "@chakra-ui/utils" "1.8.0" + +"@chakra-ui/popover@1.8.0": + version "1.8.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/popover/-/popover-1.8.0.tgz#7313fbef2bd0f9302c224611076258d9cbd17fb6" + integrity sha512-TNk5rztee9pen8vAQyBGuAxO0SpTvibJFqwnXDEFbDHDVd63HvH9IUNgQ4eB6hyh8kWrprTmU4KAnV5UDMvDWg== + dependencies: + "@chakra-ui/close-button" "1.1.9" + "@chakra-ui/hooks" "1.5.3" + "@chakra-ui/popper" "2.2.1" + "@chakra-ui/react-utils" "1.1.2" + "@chakra-ui/utils" "1.8.0" + +"@chakra-ui/popper@2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@chakra-ui/popper/-/popper-2.2.1.tgz#51d49933ee837b396d78d9daaab1d9809afea982" + integrity sha512-W0hMTBp2X62UooF3qPNmsEW0IJfz72gr2DN8nsCvHQrMiARB9s2jECEss6qEsB97tnmIG8k2TNee8IzTGLmMyA== + dependencies: + "@chakra-ui/react-utils" "1.1.2" + "@popperjs/core" "2.4.4" + +"@chakra-ui/portal@1.2.6": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@chakra-ui/portal/-/portal-1.2.6.tgz#6f6c927870ca645ee1a4abd0c0d003b9c3f57565" + integrity sha512-OqsMN50XTOJezjfXwO7VxiiVpXWQhe1ngAeGGHEPHxsnNA8LI66uk1+GX3YjjclbsLMKNdnS0WcNuCRKSv/AAA== + dependencies: + "@chakra-ui/hooks" "1.5.3" + "@chakra-ui/react-utils" "1.1.2" + "@chakra-ui/utils" "1.8.0" + +"@chakra-ui/progress@1.1.10": + version "1.1.10" + resolved "https://registry.yarnpkg.com/@chakra-ui/progress/-/progress-1.1.10.tgz#d8fadae56e57fa65324cff0c8c4b1e346961deca" + integrity sha512-9f5NN690GdF3rpPAhXVHgJHVSRUUXETHABFlzBsGZrr+AMzURo1xwp0USwzZrtzk4v9FpRy3Op/Td46oQodDSQ== + dependencies: + "@chakra-ui/theme-tools" "1.1.7" + "@chakra-ui/utils" "1.8.0" + +"@chakra-ui/radio@1.3.7": + version "1.3.7" + resolved "https://registry.yarnpkg.com/@chakra-ui/radio/-/radio-1.3.7.tgz#742b5262f2c07c4cc884783ef94b3f0bc78d96b9" + integrity sha512-CqZWmFLVyAnzGeRyxsubQ2lQLSSedDldox3Rul3EQpHbKLhG3QUE3lLiedpui1/cwal5Ero9AWxVCR7jAg7WZQ== + dependencies: + "@chakra-ui/form-control" "1.3.7" + "@chakra-ui/hooks" "1.5.3" + "@chakra-ui/react-utils" "1.1.2" + "@chakra-ui/utils" "1.8.0" + "@chakra-ui/visually-hidden" "1.0.12" + +"@chakra-ui/react-env@1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-env/-/react-env-1.0.4.tgz#b053d44d61b63dcf5997b24bdf2454bdcdb1b1ed" + integrity sha512-FkZR/WW7WI6LR3Wgm+OeuDhTNCcD77U/yWAxSo1tvEqqL5uUvD6Bi/Ko9E3lI5yhdoJ4t99ksf1vUBlrMG92vw== + dependencies: + "@chakra-ui/utils" "1.8.0" + +"@chakra-ui/react-utils@1.1.2", "@chakra-ui/react-utils@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@chakra-ui/react-utils/-/react-utils-1.1.2.tgz#7ea80b6ae25bd7b182095cc9ffaad23c464408b5" + integrity sha512-S8jPVKGZH2qF7ZGxl/0DF/dXXI2AxDNGf4Ahi2LGHqajMvqBB7vtYIRRmIA7+jAnErhzO8WUi3i4Z7oScp6xSA== + dependencies: + "@chakra-ui/utils" "^1.7.0" + +"@chakra-ui/react@^1.6.4": + version "1.6.4" + resolved "https://registry.yarnpkg.com/@chakra-ui/react/-/react-1.6.4.tgz#6c8c6d65cb07e7f80d08073caad41a50a65f7da3" + integrity sha512-TBsSNT7+UHmsilXWWXFmwn+mFmBqHhsnjn443B9rL5AlfYBzXKP75TrIJ4AnQdZtgvAdVwIbWEkzs4nXvxHcjw== + dependencies: + "@chakra-ui/accordion" "1.3.3" + "@chakra-ui/alert" "1.2.5" + "@chakra-ui/avatar" "1.2.6" + "@chakra-ui/breadcrumb" "1.2.6" + "@chakra-ui/button" "1.4.0" + "@chakra-ui/checkbox" "1.5.3" + "@chakra-ui/close-button" "1.1.9" + "@chakra-ui/control-box" "1.0.13" + "@chakra-ui/counter" "1.1.6" + "@chakra-ui/css-reset" "1.0.0" + "@chakra-ui/editable" "1.2.6" + "@chakra-ui/form-control" "1.3.7" + "@chakra-ui/hooks" "1.5.3" + "@chakra-ui/icon" "1.1.9" + "@chakra-ui/image" "1.0.16" + "@chakra-ui/input" "1.2.7" + "@chakra-ui/layout" "1.4.6" + "@chakra-ui/live-region" "1.0.12" + "@chakra-ui/media-query" "1.1.0" + "@chakra-ui/menu" "1.7.0" + "@chakra-ui/modal" "1.8.8" + "@chakra-ui/number-input" "1.2.7" + "@chakra-ui/pin-input" "1.6.2" + "@chakra-ui/popover" "1.8.0" + "@chakra-ui/popper" "2.2.1" + "@chakra-ui/portal" "1.2.6" + "@chakra-ui/progress" "1.1.10" + "@chakra-ui/radio" "1.3.7" + "@chakra-ui/react-env" "1.0.4" + "@chakra-ui/select" "1.1.11" + "@chakra-ui/skeleton" "1.1.15" + "@chakra-ui/slider" "1.2.6" + "@chakra-ui/spinner" "1.1.10" + "@chakra-ui/stat" "1.1.10" + "@chakra-ui/switch" "1.2.6" + "@chakra-ui/system" "1.7.0" + "@chakra-ui/table" "1.2.4" + "@chakra-ui/tabs" "1.5.2" + "@chakra-ui/tag" "1.1.10" + "@chakra-ui/textarea" "1.1.11" + "@chakra-ui/theme" "1.9.1" + "@chakra-ui/toast" "1.2.8" + "@chakra-ui/tooltip" "1.3.7" + "@chakra-ui/transition" "1.3.2" + "@chakra-ui/utils" "1.8.0" + "@chakra-ui/visually-hidden" "1.0.12" + +"@chakra-ui/select@1.1.11": + version "1.1.11" + resolved "https://registry.yarnpkg.com/@chakra-ui/select/-/select-1.1.11.tgz#918916ba0c74533d5651749a174d1c68d2f260bd" + integrity sha512-C/oAf0d2gZYcZnHurUF1wp174oLPe42nzetyqqDv1fmG7etaSMrVJTjR1EsWLkvrAsKDSNNAJ/acmcvsnOn9Sw== + dependencies: + "@chakra-ui/form-control" "1.3.7" + "@chakra-ui/utils" "1.8.0" + +"@chakra-ui/skeleton@1.1.15": + version "1.1.15" + resolved "https://registry.yarnpkg.com/@chakra-ui/skeleton/-/skeleton-1.1.15.tgz#88e19f0c670745a37de2941f9e756de12b0c30af" + integrity sha512-rknJe6h5XVKTN5ckZs+nN1riflgv1fis9qg3u6Q/XdafWT9AVYpZw77nbJDqz+KcBlZDNgrZRAhJ9Hj9IF9aCA== + dependencies: + "@chakra-ui/hooks" "1.5.3" + "@chakra-ui/media-query" "1.1.0" + "@chakra-ui/system" "1.7.0" + "@chakra-ui/utils" "1.8.0" + +"@chakra-ui/slider@1.2.6": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@chakra-ui/slider/-/slider-1.2.6.tgz#069c33ddaa330e7f7aae31dce072ddb18249a6ff" + integrity sha512-KAq9UvokPCUPwbRg4geDsXohR3Ii0A2R2w/JpgJDHRRQsHpZf8ClUVfSj7UkQaVbnGNybd34IIHRUbLR6SkE1Q== + dependencies: + "@chakra-ui/hooks" "1.5.3" + "@chakra-ui/react-utils" "1.1.2" + "@chakra-ui/utils" "1.8.0" + +"@chakra-ui/spinner@1.1.10": + version "1.1.10" + resolved "https://registry.yarnpkg.com/@chakra-ui/spinner/-/spinner-1.1.10.tgz#eb4abed7b45083bfdcb589b87eab5ef41811d51b" + integrity sha512-md5kFkoy3usp1sEv8m2SekNvXxdPbdx9aXHlknhhjPJB3UvYKZUPAQ/9sFr2edh89ZyVUXjt9Jh58YHDwtqCdg== + dependencies: + "@chakra-ui/utils" "1.8.0" + "@chakra-ui/visually-hidden" "1.0.12" + +"@chakra-ui/stat@1.1.10": + version "1.1.10" + resolved "https://registry.yarnpkg.com/@chakra-ui/stat/-/stat-1.1.10.tgz#a24017a8b506c29d979e94701f2975bb8ae4a875" + integrity sha512-5CX4kOVyI09/4/enXjaNOiU+MUmVKuzuxBa+a0esaD3+r3Gz17ssK0kJ9fsEdYSSXdOWlsM4Fi3L8ATQC2y9xA== + dependencies: + "@chakra-ui/icon" "1.1.9" + "@chakra-ui/utils" "1.8.0" + "@chakra-ui/visually-hidden" "1.0.12" + +"@chakra-ui/styled-system@1.12.0": + version "1.12.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/styled-system/-/styled-system-1.12.0.tgz#acc8f89aefa799dced8d5e805f1817fbd56cf837" + integrity sha512-bDs5K7ZnIeBcVOkaOSW/L8/b+ToEG0YH5+MtTxxK8OXwfoFKnuZKfxqwzcM2PDqg3LKb+qPcGBB+BkidTgUorg== + dependencies: + "@chakra-ui/utils" "1.8.0" + csstype "^3.0.6" + +"@chakra-ui/switch@1.2.6": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@chakra-ui/switch/-/switch-1.2.6.tgz#209c77a3797e075bba589e012aa12e09697bff5c" + integrity sha512-adQE3hPUlSu5A+kuVGyQyVMEO80OGECoHt5TCll2MQRxXI21xQ+VKBFrFpOJ5mmEoOLzjTGTtNQCrnf1iwjQ7g== + dependencies: + "@chakra-ui/checkbox" "1.5.3" + "@chakra-ui/utils" "1.8.0" + +"@chakra-ui/system@1.7.0": + version "1.7.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/system/-/system-1.7.0.tgz#2cd05beabeb5a2ceceaaa628760b194093ab93f4" + integrity sha512-/ke6XjsZ5RwSuxQh9BKdAZZ36buDmUjZb6lcYgYdPW365L9ZwFnT9jlIv3ch729O4xfzXPuIh1pCdrv+iu4PWw== + dependencies: + "@chakra-ui/color-mode" "1.1.9" + "@chakra-ui/react-utils" "1.1.2" + "@chakra-ui/styled-system" "1.12.0" + "@chakra-ui/utils" "1.8.0" + react-fast-compare "3.2.0" + +"@chakra-ui/table@1.2.4": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@chakra-ui/table/-/table-1.2.4.tgz#f2de9cea0fa0b37f9abb35222bf3ba5b7636bdb5" + integrity sha512-nB+kSy07d5v4WCsiUB86P0tfajL847VD3GDDauW+x0HlJRI0Q7UFOnJZGANM3VliA/LDci5PjIIDDAL3cW3ISg== + dependencies: + "@chakra-ui/utils" "1.8.0" + +"@chakra-ui/tabs@1.5.2": + version "1.5.2" + resolved "https://registry.yarnpkg.com/@chakra-ui/tabs/-/tabs-1.5.2.tgz#6c58d6d623bd58d981fa422992623a953f100dea" + integrity sha512-DJVuj/X349ZxlUUWxrlAXD2Ih6Hvs9fEbUU7aBzzLwVgLePoAz8yAXLJPtB2YlTa2+MTZcwWw76I5M8Ijcg3OA== + dependencies: + "@chakra-ui/clickable" "1.1.5" + "@chakra-ui/descendant" "2.0.1" + "@chakra-ui/hooks" "1.5.3" + "@chakra-ui/react-utils" "1.1.2" + "@chakra-ui/utils" "1.8.0" + +"@chakra-ui/tag@1.1.10": + version "1.1.10" + resolved "https://registry.yarnpkg.com/@chakra-ui/tag/-/tag-1.1.10.tgz#19e830bbe4064f9ad6ad25d1eae80fe0911f1968" + integrity sha512-pfwjohkbSewlm187rMZ4A6Mz4V/L170M0FQYCzGZ5avkotV/ecqILU4BLJp7uDT9x2FW8hsAsXv2whuHrpcosQ== + dependencies: + "@chakra-ui/icon" "1.1.9" + "@chakra-ui/utils" "1.8.0" + +"@chakra-ui/textarea@1.1.11": + version "1.1.11" + resolved "https://registry.yarnpkg.com/@chakra-ui/textarea/-/textarea-1.1.11.tgz#412fc396317bd03c52c39596a4456918be79b0c1" + integrity sha512-R2PmGcLP1zyBL5xK8IJuY66IKCsdEOpGlf5rJZOI/2XhUF1MrZTJveUHnkxur3O2JqGhJUxzY15rgwE17/vZcA== + dependencies: + "@chakra-ui/form-control" "1.3.7" + "@chakra-ui/utils" "1.8.0" + +"@chakra-ui/theme-tools@1.1.7", "@chakra-ui/theme-tools@^1.1.7": + version "1.1.7" + resolved "https://registry.yarnpkg.com/@chakra-ui/theme-tools/-/theme-tools-1.1.7.tgz#ffd3dc2d22a935e1a1df47b155c4cef60ff3f603" + integrity sha512-i8KpxjgoQPsoWAyHX+4kRMSioN9WVfyky+2sdFDHhEuDNL/iNYfKQMZjt8RR67apK/dSswMqh5UF2lWSM+lQhw== + dependencies: + "@chakra-ui/utils" "1.8.0" + "@types/tinycolor2" "1.4.2" + tinycolor2 "1.4.2" + +"@chakra-ui/theme@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@chakra-ui/theme/-/theme-1.9.1.tgz#2ddff69ea21e3e6a0e6fd9d4b9f77170c6145009" + integrity sha512-obIp4NAJsK2Eo7oWqv8iZESfpySCiQWypyAQ5hrwTTrk2bh4y9LC+5xKHyCHVZq1fu7OSS2fz6RpATwRBNtVFg== + dependencies: + "@chakra-ui/theme-tools" "1.1.7" + "@chakra-ui/utils" "1.8.0" + +"@chakra-ui/toast@1.2.8": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@chakra-ui/toast/-/toast-1.2.8.tgz#903075674e0cf73f384a740835c6f51044ae1d9c" + integrity sha512-00MxuNXWvdWvAS4D5BDfQlL1/3qcZfZeLnJwTU774t/+yjh5j5/GFLoOBwKboX0ViGrcH7MoCgvUfkaAJ1Yd1w== + dependencies: + "@chakra-ui/alert" "1.2.5" + "@chakra-ui/close-button" "1.1.9" + "@chakra-ui/hooks" "1.5.3" + "@chakra-ui/theme" "1.9.1" + "@chakra-ui/transition" "1.3.2" + "@chakra-ui/utils" "1.8.0" + "@reach/alert" "0.13.2" + +"@chakra-ui/tooltip@1.3.7": + version "1.3.7" + resolved "https://registry.yarnpkg.com/@chakra-ui/tooltip/-/tooltip-1.3.7.tgz#b9b8cdd95e51dd440e450a686b7070fd01b612df" + integrity sha512-gz/Tfdkg9UYMMzfzgxMTGyCSMyHyco6nOhPGviz4MJWH8RsAH2MQ4Qj4TcK21L1hkWIsC8kSSjAQ381RNY0Q6g== + dependencies: + "@chakra-ui/hooks" "1.5.3" + "@chakra-ui/popper" "2.2.1" + "@chakra-ui/portal" "1.2.6" + "@chakra-ui/react-utils" "1.1.2" + "@chakra-ui/utils" "1.8.0" + "@chakra-ui/visually-hidden" "1.0.12" + +"@chakra-ui/transition@1.3.2": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@chakra-ui/transition/-/transition-1.3.2.tgz#4f0f5ba8d1d74978d5e6c04001d82b3da74da251" + integrity sha512-Rk15J23z96l1YjyNww7cIxdVEXj/slgspv7tYh1ugh0DFR6XebRwKBxXt5FRYp0d4+0CobJ6gvuiUsfYGS2roA== + dependencies: + "@chakra-ui/utils" "1.8.0" + +"@chakra-ui/utils@1.8.0", "@chakra-ui/utils@^1.7.0", "@chakra-ui/utils@^1.8.0": + version "1.8.0" + resolved "https://registry.yarnpkg.com/@chakra-ui/utils/-/utils-1.8.0.tgz#f7aad8175cc5a26a1d2795dc78691bbc21fd539e" + integrity sha512-BWIhKcXnLbOIwCTKeNcOStNwk9RyYVA9xRRFPGK6Kp3EhrxP0rDwAbu4D3o3qAc+yhIDhGmPaIj1jRXHB5DTfg== + dependencies: + "@types/lodash.mergewith" "4.6.6" + css-box-model "1.2.1" + framesync "5.3.0" + lodash.mergewith "4.6.2" + +"@chakra-ui/visually-hidden@1.0.12": + version "1.0.12" + resolved "https://registry.yarnpkg.com/@chakra-ui/visually-hidden/-/visually-hidden-1.0.12.tgz#9a5cf5c65c2e933a891442c4dd66767cf2f5f75f" + integrity sha512-CSRH1ySzI3QYP5QFrLFWgpy40rpddGn4Z+BjsZ5pf+FGp/KUEpFKUx8nZyGfHlT+flMCj6Tpu7ftPyWCh1HERg== + dependencies: + "@chakra-ui/utils" "1.8.0" + "@changesets/apply-release-plan@5.0.0", "@changesets/apply-release-plan@^5.0.0": version "5.0.0" resolved "https://registry.yarnpkg.com/@changesets/apply-release-plan/-/apply-release-plan-5.0.0.tgz#11bf168acecbf4cfa2b0e6425160bac5ceeec1c3" @@ -1409,371 +1923,23 @@ human-id "^1.0.2" prettier "^1.19.1" -"@docsearch/css@3.0.0-alpha.34": - version "3.0.0-alpha.34" - resolved "https://registry.yarnpkg.com/@docsearch/css/-/css-3.0.0-alpha.34.tgz#5d5c39955956e237884a9997eb29e28c8adc99fa" - integrity sha512-ZUbmxbN9gQp3vuBo9GDnm+ywB9aZQSh0ogjt6865PmeRUvyCCvgSwyZktliLPvAztoGX56qewQjxNcso3RrSow== - -"@docsearch/react@^3.0.0-alpha.33": - version "3.0.0-alpha.34" - resolved "https://registry.yarnpkg.com/@docsearch/react/-/react-3.0.0-alpha.34.tgz#fb7e31e31593c26dadb607b9451d274b84b0b05a" - integrity sha512-BBVxu2qY1fyhxJfrGZvknFL6j1fJ3wLZvf2DsmVfmihu/RhYYnf8/C1gbc7RWX2fSoSzbQCcSuNbn4RvjuUJ+A== +"@emotion/babel-plugin@^11.3.0": + version "11.3.0" + resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.3.0.tgz#3a16850ba04d8d9651f07f3fb674b3436a4fb9d7" + integrity sha512-UZKwBV2rADuhRp+ZOGgNWg2eYgbzKzQXfQPtJbu/PLy8onurxlNCLvxMQEvlr1/GudguPI5IU9qIY1+2z1M5bA== dependencies: - "@algolia/autocomplete-core" "1.0.0-alpha.44" - "@algolia/autocomplete-preset-algolia" "1.0.0-alpha.44" - "@docsearch/css" "3.0.0-alpha.34" - algoliasearch "^4.0.0" - -"@docusaurus/core@2.0.0-beta.ff31de0ff": - version "2.0.0-beta.ff31de0ff" - resolved "https://registry.yarnpkg.com/@docusaurus/core/-/core-2.0.0-beta.ff31de0ff.tgz#60941dfac5612b57ea34012753e381a4b25c8f88" - integrity sha512-+4Mmm5Zi1AvnFi0r/KfwSrXqOVQQPXQN610KcwrNsfXvq2QTR5O7QwXzUdZSERLQ183+iI1PD4x7bAiSSmwUBw== - dependencies: - "@babel/core" "^7.12.16" - "@babel/generator" "^7.12.15" - "@babel/plugin-syntax-dynamic-import" "^7.8.3" - "@babel/plugin-transform-runtime" "^7.12.15" - "@babel/preset-env" "^7.12.16" - "@babel/preset-react" "^7.12.13" - "@babel/preset-typescript" "^7.12.16" - "@babel/runtime" "^7.12.5" - "@babel/runtime-corejs3" "^7.12.13" - "@babel/traverse" "^7.12.13" - "@docusaurus/cssnano-preset" "2.0.0-beta.ff31de0ff" - "@docusaurus/react-loadable" "5.5.0" - "@docusaurus/types" "2.0.0-beta.ff31de0ff" - "@docusaurus/utils" "2.0.0-beta.ff31de0ff" - "@docusaurus/utils-validation" "2.0.0-beta.ff31de0ff" - "@endiliey/static-site-generator-webpack-plugin" "^4.0.0" - "@svgr/webpack" "^5.5.0" - autoprefixer "^10.2.5" - babel-loader "^8.2.2" - babel-plugin-dynamic-import-node "2.3.0" - boxen "^5.0.1" - chalk "^4.1.1" - chokidar "^3.5.1" - clean-css "^5.1.2" - commander "^5.1.0" - copy-webpack-plugin "^8.1.1" - core-js "^3.9.1" - css-loader "^5.1.1" - css-minimizer-webpack-plugin "^2.0.0" - cssnano "^5.0.4" - del "^6.0.0" - detect-port "^1.3.0" - eta "^1.12.1" - express "^4.17.1" - file-loader "^6.2.0" - fs-extra "^10.0.0" - github-slugger "^1.3.0" - globby "^11.0.2" - html-minifier-terser "^5.1.1" - html-tags "^3.1.0" - html-webpack-plugin "^5.3.1" - import-fresh "^3.3.0" - is-root "^2.1.0" - leven "^3.1.0" - lodash "^4.17.20" - mini-css-extract-plugin "^1.6.0" - module-alias "^2.2.2" - nprogress "^0.2.0" - postcss "^8.2.15" - postcss-loader "^5.3.0" - prompts "^2.4.1" - react-dev-utils "^11.0.1" - react-error-overlay "^6.0.9" - react-helmet "^6.1.0" - react-loadable "^5.5.0" - react-loadable-ssr-addon-v5-slorber "^1.0.1" - react-router "^5.2.0" - react-router-config "^5.1.1" - react-router-dom "^5.2.0" - resolve-pathname "^3.0.0" - rtl-detect "^1.0.3" - semver "^7.3.4" - serve-handler "^6.1.3" - shelljs "^0.8.4" - std-env "^2.2.1" - strip-ansi "^6.0.0" - terser-webpack-plugin "^5.1.2" - tslib "^2.2.0" - update-notifier "^5.1.0" - url-loader "^4.1.1" - wait-on "^5.3.0" - webpack "^5.37.0" - webpack-bundle-analyzer "^4.4.2" - webpack-dev-server "^3.11.2" - webpack-merge "^5.7.3" - webpackbar "^5.0.0-3" - -"@docusaurus/cssnano-preset@2.0.0-beta.ff31de0ff": - version "2.0.0-beta.ff31de0ff" - resolved "https://registry.yarnpkg.com/@docusaurus/cssnano-preset/-/cssnano-preset-2.0.0-beta.ff31de0ff.tgz#9c2c64b58da67311c27c17e020451ed22100b9ad" - integrity sha512-yoiQSxzYYWXqNgVfXG0gdsx28lUDi/vGvCpE1qZXX/0Nxyy3fOdWbktmaBx+qJrR+xD+SdGJXVuwX0w95NiIYQ== - dependencies: - cssnano-preset-advanced "^5.1.1" - postcss "^8.2.15" - postcss-sort-media-queries "^3.10.11" - -"@docusaurus/mdx-loader@2.0.0-beta.ff31de0ff": - version "2.0.0-beta.ff31de0ff" - resolved "https://registry.yarnpkg.com/@docusaurus/mdx-loader/-/mdx-loader-2.0.0-beta.ff31de0ff.tgz#80fb06c4ec1f6dc081b618f9b6d8b10935ee245b" - integrity sha512-cgZuUFxUNui3UMlA4es2Bc71HS6DEnmDQ74UdZlxCvRZXASgoT2a8T2ATilSmT1b7srgWmBORAqsJ154tW+R5w== - dependencies: - "@babel/parser" "^7.12.16" - "@babel/traverse" "^7.12.13" - "@docusaurus/core" "2.0.0-beta.ff31de0ff" - "@docusaurus/utils" "2.0.0-beta.ff31de0ff" - "@mdx-js/mdx" "^1.6.21" - "@mdx-js/react" "^1.6.21" - escape-html "^1.0.3" - file-loader "^6.2.0" - fs-extra "^10.0.0" - github-slugger "^1.3.0" - gray-matter "^4.0.3" - mdast-util-to-string "^2.0.0" - remark-emoji "^2.1.0" - stringify-object "^3.3.0" - unist-util-visit "^2.0.2" - url-loader "^4.1.1" - webpack "^5.37.0" - -"@docusaurus/plugin-content-blog@2.0.0-beta.ff31de0ff": - version "2.0.0-beta.ff31de0ff" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-blog/-/plugin-content-blog-2.0.0-beta.ff31de0ff.tgz#41939c9588ddc34e5f3ca9f5119dbb97405375be" - integrity sha512-abd9Fnqn7kYifIVUdYVwC9yeG2lEBFn3T0fNREplmrjtdNQUWfXx8hGMKOhigXmIzWjGdqtti3/2pLmRxomNIA== - dependencies: - "@docusaurus/core" "2.0.0-beta.ff31de0ff" - "@docusaurus/mdx-loader" "2.0.0-beta.ff31de0ff" - "@docusaurus/types" "2.0.0-beta.ff31de0ff" - "@docusaurus/utils" "2.0.0-beta.ff31de0ff" - "@docusaurus/utils-validation" "2.0.0-beta.ff31de0ff" - chalk "^4.1.1" - feed "^4.2.2" - fs-extra "^10.0.0" - globby "^11.0.2" - loader-utils "^2.0.0" - lodash "^4.17.20" - reading-time "^1.3.0" - remark-admonitions "^1.2.1" - tslib "^2.2.0" - webpack "^5.37.0" - -"@docusaurus/plugin-content-docs@2.0.0-beta.ff31de0ff": - version "2.0.0-beta.ff31de0ff" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-docs/-/plugin-content-docs-2.0.0-beta.ff31de0ff.tgz#dd9f162bfd44f129c1ae5976332276540b46de8e" - integrity sha512-OSwna5U19PUw2GOKd4ZgYIfisVLXsmwVNYpsrIznNnTeschbpdcowRbfgxAxzwglRMwPbP7WkoqI4D5M0x5BJg== - dependencies: - "@docusaurus/core" "2.0.0-beta.ff31de0ff" - "@docusaurus/mdx-loader" "2.0.0-beta.ff31de0ff" - "@docusaurus/types" "2.0.0-beta.ff31de0ff" - "@docusaurus/utils" "2.0.0-beta.ff31de0ff" - "@docusaurus/utils-validation" "2.0.0-beta.ff31de0ff" - chalk "^4.1.1" - combine-promises "^1.1.0" - execa "^5.0.0" - fs-extra "^10.0.0" - globby "^11.0.2" - import-fresh "^3.2.2" - js-yaml "^4.0.0" - loader-utils "^1.2.3" - lodash "^4.17.20" - remark-admonitions "^1.2.1" - shelljs "^0.8.4" - tslib "^2.2.0" - utility-types "^3.10.0" - webpack "^5.37.0" - -"@docusaurus/plugin-content-pages@2.0.0-beta.ff31de0ff": - version "2.0.0-beta.ff31de0ff" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-pages/-/plugin-content-pages-2.0.0-beta.ff31de0ff.tgz#01c5033a74dfa4f01c87a43c9011fcd26ef16a9d" - integrity sha512-6JhUrzofphDA5qxD1CMzQ4bNnS6tbCeklC6ld7D/ubqfb0/vLxQBixGwMSkkxlTGsa8eEcjh4W4fAoUjGnTXOg== - dependencies: - "@docusaurus/core" "2.0.0-beta.ff31de0ff" - "@docusaurus/mdx-loader" "2.0.0-beta.ff31de0ff" - "@docusaurus/types" "2.0.0-beta.ff31de0ff" - "@docusaurus/utils" "2.0.0-beta.ff31de0ff" - "@docusaurus/utils-validation" "2.0.0-beta.ff31de0ff" - globby "^11.0.2" - lodash "^4.17.20" - minimatch "^3.0.4" - remark-admonitions "^1.2.1" - slash "^3.0.0" - tslib "^2.1.0" - webpack "^5.28.0" - -"@docusaurus/plugin-debug@2.0.0-beta.ff31de0ff": - version "2.0.0-beta.ff31de0ff" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-debug/-/plugin-debug-2.0.0-beta.ff31de0ff.tgz#6643006e300482913dc060ea2cebd94e1c242e7e" - integrity sha512-5cNs/HbtWh3nn3Bim35XN0KtfleyR6Ju07Yt7RKdlvPCRNKm/wUtFEcUayuuY6nyyF9WYvjH/k7rd4AhO098AA== - dependencies: - "@docusaurus/core" "2.0.0-beta.ff31de0ff" - "@docusaurus/types" "2.0.0-beta.ff31de0ff" - "@docusaurus/utils" "2.0.0-beta.ff31de0ff" - react-json-view "^1.21.3" - tslib "^2.1.0" - -"@docusaurus/plugin-google-analytics@2.0.0-beta.ff31de0ff": - version "2.0.0-beta.ff31de0ff" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-2.0.0-beta.ff31de0ff.tgz#cef062d4847033064df66116ae1d91e6a3800d38" - integrity sha512-An3rdHpVjf8RZiZqxcQMO+nTE6vz6isowP1QsfPjiyVLFercQ116RuBodUTjkyOV/rCL1bHvdh9B2G8dp79Zbw== - dependencies: - "@docusaurus/core" "2.0.0-beta.ff31de0ff" - -"@docusaurus/plugin-google-gtag@2.0.0-beta.ff31de0ff": - version "2.0.0-beta.ff31de0ff" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-2.0.0-beta.ff31de0ff.tgz#74b3de7a8bd3bae8da21e39616c067b4ecdadd74" - integrity sha512-4nNafEi8wfikxVKY8JKClglSP0vd5ahlSix4b1wsYNcPqxeJQHwx2VIkRDIPdvO9ySFdRMetzWr/pNMsxb/xpA== - dependencies: - "@docusaurus/core" "2.0.0-beta.ff31de0ff" - -"@docusaurus/plugin-sitemap@2.0.0-beta.ff31de0ff": - version "2.0.0-beta.ff31de0ff" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-sitemap/-/plugin-sitemap-2.0.0-beta.ff31de0ff.tgz#4d96e383015bc3d25f3f96c721aa03926a99ae71" - integrity sha512-4z0hpdlPgwWU9sVVUdwiHCgnm7IVvAw8LaEzZmbMfZcVON3ImGNOHRMxgN85C29xWT/QwSx6k9NL+paB/gorGQ== - dependencies: - "@docusaurus/core" "2.0.0-beta.ff31de0ff" - "@docusaurus/types" "2.0.0-beta.ff31de0ff" - "@docusaurus/utils" "2.0.0-beta.ff31de0ff" - "@docusaurus/utils-validation" "2.0.0-beta.ff31de0ff" - fs-extra "^10.0.0" - sitemap "^7.0.0" - tslib "^2.2.0" - -"@docusaurus/preset-classic@2.0.0-beta.ff31de0ff": - version "2.0.0-beta.ff31de0ff" - resolved "https://registry.yarnpkg.com/@docusaurus/preset-classic/-/preset-classic-2.0.0-beta.ff31de0ff.tgz#94c750aa5dfc5686d451f51e67acaf5bb3532be9" - integrity sha512-kXTtH1CygI7+jL/Tr2gQwGytE4IZti/Nep7f3p+i0I4euihMz90413CUHdp6/jx3HnrzcO5lPKAfdlZXbKh5Rw== - dependencies: - "@docusaurus/core" "2.0.0-beta.ff31de0ff" - "@docusaurus/plugin-content-blog" "2.0.0-beta.ff31de0ff" - "@docusaurus/plugin-content-docs" "2.0.0-beta.ff31de0ff" - "@docusaurus/plugin-content-pages" "2.0.0-beta.ff31de0ff" - "@docusaurus/plugin-debug" "2.0.0-beta.ff31de0ff" - "@docusaurus/plugin-google-analytics" "2.0.0-beta.ff31de0ff" - "@docusaurus/plugin-google-gtag" "2.0.0-beta.ff31de0ff" - "@docusaurus/plugin-sitemap" "2.0.0-beta.ff31de0ff" - "@docusaurus/theme-classic" "2.0.0-beta.ff31de0ff" - "@docusaurus/theme-search-algolia" "2.0.0-beta.ff31de0ff" - -"@docusaurus/react-loadable@5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@docusaurus/react-loadable/-/react-loadable-5.5.0.tgz#6d6f0c8fd9a434b62a1ab1f8645ee7bde5a9ec21" - integrity sha512-Ld/kwUE6yATIOTLq3JCsWiTa/drisajwKqBQ2Rw6IcT+sFsKfYek8F2jSH8f68AT73xX97UehduZeCSlnuCBIg== - dependencies: - prop-types "^15.6.2" - -"@docusaurus/theme-classic@2.0.0-beta.ff31de0ff": - version "2.0.0-beta.ff31de0ff" - resolved "https://registry.yarnpkg.com/@docusaurus/theme-classic/-/theme-classic-2.0.0-beta.ff31de0ff.tgz#99eaeb18d4a236c9b401be0793f4391860fece88" - integrity sha512-qiV+rgqZIKSzd0DKPgCQCyBP/LQiocqhhwIAWoOxvhbeUx4mmBAt2JtrQQnvg5jPOpa6uKVDu0JAamE1ldP5rg== - dependencies: - "@docusaurus/core" "2.0.0-beta.ff31de0ff" - "@docusaurus/plugin-content-blog" "2.0.0-beta.ff31de0ff" - "@docusaurus/plugin-content-docs" "2.0.0-beta.ff31de0ff" - "@docusaurus/plugin-content-pages" "2.0.0-beta.ff31de0ff" - "@docusaurus/theme-common" "2.0.0-beta.ff31de0ff" - "@docusaurus/types" "2.0.0-beta.ff31de0ff" - "@docusaurus/utils" "2.0.0-beta.ff31de0ff" - "@docusaurus/utils-validation" "2.0.0-beta.ff31de0ff" - "@mdx-js/mdx" "^1.6.21" - "@mdx-js/react" "^1.6.21" - chalk "^4.1.1" - clsx "^1.1.1" - copy-text-to-clipboard "^3.0.1" - fs-extra "^10.0.0" - globby "^11.0.2" - infima "0.2.0-alpha.23" - lodash "^4.17.20" - parse-numeric-range "^1.2.0" - postcss "^8.2.15" - prism-react-renderer "^1.2.1" - prismjs "^1.23.0" - prop-types "^15.7.2" - react-router-dom "^5.2.0" - rtlcss "^3.1.2" - -"@docusaurus/theme-common@2.0.0-beta.ff31de0ff": - version "2.0.0-beta.ff31de0ff" - resolved "https://registry.yarnpkg.com/@docusaurus/theme-common/-/theme-common-2.0.0-beta.ff31de0ff.tgz#080413342c3e0b36b86dfc17ae0fc9ada5cd8fa3" - integrity sha512-v98AvBy3F2qWuqofN30E/lvrA/B0eh+0g9Ly5Y3ZSJxMovGazp8jbP1YJ6pnz+ttUvbZEOFLpV9SUMe7ZMcB4Q== - dependencies: - "@docusaurus/core" "2.0.0-beta.ff31de0ff" - "@docusaurus/plugin-content-blog" "2.0.0-beta.ff31de0ff" - "@docusaurus/plugin-content-docs" "2.0.0-beta.ff31de0ff" - "@docusaurus/plugin-content-pages" "2.0.0-beta.ff31de0ff" - "@docusaurus/types" "2.0.0-beta.ff31de0ff" - tslib "^2.1.0" - -"@docusaurus/theme-search-algolia@2.0.0-beta.ff31de0ff": - version "2.0.0-beta.ff31de0ff" - resolved "https://registry.yarnpkg.com/@docusaurus/theme-search-algolia/-/theme-search-algolia-2.0.0-beta.ff31de0ff.tgz#d40b75f390292e3c5362b30fd65daf02601e4022" - integrity sha512-eTtObHogSlC+FGMhR7f5LAt3q3S8UCsJ3x0OMCnZM8AF6NS7aMJX26T4isyDv1j6xY3quUJiortFLyZ65Is78g== - dependencies: - "@docsearch/react" "^3.0.0-alpha.33" - "@docusaurus/core" "2.0.0-beta.ff31de0ff" - "@docusaurus/theme-common" "2.0.0-beta.ff31de0ff" - "@docusaurus/utils" "2.0.0-beta.ff31de0ff" - "@docusaurus/utils-validation" "2.0.0-beta.ff31de0ff" - algoliasearch "^4.8.4" - algoliasearch-helper "^3.3.4" - clsx "^1.1.1" - eta "^1.12.1" - lodash "^4.17.20" - -"@docusaurus/types@2.0.0-beta.ff31de0ff": - version "2.0.0-beta.ff31de0ff" - resolved "https://registry.yarnpkg.com/@docusaurus/types/-/types-2.0.0-beta.ff31de0ff.tgz#76fd185206d24fc83e1436c812e4d995a31b23b3" - integrity sha512-7kr1nCXtlRlU5PyBgQJzAxpamCnZcMz1syjzMWGR5Njxt4ejXIBz3nPpLA5DPoVpFqi5BhCld5V2wQ/JhAYV9w== - dependencies: - commander "^5.1.0" - joi "^17.4.0" - querystring "0.2.0" - webpack "^5.37.0" - webpack-merge "^5.7.3" - -"@docusaurus/utils-validation@2.0.0-beta.ff31de0ff": - version "2.0.0-beta.ff31de0ff" - resolved "https://registry.yarnpkg.com/@docusaurus/utils-validation/-/utils-validation-2.0.0-beta.ff31de0ff.tgz#0964cf29a7f729e6587511161ba1aac6890985d9" - integrity sha512-IcgA+nqQvCakMSCkf2Lxs5rVGRvBpgyhtq9O1XKGfFU30gxVgB2xySUxQrfzGcmCjJaZ8G8xtF7PD3BfB3pZiw== - dependencies: - "@docusaurus/utils" "2.0.0-beta.ff31de0ff" - chalk "^4.1.1" - joi "^17.4.0" - tslib "^2.1.0" - -"@docusaurus/utils@2.0.0-beta.ff31de0ff": - version "2.0.0-beta.ff31de0ff" - resolved "https://registry.yarnpkg.com/@docusaurus/utils/-/utils-2.0.0-beta.ff31de0ff.tgz#9ab821b6820f25116a932aeb022854251e620cae" - integrity sha512-Dr8qOjScfSVpMMxxb4UsEl2bReRMmflcsJ+gKwfx73lOvXFOcYF2+zF0h0Hy8PRzxiEhTBus7/6S0U8YoYNWvQ== - dependencies: - "@docusaurus/types" "2.0.0-beta.ff31de0ff" - "@types/github-slugger" "^1.3.0" - chalk "^4.1.1" - escape-string-regexp "^4.0.0" - fs-extra "^10.0.0" - gray-matter "^4.0.3" - lodash "^4.17.20" - resolve-pathname "^3.0.0" - tslib "^2.2.0" - -"@emotion/babel-plugin@^11.3.0": - version "11.3.0" - resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.3.0.tgz#3a16850ba04d8d9651f07f3fb674b3436a4fb9d7" - integrity sha512-UZKwBV2rADuhRp+ZOGgNWg2eYgbzKzQXfQPtJbu/PLy8onurxlNCLvxMQEvlr1/GudguPI5IU9qIY1+2z1M5bA== - dependencies: - "@babel/helper-module-imports" "^7.12.13" - "@babel/plugin-syntax-jsx" "^7.12.13" - "@babel/runtime" "^7.13.10" - "@emotion/hash" "^0.8.0" - "@emotion/memoize" "^0.7.5" - "@emotion/serialize" "^1.0.2" - babel-plugin-macros "^2.6.1" - convert-source-map "^1.5.0" - escape-string-regexp "^4.0.0" - find-root "^1.1.0" - source-map "^0.5.7" - stylis "^4.0.3" + "@babel/helper-module-imports" "^7.12.13" + "@babel/plugin-syntax-jsx" "^7.12.13" + "@babel/runtime" "^7.13.10" + "@emotion/hash" "^0.8.0" + "@emotion/memoize" "^0.7.5" + "@emotion/serialize" "^1.0.2" + babel-plugin-macros "^2.6.1" + convert-source-map "^1.5.0" + escape-string-regexp "^4.0.0" + find-root "^1.1.0" + source-map "^0.5.7" + stylis "^4.0.3" "@emotion/cache@^11.4.0": version "11.4.0" @@ -1791,7 +1957,7 @@ resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.8.0.tgz#bbbff68978fefdbe68ccb533bc8cbe1d1afb5413" integrity sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow== -"@emotion/is-prop-valid@^0.8.8": +"@emotion/is-prop-valid@^0.8.2": version "0.8.8" resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a" integrity sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA== @@ -1855,12 +2021,7 @@ "@emotion/serialize" "^1.0.2" "@emotion/utils" "^1.0.0" -"@emotion/stylis@^0.8.4": - version "0.8.5" - resolved "https://registry.yarnpkg.com/@emotion/stylis/-/stylis-0.8.5.tgz#deacb389bd6ee77d1e7fcaccce9e16c5c7e78e04" - integrity sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ== - -"@emotion/unitless@^0.7.4", "@emotion/unitless@^0.7.5": +"@emotion/unitless@^0.7.5": version "0.7.5" resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.5.tgz#77211291c1900a700b8a78cfafda3160d76949ed" integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg== @@ -1875,17 +2036,6 @@ resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz#8eed982e2ee6f7f4e44c253e12962980791efd46" integrity sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA== -"@endiliey/static-site-generator-webpack-plugin@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@endiliey/static-site-generator-webpack-plugin/-/static-site-generator-webpack-plugin-4.0.0.tgz#94bfe58fd83aeda355de797fcb5112adaca3a6b1" - integrity sha512-3MBqYCs30qk1OBRC697NqhGouYbs71D1B8hrk/AFJC6GwF2QaJOQZtA1JYAaGSe650sZ8r5ppRTtCRXepDWlng== - dependencies: - bluebird "^3.7.1" - cheerio "^0.22.0" - eval "^0.1.4" - url "^0.11.0" - webpack-sources "^1.4.3" - "@eslint/eslintrc@^0.4.2": version "0.4.2" resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.2.tgz#f63d0ef06f5c0c57d76c4ab5f63d3835c51b0179" @@ -1901,39 +2051,95 @@ minimatch "^3.0.4" strip-json-comments "^3.1.1" -"@fullhuman/postcss-purgecss@^3.1.3": - version "3.1.3" - resolved "https://registry.yarnpkg.com/@fullhuman/postcss-purgecss/-/postcss-purgecss-3.1.3.tgz#47af7b87c9bfb3de4bc94a38f875b928fffdf339" - integrity sha512-kwOXw8fZ0Lt1QmeOOrd+o4Ibvp4UTEBFQbzvWldjlKv5n+G9sXfIPn1hh63IQIL8K8vbvv1oYMJiIUbuy9bGaA== - dependencies: - purgecss "^3.1.3" - -"@graphql-tools/mock@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@graphql-tools/mock/-/mock-7.0.0.tgz#b43858f47fedfbf7d8bbbf7d33e6acb64b8b7da7" - integrity sha512-ShO8D9HudgnhqoWeKb3iejGtPV8elFqSO1U0O70g3FH3W/CBW2abXfuyodBUevXVGIjyqzfkNzVtpIE0qiOVVQ== +"@fullhuman/postcss-purgecss@^4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@fullhuman/postcss-purgecss/-/postcss-purgecss-4.0.3.tgz#55d71712ec1c7a88e0d1ba5f10ce7fb6aa05beb4" + integrity sha512-/EnQ9UDWGGqHkn1UKAwSgh+gJHPKmD+Z+5dQ4gWT4qq2NUyez3zqAfZNwFH3eSgmgO+wjTXfhlLchx2M9/K+7Q== dependencies: - "@graphql-tools/schema" "^7.0.0" - "@graphql-tools/utils" "^7.0.0" - tslib "~2.0.1" + purgecss "^4.0.3" "@graphql-typed-document-node/core@^3.0.0": version "3.1.0" resolved "https://registry.yarnpkg.com/@graphql-typed-document-node/core/-/core-3.1.0.tgz#0eee6373e11418bfe0b5638f654df7a4ca6a3950" integrity sha512-wYn6r8zVZyQJ6rQaALBEln5B1pzxb9shV5Ef97kTvn6yVGrqyXVnDqnU24MXnFubR+rZjBY9NWuxX3FB2sTsjg== -"@hapi/hoek@^9.0.0": - version "9.1.1" - resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.1.1.tgz#9daf5745156fd84b8e9889a2dc721f0c58e894aa" - integrity sha512-CAEbWH7OIur6jEOzaai83jq3FmKmv4PmX1JYfs9IrYcGEVI/lyL1EXJGCj7eFVJ0bg5QR8LMxBlEtA+xKiLpFw== +"@guild-docs/client@^0.2.14": + version "0.2.18" + resolved "https://registry.yarnpkg.com/@guild-docs/client/-/client-0.2.18.tgz#44f53bf5217ed949176203a6c817849d288938a7" + integrity sha512-O+Q3GKVhSCYRMO3CCkHb21vSJTW8HPH2yEXONZHiwPTr/zhOilTYq/MP2P66JjY5I17eIka7JYLLO3meYXkBlQ== + dependencies: + "@guild-docs/types" "^0.2.17" + immer "^9.0.3" + next-mdx-remote "^3.0.2" + next-seo "^4.26.0" + nprogress "^0.2.0" + react-icons "^4.2.0" + react-intersection-observer "^8.32.0" + react-use "^17.2.4" + use-immer "^0.6.0" + zustand "^3.5.5" + +"@guild-docs/server@^0.2.13": + version "0.2.18" + resolved "https://registry.yarnpkg.com/@guild-docs/server/-/server-0.2.18.tgz#f6fee8f73729f49ef614a4e052351f6745a6341a" + integrity sha512-XGJ+y79DwkTOvYu0O2Pvu3wig6hmkUuZwMUw6h7/E8rzm1SR19M8isQzqWPC7whBAw6GosHvsnAjGHzCqIQ6pQ== + dependencies: + "@guild-docs/types" "^0.2.16" + github-slugger "^1.3.0" + globby "^11.0.4" + gray-matter "^4.0.3" + next-mdx-remote "^3.0.2" + npms.io "^2.0.6" + remark-emoji "^2.2.0" + remark-slug "^6.0.0" + tiny-lru "^7.0.6" + +"@guild-docs/types@^0.2.16", "@guild-docs/types@^0.2.17": + version "0.2.17" + resolved "https://registry.yarnpkg.com/@guild-docs/types/-/types-0.2.17.tgz#796927a483f200d78b69bd17ac93c290ec5de8d8" + integrity sha512-U9zUTOX3KRC+ZollJ9/5y4Jrpd0QB4IyicGL12G1c55Y5tLtZ2hQr8gWk92YEPFsmrH+1UmMjIvOToLynuD7qA== + +"@hapi/accept@5.0.2": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@hapi/accept/-/accept-5.0.2.tgz#ab7043b037e68b722f93f376afb05e85c0699523" + integrity sha512-CmzBx/bXUR8451fnZRuZAJRlzgm0Jgu5dltTX/bszmR2lheb9BpyN47Q1RbaGTsvFzn0PXAEs+lXDKfshccYZw== + dependencies: + "@hapi/boom" "9.x.x" + "@hapi/hoek" "9.x.x" + +"@hapi/boom@9.x.x": + version "9.1.3" + resolved "https://registry.yarnpkg.com/@hapi/boom/-/boom-9.1.3.tgz#22cad56e39b7a4819161a99b1db19eaaa9b6cc6e" + integrity sha512-RlrGyZ603hE/eRTZtTltocRm50HHmrmL3kGOP0SQ9MasazlW1mt/fkv4C5P/6rnpFXjwld/POFX1C8tMZE3ldg== + dependencies: + "@hapi/hoek" "9.x.x" + +"@hapi/hoek@9.x.x", "@hapi/hoek@^9.0.0": + version "9.2.0" + resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.2.0.tgz#f3933a44e365864f4dad5db94158106d511e8131" + integrity sha512-sqKVVVOe5ivCaXDWivIJYVSaEgdQK9ul7a4Kity5Iw7u9+wBAPbX1RMSnLLmp7O4Vzj0WOWwMAJsTL00xwaNug== "@hapi/topo@^5.0.0": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-5.0.0.tgz#c19af8577fa393a06e9c77b60995af959be721e7" - integrity sha512-tFJlT47db0kMqVm3H4nQYgn6Pwg10GTZHb1pwmSiv1K4ks6drQOtfEF5ZnPjkvC+y4/bUPHK+bc87QvLcL+WMw== + version "5.1.0" + resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-5.1.0.tgz#dc448e332c6c6e37a4dc02fd84ba8d44b9afb012" + integrity sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg== dependencies: "@hapi/hoek" "^9.0.0" +"@humanwhocodes/config-array@^0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9" + integrity sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg== + dependencies: + "@humanwhocodes/object-schema" "^1.2.0" + debug "^4.1.1" + minimatch "^3.0.4" + +"@humanwhocodes/object-schema@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz#87de7af9c231826fdd68ac7258f77c429e0e5fcf" + integrity sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w== + "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" @@ -1950,94 +2156,94 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== -"@jest/console@^27.0.2": - version "27.0.2" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-27.0.2.tgz#b8eeff8f21ac51d224c851e1729d2630c18631e6" - integrity sha512-/zYigssuHLImGeMAACkjI4VLAiiJznHgAl3xnFT19iWyct2LhrH3KXOjHRmxBGTkiPLZKKAJAgaPpiU9EZ9K+w== +"@jest/console@^27.0.6": + version "27.0.6" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-27.0.6.tgz#3eb72ea80897495c3d73dd97aab7f26770e2260f" + integrity sha512-fMlIBocSHPZ3JxgWiDNW/KPj6s+YRd0hicb33IrmelCcjXo/pXPwvuiKFmZz+XuqI/1u7nbUK10zSsWL/1aegg== dependencies: - "@jest/types" "^27.0.2" + "@jest/types" "^27.0.6" "@types/node" "*" chalk "^4.0.0" - jest-message-util "^27.0.2" - jest-util "^27.0.2" + jest-message-util "^27.0.6" + jest-util "^27.0.6" slash "^3.0.0" -"@jest/core@^27.0.4": - version "27.0.4" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-27.0.4.tgz#679bf9ac07900da2ddbb9667bb1afa8029038f53" - integrity sha512-+dsmV8VUs1h/Szb+rEWk8xBM1fp1I///uFy9nk3wXGvRsF2lBp8EVPmtWc+QFRb3MY2b7u2HbkGF1fzoDzQTLA== +"@jest/core@^27.0.6": + version "27.0.6" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-27.0.6.tgz#c5f642727a0b3bf0f37c4b46c675372d0978d4a1" + integrity sha512-SsYBm3yhqOn5ZLJCtccaBcvD/ccTLCeuDv8U41WJH/V1MW5eKUkeMHT9U+Pw/v1m1AIWlnIW/eM2XzQr0rEmow== dependencies: - "@jest/console" "^27.0.2" - "@jest/reporters" "^27.0.4" - "@jest/test-result" "^27.0.2" - "@jest/transform" "^27.0.2" - "@jest/types" "^27.0.2" + "@jest/console" "^27.0.6" + "@jest/reporters" "^27.0.6" + "@jest/test-result" "^27.0.6" + "@jest/transform" "^27.0.6" + "@jest/types" "^27.0.6" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" emittery "^0.8.1" exit "^0.1.2" graceful-fs "^4.2.4" - jest-changed-files "^27.0.2" - jest-config "^27.0.4" - jest-haste-map "^27.0.2" - jest-message-util "^27.0.2" - jest-regex-util "^27.0.1" - jest-resolve "^27.0.4" - jest-resolve-dependencies "^27.0.4" - jest-runner "^27.0.4" - jest-runtime "^27.0.4" - jest-snapshot "^27.0.4" - jest-util "^27.0.2" - jest-validate "^27.0.2" - jest-watcher "^27.0.2" + jest-changed-files "^27.0.6" + jest-config "^27.0.6" + jest-haste-map "^27.0.6" + jest-message-util "^27.0.6" + jest-regex-util "^27.0.6" + jest-resolve "^27.0.6" + jest-resolve-dependencies "^27.0.6" + jest-runner "^27.0.6" + jest-runtime "^27.0.6" + jest-snapshot "^27.0.6" + jest-util "^27.0.6" + jest-validate "^27.0.6" + jest-watcher "^27.0.6" micromatch "^4.0.4" p-each-series "^2.1.0" rimraf "^3.0.0" slash "^3.0.0" strip-ansi "^6.0.0" -"@jest/environment@^27.0.3": - version "27.0.3" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-27.0.3.tgz#68769b1dfdd213e3456169d64fbe9bd63a5fda92" - integrity sha512-pN9m7fbKsop5vc3FOfH8NF7CKKdRbEZzcxfIo1n2TT6ucKWLFq0P6gCJH0GpnQp036++yY9utHOxpeT1WnkWTA== +"@jest/environment@^27.0.6": + version "27.0.6" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-27.0.6.tgz#ee293fe996db01d7d663b8108fa0e1ff436219d2" + integrity sha512-4XywtdhwZwCpPJ/qfAkqExRsERW+UaoSRStSHCCiQTUpoYdLukj+YJbQSFrZjhlUDRZeNiU9SFH0u7iNimdiIg== dependencies: - "@jest/fake-timers" "^27.0.3" - "@jest/types" "^27.0.2" + "@jest/fake-timers" "^27.0.6" + "@jest/types" "^27.0.6" "@types/node" "*" - jest-mock "^27.0.3" + jest-mock "^27.0.6" -"@jest/fake-timers@^27.0.3": - version "27.0.3" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-27.0.3.tgz#9899ba6304cc636734c74478df502e18136461dd" - integrity sha512-fQ+UCKRIYKvTCEOyKPnaPnomLATIhMnHC/xPZ7yT1Uldp7yMgMxoYIFidDbpSTgB79+/U+FgfoD30c6wg3IUjA== +"@jest/fake-timers@^27.0.6": + version "27.0.6" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-27.0.6.tgz#cbad52f3fe6abe30e7acb8cd5fa3466b9588e3df" + integrity sha512-sqd+xTWtZ94l3yWDKnRTdvTeZ+A/V7SSKrxsrOKSqdyddb9CeNRF8fbhAU0D7ZJBpTTW2nbp6MftmKJDZfW2LQ== dependencies: - "@jest/types" "^27.0.2" + "@jest/types" "^27.0.6" "@sinonjs/fake-timers" "^7.0.2" "@types/node" "*" - jest-message-util "^27.0.2" - jest-mock "^27.0.3" - jest-util "^27.0.2" + jest-message-util "^27.0.6" + jest-mock "^27.0.6" + jest-util "^27.0.6" -"@jest/globals@^27.0.3": - version "27.0.3" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-27.0.3.tgz#1cf8933b7791bba0b99305cbf39fd4d2e3fe4060" - integrity sha512-OzsIuf7uf+QalqAGbjClyezzEcLQkdZ+7PejUrZgDs+okdAK8GwRCGcYCirHvhMBBQh60Jr3NlIGbn/KBPQLEQ== +"@jest/globals@^27.0.6": + version "27.0.6" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-27.0.6.tgz#48e3903f99a4650673d8657334d13c9caf0e8f82" + integrity sha512-DdTGCP606rh9bjkdQ7VvChV18iS7q0IMJVP1piwTWyWskol4iqcVwthZmoJEf7obE1nc34OpIyoVGPeqLC+ryw== dependencies: - "@jest/environment" "^27.0.3" - "@jest/types" "^27.0.2" - expect "^27.0.2" + "@jest/environment" "^27.0.6" + "@jest/types" "^27.0.6" + expect "^27.0.6" -"@jest/reporters@^27.0.4": - version "27.0.4" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-27.0.4.tgz#95609b1be97afb80d55d8aa3d7c3179c15810e65" - integrity sha512-Xa90Nm3JnV0xCe4M6A10M9WuN9krb+WFKxV1A98Y4ePCw40n++r7uxFUNU7DT1i9Behj7fjrAIju9oU0t1QtCg== +"@jest/reporters@^27.0.6": + version "27.0.6" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-27.0.6.tgz#91e7f2d98c002ad5df94d5b5167c1eb0b9fd5b00" + integrity sha512-TIkBt09Cb2gptji3yJXb3EE+eVltW6BjO7frO7NEfjI9vSIYoISi5R3aI3KpEDXlB1xwB+97NXIqz84qYeYsfA== dependencies: "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^27.0.2" - "@jest/test-result" "^27.0.2" - "@jest/transform" "^27.0.2" - "@jest/types" "^27.0.2" + "@jest/console" "^27.0.6" + "@jest/test-result" "^27.0.6" + "@jest/transform" "^27.0.6" + "@jest/types" "^27.0.6" chalk "^4.0.0" collect-v8-coverage "^1.0.0" exit "^0.1.2" @@ -2048,60 +2254,60 @@ istanbul-lib-report "^3.0.0" istanbul-lib-source-maps "^4.0.0" istanbul-reports "^3.0.2" - jest-haste-map "^27.0.2" - jest-resolve "^27.0.4" - jest-util "^27.0.2" - jest-worker "^27.0.2" + jest-haste-map "^27.0.6" + jest-resolve "^27.0.6" + jest-util "^27.0.6" + jest-worker "^27.0.6" slash "^3.0.0" source-map "^0.6.0" string-length "^4.0.1" terminal-link "^2.0.0" - v8-to-istanbul "^7.0.0" + v8-to-istanbul "^8.0.0" -"@jest/source-map@^27.0.1": - version "27.0.1" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-27.0.1.tgz#2afbf73ddbaddcb920a8e62d0238a0a9e0a8d3e4" - integrity sha512-yMgkF0f+6WJtDMdDYNavmqvbHtiSpwRN2U/W+6uztgfqgkq/PXdKPqjBTUF1RD/feth4rH5N3NW0T5+wIuln1A== +"@jest/source-map@^27.0.6": + version "27.0.6" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-27.0.6.tgz#be9e9b93565d49b0548b86e232092491fb60551f" + integrity sha512-Fek4mi5KQrqmlY07T23JRi0e7Z9bXTOOD86V/uS0EIW4PClvPDqZOyFlLpNJheS6QI0FNX1CgmPjtJ4EA/2M+g== dependencies: callsites "^3.0.0" graceful-fs "^4.2.4" source-map "^0.6.0" -"@jest/test-result@^27.0.2": - version "27.0.2" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-27.0.2.tgz#0451049e32ceb609b636004ccc27c8fa22263f10" - integrity sha512-gcdWwL3yP5VaIadzwQtbZyZMgpmes8ryBAJp70tuxghiA8qL4imJyZex+i+USQH2H4jeLVVszhwntgdQ97fccA== +"@jest/test-result@^27.0.6": + version "27.0.6" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-27.0.6.tgz#3fa42015a14e4fdede6acd042ce98c7f36627051" + integrity sha512-ja/pBOMTufjX4JLEauLxE3LQBPaI2YjGFtXexRAjt1I/MbfNlMx0sytSX3tn5hSLzQsR3Qy2rd0hc1BWojtj9w== dependencies: - "@jest/console" "^27.0.2" - "@jest/types" "^27.0.2" + "@jest/console" "^27.0.6" + "@jest/types" "^27.0.6" "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" -"@jest/test-sequencer@^27.0.4": - version "27.0.4" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-27.0.4.tgz#976493b277594d81e589896f0ed21f198308928a" - integrity sha512-6UFEVwdmxYdyNffBxVVZxmXEdBE4riSddXYSnFNH0ELFQFk/bvagizim8WfgJTqF4EKd+j1yFxvhb8BMHfOjSQ== +"@jest/test-sequencer@^27.0.6": + version "27.0.6" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-27.0.6.tgz#80a913ed7a1130545b1cd777ff2735dd3af5d34b" + integrity sha512-bISzNIApazYOlTHDum9PwW22NOyDa6VI31n6JucpjTVM0jD6JDgqEZ9+yn575nDdPF0+4csYDxNNW13NvFQGZA== dependencies: - "@jest/test-result" "^27.0.2" + "@jest/test-result" "^27.0.6" graceful-fs "^4.2.4" - jest-haste-map "^27.0.2" - jest-runtime "^27.0.4" + jest-haste-map "^27.0.6" + jest-runtime "^27.0.6" -"@jest/transform@^27.0.2": - version "27.0.2" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-27.0.2.tgz#b073b7c589e3f4b842102468875def2bb722d6b5" - integrity sha512-H8sqKlgtDfVog/s9I4GG2XMbi4Ar7RBxjsKQDUhn2XHAi3NG+GoQwWMER+YfantzExbjNqQvqBHzo/G2pfTiPw== +"@jest/transform@^27.0.2", "@jest/transform@^27.0.6": + version "27.0.6" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-27.0.6.tgz#189ad7107413208f7600f4719f81dd2f7278cc95" + integrity sha512-rj5Dw+mtIcntAUnMlW/Vju5mr73u8yg+irnHwzgtgoeI6cCPOvUwQ0D1uQtc/APmWgvRweEb1g05pkUpxH3iCA== dependencies: "@babel/core" "^7.1.0" - "@jest/types" "^27.0.2" + "@jest/types" "^27.0.6" 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 "^27.0.2" - jest-regex-util "^27.0.1" - jest-util "^27.0.2" + jest-haste-map "^27.0.6" + jest-regex-util "^27.0.6" + jest-util "^27.0.6" micromatch "^4.0.4" pirates "^4.0.1" slash "^3.0.0" @@ -2119,10 +2325,10 @@ "@types/yargs" "^15.0.0" chalk "^4.0.0" -"@jest/types@^27.0.2": - version "27.0.2" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.0.2.tgz#e153d6c46bda0f2589f0702b071f9898c7bbd37e" - integrity sha512-XpjCtJ/99HB4PmyJ2vgmN7vT+JLP7RW1FBT9RgnMFS4Dt7cvIyBee8O3/j98aUZ34ZpenPZFqmaaObWSeL65dg== +"@jest/types@^27.0.2", "@jest/types@^27.0.6": + version "27.0.6" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.0.6.tgz#9a992bc517e0c49f035938b8549719c2de40706b" + integrity sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g== dependencies: "@types/istanbul-lib-coverage" "^2.0.0" "@types/istanbul-reports" "^3.0.0" @@ -2151,7 +2357,7 @@ globby "^11.0.0" read-yaml-file "^1.1.0" -"@mdx-js/mdx@^1.6.21": +"@mdx-js/mdx@^1.6.22": version "1.6.22" resolved "https://registry.yarnpkg.com/@mdx-js/mdx/-/mdx-1.6.22.tgz#8a723157bf90e78f17dc0f27995398e6c731f1ba" integrity sha512-AMxuLxPz2j5/6TpF/XSdKpQP1NlG0z11dFOlq+2IP/lSgl11GY8ji6S/rgsViN/L0BDvHvUMruRb7ub+24LUYA== @@ -2176,7 +2382,7 @@ unist-builder "2.0.3" unist-util-visit "2.0.3" -"@mdx-js/react@^1.6.21": +"@mdx-js/react@^1.6.22": version "1.6.22" resolved "https://registry.yarnpkg.com/@mdx-js/react/-/react-1.6.22.tgz#ae09b4744fddc74714ee9f9d6f17a66e77c43573" integrity sha512-TDoPum4SHdfPiGSAaRBw7ECyI8VaHpK8GJugbJIJuqyh6kzw9ZLJZW3HGL3NNrJGxcAixUvqROm+YuQOo5eXtg== @@ -2186,10 +2392,49 @@ resolved "https://registry.yarnpkg.com/@mdx-js/util/-/util-1.6.22.tgz#219dfd89ae5b97a8801f015323ffa4b62f45718b" integrity sha512-H1rQc1ZOHANWBvPcW+JpGwr+juXSxM8Q8YCkm3GhZd8REu1fHR3z99CErO1p9pkcfcxZnMdIZdIsXkOHY0NilA== -"@microsoft/fetch-event-source@2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@microsoft/fetch-event-source/-/fetch-event-source-2.0.1.tgz#9ceecc94b49fbaa15666e38ae8587f64acce007d" - integrity sha512-W6CLUJ2eBMw3Rec70qrsEW0jOm/3twwJv21mrmj2yORiaVmVYGS4sSS5yUwvQc1ZlDLYGPnClVWmUUMagKNsfA== +"@n1ru4l/graphql-live-query@0.7.1": + version "0.7.1" + resolved "https://registry.yarnpkg.com/@n1ru4l/graphql-live-query/-/graphql-live-query-0.7.1.tgz#c020d017c3ed6bcfdde49a7106ba035e4d0774f5" + integrity sha512-5kJPe2FkPNsCGu9tocKIzUSNO986qAqdnbk8hIFqWlpVPBAmEAOYb1mr6PA18FYAlu7ojWm9Hm13k29aj2GGlQ== + +"@next/bundle-analyzer@^11.0.1": + version "11.0.1" + resolved "https://registry.yarnpkg.com/@next/bundle-analyzer/-/bundle-analyzer-11.0.1.tgz#6f5d617ae861346ac9bf6a1e7bd05444a7fedcc1" + integrity sha512-/+VqZsEu1Q19PlJyNrXJ0qNuYVH1ZiA9fz3G1tiTLdJmHHt4SeAqiBejHvuy8nkttGnHg7uUTdycvVujK0IcQQ== + dependencies: + webpack-bundle-analyzer "4.3.0" + +"@next/env@11.0.1": + version "11.0.1" + resolved "https://registry.yarnpkg.com/@next/env/-/env-11.0.1.tgz#6dc96ac76f1663ab747340e907e8933f190cc8fd" + integrity sha512-yZfKh2U6R9tEYyNUrs2V3SBvCMufkJ07xMH5uWy8wqcl5gAXoEw6A/1LDqwX3j7pUutF9d1ZxpdGDA3Uag+aQQ== + +"@next/polyfill-module@11.0.1": + version "11.0.1" + resolved "https://registry.yarnpkg.com/@next/polyfill-module/-/polyfill-module-11.0.1.tgz#ca2a110c1c44672cbcff6c2b983f0c0549d87291" + integrity sha512-Cjs7rrKCg4CF4Jhri8PCKlBXhszTfOQNl9AjzdNy4K5jXFyxyoSzuX2rK4IuoyE+yGp5A3XJCBEmOQ4xbUp9Mg== + +"@next/react-dev-overlay@11.0.1": + version "11.0.1" + resolved "https://registry.yarnpkg.com/@next/react-dev-overlay/-/react-dev-overlay-11.0.1.tgz#3c481e83347255abd466dcf7e59ac8a79a0d7fd6" + integrity sha512-lvUjMVpLsgzADs9Q8wtC5LNqvfdN+M0BDMSrqr04EDWAyyX0vURHC9hkvLbyEYWyh+WW32pwjKBXdkMnJhoqMg== + dependencies: + "@babel/code-frame" "7.12.11" + anser "1.4.9" + chalk "4.0.0" + classnames "2.2.6" + css.escape "1.5.1" + data-uri-to-buffer "3.0.1" + platform "1.3.6" + shell-quote "1.7.2" + source-map "0.8.0-beta.0" + stacktrace-parser "0.1.10" + strip-ansi "6.0.0" + +"@next/react-refresh-utils@11.0.1": + version "11.0.1" + resolved "https://registry.yarnpkg.com/@next/react-refresh-utils/-/react-refresh-utils-11.0.1.tgz#a7509f22b6f70c13101a26573afd295295f1c020" + integrity sha512-K347DM6Z7gBSE+TfUaTTceWvbj0B6iNAsFZXbFZOlfg3uyz2sbKpzPYYFocCc27yjLaS8OfR8DEdS2mZXi8Saw== "@nodelib/fs.scandir@2.1.4": version "2.1.4" @@ -2212,10 +2457,42 @@ "@nodelib/fs.scandir" "2.1.4" fastq "^1.6.0" -"@polka/url@^1.0.0-next.9": - version "1.0.0-next.11" - resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.11.tgz#aeb16f50649a91af79dbe36574b66d0f9e4d9f71" - integrity sha512-3NsZsJIA/22P3QUyrEDNA2D133H4j224twJrdipXN38dpnIOzAbUDtOwkcJ5pXmn75w7LSQDjA4tO9dm1XlqlA== +"@polka/url@^1.0.0-next.15": + version "1.0.0-next.15" + resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.15.tgz#6a9d143f7f4f49db2d782f9e1c8839a29b43ae23" + integrity sha512-15spi3V28QdevleWBNXE4pIls3nFZmBbUGrW9IVPwiQczuSb9n76TCB4bsk8TSel+I1OkHEdPhu5QKMfY6rQHA== + +"@popperjs/core@2.4.4": + version "2.4.4" + resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.4.4.tgz#11d5db19bd178936ec89cd84519c4de439574398" + integrity sha512-1oO6+dN5kdIA3sKPZhRGJTfGVP4SWV6KqlMOwry4J3HfyD68sl/3KmG7DeYUzvN+RbhXDnv/D8vNNB8168tAMg== + +"@reach/alert@0.13.2": + version "0.13.2" + resolved "https://registry.yarnpkg.com/@reach/alert/-/alert-0.13.2.tgz#71c4a848d51341f1d6d9eaae060975391c224870" + integrity sha512-LDz83AXCrClyq/MWe+0vaZfHp1Ytqn+kgL5VxG7rirUvmluWaj/snxzfNPWn0Ma4K2YENmXXRC/iHt5X95SqIg== + dependencies: + "@reach/utils" "0.13.2" + "@reach/visually-hidden" "0.13.2" + prop-types "^15.7.2" + tslib "^2.1.0" + +"@reach/utils@0.13.2": + version "0.13.2" + resolved "https://registry.yarnpkg.com/@reach/utils/-/utils-0.13.2.tgz#87e8fef8ebfe583fa48250238a1a3ed03189fcc8" + integrity sha512-3ir6cN60zvUrwjOJu7C6jec/samqAeyAB12ZADK+qjnmQPdzSYldrFWwDVV5H0WkhbYXR3uh+eImu13hCetNPQ== + dependencies: + "@types/warning" "^3.0.0" + tslib "^2.1.0" + warning "^4.0.3" + +"@reach/visually-hidden@0.13.2": + version "0.13.2" + resolved "https://registry.yarnpkg.com/@reach/visually-hidden/-/visually-hidden-0.13.2.tgz#ee21de376a7e57e60dc92d95a671073796caa17e" + integrity sha512-sPZwNS0/duOuG0mYwE5DmgEAzW9VhgU3aIt1+mrfT/xiT9Cdncqke+kRBQgU708q/Ttm9tWsoHni03nn/SuPTQ== + dependencies: + prop-types "^15.7.2" + tslib "^2.1.0" "@rollup/plugin-node-resolve@7.1.1": version "7.1.1" @@ -2238,9 +2515,9 @@ picomatch "^2.2.2" "@sideway/address@^4.1.0": - version "4.1.1" - resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.1.tgz#9e321e74310963fdf8eebfbee09c7bd69972de4d" - integrity sha512-+I5aaQr3m0OAmMr7RQ3fR9zx55sejEYR2BFJaxL+zT3VM2611X0SHvPWIbAUBZVTn/YzYKbV8gJ2oT/QELknfQ== + version "4.1.2" + resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.2.tgz#811b84333a335739d3969cfc434736268170cad1" + integrity sha512-idTz8ibqWFrPU8kMirL0CoPH/A29XOzzAzpyN3zQ4kAWnzmNfFmRaoMNN6VI8ske5M73HZyhIaW4OuSFIdM4oA== dependencies: "@hapi/hoek" "^9.0.0" @@ -2254,11 +2531,6 @@ resolved "https://registry.yarnpkg.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz#cff8ffadc372ad29fd3f78277aeb29e632cc70df" integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ== -"@sindresorhus/is@^0.14.0": - version "0.14.0" - resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" - integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== - "@sinonjs/commons@^1.7.0": version "1.8.2" resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.2.tgz#858f5c4b48d80778fde4b9d541f27edc0d56488b" @@ -2273,120 +2545,10 @@ dependencies: "@sinonjs/commons" "^1.7.0" -"@svgr/babel-plugin-add-jsx-attribute@^5.4.0": - version "5.4.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-5.4.0.tgz#81ef61947bb268eb9d50523446f9c638fb355906" - integrity sha512-ZFf2gs/8/6B8PnSofI0inYXr2SDNTDScPXhN7k5EqD4aZ3gi6u+rbmZHVB8IM3wDyx8ntKACZbtXSm7oZGRqVg== - -"@svgr/babel-plugin-remove-jsx-attribute@^5.4.0": - version "5.4.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-5.4.0.tgz#6b2c770c95c874654fd5e1d5ef475b78a0a962ef" - integrity sha512-yaS4o2PgUtwLFGTKbsiAy6D0o3ugcUhWK0Z45umJ66EPWunAz9fuFw2gJuje6wqQvQWOTJvIahUwndOXb7QCPg== - -"@svgr/babel-plugin-remove-jsx-empty-expression@^5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-5.0.1.tgz#25621a8915ed7ad70da6cea3d0a6dbc2ea933efd" - integrity sha512-LA72+88A11ND/yFIMzyuLRSMJ+tRKeYKeQ+mR3DcAZ5I4h5CPWN9AHyUzJbWSYp/u2u0xhmgOe0+E41+GjEueA== - -"@svgr/babel-plugin-replace-jsx-attribute-value@^5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-5.0.1.tgz#0b221fc57f9fcd10e91fe219e2cd0dd03145a897" - integrity sha512-PoiE6ZD2Eiy5mK+fjHqwGOS+IXX0wq/YDtNyIgOrc6ejFnxN4b13pRpiIPbtPwHEc+NT2KCjteAcq33/F1Y9KQ== - -"@svgr/babel-plugin-svg-dynamic-title@^5.4.0": - version "5.4.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-5.4.0.tgz#139b546dd0c3186b6e5db4fefc26cb0baea729d7" - integrity sha512-zSOZH8PdZOpuG1ZVx/cLVePB2ibo3WPpqo7gFIjLV9a0QsuQAzJiwwqmuEdTaW2pegyBE17Uu15mOgOcgabQZg== - -"@svgr/babel-plugin-svg-em-dimensions@^5.4.0": - version "5.4.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-5.4.0.tgz#6543f69526632a133ce5cabab965deeaea2234a0" - integrity sha512-cPzDbDA5oT/sPXDCUYoVXEmm3VIoAWAPT6mSPTJNbQaBNUuEKVKyGH93oDY4e42PYHRW67N5alJx/eEol20abw== - -"@svgr/babel-plugin-transform-react-native-svg@^5.4.0": - version "5.4.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-5.4.0.tgz#00bf9a7a73f1cad3948cdab1f8dfb774750f8c80" - integrity sha512-3eYP/SaopZ41GHwXma7Rmxcv9uRslRDTY1estspeB1w1ueZWd/tPlMfEOoccYpEMZU3jD4OU7YitnXcF5hLW2Q== - -"@svgr/babel-plugin-transform-svg-component@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-5.5.0.tgz#583a5e2a193e214da2f3afeb0b9e8d3250126b4a" - integrity sha512-q4jSH1UUvbrsOtlo/tKcgSeiCHRSBdXoIoqX1pgcKK/aU3JD27wmMKwGtpB8qRYUYoyXvfGxUVKchLuR5pB3rQ== - -"@svgr/babel-preset@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-preset/-/babel-preset-5.5.0.tgz#8af54f3e0a8add7b1e2b0fcd5a882c55393df327" - integrity sha512-4FiXBjvQ+z2j7yASeGPEi8VD/5rrGQk4Xrq3EdJmoZgz/tpqChpo5hgXDvmEauwtvOc52q8ghhZK4Oy7qph4ig== - dependencies: - "@svgr/babel-plugin-add-jsx-attribute" "^5.4.0" - "@svgr/babel-plugin-remove-jsx-attribute" "^5.4.0" - "@svgr/babel-plugin-remove-jsx-empty-expression" "^5.0.1" - "@svgr/babel-plugin-replace-jsx-attribute-value" "^5.0.1" - "@svgr/babel-plugin-svg-dynamic-title" "^5.4.0" - "@svgr/babel-plugin-svg-em-dimensions" "^5.4.0" - "@svgr/babel-plugin-transform-react-native-svg" "^5.4.0" - "@svgr/babel-plugin-transform-svg-component" "^5.5.0" - -"@svgr/core@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@svgr/core/-/core-5.5.0.tgz#82e826b8715d71083120fe8f2492ec7d7874a579" - integrity sha512-q52VOcsJPvV3jO1wkPtzTuKlvX7Y3xIcWRpCMtBF3MrteZJtBfQw/+u0B1BHy5ColpQc1/YVTrPEtSYIMNZlrQ== - dependencies: - "@svgr/plugin-jsx" "^5.5.0" - camelcase "^6.2.0" - cosmiconfig "^7.0.0" - -"@svgr/hast-util-to-babel-ast@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-5.5.0.tgz#5ee52a9c2533f73e63f8f22b779f93cd432a5461" - integrity sha512-cAaR/CAiZRB8GP32N+1jocovUtvlj0+e65TB50/6Lcime+EA49m/8l+P2ko+XPJ4dw3xaPS3jOL4F2X4KWxoeQ== - dependencies: - "@babel/types" "^7.12.6" - -"@svgr/plugin-jsx@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@svgr/plugin-jsx/-/plugin-jsx-5.5.0.tgz#1aa8cd798a1db7173ac043466d7b52236b369000" - integrity sha512-V/wVh33j12hGh05IDg8GpIUXbjAPnTdPTKuP4VNLggnwaHMPNQNae2pRnyTAILWCQdz5GyMqtO488g7CKM8CBA== - dependencies: - "@babel/core" "^7.12.3" - "@svgr/babel-preset" "^5.5.0" - "@svgr/hast-util-to-babel-ast" "^5.5.0" - svg-parser "^2.0.2" - -"@svgr/plugin-svgo@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@svgr/plugin-svgo/-/plugin-svgo-5.5.0.tgz#02da55d85320549324e201c7b2e53bf431fcc246" - integrity sha512-r5swKk46GuQl4RrVejVwpeeJaydoxkdwkM1mBKOgJLBUJPGaLci6ylg/IjhrRsREKDkr4kbMWdgOtbXEh0fyLQ== - dependencies: - cosmiconfig "^7.0.0" - deepmerge "^4.2.2" - svgo "^1.2.2" - -"@svgr/webpack@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@svgr/webpack/-/webpack-5.5.0.tgz#aae858ee579f5fa8ce6c3166ef56c6a1b381b640" - integrity sha512-DOBOK255wfQxguUta2INKkzPj6AIS6iafZYiYmHn6W3pHlycSRRlvWKCfLDG10fXfLWqE3DJHgRUOyJYmARa7g== - dependencies: - "@babel/core" "^7.12.3" - "@babel/plugin-transform-react-constant-elements" "^7.12.1" - "@babel/preset-env" "^7.12.1" - "@babel/preset-react" "^7.12.5" - "@svgr/core" "^5.5.0" - "@svgr/plugin-jsx" "^5.5.0" - "@svgr/plugin-svgo" "^5.5.0" - loader-utils "^2.0.0" - -"@szmarczak/http-timer@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" - integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA== - dependencies: - defer-to-connect "^1.0.1" - -"@theguild/components@1.2.4": - version "1.2.4" - resolved "https://registry.yarnpkg.com/@theguild/components/-/components-1.2.4.tgz#08a604fc38a94d62a2e4c8ff8605f6346e46f28c" - integrity sha512-0nxytVpdXB2aey7Mn8hHSlyP/9jSgpAwlxjkzajVwjawkV13+h0VaQl19d6DT8mmbi4uB50uF4o0g4HgKl0FWQ== +"@theguild/components@1.4.2": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@theguild/components/-/components-1.4.2.tgz#3eb507ba5eb9404a24c21b7441bb5c540646ddd1" + integrity sha512-ERz8MclhrvuSOl7cLMYPQWQT/vNkDyRiow6VpMVKCC2SiXf2Js2RtG8KKMNZY9QwRjX8PhDkJW9KXikV6ugdGA== dependencies: "@emotion/react" "^11.4.0" "@emotion/styled" "^11.3.0" @@ -2399,18 +2561,19 @@ react-player "^2.9.0" tailwindcss "^2.1.4" twin.macro "^2.4.2" - use-debounce "^6.0.1" + use-debounce "^7.0.0" + validator "13.6.0" + +"@tokenizer/token@^0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@tokenizer/token/-/token-0.1.1.tgz#f0d92c12f87079ddfd1b29f614758b9696bc29e3" + integrity sha512-XO6INPbZCxdprl+9qa/AAbFFOMzzwqYxpjPgLICrMD6C2FCw6qfJOPcBk6JqqPLSaZ/Qx87qn4rpPmPMwaAK6w== "@tootallnate/once@1": version "1.1.2" resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== -"@trysound/sax@0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.1.1.tgz#3348564048e7a2d7398c935d466c0414ebb6a669" - integrity sha512-Z6DoceYb/1xSg5+e+ZlPZ9v0N16ZvZ+wYMraFue4HYrE4ttONKtsvruIRf6t9TBR0YvSOfi1hUU0fJfBLCDYow== - "@types/accepts@*": version "1.3.5" resolved "https://registry.yarnpkg.com/@types/accepts/-/accepts-1.3.5.tgz#c34bec115cfc746e04fe5a059df4ce7e7b391575" @@ -2453,10 +2616,10 @@ "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" -"@types/babel__traverse@*", "@types/babel__traverse@7.11.1", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": - version "7.11.1" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.11.1.tgz#654f6c4f67568e24c23b367e947098c6206fa639" - integrity sha512-Vs0hm0vPahPMYi9tDjtP66llufgO3ST16WXaSTtDGEl9cewAl3AibmxWw6TINOqHPT9z0uABKAYjT9jNSg4npw== +"@types/babel__traverse@*", "@types/babel__traverse@7.14.0", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.14.0.tgz#a34277cf8acbd3185ea74129e1f100491eb1da7f" + integrity sha512-IilJZ1hJBUZwMOVDNTdflOOLzJB/ZtljYVa7k3gEZN/jqIJIPkWHC6dvbX+DD2CwZDHB9wAKzZPzzqMIkW37/w== dependencies: "@babel/types" "^7.3.0" @@ -2473,6 +2636,13 @@ resolved "https://registry.yarnpkg.com/@types/braces/-/braces-3.0.0.tgz#7da1c0d44ff1c7eb660a36ec078ea61ba7eb42cb" integrity sha1-faHA1E/xx+tmCjbsB46mG6frQss= +"@types/concurrently@^6.2.0": + version "6.2.0" + resolved "https://registry.yarnpkg.com/@types/concurrently/-/concurrently-6.2.0.tgz#d6b645006edf298cf624ad67d29a06a4d9ce0682" + integrity sha512-lWoHMkfoFWdFJ2IZ02PxepWVnGfNYZdblFF1o1gJ2YiUKN1TcEnNwDOrQMZbx0xt2bq09I+dYe9TS+dHf60VXw== + dependencies: + "@types/node" "*" + "@types/connect@*": version "3.4.34" resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.34.tgz#170a40223a6d666006d93ca128af2beb1d9b1901" @@ -2500,32 +2670,42 @@ resolved "https://registry.yarnpkg.com/@types/dateformat/-/dateformat-3.0.1.tgz#98d747a2e5e9a56070c6bf14e27bff56204e34cc" integrity sha512-KlPPdikagvL6ELjWsljbyDIPzNCeliYkqRpI+zea99vBBbCIA5JNshZAwQKTON139c87y9qvTFVgkFd14rtS4g== +"@types/debug@^4.1.5": + version "4.1.6" + resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.6.tgz#0b7018723084918a865eff99249c490505df2163" + integrity sha512-7fDOJFA/x8B+sO1901BmHlf5dE1cxBU8mRXj8QOEDnn16hhGJv/IHxJtZhvsabZsIMn0eLIyeOKAeqSNJJYTpA== + "@types/eslint-scope@^3.7.0": - version "3.7.0" - resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.0.tgz#4792816e31119ebd506902a482caec4951fabd86" - integrity sha512-O/ql2+rrCUe2W2rs7wMR+GqPRcgB6UiqN5RhrR5xruFlY7l9YLMn0ZkDzjoHLeiFkR8MCQZVudUuuvQ2BLC9Qw== + version "3.7.1" + resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.1.tgz#8dc390a7b4f9dd9f1284629efce982e41612116e" + integrity sha512-SCFeogqiptms4Fg29WpOTk5nHIzfpKCemSN63ksBQYKTcXoJEmJagV+DhVmbapZzY4/5YaOV1nZwrsU79fFm1g== dependencies: "@types/eslint" "*" "@types/estree" "*" "@types/eslint@*": - version "7.2.10" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-7.2.10.tgz#4b7a9368d46c0f8cd5408c23288a59aa2394d917" - integrity sha512-kUEPnMKrqbtpCq/KTaGFFKAcz6Ethm2EjCoKIDaCmfRBWLbFuTcOJfTlorwbnboXBzahqWLgUp1BQeKHiJzPUQ== + version "7.28.0" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-7.28.0.tgz#7e41f2481d301c68e14f483fe10b017753ce8d5a" + integrity sha512-07XlgzX0YJUn4iG1ocY4IX9DzKSmMGUs6ESKlxWhZRaa0fatIWaHWUVapcuGa8r5HFnTqzj+4OCjd5f7EZ/i/A== dependencies: "@types/estree" "*" "@types/json-schema" "*" -"@types/estree@*", "@types/estree@^0.0.47": - version "0.0.47" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.47.tgz#d7a51db20f0650efec24cd04994f523d93172ed4" - integrity sha512-c5ciR06jK8u9BstrmJyO97m+klJrrhCf9u3rLu3DEAJBirxRqSCvDQoYKmxuYwQI5SZChAWu+tq9oVlGRuzPAg== +"@types/estree@*", "@types/estree@^0.0.48": + version "0.0.48" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.48.tgz#18dc8091b285df90db2f25aa7d906cfc394b7f74" + integrity sha512-LfZwXoGUDo0C3me81HXgkBg5CTQYb6xzEl+fNmbO4JdRiSKQ8A0GD1OBBvKAIsbCUgoyAty7m99GqqMQe784ew== "@types/estree@0.0.39": version "0.0.39" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== +"@types/estree@^0.0.47": + version "0.0.47" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.47.tgz#d7a51db20f0650efec24cd04994f523d93172ed4" + integrity sha512-c5ciR06jK8u9BstrmJyO97m+klJrrhCf9u3rLu3DEAJBirxRqSCvDQoYKmxuYwQI5SZChAWu+tq9oVlGRuzPAg== + "@types/express-serve-static-core@^4.17.18": version "4.17.19" resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.19.tgz#00acfc1632e729acac4f1530e9e16f6dd1508a1d" @@ -2557,19 +2737,6 @@ dependencies: "@types/node" "*" -"@types/github-slugger@^1.3.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@types/github-slugger/-/github-slugger-1.3.0.tgz#16ab393b30d8ae2a111ac748a015ac05a1fc5524" - integrity sha512-J/rMZa7RqiH/rT29TEVZO4nBoDP9XJOjnbbIofg7GQKs4JIduEO3WLpte+6WeUz/TcrXKlY+bM7FYrp8yFB+3g== - -"@types/glob@^7.1.1": - version "7.1.3" - resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.3.tgz#e6ba80f36b7daad2c685acd9266382e68985c183" - integrity sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w== - dependencies: - "@types/minimatch" "*" - "@types/node" "*" - "@types/graceful-fs@^4.1.2": version "4.1.5" resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15" @@ -2594,10 +2761,13 @@ dependencies: "@types/unist" "*" -"@types/html-minifier-terser@^5.0.0": - version "5.1.1" - resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz#3c9ee980f1a10d6021ae6632ca3e79ca2ec4fb50" - integrity sha512-giAlZwstKbmvMk1OO7WXSj4OZ0keXAcl2TQq4LWHiiPH2ByaH7WeUzng+Qej8UPxxv+8lRTuouo0iaNDBuzIBA== +"@types/hoist-non-react-statics@^3.3.1": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f" + integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA== + dependencies: + "@types/react" "*" + hoist-non-react-statics "^3.3.0" "@types/http-assert@*": version "1.5.1" @@ -2609,12 +2779,12 @@ resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-1.8.0.tgz#682477dbbbd07cd032731cb3b0e7eaee3d026b69" integrity sha512-2aoSC4UUbHDj2uCsCxcG/vRMXey/m17bC7UwitVm5hn22nI8O8Y9iDpA76Orc+DWkQ4zZrOKEshCqR/jSuXAHA== -"@types/http-proxy-agent@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@types/http-proxy-agent/-/http-proxy-agent-4.0.0.tgz#6aa52287365115da1667384182ccc2f42603326d" - integrity sha512-KHJ5VLu4L0YBj+ZeDKVnGloSMmgdzLlhfSVL8XSwwv5SRoeWVEcco7kNpEIzzsS95lncn43J9vW3m88eX7Yzeg== +"@types/i18next-fs-backend@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/i18next-fs-backend/-/i18next-fs-backend-1.0.0.tgz#3fb0374f4d376375b7cc1d3729bca663d104fa64" + integrity sha512-PotQ0NE17NavxXCsdyq9qIKZQOB7+A5O/2nDdvfbfm6/IgvvC1YUO6hxK3nIHASu+QGjO1QV5J8PJw4OL12LMQ== dependencies: - http-proxy-agent "*" + i18next "^19.7.0" "@types/is-glob@4.0.1": version "4.0.1" @@ -2648,12 +2818,17 @@ jest-diff "^26.0.0" pretty-format "^26.0.0" +"@types/js-cookie@^2.2.6": + version "2.2.6" + resolved "https://registry.yarnpkg.com/@types/js-cookie/-/js-cookie-2.2.6.tgz#f1a1cb35aff47bc5cfb05cb0c441ca91e914c26f" + integrity sha512-+oY0FDTO2GYKEV0YPvSshGq9t7YozVkgvXLty7zogQNuCxBhT9/3INX9Q7H1aRZ4SUDRXAKlJuA4EA5nTt7SNw== + "@types/js-yaml@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-4.0.0.tgz#d1a11688112091f2c711674df3a65ea2f47b5dfb" integrity sha512-4vlpCM5KPCL5CfGmTbpjwVKbISRYhduEJvvUWsH5EB7QInhEj94XPZ3ts/9FPiLZFqYO0xoW4ZL8z2AabTGgJA== -"@types/json-schema@*", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.6", "@types/json-schema@^7.0.7": +"@types/json-schema@*", "@types/json-schema@^7.0.7": version "7.0.7" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad" integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA== @@ -2701,7 +2876,14 @@ "@types/koa-compose" "*" "@types/node" "*" -"@types/lodash@4.14.170": +"@types/lodash.mergewith@4.6.6": + version "4.6.6" + resolved "https://registry.yarnpkg.com/@types/lodash.mergewith/-/lodash.mergewith-4.6.6.tgz#c4698f5b214a433ff35cb2c75ee6ec7f99d79f10" + integrity sha512-RY/8IaVENjG19rxTZu9Nukqh0W2UrYgmBj5sdns4hWRZaV8PqR7wIKHFKzvOTjo4zVRV7sVI+yFhAJql12Kfqg== + dependencies: + "@types/lodash" "*" + +"@types/lodash@*", "@types/lodash@4.14.170": version "4.14.170" resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.170.tgz#0d67711d4bf7f4ca5147e9091b847479b87925d6" integrity sha512-bpcvu/MKHHeYX+qeEN8GE7DIravODWdACVA1ctevD8CN24RhPZIKMn9ntfAsrvLfSX3cR5RrBKAbYm9bGs0A+Q== @@ -2713,7 +2895,14 @@ dependencies: "@types/unist" "*" -"@types/micromatch@latest": +"@types/mdx-js__react@^1.5.3": + version "1.5.3" + resolved "https://registry.yarnpkg.com/@types/mdx-js__react/-/mdx-js__react-1.5.3.tgz#2f858ab0ee5fc60b642f3764ef9001fe0530fe43" + integrity sha512-flP0BpS5rXnEbkU5ih79ARaI/+rK10Iee+zxTaWYtoiyc2+f1EJ8EnYgMmXHdAuI7OX4J9/hdoXfrfrri0AT+Q== + dependencies: + "@types/react" "*" + +"@types/micromatch@4.0.1", "@types/micromatch@latest": version "4.0.1" resolved "https://registry.yarnpkg.com/@types/micromatch/-/micromatch-4.0.1.tgz#9381449dd659fc3823fd2a4190ceacc985083bc7" integrity sha1-k4FEndZZ/Dgj/SpBkM6syYUIO8c= @@ -2725,17 +2914,12 @@ resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw== -"@types/minimatch@*": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" - integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== - -"@types/minimist@^1.2.0": +"@types/minimist@^1.2.0", "@types/minimist@^1.2.1": version "1.2.1" resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.1.tgz#283f669ff76d7b8260df8ab7a4262cc83d988256" integrity sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg== -"@types/node@*", "@types/node@^15.0.1": +"@types/node@*": version "15.6.0" resolved "https://registry.yarnpkg.com/@types/node/-/node-15.6.0.tgz#f0ddca5a61e52627c9dcb771a6039d44694597bc" integrity sha512-gCYSfQpy+LYhOFTKAeE8BkyGqaxmlFxe+n4DKM6DR0wzw/HISUE/hAmkC/KT8Sw5PCJblqg062b3z9gucv3k0A== @@ -2750,6 +2934,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.6.tgz#7b73cce37352936e628c5ba40326193443cfba25" integrity sha512-sRVq8d+ApGslmkE9e3i+D3gFGk7aZHAT+G4cIpIEdLJYPsWiSPwcAnJEjddLQQDqV3Ra2jOclX/Sv6YrvGYiWA== +"@types/node@^15.12.4": + version "15.14.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-15.14.1.tgz#4f9d3689532499fdda1c898e19f4593718655e36" + integrity sha512-wF6hazbsnwaW3GhK4jFuw5NaLDQVRQ6pWQUGAUrJzxixFkTaODSiAKMPXuHwPEPkAKQWHAzj6uJ5h+3zU9gQxg== + "@types/normalize-package-data@^2.4.0": version "2.4.0" resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" @@ -2770,10 +2959,10 @@ resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.2.3.tgz#ef65165aea2924c9359205bf748865b8881753c0" integrity sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA== -"@types/q@^1.5.1": - version "1.5.4" - resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.4.tgz#15925414e0ad2cd765bfef58842f7e26a7accb24" - integrity sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug== +"@types/prop-types@*": + version "15.7.3" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7" + integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw== "@types/qs@*": version "6.9.6" @@ -2785,6 +2974,30 @@ resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c" integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA== +"@types/react-dom@^17.0.8": + version "17.0.8" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.8.tgz#3180de6d79bf53762001ad854e3ce49f36dd71fc" + integrity sha512-0ohAiJAx1DAUEcY9UopnfwCE9sSMDGnY/oXjWMax6g3RpzmTt2GMyMVAXcbn0mo8XAff0SbQJl2/SBU+hjSZ1A== + dependencies: + "@types/react" "*" + +"@types/react@*", "@types/react@^17.0.0", "@types/react@^17.0.11": + version "17.0.13" + resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.13.tgz#6b7c9a8f2868586ad87d941c02337c6888fb874f" + integrity sha512-D/G3PiuqTfE3IMNjLn/DCp6umjVCSvtZTPdtAFy5+Ved6CsdRvivfKeCzw79W4AatShtU4nGqgvOv5Gro534vQ== + dependencies: + "@types/prop-types" "*" + "@types/scheduler" "*" + csstype "^3.0.2" + +"@types/readable-stream@^2.3.9": + version "2.3.10" + resolved "https://registry.yarnpkg.com/@types/readable-stream/-/readable-stream-2.3.10.tgz#0f1a512ca30bec5e53d3282133b9237a703e7562" + integrity sha512-xwSXvAv9x4B9Vj88AMZnFyEVLilz1EBxKvRUhGqIF4nJpRQBSTm7jS236X4Y9Y2qPsVvaMxwrGJlNhLHEahlFQ== + dependencies: + "@types/node" "*" + safe-buffer "*" + "@types/relay-compiler@8.0.0": version "8.0.0" resolved "https://registry.yarnpkg.com/@types/relay-compiler/-/relay-compiler-8.0.0.tgz#98961b923555145067d3895f8774f3024f14e6fa" @@ -2806,12 +3019,10 @@ dependencies: "@types/node" "*" -"@types/sax@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@types/sax/-/sax-1.2.1.tgz#e0248be936ece791a82db1a57f3fb5f7c87e8172" - integrity sha512-dqYdvN7Sbw8QT/0Ci5rhjE4/iCMJEM0Y9rHpCu+gGXD9Lwbz28t6HI2yegsB6BoV1sShRMU6lAmAcgRjmFy7LA== - dependencies: - "@types/node" "*" +"@types/scheduler@*": + version "0.16.1" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.1.tgz#18845205e86ff0038517aab7a18a62a6b9f71275" + integrity sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA== "@types/semver@^6.0.0": version "6.2.2" @@ -2831,27 +3042,46 @@ resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.0.tgz#7036640b4e21cc2f259ae826ce843d277dad8cff" integrity sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw== +"@types/tinycolor2@1.4.2": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@types/tinycolor2/-/tinycolor2-1.4.2.tgz#721ca5c5d1a2988b4a886e35c2ffc5735b6afbdf" + integrity sha512-PeHg/AtdW6aaIO2a+98Xj7rWY4KC1E6yOy7AFknJQ7VXUGNrMlyxDFxJo7HqLtjQms/ZhhQX52mLVW/EX3JGOw== + "@types/unist@*", "@types/unist@^2.0.0", "@types/unist@^2.0.2", "@types/unist@^2.0.3": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.3.tgz#9c088679876f374eb5983f150d4787aa6fb32d7e" - integrity sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ== + version "2.0.5" + resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.5.tgz#fdd299f23205c3455af88ce618dd65c14cb73e22" + integrity sha512-wnra4Vw9dopnuybR6HBywJ/URYpYrKLoepBTEtgfJup8Ahoi2zJECPP2cwiXp7btTvOT2CULv87aQRA4eZSP6g== "@types/valid-url@1.0.3": version "1.0.3" resolved "https://registry.yarnpkg.com/@types/valid-url/-/valid-url-1.0.3.tgz#a124389fb953559c7f889795a98620e91adb3687" integrity sha512-+33x29mg+ecU88ODdWpqaie2upIuRkhujVLA7TuJjM823cNMbeggfI6NhxewaRaRF8dy+g33e4uIg/m5Mb3xDQ== -"@types/websocket@1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@types/websocket/-/websocket-1.0.2.tgz#d2855c6a312b7da73ed16ba6781815bf30c6187a" - integrity sha512-B5m9aq7cbbD/5/jThEr33nUY8WEfVi6A2YKCTOvw5Ldy7mtsOkqRvGjnzy6g7iMMDsgu7xREuCzqATLDLQVKcQ== +"@types/warning@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/warning/-/warning-3.0.0.tgz#0d2501268ad8f9962b740d387c4654f5f8e23e52" + integrity sha1-DSUBJorY+ZYrdA04fEZU9fjiPlI= + +"@types/webpack@5.28.0": + version "5.28.0" + resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-5.28.0.tgz#78dde06212f038d77e54116cfe69e88ae9ed2c03" + integrity sha512-8cP0CzcxUiFuA9xGJkfeVpqmWTk9nx6CWwamRGCj95ph1SmlRRk9KlCZ6avhCbZd4L68LvYT6l1kpdEnQXrF8w== + dependencies: + "@types/node" "*" + tapable "^2.2.0" + webpack "^5" + +"@types/websocket@1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@types/websocket/-/websocket-1.0.3.tgz#49e09f939afd0ccdee4f7108d4712ec9feb0f153" + integrity sha512-ZdoTSwmDsKR7l1I8fpfQtmTI/hUwlOvE3q0iyJsp4tXU0MkdrYowimDzwxjhQvxU4qjhHLd3a6ig0OXRbLgIdw== dependencies: "@types/node" "*" -"@types/ws@7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.4.tgz#93e1e00824c1de2608c30e6de4303ab3b4c0c9bc" - integrity sha512-d/7W23JAXPodQNbOZNXvl2K+bqAQrCMwlh/nuQsPSQk6Fq0opHoPrUw43aHsvSbIiQPr8Of2hkFbnz1XBFVyZQ== +"@types/ws@7.4.6": + version "7.4.6" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.6.tgz#c4320845e43d45a7129bb32905e28781c71c1fff" + integrity sha512-ijZ1vzRawI7QoWnTNL8KpHixd2b2XVb9I9HAqI3triPsh1EC0xH0Eg6w2O3TKbDCgiNNlJqfrof6j4T2I+l9vw== dependencies: "@types/node" "*" @@ -2879,74 +3109,73 @@ resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.8.2.tgz#808c9fa7e4517274ed555fa158f2de4b4f468e71" integrity sha512-HrCIVMLjE1MOozVoD86622S7aunluLb2PJdPfb3nYiEtohm8mIB/vyv0Fd37AdeMFrTUQXEunw78YloMA3Qilg== -"@typescript-eslint/eslint-plugin@4.26.1": - version "4.26.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.26.1.tgz#b9c7313321cb837e2bf8bebe7acc2220659e67d3" - integrity sha512-aoIusj/8CR+xDWmZxARivZjbMBQTT9dImUtdZ8tVCVRXgBUuuZyM5Of5A9D9arQPxbi/0rlJLcuArclz/rCMJw== +"@typescript-eslint/eslint-plugin@4.28.0": + version "4.28.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.28.0.tgz#1a66f03b264844387beb7dc85e1f1d403bd1803f" + integrity sha512-KcF6p3zWhf1f8xO84tuBailV5cN92vhS+VT7UJsPzGBm9VnQqfI9AsiMUFUCYHTYPg1uCCo+HyiDnpDuvkAMfQ== dependencies: - "@typescript-eslint/experimental-utils" "4.26.1" - "@typescript-eslint/scope-manager" "4.26.1" + "@typescript-eslint/experimental-utils" "4.28.0" + "@typescript-eslint/scope-manager" "4.28.0" debug "^4.3.1" functional-red-black-tree "^1.0.1" - lodash "^4.17.21" regexpp "^3.1.0" semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/experimental-utils@4.26.1": - version "4.26.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.26.1.tgz#a35980a2390da9232aa206b27f620eab66e94142" - integrity sha512-sQHBugRhrXzRCs9PaGg6rowie4i8s/iD/DpTB+EXte8OMDfdCG5TvO73XlO9Wc/zi0uyN4qOmX9hIjQEyhnbmQ== +"@typescript-eslint/experimental-utils@4.28.0": + version "4.28.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.28.0.tgz#13167ed991320684bdc23588135ae62115b30ee0" + integrity sha512-9XD9s7mt3QWMk82GoyUpc/Ji03vz4T5AYlHF9DcoFNfJ/y3UAclRsfGiE2gLfXtyC+JRA3trR7cR296TEb1oiQ== dependencies: "@types/json-schema" "^7.0.7" - "@typescript-eslint/scope-manager" "4.26.1" - "@typescript-eslint/types" "4.26.1" - "@typescript-eslint/typescript-estree" "4.26.1" + "@typescript-eslint/scope-manager" "4.28.0" + "@typescript-eslint/types" "4.28.0" + "@typescript-eslint/typescript-estree" "4.28.0" eslint-scope "^5.1.1" eslint-utils "^3.0.0" -"@typescript-eslint/parser@4.26.1": - version "4.26.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.26.1.tgz#cecfdd5eb7a5c13aabce1c1cfd7fbafb5a0f1e8e" - integrity sha512-q7F3zSo/nU6YJpPJvQveVlIIzx9/wu75lr6oDbDzoeIRWxpoc/HQ43G4rmMoCc5my/3uSj2VEpg/D83LYZF5HQ== +"@typescript-eslint/parser@4.28.0": + version "4.28.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.28.0.tgz#2404c16751a28616ef3abab77c8e51d680a12caa" + integrity sha512-7x4D22oPY8fDaOCvkuXtYYTQ6mTMmkivwEzS+7iml9F9VkHGbbZ3x4fHRwxAb5KeuSkLqfnYjs46tGx2Nour4A== dependencies: - "@typescript-eslint/scope-manager" "4.26.1" - "@typescript-eslint/types" "4.26.1" - "@typescript-eslint/typescript-estree" "4.26.1" + "@typescript-eslint/scope-manager" "4.28.0" + "@typescript-eslint/types" "4.28.0" + "@typescript-eslint/typescript-estree" "4.28.0" debug "^4.3.1" -"@typescript-eslint/scope-manager@4.26.1": - version "4.26.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.26.1.tgz#075a74a15ff33ee3a7ed33e5fce16ee86689f662" - integrity sha512-TW1X2p62FQ8Rlne+WEShyd7ac2LA6o27S9i131W4NwDSfyeVlQWhw8ylldNNS8JG6oJB9Ha9Xyc+IUcqipvheQ== +"@typescript-eslint/scope-manager@4.28.0": + version "4.28.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.28.0.tgz#6a3009d2ab64a30fc8a1e257a1a320067f36a0ce" + integrity sha512-eCALCeScs5P/EYjwo6se9bdjtrh8ByWjtHzOkC4Tia6QQWtQr3PHovxh3TdYTuFcurkYI4rmFsRFpucADIkseg== dependencies: - "@typescript-eslint/types" "4.26.1" - "@typescript-eslint/visitor-keys" "4.26.1" + "@typescript-eslint/types" "4.28.0" + "@typescript-eslint/visitor-keys" "4.28.0" -"@typescript-eslint/types@4.26.1": - version "4.26.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.26.1.tgz#9e7c523f73c34b04a765e4167ca5650436ef1d38" - integrity sha512-STyMPxR3cS+LaNvS8yK15rb8Y0iL0tFXq0uyl6gY45glyI7w0CsyqyEXl/Fa0JlQy+pVANeK3sbwPneCbWE7yg== +"@typescript-eslint/types@4.28.0": + version "4.28.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.28.0.tgz#a33504e1ce7ac51fc39035f5fe6f15079d4dafb0" + integrity sha512-p16xMNKKoiJCVZY5PW/AfILw2xe1LfruTcfAKBj3a+wgNYP5I9ZEKNDOItoRt53p4EiPV6iRSICy8EPanG9ZVA== -"@typescript-eslint/typescript-estree@4.26.1": - version "4.26.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.26.1.tgz#b2ce2e789233d62283fae2c16baabd4f1dbc9633" - integrity sha512-l3ZXob+h0NQzz80lBGaykdScYaiEbFqznEs99uwzm8fPHhDjwaBFfQkjUC/slw6Sm7npFL8qrGEAMxcfBsBJUg== +"@typescript-eslint/typescript-estree@4.28.0": + version "4.28.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.0.tgz#e66d4e5aa2ede66fec8af434898fe61af10c71cf" + integrity sha512-m19UQTRtxMzKAm8QxfKpvh6OwQSXaW1CdZPoCaQuLwAq7VZMNuhJmZR4g5281s2ECt658sldnJfdpSZZaxUGMQ== dependencies: - "@typescript-eslint/types" "4.26.1" - "@typescript-eslint/visitor-keys" "4.26.1" + "@typescript-eslint/types" "4.28.0" + "@typescript-eslint/visitor-keys" "4.28.0" debug "^4.3.1" globby "^11.0.3" is-glob "^4.0.1" semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/visitor-keys@4.26.1": - version "4.26.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.26.1.tgz#0d55ea735cb0d8903b198017d6d4f518fdaac546" - integrity sha512-IGouNSSd+6x/fHtYRyLOM6/C+QxMDzWlDtN41ea+flWuSF9g02iqcIlX8wM53JkfljoIjP0U+yp7SiTS1onEkw== +"@typescript-eslint/visitor-keys@4.28.0": + version "4.28.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.0.tgz#255c67c966ec294104169a6939d96f91c8a89434" + integrity sha512-PjJyTWwrlrvM5jazxYF5ZPs/nl0kHDZMVbuIcbpawVXaDPelp3+S9zpOz5RmVUfS/fD5l5+ZXNKnWhNYjPzCvw== dependencies: - "@typescript-eslint/types" "4.26.1" + "@typescript-eslint/types" "4.28.0" eslint-visitor-keys "^2.0.0" "@vercel/ncc@0.28.3": @@ -2954,36 +3183,37 @@ resolved "https://registry.yarnpkg.com/@vercel/ncc/-/ncc-0.28.3.tgz#9461bdbf334d616759b0e7e5415e2f480b9aa30f" integrity sha512-g3gk4D9itbhUQa5MtN7TOdeoQnNLkPDCox5SBaQ/H3Or5lo59TOaZWrLb+x47StiAJ+8DXZS/9MJ67cIBWSsRw== -"@vue/compiler-core@3.1.1": - version "3.1.1" - resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.1.1.tgz#4f2c5d70eabd454675714cc8bd2b97f6a8efb196" - integrity sha512-Z1RO3T6AEtAUFf2EqqovFm3ohAeTvFzRtB0qUENW2nEerJfdlk13/LS1a0EgsqlzxmYfR/S/S/gW9PLbFZZxkA== +"@vue/compiler-core@3.1.4": + version "3.1.4" + resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.1.4.tgz#a3a74cf52e8f01af386d364ac8a099cbeb260424" + integrity sha512-TnUz+1z0y74O/A4YKAbzsdUfamyHV73MihrEfvettWpm9bQKVoZd1nEmR1cGN9LsXWlwAvVQBetBlWdOjmQO5Q== dependencies: "@babel/parser" "^7.12.0" "@babel/types" "^7.12.0" - "@vue/shared" "3.1.1" + "@vue/shared" "3.1.4" estree-walker "^2.0.1" source-map "^0.6.1" -"@vue/compiler-dom@3.1.1": - version "3.1.1" - resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.1.1.tgz#ef60d856ac2ede5b2ad5c72a7a68122895e3d652" - integrity sha512-nobRIo0t5ibzg+q8nC31m+aJhbq8FbWUoKvk6h3Vs1EqTDJaj6lBTcVTq5or8AYht7FbSpdAJ81isbJ1rWNX7A== +"@vue/compiler-dom@3.1.4": + version "3.1.4" + resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.1.4.tgz#bf3795e1449f32c965d38c4ea6d808ca05fdfc97" + integrity sha512-3tG2ScHkghhUBuFwl9KgyZhrS8CPFZsO7hUDekJgIp5b1OMkROr4AvxHu6rRMl4WkyvYkvidFNBS2VfOnwa6Kw== dependencies: - "@vue/compiler-core" "3.1.1" - "@vue/shared" "3.1.1" + "@vue/compiler-core" "3.1.4" + "@vue/shared" "3.1.4" -"@vue/compiler-sfc@3.1.1": - version "3.1.1" - resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.1.1.tgz#d4e4507c013d0b219f0b106b317ec5bb1cde3398" - integrity sha512-lSgMsZaYHF+bAgryq5aUqpvyfhu52GJI2/4LoiJCE5uaxc6FCZfxfgqgw/d9ltiZghv+HiISFtmQVAVvlsk+/w== +"@vue/compiler-sfc@3.1.4": + version "3.1.4" + resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.1.4.tgz#93e87db950e0711339c18baa7bb7d28d3522d7bc" + integrity sha512-4KDQg60Khy3SgnF+V/TB2NZqzmM4TyGRmzsxqG1SebGdMSecCweFDSlI/F1vDYk6dKiCHgmpoT9A1sLxswkJ0A== dependencies: "@babel/parser" "^7.13.9" "@babel/types" "^7.13.0" - "@vue/compiler-core" "3.1.1" - "@vue/compiler-dom" "3.1.1" - "@vue/compiler-ssr" "3.1.1" - "@vue/shared" "3.1.1" + "@types/estree" "^0.0.48" + "@vue/compiler-core" "3.1.4" + "@vue/compiler-dom" "3.1.4" + "@vue/compiler-ssr" "3.1.4" + "@vue/shared" "3.1.4" consolidate "^0.16.0" estree-walker "^2.0.1" hash-sum "^2.0.0" @@ -2995,18 +3225,18 @@ postcss-selector-parser "^6.0.4" source-map "^0.6.1" -"@vue/compiler-ssr@3.1.1": - version "3.1.1" - resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.1.1.tgz#1d08b98601397258ed059b75966e0e94a385d770" - integrity sha512-7H6krZtVt3h/YzfNp7eYK41hMDz8ZskiBy+Wby+EDRINX6BD9JQ5C8zyy2xAa7T6Iz2VrQzsaJ/Bb52lTPSS5A== +"@vue/compiler-ssr@3.1.4": + version "3.1.4" + resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.1.4.tgz#7f6eaac5b1851fc15c82c083e8179eb1216b303c" + integrity sha512-Box8fCuCFPp0FuimIswjDkjwiSDCBkHvt/xVALyFkYCiIMWv2eR53fIjmlsnEHhcBuZ+VgRC+UanCTcKvSA1gA== dependencies: - "@vue/compiler-dom" "3.1.1" - "@vue/shared" "3.1.1" + "@vue/compiler-dom" "3.1.4" + "@vue/shared" "3.1.4" -"@vue/shared@3.1.1": - version "3.1.1" - resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.1.1.tgz#2287cfc3dc20e5b20aeb65c2c3a56533bdca801c" - integrity sha512-g+4pzAw7PYSjARtLBoDq6DmcblX8i9KJHSCnyM5VDDFFifUaUT9iHbFpOF/KOizQ9f7QAqU2JH3Y6aXjzUMhVA== +"@vue/shared@3.1.4": + version "3.1.4" + resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.1.4.tgz#c14c461ec42ea2c1556e86f60b0354341d91adc3" + integrity sha512-6O45kZAmkLvzGLToBxEz4lR2W6kXohCtebV2UxjH9GXjd8X9AhEn68FN9eNanFtWNzvgw1hqd6HkPRVQalqf7Q== "@webassemblyjs/ast@1.11.0": version "1.11.0" @@ -3150,6 +3380,11 @@ dependencies: tslib "^2.1.0" +"@xobotyi/scrollbar-width@^1.9.5": + version "1.9.5" + resolved "https://registry.yarnpkg.com/@xobotyi/scrollbar-width/-/scrollbar-width-1.9.5.tgz#80224a6919272f405b87913ca13b92929bdf3c4d" + integrity sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ== + "@xtuc/ieee754@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" @@ -3177,7 +3412,7 @@ abort-controller@3.0.0: dependencies: event-target-shim "^5.0.0" -accepts@^1.3.7, accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: +accepts@^1.3.7, accepts@~1.3.7: version "1.3.7" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== @@ -3213,25 +3448,25 @@ acorn-walk@^7.0.0, acorn-walk@^7.1.1: integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== acorn-walk@^8.0.0: - version "8.0.2" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.0.2.tgz#d4632bfc63fd93d0f15fd05ea0e984ffd3f5a8c3" - integrity sha512-+bpA9MJsHdZ4bgfDcpk0ozQyhhVct7rzOmO0s1IIr0AGGgKBljss8n2zp11rRP2wid5VGeh04CgeKzgat5/25A== + version "8.1.1" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.1.1.tgz#3ddab7f84e4a7e2313f6c414c5b7dac85f4e3ebc" + integrity sha512-FbJdceMlPHEAWJOILDk1fXD8lnTlEIWFkqtfk+MvmL5q/qlHfN7GEHcsFZWt/Tea9jRNPWUZG4G976nqAAmU9w== acorn@^7.0.0, acorn@^7.1.1, acorn@^7.4.0: version "7.4.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^8.0.4, acorn@^8.2.1, acorn@^8.2.4: +acorn@^8.0.4, acorn@^8.2.1: + version "8.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.4.1.tgz#56c36251fc7cabc7096adc18f05afe814321a28c" + integrity sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA== + +acorn@^8.2.4: version "8.2.4" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.2.4.tgz#caba24b08185c3b56e3168e97d15ed17f4d31fd0" integrity sha512-Ibt84YwBDDA890eDiDCEqcbwvHlBvzzDkU2cGBBDDI1QWT12jTiXIOn2CIw5KK4i6N5Z2HUxwYjzriDyqaqqZg== -address@1.1.2, address@^1.0.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" - integrity sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA== - agent-base@6: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" @@ -3247,17 +3482,12 @@ aggregate-error@^3.0.0: clean-stack "^2.0.0" indent-string "^4.0.0" -ajv-errors@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" - integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== - -ajv-keywords@^3.1.0, ajv-keywords@^3.5.2: +ajv-keywords@^3.5.2: version "3.5.2" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== -ajv@^6.1.0, ajv@^6.10.0, ajv@^6.12.4, ajv@^6.12.5: +ajv@^6.10.0, ajv@^6.12.4, ajv@^6.12.5: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -3277,37 +3507,37 @@ ajv@^8.0.1: require-from-string "^2.0.2" uri-js "^4.2.2" -algoliasearch-helper@^3.3.4, algoliasearch-helper@^3.4.3: - version "3.4.4" - resolved "https://registry.yarnpkg.com/algoliasearch-helper/-/algoliasearch-helper-3.4.4.tgz#f2eb46bc4d2f6fed82c7201b8ac4ce0a1988ae67" - integrity sha512-OjyVLjykaYKCMxxRMZNiwLp8CS310E0qAeIY2NaublcmLAh8/SL19+zYHp7XCLtMem2ZXwl3ywMiA32O9jszuw== +algoliasearch-helper@^3.5.3: + version "3.5.4" + resolved "https://registry.yarnpkg.com/algoliasearch-helper/-/algoliasearch-helper-3.5.4.tgz#21b20ab8a258daa9dde9aef2daa5e8994cd66077" + integrity sha512-t+FLhXYnPZiwjYe5ExyN962HQY8mi3KwRju3Lyf6OBgtRdx30d6mqvtClXf5NeBihH45Xzj6t4Y5YyvAI432XA== dependencies: events "^1.1.1" -algoliasearch@^4.0.0, algoliasearch@^4.8.4, algoliasearch@^4.9.1: - version "4.9.1" - resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-4.9.1.tgz#1fa8ece3f9808e465226176b88b953801c2274e0" - integrity sha512-EeJUYXzBEhZSsL6tXc3hseLBCtlNLa1MZ4mlMK6EeX38yRjY5vgnFcNNml6uUhlOjvheKxgkKRpPWkxgL8Cqkg== - dependencies: - "@algolia/cache-browser-local-storage" "4.9.1" - "@algolia/cache-common" "4.9.1" - "@algolia/cache-in-memory" "4.9.1" - "@algolia/client-account" "4.9.1" - "@algolia/client-analytics" "4.9.1" - "@algolia/client-common" "4.9.1" - "@algolia/client-recommendation" "4.9.1" - "@algolia/client-search" "4.9.1" - "@algolia/logger-common" "4.9.1" - "@algolia/logger-console" "4.9.1" - "@algolia/requester-browser-xhr" "4.9.1" - "@algolia/requester-common" "4.9.1" - "@algolia/requester-node-http" "4.9.1" - "@algolia/transporter" "4.9.1" - -alphanum-sort@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" - integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM= +algoliasearch@^4.9.1: + version "4.10.3" + resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-4.10.3.tgz#22df4bb02fbf13a765b18b85df8745ee9c04f00a" + integrity sha512-OLY0AWlPKGLbSaw14ivMB7BT5fPdp8VdzY4L8FtzZnqmLKsyes24cltGlf7/X96ACkYEcT390SReCDt/9SUIRg== + dependencies: + "@algolia/cache-browser-local-storage" "4.10.3" + "@algolia/cache-common" "4.10.3" + "@algolia/cache-in-memory" "4.10.3" + "@algolia/client-account" "4.10.3" + "@algolia/client-analytics" "4.10.3" + "@algolia/client-common" "4.10.3" + "@algolia/client-personalization" "4.10.3" + "@algolia/client-search" "4.10.3" + "@algolia/logger-common" "4.10.3" + "@algolia/logger-console" "4.10.3" + "@algolia/requester-browser-xhr" "4.10.3" + "@algolia/requester-common" "4.10.3" + "@algolia/requester-node-http" "4.10.3" + "@algolia/transporter" "4.10.3" + +anser@1.4.9: + version "1.4.9" + resolved "https://registry.yarnpkg.com/anser/-/anser-1.4.9.tgz#1f85423a5dcf8da4631a341665ff675b96845760" + integrity sha512-AI+BjTeGt2+WFk4eWcqbQ7snZpDBt8SaLlj0RT2h5xfdWaiy51OjYvqwMrNzJLGy8iOAL6nKDITWO+rd4MkYEA== ansi-align@^2.0.0: version "2.0.0" @@ -3316,56 +3546,29 @@ ansi-align@^2.0.0: dependencies: string-width "^2.0.0" -ansi-align@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.0.tgz#b536b371cf687caaef236c18d3e21fe3797467cb" - integrity sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw== - dependencies: - string-width "^3.0.0" - -ansi-colors@^3.0.0: - version "3.2.4" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf" - integrity sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA== - ansi-colors@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== -ansi-escapes@^4.2.1, ansi-escapes@^4.3.0, ansi-escapes@^4.3.1: +ansi-escapes@^4.2.1, ansi-escapes@^4.3.0: version "4.3.1" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.1.tgz#a5c47cc43181f1f38ffd7076837700d395522a61" integrity sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA== dependencies: type-fest "^0.11.0" -ansi-html@0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" - integrity sha1-gTWEAhliqenm/QOflA0S9WynhZ4= - -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= - ansi-regex@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= -ansi-regex@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" - integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== - ansi-regex@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== -ansi-styles@^3.2.0, ansi-styles@^3.2.1: +ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== @@ -3384,15 +3587,7 @@ ansi-styles@^5.0.0: resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== -anymatch@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" - integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== - dependencies: - micromatch "^3.1.4" - normalize-path "^2.1.1" - -anymatch@^3.0.3, anymatch@~3.1.1: +anymatch@^3.0.3: version "3.1.1" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== @@ -3400,12 +3595,20 @@ anymatch@^3.0.3, anymatch@~3.1.1: normalize-path "^3.0.0" picomatch "^2.0.4" -apollo-upload-client@15.0.0: - version "15.0.0" - resolved "https://registry.yarnpkg.com/apollo-upload-client/-/apollo-upload-client-15.0.0.tgz#02ad5a156c146c13f3a93b9658196e5d73a73fca" - integrity sha512-7kyBwflLTqRhfsNIIBc94z1Row3WVWOgLm77izAuG3YJEzUbpy8k4775G40j3xlToSey5c7CR/9NOdoDcQw/xg== +anymatch@~3.1.1, anymatch@~3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +apollo-upload-client@16.0.0: + version "16.0.0" + resolved "https://registry.yarnpkg.com/apollo-upload-client/-/apollo-upload-client-16.0.0.tgz#704c9bc21e12bd4687172876eb927cf756b2e524" + integrity sha512-aLhYucyA0T8aBEQ5g+p13qnR9RUyL8xqb8FSZ7e/Kw2KUOsotLUlFluLobqaE7JSUFwc6sKfXIcwB7y4yEjbZg== dependencies: - extract-files "^10.0.0" + extract-files "^11.0.0" arg@^5.0.0: version "5.0.0" @@ -3424,31 +3627,18 @@ argparse@^2.0.1: resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== -arr-diff@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" - integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= - -arr-flatten@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" - integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== - -arr-union@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" - integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= +aria-hidden@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/aria-hidden/-/aria-hidden-1.1.3.tgz#bb48de18dc84787a3c6eee113709c473c64ec254" + integrity sha512-RhVWFtKH5BiGMycI72q2RAFMLQi8JP9bLuQXgR5a8Znp7P5KOIADSJeyfI8PCVxLEp067B2HbP5JIiI/PXIZeA== + dependencies: + tslib "^1.0.0" array-flatten@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= -array-flatten@^2.1.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" - integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== - array-includes@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.3.tgz#c7f619b382ad2afaf5326cddfdc0afc61af7690a" @@ -3460,28 +3650,11 @@ array-includes@^3.1.3: get-intrinsic "^1.1.1" is-string "^1.0.5" -array-union@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" - integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= - dependencies: - array-uniq "^1.0.1" - array-union@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== -array-uniq@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" - integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= - -array-unique@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" - integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= - array.prototype.flat@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz#6ef638b43312bd401b4c6199fdec7e2dc9e9a123" @@ -3501,32 +3674,43 @@ asap@~2.0.3: resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= -assign-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" - integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= +asn1.js@^5.2.0: + version "5.4.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.4.1.tgz#11a980b84ebb91781ce35b0fdc2ee294e3783f07" + integrity sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA== + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + safer-buffer "^2.1.0" -astral-regex@^2.0.0: +assert@2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" - integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== + resolved "https://registry.yarnpkg.com/assert/-/assert-2.0.0.tgz#95fc1c616d48713510680f2eaf2d10dd22e02d32" + integrity sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A== + dependencies: + es6-object-assign "^1.1.0" + is-nan "^1.2.1" + object-is "^1.0.1" + util "^0.12.0" -async-each@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" - integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== +assert@^1.1.1: + version "1.5.0" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" + integrity sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA== + dependencies: + object-assign "^4.1.1" + util "0.10.3" -async-limiter@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" - integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== +ast-types@0.13.2: + version "0.13.2" + resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.13.2.tgz#df39b677a911a83f3a049644fb74fdded23cea48" + integrity sha512-uWMHxJxtfj/1oZClOxDEV1sQ1HCDkA4MG8Gr69KKeBjEVH0R84WlejZ0y2DcwyBlpAEMltmVYkVgqfLFb2oyiA== -async@^2.6.2: - version "2.6.3" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" - integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== - dependencies: - lodash "^4.17.14" +astral-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" + integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== asynckit@^0.4.0: version "0.4.0" @@ -3538,54 +3722,44 @@ at-least-node@^1.0.0: resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== -atob@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" - integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== - -autoprefixer@^10.0.2, autoprefixer@^10.2.5: - version "10.2.5" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.2.5.tgz#096a0337dbc96c0873526d7fef5de4428d05382d" - integrity sha512-7H4AJZXvSsn62SqZyJCP+1AWwOuoYpUfK6ot9vm0e87XD6mT8lDywc9D9OTJPMULyGcvmIxzTAMeG2Cc+YX+fA== +autoprefixer@^10.2.5: + version "10.2.6" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.2.6.tgz#aadd9ec34e1c98d403e01950038049f0eb252949" + integrity sha512-8lChSmdU6dCNMCQopIf4Pe5kipkAGj/fvTMslCsih0uHpOrXOPUEVOmYMMqmw3cekQkSD7EhIeuYl5y0BLdKqg== dependencies: - browserslist "^4.16.3" - caniuse-lite "^1.0.30001196" + browserslist "^4.16.6" + caniuse-lite "^1.0.30001230" colorette "^1.2.2" - fraction.js "^4.0.13" + fraction.js "^4.1.1" normalize-range "^0.1.2" postcss-value-parser "^4.1.0" -axios@^0.21.1: +available-typed-arrays@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.4.tgz#9e0ae84ecff20caae6a94a1c3bc39b955649b7a9" + integrity sha512-SA5mXJWrId1TaQjfxUYghbqQ/hYioKmLJvPJyDuYRtXXenFNMjj4hSSt1Cf1xsuXSXrtxrVC5Ot4eU6cOtBDdA== + +axios@0.21.1, axios@^0.21.1: version "0.21.1" resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8" integrity sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA== dependencies: follow-redirects "^1.10.0" -babel-jest@27.0.2, babel-jest@^27.0.2: - version "27.0.2" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.0.2.tgz#7dc18adb01322acce62c2af76ea2c7cd186ade37" - integrity sha512-9OThPl3/IQbo4Yul2vMz4FYwILPQak8XelX4YGowygfHaOl5R5gfjm4iVx4d8aUugkW683t8aq0A74E7b5DU1Q== +babel-jest@27.0.6, babel-jest@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.0.6.tgz#e99c6e0577da2655118e3608b68761a5a69bd0d8" + integrity sha512-iTJyYLNc4wRofASmofpOc5NK9QunwMk+TLFgGXsTFS8uEqmd8wdI7sga0FPe2oVH3b5Agt/EAK1QjPEuKL8VfA== dependencies: - "@jest/transform" "^27.0.2" - "@jest/types" "^27.0.2" + "@jest/transform" "^27.0.6" + "@jest/types" "^27.0.6" "@types/babel__core" "^7.1.14" babel-plugin-istanbul "^6.0.0" - babel-preset-jest "^27.0.1" + babel-preset-jest "^27.0.6" chalk "^4.0.0" graceful-fs "^4.2.4" slash "^3.0.0" -babel-loader@^8.2.2: - version "8.2.2" - resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.2.tgz#9363ce84c10c9a40e6c753748e1441b60c8a0b81" - integrity sha512-JvTd0/D889PQBtUXJ2PXaKU/pjZDMtHA9V2ecm+eNRmmBCMR09a+fmpGTNwnJtFmFl5Ei7Vy47LjBb+L0wQ99g== - dependencies: - find-cache-dir "^3.3.1" - loader-utils "^1.4.0" - make-dir "^3.1.0" - schema-utils "^2.6.5" - babel-plugin-apply-mdx-type-prop@1.6.22: version "1.6.22" resolved "https://registry.yarnpkg.com/babel-plugin-apply-mdx-type-prop/-/babel-plugin-apply-mdx-type-prop-1.6.22.tgz#d216e8fd0de91de3f1478ef3231e05446bc8705b" @@ -3594,13 +3768,6 @@ babel-plugin-apply-mdx-type-prop@1.6.22: "@babel/helper-plugin-utils" "7.10.4" "@mdx-js/util" "1.6.22" -babel-plugin-dynamic-import-node@2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz#f00f507bdaa3c3e3ff6e7e5e98d90a7acab96f7f" - integrity sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ== - dependencies: - object.assign "^4.1.0" - babel-plugin-dynamic-import-node@^2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" @@ -3626,10 +3793,10 @@ babel-plugin-istanbul@^6.0.0: istanbul-lib-instrument "^4.0.0" test-exclude "^6.0.0" -babel-plugin-jest-hoist@^27.0.1: - version "27.0.1" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.0.1.tgz#a6d10e484c93abff0f4e95f437dad26e5736ea11" - integrity sha512-sqBF0owAcCDBVEDtxqfYr2F36eSHdx7lAVGyYuOBRnKdD6gzcy0I0XrAYCZgOA3CRrLhmR+Uae9nogPzmAtOfQ== +babel-plugin-jest-hoist@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.0.6.tgz#f7c6b3d764af21cb4a2a1ab6870117dbde15b456" + integrity sha512-CewFeM9Vv2gM7Yr9n5eyyLVPRSiBnk6lKZRjgwYnGKSl9M14TMn2vkN02wTF04OGuSDLEzlWiMzvjXuW9mB6Gw== dependencies: "@babel/template" "^7.3.3" "@babel/types" "^7.3.3" @@ -3645,15 +3812,6 @@ babel-plugin-macros@^2.6.1, babel-plugin-macros@^2.8.0: cosmiconfig "^6.0.0" resolve "^1.12.0" -babel-plugin-polyfill-corejs2@^0.1.4: - version "0.1.10" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.1.10.tgz#a2c5c245f56c0cac3dbddbf0726a46b24f0f81d1" - integrity sha512-DO95wD4g0A8KRaHKi0D51NdGXzvpqVLnLu5BTvDlpqUEpTmeEtypgC1xqesORaWmiUOQI14UHKlzNd9iZ2G3ZA== - dependencies: - "@babel/compat-data" "^7.13.0" - "@babel/helper-define-polyfill-provider" "^0.1.5" - semver "^6.1.1" - babel-plugin-polyfill-corejs2@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.2.tgz#e9124785e6fd94f94b618a7954e5693053bf5327" @@ -3663,14 +3821,6 @@ babel-plugin-polyfill-corejs2@^0.2.2: "@babel/helper-define-polyfill-provider" "^0.2.2" semver "^6.1.1" -babel-plugin-polyfill-corejs3@^0.1.3: - version "0.1.7" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.1.7.tgz#80449d9d6f2274912e05d9e182b54816904befd0" - integrity sha512-u+gbS9bbPhZWEeyy1oR/YaaSpod/KDT07arZHb80aTpl8H5ZBq+uN1nN9/xtX7jQyfLdPfoqI4Rue/MQSWJquw== - dependencies: - "@babel/helper-define-polyfill-provider" "^0.1.5" - core-js-compat "^3.8.1" - babel-plugin-polyfill-corejs3@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.2.tgz#7424a1682ee44baec817327710b1b094e5f8f7f5" @@ -3679,13 +3829,6 @@ babel-plugin-polyfill-corejs3@^0.2.2: "@babel/helper-define-polyfill-provider" "^0.2.2" core-js-compat "^3.9.1" -babel-plugin-polyfill-regenerator@^0.1.2: - version "0.1.6" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.1.6.tgz#0fe06a026fe0faa628ccc8ba3302da0a6ce02f3f" - integrity sha512-OUrYG9iKPKz8NxswXbRAdSwF0GhRdIEMTloQATJi4bDuFqrXaXcCUT/VGNrr8pBcjMh1RxZ7Xt9cytVJTJfvMg== - dependencies: - "@babel/helper-define-polyfill-provider" "^0.1.5" - babel-plugin-polyfill-regenerator@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.2.tgz#b310c8d642acada348c1fa3b3e6ce0e851bee077" @@ -3693,17 +3836,7 @@ babel-plugin-polyfill-regenerator@^0.2.2: dependencies: "@babel/helper-define-polyfill-provider" "^0.2.2" -"babel-plugin-styled-components@>= 1.12.0": - version "1.12.0" - resolved "https://registry.yarnpkg.com/babel-plugin-styled-components/-/babel-plugin-styled-components-1.12.0.tgz#1dec1676512177de6b827211e9eda5a30db4f9b9" - integrity sha512-FEiD7l5ZABdJPpLssKXjBUJMYqzbcNzBowfXDCdJhOpbhWiewapUaY+LZGT8R4Jg2TwOjGjG4RKeyrO5p9sBkA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.0.0" - "@babel/helper-module-imports" "^7.0.0" - babel-plugin-syntax-jsx "^6.18.0" - lodash "^4.17.11" - -babel-plugin-syntax-jsx@^6.18.0: +babel-plugin-syntax-jsx@6.18.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" integrity sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY= @@ -3764,12 +3897,12 @@ babel-preset-fbjs@^3.3.0: "@babel/plugin-transform-template-literals" "^7.0.0" babel-plugin-syntax-trailing-function-commas "^7.0.0-beta.0" -babel-preset-jest@^27.0.1: - version "27.0.1" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-27.0.1.tgz#7a50c75d16647c23a2cf5158d5bb9eb206b10e20" - integrity sha512-nIBIqCEpuiyhvjQs2mVNwTxQQa2xk70p9Dd/0obQGBf8FBzbnI8QhQKzLsWMN2i6q+5B0OcWDtrboBX5gmOLyA== +babel-preset-jest@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-27.0.6.tgz#909ef08e9f24a4679768be2f60a3df0856843f9d" + integrity sha512-WObA0/Biw2LrVVwZkF/2GqbOdzhKD6Fkdwhoy9ASIrOWr/zodcSpQh72JOkEn6NWyjmnPDjNSqaGN4KnpKzhXw== dependencies: - babel-plugin-jest-hoist "^27.0.1" + babel-plugin-jest-hoist "^27.0.6" babel-preset-current-node-syntax "^1.0.0" backo2@^1.0.2: @@ -3787,34 +3920,11 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= -base16@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/base16/-/base16-1.0.0.tgz#e297f60d7ec1014a7a971a39ebc8a98c0b681e70" - integrity sha1-4pf2DX7BAUp6lxo568ipjAtoHnA= - -base64-js@^1.3.1: +base64-js@^1.0.2, base64-js@^1.3.1: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== -base@^0.11.1: - version "0.11.2" - resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" - integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== - dependencies: - 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" - -batch@0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" - integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY= - better-path-resolve@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/better-path-resolve/-/better-path-resolve-1.0.0.tgz#13a35a1104cdd48a7b74bf8758f96a1ee613f99d" @@ -3827,28 +3937,26 @@ big.js@^5.2.2: resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== -binary-extensions@^1.0.0: - version "1.13.1" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" - integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== - binary-extensions@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== -bindings@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" - integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== - dependencies: - file-uri-to-path "1.0.0" - -bluebird@^3.7.1, bluebird@^3.7.2: +bluebird@^3.7.2: version "3.7.2" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9: + version "4.12.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" + integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== + +bn.js@^5.0.0, bn.js@^5.1.1: + version "5.2.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.0.tgz#358860674396c6997771a9d051fcc1b57d4ae002" + integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw== + bob-the-bundler@1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/bob-the-bundler/-/bob-the-bundler-1.4.1.tgz#794382f60f0d2a68c57d85a41d06caf4a45cb1b4" @@ -3873,7 +3981,7 @@ bob-the-bundler@1.4.1: tslib "^1.11.1" yargs "15.3.1" -body-parser@1.19.0: +body-parser@1.19.0, body-parser@^1.19.0: version "1.19.0" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== @@ -3889,23 +3997,6 @@ body-parser@1.19.0: raw-body "2.4.0" type-is "~1.6.17" -bonjour@^3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5" - integrity sha1-jokKGD2O6aI5OzhExpGkK897yfU= - dependencies: - array-flatten "^2.1.0" - deep-equal "^1.0.1" - dns-equal "^1.0.0" - dns-txt "^2.0.2" - multicast-dns "^6.0.1" - multicast-dns-service-types "^1.1.0" - -boolbase@^1.0.0, boolbase@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" - integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= - boxen@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b" @@ -3919,20 +4010,6 @@ boxen@^1.3.0: term-size "^1.2.0" widest-line "^2.0.0" -boxen@^5.0.0, boxen@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.0.1.tgz#657528bdd3f59a772b8279b831f27ec2c744664b" - integrity sha512-49VBlw+PrWEF51aCmy7QIteYPIFZxSpvqBdP/2itCPPlJ49kj9zg/XPRFrdkne2W+CfwXUls8exMvu1RysZpKA== - dependencies: - ansi-align "^3.0.0" - camelcase "^6.2.0" - chalk "^4.1.0" - cli-boxes "^2.2.1" - string-width "^4.2.0" - type-fest "^0.20.2" - widest-line "^3.1.0" - wrap-ansi "^7.0.0" - brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -3941,22 +4018,6 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" -braces@^2.3.1, braces@^2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" - integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== - dependencies: - 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" - braces@^3.0.1, braces@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" @@ -3971,22 +4032,78 @@ breakword@^1.0.5: dependencies: wcwidth "^1.0.1" +brorand@^1.0.1, brorand@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= + browser-process-hrtime@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== -browserslist@4.14.2: - version "4.14.2" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.14.2.tgz#1b3cec458a1ba87588cc5e9be62f19b6d48813ce" - integrity sha512-HI4lPveGKUR0x2StIz+2FXfDk9SfVMrxn6PLh1JeGUwcuoDkdKZebWiyLRJ68iIPDpMI4JLVDf7S7XzslgWOhw== +browserify-aes@^1.0.0, browserify-aes@^1.0.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== + dependencies: + buffer-xor "^1.0.3" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.3" + inherits "^2.0.1" + safe-buffer "^5.0.1" + +browserify-cipher@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + +browserify-des@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +browserify-rsa@^4.0.0, browserify-rsa@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.0.tgz#b2fd06b5b75ae297f7ce2dc651f918f5be158c8d" + integrity sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog== + dependencies: + bn.js "^5.0.0" + randombytes "^2.0.1" + +browserify-sign@^4.0.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.1.tgz#eaf4add46dd54be3bb3b36c0cf15abbeba7956c3" + integrity sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg== + dependencies: + bn.js "^5.1.1" + browserify-rsa "^4.0.1" + create-hash "^1.2.0" + create-hmac "^1.1.7" + elliptic "^6.5.3" + inherits "^2.0.4" + parse-asn1 "^5.1.5" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" + +browserify-zlib@0.2.0, browserify-zlib@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" + integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== dependencies: - caniuse-lite "^1.0.30001125" - electron-to-chromium "^1.3.564" - escalade "^3.0.2" - node-releases "^1.1.61" + pako "~1.0.5" -browserslist@^4.0.0, browserslist@^4.14.5, browserslist@^4.16.0, browserslist@^4.16.3, browserslist@^4.16.6: +browserslist@4.16.6, browserslist@^4.14.5, browserslist@^4.16.6: version "4.16.6" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.6.tgz#d7901277a5a88e554ed305b183ec9b0c08f66fa2" integrity sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ== @@ -4021,10 +4138,27 @@ buffer-from@1.x, buffer-from@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== -buffer-indexof@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c" - integrity sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g== +buffer-xor@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= + +buffer@5.6.0: + version "5.6.0" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.6.0.tgz#a31749dc7d81d84db08abf937b6b8c4033f62786" + integrity sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + +buffer@^4.3.0: + version "4.9.2" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" + integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" buffer@^5.7.0: version "5.7.1" @@ -4039,6 +4173,11 @@ builtin-modules@^3.1.0: resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.2.0.tgz#45d5db99e7ee5e6bc4f362e008bf917ab5049887" integrity sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA== +builtin-status-codes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" + integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= + builtins@4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/builtins/-/builtins-4.0.0.tgz#a8345420de82068fdc4d6559d0456403a8fb1905" @@ -4053,44 +4192,11 @@ busboy@^0.3.1: dependencies: dicer "0.3.0" -bytes@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" - integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= - bytes@3.1.0, bytes@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== -cache-base@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" - integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== - dependencies: - 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" - -cacheable-request@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" - integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg== - dependencies: - clone-response "^1.0.2" - get-stream "^5.1.0" - http-cache-semantics "^4.0.0" - keyv "^3.0.0" - lowercase-keys "^2.0.0" - normalize-url "^4.1.0" - responselike "^1.0.2" - call-bind@^1.0.0, call-bind@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" @@ -4104,14 +4210,6 @@ callsites@^3.0.0: resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== -camel-case@4.1.2, camel-case@^4.1.1: - version "4.1.2" - resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.2.tgz#9728072a954f805228225a6deea6b38461e1bd5a" - integrity sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw== - dependencies: - pascal-case "^3.1.2" - tslib "^2.0.3" - camelcase-css@2.0.1, camelcase-css@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5" @@ -4141,22 +4239,12 @@ camelcase@^6.2.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809" integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== -camelize@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.0.tgz#164a5483e630fa4321e5af07020e531831b2609b" - integrity sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs= - -caniuse-api@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" - integrity sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw== - dependencies: - browserslist "^4.0.0" - caniuse-lite "^1.0.0" - lodash.memoize "^4.1.2" - lodash.uniq "^4.5.0" +caniuse-lite@^1.0.30001202, caniuse-lite@^1.0.30001228, caniuse-lite@^1.0.30001230: + version "1.0.30001242" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001242.tgz#04201627abcd60dc89211f22cbe2347306cda46b" + integrity sha512-KvNuZ/duufelMB3w2xtf9gEWCSxJwUgoxOx5b6ScLXC4kPc9xsczUVCPrQU26j5kOsHM4pSUL54tAZt5THQKug== -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001125, caniuse-lite@^1.0.30001196, caniuse-lite@^1.0.30001219: +caniuse-lite@^1.0.30001219: version "1.0.30001228" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz#bfdc5942cd3326fa51ee0b42fbef4da9d492a7fa" integrity sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A== @@ -4174,7 +4262,7 @@ ccount@^1.0.0, ccount@^1.0.3: resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.1.0.tgz#246687debb6014735131be8abab2d93898f8d043" integrity sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg== -chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1, chalk@^2.4.2: +chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -4183,6 +4271,14 @@ chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1, chalk@^2.4. escape-string-regexp "^1.0.5" supports-color "^5.3.0" +chalk@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.0.0.tgz#6e98081ed2d17faab615eb52ac66ec1fe6209e72" + integrity sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + chalk@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" @@ -4224,48 +4320,7 @@ chardet@^0.7.0: resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== -cheerio@^0.22.0: - version "0.22.0" - resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-0.22.0.tgz#a9baa860a3f9b595a6b81b1a86873121ed3a269e" - integrity sha1-qbqoYKP5tZWmuBsahocxIe06Jp4= - dependencies: - css-select "~1.2.0" - dom-serializer "~0.1.0" - entities "~1.1.1" - htmlparser2 "^3.9.1" - lodash.assignin "^4.0.9" - lodash.bind "^4.1.4" - lodash.defaults "^4.0.1" - lodash.filter "^4.4.0" - lodash.flatten "^4.2.0" - lodash.foreach "^4.3.0" - lodash.map "^4.4.0" - lodash.merge "^4.4.0" - lodash.pick "^4.2.1" - lodash.reduce "^4.4.0" - lodash.reject "^4.4.0" - lodash.some "^4.4.0" - -chokidar@^2.1.8: - version "2.1.8" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" - integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== - dependencies: - anymatch "^2.0.0" - async-each "^1.0.1" - braces "^2.3.2" - glob-parent "^3.1.0" - inherits "^2.0.3" - is-binary-path "^1.0.0" - is-glob "^4.0.0" - normalize-path "^3.0.0" - path-is-absolute "^1.0.0" - readdirp "^2.2.1" - upath "^1.1.1" - optionalDependencies: - fsevents "^1.2.7" - -chokidar@^3.5.1: +chokidar@3.5.1: version "3.5.1" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a" integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw== @@ -4280,57 +4335,59 @@ chokidar@^3.5.1: optionalDependencies: fsevents "~2.3.1" -chrome-trace-event@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4" - integrity sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ== +chokidar@^3.4.0, chokidar@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" + integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ== dependencies: - tslib "^1.9.0" + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +chrome-trace-event@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" + integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== ci-info@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== -ci-info@^3.0.0, ci-info@^3.1.1: +ci-info@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.1.1.tgz#9a32fcefdf7bcdb6f0a7e1c0f8098ec57897b80a" integrity sha512-kdRWLBIJwdsYJWYJFtAFFYxybguqeF91qpZaggjG5Nf8QKdizFG2hjqvaTXbxFIcYbSaD74KpAXv6BSm17DHEQ== +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + cjs-module-lexer@^1.0.0: version "1.2.1" resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.1.tgz#2fd46d9906a126965aa541345c499aaa18e8cd73" integrity sha512-jVamGdJPDeuQilKhvVn1h3knuMOZzr8QDnpk+M9aMlCaMkTDd6fBWPhiDqFvFZ07pL0liqabAiuy8SY4jGHeaw== -class-utils@^0.3.5: - version "0.3.6" - resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" - integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== - dependencies: - arr-union "^3.1.0" - define-property "^0.2.5" - isobject "^3.0.0" - static-extend "^0.1.1" +classnames@2.2.6: + version "2.2.6" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.6.tgz#43935bffdd291f326dad0a205309b38d00f650ce" + integrity sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q== -classnames@2.3.1, classnames@^2.2.5: +classnames@^2.2.5, classnames@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e" integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA== -clean-css@^4.2.3: - version "4.2.3" - resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.3.tgz#507b5de7d97b48ee53d84adb0160ff6216380f78" - integrity sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA== - dependencies: - source-map "~0.6.0" - -clean-css@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.1.2.tgz#6ea0da7286b4ddc2469a1b776e2461a5007eed54" - integrity sha512-QcaGg9OuMo+0Ds933yLOY+gHPWbxhxqF0HDexmToPf8pczvmvZGYzd+QqWp9/mkucAOKViI+dSFOqoZIvXbeBw== - dependencies: - source-map "~0.6.0" - clean-set@^1.1.1: version "1.1.2" resolved "https://registry.yarnpkg.com/clean-set/-/clean-set-1.1.2.tgz#76d8bf238c3e27827bfa73073ecdfdc767187070" @@ -4346,11 +4403,6 @@ cli-boxes@^1.0.0: resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" integrity sha1-T6kXw+WclKAEzWH47lCdplFocUM= -cli-boxes@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" - integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== - cli-cursor@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" @@ -4366,24 +4418,6 @@ cli-truncate@^2.1.0: slice-ansi "^3.0.0" string-width "^4.2.0" -clipboard@^2.0.0: - version "2.0.8" - resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-2.0.8.tgz#ffc6c103dd2967a83005f3f61976aa4655a4cdba" - integrity sha512-Y6WO0unAIQp5bLmk1zdThRhgJt/x3ks6f30s3oE3H1mgIEU33XyQjEf8gsf6DxC7NPX8Y1SsNWjUjL/ywLnnbQ== - dependencies: - good-listener "^1.2.2" - select "^1.1.2" - tiny-emitter "^2.0.0" - -cliui@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" - integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== - dependencies: - string-width "^3.1.0" - strip-ansi "^5.2.0" - wrap-ansi "^5.1.0" - cliui@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" @@ -4402,46 +4436,16 @@ cliui@^7.0.2: strip-ansi "^6.0.0" wrap-ansi "^7.0.0" -clone-deep@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" - integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== - dependencies: - is-plain-object "^2.0.4" - kind-of "^6.0.2" - shallow-clone "^3.0.0" - -clone-response@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" - integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= - dependencies: - mimic-response "^1.0.0" - clone@^1.0.2: version "1.0.4" resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= -clsx@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188" - integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA== - co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= -coa@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/coa/-/coa-2.0.2.tgz#43f6c21151b4ef2bf57187db0d73de229e3e7ec3" - integrity sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA== - dependencies: - "@types/q" "^1.5.1" - chalk "^2.4.1" - q "^1.1.2" - collapse-white-space@^1.0.2: version "1.0.6" resolved "https://registry.yarnpkg.com/collapse-white-space/-/collapse-white-space-1.0.6.tgz#e63629c0016665792060dbbeb79c42239d2c5287" @@ -4452,14 +4456,6 @@ collect-v8-coverage@^1.0.0: resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" integrity sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg== -collection-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" - integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= - dependencies: - map-visit "^1.0.0" - object-visit "^1.0.0" - color-convert@^1.9.0, color-convert@^1.9.1: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" @@ -4500,26 +4496,11 @@ color@^3.1.3: color-convert "^1.9.1" color-string "^1.5.4" -colord@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/colord/-/colord-2.0.0.tgz#f8c19f2526b7dc5b22d6e57ef102f03a2a43a3d8" - integrity sha512-WMDFJfoY3wqPZNpKUFdse3HhD5BHCbE9JCdxRzoVH+ywRITGOeWAHNkGEmyxLlErEpN9OLMWgdM9dWQtDk5dog== - colorette@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== -colors@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" - integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== - -combine-promises@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/combine-promises/-/combine-promises-1.1.0.tgz#72db90743c0ca7aab7d0d8d2052fd7b0f674de71" - integrity sha512-ZI9jvcLDxqwaXEixOhArm3r7ReIivsXkpbyEWyeOhzz1QS0iSgBPnWvEqvIQtYyamGCYA88gFhmUrs9hrrQ0pg== - combined-stream@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" @@ -4537,12 +4518,7 @@ commander@^2.20.0: resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== -commander@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" - integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== - -commander@^5.1.0: +commander@^5.0.0: version "5.1.0" resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae" integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg== @@ -4552,7 +4528,7 @@ commander@^6.0.0, commander@^6.2.0: resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== -commander@^7.1.0, commander@^7.2.0: +commander@^7.2.0: version "7.2.0" resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== @@ -4562,37 +4538,17 @@ commondir@^1.0.1: resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= -component-emitter@^1.2.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" - integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== - -compressible@~2.0.16: - version "2.0.18" - resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" - integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== - dependencies: - mime-db ">= 1.43.0 < 2" - -compression@^1.7.4: - version "1.7.4" - resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" - integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== - dependencies: - accepts "~1.3.5" - bytes "3.0.0" - compressible "~2.0.16" - debug "2.6.9" - on-headers "~1.0.2" - safe-buffer "5.1.2" - vary "~1.1.2" +compute-scroll-into-view@1.0.14: + version "1.0.14" + resolved "https://registry.yarnpkg.com/compute-scroll-into-view/-/compute-scroll-into-view-1.0.14.tgz#80e3ebb25d6aa89f42e533956cb4b16a04cfe759" + integrity sha512-mKDjINe3tc6hGelUMNDzuhorIUZ7kS7BwyY0r2wQd2HOH2tRuJykiC06iSEX8y1TuhNzvz4GcJnK16mM2J1NMQ== concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= -concurrently@6.2.0: +concurrently@6.2.0, concurrently@^6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-6.2.0.tgz#587e2cb8afca7234172d8ea55176088632c4c56d" integrity sha512-v9I4Y3wFoXCSY2L73yYgwA9ESrQMpRn80jMcqMgHx720Hecz2GZAvTI6bREVST6lkddNypDKRN22qhK0X8Y00g== @@ -4607,32 +4563,15 @@ concurrently@6.2.0: tree-kill "^1.2.2" yargs "^16.2.0" -configstore@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/configstore/-/configstore-5.0.1.tgz#d365021b5df4b98cdd187d6a3b0e3f6a7cc5ed96" - integrity sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA== - dependencies: - dot-prop "^5.2.0" - graceful-fs "^4.1.2" - make-dir "^3.0.0" - unique-string "^2.0.0" - write-file-atomic "^3.0.0" - xdg-basedir "^4.0.0" - -connect-history-api-fallback@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" - integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg== - consola@2.11.3: version "2.11.3" resolved "https://registry.yarnpkg.com/consola/-/consola-2.11.3.tgz#f7315836224c143ac5094b47fd4c816c2cd1560e" integrity sha512-aoW0YIIAmeftGR8GSpw6CGQluNdkWMWh3yEFjH/hmynTYnMtibXszii3lxCXmk8YxJtI3FAK5aTiquA5VH68Gw== -consola@^2.15.0: - version "2.15.3" - resolved "https://registry.yarnpkg.com/consola/-/consola-2.15.3.tgz#2e11f98d6a4be71ff72e0bdf07bd23e12cb61550" - integrity sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw== +console-browserify@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" + integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== consolidate@^0.16.0: version "0.16.0" @@ -4641,10 +4580,10 @@ consolidate@^0.16.0: dependencies: bluebird "^3.7.2" -content-disposition@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" - integrity sha1-DPaLud318r55YcOoUXjLhdunjLQ= +constants-browserify@1.0.0, constants-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" + integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= content-disposition@0.5.3: version "0.5.3" @@ -4658,13 +4597,20 @@ content-type@^1.0.4, content-type@~1.0.4: resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== -convert-source-map@^1.4.0, convert-source-map@^1.5.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: +convert-source-map@1.7.0, convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== dependencies: safe-buffer "~5.1.1" +convert-source-map@^1.5.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" + integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== + dependencies: + safe-buffer "~5.1.1" + cookie-signature@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" @@ -4675,46 +4621,25 @@ cookie@0.4.0: resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== -copy-descriptor@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" - integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= - -copy-text-to-clipboard@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/copy-text-to-clipboard/-/copy-text-to-clipboard-3.0.1.tgz#8cbf8f90e0a47f12e4a24743736265d157bce69c" - integrity sha512-rvVsHrpFcL4F2P8ihsoLdFHmd404+CMg71S756oRSeQgqk51U3kicGdnvfkrxva0xXH92SjGS62B0XIJsbh+9Q== - -copy-webpack-plugin@^8.1.1: - version "8.1.1" - resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-8.1.1.tgz#3f697e162764925c2f0d235f380676125508fd26" - integrity sha512-rYM2uzRxrLRpcyPqGceRBDpxxUV8vcDqIKxAUKfcnFpcrPxT5+XvhTxv7XLjo5AvEJFPdAE3zCogG2JVahqgSQ== +copy-to-clipboard@3.3.1, copy-to-clipboard@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/copy-to-clipboard/-/copy-to-clipboard-3.3.1.tgz#115aa1a9998ffab6196f93076ad6da3b913662ae" + integrity sha512-i13qo6kIHTTpCm8/Wup+0b1mVWETvu2kIMzKoK8FpkLkFxlt0znUAHcMzox+T8sPlqtZXq3CulEjQHsYiGFJUw== dependencies: - fast-glob "^3.2.5" - glob-parent "^5.1.1" - globby "^11.0.3" - normalize-path "^3.0.0" - p-limit "^3.1.0" - schema-utils "^3.0.0" - serialize-javascript "^5.0.1" + toggle-selection "^1.0.6" -core-js-compat@^3.14.0, core-js-compat@^3.8.1, core-js-compat@^3.9.1: - version "3.14.0" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.14.0.tgz#b574dabf29184681d5b16357bd33d104df3d29a5" - integrity sha512-R4NS2eupxtiJU+VwgkF9WTpnSfZW4pogwKHd8bclWU2sp93Pr5S1uYJI84cMOubJRou7bcfL0vmwtLslWN5p3A== +core-js-compat@^3.15.0, core-js-compat@^3.9.1: + version "3.15.0" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.15.0.tgz#e14a371123db9d1c5b41206d3f420643d238b8fa" + integrity sha512-8X6lWsG+s7IfOKzV93a7fRYfWRZobOfjw5V5rrq43Vh/W+V6qYxl7Akalsvgab4PFT/4L/pjQbdBUEM36NXKrw== dependencies: browserslist "^4.16.6" semver "7.0.0" -core-js-pure@^3.0.0: - version "3.9.1" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.9.1.tgz#677b322267172bd490e4464696f790cbc355bec5" - integrity sha512-laz3Zx0avrw9a4QEIdmIblnVuJz8W51leY9iLThatCsFawWxC3sE4guASC78JbCin+DkwMpCdp1AVAuzL/GN7A== - -core-js@^3.14.0, core-js@^3.9.1: - version "3.14.0" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.14.0.tgz#62322b98c71cc2018b027971a69419e2425c2a6c" - integrity sha512-3s+ed8er9ahK+zJpp9ZtuVcDoFzHNiZsPbNAAE4KXgrRHbjSqqNN6xGSXq6bq7TZIbKj4NLrLb6bJ5i+vSVjHA== +core-js@^3, core-js@^3.14.0: + version "3.15.2" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.15.2.tgz#740660d2ff55ef34ce664d7e2455119c5bdd3d61" + integrity sha512-tKs41J7NJVuaya8DxIOCnl8QuPHx5/ZVbFo1oKgVl1qHFBBrDctzQGtuLjPpRdNTWmKPH6oEvgN/MUID+l485Q== core-util-is@~1.0.0: version "1.0.2" @@ -4743,6 +4668,44 @@ cosmiconfig@^7.0.0: path-type "^4.0.0" yaml "^1.10.0" +create-ecdh@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" + integrity sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A== + dependencies: + bn.js "^4.1.0" + elliptic "^6.5.3" + +create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +cross-env@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf" + integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw== + dependencies: + cross-spawn "^7.0.1" + cross-fetch@3.1.4, cross-fetch@^3.0.4, cross-fetch@^3.0.6: version "3.1.4" resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.4.tgz#9723f3a3a247bf8b89039f3a380a9244e8fa2f39" @@ -4759,15 +4722,6 @@ cross-spawn@7.0.1: shebang-command "^2.0.0" which "^2.0.1" -cross-spawn@7.0.3, cross-spawn@^7.0.2, cross-spawn@^7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - cross-spawn@^5.0.1, cross-spawn@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" @@ -4777,7 +4731,7 @@ cross-spawn@^5.0.1, cross-spawn@^5.1.0: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^6.0.0, cross-spawn@^6.0.5: +cross-spawn@^6.0.5: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== @@ -4788,121 +4742,61 @@ cross-spawn@^6.0.0, cross-spawn@^6.0.5: shebang-command "^1.2.0" which "^1.2.9" -crypto-random-string@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" - integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== - -css-color-keywords@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/css-color-keywords/-/css-color-keywords-1.0.0.tgz#fea2616dc676b2962686b3af8dbdbe180b244e05" - integrity sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU= - -css-color-names@^0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" - integrity sha1-gIrcLnnPhHOAabZGyyDsJ762KeA= - -css-color-names@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-1.0.1.tgz#6ff7ee81a823ad46e020fa2fd6ab40a887e2ba67" - integrity sha512-/loXYOch1qU1biStIFsHH8SxTmOseh1IJqFvy8IujXOm1h+QjUdDhkzOrR5HG8K8mlxREj0yfi8ewCHx0eMxzA== - -css-declaration-sorter@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.0.3.tgz#9dfd8ea0df4cc7846827876fafb52314890c21a9" - integrity sha512-52P95mvW1SMzuRZegvpluT6yEv0FqQusydKQPZsNN5Q7hh8EwQvN8E2nwuJ16BBvNN6LcoIZXu/Bk58DAhrrxw== +cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== dependencies: - timsort "^0.3.0" + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" -css-loader@^5.1.1: - version "5.1.3" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-5.1.3.tgz#87f6fc96816b20debe3cf682f85c7e56a963d0d1" - integrity sha512-CoPZvyh8sLiGARK3gqczpfdedbM74klGWurF2CsNZ2lhNaXdLIUks+3Mfax3WBeRuHoglU+m7KG/+7gY6G4aag== - dependencies: - camelcase "^6.2.0" - cssesc "^3.0.0" - icss-utils "^5.1.0" - loader-utils "^2.0.0" - postcss "^8.2.8" - postcss-modules-extract-imports "^3.0.0" - postcss-modules-local-by-default "^4.0.0" - postcss-modules-scope "^3.0.0" - postcss-modules-values "^4.0.0" - postcss-value-parser "^4.1.0" - schema-utils "^3.0.0" - semver "^7.3.4" +crypto-browserify@3.12.0, crypto-browserify@^3.11.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== + dependencies: + browserify-cipher "^1.0.0" + browserify-sign "^4.0.0" + create-ecdh "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.0" + diffie-hellman "^5.0.0" + inherits "^2.0.1" + pbkdf2 "^3.0.3" + public-encrypt "^4.0.0" + randombytes "^2.0.0" + randomfill "^1.0.3" -css-minimizer-webpack-plugin@^2.0.0: +crypto-random-string@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-2.0.0.tgz#3c42f6624ed4cf4780dd963e23ee649e5a25c1a8" - integrity sha512-cG/uc94727tx5pBNtb1Sd7gvUPzwmcQi1lkpfqTpdkuNq75hJCw7bIVsCNijLm4dhDcr1atvuysl2rZqOG8Txw== - dependencies: - cssnano "^5.0.0" - jest-worker "^26.3.0" - p-limit "^3.0.2" - postcss "^8.2.9" - schema-utils "^3.0.0" - serialize-javascript "^5.0.1" - source-map "^0.6.1" - -css-select-base-adapter@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz#3b2ff4972cc362ab88561507a95408a1432135d7" - integrity sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w== - -css-select@^2.0.0, css-select@^2.0.2: - version "2.1.0" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-2.1.0.tgz#6a34653356635934a81baca68d0255432105dbef" - integrity sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ== - dependencies: - boolbase "^1.0.0" - css-what "^3.2.1" - domutils "^1.7.0" - nth-check "^1.0.2" - -css-select@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-3.1.2.tgz#d52cbdc6fee379fba97fb0d3925abbd18af2d9d8" - integrity sha512-qmss1EihSuBNWNNhHjxzxSfJoFBM/lERB/Q4EnsJQQC62R2evJDW481091oAdOr9uh46/0n4nrg0It5cAnj1RA== - dependencies: - boolbase "^1.0.0" - css-what "^4.0.0" - domhandler "^4.0.0" - domutils "^2.4.3" - nth-check "^2.0.0" + resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" + integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== -css-select@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" - integrity sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg= +css-box-model@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/css-box-model/-/css-box-model-1.2.1.tgz#59951d3b81fd6b2074a62d49444415b0d2b4d7c1" + integrity sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw== dependencies: - boolbase "~1.0.0" - css-what "2.1" - domutils "1.5.1" - nth-check "~1.0.1" + tiny-invariant "^1.0.6" -css-to-react-native@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/css-to-react-native/-/css-to-react-native-3.0.0.tgz#62dbe678072a824a689bcfee011fc96e02a7d756" - integrity sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ== +css-in-js-utils@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/css-in-js-utils/-/css-in-js-utils-2.0.1.tgz#3b472b398787291b47cfe3e44fecfdd9e914ba99" + integrity sha512-PJF0SpJT+WdbVVt0AOYp9C8GnuruRlL/UFW7932nLWmFLQTaWEzTBQEx7/hn4BuV+WON75iAViSUJLiU3PKbpA== dependencies: - camelize "^1.0.0" - css-color-keywords "^1.0.0" - postcss-value-parser "^4.0.2" + hyphenate-style-name "^1.0.2" + isobject "^3.0.1" -css-tree@1.0.0-alpha.37: - version "1.0.0-alpha.37" - resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.37.tgz#98bebd62c4c1d9f960ec340cf9f7522e30709a22" - integrity sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg== - dependencies: - mdn-data "2.0.4" - source-map "^0.6.1" +css-selector-parser@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/css-selector-parser/-/css-selector-parser-1.4.1.tgz#03f9cb8a81c3e5ab2c51684557d5aaf6d2569759" + integrity sha512-HYPSb7y/Z7BNDCOrakL4raGO2zltZkbeXyAd6Tg9obzix6QhzxCotdBl6VT0Dv4vZfJGVz3WL/xaEI9Ly3ul0g== css-tree@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.2.tgz#9ae393b5dafd7dae8a622475caec78d3d8fbd7b5" - integrity sha512-wCoWush5Aeo48GLhfHPbmvZs59Z+M7k5+B1xDnXbdWNcEF423DoFdqSWE0PM5aNk5nI5cp1q7ms36zGApY/sKQ== + version "1.1.3" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d" + integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q== dependencies: mdn-data "2.0.14" source-map "^0.6.1" @@ -4912,93 +4806,29 @@ css-unit-converter@^1.1.1: resolved "https://registry.yarnpkg.com/css-unit-converter/-/css-unit-converter-1.1.2.tgz#4c77f5a1954e6dbff60695ecb214e3270436ab21" integrity sha512-IiJwMC8rdZE0+xiEZHeru6YoONC4rfPMqGm2W85jMIbkFvv5nFTwJVFHam2eFrN6txmoUYFAFXiv8ICVeTO0MA== -css-what@2.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2" - integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg== - -css-what@^3.2.1: - version "3.4.2" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.4.2.tgz#ea7026fcb01777edbde52124e21f327e7ae950e4" - integrity sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ== - -css-what@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-4.0.0.tgz#35e73761cab2eeb3d3661126b23d7aa0e8432233" - integrity sha512-teijzG7kwYfNVsUh2H/YN62xW3KK9YhXEgSlbxMlcyjPNvdKJqFx5lrwlJgoFP1ZHlB89iGDlo/JyshKeRhv5A== +css.escape@1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb" + integrity sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s= cssesc@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== -cssnano-preset-advanced@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/cssnano-preset-advanced/-/cssnano-preset-advanced-5.1.1.tgz#97652704ef799f13fa22922c6a069c9434ef2123" - integrity sha512-ct1RkopkLdOTJScU6WqGMhPYpEzvd2A8lD0vXTYzm4xleZ8rloK9RRi9LC3QcnNyArzPHnHQ182ukrXvhqzzTg== - dependencies: - autoprefixer "^10.0.2" - cssnano-preset-default "^5.1.1" - postcss-discard-unused "^5.0.1" - postcss-merge-idents "^5.0.1" - postcss-reduce-idents "^5.0.1" - postcss-zindex "^5.0.1" - -cssnano-preset-default@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-5.1.1.tgz#5cd783caed942cc94159aeb10583af4691445b8c" - integrity sha512-kAhR71Tascmnjlhl4UegGA3KGGbMLXHkkqVpA9idsRT1JmIhIsz1C3tDpBeQMUw5EX5Rfb1HGc/PRqD2AFk3Vg== - dependencies: - css-declaration-sorter "^6.0.3" - cssnano-utils "^2.0.1" - postcss-calc "^8.0.0" - postcss-colormin "^5.1.1" - postcss-convert-values "^5.0.1" - postcss-discard-comments "^5.0.1" - postcss-discard-duplicates "^5.0.1" - postcss-discard-empty "^5.0.1" - postcss-discard-overridden "^5.0.1" - postcss-merge-longhand "^5.0.2" - postcss-merge-rules "^5.0.1" - postcss-minify-font-values "^5.0.1" - postcss-minify-gradients "^5.0.1" - postcss-minify-params "^5.0.1" - postcss-minify-selectors "^5.1.0" - postcss-normalize-charset "^5.0.1" - postcss-normalize-display-values "^5.0.1" - postcss-normalize-positions "^5.0.1" - postcss-normalize-repeat-style "^5.0.1" - postcss-normalize-string "^5.0.1" - postcss-normalize-timing-functions "^5.0.1" - postcss-normalize-unicode "^5.0.1" - postcss-normalize-url "^5.0.1" - postcss-normalize-whitespace "^5.0.1" - postcss-ordered-values "^5.0.1" - postcss-reduce-initial "^5.0.1" - postcss-reduce-transforms "^5.0.1" - postcss-svgo "^5.0.1" - postcss-unique-selectors "^5.0.1" - -cssnano-utils@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/cssnano-utils/-/cssnano-utils-2.0.1.tgz#8660aa2b37ed869d2e2f22918196a9a8b6498ce2" - integrity sha512-i8vLRZTnEH9ubIyfdZCAdIdgnHAUeQeByEeQ2I7oTilvP9oHO6RScpeq3GsFUVqeB8uZgOQ9pw8utofNn32hhQ== - -cssnano@^5.0.0, cssnano@^5.0.4: - version "5.0.4" - resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-5.0.4.tgz#5ca90729c94c71c4bc3d45abb543be10740bf381" - integrity sha512-I+fDW74CJ4yb31765ov9xXe70XLZvFTXjwhmA//VgAAuSAU34Oblbe94Q9zffiCX1VhcSfQWARQnwhz+Nqgb4Q== +cssnano-preset-simple@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/cssnano-preset-simple/-/cssnano-preset-simple-2.0.0.tgz#b55e72cb970713f425560a0e141b0335249e2f96" + integrity sha512-HkufSLkaBJbKBFx/7aj5HmCK9Ni/JedRQm0mT2qBzMG/dEuJOLnMt2lK6K1rwOOyV4j9aSY+knbW9WoS7BYpzg== dependencies: - cosmiconfig "^7.0.0" - cssnano-preset-default "^5.1.1" - is-resolvable "^1.1.0" + caniuse-lite "^1.0.30001202" -csso@^4.0.2, csso@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529" - integrity sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA== +cssnano-simple@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/cssnano-simple/-/cssnano-simple-2.0.0.tgz#930d9dcd8ba105c5a62ce719cb00854da58b5c05" + integrity sha512-0G3TXaFxlh/szPEG/o3VcmCwl0N3E60XNb9YZZijew5eIs6fLjJuOPxQd9yEBaX2p/YfJtt49i4vYi38iH6/6w== dependencies: - css-tree "^1.1.2" + cssnano-preset-simple "^2.0.0" cssom@^0.4.4: version "0.4.4" @@ -5017,7 +4847,7 @@ cssstyle@^2.3.0: dependencies: cssom "~0.3.6" -csstype@^3.0.2: +csstype@^3.0.2, csstype@^3.0.6: version "3.0.8" resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.8.tgz#d2266a792729fb227cd216fb572f43728e1ad340" integrity sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw== @@ -5047,6 +4877,11 @@ csv@^5.3.1: csv-stringify "^5.6.2" stream-transform "^2.0.4" +data-uri-to-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz#594b8973938c5bc2c33046535785341abc4f3636" + integrity sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og== + data-urls@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" @@ -5071,7 +4906,7 @@ dateformat@4.5.1: resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-4.5.1.tgz#c20e7a9ca77d147906b6dc2261a8be0a5bd2173c" integrity sha512-OD0TZ+B7yP7ZgpJf5K2DIbj3FZvFvxgFUuaqA/V5zTjAtAAXZ1E8bktHxmAGs4x5b7PflqA9LeQ84Og7wYtF7Q== -debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.9: +debug@2, debug@2.6.9, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== @@ -5085,7 +4920,7 @@ debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: dependencies: ms "2.1.2" -debug@^3.1.1, debug@^3.2.6, debug@^3.2.7: +debug@^3.2.7: version "3.2.7" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== @@ -5105,45 +4940,21 @@ decamelize@^1.1.0, decamelize@^1.2.0: resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= +decamelize@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-5.0.0.tgz#88358157b010ef133febfd27c18994bd80c6215b" + integrity sha512-U75DcT5hrio3KNtvdULAWnLiAPbFUC4191ldxMmj4FA/mRuBnmDwU0boNfPyFRhnan+Jm+haLeSn3P0afcBn4w== + decimal.js@^10.2.1: version "10.2.1" resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.2.1.tgz#238ae7b0f0c793d3e3cea410108b35a2c01426a3" integrity sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw== -decode-uri-component@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" - integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= - -decompress-response@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" - integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= - dependencies: - mimic-response "^1.0.0" - dedent@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= -deep-equal@^1.0.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" - integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== - dependencies: - is-arguments "^1.0.4" - is-date-object "^1.0.1" - is-regex "^1.0.4" - object-is "^1.0.1" - object-keys "^1.1.1" - regexp.prototype.flags "^1.2.0" - -deep-extend@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== - deep-is@^0.1.3, deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" @@ -5154,14 +4965,6 @@ deepmerge@^4.0.0, deepmerge@^4.2.2: resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== -default-gateway@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-4.2.0.tgz#167104c7500c2115f6dd69b0a536bb8ed720552b" - integrity sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA== - dependencies: - execa "^1.0.0" - ip-regex "^2.1.0" - defaults@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" @@ -5169,10 +4972,10 @@ defaults@^1.0.3: dependencies: clone "^1.0.2" -defer-to-connect@^1.0.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" - integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== +define-lazy-prop@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" + integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== define-properties@^1.1.3: version "1.1.3" @@ -5181,46 +4984,11 @@ define-properties@^1.1.3: dependencies: object-keys "^1.0.12" -define-property@^0.2.5: - version "0.2.5" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" - integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= - dependencies: - is-descriptor "^0.1.0" - -define-property@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" - integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= - dependencies: - is-descriptor "^1.0.0" - -define-property@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" - integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== - dependencies: - is-descriptor "^1.0.2" - isobject "^3.0.1" - defined@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" integrity sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM= -del@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/del/-/del-4.1.1.tgz#9e8f117222ea44a31ff3a156c049b99052a9f0b4" - integrity sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ== - dependencies: - "@types/glob" "^7.1.1" - globby "^6.1.0" - is-path-cwd "^2.0.0" - is-path-in-cwd "^2.0.0" - p-map "^2.0.0" - pify "^4.0.1" - rimraf "^2.6.3" - del@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/del/-/del-6.0.0.tgz#0b40d0332cea743f1614f818be4feb717714c952" @@ -5240,16 +5008,19 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= -delegate@^3.1.2: - version "3.2.0" - resolved "https://registry.yarnpkg.com/delegate/-/delegate-3.2.0.tgz#b66b71c3158522e8ab5744f720d8ca0c2af59166" - integrity sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw== - depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= +des.js@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" + integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA== + dependencies: + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + destroy@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" @@ -5277,26 +5048,10 @@ detect-newline@^3.0.0: resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== -detect-node@^2.0.4: - version "2.0.5" - resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.5.tgz#9d270aa7eaa5af0b72c4c9d9b814e7f4ce738b79" - integrity sha512-qi86tE6hRcFHy8jI1m2VG+LaPUR1LhqDa5G8tVjuUXmOrpuAgqsA1pN0+ldgr3aKUH+QLI9hCY/OcRYisERejw== - -detect-port-alt@1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/detect-port-alt/-/detect-port-alt-1.1.6.tgz#24707deabe932d4a3cf621302027c2b266568275" - integrity sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q== - dependencies: - address "^1.0.1" - debug "^2.6.0" - -detect-port@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/detect-port/-/detect-port-1.3.0.tgz#d9c40e9accadd4df5cac6a782aefd014d573d1f1" - integrity sha512-E+B1gzkl2gqxt1IhUzwjrxBKRqx1UzC3WLONHinn8S3T6lwV/agVCyitiFOsGJ/eYuEUBvD71MZHy3Pv1G9doQ== - dependencies: - address "^1.0.1" - debug "^2.6.0" +detect-node-es@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/detect-node-es/-/detect-node-es-1.1.0.tgz#163acdf643330caa0b4cd7c21e7ee7755d6fa493" + integrity sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ== detective@^5.2.0: version "5.2.0" @@ -5315,19 +5070,28 @@ dicer@0.3.0: streamsearch "0.1.2" didyoumean@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.1.tgz#e92edfdada6537d484d73c0172fd1eba0c4976ff" - integrity sha1-6S7f2tplN9SE1zwBcv0eugxJdv8= + version "1.2.2" + resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037" + integrity sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw== diff-sequences@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-26.6.2.tgz#48ba99157de1923412eed41db6b6d4aa9ca7c0b1" integrity sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q== -diff-sequences@^27.0.1: - version "27.0.1" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.0.1.tgz#9c9801d52ed5f576ff0a20e3022a13ee6e297e7c" - integrity sha512-XPLijkfJUh/PIBnfkcSHgvD6tlYixmcMAn3osTk6jt+H0v/mgURto1XUiD9DKuGX5NDoVS6dSlA23gd9FUaCFg== +diff-sequences@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.0.6.tgz#3305cb2e55a033924054695cc66019fd7f8e5723" + integrity sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ== + +diffie-hellman@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" dir-glob@^3.0.1: version "3.0.1" @@ -5341,26 +5105,6 @@ dlv@^1.1.3: resolved "https://registry.yarnpkg.com/dlv/-/dlv-1.1.3.tgz#5c198a8a11453596e751494d49874bc7732f2e79" integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA== -dns-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" - integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0= - -dns-packet@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.1.tgz#12aa426981075be500b910eedcd0b47dd7deda5a" - integrity sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg== - dependencies: - ip "^1.1.0" - safe-buffer "^5.0.1" - -dns-txt@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/dns-txt/-/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6" - integrity sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY= - dependencies: - buffer-indexof "^1.0.0" - doctrine@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" @@ -5375,39 +5119,15 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" -dom-converter@^0.2: - version "0.2.0" - resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768" - integrity sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA== - dependencies: - utila "~0.4" - -dom-serializer@0, dom-serializer@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.1.tgz#1ec4059e284babed36eec2941d4a970a189ce7c0" - integrity sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA== - dependencies: - domelementtype "^1.3.0" - entities "^1.1.1" - -dom-serializer@^1.0.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.3.1.tgz#d845a1565d7c041a95e5dab62184ab41e3a519be" - integrity sha512-Pv2ZluG5ife96udGgEDovOOOA5UELkltfJpnIExPrAk1LTvecolUGn6lIaoLh86d83GiB86CjzciMd9BuRB71Q== - dependencies: - domelementtype "^2.0.1" - domhandler "^4.0.0" - entities "^2.0.0" - -domelementtype@1, domelementtype@^1.3.0, domelementtype@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" - integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== +domain-browser@4.19.0: + version "4.19.0" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-4.19.0.tgz#1093e17c0a17dbd521182fe90d49ac1370054af1" + integrity sha512-fRA+BaAWOR/yr/t7T9E9GJztHPeFjj8U35ajyAjCDtAAnTn1Rc1f6W6VGPJrO1tkQv9zWu+JRof7z6oQtiYVFQ== -domelementtype@^2.0.1, domelementtype@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57" - integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A== +domain-browser@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" + integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== domexception@^2.0.1: version "2.0.1" @@ -5416,45 +5136,6 @@ domexception@^2.0.1: dependencies: webidl-conversions "^5.0.0" -domhandler@^2.3.0: - version "2.4.2" - resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" - integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA== - dependencies: - domelementtype "1" - -domhandler@^4.0.0, domhandler@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.2.0.tgz#f9768a5f034be60a89a27c2e4d0f74eba0d8b059" - integrity sha512-zk7sgt970kzPks2Bf+dwT/PLzghLnsivb9CcxkvR8Mzr66Olr0Ofd8neSbglHJHaHa2MadfoSdNlKYAaafmWfA== - dependencies: - domelementtype "^2.2.0" - -domutils@1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" - integrity sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8= - dependencies: - dom-serializer "0" - domelementtype "1" - -domutils@^1.5.1, domutils@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" - integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== - dependencies: - dom-serializer "0" - domelementtype "1" - -domutils@^2.4.3: - version "2.6.0" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.6.0.tgz#2e15c04185d43fb16ae7057cb76433c6edb938b7" - integrity sha512-y0BezHuy4MDYxh6OvolXYsH+1EMGmFbwv5FKW7ovwMG6zTPWqNPq3WF9ayZssFq+UlKdffGLbOEaghNdaOm1WA== - dependencies: - dom-serializer "^1.0.1" - domelementtype "^2.2.0" - domhandler "^4.2.0" - dot-case@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751" @@ -5463,13 +5144,6 @@ dot-case@^3.0.4: no-case "^3.0.4" tslib "^2.0.3" -dot-prop@^5.2.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88" - integrity sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q== - dependencies: - is-obj "^2.0.0" - dotenv@^10.0.0: version "10.0.0" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81" @@ -5480,12 +5154,7 @@ dset@^2.0.1: resolved "https://registry.yarnpkg.com/dset/-/dset-2.1.0.tgz#cd1e99e55cf32366d8f144f906c42f7fb3bf431e" integrity sha512-hlQYwNEdW7Qf8zxysy+yN1E8C/SxRst3Z9n+IvXOR35D9bPVwNHhnL8ZBeoZjvinuGrlvGg6pAMDwhmjqFDgjA== -duplexer3@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" - integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= - -duplexer@^0.1.1, duplexer@^0.1.2: +duplexer@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== @@ -5502,11 +5171,24 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= -electron-to-chromium@^1.3.564, electron-to-chromium@^1.3.723: +electron-to-chromium@^1.3.723: version "1.3.727" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.727.tgz#857e310ca00f0b75da4e1db6ff0e073cc4a91ddf" integrity sha512-Mfz4FIB4FSvEwBpDfdipRIrwd6uo8gUDoRDF4QEYb4h4tSuI3ov594OrjU6on042UlFHouIJpClDODGkPcBSbg== +elliptic@^6.5.3: + version "6.5.4" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" + integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== + dependencies: + bn.js "^4.11.9" + brorand "^1.1.0" + hash.js "^1.0.0" + hmac-drbg "^1.0.1" + inherits "^2.0.4" + minimalistic-assert "^1.0.1" + minimalistic-crypto-utils "^1.0.1" + emittery@^0.8.1: version "0.8.1" resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.8.1.tgz#bb23cc86d03b30aa75a7f734819dee2e1ba70860" @@ -5517,16 +5199,16 @@ emittery@^0.8.1: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-6.1.1.tgz#c6cd0ec1b0642e2a3c67a1137efc5e796da4f88e" integrity sha1-xs0OwbBkLio8Z6ETfvxeeW2k+I4= -emoji-regex@^7.0.1: - version "7.0.3" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" - integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== - emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== +emojis-list@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" + integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= + emojis-list@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" @@ -5542,12 +5224,12 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= -end-of-stream@^1.1.0: - version "1.4.4" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" - integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== +encoding@0.1.13: + version "0.1.13" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" + integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== dependencies: - once "^1.4.0" + iconv-lite "^0.6.2" enhanced-resolve@^5.8.0: version "5.8.2" @@ -5564,23 +5246,6 @@ enquirer@^2.3.0, enquirer@^2.3.5, enquirer@^2.3.6: dependencies: ansi-colors "^4.1.1" -entities@^1.1.1, entities@~1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" - integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== - -entities@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" - integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== - -errno@^0.1.3: - version "0.1.8" - resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" - integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== - dependencies: - prr "~1.0.1" - error-ex@^1.3.1: version "1.3.2" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" @@ -5588,7 +5253,14 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -es-abstract@^1.17.2, es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2: +error-stack-parser@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.0.6.tgz#5a99a707bd7a4c58a797902d48d82803ede6aad8" + integrity sha512-d51brTeqC+BHlwF0BhPtcYgF5nlzf9ZZ0ZIUQNZpc9ZB9qw5IJ2diTrBY9jlCJkTLITYPjmiX6OWCwH+fuyNgQ== + dependencies: + stackframe "^1.1.1" + +es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2: version "1.18.0" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.0.tgz#ab80b359eecb7ede4c298000390bc5ac3ec7b5a4" integrity sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw== @@ -5624,31 +5296,44 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" -escalade@^3.0.2, escalade@^3.1.1: +es6-object-assign@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/es6-object-assign/-/es6-object-assign-1.1.0.tgz#c2c3582656247c39ea107cb1e6652b6f9f24523c" + integrity sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw= + +esbuild-register@^2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/esbuild-register/-/esbuild-register-2.6.0.tgz#9f19a54c82be751dd87673d6a66d7b9e1cdd8498" + integrity sha512-2u4AtnCXP5nivtIxZryiZOUcEQkOzFS7UhAqibUEmaTAThJ48gDLYTBF/Fsz+5r0hbV1jrFE6PQvPDUrKZNt/Q== + dependencies: + esbuild "^0.12.8" + jsonc-parser "^3.0.0" + +esbuild@^0.11.12, esbuild@^0.12.8, esbuild@^0.12.9: + version "0.12.15" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.12.15.tgz#9d99cf39aeb2188265c5983e983e236829f08af0" + integrity sha512-72V4JNd2+48eOVCXx49xoSWHgC3/cCy96e7mbXKY+WOWghN00cCmlGnwVLRhRHorvv0dgCyuMYBZlM2xDM5OQw== + +escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== -escape-goat@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675" - integrity sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q== - escape-html@^1.0.3, escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= -escape-string-regexp@2.0.0, escape-string-regexp@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" - integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== - escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= +escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + escape-string-regexp@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" @@ -5775,13 +5460,14 @@ eslint-visitor-keys@^2.0.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8" integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ== -eslint@7.28.0: - version "7.28.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.28.0.tgz#435aa17a0b82c13bb2be9d51408b617e49c1e820" - integrity sha512-UMfH0VSjP0G4p3EWirscJEQ/cHqnT/iuH6oNZOB94nBjWbMnhGEPxsZm1eyIW0C/9jLI0Fow4W5DXLjEI7mn1g== +eslint@7.30.0: + version "7.30.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.30.0.tgz#6d34ab51aaa56112fd97166226c9a97f505474f8" + integrity sha512-VLqz80i3as3NdloY44BQSJpFw534L9Oh+6zJOUaViV4JPd+DaHwutqP7tcpkW3YiXbK6s05RZl7yl7cQn+lijg== dependencies: "@babel/code-frame" "7.12.11" "@eslint/eslintrc" "^0.4.2" + "@humanwhocodes/config-array" "^0.5.0" ajv "^6.10.0" chalk "^4.0.0" cross-spawn "^7.0.2" @@ -5873,23 +5559,11 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== -eta@^1.12.1: - version "1.12.1" - resolved "https://registry.yarnpkg.com/eta/-/eta-1.12.1.tgz#d985766591676c323f02dfc48a67539212745937" - integrity sha512-H8npoci2J/7XiPnVcCVulBSPsTNGvGaINyMjQDU8AFqp9LGsEYS88g2CiU+d01Sg44WtX7o4nb8wUJ9vnI+tiA== - -etag@~1.8.1: +etag@1.8.1, etag@~1.8.1: version "1.8.1" resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= -eval@^0.1.4: - version "0.1.6" - resolved "https://registry.yarnpkg.com/eval/-/eval-0.1.6.tgz#9620d7d8c85515e97e6b47c5814f46ae381cb3cc" - integrity sha512-o0XUw+5OGkXw4pJZzQoXUk+H87DHuC+7ZE//oSrRGtatTmr12oTnLfg6QOq9DyTt0c/p4TwzgmkKrBzWTSizyQ== - dependencies: - require-like ">= 0.1.1" - event-target-shim@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" @@ -5900,27 +5574,23 @@ eventemitter3@^3.1.0: resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.2.tgz#2d3d48f9c346698fce83a85d7d664e98535df6e7" integrity sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q== -eventemitter3@^4.0.0: - version "4.0.7" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" - integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== - events@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" integrity sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ= -events@^3.2.0: +events@^3.0.0, events@^3.2.0: version "3.3.0" resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== -eventsource@^1.0.7: - version "1.1.0" - resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-1.1.0.tgz#00e8ca7c92109e94b0ddf32dac677d841028cfaf" - integrity sha512-VSJjT5oCNrFvCS6igjzPAt5hBzQ2qPBFIbJ03zLI9SE0mxwZpMw6BfJrbFHm1a141AavMEB8JHmBhWAd66PfCg== +evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== dependencies: - original "^1.0.0" + md5.js "^1.3.4" + safe-buffer "^5.1.1" execa@^0.7.0: version "0.7.0" @@ -5935,19 +5605,6 @@ execa@^0.7.0: signal-exit "^3.0.0" strip-eof "^1.0.0" -execa@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" - integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== - dependencies: - 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" - execa@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/execa/-/execa-5.0.0.tgz#4029b0007998a841fbd1032e5f4de86a3c1e3376" @@ -5968,30 +5625,17 @@ exit@^0.1.2: resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= -expand-brackets@^2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" - integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= - dependencies: - 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" - -expect@^27.0.2: - version "27.0.2" - resolved "https://registry.yarnpkg.com/expect/-/expect-27.0.2.tgz#e66ca3a4c9592f1c019fa1d46459a9d2084f3422" - integrity sha512-YJFNJe2+P2DqH+ZrXy+ydRQYO87oxRUonZImpDodR1G7qo3NYd3pL+NQ9Keqpez3cehczYwZDBC3A7xk3n7M/w== +expect@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/expect/-/expect-27.0.6.tgz#a4d74fbe27222c718fff68ef49d78e26a8fd4c05" + integrity sha512-psNLt8j2kwg42jGBDSfAlU49CEZxejN1f1PlANWDZqIhBOVU/c2Pm888FcjWJzFewhIsNWfZJeLjUjtKGiPuSw== dependencies: - "@jest/types" "^27.0.2" + "@jest/types" "^27.0.6" ansi-styles "^5.0.0" - jest-get-type "^27.0.1" - jest-matcher-utils "^27.0.2" - jest-message-util "^27.0.2" - jest-regex-util "^27.0.1" + jest-get-type "^27.0.6" + jest-matcher-utils "^27.0.6" + jest-message-util "^27.0.6" + jest-regex-util "^27.0.6" express-graphql@0.12.0: version "0.12.0" @@ -6003,7 +5647,7 @@ express-graphql@0.12.0: http-errors "1.8.0" raw-body "^2.4.1" -express@^4.17.1: +express@4.17.1, express@^4.17.1: version "4.17.1" resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== @@ -6046,14 +5690,6 @@ extend-shallow@^2.0.1: dependencies: is-extendable "^0.1.0" -extend-shallow@^3.0.0, extend-shallow@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" - integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= - dependencies: - assign-symbols "^1.0.0" - is-extendable "^1.0.1" - extend@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" @@ -6073,24 +5709,10 @@ external-editor@^3.1.0: iconv-lite "^0.4.24" tmp "^0.0.33" -extglob@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" - integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== - dependencies: - 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" - -extract-files@10.0.0, extract-files@^10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/extract-files/-/extract-files-10.0.0.tgz#228b1da1d910971cf8d7f1ed259653c6001ba5ad" - integrity sha512-4KXYOSf8SlMlQCj94Ygy89xIZU2GTs0HU2Nz9mG2/F5TKsHyq/3sDWGjHgHmfw9RhXF3hO+pBKyC6JfIHD52bw== +extract-files@11.0.0, extract-files@^11.0.0: + version "11.0.0" + resolved "https://registry.yarnpkg.com/extract-files/-/extract-files-11.0.0.tgz#b72d428712f787eef1f5193aff8ab5351ca8469a" + integrity sha512-FuoE1qtbJ4bBVvv94CC7s0oTnKUGvQs+Rjf1L2SJFfS+HTVVjhPFtehPdQ0JiGPqVNfSSZvL5yzHHQq2Z4WNhQ== extract-files@^9.0.0: version "9.0.0" @@ -6102,7 +5724,7 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-glob@^3.1.1, fast-glob@^3.2.5: +fast-glob@^3.1.1: version "3.2.5" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.5.tgz#7939af2a656de79a4f1901903ee8adcaa7cb9661" integrity sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg== @@ -6114,6 +5736,17 @@ fast-glob@^3.1.1, fast-glob@^3.2.5: micromatch "^4.0.2" picomatch "^2.2.1" +fast-glob@^3.2.5: + version "3.2.6" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.6.tgz#434dd9529845176ea049acc9343e8282765c6e1a" + integrity sha512-GnLuqj/pvQ7pX8/L4J84nijv6sAnlwvSDpMkJi9i7nPmPxGtRPkBSStfvDW5l6nMdX9VWe+pkKWFTgD+vF2QSQ== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" @@ -6124,12 +5757,15 @@ fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= -fast-url-parser@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/fast-url-parser/-/fast-url-parser-1.1.3.tgz#f4af3ea9f34d8a271cf58ad2b3759f431f0b318d" - integrity sha1-9K8+qfNNiicc9YrSs3WfQx8LMY0= - dependencies: - punycode "^1.3.2" +fast-shallow-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fast-shallow-equal/-/fast-shallow-equal-1.0.0.tgz#d4dcaf6472440dcefa6f88b98e3251e27f25628b" + integrity sha512-HPtaa38cPgWvaCFmRNhlc6NG7pv6NUHqjPgVAkWGoB9mQMwYB27/K0CvOM5Czy+qpT3e8XJ6Q4aPAnzpNpzNaw== + +fastest-stable-stringify@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/fastest-stable-stringify/-/fastest-stable-stringify-2.0.2.tgz#3757a6774f6ec8de40c4e86ec28ea02417214c76" + integrity sha512-bijHueCGd0LqqNK9b5oCMHc0MluJAx0cwqASgbWMvkO01lCYgIhacVRLcaDz3QnyYIRNJRDwMb41VuT6pHJ91Q== fastq@^1.6.0: version "1.11.0" @@ -6138,13 +5774,6 @@ fastq@^1.6.0: dependencies: reusify "^1.0.4" -faye-websocket@^0.11.3: - version "0.11.3" - resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.3.tgz#5c0e9a8968e8912c286639fde977a8b209f2508e" - integrity sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA== - dependencies: - websocket-driver ">=0.5.1" - fb-watchman@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85" @@ -6152,13 +5781,6 @@ fb-watchman@^2.0.0: dependencies: bser "2.1.1" -fbemitter@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/fbemitter/-/fbemitter-3.0.0.tgz#00b2a1af5411254aab416cd75f9e6289bee4bff3" - integrity sha512-KWKaceCwKQU0+HPoop6gn4eOHk50bBv/VxjJtGMfwmJt3D29JpN4H4eisCtIPA+a8GVBam+ldMMpMjJUvpDyHw== - dependencies: - fbjs "^3.0.0" - fbjs-css-vars@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz#216551136ae02fe255932c3ec8775f18e2c078b8" @@ -6177,13 +5799,6 @@ fbjs@^3.0.0: setimmediate "^1.0.5" ua-parser-js "^0.7.18" -feed@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/feed/-/feed-4.2.2.tgz#865783ef6ed12579e2c44bbef3c9113bc4956a7e" - integrity sha512-u5/sxGfiMfZNtJ3OvQpXcvotFpYkL0n9u9mM2vkui2nGo8b4wvDkJ8gAkYqbA8QpGyFCv3RK0Z+Iv+9veCS9bQ== - dependencies: - xml-js "^1.6.11" - figures@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" @@ -6198,33 +5813,14 @@ file-entry-cache@^6.0.1: dependencies: flat-cache "^3.0.4" -file-loader@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.2.0.tgz#baef7cf8e1840df325e4390b4484879480eebe4d" - integrity sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw== - dependencies: - loader-utils "^2.0.0" - schema-utils "^3.0.0" - -file-uri-to-path@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" - integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== - -filesize@6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/filesize/-/filesize-6.1.0.tgz#e81bdaa780e2451d714d71c0d7a4f3238d37ad00" - integrity sha512-LpCHtPQ3sFx67z+uh2HnSyWSLLu5Jxo21795uRDuar/EOuYWXib5EmPaGIBuSnRqH2IODiKA2k5re/K9OnN/Yg== - -fill-range@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" - integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= +file-type@^16.5.0: + version "16.5.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-16.5.0.tgz#16a2626f3b33bac612f6e81e52216f3a7c8e12a2" + integrity sha512-OxgWA9tbL8N/WP00GD1z8O0MiwQKFyWRs1q+3FhjdvcGgKqwxcejyGWso3n4/IMU6DdwV+ARZ4A7TTnPkDcSiw== dependencies: - extend-shallow "^2.0.1" - is-number "^3.0.0" - repeat-string "^1.6.1" - to-regex-range "^2.1.0" + readable-web-to-node-stream "^3.0.0" + strtok3 "^6.0.3" + token-types "^2.0.0" fill-range@^7.0.1: version "7.0.1" @@ -6246,7 +5842,7 @@ finalhandler@~1.1.2: statuses "~1.5.0" unpipe "~1.0.0" -find-cache-dir@^3.3.1: +find-cache-dir@3.3.1, find-cache-dir@^3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.1.tgz#89b33fad4a4670daa94f855f7fbe31d6d84fe880" integrity sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ== @@ -6260,14 +5856,6 @@ find-root@^1.1.0: resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng== -find-up@4.1.0, find-up@^4.0.0, find-up@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" - integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - find-up@^2.0.0, find-up@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" @@ -6275,12 +5863,13 @@ find-up@^2.0.0, find-up@^2.1.0: dependencies: locate-path "^2.0.0" -find-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" - integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== +find-up@^4.0.0, find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== dependencies: - locate-path "^3.0.0" + locate-path "^5.0.0" + path-exists "^4.0.0" find-up@^5.0.0: version "5.0.0" @@ -6318,50 +5907,36 @@ flatted@^3.1.0: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.1.tgz#c4b489e80096d9df1dfc97c79871aea7c617c469" integrity sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA== -flux@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/flux/-/flux-4.0.1.tgz#7843502b02841d4aaa534af0b373034a1f75ee5c" - integrity sha512-emk4RCvJ8RzNP2lNpphKnG7r18q8elDYNAPx7xn+bDeOIo9FFfxEfIQ2y6YbQNmnsGD3nH1noxtLE64Puz1bRQ== +focus-lock@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/focus-lock/-/focus-lock-0.8.1.tgz#bb36968abf77a2063fa173cb6c47b12ac8599d33" + integrity sha512-/LFZOIo82WDsyyv7h7oc0MJF9ACOvDRdx9rWPZ2pgMfNWu/z8hQDBtOchuB/0BVLmuFOZjV02YwUVzNsWx/EzA== dependencies: - fbemitter "^3.0.0" - fbjs "^3.0.0" + tslib "^1.9.3" focus-trap-react@^8.5.0: - version "8.5.0" - resolved "https://registry.yarnpkg.com/focus-trap-react/-/focus-trap-react-8.5.0.tgz#c4d08609ed1da0976b856519fd2c97760524474c" - integrity sha512-YnQ3PtoszlXqHQQIYCnnTbWsXa6daEACXg9KkFvv357PkJUVp347G9L+e9WJwj2KgSIX+pTDcZFx+f7azo8dhw== + version "8.7.0" + resolved "https://registry.yarnpkg.com/focus-trap-react/-/focus-trap-react-8.7.0.tgz#5cf7fceb14561ccbb54208958e63422e1116266d" + integrity sha512-zqQKgyYFvd9F1We6WeUZkLo/qGWrZKMGMtOXBz+18gyjg5XIzjz+cX8qdtpUZ2eJdyp/1AdHhcklCN8edyF0Ew== dependencies: - focus-trap "^6.4.0" + focus-trap "^6.6.0" -focus-trap@^6.4.0: - version "6.5.0" - resolved "https://registry.yarnpkg.com/focus-trap/-/focus-trap-6.5.0.tgz#d99fdf5f3da07c08e7f5b9cad33746db2b215f97" - integrity sha512-mezVantxaWNMrcJcrdw/bDfW3rVkl0xcdHKiHbNZzJ2R+KfcW9S6j48wFUAu7C52GFeQDGEWgDEIAvk9PxFvZw== +focus-trap@^6.6.0: + version "6.6.0" + resolved "https://registry.yarnpkg.com/focus-trap/-/focus-trap-6.6.0.tgz#7fb37679926ec1bd762d0748b056c68a64a9e8cf" + integrity sha512-2hWVR3XbBejn5v8wDW9DFzLWXcxMNaSJ/CtE3E+FJjjBCLwIYbZJwjUi2RDBfQPM58gHEt5hck0jrJgHR9/s+A== dependencies: tabbable "^5.2.0" -follow-redirects@^1.0.0, follow-redirects@^1.10.0: - version "1.13.3" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.3.tgz#e5598ad50174c1bc4e872301e82ac2cd97f90267" - integrity sha512-DUgl6+HDzB0iEptNQEXLx/KhTmDb8tZUHSeLqpnjpknR70H0nC2t9N73BK6fN4hOvJ84pKlIQVQ4k5FFlBedKA== - -for-in@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" - integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= +follow-redirects@^1.10.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.1.tgz#d9114ded0a1cfdd334e164e6662ad02bfd91ff43" + integrity sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg== -fork-ts-checker-webpack-plugin@4.1.6: - version "4.1.6" - resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-4.1.6.tgz#5055c703febcf37fa06405d400c122b905167fc5" - integrity sha512-DUxuQaKoqfNne8iikd14SAkh5uw4+8vNifp6gmA73yYNS6ywLIWSLD/n/mBzHQRpW3J7rbATEakmiA8JvkTyZw== - dependencies: - "@babel/code-frame" "^7.5.5" - chalk "^2.4.1" - micromatch "^3.1.10" - minimatch "^3.0.4" - semver "^5.6.0" - tapable "^1.0.0" - worker-rpc "^0.1.0" +foreach@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" + integrity sha1-C+4AUBiusmDQo6865ljdATbsG5k= form-data@4.0.0: version "4.0.0" @@ -6381,22 +5956,35 @@ form-data@^3.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" -forwarded@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" - integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== -fraction.js@^4.0.13: - version "4.0.13" - resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.0.13.tgz#3c1c315fa16b35c85fffa95725a36fa729c69dfe" - integrity sha512-E1fz2Xs9ltlUp+qbiyx9wmt2n9dRzPsS11Jtdb8D2o+cC7wr9xkkKsVKJuBX0ST+LVS+LhLO+SbLJNtfWcJvXA== +fraction.js@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.1.1.tgz#ac4e520473dae67012d618aab91eda09bcb400ff" + integrity sha512-MHOhvvxHTfRFpF1geTK9czMIZ6xclsEor2wkIGYYq+PxcQqT7vStJqjhe6S1TenZrMZzo+wlqOufBDVepUEgPg== + +framer-motion@^4.1.17: + version "4.1.17" + resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-4.1.17.tgz#4029469252a62ea599902e5a92b537120cc89721" + integrity sha512-thx1wvKzblzbs0XaK2X0G1JuwIdARcoNOW7VVwjO8BUltzXPyONGAElLu6CiCScsOQRI7FIk/45YTFtJw5Yozw== + dependencies: + framesync "5.3.0" + hey-listen "^1.0.8" + popmotion "9.3.6" + style-value-types "4.1.4" + tslib "^2.1.0" + optionalDependencies: + "@emotion/is-prop-valid" "^0.8.2" -fragment-cache@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" - integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= +framesync@5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/framesync/-/framesync-5.3.0.tgz#0ecfc955e8f5a6ddc8fdb0cc024070947e1a0d9b" + integrity sha512-oc5m68HDO/tuK2blj7ZcdEBRx3p1PjrgHazL8GYEpvULhrtGIFbQArN6cQS2QhW8mitffaB+VYzMjDqBxxQeoA== dependencies: - map-cache "^0.2.2" + tslib "^2.1.0" fresh@0.5.2: version "0.5.2" @@ -6445,30 +6033,12 @@ fs-extra@^7.0.1: jsonfile "^4.0.0" universalify "^0.1.0" -fs-extra@^9.1.0: - version "9.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" - integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== - dependencies: - at-least-node "^1.0.0" - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -fsevents@^1.2.7: - version "1.2.13" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38" - integrity sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw== - dependencies: - bindings "^1.5.0" - nan "^2.12.1" - -fsevents@^2.3.2, fsevents@~2.3.1: +fsevents@^2.3.2, fsevents@~2.3.1, fsevents@~2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== @@ -6514,6 +6084,18 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.1: has "^1.0.3" has-symbols "^1.0.1" +get-nonce@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/get-nonce/-/get-nonce-1.0.1.tgz#fdf3f0278073820d2ce9426c18f07481b1e0cdf3" + integrity sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q== + +get-orientation@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/get-orientation/-/get-orientation-1.1.2.tgz#20507928951814f8a91ded0a0e67b29dfab98947" + integrity sha512-/pViTfifW+gBbh/RnlFYHINvELT9Znt+SYyDKAUL6uV6By019AK/s+i9XP4jSwq7lwP38Fd8HVeTxym3+hkwmQ== + dependencies: + stream-parser "^0.3.1" + get-own-enumerable-property-symbols@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" @@ -6524,81 +6106,51 @@ get-package-type@^0.1.0: resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== +get-stdin@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-9.0.0.tgz#3983ff82e03d56f1b2ea0d3e60325f39d703a575" + integrity sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA== + get-stream@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= -get-stream@^4.0.0, get-stream@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" - integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== - dependencies: - pump "^3.0.0" - -get-stream@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" - integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== - dependencies: - pump "^3.0.0" - get-stream@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.0.tgz#3e0012cb6827319da2706e601a1583e8629a6718" integrity sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg== -get-value@^2.0.3, get-value@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" - integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= - -github-slugger@^1.3.0: +github-slugger@^1.0.0, github-slugger@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/github-slugger/-/github-slugger-1.3.0.tgz#9bd0a95c5efdfc46005e82a906ef8e2a059124c9" integrity sha512-gwJScWVNhFYSRDvURk/8yhcFBee6aFjye2a7Lhb2bUyRulpIoek9p0I9Kt7PT67d/nUlZbFu8L9RLiA0woQN8Q== dependencies: emoji-regex ">=6.0.0 <=6.1.1" -glob-base@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" - integrity sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q= - dependencies: - glob-parent "^2.0.0" - is-glob "^2.0.0" - -glob-parent@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" - integrity sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg= - dependencies: - is-glob "^2.0.0" - -glob-parent@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" - integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= - dependencies: - is-glob "^3.1.0" - path-dirname "^1.0.0" - -glob-parent@^5.1.0, glob-parent@^5.1.1, glob-parent@^5.1.2, glob-parent@~5.1.0: +glob-parent@^5.1.0, glob-parent@^5.1.2, glob-parent@~5.1.0, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" +glob-parent@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.0.tgz#f851b59b388e788f3a44d63fab50382b2859c33c" + integrity sha512-Hdd4287VEJcZXUwv1l8a+vXC1GjOQqXe+VS30w/ypihpcnu9M1n3xeYeJu5CBpeEQj2nAab2xxz28GuA3vp4Ww== + dependencies: + is-glob "^4.0.1" + glob-to-regexp@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== -glob@^7.0.0, glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: - version "7.1.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== +glob@^7.0.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.7: + version "7.1.7" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" + integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" @@ -6607,29 +6159,6 @@ glob@^7.0.0, glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: once "^1.3.0" path-is-absolute "^1.0.0" -global-dirs@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-3.0.0.tgz#70a76fe84ea315ab37b1f5576cbde7d48ef72686" - integrity sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA== - dependencies: - ini "2.0.0" - -global-modules@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" - integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A== - dependencies: - global-prefix "^3.0.0" - -global-prefix@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-3.0.0.tgz#fc85f73064df69f50421f47f883fe5b913ba9b97" - integrity sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg== - dependencies: - ini "^1.3.5" - kind-of "^6.0.2" - which "^1.3.1" - globals@^11.1.0: version "11.12.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" @@ -6654,22 +6183,10 @@ globby@11.0.0: merge2 "^1.3.0" slash "^3.0.0" -globby@11.0.1: - version "11.0.1" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.1.tgz#9a2bf107a068f3ffeabc49ad702c79ede8cfd357" - integrity sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ== - dependencies: - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.1.1" - ignore "^5.1.4" - merge2 "^1.3.0" - slash "^3.0.0" - -globby@11.0.3, globby@^11.0.0, globby@^11.0.1, globby@^11.0.2, globby@^11.0.3: - version "11.0.3" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.3.tgz#9b1f0cb523e171dd1ad8c7b2a9fb4b644b9593cb" - integrity sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg== +globby@11.0.4, globby@^11.0.0, globby@^11.0.1, globby@^11.0.3, globby@^11.0.4: + version "11.0.4" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5" + integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg== dependencies: array-union "^2.1.0" dir-glob "^3.0.1" @@ -6678,41 +6195,6 @@ globby@11.0.3, globby@^11.0.0, globby@^11.0.1, globby@^11.0.2, globby@^11.0.3: merge2 "^1.3.0" slash "^3.0.0" -globby@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" - integrity sha1-9abXDoOV4hyFj7BInWTfAkJNUGw= - dependencies: - array-union "^1.0.1" - glob "^7.0.3" - object-assign "^4.0.1" - pify "^2.0.0" - pinkie-promise "^2.0.0" - -good-listener@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/good-listener/-/good-listener-1.2.2.tgz#d53b30cdf9313dffb7dc9a0d477096aa6d145c50" - integrity sha1-1TswzfkxPf+33JoNR3CWqm0UXFA= - dependencies: - delegate "^3.1.2" - -got@^9.6.0: - version "9.6.0" - resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" - integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q== - dependencies: - "@sindresorhus/is" "^0.14.0" - "@szmarczak/http-timer" "^1.1.2" - cacheable-request "^6.0.0" - decompress-response "^3.3.0" - duplexer3 "^0.1.4" - get-stream "^4.1.0" - lowercase-keys "^1.0.1" - mimic-response "^1.0.1" - p-cancelable "^1.0.0" - to-readable-stream "^1.0.0" - url-parse-lax "^3.0.0" - graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.5, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4: version "4.2.6" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" @@ -6751,10 +6233,10 @@ graphql-subscriptions@1.2.1: dependencies: iterall "^1.3.0" -graphql-tag@2.12.4, graphql-tag@^2.12.0: - version "2.12.4" - resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.12.4.tgz#d34066688a4f09e72d6f4663c74211e9b4b7c4bf" - integrity sha512-VV1U4O+9x99EkNpNmCUV5RZwq6MnK4+pGbRYWG+lA/m3uo7TSqJF81OkcOP148gFP6fzdl7JWYBrwWVTS9jXww== +graphql-tag@2.12.5, graphql-tag@^2.12.0: + version "2.12.5" + resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.12.5.tgz#5cff974a67b417747d05c8d9f5f3cb4495d0db8f" + integrity sha512-5xNhP4063d16Pz3HBtKprutsPrmHZi5IdUGOWRxA2B6VF7BIRGOHZ5WQvDmJXZuPcBg7rYwaFxvQYjqkSdR3TQ== dependencies: tslib "^2.1.0" @@ -6779,10 +6261,10 @@ graphql-ws@^5.0.0: resolved "https://registry.yarnpkg.com/graphql-ws/-/graphql-ws-5.0.0.tgz#30f55a649f8dc825c51b6f7cfc05e513688c4f8d" integrity sha512-SSSn5xQB5bDtmIwn2Rkw9WakrNbkDvPP5B7J5pKhFoDfQkF5xs9BaqelsGljoRs4rrdmWq9xw/QVtEXmjImZQA== -graphql@15.5.0, graphql@^14.5.3, graphql@^15.3.0: - version "15.5.0" - resolved "https://registry.yarnpkg.com/graphql/-/graphql-15.5.0.tgz#39d19494dbe69d1ea719915b578bf920344a69d5" - integrity sha512-OmaM7y0kaK31NKG31q4YbD2beNYa6jBBKtMFT6gLYJljHLJr42IqJ8KX08u3Li/0ifzTU5HjmoOOrwa5BRLeDA== +graphql@15.5.1, graphql@^14.5.3, graphql@^15.3.0: + version "15.5.1" + resolved "https://registry.yarnpkg.com/graphql/-/graphql-15.5.1.tgz#f2f84415d8985e7b84731e7f3536f8bb9d383aad" + integrity sha512-FeTRX67T3LoE3LWAxxOlW2K3Bz+rMYAC18rRguK4wgXaTZMiJwSUwDmPFo3UadAKbzirKIg5Qy+sNJXbpPRnQw== gray-matter@^4.0.3: version "4.0.3" @@ -6794,14 +6276,6 @@ gray-matter@^4.0.3: section-matter "^1.0.0" strip-bom-string "^1.0.0" -gzip-size@5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-5.1.1.tgz#cb9bee692f87c0612b232840a873904e4c135274" - integrity sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA== - dependencies: - duplexer "^0.1.1" - pify "^4.0.1" - gzip-size@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-6.0.0.tgz#065367fd50c239c0671cbcbad5be3e2eeb10e462" @@ -6809,11 +6283,6 @@ gzip-size@^6.0.0: dependencies: duplexer "^0.1.2" -handle-thing@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" - integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== - handlebars@^4.7.7: version "4.7.7" resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1" @@ -6851,42 +6320,6 @@ has-symbols@^1.0.0, has-symbols@^1.0.1, has-symbols@^1.0.2: resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== -has-value@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" - integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= - dependencies: - get-value "^2.0.3" - has-values "^0.1.4" - isobject "^2.0.0" - -has-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" - integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= - dependencies: - get-value "^2.0.6" - has-values "^1.0.0" - isobject "^3.0.0" - -has-values@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" - integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= - -has-values@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" - integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= - dependencies: - is-number "^3.0.0" - kind-of "^4.0.0" - -has-yarn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-2.1.0.tgz#137e11354a7b5bf11aa5cb649cf0c6f3ff2b2e77" - integrity sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw== - has@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" @@ -6894,11 +6327,28 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" +hash-base@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" + integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== + dependencies: + inherits "^2.0.4" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" + hash-sum@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/hash-sum/-/hash-sum-2.0.0.tgz#81d01bb5de8ea4a214ad5d6ead1b523460b0b45a" integrity sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg== +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + hast-to-hyperscript@^9.0.0: version "9.0.1" resolved "https://registry.yarnpkg.com/hast-to-hyperscript/-/hast-to-hyperscript-9.0.1.tgz#9b67fd188e4c81e8ad66f803855334173920218d" @@ -6988,29 +6438,26 @@ hastscript@^6.0.0: property-information "^5.0.0" space-separated-tokens "^1.0.0" -he@^1.2.0: +he@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== -hex-color-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e" - integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ== +hey-listen@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/hey-listen/-/hey-listen-1.0.8.tgz#8e59561ff724908de1aa924ed6ecc84a56a9aa68" + integrity sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q== -history@^4.9.0: - version "4.10.1" - resolved "https://registry.yarnpkg.com/history/-/history-4.10.1.tgz#33371a65e3a83b267434e2b3f3b1b4c58aad4cf3" - integrity sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew== +hmac-drbg@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= dependencies: - "@babel/runtime" "^7.1.2" - loose-envify "^1.2.0" - resolve-pathname "^3.0.0" - tiny-invariant "^1.0.2" - tiny-warning "^1.0.0" - value-equal "^1.0.1" + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" -hoist-non-react-statics@^3.0.0, hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.1, hoist-non-react-statics@^3.3.2: +hoist-non-react-statics@^3.2.0, hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.1, hoist-non-react-statics@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== @@ -7022,25 +6469,12 @@ hosted-git-info@^2.1.4: resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== -hpack.js@^2.1.6: - version "2.1.6" - resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" - integrity sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI= +hosted-git-info@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-4.0.2.tgz#5e425507eede4fea846b7262f0838456c4209961" + integrity sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg== dependencies: - inherits "^2.0.1" - obuf "^1.0.0" - readable-stream "^2.0.1" - wbuf "^1.1.0" - -hsl-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/hsl-regex/-/hsl-regex-1.0.0.tgz#d49330c789ed819e276a4c0d272dffa30b18fe6e" - integrity sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4= - -hsla-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/hsla-regex/-/hsla-regex-1.0.0.tgz#c1ce7a3168c8c6614033a4b5f7877f3b225f9c38" - integrity sha1-wc56MWjIxmFAM6S194d/OyJfnDg= + lru-cache "^6.0.0" html-encoding-sniffer@^2.0.1: version "2.0.1" @@ -7049,28 +6483,17 @@ html-encoding-sniffer@^2.0.1: dependencies: whatwg-encoding "^1.0.5" -html-entities@^1.3.1: - version "1.4.0" - resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.4.0.tgz#cfbd1b01d2afaf9adca1b10ae7dffab98c71d2dc" - integrity sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA== - html-escaper@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== -html-minifier-terser@^5.0.1, html-minifier-terser@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz#922e96f1f3bb60832c2634b79884096389b1f054" - integrity sha512-ZPr5MNObqnV/T9akshPKbVgyOqLmy+Bxo7juKCfTfnjNniTAMdy4hz21YQqoofMBJD2kdREaqPPdThoR78Tgxg== +html-parse-stringify@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz#dfc1017347ce9f77c8141a507f233040c59c55d2" + integrity sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg== dependencies: - camel-case "^4.1.1" - clean-css "^4.2.3" - commander "^4.1.1" - he "^1.2.0" - param-case "^3.0.3" - relateurl "^0.2.7" - terser "^4.6.3" + void-elements "3.1.0" html-tags@^3.1.0: version "3.1.0" @@ -7082,39 +6505,6 @@ html-void-elements@^1.0.0: resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-1.0.5.tgz#ce9159494e86d95e45795b166c2021c2cfca4483" integrity sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w== -html-webpack-plugin@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.3.1.tgz#8797327548e3de438e3494e0c6d06f181a7f20d1" - integrity sha512-rZsVvPXUYFyME0cuGkyOHfx9hmkFa4pWfxY/mdY38PsBEaVNsRoA+Id+8z6DBDgyv3zaw6XQszdF8HLwfQvcdQ== - dependencies: - "@types/html-minifier-terser" "^5.0.0" - html-minifier-terser "^5.0.1" - lodash "^4.17.20" - pretty-error "^2.1.1" - tapable "^2.0.0" - -htmlparser2@^3.10.1, htmlparser2@^3.9.1: - version "3.10.1" - resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f" - integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ== - dependencies: - domelementtype "^1.3.1" - domhandler "^2.3.0" - domutils "^1.5.1" - entities "^1.1.1" - inherits "^2.0.1" - readable-stream "^3.1.1" - -http-cache-semantics@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" - integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== - -http-deceiver@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" - integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc= - http-errors@1.7.2: version "1.7.2" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" @@ -7148,22 +6538,7 @@ http-errors@1.8.0, http-errors@^1.8.0: statuses ">= 1.5.0 < 2" toidentifier "1.0.0" -http-errors@~1.6.2: - version "1.6.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" - integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= - dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.0" - statuses ">= 1.4.0 < 2" - -http-parser-js@>=0.5.1: - version "0.5.3" - resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.3.tgz#01d2709c79d41698bb01d4decc5e9da4e4a033d9" - integrity sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg== - -http-proxy-agent@*, http-proxy-agent@^4.0.1: +http-proxy-agent@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== @@ -7172,24 +6547,10 @@ http-proxy-agent@*, http-proxy-agent@^4.0.1: agent-base "6" debug "4" -http-proxy-middleware@0.19.1: - version "0.19.1" - resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz#183c7dc4aa1479150306498c210cdaf96080a43a" - integrity sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q== - dependencies: - http-proxy "^1.17.0" - is-glob "^4.0.0" - lodash "^4.17.11" - micromatch "^3.1.10" - -http-proxy@^1.17.0: - version "1.18.1" - resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" - integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== - dependencies: - eventemitter3 "^4.0.0" - follow-redirects "^1.0.0" - requires-port "^1.0.0" +https-browserify@1.0.0, https-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" + integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= https-proxy-agent@^5.0.0: version "5.0.0" @@ -7209,10 +6570,34 @@ human-signals@^2.1.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== -husky@6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/husky/-/husky-6.0.0.tgz#810f11869adf51604c32ea577edbc377d7f9319e" - integrity sha512-SQS2gDTB7tBN486QSoKPKQItZw97BMOd+Kdb6ghfpBc0yXyzrddI0oDV5MkDAbuB4X2mO3/nj60TRMcYxwzZeQ== +husky@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/husky/-/husky-7.0.0.tgz#3dbd5d28e76234689ee29bb41e048f28e3e46616" + integrity sha512-xK7lO0EtSzfFPiw+oQncQVy/XqV7UVVjxBByc+Iv5iK3yhW9boDoWgvZy3OGo48QKg/hUtZkzz0hi2HXa0kn7w== + +hyphenate-style-name@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz#691879af8e220aea5750e8827db4ef62a54e361d" + integrity sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ== + +i18next-fs-backend@^1.0.7: + version "1.1.1" + resolved "https://registry.yarnpkg.com/i18next-fs-backend/-/i18next-fs-backend-1.1.1.tgz#1d8028926803f63784ffa0f2b1478fb369f92735" + integrity sha512-RFkfy10hNxJqc7MVAp5iAZq0Tum6msBCNebEe3OelOBvrROvzHUPaR8Qe10RQrOGokTm0W4vJGEJzruFkEt+hQ== + +i18next@^19.7.0: + version "19.9.2" + resolved "https://registry.yarnpkg.com/i18next/-/i18next-19.9.2.tgz#ea5a124416e3c5ab85fddca2c8e3c3669a8da397" + integrity sha512-0i6cuo6ER6usEOtKajUUDj92zlG+KArFia0857xxiEHAQcUwh/RtOQocui1LPJwunSYT574Pk64aNva1kwtxZg== + dependencies: + "@babel/runtime" "^7.12.0" + +i18next@^20.1.0: + version "20.3.2" + resolved "https://registry.yarnpkg.com/i18next/-/i18next-20.3.2.tgz#5195e76b9e0848a1c198001bf6c7fc72995a55f1" + integrity sha512-e8CML2R9Ng2sSQOM80wb/PrM2j8mDm84o/T4Amzn9ArVyNX5/ENWxxAXkRpZdTQNDaxKImF93Wep4mAoozFrKw== + dependencies: + "@babel/runtime" "^7.12.0" iconv-lite@0.4.24, iconv-lite@^0.4.24: version "0.4.24" @@ -7221,17 +6606,24 @@ iconv-lite@0.4.24, iconv-lite@^0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" +iconv-lite@^0.6.2: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + icss-replace-symbols@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz#06ea6f83679a7749e386cfe1fe812ae5db223ded" integrity sha1-Bupvg2ead0njhs/h/oEq5dsiPe0= -icss-utils@^5.0.0, icss-utils@^5.1.0: +icss-utils@^5.0.0: version "5.1.0" resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== -ieee754@^1.1.13: +ieee754@^1.1.13, ieee754@^1.1.4, ieee754@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== @@ -7246,17 +6638,31 @@ ignore@^5.1.1, ignore@^5.1.4: resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== -immer@8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/immer/-/immer-8.0.1.tgz#9c73db683e2b3975c424fb0572af5889877ae656" - integrity sha512-aqXhGP7//Gui2+UrEtvxZxSquQVXTpZ7KDxfCcKAF3Vysvw0CViVaW9RZ1j1xlIYqaaaipBoqdqeibkc18PNvA== +image-size@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/image-size/-/image-size-1.0.0.tgz#58b31fe4743b1cec0a0ac26f5c914d3c5b2f0750" + integrity sha512-JLJ6OwBfO1KcA+TvJT+v8gbE6iWbj24LyDNFgFEN0lzegn6cC6a/p3NIDaepMsJjQjlUWqIC7wJv8lBFxPNjcw== + dependencies: + queue "6.0.2" + +immer@^9.0.3: + version "9.0.5" + resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.5.tgz#a7154f34fe7064f15f00554cc94c66cc0bf453ec" + integrity sha512-2WuIehr2y4lmYz9gaQzetPR2ECniCifk4ORaQbU3g5EalLt+0IVTosEPJ5BoYl/75ky2mivzdRzV8wWgQGOSYQ== immutable@~3.7.6: version "3.7.6" resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.7.6.tgz#13b4d3cb12befa15482a26fe1b2ebae640071e4b" integrity sha1-E7TTyxK++hVIKib+Gy665kAHHks= -import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1, import-fresh@^3.2.2, import-fresh@^3.3.0: +import-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-3.0.0.tgz#20845547718015126ea9b3676b7592fb8bd4cf92" + integrity sha512-4pnzH16plW+hgvRECbDWpQl3cqtvSofHWh44met7ESfZ8UZOWWddm8hEyDTqREJ9RbYHY8gi8DqmaelApoOGMg== + dependencies: + import-from "^3.0.0" + +import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1: version "3.3.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== @@ -7269,18 +6675,12 @@ import-from@4.0.0: resolved "https://registry.yarnpkg.com/import-from/-/import-from-4.0.0.tgz#2710b8d66817d232e16f4166e319248d3d5492e2" integrity sha512-P9J71vT5nLlDeV8FHs5nNxaLbrpfAV5cF5srvbZfpwpcJoM/xZR3hiv+q+SAnuSmuGbXMWud063iIMx/V/EWZQ== -import-lazy@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" - integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM= - -import-local@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d" - integrity sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ== +import-from@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/import-from/-/import-from-3.0.0.tgz#055cfec38cd5a27d8057ca51376d7d3bf0891966" + integrity sha512-CiuXOFFSzkU5x/CR0+z7T91Iht4CXgfCxVOFRhh2Zyhg5wOpWvvDLQUsWl+gcN+QscYBjez8hDCt85O7RLDttQ== dependencies: - pkg-dir "^3.0.0" - resolve-cwd "^2.0.0" + resolve-from "^5.0.0" import-local@^3.0.2: version "3.0.2" @@ -7300,10 +6700,10 @@ indent-string@^4.0.0: resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== -infima@0.2.0-alpha.23: - version "0.2.0-alpha.23" - resolved "https://registry.yarnpkg.com/infima/-/infima-0.2.0-alpha.23.tgz#2c17b473784ae8244fd985f126f9c27a49b24523" - integrity sha512-V0RTjB1otjpH3E2asbydx3gz7ovdSJsuV7r9JTdBggqRilnelTJUcXxLawBQQKsjQi5qPcRTjxnlaV8xyyKhhw== +indent-string@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-5.0.0.tgz#4fd2980fccaf8622d14c64d694f4cf33c81951a5" + integrity sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg== inflight@^1.0.4: version "1.0.6" @@ -7313,43 +6713,32 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.0, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: +inherits@2, inherits@2.0.4, inherits@^2.0.0, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3, inherits@~2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +inherits@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= + inherits@2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= -ini@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5" - integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== - -ini@^1.3.5, ini@~1.3.0: - version "1.3.8" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" - integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== - inline-style-parser@0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/inline-style-parser/-/inline-style-parser-0.1.1.tgz#ec8a3b429274e9c0a1f1c4ffa9453a7fef72cea1" integrity sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q== -internal-ip@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-4.3.0.tgz#845452baad9d2ca3b69c635a137acb9a0dad0907" - integrity sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg== +inline-style-prefixer@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/inline-style-prefixer/-/inline-style-prefixer-6.0.0.tgz#f73d5dbf2855733d6b153a4d24b7b47a73e9770b" + integrity sha512-XTHvRUS4ZJNzC1GixJRmOlWSS45fSt+DJoyQC9ytj0WxQfcgofQtDtyKKYxHUqEsWCs+LIWftPF1ie7+i012Fg== dependencies: - default-gateway "^4.2.0" - ipaddr.js "^1.9.0" - -interpret@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" - integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== + css-in-js-utils "^2.0.0" invariant@^2.2.4: version "2.2.4" @@ -7358,40 +6747,11 @@ invariant@^2.2.4: dependencies: loose-envify "^1.0.0" -ip-regex@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" - integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk= - -ip@^1.1.0, ip@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" - integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= - -ipaddr.js@1.9.1, ipaddr.js@^1.9.0: +ipaddr.js@1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== -is-absolute-url@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-3.0.3.tgz#96c6a22b6a23929b11ea0afb1836c36ad4a5d698" - integrity sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q== - -is-accessor-descriptor@^0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" - integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= - dependencies: - kind-of "^3.0.2" - -is-accessor-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" - integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== - dependencies: - kind-of "^6.0.0" - is-alphabetical@1.0.4, is-alphabetical@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-1.0.4.tgz#9e7d6b94916be22153745d184c298cbf986a686d" @@ -7427,13 +6787,6 @@ is-bigint@^1.0.1: resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.1.tgz#6923051dfcbc764278540b9ce0e6b3213aa5ebc2" integrity sha512-J0ELF4yHFxHy0cmSxZuheDOz2luOdVvqjwmEcj8H/L1JHeuEDSDbeRP+Dk9kFVk5RTFzbucJ2Kb9F7ixY2QaCg== -is-binary-path@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" - integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= - dependencies: - binary-extensions "^1.0.0" - is-binary-path@~2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" @@ -7448,11 +6801,6 @@ is-boolean-object@^1.1.0: dependencies: call-bind "^1.0.0" -is-buffer@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" - integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== - is-buffer@^2.0.0: version "2.0.5" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" @@ -7477,18 +6825,6 @@ is-ci@^3.0.0: dependencies: ci-info "^3.1.1" -is-color-stop@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-color-stop/-/is-color-stop-1.1.0.tgz#cfff471aee4dd5c9e158598fbe12967b5cdad345" - integrity sha1-z/9HGu5N1cnhWFmPvhKWe1za00U= - dependencies: - css-color-names "^0.0.4" - hex-color-regex "^1.1.0" - hsl-regex "^1.0.0" - hsla-regex "^1.0.0" - rgb-regex "^1.0.1" - rgba-regex "^1.0.0" - is-core-module@^2.2.0, is-core-module@^2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.4.0.tgz#8e9fc8e15027b011418026e98f0e6f4d86305cc1" @@ -7496,20 +6832,6 @@ is-core-module@^2.2.0, is-core-module@^2.4.0: dependencies: has "^1.0.3" -is-data-descriptor@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" - integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= - dependencies: - kind-of "^3.0.2" - -is-data-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" - integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== - dependencies: - kind-of "^6.0.0" - is-date-object@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" @@ -7520,52 +6842,22 @@ is-decimal@^1.0.0: resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-1.0.4.tgz#65a3a5958a1c5b63a706e1b333d7cd9f630d3fa5" integrity sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw== -is-descriptor@^0.1.0: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" - integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== - dependencies: - is-accessor-descriptor "^0.1.6" - is-data-descriptor "^0.1.4" - kind-of "^5.0.0" - -is-descriptor@^1.0.0, is-descriptor@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" - integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== - dependencies: - is-accessor-descriptor "^1.0.0" - is-data-descriptor "^1.0.0" - kind-of "^6.0.2" - is-docker@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.1.1.tgz#4125a88e44e450d384e09047ede71adc2d144156" integrity sha512-ZOoqiXfEwtGknTiuDEy8pN2CfE3TxMHprvNer1mXiqwkOT77Rw3YVrUQ52EqAOU3QAWDQ+bQdx7HJzrv7LS2Hw== -is-dotfile@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" - integrity sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE= +is-docker@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== -is-extendable@^0.1.0, is-extendable@^0.1.1: +is-extendable@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= -is-extendable@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" - integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== - dependencies: - is-plain-object "^2.0.4" - -is-extglob@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" - integrity sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA= - -is-extglob@^2.1.0, is-extglob@^2.1.1: +is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= @@ -7585,6 +6877,11 @@ is-generator-fn@^2.0.0: resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== +is-generator-function@^1.0.7: + version "1.0.9" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.9.tgz#e5f82c2323673e7fcad3d12858c83c4039f6399c" + integrity sha512-ZJ34p1uvIfptHCN7sFTjGibB9/oBg17sHqzDLfuwhvmN/qLVvIQXRQ8licZQ35WJ8KuEQt/etnnzQFI9C9Ue/A== + is-glob@4.0.1, is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" @@ -7592,60 +6889,34 @@ is-glob@4.0.1, is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" -is-glob@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" - integrity sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM= - dependencies: - is-extglob "^1.0.0" - -is-glob@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" - integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= - dependencies: - is-extglob "^2.1.0" - is-hexadecimal@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz#cc35c97588da4bd49a8eedd6bc4082d44dcb23a7" integrity sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw== -is-installed-globally@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.4.0.tgz#9a0fd407949c30f86eb6959ef1b7994ed0b7b520" - integrity sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ== - dependencies: - global-dirs "^3.0.0" - is-path-inside "^3.0.2" - is-module@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" integrity sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE= +is-nan@^1.2.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/is-nan/-/is-nan-1.3.2.tgz#043a54adea31748b55b6cd4e09aadafa69bd9e1d" + integrity sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + is-negative-zero@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== -is-npm@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-5.0.0.tgz#43e8d65cc56e1b67f8d47262cf667099193f45a8" - integrity sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA== - is-number-object@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.4.tgz#36ac95e741cf18b283fc1ddf5e83da798e3ec197" integrity sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw== -is-number@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" - integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= - dependencies: - kind-of "^3.0.2" - is-number@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" @@ -7656,30 +6927,11 @@ is-obj@^1.0.1: resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= -is-obj@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" - integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== - -is-path-cwd@^2.0.0, is-path-cwd@^2.2.0: +is-path-cwd@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ== -is-path-in-cwd@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz#bfe2dca26c69f397265a4009963602935a053acb" - integrity sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ== - dependencies: - is-path-inside "^2.1.0" - -is-path-inside@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-2.1.0.tgz#7c9810587d659a40d27bcdb4d5616eab059494b2" - integrity sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg== - dependencies: - path-is-inside "^1.0.2" - is-path-inside@^3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" @@ -7695,13 +6947,6 @@ is-plain-obj@^2.0.0: resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== -is-plain-object@^2.0.3, is-plain-object@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" - integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== - dependencies: - isobject "^3.0.1" - is-potential-custom-element-name@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" @@ -7712,7 +6957,7 @@ is-promise@4.0.0: resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-4.0.0.tgz#42ff9f84206c1991d26debf520dd5c01042dd2f3" integrity sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ== -is-regex@^1.0.4, is-regex@^1.1.2: +is-regex@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.2.tgz#81c8ebde4db142f2cf1c53fc86d6a45788266251" integrity sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg== @@ -7725,16 +6970,6 @@ is-regexp@^1.0.0: resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" integrity sha1-/S2INUXEa6xaYz57mgnof6LLUGk= -is-resolvable@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" - integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg== - -is-root@2.1.0, is-root@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-root/-/is-root-2.1.0.tgz#809e18129cf1129644302a4f8544035d51984a9c" - integrity sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg== - is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" @@ -7764,6 +6999,17 @@ is-symbol@^1.0.2, is-symbol@^1.0.3: dependencies: has-symbols "^1.0.1" +is-typed-array@^1.1.3: + version "1.1.5" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.5.tgz#f32e6e096455e329eb7b423862456aa213f0eb4e" + integrity sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug== + dependencies: + available-typed-arrays "^1.0.2" + call-bind "^1.0.2" + es-abstract "^1.18.0-next.2" + foreach "^2.0.5" + has-symbols "^1.0.1" + is-typedarray@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" @@ -7779,7 +7025,7 @@ is-whitespace-character@^1.0.0: resolved "https://registry.yarnpkg.com/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz#0858edd94a95594c7c9dd0b5c174ec6e45ee4aa7" integrity sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w== -is-windows@^1.0.0, is-windows@^1.0.2: +is-windows@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== @@ -7789,29 +7035,14 @@ is-word-character@^1.0.0: resolved "https://registry.yarnpkg.com/is-word-character/-/is-word-character-1.0.4.tgz#ce0e73216f98599060592f62ff31354ddbeb0230" integrity sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA== -is-wsl@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" - integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= - -is-wsl@^2.1.1: +is-wsl@^2.1.1, is-wsl@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== dependencies: is-docker "^2.0.0" -is-yarn-global@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/is-yarn-global/-/is-yarn-global-0.3.0.tgz#d502d3382590ea3004893746754c89139973e232" - integrity sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw== - -isarray@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= - -isarray@1.0.0, isarray@~1.0.0: +isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= @@ -7821,14 +7052,7 @@ isexe@^2.0.0: resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= -isobject@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= - dependencies: - isarray "1.0.0" - -isobject@^3.0.0, isobject@^3.0.1: +isobject@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= @@ -7897,84 +7121,84 @@ iterall@^1.2.1, iterall@^1.3.0: resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.3.0.tgz#afcb08492e2915cbd8a0884eb93a8c94d0d72fea" integrity sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg== -jest-changed-files@^27.0.2: - version "27.0.2" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-27.0.2.tgz#997253042b4a032950fc5f56abf3c5d1f8560801" - integrity sha512-eMeb1Pn7w7x3wue5/vF73LPCJ7DKQuC9wQUR5ebP9hDPpk5hzcT/3Hmz3Q5BOFpR3tgbmaWhJcMTVgC8Z1NuMw== +jest-changed-files@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-27.0.6.tgz#bed6183fcdea8a285482e3b50a9a7712d49a7a8b" + integrity sha512-BuL/ZDauaq5dumYh5y20sn4IISnf1P9A0TDswTxUi84ORGtVa86ApuBHqICL0vepqAnZiY6a7xeSPWv2/yy4eA== dependencies: - "@jest/types" "^27.0.2" + "@jest/types" "^27.0.6" execa "^5.0.0" throat "^6.0.1" -jest-circus@^27.0.4: - version "27.0.4" - resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-27.0.4.tgz#3b261514ee3b3da33def736a6352c98ff56bb6e6" - integrity sha512-QD+eblDiRphta630WRKewuASLs/oY1Zki2G4bccntRvrTHQ63ljwFR5TLduuK4Zg0ZPzW0+8o6AP7KRd1yKOjw== +jest-circus@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-27.0.6.tgz#dd4df17c4697db6a2c232aaad4e9cec666926668" + integrity sha512-OJlsz6BBeX9qR+7O9lXefWoc2m9ZqcZ5Ohlzz0pTEAG4xMiZUJoacY8f4YDHxgk0oKYxj277AfOk9w6hZYvi1Q== dependencies: - "@jest/environment" "^27.0.3" - "@jest/test-result" "^27.0.2" - "@jest/types" "^27.0.2" + "@jest/environment" "^27.0.6" + "@jest/test-result" "^27.0.6" + "@jest/types" "^27.0.6" "@types/node" "*" chalk "^4.0.0" co "^4.6.0" dedent "^0.7.0" - expect "^27.0.2" + expect "^27.0.6" is-generator-fn "^2.0.0" - jest-each "^27.0.2" - jest-matcher-utils "^27.0.2" - jest-message-util "^27.0.2" - jest-runtime "^27.0.4" - jest-snapshot "^27.0.4" - jest-util "^27.0.2" - pretty-format "^27.0.2" + jest-each "^27.0.6" + jest-matcher-utils "^27.0.6" + jest-message-util "^27.0.6" + jest-runtime "^27.0.6" + jest-snapshot "^27.0.6" + jest-util "^27.0.6" + pretty-format "^27.0.6" slash "^3.0.0" stack-utils "^2.0.3" throat "^6.0.1" -jest-cli@^27.0.4: - version "27.0.4" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-27.0.4.tgz#491b12c754c0d7c6873b13a66f26b3a80a852910" - integrity sha512-E0T+/i2lxsWAzV7LKYd0SB7HUAvePqaeIh5vX43/G5jXLhv1VzjYzJAGEkTfvxV774ll9cyE2ljcL73PVMEOXQ== +jest-cli@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-27.0.6.tgz#d021e5f4d86d6a212450d4c7b86cb219f1e6864f" + integrity sha512-qUUVlGb9fdKir3RDE+B10ULI+LQrz+MCflEH2UJyoUjoHHCbxDrMxSzjQAPUMsic4SncI62ofYCcAvW6+6rhhg== dependencies: - "@jest/core" "^27.0.4" - "@jest/test-result" "^27.0.2" - "@jest/types" "^27.0.2" + "@jest/core" "^27.0.6" + "@jest/test-result" "^27.0.6" + "@jest/types" "^27.0.6" chalk "^4.0.0" exit "^0.1.2" graceful-fs "^4.2.4" import-local "^3.0.2" - jest-config "^27.0.4" - jest-util "^27.0.2" - jest-validate "^27.0.2" + jest-config "^27.0.6" + jest-util "^27.0.6" + jest-validate "^27.0.6" prompts "^2.0.1" yargs "^16.0.3" -jest-config@^27.0.4: - version "27.0.4" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-27.0.4.tgz#c4f41378acf40ca77860fb4e213b12109d87b8cf" - integrity sha512-VkQFAHWnPQefdvHU9A+G3H/Z3NrrTKqWpvxgQz3nkUdkDTWeKJE6e//BL+R7z79dXOMVksYgM/z6ndtN0hfChg== +jest-config@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-27.0.6.tgz#119fb10f149ba63d9c50621baa4f1f179500277f" + integrity sha512-JZRR3I1Plr2YxPBhgqRspDE2S5zprbga3swYNrvY3HfQGu7p/GjyLOqwrYad97tX3U3mzT53TPHVmozacfP/3w== dependencies: "@babel/core" "^7.1.0" - "@jest/test-sequencer" "^27.0.4" - "@jest/types" "^27.0.2" - babel-jest "^27.0.2" + "@jest/test-sequencer" "^27.0.6" + "@jest/types" "^27.0.6" + babel-jest "^27.0.6" chalk "^4.0.0" deepmerge "^4.2.2" glob "^7.1.1" graceful-fs "^4.2.4" is-ci "^3.0.0" - jest-circus "^27.0.4" - jest-environment-jsdom "^27.0.3" - jest-environment-node "^27.0.3" - jest-get-type "^27.0.1" - jest-jasmine2 "^27.0.4" - jest-regex-util "^27.0.1" - jest-resolve "^27.0.4" - jest-runner "^27.0.4" - jest-util "^27.0.2" - jest-validate "^27.0.2" + jest-circus "^27.0.6" + jest-environment-jsdom "^27.0.6" + jest-environment-node "^27.0.6" + jest-get-type "^27.0.6" + jest-jasmine2 "^27.0.6" + jest-regex-util "^27.0.6" + jest-resolve "^27.0.6" + jest-runner "^27.0.6" + jest-util "^27.0.6" + jest-validate "^27.0.6" micromatch "^4.0.4" - pretty-format "^27.0.2" + pretty-format "^27.0.6" jest-diff@^26.0.0: version "26.6.2" @@ -7986,152 +7210,152 @@ jest-diff@^26.0.0: jest-get-type "^26.3.0" pretty-format "^26.6.2" -jest-diff@^27.0.2: - version "27.0.2" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.0.2.tgz#f315b87cee5dc134cf42c2708ab27375cc3f5a7e" - integrity sha512-BFIdRb0LqfV1hBt8crQmw6gGQHVDhM87SpMIZ45FPYKReZYG5er1+5pIn2zKqvrJp6WNox0ylR8571Iwk2Dmgw== +jest-diff@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.0.6.tgz#4a7a19ee6f04ad70e0e3388f35829394a44c7b5e" + integrity sha512-Z1mqgkTCSYaFgwTlP/NUiRzdqgxmmhzHY1Tq17zL94morOHfHu3K4bgSgl+CR4GLhpV8VxkuOYuIWnQ9LnFqmg== dependencies: chalk "^4.0.0" - diff-sequences "^27.0.1" - jest-get-type "^27.0.1" - pretty-format "^27.0.2" + diff-sequences "^27.0.6" + jest-get-type "^27.0.6" + pretty-format "^27.0.6" -jest-docblock@^27.0.1: - version "27.0.1" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-27.0.1.tgz#bd9752819b49fa4fab1a50b73eb58c653b962e8b" - integrity sha512-TA4+21s3oebURc7VgFV4r7ltdIJ5rtBH1E3Tbovcg7AV+oLfD5DcJ2V2vJ5zFA9sL5CFd/d2D6IpsAeSheEdrA== +jest-docblock@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-27.0.6.tgz#cc78266acf7fe693ca462cbbda0ea4e639e4e5f3" + integrity sha512-Fid6dPcjwepTFraz0YxIMCi7dejjJ/KL9FBjPYhBp4Sv1Y9PdhImlKZqYU555BlN4TQKaTc+F2Av1z+anVyGkA== dependencies: detect-newline "^3.0.0" -jest-each@^27.0.2: - version "27.0.2" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-27.0.2.tgz#865ddb4367476ced752167926b656fa0dcecd8c7" - integrity sha512-OLMBZBZ6JkoXgUenDtseFRWA43wVl2BwmZYIWQws7eS7pqsIvePqj/jJmEnfq91ALk3LNphgwNK/PRFBYi7ITQ== +jest-each@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-27.0.6.tgz#cee117071b04060158dc8d9a66dc50ad40ef453b" + integrity sha512-m6yKcV3bkSWrUIjxkE9OC0mhBZZdhovIW5ergBYirqnkLXkyEn3oUUF/QZgyecA1cF1QFyTE8bRRl8Tfg1pfLA== dependencies: - "@jest/types" "^27.0.2" + "@jest/types" "^27.0.6" chalk "^4.0.0" - jest-get-type "^27.0.1" - jest-util "^27.0.2" - pretty-format "^27.0.2" - -jest-environment-jsdom@^27.0.3: - version "27.0.3" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-27.0.3.tgz#ed73e913ddc03864eb9f934b5cbabf1b63504e2e" - integrity sha512-5KLmgv1bhiimpSA8oGTnZYk6g4fsNyZiA/6gI2tAZUgrufd7heRUSVh4gRokzZVEj8zlwAQYT0Zs6tuJSW/ECA== - dependencies: - "@jest/environment" "^27.0.3" - "@jest/fake-timers" "^27.0.3" - "@jest/types" "^27.0.2" + jest-get-type "^27.0.6" + jest-util "^27.0.6" + pretty-format "^27.0.6" + +jest-environment-jsdom@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-27.0.6.tgz#f66426c4c9950807d0a9f209c590ce544f73291f" + integrity sha512-FvetXg7lnXL9+78H+xUAsra3IeZRTiegA3An01cWeXBspKXUhAwMM9ycIJ4yBaR0L7HkoMPaZsozCLHh4T8fuw== + dependencies: + "@jest/environment" "^27.0.6" + "@jest/fake-timers" "^27.0.6" + "@jest/types" "^27.0.6" "@types/node" "*" - jest-mock "^27.0.3" - jest-util "^27.0.2" + jest-mock "^27.0.6" + jest-util "^27.0.6" jsdom "^16.6.0" -jest-environment-node@^27.0.3: - version "27.0.3" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-27.0.3.tgz#b4acb3679d2552a4215732cab8b0ca7ec4398ee0" - integrity sha512-co2/IVnIFL3cItpFULCvXFg9us4gvWXgs7mutAMPCbFhcqh56QAOdKhNzC2+RycsC/k4mbMj1VF+9F/NzA0ROg== +jest-environment-node@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-27.0.6.tgz#a6699b7ceb52e8d68138b9808b0c404e505f3e07" + integrity sha512-+Vi6yLrPg/qC81jfXx3IBlVnDTI6kmRr08iVa2hFCWmJt4zha0XW7ucQltCAPhSR0FEKEoJ3i+W4E6T0s9is0w== dependencies: - "@jest/environment" "^27.0.3" - "@jest/fake-timers" "^27.0.3" - "@jest/types" "^27.0.2" + "@jest/environment" "^27.0.6" + "@jest/fake-timers" "^27.0.6" + "@jest/types" "^27.0.6" "@types/node" "*" - jest-mock "^27.0.3" - jest-util "^27.0.2" + jest-mock "^27.0.6" + jest-util "^27.0.6" jest-get-type@^26.3.0: version "26.3.0" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-26.3.0.tgz#e97dc3c3f53c2b406ca7afaed4493b1d099199e0" integrity sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig== -jest-get-type@^27.0.1: - version "27.0.1" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.0.1.tgz#34951e2b08c8801eb28559d7eb732b04bbcf7815" - integrity sha512-9Tggo9zZbu0sHKebiAijyt1NM77Z0uO4tuWOxUCujAiSeXv30Vb5D4xVF4UR4YWNapcftj+PbByU54lKD7/xMg== +jest-get-type@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.0.6.tgz#0eb5c7f755854279ce9b68a9f1a4122f69047cfe" + integrity sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg== -jest-haste-map@^27.0.2: - version "27.0.2" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-27.0.2.tgz#3f1819400c671237e48b4d4b76a80a0dbed7577f" - integrity sha512-37gYfrYjjhEfk37C4bCMWAC0oPBxDpG0qpl8lYg8BT//wf353YT/fzgA7+Dq0EtM7rPFS3JEcMsxdtDwNMi2cA== +jest-haste-map@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-27.0.6.tgz#4683a4e68f6ecaa74231679dca237279562c8dc7" + integrity sha512-4ldjPXX9h8doB2JlRzg9oAZ2p6/GpQUNAeiYXqcpmrKbP0Qev0wdZlxSMOmz8mPOEnt4h6qIzXFLDi8RScX/1w== dependencies: - "@jest/types" "^27.0.2" + "@jest/types" "^27.0.6" "@types/graceful-fs" "^4.1.2" "@types/node" "*" anymatch "^3.0.3" fb-watchman "^2.0.0" graceful-fs "^4.2.4" - jest-regex-util "^27.0.1" - jest-serializer "^27.0.1" - jest-util "^27.0.2" - jest-worker "^27.0.2" + jest-regex-util "^27.0.6" + jest-serializer "^27.0.6" + jest-util "^27.0.6" + jest-worker "^27.0.6" micromatch "^4.0.4" walker "^1.0.7" optionalDependencies: fsevents "^2.3.2" -jest-jasmine2@^27.0.4: - version "27.0.4" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-27.0.4.tgz#c669519ccf4904a485338555e1e66cad36bb0670" - integrity sha512-yj3WrjjquZwkJw+eA4c9yucHw4/+EHndHWSqgHbHGQfT94ihaaQsa009j1a0puU8CNxPDk0c1oAPeOpdJUElwA== +jest-jasmine2@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-27.0.6.tgz#fd509a9ed3d92bd6edb68a779f4738b100655b37" + integrity sha512-cjpH2sBy+t6dvCeKBsHpW41mjHzXgsavaFMp+VWRf0eR4EW8xASk1acqmljFtK2DgyIECMv2yCdY41r2l1+4iA== dependencies: "@babel/traverse" "^7.1.0" - "@jest/environment" "^27.0.3" - "@jest/source-map" "^27.0.1" - "@jest/test-result" "^27.0.2" - "@jest/types" "^27.0.2" + "@jest/environment" "^27.0.6" + "@jest/source-map" "^27.0.6" + "@jest/test-result" "^27.0.6" + "@jest/types" "^27.0.6" "@types/node" "*" chalk "^4.0.0" co "^4.6.0" - expect "^27.0.2" + expect "^27.0.6" is-generator-fn "^2.0.0" - jest-each "^27.0.2" - jest-matcher-utils "^27.0.2" - jest-message-util "^27.0.2" - jest-runtime "^27.0.4" - jest-snapshot "^27.0.4" - jest-util "^27.0.2" - pretty-format "^27.0.2" + jest-each "^27.0.6" + jest-matcher-utils "^27.0.6" + jest-message-util "^27.0.6" + jest-runtime "^27.0.6" + jest-snapshot "^27.0.6" + jest-util "^27.0.6" + pretty-format "^27.0.6" throat "^6.0.1" -jest-leak-detector@^27.0.2: - version "27.0.2" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-27.0.2.tgz#ce19aa9dbcf7a72a9d58907a970427506f624e69" - integrity sha512-TZA3DmCOfe8YZFIMD1GxFqXUkQnIoOGQyy4hFCA2mlHtnAaf+FeOMxi0fZmfB41ZL+QbFG6BVaZF5IeFIVy53Q== +jest-leak-detector@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-27.0.6.tgz#545854275f85450d4ef4b8fe305ca2a26450450f" + integrity sha512-2/d6n2wlH5zEcdctX4zdbgX8oM61tb67PQt4Xh8JFAIy6LRKUnX528HulkaG6nD5qDl5vRV1NXejCe1XRCH5gQ== dependencies: - jest-get-type "^27.0.1" - pretty-format "^27.0.2" + jest-get-type "^27.0.6" + pretty-format "^27.0.6" -jest-matcher-utils@^27.0.2: - version "27.0.2" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.0.2.tgz#f14c060605a95a466cdc759acc546c6f4cbfc4f0" - integrity sha512-Qczi5xnTNjkhcIB0Yy75Txt+Ez51xdhOxsukN7awzq2auZQGPHcQrJ623PZj0ECDEMOk2soxWx05EXdXGd1CbA== +jest-matcher-utils@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.0.6.tgz#2a8da1e86c620b39459f4352eaa255f0d43e39a9" + integrity sha512-OFgF2VCQx9vdPSYTHWJ9MzFCehs20TsyFi6bIHbk5V1u52zJOnvF0Y/65z3GLZHKRuTgVPY4Z6LVePNahaQ+tA== dependencies: chalk "^4.0.0" - jest-diff "^27.0.2" - jest-get-type "^27.0.1" - pretty-format "^27.0.2" + jest-diff "^27.0.6" + jest-get-type "^27.0.6" + pretty-format "^27.0.6" -jest-message-util@^27.0.2: - version "27.0.2" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-27.0.2.tgz#181c9b67dff504d8f4ad15cba10d8b80f272048c" - integrity sha512-rTqWUX42ec2LdMkoUPOzrEd1Tcm+R1KfLOmFK+OVNo4MnLsEaxO5zPDb2BbdSmthdM/IfXxOZU60P/WbWF8BTw== +jest-message-util@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-27.0.6.tgz#158bcdf4785706492d164a39abca6a14da5ab8b5" + integrity sha512-rBxIs2XK7rGy+zGxgi+UJKP6WqQ+KrBbD1YMj517HYN3v2BG66t3Xan3FWqYHKZwjdB700KiAJ+iES9a0M+ixw== dependencies: "@babel/code-frame" "^7.12.13" - "@jest/types" "^27.0.2" + "@jest/types" "^27.0.6" "@types/stack-utils" "^2.0.0" chalk "^4.0.0" graceful-fs "^4.2.4" micromatch "^4.0.4" - pretty-format "^27.0.2" + pretty-format "^27.0.6" slash "^3.0.0" stack-utils "^2.0.3" -jest-mock@^27.0.3: - version "27.0.3" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-27.0.3.tgz#5591844f9192b3335c0dca38e8e45ed297d4d23d" - integrity sha512-O5FZn5XDzEp+Xg28mUz4ovVcdwBBPfAhW9+zJLO0Efn2qNbYcDaJvSlRiQ6BCZUCVOJjALicuJQI9mRFjv1o9Q== +jest-mock@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-27.0.6.tgz#0efdd40851398307ba16778728f6d34d583e3467" + integrity sha512-lzBETUoK8cSxts2NYXSBWT+EJNzmUVtVVwS1sU9GwE1DLCfGsngg+ZVSIe0yd0ZSm+y791esiuo+WSwpXJQ5Bw== dependencies: - "@jest/types" "^27.0.2" + "@jest/types" "^27.0.6" "@types/node" "*" jest-pnp-resolver@^1.2.2: @@ -8139,76 +7363,76 @@ jest-pnp-resolver@^1.2.2: resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== -jest-regex-util@^27.0.1: - version "27.0.1" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.0.1.tgz#69d4b1bf5b690faa3490113c47486ed85dd45b68" - integrity sha512-6nY6QVcpTgEKQy1L41P4pr3aOddneK17kn3HJw6SdwGiKfgCGTvH02hVXL0GU8GEKtPH83eD2DIDgxHXOxVohQ== +jest-regex-util@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.0.6.tgz#02e112082935ae949ce5d13b2675db3d8c87d9c5" + integrity sha512-SUhPzBsGa1IKm8hx2F4NfTGGp+r7BXJ4CulsZ1k2kI+mGLG+lxGrs76veN2LF/aUdGosJBzKgXmNCw+BzFqBDQ== -jest-resolve-dependencies@^27.0.4: - version "27.0.4" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.0.4.tgz#a07a242d70d668afd3fcf7f4270755eebb1fe579" - integrity sha512-F33UPfw1YGWCV2uxJl7wD6TvcQn5IC0LtguwY3r4L7R6H4twpLkp5Q2ZfzRx9A2I3G8feiy0O0sqcn/Qoym71A== +jest-resolve-dependencies@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.0.6.tgz#3e619e0ef391c3ecfcf6ef4056207a3d2be3269f" + integrity sha512-mg9x9DS3BPAREWKCAoyg3QucCr0n6S8HEEsqRCKSPjPcu9HzRILzhdzY3imsLoZWeosEbJZz6TKasveczzpJZA== dependencies: - "@jest/types" "^27.0.2" - jest-regex-util "^27.0.1" - jest-snapshot "^27.0.4" + "@jest/types" "^27.0.6" + jest-regex-util "^27.0.6" + jest-snapshot "^27.0.6" -jest-resolve@^27.0.4: - version "27.0.4" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-27.0.4.tgz#8a27bc3f2f00c8ea28f3bc99bbf6f468300a703d" - integrity sha512-BcfyK2i3cG79PDb/6gB6zFeFQlcqLsQjGBqznFCpA0L/3l1L/oOsltdUjs5eISAWA9HS9qtj8v2PSZr/yWxONQ== +jest-resolve@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-27.0.6.tgz#e90f436dd4f8fbf53f58a91c42344864f8e55bff" + integrity sha512-yKmIgw2LgTh7uAJtzv8UFHGF7Dm7XfvOe/LQ3Txv101fLM8cx2h1QVwtSJ51Q/SCxpIiKfVn6G2jYYMDNHZteA== dependencies: - "@jest/types" "^27.0.2" + "@jest/types" "^27.0.6" chalk "^4.0.0" escalade "^3.1.1" graceful-fs "^4.2.4" jest-pnp-resolver "^1.2.2" - jest-util "^27.0.2" - jest-validate "^27.0.2" + jest-util "^27.0.6" + jest-validate "^27.0.6" resolve "^1.20.0" slash "^3.0.0" -jest-runner@^27.0.4: - version "27.0.4" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-27.0.4.tgz#2787170a9509b792ae129794f6944d27d5d12a4f" - integrity sha512-NfmvSYLCsCJk2AG8Ar2NAh4PhsJJpO+/r+g4bKR5L/5jFzx/indUpnVBdrfDvuqhGLLAvrKJ9FM/Nt8o1dsqxg== +jest-runner@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-27.0.6.tgz#1325f45055539222bbc7256a6976e993ad2f9520" + integrity sha512-W3Bz5qAgaSChuivLn+nKOgjqNxM7O/9JOJoKDCqThPIg2sH/d4A/lzyiaFgnb9V1/w29Le11NpzTJSzga1vyYQ== dependencies: - "@jest/console" "^27.0.2" - "@jest/environment" "^27.0.3" - "@jest/test-result" "^27.0.2" - "@jest/transform" "^27.0.2" - "@jest/types" "^27.0.2" + "@jest/console" "^27.0.6" + "@jest/environment" "^27.0.6" + "@jest/test-result" "^27.0.6" + "@jest/transform" "^27.0.6" + "@jest/types" "^27.0.6" "@types/node" "*" chalk "^4.0.0" emittery "^0.8.1" exit "^0.1.2" graceful-fs "^4.2.4" - jest-docblock "^27.0.1" - jest-environment-jsdom "^27.0.3" - jest-environment-node "^27.0.3" - jest-haste-map "^27.0.2" - jest-leak-detector "^27.0.2" - jest-message-util "^27.0.2" - jest-resolve "^27.0.4" - jest-runtime "^27.0.4" - jest-util "^27.0.2" - jest-worker "^27.0.2" + jest-docblock "^27.0.6" + jest-environment-jsdom "^27.0.6" + jest-environment-node "^27.0.6" + jest-haste-map "^27.0.6" + jest-leak-detector "^27.0.6" + jest-message-util "^27.0.6" + jest-resolve "^27.0.6" + jest-runtime "^27.0.6" + jest-util "^27.0.6" + jest-worker "^27.0.6" source-map-support "^0.5.6" throat "^6.0.1" -jest-runtime@^27.0.4: - version "27.0.4" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-27.0.4.tgz#2e4a6aa77cac32ac612dfe12768387a8aa15c2f0" - integrity sha512-voJB4xbAjS/qYPboV+e+gmg3jfvHJJY4CagFWBOM9dQKtlaiTjcpD2tWwla84Z7PtXSQPeIpXY0qksA9Dum29A== - dependencies: - "@jest/console" "^27.0.2" - "@jest/environment" "^27.0.3" - "@jest/fake-timers" "^27.0.3" - "@jest/globals" "^27.0.3" - "@jest/source-map" "^27.0.1" - "@jest/test-result" "^27.0.2" - "@jest/transform" "^27.0.2" - "@jest/types" "^27.0.2" +jest-runtime@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-27.0.6.tgz#45877cfcd386afdd4f317def551fc369794c27c9" + integrity sha512-BhvHLRVfKibYyqqEFkybsznKwhrsu7AWx2F3y9G9L95VSIN3/ZZ9vBpm/XCS2bS+BWz3sSeNGLzI3TVQ0uL85Q== + dependencies: + "@jest/console" "^27.0.6" + "@jest/environment" "^27.0.6" + "@jest/fake-timers" "^27.0.6" + "@jest/globals" "^27.0.6" + "@jest/source-map" "^27.0.6" + "@jest/test-result" "^27.0.6" + "@jest/transform" "^27.0.6" + "@jest/types" "^27.0.6" "@types/yargs" "^16.0.0" chalk "^4.0.0" cjs-module-lexer "^1.0.0" @@ -8216,30 +7440,30 @@ jest-runtime@^27.0.4: exit "^0.1.2" glob "^7.1.3" graceful-fs "^4.2.4" - jest-haste-map "^27.0.2" - jest-message-util "^27.0.2" - jest-mock "^27.0.3" - jest-regex-util "^27.0.1" - jest-resolve "^27.0.4" - jest-snapshot "^27.0.4" - jest-util "^27.0.2" - jest-validate "^27.0.2" + jest-haste-map "^27.0.6" + jest-message-util "^27.0.6" + jest-mock "^27.0.6" + jest-regex-util "^27.0.6" + jest-resolve "^27.0.6" + jest-snapshot "^27.0.6" + jest-util "^27.0.6" + jest-validate "^27.0.6" slash "^3.0.0" strip-bom "^4.0.0" yargs "^16.0.3" -jest-serializer@^27.0.1: - version "27.0.1" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-27.0.1.tgz#2464d04dcc33fb71dc80b7c82e3c5e8a08cb1020" - integrity sha512-svy//5IH6bfQvAbkAEg1s7xhhgHTtXu0li0I2fdKHDsLP2P2MOiscPQIENQep8oU2g2B3jqLyxKKzotZOz4CwQ== +jest-serializer@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-27.0.6.tgz#93a6c74e0132b81a2d54623251c46c498bb5bec1" + integrity sha512-PtGdVK9EGC7dsaziskfqaAPib6wTViY3G8E5wz9tLVPhHyiDNTZn/xjZ4khAw+09QkoOVpn7vF5nPSN6dtBexA== dependencies: "@types/node" "*" graceful-fs "^4.2.4" -jest-snapshot@^27.0.4: - version "27.0.4" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-27.0.4.tgz#2b96e22ca90382b3e93bd0aae2ce4c78bf51fb5b" - integrity sha512-hnjrvpKGdSMvKfbHyaG5Kul7pDJGZvjVy0CKpzhu28MmAssDXS6GpynhXzgst1wBQoKD8c9b2VS2a5yhDLQRCA== +jest-snapshot@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-27.0.6.tgz#f4e6b208bd2e92e888344d78f0f650bcff05a4bf" + integrity sha512-NTHaz8He+ATUagUgE7C/UtFcRoHqR2Gc+KDfhQIyx+VFgwbeEMjeP+ILpUTLosZn/ZtbNdCF5LkVnN/l+V751A== dependencies: "@babel/core" "^7.7.2" "@babel/generator" "^7.7.2" @@ -8247,70 +7471,70 @@ jest-snapshot@^27.0.4: "@babel/plugin-syntax-typescript" "^7.7.2" "@babel/traverse" "^7.7.2" "@babel/types" "^7.0.0" - "@jest/transform" "^27.0.2" - "@jest/types" "^27.0.2" + "@jest/transform" "^27.0.6" + "@jest/types" "^27.0.6" "@types/babel__traverse" "^7.0.4" "@types/prettier" "^2.1.5" babel-preset-current-node-syntax "^1.0.0" chalk "^4.0.0" - expect "^27.0.2" + expect "^27.0.6" graceful-fs "^4.2.4" - jest-diff "^27.0.2" - jest-get-type "^27.0.1" - jest-haste-map "^27.0.2" - jest-matcher-utils "^27.0.2" - jest-message-util "^27.0.2" - jest-resolve "^27.0.4" - jest-util "^27.0.2" + jest-diff "^27.0.6" + jest-get-type "^27.0.6" + jest-haste-map "^27.0.6" + jest-matcher-utils "^27.0.6" + jest-message-util "^27.0.6" + jest-resolve "^27.0.6" + jest-util "^27.0.6" natural-compare "^1.4.0" - pretty-format "^27.0.2" + pretty-format "^27.0.6" semver "^7.3.2" -jest-util@^27.0.0, jest-util@^27.0.2: - version "27.0.2" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-27.0.2.tgz#fc2c7ace3c75ae561cf1e5fdb643bf685a5be7c7" - integrity sha512-1d9uH3a00OFGGWSibpNYr+jojZ6AckOMCXV2Z4K3YXDnzpkAaXQyIpY14FOJPiUmil7CD+A6Qs+lnnh6ctRbIA== +jest-util@^27.0.0, jest-util@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-27.0.6.tgz#e8e04eec159de2f4d5f57f795df9cdc091e50297" + integrity sha512-1JjlaIh+C65H/F7D11GNkGDDZtDfMEM8EBXsvd+l/cxtgQ6QhxuloOaiayt89DxUvDarbVhqI98HhgrM1yliFQ== dependencies: - "@jest/types" "^27.0.2" + "@jest/types" "^27.0.6" "@types/node" "*" chalk "^4.0.0" graceful-fs "^4.2.4" is-ci "^3.0.0" picomatch "^2.2.3" -jest-validate@^27.0.2: - version "27.0.2" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-27.0.2.tgz#7fe2c100089449cd5cbb47a5b0b6cb7cda5beee5" - integrity sha512-UgBF6/oVu1ofd1XbaSotXKihi8nZhg0Prm8twQ9uCuAfo59vlxCXMPI/RKmrZEVgi3Nd9dS0I8A0wzWU48pOvg== +jest-validate@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-27.0.6.tgz#930a527c7a951927df269f43b2dc23262457e2a6" + integrity sha512-yhZZOaMH3Zg6DC83n60pLmdU1DQE46DW+KLozPiPbSbPhlXXaiUTDlhHQhHFpaqIFRrInko1FHXjTRpjWRuWfA== dependencies: - "@jest/types" "^27.0.2" + "@jest/types" "^27.0.6" camelcase "^6.2.0" chalk "^4.0.0" - jest-get-type "^27.0.1" + jest-get-type "^27.0.6" leven "^3.1.0" - pretty-format "^27.0.2" + pretty-format "^27.0.6" -jest-watcher@^27.0.2: - version "27.0.2" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-27.0.2.tgz#dab5f9443e2d7f52597186480731a8c6335c5deb" - integrity sha512-8nuf0PGuTxWj/Ytfw5fyvNn/R80iXY8QhIT0ofyImUvdnoaBdT6kob0GmhXR+wO+ALYVnh8bQxN4Tjfez0JgkA== +jest-watcher@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-27.0.6.tgz#89526f7f9edf1eac4e4be989bcb6dec6b8878d9c" + integrity sha512-/jIoKBhAP00/iMGnTwUBLgvxkn7vsOweDrOTSPzc7X9uOyUtJIDthQBTI1EXz90bdkrxorUZVhJwiB69gcHtYQ== dependencies: - "@jest/test-result" "^27.0.2" - "@jest/types" "^27.0.2" + "@jest/test-result" "^27.0.6" + "@jest/types" "^27.0.6" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" - jest-util "^27.0.2" + jest-util "^27.0.6" string-length "^4.0.1" -jest-worker@^26.3.0, jest-worker@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" - integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== +jest-worker@27.0.0-next.5: + version "27.0.0-next.5" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.0.0-next.5.tgz#5985ee29b12a4e191f4aae4bb73b97971d86ec28" + integrity sha512-mk0umAQ5lT+CaOJ+Qp01N6kz48sJG2kr2n1rX0koqKf6FIygQV0qLOdN9SCYID4IVeSigDOcPeGLozdMLYfb5g== dependencies: "@types/node" "*" merge-stream "^2.0.0" - supports-color "^7.0.0" + supports-color "^8.0.0" jest-worker@^27.0.2: version "27.0.2" @@ -8321,16 +7545,25 @@ jest-worker@^27.0.2: merge-stream "^2.0.0" supports-color "^8.0.0" -jest@27.0.4: - version "27.0.4" - resolved "https://registry.yarnpkg.com/jest/-/jest-27.0.4.tgz#91d4d564b36bcf93b98dac1ab19f07089e670f53" - integrity sha512-Px1iKFooXgGSkk1H8dJxxBIrM3tsc5SIuI4kfKYK2J+4rvCvPGr/cXktxh0e9zIPQ5g09kOMNfHQEmusBUf/ZA== +jest-worker@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.0.6.tgz#a5fdb1e14ad34eb228cfe162d9f729cdbfa28aed" + integrity sha512-qupxcj/dRuA3xHPMUd40gr2EaAurFbkwzOh7wfPaeE9id7hyjURRQoqNfHifHK3XjJU6YJJUQKILGUnwGPEOCA== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +jest@27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/jest/-/jest-27.0.6.tgz#10517b2a628f0409087fbf473db44777d7a04505" + integrity sha512-EjV8aETrsD0wHl7CKMibKwQNQc3gIRBXlTikBmmHUeVMKaPFxdcUIBfoDqTSXDoGJIivAYGqCWVlzCSaVjPQsA== dependencies: - "@jest/core" "^27.0.4" + "@jest/core" "^27.0.6" import-local "^3.0.2" - jest-cli "^27.0.4" + jest-cli "^27.0.6" -joi@^17.3.0, joi@^17.4.0: +joi@^17.3.0: version "17.4.0" resolved "https://registry.yarnpkg.com/joi/-/joi-17.4.0.tgz#b5c2277c8519e016316e49ababd41a1908d9ef20" integrity sha512-F4WiW2xaV6wc1jxete70Rw4V/VuMd6IN+a5ilZsxG4uYtUXWu2kq9W5P2dz30e7Gmw8RCbY/u/uk+dMPma9tAg== @@ -8341,6 +7574,11 @@ joi@^17.3.0, joi@^17.4.0: "@sideway/formula" "^3.0.0" "@sideway/pinpoint" "^2.0.0" +js-cookie@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-2.2.1.tgz#69e106dc5d5806894562902aa5baec3744e9b2b8" + integrity sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ== + "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -8361,7 +7599,7 @@ js-yaml@^4.0.0: dependencies: argparse "^2.0.1" -jsdom@^16.6.0: +jsdom@^16.5.3, jsdom@^16.6.0: version "16.6.0" resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.6.0.tgz#f79b3786682065492a3da6a60a4695da983805ac" integrity sha512-Ty1vmF4NHJkolaEmdjtxTfSfkdb8Ywarwf63f+F8/mDD1uLSSWDxDuMiZxiPhwunLrn9LOSVItWj4bLYsLN3Dg== @@ -8404,11 +7642,6 @@ jsesc@~0.5.0: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= -json-buffer@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" - integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= - json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" @@ -8446,11 +7679,6 @@ json-stringify-safe@^5.0.1: resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= -json3@^3.3.3: - version "3.3.3" - resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81" - integrity sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA== - json5@2.x, json5@^2.1.2: version "2.2.0" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" @@ -8465,6 +7693,11 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" +jsonc-parser@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.0.0.tgz#abdd785701c7e7eaca8a9ec8cf070ca51a745a22" + integrity sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA== + jsonfile@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" @@ -8519,37 +7752,6 @@ jws@^3.2.2: jwa "^1.4.1" safe-buffer "^5.0.1" -keyv@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" - integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA== - dependencies: - json-buffer "3.0.0" - -killable@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892" - integrity sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg== - -kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: - version "3.2.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= - dependencies: - is-buffer "^1.1.5" - -kind-of@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" - integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= - dependencies: - is-buffer "^1.1.5" - -kind-of@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" - integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== - kind-of@^6.0.0, kind-of@^6.0.2, kind-of@^6.0.3: version "6.0.3" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" @@ -8567,18 +7769,6 @@ kleur@^3.0.3: resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== -klona@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.4.tgz#7bb1e3affb0cb8624547ef7e8f6708ea2e39dfc0" - integrity sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA== - -latest-version@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-5.1.0.tgz#119dfe908fe38d15dfa43ecd13fa12ec8832face" - integrity sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA== - dependencies: - package-json "^6.3.0" - leven@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" @@ -8600,6 +7790,11 @@ levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" +lilconfig@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.0.3.tgz#68f3005e921dafbd2a2afb48379986aa6d2579fd" + integrity sha512-EHKqr/+ZvdKCifpNrJCKxBTgk5XupZA3y/aCPY9mxfgBzmgh93Mt/WqjjQ38oMxXuvDokaKiM3lAgvSH2sjtHg== + lines-and-columns@^1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" @@ -8671,16 +7866,16 @@ loader-runner@^4.2.0: resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384" integrity sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw== -loader-utils@2.0.0, loader-utils@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.0.tgz#e4cace5b816d425a166b5f097e10cd12b36064b0" - integrity sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ== +loader-utils@1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7" + integrity sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA== dependencies: big.js "^5.2.2" - emojis-list "^3.0.0" - json5 "^2.1.2" + emojis-list "^2.0.0" + json5 "^1.0.1" -loader-utils@^1.1.0, loader-utils@^1.2.3, loader-utils@^1.4.0: +loader-utils@^1.1.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== @@ -8697,14 +7892,6 @@ locate-path@^2.0.0: p-locate "^2.0.0" path-exists "^3.0.0" -locate-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" - integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== - dependencies: - p-locate "^3.0.0" - path-exists "^3.0.0" - locate-path@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" @@ -8719,16 +7906,6 @@ locate-path@^6.0.0: dependencies: p-locate "^5.0.0" -lodash.assignin@^4.0.9: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.assignin/-/lodash.assignin-4.2.0.tgz#ba8df5fb841eb0a3e8044232b0e263a8dc6a28a2" - integrity sha1-uo31+4QesKPoBEIysOJjqNxqKKI= - -lodash.bind@^4.1.4: - version "4.2.1" - resolved "https://registry.yarnpkg.com/lodash.bind/-/lodash.bind-4.2.1.tgz#7ae3017e939622ac31b7d7d7dcb1b34db1690d35" - integrity sha1-euMBfpOWIqwxt9fX3LGzTbFpDTU= - lodash.camelcase@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" @@ -8739,46 +7916,16 @@ lodash.clonedeep@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= -lodash.curry@^4.0.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/lodash.curry/-/lodash.curry-4.1.1.tgz#248e36072ede906501d75966200a86dab8b23170" - integrity sha1-JI42By7ekGUB11lmIAqG2riyMXA= - lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= -lodash.defaults@^4.0.1: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" - integrity sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw= - -lodash.filter@^4.4.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.filter/-/lodash.filter-4.6.0.tgz#668b1d4981603ae1cc5a6fa760143e480b4c4ace" - integrity sha1-ZosdSYFgOuHMWm+nYBQ+SAtMSs4= - lodash.flatmap@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.flatmap/-/lodash.flatmap-4.5.0.tgz#ef8cbf408f6e48268663345305c6acc0b778702e" integrity sha1-74y/QI9uSCaGYzRTBcaswLd4cC4= -lodash.flatten@^4.2.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" - integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8= - -lodash.flow@^3.3.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/lodash.flow/-/lodash.flow-3.5.0.tgz#87bf40292b8cf83e4e8ce1a3ae4209e20071675a" - integrity sha1-h79AKSuM+D5OjOGjrkIJ4gBxZ1o= - -lodash.foreach@^4.3.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.foreach/-/lodash.foreach-4.5.0.tgz#1a6a35eace401280c7f06dddec35165ab27e3e53" - integrity sha1-Gmo16s5AEoDH8G3d7DUWWrJ+PlM= - lodash.get@4.4.2, lodash.get@^4.4.2: version "4.4.2" resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" @@ -8814,50 +7961,30 @@ lodash.isstring@^4.0.1: resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE= -lodash.map@^4.4.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3" - integrity sha1-dx7Hg540c9nEzeKLGTlMNWL09tM= - -lodash.memoize@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" - integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= - -lodash.merge@^4.4.0, lodash.merge@^4.6.2: +lodash.merge@^4.6.2: version "4.6.2" resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== +lodash.mergewith@4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz#617121f89ac55f59047c7aec1ccd6654c6590f55" + integrity sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ== + lodash.once@^4.0.0: version "4.1.1" resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w= -lodash.pick@^4.2.1: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" - integrity sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM= - -lodash.reduce@^4.4.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.reduce/-/lodash.reduce-4.6.0.tgz#f1ab6b839299ad48f784abbf476596f03b914d3b" - integrity sha1-8atrg5KZrUj3hKu/R2WW8DuRTTs= - -lodash.reject@^4.4.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.reject/-/lodash.reject-4.6.0.tgz#80d6492dc1470864bbf583533b651f42a9f52415" - integrity sha1-gNZJLcFHCGS79YNTO2UfQqn1JBU= - lodash.set@^4.3.2: version "4.3.2" resolved "https://registry.yarnpkg.com/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23" integrity sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM= -lodash.some@^4.4.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" - integrity sha1-G7nzFO9ri63tE7VJFpsqlF62jk0= +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= lodash.startcase@^4.4.0: version "4.4.0" @@ -8879,12 +8006,12 @@ lodash.truncate@^4.4.2: resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= -lodash.uniq@4.5.0, lodash.uniq@^4.5.0: +lodash.uniq@4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= -lodash@4.17.21, lodash@4.x, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.7.0: +lodash@4.17.21, lodash@4.x, lodash@^4.17.13, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.7.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -8907,12 +8034,7 @@ log-update@^4.0.0: slice-ansi "^4.0.0" wrap-ansi "^6.2.0" -loglevel@^1.6.8: - version "1.7.1" - resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.1.tgz#005fde2f5e6e47068f935ff28573e125ef72f197" - integrity sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw== - -loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, 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== @@ -8926,16 +8048,6 @@ lower-case@^2.0.2: dependencies: tslib "^2.0.3" -lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" - integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== - -lowercase-keys@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" - integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== - lru-cache@^4.0.1: version "4.1.5" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" @@ -8978,7 +8090,7 @@ make-dir@^2.1.0: pify "^4.0.1" semver "^5.6.0" -make-dir@^3.0.0, make-dir@^3.0.2, make-dir@^3.1.0: +make-dir@^3.0.0, make-dir@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== @@ -8997,11 +8109,6 @@ makeerror@1.0.x: dependencies: tmpl "1.0.x" -map-cache@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" - integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= - map-obj@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" @@ -9012,22 +8119,24 @@ map-obj@^4.0.0: resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-4.2.0.tgz#0e8bc823e2aaca8a0942567d12ed14f389eec153" integrity sha512-NAq0fCmZYGz9UFEQyndp7sisrow4GroyGeKluyKC/chuITZsPyOyC1UJZPJlVFImhXdROIP5xqouRLThT3BbpQ== -map-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" - integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= - dependencies: - object-visit "^1.0.0" - markdown-escapes@^1.0.0: version "1.0.4" resolved "https://registry.yarnpkg.com/markdown-escapes/-/markdown-escapes-1.0.4.tgz#c95415ef451499d7602b91095f3c8e8975f78535" integrity sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg== -marked@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/marked/-/marked-2.0.3.tgz#3551c4958c4da36897bda2a16812ef1399c8d6b0" - integrity sha512-5otztIIcJfPc2qGTN8cVtOJEjNJZ0jwa46INMagrYfk0EvqtRuEHLsEe0LrFS0/q+ZRKT0+kXK7P2T1AN5lWRA== +marked@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/marked/-/marked-2.1.1.tgz#b7c27f520fc4de0ddd049d9b4be3b04e06314923" + integrity sha512-5XFS69o9CzDpQDSpUYC+AN2xvq8yl1EGa5SG/GI1hP78/uTeo3PDfiDNmsUyiahpyhToDDJhQk7fNtJsga+KVw== + +md5.js@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" mdast-squeeze-paragraphs@^4.0.0: version "4.0.0" @@ -9057,21 +8166,16 @@ mdast-util-to-hast@10.0.1: unist-util-position "^3.0.0" unist-util-visit "^2.0.0" -mdast-util-to-string@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz#b8cfe6a713e1091cb5b728fc48885a4767f8b97b" - integrity sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w== +mdast-util-to-string@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz#27055500103f51637bd07d01da01eb1967a43527" + integrity sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A== mdn-data@2.0.14: version "2.0.14" resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== -mdn-data@2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b" - integrity sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA== - mdurl@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" @@ -9087,13 +8191,23 @@ memoize-one@^5.1.1: resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.2.1.tgz#8337aa3c4335581839ec01c3d594090cebe8f00e" integrity sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q== -memory-fs@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" - integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= +meow@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/meow/-/meow-10.0.1.tgz#3252e728f4d8603ecae3a5b6460aaae4aea44ae0" + integrity sha512-65vCCdUI8wS5upK24fDFo25FcViNExdTGAR/vaWN4E6fXsWQ8fGdbkjCWp3nDTuJMlIYuEoAEMiB2/b81DBJjg== dependencies: - errno "^0.1.3" - readable-stream "^2.0.1" + "@types/minimist" "^1.2.1" + camelcase-keys "^6.2.2" + decamelize "^5.0.0" + decamelize-keys "^1.1.0" + hard-rejection "^2.1.0" + minimist-options "4.1.0" + normalize-package-data "^3.0.2" + read-pkg-up "^8.0.0" + redent "^4.0.0" + trim-newlines "^4.0.1" + type-fest "^1.0.2" + yargs-parser "^20.2.7" meow@^6.0.0: version "6.1.1" @@ -9154,30 +8268,6 @@ methods@~1.1.2: resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= -microevent.ts@~0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/microevent.ts/-/microevent.ts-0.1.1.tgz#70b09b83f43df5172d0205a63025bce0f7357fa0" - integrity sha512-jo1OfR4TaEwd5HOrt5+tAZ9mqT4jmpNAusXtyfNzqVm9uiSYFZlKM1wYL4oU7azZW/PxQW53wM0S6OR1JHNa2g== - -micromatch@^3.1.10, micromatch@^3.1.4: - version "3.1.10" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" - integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== - dependencies: - 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" - micromatch@^4.0.2, micromatch@^4.0.4: version "4.0.4" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" @@ -9186,36 +8276,44 @@ micromatch@^4.0.2, micromatch@^4.0.4: braces "^3.0.1" picomatch "^2.2.3" -mime-db@1.46.0, "mime-db@>= 1.43.0 < 2": +miller-rabin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + +mime-db@1.46.0: version "1.46.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.46.0.tgz#6267748a7f799594de3cbc8cde91def349661cee" integrity sha512-svXaP8UQRZ5K7or+ZmfNhg2xX3yKDMUzqadsSqi4NCH/KomcH75MAMYAGVlvXn4+b/xOPhS3I2uHKRUzvjY7BQ== -mime-db@~1.33.0: - version "1.33.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db" - integrity sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ== - -mime-types@2.1.18: - version "2.1.18" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8" - integrity sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ== - dependencies: - mime-db "~1.33.0" +mime-db@1.48.0: + version "1.48.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.48.0.tgz#e35b31045dd7eada3aaad537ed88a33afbef2d1d" + integrity sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ== -mime-types@^2.1.12, mime-types@^2.1.27, mime-types@~2.1.17, mime-types@~2.1.24: +mime-types@^2.1.12, mime-types@~2.1.24: version "2.1.29" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.29.tgz#1d4ab77da64b91f5f72489df29236563754bb1b2" integrity sha512-Y/jMt/S5sR9OaqteJtslsFZKWOIIqMACsJSiHghlCAyhf7jfVYjKBmLiX8OgpWeW+fjJ2b+Az69aPFPkUOY6xQ== dependencies: mime-db "1.46.0" +mime-types@^2.1.27: + version "2.1.31" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.31.tgz#a00d76b74317c61f9c2db2218b8e9f8e9c5c9e6b" + integrity sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg== + dependencies: + mime-db "1.48.0" + mime@1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== -mime@^2.3.1, mime@^2.4.4: +mime@^2.3.1: version "2.5.2" resolved "https://registry.yarnpkg.com/mime/-/mime-2.5.2.tgz#6e3dc6cc2b9510643830e5f19d5cb753da5eeabe" integrity sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg== @@ -9225,38 +8323,21 @@ mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== -mimic-response@^1.0.0, mimic-response@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" - integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== - -min-indent@^1.0.0: +min-indent@^1.0.0, min-indent@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== -mini-create-react-context@^0.4.0: - version "0.4.1" - resolved "https://registry.yarnpkg.com/mini-create-react-context/-/mini-create-react-context-0.4.1.tgz#072171561bfdc922da08a60c2197a497cc2d1d5e" - integrity sha512-YWCYEmd5CQeHGSAKrYvXgmzzkrvssZcuuQDDeqkT+PziKGMgE+0MCCtcKbROzocGBG1meBLl2FotlRwf4gAzbQ== - dependencies: - "@babel/runtime" "^7.12.1" - tiny-warning "^1.0.3" - -mini-css-extract-plugin@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-1.6.0.tgz#b4db2525af2624899ed64a23b0016e0036411893" - integrity sha512-nPFKI7NSy6uONUo9yn2hIfb9vyYvkFu95qki0e21DQ9uaqNKDP15DGpK0KnV6wDroWxPHtExrdEwx/yDQ8nVRw== - dependencies: - loader-utils "^2.0.0" - schema-utils "^3.0.0" - webpack-sources "^1.1.0" - -minimalistic-assert@^1.0.0: +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== +minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= + minimatch@3.0.4, minimatch@^3.0.0, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" @@ -9264,7 +8345,7 @@ minimatch@3.0.4, minimatch@^3.0.0, minimatch@^3.0.4: dependencies: brace-expansion "^1.1.7" -minimist-options@^4.0.2: +minimist-options@4.1.0, minimist-options@^4.0.2: version "4.1.0" resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-4.1.0.tgz#c0655713c53a8a2ebd77ffa247d342c40f010619" integrity sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A== @@ -9278,31 +8359,16 @@ minimist@^1.1.1, minimist@^1.2.0, minimist@^1.2.5: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== -mixin-deep@^1.2.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" - integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== - dependencies: - for-in "^1.0.2" - is-extendable "^1.0.1" - mixme@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/mixme/-/mixme-0.4.0.tgz#a1aee27f0d63cc905e1cc6ddc98abf94d414435e" integrity sha512-B4Sm1CDC5+ov5AYxSkyeT5HLtiDgNOLKwFlq34wr8E2O3zRdTvQiLzo599Jt9cir6VJrSenOlgvdooVYCQJIYw== -mkdirp@1.0.4, mkdirp@1.x, mkdirp@^1.0.4: +mkdirp@1.0.4, mkdirp@1.x: version "1.0.4" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== -mkdirp@^0.5.1, mkdirp@^0.5.5, mkdirp@~0.5.1: - version "0.5.5" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" - integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== - dependencies: - minimist "^1.2.5" - mock-http@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/mock-http/-/mock-http-1.1.0.tgz#b89380a718a103fc5801095804bedd0b20f7638c" @@ -9317,15 +8383,10 @@ mock-socket@9.0.3: dependencies: url-parse "^1.4.4" -modern-normalize@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/modern-normalize/-/modern-normalize-1.0.0.tgz#539d84a1e141338b01b346f3e27396d0ed17601e" - integrity sha512-1lM+BMLGuDfsdwf3rsgBSrxJwAZHFIrQ8YR61xIqdHo0uNKI9M52wNpHSrliZATJp51On6JD0AfRxd4YGSU0lw== - -module-alias@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/module-alias/-/module-alias-2.2.2.tgz#151cdcecc24e25739ff0aa6e51e1c5716974c0e0" - integrity sha512-A/78XjoX2EmNvppVWEhM2oGk3x4lLxnkEA4jTbaK97QKSDjkIoOsKQlfylt/d3kKKi596Qy3NP5XrXJ6fZIC9Q== +modern-normalize@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/modern-normalize/-/modern-normalize-1.1.0.tgz#da8e80140d9221426bd4f725c6e11283d34f90b7" + integrity sha512-2lMlY1Yc1+CUy0gw4H95uNN7vjbpoED7NNRSBHE25nWfLBdmMzFCsPshlzbxHz+gYMcBEUN8V4pU16prcdPSgA== moment@^2.15.2: version "2.29.1" @@ -9347,45 +8408,31 @@ ms@2.1.2, ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -multicast-dns-service-types@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901" - integrity sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE= - -multicast-dns@^6.0.1: - version "6.2.3" - resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-6.2.3.tgz#a0ec7bd9055c4282f790c3c82f4e28db3b31b229" - integrity sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g== +nano-css@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/nano-css/-/nano-css-5.3.1.tgz#b709383e07ad3be61f64edffacb9d98250b87a1f" + integrity sha512-ENPIyNzANQRyYVvb62ajDd7PAyIgS2LIUnT9ewih4yrXSZX4hKoUwssy8WjUH++kEOA5wUTMgNnV7ko5n34kUA== dependencies: - dns-packet "^1.3.1" - thunky "^1.0.2" - -nan@^2.12.1: - version "2.14.2" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19" - integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ== - -nanoid@^3.1.23: + css-tree "^1.1.2" + csstype "^3.0.6" + fastest-stable-stringify "^2.0.2" + inline-style-prefixer "^6.0.0" + rtl-css-js "^1.14.0" + sourcemap-codec "^1.4.8" + stacktrace-js "^2.0.2" + stylis "^4.0.6" + +nanoid@^3.1.22, nanoid@^3.1.23: version "3.1.23" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.23.tgz#f744086ce7c2bc47ee0a8472574d5c78e4183a81" integrity sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw== -nanomatch@^1.2.9: - version "1.2.13" - resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" - integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - define-property "^2.0.2" - extend-shallow "^3.0.2" - fragment-cache "^0.2.1" - is-windows "^1.0.2" - kind-of "^6.0.2" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" +native-url@0.3.4: + version "0.3.4" + resolved "https://registry.yarnpkg.com/native-url/-/native-url-0.3.4.tgz#29c943172aed86c63cee62c8c04db7f5756661f8" + integrity sha512-6iM8R99ze45ivyH8vybJ7X0yekIcPf5GgLV5K0ENCbmRcaRIDoj37BC8iLEmaaBfqqb8enuZ5p0uhY+lVAbAcA== + dependencies: + querystring "^0.2.0" natural-compare@^1.4.0: version "1.4.0" @@ -9402,6 +8449,102 @@ neo-async@^2.6.0, neo-async@^2.6.2: resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== +next-i18next@^8.5.1: + version "8.5.3" + resolved "https://registry.yarnpkg.com/next-i18next/-/next-i18next-8.5.3.tgz#219cfb0567afbe505b47a0fc084fba5247fb985a" + integrity sha512-XV+dL7iW/aOpDMIcWIB2HhfSC9cpaM9yXggE9zJFh+7r2UxJVfC23pw3u5MHFgwkcw5daC4SDBvZoVRrXSFdYQ== + dependencies: + "@babel/runtime" "^7.13.17" + "@types/hoist-non-react-statics" "^3.3.1" + "@types/i18next-fs-backend" "^1.0.0" + core-js "^3" + hoist-non-react-statics "^3.2.0" + i18next "^20.1.0" + i18next-fs-backend "^1.0.7" + react-i18next "^11.8.13" + +next-mdx-remote@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/next-mdx-remote/-/next-mdx-remote-3.0.2.tgz#7e1159b4eb8a6bdd4000c0b6e6631f94d8683f04" + integrity sha512-imLrrw6c/Hi1BKRyJE9yLhk45N5zzw+/CxSQRHOAByYUSOhd+DNjUaqm2jtd+/GgxJeYB1d3fJPXmvUZTez1MQ== + dependencies: + "@mdx-js/mdx" "^1.6.22" + "@mdx-js/react" "^1.6.22" + esbuild "^0.11.12" + pkg-dir "^5.0.0" + +next-remote-watch@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/next-remote-watch/-/next-remote-watch-1.0.0.tgz#34c5a015b1bd191f906479c00baabd1a33cf04f5" + integrity sha512-kV+pglCwcnKyqJIXPHUUrnZr9d3rCqCIEQWBkFYC02GDXHyKVmcFytoY6q0+wMIQqh/izIAQL1x6OKXZhksjLA== + dependencies: + body-parser "^1.19.0" + chalk "^4.0.0" + chokidar "^3.4.0" + commander "^5.0.0" + express "^4.17.1" + +next-seo@^4.26.0: + version "4.26.0" + resolved "https://registry.yarnpkg.com/next-seo/-/next-seo-4.26.0.tgz#4218cfae5651fdc2e330dcdf1cc1b34ce199d41c" + integrity sha512-5TqywQ3XAwqdmEU1AyNZjR7WdDKFTkDD8aBtgQelPvzBUEy8i0mTjtiw+09jhiHFNik6FqS8uPKCaYcY6jRgSQ== + +next@^11.0.1: + version "11.0.1" + resolved "https://registry.yarnpkg.com/next/-/next-11.0.1.tgz#b8e3914d153aaf7143cb98c09bcd3c8230eeb17a" + integrity sha512-yR7be7asNbvpVNpi6xxEg28wZ7Gqmj1nOt0sABH9qORmF3+pms2KZ7Cng33oK5nqPIzEEFJD0pp2PCe3/ueMIg== + dependencies: + "@babel/runtime" "7.12.5" + "@hapi/accept" "5.0.2" + "@next/env" "11.0.1" + "@next/polyfill-module" "11.0.1" + "@next/react-dev-overlay" "11.0.1" + "@next/react-refresh-utils" "11.0.1" + assert "2.0.0" + ast-types "0.13.2" + browserify-zlib "0.2.0" + browserslist "4.16.6" + buffer "5.6.0" + caniuse-lite "^1.0.30001228" + chalk "2.4.2" + chokidar "3.5.1" + constants-browserify "1.0.0" + crypto-browserify "3.12.0" + cssnano-simple "2.0.0" + domain-browser "4.19.0" + encoding "0.1.13" + etag "1.8.1" + find-cache-dir "3.3.1" + get-orientation "1.1.2" + https-browserify "1.0.0" + image-size "1.0.0" + jest-worker "27.0.0-next.5" + native-url "0.3.4" + node-fetch "2.6.1" + node-html-parser "1.4.9" + node-libs-browser "^2.2.1" + os-browserify "0.3.0" + p-limit "3.1.0" + path-browserify "1.0.1" + pnp-webpack-plugin "1.6.4" + postcss "8.2.13" + process "0.11.10" + prop-types "15.7.2" + querystring-es3 "0.2.1" + raw-body "2.4.1" + react-is "17.0.2" + react-refresh "0.8.3" + stream-browserify "3.0.0" + stream-http "3.1.1" + string_decoder "1.3.0" + styled-jsx "3.3.2" + timers-browserify "2.0.12" + tty-browserify "0.0.1" + use-subscription "1.5.1" + util "0.12.3" + vm-browserify "1.1.2" + watchpack "2.1.1" + nice-try@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" @@ -9415,10 +8558,10 @@ no-case@^3.0.4: lower-case "^2.0.2" tslib "^2.0.3" -nock@13.1.0: - version "13.1.0" - resolved "https://registry.yarnpkg.com/nock/-/nock-13.1.0.tgz#41c8ce8b35ab7d618c4cbf40de1d5bce319979ba" - integrity sha512-3N3DUY8XYrxxzWazQ+nSBpiaJ3q6gcpNh4gXovC/QBxrsvNp4tq+wsLHF6mJ3nrn3lPLn7KCJqKxy/9aD+0fdw== +nock@13.1.1: + version "13.1.1" + resolved "https://registry.yarnpkg.com/nock/-/nock-13.1.1.tgz#3c830129d4560957f59b6f480a41ddbaf9cf57af" + integrity sha512-YKTR9MjfK3kS9/l4nuTxyYm30cgOExRHzkLNhL8nhEUyU4f8Za/dRxOqjhVT1vGs0svWo3dDnJTUX1qxYeWy5w== dependencies: debug "^4.1.0" json-stringify-safe "^5.0.1" @@ -9437,22 +8580,53 @@ node-fetch@2.6.1, node-fetch@^2.6.1: resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== -node-forge@^0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3" - integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA== +node-html-parser@1.4.9: + version "1.4.9" + resolved "https://registry.yarnpkg.com/node-html-parser/-/node-html-parser-1.4.9.tgz#3c8f6cac46479fae5800725edb532e9ae8fd816c" + integrity sha512-UVcirFD1Bn0O+TSmloHeHqZZCxHjvtIeGdVdGMhyZ8/PWlEiZaZ5iJzR189yKZr8p0FXN58BUeC7RHRkf/KYGw== + dependencies: + he "1.2.0" node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= +node-libs-browser@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" + integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q== + dependencies: + assert "^1.1.1" + browserify-zlib "^0.2.0" + buffer "^4.3.0" + console-browserify "^1.1.0" + constants-browserify "^1.0.0" + crypto-browserify "^3.11.0" + domain-browser "^1.1.1" + events "^3.0.0" + https-browserify "^1.0.0" + os-browserify "^0.3.0" + path-browserify "0.0.1" + process "^0.11.10" + punycode "^1.2.4" + querystring-es3 "^0.2.0" + readable-stream "^2.3.3" + stream-browserify "^2.0.1" + stream-http "^2.7.2" + string_decoder "^1.0.0" + timers-browserify "^2.0.4" + tty-browserify "0.0.0" + url "^0.11.0" + util "^0.11.0" + vm-browserify "^1.0.1" + node-modules-regexp@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= -node-releases@^1.1.61, node-releases@^1.1.71: +node-releases@^1.1.71: version "1.1.71" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.71.tgz#cb1334b179896b1c89ecfdd4b725fb7bbdfc7dbb" integrity sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg== @@ -9467,7 +8641,17 @@ normalize-package-data@^2.3.2, normalize-package-data@^2.5.0: semver "2 || 3 || 4 || 5" validate-npm-package-license "^3.0.1" -normalize-path@^2.1.1: +normalize-package-data@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-3.0.2.tgz#cae5c410ae2434f9a6c1baa65d5bc3b9366c8699" + integrity sha512-6CdZocmfGaKnIHPVFhJJZ3GuR8SsLKvDANFp47Jmy51aKIr8akjAWTSxtpI+MBgBFdSMRyo4hMpDlT6dTffgZg== + dependencies: + hosted-git-info "^4.0.1" + resolve "^1.20.0" + semver "^7.3.4" + validate-npm-package-license "^3.0.1" + +normalize-path@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= @@ -9484,11 +8668,6 @@ normalize-range@^0.1.2: resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI= -normalize-url@^4.1.0, normalize-url@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129" - integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ== - npm-run-path@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" @@ -9503,25 +8682,18 @@ npm-run-path@^4.0.1: dependencies: path-key "^3.0.0" +npms.io@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/npms.io/-/npms.io-2.0.6.tgz#bad3e61f5ce68a2e3bafed834e69dd1a225fffd4" + integrity sha512-trjF9FDKWSy6qAbjIhvfNxtepxokgS7DQzog3cgrZmnunhFJ9yaZDRiu36a4GuBjuxbLLQxayjTsYoGIJlpcnQ== + dependencies: + axios "0.21.1" + nprogress@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/nprogress/-/nprogress-0.2.0.tgz#cb8f34c53213d895723fcbab907e9422adbcafb1" integrity sha1-y480xTIT2JVyP8urkH6UIq28r7E= -nth-check@^1.0.2, nth-check@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" - integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== - dependencies: - boolbase "~1.0.0" - -nth-check@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.0.tgz#1bb4f6dac70072fc313e8c9cd1417b5074c0a125" - integrity sha512-i4sc/Kj8htBrAiH1viZ0TgU8Y5XqCaV/FziYK6TBczxmeKm3AEFWqqF3195yKudrarqy7Zu80Ra5dobFjn9X/Q== - dependencies: - boolbase "^1.0.0" - nullthrows@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/nullthrows/-/nullthrows-1.1.1.tgz#7818258843856ae971eae4208ad7d7eb19a431b1" @@ -9532,24 +8704,15 @@ nwsapi@^2.2.0: resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== -object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: +object-assign@^4.0.0, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= -object-copy@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" - integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= - dependencies: - copy-descriptor "^0.1.0" - define-property "^0.2.5" - kind-of "^3.0.3" - -object-hash@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.1.1.tgz#9447d0279b4fcf80cff3259bf66a1dc73afabe09" - integrity sha512-VOJmgmS+7wvXf8CjbQmimtCnEx3IAoLxI3fp2fbWehxrWBcAQFbk+vcwb6vzR0VZv/eNCJ/27j151ZTwqW/JeQ== +object-hash@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.2.0.tgz#5ad518581eefc443bd763472b8ff2e9c2c0d54a5" + integrity sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw== object-inspect@^1.9.0: version "1.9.0" @@ -9574,13 +8737,6 @@ object-path@^0.11.5: resolved "https://registry.yarnpkg.com/object-path/-/object-path-0.11.5.tgz#d4e3cf19601a5140a55a16ad712019a9c50b577a" integrity sha512-jgSbThcoR/s+XumvGMTMf81QVBmah+/Q7K7YduKeKVWL7N111unR2d6pZZarSk6kY/caeNxUDyxOvMWyzoU2eg== -object-visit@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" - integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= - dependencies: - isobject "^3.0.0" - object.assign@^4.1.0, object.assign@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" @@ -9591,23 +8747,7 @@ object.assign@^4.1.0, object.assign@^4.1.2: has-symbols "^1.0.1" object-keys "^1.1.1" -object.getownpropertydescriptors@^2.1.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz#1bd63aeacf0d5d2d2f31b5e393b03a7c601a23f7" - integrity sha512-WtxeKSzfBjlzL+F9b7M7hewDzMwy+C8NRssHd1YrNlzHzIDrXcXiNOMrezdAEM4UXixgV+vvnyBeN7Rygl2ttQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.18.0-next.2" - -object.pick@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" - integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= - dependencies: - isobject "^3.0.1" - -object.values@^1.1.0, object.values@^1.1.3: +object.values@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.3.tgz#eaa8b1e17589f02f698db093f7c62ee1699742ee" integrity sha512-nkF6PfDB9alkOUxpf1HNm/QlkeW3SReqL5WXeBLpEJJnlPSvRaDQpW3gQTksTN3fgJX4hL42RzKyOin6ff3tyw== @@ -9617,11 +8757,6 @@ object.values@^1.1.0, object.values@^1.1.3: es-abstract "^1.18.0-next.2" has "^1.0.3" -obuf@^1.0.0, obuf@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" - integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== - on-finished@~2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" @@ -9629,12 +8764,7 @@ on-finished@~2.3.0: dependencies: ee-first "1.1.1" -on-headers@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" - integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== - -once@^1.3.0, once@^1.3.1, once@^1.4.0: +once@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= @@ -9655,7 +8785,18 @@ onigasm@^2.2.5: dependencies: lru-cache "^5.1.1" -open@^7.0.2, open@^7.4.2: +open-cli@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/open-cli/-/open-cli-7.0.0.tgz#e2f4e4d005bb2b571c7d529970a2c723d5f1779f" + integrity sha512-VxL1HWSsufFSxdcOq5Ijkd1sjK7XnmCI1QF1bYk4va3JI2nl+wLTTgOZ4i1OyNljb9rLoqajtFNCl91DmiIkQw== + dependencies: + file-type "^16.5.0" + get-stdin "^9.0.0" + meow "^10.0.1" + open "^8.2.0" + tempy "^1.0.1" + +open@^7.4.2: version "7.4.2" resolved "https://registry.yarnpkg.com/open/-/open-7.4.2.tgz#b8147e26dcf3e426316c730089fd71edd29c2321" integrity sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q== @@ -9663,18 +8804,20 @@ open@^7.0.2, open@^7.4.2: is-docker "^2.0.0" is-wsl "^2.1.1" +open@^8.2.0: + version "8.2.1" + resolved "https://registry.yarnpkg.com/open/-/open-8.2.1.tgz#82de42da0ccbf429bc12d099dad2e0975e14e8af" + integrity sha512-rXILpcQlkF/QuFez2BJDf3GsqpjGKbkUUToAIGo9A0Q6ZkoSGogZJulrUdwRkrAsoQvoZsrjCYt8+zblOk7JQQ== + dependencies: + define-lazy-prop "^2.0.0" + is-docker "^2.1.1" + is-wsl "^2.2.0" + opener@^1.5.2: version "1.5.2" resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598" integrity sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A== -opn@^5.5.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/opn/-/opn-5.5.0.tgz#fc7164fab56d235904c51c3b27da6758ca3b9bfc" - integrity sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA== - dependencies: - is-wsl "^1.1.0" - optimism@^0.16.0: version "0.16.1" resolved "https://registry.yarnpkg.com/optimism/-/optimism-0.16.1.tgz#7c8efc1f3179f18307b887e18c15c5b7133f6e7d" @@ -9707,12 +8850,10 @@ optionator@^0.9.1: type-check "^0.4.0" word-wrap "^1.2.3" -original@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/original/-/original-1.0.2.tgz#e442a61cffe1c5fd20a65f3261c26663b303f25f" - integrity sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg== - dependencies: - url-parse "^1.4.3" +os-browserify@0.3.0, os-browserify@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" + integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= os-tmpdir@~1.0.2: version "1.0.2" @@ -9724,11 +8865,6 @@ outdent@^0.5.0: resolved "https://registry.yarnpkg.com/outdent/-/outdent-0.5.0.tgz#9e10982fdc41492bb473ad13840d22f9655be2ff" integrity sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q== -p-cancelable@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" - integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== - p-each-series@^2.1.0: version "2.2.0" resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-2.2.0.tgz#105ab0357ce72b202a8a8b94933672657b5e2a9a" @@ -9746,7 +8882,7 @@ p-finally@^1.0.0: resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= -p-limit@2.2.2, p-limit@^2.0.0, p-limit@^2.2.0: +p-limit@2.2.2, p-limit@^2.2.0: version "2.2.2" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.2.tgz#61279b67721f5287aa1c13a9a7fbbc48c9291b1e" integrity sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ== @@ -9774,13 +8910,6 @@ p-locate@^2.0.0: dependencies: p-limit "^1.1.0" -p-locate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" - integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== - dependencies: - p-limit "^2.0.0" - p-locate@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" @@ -9807,13 +8936,6 @@ p-map@^4.0.0: dependencies: aggregate-error "^3.0.0" -p-retry@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-3.0.1.tgz#316b4c8893e2c8dc1cfa891f406c4b422bebf328" - integrity sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w== - dependencies: - retry "^0.12.0" - p-try@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" @@ -9824,17 +8946,12 @@ p-try@^2.0.0: resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== -package-json@^6.3.0: - version "6.5.0" - resolved "https://registry.yarnpkg.com/package-json/-/package-json-6.5.0.tgz#6feedaca35e75725876d0b0e64974697fed145b0" - integrity sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ== - dependencies: - got "^9.6.0" - registry-auth-token "^4.0.0" - registry-url "^5.0.0" - semver "^6.2.0" +pako@~1.0.5: + version "1.0.11" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" + integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== -param-case@3.0.4, param-case@^3.0.3: +param-case@3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5" integrity sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A== @@ -9849,6 +8966,17 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" +parse-asn1@^5.0.0, parse-asn1@^5.1.5: + version "5.1.6" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.6.tgz#385080a3ec13cb62a62d39409cb3e88844cdaed4" + integrity sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw== + dependencies: + asn1.js "^5.2.0" + browserify-aes "^1.0.0" + evp_bytestokey "^1.0.0" + pbkdf2 "^3.0.3" + safe-buffer "^5.1.1" + parse-entities@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-2.0.0.tgz#53c6eb5b9314a1f4ec99fa0fdf7ce01ecda0cbe8" @@ -9861,16 +8989,6 @@ parse-entities@^2.0.0: is-decimal "^1.0.0" is-hexadecimal "^1.0.0" -parse-glob@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" - integrity sha1-ssN2z7EfNVE7rdFz7wu246OIORw= - dependencies: - glob-base "^0.3.0" - is-dotfile "^1.0.0" - is-extglob "^1.0.0" - is-glob "^2.0.0" - parse-json@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" @@ -9879,7 +8997,7 @@ parse-json@^4.0.0: error-ex "^1.3.1" json-parse-better-errors "^1.0.1" -parse-json@^5.0.0: +parse-json@^5.0.0, parse-json@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== @@ -9894,7 +9012,14 @@ parse-numeric-range@^1.2.0: resolved "https://registry.yarnpkg.com/parse-numeric-range/-/parse-numeric-range-1.2.0.tgz#aa70b00f29624ed13e9f943e9461b306e386b0fa" integrity sha512-1q2tXpAOplPxcl8vrIGPWz1dJxxfmdRkCFcpxxMBerDnGuuHalOWF/xj9L8Nn5XoTUoB/6F0CeQBp2fMgkOYFg== -parse5@6.0.1, parse5@^6.0.0: +parse5-htmlparser2-tree-adapter@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz#2cdf9ad823321140370d4dbf5d3e92c7c8ddc6e6" + integrity sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA== + dependencies: + parse5 "^6.0.1" + +parse5@6.0.1, parse5@^6.0.0, parse5@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== @@ -9904,24 +9029,11 @@ parse5@^5.0.0: resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178" integrity sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug== -parseurl@~1.3.2, parseurl@~1.3.3: +parseurl@~1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== -pascal-case@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.2.tgz#b48e0ef2b98e205e7c1dae747d0b1508237660eb" - integrity sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g== - dependencies: - no-case "^3.0.4" - tslib "^2.0.3" - -pascalcase@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" - integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= - patch-package@6.4.7: version "6.4.7" resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-6.4.7.tgz#2282d53c397909a0d9ef92dae3fdeb558382b148" @@ -9941,10 +9053,15 @@ patch-package@6.4.7: slash "^2.0.0" tmp "^0.0.33" -path-dirname@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" - integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= +path-browserify@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" + integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ== + +path-browserify@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" + integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== path-exists@^3.0.0: version "3.0.0" @@ -9961,11 +9078,6 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= -path-is-inside@1.0.2, path-is-inside@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" - integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= - path-key@^2.0.0, path-key@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" @@ -9986,18 +9098,6 @@ path-to-regexp@0.1.7: resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= -path-to-regexp@2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-2.2.1.tgz#90b617025a16381a879bc82a38d4e8bdeb2bcf45" - integrity sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ== - -path-to-regexp@^1.7.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a" - integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA== - dependencies: - isarray "0.0.1" - path-type@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" @@ -10010,16 +9110,27 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== +pbkdf2@^3.0.3: + version "3.1.2" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" + integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +peek-readable@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-3.1.3.tgz#932480d46cf6aa553c46c68566c4fb69a82cd2b1" + integrity sha512-mpAcysyRJxmICBcBa5IXH7SZPvWkcghm6Fk8RekoS3v+BpbSzlZzuWbMx+GXrlUwESi9qHar4nVEZNMKylIHvg== + picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2, picomatch@^2.2.3: version "2.2.3" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.3.tgz#465547f359ccc206d3c48e46a1bcb89bf7ee619d" integrity sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg== -pify@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= - pify@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" @@ -10030,18 +9141,6 @@ pify@^4.0.1: resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== -pinkie-promise@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= - dependencies: - pinkie "^2.0.0" - -pinkie@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= - pirates@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87" @@ -10056,13 +9155,6 @@ pkg-dir@^2.0.0: dependencies: find-up "^2.1.0" -pkg-dir@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" - integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== - dependencies: - find-up "^3.0.0" - pkg-dir@^4.1.0, pkg-dir@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" @@ -10070,12 +9162,12 @@ pkg-dir@^4.1.0, pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" -pkg-up@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5" - integrity sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA== +pkg-dir@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-5.0.0.tgz#a02d6aebe6ba133a928f74aec20bafdfe6b8e760" + integrity sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA== dependencies: - find-up "^3.0.0" + find-up "^5.0.0" pkg-up@^2.0.0: version "2.0.0" @@ -10084,6 +9176,11 @@ pkg-up@^2.0.0: dependencies: find-up "^2.1.0" +platform@1.3.6: + version "1.3.6" + resolved "https://registry.yarnpkg.com/platform/-/platform-1.3.6.tgz#48b4ce983164b209c2d45a107adb31f473a6e7a7" + integrity sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg== + please-upgrade-node@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz#aeddd3f994c933e4ad98b99d9a556efa0e2fe942" @@ -10091,6 +9188,13 @@ please-upgrade-node@^3.2.0: dependencies: semver-compare "^1.0.0" +pnp-webpack-plugin@1.6.4: + version "1.6.4" + resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz#c9711ac4dc48a685dabafc86f8b6dd9f8df84149" + integrity sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg== + dependencies: + ts-pnp "^1.1.6" + polished@^4.1.3: version "4.1.3" resolved "https://registry.yarnpkg.com/polished/-/polished-4.1.3.tgz#7a3abf2972364e7d97770b827eec9a9e64002cfc" @@ -10098,80 +9202,15 @@ polished@^4.1.3: dependencies: "@babel/runtime" "^7.14.0" -portfinder@^1.0.26: - version "1.0.28" - resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.28.tgz#67c4622852bd5374dd1dd900f779f53462fac778" - integrity sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA== - dependencies: - async "^2.6.2" - debug "^3.1.1" - mkdirp "^0.5.5" - -posix-character-classes@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" - integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= - -postcss-calc@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-8.0.0.tgz#a05b87aacd132740a5db09462a3612453e5df90a" - integrity sha512-5NglwDrcbiy8XXfPM11F3HeC6hoT9W7GUH/Zi5U/p7u3Irv4rHhdDcIZwG0llHXV4ftsBjpfWMXAnXNl4lnt8g== +popmotion@9.3.6: + version "9.3.6" + resolved "https://registry.yarnpkg.com/popmotion/-/popmotion-9.3.6.tgz#b5236fa28f242aff3871b9e23721f093133248d1" + integrity sha512-ZTbXiu6zIggXzIliMi8LGxXBF5ST+wkpXGEjeTUDUOCdSQ356hij/xjeUdv0F8zCQNeqB1+PR5/BB+gC+QLAPw== dependencies: - postcss-selector-parser "^6.0.2" - postcss-value-parser "^4.0.2" - -postcss-colormin@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-5.1.1.tgz#834d262f6021f832d9085e355f08ade288a92a1d" - integrity sha512-SyTmqKKN6PyYNeeKEC0hqIP5CDuprO1hHurdW1aezDyfofDUOn7y7MaxcolbsW3oazPwFiGiY30XRiW1V4iZpA== - dependencies: - browserslist "^4.16.0" - colord "^2.0.0" - postcss-value-parser "^4.1.0" - -postcss-convert-values@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-5.0.1.tgz#4ec19d6016534e30e3102fdf414e753398645232" - integrity sha512-C3zR1Do2BkKkCgC0g3sF8TS0koF2G+mN8xxayZx3f10cIRmTaAnpgpRQZjNekTZxM2ciSPoh2IWJm0VZx8NoQg== - dependencies: - postcss-value-parser "^4.1.0" - -postcss-discard-comments@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-5.0.1.tgz#9eae4b747cf760d31f2447c27f0619d5718901fe" - integrity sha512-lgZBPTDvWrbAYY1v5GYEv8fEO/WhKOu/hmZqmCYfrpD6eyDWWzAOsl2rF29lpvziKO02Gc5GJQtlpkTmakwOWg== - -postcss-discard-duplicates@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-5.0.1.tgz#68f7cc6458fe6bab2e46c9f55ae52869f680e66d" - integrity sha512-svx747PWHKOGpAXXQkCc4k/DsWo+6bc5LsVrAsw+OU+Ibi7klFZCyX54gjYzX4TH+f2uzXjRviLARxkMurA2bA== - -postcss-discard-empty@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-5.0.1.tgz#ee136c39e27d5d2ed4da0ee5ed02bc8a9f8bf6d8" - integrity sha512-vfU8CxAQ6YpMxV2SvMcMIyF2LX1ZzWpy0lqHDsOdaKKLQVQGVP1pzhrI9JlsO65s66uQTfkQBKBD/A5gp9STFw== - -postcss-discard-overridden@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-5.0.1.tgz#454b41f707300b98109a75005ca4ab0ff2743ac6" - integrity sha512-Y28H7y93L2BpJhrdUR2SR2fnSsT+3TVx1NmVQLbcnZWwIUpJ7mfcTC6Za9M2PG6w8j7UQRfzxqn8jU2VwFxo3Q== - -postcss-discard-unused@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-discard-unused/-/postcss-discard-unused-5.0.1.tgz#63e35a74a154912f93d4e75a1e6ff3cc146f934b" - integrity sha512-tD6xR/xyZTwfhKYRw0ylfCY8wbfhrjpKAMnDKRTLMy2fNW5hl0hoV6ap5vo2JdCkuHkP3CHw72beO4Y8pzFdww== - dependencies: - postcss-selector-parser "^6.0.5" - -postcss-functions@^3: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-functions/-/postcss-functions-3.0.0.tgz#0e94d01444700a481de20de4d55fb2640564250e" - integrity sha1-DpTQFERwCkgd4g3k1V+yZAVkJQ4= - dependencies: - glob "^7.1.2" - object-assign "^4.1.1" - postcss "^6.0.9" - postcss-value-parser "^3.3.0" + framesync "5.3.0" + hey-listen "^1.0.8" + style-value-types "4.1.4" + tslib "^2.1.0" postcss-js@^3.0.3: version "3.0.3" @@ -10181,77 +9220,14 @@ postcss-js@^3.0.3: camelcase-css "^2.0.1" postcss "^8.1.6" -postcss-loader@^5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-5.3.0.tgz#1657f869e48d4fdb018a40771c235e499ee26244" - integrity sha512-/+Z1RAmssdiSLgIZwnJHwBMnlABPgF7giYzTN2NOfr9D21IJZ4mQC1R2miwp80zno9M4zMD/umGI8cR+2EL5zw== - dependencies: - cosmiconfig "^7.0.0" - klona "^2.0.4" - semver "^7.3.4" - -postcss-merge-idents@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-merge-idents/-/postcss-merge-idents-5.0.1.tgz#6b5856fc28f2571f28ecce49effb9b0e64be9437" - integrity sha512-xu8ueVU0RszbI2gKkxR6mluupsOSSLvt8q4gA2fcKFkA+x6SlH3cb4cFHpDvcRCNFbUmCR/VUub+Y6zPOjPx+Q== - dependencies: - cssnano-utils "^2.0.1" - postcss-value-parser "^4.1.0" - -postcss-merge-longhand@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-5.0.2.tgz#277ada51d9a7958e8ef8cf263103c9384b322a41" - integrity sha512-BMlg9AXSI5G9TBT0Lo/H3PfUy63P84rVz3BjCFE9e9Y9RXQZD3+h3YO1kgTNsNJy7bBc1YQp8DmSnwLIW5VPcw== - dependencies: - css-color-names "^1.0.1" - postcss-value-parser "^4.1.0" - stylehacks "^5.0.1" - -postcss-merge-rules@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-5.0.1.tgz#4ff61c5089d86845184a0f149e88d687028bef7e" - integrity sha512-UR6R5Ph0c96QB9TMBH3ml8/kvPCThPHepdhRqAbvMRDRHQACPC8iM5NpfIC03+VRMZTGXy4L/BvFzcDFCgb+fA== - dependencies: - browserslist "^4.16.0" - caniuse-api "^3.0.0" - cssnano-utils "^2.0.1" - postcss-selector-parser "^6.0.5" - vendors "^1.0.3" - -postcss-minify-font-values@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-5.0.1.tgz#a90cefbfdaa075bd3dbaa1b33588bb4dc268addf" - integrity sha512-7JS4qIsnqaxk+FXY1E8dHBDmraYFWmuL6cgt0T1SWGRO5bzJf8sUoelwa4P88LEWJZweHevAiDKxHlofuvtIoA== - dependencies: - postcss-value-parser "^4.1.0" - -postcss-minify-gradients@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-5.0.1.tgz#2dc79fd1a1afcb72a9e727bc549ce860f93565d2" - integrity sha512-odOwBFAIn2wIv+XYRpoN2hUV3pPQlgbJ10XeXPq8UY2N+9ZG42xu45lTn/g9zZ+d70NKSQD6EOi6UiCMu3FN7g== - dependencies: - cssnano-utils "^2.0.1" - is-color-stop "^1.1.0" - postcss-value-parser "^4.1.0" - -postcss-minify-params@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-5.0.1.tgz#371153ba164b9d8562842fdcd929c98abd9e5b6c" - integrity sha512-4RUC4k2A/Q9mGco1Z8ODc7h+A0z7L7X2ypO1B6V8057eVK6mZ6xwz6QN64nHuHLbqbclkX1wyzRnIrdZehTEHw== - dependencies: - alphanum-sort "^1.0.2" - browserslist "^4.16.0" - cssnano-utils "^2.0.1" - postcss-value-parser "^4.1.0" - uniqs "^2.0.0" - -postcss-minify-selectors@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-5.1.0.tgz#4385c845d3979ff160291774523ffa54eafd5a54" - integrity sha512-NzGBXDa7aPsAcijXZeagnJBKBPMYLaJJzB8CQh6ncvyl2sIndLVWfbcDi0SBjRWk5VqEjXvf8tYwzoKf4Z07og== +postcss-load-config@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-3.1.0.tgz#d39c47091c4aec37f50272373a6a648ef5e97829" + integrity sha512-ipM8Ds01ZUophjDTQYSVP70slFSYg3T0/zyfII5vzhN6V57YSxMgG5syXuwi5VtS8wSf3iL30v0uBdoIVx4Q0g== dependencies: - alphanum-sort "^1.0.2" - postcss-selector-parser "^6.0.5" + import-cwd "^3.0.0" + lilconfig "^2.0.3" + yaml "^1.10.2" postcss-modules-extract-imports@^3.0.0: version "3.0.0" @@ -10302,105 +9278,7 @@ postcss-nested@5.0.5: dependencies: postcss-selector-parser "^6.0.4" -postcss-normalize-charset@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-5.0.1.tgz#121559d1bebc55ac8d24af37f67bd4da9efd91d0" - integrity sha512-6J40l6LNYnBdPSk+BHZ8SF+HAkS4q2twe5jnocgd+xWpz/mx/5Sa32m3W1AA8uE8XaXN+eg8trIlfu8V9x61eg== - -postcss-normalize-display-values@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-5.0.1.tgz#62650b965981a955dffee83363453db82f6ad1fd" - integrity sha512-uupdvWk88kLDXi5HEyI9IaAJTE3/Djbcrqq8YgjvAVuzgVuqIk3SuJWUisT2gaJbZm1H9g5k2w1xXilM3x8DjQ== - dependencies: - cssnano-utils "^2.0.1" - postcss-value-parser "^4.1.0" - -postcss-normalize-positions@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-5.0.1.tgz#868f6af1795fdfa86fbbe960dceb47e5f9492fe5" - integrity sha512-rvzWAJai5xej9yWqlCb1OWLd9JjW2Ex2BCPzUJrbaXmtKtgfL8dBMOOMTX6TnvQMtjk3ei1Lswcs78qKO1Skrg== - dependencies: - postcss-value-parser "^4.1.0" - -postcss-normalize-repeat-style@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.0.1.tgz#cbc0de1383b57f5bb61ddd6a84653b5e8665b2b5" - integrity sha512-syZ2itq0HTQjj4QtXZOeefomckiV5TaUO6ReIEabCh3wgDs4Mr01pkif0MeVwKyU/LHEkPJnpwFKRxqWA/7O3w== - dependencies: - cssnano-utils "^2.0.1" - postcss-value-parser "^4.1.0" - -postcss-normalize-string@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-5.0.1.tgz#d9eafaa4df78c7a3b973ae346ef0e47c554985b0" - integrity sha512-Ic8GaQ3jPMVl1OEn2U//2pm93AXUcF3wz+OriskdZ1AOuYV25OdgS7w9Xu2LO5cGyhHCgn8dMXh9bO7vi3i9pA== - dependencies: - postcss-value-parser "^4.1.0" - -postcss-normalize-timing-functions@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.0.1.tgz#8ee41103b9130429c6cbba736932b75c5e2cb08c" - integrity sha512-cPcBdVN5OsWCNEo5hiXfLUnXfTGtSFiBU9SK8k7ii8UD7OLuznzgNRYkLZow11BkQiiqMcgPyh4ZqXEEUrtQ1Q== - dependencies: - cssnano-utils "^2.0.1" - postcss-value-parser "^4.1.0" - -postcss-normalize-unicode@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-5.0.1.tgz#82d672d648a411814aa5bf3ae565379ccd9f5e37" - integrity sha512-kAtYD6V3pK0beqrU90gpCQB7g6AOfP/2KIPCVBKJM2EheVsBQmx/Iof+9zR9NFKLAx4Pr9mDhogB27pmn354nA== - dependencies: - browserslist "^4.16.0" - postcss-value-parser "^4.1.0" - -postcss-normalize-url@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-5.0.1.tgz#ffa9fe545935d8b57becbbb7934dd5e245513183" - integrity sha512-hkbG0j58Z1M830/CJ73VsP7gvlG1yF+4y7Fd1w4tD2c7CaA2Psll+pQ6eQhth9y9EaqZSLzamff/D0MZBMbYSg== - dependencies: - is-absolute-url "^3.0.3" - normalize-url "^4.5.0" - postcss-value-parser "^4.1.0" - -postcss-normalize-whitespace@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.0.1.tgz#b0b40b5bcac83585ff07ead2daf2dcfbeeef8e9a" - integrity sha512-iPklmI5SBnRvwceb/XH568yyzK0qRVuAG+a1HFUsFRf11lEJTiQQa03a4RSCQvLKdcpX7XsI1Gen9LuLoqwiqA== - dependencies: - postcss-value-parser "^4.1.0" - -postcss-ordered-values@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-5.0.1.tgz#79ef6e2bd267ccad3fc0c4f4a586dfd01c131f64" - integrity sha512-6mkCF5BQ25HvEcDfrMHCLLFHlraBSlOXFnQMHYhSpDO/5jSR1k8LdEXOkv+7+uzW6o6tBYea1Km0wQSRkPJkwA== - dependencies: - cssnano-utils "^2.0.1" - postcss-value-parser "^4.1.0" - -postcss-reduce-idents@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-reduce-idents/-/postcss-reduce-idents-5.0.1.tgz#99b49ce8ee6f9c179447671cc9693e198e877bb7" - integrity sha512-6Rw8iIVFbqtaZExgWK1rpVgP7DPFRPh0DDFZxJ/ADNqPiH10sPCoq5tgo6kLiTyfh9sxjKYjXdc8udLEcPOezg== - dependencies: - postcss-value-parser "^4.1.0" - -postcss-reduce-initial@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-5.0.1.tgz#9d6369865b0f6f6f6b165a0ef5dc1a4856c7e946" - integrity sha512-zlCZPKLLTMAqA3ZWH57HlbCjkD55LX9dsRyxlls+wfuRfqCi5mSlZVan0heX5cHr154Dq9AfbH70LyhrSAezJw== - dependencies: - browserslist "^4.16.0" - caniuse-api "^3.0.0" - -postcss-reduce-transforms@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-5.0.1.tgz#93c12f6a159474aa711d5269923e2383cedcf640" - integrity sha512-a//FjoPeFkRuAguPscTVmRQUODP+f3ke2HqFNgGPwdYnpeC29RZdCBvGRGTsKpMURb/I3p6jdKoBQ2zI+9Q7kA== - dependencies: - cssnano-utils "^2.0.1" - postcss-value-parser "^4.1.0" - -postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.5: +postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.6: version "6.0.6" resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz#2c5bba8174ac2f6981ab631a42ab0ee54af332ea" integrity sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg== @@ -10408,55 +9286,26 @@ postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector cssesc "^3.0.0" util-deprecate "^1.0.2" -postcss-sort-media-queries@^3.10.11: - version "3.10.11" - resolved "https://registry.yarnpkg.com/postcss-sort-media-queries/-/postcss-sort-media-queries-3.10.11.tgz#9e06c220c752c69d3ea4a6d55ac7d4960e201c4a" - integrity sha512-78Ak5YSnalr+UTdZa2OCSNAxvEnHg3GRqWccStljJW7MqeU0cJtMA5OzaMmn+upM+iI5vykWzibVEAYaaAlSzw== - dependencies: - sort-css-media-queries "1.5.4" - -postcss-svgo@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-5.0.1.tgz#6ed5e01e164e59204978994d844c653a331a8100" - integrity sha512-cD7DFo6tF9i5eWvwtI4irKOHCpmASFS0xvZ5EQIgEdA1AWfM/XiHHY/iss0gcKHhkqwgYmuo2M0KhJLd5Us6mg== - dependencies: - postcss-value-parser "^4.1.0" - svgo "^2.3.0" - -postcss-unique-selectors@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-5.0.1.tgz#3be5c1d7363352eff838bd62b0b07a0abad43bfc" - integrity sha512-gwi1NhHV4FMmPn+qwBNuot1sG1t2OmacLQ/AX29lzyggnjd+MnVD5uqQmpXO3J17KGL2WAxQruj1qTd3H0gG/w== - dependencies: - alphanum-sort "^1.0.2" - postcss-selector-parser "^6.0.5" - uniqs "^2.0.0" - postcss-value-parser@^3.3.0: version "3.3.1" resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== -postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0: +postcss-value-parser@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb" integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ== -postcss-zindex@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-zindex/-/postcss-zindex-5.0.1.tgz#c585724beb69d356af8c7e68847b28d6298ece03" - integrity sha512-nwgtJJys+XmmSGoYCcgkf/VczP8Mp/0OfSv3v0+fw0uABY4yxw+eFs0Xp9nAZHIKnS5j+e9ywQ+RD+ONyvl5pA== - -postcss@^6.0.9: - version "6.0.23" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.23.tgz#61c82cc328ac60e677645f979054eb98bc0e3324" - integrity sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag== +postcss@8.2.13: + version "8.2.13" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.13.tgz#dbe043e26e3c068e45113b1ed6375d2d37e2129f" + integrity sha512-FCE5xLH+hjbzRdpbRb1IMCvPv9yZx2QnDarBEYSN0N0HYk+TcXsEhwdFcFb+SRWOKzKGErhIEbBK2ogyLdTtfQ== dependencies: - chalk "^2.4.1" + colorette "^1.2.2" + nanoid "^3.1.22" source-map "^0.6.1" - supports-color "^5.4.0" -postcss@^8.1.10, postcss@^8.1.6, postcss@^8.1.8, postcss@^8.2.1, postcss@^8.2.15, postcss@^8.2.4, postcss@^8.2.8, postcss@^8.2.9: +postcss@^8.1.10: version "8.3.0" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.0.tgz#b1a713f6172ca427e3f05ef1303de8b65683325f" integrity sha512-+ogXpdAjWGa+fdYY5BQ96V/6tAo+TdSSIMP5huJBIygdWwKtVoB5JWZ7yUd4xZ8r+8Kvvx4nyg/PQ071H4UtcQ== @@ -10465,6 +9314,15 @@ postcss@^8.1.10, postcss@^8.1.6, postcss@^8.1.8, postcss@^8.2.1, postcss@^8.2.15 nanoid "^3.1.23" source-map-js "^0.6.2" +postcss@^8.1.6, postcss@^8.1.8, postcss@^8.2.1: + version "8.3.5" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.5.tgz#982216b113412bc20a86289e91eb994952a5b709" + integrity sha512-NxTuJocUhYGsMiMFHDUkmjSKT3EdH4/WbGF6GCi1NDGk+vbcUTun4fpbOqaPtD8IIsztA2ilZm2DhYCuyN58gA== + dependencies: + colorette "^1.2.2" + nanoid "^3.1.23" + source-map-js "^0.6.2" + preferred-pm@^3.0.0: version "3.0.3" resolved "https://registry.yarnpkg.com/preferred-pm/-/preferred-pm-3.0.3.tgz#1b6338000371e3edbce52ef2e4f65eb2e73586d6" @@ -10485,29 +9343,16 @@ prelude-ls@~1.1.2: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= -prepend-http@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" - integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= - -prettier@2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.1.tgz#76903c3f8c4449bc9ac597acefa24dc5ad4cbea6" - integrity sha512-p+vNbgpLjif/+D+DwAZAbndtRrR0md0MwfmOVN9N+2RgyACMT+7tfaRnT+WDPkqnuVwleyuBIG2XBxKDme3hPA== +prettier@2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.2.tgz#ef280a05ec253712e486233db5c6f23441e7342d" + integrity sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ== prettier@^1.19.1: version "1.19.1" resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== -pretty-error@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-2.1.2.tgz#be89f82d81b1c86ec8fdfbc385045882727f93b6" - integrity sha512-EY5oDzmsX5wvuynAByrmY0P0hcp+QpnAKbJng2A2MPjVKXCxrDSUkzghVJ4ZGPIv+JC4gX8fPUWscC0RtjsWGw== - dependencies: - lodash "^4.17.20" - renderkid "^2.0.4" - pretty-format@^26.0.0, pretty-format@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.6.2.tgz#e35c2705f14cb7fe2fe94fa078345b444120fc93" @@ -10518,12 +9363,12 @@ pretty-format@^26.0.0, pretty-format@^26.6.2: ansi-styles "^4.0.0" react-is "^17.0.1" -pretty-format@^27.0.2: - version "27.0.2" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.0.2.tgz#9283ff8c4f581b186b2d4da461617143dca478a4" - integrity sha512-mXKbbBPnYTG7Yra9qFBtqj+IXcsvxsvOBco3QHxtxTl+hHKq6QdzMZ+q0CtL4ORHZgwGImRr2XZUX2EWzORxig== +pretty-format@^27.0.6: + version "27.0.6" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.0.6.tgz#ab770c47b2c6f893a21aefc57b75da63ef49a11f" + integrity sha512-8tGD7gBIENgzqA+UBzObyWqQ5B778VIFZA/S66cclyd5YkFLYs2Js7gxDKf0MXtTc9zcS7t1xhdfcElJ3YIvkQ== dependencies: - "@jest/types" "^27.0.2" + "@jest/types" "^27.0.6" ansi-regex "^5.0.0" ansi-styles "^5.0.0" react-is "^17.0.1" @@ -10533,28 +9378,26 @@ pretty-hrtime@^1.0.3: resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" integrity sha1-t+PqQkNaTJsnWdmeDyAesZWALuE= -pretty-time@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/pretty-time/-/pretty-time-1.1.0.tgz#ffb7429afabb8535c346a34e41873adf3d74dd0e" - integrity sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA== - -prism-react-renderer@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/prism-react-renderer/-/prism-react-renderer-1.2.1.tgz#392460acf63540960e5e3caa699d851264e99b89" - integrity sha512-w23ch4f75V1Tnz8DajsYKvY5lF7H1+WvzvLUcF0paFxkTHSp42RS0H5CttdN2Q8RR3DRGZ9v5xD/h3n8C8kGmg== +prism-themes@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/prism-themes/-/prism-themes-1.7.0.tgz#487a5d16152cab515a298af3145345eafb7be372" + integrity sha512-D5EsUQXOY4W9pcGwrOXFJiT22RRUuxWaaxyVNMGHRGr96h86K1XLLWMhzc3tXL0Qri7BhRE8mJtEN/ZZSNau6w== prismjs@^1.23.0: - version "1.23.0" - resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.23.0.tgz#d3b3967f7d72440690497652a9d40ff046067f33" - integrity sha512-c29LVsqOaLbBHuIbsTxaKENh1N2EQBOHaWv7gkHN4dgRbxSREqDnDbtFJYdpPauS4YCplMSNCABQ6Eeor69bAA== - optionalDependencies: - clipboard "^2.0.0" + version "1.24.1" + resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.24.1.tgz#c4d7895c4d6500289482fa8936d9cdd192684036" + integrity sha512-mNPsedLuk90RVJioIky8ANZEwYm5w9LcvCXrxHlwf4fNVSn8jEipMybMkWUyyF0JhnC+C4VcOVSBuHRKs1L5Ow== process-nextick-args@~2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== +process@0.11.10, process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= + progress@^2.0.0, progress@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" @@ -10567,15 +9410,7 @@ promise@^7.1.1: dependencies: asap "~2.0.3" -prompts@2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.0.tgz#4aa5de0723a231d1ee9121c40fdf663df73f61d7" - integrity sha512-awZAKrk3vN6CroQukBL+R9051a4R3zCZBlJm/HBfrSZ8iTpYix3VX1vU4mveiLpiwmOJT4wokTF9m6HUk4KqWQ== - dependencies: - kleur "^3.0.3" - sisteransi "^1.0.5" - -prompts@^2.0.1, prompts@^2.4.1: +prompts@^2.0.1: version "2.4.1" resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.1.tgz#befd3b1195ba052f9fd2fde8a486c4e82ee77f61" integrity sha512-EQyfIuO2hPDsX1L/blblV+H7I0knhgAd82cVneCwcdND9B8AuCDuRcBH6yIcG4dFzlOUqbazQqwGjx5xmsNLuQ== @@ -10583,7 +9418,7 @@ prompts@^2.0.1, prompts@^2.4.1: kleur "^3.0.3" sisteransi "^1.0.5" -prop-types@^15.5.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: +prop-types@15.7.2, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== @@ -10605,18 +9440,13 @@ property-information@^5.0.0, property-information@^5.3.0: xtend "^4.0.0" proxy-addr@~2.0.5: - version "2.0.6" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" - integrity sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw== + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== dependencies: - forwarded "~0.1.2" + forwarded "0.2.0" ipaddr.js "1.9.1" -prr@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" - integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= - pseudomap@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" @@ -10627,61 +9457,63 @@ psl@^1.1.33: resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== -pump@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== +public-encrypt@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" + integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" + bn.js "^4.1.0" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + parse-asn1 "^5.0.0" + randombytes "^2.0.1" + safe-buffer "^5.1.2" -punycode@1.3.2, punycode@^1.3.2: +punycode@1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= +punycode@^1.2.4: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= + punycode@^2.1.0, punycode@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== -pupa@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/pupa/-/pupa-2.1.1.tgz#f5e8fd4afc2c5d97828faa523549ed8744a20d62" - integrity sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A== - dependencies: - escape-goat "^2.0.0" - -pure-color@^1.2.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/pure-color/-/pure-color-1.3.0.tgz#1fe064fb0ac851f0de61320a8bf796836422f33e" - integrity sha1-H+Bk+wrIUfDeYTIKi/eWg2Qi8z4= - -purgecss@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/purgecss/-/purgecss-3.1.3.tgz#26987ec09d12eeadc318e22f6e5a9eb0be094f41" - integrity sha512-hRSLN9mguJ2lzlIQtW4qmPS2kh6oMnA9RxdIYK8sz18QYqd6ePp4GNDl18oWHA1f2v2NEQIh51CO8s/E3YGckQ== +purgecss@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/purgecss/-/purgecss-4.0.3.tgz#8147b429f9c09db719e05d64908ea8b672913742" + integrity sha512-PYOIn5ibRIP34PBU9zohUcCI09c7drPJJtTDAc0Q6QlRz2/CHQ8ywGLdE7ZhxU2VTqB7p5wkvj5Qcm05Rz3Jmw== dependencies: commander "^6.0.0" glob "^7.0.0" postcss "^8.2.1" postcss-selector-parser "^6.0.2" -q@^1.1.2: - version "1.5.1" - resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" - integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= - qs@6.7.0: version "6.7.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== +querystring-es3@0.2.1, querystring-es3@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM= + querystring@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= +querystring@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.1.tgz#40d77615bb09d16902a85c3e38aa8b5ed761c2dd" + integrity sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg== + querystringify@^2.1.1: version "2.2.0" resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" @@ -10692,6 +9524,13 @@ queue-microtask@^1.2.2: resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.2.tgz#abf64491e6ecf0f38a6502403d4cda04f372dfd3" integrity sha512-dB15eXv3p2jDlbOiNLyMabYg1/sXvppd8DP2J3EOCQ0AkuSXCW2tP7mnVouVLJKgUMY6yP0kcQDVpLCN13h4Xg== +queue@6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/queue/-/queue-6.0.2.tgz#b91525283e2315c7553d2efa18d83e76432fed65" + integrity sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA== + dependencies: + inherits "~2.0.3" + quick-lru@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f" @@ -10702,19 +9541,22 @@ quick-lru@^5.1.1: resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== -randombytes@^2.1.0: +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== dependencies: safe-buffer "^5.1.0" -range-parser@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" - integrity sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4= +randomfill@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== + dependencies: + randombytes "^2.0.5" + safe-buffer "^5.1.0" -range-parser@^1.2.1, range-parser@~1.2.1: +range-parser@~1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== @@ -10729,7 +9571,7 @@ raw-body@2.4.0: iconv-lite "0.4.24" unpipe "1.0.0" -raw-body@^2.4.1: +raw-body@2.4.1, raw-body@^2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.1.tgz#30ac82f98bb5ae8c152e67149dac8d55153b168c" integrity sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA== @@ -10739,57 +9581,14 @@ raw-body@^2.4.1: iconv-lite "0.4.24" unpipe "1.0.0" -rc@^1.2.8: - version "1.2.8" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" - integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== - dependencies: - deep-extend "^0.6.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - -react-base16-styling@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/react-base16-styling/-/react-base16-styling-0.6.0.tgz#ef2156d66cf4139695c8a167886cb69ea660792c" - integrity sha1-7yFW1mz0E5aVyKFniGy2nqZgeSw= +react-clientside-effect@^1.2.2: + version "1.2.5" + resolved "https://registry.yarnpkg.com/react-clientside-effect/-/react-clientside-effect-1.2.5.tgz#e2c4dc3c9ee109f642fac4f5b6e9bf5bcd2219a3" + integrity sha512-2bL8qFW1TGBHozGGbVeyvnggRpMjibeZM2536AKNENLECutp2yfs44IL8Hmpn8qjFQ2K7A9PnYf3vc7aQq/cPA== dependencies: - base16 "^1.0.0" - lodash.curry "^4.0.1" - lodash.flow "^3.3.0" - pure-color "^1.2.0" + "@babel/runtime" "^7.12.13" -react-dev-utils@^11.0.1: - version "11.0.4" - resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-11.0.4.tgz#a7ccb60257a1ca2e0efe7a83e38e6700d17aa37a" - integrity sha512-dx0LvIGHcOPtKbeiSUM4jqpBl3TcY7CDjZdfOIcKeznE7BWr9dg0iPG90G5yfVQ+p/rGNMXdbfStvzQZEVEi4A== - dependencies: - "@babel/code-frame" "7.10.4" - address "1.1.2" - browserslist "4.14.2" - chalk "2.4.2" - cross-spawn "7.0.3" - detect-port-alt "1.1.6" - escape-string-regexp "2.0.0" - filesize "6.1.0" - find-up "4.1.0" - fork-ts-checker-webpack-plugin "4.1.6" - global-modules "2.0.0" - globby "11.0.1" - gzip-size "5.1.1" - immer "8.0.1" - is-root "2.1.0" - loader-utils "2.0.0" - open "^7.0.2" - pkg-up "3.1.0" - prompts "2.4.0" - react-error-overlay "^6.0.9" - recursive-readdir "2.2.2" - shell-quote "1.7.2" - strip-ansi "6.0.0" - text-table "0.2.0" - -react-dom@17.0.2: +react-dom@^17.0.2: version "17.0.2" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23" integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA== @@ -10798,49 +9597,69 @@ react-dom@17.0.2: object-assign "^4.1.1" scheduler "^0.20.2" -react-error-overlay@^6.0.9: - version "6.0.9" - resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.9.tgz#3c743010c9359608c375ecd6bc76f35d93995b0a" - integrity sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew== - -react-fast-compare@^3.0.0, react-fast-compare@^3.0.1, react-fast-compare@^3.1.1: +react-fast-compare@3.2.0, react-fast-compare@^3.0.0, react-fast-compare@^3.0.1: version "3.2.0" resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.0.tgz#641a9da81b6a6320f270e89724fb45a0b39e43bb" integrity sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA== -react-helmet@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/react-helmet/-/react-helmet-6.1.0.tgz#a750d5165cb13cf213e44747502652e794468726" - integrity sha512-4uMzEY9nlDlgxr61NL3XbKRy1hEkXmKNXhjbAIOVw5vcFrsdYbH2FEwcNyWvWinl103nXgzYNlns9ca+8kFiWw== +react-focus-lock@2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/react-focus-lock/-/react-focus-lock-2.5.0.tgz#12e3a3940e897c26e2c2a0408cd25ea3c99b3709" + integrity sha512-XLxj6uTXgz0US8TmqNU2jMfnXwZG0mH2r/afQqvPEaX6nyEll5LHVcEXk2XDUQ34RVeLPkO/xK5x6c/qiuSq/A== dependencies: - object-assign "^4.1.1" - prop-types "^15.7.2" - react-fast-compare "^3.1.1" - react-side-effect "^2.1.0" + "@babel/runtime" "^7.0.0" + focus-lock "^0.8.1" + prop-types "^15.6.2" + react-clientside-effect "^1.2.2" + use-callback-ref "^1.2.1" + use-sidecar "^1.0.1" + +react-i18next@^11.8.13: + version "11.11.1" + resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-11.11.1.tgz#758edd7ef521f6703c2d6b83f3165d078f7acf35" + integrity sha512-MtfzPEOvx0ev2cz0HmrEcduuqkktSa5bfeN8Flp0cvN0xP3H3MRSTa8P6pxPtqstHbRe1cD9QBOr5T/FEV2gOw== + dependencies: + "@babel/runtime" "^7.14.5" + html-parse-stringify "^3.0.1" + +react-icons@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-4.2.0.tgz#6dda80c8a8f338ff96a1851424d63083282630d0" + integrity sha512-rmzEDFt+AVXRzD7zDE21gcxyBizD/3NqjbX6cmViAgdqfJ2UiLer8927/QhhrXQV7dEj/1EGuOTPp7JnLYVJKQ== -react-instantsearch-core@^6.11.0: - version "6.11.0" - resolved "https://registry.yarnpkg.com/react-instantsearch-core/-/react-instantsearch-core-6.11.0.tgz#103fd4dd14c0e057fdde88e32bf419497b1fb55e" - integrity sha512-RE5pPuSL5e3+wgMl+QLY+MgyqgNXBrfppqk3podOXTdWpQ5VdaXVrpeWVcmFJlRRKPLJI6RGqCiHVRTaGt1HVw== +react-instantsearch-core@^6.12.0: + version "6.12.0" + resolved "https://registry.yarnpkg.com/react-instantsearch-core/-/react-instantsearch-core-6.12.0.tgz#f4bd044c0b5939d2129b95d3bf298e407a41a2b5" + integrity sha512-k7/sQLai5fhhiQxKFt7e3lA13SJpp843raQ6f8EtJL/bdFZPDHnOS3fPrxV/sduBkIrX7Hv+DrEOY1KkJGu2sA== dependencies: "@babel/runtime" "^7.1.2" - algoliasearch-helper "^3.4.3" + algoliasearch-helper "^3.5.3" prop-types "^15.6.2" react-fast-compare "^3.0.0" react-instantsearch-dom@^6.11.0: - version "6.11.0" - resolved "https://registry.yarnpkg.com/react-instantsearch-dom/-/react-instantsearch-dom-6.11.0.tgz#8e319e7a2fab98051978c9ba3b2eb25747bdd354" - integrity sha512-OXbP3OuT52HAoCbQiPxPAL9q/Lm5pm+eRx8TMKB2kcf6fQzc+L7RMy7fveuMENcmBks+vdD2+G7DGM8oVv9etg== + version "6.12.0" + resolved "https://registry.yarnpkg.com/react-instantsearch-dom/-/react-instantsearch-dom-6.12.0.tgz#fb2a95643cfa896b4199131e70d0de308baaf932" + integrity sha512-/UMnmX0SPkvT8yOL2mAAfjz89ohGSZScb9X6hql9hydcS94cGoojysIUHJ/C+/1f8ciF2zni6I8AYddMdaqrSg== dependencies: "@babel/runtime" "^7.1.2" - algoliasearch-helper "^3.4.3" + algoliasearch-helper "^3.5.3" classnames "^2.2.5" prop-types "^15.6.2" react-fast-compare "^3.0.0" - react-instantsearch-core "^6.11.0" + react-instantsearch-core "^6.12.0" -react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1: +react-intersection-observer@^8.32.0: + version "8.32.0" + resolved "https://registry.yarnpkg.com/react-intersection-observer/-/react-intersection-observer-8.32.0.tgz#47249332e12e8bb99ed35a10bb7dd10446445a7b" + integrity sha512-RlC6FvS3MFShxTn4FHAy904bVjX5Nn4/eTjUkurW0fHK+M/fyQdXuyCy9+L7yjA+YMGogzzSJNc7M4UtfSKvtw== + +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== @@ -10850,35 +9669,6 @@ react-is@^17.0.1: resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.1.tgz#5b3531bd76a645a4c9fb6e693ed36419e3301339" integrity sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA== -react-json-view@^1.21.3: - version "1.21.3" - resolved "https://registry.yarnpkg.com/react-json-view/-/react-json-view-1.21.3.tgz#f184209ee8f1bf374fb0c41b0813cff54549c475" - integrity sha512-13p8IREj9/x/Ye4WI/JpjhoIwuzEgUAtgJZNBJckfzJt1qyh24BdTm6UQNGnyTq9dapQdrqvquZTo3dz1X6Cjw== - dependencies: - flux "^4.0.1" - react-base16-styling "^0.6.0" - react-lifecycles-compat "^3.0.4" - react-textarea-autosize "^8.3.2" - -react-lifecycles-compat@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" - integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== - -react-loadable-ssr-addon-v5-slorber@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/react-loadable-ssr-addon-v5-slorber/-/react-loadable-ssr-addon-v5-slorber-1.0.1.tgz#2cdc91e8a744ffdf9e3556caabeb6e4278689883" - integrity sha512-lq3Lyw1lGku8zUEJPDxsNm1AfYHBrO9Y1+olAYwpUJ2IGFBskM0DMKok97A6LWUpHm+o7IvQBOWu9MLenp9Z+A== - dependencies: - "@babel/runtime" "^7.10.3" - -react-loadable@^5.5.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/react-loadable/-/react-loadable-5.5.0.tgz#582251679d3da86c32aae2c8e689c59f1196d8c4" - integrity sha512-C8Aui0ZpMd4KokxRdVAm2bQtI03k2RMRNzOB+IipV3yxFTSVICv7WoUr5L9ALB5BmKO1iHgZtWM8EvYG83otdg== - dependencies: - prop-types "^15.5.0" - react-paginate@^7.1.3: version "7.1.3" resolved "https://registry.yarnpkg.com/react-paginate/-/react-paginate-7.1.3.tgz#51a2ccb13febc7f96d28405bdf6e029510227206" @@ -10897,57 +9687,65 @@ react-player@^2.9.0: prop-types "^15.7.2" react-fast-compare "^3.0.1" -react-router-config@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/react-router-config/-/react-router-config-5.1.1.tgz#0f4263d1a80c6b2dc7b9c1902c9526478194a988" - integrity sha512-DuanZjaD8mQp1ppHjgnnUnyOlqYXZVjnov/JzFhjLEwd3Z4dYjMSnqrEzzGThH47vpCOqPPwJM2FtthLeJ8Pbg== - dependencies: - "@babel/runtime" "^7.1.2" +react-refresh@0.8.3: + version "0.8.3" + resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.8.3.tgz#721d4657672d400c5e3c75d063c4a85fb2d5d68f" + integrity sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg== -react-router-dom@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.2.0.tgz#9e65a4d0c45e13289e66c7b17c7e175d0ea15662" - integrity sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA== +react-remove-scroll-bar@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/react-remove-scroll-bar/-/react-remove-scroll-bar-2.2.0.tgz#d4d545a7df024f75d67e151499a6ab5ac97c8cdd" + integrity sha512-UU9ZBP1wdMR8qoUs7owiVcpaPwsQxUDC2lypP6mmixaGlARZa7ZIBx1jcuObLdhMOvCsnZcvetOho0wzPa9PYg== dependencies: - "@babel/runtime" "^7.1.2" - history "^4.9.0" - loose-envify "^1.3.1" - prop-types "^15.6.2" - react-router "5.2.0" - tiny-invariant "^1.0.2" - tiny-warning "^1.0.0" + react-style-singleton "^2.1.0" + tslib "^1.0.0" -react-router@5.2.0, react-router@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/react-router/-/react-router-5.2.0.tgz#424e75641ca8747fbf76e5ecca69781aa37ea293" - integrity sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw== +react-remove-scroll@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/react-remove-scroll/-/react-remove-scroll-2.4.1.tgz#e0af6126621083a5064591d367291a81b2d107f5" + integrity sha512-K7XZySEzOHMTq7dDwcHsZA6Y7/1uX5RsWhRXVYv8rdh+y9Qz2nMwl9RX/Mwnj/j7JstCGmxyfyC0zbVGXYh3mA== dependencies: - "@babel/runtime" "^7.1.2" - history "^4.9.0" - hoist-non-react-statics "^3.1.0" - loose-envify "^1.3.1" - mini-create-react-context "^0.4.0" - path-to-regexp "^1.7.0" - prop-types "^15.6.2" - react-is "^16.6.0" - tiny-invariant "^1.0.2" - tiny-warning "^1.0.0" + react-remove-scroll-bar "^2.1.0" + react-style-singleton "^2.1.0" + tslib "^1.0.0" + use-callback-ref "^1.2.3" + use-sidecar "^1.0.1" -react-side-effect@^2.1.0: +react-style-singleton@^2.1.0: version "2.1.1" - resolved "https://registry.yarnpkg.com/react-side-effect/-/react-side-effect-2.1.1.tgz#66c5701c3e7560ab4822a4ee2742dee215d72eb3" - integrity sha512-2FoTQzRNTncBVtnzxFOk2mCpcfxQpenBMbk5kSVBg5UcPqV9fRbgY2zhb7GTWWOlpFmAxhClBDlIq8Rsubz1yQ== + resolved "https://registry.yarnpkg.com/react-style-singleton/-/react-style-singleton-2.1.1.tgz#ce7f90b67618be2b6b94902a30aaea152ce52e66" + integrity sha512-jNRp07Jza6CBqdRKNgGhT3u9umWvils1xsuMOjZlghBDH2MU0PL2WZor4PGYjXpnRCa9DQSlHMs/xnABWOwYbA== + dependencies: + get-nonce "^1.0.0" + invariant "^2.2.4" + tslib "^1.0.0" + +react-universal-interface@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/react-universal-interface/-/react-universal-interface-0.6.2.tgz#5e8d438a01729a4dbbcbeeceb0b86be146fe2b3b" + integrity sha512-dg8yXdcQmvgR13RIlZbTRQOoUrDciFVoSBZILwjE2LFISxZZ8loVJKAkuzswl5js8BHda79bIb2b84ehU8IjXw== -react-textarea-autosize@^8.3.2: - version "8.3.2" - resolved "https://registry.yarnpkg.com/react-textarea-autosize/-/react-textarea-autosize-8.3.2.tgz#4f9374d357b0a6f6469956726722549124a1b2db" - integrity sha512-JrMWVgQSaExQByP3ggI1eA8zF4mF0+ddVuX7acUeK2V7bmrpjVOY72vmLz2IXFJSAXoY3D80nEzrn0GWajWK3Q== +react-use@^17.2.4: + version "17.2.4" + resolved "https://registry.yarnpkg.com/react-use/-/react-use-17.2.4.tgz#1f89be3db0a8237c79253db0a15e12bbe3cfeff1" + integrity sha512-vQGpsAM0F5UIlshw5UI8ULGPS4yn5rm7/qvn3T1Gnkrz7YRMEEMh+ynKcmRloOyiIeLvKWiQjMiwRGtdbgs5qQ== dependencies: - "@babel/runtime" "^7.10.2" - use-composed-ref "^1.0.0" - use-latest "^1.0.0" + "@types/js-cookie" "^2.2.6" + "@xobotyi/scrollbar-width" "^1.9.5" + copy-to-clipboard "^3.3.1" + fast-deep-equal "^3.1.3" + fast-shallow-equal "^1.0.0" + js-cookie "^2.2.1" + nano-css "^5.3.1" + react-universal-interface "^0.6.2" + resize-observer-polyfill "^1.5.1" + screenfull "^5.1.0" + set-harmonic-interval "^1.0.1" + throttle-debounce "^3.0.1" + ts-easing "^0.2.0" + tslib "^2.1.0" -react@17.0.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== @@ -10972,6 +9770,15 @@ read-pkg-up@^7.0.1: read-pkg "^5.2.0" type-fest "^0.8.1" +read-pkg-up@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-8.0.0.tgz#72f595b65e66110f43b052dd9af4de6b10534670" + integrity sha512-snVCqPczksT0HS2EC+SxUndvSzn6LRCwpfSvLrIfR5BKDQQZMaI6jPRC9dYvYFDRAuFEAnkwww8kBBNE/3VvzQ== + dependencies: + find-up "^5.0.0" + read-pkg "^6.0.0" + type-fest "^1.0.1" + read-pkg@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" @@ -10991,6 +9798,16 @@ read-pkg@^5.2.0: parse-json "^5.0.0" type-fest "^0.6.0" +read-pkg@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-6.0.0.tgz#a67a7d6a1c2b0c3cd6aa2ea521f40c458a4a504c" + integrity sha512-X1Fu3dPuk/8ZLsMhEj5f4wFAF0DWoK7qhGJvgaijocXxBmSToKfbFtqbxMO7bVjNA1dmE5huAzjXj/ey86iw9Q== + dependencies: + "@types/normalize-package-data" "^2.4.0" + normalize-package-data "^3.0.2" + parse-json "^5.2.0" + type-fest "^1.0.1" + read-yaml-file@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/read-yaml-file/-/read-yaml-file-1.1.0.tgz#9362bbcbdc77007cc8ea4519fe1c0b821a7ce0d8" @@ -11001,7 +9818,7 @@ read-yaml-file@^1.1.0: pify "^4.0.1" strip-bom "^3.0.0" -readable-stream@^2.0.1, readable-stream@^2.0.2: +readable-stream@^2.0.2, readable-stream@^2.3.3, readable-stream@^2.3.6: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== @@ -11014,7 +9831,7 @@ readable-stream@^2.0.1, readable-stream@^2.0.2: string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-stream@^3.0.6, readable-stream@^3.1.1: +readable-stream@^3.5.0, readable-stream@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== @@ -11023,14 +9840,13 @@ readable-stream@^3.0.6, readable-stream@^3.1.1: string_decoder "^1.1.1" util-deprecate "^1.0.1" -readdirp@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" - integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== +readable-web-to-node-stream@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.1.tgz#3f619b1bc5dd73a4cfe5c5f9b4f6faba55dff845" + integrity sha512-4zDC6CvjUyusN7V0QLsXVB7pJCD9+vtrM9bYDRv6uBQ+SKfx36rp5AFNPRgh9auKRul/a1iFZJYXcCbwRL+SaA== dependencies: - graceful-fs "^4.1.11" - micromatch "^3.1.10" - readable-stream "^2.0.2" + "@types/readable-stream" "^2.3.9" + readable-stream "^3.6.0" readdirp@~3.5.0: version "3.5.0" @@ -11039,24 +9855,12 @@ readdirp@~3.5.0: dependencies: picomatch "^2.2.1" -reading-time@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/reading-time/-/reading-time-1.3.0.tgz#d13e74431589a4a9038669f24d5acbc08bbb015d" - integrity sha512-RJ8J5O6UvrclfZpcPSPuKusrdRfoY7uXXoYOOdeswZNtSkQaewT3919yz6RyloDBR+iwcUyz5zGOUjhgvfuv3g== - -rechoir@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" - integrity sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q= - dependencies: - resolve "^1.1.6" - -recursive-readdir@2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.2.tgz#9946fb3274e1628de6e36b2f6714953b4845094f" - integrity sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg== +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== dependencies: - minimatch "3.0.4" + picomatch "^2.2.1" redent@^3.0.0: version "3.0.0" @@ -11066,6 +9870,14 @@ redent@^3.0.0: indent-string "^4.0.0" strip-indent "^3.0.0" +redent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-4.0.0.tgz#0c0ba7caabb24257ab3bb7a4fd95dd1d5c5681f9" + integrity sha512-tYkDkVVtYkSVhuQ4zBgfvciymHaeuel+zFKXShfDnFP5SyVEP7qo70Rf1jTOTCx3vGNAbnEi/xFkcfQVMIBWag== + dependencies: + indent-string "^5.0.0" + strip-indent "^4.0.0" + reduce-css-calc@^2.1.8: version "2.1.8" resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-2.1.8.tgz#7ef8761a28d614980dc0c982f772c93f7a99de03" @@ -11098,22 +9910,6 @@ regenerator-transform@^0.14.2: dependencies: "@babel/runtime" "^7.8.4" -regex-not@^1.0.0, regex-not@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" - integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== - dependencies: - extend-shallow "^3.0.2" - safe-regex "^1.1.0" - -regexp.prototype.flags@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26" - integrity sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - regexpp@^3.0.0, regexpp@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2" @@ -11131,20 +9927,6 @@ regexpu-core@^4.7.1: unicode-match-property-ecmascript "^1.0.4" unicode-match-property-value-ecmascript "^1.2.0" -registry-auth-token@^4.0.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-4.2.1.tgz#6d7b4006441918972ccd5fedcd41dc322c79b250" - integrity sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw== - dependencies: - rc "^1.2.8" - -registry-url@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-5.1.0.tgz#e98334b50d5434b81136b44ec638d9c2009c5009" - integrity sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw== - dependencies: - rc "^1.2.8" - regjsgen@^0.5.1: version "0.5.2" resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.2.tgz#92ff295fb1deecbf6ecdab2543d207e91aa33733" @@ -11166,11 +9948,6 @@ rehype-parse@^6.0.2: parse5 "^5.0.0" xtend "^4.0.0" -relateurl@^0.2.7: - version "0.2.7" - resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" - integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk= - relay-compiler@11.0.2: version "11.0.2" resolved "https://registry.yarnpkg.com/relay-compiler/-/relay-compiler-11.0.2.tgz#e1e09a1c881d169a7a524ead728ad6a89c7bd4af" @@ -11212,14 +9989,14 @@ remark-admonitions@^1.2.1: unified "^8.4.2" unist-util-visit "^2.0.1" -remark-emoji@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/remark-emoji/-/remark-emoji-2.1.0.tgz#69165d1181b98a54ad5d9ef811003d53d7ebc7db" - integrity sha512-lDddGsxXURV01WS9WAiS9rO/cedO1pvr9tahtLhr6qCGFhHG4yZSJW3Ha4Nw9Uk1hLNmUBtPC0+m45Ms+xEitg== +remark-emoji@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/remark-emoji/-/remark-emoji-2.2.0.tgz#1c702090a1525da5b80e15a8f963ef2c8236cac7" + integrity sha512-P3cj9s5ggsUvWw5fS2uzCHJMGuXYRb0NnZqYlNecewXt8QBU9n5vW3DUUKOhepS8F9CwdMx9B8a3i7pqFWAI5w== dependencies: emoticon "^3.2.0" node-emoji "^1.10.0" - unist-util-visit "^2.0.2" + unist-util-visit "^2.0.3" remark-footnotes@2.0.0: version "2.0.0" @@ -11262,6 +10039,30 @@ remark-parse@8.0.3: vfile-location "^3.0.0" xtend "^4.0.1" +remark-prism@^1.3.6: + version "1.3.6" + resolved "https://registry.yarnpkg.com/remark-prism/-/remark-prism-1.3.6.tgz#f733aaec1b9f37975ea730fca86c014dc9775cda" + integrity sha512-yYSXJ2MEK2DeD9UKDKFkQPcVqRx6aX2FYD1kE27ScogpZ/BBO8MoOO6gf/AKqfXvKGnP51wqvDEBmPseypgaug== + dependencies: + classnames "^2.3.1" + css-selector-parser "^1.4.1" + escape-html "^1.0.3" + jsdom "^16.5.3" + parse-numeric-range "^1.2.0" + parse5 "^6.0.1" + parse5-htmlparser2-tree-adapter "^6.0.1" + prismjs "^1.23.0" + unist-util-map "^2.0.1" + +remark-slug@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/remark-slug/-/remark-slug-6.0.0.tgz#2b54a14a7b50407a5e462ac2f376022cce263e2c" + integrity sha512-ln67v5BrGKHpETnm6z6adlJPhESFJwfuZZ3jrmi+lKTzeZxh2tzFzUfDD4Pm2hRGOarHLuGToO86MNMZ/hA67Q== + dependencies: + github-slugger "^1.0.0" + mdast-util-to-string "^1.0.0" + unist-util-visit "^2.0.0" + remark-squeeze-paragraphs@4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/remark-squeeze-paragraphs/-/remark-squeeze-paragraphs-4.0.0.tgz#76eb0e085295131c84748c8e43810159c5653ead" @@ -11274,23 +10075,7 @@ remove-trailing-separator@^1.0.1: resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= -renderkid@^2.0.4: - version "2.0.5" - resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-2.0.5.tgz#483b1ac59c6601ab30a7a596a5965cabccfdd0a5" - integrity sha512-ccqoLg+HLOHq1vdfYNm4TBeaCDIi1FLt3wGojTDSvdewUv65oTmI3cnT2E4hRjl1gzKZIPK+KZrXzlUYKnR+vQ== - dependencies: - css-select "^2.0.2" - dom-converter "^0.2" - htmlparser2 "^3.10.1" - lodash "^4.17.20" - strip-ansi "^3.0.0" - -repeat-element@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" - integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== - -repeat-string@^1.5.4, repeat-string@^1.6.1: +repeat-string@^1.5.4: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= @@ -11310,11 +10095,6 @@ require-from-string@^2.0.2: resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== -"require-like@>= 0.1.1": - version "0.1.2" - resolved "https://registry.yarnpkg.com/require-like/-/require-like-0.1.2.tgz#ad6f30c13becd797010c468afa775c0c0a6b47fa" - integrity sha1-rW8wwTvs15cBDEaK+ndcDAprR/o= - require-main-filename@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" @@ -11325,12 +10105,10 @@ requires-port@^1.0.0: resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= -resolve-cwd@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" - integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo= - dependencies: - resolve-from "^3.0.0" +resize-observer-polyfill@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464" + integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg== resolve-cwd@^3.0.0: version "3.0.0" @@ -11344,26 +10122,11 @@ resolve-from@5.0.0, resolve-from@^5.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== -resolve-from@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" - integrity sha1-six699nWiBvItuZTM17rywoYh0g= - resolve-from@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== -resolve-pathname@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-3.0.0.tgz#99d02224d3cf263689becbb393bc560313025dcd" - integrity sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng== - -resolve-url@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" - integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= - resolve@1.15.1: version "1.15.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.1.tgz#27bdcdeffeaf2d6244b95bb0f9f4b4653451f3e8" @@ -11371,7 +10134,7 @@ resolve@1.15.1: dependencies: path-parse "^1.0.6" -resolve@^1.1.6, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.20.0, resolve@^1.3.2: +resolve@^1.10.0, resolve@^1.10.1, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.20.0, resolve@^1.3.2: version "1.20.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== @@ -11379,13 +10142,6 @@ resolve@^1.1.6, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.12.0, resolve@^1.13 is-core-module "^2.2.0" path-parse "^1.0.6" -responselike@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" - integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec= - dependencies: - lowercase-keys "^1.0.0" - restore-cursor@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" @@ -11394,31 +10150,11 @@ restore-cursor@^3.1.0: onetime "^5.1.0" signal-exit "^3.0.2" -ret@~0.1.10: - version "0.1.15" - resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" - integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== - -retry@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" - integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= - reusify@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -rgb-regex@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/rgb-regex/-/rgb-regex-1.0.1.tgz#c0e0d6882df0e23be254a475e8edd41915feaeb1" - integrity sha1-wODWiC3w4jviVKR16O3UGRX+rrE= - -rgba-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3" - integrity sha1-QzdOLiyglosO8VI0YLfXMP8i7rM= - rimraf@^2.6.3: version "2.7.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" @@ -11433,6 +10169,14 @@ rimraf@^3.0.0, rimraf@^3.0.2: dependencies: glob "^7.1.3" +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + rollup-plugin-generate-package-json@3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/rollup-plugin-generate-package-json/-/rollup-plugin-generate-package-json-3.2.0.tgz#e9c1d358f2be6c58b49853af58205292d45a33ff" @@ -11459,21 +10203,12 @@ rollup@2.3.2: optionalDependencies: fsevents "~2.1.2" -rtl-detect@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/rtl-detect/-/rtl-detect-1.0.3.tgz#42145b9a4f9cf0b94c4542aba90d57f0d18559bf" - integrity sha512-2sMcZO60tL9YDEFe24gqddg3hJ+xSmJFN8IExcQUxeHxQzydQrN6GHPL+yAWgzItXSI7es53hcZC9pJneuZDKA== - -rtlcss@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/rtlcss/-/rtlcss-3.1.2.tgz#4800d3d03525791a720f676a8ad2c6acf8efdfb2" - integrity sha512-b04YSX37siupPOWUEguEBReWX2w4QT89C0PI9g2JzZycbq7zrgPmTr1DA1pizSWpKRFdCjjnrx/SSvU4fOHmGg== +rtl-css-js@^1.14.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/rtl-css-js/-/rtl-css-js-1.14.1.tgz#f79781d6a0c510abe73fde60aa3cbe9dfd134a45" + integrity sha512-G9N1s/6329FpJr8k9e1U/Lg0IDWThv99sb7k0IrXHjSnubxe01h52/ajsPRafJK1/2Vqrhz3VKLe3E1dx6jS9Q== dependencies: - chalk "^4.1.0" - find-up "^5.0.0" - mkdirp "^1.0.4" - postcss "^8.2.4" - strip-json-comments "^3.1.1" + "@babel/runtime" "^7.1.2" run-parallel@^1.1.9: version "1.2.0" @@ -11489,28 +10224,21 @@ rxjs@^6.6.3, rxjs@^6.6.7: dependencies: tslib "^1.9.0" -safe-buffer@5.1.2, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@~5.1.0, safe-buffer@~5.1.1: +safe-buffer@*, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-buffer@5.1.2, safe-buffer@^5.0.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" - integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= - dependencies: - ret "~0.1.10" - -"safer-buffer@>= 2.1.2 < 3": +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -sax@^1.2.4, sax@~1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" - integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== - saxes@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d" @@ -11526,33 +10254,20 @@ scheduler@^0.20.2: loose-envify "^1.1.0" object-assign "^4.1.1" -schema-utils@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" - integrity sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g== - dependencies: - ajv "^6.1.0" - ajv-errors "^1.0.0" - ajv-keywords "^3.1.0" - -schema-utils@^2.6.5: - version "2.7.1" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7" - integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg== - dependencies: - "@types/json-schema" "^7.0.5" - ajv "^6.12.4" - ajv-keywords "^3.5.2" - schema-utils@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.0.0.tgz#67502f6aa2b66a2d4032b4279a2944978a0913ef" - integrity sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA== + version "3.1.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.0.tgz#95986eb604f66daadeed56e379bfe7a7f963cdb9" + integrity sha512-tTEaeYkyIhEZ9uWgAjDerWov3T9MgX8dhhy2r0IGeeX4W8ngtGl1++dUve/RUqzuaASSh7shwCDJjEzthxki8w== dependencies: - "@types/json-schema" "^7.0.6" + "@types/json-schema" "^7.0.7" ajv "^6.12.5" ajv-keywords "^3.5.2" +screenfull@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/screenfull/-/screenfull-5.1.0.tgz#85c13c70f4ead4c1b8a935c70010dfdcd2c0e5c8" + integrity sha512-dYaNuOdzr+kc6J6CFcBrzkLCfyGcMg+gWkJ8us93IQ7y1cevhQAugFsaCdMHb6lw8KV3xPzSxzH7zM1dQap9mA== + scuid@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/scuid/-/scuid-1.1.0.tgz#d3f9f920956e737a60f72d0e4ad280bf324d5dab" @@ -11566,35 +10281,11 @@ section-matter@^1.0.0: extend-shallow "^2.0.1" kind-of "^6.0.0" -select-hose@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" - integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo= - -select@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/select/-/select-1.1.2.tgz#0e7350acdec80b1108528786ec1d4418d11b396d" - integrity sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0= - -selfsigned@^1.10.8: - version "1.10.8" - resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.8.tgz#0d17208b7d12c33f8eac85c41835f27fc3d81a30" - integrity sha512-2P4PtieJeEwVgTU9QEcwIRDQ/mXJLX8/+I3ur+Pg16nS8oNbrGxEso9NyYWy8NAmXiNl4dlAp5MwoNeCWzON4w== - dependencies: - node-forge "^0.10.0" - semver-compare@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= -semver-diff@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-3.1.1.tgz#05f77ce59f325e00e2706afd67bb506ddb1ca32b" - integrity sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg== - dependencies: - semver "^6.3.0" - "semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.6.0: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" @@ -11612,7 +10303,7 @@ semver@7.x, semver@^7.0.0, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^ dependencies: lru-cache "^6.0.0" -semver@^6.0.0, semver@^6.1.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: +semver@^6.0.0, semver@^6.1.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== @@ -11636,40 +10327,13 @@ send@0.17.1: range-parser "~1.2.1" statuses "~1.5.0" -serialize-javascript@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-5.0.1.tgz#7886ec848049a462467a97d3d918ebb2aaf934f4" - integrity sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA== +serialize-javascript@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" + integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== dependencies: randombytes "^2.1.0" -serve-handler@^6.1.3: - version "6.1.3" - resolved "https://registry.yarnpkg.com/serve-handler/-/serve-handler-6.1.3.tgz#1bf8c5ae138712af55c758477533b9117f6435e8" - integrity sha512-FosMqFBNrLyeiIDvP1zgO6YoTzFYHxLDEIavhlmQ+knB2Z7l1t+kGLHkZIDN7UVWqQAmKI3D20A6F6jo3nDd4w== - dependencies: - bytes "3.0.0" - content-disposition "0.5.2" - fast-url-parser "1.1.3" - mime-types "2.1.18" - minimatch "3.0.4" - path-is-inside "1.0.2" - path-to-regexp "2.2.1" - range-parser "1.2.0" - -serve-index@^1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" - integrity sha1-03aNabHn2C5c4FD/9bRTvqEqkjk= - dependencies: - accepts "~1.3.4" - batch "0.6.1" - debug "2.6.9" - escape-html "~1.0.3" - http-errors "~1.6.2" - mime-types "~2.1.17" - parseurl "~1.3.2" - serve-static@1.14.1: version "1.14.1" resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" @@ -11685,26 +10349,16 @@ set-blocking@^2.0.0: resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= -set-value@^2.0.0, set-value@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" - integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== - dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.3" - split-string "^3.0.1" +set-harmonic-interval@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/set-harmonic-interval/-/set-harmonic-interval-1.0.1.tgz#e1773705539cdfb80ce1c3d99e7f298bb3995249" + integrity sha512-AhICkFV84tBP1aWqPwLZqFvAwqEoVA9kxNMniGEUvzOlm4vLmOFLiTT3UZ6bziJTy4bOVpzWGTfSCbmaayGx8g== -setimmediate@^1.0.5: +setimmediate@^1.0.4, setimmediate@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= -setprototypeof@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" - integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== - setprototypeof@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" @@ -11715,17 +10369,13 @@ setprototypeof@1.2.0: resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== -shallow-clone@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" - integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== +sha.js@^2.4.0, sha.js@^2.4.8: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== dependencies: - kind-of "^6.0.2" - -shallowequal@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8" - integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ== + inherits "^2.0.1" + safe-buffer "^5.0.1" shebang-command@^1.2.0: version "1.2.0" @@ -11756,15 +10406,6 @@ shell-quote@1.7.2: resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2" integrity sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg== -shelljs@^0.8.4: - version "0.8.4" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.4.tgz#de7684feeb767f8716b326078a8a00875890e3c2" - integrity sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ== - dependencies: - glob "^7.0.0" - interpret "^1.0.0" - rechoir "^0.6.2" - shiki@^0.9.3: version "0.9.3" resolved "https://registry.yarnpkg.com/shiki/-/shiki-0.9.3.tgz#7bf7bcf3ed50ca525ec89cc09254abce4264d5ca" @@ -11791,11 +10432,11 @@ simple-swizzle@^0.2.2: is-arrayish "^0.3.1" sirv@^1.0.7: - version "1.0.11" - resolved "https://registry.yarnpkg.com/sirv/-/sirv-1.0.11.tgz#81c19a29202048507d6ec0d8ba8910fda52eb5a4" - integrity sha512-SR36i3/LSWja7AJNRBz4fF/Xjpn7lQFI30tZ434dIy+bitLYSP+ZEenHg36i23V2SGEz+kqjksg0uOGZ5LPiqg== + version "1.0.12" + resolved "https://registry.yarnpkg.com/sirv/-/sirv-1.0.12.tgz#d816c882b35489b3c63290e2f455ae3eccd5f652" + integrity sha512-+jQoCxndz7L2tqQL4ZyzfDhky0W/4ZJip3XoOuxyQWnAwMxindLl3Xv1qT4x1YX/re0leShvTm8Uk0kQspGhBg== dependencies: - "@polka/url" "^1.0.0-next.9" + "@polka/url" "^1.0.0-next.15" mime "^2.3.1" totalist "^1.0.0" @@ -11804,16 +10445,6 @@ sisteransi@^1.0.5: resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== -sitemap@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/sitemap/-/sitemap-7.0.0.tgz#022bef4df8cba42e38e1fe77039f234cab0372b6" - integrity sha512-Ud0jrRQO2k7fEtPAM+cQkBKoMvxQyPKNXKDLn8tRVHxRCsdDQ2JZvw+aZ5IRYYQVAV9iGxEar6boTwZzev+x3g== - dependencies: - "@types/node" "^15.0.1" - "@types/sax" "^1.2.1" - arg "^5.0.0" - sax "^1.2.4" - slash@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" @@ -11853,62 +10484,6 @@ smartwrap@^1.2.3: wcwidth "^1.0.1" yargs "^15.1.0" -snapdragon-node@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" - integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== - dependencies: - define-property "^1.0.0" - isobject "^3.0.0" - snapdragon-util "^3.0.1" - -snapdragon-util@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" - integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== - dependencies: - kind-of "^3.2.0" - -snapdragon@^0.8.1: - version "0.8.2" - resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" - integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== - dependencies: - base "^0.11.1" - debug "^2.2.0" - define-property "^0.2.5" - extend-shallow "^2.0.1" - map-cache "^0.2.2" - source-map "^0.5.6" - source-map-resolve "^0.5.0" - use "^3.1.0" - -sockjs-client@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.5.0.tgz#2f8ff5d4b659e0d092f7aba0b7c386bd2aa20add" - integrity sha512-8Dt3BDi4FYNrCFGTL/HtwVzkARrENdwOUf1ZoW/9p3M8lZdFT35jVdrHza+qgxuG9H3/shR4cuX/X9umUrjP8Q== - dependencies: - debug "^3.2.6" - eventsource "^1.0.7" - faye-websocket "^0.11.3" - inherits "^2.0.4" - json3 "^3.3.3" - url-parse "^1.4.7" - -sockjs@^0.3.21: - version "0.3.21" - resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.21.tgz#b34ffb98e796930b60a0cfa11904d6a339a7d417" - integrity sha512-DhbPFGpxjc6Z3I+uX07Id5ZO2XwYsWOrYjaSeieES78cq+JaJvVe5q/m1uvjIQhXinhIeCFRH6JgXe+mvVMyXw== - dependencies: - faye-websocket "^0.11.3" - uuid "^3.4.0" - websocket-driver "^0.7.4" - -sort-css-media-queries@1.5.4: - version "1.5.4" - resolved "https://registry.yarnpkg.com/sort-css-media-queries/-/sort-css-media-queries-1.5.4.tgz#24182b12002a13d01ba943ddf74f5098d7c244ce" - integrity sha512-YP5W/h4Sid/YP7Lp87ejJ5jP13/Mtqt2vx33XyhO+IAugKlufRPbOrPlIiEUuxmpNBSBd3EeeQpFhdu3RfI2Ag== - sort-keys@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" @@ -11916,7 +10491,7 @@ sort-keys@^2.0.0: dependencies: is-plain-obj "^1.0.0" -source-list-map@^2.0.0, source-list-map@^2.0.1: +source-list-map@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== @@ -11926,18 +10501,7 @@ source-map-js@^0.6.2: resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e" integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug== -source-map-resolve@^0.5.0: - version "0.5.3" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" - integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== - dependencies: - atob "^2.1.2" - decode-uri-component "^0.2.0" - resolve-url "^0.2.1" - source-map-url "^0.4.0" - urix "^0.1.0" - -source-map-support@^0.5.6, source-map-support@~0.5.12, source-map-support@~0.5.19: +source-map-support@^0.5.6, source-map-support@~0.5.19: version "0.5.19" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== @@ -11945,27 +10509,34 @@ source-map-support@^0.5.6, source-map-support@~0.5.12, source-map-support@~0.5.1 buffer-from "^1.0.0" source-map "^0.6.0" -source-map-url@^0.4.0: - version "0.4.1" - resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" - integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== +source-map@0.5.6: + version "0.5.6" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" + integrity sha1-dc449SvwczxafwwRjYEzSiu19BI= + +source-map@0.7.3, source-map@^0.7.3, source-map@~0.7.2: + version "0.7.3" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" + integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== -source-map@^0.5.0, source-map@^0.5.6, source-map@^0.5.7: +source-map@0.8.0-beta.0: + version "0.8.0-beta.0" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.8.0-beta.0.tgz#d4c1bb42c3f7ee925f005927ba10709e0d1d1f11" + integrity sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA== + dependencies: + whatwg-url "^7.0.0" + +source-map@^0.5.0, source-map@^0.5.7: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= -source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -source-map@^0.7.3, source-map@~0.7.2: - version "0.7.3" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" - integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== - -sourcemap-codec@^1.4.4: +sourcemap-codec@^1.4.4, sourcemap-codec@^1.4.8: version "1.4.8" resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== @@ -12014,45 +10585,17 @@ spdx-license-ids@^3.0.0: resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz#e9c18a410e5ed7e12442a549fbd8afa767038d65" integrity sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ== -spdy-transport@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" - integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== - dependencies: - debug "^4.1.0" - detect-node "^2.0.4" - hpack.js "^2.1.6" - obuf "^1.1.2" - readable-stream "^3.0.6" - wbuf "^1.7.3" - -spdy@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b" - integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== - dependencies: - debug "^4.1.0" - handle-thing "^2.0.0" - http-deceiver "^1.2.7" - select-hose "^2.0.0" - spdy-transport "^3.0.0" - -split-string@^3.0.1, split-string@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" - integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== - dependencies: - extend-shallow "^3.0.0" - sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= -stable@^0.1.8: - version "0.1.8" - resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" - integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== +stack-generator@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/stack-generator/-/stack-generator-2.0.5.tgz#fb00e5b4ee97de603e0773ea78ce944d81596c36" + integrity sha512-/t1ebrbHkrLrDuNMdeAcsvynWgoH/i4o8EGGfX7dEYDoTXOYVAkEpFdtshlvabzc6JlJ8Kf9YdFEoz7JkzGN9Q== + dependencies: + stackframe "^1.1.1" stack-utils@^2.0.3: version "2.0.3" @@ -12061,30 +10604,88 @@ stack-utils@^2.0.3: dependencies: escape-string-regexp "^2.0.0" +stackframe@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.2.0.tgz#52429492d63c62eb989804c11552e3d22e779303" + integrity sha512-GrdeshiRmS1YLMYgzF16olf2jJ/IzxXY9lhKOskuVziubpTYcYqyOwYeJKzQkwy7uN0fYSsbsC4RQaXf9LCrYA== + +stacktrace-gps@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/stacktrace-gps/-/stacktrace-gps-3.0.4.tgz#7688dc2fc09ffb3a13165ebe0dbcaf41bcf0c69a" + integrity sha512-qIr8x41yZVSldqdqe6jciXEaSCKw1U8XTXpjDuy0ki/apyTn/r3w9hDAAQOhZdxvsC93H+WwwEu5cq5VemzYeg== + dependencies: + source-map "0.5.6" + stackframe "^1.1.1" + +stacktrace-js@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/stacktrace-js/-/stacktrace-js-2.0.2.tgz#4ca93ea9f494752d55709a081d400fdaebee897b" + integrity sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg== + dependencies: + error-stack-parser "^2.0.6" + stack-generator "^2.0.5" + stacktrace-gps "^3.0.4" + +stacktrace-parser@0.1.10: + version "0.1.10" + resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz#29fb0cae4e0d0b85155879402857a1639eb6051a" + integrity sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg== + dependencies: + type-fest "^0.7.1" + state-toggle@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/state-toggle/-/state-toggle-1.0.3.tgz#e123b16a88e143139b09c6852221bc9815917dfe" integrity sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ== -static-extend@^0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" - integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= - dependencies: - define-property "^0.2.5" - object-copy "^0.1.0" - -"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@~1.5.0: +"statuses@>= 1.5.0 < 2", statuses@~1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= -std-env@^2.2.1: - version "2.3.0" - resolved "https://registry.yarnpkg.com/std-env/-/std-env-2.3.0.tgz#66d4a4a4d5224242ed8e43f5d65cfa9095216eee" - integrity sha512-4qT5B45+Kjef2Z6pE0BkskzsH0GO7GrND0wGlTM1ioUe3v0dGYx9ZJH0Aro/YyA8fqQ5EyIKDRjZojJYMFTflw== +stream-browserify@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-3.0.0.tgz#22b0a2850cdf6503e73085da1fc7b7d0c2122f2f" + integrity sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA== + dependencies: + inherits "~2.0.4" + readable-stream "^3.5.0" + +stream-browserify@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" + integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg== + dependencies: + inherits "~2.0.1" + readable-stream "^2.0.2" + +stream-http@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-3.1.1.tgz#0370a8017cf8d050b9a8554afe608f043eaff564" + integrity sha512-S7OqaYu0EkFpgeGFb/NPOoPLxFko7TPqtEeFg5DXPB4v/KETHG0Ln6fRFrNezoelpaDKmycEmmZ81cC9DAwgYg== + dependencies: + builtin-status-codes "^3.0.0" + inherits "^2.0.4" + readable-stream "^3.6.0" + xtend "^4.0.2" + +stream-http@^2.7.2: + version "2.8.3" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" + integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw== + dependencies: + builtin-status-codes "^3.0.0" + inherits "^2.0.1" + readable-stream "^2.3.6" + to-arraybuffer "^1.0.0" + xtend "^4.0.0" + +stream-parser@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/stream-parser/-/stream-parser-0.3.1.tgz#1618548694420021a1182ff0af1911c129761773" + integrity sha1-FhhUhpRCACGhGC/wrxkRwSl2F3M= dependencies: - ci-info "^3.0.0" + debug "2" stream-transform@^2.0.4: version "2.0.4" @@ -12103,7 +10704,7 @@ string-argv@0.3.1: resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg== -string-hash@^1.1.1: +string-hash@1.1.3, string-hash@^1.1.1: version "1.1.3" resolved "https://registry.yarnpkg.com/string-hash/-/string-hash-1.1.3.tgz#e8aafc0ac1855b4666929ed7dd1275df5d6c811b" integrity sha1-6Kr8CsGFW0Zmkp7X3RJ1311sgRs= @@ -12129,16 +10730,7 @@ string-width@^2.0.0, string-width@^2.1.1: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" -string-width@^3.0.0, string-width@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" - integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== - dependencies: - emoji-regex "^7.0.1" - is-fullwidth-code-point "^2.0.0" - strip-ansi "^5.1.0" - -string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0: +string-width@^4.1.0, string-width@^4.2.0: version "4.2.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5" integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA== @@ -12163,7 +10755,14 @@ string.prototype.trimstart@^1.0.4: call-bind "^1.0.2" define-properties "^1.1.3" -string_decoder@^1.1.1, string_decoder@~1.1.1: +string_decoder@1.3.0, string_decoder@^1.0.0, string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== @@ -12186,13 +10785,6 @@ strip-ansi@6.0.0, strip-ansi@^6.0.0: dependencies: ansi-regex "^5.0.0" -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= - dependencies: - ansi-regex "^2.0.0" - strip-ansi@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" @@ -12200,13 +10792,6 @@ strip-ansi@^4.0.0: dependencies: ansi-regex "^3.0.0" -strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" - integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== - dependencies: - ansi-regex "^4.1.0" - strip-bom-string@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-bom-string/-/strip-bom-string-1.0.0.tgz#e5211e9224369fbb81d633a2f00044dc8cedad92" @@ -12239,15 +10824,26 @@ strip-indent@^3.0.0: dependencies: min-indent "^1.0.0" +strip-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-4.0.0.tgz#b41379433dd06f5eae805e21d631e07ee670d853" + integrity sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA== + dependencies: + min-indent "^1.0.1" + strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== -strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= +strtok3@^6.0.3: + version "6.0.8" + resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-6.0.8.tgz#c839157f615c10ba0f4ae35067dad9959eeca346" + integrity sha512-QLgv+oiXwXgCgp2PdPPa+Jpp4D9imK9e/0BsyfeFMr6QL6wMVqoVn9+OXQ9I7MZbmUzN6lmitTJ09uwS2OmGcw== + dependencies: + "@tokenizer/token" "^0.1.1" + "@types/debug" "^4.1.5" + peek-readable "^3.1.3" style-to-object@0.3.0, style-to-object@^0.3.0: version "0.3.0" @@ -12256,31 +10852,39 @@ style-to-object@0.3.0, style-to-object@^0.3.0: dependencies: inline-style-parser "0.1.1" -styled-components@5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.3.0.tgz#e47c3d3e9ddfff539f118a3dd0fd4f8f4fb25727" - integrity sha512-bPJKwZCHjJPf/hwTJl6TbkSZg/3evha+XPEizrZUGb535jLImwDUdjTNxXqjjaASt2M4qO4AVfoHJNe3XB/tpQ== - dependencies: - "@babel/helper-module-imports" "^7.0.0" - "@babel/traverse" "^7.4.5" - "@emotion/is-prop-valid" "^0.8.8" - "@emotion/stylis" "^0.8.4" - "@emotion/unitless" "^0.7.4" - babel-plugin-styled-components ">= 1.12.0" - css-to-react-native "^3.0.0" - hoist-non-react-statics "^3.0.0" - shallowequal "^1.1.0" - supports-color "^5.5.0" - -stylehacks@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-5.0.1.tgz#323ec554198520986806388c7fdaebc38d2c06fb" - integrity sha512-Es0rVnHIqbWzveU1b24kbw92HsebBepxfcqe5iix7t9j0PQqhs0IxXVXv0pY2Bxa08CgMkzD6OWql7kbGOuEdA== +style-value-types@4.1.4: + version "4.1.4" + resolved "https://registry.yarnpkg.com/style-value-types/-/style-value-types-4.1.4.tgz#80f37cb4fb024d6394087403dfb275e8bb627e75" + integrity sha512-LCJL6tB+vPSUoxgUBt9juXIlNJHtBMy8jkXzUJSBzeHWdBu6lhzHqCvLVkXFGsFIlNa2ln1sQHya/gzaFmB2Lg== dependencies: - browserslist "^4.16.0" - postcss-selector-parser "^6.0.4" + hey-listen "^1.0.8" + tslib "^2.1.0" -stylis@^4.0.3: +styled-jsx@3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-3.3.2.tgz#2474601a26670a6049fb4d3f94bd91695b3ce018" + integrity sha512-daAkGd5mqhbBhLd6jYAjYBa9LpxYCzsgo/f6qzPdFxVB8yoGbhxvzQgkC0pfmCVvW3JuAEBn0UzFLBfkHVZG1g== + dependencies: + "@babel/types" "7.8.3" + babel-plugin-syntax-jsx "6.18.0" + convert-source-map "1.7.0" + loader-utils "1.2.3" + source-map "0.7.3" + string-hash "1.1.3" + stylis "3.5.4" + stylis-rule-sheet "0.0.10" + +stylis-rule-sheet@0.0.10: + version "0.0.10" + resolved "https://registry.yarnpkg.com/stylis-rule-sheet/-/stylis-rule-sheet-0.0.10.tgz#44e64a2b076643f4b52e5ff71efc04d8c3c4a430" + integrity sha512-nTbZoaqoBnmK+ptANthb10ZRZOGC+EmTLLUxeYIuHNkEKcmKgXX1XWKkUBT2Ac4es3NybooPe0SmvKdhKJZAuw== + +stylis@3.5.4: + version "3.5.4" + resolved "https://registry.yarnpkg.com/stylis/-/stylis-3.5.4.tgz#f665f25f5e299cf3d64654ab949a57c768b73fbe" + integrity sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q== + +stylis@^4.0.3, stylis@^4.0.6: version "4.0.10" resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.0.10.tgz#446512d1097197ab3f02fb3c258358c3f7a14240" integrity sha512-m3k+dk7QeJw660eIKRRn3xPF6uuvHs/FFzjX3HQ5ove0qYsiygoAhwn5a3IYKaZPo5LrYD0rfVmtv1gNY1uYwg== @@ -12296,20 +10900,13 @@ subscriptions-transport-ws@^0.10.0: symbol-observable "^1.0.4" ws "^5.2.0 || ^6.0.0 || ^7.0.0" -supports-color@^5.3.0, supports-color@^5.4.0, supports-color@^5.5.0: +supports-color@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== dependencies: has-flag "^3.0.0" -supports-color@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" - integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== - dependencies: - has-flag "^3.0.0" - supports-color@^7.0.0, supports-color@^7.1.0: version "7.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" @@ -12332,43 +10929,6 @@ supports-hyperlinks@^2.0.0: has-flag "^4.0.0" supports-color "^7.0.0" -svg-parser@^2.0.2: - version "2.0.4" - resolved "https://registry.yarnpkg.com/svg-parser/-/svg-parser-2.0.4.tgz#fdc2e29e13951736140b76cb122c8ee6630eb6b5" - integrity sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ== - -svgo@^1.2.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.3.2.tgz#b6dc511c063346c9e415b81e43401145b96d4167" - integrity sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw== - dependencies: - chalk "^2.4.1" - coa "^2.0.2" - css-select "^2.0.0" - css-select-base-adapter "^0.1.1" - css-tree "1.0.0-alpha.37" - csso "^4.0.2" - js-yaml "^3.13.1" - mkdirp "~0.5.1" - object.values "^1.1.0" - sax "~1.2.4" - stable "^0.1.8" - unquote "~1.1.1" - util.promisify "~1.0.0" - -svgo@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/svgo/-/svgo-2.3.0.tgz#6b3af81d0cbd1e19c83f5f63cec2cb98c70b5373" - integrity sha512-fz4IKjNO6HDPgIQxu4IxwtubtbSfGEAJUq/IXyTPIkGhWck/faiiwfkvsB8LnBkKLvSoyNNIY6d13lZprJMc9Q== - dependencies: - "@trysound/sax" "0.1.1" - chalk "^4.1.0" - commander "^7.1.0" - css-select "^3.1.2" - css-tree "^1.1.2" - csso "^4.2.0" - stable "^0.1.8" - symbol-observable@^1.0.4: version "1.2.0" resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" @@ -12410,48 +10970,63 @@ table@^6.0.9: strip-ansi "^6.0.0" tailwindcss@^2.1.0, tailwindcss@^2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-2.1.4.tgz#ee8a1b8ccc140db61960b6738f968a8a1c4cd1f8" - integrity sha512-fh1KImDLg6se/Suaelju/5oFbqq1b0ntagmGLu0aG9LlnNPGHgO1n/4E57CbKcCtyz/VYnvVXUiWmfyfBBZQ6g== + version "2.2.4" + resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-2.2.4.tgz#6a2e259b1e26125aeaa7cdc479963fd217c308b0" + integrity sha512-OdBCPgazNNsknSP+JfrPzkay9aqKjhKtFhbhgxHgvEFdHy/GuRPo2SCJ4w1SFTN8H6FPI4m6qD/Jj20NWY1GkA== dependencies: - "@fullhuman/postcss-purgecss" "^3.1.3" + "@fullhuman/postcss-purgecss" "^4.0.3" + arg "^5.0.0" bytes "^3.0.0" - chalk "^4.1.0" - chokidar "^3.5.1" + chalk "^4.1.1" + chokidar "^3.5.2" color "^3.1.3" + cosmiconfig "^7.0.0" detective "^5.2.0" didyoumean "^1.2.1" dlv "^1.1.3" fast-glob "^3.2.5" - fs-extra "^9.1.0" + fs-extra "^10.0.0" + glob-parent "^6.0.0" html-tags "^3.1.0" + is-glob "^4.0.1" lodash "^4.17.21" lodash.topath "^4.5.2" - modern-normalize "^1.0.0" + modern-normalize "^1.1.0" node-emoji "^1.8.1" normalize-path "^3.0.0" - object-hash "^2.1.1" - parse-glob "^3.0.4" - postcss-functions "^3" + object-hash "^2.2.0" postcss-js "^3.0.3" + postcss-load-config "^3.1.0" postcss-nested "5.0.5" - postcss-selector-parser "^6.0.4" + postcss-selector-parser "^6.0.6" postcss-value-parser "^4.1.0" pretty-hrtime "^1.0.3" quick-lru "^5.1.1" reduce-css-calc "^2.1.8" resolve "^1.20.0" + tmp "^0.2.1" -tapable@^1.0.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" - integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== - -tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0: +tapable@^2.1.1, tapable@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.0.tgz#5c373d281d9c672848213d0e037d1c4165ab426b" integrity sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw== +temp-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-2.0.0.tgz#bde92b05bdfeb1516e804c9c00ad45177f31321e" + integrity sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg== + +tempy@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tempy/-/tempy-1.0.1.tgz#30fe901fd869cfb36ee2bd999805aa72fbb035de" + integrity sha512-biM9brNqxSc04Ee71hzFbryD11nX7VPhQQY32AdDmjFvodsRFz/3ufeoTZ6uYkRFfGo188tENcASNs3vTdsM0w== + dependencies: + del "^6.0.0" + is-stream "^2.0.0" + temp-dir "^2.0.0" + type-fest "^0.16.0" + unique-string "^2.0.0" + term-size@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" @@ -12472,31 +11047,22 @@ terminal-link@^2.0.0: ansi-escapes "^4.2.1" supports-hyperlinks "^2.0.0" -terser-webpack-plugin@^5.1.1, terser-webpack-plugin@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.1.2.tgz#51d295eb7cc56785a67a372575fdc46e42d5c20c" - integrity sha512-6QhDaAiVHIQr5Ab3XUWZyDmrIPCHMiqJVljMF91YKyqwKkL5QHnYMkrMBy96v9Z7ev1hGhSEw1HQZc2p/s5Z8Q== +terser-webpack-plugin@^5.1.1: + version "5.1.4" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.1.4.tgz#c369cf8a47aa9922bd0d8a94fe3d3da11a7678a1" + integrity sha512-C2WkFwstHDhVEmsmlCxrXUtVklS+Ir1A7twrYzrDrQQOIMOaVAYykaoo/Aq1K0QRkMoY2hhvDQY1cm4jnIMFwA== dependencies: - jest-worker "^26.6.2" + jest-worker "^27.0.2" p-limit "^3.1.0" schema-utils "^3.0.0" - serialize-javascript "^5.0.1" + serialize-javascript "^6.0.0" source-map "^0.6.1" terser "^5.7.0" -terser@^4.6.3: - version "4.8.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-4.8.0.tgz#63056343d7c70bb29f3af665865a46fe03a0df17" - integrity sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw== - dependencies: - commander "^2.20.0" - source-map "~0.6.1" - source-map-support "~0.5.12" - terser@^5.7.0: - version "5.7.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.7.0.tgz#a761eeec206bc87b605ab13029876ead938ae693" - integrity sha512-HP5/9hp2UaZt5fYkuhNBR8YyRcT8juw8+uFbAme53iN9hblvKnLUTKkmwJG6ocWpIKf8UK4DoeWG4ty0J6S6/g== + version "5.7.1" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.7.1.tgz#2dc7a61009b66bb638305cb2a824763b116bf784" + integrity sha512-b3e+d5JbHAe/JSjwsC3Zn55wsBIM7AsHLjKxT31kGCldgbpFePaFo+PiddtO6uwRZWRw7sPXmAN8dTW61xmnSg== dependencies: commander "^2.20.0" source-map "~0.7.2" @@ -12511,52 +11077,52 @@ test-exclude@^6.0.0: glob "^7.1.4" minimatch "^3.0.4" -text-table@0.2.0, text-table@^0.2.0: +text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= -the-guild-components@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/the-guild-components/-/the-guild-components-1.2.4.tgz#38205d5b351ded715e02c83591e869cb4a841f46" - integrity sha512-mNSBso+GQ/RWLRT5XySNdFnQ0TVGB6YE4L/7MyBsFRw3vgO8K74LuJGVsKzUWX51PetSaus+nVl0DHWfJGpz7g== - dependencies: - "@theguild/components" "1.2.4" - throat@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.1.tgz#d514fedad95740c12c2d7fc70ea863eb51ade375" integrity sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w== +throttle-debounce@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/throttle-debounce/-/throttle-debounce-3.0.1.tgz#32f94d84dfa894f786c9a1f290e7a645b6a19abb" + integrity sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg== + through@^2.3.8: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= -thunky@^1.0.2: - version "1.1.0" - resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" - integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== +timers-browserify@2.0.12, timers-browserify@^2.0.4: + version "2.0.12" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.12.tgz#44a45c11fbf407f34f97bccd1577c652361b00ee" + integrity sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ== + dependencies: + setimmediate "^1.0.4" timsort@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4" integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q= -tiny-emitter@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423" - integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q== - -tiny-invariant@^1.0.2: +tiny-invariant@^1.0.6: version "1.1.0" resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.1.0.tgz#634c5f8efdc27714b7f386c35e6760991d230875" integrity sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw== -tiny-warning@^1.0.0, tiny-warning@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" - integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== +tiny-lru@^7.0.6: + version "7.0.6" + resolved "https://registry.yarnpkg.com/tiny-lru/-/tiny-lru-7.0.6.tgz#b0c3cdede1e5882aa2d1ae21cb2ceccf2a331f24" + integrity sha512-zNYO0Kvgn5rXzWpL0y3RS09sMK67eGaQj9805jlK9G6pSadfriTczzLHFXa/xcW4mIRfmlB9HyQ/+SgL0V1uow== + +tinycolor2@1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.2.tgz#3f6a4d1071ad07676d7fa472e1fac40a719d8803" + integrity sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA== tmp@^0.0.33: version "0.0.33" @@ -12565,36 +11131,28 @@ tmp@^0.0.33: dependencies: os-tmpdir "~1.0.2" +tmp@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" + integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== + dependencies: + rimraf "^3.0.0" + tmpl@1.0.x: version "1.0.4" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" integrity sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE= +to-arraybuffer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" + integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= + to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= -to-object-path@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" - integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= - dependencies: - kind-of "^3.0.2" - -to-readable-stream@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771" - integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q== - -to-regex-range@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" - integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= - dependencies: - is-number "^3.0.0" - repeat-string "^1.6.1" - to-regex-range@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" @@ -12602,21 +11160,24 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" -to-regex@^3.0.1, to-regex@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" - integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== - dependencies: - define-property "^2.0.2" - extend-shallow "^3.0.2" - regex-not "^1.0.2" - safe-regex "^1.1.0" +toggle-selection@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/toggle-selection/-/toggle-selection-1.0.6.tgz#6e45b1263f2017fa0acc7d89d78b15b8bf77da32" + integrity sha1-bkWxJj8gF/oKzH2J14sVuL932jI= toidentifier@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== +token-types@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/token-types/-/token-types-2.1.1.tgz#bd585d64902aaf720b8979d257b4b850b4d45c45" + integrity sha512-wnQcqlreS6VjthyHO3Y/kpK/emflxDBNhlNUPfh7wE39KnuDdOituXomIbyI79vBtF0Ninpkh72mcuRHo+RG3Q== + dependencies: + "@tokenizer/token" "^0.1.1" + ieee754 "^1.2.1" + totalist@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/totalist/-/totalist-1.1.0.tgz#a4d65a3e546517701e3e5c37a47a70ac97fe56df" @@ -12631,6 +11192,13 @@ tough-cookie@^4.0.0: punycode "^2.1.1" universalify "^0.1.2" +tr46@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" + integrity sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk= + dependencies: + punycode "^2.1.0" + tr46@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.0.2.tgz#03273586def1595ae08fedb38d7733cee91d2479" @@ -12648,6 +11216,11 @@ trim-newlines@^3.0.0: resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.0.tgz#79726304a6a898aa8373427298d54c2ee8b1cb30" integrity sha512-C4+gOpvmxaSMKuEf9Qc134F1ZuOHVXKRbtEflf4NTtuuJDEIJ9p5PXsalL8SkeRw+qit1Mo+yuvMPAKwWg/1hA== +trim-newlines@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-4.0.2.tgz#d6aaaf6a0df1b4b536d183879a6b939489808c7c" + integrity sha512-GJtWyq9InR/2HRiLZgpIKv+ufIKrVrvjQWEj7PxAXNc5dwbNJkqhAUoAGgzRmULAnoOM5EIpveYd3J2VeSAIew== + trim-trailing-lines@^1.0.0: version "1.1.4" resolved "https://registry.yarnpkg.com/trim-trailing-lines/-/trim-trailing-lines-1.1.4.tgz#bd4abbec7cc880462f10b2c8b5ce1d8d1ec7c2c0" @@ -12663,10 +11236,10 @@ trough@^1.0.0: resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.5.tgz#b8b639cefad7d0bb2abd37d433ff8293efa5f406" integrity sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA== -ts-essentials@^2.0.3: - version "2.0.12" - resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-2.0.12.tgz#c9303f3d74f75fa7528c3d49b80e089ab09d8745" - integrity sha512-3IVX4nI6B5cc31/GFFE+i8ey/N2eA0CZDbo6n0yrz0zDX8ZJ8djmU1p+XRz7G3is0F3bB3pu2pAroFdAWQKU3w== +ts-easing@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/ts-easing/-/ts-easing-0.2.0.tgz#c8a8a35025105566588d87dbda05dd7fbfa5a4ec" + integrity sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ== ts-invariant@^0.7.0: version "0.7.3" @@ -12698,6 +11271,11 @@ ts-jest@27.0.3: semver "7.x" yargs-parser "20.x" +ts-pnp@^1.1.6: + version "1.2.0" + resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92" + integrity sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw== + ts-tiny-invariant@0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/ts-tiny-invariant/-/ts-tiny-invariant-0.0.3.tgz#6f51c153c285a7839bb59b1e5a2721fcb25a5e39" @@ -12718,16 +11296,21 @@ tslib@1.11.1, tslib@^1.10.0, tslib@^1.11.1, tslib@^1.8.1, tslib@^1.9.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35" integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA== -tslib@^2.0.3, tslib@^2.1.0, tslib@^2.2.0, tslib@~2.2.0: +tslib@^1.0.0, tslib@^1.9.3: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +tslib@^2.0.3, tslib@^2.1.0, tslib@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.0.tgz#803b8cdab3e12ba581a4ca41c8839bbb0dacb09e" + integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg== + +tslib@~2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.2.0.tgz#fb2c475977e35e241311ede2693cee1ec6698f5c" integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w== -tslib@~2.0.1: - version "2.0.3" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.3.tgz#8e0741ac45fc0c226e58a17bfc3e64b9bc6ca61c" - integrity sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ== - tsutils@^3.21.0: version "3.21.0" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" @@ -12735,6 +11318,16 @@ tsutils@^3.21.0: dependencies: tslib "^1.8.1" +tty-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" + integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= + +tty-browserify@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.1.tgz#3f05251ee17904dfd0677546670db9651682b811" + integrity sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw== + tty-table@^2.8.10: version "2.8.13" resolved "https://registry.yarnpkg.com/tty-table/-/tty-table-2.8.13.tgz#d484a416381973eaebbdf19c79136b390e5c6d70" @@ -12748,11 +11341,12 @@ tty-table@^2.8.10: yargs "^15.1.0" twin.macro@^2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/twin.macro/-/twin.macro-2.4.2.tgz#bb4de5de408d5cff576d45be43149485e83b72e3" - integrity sha512-O+7JGabRqJHQbO+N+dsd1wSWHMbJj20C9QowaY8ncs5Ix640HQbwj7q/qm3yeYK6CiCPZsUcNCJVv+LUSSfWIg== + version "2.6.1" + resolved "https://registry.yarnpkg.com/twin.macro/-/twin.macro-2.6.1.tgz#d9bc03c7edd9c869cde66e4a9f0874c76acf9836" + integrity sha512-GDneAn95SKAfnyZyCAsgvoi4q33vOQnS5B34T3jHK1qUhNjv7ZXbbDYKx0yU450TOmzcPng9oq7bzTFlnHt4zw== dependencies: "@babel/parser" "^7.12.5" + "@babel/template" "^7.14.5" autoprefixer "^10.2.5" babel-plugin-macros "^2.8.0" chalk "^4.1.0" @@ -12796,6 +11390,11 @@ type-fest@^0.13.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.13.1.tgz#0172cb5bce80b0bd542ea348db50c7e21834d934" integrity sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg== +type-fest@^0.16.0: + version "0.16.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.16.0.tgz#3240b891a78b0deae910dbeb86553e552a148860" + integrity sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg== + type-fest@^0.20.2: version "0.20.2" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" @@ -12811,11 +11410,21 @@ type-fest@^0.6.0: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== +type-fest@^0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48" + integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg== + type-fest@^0.8.1: version "0.8.1" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== +type-fest@^1.0.1, type-fest@^1.0.2: + version "1.2.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-1.2.1.tgz#232990aa513f3f5223abf54363975dfe3a121a2e" + integrity sha512-SbmIRuXhJs8KTneu77Ecylt9zuqL683tuiLYpTRil4H++eIhqCmx6ko6KAFem9dty8sOdnEiX7j4K1nRE628fQ== + type-is@~1.6.17, type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" @@ -12836,34 +11445,32 @@ typedoc-default-themes@^0.12.10: resolved "https://registry.yarnpkg.com/typedoc-default-themes/-/typedoc-default-themes-0.12.10.tgz#614c4222fe642657f37693ea62cad4dafeddf843" integrity sha512-fIS001cAYHkyQPidWXmHuhs8usjP5XVJjWB8oZGqkTowZaz3v7g3KDZeeqE82FBrmkAnIBOY3jgy7lnPnqATbA== -typedoc-plugin-markdown@3.9.0: - version "3.9.0" - resolved "https://registry.yarnpkg.com/typedoc-plugin-markdown/-/typedoc-plugin-markdown-3.9.0.tgz#d9c0390b8ddeeda56fdbf01264521ef04b3c19c7" - integrity sha512-s445YeUe8bH7me15T+hsHZgNmAvvF7QIpX02vFgseLGtghAwmtdZYVOqPneWoKqRv/JNpPSuyZb3CeblML9jOg== +typedoc-plugin-markdown@3.10.2: + version "3.10.2" + resolved "https://registry.yarnpkg.com/typedoc-plugin-markdown/-/typedoc-plugin-markdown-3.10.2.tgz#4b1400706d4c8c3924481808aba4efa684605174" + integrity sha512-eAV7fuCymdbUIk2P3jjehUWG0VE3YSr/qGGYAHUEBTrRZMuFxS/rYrooF0PPabBUdbprL4BKV8HaP7oed12T2Q== dependencies: handlebars "^4.7.7" -typedoc@0.20.36: - version "0.20.36" - resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.20.36.tgz#ee5523c32f566ad8283fc732aa8ea322d1a45f6a" - integrity sha512-qFU+DWMV/hifQ9ZAlTjdFO9wbUIHuUBpNXzv68ZyURAP9pInjZiO4+jCPeAzHVcaBCHER9WL/+YzzTt6ZlN/Nw== +typedoc@0.21.2: + version "0.21.2" + resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.21.2.tgz#cf5094314d3d63e95a8ef052ceff06a6cafd509d" + integrity sha512-SR1ByJB3USg+jxoxwzMRP07g/0f/cQUE5t7gOh1iTUyjTPyJohu9YSKRlK+MSXXqlhIq+m0jkEHEG5HoY7/Adg== dependencies: - colors "^1.4.0" - fs-extra "^9.1.0" + glob "^7.1.7" handlebars "^4.7.7" lodash "^4.17.21" lunr "^2.3.9" - marked "^2.0.3" + marked "^2.1.1" minimatch "^3.0.0" progress "^2.0.3" - shelljs "^0.8.4" shiki "^0.9.3" typedoc-default-themes "^0.12.10" -typescript@4.3.2: - version "4.3.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.2.tgz#399ab18aac45802d6f2498de5054fcbbe716a805" - integrity sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw== +typescript@4.3.5, typescript@^4.3.4: + version "4.3.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.5.tgz#4d1c37cc16e893973c45a06886b7113234f119f4" + integrity sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA== typescript@^3.0.0: version "3.9.9" @@ -12944,21 +11551,6 @@ unified@^8.4.2: trough "^1.0.0" vfile "^4.0.0" -union-value@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" - integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== - dependencies: - arr-union "^3.1.0" - get-value "^2.0.6" - is-extendable "^0.1.1" - set-value "^2.0.1" - -uniqs@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/uniqs/-/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02" - integrity sha1-/+3ks2slKQaW5uFl1KWe25mOawI= - unique-string@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d" @@ -12981,6 +11573,14 @@ unist-util-is@^4.0.0: resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-4.1.0.tgz#976e5f462a7a5de73d94b706bac1b90671b57797" integrity sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg== +unist-util-map@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unist-util-map/-/unist-util-map-2.0.1.tgz#c3fca064486d3937c4dad8b39c64974faae7c7c4" + integrity sha512-VdNvk4BQUUU9Rgr8iUOvclHa/iN9O+6Dt66FKij8l9OVezGG37gGWCPU5KSax1R2degqXFvl3kWTkvzL79e9tQ== + dependencies: + "@types/mdast" "^3.0.0" + object-assign "^4.0.0" + unist-util-position@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/unist-util-position/-/unist-util-position-3.1.0.tgz#1c42ee6301f8d52f47d14f62bbdb796571fa2d47" @@ -12994,9 +11594,9 @@ unist-util-remove-position@^2.0.0: unist-util-visit "^2.0.0" unist-util-remove@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/unist-util-remove/-/unist-util-remove-2.0.1.tgz#fa13c424ff8e964f3aa20d1098b9a690c6bfaa39" - integrity sha512-YtuetK6o16CMfG+0u4nndsWpujgsHDHHLyE0yGpJLLn5xSjKeyGyzEBOI2XbmoUHCYabmNgX52uxlWoQhcvR7Q== + version "2.1.0" + resolved "https://registry.yarnpkg.com/unist-util-remove/-/unist-util-remove-2.1.0.tgz#b0b4738aa7ee445c402fda9328d604a02d010588" + integrity sha512-J8NYPyBm4baYLdCbjmf1bhPu45Cr1MWTm77qd9istEkzWpnN6O9tMsEbB2JhNnBCqGENRqEWomQ+He6au0B27Q== dependencies: unist-util-is "^4.0.0" @@ -13015,7 +11615,7 @@ unist-util-visit-parents@^3.0.0: "@types/unist" "^2.0.0" unist-util-is "^4.0.0" -unist-util-visit@2.0.3, unist-util-visit@^2.0.0, unist-util-visit@^2.0.1, unist-util-visit@^2.0.2: +unist-util-visit@2.0.3, unist-util-visit@^2.0.0, unist-util-visit@^2.0.1, unist-util-visit@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-2.0.3.tgz#c3703893146df47203bb8a9795af47d7b971208c" integrity sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q== @@ -13051,44 +11651,6 @@ unpipe@1.0.0, unpipe@~1.0.0: resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= -unquote@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/unquote/-/unquote-1.1.1.tgz#8fded7324ec6e88a0ff8b905e7c098cdc086d544" - integrity sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ= - -unset-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" - integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= - dependencies: - has-value "^0.3.1" - isobject "^3.0.0" - -upath@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" - integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== - -update-notifier@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-5.1.0.tgz#4ab0d7c7f36a231dd7316cf7729313f0214d9ad9" - integrity sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw== - dependencies: - boxen "^5.0.0" - chalk "^4.1.0" - configstore "^5.0.1" - has-yarn "^2.1.0" - import-lazy "^2.1.0" - is-ci "^2.0.0" - is-installed-globally "^0.4.0" - is-npm "^5.0.0" - is-yarn-global "^0.3.0" - latest-version "^5.1.0" - pupa "^2.1.1" - semver "^7.3.4" - semver-diff "^3.1.1" - xdg-basedir "^4.0.0" - uri-js@^4.2.2: version "4.4.1" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" @@ -13096,28 +11658,7 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" -urix@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" - integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= - -url-loader@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-4.1.1.tgz#28505e905cae158cf07c92ca622d7f237e70a4e2" - integrity sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA== - dependencies: - loader-utils "^2.0.0" - mime-types "^2.1.27" - schema-utils "^3.0.0" - -url-parse-lax@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" - integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww= - dependencies: - prepend-http "^2.0.0" - -url-parse@^1.4.3, url-parse@^1.4.4, url-parse@^1.4.7: +url-parse@^1.4.4: version "1.5.1" resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.1.tgz#d5fa9890af8a5e1f274a2c98376510f6425f6e3b" integrity sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q== @@ -13133,79 +11674,93 @@ url@^0.11.0: punycode "1.3.2" querystring "0.2.0" -use-composed-ref@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/use-composed-ref/-/use-composed-ref-1.1.0.tgz#9220e4e94a97b7b02d7d27eaeab0b37034438bbc" - integrity sha512-my1lNHGWsSDAhhVAT4MKs6IjBUtG6ZG11uUqexPH9PptiIZDQOzaF4f5tEbJ2+7qvNbtXNBbU3SfmN+fXlWDhg== - dependencies: - ts-essentials "^2.0.3" +use-callback-ref@^1.2.1, use-callback-ref@^1.2.3: + version "1.2.5" + resolved "https://registry.yarnpkg.com/use-callback-ref/-/use-callback-ref-1.2.5.tgz#6115ed242cfbaed5915499c0a9842ca2912f38a5" + integrity sha512-gN3vgMISAgacF7sqsLPByqoePooY3n2emTH59Ur5d/M8eg4WTWu1xp8i8DHjohftIyEx0S08RiYxbffr4j8Peg== -use-debounce@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/use-debounce/-/use-debounce-6.0.1.tgz#ed1eb2b30189408fb9792ea2887f4c6c3cb401a3" - integrity sha512-kpvIxpa0vOLz/2I2sfNJ72mUeaT2CMNCu5BT1f2HkV9qZK27UVSOFf1sSSu+wjJE4TcR2VTXS2SM569+m3TN7Q== +use-debounce@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/use-debounce/-/use-debounce-7.0.0.tgz#00a67d23d4fe09905e11145a99278da06c01c880" + integrity sha512-4fvxEEs7ztdNMh+c497HAgysdq2+Ascem6EaDANGlCIap1JzqfL03Xw8xkYc2lShfXm4uO6PA6V5zcXN7gJdFA== -use-isomorphic-layout-effect@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.1.tgz#7bb6589170cd2987a152042f9084f9effb75c225" - integrity sha512-L7Evj8FGcwo/wpbv/qvSfrkHFtOpCzvM5yl2KVyDJoylVuSvzphiiasmjgQPttIGBAy2WKiBNR98q8w7PiNgKQ== +use-immer@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/use-immer/-/use-immer-0.6.0.tgz#ca6aa5ade93018e2c65cf128d19ada54fc23f70d" + integrity sha512-dFGRfvWCqPDTOt/S431ETYTg6+uxbpb7A1pptufwXVzGJY3RlXr38+3wyLNpc6SbbmAKjWl6+EP6uW74fkEsXQ== -use-latest@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/use-latest/-/use-latest-1.2.0.tgz#a44f6572b8288e0972ec411bdd0840ada366f232" - integrity sha512-d2TEuG6nSLKQLAfW3By8mKr8HurOlTkul0sOpxbClIv4SQ4iOd7BYr7VIzdbktUCnv7dua/60xzd8igMU6jmyw== +use-sidecar@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/use-sidecar/-/use-sidecar-1.0.5.tgz#ffff2a17c1df42e348624b699ba6e5c220527f2b" + integrity sha512-k9jnrjYNwN6xYLj1iaGhonDghfvmeTmYjAiGvOr7clwKfPjMXJf4/HOr7oT5tJwYafgp2tG2l3eZEOfoELiMcA== dependencies: - use-isomorphic-layout-effect "^1.0.0" + detect-node-es "^1.1.0" + tslib "^1.9.3" -use@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" - integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== +use-subscription@1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/use-subscription/-/use-subscription-1.5.1.tgz#73501107f02fad84c6dd57965beb0b75c68c42d1" + integrity sha512-Xv2a1P/yReAjAbhylMfFplFKj9GssgTwN7RlcTxBujFQcloStWNDQdc4g4NRWH9xS4i/FDk04vQBptAXoF3VcA== + dependencies: + object-assign "^4.1.1" util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= -util.promisify@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.1.tgz#6baf7774b80eeb0f7520d8b81d07982a59abbaee" - integrity sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA== +util@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.2" - has-symbols "^1.0.1" - object.getownpropertydescriptors "^2.1.0" + inherits "2.0.1" -utila@~0.4: - version "0.4.0" - resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" - integrity sha1-ihagXURWV6Oupe7MWxKk+lN5dyw= +util@0.12.3: + version "0.12.3" + resolved "https://registry.yarnpkg.com/util/-/util-0.12.3.tgz#971bb0292d2cc0c892dab7c6a5d37c2bec707888" + integrity sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog== + dependencies: + inherits "^2.0.3" + is-arguments "^1.0.4" + is-generator-function "^1.0.7" + is-typed-array "^1.1.3" + safe-buffer "^5.1.2" + which-typed-array "^1.1.2" + +util@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" + integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ== + dependencies: + inherits "2.0.3" -utility-types@^3.10.0: - version "3.10.0" - resolved "https://registry.yarnpkg.com/utility-types/-/utility-types-3.10.0.tgz#ea4148f9a741015f05ed74fd615e1d20e6bed82b" - integrity sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg== +util@^0.12.0: + version "0.12.4" + resolved "https://registry.yarnpkg.com/util/-/util-0.12.4.tgz#66121a31420df8f01ca0c464be15dfa1d1850253" + integrity sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw== + dependencies: + inherits "^2.0.3" + is-arguments "^1.0.4" + is-generator-function "^1.0.7" + is-typed-array "^1.1.3" + safe-buffer "^5.1.2" + which-typed-array "^1.1.2" utils-merge@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= -uuid@^3.3.2, uuid@^3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" - integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== - v8-compile-cache@^2.0.3: version "2.3.0" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== -v8-to-istanbul@^7.0.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-7.1.0.tgz#5b95cef45c0f83217ec79f8fc7ee1c8b486aee07" - integrity sha512-uXUVqNUCLa0AH1vuVxzi+MI4RfxEOKt9pBgKwHbgH7st8Kv2P1m+jvWNnektzBh5QShF3ODgKmUFCf38LnVz1g== +v8-to-istanbul@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-8.0.0.tgz#4229f2a99e367f3f018fa1d5c2b8ec684667c69c" + integrity sha512-LkmXi8UUNxnCC+JlH7/fsfsKr5AU110l+SYGJimWNkWhxbN5EyeOtm1MJ0hhvqMMOhGwBj1Fp70Yv9i+hX0QAg== dependencies: "@types/istanbul-lib-coverage" "^2.0.1" convert-source-map "^1.6.0" @@ -13224,10 +11779,10 @@ validate-npm-package-license@^3.0.1: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" -value-equal@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/value-equal/-/value-equal-1.0.1.tgz#1e0b794c734c5c0cade179c437d356d931a34d6c" - integrity sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw== +validator@13.6.0: + version "13.6.0" + resolved "https://registry.yarnpkg.com/validator/-/validator-13.6.0.tgz#1e71899c14cdc7b2068463cb24c1cc16f6ec7059" + integrity sha512-gVgKbdbHgtxpRyR8K0O6oFZPhhB5tT1jeEHZR0Znr9Svg03U0+r9DXWMrnRAB+HtCStDQKlaIZm42tVsVjqtjg== value-or-promise@1.0.10: version "1.0.10" @@ -13239,11 +11794,6 @@ vary@~1.1.2: resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= -vendors@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.4.tgz#e2b800a53e7a29b93506c3cf41100d16c4c4ad8e" - integrity sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w== - vfile-location@^3.0.0, vfile-location@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-3.2.0.tgz#d8e41fbcbd406063669ebf6c33d56ae8721d0f3c" @@ -13267,6 +11817,16 @@ vfile@^4.0.0: unist-util-stringify-position "^2.0.0" vfile-message "^2.0.0" +vm-browserify@1.1.2, vm-browserify@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" + integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== + +void-elements@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-3.1.0.tgz#614f7fbf8d801f0bb5f0661f5b2f5785750e4f09" + integrity sha1-YU9/v42AHwu18GYfWy9XhXUOTwk= + vscode-textmate@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-5.2.0.tgz#01f01760a391e8222fe4f33fbccbd1ad71aed74e" @@ -13304,7 +11864,14 @@ walker@^1.0.7: dependencies: makeerror "1.0.x" -watchpack@^2.0.0: +warning@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3" + integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w== + dependencies: + loose-envify "^1.0.0" + +watchpack@2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.1.1.tgz#e99630550fca07df9f90a06056987baa40a689c7" integrity sha512-Oo7LXCmc1eE1AjyuSBmtC3+Wy4HcV8PxWh2kP6fOl8yTlNS7r0K9l1ao2lrrUza7V39Y3D/BbJgY8VeSlc5JKw== @@ -13312,12 +11879,13 @@ watchpack@^2.0.0: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" -wbuf@^1.1.0, wbuf@^1.7.3: - version "1.7.3" - resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" - integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== +watchpack@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.2.0.tgz#47d78f5415fe550ecd740f99fe2882323a58b1ce" + integrity sha512-up4YAn/XHgZHIxFBVCdlMiWDj6WaLKpwVeGQk2I5thdYxF/KmF0aaz6TfJZ/hfl1h/XlcDr7k1KH7ThDagpFaA== dependencies: - minimalistic-assert "^1.0.0" + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" wcwidth@^1.0.1: version "1.0.1" @@ -13331,6 +11899,11 @@ web-namespaces@^1.0.0, web-namespaces@^1.1.2: resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-1.1.4.tgz#bc98a3de60dadd7faefc403d1076d529f5e030ec" integrity sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw== +webidl-conversions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" + integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== + webidl-conversions@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff" @@ -13341,10 +11914,10 @@ webidl-conversions@^6.1.0: resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514" integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w== -webpack-bundle-analyzer@^4.4.2: - version "4.4.2" - resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.4.2.tgz#39898cf6200178240910d629705f0f3493f7d666" - integrity sha512-PIagMYhlEzFfhMYOzs5gFT55DkUdkyrJi/SxJp8EF3YMWhS+T9vvs2EoTetpk5qb6VsCq02eXTlRDOydRhDFAQ== +webpack-bundle-analyzer@4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.3.0.tgz#2f3c0ca9041d5ee47fa418693cf56b4a518b578b" + integrity sha512-J3TPm54bPARx6QG8z4cKBszahnUglcv70+N+8gUqv2I5KOFHJbzBiLx+pAp606so0X004fxM7hqRu10MLjJifA== dependencies: acorn "^8.0.4" acorn-walk "^8.0.0" @@ -13356,80 +11929,6 @@ webpack-bundle-analyzer@^4.4.2: sirv "^1.0.7" ws "^7.3.1" -webpack-dev-middleware@^3.7.2: - version "3.7.3" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz#0639372b143262e2b84ab95d3b91a7597061c2c5" - integrity sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ== - dependencies: - memory-fs "^0.4.1" - mime "^2.4.4" - mkdirp "^0.5.1" - range-parser "^1.2.1" - webpack-log "^2.0.0" - -webpack-dev-server@^3.11.2: - version "3.11.2" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.11.2.tgz#695ebced76a4929f0d5de7fd73fafe185fe33708" - integrity sha512-A80BkuHRQfCiNtGBS1EMf2ChTUs0x+B3wGDFmOeT4rmJOHhHTCH2naNxIHhmkr0/UillP4U3yeIyv1pNp+QDLQ== - dependencies: - ansi-html "0.0.7" - bonjour "^3.5.0" - chokidar "^2.1.8" - compression "^1.7.4" - connect-history-api-fallback "^1.6.0" - debug "^4.1.1" - del "^4.1.1" - express "^4.17.1" - html-entities "^1.3.1" - http-proxy-middleware "0.19.1" - import-local "^2.0.0" - internal-ip "^4.3.0" - ip "^1.1.5" - is-absolute-url "^3.0.3" - killable "^1.0.1" - loglevel "^1.6.8" - opn "^5.5.0" - p-retry "^3.0.1" - portfinder "^1.0.26" - schema-utils "^1.0.0" - selfsigned "^1.10.8" - semver "^6.3.0" - serve-index "^1.9.1" - sockjs "^0.3.21" - sockjs-client "^1.5.0" - spdy "^4.0.2" - strip-ansi "^3.0.1" - supports-color "^6.1.0" - url "^0.11.0" - webpack-dev-middleware "^3.7.2" - webpack-log "^2.0.0" - ws "^6.2.1" - yargs "^13.3.2" - -webpack-log@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/webpack-log/-/webpack-log-2.0.0.tgz#5b7928e0637593f119d32f6227c1e0ac31e1b47f" - integrity sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg== - dependencies: - ansi-colors "^3.0.0" - uuid "^3.3.2" - -webpack-merge@^5.7.3: - version "5.7.3" - resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.7.3.tgz#2a0754e1877a25a8bbab3d2475ca70a052708213" - integrity sha512-6/JUQv0ELQ1igjGDzHkXbVDRxkfA57Zw7PfiupdLFJYrgFqY5ZP8xxbpp2lU3EPwYx89ht5Z/aDkD40hFCm5AA== - dependencies: - clone-deep "^4.0.1" - wildcard "^2.0.0" - -webpack-sources@^1.1.0, webpack-sources@^1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" - integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== - dependencies: - source-list-map "^2.0.0" - source-map "~0.6.1" - webpack-sources@^2.1.1: version "2.2.0" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-2.2.0.tgz#058926f39e3d443193b6c31547229806ffd02bac" @@ -13438,7 +11937,7 @@ webpack-sources@^2.1.1: source-list-map "^2.0.1" source-map "^0.6.1" -webpack@^5.28.0, webpack@^5.37.0: +webpack@^5: version "5.37.1" resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.37.1.tgz#2deb5acd350583c1ab9338471f323381b0b0c14b" integrity sha512-btZjGy/hSjCAAVHw+cKG+L0M+rstlyxbO2C+BOTaQ5/XAnxkDrP5sVbqWhXgo4pL3X2dcOib6rqCP20Zr9PLow== @@ -13467,34 +11966,6 @@ webpack@^5.28.0, webpack@^5.37.0: watchpack "^2.0.0" webpack-sources "^2.1.1" -webpackbar@^5.0.0-3: - version "5.0.0-3" - resolved "https://registry.yarnpkg.com/webpackbar/-/webpackbar-5.0.0-3.tgz#f4f96c8fb13001b2bb1348252db4c980ab93aaac" - integrity sha512-viW6KCYjMb0NPoDrw2jAmLXU2dEOhRrtku28KmOfeE1vxbfwCYuTbTaMhnkrCZLFAFyY9Q49Z/jzYO80Dw5b8g== - dependencies: - ansi-escapes "^4.3.1" - chalk "^4.1.0" - consola "^2.15.0" - figures "^3.2.0" - pretty-time "^1.1.0" - std-env "^2.2.1" - text-table "^0.2.0" - wrap-ansi "^7.0.0" - -websocket-driver@>=0.5.1, websocket-driver@^0.7.4: - version "0.7.4" - resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" - integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== - dependencies: - http-parser-js ">=0.5.1" - safe-buffer ">=5.1.0" - websocket-extensions ">=0.1.1" - -websocket-extensions@>=0.1.1: - version "0.1.4" - resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" - integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== - whatwg-encoding@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" @@ -13512,6 +11983,15 @@ whatwg-mimetype@^2.3.0: resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== +whatwg-url@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" + integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg== + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + whatwg-url@^8.0.0, whatwg-url@^8.5.0: version "8.5.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.5.0.tgz#7752b8464fc0903fec89aa9846fc9efe07351fd3" @@ -13545,7 +12025,20 @@ which-pm@2.0.0: load-yaml-file "^0.2.0" path-exists "^4.0.0" -which@^1.2.9, which@^1.3.1: +which-typed-array@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.4.tgz#8fcb7d3ee5adf2d771066fba7cf37e32fe8711ff" + integrity sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA== + dependencies: + available-typed-arrays "^1.0.2" + call-bind "^1.0.0" + es-abstract "^1.18.0-next.1" + foreach "^2.0.5" + function-bind "^1.1.1" + has-symbols "^1.0.1" + is-typed-array "^1.1.3" + +which@^1.2.9: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== @@ -13566,18 +12059,6 @@ widest-line@^2.0.0: dependencies: string-width "^2.1.1" -widest-line@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" - integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg== - dependencies: - string-width "^4.0.0" - -wildcard@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec" - integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw== - word-wrap@^1.2.3, word-wrap@~1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" @@ -13588,22 +12069,6 @@ wordwrap@^1.0.0: resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= -worker-rpc@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/worker-rpc/-/worker-rpc-0.1.1.tgz#cb565bd6d7071a8f16660686051e969ad32f54d5" - integrity sha512-P1WjMrUB3qgJNI9jfmpZ/htmBEjFh//6l/5y8SD9hg1Ef5zTTVVoRjTrTEzPrNBQvmhMxkoTsjOXN10GWU7aCg== - dependencies: - microevent.ts "~0.1.1" - -wrap-ansi@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" - integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== - dependencies: - ansi-styles "^3.2.0" - string-width "^3.0.0" - strip-ansi "^5.0.0" - wrap-ansi@^6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" @@ -13667,29 +12132,15 @@ write-pkg@^4.0.0: type-fest "^0.4.1" write-json-file "^3.2.0" -ws@7.4.6, "ws@^5.2.0 || ^6.0.0 || ^7.0.0", ws@^7.3.1, ws@^7.4.5: - version "7.4.6" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" - integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== - -ws@^6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb" - integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA== - dependencies: - async-limiter "~1.0.0" - -xdg-basedir@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13" - integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q== +ws@7.5.2, "ws@^5.2.0 || ^6.0.0 || ^7.0.0", ws@^7.4.5: + version "7.5.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.2.tgz#09cc8fea3bec1bc5ed44ef51b42f945be36900f6" + integrity sha512-lkF7AWRicoB9mAgjeKbGqVUekLnSNO4VjKVnuPHpQeOxZOErX6BPXwJk70nFslRCEEA8EVW7ZjKwXaP9N+1sKQ== -xml-js@^1.6.11: - version "1.6.11" - resolved "https://registry.yarnpkg.com/xml-js/-/xml-js-1.6.11.tgz#927d2f6947f7f1c19a316dd8eea3614e8b18f8e9" - integrity sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g== - dependencies: - sax "^1.2.4" +ws@^7.3.1: + version "7.5.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.3.tgz#160835b63c7d97bfab418fc1b8a9fced2ac01a74" + integrity sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg== xml-name-validator@^3.0.0: version "3.0.0" @@ -13736,7 +12187,7 @@ yaml-ast-parser@^0.0.43: resolved "https://registry.yarnpkg.com/yaml-ast-parser/-/yaml-ast-parser-0.0.43.tgz#e8a23e6fb4c38076ab92995c5dca33f3d3d7c9bb" integrity sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A== -yaml@^1.10.0, yaml@^1.7.2: +yaml@^1.10.0, yaml@^1.10.2, yaml@^1.7.2: version "1.10.2" resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== @@ -13746,14 +12197,6 @@ yargs-parser@20.x, yargs-parser@^20.2.2: resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.7.tgz#61df85c113edfb5a7a4e36eb8aa60ef423cbc90a" integrity sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw== -yargs-parser@^13.1.2: - version "13.1.2" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" - integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - yargs-parser@^18.1.1, yargs-parser@^18.1.3: version "18.1.3" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" @@ -13762,6 +12205,11 @@ yargs-parser@^18.1.1, yargs-parser@^18.1.3: camelcase "^5.0.0" decamelize "^1.2.0" +yargs-parser@^20.2.7: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + yargs@15.3.1, yargs@^15.1.0, yargs@^15.3.1: version "15.3.1" resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.3.1.tgz#9505b472763963e54afe60148ad27a330818e98b" @@ -13779,22 +12227,6 @@ yargs@15.3.1, yargs@^15.1.0, yargs@^15.3.1: y18n "^4.0.0" yargs-parser "^18.1.1" -yargs@^13.3.2: - version "13.3.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" - integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== - dependencies: - cliui "^5.0.0" - find-up "^3.0.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" - which-module "^2.0.0" - y18n "^4.0.0" - yargs-parser "^13.1.2" - yargs@^16.0.3, yargs@^16.2.0: version "16.2.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" @@ -13818,6 +12250,11 @@ zen-observable@^0.8.14: resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.15.tgz#96415c512d8e3ffd920afd3889604e30b9eaac15" integrity sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ== +zustand@^3.5.5: + version "3.5.5" + resolved "https://registry.yarnpkg.com/zustand/-/zustand-3.5.5.tgz#628458ad70621ddc2a17dbee49be963e5c0dccb5" + integrity sha512-iTiJoxzYFtiD7DhscgwK2P4Kft1JcZEI2U7mG8IxiOFM4KpBAiJZfFop3r/3wbCuyltXI6ph1Fx90e4j/S43XA== + zwitch@^1.0.0: version "1.0.5" resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-1.0.5.tgz#d11d7381ffed16b742f6af7b3f223d5cd9fe9920"