import { Types , CodegenPlugin } from '@graphql-codegen/plugin-helpers' ; import type { Source } from '@graphql-tools/utils' ; import addPlugin from '@graphql-codegen/add' ; import { join } from 'path' ; import { FragmentDefinitionNode , buildASTSchema , GraphQLSchema , DocumentNode , Kind } from 'graphql' ; import { appendExtensionToFilePath , defineFilepathSubfolder } from './utils' ; import { resolveDocumentImports , DocumentImportResolverOptions } from './resolve-document-imports' ; import { FragmentImport , getConfigValue , ImportDeclaration , ImportSource , LoadedFragment , } from '@graphql-codegen/visitor-plugin-common' ; export { resolveDocumentImports , DocumentImportResolverOptions } ; export type FragmentImportFromFn = ( source : ImportSource < FragmentImport > , sourceFilePath : string ) => ImportSource < FragmentImport > ; export type NearOperationFileConfig = { description exampleMarkdown baseTypesPath : string ; description exampleMarkdown importAllFragmentsFrom ? : string | FragmentImportFromFn ; description default exampleMarkdown extension ? : string ; description default exampleMarkdown cwd ? : string ; description default exampleMarkdown folder ? : string ; description default exampleMarkdown importTypesNamespace ? : string ; } ; export type FragmentNameToFile = { [ fragmentName ] : { location : string ; importsNames : string [ ] ; onType : string ; node : FragmentDefinitionNode ; } ; } ; export const preset = { buildGeneratesSection : options => { const schemaObject = options . schemaAst ? options . schemaAst : buildASTSchema ( options . schema , options . config as any ) ; const baseDir = options . presetConfig . cwd || process . cwd ( ) ; const extension = options . presetConfig . extension || '.generated.ts' ; const folder = options . presetConfig . folder || '' ; const importTypesNamespace = options . presetConfig . importTypesNamespace || 'Types' ; const importAllFragmentsFrom = options . presetConfig . importAllFragmentsFrom || null ; const baseTypesPath = options . presetConfig . baseTypesPath ; if ( ! baseTypesPath ) { throw new Error ( `Preset "near-operation-file" requires you to specify "baseTypesPath" configuration and point it to your base types file (generated by "typescript" plugin)!` ) ; } const shouldAbsolute = ! baseTypesPath . startsWith ( '~' ) ; const pluginMap = { ... options . pluginMap , add : addPlugin , } ; const sources = resolveDocumentImports ( options , schemaObject , { baseDir , generateFilePath ( location ) { const newFilePath = defineFilepathSubfolder ( location , folder ) ; return appendExtensionToFilePath ( newFilePath , extension ) ; } , schemaTypesSource : { path : shouldAbsolute ? join ( options . baseOutputDir , baseTypesPath ) : baseTypesPath , namespace : importTypesNamespace , } , typesImport : options . config . useTypeImports ?? false , } , getConfigValue ( options . config . dedupeFragments , false ) ) ; const filePathsMap = new Map < string , { importStatements : Set < string > ; documents : Array < Source > ; externalFragments : Array < LoadedFragment < { level : number ; } > > ; fragmentImports : Array < ImportDeclaration < FragmentImport > > ; } > ( ) ; for ( const source of sources ) { let record = filePathsMap . get ( source . filename ) ; if ( record === undefined ) { record = { importStatements : new Set ( ) , documents : [ ] , externalFragments : [ ] , fragmentImports : [ ] , } ; filePathsMap . set ( source . filename , record ) ; } for ( const importStatement of source . importStatements ) { record . importStatements . add ( importStatement ) ; } record . documents . push ( ... source . documents ) ; record . externalFragments . push ( ... source . externalFragments ) ; record . fragmentImports . push ( ... source . fragmentImports ) ; } const artifacts = [ ] ; for ( const [ filename , record ] of filePathsMap . entries ( ) ) { let fragmentImportsArr = record . fragmentImports ; if ( importAllFragmentsFrom ) { fragmentImportsArr = record . fragmentImports . map < ImportDeclaration < FragmentImport > > ( t => { const newImportSource = typeof importAllFragmentsFrom === 'string' ? { ... t . importSource , path : importAllFragmentsFrom } : importAllFragmentsFrom ( t . importSource , filename ) ; return { ... t , importSource : newImportSource || t . importSource , } ; } ) ; } const plugins = [ ... ( options . config . globalNamespace ? [ ] : Array . from ( record . importStatements ) . map ( importStatement => ( { add : { content : importStatement } } ) ) ) , ... options . plugins , ] ; const config = { ... options . config , exportFragmentSpreadSubTypes : true , namespacedImportName : importTypesNamespace , externalFragments : record . externalFragments , fragmentImports : fragmentImportsArr , } ; const document = { kind : Kind . DOCUMENT , definitions : [ ] } ; const combinedSource = { rawSDL : '' , document : document , location : record . documents [ 0 ] . location , } ; for ( const source of record . documents ) { combinedSource . rawSDL += source . rawSDL ; ( combinedSource . document . definitions as any ) . push ( ... source . document . definitions ) ; } artifacts . push ( { filename , documents : [ combinedSource ] , plugins , pluginMap , config , schema : options . schema , schemaAst : schemaObject , skipDocumentsValidation : true , } ) ; } return artifacts ; } , } ; export default preset ;