@sanity/codegen 6.0.3 → 6.1.1

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.
@@ -24,7 +24,17 @@ export declare type CodegenConfig = TypeGenConfig
24
24
  */
25
25
  export declare const configDefinition: z.ZodObject<
26
26
  {
27
- formatGeneratedCode: z.ZodDefault<z.ZodBoolean>
27
+ formatGeneratedCode: z.ZodDefault<
28
+ z.ZodUnion<
29
+ readonly [
30
+ z.ZodBoolean,
31
+ z.ZodEnum<{
32
+ oxfmt: 'oxfmt'
33
+ prettier: 'prettier'
34
+ }>,
35
+ ]
36
+ >
37
+ >
28
38
  generates: z.ZodDefault<z.ZodString>
29
39
  overloadClientMethods: z.ZodDefault<z.ZodBoolean>
30
40
  path: z.ZodDefault<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString>]>>
@@ -1,11 +1,11 @@
1
1
  import { writeFile } from 'node:fs/promises';
2
2
  import { spinner } from '@sanity/cli-core/ux';
3
- import { format, resolveConfig as resolvePrettierConfig } from 'prettier';
4
3
  import { count } from '../utils/count.js';
5
4
  import { debug } from '../utils/debug.js';
6
5
  import { formatPath } from '../utils/formatPath.js';
7
6
  import { getMessage } from '../utils/getMessage.js';
8
7
  import { percent } from '../utils/percent.js';
8
+ import { defineFormatter } from '../utils/resolveFormatter.js';
9
9
  import { generatedFileWarning } from './generatedFileWarning.js';
10
10
  /**
11
11
  * Processes the event stream from a typegen worker thread.
@@ -57,18 +57,22 @@ import { generatedFileWarning } from './generatedFileWarning.js';
57
57
  const code = `${generatedFileWarning}${result.code}`;
58
58
  await writeFile(generates, code);
59
59
  let formattingError = false;
60
- if (formatGeneratedCode) {
61
- spin.text = `Formatting generated types with prettier…`;
62
- try {
63
- const prettierConfig = await resolvePrettierConfig(generates);
64
- const formattedCode = await format(code, {
65
- ...prettierConfig,
66
- parser: 'typescript'
67
- });
68
- await writeFile(generates, formattedCode);
69
- } catch (err) {
70
- formattingError = true;
71
- spin.warn(`Failed to format generated types with prettier: ${getMessage(err)}`);
60
+ let formatterName;
61
+ if (formatGeneratedCode !== false) {
62
+ const formatter = defineFormatter(formatGeneratedCode);
63
+ if (formatter) {
64
+ formatterName = formatter.name;
65
+ try {
66
+ const { format } = await formatter.resolve();
67
+ if (format) {
68
+ spin.text = `Formatting generated types with ${formatter.name}…`;
69
+ const formattedCode = await format(generates, code);
70
+ await writeFile(generates, formattedCode);
71
+ }
72
+ } catch (err) {
73
+ formattingError = true;
74
+ spin.warn(`Failed to format generated types with ${formatter.name}: ${getMessage(err)}`);
75
+ }
72
76
  }
73
77
  }
74
78
  if (filesWithErrors > 0) {
@@ -87,8 +91,8 @@ import { generatedFileWarning } from './generatedFileWarning.js';
87
91
  unknownTypeNodesRatio: typeNodesGenerated > 0 ? unknownTypeNodesGenerated / typeNodesGenerated : 0
88
92
  };
89
93
  let successText = `Successfully generated types to ${formatPath(generates)} in ${Number(stats.duration).toFixed(0)}ms` + `\n └─ ${count(queriesCount, 'queries', 'query')} and ${count(schemaTypesCount, 'schema types', 'schema type')}` + `\n └─ found queries in ${count(queryFilesCount, 'files', 'file')} after evaluating ${count(evaluatedFiles, 'files', 'file')}`;
90
- if (formatGeneratedCode) {
91
- successText += `\n └─ ${formattingError ? 'an error occured during formatting' : 'formatted the generated code with prettier'}`;
94
+ if (formatterName) {
95
+ successText += `\n └─ ${formattingError ? 'an error occurred during formatting' : `formatted the generated code with ${formatterName}`}`;
92
96
  }
93
97
  spin.succeed(successText);
94
98
  return {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/actions/streamProcessor.ts"],"sourcesContent":["import {writeFile} from 'node:fs/promises'\n\nimport {spinner} from '@sanity/cli-core/ux'\nimport {WorkerChannelReceiver} from '@sanity/worker-channels'\nimport {format, resolveConfig as resolvePrettierConfig} from 'prettier'\n\nimport {TypeGenConfig} from '../readConfig.js'\nimport {count} from '../utils/count.js'\nimport {debug} from '../utils/debug.js'\nimport {formatPath} from '../utils/formatPath.js'\nimport {getMessage} from '../utils/getMessage.js'\nimport {percent} from '../utils/percent.js'\nimport {generatedFileWarning} from './generatedFileWarning.js'\nimport {TypegenWorkerChannel} from './types.js'\n\n/**\n * Processes the event stream from a typegen worker thread.\n *\n * Listens to worker channel events, displays progress via CLI spinners,\n * writes the generated types to disk, and optionally formats with prettier.\n *\n * @param receiver - Worker channel receiver for typegen events\n * @param options - Typegen configuration options\n * @returns Generation result containing the generated code and statistics\n */\nexport async function processTypegenWorkerStream(\n receiver: WorkerChannelReceiver<TypegenWorkerChannel>,\n options: TypeGenConfig,\n) {\n const start = Date.now()\n const {formatGeneratedCode, generates, schema} = options\n\n const spin = spinner().start(`Loading schema…`)\n\n try {\n await receiver.event.loadedSchema()\n spin.succeed(`Schema loaded from ${formatPath(schema ?? '')}`)\n\n spin.start('Generating schema types…')\n const {expectedFileCount} = await receiver.event.typegenStarted()\n const {schemaTypeDeclarations} = await receiver.event.generatedSchemaTypes()\n const schemaTypesCount = schemaTypeDeclarations.length\n\n spin.text = 'Generating query types…'\n\n let queriesCount = 0\n let evaluatedFiles = 0\n let filesWithErrors = 0\n let queryFilesCount = 0\n let typeNodesGenerated = 0\n let unknownTypeNodesGenerated = 0\n let emptyUnionTypeNodesGenerated = 0\n\n for await (const {errors, queries} of receiver.stream.evaluatedModules()) {\n evaluatedFiles++\n queriesCount += queries.length\n queryFilesCount += queries.length > 0 ? 1 : 0\n filesWithErrors += errors.length > 0 ? 1 : 0\n\n for (const {stats} of queries) {\n typeNodesGenerated += stats.allTypes\n unknownTypeNodesGenerated += stats.unknownTypes\n emptyUnionTypeNodesGenerated += stats.emptyUnions\n }\n\n for (const error of errors) {\n spin.fail(getMessage(error))\n }\n\n if (!spin.isSpinning) {\n spin.start()\n }\n\n spin.text =\n `Generating query types… (${percent(evaluatedFiles / expectedFileCount)})\\n` +\n ` └─ Processed ${count(evaluatedFiles)} of ${count(expectedFileCount, 'files')}. ` +\n `Found ${count(queriesCount, 'queries', 'query')} from ${count(queryFilesCount, 'files')}.`\n }\n\n const result = await receiver.event.typegenComplete()\n const code = `${generatedFileWarning}${result.code}`\n await writeFile(generates, code)\n\n let formattingError = false\n if (formatGeneratedCode) {\n spin.text = `Formatting generated types with prettier…`\n\n try {\n const prettierConfig = await resolvePrettierConfig(generates)\n const formattedCode = await format(code, {\n ...prettierConfig,\n parser: 'typescript' as const,\n })\n await writeFile(generates, formattedCode)\n } catch (err) {\n formattingError = true\n spin.warn(`Failed to format generated types with prettier: ${getMessage(err)}`)\n }\n }\n\n if (filesWithErrors > 0) {\n spin.warn(`Encountered errors in ${count(filesWithErrors, 'files')} while generating types`)\n }\n\n const stats = {\n duration: Date.now() - start,\n emptyUnionTypeNodesGenerated,\n filesWithErrors,\n outputSize: Buffer.byteLength(code),\n queriesCount,\n queryFilesCount,\n schemaTypesCount,\n typeNodesGenerated,\n unknownTypeNodesGenerated,\n unknownTypeNodesRatio:\n typeNodesGenerated > 0 ? unknownTypeNodesGenerated / typeNodesGenerated : 0,\n }\n\n let successText =\n `Successfully generated types to ${formatPath(generates)} in ${Number(stats.duration).toFixed(0)}ms` +\n `\\n └─ ${count(queriesCount, 'queries', 'query')} and ${count(schemaTypesCount, 'schema types', 'schema type')}` +\n `\\n └─ found queries in ${count(queryFilesCount, 'files', 'file')} after evaluating ${count(evaluatedFiles, 'files', 'file')}`\n\n if (formatGeneratedCode) {\n successText += `\\n └─ ${formattingError ? 'an error occured during formatting' : 'formatted the generated code with prettier'}`\n }\n\n spin.succeed(successText)\n\n return {\n ...stats,\n code,\n }\n } catch (err) {\n spin.fail()\n debug('error generating types', err)\n throw err\n } finally {\n receiver.unsubscribe()\n }\n}\n"],"names":["writeFile","spinner","format","resolveConfig","resolvePrettierConfig","count","debug","formatPath","getMessage","percent","generatedFileWarning","processTypegenWorkerStream","receiver","options","start","Date","now","formatGeneratedCode","generates","schema","spin","event","loadedSchema","succeed","expectedFileCount","typegenStarted","schemaTypeDeclarations","generatedSchemaTypes","schemaTypesCount","length","text","queriesCount","evaluatedFiles","filesWithErrors","queryFilesCount","typeNodesGenerated","unknownTypeNodesGenerated","emptyUnionTypeNodesGenerated","errors","queries","stream","evaluatedModules","stats","allTypes","unknownTypes","emptyUnions","error","fail","isSpinning","result","typegenComplete","code","formattingError","prettierConfig","formattedCode","parser","err","warn","duration","outputSize","Buffer","byteLength","unknownTypeNodesRatio","successText","Number","toFixed","unsubscribe"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/actions/streamProcessor.ts"],"sourcesContent":["import {writeFile} from 'node:fs/promises'\n\nimport {spinner} from '@sanity/cli-core/ux'\nimport {WorkerChannelReceiver} from '@sanity/worker-channels'\n\nimport {TypeGenConfig} from '../readConfig.js'\nimport {count} from '../utils/count.js'\nimport {debug} from '../utils/debug.js'\nimport {formatPath} from '../utils/formatPath.js'\nimport {getMessage} from '../utils/getMessage.js'\nimport {percent} from '../utils/percent.js'\nimport {defineFormatter} from '../utils/resolveFormatter.js'\nimport {generatedFileWarning} from './generatedFileWarning.js'\nimport {TypegenWorkerChannel} from './types.js'\n\n/**\n * Processes the event stream from a typegen worker thread.\n *\n * Listens to worker channel events, displays progress via CLI spinners,\n * writes the generated types to disk, and optionally formats with prettier.\n *\n * @param receiver - Worker channel receiver for typegen events\n * @param options - Typegen configuration options\n * @returns Generation result containing the generated code and statistics\n */\nexport async function processTypegenWorkerStream(\n receiver: WorkerChannelReceiver<TypegenWorkerChannel>,\n options: TypeGenConfig,\n) {\n const start = Date.now()\n const {formatGeneratedCode, generates, schema} = options\n\n const spin = spinner().start(`Loading schema…`)\n\n try {\n await receiver.event.loadedSchema()\n spin.succeed(`Schema loaded from ${formatPath(schema ?? '')}`)\n\n spin.start('Generating schema types…')\n const {expectedFileCount} = await receiver.event.typegenStarted()\n const {schemaTypeDeclarations} = await receiver.event.generatedSchemaTypes()\n const schemaTypesCount = schemaTypeDeclarations.length\n\n spin.text = 'Generating query types…'\n\n let queriesCount = 0\n let evaluatedFiles = 0\n let filesWithErrors = 0\n let queryFilesCount = 0\n let typeNodesGenerated = 0\n let unknownTypeNodesGenerated = 0\n let emptyUnionTypeNodesGenerated = 0\n\n for await (const {errors, queries} of receiver.stream.evaluatedModules()) {\n evaluatedFiles++\n queriesCount += queries.length\n queryFilesCount += queries.length > 0 ? 1 : 0\n filesWithErrors += errors.length > 0 ? 1 : 0\n\n for (const {stats} of queries) {\n typeNodesGenerated += stats.allTypes\n unknownTypeNodesGenerated += stats.unknownTypes\n emptyUnionTypeNodesGenerated += stats.emptyUnions\n }\n\n for (const error of errors) {\n spin.fail(getMessage(error))\n }\n\n if (!spin.isSpinning) {\n spin.start()\n }\n\n spin.text =\n `Generating query types… (${percent(evaluatedFiles / expectedFileCount)})\\n` +\n ` └─ Processed ${count(evaluatedFiles)} of ${count(expectedFileCount, 'files')}. ` +\n `Found ${count(queriesCount, 'queries', 'query')} from ${count(queryFilesCount, 'files')}.`\n }\n\n const result = await receiver.event.typegenComplete()\n const code = `${generatedFileWarning}${result.code}`\n await writeFile(generates, code)\n\n let formattingError = false\n let formatterName: string | undefined\n if (formatGeneratedCode !== false) {\n const formatter = defineFormatter(formatGeneratedCode)\n if (formatter) {\n formatterName = formatter.name\n try {\n const {format} = await formatter.resolve()\n if (format) {\n spin.text = `Formatting generated types with ${formatter.name}…`\n const formattedCode = await format(generates, code)\n await writeFile(generates, formattedCode)\n }\n } catch (err) {\n formattingError = true\n spin.warn(`Failed to format generated types with ${formatter.name}: ${getMessage(err)}`)\n }\n }\n }\n\n if (filesWithErrors > 0) {\n spin.warn(`Encountered errors in ${count(filesWithErrors, 'files')} while generating types`)\n }\n\n const stats = {\n duration: Date.now() - start,\n emptyUnionTypeNodesGenerated,\n filesWithErrors,\n outputSize: Buffer.byteLength(code),\n queriesCount,\n queryFilesCount,\n schemaTypesCount,\n typeNodesGenerated,\n unknownTypeNodesGenerated,\n unknownTypeNodesRatio:\n typeNodesGenerated > 0 ? unknownTypeNodesGenerated / typeNodesGenerated : 0,\n }\n\n let successText =\n `Successfully generated types to ${formatPath(generates)} in ${Number(stats.duration).toFixed(0)}ms` +\n `\\n └─ ${count(queriesCount, 'queries', 'query')} and ${count(schemaTypesCount, 'schema types', 'schema type')}` +\n `\\n └─ found queries in ${count(queryFilesCount, 'files', 'file')} after evaluating ${count(evaluatedFiles, 'files', 'file')}`\n\n if (formatterName) {\n successText += `\\n └─ ${formattingError ? 'an error occurred during formatting' : `formatted the generated code with ${formatterName}`}`\n }\n\n spin.succeed(successText)\n\n return {\n ...stats,\n code,\n }\n } catch (err) {\n spin.fail()\n debug('error generating types', err)\n throw err\n } finally {\n receiver.unsubscribe()\n }\n}\n"],"names":["writeFile","spinner","count","debug","formatPath","getMessage","percent","defineFormatter","generatedFileWarning","processTypegenWorkerStream","receiver","options","start","Date","now","formatGeneratedCode","generates","schema","spin","event","loadedSchema","succeed","expectedFileCount","typegenStarted","schemaTypeDeclarations","generatedSchemaTypes","schemaTypesCount","length","text","queriesCount","evaluatedFiles","filesWithErrors","queryFilesCount","typeNodesGenerated","unknownTypeNodesGenerated","emptyUnionTypeNodesGenerated","errors","queries","stream","evaluatedModules","stats","allTypes","unknownTypes","emptyUnions","error","fail","isSpinning","result","typegenComplete","code","formattingError","formatterName","formatter","name","format","resolve","formattedCode","err","warn","duration","outputSize","Buffer","byteLength","unknownTypeNodesRatio","successText","Number","toFixed","unsubscribe"],"mappings":"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"}
@@ -4,7 +4,13 @@ import * as z from 'zod';
4
4
  /**
5
5
  * @public
6
6
  */ export const configDefinition = z.object({
7
- formatGeneratedCode: z.boolean().default(true),
7
+ formatGeneratedCode: z.union([
8
+ z.boolean(),
9
+ z.enum([
10
+ 'oxfmt',
11
+ 'prettier'
12
+ ])
13
+ ]).default(true),
8
14
  generates: z.string().default('./sanity.types.ts'),
9
15
  overloadClientMethods: z.boolean().default(true),
10
16
  path: z.string().or(z.array(z.string())).default([
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/readConfig.ts"],"sourcesContent":["import {readFile} from 'node:fs/promises'\n\nimport json5 from 'json5'\nimport * as z from 'zod'\n\n/**\n * @public\n */\nexport const configDefinition = z.object({\n formatGeneratedCode: z.boolean().default(true),\n generates: z.string().default('./sanity.types.ts'),\n overloadClientMethods: z.boolean().default(true),\n path: z\n .string()\n .or(z.array(z.string()))\n .default([\n './src/**/*.{ts,tsx,js,jsx,mjs,cjs,astro,vue,svelte}',\n './app/**/*.{ts,tsx,js,jsx,mjs,cjs,astro,vue,svelte}',\n './sanity/**/*.{ts,tsx,js,jsx,mjs,cjs}',\n ]),\n schema: z.string().default('./schema.json'),\n})\n\n/** @public */\nexport type TypeGenConfig = z.infer<typeof configDefinition>\n\n/**\n * @deprecated use TypeGenConfig\n * @public\n */\nexport type CodegenConfig = TypeGenConfig\n\n/**\n * Read, parse and process a config file\n * @internal\n */\nexport async function readConfig(path: string): Promise<TypeGenConfig> {\n try {\n const content = await readFile(path, 'utf8')\n const json = json5.parse(content)\n return configDefinition.parseAsync(json)\n } catch (error) {\n if (error instanceof z.ZodError) {\n throw new Error(\n `Error in config file\\n ${error.issues.map((err) => err.message).join('\\n')}`,\n {cause: error},\n )\n }\n if (typeof error === 'object' && error !== null && 'code' in error && error.code === 'ENOENT') {\n return configDefinition.parse({})\n }\n\n throw error\n }\n}\n"],"names":["readFile","json5","z","configDefinition","object","formatGeneratedCode","boolean","default","generates","string","overloadClientMethods","path","or","array","schema","readConfig","content","json","parse","parseAsync","error","ZodError","Error","issues","map","err","message","join","cause","code"],"mappings":"AAAA,SAAQA,QAAQ,QAAO,mBAAkB;AAEzC,OAAOC,WAAW,QAAO;AACzB,YAAYC,OAAO,MAAK;AAExB;;CAEC,GACD,OAAO,MAAMC,mBAAmBD,EAAEE,MAAM,CAAC;IACvCC,qBAAqBH,EAAEI,OAAO,GAAGC,OAAO,CAAC;IACzCC,WAAWN,EAAEO,MAAM,GAAGF,OAAO,CAAC;IAC9BG,uBAAuBR,EAAEI,OAAO,GAAGC,OAAO,CAAC;IAC3CI,MAAMT,EACHO,MAAM,GACNG,EAAE,CAACV,EAAEW,KAAK,CAACX,EAAEO,MAAM,KACnBF,OAAO,CAAC;QACP;QACA;QACA;KACD;IACHO,QAAQZ,EAAEO,MAAM,GAAGF,OAAO,CAAC;AAC7B,GAAE;AAWF;;;CAGC,GACD,OAAO,eAAeQ,WAAWJ,IAAY;IAC3C,IAAI;QACF,MAAMK,UAAU,MAAMhB,SAASW,MAAM;QACrC,MAAMM,OAAOhB,MAAMiB,KAAK,CAACF;QACzB,OAAOb,iBAAiBgB,UAAU,CAACF;IACrC,EAAE,OAAOG,OAAO;QACd,IAAIA,iBAAiBlB,EAAEmB,QAAQ,EAAE;YAC/B,MAAM,IAAIC,MACR,CAAC,uBAAuB,EAAEF,MAAMG,MAAM,CAACC,GAAG,CAAC,CAACC,MAAQA,IAAIC,OAAO,EAAEC,IAAI,CAAC,OAAO,EAC7E;gBAACC,OAAOR;YAAK;QAEjB;QACA,IAAI,OAAOA,UAAU,YAAYA,UAAU,QAAQ,UAAUA,SAASA,MAAMS,IAAI,KAAK,UAAU;YAC7F,OAAO1B,iBAAiBe,KAAK,CAAC,CAAC;QACjC;QAEA,MAAME;IACR;AACF"}
1
+ {"version":3,"sources":["../src/readConfig.ts"],"sourcesContent":["import {readFile} from 'node:fs/promises'\n\nimport json5 from 'json5'\nimport * as z from 'zod'\n\n/**\n * The formatter to use for generated code.\n * - `false` - Do not format generated code.\n * - `true` | `'prettier'` - Format with prettier.\n * - `'oxfmt'` - Format with oxfmt. Throws if oxfmt is not installed.\n * @public\n */\nexport type FormatGeneratedCode = 'oxfmt' | 'prettier' | boolean\n\n/**\n * @public\n */\nexport const configDefinition = z.object({\n formatGeneratedCode: z.union([z.boolean(), z.enum(['oxfmt', 'prettier'])]).default(true),\n generates: z.string().default('./sanity.types.ts'),\n overloadClientMethods: z.boolean().default(true),\n path: z\n .string()\n .or(z.array(z.string()))\n .default([\n './src/**/*.{ts,tsx,js,jsx,mjs,cjs,astro,vue,svelte}',\n './app/**/*.{ts,tsx,js,jsx,mjs,cjs,astro,vue,svelte}',\n './sanity/**/*.{ts,tsx,js,jsx,mjs,cjs}',\n ]),\n schema: z.string().default('./schema.json'),\n})\n\n/** @public */\nexport type TypeGenConfig = z.infer<typeof configDefinition>\n\n/**\n * @deprecated use TypeGenConfig\n * @public\n */\nexport type CodegenConfig = TypeGenConfig\n\n/**\n * Read, parse and process a config file\n * @internal\n */\nexport async function readConfig(path: string): Promise<TypeGenConfig> {\n try {\n const content = await readFile(path, 'utf8')\n const json = json5.parse(content)\n return configDefinition.parseAsync(json)\n } catch (error) {\n if (error instanceof z.ZodError) {\n throw new Error(\n `Error in config file\\n ${error.issues.map((err) => err.message).join('\\n')}`,\n {cause: error},\n )\n }\n if (typeof error === 'object' && error !== null && 'code' in error && error.code === 'ENOENT') {\n return configDefinition.parse({})\n }\n\n throw error\n }\n}\n"],"names":["readFile","json5","z","configDefinition","object","formatGeneratedCode","union","boolean","enum","default","generates","string","overloadClientMethods","path","or","array","schema","readConfig","content","json","parse","parseAsync","error","ZodError","Error","issues","map","err","message","join","cause","code"],"mappings":"AAAA,SAAQA,QAAQ,QAAO,mBAAkB;AAEzC,OAAOC,WAAW,QAAO;AACzB,YAAYC,OAAO,MAAK;AAWxB;;CAEC,GACD,OAAO,MAAMC,mBAAmBD,EAAEE,MAAM,CAAC;IACvCC,qBAAqBH,EAAEI,KAAK,CAAC;QAACJ,EAAEK,OAAO;QAAIL,EAAEM,IAAI,CAAC;YAAC;YAAS;SAAW;KAAE,EAAEC,OAAO,CAAC;IACnFC,WAAWR,EAAES,MAAM,GAAGF,OAAO,CAAC;IAC9BG,uBAAuBV,EAAEK,OAAO,GAAGE,OAAO,CAAC;IAC3CI,MAAMX,EACHS,MAAM,GACNG,EAAE,CAACZ,EAAEa,KAAK,CAACb,EAAES,MAAM,KACnBF,OAAO,CAAC;QACP;QACA;QACA;KACD;IACHO,QAAQd,EAAES,MAAM,GAAGF,OAAO,CAAC;AAC7B,GAAE;AAWF;;;CAGC,GACD,OAAO,eAAeQ,WAAWJ,IAAY;IAC3C,IAAI;QACF,MAAMK,UAAU,MAAMlB,SAASa,MAAM;QACrC,MAAMM,OAAOlB,MAAMmB,KAAK,CAACF;QACzB,OAAOf,iBAAiBkB,UAAU,CAACF;IACrC,EAAE,OAAOG,OAAO;QACd,IAAIA,iBAAiBpB,EAAEqB,QAAQ,EAAE;YAC/B,MAAM,IAAIC,MACR,CAAC,uBAAuB,EAAEF,MAAMG,MAAM,CAACC,GAAG,CAAC,CAACC,MAAQA,IAAIC,OAAO,EAAEC,IAAI,CAAC,OAAO,EAC7E;gBAACC,OAAOR;YAAK;QAEjB;QACA,IAAI,OAAOA,UAAU,YAAYA,UAAU,QAAQ,UAAUA,SAASA,MAAMS,IAAI,KAAK,UAAU;YAC7F,OAAO5B,iBAAiBiB,KAAK,CAAC,CAAC;QACjC;QAEA,MAAME;IACR;AACF"}
@@ -198,6 +198,15 @@ import { QueryEvaluationError } from './types.js';
198
198
  internalReferenceSymbol,
199
199
  schemaTypeDeclarations
200
200
  });
201
+ // Queries can produce `inline` type nodes that the schema-side generator
202
+ // never sees (e.g. filtering a tagged-union array down to its inline
203
+ // members). Evaluate modules before deciding whether the ArrayOf helper is
204
+ // needed, so query-only usage still triggers the declaration.
205
+ const evaluatedModules = await TypeGenerator.getEvaluatedModules({
206
+ ...options,
207
+ schemaTypeDeclarations,
208
+ schemaTypeGenerator
209
+ });
201
210
  const program = t.program([]);
202
211
  let code = '';
203
212
  program.body.push(internalReferenceSymbol.ast);
@@ -213,11 +222,6 @@ import { QueryEvaluationError } from './types.js';
213
222
  }
214
223
  program.body.push(allSanitySchemaTypesDeclaration.ast);
215
224
  code += allSanitySchemaTypesDeclaration.code;
216
- const evaluatedModules = await TypeGenerator.getEvaluatedModules({
217
- ...options,
218
- schemaTypeDeclarations,
219
- schemaTypeGenerator
220
- });
221
225
  for (const { queries } of evaluatedModules){
222
226
  for (const query of queries){
223
227
  program.body.push(query.ast);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/typescript/typeGenerator.ts"],"sourcesContent":["/* eslint-disable unicorn/consistent-function-scoping */\nimport process from 'node:process'\n\nimport * as t from '@babel/types'\nimport {type WorkerChannel, type WorkerChannelReporter} from '@sanity/worker-channels'\nimport {type SchemaType} from 'groq-js'\nimport {createSelector} from 'reselect'\n\nimport {resultSuffix} from '../casing.js'\nimport {\n ALL_SANITY_SCHEMA_TYPES,\n ARRAY_OF,\n INTERNAL_REFERENCE_SYMBOL,\n SANITY_QUERIES,\n} from './constants.js'\nimport {\n computeOnce,\n generateCode,\n getUniqueIdentifierForName,\n normalizePrintablePath,\n} from './helpers.js'\nimport {SchemaTypeGenerator} from './schemaTypeGenerator.js'\nimport {\n type EvaluatedModule,\n type EvaluatedQuery,\n type ExtractedModule,\n QueryEvaluationError,\n type QueryExtractionError,\n} from './types.js'\n\n/** @public */\nexport type TypegenWorkerChannel = WorkerChannel.Definition<{\n evaluatedModules: WorkerChannel.Stream<EvaluatedModule>\n generatedQueryTypes: WorkerChannel.Event<{\n queryMapDeclaration: {ast: t.Program; code: string}\n }>\n generatedSchemaTypes: WorkerChannel.Event<{\n allSanitySchemaTypesDeclaration: {\n ast: t.ExportNamedDeclaration\n code: string\n id: t.Identifier\n }\n internalReferenceSymbol: {\n ast: t.ExportNamedDeclaration\n code: string\n id: t.Identifier\n }\n schemaTypeDeclarations: {\n ast: t.ExportNamedDeclaration\n code: string\n id: t.Identifier\n name: string\n tsType: t.TSType\n }[]\n }>\n}>\n\n/** @public */\nexport interface GenerateTypesOptions {\n schema: SchemaType\n\n overloadClientMethods?: boolean\n queries?: AsyncIterable<ExtractedModule>\n reporter?: WorkerChannelReporter<TypegenWorkerChannel>\n root?: string\n schemaPath?: string\n}\n\ntype GetEvaluatedModulesOptions = GenerateTypesOptions & {\n schemaTypeDeclarations: ReturnType<TypeGenerator['getSchemaTypeDeclarations']>\n schemaTypeGenerator: SchemaTypeGenerator\n}\ntype GetQueryMapDeclarationOptions = GenerateTypesOptions & {\n evaluatedModules: EvaluatedModule[]\n}\n\n/**\n * A class used to generate TypeScript types from a given schema\n * @beta\n */\nexport class TypeGenerator {\n private getSchemaTypeGenerator = createSelector(\n [(options: GenerateTypesOptions) => options.schema],\n\n (schema) => new SchemaTypeGenerator(schema),\n )\n\n private getSchemaTypeDeclarations = createSelector(\n [\n (options: GenerateTypesOptions) => options.root,\n (options: GenerateTypesOptions) => options.schemaPath,\n this.getSchemaTypeGenerator,\n ],\n\n (root = process.cwd(), schemaPath, schema) =>\n [...schema].map(({id, name, tsType}, index) => {\n const typeAlias = t.tsTypeAliasDeclaration(id, null, tsType)\n let ast = t.exportNamedDeclaration(typeAlias)\n\n if (index === 0 && schemaPath) {\n ast = t.addComments(ast, 'leading', [\n {type: 'CommentLine', value: ` Source: ${normalizePrintablePath(root, schemaPath)}`},\n ])\n }\n const code = generateCode(ast)\n return {ast, code, id, name, tsType}\n }),\n )\n\n private getAllSanitySchemaTypesDeclaration = createSelector(\n [this.getSchemaTypeDeclarations],\n (schemaTypes) => {\n const ast = t.exportNamedDeclaration(\n t.tsTypeAliasDeclaration(\n ALL_SANITY_SCHEMA_TYPES,\n null,\n schemaTypes.length > 0\n ? t.tsUnionType(schemaTypes.map(({id}) => t.tsTypeReference(id)))\n : t.tsNeverKeyword(),\n ),\n )\n const code = generateCode(ast)\n\n return {ast, code, id: ALL_SANITY_SCHEMA_TYPES}\n },\n )\n\n private getArrayOfDeclaration = computeOnce(() => {\n // Creates: type ArrayOf<T> = Array<T & { _key: string }>;\n const typeParam = t.tsTypeParameter(null, null, 'T')\n const intersectionType = t.tsIntersectionType([\n t.tsTypeReference(t.identifier('T')),\n t.tsTypeLiteral([\n t.tsPropertySignature(t.identifier('_key'), t.tsTypeAnnotation(t.tsStringKeyword())),\n ]),\n ])\n const arrayType = t.tsTypeReference(\n t.identifier('Array'),\n t.tsTypeParameterInstantiation([intersectionType]),\n )\n\n const ast = t.tsTypeAliasDeclaration(\n ARRAY_OF,\n t.tsTypeParameterDeclaration([typeParam]),\n arrayType,\n )\n const code = generateCode(ast)\n\n return {ast, code, id: ARRAY_OF}\n })\n\n private getInternalReferenceSymbolDeclaration = computeOnce(() => {\n const typeOperator = t.tsTypeOperator(t.tsSymbolKeyword(), 'unique')\n\n const id = INTERNAL_REFERENCE_SYMBOL\n id.typeAnnotation = t.tsTypeAnnotation(typeOperator)\n\n const declaration = t.variableDeclaration('const', [t.variableDeclarator(id)])\n declaration.declare = true\n const ast = t.exportNamedDeclaration(declaration)\n const code = generateCode(ast)\n\n return {ast, code, id}\n })\n\n private static async getEvaluatedModules({\n queries: extractedModules,\n reporter: report,\n root = process.cwd(),\n schemaTypeDeclarations,\n schemaTypeGenerator,\n }: GetEvaluatedModulesOptions) {\n if (!extractedModules) {\n report?.stream.evaluatedModules.end()\n return []\n }\n\n const currentIdentifiers = new Set<string>(schemaTypeDeclarations.map(({id}) => id.name))\n const evaluatedModuleResults: EvaluatedModule[] = []\n\n for await (const {filename, ...extractedModule} of extractedModules) {\n const queries: EvaluatedQuery[] = []\n const errors: (QueryEvaluationError | QueryExtractionError)[] = [...extractedModule.errors]\n\n for (const extractedQuery of extractedModule.queries) {\n const {variable} = extractedQuery\n try {\n const {stats, tsType} = schemaTypeGenerator.evaluateQuery(extractedQuery)\n const id = getUniqueIdentifierForName(resultSuffix(variable.id.name), currentIdentifiers)\n const typeAlias = t.tsTypeAliasDeclaration(id, null, tsType)\n const trimmedQuery = extractedQuery.query.replaceAll(/(\\r\\n|\\n|\\r)/gm, '').trim()\n const ast = t.addComments(t.exportNamedDeclaration(typeAlias), 'leading', [\n {type: 'CommentLine', value: ` Source: ${normalizePrintablePath(root, filename)}`},\n {type: 'CommentLine', value: ` Variable: ${variable.id.name}`},\n {type: 'CommentLine', value: ` Query: ${trimmedQuery}`},\n ])\n\n const evaluatedQueryResult: EvaluatedQuery = {\n ast,\n code: generateCode(ast),\n id,\n stats,\n tsType,\n ...extractedQuery,\n }\n\n currentIdentifiers.add(id.name)\n queries.push(evaluatedQueryResult)\n } catch (cause) {\n errors.push(new QueryEvaluationError({cause, filename, variable}))\n }\n }\n\n const evaluatedModule: EvaluatedModule = {\n errors,\n filename,\n queries,\n }\n report?.stream.evaluatedModules.emit(evaluatedModule)\n evaluatedModuleResults.push(evaluatedModule)\n }\n report?.stream.evaluatedModules.end()\n\n return evaluatedModuleResults\n }\n\n private static async getQueryMapDeclaration({\n evaluatedModules,\n overloadClientMethods = true,\n }: GetQueryMapDeclarationOptions) {\n if (!overloadClientMethods) return {ast: t.program([]), code: ''}\n\n const queries = evaluatedModules.flatMap((module) => module.queries)\n if (queries.length === 0) return {ast: t.program([]), code: ''}\n\n const typesByQuerystring: {[query: string]: string[]} = {}\n for (const {id, query} of queries) {\n typesByQuerystring[query] ??= []\n typesByQuerystring[query].push(id.name)\n }\n\n const queryReturnInterface = t.tsInterfaceDeclaration(\n SANITY_QUERIES,\n null,\n [],\n t.tsInterfaceBody(\n Object.entries(typesByQuerystring).map(([query, types]) => {\n return t.tsPropertySignature(\n t.stringLiteral(query),\n t.tsTypeAnnotation(\n types.length > 0\n ? t.tsUnionType(types.map((type) => t.tsTypeReference(t.identifier(type))))\n : t.tsNeverKeyword(),\n ),\n )\n }),\n ),\n )\n\n const declareModule = t.declareModule(\n t.stringLiteral('@sanity/client'),\n t.blockStatement([queryReturnInterface]),\n )\n\n const clientImport = t.addComments(\n t.importDeclaration([], t.stringLiteral('@sanity/client')),\n 'leading',\n [{type: 'CommentLine', value: ' Query TypeMap'}],\n )\n\n const ast = t.program([clientImport, declareModule])\n const code = generateCode(ast)\n return {ast, code}\n }\n\n async generateTypes(options: GenerateTypesOptions) {\n const {reporter: report} = options\n const internalReferenceSymbol = this.getInternalReferenceSymbolDeclaration()\n const schemaTypeGenerator = this.getSchemaTypeGenerator(options)\n const schemaTypeDeclarations = this.getSchemaTypeDeclarations(options)\n const allSanitySchemaTypesDeclaration = this.getAllSanitySchemaTypesDeclaration(options)\n\n report?.event.generatedSchemaTypes({\n allSanitySchemaTypesDeclaration,\n internalReferenceSymbol,\n schemaTypeDeclarations,\n })\n\n const program = t.program([])\n let code = ''\n\n program.body.push(internalReferenceSymbol.ast)\n code += internalReferenceSymbol.code\n\n if (schemaTypeGenerator.isArrayOfUsed()) {\n const arrayOfDeclaration = this.getArrayOfDeclaration()\n program.body.push(arrayOfDeclaration.ast)\n code += arrayOfDeclaration.code\n }\n\n for (const declaration of schemaTypeDeclarations) {\n program.body.push(declaration.ast)\n code += declaration.code\n }\n\n program.body.push(allSanitySchemaTypesDeclaration.ast)\n code += allSanitySchemaTypesDeclaration.code\n\n const evaluatedModules = await TypeGenerator.getEvaluatedModules({\n ...options,\n schemaTypeDeclarations,\n schemaTypeGenerator,\n })\n\n for (const {queries} of evaluatedModules) {\n for (const query of queries) {\n program.body.push(query.ast)\n code += query.code\n }\n }\n\n const queryMapDeclaration = await TypeGenerator.getQueryMapDeclaration({\n ...options,\n evaluatedModules,\n })\n program.body.push(...queryMapDeclaration.ast.body)\n code += queryMapDeclaration.code\n\n report?.event.generatedQueryTypes({queryMapDeclaration})\n\n return {ast: program, code}\n }\n}\n"],"names":["process","t","createSelector","resultSuffix","ALL_SANITY_SCHEMA_TYPES","ARRAY_OF","INTERNAL_REFERENCE_SYMBOL","SANITY_QUERIES","computeOnce","generateCode","getUniqueIdentifierForName","normalizePrintablePath","SchemaTypeGenerator","QueryEvaluationError","TypeGenerator","getSchemaTypeGenerator","options","schema","getSchemaTypeDeclarations","root","schemaPath","cwd","map","id","name","tsType","index","typeAlias","tsTypeAliasDeclaration","ast","exportNamedDeclaration","addComments","type","value","code","getAllSanitySchemaTypesDeclaration","schemaTypes","length","tsUnionType","tsTypeReference","tsNeverKeyword","getArrayOfDeclaration","typeParam","tsTypeParameter","intersectionType","tsIntersectionType","identifier","tsTypeLiteral","tsPropertySignature","tsTypeAnnotation","tsStringKeyword","arrayType","tsTypeParameterInstantiation","tsTypeParameterDeclaration","getInternalReferenceSymbolDeclaration","typeOperator","tsTypeOperator","tsSymbolKeyword","typeAnnotation","declaration","variableDeclaration","variableDeclarator","declare","getEvaluatedModules","queries","extractedModules","reporter","report","schemaTypeDeclarations","schemaTypeGenerator","stream","evaluatedModules","end","currentIdentifiers","Set","evaluatedModuleResults","filename","extractedModule","errors","extractedQuery","variable","stats","evaluateQuery","trimmedQuery","query","replaceAll","trim","evaluatedQueryResult","add","push","cause","evaluatedModule","emit","getQueryMapDeclaration","overloadClientMethods","program","flatMap","module","typesByQuerystring","queryReturnInterface","tsInterfaceDeclaration","tsInterfaceBody","Object","entries","types","stringLiteral","declareModule","blockStatement","clientImport","importDeclaration","generateTypes","internalReferenceSymbol","allSanitySchemaTypesDeclaration","event","generatedSchemaTypes","body","isArrayOfUsed","arrayOfDeclaration","queryMapDeclaration","generatedQueryTypes"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/typescript/typeGenerator.ts"],"sourcesContent":["/* eslint-disable unicorn/consistent-function-scoping */\nimport process from 'node:process'\n\nimport * as t from '@babel/types'\nimport {type WorkerChannel, type WorkerChannelReporter} from '@sanity/worker-channels'\nimport {type SchemaType} from 'groq-js'\nimport {createSelector} from 'reselect'\n\nimport {resultSuffix} from '../casing.js'\nimport {\n ALL_SANITY_SCHEMA_TYPES,\n ARRAY_OF,\n INTERNAL_REFERENCE_SYMBOL,\n SANITY_QUERIES,\n} from './constants.js'\nimport {\n computeOnce,\n generateCode,\n getUniqueIdentifierForName,\n normalizePrintablePath,\n} from './helpers.js'\nimport {SchemaTypeGenerator} from './schemaTypeGenerator.js'\nimport {\n type EvaluatedModule,\n type EvaluatedQuery,\n type ExtractedModule,\n QueryEvaluationError,\n type QueryExtractionError,\n} from './types.js'\n\n/** @public */\nexport type TypegenWorkerChannel = WorkerChannel.Definition<{\n evaluatedModules: WorkerChannel.Stream<EvaluatedModule>\n generatedQueryTypes: WorkerChannel.Event<{\n queryMapDeclaration: {ast: t.Program; code: string}\n }>\n generatedSchemaTypes: WorkerChannel.Event<{\n allSanitySchemaTypesDeclaration: {\n ast: t.ExportNamedDeclaration\n code: string\n id: t.Identifier\n }\n internalReferenceSymbol: {\n ast: t.ExportNamedDeclaration\n code: string\n id: t.Identifier\n }\n schemaTypeDeclarations: {\n ast: t.ExportNamedDeclaration\n code: string\n id: t.Identifier\n name: string\n tsType: t.TSType\n }[]\n }>\n}>\n\n/** @public */\nexport interface GenerateTypesOptions {\n schema: SchemaType\n\n overloadClientMethods?: boolean\n queries?: AsyncIterable<ExtractedModule>\n reporter?: WorkerChannelReporter<TypegenWorkerChannel>\n root?: string\n schemaPath?: string\n}\n\ntype GetEvaluatedModulesOptions = GenerateTypesOptions & {\n schemaTypeDeclarations: ReturnType<TypeGenerator['getSchemaTypeDeclarations']>\n schemaTypeGenerator: SchemaTypeGenerator\n}\ntype GetQueryMapDeclarationOptions = GenerateTypesOptions & {\n evaluatedModules: EvaluatedModule[]\n}\n\n/**\n * A class used to generate TypeScript types from a given schema\n * @beta\n */\nexport class TypeGenerator {\n private getSchemaTypeGenerator = createSelector(\n [(options: GenerateTypesOptions) => options.schema],\n\n (schema) => new SchemaTypeGenerator(schema),\n )\n\n private getSchemaTypeDeclarations = createSelector(\n [\n (options: GenerateTypesOptions) => options.root,\n (options: GenerateTypesOptions) => options.schemaPath,\n this.getSchemaTypeGenerator,\n ],\n\n (root = process.cwd(), schemaPath, schema) =>\n [...schema].map(({id, name, tsType}, index) => {\n const typeAlias = t.tsTypeAliasDeclaration(id, null, tsType)\n let ast = t.exportNamedDeclaration(typeAlias)\n\n if (index === 0 && schemaPath) {\n ast = t.addComments(ast, 'leading', [\n {type: 'CommentLine', value: ` Source: ${normalizePrintablePath(root, schemaPath)}`},\n ])\n }\n const code = generateCode(ast)\n return {ast, code, id, name, tsType}\n }),\n )\n\n private getAllSanitySchemaTypesDeclaration = createSelector(\n [this.getSchemaTypeDeclarations],\n (schemaTypes) => {\n const ast = t.exportNamedDeclaration(\n t.tsTypeAliasDeclaration(\n ALL_SANITY_SCHEMA_TYPES,\n null,\n schemaTypes.length > 0\n ? t.tsUnionType(schemaTypes.map(({id}) => t.tsTypeReference(id)))\n : t.tsNeverKeyword(),\n ),\n )\n const code = generateCode(ast)\n\n return {ast, code, id: ALL_SANITY_SCHEMA_TYPES}\n },\n )\n\n private getArrayOfDeclaration = computeOnce(() => {\n // Creates: type ArrayOf<T> = Array<T & { _key: string }>;\n const typeParam = t.tsTypeParameter(null, null, 'T')\n const intersectionType = t.tsIntersectionType([\n t.tsTypeReference(t.identifier('T')),\n t.tsTypeLiteral([\n t.tsPropertySignature(t.identifier('_key'), t.tsTypeAnnotation(t.tsStringKeyword())),\n ]),\n ])\n const arrayType = t.tsTypeReference(\n t.identifier('Array'),\n t.tsTypeParameterInstantiation([intersectionType]),\n )\n\n const ast = t.tsTypeAliasDeclaration(\n ARRAY_OF,\n t.tsTypeParameterDeclaration([typeParam]),\n arrayType,\n )\n const code = generateCode(ast)\n\n return {ast, code, id: ARRAY_OF}\n })\n\n private getInternalReferenceSymbolDeclaration = computeOnce(() => {\n const typeOperator = t.tsTypeOperator(t.tsSymbolKeyword(), 'unique')\n\n const id = INTERNAL_REFERENCE_SYMBOL\n id.typeAnnotation = t.tsTypeAnnotation(typeOperator)\n\n const declaration = t.variableDeclaration('const', [t.variableDeclarator(id)])\n declaration.declare = true\n const ast = t.exportNamedDeclaration(declaration)\n const code = generateCode(ast)\n\n return {ast, code, id}\n })\n\n private static async getEvaluatedModules({\n queries: extractedModules,\n reporter: report,\n root = process.cwd(),\n schemaTypeDeclarations,\n schemaTypeGenerator,\n }: GetEvaluatedModulesOptions) {\n if (!extractedModules) {\n report?.stream.evaluatedModules.end()\n return []\n }\n\n const currentIdentifiers = new Set<string>(schemaTypeDeclarations.map(({id}) => id.name))\n const evaluatedModuleResults: EvaluatedModule[] = []\n\n for await (const {filename, ...extractedModule} of extractedModules) {\n const queries: EvaluatedQuery[] = []\n const errors: (QueryEvaluationError | QueryExtractionError)[] = [...extractedModule.errors]\n\n for (const extractedQuery of extractedModule.queries) {\n const {variable} = extractedQuery\n try {\n const {stats, tsType} = schemaTypeGenerator.evaluateQuery(extractedQuery)\n const id = getUniqueIdentifierForName(resultSuffix(variable.id.name), currentIdentifiers)\n const typeAlias = t.tsTypeAliasDeclaration(id, null, tsType)\n const trimmedQuery = extractedQuery.query.replaceAll(/(\\r\\n|\\n|\\r)/gm, '').trim()\n const ast = t.addComments(t.exportNamedDeclaration(typeAlias), 'leading', [\n {type: 'CommentLine', value: ` Source: ${normalizePrintablePath(root, filename)}`},\n {type: 'CommentLine', value: ` Variable: ${variable.id.name}`},\n {type: 'CommentLine', value: ` Query: ${trimmedQuery}`},\n ])\n\n const evaluatedQueryResult: EvaluatedQuery = {\n ast,\n code: generateCode(ast),\n id,\n stats,\n tsType,\n ...extractedQuery,\n }\n\n currentIdentifiers.add(id.name)\n queries.push(evaluatedQueryResult)\n } catch (cause) {\n errors.push(new QueryEvaluationError({cause, filename, variable}))\n }\n }\n\n const evaluatedModule: EvaluatedModule = {\n errors,\n filename,\n queries,\n }\n report?.stream.evaluatedModules.emit(evaluatedModule)\n evaluatedModuleResults.push(evaluatedModule)\n }\n report?.stream.evaluatedModules.end()\n\n return evaluatedModuleResults\n }\n\n private static async getQueryMapDeclaration({\n evaluatedModules,\n overloadClientMethods = true,\n }: GetQueryMapDeclarationOptions) {\n if (!overloadClientMethods) return {ast: t.program([]), code: ''}\n\n const queries = evaluatedModules.flatMap((module) => module.queries)\n if (queries.length === 0) return {ast: t.program([]), code: ''}\n\n const typesByQuerystring: {[query: string]: string[]} = {}\n for (const {id, query} of queries) {\n typesByQuerystring[query] ??= []\n typesByQuerystring[query].push(id.name)\n }\n\n const queryReturnInterface = t.tsInterfaceDeclaration(\n SANITY_QUERIES,\n null,\n [],\n t.tsInterfaceBody(\n Object.entries(typesByQuerystring).map(([query, types]) => {\n return t.tsPropertySignature(\n t.stringLiteral(query),\n t.tsTypeAnnotation(\n types.length > 0\n ? t.tsUnionType(types.map((type) => t.tsTypeReference(t.identifier(type))))\n : t.tsNeverKeyword(),\n ),\n )\n }),\n ),\n )\n\n const declareModule = t.declareModule(\n t.stringLiteral('@sanity/client'),\n t.blockStatement([queryReturnInterface]),\n )\n\n const clientImport = t.addComments(\n t.importDeclaration([], t.stringLiteral('@sanity/client')),\n 'leading',\n [{type: 'CommentLine', value: ' Query TypeMap'}],\n )\n\n const ast = t.program([clientImport, declareModule])\n const code = generateCode(ast)\n return {ast, code}\n }\n\n async generateTypes(options: GenerateTypesOptions) {\n const {reporter: report} = options\n const internalReferenceSymbol = this.getInternalReferenceSymbolDeclaration()\n const schemaTypeGenerator = this.getSchemaTypeGenerator(options)\n const schemaTypeDeclarations = this.getSchemaTypeDeclarations(options)\n const allSanitySchemaTypesDeclaration = this.getAllSanitySchemaTypesDeclaration(options)\n\n report?.event.generatedSchemaTypes({\n allSanitySchemaTypesDeclaration,\n internalReferenceSymbol,\n schemaTypeDeclarations,\n })\n\n // Queries can produce `inline` type nodes that the schema-side generator\n // never sees (e.g. filtering a tagged-union array down to its inline\n // members). Evaluate modules before deciding whether the ArrayOf helper is\n // needed, so query-only usage still triggers the declaration.\n const evaluatedModules = await TypeGenerator.getEvaluatedModules({\n ...options,\n schemaTypeDeclarations,\n schemaTypeGenerator,\n })\n\n const program = t.program([])\n let code = ''\n\n program.body.push(internalReferenceSymbol.ast)\n code += internalReferenceSymbol.code\n\n if (schemaTypeGenerator.isArrayOfUsed()) {\n const arrayOfDeclaration = this.getArrayOfDeclaration()\n program.body.push(arrayOfDeclaration.ast)\n code += arrayOfDeclaration.code\n }\n\n for (const declaration of schemaTypeDeclarations) {\n program.body.push(declaration.ast)\n code += declaration.code\n }\n\n program.body.push(allSanitySchemaTypesDeclaration.ast)\n code += allSanitySchemaTypesDeclaration.code\n\n for (const {queries} of evaluatedModules) {\n for (const query of queries) {\n program.body.push(query.ast)\n code += query.code\n }\n }\n\n const queryMapDeclaration = await TypeGenerator.getQueryMapDeclaration({\n ...options,\n evaluatedModules,\n })\n program.body.push(...queryMapDeclaration.ast.body)\n code += queryMapDeclaration.code\n\n report?.event.generatedQueryTypes({queryMapDeclaration})\n\n return {ast: program, code}\n }\n}\n"],"names":["process","t","createSelector","resultSuffix","ALL_SANITY_SCHEMA_TYPES","ARRAY_OF","INTERNAL_REFERENCE_SYMBOL","SANITY_QUERIES","computeOnce","generateCode","getUniqueIdentifierForName","normalizePrintablePath","SchemaTypeGenerator","QueryEvaluationError","TypeGenerator","getSchemaTypeGenerator","options","schema","getSchemaTypeDeclarations","root","schemaPath","cwd","map","id","name","tsType","index","typeAlias","tsTypeAliasDeclaration","ast","exportNamedDeclaration","addComments","type","value","code","getAllSanitySchemaTypesDeclaration","schemaTypes","length","tsUnionType","tsTypeReference","tsNeverKeyword","getArrayOfDeclaration","typeParam","tsTypeParameter","intersectionType","tsIntersectionType","identifier","tsTypeLiteral","tsPropertySignature","tsTypeAnnotation","tsStringKeyword","arrayType","tsTypeParameterInstantiation","tsTypeParameterDeclaration","getInternalReferenceSymbolDeclaration","typeOperator","tsTypeOperator","tsSymbolKeyword","typeAnnotation","declaration","variableDeclaration","variableDeclarator","declare","getEvaluatedModules","queries","extractedModules","reporter","report","schemaTypeDeclarations","schemaTypeGenerator","stream","evaluatedModules","end","currentIdentifiers","Set","evaluatedModuleResults","filename","extractedModule","errors","extractedQuery","variable","stats","evaluateQuery","trimmedQuery","query","replaceAll","trim","evaluatedQueryResult","add","push","cause","evaluatedModule","emit","getQueryMapDeclaration","overloadClientMethods","program","flatMap","module","typesByQuerystring","queryReturnInterface","tsInterfaceDeclaration","tsInterfaceBody","Object","entries","types","stringLiteral","declareModule","blockStatement","clientImport","importDeclaration","generateTypes","internalReferenceSymbol","allSanitySchemaTypesDeclaration","event","generatedSchemaTypes","body","isArrayOfUsed","arrayOfDeclaration","queryMapDeclaration","generatedQueryTypes"],"mappings":"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"}
@@ -0,0 +1,99 @@
1
+ import { debug } from './debug.js';
2
+ // Wrapper to avoid lint rule against dynamic imports
3
+ // eslint-disable-next-line no-restricted-syntax
4
+ const tryImport = (specifier)=>import(specifier);
5
+ /**
6
+ * Synchronously defines a formatter based on the `formatGeneratedCode` configuration.
7
+ * The `name` is available immediately; call `resolve()` to load the formatter (which may throw).
8
+ *
9
+ * Returns `undefined` if `formatGeneratedCode` is `false`.
10
+ *
11
+ * @param formatGeneratedCode - The formatter mode to resolve
12
+ */ export function defineFormatter(formatGeneratedCode) {
13
+ if (formatGeneratedCode === false) {
14
+ return undefined;
15
+ }
16
+ if (formatGeneratedCode === 'oxfmt') {
17
+ return {
18
+ name: 'oxfmt',
19
+ resolve: resolveOxfmt
20
+ };
21
+ }
22
+ // true or 'prettier' → use prettier
23
+ return {
24
+ name: 'prettier',
25
+ resolve: resolvePrettier
26
+ };
27
+ }
28
+ /**
29
+ * Resolves a code formatter based on the `formatGeneratedCode` configuration.
30
+ *
31
+ * Resolution:
32
+ * - `false` → no formatter
33
+ * - `true` | `'prettier'` → prettier (always available as a dependency)
34
+ * - `'oxfmt'` → oxfmt, throws if not installed
35
+ *
36
+ * @param formatGeneratedCode - The formatter mode to resolve
37
+ */ export async function resolveFormatter(formatGeneratedCode) {
38
+ const defined = defineFormatter(formatGeneratedCode);
39
+ if (!defined) {
40
+ return {
41
+ format: undefined,
42
+ name: undefined
43
+ };
44
+ }
45
+ return defined.resolve();
46
+ }
47
+ async function resolveOxfmt() {
48
+ try {
49
+ const oxfmt = await tryImport('oxfmt');
50
+ const format = oxfmt.format ?? oxfmt.default?.format;
51
+ if (typeof format !== 'function') {
52
+ throw new TypeError('oxfmt module does not export a format function');
53
+ }
54
+ return {
55
+ format: async (filename, text)=>{
56
+ const result = await format(filename, text);
57
+ if (result.errors && result.errors.length > 0) {
58
+ throw new Error('Failed to format generated code with oxfmt', {
59
+ cause: result.errors
60
+ });
61
+ }
62
+ return result.code;
63
+ },
64
+ name: 'oxfmt'
65
+ };
66
+ } catch (err) {
67
+ throw new Error('formatGeneratedCode is set to "oxfmt" but oxfmt could not be loaded. ' + 'Make sure oxfmt is installed as a dependency in your project. ' + 'See: https://oxc.rs/docs/guide/usage/formatter/quickstart.html', {
68
+ cause: err
69
+ });
70
+ }
71
+ }
72
+ async function resolvePrettier() {
73
+ try {
74
+ const prettier = await tryImport('prettier');
75
+ const format = prettier.format ?? prettier.default?.format;
76
+ const resolveConfig = prettier.resolveConfig ?? prettier.default?.resolveConfig;
77
+ if (typeof format !== 'function') {
78
+ throw new TypeError('prettier module does not export a format function');
79
+ }
80
+ return {
81
+ format: async (filename, text)=>{
82
+ const prettierConfig = typeof resolveConfig === 'function' ? await resolveConfig(filename) : undefined;
83
+ return format(text, {
84
+ ...prettierConfig,
85
+ parser: 'typescript'
86
+ });
87
+ },
88
+ name: 'prettier'
89
+ };
90
+ } catch (err) {
91
+ debug('prettier not available: %s', err instanceof Error ? err.message : err);
92
+ return {
93
+ format: undefined,
94
+ name: undefined
95
+ };
96
+ }
97
+ }
98
+
99
+ //# sourceMappingURL=resolveFormatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/resolveFormatter.ts"],"sourcesContent":["import {type FormatGeneratedCode} from '../readConfig.js'\nimport {debug} from './debug.js'\n\n/**\n * A resolved formatter function that takes a filename and text, and returns formatted text.\n */\nexport type FormatterFn = (filename: string, text: string) => Promise<string>\n\n/**\n * The result of resolving a formatter.\n */\nexport interface ResolvedFormatter {\n /** The formatter function, or undefined if no formatter was found */\n format: FormatterFn | undefined\n /** The name of the resolved formatter, for display purposes */\n name: string | undefined\n}\n\n/**\n * A defined formatter with a known name and an async resolve step.\n */\nexport interface DefinedFormatter {\n /** The name of the formatter, available synchronously */\n name: string\n /** Resolves the formatter — may throw if the formatter cannot be loaded */\n resolve: () => Promise<ResolvedFormatter>\n}\n\n// Wrapper to avoid lint rule against dynamic imports\n// eslint-disable-next-line no-restricted-syntax\nconst tryImport = (specifier: string) => import(specifier)\n\n/**\n * Synchronously defines a formatter based on the `formatGeneratedCode` configuration.\n * The `name` is available immediately; call `resolve()` to load the formatter (which may throw).\n *\n * Returns `undefined` if `formatGeneratedCode` is `false`.\n *\n * @param formatGeneratedCode - The formatter mode to resolve\n */\nexport function defineFormatter(\n formatGeneratedCode: FormatGeneratedCode,\n): DefinedFormatter | undefined {\n if (formatGeneratedCode === false) {\n return undefined\n }\n\n if (formatGeneratedCode === 'oxfmt') {\n return {name: 'oxfmt', resolve: resolveOxfmt}\n }\n\n // true or 'prettier' → use prettier\n return {name: 'prettier', resolve: resolvePrettier}\n}\n\n/**\n * Resolves a code formatter based on the `formatGeneratedCode` configuration.\n *\n * Resolution:\n * - `false` → no formatter\n * - `true` | `'prettier'` → prettier (always available as a dependency)\n * - `'oxfmt'` → oxfmt, throws if not installed\n *\n * @param formatGeneratedCode - The formatter mode to resolve\n */\nexport async function resolveFormatter(\n formatGeneratedCode: FormatGeneratedCode,\n): Promise<ResolvedFormatter> {\n const defined = defineFormatter(formatGeneratedCode)\n if (!defined) {\n return {format: undefined, name: undefined}\n }\n return defined.resolve()\n}\n\nasync function resolveOxfmt(): Promise<ResolvedFormatter> {\n try {\n const oxfmt = await tryImport('oxfmt')\n const format = oxfmt.format ?? oxfmt.default?.format\n if (typeof format !== 'function') {\n throw new TypeError('oxfmt module does not export a format function')\n }\n return {\n format: async (filename: string, text: string) => {\n const result = await format(filename, text)\n if (result.errors && result.errors.length > 0) {\n throw new Error('Failed to format generated code with oxfmt', {cause: result.errors})\n }\n return result.code\n },\n name: 'oxfmt',\n }\n } catch (err) {\n throw new Error(\n 'formatGeneratedCode is set to \"oxfmt\" but oxfmt could not be loaded. ' +\n 'Make sure oxfmt is installed as a dependency in your project. ' +\n 'See: https://oxc.rs/docs/guide/usage/formatter/quickstart.html',\n {cause: err},\n )\n }\n}\n\nasync function resolvePrettier(): Promise<ResolvedFormatter> {\n try {\n const prettier = await tryImport('prettier')\n const format = prettier.format ?? prettier.default?.format\n const resolveConfig = prettier.resolveConfig ?? prettier.default?.resolveConfig\n if (typeof format !== 'function') {\n throw new TypeError('prettier module does not export a format function')\n }\n return {\n format: async (filename: string, text: string) => {\n const prettierConfig =\n typeof resolveConfig === 'function' ? await resolveConfig(filename) : undefined\n return format(text, {\n ...prettierConfig,\n parser: 'typescript' as const,\n })\n },\n name: 'prettier',\n }\n } catch (err) {\n debug('prettier not available: %s', err instanceof Error ? err.message : err)\n return {format: undefined, name: undefined}\n }\n}\n"],"names":["debug","tryImport","specifier","defineFormatter","formatGeneratedCode","undefined","name","resolve","resolveOxfmt","resolvePrettier","resolveFormatter","defined","format","oxfmt","default","TypeError","filename","text","result","errors","length","Error","cause","code","err","prettier","resolveConfig","prettierConfig","parser","message"],"mappings":"AACA,SAAQA,KAAK,QAAO,aAAY;AA2BhC,qDAAqD;AACrD,gDAAgD;AAChD,MAAMC,YAAY,CAACC,YAAsB,MAAM,CAACA;AAEhD;;;;;;;CAOC,GACD,OAAO,SAASC,gBACdC,mBAAwC;IAExC,IAAIA,wBAAwB,OAAO;QACjC,OAAOC;IACT;IAEA,IAAID,wBAAwB,SAAS;QACnC,OAAO;YAACE,MAAM;YAASC,SAASC;QAAY;IAC9C;IAEA,oCAAoC;IACpC,OAAO;QAACF,MAAM;QAAYC,SAASE;IAAe;AACpD;AAEA;;;;;;;;;CASC,GACD,OAAO,eAAeC,iBACpBN,mBAAwC;IAExC,MAAMO,UAAUR,gBAAgBC;IAChC,IAAI,CAACO,SAAS;QACZ,OAAO;YAACC,QAAQP;YAAWC,MAAMD;QAAS;IAC5C;IACA,OAAOM,QAAQJ,OAAO;AACxB;AAEA,eAAeC;IACb,IAAI;QACF,MAAMK,QAAQ,MAAMZ,UAAU;QAC9B,MAAMW,SAASC,MAAMD,MAAM,IAAIC,MAAMC,OAAO,EAAEF;QAC9C,IAAI,OAAOA,WAAW,YAAY;YAChC,MAAM,IAAIG,UAAU;QACtB;QACA,OAAO;YACLH,QAAQ,OAAOI,UAAkBC;gBAC/B,MAAMC,SAAS,MAAMN,OAAOI,UAAUC;gBACtC,IAAIC,OAAOC,MAAM,IAAID,OAAOC,MAAM,CAACC,MAAM,GAAG,GAAG;oBAC7C,MAAM,IAAIC,MAAM,8CAA8C;wBAACC,OAAOJ,OAAOC,MAAM;oBAAA;gBACrF;gBACA,OAAOD,OAAOK,IAAI;YACpB;YACAjB,MAAM;QACR;IACF,EAAE,OAAOkB,KAAK;QACZ,MAAM,IAAIH,MACR,0EACE,mEACA,kEACF;YAACC,OAAOE;QAAG;IAEf;AACF;AAEA,eAAef;IACb,IAAI;QACF,MAAMgB,WAAW,MAAMxB,UAAU;QACjC,MAAMW,SAASa,SAASb,MAAM,IAAIa,SAASX,OAAO,EAAEF;QACpD,MAAMc,gBAAgBD,SAASC,aAAa,IAAID,SAASX,OAAO,EAAEY;QAClE,IAAI,OAAOd,WAAW,YAAY;YAChC,MAAM,IAAIG,UAAU;QACtB;QACA,OAAO;YACLH,QAAQ,OAAOI,UAAkBC;gBAC/B,MAAMU,iBACJ,OAAOD,kBAAkB,aAAa,MAAMA,cAAcV,YAAYX;gBACxE,OAAOO,OAAOK,MAAM;oBAClB,GAAGU,cAAc;oBACjBC,QAAQ;gBACV;YACF;YACAtB,MAAM;QACR;IACF,EAAE,OAAOkB,KAAK;QACZxB,MAAM,8BAA8BwB,eAAeH,QAAQG,IAAIK,OAAO,GAAGL;QACzE,OAAO;YAACZ,QAAQP;YAAWC,MAAMD;QAAS;IAC5C;AACF"}
@@ -41,5 +41,5 @@
41
41
  ]
42
42
  }
43
43
  },
44
- "version": "6.0.3"
44
+ "version": "6.1.1"
45
45
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanity/codegen",
3
- "version": "6.0.3",
3
+ "version": "6.1.1",
4
4
  "description": "Codegen toolkit for Sanity.io",
5
5
  "keywords": [
6
6
  "sanity",
@@ -80,6 +80,7 @@
80
80
  "husky": "^9.1.7",
81
81
  "lint-staged": "^16.4.0",
82
82
  "oclif": "^4.22.85",
83
+ "oxfmt": "^0.47.0",
83
84
  "prettier-plugin-packagejson": "^3.0.2",
84
85
  "rimraf": "^5.0.10",
85
86
  "tinyglobby": "^0.2.16",
@@ -89,7 +90,13 @@
89
90
  "peerDependencies": {
90
91
  "@oclif/core": "^4.8.0",
91
92
  "@sanity/cli-core": "^1",
92
- "@sanity/telemetry": "^0.9.0"
93
+ "@sanity/telemetry": "^0.9.0",
94
+ "oxfmt": "*"
95
+ },
96
+ "peerDependenciesMeta": {
97
+ "oxfmt": {
98
+ "optional": true
99
+ }
93
100
  },
94
101
  "engines": {
95
102
  "node": ">=20.19 <22 || >=22.12"