@@ -90,6 +90,10 @@ export interface GraphQLTagPluckOptions {
90
90
* The magic comment anchor to look for when parsing GraphQL strings. Defaults to `graphql`.
91
91
*/
92
92
gqlMagicComment ?: string ;
93
+ /**
94
+ * The name of a custom Vue block that contains raw GraphQL to be plucked.
95
+ */
96
+ gqlVueBlock ?: string ;
93
97
/**
94
98
* Allows to use a global identifier instead of a module import.
95
99
* ```js
@@ -122,6 +126,23 @@ function parseWithVue(vueTemplateCompiler: typeof import('@vue/compiler-sfc'), f
122
126
: '' ;
123
127
}
124
128
129
+ function customBlockFromVue (
130
+ // tslint:disable-next-line: no-implicit-dependencies
131
+ vueTemplateCompiler : typeof import ( '@vue/compiler-sfc' ) ,
132
+ fileData : string ,
133
+ filePath : string ,
134
+ blockType : string
135
+ ) : Source | undefined {
136
+ const { descriptor } = vueTemplateCompiler . parse ( fileData ) ;
137
+
138
+ const block = descriptor . customBlocks . find ( b => b . type === blockType ) ;
139
+ if ( block === undefined ) {
140
+ return ;
141
+ }
142
+
143
+ return new Source ( block . content . trim ( ) , filePath , block . loc . start ) ;
144
+ }
145
+
125
146
// tslint:disable-next-line: no-implicit-dependencies
126
147
function parseWithSvelte ( svelte2tsx : typeof import ( 'svelte2tsx' ) , fileData : string ) {
127
148
const fileInTsx = svelte2tsx . svelte2tsx ( fileData ) ;
@@ -145,13 +166,22 @@ export const gqlPluckFromCodeString = async (
145
166
validate ( { code, options } ) ;
146
167
147
168
const fileExt = extractExtension ( filePath ) ;
169
+
170
+ let blockSource ;
148
171
if ( fileExt === '.vue' ) {
172
+ if ( options . gqlVueBlock ) {
173
+ blockSource = await pluckVueFileCustomBlock ( code , filePath , options . gqlVueBlock ) ;
174
+ }
149
175
code = await pluckVueFileScript ( code ) ;
150
176
} else if ( fileExt === '.svelte' ) {
151
177
code = await pluckSvelteFileScript ( code ) ;
152
178
}
153
179
154
- return parseCode ( { code, filePath, options } ) . map ( t => new Source ( t . content , filePath , t . loc . start ) ) ;
180
+ const sources = parseCode ( { code, filePath, options } ) . map ( t => new Source ( t . content , filePath , t . loc . start ) ) ;
181
+ if ( blockSource ) {
182
+ sources . push ( blockSource ) ;
183
+ }
184
+ return sources ;
155
185
} ;
156
186
157
187
/**
@@ -171,13 +201,22 @@ export const gqlPluckFromCodeStringSync = (
171
201
validate ( { code, options } ) ;
172
202
173
203
const fileExt = extractExtension ( filePath ) ;
204
+
205
+ let blockSource ;
174
206
if ( fileExt === '.vue' ) {
207
+ if ( options . gqlVueBlock ) {
208
+ blockSource = pluckVueFileCustomBlockSync ( code , filePath , options . gqlVueBlock ) ;
209
+ }
175
210
code = pluckVueFileScriptSync ( code ) ;
176
211
} else if ( fileExt === '.svelte' ) {
177
212
code = pluckSvelteFileScriptSync ( code ) ;
178
213
}
179
214
180
- return parseCode ( { code, filePath, options } ) . map ( t => new Source ( t . content , filePath , t . loc . start ) ) ;
215
+ const sources = parseCode ( { code, filePath, options } ) . map ( t => new Source ( t . content , filePath , t . loc . start ) ) ;
216
+ if ( blockSource ) {
217
+ sources . push ( blockSource ) ;
218
+ }
219
+ return sources ;
181
220
} ;
182
221
183
222
export function parseCode ( {
@@ -250,31 +289,44 @@ const MissingSvelteTemplateCompilerError = new Error(
250
289
` )
251
290
) ;
252
291
253
- async function pluckVueFileScript ( fileData : string ) {
254
- let vueTemplateCompiler : typeof import ( '@vue/compiler-sfc' ) ;
292
+ async function loadVueCompilerSync ( ) {
255
293
try {
256
294
// eslint-disable-next-line import/no-extraneous-dependencies
257
- vueTemplateCompiler = await import ( '@vue/compiler-sfc' ) ;
295
+ return await import ( '@vue/compiler-sfc' ) ;
258
296
} catch ( e : any ) {
259
297
throw MissingVueTemplateCompilerError ;
260
298
}
261
-
262
- return parseWithVue ( vueTemplateCompiler , fileData ) ;
263
299
}
264
300
265
- function pluckVueFileScriptSync ( fileData : string ) {
266
- let vueTemplateCompiler : typeof import ( '@vue/compiler-sfc' ) ;
267
-
301
+ function loadVueCompilerAsync ( ) {
268
302
try {
269
303
// eslint-disable-next-line import/no-extraneous-dependencies
270
- vueTemplateCompiler = require ( '@vue/compiler-sfc' ) ;
304
+ return require ( '@vue/compiler-sfc' ) ;
271
305
} catch ( e : any ) {
272
306
throw MissingVueTemplateCompilerError ;
273
307
}
308
+ }
274
309
310
+ async function pluckVueFileScript ( fileData : string ) {
311
+ const vueTemplateCompiler = await loadVueCompilerSync ( ) ;
275
312
return parseWithVue ( vueTemplateCompiler , fileData ) ;
276
313
}
277
314
315
+ function pluckVueFileScriptSync ( fileData : string ) {
316
+ const vueTemplateCompiler = loadVueCompilerAsync ( ) ;
317
+ return parseWithVue ( vueTemplateCompiler , fileData ) ;
318
+ }
319
+
320
+ async function pluckVueFileCustomBlock ( fileData : string , filePath : string , blockType : string ) {
321
+ const vueTemplateCompiler = await loadVueCompilerSync ( ) ;
322
+ return customBlockFromVue ( vueTemplateCompiler , fileData , filePath , blockType ) ;
323
+ }
324
+
325
+ function pluckVueFileCustomBlockSync ( fileData : string , filePath : string , blockType : string ) {
326
+ const vueTemplateCompiler = loadVueCompilerAsync ( ) ;
327
+ return customBlockFromVue ( vueTemplateCompiler , fileData , filePath , blockType ) ;
328
+ }
329
+
278
330
async function pluckSvelteFileScript ( fileData : string ) {
279
331
let svelte2tsx : typeof import ( 'svelte2tsx' ) ;
280
332
try {
0 commit comments