diff --git a/.eslintrc.js b/.eslintrc.js index 5fc19b9..0cb21be 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,9 +1,20 @@ module.exports = { - extends: ['@khanacademy'], root: true, - parser: '@babel/eslint-parser', - plugins: ['flowtype-errors'], + plugins: ["prettier", "jest"], + extends: ["eslint:recommended", "prettier"], + parser: "@typescript-eslint/parser", + parserOptions: { + sourceType: "module", + ecmaVersion: 2020, + }, rules: { - 'prettier/prettier': ['error', {singleQuote: true}], + "prettier/prettier": "error", + "no-unused-vars": "off", + "no-case-declarations": "off", + }, + env: { + es6: true, + node: true, + jest: true, }, }; diff --git a/.github/workflows/changeset-release.yml b/.github/workflows/changeset-release.yml index 30fea6c..b6e0689 100644 --- a/.github/workflows/changeset-release.yml +++ b/.github/workflows/changeset-release.yml @@ -31,12 +31,10 @@ jobs: name: Release runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 + - uses: Khan/actions@shared-node-cache-v2 with: - fetch-depth: 0 - - uses: Khan/actions@shared-node-cache-v0.0.2 - with: - node-version: 16.x + node-version: 20.x - name: Create Release Pull Request or Publish to npm id: changesets diff --git a/.github/workflows/pr-checks.yml b/.github/workflows/pr-checks.yml index e504a81..7aa2ea1 100644 --- a/.github/workflows/pr-checks.yml +++ b/.github/workflows/pr-checks.yml @@ -14,45 +14,45 @@ jobs: strategy: matrix: os: [ubuntu-latest] - node-version: [16.x] + node-version: [20.x] steps: - - uses: actions/checkout@v2 - - uses: Khan/actions@shared-node-cache-v0 + - uses: actions/checkout@v4 + - uses: Khan/actions@shared-node-cache-v2 with: node-version: ${{ matrix.node-version }} - name: Get All Changed Files - uses: Khan/actions@get-changed-files-v1 + uses: Khan/actions@get-changed-files-v2 id: changed - - id: js-files - name: Find .js changed files - uses: Khan/actions@filter-files-v0 + - id: ts-files + name: Find .ts changed files + uses: Khan/actions@filter-files-v1 with: changed-files: ${{ steps.changed.outputs.files }} - extensions: '.js' + extensions: '.ts' - - name: Run Flow - if: steps.js-files.outputs.filtered != '[]' - run: yarn flow + - name: Run TypeScript + if: steps.ts-files.outputs.filtered != '[]' + run: yarn tsc - id: eslint-reset - uses: Khan/actions@filter-files-v0 + uses: Khan/actions@filter-files-v1 name: Files that would trigger a full eslint run with: changed-files: ${{ steps.changed.outputs.files }} files: '.eslintrc.js,package.json,.eslintignore' - - name: Eslint + - name: ESlint uses: Khan/actions@full-or-limited-v0 with: full-trigger: ${{ steps.eslint-reset.outputs.filtered }} - full: yarn eslint - limited-trigger: ${{ steps.js-files.outputs.filtered }} + full: yarn eslint src/**/*.ts + limited-trigger: ${{ steps.ts-files.outputs.filtered }} limited: yarn eslint {} - id: jest-reset - uses: Khan/actions@filter-files-v0 + uses: Khan/actions@filter-files-v0=1 name: Files that would trigger a full jest run with: changed-files: ${{ steps.changed.outputs.files }} @@ -63,5 +63,5 @@ jobs: with: full-trigger: ${{ steps.jest-reset.outputs.filtered }} full: yarn jest - limited-trigger: ${{ steps.js-files.outputs.filtered }} + limited-trigger: ${{ steps.ts-files.outputs.filtered }} limited: yarn jest --findRelatedTests {} diff --git a/.prettierrc b/.prettierrc index 3a4ff61..aef2408 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,7 +1,7 @@ { - "parser": "flow", + "parser": "typescript", "tabWidth": 4, "trailingComma": "all", "bracketSpacing": false, - "singleQuote": true + "singleQuote": false } diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..a3e7a00 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "editor.defaultFormatter": "dbaeumer.vscode-eslint", + "editor.formatOnPaste": true, + "editor.formatOnSave": true, + "eslint.format.enable": true +} diff --git a/package.json b/package.json index 1e2e245..7cf8043 100644 --- a/package.json +++ b/package.json @@ -17,20 +17,21 @@ "@babel/preset-env": "^7.16.11", "@babel/preset-typescript": "^7.22.5", "@changesets/cli": "^2.21.1", - "@khanacademy/eslint-config": "^0.1.0", + "@khanacademy/eslint-config": "^4.0.0", "@types/jest": "^29.5.3", + "@types/prop-types": "^15.7.12", + "@types/react": "^18.3.3", + "@typescript-eslint/eslint-plugin": "^7.17.0", + "@typescript-eslint/parser": "^7.17.0", "babel-jest": "23.4.2", - "eslint": "8.7.0", + "eslint": "^8.57.0", "eslint-config-prettier": "7.0.0", - "eslint-plugin-flowtype": "^8.0.3", - "eslint-plugin-flowtype-errors": "^4.5.0", - "eslint-plugin-jsx-a11y": "^6.5.1", + "eslint-plugin-jest": "^28.6.0", "eslint-plugin-prettier": "^4.0.0", - "eslint-plugin-react": "^7.29.2", - "eslint-plugin-react-hooks": "^4.3.0", - "flow-bin": "^0.172.0", "graphql-tag": "2.10.1", "jest": "^27.5.1", + "prettier": "^2.5.1", + "prettier-eslint": "^13.0.0", "typescript": "^5.1.6" }, "dependencies": { @@ -40,9 +41,7 @@ "@babel/types": "^7.17.0", "@khanacademy/wonder-stuff-core": "^1.5.1", "apollo-utilities": "^1.3.4", - "graphql": "^16.3.0", - "jsonschema": "^1.4.1", - "prettier": "^2.5.1", - "prettier-eslint": "^13.0.0" + "graphql": "^16.9.0", + "jsonschema": "^1.4.1" } } diff --git a/src/__test__/generateTypeFileContents.test.ts b/src/__test__/generateTypeFileContents.test.ts index a03dd56..4711f05 100644 --- a/src/__test__/generateTypeFileContents.test.ts +++ b/src/__test__/generateTypeFileContents.test.ts @@ -1,15 +1,16 @@ // Test the generate the type file contents +import {describe, it, expect} from "@jest/globals"; +import gql from "graphql-tag"; -import {getSchemas} from '../cli/config'; -import {generateTypeFileContents, indexPrelude} from '../generateTypeFiles'; -import gql from 'graphql-tag'; +import {getSchemas} from "../cli/config"; +import {generateTypeFileContents, indexPrelude} from "../generateTypeFiles"; -const [_, exampleSchema] = getSchemas(__dirname + '/example-schema.graphql'); +const [_, exampleSchema] = getSchemas(__dirname + "/example-schema.graphql"); -describe('generateTypeFileContents', () => { - it('split types should export response & variables types', () => { +describe("generateTypeFileContents", () => { + it("split types should export response & variables types", () => { const {indexContents, files} = generateTypeFileContents( - 'hello.js', + "hello.js", exampleSchema, gql` query Hello { @@ -18,9 +19,9 @@ describe('generateTypeFileContents', () => { } } `, - {splitTypes: true, schemaFilePath: ''}, - '__generated__', - indexPrelude('yarn queries'), + {splitTypes: true, schemaFilePath: ""}, + "__generated__", + indexPrelude("yarn queries"), ); expect(indexContents).toMatchInlineSnapshot(` "// AUTOGENERATED @@ -35,7 +36,7 @@ describe('generateTypeFileContents', () => { expect( Object.keys(files) .map((k: any) => `// ${k}\n${files[k]}`) - .join('\n\n'), + .join("\n\n"), ).toMatchInlineSnapshot(` "// __generated__/Hello.ts // AUTOGENERATED -- DO NOT EDIT @@ -56,9 +57,9 @@ describe('generateTypeFileContents', () => { `); }); - it('should respect the typeFileName option', () => { + it("should respect the typeFileName option", () => { const {files} = generateTypeFileContents( - 'hello.js', + "hello.js", exampleSchema, gql` query Hello { @@ -69,16 +70,16 @@ describe('generateTypeFileContents', () => { `, { splitTypes: true, - typeFileName: 'prefix-[operationName]-suffix.js', - schemaFilePath: '', + typeFileName: "prefix-[operationName]-suffix.js", + schemaFilePath: "", }, - '__generated__', - indexPrelude('yarn queries'), + "__generated__", + indexPrelude("yarn queries"), ); expect( Object.keys(files) .map((k: any) => `// ${k}\n${files[k]}`) - .join('\n\n'), + .join("\n\n"), ).toMatchInlineSnapshot(` "// __generated__/prefix-Hello-suffix.js // AUTOGENERATED -- DO NOT EDIT @@ -99,10 +100,10 @@ describe('generateTypeFileContents', () => { `); }); - describe('experimentalEnums', () => { - it('should generate the expected values', () => { + describe("experimentalEnums", () => { + it("should generate the expected values", () => { const {files} = generateTypeFileContents( - 'hello.js', + "hello.js", exampleSchema, gql` query Hello { @@ -113,15 +114,15 @@ describe('generateTypeFileContents', () => { `, { experimentalEnums: true, - schemaFilePath: '', + schemaFilePath: "", }, - '__generated__', - indexPrelude('yarn queries'), + "__generated__", + indexPrelude("yarn queries"), ); expect( Object.keys(files) .map((k: any) => `// ${k}\n${files[k]}`) - .join('\n\n'), + .join("\n\n"), ).toMatchInlineSnapshot(` "// __generated__/Hello.ts // AUTOGENERATED -- DO NOT EDIT diff --git a/src/__test__/graphql-flow.test.ts b/src/__test__/graphql-flow.test.ts index b728c1a..c6f4838 100644 --- a/src/__test__/graphql-flow.test.ts +++ b/src/__test__/graphql-flow.test.ts @@ -1,22 +1,21 @@ /** * Tests for our graphql flow generation! */ +import {describe, it, expect} from "@jest/globals"; +import gql from "graphql-tag"; -import {getSchemas} from '../cli/config'; -import {documentToFlowTypes} from '..'; -import gql from 'graphql-tag'; - -import type {GenerateConfig} from '../types'; +import {getSchemas} from "../cli/config"; +import {documentToFlowTypes} from ".."; +import type {GenerateConfig} from "../types"; // This allows us to "snapshot" a string cleanly. -/* eslint-disable flowtype-errors/uncovered */ + expect.addSnapshotSerializer({ - test: (value: any) => value && typeof value === 'string', + test: (value: any) => value && typeof value === "string", print: (value: any, _: any, __: any) => value, }); -/* eslint-enable flowtype-errors/uncovered */ -const [_, exampleSchema] = getSchemas(__dirname + '/example-schema.graphql'); +const [_, exampleSchema] = getSchemas(__dirname + "/example-schema.graphql"); const rawQueryToFlowTypes = ( query: string, @@ -24,8 +23,8 @@ const rawQueryToFlowTypes = ( ): string => { const node = gql(query); return documentToFlowTypes(node, exampleSchema, { - schemaFilePath: '', - scalars: {PositiveNumber: 'number'}, + schemaFilePath: "", + scalars: {PositiveNumber: "number"}, ...options, }) .map( @@ -34,13 +33,13 @@ const rawQueryToFlowTypes = ( Object.keys(extraTypes) .sort() .map((k: any) => `\nexport type ${k} = ${extraTypes[k]};`) - .join(''), + .join(""), ) - .join('\n\n'); + .join("\n\n"); }; -describe('graphql-flow generation', () => { - it('should allow custom scalars as input', () => { +describe("graphql-flow generation", () => { + it("should allow custom scalars as input", () => { const result = rawQueryToFlowTypes(` query SomeQuery($candies: PositiveNumber!) { candies(number: $candies) @@ -60,7 +59,7 @@ describe('graphql-flow generation', () => { `); }); - it('should split types', () => { + it("should split types", () => { const result = rawQueryToFlowTypes( ` query SomeQuery($id: String!) { @@ -87,7 +86,7 @@ describe('graphql-flow generation', () => { `); }); - it('should work with a basic query', () => { + it("should work with a basic query", () => { const result = rawQueryToFlowTypes(` query SomeQuery { human(id: "Han Solo") { @@ -123,7 +122,7 @@ describe('graphql-flow generation', () => { `); }); - it('renames', () => { + it("renames", () => { const result = rawQueryToFlowTypes(` query SomeQuery { human(id: "Han Solo") { @@ -147,7 +146,7 @@ describe('graphql-flow generation', () => { `); }); - it('should work with unions', () => { + it("should work with unions", () => { const result = rawQueryToFlowTypes(` query SomeQuery { friend(id: "Han Solo") { @@ -184,7 +183,7 @@ describe('graphql-flow generation', () => { `); }); - it('should work with fragments on interface', () => { + it("should work with fragments on interface", () => { const result = rawQueryToFlowTypes(` query SomeQuery { human(id: "Han Solo") { @@ -275,7 +274,7 @@ describe('graphql-flow generation', () => { `); }); - it('should work with a readOnlyArray turned off', () => { + it("should work with a readOnlyArray turned off", () => { const result = rawQueryToFlowTypes( ` query SomeQuery { @@ -306,8 +305,8 @@ describe('graphql-flow generation', () => { `); }); - describe('Object properties', () => { - it('should reject invalid field', () => { + describe("Object properties", () => { + it("should reject invalid field", () => { expect(() => rawQueryToFlowTypes(` query SomeQuery { @@ -321,7 +320,7 @@ describe('graphql-flow generation', () => { ); }); - it('should reject an unknown fragment', () => { + it("should reject an unknown fragment", () => { expect(() => rawQueryToFlowTypes(` query SomeQuery { @@ -336,8 +335,8 @@ describe('graphql-flow generation', () => { }); }); - describe('Fragments', () => { - it('should resolve correctly, and produce a type file for the fragment', () => { + describe("Fragments", () => { + it("should resolve correctly, and produce a type file for the fragment", () => { const result = rawQueryToFlowTypes( `query Hello { hero(episode: JEDI) { @@ -380,7 +379,7 @@ describe('graphql-flow generation', () => { `); }); - it('Should specialize the fragment type correctly', () => { + it("Should specialize the fragment type correctly", () => { const result = rawQueryToFlowTypes( `query Deps { droid(id: "hello") { @@ -435,7 +434,7 @@ describe('graphql-flow generation', () => { }); }); - it('should generate all types when exportAllObjectTypes is set', () => { + it("should generate all types when exportAllObjectTypes is set", () => { const result = rawQueryToFlowTypes( ` query SomeQuery { @@ -488,8 +487,8 @@ describe('graphql-flow generation', () => { `); }); - describe('Input variables', () => { - it('should generate a variables type', () => { + describe("Input variables", () => { + it("should generate a variables type", () => { const result = rawQueryToFlowTypes( `query SomeQuery($id: String!, $episode: Episode) { human(id: $id) { @@ -531,7 +530,7 @@ describe('graphql-flow generation', () => { `); }); - it('should handle an inline fragment on an interface without a typeCondition', () => { + it("should handle an inline fragment on an interface without a typeCondition", () => { const result = rawQueryToFlowTypes( ` query SomeQuery { @@ -563,7 +562,7 @@ describe('graphql-flow generation', () => { `); }); - it('should handle an inline fragment on an object (not an interface)', () => { + it("should handle an inline fragment on an object (not an interface)", () => { const result = rawQueryToFlowTypes( ` query SomeQuery { @@ -594,7 +593,7 @@ describe('graphql-flow generation', () => { `); }); - it('should handle a complex input variable', () => { + it("should handle a complex input variable", () => { const result = rawQueryToFlowTypes( `mutation addCharacter($character: CharacterInput!) { addCharacter(character: $character) { diff --git a/src/__test__/processPragmas.test.ts b/src/__test__/processPragmas.test.ts index 4e94f38..2450bab 100644 --- a/src/__test__/processPragmas.test.ts +++ b/src/__test__/processPragmas.test.ts @@ -1,15 +1,16 @@ -import type {CrawlConfig, GenerateConfig} from '../types'; +import {describe, it, expect} from "@jest/globals"; -import {processPragmas} from '../generateTypeFiles'; +import type {CrawlConfig, GenerateConfig} from "../types"; +import {processPragmas} from "../generateTypeFiles"; -const pragma = '# @autogen\n'; -const loosePragma = '# @autogen-loose\n'; +const pragma = "# @autogen\n"; +const loosePragma = "# @autogen-loose\n"; -const baseGenerate: GenerateConfig = {schemaFilePath: ''}; -const baseCrawl: CrawlConfig = {root: ''}; +const baseGenerate: GenerateConfig = {schemaFilePath: ""}; +const baseCrawl: CrawlConfig = {root: ""}; -describe('processPragmas', () => { - it('should work with no pragmas', () => { +describe("processPragmas", () => { + it("should work with no pragmas", () => { expect( processPragmas(baseGenerate, baseCrawl, `query X { Y }`), ).toEqual({ @@ -18,7 +19,7 @@ describe('processPragmas', () => { }); }); - it('should reject query without required pragma', () => { + it("should reject query without required pragma", () => { expect( processPragmas( baseGenerate, @@ -28,7 +29,7 @@ describe('processPragmas', () => { ).toEqual({generate: false}); }); - it('should accept query with required pragma', () => { + it("should accept query with required pragma", () => { expect( processPragmas( baseGenerate, @@ -44,7 +45,7 @@ describe('processPragmas', () => { }); }); - it('should accept query with loose pragma', () => { + it("should accept query with loose pragma", () => { expect( processPragmas( baseGenerate, @@ -60,11 +61,11 @@ describe('processPragmas', () => { }); }); - it('should reject query with ignore pragma', () => { + it("should reject query with ignore pragma", () => { expect( processPragmas( baseGenerate, - {...baseCrawl, ignorePragma: '# @ignore\n'}, + {...baseCrawl, ignorePragma: "# @ignore\n"}, `query X { # @ignore Y diff --git a/src/cli/__test__/config.test.ts b/src/cli/__test__/config.test.ts index c0b7415..85b1f5a 100644 --- a/src/cli/__test__/config.test.ts +++ b/src/cli/__test__/config.test.ts @@ -1,113 +1,108 @@ -import type {Config} from '../../types'; +import {describe, it, expect} from "@jest/globals"; -import {findApplicableConfig, validateOrThrow} from '../config'; -import configSchema from '../../../schema.json'; +import type {Config} from "../../types"; +import {findApplicableConfig, validateOrThrow} from "../config"; +import configSchema from "../../../schema.json"; -describe('findApplicableConfig', () => { - it('should work with one that matches', () => { +describe("findApplicableConfig", () => { + it("should work with one that matches", () => { const config = { - schemaFilePath: 'ok.graphql', + schemaFilePath: "ok.graphql", } as const; - expect(findApplicableConfig('/hello', config)).toBe(config); + expect(findApplicableConfig("/hello", config)).toBe(config); }); - it('should be falsy if nothing matches', () => { + it("should be falsy if nothing matches", () => { const config = { - schemaFilePath: 'ok.graphql', + schemaFilePath: "ok.graphql", exclude: [/hello$/], } as const; - expect(findApplicableConfig('/hello', config as any)).toBeUndefined(); + expect(findApplicableConfig("/hello", config as any)).toBeUndefined(); }); - it('should match & exclude with multiple configs', () => { + it("should match & exclude with multiple configs", () => { const configs = [ - {schemaFilePath: 'one', match: [/\.jsx$/], exclude: [/^test/]}, - {schemaFilePath: 'two', exclude: [/^hello/]}, - {schemaFilePath: 'three'}, + {schemaFilePath: "one", match: [/\.jsx$/], exclude: [/^test/]}, + {schemaFilePath: "two", exclude: [/^hello/]}, + {schemaFilePath: "three"}, ]; - expect(findApplicableConfig('hello.js', configs)).toBe(configs[2]); - expect(findApplicableConfig('goodbye.js', configs)).toBe(configs[1]); - expect(findApplicableConfig('hello.jsx', configs)).toBe(configs[0]); - expect(findApplicableConfig('test.jsx', configs)).toBe(configs[1]); + expect(findApplicableConfig("hello.js", configs)).toBe(configs[2]); + expect(findApplicableConfig("goodbye.js", configs)).toBe(configs[1]); + expect(findApplicableConfig("hello.jsx", configs)).toBe(configs[0]); + expect(findApplicableConfig("test.jsx", configs)).toBe(configs[1]); }); }); -describe('jsonschema validation', () => { - it('should accept valid schema', () => { +describe("jsonschema validation", () => { + it("should accept valid schema", () => { const config: Config = { crawl: { - root: '/here/we/crawl', + root: "/here/we/crawl", }, generate: { match: [/\.fixture\.js$/], exclude: [ - '_test\\.js$', - '\\bcourse-editor-package\\b', - '\\.fixture\\.js$', - '\\b__flowtests__\\b', - '\\bcourse-editor\\b', + "_test\\.js$", + "\\bcourse-editor-package\\b", + "\\.fixture\\.js$", + "\\b__flowtests__\\b", + "\\bcourse-editor\\b", ], readOnlyArray: false, - regenerateCommand: 'make gqlflow', + regenerateCommand: "make gqlflow", scalars: { - JSONString: 'string', - KALocale: 'string', - NaiveDateTime: 'string', + JSONString: "string", + KALocale: "string", + NaiveDateTime: "string", }, splitTypes: true, - generatedDirectory: '__graphql-types__', + generatedDirectory: "__graphql-types__", exportAllObjectTypes: true, - schemaFilePath: './composed_schema.graphql', + schemaFilePath: "./composed_schema.graphql", }, }; - validateOrThrow( - config, - configSchema, // eslint-disable-line flowtype-errors/uncovered - ); + validateOrThrow(config, configSchema); }); - it('should accept a schema with multiple generate configs', () => { + it("should accept a schema with multiple generate configs", () => { const generate = { match: [/\.fixture\.js$/], exclude: [ - '_test\\.js$', - '\\bcourse-editor-package\\b', - '\\.fixture\\.js$', - '\\b__flowtests__\\b', - '\\bcourse-editor\\b', + "_test\\.js$", + "\\bcourse-editor-package\\b", + "\\.fixture\\.js$", + "\\b__flowtests__\\b", + "\\bcourse-editor\\b", ], readOnlyArray: false, - regenerateCommand: 'make gqlflow', + regenerateCommand: "make gqlflow", scalars: { - JSONString: 'string', - KALocale: 'string', - NaiveDateTime: 'string', + JSONString: "string", + KALocale: "string", + NaiveDateTime: "string", }, splitTypes: true, - generatedDirectory: '__graphql-types__', + generatedDirectory: "__graphql-types__", exportAllObjectTypes: true, - schemaFilePath: './composed_schema.graphql', + schemaFilePath: "./composed_schema.graphql", } as const; const config: Config = { crawl: { - root: '/here/we/crawl', + root: "/here/we/crawl", }, generate: [ {...generate, match: [/^static/], exportAllObjectTypes: false}, generate, ], }; - validateOrThrow( - config, - configSchema, // eslint-disable-line flowtype-errors/uncovered - ); + validateOrThrow(config, configSchema); }); - it('should reject invalid schema', () => { + it("should reject invalid schema", () => { expect(() => validateOrThrow( - {schemaFilePath: 10, options: {extraOption: 'hello'}}, - configSchema, // eslint-disable-line flowtype-errors/uncovered + {schemaFilePath: 10, options: {extraOption: "hello"}}, + configSchema, ), ).toThrowErrorMatchingInlineSnapshot(` "instance is not allowed to have the additional property \\"schemaFilePath\\" diff --git a/src/cli/config.ts b/src/cli/config.ts index 8e77f4d..1b87ae3 100644 --- a/src/cli/config.ts +++ b/src/cli/config.ts @@ -1,34 +1,32 @@ -import type {Schema} from '../types'; -import type {GraphQLSchema} from 'graphql/type/schema'; +import type {Schema} from "../types"; +import type {GraphQLSchema} from "graphql/type/schema"; -import {schemaFromIntrospectionData} from '../schemaFromIntrospectionData'; -import configSchema from '../../schema.json'; // eslint-disable-line flowtype-errors/uncovered +import {schemaFromIntrospectionData} from "../schemaFromIntrospectionData"; +import configSchema from "../../schema.json"; -import fs from 'fs'; +import fs from "fs"; import { buildClientSchema, buildSchema, getIntrospectionQuery, graphqlSync, IntrospectionQuery, -} from 'graphql'; -import type {Config, GenerateConfig} from '../types'; -import {validate} from 'jsonschema'; // eslint-disable-line flowtype-errors/uncovered +} from "graphql"; +import type {Config, GenerateConfig} from "../types"; +import {validate} from "jsonschema"; export const validateOrThrow = (value: unknown, jsonSchema: unknown) => { - /* eslint-disable flowtype-errors/uncovered */ const result = validate(value, jsonSchema); if (!result.valid) { throw new Error( - result.errors.map((error) => error.toString()).join('\n'), + result.errors.map((error) => error.toString()).join("\n"), ); } - /* eslint-enable flowtype-errors/uncovered */ }; export const loadConfigFile = (configFile: string): Config => { - const data: Config = require(configFile); // eslint-disable-line flowtype-errors/uncovered - validateOrThrow(data, configSchema); // eslint-disable-line flowtype-errors/uncovered + const data: Config = require(configFile); + validateOrThrow(data, configSchema); return data; }; @@ -36,20 +34,18 @@ export const loadConfigFile = (configFile: string): Config => { * Loads a .json 'introspection query response', or a .graphql schema definition. */ export const getSchemas = (schemaFilePath: string): [GraphQLSchema, Schema] => { - const raw = fs.readFileSync(schemaFilePath, 'utf8'); - if (schemaFilePath.endsWith('.graphql')) { + const raw = fs.readFileSync(schemaFilePath, "utf8"); + if (schemaFilePath.endsWith(".graphql")) { const schemaForValidation = buildSchema(raw); const queryResponse = graphqlSync({ schema: schemaForValidation, source: getIntrospectionQuery({descriptions: true}), }); const schemaForTypeGeneration = schemaFromIntrospectionData( - // eslint-disable-next-line flowtype-errors/uncovered - ((queryResponse.data as any) as IntrospectionQuery), + queryResponse.data as any as IntrospectionQuery, ); return [schemaForValidation, schemaForTypeGeneration]; } else { - // eslint-disable-next-line flowtype-errors/uncovered const introspectionData: IntrospectionQuery = JSON.parse(raw); const schemaForValidation = buildClientSchema(introspectionData); const schemaForTypeGeneration = @@ -63,12 +59,19 @@ export const getSchemas = (schemaFilePath: string): [GraphQLSchema, Schema] => { * - no item of `exclude` matches * - at least one item of `match` matches */ -export const findApplicableConfig = (path: string, configs: Array | GenerateConfig): GenerateConfig | null | undefined => { +export const findApplicableConfig = ( + path: string, + configs: Array | GenerateConfig, +): GenerateConfig | null | undefined => { if (!Array.isArray(configs)) { configs = [configs]; } return configs.find((config) => { - if (config.exclude?.some((exclude: any) => new RegExp(exclude).test(path))) { + if ( + config.exclude?.some((exclude: any) => + new RegExp(exclude).test(path), + ) + ) { return false; } if (!config.match) { diff --git a/src/cli/run.ts b/src/cli/run.ts index 522dcde..f56d0ce 100644 --- a/src/cli/run.ts +++ b/src/cli/run.ts @@ -1,22 +1,22 @@ #!/usr/bin/env node /* eslint-disable no-console */ -import type {Schema} from '../types'; -import type {GraphQLSchema} from 'graphql/type/schema'; +import type {Schema} from "../types"; +import type {GraphQLSchema} from "graphql/type/schema"; -import {generateTypeFiles, processPragmas} from '../generateTypeFiles'; -import {processFiles} from '../parser/parse'; -import {resolveDocuments} from '../parser/resolve'; -import {findApplicableConfig, getSchemas, loadConfigFile} from './config'; +import {generateTypeFiles, processPragmas} from "../generateTypeFiles"; +import {processFiles} from "../parser/parse"; +import {resolveDocuments} from "../parser/resolve"; +import {findApplicableConfig, getSchemas, loadConfigFile} from "./config"; -import {addTypenameToDocument} from 'apollo-utilities'; // eslint-disable-line flowtype-errors/uncovered +import {addTypenameToDocument} from "apollo-utilities"; -import {execSync} from 'child_process'; -import {existsSync, mkdirSync, readFileSync, writeFileSync} from 'fs'; -import {DocumentNode} from 'graphql'; -import {print} from 'graphql/language/printer'; -import {validate} from 'graphql/validation'; -import path from 'path'; -import {dirname} from 'path'; +import {execSync} from "child_process"; +import {existsSync, mkdirSync, readFileSync, writeFileSync} from "fs"; +import {DocumentNode} from "graphql"; +import {print} from "graphql/language/printer"; +import {validate} from "graphql/validation"; +import path from "path"; +import {dirname} from "path"; /** * This CLI tool executes the following steps: @@ -38,28 +38,28 @@ const findGraphqlTagReferences = (root: string): Array => { const response = execSync( "git grep -I --word-regexp --name-only --fixed-strings --untracked 'graphql-tag' -- '*.js' '*.jsx' '*.ts' '*.tsx'", { - encoding: 'utf8', + encoding: "utf8", cwd: root, }, ); return response .trim() - .split('\n') + .split("\n") .map((relative) => path.join(root, relative)); }; const [_, __, configFilePath, ...cliFiles] = process.argv; if ( - configFilePath === '-h' || - configFilePath === '--help' || - configFilePath === 'help' || + configFilePath === "-h" || + configFilePath === "--help" || + configFilePath === "help" || !configFilePath ) { console.log(`graphql-flow Usage: graphql-flow [configFile.json] [filesToCrawl...]`); - process.exit(1); // eslint-disable-line flowtype-errors/uncovered + process.exit(1); } const makeAbsPath = (maybeRelativePath: string, basePath: string) => { @@ -80,20 +80,20 @@ const inputFiles = cliFiles.length /** Step (2) */ -const files = processFiles(inputFiles, (f) => { +const files = processFiles(inputFiles, config, (f) => { if (existsSync(f)) { - return readFileSync(f, 'utf8'); + return readFileSync(f, "utf8"); } - if (existsSync(f + '.js')) { - return {text: readFileSync(f + '.js', 'utf8'), resolvedPath: f + '.js'}; + if (existsSync(f + ".js")) { + return {text: readFileSync(f + ".js", "utf8"), resolvedPath: f + ".js"}; } - if (existsSync(f + '.ts')) { - return {text: readFileSync(f + '.ts', 'utf8'), resolvedPath: f + '.ts'}; + if (existsSync(f + ".ts")) { + return {text: readFileSync(f + ".ts", "utf8"), resolvedPath: f + ".ts"}; } - if (existsSync(f + '.tsx')) { + if (existsSync(f + ".tsx")) { return { - text: readFileSync(f + '.tsx', 'utf8'), - resolvedPath: f + '.tsx', + text: readFileSync(f + ".tsx", "utf8"), + resolvedPath: f + ".tsx", }; } throw new Error(`Unable to find ${f}`); @@ -112,27 +112,27 @@ Object.keys(files).forEach((key) => { }); if (filesHadErrors) { - console.error('Aborting'); - process.exit(1); // eslint-disable-line flowtype-errors/uncovered + console.error("Aborting"); + process.exit(1); } /** Step (3) */ -const {resolved, errors} = resolveDocuments(files); +const {resolved, errors} = resolveDocuments(files, config); if (errors.length) { errors.forEach((error) => { console.error(`Resolution error ${error.message} in ${error.loc.path}`); }); - console.error('Aborting'); - process.exit(1); // eslint-disable-line flowtype-errors/uncovered + console.error("Aborting"); + process.exit(1); } -console.log(Object.keys(resolved).length, 'resolved queries'); +console.log(Object.keys(resolved).length, "resolved queries"); /** Step (4) */ const schemaCache: { - [key: string]: [GraphQLSchema, Schema] + [key: string]: [GraphQLSchema, Schema]; } = {}; const getCachedSchemas = (schemaFilePath: string) => { if (!schemaCache[schemaFilePath]) { @@ -151,20 +151,19 @@ Object.keys(resolved).forEach((filePathAndLine) => { const {document, raw} = resolved[filePathAndLine]; const hasNonFragments = document.definitions.some( - ({kind}) => kind !== 'FragmentDefinition', + ({kind}) => kind !== "FragmentDefinition", ); const rawSource: string = raw.literals[0]; const generateConfig = findApplicableConfig( // strip off the trailing line number, e.g. `:23` - filePathAndLine.split(':')[0], + filePathAndLine.split(":")[0], config.generate, ); if (!generateConfig) { return; // no generate config matches, bail } - // eslint-disable-next-line flowtype-errors/uncovered const withTypeNames: DocumentNode = addTypenameToDocument(document); const printed = print(withTypeNames); if (hasNonFragments && !printedOperations.includes(printed)) { @@ -188,9 +187,8 @@ Object.keys(resolved).forEach((filePathAndLine) => { ); if (hasNonFragments) { - /* eslint-disable flowtype-errors/uncovered */ const errors = validate(schemaForValidation, withTypeNames); - /* eslint-disable flowtype-errors/uncovered */ + if (errors.length) { errors.forEach((error) => { console.error( @@ -201,7 +199,6 @@ Object.keys(resolved).forEach((filePathAndLine) => { validationFailures++; }); } - /* eslint-enable flowtype-errors/uncovered */ } try { @@ -211,11 +208,10 @@ Object.keys(resolved).forEach((filePathAndLine) => { withTypeNames, generateConfig, ); - // eslint-disable-next-line flowtype-errors/uncovered } catch (err: any) { console.error(`Error while generating operation from ${raw.loc.path}`); console.error(printed); - // eslint-disable-next-line flowtype-errors/uncovered + console.error(err); validationFailures++; } @@ -225,7 +221,7 @@ if (validationFailures) { console.error( `Encountered ${validationFailures} validation failures while printing types.`, ); - // eslint-disable-next-line flowtype-errors/uncovered + process.exit(1); } diff --git a/src/enums.ts b/src/enums.ts index 29d08cb..cf424d8 100644 --- a/src/enums.ts +++ b/src/enums.ts @@ -1,11 +1,11 @@ /** * Both input & output types can have enums & scalars. */ -import * as babelTypes from '@babel/types'; -import type {TSType} from '@babel/types'; -import type {Context} from './types'; -import {maybeAddDescriptionComment} from './utils'; -import type {IntrospectionEnumType} from 'graphql/utilities/introspectionQuery'; +import * as babelTypes from "@babel/types"; +import type {TSType} from "@babel/types"; +import type {Context} from "./types"; +import {maybeAddDescriptionComment} from "./utils"; +import type {IntrospectionEnumType} from "graphql"; export const experimentalEnumTypeToFlow = ( ctx: Context, @@ -40,13 +40,13 @@ export const enumTypeToFlow = (ctx: Context, name: string): TSType => { (n) => `- ${n.name}` + (n.description - ? '\n\n ' + n.description.replace(/\n/g, '\n ') - : ''), + ? "\n\n " + n.description.replace(/\n/g, "\n ") + : ""), ) - .join('\n'); + .join("\n"); if (enumConfig.description) { combinedDescription = - enumConfig.description + '\n\n' + combinedDescription; + enumConfig.description + "\n\n" + combinedDescription; } return ctx.experimentalEnumsMap @@ -64,15 +64,15 @@ export const enumTypeToFlow = (ctx: Context, name: string): TSType => { }; export const builtinScalars: { - [key: string]: string, + [key: string]: string; } = { - Boolean: 'boolean', - String: 'string', - DateTime: 'string', - Date: 'string', - ID: 'string', - Int: 'number', - Float: 'number', + Boolean: "boolean", + String: "string", + DateTime: "string", + Date: "string", + ID: "string", + Int: "number", + Float: "number", }; export const scalarTypeToFlow = (ctx: Context, name: string): TSType => { diff --git a/src/generateResponseType.ts b/src/generateResponseType.ts index 467037c..3626558 100644 --- a/src/generateResponseType.ts +++ b/src/generateResponseType.ts @@ -1,40 +1,44 @@ /* eslint-disable no-console */ -import generate from '@babel/generator'; // eslint-disable-line flowtype-errors/uncovered -import * as babelTypes from '@babel/types'; -import {TSType} from '@babel/types'; +import generate from "@babel/generator"; +import * as babelTypes from "@babel/types"; +import {TSType} from "@babel/types"; import type { FieldNode, IntrospectionOutputTypeRef, OperationDefinitionNode, FragmentDefinitionNode, SelectionNode, -} from 'graphql'; -import type {Context, Schema, Selections} from './types'; +} from "graphql"; +import type {Context, Schema, Selections} from "./types"; import { liftLeadingPropertyComments, maybeAddDescriptionComment, transferLeadingComments, nullableType, objectTypeFromProperties, -} from './utils'; -import {enumTypeToFlow, scalarTypeToFlow} from './enums'; +} from "./utils"; +import {enumTypeToFlow, scalarTypeToFlow} from "./enums"; import type { IntrospectionField, IntrospectionInterfaceType, IntrospectionObjectType, IntrospectionUnionType, -} from 'graphql/utilities/introspectionQuery'; +} from "graphql"; -export const generateResponseType = (schema: Schema, query: OperationDefinitionNode, ctx: Context): string => { +export const generateResponseType = ( + schema: Schema, + query: OperationDefinitionNode, + ctx: Context, +): string => { const ast = querySelectionToObjectType( ctx, query.selectionSet.selections, - query.operation === 'mutation' + query.operation === "mutation" ? schema.typesByName.Mutation : schema.typesByName.Query, - query.operation === 'mutation' ? 'mutation' : 'query', + query.operation === "mutation" ? "mutation" : "query", ); - // eslint-disable-next-line flowtype-errors/uncovered + return generate(ast).code; }; @@ -45,17 +49,17 @@ const sortedObjectTypeAnnotation = ( const obj = objectTypeFromProperties( properties.sort((a, b) => { if ( - a.type === 'TSPropertySignature' && - b.type === 'TSPropertySignature' + a.type === "TSPropertySignature" && + b.type === "TSPropertySignature" ) { - const aName = a.key.type === 'Identifier' ? a.key.name : ''; - const bName = b.key.type === 'Identifier' ? b.key.name : ''; + const aName = a.key.type === "Identifier" ? a.key.name : ""; + const bName = b.key.type === "Identifier" ? b.key.name : ""; return aName < bName ? -1 : 1; } return 0; }), ); - const name = ctx.path.join('_'); + const name = ctx.path.join("_"); const isTopLevelType = ctx.path.length <= 1; if (ctx.allObjectTypes != null && !isTopLevelType) { ctx.allObjectTypes[name] = obj; @@ -65,7 +69,11 @@ const sortedObjectTypeAnnotation = ( } }; -export const generateFragmentType = (schema: Schema, fragment: FragmentDefinitionNode, ctx: Context): string => { +export const generateFragmentType = ( + schema: Schema, + fragment: FragmentDefinitionNode, + ctx: Context, +): string => { const onType = fragment.typeCondition.name.value; let ast; @@ -95,28 +103,31 @@ export const generateFragmentType = (schema: Schema, fragment: FragmentDefinitio throw new Error(`Unknown ${onType}`); } - // eslint-disable-next-line flowtype-errors/uncovered return generate(ast).code; }; -const _typeToFlow = (ctx: Context, type: any, selection: FieldNode): babelTypes.TSType => { - if (type.kind === 'SCALAR') { +const _typeToFlow = ( + ctx: Context, + type: any, + selection: FieldNode, +): babelTypes.TSType => { + if (type.kind === "SCALAR") { return scalarTypeToFlow(ctx, type.name); } - if (type.kind === 'LIST') { + if (type.kind === "LIST") { return babelTypes.tsTypeReference( ctx.readOnlyArray - ? babelTypes.identifier('ReadonlyArray') - : babelTypes.identifier('Array'), + ? babelTypes.identifier("ReadonlyArray") + : babelTypes.identifier("Array"), babelTypes.tsTypeParameterInstantiation([ typeToFlow(ctx, type.ofType, selection), ]), ); } - if (type.kind === 'UNION') { + if (type.kind === "UNION") { const union = ctx.schema.unionsByName[type.name]; if (!selection.selectionSet) { - console.log('no selection set', selection); + console.log("no selection set", selection); return babelTypes.tsAnyKeyword(); } return unionOrInterfaceToFlow( @@ -126,9 +137,9 @@ const _typeToFlow = (ctx: Context, type: any, selection: FieldNode): babelTypes. ); } - if (type.kind === 'INTERFACE') { + if (type.kind === "INTERFACE") { if (!selection.selectionSet) { - console.log('no selection set', selection); + console.log("no selection set", selection); return babelTypes.tsAnyKeyword(); } return unionOrInterfaceToFlow( @@ -137,22 +148,22 @@ const _typeToFlow = (ctx: Context, type: any, selection: FieldNode): babelTypes. selection.selectionSet.selections, ); } - if (type.kind === 'ENUM') { + if (type.kind === "ENUM") { return enumTypeToFlow(ctx, type.name); } - if (type.kind !== 'OBJECT') { - console.log('not object', type); + if (type.kind !== "OBJECT") { + console.log("not object", type); return babelTypes.tsAnyKeyword(); } const tname = type.name; if (!ctx.schema.typesByName[tname]) { - console.log('unknown referenced type', tname); + console.log("unknown referenced type", tname); return babelTypes.tsAnyKeyword(); } const childType = ctx.schema.typesByName[tname]; if (!selection.selectionSet) { - console.log('no selection set', selection); + console.log("no selection set", selection); return babelTypes.tsAnyKeyword(); } return maybeAddDescriptionComment( @@ -166,9 +177,13 @@ const _typeToFlow = (ctx: Context, type: any, selection: FieldNode): babelTypes. ); }; -export const typeToFlow = (ctx: Context, type: IntrospectionOutputTypeRef, selection: FieldNode): babelTypes.TSType => { +export const typeToFlow = ( + ctx: Context, + type: IntrospectionOutputTypeRef, + selection: FieldNode, +): babelTypes.TSType => { // throw new Error('npoe'); - if (type.kind === 'NON_NULL') { + if (type.kind === "NON_NULL") { return _typeToFlow(ctx, type.ofType, selection); } // If we don'babelTypes care about strict nullability checking, then pretend everything is non-null @@ -180,22 +195,25 @@ export const typeToFlow = (ctx: Context, type: IntrospectionOutputTypeRef, selec return transferLeadingComments(inner, result); }; -const ensureOnlyOneTypenameProperty = (properties: Array) => { +const ensureOnlyOneTypenameProperty = ( + properties: Array, +) => { let seenTypeName: false | string = false; return properties.filter((type) => { // The apollo-utilities "addTypeName" utility will add it // even if it's already specified :( so we have to filter out // the extra one here. if ( - type.type === 'TSPropertySignature' && + type.type === "TSPropertySignature" && type.key.type === "Identifier" && - type.key.name === '__typename' + type.key.name === "__typename" ) { const name = - type.typeAnnotation?.typeAnnotation.type === 'TSLiteralType' && - type.typeAnnotation.typeAnnotation.literal.type === 'StringLiteral' + type.typeAnnotation?.typeAnnotation.type === "TSLiteralType" && + type.typeAnnotation.typeAnnotation.literal.type === + "StringLiteral" ? type.typeAnnotation.typeAnnotation.literal.value - : 'INVALID'; + : "INVALID"; if (seenTypeName) { if (name !== seenTypeName) { throw new Error( @@ -210,7 +228,12 @@ const ensureOnlyOneTypenameProperty = (properties: Array { +const querySelectionToObjectType = ( + ctx: Context, + selections: any, + type: any, + typeName: string, +): babelTypes.TSType => { return sortedObjectTypeAnnotation( ctx, ensureOnlyOneTypenameProperty( @@ -223,15 +246,15 @@ export const objectPropertiesToFlow = ( ctx: Context, type: IntrospectionObjectType & { fieldsByName: { - [name: string]: IntrospectionField - } + [name: string]: IntrospectionField; + }; }, typeName: string, selections: Selections, ): Array => { return selections.flatMap((selection) => { switch (selection.kind) { - case 'InlineFragment': { + case "InlineFragment": { const newTypeName = selection.typeCondition?.name.value ?? typeName; if (newTypeName !== typeName) { @@ -244,7 +267,7 @@ export const objectPropertiesToFlow = ( selection.selectionSet.selections, ); } - case 'FragmentSpread': + case "FragmentSpread": if (!ctx.fragments[selection.name.value]) { ctx.errors.push( `No fragment named '${selection.name.value}'. Did you forget to include it in the template literal?`, @@ -255,7 +278,7 @@ export const objectPropertiesToFlow = ( babelTypes.tsTypeAnnotation( babelTypes.tsTypeReference( babelTypes.identifier(`UNKNOWN_FRAGMENT`), - ) + ), ), ), ]; @@ -265,16 +288,15 @@ export const objectPropertiesToFlow = ( ctx, type, typeName, - ctx.fragments[selection.name.value].selectionSet - .selections, + ctx.fragments[selection.name.value].selectionSet.selections, ); - case 'Field': + case "Field": const name = selection.name.value; const alias: string = selection.alias ? selection.alias.value : name; - if (name === '__typename') { + if (name === "__typename") { return [ babelTypes.tsPropertySignature( babelTypes.identifier(alias), @@ -298,9 +320,9 @@ export const objectPropertiesToFlow = ( babelTypes.identifier( `UNKNOWN_FIELD["${name}"]`, ), - ) + ), ), - ) + ), ]; } const typeField = type.fieldsByName[name]; @@ -320,7 +342,7 @@ export const objectPropertiesToFlow = ( typeField.type, selection, ), - ) + ), ), ), ), @@ -328,7 +350,6 @@ export const objectPropertiesToFlow = ( default: ctx.errors.push( - // @ts-expect-error: `selection` is `never` here `Unsupported selection kind '${selection.kind}'`, ); return []; @@ -338,19 +359,21 @@ export const objectPropertiesToFlow = ( export const unionOrInterfaceToFlow = ( ctx: Context, - type: IntrospectionUnionType | IntrospectionInterfaceType & { - fieldsByName: { - [key: string]: IntrospectionField - } - }, + type: + | IntrospectionUnionType + | (IntrospectionInterfaceType & { + fieldsByName: { + [key: string]: IntrospectionField; + }; + }), selections: Selections, ): TSType => { const allFields = selections.every( - (selection) => selection.kind === 'Field', + (selection) => selection.kind === "Field", ); const selectedAttributes: Array<{ - attributes: Array - typeName: string + attributes: Array; + typeName: string; }> = type.possibleTypes .slice() .sort((a, b) => { @@ -382,23 +405,25 @@ export const unionOrInterfaceToFlow = ( const sharedAttributes = selectedAttributes[0].attributes.slice(); const typeNameIndex = selectedAttributes[0].attributes.findIndex( (x) => - x.type === 'TSPropertySignature' && - x.key.type === 'Identifier' && - x.key.name === '__typename', + x.type === "TSPropertySignature" && + x.key.type === "Identifier" && + x.key.name === "__typename", ); if (typeNameIndex !== -1) { sharedAttributes[typeNameIndex] = babelTypes.tsPropertySignature( - babelTypes.identifier('__typename'), + babelTypes.identifier("__typename"), babelTypes.tsTypeAnnotation( babelTypes.tsUnionType( selectedAttributes.map( (attrs) => - (attrs.attributes[ - typeNameIndex - ] as babelTypes.TSPropertySignature).typeAnnotation!.typeAnnotation, + ( + attrs.attributes[ + typeNameIndex + ] as babelTypes.TSPropertySignature + ).typeAnnotation!.typeAnnotation, ), ), - ) + ), ); } return sortedObjectTypeAnnotation(ctx, sharedAttributes); @@ -447,17 +472,20 @@ export const unionOrInterfaceToFlow = ( ), ), ); - const name = ctx.path.join('_'); + const name = ctx.path.join("_"); if (ctx.allObjectTypes && ctx.path.length > 1) { ctx.allObjectTypes[name] = result; - return babelTypes.tsTypeReference( - babelTypes.identifier(name), - ); + return babelTypes.tsTypeReference(babelTypes.identifier(name)); } return result; }; -const unionOrInterfaceSelection = (config: Context, type: any, possible: any, selection: SelectionNode): Array => { - if (selection.kind === 'Field' && selection.name.value === '__typename') { +const unionOrInterfaceSelection = ( + config: Context, + type: any, + possible: any, + selection: SelectionNode, +): Array => { + if (selection.kind === "Field" && selection.name.value === "__typename") { const alias = selection.alias ? selection.alias.value : selection.name.value; @@ -472,17 +500,17 @@ const unionOrInterfaceSelection = (config: Context, type: any, possible: any, se ), ]; } - if (selection.kind === 'Field' && type.kind !== 'UNION') { + if (selection.kind === "Field" && type.kind !== "UNION") { // this is an interface const name = selection.name.value; const alias = selection.alias ? selection.alias.value : name; if (!type.fieldsByName[name]) { config.errors.push( - 'Unknown field: ' + + "Unknown field: " + name + - ' on type ' + + " on type " + type.name + - ' for possible ' + + " for possible " + possible.name, ); return [ @@ -512,7 +540,7 @@ const unionOrInterfaceSelection = (config: Context, type: any, possible: any, se ), ]; } - if (selection.kind === 'FragmentSpread') { + if (selection.kind === "FragmentSpread") { const fragment = config.fragments[selection.name.value]; if (!fragment) { throw new Error(`Unknown fragment ${selection.name.value}`); @@ -525,23 +553,24 @@ const unionOrInterfaceSelection = (config: Context, type: any, possible: any, se ]) || typeName === possible.name ) { - return fragment.selectionSet.selections.flatMap((selection: SelectionNode) => - unionOrInterfaceSelection( - config, - config.schema.typesByName[possible.name], - possible, - selection, - ), + return fragment.selectionSet.selections.flatMap( + (selection: SelectionNode) => + unionOrInterfaceSelection( + config, + config.schema.typesByName[possible.name], + possible, + selection, + ), ); } else { return []; } } - if (selection.kind !== 'InlineFragment') { + if (selection.kind !== "InlineFragment") { config.errors.push( `union selectors must be inline fragment: found ${selection.kind}`, ); - if (type.kind === 'UNION') { + if (type.kind === "UNION") { config.errors .push(`You're trying to select a field from the union ${type.name}, but the only field you're allowed to select is "__typename". diff --git a/src/generateTypeFiles.ts b/src/generateTypeFiles.ts index 2b60679..18d9915 100644 --- a/src/generateTypeFiles.ts +++ b/src/generateTypeFiles.ts @@ -1,13 +1,15 @@ -import type {DocumentNode} from 'graphql'; -import type {GenerateConfig, CrawlConfig, Schema} from './types'; -import fs from 'fs'; -import path from 'path'; -import {documentToFlowTypes} from '.'; - -export const indexPrelude = (regenerateCommand?: string): string => `// AUTOGENERATED +import type {DocumentNode} from "graphql"; +import type {GenerateConfig, CrawlConfig, Schema} from "./types"; +import fs from "fs"; +import path from "path"; +import {documentToFlowTypes} from "."; + +export const indexPrelude = ( + regenerateCommand?: string, +): string => `// AUTOGENERATED // NOTE: New response types are added to this file automatically. // Outdated response types can be removed manually as they are deprecated. -//${regenerateCommand ? ' To regenerate, run ' + regenerateCommand : ''} +//${regenerateCommand ? " To regenerate, run " + regenerateCommand : ""} // `; @@ -20,10 +22,10 @@ export const generateTypeFileContents = ( generatedDir: string, indexContents: string, ): { - indexContents: string + indexContents: string; files: { - [key: string]: string - } + [key: string]: string; + }; } => { const files: Record = {}; @@ -31,7 +33,7 @@ export const generateTypeFileContents = ( const addToIndex = (filePath: string, typeName: unknown) => { if (options.typeScript || options.omitFileExtensions) { // Typescript doesn't like file extensions - filePath = filePath.replace(/\.ts$/, ''); + filePath = filePath.replace(/\.ts$/, ""); } const newLine = `export type {${typeName}} from './${path.basename( filePath, @@ -39,7 +41,7 @@ export const generateTypeFileContents = ( // We match the entire new line to avoid issues that can arise from // prefix matches. if (indexContents.indexOf(newLine) === -1) { - indexContents += newLine + '\n'; + indexContents += newLine + "\n"; } }; @@ -49,7 +51,7 @@ export const generateTypeFileContents = ( // We write all generated files to a `__generated__` subdir to keep // things tidy. const targetFileName = options.typeFileName - ? options.typeFileName.replace('[operationName]', name) + ? options.typeFileName.replace("[operationName]", name) : `${name}.ts`; const targetPath = path.join(generatedDir, targetFileName); @@ -60,7 +62,7 @@ export const generateTypeFileContents = ( )}'\n` + (options.regenerateCommand ? `// To regenerate, run '${options.regenerateCommand}'.\n` - : '') + + : "") + code; if (options.splitTypes && !isFragment) { fileContents += @@ -88,7 +90,7 @@ export const generateTypeFileContents = ( fileContents // Remove whitespace from the ends of lines; babel's generate sometimes // leaves them hanging around. - .replace(/\s+$/gm, '') + '\n'; + .replace(/\s+$/gm, "") + "\n"; }, ); @@ -96,7 +98,7 @@ export const generateTypeFileContents = ( }; const getGeneratedDir = (fileName: string, options: GenerateConfig) => { - const generatedDirectory = options.generatedDirectory ?? '__generated__'; + const generatedDirectory = options.generatedDirectory ?? "__generated__"; if (path.isAbsolute(generatedDirectory)) { // fileName is absolute here, so we make it relative to cwd // for more reasonable filenames. We convert leading ..'s @@ -105,7 +107,7 @@ const getGeneratedDir = (fileName: string, options: GenerateConfig) => { generatedDirectory, path .relative(process.cwd(), path.dirname(fileName)) - .replace(/\.\.\//g, '__/'), + .replace(/\.\.\//g, "__/"), ); } else { return path.join(path.dirname(fileName), generatedDirectory); @@ -119,7 +121,7 @@ export const generateTypeFiles = ( options: GenerateConfig, ) => { const generatedDir = getGeneratedDir(fileName, options); - const indexFile = path.join(generatedDir, 'index.ts'); + const indexFile = path.join(generatedDir, "index.ts"); if (!fs.existsSync(generatedDir)) { fs.mkdirSync(generatedDir, {recursive: true}); @@ -134,7 +136,7 @@ export const generateTypeFiles = ( document, options, generatedDir, - fs.readFileSync(indexFile, 'utf8'), + fs.readFileSync(indexFile, "utf8"), ); fs.writeFileSync(indexFile, indexContents); @@ -150,8 +152,8 @@ export const processPragmas = ( crawlConfig: CrawlConfig, rawSource: string, ): { - generate: boolean - strict?: boolean + generate: boolean; + strict?: boolean; } => { if ( crawlConfig.ignorePragma && diff --git a/src/generateVariablesType.ts b/src/generateVariablesType.ts index 87daa4e..4e61c1e 100644 --- a/src/generateVariablesType.ts +++ b/src/generateVariablesType.ts @@ -1,15 +1,15 @@ -import generate from '@babel/generator'; // eslint-disable-line flowtype-errors/uncovered -import * as babelTypes from '@babel/types'; -import type {OperationDefinitionNode, TypeNode} from 'graphql/language/ast'; -import type {IntrospectionInputTypeRef} from 'graphql/utilities/introspectionQuery'; -import {builtinScalars, enumTypeToFlow, scalarTypeToFlow} from './enums'; -import {nullableType, isnNullableType, objectTypeFromProperties} from './utils'; -import type {Context, Schema} from './types'; +import generate from "@babel/generator"; +import * as babelTypes from "@babel/types"; +import type {OperationDefinitionNode, TypeNode} from "graphql/language/ast"; +import type {IntrospectionInputTypeRef} from "graphql"; +import {builtinScalars, enumTypeToFlow, scalarTypeToFlow} from "./enums"; +import {nullableType, isnNullableType, objectTypeFromProperties} from "./utils"; +import type {Context, Schema} from "./types"; import { liftLeadingPropertyComments, maybeAddDescriptionComment, transferLeadingComments, -} from './utils'; +} from "./utils"; export const inputObjectToFlow = ( ctx: Context, @@ -59,7 +59,7 @@ export const inputRefToFlow = ( ctx: Context, inputRef: IntrospectionInputTypeRef, ): babelTypes.TSType => { - if (inputRef.kind === 'NON_NULL') { + if (inputRef.kind === "NON_NULL") { return _inputRefToFlow(ctx, inputRef.ofType); } const result = _inputRefToFlow(ctx, inputRef); @@ -70,18 +70,18 @@ const _inputRefToFlow = ( ctx: Context, inputRef: IntrospectionInputTypeRef, ): babelTypes.TSType => { - if (inputRef.kind === 'SCALAR') { + if (inputRef.kind === "SCALAR") { return scalarTypeToFlow(ctx, inputRef.name); } - if (inputRef.kind === 'ENUM') { + if (inputRef.kind === "ENUM") { return enumTypeToFlow(ctx, inputRef.name); } - if (inputRef.kind === 'INPUT_OBJECT') { + if (inputRef.kind === "INPUT_OBJECT") { return inputObjectToFlow(ctx, inputRef.name); } - if (inputRef.kind === 'LIST') { + if (inputRef.kind === "LIST") { return babelTypes.tsTypeReference( - babelTypes.identifier('ReadonlyArray'), + babelTypes.identifier("ReadonlyArray"), babelTypes.tsTypeParameterInstantiation([ inputRefToFlow(ctx, inputRef.ofType), ]), @@ -93,7 +93,7 @@ const _inputRefToFlow = ( }; const variableToFlow = (ctx: Context, type: TypeNode): babelTypes.TSType => { - if (type.kind === 'NonNullType') { + if (type.kind === "NonNullType") { return _variableToFlow(ctx, type.type); } const result = _variableToFlow(ctx, type); @@ -101,7 +101,7 @@ const variableToFlow = (ctx: Context, type: TypeNode): babelTypes.TSType => { }; const _variableToFlow = (ctx: Context, type: TypeNode): babelTypes.TSType => { - if (type.kind === 'NamedType') { + if (type.kind === "NamedType") { if (builtinScalars[type.name.value]) { return scalarTypeToFlow(ctx, type.name.value); } @@ -116,16 +116,16 @@ const _variableToFlow = (ctx: Context, type: TypeNode): babelTypes.TSType => { } return inputObjectToFlow(ctx, type.name.value); } - if (type.kind === 'ListType') { + if (type.kind === "ListType") { return babelTypes.tsTypeReference( - babelTypes.identifier('ReadonlyArray'), + babelTypes.identifier("ReadonlyArray"), babelTypes.tsTypeParameterInstantiation([ variableToFlow(ctx, type.type), ]), ); } return babelTypes.tsLiteralType( - babelTypes.stringLiteral('UNKNOWN' + JSON.stringify(type)), + babelTypes.stringLiteral("UNKNOWN" + JSON.stringify(type)), ); }; @@ -142,5 +142,5 @@ export const generateVariablesType = ( ); }), ); - return generate(variableObject).code; // eslint-disable-line flowtype-errors/uncovered + return generate(variableObject).code; }; diff --git a/src/index.ts b/src/index.ts index 5930381..bedf21e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,4 @@ -import {isTruthy} from '@khanacademy/wonder-stuff-core'; +import {isTruthy} from "@khanacademy/wonder-stuff-core"; /* eslint-disable no-console */ /* flow-uncovered-file */ /** @@ -7,17 +7,17 @@ import {isTruthy} from '@khanacademy/wonder-stuff-core'; * It relies on `introspection-query.json` existing in this directory, * which is produced by running `./tools/graphql-flow/sendIntrospection.js`. */ -import type {DefinitionNode, DocumentNode} from 'graphql'; +import type {DefinitionNode, DocumentNode} from "graphql"; -import generate from '@babel/generator'; // eslint-disable-line flowtype-errors/uncovered +import generate from "@babel/generator"; import { generateFragmentType, generateResponseType, -} from './generateResponseType'; -import {generateVariablesType} from './generateVariablesType'; -import type {Node} from '@babel/types'; +} from "./generateResponseType"; +import {generateVariablesType} from "./generateVariablesType"; +import type {Node} from "@babel/types"; -import type {Context, Schema, GenerateConfig} from './types'; +import type {Context, Schema, GenerateConfig} from "./types"; const optionsToConfig = ( schema: Schema, @@ -34,7 +34,7 @@ const optionsToConfig = ( } as const; const fragments: Record = {}; definitions.forEach((def) => { - if (def.kind === 'FragmentDefinition') { + if (def.kind === "FragmentDefinition") { fragments[def.name.value] = def; } }); @@ -56,22 +56,26 @@ const optionsToConfig = ( export class FlowGenerationError extends Error { messages: Array; constructor(errors: Array) { - super(`Graphql-flow type generation failed! ${errors.join('; ')}`); + super(`Graphql-flow type generation failed! ${errors.join("; ")}`); this.messages = errors; } } -export const documentToFlowTypes = (document: DocumentNode, schema: Schema, options?: GenerateConfig): ReadonlyArray<{ - name: string - typeName: string - code: string - isFragment?: boolean +export const documentToFlowTypes = ( + document: DocumentNode, + schema: Schema, + options?: GenerateConfig, +): ReadonlyArray<{ + name: string; + typeName: string; + code: string; + isFragment?: boolean; extraTypes: { - [key: string]: string - } + [key: string]: string; + }; experimentalEnums: { - [key: string]: string - } + [key: string]: string; + }; }> => { const errors: Array = []; const config = optionsToConfig( @@ -82,7 +86,7 @@ export const documentToFlowTypes = (document: DocumentNode, schema: Schema, opti ); const result = document.definitions .map((item) => { - if (item.kind === 'FragmentDefinition') { + if (item.kind === "FragmentDefinition") { const name = item.name.value; const types: Record = {}; const code = `export type ${name} = ${generateFragmentType( @@ -112,8 +116,8 @@ export const documentToFlowTypes = (document: DocumentNode, schema: Schema, opti }; } if ( - item.kind === 'OperationDefinition' && - (item.operation === 'query' || item.operation === 'mutation') && + item.kind === "OperationDefinition" && + (item.operation === "query" || item.operation === "mutation") && item.name ) { const types: Record = {}; @@ -150,18 +154,13 @@ export const documentToFlowTypes = (document: DocumentNode, schema: Schema, opti return result; }; -function codegenExtraTypes( - types: { - [key: string]: Node - }, -): { - [key: string]: string +function codegenExtraTypes(types: {[key: string]: Node}): { + [key: string]: string; } { const extraTypes: { - [key: string]: string + [key: string]: string; } = {}; Object.keys(types).forEach((k: string) => { - // eslint-disable-next-line flowtype-errors/uncovered extraTypes[k] = generate(types[k]).code; }); return extraTypes; diff --git a/src/parser/__test__/parse.test.ts b/src/parser/__test__/parse.test.ts index 3e1faeb..f4a5644 100644 --- a/src/parser/__test__/parse.test.ts +++ b/src/parser/__test__/parse.test.ts @@ -1,15 +1,20 @@ -import {processFiles} from '../parse'; -import {resolveDocuments} from '../resolve'; +import {describe, it, expect} from "@jest/globals"; -import {print} from 'graphql/language/printer'; +import {Config} from "../../types"; +import {processFiles} from "../parse"; +import {resolveDocuments} from "../resolve"; + +import {print} from "graphql/language/printer"; const fixtureFiles: { - [key: string]: string | { - text: string - resolvedPath: string - } + [key: string]: + | string + | { + text: string; + resolvedPath: string; + }; } = { - '/firstFile.js': ` + "/firstFile.js": ` // Note that you can import graphql-tag as // something other than gql. import tagme from 'graphql-tag'; @@ -35,7 +40,7 @@ const fixtureFiles: { } \`;`, - '/secondFile.js': ` + "/secondFile.js": ` import gql from 'graphql-tag'; import {fromFirstFile} from './firstFile.js'; // This import won't be followed, because it's not exported @@ -52,7 +57,7 @@ const fixtureFiles: { \`; export {secondFragment};`, - '/thirdFile.js': ` + "/thirdFile.js": ` import {fromFirstFile, alsoFirst, secondFragment} from './secondFile.js'; import gql from 'graphql-tag'; import type {someType} from './somePlace'; @@ -91,7 +96,7 @@ const fixtureFiles: { \`; }`, - '/invalidThings.js': ` + "/invalidThings.js": ` import gql from 'graphql-tag'; // Importing a fragment from an npm module is invalid. import someExternalFragment from 'somewhere'; @@ -107,7 +112,7 @@ const fixtureFiles: { \`; `, - '/circular.js': ` + "/circular.js": ` import gql from 'graphql-tag'; export {otherThing} from './invalidReferences.js'; import {one} from './invalidReferences.js'; @@ -119,7 +124,7 @@ const fixtureFiles: { \`; `, - '/invalidReferences.js': ` + "/invalidReferences.js": ` import gql from 'graphql-tag'; import {otherThing, two, doesntExist} from './circular.js'; // 'otherThing' is imported circularly @@ -149,13 +154,39 @@ const getFileSource = (name: string) => { return fixtureFiles[name]; }; -describe('processing fragments in various ways', () => { - it('should work', () => { - const files = processFiles(['/thirdFile.js'], getFileSource); +describe("processing fragments in various ways", () => { + it("should work", () => { + const config: Config = { + crawl: { + root: "/here/we/crawl", + }, + generate: { + match: [/\.fixture\.js$/], + exclude: [ + "_test\\.js$", + "\\bcourse-editor-package\\b", + "\\.fixture\\.js$", + "\\b__flowtests__\\b", + "\\bcourse-editor\\b", + ], + readOnlyArray: false, + regenerateCommand: "make gqlflow", + scalars: { + JSONString: "string", + KALocale: "string", + NaiveDateTime: "string", + }, + splitTypes: true, + generatedDirectory: "__graphql-types__", + exportAllObjectTypes: true, + schemaFilePath: "./composed_schema.graphql", + }, + }; + const files = processFiles(["/thirdFile.js"], config, getFileSource); Object.keys(files).forEach((k: any) => { expect(files[k].errors).toEqual([]); }); - const {resolved, errors} = resolveDocuments(files); + const {resolved, errors} = resolveDocuments(files, config); expect(errors).toEqual([]); const printed: Record = {}; Object.keys(resolved).map( @@ -215,9 +246,39 @@ describe('processing fragments in various ways', () => { `); }); - it('should flag things it doesnt support', () => { - const files = processFiles(['/invalidThings.js'], getFileSource); - expect(files['/invalidThings.js'].errors.map((m: any) => m.message)) + it("should flag things it doesnt support", () => { + const config: Config = { + crawl: { + root: "/here/we/crawl", + }, + generate: { + match: [/\.fixture\.js$/], + exclude: [ + "_test\\.js$", + "\\bcourse-editor-package\\b", + "\\.fixture\\.js$", + "\\b__flowtests__\\b", + "\\bcourse-editor\\b", + ], + readOnlyArray: false, + regenerateCommand: "make gqlflow", + scalars: { + JSONString: "string", + KALocale: "string", + NaiveDateTime: "string", + }, + splitTypes: true, + generatedDirectory: "__graphql-types__", + exportAllObjectTypes: true, + schemaFilePath: "./composed_schema.graphql", + }, + }; + const files = processFiles( + ["/invalidThings.js"], + config, + getFileSource, + ); + expect(files["/invalidThings.js"].errors.map((m: any) => m.message)) .toMatchInlineSnapshot(` Array [ "Unable to resolve someExternalFragment", @@ -227,12 +288,42 @@ describe('processing fragments in various ways', () => { `); }); - it('should flag resolution errors', () => { - const files = processFiles(['/invalidReferences.js'], getFileSource); + it("should flag resolution errors", () => { + const config: Config = { + crawl: { + root: "/here/we/crawl", + }, + generate: { + match: [/\.fixture\.js$/], + exclude: [ + "_test\\.js$", + "\\bcourse-editor-package\\b", + "\\.fixture\\.js$", + "\\b__flowtests__\\b", + "\\bcourse-editor\\b", + ], + readOnlyArray: false, + regenerateCommand: "make gqlflow", + scalars: { + JSONString: "string", + KALocale: "string", + NaiveDateTime: "string", + }, + splitTypes: true, + generatedDirectory: "__graphql-types__", + exportAllObjectTypes: true, + schemaFilePath: "./composed_schema.graphql", + }, + }; + const files = processFiles( + ["/invalidReferences.js"], + config, + getFileSource, + ); Object.keys(files).forEach((k: any) => { expect(files[k].errors).toEqual([]); }); - const {resolved, errors} = resolveDocuments(files); + const {resolved, errors} = resolveDocuments(files, config); expect(errors.map((m: any) => m.message)).toMatchInlineSnapshot(` Array [ "Circular import /circular.js -> /invalidReferences.js -> /circular.js", diff --git a/src/parser/__test__/utils.test.ts b/src/parser/__test__/utils.test.ts new file mode 100644 index 0000000..607d972 --- /dev/null +++ b/src/parser/__test__/utils.test.ts @@ -0,0 +1,80 @@ +import fs from "fs"; +import {describe, it, expect, jest} from "@jest/globals"; +import type {Config} from "../../types"; + +import {getPathWithExtension} from "../utils"; + +const generate = { + match: [/\.fixture\.js$/], + exclude: [ + "_test\\.js$", + "\\bcourse-editor-package\\b", + "\\.fixture\\.js$", + "\\b__flowtests__\\b", + "\\bcourse-editor\\b", + ], + readOnlyArray: false, + regenerateCommand: "make gqlflow", + scalars: { + JSONString: "string", + KALocale: "string", + NaiveDateTime: "string", + }, + splitTypes: true, + generatedDirectory: "__graphql-types__", + exportAllObjectTypes: true, + schemaFilePath: "./composed_schema.graphql", +} as const; + +const config: Config = { + crawl: { + root: "/here/we/crawl", + }, + generate: [ + {...generate, match: [/^static/], exportAllObjectTypes: false}, + generate, + ], +}; + +describe("getPathWithExtension", () => { + it("should handle a basic missing extension", () => { + // Arrange + jest.spyOn(fs, "existsSync").mockImplementation((path) => + typeof path === "string" ? path.endsWith(".js") : false, + ); + + // Act + const result = getPathWithExtension("/path/to/file", config); + + // Assert + expect(result).toBe("/path/to/file.js"); + }); + + it("returns an empty string if no file is found", () => { + // Arrange + jest.spyOn(fs, "existsSync").mockImplementation((path) => false); + + // Act + const result = getPathWithExtension("/path/to/file", config); + + // Assert + expect(result).toBe(""); + }); + + it("maps aliases to their correct value", () => { + // Arrange + jest.spyOn(fs, "existsSync").mockImplementation((path) => + typeof path === "string" ? path.endsWith(".js") : false, + ); + const tmpConfig: Config = { + ...config, + alias: [{find: "~", replacement: "../../some/prefix"}], + }; + + // Act + const result = getPathWithExtension("~/dir/file", tmpConfig); + + // Assert + expect(result).toBe("../../some/prefix/dir/file.js"); + }); +}); diff --git a/src/parser/parse.ts b/src/parser/parse.ts index 5b7a146..da6e439 100644 --- a/src/parser/parse.ts +++ b/src/parser/parse.ts @@ -1,17 +1,18 @@ -import {isTruthy} from '@khanacademy/wonder-stuff-core'; +import {isTruthy} from "@khanacademy/wonder-stuff-core"; import type { - BabelNodeImportDeclaration, - BabelNodeVariableDeclarator, - BabelNodeTaggedTemplateExpression, - BabelNodeFile, -} from '@babel/types'; + ImportDeclaration, + VariableDeclarator, + TaggedTemplateExpression, + File, +} from "@babel/types"; -import {parse} from '@babel/parser'; // eslint-disable-line flowtype-errors/uncovered -import traverse from '@babel/traverse'; // eslint-disable-line flowtype-errors/uncovered +import {parse, ParserPlugin} from "@babel/parser"; +import traverse from "@babel/traverse"; -import path from 'path'; +import path from "path"; -import {getPathWithExtension} from './utils'; +import {getPathWithExtension} from "./utils"; +import {Config} from "../types"; /** * This file is responsible for finding all gql`-annotated @@ -43,52 +44,52 @@ import {getPathWithExtension} from './utils'; */ export type Template = { - literals: Array - expressions: Array - loc: Loc + literals: Array; + expressions: Array; + loc: Loc; }; export type Loc = { - start: number - end: number - path: string - line: number + start: number; + end: number; + path: string; + line: number; }; export type Document = { - type: 'document' - source: Template + type: "document"; + source: Template; }; export type Import = { - type: 'import' - name: string - path: string - loc: Loc + type: "import"; + name: string; + path: string; + loc: Loc; }; export type Operation = { - source: Template + source: Template; // TODO: Determine if an operation is already wrapped // in `gqlOp` so we can automatically wrap if needed. // needsWrapping: boolean, }; export type FileResult = { - path: string - operations: Array + path: string; + operations: Array; exports: { - [key: string]: Document | Import - } + [key: string]: Document | Import; + }; locals: { - [key: string]: Document | Import - } + [key: string]: Document | Import; + }; errors: Array<{ - loc: Loc - message: string - }> + loc: Loc; + message: string; + }>; }; export type Files = { - [path: string]: FileResult + [path: string]: FileResult; }; /** @@ -99,12 +100,15 @@ export type Files = { * potentially relevant, and of course any values referenced * from a graphql template are treated as relevant. */ -const listExternalReferences = (file: FileResult): Array => { +const listExternalReferences = ( + file: FileResult, + config: Config, +): Array => { const paths: Record = {}; const add = (v: Document | Import, followImports: boolean) => { - if (v.type === 'import') { + if (v.type === "import") { if (followImports) { - const absPath = getPathWithExtension(v.path); + const absPath = getPathWithExtension(v.path, config); if (absPath) { paths[absPath] = true; } @@ -142,10 +146,12 @@ const listExternalReferences = (file: FileResult): Array => { export const processFile = ( filePath: string, - contents: string | { - text: string - resolvedPath: string - }, + contents: + | string + | { + text: string; + resolvedPath: string; + }, ): FileResult => { const dir = path.dirname(filePath); const result: FileResult = { @@ -155,55 +161,51 @@ export const processFile = ( locals: {}, errors: [], }; - const resolved = - typeof contents === 'string' ? filePath : contents.resolvedPath; - const text = typeof contents === 'string' ? contents : contents.text; - const plugins = resolved.match(/\.tsx?$/) - ? ['typescript', filePath.endsWith('x') ? 'jsx' : null].filter(isTruthy) - : [['flow', {enums: true}], 'jsx']; - /* eslint-disable flowtype-errors/uncovered */ - const ast: BabelNodeFile = parse(text, { - sourceType: 'module', + const text = typeof contents === "string" ? contents : contents.text; + const plugins: Array = filePath.endsWith("x") + ? ["typescript", "jsx"] + : ["typescript"]; + const ast: File = parse(text, { + sourceType: "module", allowImportExportEverywhere: true, plugins: plugins, }); - /* eslint-enable flowtype-errors/uncovered */ - const gqlTagNames = []; + const gqlTagNames: Array = []; const seenTemplates: { - [key: number]: Document | false + [key: number]: Document | false; } = {}; ast.program.body.forEach((toplevel) => { - if (toplevel.type === 'ImportDeclaration') { + if (toplevel.type === "ImportDeclaration") { const newLocals = getLocals(dir, toplevel, filePath); if (newLocals) { Object.keys(newLocals).forEach((k) => { const local = newLocals[k]; - if (local.path.startsWith('/')) { + if (local.path.startsWith("/")) { result.locals[k] = local; } if ( - local.path === 'graphql-tag' && - local.name === 'default' + local.path === "graphql-tag" && + local.name === "default" ) { gqlTagNames.push(k); } }); } } - if (toplevel.type === 'ExportNamedDeclaration') { + if (toplevel.type === "ExportNamedDeclaration") { if (toplevel.source) { const source = toplevel.source; - const importPath = source.value.startsWith('.') + const importPath = source.value.startsWith(".") ? path.resolve(path.join(dir, source.value)) : source.value; - toplevel.specifiers?.forEach((spec: unknown) => { + toplevel.specifiers?.forEach((spec) => { if ( - spec.type === 'ExportSpecifier' && - spec.exported.type === 'Identifier' + spec.type === "ExportSpecifier" && + spec.exported.type === "Identifier" ) { result.exports[spec.exported.name] = { - type: 'import', + type: "import", name: spec.local.name, path: importPath, loc: { @@ -216,10 +218,10 @@ export const processFile = ( } }); } else { - toplevel.specifiers?.forEach((spec: unknown) => { - if (spec.type === 'ExportSpecifier') { + toplevel.specifiers?.forEach((spec) => { + if (spec.type === "ExportSpecifier") { const local = result.locals[spec.local.name]; - if (local && spec.exported.type === 'Identifier') { + if (local && spec.exported.type === "Identifier") { result.exports[spec.exported.name] = local; } } @@ -228,23 +230,23 @@ export const processFile = ( } const processDeclarator = ( - decl: BabelNodeVariableDeclarator, + decl: VariableDeclarator, isExported: boolean, ) => { - if (decl.id.type !== 'Identifier' || !decl.init) { + if (decl.id.type !== "Identifier" || !decl.init) { return; } const {init} = decl; const id = decl.id.name; if ( - init.type === 'TaggedTemplateExpression' && - init.tag.type === 'Identifier' + init.type === "TaggedTemplateExpression" && + init.tag.type === "Identifier" ) { if (gqlTagNames.includes(init.tag.name)) { const tpl = processTemplate(init, result); if (tpl) { const document = (result.locals[id] = { - type: 'document', + type: "document", source: tpl, }); seenTemplates[init.start ?? -1] = document; @@ -256,7 +258,7 @@ export const processFile = ( } } } - if (init.type === 'Identifier' && result.locals[init.name]) { + if (init.type === "Identifier" && result.locals[init.name]) { result.locals[id] = result.locals[init.name]; if (isExported) { result.exports[id] = result.locals[init.name]; @@ -264,15 +266,15 @@ export const processFile = ( } }; - if (toplevel.type === 'VariableDeclaration') { + if (toplevel.type === "VariableDeclaration") { toplevel.declarations.forEach((decl) => { processDeclarator(decl, false); }); } if ( - toplevel.type === 'ExportNamedDeclaration' && - toplevel.declaration?.type === 'VariableDeclaration' + toplevel.type === "ExportNamedDeclaration" && + toplevel.declaration?.type === "VariableDeclaration" ) { toplevel.declaration.declarations.forEach((decl) => { processDeclarator(decl, true); @@ -281,21 +283,21 @@ export const processFile = ( }); const visitTpl = ( - node: BabelNodeTaggedTemplateExpression, + node: TaggedTemplateExpression, getBinding: (name: string) => Document | null, ) => { if (seenTemplates[node.start ?? -1] != null) { return; } if ( - node.tag.type !== 'Identifier' || + node.tag.type !== "Identifier" || !gqlTagNames.includes(node.tag.name) ) { return; } const tpl = processTemplate(node, result, getBinding); if (tpl) { - seenTemplates[node.start ?? -1] = {type: 'document', source: tpl}; + seenTemplates[node.start ?? -1] = {type: "document", source: tpl}; result.operations.push({ source: tpl, }); @@ -304,35 +306,37 @@ export const processFile = ( } }; - /* eslint-disable flowtype-errors/uncovered */ traverse(ast, { - TaggedTemplateExpression(path: unknown) { + TaggedTemplateExpression(path) { visitTpl(path.node, (name) => { const binding = path.scope.getBinding(name); - const start = binding.path.node.init - ? binding.path.node.init.start - : null; + if (!binding) { + return null; + } + const start = + "init" in binding.path.node && binding.path.node.init + ? binding.path.node.init.start + : null; if (start && seenTemplates[start]) { - return seenTemplates[start]; + return seenTemplates[start] || null; } return null; }); }, }); - /* eslint-enable flowtype-errors/uncovered */ return result; }; const processTemplate = ( - tpl: BabelNodeTaggedTemplateExpression, + tpl: TaggedTemplateExpression, result: FileResult, // getBinding?: (name: string) => Binding, // seenTemplates, getTemplate?: (name: string) => Document | null, ): Template | null | undefined => { // 'cooked' is the string as runtime javascript will see it. - const literals = tpl.quasi.quasis.map((q) => q.value.cooked || ''); + const literals = tpl.quasi.quasis.map((q) => q.value.cooked || ""); const expressions = tpl.quasi.expressions.map( (expr): null | Document | Import => { const loc: Loc = { @@ -341,7 +345,7 @@ const processTemplate = ( line: expr.loc?.start.line ?? -1, path: result.path, }; - if (expr.type !== 'Identifier') { + if (expr.type !== "Identifier") { result.errors.push({ loc, message: `Template literal interpolation must be an identifier`, @@ -378,29 +382,36 @@ const processTemplate = ( }; }; -const getLocals = (dir: unknown, toplevel: BabelNodeImportDeclaration, myPath: string): { - [key: string]: Import -} | null | undefined => { - if (toplevel.importKind === 'type') { +const getLocals = ( + dir: string, + toplevel: ImportDeclaration, + myPath: string, +): + | { + [key: string]: Import; + } + | null + | undefined => { + if (toplevel.importKind === "type") { return null; } - const importPath = toplevel.source.value.startsWith('.') + const importPath = toplevel.source.value.startsWith(".") ? path.resolve(path.join(dir, toplevel.source.value)) : toplevel.source.value; const locals: Record = {}; toplevel.specifiers.forEach((spec) => { - if (spec.type === 'ImportDefaultSpecifier') { + if (spec.type === "ImportDefaultSpecifier") { locals[spec.local.name] = { - type: 'import', - name: 'default', + type: "import", + name: "default", path: importPath, loc: {start: spec.start, end: spec.end, path: myPath}, }; - } else if (spec.type === 'ImportSpecifier') { + } else if (spec.type === "ImportSpecifier") { locals[spec.local.name] = { - type: 'import', + type: "import", name: - spec.imported.type === 'Identifier' + spec.imported.type === "Identifier" ? spec.imported.name : spec.imported.value, path: importPath, @@ -413,21 +424,24 @@ const getLocals = (dir: unknown, toplevel: BabelNodeImportDeclaration, myPath: s export const processFiles = ( filePaths: Array, - getFileSource: (path: string) => string | { - text: string - resolvedPath: string - }, + config: Config, + getFileSource: (path: string) => + | string + | { + text: string; + resolvedPath: string; + }, ): Files => { const files: Files = {}; const toProcess = filePaths.slice(); while (toProcess.length) { const next = toProcess.shift(); - if (files[next]) { + if (!next || files[next]) { continue; } const result = processFile(next, getFileSource(next)); files[next] = result; - listExternalReferences(result).forEach((path) => { + listExternalReferences(result, config).forEach((path) => { if (!files[path] && !toProcess.includes(path)) { toProcess.push(path); } diff --git a/src/parser/resolve.ts b/src/parser/resolve.ts index 8342642..03df2cb 100644 --- a/src/parser/resolve.ts +++ b/src/parser/resolve.ts @@ -1,30 +1,41 @@ -import gql from 'graphql-tag'; -import {getPathWithExtension} from './utils'; -import type {DocumentNode} from 'graphql/language/ast'; -import type {FileResult, Files, Import, Template, Document} from './parse'; +import gql from "graphql-tag"; +import {getPathWithExtension} from "./utils"; +import type {DocumentNode} from "graphql/language/ast"; +import type {FileResult, Files, Import, Template, Document} from "./parse"; +import {Config} from "../types"; export type Resolved = { [key: string]: { - document: DocumentNode - raw: Template - } + document: DocumentNode; + raw: Template; + }; }; -export const resolveDocuments = (files: Files): { - resolved: Resolved - errors: FileResult['errors'] +export const resolveDocuments = ( + files: Files, + config: Config, +): { + resolved: Resolved; + errors: FileResult["errors"]; } => { const resolved: Resolved = {}; - const errors: FileResult['errors'] = []; + const errors: FileResult["errors"] = []; Object.keys(files).forEach((path) => { const file = files[path]; file.operations.forEach((op) => { - resolveGqlTemplate(op.source, files, errors, resolved, {}); + resolveGqlTemplate(op.source, files, errors, resolved, {}, config); }); Object.keys(file.locals).forEach((k) => { const local = file.locals[k]; - if (local.type === 'document') { - resolveGqlTemplate(local.source, files, errors, resolved, {}); + if (local.type === "document") { + resolveGqlTemplate( + local.source, + files, + errors, + resolved, + {}, + config, + ); } }); }); @@ -34,17 +45,18 @@ export const resolveDocuments = (files: Files): { const resolveImport = ( expr: Import, files: Files, - errors: FileResult['errors'], + errors: FileResult["errors"], seen: { - [key: string]: true + [key: string]: true; }, + config: Config, ): Document | null | undefined => { - const absPath: string = getPathWithExtension(expr.path); + const absPath: string = getPathWithExtension(expr.path, config); if (seen[absPath]) { errors.push({ loc: expr.loc, message: `Circular import ${Object.keys(seen).join( - ' -> ', + " -> ", )} -> ${absPath}`, }); return null; @@ -63,8 +75,8 @@ const resolveImport = ( return null; } const value = res.exports[expr.name]; - if (value.type === 'import') { - return resolveImport(value, files, errors, seen); + if (value.type === "import") { + return resolveImport(value, files, errors, seen, config); } return value; }; @@ -72,13 +84,14 @@ const resolveImport = ( const resolveGqlTemplate = ( template: Template, files: Files, - errors: FileResult['errors'], + errors: FileResult["errors"], resolved: Resolved, seen: { - [key: string]: Template + [key: string]: Template; }, + config: Config, ): DocumentNode | null | undefined => { - const key = template.loc.path + ':' + template.loc.line; + const key = template.loc.path + ":" + template.loc.line; if (seen[key]) { errors.push({ loc: template.loc, @@ -86,12 +99,12 @@ const resolveGqlTemplate = ( .map( (k) => k + - ' ~ ' + + " ~ " + seen[k].expressions.length + - ',' + + "," + seen[k].literals.length, ) - .join(' -> ')} -> ${key}`, + .join(" -> ")} -> ${key}`, }); return null; } @@ -100,17 +113,31 @@ const resolveGqlTemplate = ( return resolved[key].document; } const expressions = template.expressions.map((expr) => { - if (expr.type === 'import') { - const document = resolveImport(expr, files, errors, {}); + if (expr.type === "import") { + const document = resolveImport(expr, files, errors, {}, config); return document - ? resolveGqlTemplate(document.source, files, errors, resolved, { - ...seen, - }) + ? resolveGqlTemplate( + document.source, + files, + errors, + resolved, + { + ...seen, + }, + config, + ) : null; } - return resolveGqlTemplate(expr.source, files, errors, resolved, { - ...seen, - }); + return resolveGqlTemplate( + expr.source, + files, + errors, + resolved, + { + ...seen, + }, + config, + ); }); if (expressions.includes(null)) { return null; diff --git a/src/parser/utils.ts b/src/parser/utils.ts index 75f87e1..d0c7eb0 100644 --- a/src/parser/utils.ts +++ b/src/parser/utils.ts @@ -1,6 +1,19 @@ -import fs from 'fs'; +import fs from "fs"; +import {Config} from "../types"; -export const getPathWithExtension = (pathWithoutExtension: string): string => { +export const getPathWithExtension = ( + pathWithoutExtension: string, + config: Config, +): string => { + // Process the path so that we can handle aliases. + if (config.alias) { + for (const {find, replacement} of config.alias) { + pathWithoutExtension = pathWithoutExtension.replace( + find, + replacement, + ); + } + } if ( /\.(less|css|png|gif|jpg|jpeg|js|jsx|ts|tsx|mjs)$/.test( pathWithoutExtension, @@ -8,17 +21,17 @@ export const getPathWithExtension = (pathWithoutExtension: string): string => { ) { return pathWithoutExtension; } - if (fs.existsSync(pathWithoutExtension + '.js')) { - return pathWithoutExtension + '.js'; + if (fs.existsSync(pathWithoutExtension + ".js")) { + return pathWithoutExtension + ".js"; } - if (fs.existsSync(pathWithoutExtension + '.jsx')) { - return pathWithoutExtension + '.jsx'; + if (fs.existsSync(pathWithoutExtension + ".jsx")) { + return pathWithoutExtension + ".jsx"; } - if (fs.existsSync(pathWithoutExtension + '.tsx')) { - return pathWithoutExtension + '.tsx'; + if (fs.existsSync(pathWithoutExtension + ".tsx")) { + return pathWithoutExtension + ".tsx"; } - if (fs.existsSync(pathWithoutExtension + '.ts')) { - return pathWithoutExtension + '.ts'; + if (fs.existsSync(pathWithoutExtension + ".ts")) { + return pathWithoutExtension + ".ts"; } // NOTE(john): This is a bit of a hack, but it's necessary for when we // have a file that doesn't exist. This will happen when we delete all of diff --git a/src/schemaFromIntrospectionData.ts b/src/schemaFromIntrospectionData.ts index e9426b0..9cc4ee0 100644 --- a/src/schemaFromIntrospectionData.ts +++ b/src/schemaFromIntrospectionData.ts @@ -2,10 +2,12 @@ * Takes the introspectionQuery response and parses it into the "Schema" * type that we use to look up types, interfaces, etc. */ -import type {IntrospectionQuery} from 'graphql'; -import type {Schema} from './types'; +import type {IntrospectionQuery} from "graphql"; +import type {Schema} from "./types"; -export const schemaFromIntrospectionData = (schema: IntrospectionQuery): Schema => { +export const schemaFromIntrospectionData = ( + schema: IntrospectionQuery, +): Schema => { const result: Schema = { interfacesByName: {}, typesByName: {}, @@ -15,15 +17,15 @@ export const schemaFromIntrospectionData = (schema: IntrospectionQuery): Schema }; schema.__schema.types.forEach((type) => { - if (type.kind === 'ENUM') { + if (type.kind === "ENUM") { result.enumsByName[type.name] = type; return; } - if (type.kind === 'UNION') { + if (type.kind === "UNION") { result.unionsByName[type.name] = type; return; } - if (type.kind === 'INTERFACE') { + if (type.kind === "INTERFACE") { result.interfacesByName[type.name] = { ...type, possibleTypesByName: {}, @@ -41,11 +43,11 @@ export const schemaFromIntrospectionData = (schema: IntrospectionQuery): Schema }); return; } - if (type.kind === 'INPUT_OBJECT') { + if (type.kind === "INPUT_OBJECT") { result.inputObjectsByName[type.name] = type; return; } - if (type.kind === 'SCALAR') { + if (type.kind === "SCALAR") { return; } result.typesByName[type.name] = { diff --git a/src/types.ts b/src/types.ts index 346bbb2..4797638 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,4 +1,4 @@ -import type {Node} from '@babel/types'; +import type {Node} from "@babel/types"; import type { FragmentDefinitionNode, IntrospectionEnumType, @@ -8,90 +8,94 @@ import type { IntrospectionObjectType, IntrospectionUnionType, SelectionNode, -} from 'graphql'; +} from "graphql"; export type Selections = ReadonlyArray; export type GenerateConfig = { - schemaFilePath: string - match?: ReadonlyArray - exclude?: ReadonlyArray - typeScript?: boolean - scalars?: Scalars - strictNullability?: boolean + schemaFilePath: string; + match?: ReadonlyArray; + exclude?: ReadonlyArray; + typeScript?: boolean; + scalars?: Scalars; + strictNullability?: boolean; /** * The command that users should run to regenerate the types files. */ - regenerateCommand?: string - readOnlyArray?: boolean - splitTypes?: boolean - generatedDirectory?: string - exportAllObjectTypes?: boolean - typeFileName?: string - experimentalEnums?: boolean - omitFileExtensions?: boolean + regenerateCommand?: string; + readOnlyArray?: boolean; + splitTypes?: boolean; + generatedDirectory?: string; + exportAllObjectTypes?: boolean; + typeFileName?: string; + experimentalEnums?: boolean; + omitFileExtensions?: boolean; }; export type CrawlConfig = { - root: string - pragma?: string - loosePragma?: string - ignorePragma?: string - dumpOperations?: string + root: string; + pragma?: string; + loosePragma?: string; + ignorePragma?: string; + dumpOperations?: string; }; export type Config = { - crawl: CrawlConfig - generate: GenerateConfig | Array + crawl: CrawlConfig; + generate: GenerateConfig | Array; + alias?: Array<{ + find: RegExp | string; + replacement: string; + }>; }; export type Schema = { interfacesByName: { [key: string]: IntrospectionInterfaceType & { fieldsByName: { - [key: string]: IntrospectionField - } + [key: string]: IntrospectionField; + }; possibleTypesByName: { - [key: string]: boolean - } - } - } + [key: string]: boolean; + }; + }; + }; inputObjectsByName: { - [key: string]: IntrospectionInputObjectType - } + [key: string]: IntrospectionInputObjectType; + }; typesByName: { [key: string]: IntrospectionObjectType & { fieldsByName: { - [key: string]: IntrospectionField - } - } - } + [key: string]: IntrospectionField; + }; + }; + }; unionsByName: { - [key: string]: IntrospectionUnionType - } + [key: string]: IntrospectionUnionType; + }; enumsByName: { - [key: string]: IntrospectionEnumType - } + [key: string]: IntrospectionEnumType; + }; }; export type Context = { - path: Array - strictNullability: boolean - readOnlyArray: boolean + path: Array; + strictNullability: boolean; + readOnlyArray: boolean; fragments: { - [key: string]: FragmentDefinitionNode - } - schema: Schema - scalars: Scalars - errors: Array + [key: string]: FragmentDefinitionNode; + }; + schema: Schema; + scalars: Scalars; + errors: Array; allObjectTypes: null | { - [key: string]: Node - } - typeScript: boolean + [key: string]: Node; + }; + typeScript: boolean; experimentalEnumsMap?: { - [key: string]: Node - } // index signature that is populated with declarations + [key: string]: Node; + }; // index signature that is populated with declarations }; export type Scalars = { - [key: string]: 'string' | 'number' | 'boolean' + [key: string]: "string" | "number" | "boolean"; }; diff --git a/src/utils.ts b/src/utils.ts index 9857155..4c73cc4 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,11 +1,16 @@ -import * as babelTypes from '@babel/types'; -import {TSPropertySignature} from '@babel/types'; +import * as babelTypes from "@babel/types"; +import {TSPropertySignature} from "@babel/types"; -export const liftLeadingPropertyComments = (property: TSPropertySignature): TSPropertySignature => { +export const liftLeadingPropertyComments = ( + property: TSPropertySignature, +): TSPropertySignature => { return transferLeadingComments(property.typeAnnotation!, property); }; -export const maybeAddDescriptionComment = (description: string | null | undefined, node: T): T => { +export const maybeAddDescriptionComment = ( + description: string | null | undefined, + node: T, +): T => { if (description) { addCommentAsLineComments(description, node); } @@ -17,18 +22,21 @@ export function addCommentAsLineComments( res: babelTypes.Node, ) { if (res.leadingComments?.length) { - res.leadingComments[0].value += '\n\n---\n\n' + description; + res.leadingComments[0].value += "\n\n---\n\n" + description; } else { babelTypes.addComment( res, - 'leading', - '* ' + description, + "leading", + "* " + description, false, // this specifies that it's a block comment, not a line comment ); } } -export const transferLeadingComments = (source: babelTypes.Node, dest: T): T => { +export const transferLeadingComments = ( + source: babelTypes.Node, + dest: T, +): T => { if (source.leadingComments?.length) { dest.leadingComments = [ ...(dest.leadingComments || []), @@ -40,17 +48,21 @@ export const transferLeadingComments = (source: babel }; export function nullableType(type: babelTypes.TSType): babelTypes.TSType { - return babelTypes.tsUnionType([type, babelTypes.tsNullKeyword(), babelTypes.tsUndefinedKeyword()]); + return babelTypes.tsUnionType([ + type, + babelTypes.tsNullKeyword(), + babelTypes.tsUndefinedKeyword(), + ]); } export function isnNullableType(type: babelTypes.TSType): boolean { let hasNull = false; let hasUndefined = false; - if (type.type === 'TSUnionType') { + if (type.type === "TSUnionType") { for (const t of type.types) { - if (t.type === 'TSNullKeyword') { + if (t.type === "TSNullKeyword") { hasNull = true; - } else if (t.type === 'TSUndefinedKeyword') { + } else if (t.type === "TSUndefinedKeyword") { hasUndefined = true; } } @@ -58,10 +70,12 @@ export function isnNullableType(type: babelTypes.TSType): boolean { return hasNull && hasUndefined; } -export function objectTypeFromProperties(properties: babelTypes.TSPropertySignature[]): babelTypes.TSTypeLiteral { - let exitingProperties: Record = {}; - let filteredProperties = properties.filter((p) => { - if (p.key.type === 'Identifier') { +export function objectTypeFromProperties( + properties: babelTypes.TSPropertySignature[], +): babelTypes.TSTypeLiteral { + const exitingProperties: Record = {}; + const filteredProperties = properties.filter((p) => { + if (p.key.type === "Identifier") { if (exitingProperties[p.key.name]) { return false; } diff --git a/tools/find-files-with-gql.ts b/tools/find-files-with-gql.ts index 40c3835..dedd8ac 100644 --- a/tools/find-files-with-gql.ts +++ b/tools/find-files-with-gql.ts @@ -1,16 +1,14 @@ -const path = require('path'); -const {execSync} = require('child_process'); +const path = require("path"); +const {execSync} = require("child_process"); export const findRepoRoot = (): string => { try { - const res = execSync('git rev-parse --show-toplevel', { - encoding: 'utf8', + const res = execSync("git rev-parse --show-toplevel", { + encoding: "utf8", }); return res.trim(); - // eslint-disable-next-line flowtype-errors/uncovered } catch (err: any) { throw new Error( - // eslint-disable-next-line flowtype-errors/uncovered `Unable to use git rev-parse to find the repository root. ${err.message}`, ); } @@ -21,18 +19,16 @@ export const findGraphqlTagReferences = (root: string): Array => { const response = execSync( "git grep -I --word-regexp --name-only --fixed-strings 'gql`' -- '*.js'", { - encoding: 'utf8', + encoding: "utf8", cwd: root, }, ); return response .trim() - .split('\n') - .map((relative) => path.join(root, relative)); - // eslint-disable-next-line flowtype-errors/uncovered + .split("\n") + .map((relative: string) => path.join(root, relative)); } catch (err: any) { throw new Error( - // eslint-disable-next-line flowtype-errors/uncovered `Unable to use git grep to find files with gql tags. ${err.message}`, ); } diff --git a/yarn.lock b/yarn.lock index b2df6e6..93ed40e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1099,28 +1099,20 @@ "@babel/plugin-transform-modules-commonjs" "^7.22.5" "@babel/plugin-transform-typescript" "^7.22.5" -"@babel/runtime-corejs3@^7.10.2": - version "7.17.2" - resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.17.2.tgz#fdca2cd05fba63388babe85d349b6801b008fd13" - integrity sha512-NcKtr2epxfIrNM4VOmPKO46TvDMCBhgi2CrSHaEarrz+Plk2K5r9QemmOFTGpZaoKnWoGH5MO+CzeRsih/Fcgg== +"@babel/runtime@^7.10.4", "@babel/runtime@^7.5.5": + version "7.17.7" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.7.tgz#a5f3328dc41ff39d803f311cfe17703418cf9825" + integrity sha512-L6rvG9GDxaLgFjg41K+5Yv9OMrU98sWe+Ykmc6FDJW/+vYZMhdOMKkISgzptMaERHvS2Y2lw9MDRm2gHhlQQoA== dependencies: - core-js-pure "^3.20.2" regenerator-runtime "^0.13.4" -"@babel/runtime@^7.10.2", "@babel/runtime@^7.16.0", "@babel/runtime@^7.16.3", "@babel/runtime@^7.8.4": +"@babel/runtime@^7.8.4": version "7.17.2" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.2.tgz#66f68591605e59da47523c631416b18508779941" integrity sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw== dependencies: regenerator-runtime "^0.13.4" -"@babel/runtime@^7.10.4", "@babel/runtime@^7.5.5": - version "7.17.7" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.7.tgz#a5f3328dc41ff39d803f311cfe17703418cf9825" - integrity sha512-L6rvG9GDxaLgFjg41K+5Yv9OMrU98sWe+Ykmc6FDJW/+vYZMhdOMKkISgzptMaERHvS2Y2lw9MDRm2gHhlQQoA== - dependencies: - regenerator-runtime "^0.13.4" - "@babel/template@^7.16.7", "@babel/template@^7.3.3": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155" @@ -1369,6 +1361,18 @@ human-id "^1.0.2" prettier "^1.19.1" +"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" + integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== + dependencies: + eslint-visitor-keys "^3.3.0" + +"@eslint-community/regexpp@^4.10.0", "@eslint-community/regexpp@^4.6.1": + version "4.11.0" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.11.0.tgz#b0ffd0312b4a3fd2d6f77237e7248a5ad3a680ae" + integrity sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A== + "@eslint/eslintrc@^0.4.3": version "0.4.3" resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c" @@ -1384,21 +1388,35 @@ minimatch "^3.0.4" strip-json-comments "^3.1.1" -"@eslint/eslintrc@^1.0.5": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.2.0.tgz#7ce1547a5c46dfe56e1e45c3c9ed18038c721c6a" - integrity sha512-igm9SjJHNEJRiUnecP/1R5T3wKLEJ7pL6e2P+GUSfCd0dGjPYYZve08uzw8L2J8foVHFz+NGu12JxRcU2gGo6w== +"@eslint/eslintrc@^2.1.4": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.4.tgz#388a269f0f25c1b6adc317b5a2c55714894c70ad" + integrity sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ== dependencies: ajv "^6.12.4" debug "^4.3.2" - espree "^9.3.1" - globals "^13.9.0" - ignore "^4.0.6" + espree "^9.6.0" + globals "^13.19.0" + ignore "^5.2.0" import-fresh "^3.2.1" js-yaml "^4.1.0" - minimatch "^3.0.4" + minimatch "^3.1.2" strip-json-comments "^3.1.1" +"@eslint/js@8.57.0": + version "8.57.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.57.0.tgz#a5417ae8427873f1dd08b70b3574b453e67b5f7f" + integrity sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g== + +"@humanwhocodes/config-array@^0.11.14": + version "0.11.14" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.14.tgz#d78e481a039f7566ecc9660b4ea7fe6b1fec442b" + integrity sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg== + dependencies: + "@humanwhocodes/object-schema" "^2.0.2" + debug "^4.3.1" + minimatch "^3.0.5" + "@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" @@ -1408,20 +1426,21 @@ debug "^4.1.1" minimatch "^3.0.4" -"@humanwhocodes/config-array@^0.9.2": - version "0.9.5" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.9.5.tgz#2cbaf9a89460da24b5ca6531b8bbfc23e1df50c7" - integrity sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw== - dependencies: - "@humanwhocodes/object-schema" "^1.2.1" - debug "^4.1.1" - minimatch "^3.0.4" +"@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== -"@humanwhocodes/object-schema@^1.2.0", "@humanwhocodes/object-schema@^1.2.1": +"@humanwhocodes/object-schema@^1.2.0": version "1.2.1" resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== +"@humanwhocodes/object-schema@^2.0.2": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz#4a2868d75d6d6963e423bcf90b7fd1be343409d3" + integrity sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA== + "@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" @@ -1651,10 +1670,10 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" -"@khanacademy/eslint-config@^0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@khanacademy/eslint-config/-/eslint-config-0.1.0.tgz#e2b2c935be685f76075ee83136752b184c1ac733" - integrity sha512-fskDM6GuRgZWmHHt2oUspcbsYNh6HNSB211372P98m3YRwkZNOeRCTFB7Byd3owfSm1z2jDYtUozgQv9zCWiVA== +"@khanacademy/eslint-config@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@khanacademy/eslint-config/-/eslint-config-4.0.0.tgz#13ad9f53c7c1503e13818045653bbd53bf5b7f3a" + integrity sha512-4FHz/TyU+HIwlVUJ/MHyQ4poob2wnyA4x6XHzvMHj5zMvHcIaDPDDzbnbeAX4dtNQY5suHIFStBPwxhJZQghZg== "@khanacademy/wonder-stuff-core@^1.5.1": version "1.5.1" @@ -1701,7 +1720,7 @@ resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== -"@nodelib/fs.walk@^1.2.3": +"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": version "1.2.8" resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== @@ -1842,6 +1861,19 @@ resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.4.4.tgz#5d9b63132df54d8909fce1c3f8ca260fdd693e17" integrity sha512-ReVR2rLTV1kvtlWFyuot+d1pkpG2Fw/XKE3PDAdj57rbM97ttSp9JZ2UsP+2EHTylra9cUf6JA7tGwW1INzUrA== +"@types/prop-types@*", "@types/prop-types@^15.7.12": + version "15.7.12" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.12.tgz#12bb1e2be27293c1406acb6af1c3f3a1481d98c6" + integrity sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q== + +"@types/react@^18.3.3": + version "18.3.3" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.3.tgz#9679020895318b0915d7a3ab004d92d33375c45f" + integrity sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw== + dependencies: + "@types/prop-types" "*" + csstype "^3.0.2" + "@types/semver@^6.0.0": version "6.2.3" resolved "https://registry.yarnpkg.com/@types/semver/-/semver-6.2.3.tgz#5798ecf1bec94eaa64db39ee52808ec0693315aa" @@ -1871,6 +1903,21 @@ dependencies: "@types/yargs-parser" "*" +"@typescript-eslint/eslint-plugin@^7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.17.0.tgz#c8ed1af1ad2928ede5cdd207f7e3090499e1f77b" + integrity sha512-pyiDhEuLM3PuANxH7uNYan1AaFs5XE0zw1hq69JBvGvE7gSuEoQl1ydtEe/XQeoC3GQxLXyOVa5kNOATgM638A== + dependencies: + "@eslint-community/regexpp" "^4.10.0" + "@typescript-eslint/scope-manager" "7.17.0" + "@typescript-eslint/type-utils" "7.17.0" + "@typescript-eslint/utils" "7.17.0" + "@typescript-eslint/visitor-keys" "7.17.0" + graphemer "^1.4.0" + ignore "^5.3.1" + natural-compare "^1.4.0" + ts-api-utils "^1.3.0" + "@typescript-eslint/experimental-utils@3.10.1": version "3.10.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-3.10.1.tgz#e179ffc81a80ebcae2ea04e0332f8b251345a686" @@ -1893,11 +1940,45 @@ "@typescript-eslint/typescript-estree" "3.10.1" eslint-visitor-keys "^1.1.0" +"@typescript-eslint/parser@^7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-7.17.0.tgz#be8e32c159190cd40a305a2121220eadea5a88e7" + integrity sha512-puiYfGeg5Ydop8eusb/Hy1k7QmOU6X3nvsqCgzrB2K4qMavK//21+PzNE8qeECgNOIoertJPUC1SpegHDI515A== + dependencies: + "@typescript-eslint/scope-manager" "7.17.0" + "@typescript-eslint/types" "7.17.0" + "@typescript-eslint/typescript-estree" "7.17.0" + "@typescript-eslint/visitor-keys" "7.17.0" + debug "^4.3.4" + +"@typescript-eslint/scope-manager@7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.17.0.tgz#e072d0f914662a7bfd6c058165e3c2b35ea26b9d" + integrity sha512-0P2jTTqyxWp9HiKLu/Vemr2Rg1Xb5B7uHItdVZ6iAenXmPo4SZ86yOPCJwMqpCyaMiEHTNqizHfsbmCFT1x9SA== + dependencies: + "@typescript-eslint/types" "7.17.0" + "@typescript-eslint/visitor-keys" "7.17.0" + +"@typescript-eslint/type-utils@7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-7.17.0.tgz#c5da78feb134c9c9978cbe89e2b1a589ed22091a" + integrity sha512-XD3aaBt+orgkM/7Cei0XNEm1vwUxQ958AOLALzPlbPqb8C1G8PZK85tND7Jpe69Wualri81PLU+Zc48GVKIMMA== + dependencies: + "@typescript-eslint/typescript-estree" "7.17.0" + "@typescript-eslint/utils" "7.17.0" + debug "^4.3.4" + ts-api-utils "^1.3.0" + "@typescript-eslint/types@3.10.1": version "3.10.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-3.10.1.tgz#1d7463fa7c32d8a23ab508a803ca2fe26e758727" integrity sha512-+3+FCUJIahE9q0lDi1WleYzjCwJs5hIsbugIgnbB+dSCYUxl8L6PwmsyOPFZde2hc1DlTo/xnkOgiTLSyAbHiQ== +"@typescript-eslint/types@7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.17.0.tgz#7ce8185bdf06bc3494e73d143dbf3293111b9cff" + integrity sha512-a29Ir0EbyKTKHnZWbNsrc/gqfIBqYPwj3F2M+jWE/9bqfEHg0AMtXzkbUkOG6QgEScxh2+Pz9OXe11jHDnHR7A== + "@typescript-eslint/typescript-estree@3.10.1": version "3.10.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-3.10.1.tgz#fd0061cc38add4fad45136d654408569f365b853" @@ -1912,6 +1993,30 @@ semver "^7.3.2" tsutils "^3.17.1" +"@typescript-eslint/typescript-estree@7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.17.0.tgz#dcab3fea4c07482329dd6107d3c6480e228e4130" + integrity sha512-72I3TGq93t2GoSBWI093wmKo0n6/b7O4j9o8U+f65TVD0FS6bI2180X5eGEr8MA8PhKMvYe9myZJquUT2JkCZw== + dependencies: + "@typescript-eslint/types" "7.17.0" + "@typescript-eslint/visitor-keys" "7.17.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + minimatch "^9.0.4" + semver "^7.6.0" + ts-api-utils "^1.3.0" + +"@typescript-eslint/utils@7.17.0", "@typescript-eslint/utils@^6.0.0 || ^7.0.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-7.17.0.tgz#815cd85b9001845d41b699b0ce4f92d6dfb84902" + integrity sha512-r+JFlm5NdB+JXc7aWWZ3fKSm1gn0pkswEwIYsrGPdsT2GjsRATAKXiNtp3vgAAO1xZhX8alIOEQnNMl3kbTgJw== + dependencies: + "@eslint-community/eslint-utils" "^4.4.0" + "@typescript-eslint/scope-manager" "7.17.0" + "@typescript-eslint/types" "7.17.0" + "@typescript-eslint/typescript-estree" "7.17.0" + "@typescript-eslint/visitor-keys@3.10.1": version "3.10.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-3.10.1.tgz#cd4274773e3eb63b2e870ac602274487ecd1e931" @@ -1919,6 +2024,19 @@ dependencies: eslint-visitor-keys "^1.1.0" +"@typescript-eslint/visitor-keys@7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.17.0.tgz#680465c734be30969e564b4647f38d6cdf49bfb0" + integrity sha512-RVGC9UhPOCsfCdI9pU++K4nD7to+jTcMIbXTSOcrLqUEW6gF2pU1UUbYJKc9cvcRSK1UDeMJ7pdMxf4bhMpV/A== + dependencies: + "@typescript-eslint/types" "7.17.0" + eslint-visitor-keys "^3.4.3" + +"@ungap/structured-clone@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" + integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== + "@wry/equality@^0.1.2": version "0.1.11" resolved "https://registry.yarnpkg.com/@wry/equality/-/equality-0.1.11.tgz#35cb156e4a96695aa81a9ecc4d03787bc17f1790" @@ -1939,7 +2057,7 @@ acorn-globals@^6.0.0: acorn "^7.1.1" acorn-walk "^7.1.1" -acorn-jsx@^5.2.0, acorn-jsx@^5.3.1: +acorn-jsx@^5.2.0, acorn-jsx@^5.3.1, acorn-jsx@^5.3.2: version "5.3.2" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== @@ -1954,11 +2072,16 @@ acorn@^7.1.1, acorn@^7.4.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^8.2.4, acorn@^8.7.0: +acorn@^8.2.4: version "8.7.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ== +acorn@^8.9.0: + version "8.12.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.12.1.tgz#71616bdccbe25e27a54439e0046e89ca76df2248" + integrity sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg== + agent-base@6: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" @@ -2067,14 +2190,6 @@ argparse@^2.0.1: resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== -aria-query@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-4.2.2.tgz#0d2ca6c9aceb56b8977e9fed6aed7e15bbd2f83b" - integrity sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA== - dependencies: - "@babel/runtime" "^7.10.2" - "@babel/runtime-corejs3" "^7.10.2" - arr-diff@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" @@ -2087,17 +2202,6 @@ arr-flatten@^1.0.1: resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== -array-includes@^3.1.3, array-includes@^3.1.4: - version "3.1.4" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.4.tgz#f5b493162c760f3539631f005ba2bb46acb45ba9" - integrity sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - get-intrinsic "^1.1.1" - is-string "^1.0.7" - array-union@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" @@ -2108,25 +2212,11 @@ array-unique@^0.2.1: resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" integrity sha1-odl8yvy8JiXMcPrc6zalDFiwGlM= -array.prototype.flatmap@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.2.5.tgz#908dc82d8a406930fdf38598d51e7411d18d4446" - integrity sha512-08u6rVyi1Lj7oqWbS9nUxliETrtIROT4XGTA4D/LWGten6E3ocm7cy9SIrmNHOL5XVbVuckUp3X6Xyg8/zpvHA== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - es-abstract "^1.19.0" - arrify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= -ast-types-flow@^0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad" - integrity sha1-9wtzXGvKGlycItmCw+Oef+ujva0= - astral-regex@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" @@ -2137,16 +2227,6 @@ asynckit@^0.4.0: resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= -axe-core@^4.3.5: - version "4.4.1" - resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.4.1.tgz#7dbdc25989298f9ad006645cd396782443757413" - integrity sha512-gd1kmb21kwNuWr6BQz8fv6GNECPBnUasepcoLbekws23NVBLODdsClRZ+bQ8+9Uomf3Sm3+Vwn0oYG9NvwnJCw== - -axobject-query@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be" - integrity sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA== - babel-code-frame@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" @@ -2379,6 +2459,13 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + braces@^1.8.2: version "1.8.5" resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" @@ -2430,7 +2517,7 @@ buffer-from@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== -call-bind@^1.0.0, call-bind@^1.0.2: +call-bind@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== @@ -2463,9 +2550,9 @@ camelcase@^6.2.0: integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== caniuse-lite@^1.0.30001312: - version "1.0.30001312" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001312.tgz#e11eba4b87e24d22697dae05455d5aea28550d5f" - integrity sha512-Wiz1Psk2MEK0pX3rUzWaunLTZzqS2JYZFzNKqAiJGiuxIjRPLgV6+VDPOg6lQOUxmDwhTlh198JsTTi8Hzw6aQ== + version "1.0.30001643" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001643.tgz" + integrity sha512-ERgWGNleEilSrHM6iUz/zJNSQTP8Mr21wDWpdgvRwcTXGAq6jMtOUPP4dqFPTdKqZ2wKTdtB+uucZ3MRpAUSmg== chalk@^1.1.3: version "1.1.3" @@ -2632,16 +2719,6 @@ core-js-compat@^3.20.2, core-js-compat@^3.21.0: browserslist "^4.19.1" semver "7.0.0" -core-js-pure@^3.20.2: - version "3.21.1" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.21.1.tgz#8c4d1e78839f5f46208de7230cebfb72bc3bdb51" - integrity sha512-12VZfFIu+wyVbBebyHmRTuEE/tZrB4tJToWcwAMcsp3h4+sHR+fMJWbKpYiCRWlhFBq+KNyO8rIV9rTkeVmznQ== - -core-js@3.8.1: - version "3.8.1" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.8.1.tgz#f51523668ac8a294d1285c3b9db44025fda66d47" - integrity sha512-9Id2xHY1W7m8hCl8NkhQn5CufmF/WuR30BTRewvCXc1aZd3kMECwNZ69ndLbekKfakw9Rf2Xyc+QR6E7Gg+obg== - core-js@^2.4.0, core-js@^2.6.5: version "2.6.12" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" @@ -2682,6 +2759,11 @@ cssstyle@^2.3.0: dependencies: cssom "~0.3.6" +csstype@^3.0.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81" + integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== + csv-generate@^3.4.3: version "3.4.3" resolved "https://registry.yarnpkg.com/csv-generate/-/csv-generate-3.4.3.tgz#bc42d943b45aea52afa896874291da4b9108ffff" @@ -2707,11 +2789,6 @@ csv@^5.3.1: csv-stringify "^5.6.5" stream-transform "^2.1.3" -damerau-levenshtein@^1.0.7: - version "1.0.8" - resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7" - integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA== - data-urls@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" @@ -2735,6 +2812,13 @@ debug@^2.6.8: dependencies: ms "2.0.0" +debug@^4.3.1, debug@^4.3.4: + version "4.3.5" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.5.tgz#e83444eceb9fedd4a1da56d671ae2446a01a6e1e" + integrity sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg== + dependencies: + ms "2.1.2" + decamelize-keys@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9" @@ -2826,13 +2910,6 @@ dlv@^1.1.0: resolved "https://registry.yarnpkg.com/dlv/-/dlv-1.1.3.tgz#5c198a8a11453596e751494d49874bc7732f2e79" integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA== -doctrine@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" - integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== - dependencies: - esutils "^2.0.2" - doctrine@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" @@ -2862,11 +2939,6 @@ emoji-regex@^8.0.0: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== -emoji-regex@^9.2.2: - version "9.2.2" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" - integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== - enquirer@^2.3.0, enquirer@^2.3.5: version "2.3.6" resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" @@ -2881,41 +2953,6 @@ error-ex@^1.2.0, error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -es-abstract@^1.19.0, es-abstract@^1.19.1: - version "1.19.1" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.1.tgz#d4885796876916959de78edaa0df456627115ec3" - integrity sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w== - dependencies: - call-bind "^1.0.2" - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - get-intrinsic "^1.1.1" - get-symbol-description "^1.0.0" - has "^1.0.3" - has-symbols "^1.0.2" - internal-slot "^1.0.3" - is-callable "^1.2.4" - is-negative-zero "^2.0.1" - is-regex "^1.1.4" - is-shared-array-buffer "^1.0.1" - is-string "^1.0.7" - is-weakref "^1.0.1" - object-inspect "^1.11.0" - object-keys "^1.1.1" - object.assign "^4.1.2" - string.prototype.trimend "^1.0.4" - string.prototype.trimstart "^1.0.4" - unbox-primitive "^1.0.1" - -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" @@ -2953,41 +2990,12 @@ eslint-config-prettier@7.0.0: resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-7.0.0.tgz#c1ae4106f74e6c0357f44adb076771d032ac0e97" integrity sha512-8Y8lGLVPPZdaNA7JXqnvETVC7IiVRgAP6afQu9gOQRn90YY3otMNh+x7Vr2vMePQntF+5erdSUBqSzCmU/AxaQ== -eslint-plugin-flowtype-errors@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype-errors/-/eslint-plugin-flowtype-errors-4.5.0.tgz#19e6e1208ef1866afd5e03ebdd8671febe85c26f" - integrity sha512-rMc7+YS1QtM8TclPOxVRdQdDmAgiRzcS84jUB5eFeHNG15Y5ledb2uWUpvZ2p4bVAfnsQhD/O8BiVZUiMkmvXQ== +eslint-plugin-jest@^28.6.0: + version "28.6.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-28.6.0.tgz#8410588d60bcafa68a91b6ec272e4a415502302a" + integrity sha512-YG28E1/MIKwnz+e2H7VwYPzHUYU4aMa19w0yGcwXnnmJH6EfgHahTJ2un3IyraUxNfnz/KUhJAFXNNwWPo12tg== dependencies: - "@babel/runtime" "^7.16.0" - core-js "3.8.1" - find-up "^5.0.0" - slash "^3.0.0" - -eslint-plugin-flowtype@^8.0.3: - version "8.0.3" - resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-8.0.3.tgz#e1557e37118f24734aa3122e7536a038d34a4912" - integrity sha512-dX8l6qUL6O+fYPtpNRideCFSpmWOUVx5QcaGLVqe/vlDiBSe4vYljDWDETwnyFzpl7By/WVIu6rcrniCgH9BqQ== - dependencies: - lodash "^4.17.21" - string-natural-compare "^3.0.1" - -eslint-plugin-jsx-a11y@^6.5.1: - version "6.5.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.5.1.tgz#cdbf2df901040ca140b6ec14715c988889c2a6d8" - integrity sha512-sVCFKX9fllURnXT2JwLN5Qgo24Ug5NF6dxhkmxsMEUZhXRcGg+X3e1JbJ84YePQKBl5E0ZjAH5Q4rkdcGY99+g== - dependencies: - "@babel/runtime" "^7.16.3" - aria-query "^4.2.2" - array-includes "^3.1.4" - ast-types-flow "^0.0.7" - axe-core "^4.3.5" - axobject-query "^2.2.0" - damerau-levenshtein "^1.0.7" - emoji-regex "^9.2.2" - has "^1.0.3" - jsx-ast-utils "^3.2.1" - language-tags "^1.0.5" - minimatch "^3.0.4" + "@typescript-eslint/utils" "^6.0.0 || ^7.0.0" eslint-plugin-prettier@^4.0.0: version "4.0.0" @@ -2996,31 +3004,6 @@ eslint-plugin-prettier@^4.0.0: dependencies: prettier-linter-helpers "^1.0.0" -eslint-plugin-react-hooks@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.3.0.tgz#318dbf312e06fab1c835a4abef00121751ac1172" - integrity sha512-XslZy0LnMn+84NEG9jSGR6eGqaZB3133L8xewQo3fQagbQuGt7a63gf+P1NGKZavEYEC3UXaWEAA/AqDkuN6xA== - -eslint-plugin-react@^7.29.2: - version "7.29.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.29.2.tgz#2d4da69d30d0a736efd30890dc6826f3e91f3f7c" - integrity sha512-ypEBTKOy5liFQXZWMchJ3LN0JX1uPI6n7MN7OPHKacqXAxq5gYC30TdO7wqGYQyxD1OrzpobdHC3hDmlRWDg9w== - dependencies: - array-includes "^3.1.4" - array.prototype.flatmap "^1.2.5" - doctrine "^2.1.0" - estraverse "^5.3.0" - jsx-ast-utils "^2.4.1 || ^3.0.0" - minimatch "^3.1.2" - object.entries "^1.1.5" - object.fromentries "^2.0.5" - object.hasown "^1.1.0" - object.values "^1.1.5" - prop-types "^15.8.1" - resolve "^2.0.0-next.3" - semver "^6.3.0" - string.prototype.matchall "^4.0.6" - eslint-scope@^5.0.0, eslint-scope@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" @@ -3029,10 +3012,10 @@ eslint-scope@^5.0.0, eslint-scope@^5.1.1: esrecurse "^4.3.0" estraverse "^4.1.1" -eslint-scope@^7.1.0: - version "7.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.1.tgz#fff34894c2f65e5226d3041ac480b4513a163642" - integrity sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw== +eslint-scope@^7.2.2: + version "7.2.2" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" + integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== dependencies: esrecurse "^4.3.0" estraverse "^5.2.0" @@ -3044,13 +3027,6 @@ eslint-utils@^2.0.0, eslint-utils@^2.1.0: dependencies: eslint-visitor-keys "^1.1.0" -eslint-utils@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" - integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== - dependencies: - eslint-visitor-keys "^2.0.0" - eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" @@ -3061,51 +3037,15 @@ eslint-visitor-keys@^2.0.0, eslint-visitor-keys@^2.1.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== -eslint-visitor-keys@^3.2.0, eslint-visitor-keys@^3.3.0: +eslint-visitor-keys@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== -eslint@8.7.0: - version "8.7.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.7.0.tgz#22e036842ee5b7cf87b03fe237731675b4d3633c" - integrity sha512-ifHYzkBGrzS2iDU7KjhCAVMGCvF6M3Xfs8X8b37cgrUlDt6bWRTpRh6T/gtSXv1HJ/BUGgmjvNvOEGu85Iif7w== - dependencies: - "@eslint/eslintrc" "^1.0.5" - "@humanwhocodes/config-array" "^0.9.2" - ajv "^6.10.0" - chalk "^4.0.0" - cross-spawn "^7.0.2" - debug "^4.3.2" - doctrine "^3.0.0" - escape-string-regexp "^4.0.0" - eslint-scope "^7.1.0" - eslint-utils "^3.0.0" - eslint-visitor-keys "^3.2.0" - espree "^9.3.0" - esquery "^1.4.0" - esutils "^2.0.2" - fast-deep-equal "^3.1.3" - file-entry-cache "^6.0.1" - functional-red-black-tree "^1.0.1" - glob-parent "^6.0.1" - globals "^13.6.0" - ignore "^5.2.0" - import-fresh "^3.0.0" - imurmurhash "^0.1.4" - is-glob "^4.0.0" - js-yaml "^4.1.0" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.4.1" - lodash.merge "^4.6.2" - minimatch "^3.0.4" - natural-compare "^1.4.0" - optionator "^0.9.1" - regexpp "^3.2.0" - strip-ansi "^6.0.1" - strip-json-comments "^3.1.0" - text-table "^0.2.0" - v8-compile-cache "^2.0.3" +eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: + version "3.4.3" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" + integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== eslint@^7.9.0: version "7.32.0" @@ -3153,6 +3093,50 @@ eslint@^7.9.0: text-table "^0.2.0" v8-compile-cache "^2.0.3" +eslint@^8.57.0: + version "8.57.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.57.0.tgz#c786a6fd0e0b68941aaf624596fb987089195668" + integrity sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@eslint-community/regexpp" "^4.6.1" + "@eslint/eslintrc" "^2.1.4" + "@eslint/js" "8.57.0" + "@humanwhocodes/config-array" "^0.11.14" + "@humanwhocodes/module-importer" "^1.0.1" + "@nodelib/fs.walk" "^1.2.8" + "@ungap/structured-clone" "^1.2.0" + ajv "^6.12.4" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.3.2" + doctrine "^3.0.0" + escape-string-regexp "^4.0.0" + eslint-scope "^7.2.2" + eslint-visitor-keys "^3.4.3" + espree "^9.6.1" + esquery "^1.4.2" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + find-up "^5.0.0" + glob-parent "^6.0.2" + globals "^13.19.0" + graphemer "^1.4.0" + ignore "^5.2.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + is-path-inside "^3.0.3" + js-yaml "^4.1.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.1.2" + natural-compare "^1.4.0" + optionator "^0.9.3" + strip-ansi "^6.0.1" + text-table "^0.2.0" + espree@^6.2.1: version "6.2.1" resolved "https://registry.yarnpkg.com/espree/-/espree-6.2.1.tgz#77fc72e1fd744a2052c20f38a5b575832e82734a" @@ -3171,14 +3155,14 @@ espree@^7.3.0, espree@^7.3.1: acorn-jsx "^5.3.1" eslint-visitor-keys "^1.3.0" -espree@^9.3.0, espree@^9.3.1: - version "9.3.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.3.1.tgz#8793b4bc27ea4c778c19908e0719e7b8f4115bcd" - integrity sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ== +espree@^9.6.0, espree@^9.6.1: + version "9.6.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" + integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== dependencies: - acorn "^8.7.0" - acorn-jsx "^5.3.1" - eslint-visitor-keys "^3.3.0" + acorn "^8.9.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^3.4.1" esprima@^4.0.0, esprima@^4.0.1: version "4.0.1" @@ -3192,6 +3176,13 @@ esquery@^1.0.1, esquery@^1.4.0: dependencies: estraverse "^5.1.0" +esquery@^1.4.2: + version "1.6.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.6.0.tgz#91419234f804d852a82dceec3e16cdc22cf9dae7" + integrity sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg== + dependencies: + estraverse "^5.1.0" + esrecurse@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" @@ -3204,7 +3195,7 @@ estraverse@^4.1.1: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== -estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0: +estraverse@^5.1.0, estraverse@^5.2.0: version "5.3.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== @@ -3418,11 +3409,6 @@ flatted@^3.1.0: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3" integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg== -flow-bin@^0.172.0: - version "0.172.0" - resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.172.0.tgz#b399d108c5a9f0272a8137fcc884dc7284b7c175" - integrity sha512-v9KolEk3qd+wFc2ABPaSr5/7VWbHOjdAzRaWwynEtaeMcKN0awlx0Q7b71g/XgVf/fWMR+K8q+3s/TCH+Gky/Q== - for-in@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" @@ -3497,7 +3483,7 @@ get-caller-file@^2.0.1, get-caller-file@^2.0.5: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: +get-intrinsic@^1.0.2: version "1.1.1" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" integrity sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q== @@ -3516,14 +3502,6 @@ get-stream@^6.0.0: resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== -get-symbol-description@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" - integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.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" @@ -3546,7 +3524,7 @@ glob-parent@^5.1.2, glob-parent@~5.1.2: dependencies: is-glob "^4.0.1" -glob-parent@^6.0.1: +glob-parent@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== @@ -3570,6 +3548,13 @@ globals@^11.1.0: resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== +globals@^13.19.0: + version "13.24.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.24.0.tgz#8432a19d78ce0c1e833949c36adb345400bb1171" + integrity sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ== + dependencies: + type-fest "^0.20.2" + globals@^13.6.0, globals@^13.9.0: version "13.12.1" resolved "https://registry.yarnpkg.com/globals/-/globals-13.12.1.tgz#ec206be932e6c77236677127577aa8e50bf1c5cb" @@ -3582,7 +3567,7 @@ globals@^9.18.0: resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ== -globby@^11.0.0: +globby@^11.0.0, globby@^11.1.0: version "11.1.0" resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== @@ -3604,15 +3589,20 @@ grapheme-splitter@^1.0.4: resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== +graphemer@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" + integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== + graphql-tag@2.10.1: version "2.10.1" resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.10.1.tgz#10aa41f1cd8fae5373eaf11f1f67260a3cad5e02" integrity sha512-jApXqWBzNXQ8jYa/HLkZJaVw9jgwNqZkywa2zfFn16Iv1Zb7ELNHkJaXHR7Quvd5SIGsy6Ny7SUKATgnu05uEg== -graphql@^16.3.0: - version "16.8.0" - resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.8.0.tgz#374478b7f27b2dc6153c8f42c1b80157f79d79d4" - integrity sha512-0oKGaR+y3qcS5mCu1vb7KG+a89vjn06C7Ihq/dDl3jA+A8B3TKomvi3CiEcVLJQGalbu8F52LxkOym7U5sSfbg== +graphql@^16.9.0: + version "16.9.0" + resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.9.0.tgz#1c310e63f16a49ce1fbb230bd0a000e99f6f115f" + integrity sha512-GGTKBX4SD7Wdb8mqeDLni2oaRGYQWjWHGKPQ24ZMnUtKfcsVoiv4uX8+LJr1K6U5VW2Lu1BwJnj7uiori0YtRw== hard-rejection@^2.1.0: version "2.1.0" @@ -3626,11 +3616,6 @@ has-ansi@^2.0.0: dependencies: ansi-regex "^2.0.0" -has-bigints@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" - integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== - has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -3641,18 +3626,11 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has-symbols@^1.0.1, has-symbols@^1.0.2: +has-symbols@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== -has-tostringtag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" - integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== - dependencies: - has-symbols "^1.0.2" - has@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" @@ -3721,6 +3699,11 @@ ignore@^5.2.0: resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== +ignore@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.1.tgz#5073e554cd42c5b33b394375f538b8593e34d4ef" + integrity sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw== + import-fresh@^3.0.0, import-fresh@^3.2.1: version "3.3.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" @@ -3760,15 +3743,6 @@ inherits@2: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== -internal-slot@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" - integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== - dependencies: - get-intrinsic "^1.1.0" - has "^1.0.3" - side-channel "^1.0.4" - invariant@^2.2.2: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" @@ -3781,13 +3755,6 @@ is-arrayish@^0.2.1: resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= -is-bigint@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" - integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== - dependencies: - has-bigints "^1.0.1" - 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" @@ -3795,24 +3762,11 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" -is-boolean-object@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" - integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^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-callable@^1.1.4, is-callable@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" - integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== - is-ci@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-3.0.1.tgz#db6ecbed1bd659c43dac0f45661e7674103d1867" @@ -3820,20 +3774,13 @@ is-ci@^3.0.1: dependencies: ci-info "^3.2.0" -is-core-module@^2.2.0, is-core-module@^2.8.1: +is-core-module@^2.8.1: version "2.8.1" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211" integrity sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA== dependencies: has "^1.0.3" -is-date-object@^1.0.1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" - integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== - dependencies: - has-tostringtag "^1.0.0" - is-dotfile@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" @@ -3890,18 +3837,6 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" -is-negative-zero@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" - integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== - -is-number-object@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.6.tgz#6a7aaf838c7f0686a50b4553f7e54a96494e89f0" - integrity sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g== - dependencies: - has-tostringtag "^1.0.0" - is-number@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" @@ -3919,6 +3854,11 @@ is-number@^7.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== +is-path-inside@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + is-plain-obj@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" @@ -3939,31 +3879,11 @@ is-primitive@^2.0.0: resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" integrity sha1-IHurkWOEmcB7Kt8kCkGochADRXU= -is-regex@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" - integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-shared-array-buffer@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6" - integrity sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA== - is-stream@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== -is-string@^1.0.5, is-string@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" - integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== - dependencies: - has-tostringtag "^1.0.0" - is-subdir@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/is-subdir/-/is-subdir-1.2.0.tgz#b791cd28fab5202e91a08280d51d9d7254fd20d4" @@ -3971,13 +3891,6 @@ is-subdir@^1.1.1: dependencies: better-path-resolve "1.0.0" -is-symbol@^1.0.2, is-symbol@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" - integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== - dependencies: - has-symbols "^1.0.2" - is-typedarray@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" @@ -3988,13 +3901,6 @@ is-utf8@^0.2.0: resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= -is-weakref@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" - integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== - dependencies: - call-bind "^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" @@ -4646,14 +4552,6 @@ jsonschema@^1.4.1: resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.4.1.tgz#cc4c3f0077fb4542982973d8a083b6b34f482dab" integrity sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ== -"jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.2.1.tgz#720b97bfe7d901b927d87c3773637ae8ea48781b" - integrity sha512-uP5vu8xfy2F9A6LGC22KO7e2/vGTS1MhP+18f++ZNlf0Ohaxbc9nIEwHAsejlJKyzfZzU5UIhe5ItYkitcZnZA== - dependencies: - array-includes "^3.1.3" - object.assign "^4.1.2" - kind-of@^3.0.2: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" @@ -4671,18 +4569,6 @@ kleur@^3.0.3: resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== -language-subtag-registry@~0.3.2: - version "0.3.21" - resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz#04ac218bea46f04cb039084602c6da9e788dd45a" - integrity sha512-L0IqwlIXjilBVVYKFT37X9Ih11Um5NEl9cbJIuU/SwP/zEEAbBPOnEeeuxVMf45ydWQRDQN3Nqc96OgbH1K+Pg== - -language-tags@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/language-tags/-/language-tags-1.0.5.tgz#d321dbc4da30ba8bf3024e040fa5c14661f9193a" - integrity sha1-0yHbxNowuovzAk4ED6XBRmH5GTo= - dependencies: - language-subtag-registry "~0.3.2" - leven@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" @@ -4772,7 +4658,7 @@ 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@^4.17.15, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.7.0: +lodash@^4.17.15, lodash@^4.17.4, lodash@^4.7.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -4790,7 +4676,7 @@ loglevel@^1.4.1: resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.8.0.tgz#e7ec73a57e1e7b419cb6c6ac06bf050b67356114" integrity sha512-G6A/nJLRgWOuuwdNuA6koovfEV1YpqqAG4pRUlFaz3jj2QNZ8M4vBqnVA+HBTmU/AMNUtlOsMmSpF6NyOjztbA== -loose-envify@^1.0.0, loose-envify@^1.4.0: +loose-envify@^1.0.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== @@ -4925,13 +4811,20 @@ min-indent@^1.0.0: resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== -minimatch@^3.0.4, minimatch@^3.1.2: +minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== dependencies: brace-expansion "^1.1.7" +minimatch@^9.0.4: + version "9.0.5" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" + integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== + dependencies: + brace-expansion "^2.0.1" + minimist-options@^4.0.2: version "4.1.0" resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-4.1.0.tgz#c0655713c53a8a2ebd77ffa247d342c40f010619" @@ -5010,22 +4903,17 @@ 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.1.0, object-assign@^4.1.1: +object-assign@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= -object-inspect@^1.11.0, object-inspect@^1.9.0: - version "1.12.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0" - integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g== - object-keys@^1.0.12, object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== -object.assign@^4.1.0, object.assign@^4.1.2: +object.assign@^4.1.0: version "4.1.2" resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== @@ -5035,32 +4923,6 @@ object.assign@^4.1.0, object.assign@^4.1.2: has-symbols "^1.0.1" object-keys "^1.1.1" -object.entries@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.5.tgz#e1acdd17c4de2cd96d5a08487cfb9db84d881861" - integrity sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - -object.fromentries@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.5.tgz#7b37b205109c21e741e605727fe8b0ad5fa08251" - integrity sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - -object.hasown@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/object.hasown/-/object.hasown-1.1.0.tgz#7232ed266f34d197d15cac5880232f7a4790afe5" - integrity sha512-MhjYRfj3GBlhSkDHo6QmvgjRLXQ2zndabdf3nX0yTyZK9rPfxb6uRpAac8HXNLy1GpqWtZ81Qh4v3uOls2sRAg== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.19.1" - object.omit@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" @@ -5069,15 +4931,6 @@ object.omit@^2.0.0: for-own "^0.1.4" is-extendable "^0.1.1" -object.values@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.5.tgz#959f63e3ce9ef108720333082131e4a459b716ac" - integrity sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - once@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" @@ -5116,6 +4969,18 @@ optionator@^0.9.1: type-check "^0.4.0" word-wrap "^1.2.3" +optionator@^0.9.3: + version "0.9.4" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.4.tgz#7ea1c1a5d91d764fb282139c88fe11e182a3a734" + integrity sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g== + dependencies: + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + word-wrap "^1.2.5" + os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" @@ -5256,7 +5121,7 @@ path-key@^3.0.0, path-key@^3.1.0: resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== -path-parse@^1.0.6, path-parse@^1.0.7: +path-parse@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== @@ -5418,15 +5283,6 @@ prompts@^2.0.1: kleur "^3.0.3" sisteransi "^1.0.5" -prop-types@^15.8.1: - version "15.8.1" - resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" - integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== - dependencies: - loose-envify "^1.4.0" - object-assign "^4.1.1" - react-is "^16.13.1" - pseudomap@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" @@ -5461,11 +5317,6 @@ randomatic@^3.0.0: kind-of "^6.0.0" math-random "^1.0.1" -react-is@^16.13.1: - version "16.13.1" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" - integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== - react-is@^17.0.1: version "17.0.2" resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" @@ -5573,15 +5424,7 @@ regex-cache@^0.4.2: dependencies: is-equal-shallow "^0.1.3" -regexp.prototype.flags@^1.3.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.1.tgz#b3f4c0059af9e47eca9f3f660e51d81307e72307" - integrity sha512-pMR7hBVUUGI7PMA37m2ofIdQCsomVnas+Jn5UPGAHQ+/LlwKm/aTLJHdasmHRzlfeZwHiAOaRSo2rbBDm3nNUQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -regexpp@^3.1.0, regexpp@^3.2.0: +regexpp@^3.1.0: version "3.2.0" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== @@ -5688,14 +5531,6 @@ resolve@^1.10.0, resolve@^1.14.2, resolve@^1.20.0: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -resolve@^2.0.0-next.3: - version "2.0.0-next.3" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.3.tgz#d41016293d4a8586a39ca5d9b5f15cbea1f55e46" - integrity sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q== - dependencies: - is-core-module "^2.2.0" - path-parse "^1.0.6" - reusify@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" @@ -5759,6 +5594,11 @@ semver@^7.2.1, semver@^7.3.2: dependencies: lru-cache "^6.0.0" +semver@^7.6.0: + version "7.6.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" + integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== + set-blocking@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" @@ -5788,15 +5628,6 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== - dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" - signal-exit@^3.0.2, signal-exit@^3.0.3: version "3.0.7" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" @@ -5921,11 +5752,6 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" -string-natural-compare@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/string-natural-compare/-/string-natural-compare-3.0.1.tgz#7a42d58474454963759e8e8b7ae63d71c1e7fdf4" - integrity sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw== - string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" @@ -5935,36 +5761,6 @@ string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string.prototype.matchall@^4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.6.tgz#5abb5dabc94c7b0ea2380f65ba610b3a544b15fa" - integrity sha512-6WgDX8HmQqvEd7J+G6VtAahhsQIssiZ8zl7zKh1VDMFyL3hRTJP4FTNA3RbIp2TOQ9AYNDcc7e3fH0Qbup+DBg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.1" - get-intrinsic "^1.1.1" - has-symbols "^1.0.2" - internal-slot "^1.0.3" - regexp.prototype.flags "^1.3.1" - side-channel "^1.0.4" - -string.prototype.trimend@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" - integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -string.prototype.trimstart@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" - integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - strip-ansi@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" @@ -6166,6 +5962,11 @@ trim-right@^1.0.1: resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= +ts-api-utils@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.3.0.tgz#4b490e27129f1e8e686b45cc4ab63714dc60eea1" + integrity sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ== + ts-invariant@^0.4.0: version "0.4.4" resolved "https://registry.yarnpkg.com/ts-invariant/-/ts-invariant-0.4.4.tgz#97a523518688f93aafad01b0e80eb803eb2abd86" @@ -6258,16 +6059,6 @@ typescript@^5.1.6: resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== -unbox-primitive@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" - integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw== - dependencies: - function-bind "^1.1.1" - has-bigints "^1.0.1" - has-symbols "^1.0.2" - which-boxed-primitive "^1.0.2" - unicode-canonical-property-names-ecmascript@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" @@ -6396,17 +6187,6 @@ whatwg-url@^8.0.0, whatwg-url@^8.5.0: tr46 "^2.1.0" webidl-conversions "^6.1.0" -which-boxed-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" - integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== - dependencies: - is-bigint "^1.0.1" - is-boolean-object "^1.1.0" - is-number-object "^1.0.4" - is-string "^1.0.5" - is-symbol "^1.0.3" - which-module@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" @@ -6439,6 +6219,11 @@ word-wrap@^1.2.3, word-wrap@~1.2.3: resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== +word-wrap@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" + integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== + wrap-ansi@^6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53"