diff --git a/.changeset/green-lions-grow.md b/.changeset/green-lions-grow.md new file mode 100644 index 00000000000..68392dcb38d --- /dev/null +++ b/.changeset/green-lions-grow.md @@ -0,0 +1,5 @@ +--- +'@graphql-eslint/eslint-plugin': minor +--- + +GraphQL v16 support diff --git a/.github/workflows/canary.yml b/.github/workflows/canary.yml index 97023285fb3..ad63dc4d065 100644 --- a/.github/workflows/canary.yml +++ b/.github/workflows/canary.yml @@ -32,10 +32,10 @@ jobs: uses: actions/cache@v2 with: path: '**/node_modules' - key: ${{ runner.os }}-16-node-modules-${{ hashFiles('yarn.lock') }} + key: ${{ runner.os }}-16-8-16-node-modules-${{ hashFiles('yarn.lock') }} restore-keys: | - ${{ runner.os }}-16-node-modules-${{ hashFiles('yarn.lock') }} - ${{ runner.os }}-16-node-modules- + ${{ runner.os }}-16-8-16-node-modules-${{ hashFiles('yarn.lock') }} + ${{ runner.os }}-16-8-16-node-modules- - name: Install Dependencies using Yarn run: yarn install && git checkout yarn.lock && yarn patch-package - name: Release Canary diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d3a30a79e9e..c7d2bd7dc9e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -35,10 +35,10 @@ jobs: uses: actions/cache@v2 with: path: '**/node_modules' - key: ${{ runner.os }}-16-node-modules-${{ hashFiles('yarn.lock') }} + key: ${{ runner.os }}-16-8-16-node-modules-${{ hashFiles('yarn.lock') }} restore-keys: | - ${{ runner.os }}-16-node-modules-${{ hashFiles('yarn.lock') }} - ${{ runner.os }}-16-node-modules- + ${{ runner.os }}-16-8-16-node-modules-${{ hashFiles('yarn.lock') }} + ${{ runner.os }}-16-8-16-node-modules- - name: Install Dependencies using Yarn run: yarn install && git checkout yarn.lock && yarn patch-package - name: Create Release Pull Request or Publish to npm diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 402c950139e..c538690afec 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -25,10 +25,10 @@ jobs: uses: actions/cache@v2 with: path: '**/node_modules' - key: ${{ runner.os }}-16-node-modules-${{ hashFiles('yarn.lock') }} + key: ${{ runner.os }}-16-8-16-node-modules-${{ hashFiles('yarn.lock') }} restore-keys: | - ${{ runner.os }}-16-node-modules-${{ hashFiles('yarn.lock') }} - ${{ runner.os }}-16-node-modules- + ${{ runner.os }}-16-8-16-node-modules-${{ hashFiles('yarn.lock') }} + ${{ runner.os }}-16-8-16-node-modules- - name: Install Dependencies using Yarn run: yarn install && git checkout yarn.lock - name: Lint @@ -36,6 +36,12 @@ jobs: typecheck: name: TypeScript Type Checking runs-on: ubuntu-latest + strategy: + matrix: + graphql_version: + # - 14 + - 15 + - 16 steps: - name: Checkout Master uses: actions/checkout@v2 @@ -49,10 +55,12 @@ jobs: uses: actions/cache@v2 with: path: '**/node_modules' - key: ${{ runner.os }}-16-node-modules-${{ hashFiles('yarn.lock') }} + key: ${{runner.os}}-16-8-${{matrix.graphql_version}}-node-modules-${{hashFiles('yarn.lock')}} restore-keys: | - ${{ runner.os }}-16-node-modules-${{ hashFiles('yarn.lock') }} - ${{ runner.os }}-16-node-modules- + ${{runner.os}}-16-8-${{matrix.graphql_version}}-node-modules-${{hashFiles('yarn.lock')}} + ${{runner.os}}-16-8-${{matrix.graphql_version}}-node-modules- + - name: Use GraphQL v${{matrix.graphql_version}} + run: node ./scripts/match-graphql.js ${{matrix.graphql_version}} - name: Install Dependencies using Yarn run: yarn install && git checkout yarn.lock - name: Build @@ -64,14 +72,18 @@ jobs: path: packages/plugin/dist test: - name: Testing on Node ${{matrix.node_version}} with ESLint v${{matrix.eslint_version}} + name: Testing on Node ${{matrix.node_version}} with ESLint v${{matrix.eslint_version}} and GraphQL v${{matrix.graphql_version}} timeout-minutes: 60 runs-on: ubuntu-latest - needs: [lint, typecheck] + needs: [typecheck] strategy: matrix: node_version: [12, 16] eslint_version: [7.32.0, 8] + graphql_version: + # - 14 + - 15 + - 16 steps: - name: Checkout Master uses: actions/checkout@v2 @@ -85,10 +97,12 @@ jobs: uses: actions/cache@v2 with: path: '**/node_modules' - key: ${{runner.os}}-${{matrix.node_version}}-${{matrix.eslint_version}}-node-modules-${{hashFiles('yarn.lock')}} + key: ${{runner.os}}-${{matrix.node_version}}-${{matrix.eslint_version}}-${{matrix.graphql_version}}-node-modules-${{hashFiles('yarn.lock')}} restore-keys: | - ${{runner.os}}-${{matrix.node_version}}-${{matrix.eslint_version}}-node-modules-${{hashFiles('yarn.lock')}} - ${{runner.os}}-${{matrix.node_version}}-${{matrix.eslint_version}}-node-modules- + ${{runner.os}}-${{matrix.node_version}}-${{matrix.eslint_version}}-${{matrix.graphql_version}}-node-modules-${{hashFiles('yarn.lock')}} + ${{runner.os}}-${{matrix.node_version}}-${{matrix.eslint_version}}-${{matrix.graphql_version}}-node-modules- + - name: Use GraphQL v${{matrix.graphql_version}} + run: node ./scripts/match-graphql.js ${{matrix.graphql_version}} - name: Use ESLint v${{matrix.eslint_version}} run: node scripts/match-eslint.mjs ${{matrix.eslint_version}} - name: Install Dependencies using Yarn diff --git a/.vscode/settings.json b/.vscode/settings.json index 4718ffd990e..ed5e943f71d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,14 @@ { - "eslint.enable": true + "eslint.enable": true, + "files.exclude": { + "**/.git": true, + "**/.DS_Store": true, + "**/node_modules": true, + "test-lib": true, + "lib": true, + "coverage": true, + "npm": true, + "**/dist": true + }, + "typescript.tsdk": "node_modules/typescript/lib" } \ No newline at end of file diff --git a/babel.config.js b/babel.config.js index e6ffbd417e7..3e4899f4a74 100644 --- a/babel.config.js +++ b/babel.config.js @@ -1,3 +1,6 @@ module.exports = { - presets: [['@babel/preset-env', { targets: { node: 'current' } }], '@babel/preset-typescript'], + presets: [ + ['@babel/preset-env', { targets: { node: process.versions.node.split('.')[0] } }], + '@babel/preset-typescript', + ], }; diff --git a/examples/basic/package.json b/examples/basic/package.json index ab2dc4f162b..041273240c1 100644 --- a/examples/basic/package.json +++ b/examples/basic/package.json @@ -9,7 +9,7 @@ "lint": "eslint ." }, "dependencies": { - "graphql": "15.7.1" + "graphql": "16.0.1" }, "devDependencies": { "@graphql-eslint/eslint-plugin": "2.3.2", diff --git a/examples/code-file/package.json b/examples/code-file/package.json index 7ca15b2f0b8..cc848ad97c7 100644 --- a/examples/code-file/package.json +++ b/examples/code-file/package.json @@ -9,7 +9,7 @@ "lint": "eslint ." }, "dependencies": { - "graphql": "15.7.1" + "graphql": "16.0.1" }, "devDependencies": { "@graphql-eslint/eslint-plugin": "2.3.2", diff --git a/examples/graphql-config-code-file/package.json b/examples/graphql-config-code-file/package.json index d90638cd1f9..d6dd566ada8 100644 --- a/examples/graphql-config-code-file/package.json +++ b/examples/graphql-config-code-file/package.json @@ -9,7 +9,7 @@ "lint": "eslint --ext graphql,js ." }, "dependencies": { - "graphql": "15.7.1", + "graphql": "16.0.1", "graphql-tag": "^2.12.5" }, "devDependencies": { diff --git a/examples/graphql-config/package.json b/examples/graphql-config/package.json index ddce1f40ace..f48fb2e7327 100644 --- a/examples/graphql-config/package.json +++ b/examples/graphql-config/package.json @@ -9,7 +9,7 @@ "lint": "eslint ." }, "dependencies": { - "graphql": "15.7.1" + "graphql": "16.0.1" }, "devDependencies": { "@graphql-eslint/eslint-plugin": "2.3.2", diff --git a/examples/prettier/package.json b/examples/prettier/package.json index 7aebc6469c3..73baab240ba 100644 --- a/examples/prettier/package.json +++ b/examples/prettier/package.json @@ -9,7 +9,7 @@ "lint": "eslint ." }, "dependencies": { - "graphql": "15.7.1" + "graphql": "16.0.1" }, "devDependencies": { "@graphql-eslint/eslint-plugin": "2.3.2", diff --git a/package.json b/package.json index 95a504bbba2..0bb7682f1e6 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,8 @@ "typescript": "4.4.4" }, "resolutions": { - "@changesets/git": "1.1.2" + "@changesets/git": "1.1.2", + "graphql": "16.0.1" }, "lint-staged": { "{packages,scripts}/**/*.{ts,tsx,js,jsx,cjs,mjs}": [ diff --git a/packages/plugin/package.json b/packages/plugin/package.json index 366448578e8..a7ddb471971 100644 --- a/packages/plugin/package.json +++ b/packages/plugin/package.json @@ -41,7 +41,7 @@ "@types/graphql-depth-limit": "1.1.3", "@types/lodash.lowercase": "4.3.6", "bob-the-bundler": "1.5.1", - "graphql": "15.7.2", + "graphql": "16.0.1", "typescript": "4.4.4" }, "peerDependencies": { diff --git a/packages/plugin/src/estree-parser/converter.ts b/packages/plugin/src/estree-parser/converter.ts index 833fdf02221..61aad877c7a 100644 --- a/packages/plugin/src/estree-parser/converter.ts +++ b/packages/plugin/src/estree-parser/converter.ts @@ -1,15 +1,14 @@ import { convertDescription, convertLocation, convertRange, extractCommentsFromAst } from './utils'; import { GraphQLESTreeNode, SafeGraphQLType } from './estree-ast'; -import { ASTNode, TypeNode, TypeInfo, visit, visitWithTypeInfo, Location, Kind, DocumentNode } from 'graphql'; -import { Comment } from 'estree'; +import { ASTNode, TypeNode, TypeInfo, visit, visitWithTypeInfo, Location, Kind, DocumentNode, ASTVisitor } from 'graphql'; export function convertToESTree( node: T, typeInfo?: TypeInfo -): { rootTree: GraphQLESTreeNode; comments: Comment[] } { - const visitor = { leave: convertNode(typeInfo) }; +) { + const visitor: ASTVisitor = { leave: convertNode(typeInfo) }; return { - rootTree: visit(node, typeInfo ? visitWithTypeInfo(typeInfo, visitor) : visitor), + rootTree: visit(node, typeInfo ? visitWithTypeInfo(typeInfo, visitor) : visitor) as GraphQLESTreeNode, comments: extractCommentsFromAst(node.loc), }; } diff --git a/packages/plugin/src/graphql-ast.ts b/packages/plugin/src/graphql-ast.ts index 28eb0dc1e99..27cea4c2bea 100644 --- a/packages/plugin/src/graphql-ast.ts +++ b/packages/plugin/src/graphql-ast.ts @@ -1,9 +1,8 @@ import { ASTNode, - Visitor, + ASTVisitor, TypeInfo, GraphQLSchema, - ASTKindToNode, visit, isInterfaceType, visitWithTypeInfo, @@ -41,7 +40,7 @@ export function getReachableTypes(schema: GraphQLSchema): ReachableTypes { } }; - const visitor: Visitor = { + const visitor: ASTVisitor = { InterfaceTypeDefinition: collect, ObjectTypeDefinition: collect, InputValueDefinition: collect, diff --git a/packages/plugin/src/parser.ts b/packages/plugin/src/parser.ts index a5f3d8bcfb0..6f18761bb83 100644 --- a/packages/plugin/src/parser.ts +++ b/packages/plugin/src/parser.ts @@ -1,5 +1,5 @@ import { parseGraphQLSDL } from '@graphql-tools/utils'; -import { GraphQLError, TypeInfo } from 'graphql'; +import { ASTNode, GraphQLError, TypeInfo, Source } from 'graphql'; import { Linter } from 'eslint'; import { convertToESTree } from './estree-parser'; import { GraphQLESLintParseResult, ParserOptions, ParserServices } from './types'; @@ -32,8 +32,8 @@ export function parseForESLint(code: string, options: ParserOptions = {}): Graph noLocation: false, }); - const { rootTree, comments } = convertToESTree(graphqlAst.document, schema ? new TypeInfo(schema) : null); - const tokens = extractTokens(code); + const { rootTree, comments } = convertToESTree(graphqlAst.document as ASTNode, schema ? new TypeInfo(schema) : null); + const tokens = extractTokens(new Source(code, filePath)); return { services: parserServices, diff --git a/packages/plugin/src/rules/graphql-js-validation.ts b/packages/plugin/src/rules/graphql-js-validation.ts index 6e40d31439a..df13823f778 100644 --- a/packages/plugin/src/rules/graphql-js-validation.ts +++ b/packages/plugin/src/rules/graphql-js-validation.ts @@ -22,7 +22,7 @@ export function validateDoc( ): void { if (documentNode?.definitions?.length > 0) { try { - const validationErrors = schema ? validate(schema, documentNode, rules) : validateSDL(documentNode, null, rules); + const validationErrors = schema ? validate(schema, documentNode, rules) : validateSDL(documentNode, null, rules as any); for (const error of validationErrors) { const validateRuleName = ruleName || `[${extractRuleName(error.stack)}]`; diff --git a/packages/plugin/src/rules/no-deprecated.ts b/packages/plugin/src/rules/no-deprecated.ts index 047472331f4..6ca1b3466e5 100644 --- a/packages/plugin/src/rules/no-deprecated.ts +++ b/packages/plugin/src/rules/no-deprecated.ts @@ -86,7 +86,7 @@ const rule: GraphQLESLintRule<[], true> = { const typeInfo = node.typeInfo(); if (typeInfo && typeInfo.enumValue) { - if (typeInfo.enumValue.isDeprecated) { + if (typeInfo.enumValue.deprecationReason) { const enumValueName = node.value; context.report({ loc: getLocation(node.loc, enumValueName), @@ -104,7 +104,7 @@ const rule: GraphQLESLintRule<[], true> = { const typeInfo = node.typeInfo(); if (typeInfo && typeInfo.fieldDef) { - if (typeInfo.fieldDef.isDeprecated) { + if (typeInfo.fieldDef.deprecationReason) { const fieldName = node.name.value; context.report({ loc: getLocation(node.loc, fieldName), diff --git a/packages/plugin/src/rules/require-description.ts b/packages/plugin/src/rules/require-description.ts index e50095dbc60..3125e166adf 100644 --- a/packages/plugin/src/rules/require-description.ts +++ b/packages/plugin/src/rules/require-description.ts @@ -49,7 +49,7 @@ const rule: GraphQLESLintRule = { examples: [ { title: 'Incorrect', - usage: [{ on: ['ObjectTypeDefinition', 'FieldDefinition'] }], + usage: [{ on: [Kind.OBJECT_TYPE_DEFINITION, Kind.FIELD_DEFINITION] }], code: /* GraphQL */ ` type someTypeName { name: String @@ -58,7 +58,7 @@ const rule: GraphQLESLintRule = { }, { title: 'Correct', - usage: [{ on: ['ObjectTypeDefinition', 'FieldDefinition'] }], + usage: [{ on: [Kind.OBJECT_TYPE_DEFINITION, Kind.FIELD_DEFINITION] }], code: /* GraphQL */ ` """ Some type description diff --git a/packages/plugin/src/sibling-operations.ts b/packages/plugin/src/sibling-operations.ts index 09989021a68..ee17368c69b 100644 --- a/packages/plugin/src/sibling-operations.ts +++ b/packages/plugin/src/sibling-operations.ts @@ -120,7 +120,7 @@ export function getSiblingOperations(options: ParserOptions, gqlConfig: GraphQLC if (definition.kind === Kind.FRAGMENT_DEFINITION) { result.push({ filePath: source.location, - document: definition, + document: definition as FragmentDefinitionNode, }); } } @@ -141,7 +141,7 @@ export function getSiblingOperations(options: ParserOptions, gqlConfig: GraphQLC if (definition.kind === Kind.OPERATION_DEFINITION) { result.push({ filePath: source.location, - document: definition, + document: definition as OperationDefinitionNode, }); } } diff --git a/packages/plugin/src/utils.ts b/packages/plugin/src/utils.ts index 82a268481a1..182b299f798 100644 --- a/packages/plugin/src/utils.ts +++ b/packages/plugin/src/utils.ts @@ -77,8 +77,8 @@ function getLexer(source: Source): Lexer { throw new Error(`Unsupported GraphQL version! Please make sure to use GraphQL v14 or newer!`); } -export function extractTokens(source: string): AST.Token[] { - const lexer = getLexer(new Source(source)); +export function extractTokens(source: Source): AST.Token[] { + const lexer = getLexer(source); const tokens: AST.Token[] = []; let token = lexer.advance(); diff --git a/packages/plugin/tests/mocks/graphql-server.ts b/packages/plugin/tests/mocks/graphql-server.ts index 71b5050cbfa..a1483adbfdc 100644 --- a/packages/plugin/tests/mocks/graphql-server.ts +++ b/packages/plugin/tests/mocks/graphql-server.ts @@ -1,11 +1,13 @@ +// eslint-disable-next-line @typescript-eslint/ban-ts-comment -- ignore type errors from `graphql` package +// @ts-nocheck import { readFileSync } from 'fs'; import { resolve } from 'path'; import { createServer, Server, IncomingMessage, ServerResponse } from 'http'; -import { buildSchema, getIntrospectionQuery, graphqlSync } from 'graphql'; +import { buildSchema, introspectionFromSchema } from 'graphql'; const sdlSchema = readFileSync(resolve(__dirname, 'user-schema.graphql'), 'utf8'); const graphqlSchemaObj = buildSchema(sdlSchema); -const introspectionQueryResult = graphqlSync(graphqlSchemaObj, getIntrospectionQuery()); +const introspectionQueryResult = introspectionFromSchema(graphqlSchemaObj); class TestGraphQLServer { private server: Server; @@ -38,7 +40,9 @@ class TestGraphQLServer { if (pathname === '/') { const { query } = await this.parseData(req); if (query.includes('query IntrospectionQuery')) { - res.end(JSON.stringify(introspectionQueryResult)); + res.end(JSON.stringify({ + data: introspectionQueryResult + })); } } else if (pathname === '/my-headers') { res.end(JSON.stringify(req.headers)); diff --git a/packages/plugin/tests/schema.spec.ts b/packages/plugin/tests/schema.spec.ts index 9012a26acfd..7c533ca4127 100644 --- a/packages/plugin/tests/schema.spec.ts +++ b/packages/plugin/tests/schema.spec.ts @@ -17,7 +17,7 @@ describe('schema', () => { expect(graphQLSchema).toBeInstanceOf(GraphQLSchema); const sdlString = printSchema(graphQLSchema); - expect(sdlString).toBe(schemaOnDisk); + expect(sdlString.trim()).toBe(schemaOnDisk.trim()); }; describe('GraphQLFileLoader', () => { @@ -54,6 +54,9 @@ describe('schema', () => { url = chunk.toString().trimRight(); done(); }); + local.stderr.on('data', chunk => { + throw new Error(chunk.toString().trimRight()); + }); }); afterAll(done => { diff --git a/patches/eslint+8.1.0.patch b/patches/eslint+8.1.0.patch index 8a892127602..bfaa9aa569f 100644 --- a/patches/eslint+8.1.0.patch +++ b/patches/eslint+8.1.0.patch @@ -1,8 +1,8 @@ diff --git a/node_modules/eslint/lib/rule-tester/rule-tester.js b/node_modules/eslint/lib/rule-tester/rule-tester.js -index 324af7b..e771420 100644 +index 7f590a5..5368321 100644 --- a/node_modules/eslint/lib/rule-tester/rule-tester.js +++ b/node_modules/eslint/lib/rule-tester/rule-tester.js -@@ -943,8 +943,18 @@ class RuleTester { +@@ -946,7 +946,17 @@ class RuleTester { "Expected no autofixes to be suggested" ); } else { @@ -21,4 +21,3 @@ index 324af7b..e771420 100644 } } else { assert.strictEqual( - result.output, diff --git a/scripts/match-graphql.js b/scripts/match-graphql.js new file mode 100644 index 00000000000..c19a782ee92 --- /dev/null +++ b/scripts/match-graphql.js @@ -0,0 +1,21 @@ +const { writeFileSync } = require('fs'); +const { resolve } = require('path'); +const { argv } = require('process'); + +const pkgPath = resolve(__dirname, '../package.json'); + +const pkg = require(pkgPath); + +const version = argv[2]; + +pkg.resolutions = pkg.resolutions || {}; +if (pkg.resolutions.graphql.startsWith(version)) { + // eslint-disable-next-line no-console + console.info(`GraphQL v${version} is match! Skipping.`); + return; +} + +const npmVersion = version.includes('-') ? version : `^${version}`; +pkg.resolutions.graphql = npmVersion; + +writeFileSync(pkgPath, JSON.stringify(pkg, null, 2), 'utf8'); diff --git a/yarn.lock b/yarn.lock index f16a46e94e3..bc479e35b2a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3923,22 +3923,10 @@ graphql-ws@^5.0.0: resolved "https://registry.yarnpkg.com/graphql-ws/-/graphql-ws-5.3.0.tgz#345f73686b639735f1f4ef0b9ea28e17c7f6a745" integrity sha512-53MbSTOmgx5i6hf3DHVD5PrXix1drDmt2ja8MW7NG+aTpKGzkXVLyNcyNpxme4SK8jVtIV6ZIHkiwirqN0efpw== -graphql@15.7.1: - version "15.7.1" - resolved "https://registry.yarnpkg.com/graphql/-/graphql-15.7.1.tgz#c821a1741e04e2bc2c91e138f34c06a86c0464f1" - integrity sha512-x34S6gC0/peBZnlK60zCJox/d45A7p6At9oN9EPA3qhoIAlR4LNZmXRLkICBckwwTMJzVdA8cx3QIQZMOl606A== - -graphql@15.7.2: - version "15.7.2" - resolved "https://registry.yarnpkg.com/graphql/-/graphql-15.7.2.tgz#85ab0eeb83722977151b3feb4d631b5f2ab287ef" - integrity sha512-AnnKk7hFQFmU/2I9YSQf3xw44ctnSFCfp3zE0N6W174gqe9fWG/2rKaKxROK7CcI3XtERpjEKFqts8o319Kf7A== - -graphql@^14.5.3: - version "14.7.0" - resolved "https://registry.yarnpkg.com/graphql/-/graphql-14.7.0.tgz#7fa79a80a69be4a31c27dda824dc04dac2035a72" - integrity sha512-l0xWZpoPKpppFzMfvVyFmp9vLN7w/ZZJPefUicMCepfJeQ8sMcztloGYY9DfjVPo6tIUDzU5Hw3MUbIjj9AVVA== - dependencies: - iterall "^1.2.2" +graphql@16.0.1, graphql@^14.5.3: + version "16.0.1" + resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.0.1.tgz#93a13cd4e0e38ca8d0832e79614c8578bfd34f10" + integrity sha512-oPvCuu6dlLdiz8gZupJ47o1clgb72r1u8NDBcQYjcV6G/iEdmE11B1bBlkhXRvV0LisP/SXRFP7tT6AgaTjpzg== hard-rejection@^2.1.0: version "2.1.0" @@ -4373,7 +4361,7 @@ istanbul-reports@^3.0.2: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" -iterall@^1.2.1, iterall@^1.2.2: +iterall@^1.2.1: version "1.3.0" resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.3.0.tgz#afcb08492e2915cbd8a0884eb93a8c94d0d72fea" integrity sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg==