11import { Plugin , ResolvedConfig } from 'vite' ;
22import { CodegenContext , generate , loadContext } from '@graphql-codegen/cli' ;
3+ import {
4+ normalizeInstanceOrArray ,
5+ Types ,
6+ } from '@graphql-codegen/plugin-helpers' ;
37import minimatch from 'minimatch' ;
48
59export default function VitePluginGraphQLCodegen ( ) : Plugin {
610 let viteConfig : ResolvedConfig ;
711 let codegenContext : CodegenContext ;
812
13+ const getRelativePath = ( path : string ) => {
14+ return path . split ( `${ viteConfig . root } /` ) . slice ( - 1 ) [ 0 ] ;
15+ } ;
16+
917 return {
1018 name : 'graphql-codegen' ,
1119 async config ( config ) {
@@ -26,17 +34,35 @@ export default function VitePluginGraphQLCodegen(): Plugin {
2634 } ,
2735 configureServer ( server ) {
2836 const listener = async ( path = '' ) => {
29- const { generates, documents } = codegenContext . getConfig ( ) ;
37+ const relativePath = getRelativePath ( path ) ;
38+ const match = ( pattern : string ) => minimatch ( relativePath , pattern ) ;
3039
31- // Check if file is a generated file
32- const generated = Object . keys ( generates ) ;
33- const isGenerated = generated . some ( file => path . includes ( file ) ) ;
34- if ( isGenerated ) return ;
40+ const codegenConfig = codegenContext . getConfig < Types . Config > ( ) ;
41+ const { generates = { } , documents } = codegenConfig ;
3542
36- // Check if file is an operation document
37- const [ , relativePath = '' ] = path . split ( `${ viteConfig . root } /` ) ;
38- const isDocument = minimatch ( relativePath , documents ) ;
39- if ( ! isDocument ) return ;
43+ // If modified file is generated
44+ for ( const [ genPath , genConfig ] of Object . entries ( generates ) ) {
45+ // If generated path is file
46+ const fileExt = genPath . split ( '.' ) . slice ( - 1 ) [ 0 ] ;
47+ const isFile = ! ! fileExt ;
48+ if ( isFile && match ( genPath ) ) return ;
49+
50+ // If generated path is directory
51+ const { preset = '' , presetConfig } = genConfig ;
52+ const isNearOperationFilePreset = preset === 'near-operation-file' ;
53+ const presetExt = presetConfig ?. extension ?? '' ;
54+ if ( isNearOperationFilePreset && match ( `**/*${ presetExt } ` ) ) return ;
55+ }
56+
57+ // If modified file is operation document
58+ if ( ! documents ) return ;
59+ const normalized = normalizeInstanceOrArray ( documents ) ;
60+ const documentFiles = codegenContext . loadDocuments ( normalized ) ;
61+
62+ for ( const docFile of await documentFiles ) {
63+ if ( ! docFile . location ) break ;
64+ if ( ! match ( getRelativePath ( docFile . location ) ) ) return ;
65+ }
4066
4167 try {
4268 await generate ( codegenContext ) ;
0 commit comments