@sanity/codegen 5.10.1 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,555 @@
1
+ import {BooleanFlag} from '@oclif/core/interfaces'
2
+ import {CustomOptions} from '@oclif/core/interfaces'
3
+ import {DefinedTelemetryTrace} from '@sanity/telemetry'
4
+ import {ExprNode} from 'groq-js'
5
+ import {FSWatcher} from 'chokidar'
6
+ import {OptionFlag} from '@oclif/core/interfaces'
7
+ import {SanityCommand} from '@sanity/cli-core'
8
+ import {SchemaType} from 'groq-js'
9
+ import {spinner} from '@sanity/cli-core/ux'
10
+ import * as t from '@babel/types'
11
+ import {TransformOptions} from '@babel/core'
12
+ import {WorkerChannel} from '@sanity/worker-channels'
13
+ import {WorkerChannelReporter} from '@sanity/worker-channels'
14
+ import * as z from 'zod'
15
+
16
+ /**
17
+ * @deprecated use TypeGenConfig
18
+ * @public
19
+ */
20
+ export declare type CodegenConfig = TypeGenConfig
21
+
22
+ /**
23
+ * @public
24
+ */
25
+ export declare const configDefinition: z.ZodObject<
26
+ {
27
+ formatGeneratedCode: z.ZodDefault<z.ZodBoolean>
28
+ generates: z.ZodDefault<z.ZodString>
29
+ overloadClientMethods: z.ZodDefault<z.ZodBoolean>
30
+ path: z.ZodDefault<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString>]>>
31
+ schema: z.ZodDefault<z.ZodString>
32
+ },
33
+ z.core.$strip
34
+ >
35
+
36
+ /**
37
+ * A module containing queries that have been evaluated.
38
+ * @public
39
+ */
40
+ export declare interface EvaluatedModule {
41
+ errors: (QueryEvaluationError | QueryExtractionError)[]
42
+ filename: string
43
+ queries: EvaluatedQuery[]
44
+ }
45
+
46
+ /**
47
+ * An `ExtractedQuery` that has been evaluated against a schema, yielding a TypeScript type.
48
+ * @public
49
+ */
50
+ export declare interface EvaluatedQuery extends ExtractedQuery {
51
+ ast: t.ExportNamedDeclaration
52
+ code: string
53
+ id: t.Identifier
54
+ stats: TypeEvaluationStats
55
+ tsType: t.TSType
56
+ }
57
+
58
+ /**
59
+ * A module (file) containing extracted GROQ queries.
60
+ * @public
61
+ */
62
+ export declare interface ExtractedModule {
63
+ errors: QueryExtractionError[]
64
+ filename: string
65
+ queries: ExtractedQuery[]
66
+ }
67
+
68
+ /**
69
+ * A GROQ query extracted from a source file.
70
+ * @public
71
+ */
72
+ export declare interface ExtractedQuery {
73
+ filename: string
74
+ query: string
75
+ variable: QueryVariable
76
+ }
77
+
78
+ /**
79
+ * Filter a union of object types by the _type property. This is handy when working with page builder
80
+ * setups where the returned type is an array containing multiple types.
81
+ *
82
+ * @example
83
+ * ```ts
84
+ *
85
+ * export type Callout = {
86
+ * _type: 'callout'
87
+ * title?: string
88
+ * content?: string
89
+ * }
90
+ *
91
+ * export type Video = {
92
+ * _type: 'video'
93
+ * url?: string
94
+ * caption?: string
95
+ * }
96
+ * type FORM_QUERY_RESULT = {
97
+ * _id: string
98
+ * title?: string
99
+ * content?: Array<
100
+ * | ({ _key: string } & Callout)
101
+ * | ({ _key: string } & Video)
102
+ * >
103
+ * } | null
104
+ *
105
+ * // Get the type of the content with the Get helper
106
+ * type Content = Get<FORM_QUERY_RESULT, 'content', number>
107
+ *
108
+ * // Get the type for a callout module from the page builder type
109
+ * type CalloutModule = FilterByType<Content, 'callout'>
110
+ * // → { _key: string } & Callout
111
+ * ```
112
+ * @public
113
+ */
114
+ export declare type FilterByType<
115
+ U extends {
116
+ _type: string
117
+ },
118
+ T extends U['_type'],
119
+ > = Extract<
120
+ U,
121
+ {
122
+ _type: T
123
+ }
124
+ >
125
+
126
+ /**
127
+ * findQueriesInPath takes a path or array of paths and returns all GROQ queries in the files.
128
+ * @param path - The path or array of paths to search for queries
129
+ * @param babelOptions - The babel configuration to use when parsing the source
130
+ * @param resolver - A resolver function to use when resolving module imports
131
+ * @returns An async generator that yields the results of the search
132
+ * @beta
133
+ * @internal
134
+ */
135
+ export declare function findQueriesInPath({
136
+ babelOptions,
137
+ path,
138
+ resolver,
139
+ }: FindQueriesInPathOptions): {
140
+ files: string[]
141
+ queries: AsyncIterable<ExtractedModule>
142
+ }
143
+
144
+ declare interface FindQueriesInPathOptions {
145
+ path: string | string[]
146
+ babelOptions?: TransformOptions
147
+ resolver?: NodeJS.RequireResolve
148
+ }
149
+
150
+ /**
151
+ * findQueriesInSource takes a source string and returns all GROQ queries in it.
152
+ * @param source - The source code to search for queries
153
+ * @param filename - The filename of the source code
154
+ * @param babelConfig - The babel configuration to use when parsing the source
155
+ * @param resolver - A resolver function to use when resolving module imports
156
+ * @returns
157
+ * @beta
158
+ * @internal
159
+ */
160
+ export declare function findQueriesInSource(
161
+ source: string,
162
+ filename: string,
163
+ babelConfig?: TransformOptions,
164
+ resolver?: NodeJS.RequireResolve,
165
+ ): ExtractedModule
166
+
167
+ /** @public */
168
+ export declare interface GenerateTypesOptions {
169
+ schema: SchemaType
170
+ overloadClientMethods?: boolean
171
+ queries?: AsyncIterable<ExtractedModule>
172
+ reporter?: WorkerChannelReporter<TypegenWorkerChannel>
173
+ root?: string
174
+ schemaPath?: string
175
+ }
176
+
177
+ /**
178
+ * Result from a single generation run.
179
+ * @public
180
+ */
181
+ export declare interface GenerationResult {
182
+ code: string
183
+ duration: number
184
+ emptyUnionTypeNodesGenerated: number
185
+ filesWithErrors: number
186
+ outputSize: number
187
+ queriesCount: number
188
+ queryFilesCount: number
189
+ schemaTypesCount: number
190
+ typeNodesGenerated: number
191
+ unknownTypeNodesGenerated: number
192
+ unknownTypeNodesRatio: number
193
+ }
194
+
195
+ /**
196
+ * Get a deeply nested property type from a complex type structure. Safely navigates
197
+ * through nullable types (`T | null | undefined`) at each level, preserving the
198
+ * nullability of the final accessed property.
199
+ *
200
+ * Supports up to 20 levels of nesting.
201
+ *
202
+ * @example
203
+ * ```ts
204
+ * type POST_QUERY_RESULT = {
205
+ * _id: string
206
+ * author: {
207
+ * profile: {
208
+ * name: string;
209
+ * } | null;
210
+ * } | null;
211
+ * links: Array<{
212
+ * _key: string
213
+ * type: 'link'
214
+ * label: string
215
+ * url: string
216
+ * }> | null
217
+ * } | null
218
+ *
219
+ * // Basic property access:
220
+ * type Id = Get<POST_QUERY_RESULT, '_id'>;
221
+ * // → string
222
+ *
223
+ * // Nested property access:
224
+ * type Profile = Get<POST_QUERY_RESULT, 'author', 'profile';
225
+ * // → { name: string } | null
226
+ *
227
+ * // Array element access using `number`:
228
+ * type Link = Get<POST_QUERY_RESULT, 'links', number, 'label'>;
229
+ * // → string
230
+ * ```
231
+ * @public
232
+ */
233
+ export declare type Get<
234
+ T,
235
+ K1 extends keyof NonNullish<T>,
236
+ K2 extends keyof NavigatePath<T, [K1]> = never,
237
+ K3 extends keyof NavigatePath<T, [K1, K2]> = never,
238
+ K4 extends keyof NavigatePath<T, [K1, K2, K3]> = never,
239
+ K5 extends keyof NavigatePath<T, [K1, K2, K3, K4]> = never,
240
+ K6 extends keyof NavigatePath<T, [K1, K2, K3, K4, K5]> = never,
241
+ K7 extends keyof NavigatePath<T, [K1, K2, K3, K4, K5, K6]> = never,
242
+ K8 extends keyof NavigatePath<T, [K1, K2, K3, K4, K5, K6, K7]> = never,
243
+ K9 extends keyof NavigatePath<T, [K1, K2, K3, K4, K5, K6, K7, K8]> = never,
244
+ K10 extends keyof NavigatePath<T, [K1, K2, K3, K4, K5, K6, K7, K8, K9]> = never,
245
+ K11 extends keyof NavigatePath<T, [K1, K2, K3, K4, K5, K6, K7, K8, K9, K10]> = never,
246
+ K12 extends keyof NavigatePath<T, [K1, K2, K3, K4, K5, K6, K7, K8, K9, K10, K11]> = never,
247
+ K13 extends keyof NavigatePath<T, [K1, K2, K3, K4, K5, K6, K7, K8, K9, K10, K11, K12]> = never,
248
+ K14 extends keyof NavigatePath<T, [K1, K2, K3, K4, K5, K6, K7, K8, K9, K10, K11, K12, K13]> =
249
+ never,
250
+ K15 extends keyof NavigatePath<T, [K1, K2, K3, K4, K5, K6, K7, K8, K9, K10, K11, K12, K13, K14]> =
251
+ never,
252
+ K16 extends keyof NavigatePath<
253
+ T,
254
+ [K1, K2, K3, K4, K5, K6, K7, K8, K9, K10, K11, K12, K13, K14, K15]
255
+ > = never,
256
+ K17 extends keyof NavigatePath<
257
+ T,
258
+ [K1, K2, K3, K4, K5, K6, K7, K8, K9, K10, K11, K12, K13, K14, K15, K16]
259
+ > = never,
260
+ K18 extends keyof NavigatePath<
261
+ T,
262
+ [K1, K2, K3, K4, K5, K6, K7, K8, K9, K10, K11, K12, K13, K14, K15, K16, K17]
263
+ > = never,
264
+ K19 extends keyof NavigatePath<
265
+ T,
266
+ [K1, K2, K3, K4, K5, K6, K7, K8, K9, K10, K11, K12, K13, K14, K15, K16, K17, K18]
267
+ > = never,
268
+ K20 extends keyof NavigatePath<
269
+ T,
270
+ [K1, K2, K3, K4, K5, K6, K7, K8, K9, K10, K11, K12, K13, K14, K15, K16, K17, K18, K19]
271
+ > = never,
272
+ > = GetAtPath<
273
+ T,
274
+ TakeUntilNever<
275
+ [K1, K2, K3, K4, K5, K6, K7, K8, K9, K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K20]
276
+ >
277
+ >
278
+
279
+ /** Recursively gets value at path, preserving nullability at final access. */
280
+ declare type GetAtPath<T, Path extends unknown[]> = Path extends []
281
+ ? T
282
+ : Path extends [infer K]
283
+ ? K extends keyof NonNullish<T>
284
+ ? NonNullish<T>[K]
285
+ : never
286
+ : Path extends [infer K, ...infer Rest]
287
+ ? K extends keyof NonNullish<T>
288
+ ? GetAtPath<NonNullish<T>[K], Rest>
289
+ : never
290
+ : never
291
+
292
+ /**
293
+ * This is a custom implementation of require.resolve that takes into account the paths
294
+ * configuration in tsconfig.json. This is necessary if we want to resolve paths that are
295
+ * custom defined in the tsconfig.json file.
296
+ * Resolving here is best effort and might not work in all cases.
297
+ * @beta
298
+ */
299
+ export declare function getResolver(cwd?: string): NodeJS.RequireResolve
300
+
301
+ /** Recursively navigates through a path, stripping nullability for key lookup. */
302
+ declare type NavigatePath<T, Path extends unknown[]> = Path extends []
303
+ ? NonNullish<T>
304
+ : Path extends [infer K, ...infer Rest]
305
+ ? K extends keyof NonNullish<T>
306
+ ? NavigatePath<NonNullish<T>[K], Rest>
307
+ : never
308
+ : never
309
+
310
+ /** Excludes `null` and `undefined` from a type. */
311
+ declare type NonNullish<T> = T extends null | undefined ? never : T
312
+
313
+ /**
314
+ * An error that occurred during query evaluation.
315
+ * @public
316
+ */
317
+ declare class QueryEvaluationError extends Error {
318
+ filename: string
319
+ variable?: QueryVariable
320
+ constructor({cause, filename, variable}: QueryEvaluationErrorOptions)
321
+ }
322
+
323
+ declare interface QueryEvaluationErrorOptions {
324
+ cause: unknown
325
+ filename: string
326
+ variable?: QueryVariable
327
+ }
328
+
329
+ /**
330
+ * An error that occurred during query extraction.
331
+ * @public
332
+ */
333
+ export declare class QueryExtractionError extends Error {
334
+ filename: string
335
+ variable?: QueryVariable
336
+ constructor({cause, filename, variable}: QueryExtractionErrorOptions)
337
+ }
338
+
339
+ declare interface QueryExtractionErrorOptions {
340
+ cause: unknown
341
+ filename: string
342
+ variable?: QueryVariable
343
+ }
344
+
345
+ declare interface QueryVariable {
346
+ id: t.Identifier
347
+ end?: number
348
+ start?: number
349
+ }
350
+
351
+ /**
352
+ * Read, parse and process a config file
353
+ * @internal
354
+ */
355
+ export declare function readConfig(path: string): Promise<TypeGenConfig>
356
+
357
+ /**
358
+ * Read a schema from a given path
359
+ * @param path - The path to the schema
360
+ * @returns The schema
361
+ * @internal
362
+ * @beta
363
+ **/
364
+ export declare function readSchema(path: string): Promise<SchemaType>
365
+
366
+ /**
367
+ * Register Babel with the given options
368
+ *
369
+ * @param babelOptions - The options to use when registering Babel
370
+ * @beta
371
+ */
372
+ export declare function registerBabel(babelOptions?: TransformOptions): void
373
+
374
+ /**
375
+ * Runs a single typegen generation.
376
+ *
377
+ * This is the programmatic API for generating TypeScript types from GROQ queries.
378
+ * It spawns a worker thread to perform the generation and displays progress via CLI spinners.
379
+ *
380
+ * @param options - Configuration options including typegen config and working directory
381
+ * @returns Generation result containing the generated code and statistics
382
+ * @public
383
+ */
384
+ export declare function runTypegenGenerate(options: RunTypegenOptions): Promise<GenerationResult>
385
+
386
+ /**
387
+ * Options for running a single typegen generation.
388
+ * This is the programmatic API for one-off generation without file watching.
389
+ * @public
390
+ */
391
+ export declare interface RunTypegenOptions {
392
+ /** Working directory (usually project root) */
393
+ workDir: string
394
+ /** Typegen configuration */
395
+ config?: Partial<TypeGenConfig>
396
+ /** Optional spinner instance for progress display */
397
+ spin?: ReturnType<typeof spinner>
398
+ }
399
+
400
+ /**
401
+ * Starts a file watcher that triggers typegen on changes.
402
+ * Watches both query files (via patterns) and the schema JSON file.
403
+ * Implements debouncing and concurrency control to prevent multiple generations.
404
+ * @public
405
+ */
406
+ export declare function runTypegenWatcher(options: RunTypegenOptions): {
407
+ getStats: () => WatcherStats
408
+ stop: () => Promise<void>
409
+ watcher: FSWatcher
410
+ }
411
+
412
+ /**
413
+ * safeParseQuery parses a GROQ query string, but first attempts to extract any parameters used in slices. This method is _only_
414
+ * intended for use in type generation where we don't actually execute the parsed AST on a dataset, and should not be used elsewhere.
415
+ * @internal
416
+ */
417
+ export declare function safeParseQuery(query: string): ExprNode
418
+
419
+ /** Builds a tuple from elements, stopping at the first `never`. */
420
+ declare type TakeUntilNever<T extends unknown[]> = T extends [infer H, ...infer Rest]
421
+ ? [H] extends [never]
422
+ ? []
423
+ : [H, ...TakeUntilNever<Rest>]
424
+ : []
425
+
426
+ /**
427
+ * Statistics from the query type evaluation process.
428
+ * @public
429
+ */
430
+ declare interface TypeEvaluationStats {
431
+ allTypes: number
432
+ emptyUnions: number
433
+ unknownTypes: number
434
+ }
435
+
436
+ /** @public */
437
+ export declare type TypeGenConfig = z.infer<typeof configDefinition>
438
+
439
+ /**
440
+ * A class used to generate TypeScript types from a given schema
441
+ * @beta
442
+ */
443
+ export declare class TypeGenerator {
444
+ private getSchemaTypeGenerator
445
+ private getSchemaTypeDeclarations
446
+ private getAllSanitySchemaTypesDeclaration
447
+ private getArrayOfDeclaration
448
+ private getInternalReferenceSymbolDeclaration
449
+ private static getEvaluatedModules
450
+ private static getQueryMapDeclaration
451
+ generateTypes(options: GenerateTypesOptions): Promise<{
452
+ ast: t.Program
453
+ code: string
454
+ }>
455
+ }
456
+
457
+ /**
458
+ * @internal
459
+ */
460
+ export declare class TypegenGenerateCommand extends SanityCommand<typeof TypegenGenerateCommand> {
461
+ static description: string
462
+ static examples: {
463
+ command: string
464
+ description: string
465
+ }[]
466
+ static flags: {
467
+ 'config-path': OptionFlag<string | undefined, CustomOptions>
468
+ watch: BooleanFlag<boolean>
469
+ }
470
+ run(): Promise<void>
471
+ private getConfig
472
+ private runSingle
473
+ private runWatcher
474
+ }
475
+
476
+ /** @public */
477
+ export declare const TypegenWatchModeTrace: DefinedTelemetryTrace<
478
+ TypegenWatchModeTraceAttributes,
479
+ void
480
+ >
481
+
482
+ /**
483
+ * Attributes for typegen watch mode trace - tracks the start and stop of watch mode
484
+ * sessions with statistics about generation runs.
485
+ */
486
+ declare type TypegenWatchModeTraceAttributes =
487
+ | {
488
+ averageGenerationDuration: number
489
+ generationFailedCount: number
490
+ generationSuccessfulCount: number
491
+ step: 'stopped'
492
+ watcherDuration: number
493
+ }
494
+ | {
495
+ step: 'started'
496
+ }
497
+
498
+ /** @public */
499
+ export declare type TypegenWorkerChannel = WorkerChannel.Definition<{
500
+ evaluatedModules: WorkerChannel.Stream<EvaluatedModule>
501
+ generatedQueryTypes: WorkerChannel.Event<{
502
+ queryMapDeclaration: {
503
+ ast: t.Program
504
+ code: string
505
+ }
506
+ }>
507
+ generatedSchemaTypes: WorkerChannel.Event<{
508
+ allSanitySchemaTypesDeclaration: {
509
+ ast: t.ExportNamedDeclaration
510
+ code: string
511
+ id: t.Identifier
512
+ }
513
+ internalReferenceSymbol: {
514
+ ast: t.ExportNamedDeclaration
515
+ code: string
516
+ id: t.Identifier
517
+ }
518
+ schemaTypeDeclarations: {
519
+ ast: t.ExportNamedDeclaration
520
+ code: string
521
+ id: t.Identifier
522
+ name: string
523
+ tsType: t.TSType
524
+ }[]
525
+ }>
526
+ }>
527
+
528
+ /** @public */
529
+ export declare const TypesGeneratedTrace: DefinedTelemetryTrace<TypesGeneratedTraceAttributes, void>
530
+
531
+ declare interface TypesGeneratedTraceAttributes {
532
+ configMethod: 'cli' | 'legacy'
533
+ configOverloadClientMethods: boolean
534
+ emptyUnionTypeNodesGenerated: number
535
+ filesWithErrors: number
536
+ outputSize: number
537
+ queriesCount: number
538
+ queryFilesCount: number
539
+ schemaTypesCount: number
540
+ typeNodesGenerated: number
541
+ unknownTypeNodesGenerated: number
542
+ unknownTypeNodesRatio: number
543
+ }
544
+
545
+ declare type WatcherStats = Omit<
546
+ Extract<
547
+ TypegenWatchModeTraceAttributes,
548
+ {
549
+ step: 'stopped'
550
+ }
551
+ >,
552
+ 'step'
553
+ >
554
+
555
+ export {}
@@ -14,6 +14,7 @@ import { processTypegenWorkerStream } from './streamProcessor.js';
14
14
  *
15
15
  * @param options - Configuration options including typegen config and working directory
16
16
  * @returns Generation result containing the generated code and statistics
17
+ * @public
17
18
  */ export async function runTypegenGenerate(options) {
18
19
  const { config, workDir } = options;
19
20
  const { formatGeneratedCode, generates, overloadClientMethods, path, schema } = prepareConfig(config);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/actions/typegenGenerate.ts"],"sourcesContent":["import {mkdir} from 'node:fs/promises'\nimport {dirname, isAbsolute, join} from 'node:path'\nimport {env} from 'node:process'\nimport {Worker} from 'node:worker_threads'\n\nimport {WorkerChannelReceiver} from '@sanity/worker-channels'\n\nimport {prepareConfig} from '../utils/config.js'\nimport {debug} from '../utils/debug.js'\nimport {processTypegenWorkerStream} from './streamProcessor.js'\nimport {\n type GenerationResult,\n type RunTypegenOptions,\n TypegenGenerateTypesWorkerData,\n TypegenWorkerChannel,\n} from './types.js'\n\n/**\n * Runs a single typegen generation.\n *\n * This is the programmatic API for generating TypeScript types from GROQ queries.\n * It spawns a worker thread to perform the generation and displays progress via CLI spinners.\n *\n * @param options - Configuration options including typegen config and working directory\n * @returns Generation result containing the generated code and statistics\n */\nexport async function runTypegenGenerate(options: RunTypegenOptions): Promise<GenerationResult> {\n const {config, workDir} = options\n\n const {formatGeneratedCode, generates, overloadClientMethods, path, schema} =\n prepareConfig(config)\n\n const outputPath = isAbsolute(generates) ? generates : join(workDir, generates)\n\n // create output dir if it isn't there\n const outputDir = dirname(outputPath)\n await mkdir(outputDir, {recursive: true})\n\n // set up worker\n const workerPath = new URL('../actions/typegenGenerate.worker.js', import.meta.url)\n const workerData: TypegenGenerateTypesWorkerData = {\n overloadClientMethods,\n schemaPath: schema,\n searchPath: path,\n workDir,\n }\n const worker = new Worker(workerPath, {env, workerData})\n\n try {\n const result = await processTypegenWorkerStream(\n WorkerChannelReceiver.from<TypegenWorkerChannel>(worker),\n {\n formatGeneratedCode,\n generates: outputPath,\n overloadClientMethods,\n path,\n schema,\n },\n )\n\n return result\n } catch (err) {\n debug('error generating types', err)\n throw err\n } finally {\n worker.terminate()\n }\n}\n"],"names":["mkdir","dirname","isAbsolute","join","env","Worker","WorkerChannelReceiver","prepareConfig","debug","processTypegenWorkerStream","runTypegenGenerate","options","config","workDir","formatGeneratedCode","generates","overloadClientMethods","path","schema","outputPath","outputDir","recursive","workerPath","URL","url","workerData","schemaPath","searchPath","worker","result","from","err","terminate"],"mappings":"AAAA,SAAQA,KAAK,QAAO,mBAAkB;AACtC,SAAQC,OAAO,EAAEC,UAAU,EAAEC,IAAI,QAAO,YAAW;AACnD,SAAQC,GAAG,QAAO,eAAc;AAChC,SAAQC,MAAM,QAAO,sBAAqB;AAE1C,SAAQC,qBAAqB,QAAO,0BAAyB;AAE7D,SAAQC,aAAa,QAAO,qBAAoB;AAChD,SAAQC,KAAK,QAAO,oBAAmB;AACvC,SAAQC,0BAA0B,QAAO,uBAAsB;AAQ/D;;;;;;;;CAQC,GACD,OAAO,eAAeC,mBAAmBC,OAA0B;IACjE,MAAM,EAACC,MAAM,EAAEC,OAAO,EAAC,GAAGF;IAE1B,MAAM,EAACG,mBAAmB,EAAEC,SAAS,EAAEC,qBAAqB,EAAEC,IAAI,EAAEC,MAAM,EAAC,GACzEX,cAAcK;IAEhB,MAAMO,aAAajB,WAAWa,aAAaA,YAAYZ,KAAKU,SAASE;IAErE,sCAAsC;IACtC,MAAMK,YAAYnB,QAAQkB;IAC1B,MAAMnB,MAAMoB,WAAW;QAACC,WAAW;IAAI;IAEvC,gBAAgB;IAChB,MAAMC,aAAa,IAAIC,IAAI,wCAAwC,YAAYC,GAAG;IAClF,MAAMC,aAA6C;QACjDT;QACAU,YAAYR;QACZS,YAAYV;QACZJ;IACF;IACA,MAAMe,SAAS,IAAIvB,OAAOiB,YAAY;QAAClB;QAAKqB;IAAU;IAEtD,IAAI;QACF,MAAMI,SAAS,MAAMpB,2BACnBH,sBAAsBwB,IAAI,CAAuBF,SACjD;YACEd;YACAC,WAAWI;YACXH;YACAC;YACAC;QACF;QAGF,OAAOW;IACT,EAAE,OAAOE,KAAK;QACZvB,MAAM,0BAA0BuB;QAChC,MAAMA;IACR,SAAU;QACRH,OAAOI,SAAS;IAClB;AACF"}
1
+ {"version":3,"sources":["../../src/actions/typegenGenerate.ts"],"sourcesContent":["import {mkdir} from 'node:fs/promises'\nimport {dirname, isAbsolute, join} from 'node:path'\nimport {env} from 'node:process'\nimport {Worker} from 'node:worker_threads'\n\nimport {WorkerChannelReceiver} from '@sanity/worker-channels'\n\nimport {prepareConfig} from '../utils/config.js'\nimport {debug} from '../utils/debug.js'\nimport {processTypegenWorkerStream} from './streamProcessor.js'\nimport {\n type GenerationResult,\n type RunTypegenOptions,\n TypegenGenerateTypesWorkerData,\n TypegenWorkerChannel,\n} from './types.js'\n\n/**\n * Runs a single typegen generation.\n *\n * This is the programmatic API for generating TypeScript types from GROQ queries.\n * It spawns a worker thread to perform the generation and displays progress via CLI spinners.\n *\n * @param options - Configuration options including typegen config and working directory\n * @returns Generation result containing the generated code and statistics\n * @public\n */\nexport async function runTypegenGenerate(options: RunTypegenOptions): Promise<GenerationResult> {\n const {config, workDir} = options\n\n const {formatGeneratedCode, generates, overloadClientMethods, path, schema} =\n prepareConfig(config)\n\n const outputPath = isAbsolute(generates) ? generates : join(workDir, generates)\n\n // create output dir if it isn't there\n const outputDir = dirname(outputPath)\n await mkdir(outputDir, {recursive: true})\n\n // set up worker\n const workerPath = new URL('../actions/typegenGenerate.worker.js', import.meta.url)\n const workerData: TypegenGenerateTypesWorkerData = {\n overloadClientMethods,\n schemaPath: schema,\n searchPath: path,\n workDir,\n }\n const worker = new Worker(workerPath, {env, workerData})\n\n try {\n const result = await processTypegenWorkerStream(\n WorkerChannelReceiver.from<TypegenWorkerChannel>(worker),\n {\n formatGeneratedCode,\n generates: outputPath,\n overloadClientMethods,\n path,\n schema,\n },\n )\n\n return result\n } catch (err) {\n debug('error generating types', err)\n throw err\n } finally {\n worker.terminate()\n }\n}\n"],"names":["mkdir","dirname","isAbsolute","join","env","Worker","WorkerChannelReceiver","prepareConfig","debug","processTypegenWorkerStream","runTypegenGenerate","options","config","workDir","formatGeneratedCode","generates","overloadClientMethods","path","schema","outputPath","outputDir","recursive","workerPath","URL","url","workerData","schemaPath","searchPath","worker","result","from","err","terminate"],"mappings":"AAAA,SAAQA,KAAK,QAAO,mBAAkB;AACtC,SAAQC,OAAO,EAAEC,UAAU,EAAEC,IAAI,QAAO,YAAW;AACnD,SAAQC,GAAG,QAAO,eAAc;AAChC,SAAQC,MAAM,QAAO,sBAAqB;AAE1C,SAAQC,qBAAqB,QAAO,0BAAyB;AAE7D,SAAQC,aAAa,QAAO,qBAAoB;AAChD,SAAQC,KAAK,QAAO,oBAAmB;AACvC,SAAQC,0BAA0B,QAAO,uBAAsB;AAQ/D;;;;;;;;;CASC,GACD,OAAO,eAAeC,mBAAmBC,OAA0B;IACjE,MAAM,EAACC,MAAM,EAAEC,OAAO,EAAC,GAAGF;IAE1B,MAAM,EAACG,mBAAmB,EAAEC,SAAS,EAAEC,qBAAqB,EAAEC,IAAI,EAAEC,MAAM,EAAC,GACzEX,cAAcK;IAEhB,MAAMO,aAAajB,WAAWa,aAAaA,YAAYZ,KAAKU,SAASE;IAErE,sCAAsC;IACtC,MAAMK,YAAYnB,QAAQkB;IAC1B,MAAMnB,MAAMoB,WAAW;QAACC,WAAW;IAAI;IAEvC,gBAAgB;IAChB,MAAMC,aAAa,IAAIC,IAAI,wCAAwC,YAAYC,GAAG;IAClF,MAAMC,aAA6C;QACjDT;QACAU,YAAYR;QACZS,YAAYV;QACZJ;IACF;IACA,MAAMe,SAAS,IAAIvB,OAAOiB,YAAY;QAAClB;QAAKqB;IAAU;IAEtD,IAAI;QACF,MAAMI,SAAS,MAAMpB,2BACnBH,sBAAsBwB,IAAI,CAAuBF,SACjD;YACEd;YACAC,WAAWI;YACXH;YACAC;YACAC;QACF;QAGF,OAAOW;IACT,EAAE,OAAOE,KAAK;QACZvB,MAAM,0BAA0BuB;QAChC,MAAMA;IACR,SAAU;QACRH,OAAOI,SAAS;IAClB;AACF"}
@@ -2,7 +2,8 @@ import { error, log } from 'node:console';
2
2
  import { isAbsolute, join, relative } from 'node:path';
3
3
  import { styleText } from 'node:util';
4
4
  import chokidar from 'chokidar';
5
- import { debounce, mean } from 'lodash-es';
5
+ import debounce from 'lodash-es/debounce.js';
6
+ import mean from 'lodash-es/mean.js';
6
7
  import { prepareConfig } from '../utils/config.js';
7
8
  import { runTypegenGenerate } from './typegenGenerate.js';
8
9
  const IGNORED_PATTERNS = [
@@ -48,6 +49,7 @@ const IGNORED_PATTERNS = [
48
49
  * Starts a file watcher that triggers typegen on changes.
49
50
  * Watches both query files (via patterns) and the schema JSON file.
50
51
  * Implements debouncing and concurrency control to prevent multiple generations.
52
+ * @public
51
53
  */ export function runTypegenWatcher(options) {
52
54
  const { config, workDir } = options;
53
55
  const { path, schema } = prepareConfig(config);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/actions/typegenWatch.ts"],"sourcesContent":["import {error, log} from 'node:console'\nimport {isAbsolute, join, relative} from 'node:path'\nimport {styleText} from 'node:util'\n\nimport chokidar, {FSWatcher} from 'chokidar'\nimport {debounce, mean} from 'lodash-es'\n\nimport {TypegenWatchModeTraceAttributes} from '../typegen.telemetry.js'\nimport {prepareConfig} from '../utils/config.js'\nimport {runTypegenGenerate} from './typegenGenerate.js'\nimport {type RunTypegenOptions} from './types.js'\n\nconst IGNORED_PATTERNS = [\n '**/node_modules/**',\n '**/.git/**',\n '**/dist/**',\n '**/lib/**',\n '**/.sanity/**',\n]\n\n/** State for tracking generation status */\ninterface WatchState {\n isGenerating: boolean\n pendingGeneration: boolean\n}\n\n/** Return type for createTypegenRunner */\ninterface TypegenRunner {\n runGeneration: () => Promise<void>\n state: WatchState\n}\n\ntype WatcherStats = Omit<Extract<TypegenWatchModeTraceAttributes, {step: 'stopped'}>, 'step'>\n\n/**\n * Creates a typegen runner with concurrency control.\n * If generation is already running, queues one more generation to run after completion.\n * Multiple queued requests are coalesced into a single pending generation.\n */\nfunction createTypegenRunner(onGenerate: () => Promise<unknown>): TypegenRunner {\n const state: WatchState = {\n isGenerating: false,\n pendingGeneration: false,\n }\n\n async function runGeneration(): Promise<void> {\n if (state.isGenerating) {\n state.pendingGeneration = true\n return\n }\n\n state.isGenerating = true\n state.pendingGeneration = false\n\n try {\n await onGenerate()\n } finally {\n state.isGenerating = false\n\n // If a change came in during generation, run again\n if (state.pendingGeneration) {\n state.pendingGeneration = false\n await runGeneration()\n }\n }\n }\n\n return {runGeneration, state}\n}\n\n/**\n * Starts a file watcher that triggers typegen on changes.\n * Watches both query files (via patterns) and the schema JSON file.\n * Implements debouncing and concurrency control to prevent multiple generations.\n */\nexport function runTypegenWatcher(options: RunTypegenOptions): {\n getStats: () => WatcherStats\n stop: () => Promise<void>\n watcher: FSWatcher\n} {\n const {config, workDir} = options\n const {path, schema} = prepareConfig(config)\n\n const stats = {\n failedCount: 0,\n startTime: Date.now(),\n successfulDurations: [] as number[],\n }\n\n const {runGeneration} = createTypegenRunner(async () => {\n try {\n const {duration} = await runTypegenGenerate({...options})\n stats.successfulDurations.push(duration)\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : err\n error(` ${styleText('red', '›')} ${errorMessage}`)\n stats.failedCount++\n }\n })\n\n // Debounced generation trigger\n const debouncedGenerate = debounce(runGeneration, 1000)\n\n // Build absolute patterns for query files and schema file\n const paths = Array.isArray(path) ? path : [path]\n const absoluteQueryPatterns = paths.map((pattern) =>\n isAbsolute(pattern) ? pattern : join(workDir, pattern),\n )\n const absoluteSchemaPath = isAbsolute(schema) ? schema : join(workDir, schema)\n const watchTargets = [...absoluteQueryPatterns, absoluteSchemaPath]\n\n // perform initial generation\n debouncedGenerate()\n\n // set up watcher\n const watcher = chokidar.watch(watchTargets, {\n cwd: workDir,\n ignored: IGNORED_PATTERNS,\n ignoreInitial: true,\n })\n\n watcher.on('all', (event: string, filePath: string) => {\n const timestamp = new Date().toLocaleTimeString()\n const relativePath = isAbsolute(filePath) ? relative(workDir, filePath) : filePath\n log(`[${timestamp}] ${event}: ${relativePath}`)\n debouncedGenerate()\n })\n\n watcher.on('error', (err: Error) => {\n error(`Watcher error: ${err.message}`)\n })\n\n return {\n getStats: () => ({\n averageGenerationDuration: mean(stats.successfulDurations) || 0,\n generationFailedCount: stats.failedCount,\n generationSuccessfulCount: stats.successfulDurations.length,\n watcherDuration: Date.now() - stats.startTime,\n }),\n stop: async () => {\n await watcher.close()\n },\n watcher,\n }\n}\n"],"names":["error","log","isAbsolute","join","relative","styleText","chokidar","debounce","mean","prepareConfig","runTypegenGenerate","IGNORED_PATTERNS","createTypegenRunner","onGenerate","state","isGenerating","pendingGeneration","runGeneration","runTypegenWatcher","options","config","workDir","path","schema","stats","failedCount","startTime","Date","now","successfulDurations","duration","push","err","errorMessage","Error","message","debouncedGenerate","paths","Array","isArray","absoluteQueryPatterns","map","pattern","absoluteSchemaPath","watchTargets","watcher","watch","cwd","ignored","ignoreInitial","on","event","filePath","timestamp","toLocaleTimeString","relativePath","getStats","averageGenerationDuration","generationFailedCount","generationSuccessfulCount","length","watcherDuration","stop","close"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/actions/typegenWatch.ts"],"sourcesContent":["import {error, log} from 'node:console'\nimport {isAbsolute, join, relative} from 'node:path'\nimport {styleText} from 'node:util'\n\nimport chokidar, {FSWatcher} from 'chokidar'\nimport debounce from 'lodash-es/debounce.js'\nimport mean from 'lodash-es/mean.js'\n\nimport {TypegenWatchModeTraceAttributes} from '../typegen.telemetry.js'\nimport {prepareConfig} from '../utils/config.js'\nimport {runTypegenGenerate} from './typegenGenerate.js'\nimport {type RunTypegenOptions} from './types.js'\n\nconst IGNORED_PATTERNS = [\n '**/node_modules/**',\n '**/.git/**',\n '**/dist/**',\n '**/lib/**',\n '**/.sanity/**',\n]\n\n/** State for tracking generation status */\ninterface WatchState {\n isGenerating: boolean\n pendingGeneration: boolean\n}\n\n/** Return type for createTypegenRunner */\ninterface TypegenRunner {\n runGeneration: () => Promise<void>\n state: WatchState\n}\n\ntype WatcherStats = Omit<Extract<TypegenWatchModeTraceAttributes, {step: 'stopped'}>, 'step'>\n\n/**\n * Creates a typegen runner with concurrency control.\n * If generation is already running, queues one more generation to run after completion.\n * Multiple queued requests are coalesced into a single pending generation.\n */\nfunction createTypegenRunner(onGenerate: () => Promise<unknown>): TypegenRunner {\n const state: WatchState = {\n isGenerating: false,\n pendingGeneration: false,\n }\n\n async function runGeneration(): Promise<void> {\n if (state.isGenerating) {\n state.pendingGeneration = true\n return\n }\n\n state.isGenerating = true\n state.pendingGeneration = false\n\n try {\n await onGenerate()\n } finally {\n state.isGenerating = false\n\n // If a change came in during generation, run again\n if (state.pendingGeneration) {\n state.pendingGeneration = false\n await runGeneration()\n }\n }\n }\n\n return {runGeneration, state}\n}\n\n/**\n * Starts a file watcher that triggers typegen on changes.\n * Watches both query files (via patterns) and the schema JSON file.\n * Implements debouncing and concurrency control to prevent multiple generations.\n * @public\n */\nexport function runTypegenWatcher(options: RunTypegenOptions): {\n getStats: () => WatcherStats\n stop: () => Promise<void>\n watcher: FSWatcher\n} {\n const {config, workDir} = options\n const {path, schema} = prepareConfig(config)\n\n const stats = {\n failedCount: 0,\n startTime: Date.now(),\n successfulDurations: [] as number[],\n }\n\n const {runGeneration} = createTypegenRunner(async () => {\n try {\n const {duration} = await runTypegenGenerate({...options})\n stats.successfulDurations.push(duration)\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : err\n error(` ${styleText('red', '›')} ${errorMessage}`)\n stats.failedCount++\n }\n })\n\n // Debounced generation trigger\n const debouncedGenerate = debounce(runGeneration, 1000)\n\n // Build absolute patterns for query files and schema file\n const paths = Array.isArray(path) ? path : [path]\n const absoluteQueryPatterns = paths.map((pattern) =>\n isAbsolute(pattern) ? pattern : join(workDir, pattern),\n )\n const absoluteSchemaPath = isAbsolute(schema) ? schema : join(workDir, schema)\n const watchTargets = [...absoluteQueryPatterns, absoluteSchemaPath]\n\n // perform initial generation\n debouncedGenerate()\n\n // set up watcher\n const watcher = chokidar.watch(watchTargets, {\n cwd: workDir,\n ignored: IGNORED_PATTERNS,\n ignoreInitial: true,\n })\n\n watcher.on('all', (event: string, filePath: string) => {\n const timestamp = new Date().toLocaleTimeString()\n const relativePath = isAbsolute(filePath) ? relative(workDir, filePath) : filePath\n log(`[${timestamp}] ${event}: ${relativePath}`)\n debouncedGenerate()\n })\n\n watcher.on('error', (err: Error) => {\n error(`Watcher error: ${err.message}`)\n })\n\n return {\n getStats: () => ({\n averageGenerationDuration: mean(stats.successfulDurations) || 0,\n generationFailedCount: stats.failedCount,\n generationSuccessfulCount: stats.successfulDurations.length,\n watcherDuration: Date.now() - stats.startTime,\n }),\n stop: async () => {\n await watcher.close()\n },\n watcher,\n }\n}\n"],"names":["error","log","isAbsolute","join","relative","styleText","chokidar","debounce","mean","prepareConfig","runTypegenGenerate","IGNORED_PATTERNS","createTypegenRunner","onGenerate","state","isGenerating","pendingGeneration","runGeneration","runTypegenWatcher","options","config","workDir","path","schema","stats","failedCount","startTime","Date","now","successfulDurations","duration","push","err","errorMessage","Error","message","debouncedGenerate","paths","Array","isArray","absoluteQueryPatterns","map","pattern","absoluteSchemaPath","watchTargets","watcher","watch","cwd","ignored","ignoreInitial","on","event","filePath","timestamp","toLocaleTimeString","relativePath","getStats","averageGenerationDuration","generationFailedCount","generationSuccessfulCount","length","watcherDuration","stop","close"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Result from a single generation run.
3
- * @internal
3
+ * @public
4
4
  */ export { };
5
5
 
6
6
  //# sourceMappingURL=types.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/actions/types.ts"],"sourcesContent":["import {spinner} from '@sanity/cli-core/ux'\nimport {WorkerChannel} from '@sanity/worker-channels'\n\nimport {TypeGenConfig} from '../readConfig.js'\nimport {type TypegenWorkerChannel as CodegenTypegenWorkerChannel} from '../typescript/typeGenerator.js'\n\n/**\n * Data passed to the typegen worker thread.\n * @internal\n */\nexport interface TypegenGenerateTypesWorkerData {\n /** Path to the schema JSON file */\n schemaPath: string\n /** Glob pattern(s) for finding query files */\n searchPath: string | string[]\n /** Working directory (project root) */\n workDir: string\n\n /** Whether to generate client method overloads */\n overloadClientMethods?: boolean\n}\n\n/**\n * Worker channel definition for typegen worker communication.\n * Extends the base TypegenWorkerChannel with additional events for progress tracking.\n * @internal\n */\nexport type TypegenWorkerChannel = WorkerChannel.Definition<\n CodegenTypegenWorkerChannel['__definition'] & {\n loadedSchema: WorkerChannel.Event\n typegenComplete: WorkerChannel.Event<{code: string}>\n typegenStarted: WorkerChannel.Event<{expectedFileCount: number}>\n }\n>\n\n/**\n * Options for running a single typegen generation.\n * This is the programmatic API for one-off generation without file watching.\n */\nexport interface RunTypegenOptions {\n /** Working directory (usually project root) */\n workDir: string\n\n /** Typegen configuration */\n config?: Partial<TypeGenConfig>\n\n /** Optional spinner instance for progress display */\n spin?: ReturnType<typeof spinner>\n}\n\n/**\n * Result from a single generation run.\n * @internal\n */\nexport interface GenerationResult {\n code: string\n duration: number\n emptyUnionTypeNodesGenerated: number\n filesWithErrors: number\n outputSize: number\n queriesCount: number\n queryFilesCount: number\n schemaTypesCount: number\n typeNodesGenerated: number\n unknownTypeNodesGenerated: number\n unknownTypeNodesRatio: number\n}\n"],"names":[],"mappings":"AAkDA;;;CAGC,GACD,WAYC"}
1
+ {"version":3,"sources":["../../src/actions/types.ts"],"sourcesContent":["import {spinner} from '@sanity/cli-core/ux'\nimport {WorkerChannel} from '@sanity/worker-channels'\n\nimport {TypeGenConfig} from '../readConfig.js'\nimport {type TypegenWorkerChannel as CodegenTypegenWorkerChannel} from '../typescript/typeGenerator.js'\n\n/**\n * Data passed to the typegen worker thread.\n * @internal\n */\nexport interface TypegenGenerateTypesWorkerData {\n /** Path to the schema JSON file */\n schemaPath: string\n /** Glob pattern(s) for finding query files */\n searchPath: string | string[]\n /** Working directory (project root) */\n workDir: string\n\n /** Whether to generate client method overloads */\n overloadClientMethods?: boolean\n}\n\n/**\n * Worker channel definition for typegen worker communication.\n * Extends the base TypegenWorkerChannel with additional events for progress tracking.\n * @internal\n */\nexport type TypegenWorkerChannel = WorkerChannel.Definition<\n CodegenTypegenWorkerChannel['__definition'] & {\n loadedSchema: WorkerChannel.Event\n typegenComplete: WorkerChannel.Event<{code: string}>\n typegenStarted: WorkerChannel.Event<{expectedFileCount: number}>\n }\n>\n\n/**\n * Options for running a single typegen generation.\n * This is the programmatic API for one-off generation without file watching.\n * @public\n */\nexport interface RunTypegenOptions {\n /** Working directory (usually project root) */\n workDir: string\n\n /** Typegen configuration */\n config?: Partial<TypeGenConfig>\n\n /** Optional spinner instance for progress display */\n spin?: ReturnType<typeof spinner>\n}\n\n/**\n * Result from a single generation run.\n * @public\n */\nexport interface GenerationResult {\n code: string\n duration: number\n emptyUnionTypeNodesGenerated: number\n filesWithErrors: number\n outputSize: number\n queriesCount: number\n queryFilesCount: number\n schemaTypesCount: number\n typeNodesGenerated: number\n unknownTypeNodesGenerated: number\n unknownTypeNodesRatio: number\n}\n"],"names":[],"mappings":"AAmDA;;;CAGC,GACD,WAYC"}
@@ -3,7 +3,8 @@ import { styleText } from 'node:util';
3
3
  import { Flags } from '@oclif/core';
4
4
  import { SanityCommand } from '@sanity/cli-core';
5
5
  import { spinner } from '@sanity/cli-core/ux';
6
- import { omit, once } from 'lodash-es';
6
+ import omit from 'lodash-es/omit.js';
7
+ import once from 'lodash-es/once.js';
7
8
  import { runTypegenGenerate } from '../../actions/typegenGenerate.js';
8
9
  import { runTypegenWatcher } from '../../actions/typegenWatch.js';
9
10
  import { configDefinition, readConfig } from '../../readConfig.js';