{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "ConfigFile",
  "description": "Relay's configuration file. Supports a single project config for simple use\ncases and a multi-project config for cases where multiple projects live in\nthe same repository.\n\nIn general, start with the SingleProjectConfigFile.",
  "anyOf": [
    {
      "description": "Base case configuration (mostly of OSS) where the project\nhave single schema, and single source directory",
      "$ref": "#/$defs/SingleProjectConfigFile"
    },
    {
      "description": "Relay can support multiple projects with multiple schemas\nand different options (output, typegen, etc...).\nThis MultiProjectConfigFile is responsible for configuring\nthese type of projects (complex)",
      "$ref": "#/$defs/MultiProjectConfigFile"
    }
  ],
  "$defs": {
    "ArgumentName": {
      "$ref": "#/$defs/StringKey"
    },
    "ConfigFileProject": {
      "type": "object",
      "properties": {
        "base": {
          "description": "If a base project is set, the documents of that project can be\nreferenced, but won't produce output artifacts.\nExtensions from the base project will be added as well and the schema\nof the base project should be a subset of the schema of this project.",
          "anyOf": [
            {
              "$ref": "#/$defs/ProjectName"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "codegenCommand": {
          "description": "Name of the command that runs the relay compiler. This will be added at\nthe top of generated code to let readers know how to regenerate the file.",
          "type": [
            "string",
            "null"
          ],
          "default": null
        },
        "customErrorType": {
          "description": "A map from GraphQL error name to import path, example:\n{\"name:: \"MyErrorName\", \"path\": \"../src/MyError\"}",
          "anyOf": [
            {
              "$ref": "#/$defs/CustomTypeImport"
            },
            {
              "type": "null"
            }
          ]
        },
        "customScalarTypes": {
          "description": "A map from GraphQL scalar types to a custom JS type, example:\n{ \"Url\": \"String\" }\n{ \"Url\": {\"name:: \"MyURL\", \"path\": \"../src/MyUrlTypes\"} }",
          "type": "object",
          "additionalProperties": {
            "$ref": "#/$defs/CustomType"
          },
          "default": {}
        },
        "diagnosticReportConfig": {
          "description": "Threshold for diagnostics to be critical to the compiler's execution.\nAll diagnostic with severities at and below this level will cause the\ncompiler to fatally exit.",
          "$ref": "#/$defs/DiagnosticReportConfig",
          "default": {
            "criticalLevel": "error"
          }
        },
        "eagerEsModules": {
          "description": "This option enables opting out of emitting es modules artifacts. When\nset to false, Relay will emit CommonJS modules.",
          "type": "boolean",
          "default": true
        },
        "enumModuleSuffix": {
          "title": "For Flow type generation",
          "description": "When set, enum values are imported from a module with this suffix.\nFor example, an enum Foo and this property set to \".test\" would be\nimported from \"Foo.test\".\nNote: an empty string is allowed and different from not setting the\nvalue, in the example above it would just import from \"Foo\".",
          "type": [
            "string",
            "null"
          ]
        },
        "excludesExtensions": {
          "description": "Some projects may need to exclude files with certain extensions.",
          "type": [
            "array",
            "null"
          ],
          "items": {
            "type": "string"
          }
        },
        "extra": {
          "description": "A placeholder for allowing extra information in the config file",
          "default": null
        },
        "extraArtifactsOutput": {
          "description": "Some projects may need to generate extra artifacts. For those, we may\nneed to provide an additional directory to put them.\nBy default the will use `output` *if available",
          "type": [
            "string",
            "null"
          ]
        },
        "featureFlags": {
          "description": "Enable and disable experimental or legacy behaviors.\nWARNING! These are not stable and may change at any time.",
          "anyOf": [
            {
              "$ref": "#/$defs/FeatureFlags"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "jsModuleFormat": {
          "description": "Import/export style to use in generated JavaScript modules.",
          "$ref": "#/$defs/JsModuleFormat",
          "default": "commonjs"
        },
        "language": {
          "description": "The desired output language, \"flow\" or \"typescript\".",
          "$ref": "#/$defs/TypegenLanguage"
        },
        "moduleImportConfig": {
          "description": "Configuration for the @module GraphQL directive.",
          "$ref": "#/$defs/ModuleImportConfig",
          "default": {
            "dynamicModuleProvider": null,
            "operationModuleProvider": null,
            "surface": null
          }
        },
        "noFutureProofEnums": {
          "description": "This option controls whether or not a catch-all entry is added to enum type definitions\nfor values that may be added in the future. Enabling this means you will have to update\nyour application whenever the GraphQL server schema adds new enum values to prevent it\nfrom breaking.",
          "type": "boolean",
          "default": false
        },
        "optionalInputFields": {
          "title": "For Flow type generation",
          "description": "When set, generated input types will have the listed fields optional\neven if the schema defines them as required.",
          "type": "array",
          "default": [],
          "items": {
            "$ref": "#/$defs/StringKey"
          }
        },
        "output": {
          "description": "A project without an output directory will put the generated files in\na __generated__ directory next to the input file.\nAll files in these directories should be generated by the Relay\ncompiler, so that the compiler can cleanup extra files.",
          "type": [
            "string",
            "null"
          ],
          "default": null
        },
        "persist": {
          "description": "If this option is set, the compiler will persist queries using this\nconfig.",
          "anyOf": [
            {
              "$ref": "#/$defs/PersistConfig"
            },
            {
              "type": "null"
            }
          ]
        },
        "relativizeJsModulePaths": {
          "description": "Whether to treat all JS module names as relative to './' (true) or not.\ndefault: true",
          "type": "boolean",
          "default": true
        },
        "requireCustomScalarTypes": {
          "description": "Require all GraphQL scalar types mapping to be defined, will throw\nif a GraphQL scalar type doesn't have a JS type",
          "type": "boolean",
          "default": false
        },
        "resolverContextType": {
          "description": "Indicates the type to import and use as the context for Relay Resolvers.",
          "anyOf": [
            {
              "$ref": "#/$defs/ResolverContextTypeInput"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "resolversSchemaModule": {
          "anyOf": [
            {
              "$ref": "#/$defs/ResolversSchemaModuleConfig"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "rollout": {
          "description": "A generic rollout state for larger codegen changes. The default is to\npass, otherwise it should be a number between 0 and 100 as a percentage.",
          "$ref": "#/$defs/Rollout",
          "default": null
        },
        "schema": {
          "description": "Path to the schema.graphql or a directory containing a schema broken up\nin multiple *.graphql files.\nExactly 1 of these options needs to be defined.",
          "type": [
            "string",
            "null"
          ]
        },
        "schemaConfig": {
          "description": "Extra configuration for the GraphQL schema itself.",
          "$ref": "#/$defs/SchemaConfig",
          "default": {
            "connectionInterface": {
              "cursor": "cursor",
              "edges": "edges",
              "endCursor": "endCursor",
              "hasNextPage": "hasNextPage",
              "hasPreviousPage": "hasPreviousPage",
              "node": "node",
              "pageInfo": "pageInfo",
              "startCursor": "startCursor"
            },
            "deferStreamInterface": {
              "deferName": "defer",
              "ifArg": "if",
              "initialCountArg": "initialCount",
              "labelArg": "label",
              "streamName": "stream",
              "useCustomizedBatchArg": "useCustomizedBatch"
            },
            "enableTokenField": false,
            "nodeInterfaceIdField": "id",
            "nodeInterfaceIdVariableName": "id",
            "nonNodeIdFields": null,
            "unselectableDirectiveName": "unselectable"
          }
        },
        "schemaDir": {
          "type": [
            "string",
            "null"
          ]
        },
        "schemaExtensions": {
          "description": "Directory containing *.graphql files with schema extensions.",
          "type": "array",
          "default": [],
          "items": {
            "type": "string"
          }
        },
        "schemaName": {
          "description": "Schema name, if differs from project name.\nIf schema name is unset, the project name will be used as schema name.",
          "anyOf": [
            {
              "$ref": "#/$defs/StringKey"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "shardOutput": {
          "description": "If `output` is provided and `shard_output` is `true`, shard the files\nby putting them under `{output_dir}/{source_relative_path}`",
          "type": "boolean",
          "default": false
        },
        "shardStripRegex": {
          "description": "Regex to match and strip parts of the `source_relative_path`",
          "type": [
            "string",
            "null"
          ],
          "default": null
        },
        "testPathRegex": {
          "description": "Optional regex to restrict @relay_test_operation to directories matching\nthis regex. Defaults to no limitations.",
          "type": [
            "string",
            "null"
          ],
          "default": null
        },
        "typescriptExcludeUndefinedFromNullableUnion": {
          "description": "Keep the previous compiler behavior by outputting an union\nof the raw type and null, and not the **correct** behavior\nof an union with the raw type, null and undefined.",
          "type": "boolean",
          "default": false
        },
        "useImportTypeSyntax": {
          "title": "For Typescript type generation",
          "description": "Whether to use the `import type` syntax introduced in Typescript\nversion 3.8. This will prevent warnings from `importsNotUsedAsValues`.",
          "type": "boolean",
          "default": false
        },
        "variableNamesComment": {
          "description": "Generates a `// @relayVariables name1 name2` header in generated operation files",
          "type": "boolean",
          "default": false
        }
      },
      "additionalProperties": false,
      "required": [
        "language"
      ]
    },
    "ConnectionInterface": {
      "description": "Configuration where Relay should expect some fields in the schema.",
      "type": "object",
      "properties": {
        "cursor": {
          "$ref": "#/$defs/StringKey"
        },
        "edges": {
          "$ref": "#/$defs/StringKey"
        },
        "endCursor": {
          "$ref": "#/$defs/StringKey"
        },
        "hasNextPage": {
          "$ref": "#/$defs/StringKey"
        },
        "hasPreviousPage": {
          "$ref": "#/$defs/StringKey"
        },
        "node": {
          "$ref": "#/$defs/StringKey"
        },
        "pageInfo": {
          "$ref": "#/$defs/StringKey"
        },
        "startCursor": {
          "$ref": "#/$defs/StringKey"
        }
      },
      "additionalProperties": false,
      "required": [
        "cursor",
        "edges",
        "endCursor",
        "hasNextPage",
        "hasPreviousPage",
        "node",
        "pageInfo",
        "startCursor"
      ]
    },
    "CustomType": {
      "description": "Defines a custom GraphQL\ndescrbing a custom scalar.",
      "anyOf": [
        {
          "description": "A string representing the name of a custom type. e.g. \"string\" or \"number\"",
          "$ref": "#/$defs/StringKey"
        },
        {
          "description": "A module which defines the custom type. e.g. { \"name\": \"MyCustomType\", \"path\": \"./Types.ts\" }",
          "$ref": "#/$defs/CustomTypeImport"
        }
      ]
    },
    "CustomTypeImport": {
      "description": "Defines a module path and export name of the Flow or TypeScript type\ndescrbing a GraphQL custom scalar.",
      "type": "object",
      "properties": {
        "name": {
          "description": "The name under which the type is exported from the module",
          "$ref": "#/$defs/StringKey"
        },
        "path": {
          "description": "The path to the module relative to the project root",
          "type": "string"
        }
      },
      "required": [
        "name",
        "path"
      ]
    },
    "DeferStreamInterface": {
      "description": "Configuration where Relay should expect some fields in the schema.",
      "type": "object",
      "properties": {
        "deferName": {
          "$ref": "#/$defs/DirectiveName"
        },
        "ifArg": {
          "$ref": "#/$defs/ArgumentName"
        },
        "initialCountArg": {
          "$ref": "#/$defs/ArgumentName"
        },
        "labelArg": {
          "$ref": "#/$defs/ArgumentName"
        },
        "streamName": {
          "$ref": "#/$defs/DirectiveName"
        },
        "useCustomizedBatchArg": {
          "$ref": "#/$defs/ArgumentName"
        }
      },
      "additionalProperties": false,
      "required": [
        "deferName",
        "streamName",
        "ifArg",
        "labelArg",
        "initialCountArg",
        "useCustomizedBatchArg"
      ]
    },
    "DeserializableProjectSet": {
      "anyOf": [
        {
          "$ref": "#/$defs/ProjectName"
        },
        {
          "type": "array",
          "items": {
            "$ref": "#/$defs/ProjectName"
          }
        }
      ]
    },
    "DiagnosticLevel": {
      "description": "Levels for reporting errors in the compiler.",
      "oneOf": [
        {
          "description": "Report only errors",
          "type": "string",
          "const": "error"
        },
        {
          "description": "Report diagnostics up to warnings",
          "type": "string",
          "const": "warning"
        },
        {
          "description": "Report diagnostics up to informational diagnostics",
          "type": "string",
          "const": "info"
        },
        {
          "description": "Report diagnostics up to hints",
          "type": "string",
          "const": "hint"
        }
      ]
    },
    "DiagnosticReportConfig": {
      "description": "Configuration for all diagnostic reporting in the compiler",
      "type": "object",
      "properties": {
        "criticalLevel": {
          "description": "Threshold for diagnostics to be critical to the compiler's execution.\nAll diagnostic with severities at and below this level will cause the\ncompiler to fatally exit.",
          "$ref": "#/$defs/DiagnosticLevel"
        }
      },
      "required": [
        "criticalLevel"
      ]
    },
    "DirectiveName": {
      "description": "Wrapper struct for clarity rather than having StringKey everywhere.",
      "$ref": "#/$defs/StringKey"
    },
    "FeatureFlag": {
      "oneOf": [
        {
          "description": "Fully disabled: developers may not use this feature",
          "type": "object",
          "properties": {
            "kind": {
              "type": "string",
              "const": "disabled"
            }
          },
          "required": [
            "kind"
          ]
        },
        {
          "description": "Fully enabled: developers may use this feature",
          "type": "object",
          "properties": {
            "kind": {
              "type": "string",
              "const": "enabled"
            }
          },
          "required": [
            "kind"
          ]
        },
        {
          "description": "Partially enabled: developers may only use this feature on the listed items (fragments, fields, types).",
          "type": "object",
          "properties": {
            "allowlist": {
              "type": "array",
              "items": {
                "$ref": "#/$defs/StringKey"
              },
              "uniqueItems": true
            },
            "kind": {
              "type": "string",
              "const": "limited"
            }
          },
          "required": [
            "kind",
            "allowlist"
          ]
        },
        {
          "description": "Partially enabled: used for gradual rollout of the feature",
          "type": "object",
          "properties": {
            "kind": {
              "type": "string",
              "const": "rollout"
            },
            "rollout": {
              "$ref": "#/$defs/Rollout"
            }
          },
          "required": [
            "kind",
            "rollout"
          ]
        },
        {
          "description": "Partially enabled: used for gradual rollout of the feature",
          "type": "object",
          "properties": {
            "kind": {
              "type": "string",
              "const": "rolloutrange"
            },
            "rollout": {
              "$ref": "#/$defs/RolloutRange"
            }
          },
          "required": [
            "kind",
            "rollout"
          ]
        }
      ]
    },
    "FeatureFlags": {
      "type": "object",
      "properties": {
        "actor_change_support": {
          "$ref": "#/$defs/FeatureFlag",
          "default": {
            "kind": "disabled"
          }
        },
        "allow_output_type_resolvers": {
          "description": "@outputType resolvers are a discontinued experimental feature. This flag\nallows users to allowlist old uses of this feature while they work to\nremove them. Weak types (types without an `id` field) returned by a Relay\nResolver should be limited to types defined using `@RelayResolver` with `@weak`.\n\nIf using the \"limited\" feature flag variant, users can allowlist a\nspecific list of field names.\n\nhttps://relay.dev/docs/next/guides/relay-resolvers/defining-types/#defining-a-weak-type",
          "$ref": "#/$defs/FeatureFlag",
          "default": {
            "kind": "disabled"
          }
        },
        "allow_required_in_mutation_response": {
          "description": "@required with an action of THROW is read-time feature that is not\ncompatible with our mutation APIs. We are in the process of removing\nany existing examples, but this flag is part of a process of removing\nany existing examples.",
          "$ref": "#/$defs/FeatureFlag",
          "default": {
            "kind": "disabled"
          }
        },
        "allow_resolver_non_nullable_return_type": {
          "description": "Allow non-nullable return types from resolvers.",
          "$ref": "#/$defs/FeatureFlag",
          "default": {
            "kind": "disabled"
          }
        },
        "allow_resolvers_in_mutation_response": {
          "description": "Relay Resolvers are a read-time feature that are not actually handled in\nour mutation APIs. We are in the process of removing any existing\nexamples, but this flag is part of a process of removing any existing\nexamples.",
          "$ref": "#/$defs/FeatureFlag",
          "default": {
            "kind": "disabled"
          }
        },
        "compact_query_text": {
          "description": "Print queries in compact form",
          "$ref": "#/$defs/FeatureFlag",
          "default": {
            "kind": "disabled"
          }
        },
        "disable_deduping_common_structures_in_artifacts": {
          "description": "Skip the optimization which extracts common JavaScript structures in\ngenerated artifacts into numbered variables and uses them by reference\nin each position in which they occur.\n\nThis optimization can make it hard to follow changes to generated\ncode, so being able to disable it can be helpful for debugging.\n\nTo disable deduping for just one fragment or operation's generated\nartifacts:\n\n```json\n\"disable_deduping_common_structures_in_artifacts\": {\n  { \"kind\": \"limited\", \"allowList\": [\"<operation_or_fragment_name>\"] }\n}\n```",
          "$ref": "#/$defs/FeatureFlag",
          "default": {
            "kind": "disabled"
          }
        },
        "disable_edge_type_name_validation_on_declerative_connection_directives": {
          "description": "Disable validation of the `edgeTypeName` argument on `@prependNode` and `@appendNode`.",
          "$ref": "#/$defs/FeatureFlag",
          "default": {
            "kind": "disabled"
          }
        },
        "disable_full_argument_type_validation": {
          "description": "Disable full GraphQL argument type validation. Historically, we only applied argument type\nvalidation to the query that was actually going to be persisted and sent\nto the server. This meant that we didn't typecheck arguments passed to\nRelay Resolvers or Client Schema Extensions.\n\nWe also permitted an escape hatch of `uncheckedArguments_DEPRECATED` for\ndefining fragment arguments which were not typechecked.\n\nWe no-longer support `uncheckedArguments_DEPRECATED`, and we typecheck\nboth client and server arguments. This flag allows you to opt out of\nthis new behavior to enable gradual adoption of the new validations.\n\nThis flag will be removed in a future version of Relay.",
          "$ref": "#/$defs/FeatureFlag",
          "default": {
            "kind": "disabled"
          }
        },
        "disable_resolver_reader_ast": {
          "description": "Mirror of `enable_resolver_normalization_ast`\nexcludes resolver metadata from reader ast",
          "type": "boolean",
          "default": false
        },
        "disable_schema_validation": {
          "description": "Disable validating the composite schema (server, client schema\nextensions, Relay Resolvers) after its built.",
          "type": "boolean",
          "default": false
        },
        "enable_3d_branch_arg_generation": {
          "type": "boolean",
          "default": false
        },
        "enable_exec_time_resolvers_directive": {
          "description": "Allow per-query opt in to normalization AST for Resolvers with exec_time_resolvers\ndirective. In contrast to enable_resolver_normalization_ast, if this is true, a\nnormalization AST can be generated for a query using the @exec_time_resolvers directive",
          "type": "boolean",
          "default": false
        },
        "enable_fragment_argument_transform": {
          "description": "Add support for parsing and transforming variable definitions on fragment\ndefinitions and arguments on fragment spreads.",
          "type": "boolean",
          "default": false
        },
        "enable_relay_resolver_mutations": {
          "description": "Allow relay resolvers to extend the Mutation type",
          "type": "boolean",
          "default": false
        },
        "enable_resolver_normalization_ast": {
          "description": "Fully build the normalization AST for Resolvers",
          "type": "boolean",
          "default": false
        },
        "enable_strict_custom_scalars": {
          "description": "Perform strict validations when custom scalar types are used",
          "type": "boolean",
          "default": false
        },
        "enforce_fragment_alias_where_ambiguous": {
          "description": "Enforce that you must add `@alias` to a fragment if it may not match,\ndue to type mismatch or `@skip`/`@include`",
          "$ref": "#/$defs/FeatureFlag",
          "default": {
            "kind": "enabled"
          }
        },
        "legacy_include_path_in_required_reader_nodes": {
          "description": "The `path` field in `@required` Reader AST nodes is no longer used. But\nremoving them in one diff is too large of a change to ship at once.\n\nThis flag will allow us to use the rollout FeatureFlag to remove them\nacross a number of diffs.",
          "$ref": "#/$defs/FeatureFlag",
          "default": {
            "kind": "disabled"
          }
        },
        "no_inline": {
          "description": "For now, this also disallows fragments with variable definitions\nThis also makes @module to opt in using @no_inline internally\nNOTE that the presence of a fragment in this list only controls whether a fragment is *allowed* to\nuse @no_inline: whether the fragment is inlined or not depends on whether it actually uses that\ndirective.",
          "$ref": "#/$defs/FeatureFlag",
          "default": {
            "kind": "disabled"
          }
        },
        "omit_resolver_type_assertions_for_confirmed_types": {
          "description": "Skip generating resolver type assertions for resolvers which have\nbeen derived from TS/Flow types.",
          "$ref": "#/$defs/FeatureFlag",
          "default": {
            "kind": "disabled"
          }
        },
        "prefer_fetchable_in_refetch_queries": {
          "description": "Feature flag to prefer `fetch_MyType()` generatior over `node()` query generator\nin @refetchable transform",
          "type": "boolean",
          "default": false
        },
        "relay_resolver_enable_interface_output_type": {
          "description": "Enable returning interfaces from Relay Resolvers without @outputType",
          "$ref": "#/$defs/FeatureFlag",
          "default": {
            "kind": "disabled"
          }
        },
        "skip_printing_nulls": {
          "$ref": "#/$defs/FeatureFlag",
          "default": {
            "kind": "disabled"
          }
        },
        "text_artifacts": {
          "description": "Enable generation of text artifacts used to generate full query strings\nlater.",
          "$ref": "#/$defs/FeatureFlag",
          "default": {
            "kind": "disabled"
          }
        },
        "use_reader_module_imports": {
          "description": "Generate the `moduleImports` field in the Reader AST.",
          "$ref": "#/$defs/FeatureFlag",
          "default": {
            "kind": "disabled"
          }
        }
      },
      "additionalProperties": false
    },
    "JsModuleFormat": {
      "description": "Formatting style for generated files.",
      "oneOf": [
        {
          "description": "Common JS style, e.g. `require('../path/MyModule')`",
          "type": "string",
          "const": "commonjs"
        },
        {
          "description": "Facebook style, e.g. `require('MyModule')`",
          "type": "string",
          "const": "haste"
        }
      ]
    },
    "LocalPersistAlgorithm": {
      "type": "string",
      "enum": [
        "MD5",
        "SHA1",
        "SHA256"
      ]
    },
    "LocalPersistConfig": {
      "description": "Configuration for local persistence of GraphQL documents.\n\nThis struct contains settings that control how GraphQL documents are persisted locally.",
      "type": "object",
      "properties": {
        "algorithm": {
          "description": "The algorithm to use for hashing the operation text.",
          "$ref": "#/$defs/LocalPersistAlgorithm",
          "default": "MD5"
        },
        "file": {
          "description": "The file path where the persisted documents will be written.",
          "type": "string"
        },
        "include_query_text": {
          "description": "Whether to include the query text in the persisted document.",
          "type": "boolean",
          "default": false
        }
      },
      "additionalProperties": false,
      "required": [
        "file"
      ]
    },
    "ModuleImportConfig": {
      "description": "Configuration for @module.",
      "type": "object",
      "properties": {
        "dynamicModuleProvider": {
          "description": "Defines the custom import statement to be generated on the\n`ModuleImport` node in ASTs, used for dynamically loading\ncomponents at runtime.",
          "anyOf": [
            {
              "$ref": "#/$defs/ModuleProvider"
            },
            {
              "type": "null"
            }
          ]
        },
        "operationModuleProvider": {
          "description": "Defines the custom import statement to be generated for the\n`operationModuleProvider` function on the `NormalizationModuleImport`\nnode in ASTs. Used in exec time client 3D.",
          "anyOf": [
            {
              "$ref": "#/$defs/ModuleProvider"
            },
            {
              "type": "null"
            }
          ]
        },
        "surface": {
          "description": "Defines the surface upon which @module is enabled.",
          "anyOf": [
            {
              "$ref": "#/$defs/Surface"
            },
            {
              "type": "null"
            }
          ]
        }
      },
      "additionalProperties": false
    },
    "ModuleProvider": {
      "oneOf": [
        {
          "description": "Generates a module provider using JSResource",
          "type": "object",
          "properties": {
            "mode": {
              "type": "string",
              "const": "JSResource"
            }
          },
          "required": [
            "mode"
          ]
        },
        {
          "description": "Generates a custom JS import, Use `<$module>` as the placeholder\nfor the actual module. e.g. `\"() => import('<$module>')\"`",
          "type": "object",
          "properties": {
            "mode": {
              "type": "string",
              "const": "Custom"
            },
            "statement": {
              "$ref": "#/$defs/StringKey"
            }
          },
          "required": [
            "mode",
            "statement"
          ]
        }
      ]
    },
    "MultiProjectConfigFile": {
      "description": "Schema of the compiler configuration JSON file.",
      "type": "object",
      "properties": {
        "$schema": {
          "description": "The user may hard-code the JSON Schema for their version of the config.",
          "type": [
            "string",
            "null"
          ]
        },
        "codegenCommand": {
          "type": [
            "string",
            "null"
          ],
          "default": null
        },
        "excludes": {
          "description": "Glob patterns that should not be part of the sources even if they are\nin the source set directories.",
          "type": "array",
          "default": [
            "**/node_modules/**",
            "**/__mocks__/**",
            "**/__generated__/**"
          ],
          "items": {
            "type": "string"
          }
        },
        "featureFlags": {
          "description": "Enable and disable experimental or legacy behaviors.\nWARNING! These are not stable and may change at any time.",
          "$ref": "#/$defs/FeatureFlags",
          "default": {
            "actor_change_support": {
              "kind": "disabled"
            },
            "allow_output_type_resolvers": {
              "kind": "disabled"
            },
            "allow_required_in_mutation_response": {
              "kind": "disabled"
            },
            "allow_resolver_non_nullable_return_type": {
              "kind": "disabled"
            },
            "allow_resolvers_in_mutation_response": {
              "kind": "disabled"
            },
            "compact_query_text": {
              "kind": "disabled"
            },
            "disable_deduping_common_structures_in_artifacts": {
              "kind": "disabled"
            },
            "disable_edge_type_name_validation_on_declerative_connection_directives": {
              "kind": "disabled"
            },
            "disable_full_argument_type_validation": {
              "kind": "disabled"
            },
            "disable_resolver_reader_ast": false,
            "disable_schema_validation": false,
            "enable_3d_branch_arg_generation": false,
            "enable_exec_time_resolvers_directive": false,
            "enable_fragment_argument_transform": false,
            "enable_relay_resolver_mutations": false,
            "enable_resolver_normalization_ast": false,
            "enable_strict_custom_scalars": false,
            "enforce_fragment_alias_where_ambiguous": {
              "kind": "disabled"
            },
            "legacy_include_path_in_required_reader_nodes": {
              "kind": "disabled"
            },
            "no_inline": {
              "kind": "disabled"
            },
            "omit_resolver_type_assertions_for_confirmed_types": {
              "kind": "disabled"
            },
            "prefer_fetchable_in_refetch_queries": false,
            "relay_resolver_enable_interface_output_type": {
              "kind": "disabled"
            },
            "skip_printing_nulls": {
              "kind": "disabled"
            },
            "text_artifacts": {
              "kind": "disabled"
            },
            "use_reader_module_imports": {
              "kind": "disabled"
            }
          }
        },
        "generatedSources": {
          "description": "Similar to sources but not affected by excludes.",
          "type": "object",
          "additionalProperties": {
            "$ref": "#/$defs/ProjectSet"
          },
          "default": {}
        },
        "header": {
          "type": "array",
          "default": [],
          "items": {
            "type": "string"
          }
        },
        "isDevVariableName": {
          "description": "Then name of the global __DEV__ variable to use in generated artifacts",
          "type": [
            "string",
            "null"
          ]
        },
        "name": {
          "description": "Optional name for this config, might be used for logging or custom extra\nartifact generator code.",
          "type": [
            "string",
            "null"
          ],
          "default": null
        },
        "noSourceControl": {
          "description": "Opt out of source control checks/integration.",
          "type": [
            "boolean",
            "null"
          ]
        },
        "projects": {
          "description": "Configuration of projects to compile.",
          "type": "object",
          "additionalProperties": {
            "$ref": "#/$defs/ConfigFileProject"
          }
        },
        "root": {
          "description": "Root directory relative to the config file. Defaults to the directory\nwhere the config is located.",
          "type": [
            "string",
            "null"
          ],
          "default": null
        },
        "savedStateConfig": {
          "description": "Watchman saved state config.",
          "anyOf": [
            {
              "$ref": "#/$defs/ScmAwareClockData"
            },
            {
              "type": "null"
            }
          ]
        },
        "sources": {
          "description": "A mapping from directory paths (relative to the root) to a source set.\nIf a path is a subdirectory of another path, the more specific path\nwins.",
          "type": "object",
          "additionalProperties": {
            "$ref": "#/$defs/DeserializableProjectSet"
          }
        }
      },
      "additionalProperties": false,
      "required": [
        "sources",
        "projects"
      ]
    },
    "NonNodeIdFieldsConfig": {
      "description": "Configuration of Relay's validation for `id` fields outside of the `Node` interface.",
      "type": "object",
      "properties": {
        "allowedIdTypes": {
          "description": "A map of parent type names to allowed type names for fields named `id`",
          "type": "object",
          "additionalProperties": {
            "$ref": "#/$defs/StringKey"
          },
          "default": {}
        }
      },
      "additionalProperties": false
    },
    "PersistConfig": {
      "description": "Configuration for how the Relay Compiler should persist GraphQL queries.",
      "anyOf": [
        {
          "description": "This variant represents a remote persistence configuration, where GraphQL queries are sent to a remote endpoint for persistence.",
          "$ref": "#/$defs/RemotePersistConfig"
        },
        {
          "description": "This variant represents a local persistence configuration, where GraphQL queries are persisted to a local JSON file.\n\nWhen this variant is used, the compiler will attempt to read the local file as a hash map,\nadd new queries to the map, and then serialize and write the resulting map to the configured path.",
          "$ref": "#/$defs/LocalPersistConfig"
        }
      ]
    },
    "ProjectName": {
      "description": "Represents the name of a project in the Relay configuration.",
      "anyOf": [
        {
          "description": "No project name is specified.",
          "type": "null"
        },
        {
          "description": "A project name.\n\nThis should match one the keys in the `projects` map in the Relay compiler config.",
          "$ref": "#/$defs/StringKey"
        }
      ]
    },
    "ProjectSet": {
      "description": "Set of project names.",
      "anyOf": [
        {
          "$ref": "#/$defs/ProjectName"
        },
        {
          "type": "array",
          "items": {
            "$ref": "#/$defs/ProjectName"
          }
        }
      ]
    },
    "RemotePersistConfig": {
      "description": "Configuration for remote persistence of GraphQL documents.",
      "type": "object",
      "properties": {
        "concurrency": {
          "description": "Number of concurrent requests that can be made to the server.",
          "type": [
            "integer",
            "null"
          ],
          "format": "uint",
          "default": null,
          "minimum": 0
        },
        "headers": {
          "description": "Additional headers to include in the POST request.",
          "type": "object",
          "additionalProperties": {
            "type": "string"
          },
          "default": {}
        },
        "includeQueryText": {
          "description": "Whether to include the query text in the persisted document.",
          "type": "boolean",
          "default": false
        },
        "params": {
          "description": "Additional parameters to include in the POST request.\n\nThe main document will be in a POST parameter `text`. This map can contain\nadditional parameters to send.",
          "type": "object",
          "additionalProperties": {
            "type": "string"
          },
          "default": {}
        },
        "url": {
          "description": "URL that the document should be persisted to via a POST request.",
          "type": "string"
        }
      },
      "additionalProperties": false,
      "required": [
        "url"
      ]
    },
    "ResolverContextTypeInput": {
      "description": "Describes the type to import and use as the context for Relay Resolvers.",
      "anyOf": [
        {
          "description": "The type imported using a relative path",
          "$ref": "#/$defs/ResolverContextTypeInputPath"
        },
        {
          "description": "The type imported using a named package",
          "$ref": "#/$defs/ResolverContextTypeInputPackage"
        }
      ]
    },
    "ResolverContextTypeInputPackage": {
      "description": "Specifies how Relay can import the Resolver context type from a named package",
      "type": "object",
      "properties": {
        "name": {
          "description": "The name under which the type is exported from the package",
          "$ref": "#/$defs/StringKey"
        },
        "package": {
          "description": "The name of the package",
          "$ref": "#/$defs/StringKey"
        }
      },
      "required": [
        "name",
        "package"
      ]
    },
    "ResolverContextTypeInputPath": {
      "description": "Specifies how Relay can import the Resolver context type from a path",
      "type": "object",
      "properties": {
        "name": {
          "description": "The name under which the type is exported from the module",
          "$ref": "#/$defs/StringKey"
        },
        "path": {
          "description": "The path to the module relative to the project root",
          "type": "string"
        }
      },
      "required": [
        "name",
        "path"
      ]
    },
    "ResolversSchemaModuleConfig": {
      "description": "Configuration for resolvers_schema_module generation",
      "type": "object",
      "properties": {
        "applyToNormalizationAst": {
          "type": "boolean",
          "default": false
        },
        "path": {
          "type": "string",
          "default": ""
        }
      },
      "additionalProperties": false
    },
    "Rollout": {
      "description": "A utility to enable gradual rollout of large codegen changes.\nCan be constructed as the Default which passes or a percentage between 0 and\n100.",
      "type": [
        "integer",
        "null"
      ],
      "format": "uint8",
      "maximum": 255,
      "minimum": 0
    },
    "RolloutRange": {
      "description": "A utility to enable gradual rollout of large codegen changes. Allows you to\nspecify a range of percentages to rollout.",
      "type": "object",
      "properties": {
        "end": {
          "type": "integer",
          "format": "uint8",
          "maximum": 255,
          "minimum": 0
        },
        "start": {
          "type": "integer",
          "format": "uint8",
          "maximum": 255,
          "minimum": 0
        }
      },
      "required": [
        "start",
        "end"
      ]
    },
    "SavedStateClockData": {
      "description": "Holds extended clock data that includes source control aware\nquery metadata.\n<https://facebook.github.io/watchman/docs/scm-query.html>",
      "type": "object",
      "properties": {
        "commit-id": {
          "type": [
            "string",
            "null"
          ]
        },
        "config": true,
        "storage": {
          "type": [
            "string",
            "null"
          ]
        }
      }
    },
    "SchemaConfig": {
      "type": "object",
      "properties": {
        "connectionInterface": {
          "$ref": "#/$defs/ConnectionInterface",
          "default": {
            "cursor": "cursor",
            "edges": "edges",
            "endCursor": "endCursor",
            "hasNextPage": "hasNextPage",
            "hasPreviousPage": "hasPreviousPage",
            "node": "node",
            "pageInfo": "pageInfo",
            "startCursor": "startCursor"
          }
        },
        "deferStreamInterface": {
          "$ref": "#/$defs/DeferStreamInterface",
          "default": {
            "deferName": "defer",
            "ifArg": "if",
            "initialCountArg": "initialCount",
            "labelArg": "label",
            "streamName": "stream",
            "useCustomizedBatchArg": "useCustomizedBatch"
          }
        },
        "enableTokenField": {
          "description": "If we should select __token field on fetchable types",
          "type": "boolean",
          "default": false
        },
        "nodeInterfaceIdField": {
          "description": "The name of the `id` field that exists on the `Node` interface.",
          "$ref": "#/$defs/StringKey",
          "default": "id"
        },
        "nodeInterfaceIdVariableName": {
          "description": "The name of the variable expected by the `node` query.",
          "$ref": "#/$defs/StringKey",
          "default": "id"
        },
        "nonNodeIdFields": {
          "anyOf": [
            {
              "$ref": "#/$defs/NonNodeIdFieldsConfig"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "unselectableDirectiveName": {
          "description": "The name of the directive indicating fields that cannot be selected",
          "$ref": "#/$defs/DirectiveName",
          "default": "unselectable"
        }
      }
    },
    "ScmAwareClockData": {
      "description": "Holds extended clock data that includes source control aware\nquery metadata.\n<https://facebook.github.io/watchman/docs/scm-query.html>",
      "type": "object",
      "properties": {
        "mergebase": {
          "type": [
            "string",
            "null"
          ]
        },
        "mergebase-with": {
          "type": [
            "string",
            "null"
          ]
        },
        "saved-state": {
          "anyOf": [
            {
              "$ref": "#/$defs/SavedStateClockData"
            },
            {
              "type": "null"
            }
          ]
        }
      }
    },
    "SingleProjectConfigFile": {
      "type": "object",
      "properties": {
        "$schema": {
          "description": "The user may hard-code the JSON Schema for their version of the config.",
          "type": [
            "string",
            "null"
          ],
          "default": null
        },
        "artifactDirectory": {
          "description": "A specific directory to output all artifacts to. When enabling this\nthe babel plugin needs `artifactDirectory` set as well.",
          "type": [
            "string",
            "null"
          ],
          "default": null
        },
        "codegenCommand": {
          "description": "Name of the command that runs the relay compiler. This will be added at\nthe top of generated code to let readers know how to regenerate the file.",
          "type": [
            "string",
            "null"
          ],
          "default": null
        },
        "customErrorType": {
          "description": "A map from GraphQL error name to import path, example:\n{\"name:: \"MyErrorName\", \"path\": \"../src/MyError\"}",
          "anyOf": [
            {
              "$ref": "#/$defs/CustomTypeImport"
            },
            {
              "type": "null"
            }
          ]
        },
        "customScalarTypes": {
          "description": "A map from GraphQL scalar types to a custom JS type, example:\n{ \"Url\": \"String\" }\n{ \"Url\": {\"name:: \"MyURL\", \"path\": \"../src/MyUrlTypes\"} }",
          "type": "object",
          "additionalProperties": {
            "$ref": "#/$defs/CustomType"
          },
          "default": {}
        },
        "eagerEsModules": {
          "description": "This option enables opting out of emitting es modules artifacts. When\nset to false, Relay will emit CommonJS modules.",
          "type": "boolean",
          "default": true
        },
        "enumModuleSuffix": {
          "title": "For Flow type generation",
          "description": "When set, enum values are imported from a module with this suffix.\nFor example, an enum Foo and this property set to \".test\" would be\nimported from \"Foo.test\".\nNote: an empty string is allowed and different from not setting the\nvalue, in the example above it would just import from \"Foo\".",
          "type": [
            "string",
            "null"
          ]
        },
        "excludes": {
          "description": "Directories to ignore under src\ndefault: ['**/node_modules/**', '**/__mocks__/**', '**/__generated__/**'],",
          "type": "array",
          "default": [
            "**/node_modules/**",
            "**/__mocks__/**",
            "**/__generated__/**"
          ],
          "items": {
            "type": "string"
          }
        },
        "extra": {
          "description": "A placeholder for allowing extra information in the config file",
          "default": null
        },
        "featureFlags": {
          "description": "Enable and disable experimental or legacy behaviors.\nWARNING! These are not stable and may change at any time.",
          "anyOf": [
            {
              "$ref": "#/$defs/FeatureFlags"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "isDevVariableName": {
          "description": "We may generate some content in the artifacts that's stripped in production if __DEV__ variable is set\nThis config option is here to define the name of that special variable",
          "type": [
            "string",
            "null"
          ],
          "default": null
        },
        "jsModuleFormat": {
          "description": "Import/export style to use in generated JavaScript modules.",
          "$ref": "#/$defs/JsModuleFormat",
          "default": "commonjs"
        },
        "language": {
          "description": "The desired output language, \"flow\" or \"typescript\".",
          "$ref": "#/$defs/TypegenLanguage"
        },
        "moduleImportConfig": {
          "description": "Configuration for @module",
          "$ref": "#/$defs/ModuleImportConfig",
          "default": {
            "dynamicModuleProvider": null,
            "operationModuleProvider": null,
            "surface": null
          }
        },
        "noFutureProofEnums": {
          "description": "This option controls whether or not a catch-all entry is added to enum type definitions\nfor values that may be added in the future. Enabling this means you will have to update\nyour application whenever the GraphQL server schema adds new enum values to prevent it\nfrom breaking.",
          "type": "boolean",
          "default": false
        },
        "noSourceControl": {
          "description": "Opt out of source control checks/integration.",
          "type": [
            "boolean",
            "null"
          ],
          "default": null
        },
        "optionalInputFields": {
          "title": "For Flow type generation",
          "description": "When set, generated input types will have the listed fields optional\neven if the schema defines them as required.",
          "type": "array",
          "default": [],
          "items": {
            "$ref": "#/$defs/StringKey"
          }
        },
        "persistConfig": {
          "description": "Query Persist Configuration\nIt contains URL and addition parameters that will be included\nwith the request (think API_KEY, APP_ID, etc...)",
          "anyOf": [
            {
              "$ref": "#/$defs/PersistConfig"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "relativizeJsModulePaths": {
          "description": "Whether to treat all JS module names as relative to './' (true) or not.\ndefault: true",
          "type": "boolean",
          "default": true
        },
        "requireCustomScalarTypes": {
          "description": "Require all GraphQL scalar types mapping to be defined, will throw\nif a GraphQL scalar type doesn't have a JS type",
          "type": "boolean",
          "default": false
        },
        "resolverContextType": {
          "description": "Indicates the type to import and use as the context for Relay Resolvers.",
          "anyOf": [
            {
              "$ref": "#/$defs/ResolverContextTypeInput"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "resolversSchemaModule": {
          "anyOf": [
            {
              "$ref": "#/$defs/ResolversSchemaModuleConfig"
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "schema": {
          "description": "Path to schema.graphql",
          "type": "string",
          "default": ""
        },
        "schemaConfig": {
          "description": "Extra configuration for the GraphQL schema itself.",
          "$ref": "#/$defs/SchemaConfig",
          "default": {
            "connectionInterface": {
              "cursor": "cursor",
              "edges": "edges",
              "endCursor": "endCursor",
              "hasNextPage": "hasNextPage",
              "hasPreviousPage": "hasPreviousPage",
              "node": "node",
              "pageInfo": "pageInfo",
              "startCursor": "startCursor"
            },
            "deferStreamInterface": {
              "deferName": "defer",
              "ifArg": "if",
              "initialCountArg": "initialCount",
              "labelArg": "label",
              "streamName": "stream",
              "useCustomizedBatchArg": "useCustomizedBatch"
            },
            "enableTokenField": false,
            "nodeInterfaceIdField": "id",
            "nodeInterfaceIdVariableName": "id",
            "nonNodeIdFields": null,
            "unselectableDirectiveName": "unselectable"
          }
        },
        "schemaExtensions": {
          "description": "List of directories with schema extensions.",
          "type": "array",
          "default": [],
          "items": {
            "type": "string"
          }
        },
        "src": {
          "description": "Root directory of application code",
          "type": "string",
          "default": ""
        },
        "typescriptExcludeUndefinedFromNullableUnion": {
          "description": "Keep the previous compiler behavior by outputting an union\nof the raw type and null, and not the **correct** behavior\nof an union with the raw type, null and undefined.",
          "type": "boolean",
          "default": false
        },
        "useImportTypeSyntax": {
          "title": "For Typescript type generation",
          "description": "Whether to use the `import type` syntax introduced in Typescript\nversion 3.8. This will prevent warnings from `importsNotUsedAsValues`.",
          "type": "boolean",
          "default": false
        }
      },
      "additionalProperties": false,
      "required": [
        "language"
      ]
    },
    "StringKey": {
      "type": "string",
      "format": null
    },
    "Surface": {
      "type": "string",
      "enum": [
        "resolvers",
        "all"
      ]
    },
    "TypegenLanguage": {
      "type": "string",
      "enum": [
        "javascript",
        "typescript",
        "flow"
      ]
    }
  }
}