@sanity/cli 3.52.4 → 3.53.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.
- package/lib/_chunks-cjs/cli.js +3538 -5423
- package/lib/_chunks-cjs/cli.js.map +1 -1
- package/lib/_chunks-cjs/generateAction.js +17 -12
- package/lib/_chunks-cjs/generateAction.js.map +1 -1
- package/lib/workers/typegenGenerate.d.ts +6 -0
- package/lib/workers/typegenGenerate.js +13 -7
- package/lib/workers/typegenGenerate.js.map +1 -1
- package/package.json +7 -7
- package/src/actions/init-project/initProject.ts +6 -3
- package/src/actions/init-project/prompts/nextjs.ts +5 -5
- package/src/actions/init-project/templates/nextjs/index.ts +67 -17
- package/src/actions/init-project/templates/nextjs/schemaTypes/blog.ts +34 -243
- package/src/actions/typegen/generate.telemetry.ts +1 -0
- package/src/actions/typegen/generateAction.ts +27 -18
- package/src/outputters/cliOutputter.ts +2 -2
- package/src/workers/typegenGenerate.ts +23 -5
@@ -44,6 +44,7 @@ async function typegenGenerateAction(args, context) {
|
|
44
44
|
workDir,
|
45
45
|
schemaPath: codegenConfig.schema,
|
46
46
|
searchPath: codegenConfig.path,
|
47
|
+
overloadClientMethods: codegenConfig.overloadClientMethods,
|
47
48
|
prettierConfig
|
48
49
|
},
|
49
50
|
// eslint-disable-next-line no-process-env
|
@@ -85,19 +86,22 @@ async function typegenGenerateAction(args, context) {
|
|
85
86
|
stats.schemaTypesCount += msg.length, fileTypeString += msg.schema, typeFile.write(fileTypeString);
|
86
87
|
return;
|
87
88
|
}
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
89
|
+
if (msg.type === "types") {
|
90
|
+
stats.queryFilesCount++;
|
91
|
+
for (const {
|
92
|
+
queryName,
|
93
|
+
query,
|
94
|
+
type,
|
95
|
+
typeNodesGenerated,
|
96
|
+
unknownTypeNodesGenerated,
|
97
|
+
emptyUnionTypeNodesGenerated
|
98
|
+
} of msg.types)
|
99
|
+
fileTypeString += `// Variable: ${queryName}
|
98
100
|
`, fileTypeString += `// Query: ${query.replace(/(\r\n|\n|\r)/gm, "")}
|
99
101
|
`, fileTypeString += type, stats.queriesCount++, stats.typeNodesGenerated += typeNodesGenerated, stats.unknownTypeNodesGenerated += unknownTypeNodesGenerated, stats.emptyUnionTypeNodesGenerated += emptyUnionTypeNodesGenerated;
|
100
|
-
|
102
|
+
typeFile.write(fileTypeString), stats.size += Buffer.byteLength(fileTypeString);
|
103
|
+
}
|
104
|
+
msg.type === "typemap" && (typeFile.write(msg.typeMap), stats.size += Buffer.byteLength(msg.typeMap));
|
101
105
|
}), worker.addListener("error", reject);
|
102
106
|
}), typeFile.close(), trace.log({
|
103
107
|
outputSize: stats.size,
|
@@ -108,7 +112,8 @@ async function typegenGenerateAction(args, context) {
|
|
108
112
|
typeNodesGenerated: stats.typeNodesGenerated,
|
109
113
|
unknownTypeNodesGenerated: stats.unknownTypeNodesGenerated,
|
110
114
|
unknownTypeNodesRatio: stats.typeNodesGenerated > 0 ? stats.unknownTypeNodesGenerated / stats.typeNodesGenerated : 0,
|
111
|
-
emptyUnionTypeNodesGenerated: stats.emptyUnionTypeNodesGenerated
|
115
|
+
emptyUnionTypeNodesGenerated: stats.emptyUnionTypeNodesGenerated,
|
116
|
+
configOverloadClientMethods: codegenConfig.overloadClientMethods
|
112
117
|
}), trace.complete(), stats.errors > 0 && spinner.warn(`Encountered errors in ${stats.errors} files while generating types`), spinner.succeed(
|
113
118
|
`Generated TypeScript types for ${stats.schemaTypesCount} schema types and ${stats.queriesCount} GROQ queries in ${stats.queryFilesCount} files into: ${codegenConfig.generates}`
|
114
119
|
);
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"generateAction.js","sources":["../../src/actions/typegen/generate.telemetry.ts","../../src/actions/typegen/generateAction.ts"],"sourcesContent":["import {defineTrace} from '@sanity/telemetry'\n\ninterface TypesGeneratedTraceAttrubutes {\n outputSize: number\n queriesCount: number\n schemaTypesCount: number\n queryFilesCount: number\n filesWithErrors: number\n typeNodesGenerated: number\n unknownTypeNodesGenerated: number\n unknownTypeNodesRatio: number\n emptyUnionTypeNodesGenerated: number\n}\n\nexport const TypesGeneratedTrace = defineTrace<TypesGeneratedTraceAttrubutes>({\n name: 'Types Generated',\n version: 0,\n description: 'Trace emitted when generating TypeScript types for queries',\n})\n","import {constants, mkdir, open, stat} from 'node:fs/promises'\nimport {dirname, join} from 'node:path'\nimport {Worker} from 'node:worker_threads'\n\nimport {readConfig} from '@sanity/codegen'\nimport prettier from 'prettier'\n\nimport {type CliCommandArguments, type CliCommandContext} from '../../types'\nimport {getCliWorkerPath} from '../../util/cliWorker'\nimport {\n type TypegenGenerateTypesWorkerData,\n type TypegenGenerateTypesWorkerMessage,\n} from '../../workers/typegenGenerate'\nimport {TypesGeneratedTrace} from './generate.telemetry'\n\nexport interface TypegenGenerateTypesCommandFlags {\n 'config-path'?: string\n}\n\nconst generatedFileWarning = `/**\n * ---------------------------------------------------------------------------------\n * This file has been generated by Sanity TypeGen.\n * Command: \\`sanity typegen generate\\`\n *\n * Any modifications made directly to this file will be overwritten the next time\n * the TypeScript definitions are generated. Please make changes to the Sanity\n * schema definitions and/or GROQ queries if you need to update these types.\n *\n * For more information on how to use Sanity TypeGen, visit the official documentation:\n * https://www.sanity.io/docs/sanity-typegen\n * ---------------------------------------------------------------------------------\n */\\n\\n`\n\nexport default async function typegenGenerateAction(\n args: CliCommandArguments<TypegenGenerateTypesCommandFlags>,\n context: CliCommandContext,\n): Promise<void> {\n const flags = args.extOptions\n const {output, workDir, telemetry} = context\n\n const trace = telemetry.trace(TypesGeneratedTrace)\n trace.start()\n\n const codegenConfig = await readConfig(flags['config-path'] || 'sanity-typegen.json')\n\n try {\n const schemaStats = await stat(codegenConfig.schema)\n if (!schemaStats.isFile()) {\n throw new Error(`Schema path is not a file: ${codegenConfig.schema}`)\n }\n } catch (err) {\n if (err.code === 'ENOENT') {\n // If the user has not provided a specific schema path (eg we're using the default), give some help\n const hint =\n codegenConfig.schema === './schema.json' ? ` - did you run \"sanity schema extract\"?` : ''\n throw new Error(`Schema file not found: ${codegenConfig.schema}${hint}`)\n }\n throw err\n }\n\n const outputPath = join(process.cwd(), codegenConfig.generates)\n const outputDir = dirname(outputPath)\n await mkdir(outputDir, {recursive: true})\n\n const prettierConfig = codegenConfig.formatGeneratedCode\n ? await prettier.resolveConfig(outputPath).catch((err) => {\n output.warn(`Failed to load prettier config: ${err.message}`)\n return null\n })\n : null\n const workerPath = await getCliWorkerPath('typegenGenerate')\n\n const spinner = output.spinner({}).start('Generating types')\n\n const worker = new Worker(workerPath, {\n workerData: {\n workDir,\n schemaPath: codegenConfig.schema,\n searchPath: codegenConfig.path,\n prettierConfig,\n } satisfies TypegenGenerateTypesWorkerData,\n // eslint-disable-next-line no-process-env\n env: process.env,\n })\n\n const typeFile = await open(\n outputPath,\n // eslint-disable-next-line no-bitwise\n constants.O_TRUNC | constants.O_CREAT | constants.O_WRONLY,\n )\n\n typeFile.write(generatedFileWarning)\n\n const stats = {\n queryFilesCount: 0,\n errors: 0,\n queriesCount: 0,\n schemaTypesCount: 0,\n unknownTypeNodesGenerated: 0,\n typeNodesGenerated: 0,\n emptyUnionTypeNodesGenerated: 0,\n size: 0,\n }\n\n await new Promise<void>((resolve, reject) => {\n worker.addListener('message', (msg: TypegenGenerateTypesWorkerMessage) => {\n if (msg.type === 'error') {\n if (msg.fatal) {\n trace.error(msg.error)\n reject(msg.error)\n return\n }\n const errorMessage = msg.filename\n ? `${msg.error.message} in \"${msg.filename}\"`\n : msg.error.message\n spinner.fail(errorMessage)\n stats.errors++\n return\n }\n if (msg.type === 'complete') {\n resolve()\n return\n }\n\n let fileTypeString = `// Source: ${msg.filename}\\n`\n\n if (msg.type === 'schema') {\n stats.schemaTypesCount += msg.length\n fileTypeString += msg.schema\n typeFile.write(fileTypeString)\n return\n }\n\n stats.queryFilesCount++\n for (const {\n queryName,\n query,\n type,\n typeNodesGenerated,\n unknownTypeNodesGenerated,\n emptyUnionTypeNodesGenerated,\n } of msg.types) {\n fileTypeString += `// Variable: ${queryName}\\n`\n fileTypeString += `// Query: ${query.replace(/(\\r\\n|\\n|\\r)/gm, '')}\\n`\n fileTypeString += type\n stats.queriesCount++\n stats.typeNodesGenerated += typeNodesGenerated\n stats.unknownTypeNodesGenerated += unknownTypeNodesGenerated\n stats.emptyUnionTypeNodesGenerated += emptyUnionTypeNodesGenerated\n }\n typeFile.write(fileTypeString)\n stats.size += Buffer.byteLength(fileTypeString)\n })\n worker.addListener('error', reject)\n })\n\n typeFile.close()\n\n trace.log({\n outputSize: stats.size,\n queriesCount: stats.queriesCount,\n schemaTypesCount: stats.schemaTypesCount,\n queryFilesCount: stats.queryFilesCount,\n filesWithErrors: stats.errors,\n typeNodesGenerated: stats.typeNodesGenerated,\n unknownTypeNodesGenerated: stats.unknownTypeNodesGenerated,\n unknownTypeNodesRatio:\n stats.typeNodesGenerated > 0 ? stats.unknownTypeNodesGenerated / stats.typeNodesGenerated : 0,\n emptyUnionTypeNodesGenerated: stats.emptyUnionTypeNodesGenerated,\n })\n\n trace.complete()\n if (stats.errors > 0) {\n spinner.warn(`Encountered errors in ${stats.errors} files while generating types`)\n }\n\n spinner.succeed(\n `Generated TypeScript types for ${stats.schemaTypesCount} schema types and ${stats.queriesCount} GROQ queries in ${stats.queryFilesCount} files into: ${codegenConfig.generates}`,\n )\n}\n"],"names":["defineTrace","telemetry","readConfig","stat","join","dirname","mkdir","prettier","getCliWorkerPath","Worker","open","constants"],"mappings":"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"}
|
1
|
+
{"version":3,"file":"generateAction.js","sources":["../../src/actions/typegen/generate.telemetry.ts","../../src/actions/typegen/generateAction.ts"],"sourcesContent":["import {defineTrace} from '@sanity/telemetry'\n\ninterface TypesGeneratedTraceAttrubutes {\n outputSize: number\n queriesCount: number\n schemaTypesCount: number\n queryFilesCount: number\n filesWithErrors: number\n typeNodesGenerated: number\n unknownTypeNodesGenerated: number\n unknownTypeNodesRatio: number\n emptyUnionTypeNodesGenerated: number\n configOverloadClientMethods: boolean\n}\n\nexport const TypesGeneratedTrace = defineTrace<TypesGeneratedTraceAttrubutes>({\n name: 'Types Generated',\n version: 0,\n description: 'Trace emitted when generating TypeScript types for queries',\n})\n","import {constants, mkdir, open, stat} from 'node:fs/promises'\nimport {dirname, join} from 'node:path'\nimport {Worker} from 'node:worker_threads'\n\nimport {readConfig} from '@sanity/codegen'\nimport prettier from 'prettier'\n\nimport {type CliCommandArguments, type CliCommandContext} from '../../types'\nimport {getCliWorkerPath} from '../../util/cliWorker'\nimport {\n type TypegenGenerateTypesWorkerData,\n type TypegenGenerateTypesWorkerMessage,\n} from '../../workers/typegenGenerate'\nimport {TypesGeneratedTrace} from './generate.telemetry'\n\nexport interface TypegenGenerateTypesCommandFlags {\n 'config-path'?: string\n}\n\nconst generatedFileWarning = `/**\n * ---------------------------------------------------------------------------------\n * This file has been generated by Sanity TypeGen.\n * Command: \\`sanity typegen generate\\`\n *\n * Any modifications made directly to this file will be overwritten the next time\n * the TypeScript definitions are generated. Please make changes to the Sanity\n * schema definitions and/or GROQ queries if you need to update these types.\n *\n * For more information on how to use Sanity TypeGen, visit the official documentation:\n * https://www.sanity.io/docs/sanity-typegen\n * ---------------------------------------------------------------------------------\n */\\n\\n`\n\nexport default async function typegenGenerateAction(\n args: CliCommandArguments<TypegenGenerateTypesCommandFlags>,\n context: CliCommandContext,\n): Promise<void> {\n const flags = args.extOptions\n const {output, workDir, telemetry} = context\n\n const trace = telemetry.trace(TypesGeneratedTrace)\n trace.start()\n\n const codegenConfig = await readConfig(flags['config-path'] || 'sanity-typegen.json')\n\n try {\n const schemaStats = await stat(codegenConfig.schema)\n if (!schemaStats.isFile()) {\n throw new Error(`Schema path is not a file: ${codegenConfig.schema}`)\n }\n } catch (err) {\n if (err.code === 'ENOENT') {\n // If the user has not provided a specific schema path (eg we're using the default), give some help\n const hint =\n codegenConfig.schema === './schema.json' ? ` - did you run \"sanity schema extract\"?` : ''\n throw new Error(`Schema file not found: ${codegenConfig.schema}${hint}`)\n }\n throw err\n }\n\n const outputPath = join(process.cwd(), codegenConfig.generates)\n const outputDir = dirname(outputPath)\n await mkdir(outputDir, {recursive: true})\n\n const prettierConfig = codegenConfig.formatGeneratedCode\n ? await prettier.resolveConfig(outputPath).catch((err) => {\n output.warn(`Failed to load prettier config: ${err.message}`)\n return null\n })\n : null\n const workerPath = await getCliWorkerPath('typegenGenerate')\n\n const spinner = output.spinner({}).start('Generating types')\n\n const worker = new Worker(workerPath, {\n workerData: {\n workDir,\n schemaPath: codegenConfig.schema,\n searchPath: codegenConfig.path,\n overloadClientMethods: codegenConfig.overloadClientMethods,\n prettierConfig,\n } satisfies TypegenGenerateTypesWorkerData,\n // eslint-disable-next-line no-process-env\n env: process.env,\n })\n\n const typeFile = await open(\n outputPath,\n // eslint-disable-next-line no-bitwise\n constants.O_TRUNC | constants.O_CREAT | constants.O_WRONLY,\n )\n\n typeFile.write(generatedFileWarning)\n\n const stats = {\n queryFilesCount: 0,\n errors: 0,\n queriesCount: 0,\n schemaTypesCount: 0,\n unknownTypeNodesGenerated: 0,\n typeNodesGenerated: 0,\n emptyUnionTypeNodesGenerated: 0,\n size: 0,\n }\n\n await new Promise<void>((resolve, reject) => {\n worker.addListener('message', (msg: TypegenGenerateTypesWorkerMessage) => {\n if (msg.type === 'error') {\n if (msg.fatal) {\n trace.error(msg.error)\n reject(msg.error)\n return\n }\n const errorMessage = msg.filename\n ? `${msg.error.message} in \"${msg.filename}\"`\n : msg.error.message\n spinner.fail(errorMessage)\n stats.errors++\n return\n }\n if (msg.type === 'complete') {\n resolve()\n return\n }\n\n let fileTypeString = `// Source: ${msg.filename}\\n`\n\n if (msg.type === 'schema') {\n stats.schemaTypesCount += msg.length\n fileTypeString += msg.schema\n typeFile.write(fileTypeString)\n return\n }\n\n if (msg.type === 'types') {\n stats.queryFilesCount++\n for (const {\n queryName,\n query,\n type,\n typeNodesGenerated,\n unknownTypeNodesGenerated,\n emptyUnionTypeNodesGenerated,\n } of msg.types) {\n fileTypeString += `// Variable: ${queryName}\\n`\n fileTypeString += `// Query: ${query.replace(/(\\r\\n|\\n|\\r)/gm, '')}\\n`\n fileTypeString += type\n stats.queriesCount++\n stats.typeNodesGenerated += typeNodesGenerated\n stats.unknownTypeNodesGenerated += unknownTypeNodesGenerated\n stats.emptyUnionTypeNodesGenerated += emptyUnionTypeNodesGenerated\n }\n typeFile.write(fileTypeString)\n stats.size += Buffer.byteLength(fileTypeString)\n }\n\n if (msg.type === 'typemap') {\n typeFile.write(msg.typeMap)\n stats.size += Buffer.byteLength(msg.typeMap)\n }\n })\n worker.addListener('error', reject)\n })\n\n typeFile.close()\n\n trace.log({\n outputSize: stats.size,\n queriesCount: stats.queriesCount,\n schemaTypesCount: stats.schemaTypesCount,\n queryFilesCount: stats.queryFilesCount,\n filesWithErrors: stats.errors,\n typeNodesGenerated: stats.typeNodesGenerated,\n unknownTypeNodesGenerated: stats.unknownTypeNodesGenerated,\n unknownTypeNodesRatio:\n stats.typeNodesGenerated > 0 ? stats.unknownTypeNodesGenerated / stats.typeNodesGenerated : 0,\n emptyUnionTypeNodesGenerated: stats.emptyUnionTypeNodesGenerated,\n configOverloadClientMethods: codegenConfig.overloadClientMethods,\n })\n\n trace.complete()\n if (stats.errors > 0) {\n spinner.warn(`Encountered errors in ${stats.errors} files while generating types`)\n }\n\n spinner.succeed(\n `Generated TypeScript types for ${stats.schemaTypesCount} schema types and ${stats.queriesCount} GROQ queries in ${stats.queryFilesCount} files into: ${codegenConfig.generates}`,\n )\n}\n"],"names":["defineTrace","telemetry","readConfig","stat","join","dirname","mkdir","prettier","getCliWorkerPath","Worker","open","constants"],"mappings":"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"}
|
@@ -6,6 +6,7 @@ export declare interface TypegenGenerateTypesWorkerData {
|
|
6
6
|
schemaPath: string
|
7
7
|
searchPath: string | string[]
|
8
8
|
prettierConfig: Options | null
|
9
|
+
overloadClientMethods?: boolean
|
9
10
|
}
|
10
11
|
|
11
12
|
export declare type TypegenGenerateTypesWorkerMessage =
|
@@ -34,6 +35,11 @@ export declare type TypegenGenerateTypesWorkerMessage =
|
|
34
35
|
schema: string
|
35
36
|
length: number
|
36
37
|
}
|
38
|
+
| {
|
39
|
+
type: 'typemap'
|
40
|
+
filename: string
|
41
|
+
typeMap: string
|
42
|
+
}
|
37
43
|
| {
|
38
44
|
type: 'complete'
|
39
45
|
}
|
@@ -53,14 +53,13 @@ async function main() {
|
|
53
53
|
const fileQueryTypes = [];
|
54
54
|
for (const { name: queryName, result: query } of result.queries)
|
55
55
|
try {
|
56
|
-
const ast = codegen.safeParseQuery(query), queryTypes = groqJs.typeEvaluate(ast, schema), type = await maybeFormatCode(
|
57
|
-
typeGenerator.generateTypeNodeTypes(`${queryName}Result`, queryTypes).trim(),
|
58
|
-
opts.prettierConfig
|
59
|
-
), queryTypeStats = walkAndCountQueryTypeNodeStats(queryTypes);
|
56
|
+
const ast = codegen.safeParseQuery(query), queryTypes = groqJs.typeEvaluate(ast, schema), typeName = `${queryName}Result`, type = typeGenerator.generateTypeNodeTypes(typeName, queryTypes), code = await maybeFormatCode(type.trim(), opts.prettierConfig), queryTypeStats = walkAndCountQueryTypeNodeStats(queryTypes);
|
60
57
|
fileQueryTypes.push({
|
61
58
|
queryName,
|
62
59
|
query,
|
63
|
-
|
60
|
+
typeName,
|
61
|
+
typeNode: queryTypes,
|
62
|
+
type: code,
|
64
63
|
unknownTypeNodesGenerated: queryTypeStats.unknownTypes,
|
65
64
|
typeNodesGenerated: queryTypeStats.allTypes,
|
66
65
|
emptyUnionTypeNodesGenerated: queryTypeStats.emptyUnions
|
@@ -76,12 +75,19 @@ async function main() {
|
|
76
75
|
query
|
77
76
|
});
|
78
77
|
}
|
79
|
-
fileQueryTypes.length > 0 && ($info(`Generated types for ${fileQueryTypes.length} queries in "${result.filename}"
|
78
|
+
if (fileQueryTypes.length > 0 && ($info(`Generated types for ${fileQueryTypes.length} queries in "${result.filename}"
|
80
79
|
`), node_worker_threads.parentPort?.postMessage({
|
81
80
|
type: "types",
|
82
81
|
types: fileQueryTypes,
|
83
82
|
filename: result.filename
|
84
|
-
}))
|
83
|
+
})), fileQueryTypes.length > 0 && opts.overloadClientMethods) {
|
84
|
+
const typeMap = typeGenerator.generateQueryMap(fileQueryTypes);
|
85
|
+
node_worker_threads.parentPort?.postMessage({
|
86
|
+
type: "typemap",
|
87
|
+
filename: result.filename,
|
88
|
+
typeMap
|
89
|
+
});
|
90
|
+
}
|
85
91
|
}
|
86
92
|
node_worker_threads.parentPort?.postMessage({
|
87
93
|
type: "complete"
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"typegenGenerate.js","sources":["../../src/workers/typegenGenerate.ts"],"sourcesContent":["import {isMainThread, parentPort, workerData as _workerData} from 'node:worker_threads'\n\nimport {\n findQueriesInPath,\n getResolver,\n readSchema,\n registerBabel,\n safeParseQuery,\n TypeGenerator,\n} from '@sanity/codegen'\nimport createDebug from 'debug'\nimport {typeEvaluate, type TypeNode} from 'groq-js'\nimport {format as prettierFormat, type Options as PrettierOptions} from 'prettier'\n\nconst $info = createDebug('sanity:codegen:generate:info')\nconst $warn = createDebug('sanity:codegen:generate:warn')\n\nexport interface TypegenGenerateTypesWorkerData {\n workDir: string\n workspaceName?: string\n schemaPath: string\n searchPath: string | string[]\n prettierConfig: PrettierOptions | null\n}\n\nexport type TypegenGenerateTypesWorkerMessage =\n | {\n type: 'error'\n error: Error\n fatal: boolean\n query?: string\n filename?: string\n }\n | {\n type: 'types'\n filename: string\n types: {\n queryName: string\n query: string\n type: string\n unknownTypeNodesGenerated: number\n typeNodesGenerated: number\n emptyUnionTypeNodesGenerated: number\n }[]\n }\n | {\n type: 'schema'\n filename: string\n schema: string\n length: number\n }\n | {\n type: 'complete'\n }\n\nif (isMainThread || !parentPort) {\n throw new Error('This module must be run as a worker thread')\n}\n\nconst opts = _workerData as TypegenGenerateTypesWorkerData\n\nregisterBabel()\n\nfunction maybeFormatCode(code: string, prettierConfig: PrettierOptions | null): Promise<string> {\n if (!prettierConfig) {\n return Promise.resolve(`${code}\\n`) // add an extra new newline, poor mans formatting\n }\n\n try {\n return prettierFormat(code, {\n ...prettierConfig,\n parser: 'typescript' as const,\n })\n } catch (err) {\n $warn(`Error formatting: ${err.message}`)\n }\n return Promise.resolve(code)\n}\n\nasync function main() {\n const schema = await readSchema(opts.schemaPath)\n\n const typeGenerator = new TypeGenerator(schema)\n const schemaTypes = await maybeFormatCode(\n [typeGenerator.generateSchemaTypes(), TypeGenerator.generateKnownTypes()].join('\\n').trim(),\n opts.prettierConfig,\n )\n const resolver = getResolver()\n\n parentPort?.postMessage({\n type: 'schema',\n schema: schemaTypes,\n filename: 'schema.json',\n length: schema.length,\n } satisfies TypegenGenerateTypesWorkerMessage)\n\n const queries = findQueriesInPath({\n path: opts.searchPath,\n resolver,\n })\n\n for await (const result of queries) {\n if (result.type === 'error') {\n parentPort?.postMessage({\n type: 'error',\n error: result.error,\n fatal: false,\n filename: result.filename,\n } satisfies TypegenGenerateTypesWorkerMessage)\n continue\n }\n $info(`Processing ${result.queries.length} queries in \"${result.filename}\"...`)\n\n const fileQueryTypes: {\n queryName: string\n query: string\n type: string\n unknownTypeNodesGenerated: number\n typeNodesGenerated: number\n emptyUnionTypeNodesGenerated: number\n }[] = []\n for (const {name: queryName, result: query} of result.queries) {\n try {\n const ast = safeParseQuery(query)\n const queryTypes = typeEvaluate(ast, schema)\n\n const type = await maybeFormatCode(\n typeGenerator.generateTypeNodeTypes(`${queryName}Result`, queryTypes).trim(),\n opts.prettierConfig,\n )\n\n const queryTypeStats = walkAndCountQueryTypeNodeStats(queryTypes)\n fileQueryTypes.push({\n queryName,\n query,\n type,\n unknownTypeNodesGenerated: queryTypeStats.unknownTypes,\n typeNodesGenerated: queryTypeStats.allTypes,\n emptyUnionTypeNodesGenerated: queryTypeStats.emptyUnions,\n })\n } catch (err) {\n parentPort?.postMessage({\n type: 'error',\n error: new Error(\n `Error generating types for query \"${queryName}\" in \"${result.filename}\": ${err.message}`,\n {cause: err},\n ),\n fatal: false,\n query,\n } satisfies TypegenGenerateTypesWorkerMessage)\n }\n }\n\n if (fileQueryTypes.length > 0) {\n $info(`Generated types for ${fileQueryTypes.length} queries in \"${result.filename}\"\\n`)\n parentPort?.postMessage({\n type: 'types',\n types: fileQueryTypes,\n filename: result.filename,\n } satisfies TypegenGenerateTypesWorkerMessage)\n }\n }\n\n parentPort?.postMessage({\n type: 'complete',\n } satisfies TypegenGenerateTypesWorkerMessage)\n}\n\nfunction walkAndCountQueryTypeNodeStats(typeNode: TypeNode): {\n allTypes: number\n unknownTypes: number\n emptyUnions: number\n} {\n switch (typeNode.type) {\n case 'unknown': {\n return {allTypes: 1, unknownTypes: 1, emptyUnions: 0}\n }\n case 'array': {\n const acc = walkAndCountQueryTypeNodeStats(typeNode.of)\n acc.allTypes += 1 // count the array type itself\n return acc\n }\n case 'object': {\n // if the rest is unknown, we count it as one unknown type\n if (typeNode.rest && typeNode.rest.type === 'unknown') {\n return {allTypes: 2, unknownTypes: 1, emptyUnions: 0} // count the object type itself as well\n }\n\n const restStats = typeNode.rest\n ? walkAndCountQueryTypeNodeStats(typeNode.rest)\n : {allTypes: 1, unknownTypes: 0, emptyUnions: 0} // count the object type itself\n\n return Object.values(typeNode.attributes).reduce((acc, attribute) => {\n const {allTypes, unknownTypes, emptyUnions} = walkAndCountQueryTypeNodeStats(\n attribute.value,\n )\n return {\n allTypes: acc.allTypes + allTypes,\n unknownTypes: acc.unknownTypes + unknownTypes,\n emptyUnions: acc.emptyUnions + emptyUnions,\n }\n }, restStats)\n }\n case 'union': {\n if (typeNode.of.length === 0) {\n return {allTypes: 1, unknownTypes: 0, emptyUnions: 1}\n }\n\n return typeNode.of.reduce(\n (acc, type) => {\n const {allTypes, unknownTypes, emptyUnions} = walkAndCountQueryTypeNodeStats(type)\n return {\n allTypes: acc.allTypes + allTypes,\n unknownTypes: acc.unknownTypes + unknownTypes,\n emptyUnions: acc.emptyUnions + emptyUnions,\n }\n },\n {allTypes: 1, unknownTypes: 0, emptyUnions: 0}, // count the union type itself\n )\n }\n default: {\n return {allTypes: 1, unknownTypes: 0, emptyUnions: 0}\n }\n }\n}\n\nmain()\n"],"names":["createDebug","isMainThread","parentPort","_workerData","registerBabel","prettierFormat","readSchema","TypeGenerator","getResolver","findQueriesInPath","safeParseQuery","typeEvaluate"],"mappings":"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"}
|
1
|
+
{"version":3,"file":"typegenGenerate.js","sources":["../../src/workers/typegenGenerate.ts"],"sourcesContent":["import {isMainThread, parentPort, workerData as _workerData} from 'node:worker_threads'\n\nimport {\n findQueriesInPath,\n getResolver,\n readSchema,\n registerBabel,\n safeParseQuery,\n TypeGenerator,\n} from '@sanity/codegen'\nimport createDebug from 'debug'\nimport {typeEvaluate, type TypeNode} from 'groq-js'\nimport {format as prettierFormat, type Options as PrettierOptions} from 'prettier'\n\nconst $info = createDebug('sanity:codegen:generate:info')\nconst $warn = createDebug('sanity:codegen:generate:warn')\n\nexport interface TypegenGenerateTypesWorkerData {\n workDir: string\n workspaceName?: string\n schemaPath: string\n searchPath: string | string[]\n prettierConfig: PrettierOptions | null\n overloadClientMethods?: boolean\n}\n\nexport type TypegenGenerateTypesWorkerMessage =\n | {\n type: 'error'\n error: Error\n fatal: boolean\n query?: string\n filename?: string\n }\n | {\n type: 'types'\n filename: string\n types: {\n queryName: string\n query: string\n type: string\n unknownTypeNodesGenerated: number\n typeNodesGenerated: number\n emptyUnionTypeNodesGenerated: number\n }[]\n }\n | {\n type: 'schema'\n filename: string\n schema: string\n length: number\n }\n | {\n type: 'typemap'\n filename: string\n typeMap: string\n }\n | {\n type: 'complete'\n }\n\nif (isMainThread || !parentPort) {\n throw new Error('This module must be run as a worker thread')\n}\n\nconst opts = _workerData as TypegenGenerateTypesWorkerData\n\nregisterBabel()\n\nfunction maybeFormatCode(code: string, prettierConfig: PrettierOptions | null): Promise<string> {\n if (!prettierConfig) {\n return Promise.resolve(`${code}\\n`) // add an extra new newline, poor mans formatting\n }\n\n try {\n return prettierFormat(code, {\n ...prettierConfig,\n parser: 'typescript' as const,\n })\n } catch (err) {\n $warn(`Error formatting: ${err.message}`)\n }\n return Promise.resolve(code)\n}\n\nasync function main() {\n const schema = await readSchema(opts.schemaPath)\n\n const typeGenerator = new TypeGenerator(schema)\n const schemaTypes = await maybeFormatCode(\n [typeGenerator.generateSchemaTypes(), TypeGenerator.generateKnownTypes()].join('\\n').trim(),\n opts.prettierConfig,\n )\n const resolver = getResolver()\n\n parentPort?.postMessage({\n type: 'schema',\n schema: schemaTypes,\n filename: 'schema.json',\n length: schema.length,\n } satisfies TypegenGenerateTypesWorkerMessage)\n\n const queries = findQueriesInPath({\n path: opts.searchPath,\n resolver,\n })\n\n for await (const result of queries) {\n if (result.type === 'error') {\n parentPort?.postMessage({\n type: 'error',\n error: result.error,\n fatal: false,\n filename: result.filename,\n } satisfies TypegenGenerateTypesWorkerMessage)\n continue\n }\n $info(`Processing ${result.queries.length} queries in \"${result.filename}\"...`)\n\n const fileQueryTypes: {\n queryName: string\n query: string\n type: string\n typeName: string\n typeNode: TypeNode\n unknownTypeNodesGenerated: number\n typeNodesGenerated: number\n emptyUnionTypeNodesGenerated: number\n }[] = []\n for (const {name: queryName, result: query} of result.queries) {\n try {\n const ast = safeParseQuery(query)\n const queryTypes = typeEvaluate(ast, schema)\n\n const typeName = `${queryName}Result`\n const type = typeGenerator.generateTypeNodeTypes(typeName, queryTypes)\n const code = await maybeFormatCode(type.trim(), opts.prettierConfig)\n\n const queryTypeStats = walkAndCountQueryTypeNodeStats(queryTypes)\n fileQueryTypes.push({\n queryName,\n query,\n typeName,\n typeNode: queryTypes,\n type: code,\n unknownTypeNodesGenerated: queryTypeStats.unknownTypes,\n typeNodesGenerated: queryTypeStats.allTypes,\n emptyUnionTypeNodesGenerated: queryTypeStats.emptyUnions,\n })\n } catch (err) {\n parentPort?.postMessage({\n type: 'error',\n error: new Error(\n `Error generating types for query \"${queryName}\" in \"${result.filename}\": ${err.message}`,\n {cause: err},\n ),\n fatal: false,\n query,\n } satisfies TypegenGenerateTypesWorkerMessage)\n }\n }\n\n if (fileQueryTypes.length > 0) {\n $info(`Generated types for ${fileQueryTypes.length} queries in \"${result.filename}\"\\n`)\n parentPort?.postMessage({\n type: 'types',\n types: fileQueryTypes,\n filename: result.filename,\n } satisfies TypegenGenerateTypesWorkerMessage)\n }\n\n if (fileQueryTypes.length > 0 && opts.overloadClientMethods) {\n const typeMap = typeGenerator.generateQueryMap(fileQueryTypes)\n parentPort?.postMessage({\n type: 'typemap',\n filename: result.filename,\n typeMap,\n } satisfies TypegenGenerateTypesWorkerMessage)\n }\n }\n\n parentPort?.postMessage({\n type: 'complete',\n } satisfies TypegenGenerateTypesWorkerMessage)\n}\n\nfunction walkAndCountQueryTypeNodeStats(typeNode: TypeNode): {\n allTypes: number\n unknownTypes: number\n emptyUnions: number\n} {\n switch (typeNode.type) {\n case 'unknown': {\n return {allTypes: 1, unknownTypes: 1, emptyUnions: 0}\n }\n case 'array': {\n const acc = walkAndCountQueryTypeNodeStats(typeNode.of)\n acc.allTypes += 1 // count the array type itself\n return acc\n }\n case 'object': {\n // if the rest is unknown, we count it as one unknown type\n if (typeNode.rest && typeNode.rest.type === 'unknown') {\n return {allTypes: 2, unknownTypes: 1, emptyUnions: 0} // count the object type itself as well\n }\n\n const restStats = typeNode.rest\n ? walkAndCountQueryTypeNodeStats(typeNode.rest)\n : {allTypes: 1, unknownTypes: 0, emptyUnions: 0} // count the object type itself\n\n return Object.values(typeNode.attributes).reduce((acc, attribute) => {\n const {allTypes, unknownTypes, emptyUnions} = walkAndCountQueryTypeNodeStats(\n attribute.value,\n )\n return {\n allTypes: acc.allTypes + allTypes,\n unknownTypes: acc.unknownTypes + unknownTypes,\n emptyUnions: acc.emptyUnions + emptyUnions,\n }\n }, restStats)\n }\n case 'union': {\n if (typeNode.of.length === 0) {\n return {allTypes: 1, unknownTypes: 0, emptyUnions: 1}\n }\n\n return typeNode.of.reduce(\n (acc, type) => {\n const {allTypes, unknownTypes, emptyUnions} = walkAndCountQueryTypeNodeStats(type)\n return {\n allTypes: acc.allTypes + allTypes,\n unknownTypes: acc.unknownTypes + unknownTypes,\n emptyUnions: acc.emptyUnions + emptyUnions,\n }\n },\n {allTypes: 1, unknownTypes: 0, emptyUnions: 0}, // count the union type itself\n )\n }\n default: {\n return {allTypes: 1, unknownTypes: 0, emptyUnions: 0}\n }\n }\n}\n\nmain()\n"],"names":["createDebug","isMainThread","parentPort","_workerData","registerBabel","prettierFormat","readSchema","TypeGenerator","getResolver","findQueriesInPath","safeParseQuery","typeEvaluate"],"mappings":"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"}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@sanity/cli",
|
3
|
-
"version": "3.
|
3
|
+
"version": "3.53.0",
|
4
4
|
"description": "Sanity CLI tool for managing Sanity installations, managing plugins, schemas and datasets",
|
5
5
|
"keywords": [
|
6
6
|
"sanity",
|
@@ -58,9 +58,9 @@
|
|
58
58
|
"dependencies": {
|
59
59
|
"@babel/traverse": "^7.23.5",
|
60
60
|
"@sanity/client": "^6.21.1",
|
61
|
-
"@sanity/codegen": "3.
|
61
|
+
"@sanity/codegen": "3.53.0",
|
62
62
|
"@sanity/telemetry": "^0.7.7",
|
63
|
-
"@sanity/util": "3.
|
63
|
+
"@sanity/util": "3.53.0",
|
64
64
|
"chalk": "^4.1.2",
|
65
65
|
"debug": "^4.3.4",
|
66
66
|
"decompress": "^4.2.0",
|
@@ -77,12 +77,12 @@
|
|
77
77
|
},
|
78
78
|
"devDependencies": {
|
79
79
|
"@jest/globals": "^29.7.0",
|
80
|
-
"@repo/package.config": "3.
|
80
|
+
"@repo/package.config": "3.53.0",
|
81
81
|
"@rexxars/gitconfiglocal": "^3.0.1",
|
82
82
|
"@rollup/plugin-node-resolve": "^15.2.3",
|
83
83
|
"@sanity/eslint-config-studio": "^4.0.0",
|
84
84
|
"@sanity/generate-help-url": "^3.0.0",
|
85
|
-
"@sanity/types": "3.
|
85
|
+
"@sanity/types": "3.53.0",
|
86
86
|
"@types/babel__traverse": "^7.20.5",
|
87
87
|
"@types/configstore": "^5.0.1",
|
88
88
|
"@types/cpx": "^1.5.2",
|
@@ -117,7 +117,7 @@
|
|
117
117
|
"lodash": "^4.17.21",
|
118
118
|
"minimist": "^1.2.5",
|
119
119
|
"open": "^8.4.0",
|
120
|
-
"ora": "^
|
120
|
+
"ora": "^8.0.1",
|
121
121
|
"p-filter": "^2.1.0",
|
122
122
|
"p-timeout": "^4.0.0",
|
123
123
|
"preferred-pm": "^3.0.3",
|
@@ -135,5 +135,5 @@
|
|
135
135
|
"engines": {
|
136
136
|
"node": ">=18"
|
137
137
|
},
|
138
|
-
"gitHead": "
|
138
|
+
"gitHead": "d60dc6d2ae67d56ae680ebfffee2c66599924b4d"
|
139
139
|
}
|
@@ -439,10 +439,14 @@ export default async function initSanity(
|
|
439
439
|
}
|
440
440
|
const {chosen} = await getPackageManagerChoice(workDir, {interactive: false})
|
441
441
|
trace.log({step: 'selectPackageManager', selectedOption: chosen})
|
442
|
+
const packages = ['@sanity/vision@3', 'sanity@3', '@sanity/image-url@1', 'styled-components@6']
|
443
|
+
if (templateToUse === 'blog') {
|
444
|
+
packages.push('@sanity/icons')
|
445
|
+
}
|
442
446
|
await installNewPackages(
|
443
447
|
{
|
444
448
|
packageManager: chosen,
|
445
|
-
packages
|
449
|
+
packages,
|
446
450
|
},
|
447
451
|
{
|
448
452
|
output: context.output,
|
@@ -1277,8 +1281,7 @@ export default async function initSanity(
|
|
1277
1281
|
'# Warning: Do not add secrets (API keys and similar) to this file, as it source controlled!',
|
1278
1282
|
'# Use `.env.local` for any secrets, and ensure it is not added to source control',
|
1279
1283
|
].join('\n')
|
1280
|
-
const shouldPrependWarning = !existingEnv.includes(warningComment)
|
1281
|
-
// prepend warning comment to the env vars if one does not exist
|
1284
|
+
const shouldPrependWarning = filename !== '.env.local' && !existingEnv.includes(warningComment)
|
1282
1285
|
if (shouldPrependWarning) {
|
1283
1286
|
await fs.writeFile(fileOutputPath, `${warningComment}\n\n${updatedEnv}`, {
|
1284
1287
|
encoding: 'utf8',
|
@@ -37,16 +37,16 @@ export function promptForNextTemplate(prompt: CliPrompter): Promise<'clean' | 'b
|
|
37
37
|
message: 'Select project template to use',
|
38
38
|
type: 'list',
|
39
39
|
choices: [
|
40
|
-
{
|
41
|
-
value: 'clean',
|
42
|
-
name: 'Clean project with no predefined schema types',
|
43
|
-
},
|
44
40
|
{
|
45
41
|
value: 'blog',
|
46
42
|
name: 'Blog (schema)',
|
47
43
|
},
|
44
|
+
{
|
45
|
+
value: 'clean',
|
46
|
+
name: 'Clean project with no predefined schema types',
|
47
|
+
},
|
48
48
|
],
|
49
|
-
default: '
|
49
|
+
default: 'blog',
|
50
50
|
})
|
51
51
|
}
|
52
52
|
|
@@ -12,17 +12,18 @@ import {structureTool} from 'sanity/structure'
|
|
12
12
|
|
13
13
|
// Go to https://www.sanity.io/docs/api-versioning to learn how API versioning works
|
14
14
|
import {apiVersion, dataset, projectId} from ${hasSrcFolder ? "'./src/sanity/env'" : "'./sanity/env'"}
|
15
|
-
import {schema} from ${hasSrcFolder ? "'./src/sanity/
|
15
|
+
import {schema} from ${hasSrcFolder ? "'./src/sanity/schemaTypes'" : "'./sanity/schemaTypes'"}
|
16
|
+
import {structure} from ${hasSrcFolder ? "'./src/sanity/structure'" : "'./sanity/structure'"}
|
16
17
|
|
17
18
|
export default defineConfig({
|
18
19
|
basePath: ':basePath:',
|
19
20
|
projectId,
|
20
21
|
dataset,
|
21
|
-
// Add and edit the content schema in the './sanity/
|
22
|
+
// Add and edit the content schema in the './sanity/schemaTypes' folder
|
22
23
|
schema,
|
23
24
|
plugins: [
|
24
|
-
structureTool(),
|
25
|
-
// Vision is
|
25
|
+
structureTool({structure}),
|
26
|
+
// Vision is for querying with GROQ from inside the Studio
|
26
27
|
// https://www.sanity.io/docs/the-vision-plugin
|
27
28
|
visionTool({defaultApiVersion: apiVersion}),
|
28
29
|
],
|
@@ -59,7 +60,8 @@ export { metadata, viewport } from 'next-sanity/studio'
|
|
59
60
|
|
60
61
|
export default function StudioPage() {
|
61
62
|
return <NextStudio config={config} />
|
62
|
-
}
|
63
|
+
}
|
64
|
+
`
|
63
65
|
|
64
66
|
// Format today's date like YYYY-MM-DD
|
65
67
|
const envTS = `export const apiVersion =
|
@@ -103,6 +105,54 @@ const schemaJS = `export const schema = {
|
|
103
105
|
}
|
104
106
|
`
|
105
107
|
|
108
|
+
const blogStructureTS = `import type {StructureResolver} from 'sanity/structure'
|
109
|
+
|
110
|
+
// https://www.sanity.io/docs/structure-builder-cheat-sheet
|
111
|
+
export const structure: StructureResolver = (S) =>
|
112
|
+
S.list()
|
113
|
+
.title('Blog')
|
114
|
+
.items([
|
115
|
+
S.documentTypeListItem('post').title('Posts'),
|
116
|
+
S.documentTypeListItem('category').title('Categories'),
|
117
|
+
S.documentTypeListItem('author').title('Authors'),
|
118
|
+
S.divider(),
|
119
|
+
...S.documentTypeListItems().filter(
|
120
|
+
(item) => item.getId() && !['post', 'category', 'author'].includes(item.getId()!),
|
121
|
+
),
|
122
|
+
])
|
123
|
+
`
|
124
|
+
|
125
|
+
const blogStructureJS = `// https://www.sanity.io/docs/structure-builder-cheat-sheet
|
126
|
+
export const structure = (S) =>
|
127
|
+
S.list()
|
128
|
+
.title('Blog')
|
129
|
+
.items([
|
130
|
+
S.documentTypeListItem('post').title('Posts'),
|
131
|
+
S.documentTypeListItem('category').title('Categories'),
|
132
|
+
S.documentTypeListItem('author').title('Authors'),
|
133
|
+
S.divider(),
|
134
|
+
...S.documentTypeListItems().filter(
|
135
|
+
(item) => item.getId() && !['post', 'category', 'author'].includes(item.getId()),
|
136
|
+
),
|
137
|
+
])
|
138
|
+
`
|
139
|
+
|
140
|
+
const structureTS = `import type {StructureResolver} from 'sanity/structure'
|
141
|
+
|
142
|
+
// https://www.sanity.io/docs/structure-builder-cheat-sheet
|
143
|
+
export const structure: StructureResolver = (S) =>
|
144
|
+
S.list()
|
145
|
+
.title('Content')
|
146
|
+
.items(S.documentTypeListItems())
|
147
|
+
`
|
148
|
+
|
149
|
+
const structureJS = `// https://www.sanity.io/docs/structure-builder-cheat-sheet
|
150
|
+
export const structure = (S) =>
|
151
|
+
S.list()
|
152
|
+
.title('Content')
|
153
|
+
.items(S.documentTypeListItems())
|
154
|
+
`
|
155
|
+
|
106
156
|
const client = `import { createClient } from 'next-sanity'
|
107
157
|
|
108
158
|
import { apiVersion, dataset, projectId } from '../env'
|
@@ -146,17 +196,8 @@ export const sanityFolder = (
|
|
146
196
|
useTypeScript: boolean,
|
147
197
|
template?: 'clean' | 'blog',
|
148
198
|
): FolderStructure => {
|
149
|
-
|
150
|
-
|
199
|
+
// Files used in both templates
|
151
200
|
const structure: FolderStructure = {
|
152
|
-
// eslint-disable-next-line no-nested-ternary
|
153
|
-
'schema.': useTypeScript
|
154
|
-
? isBlogTemplate
|
155
|
-
? blogSchemaTS
|
156
|
-
: schemaTS
|
157
|
-
: isBlogTemplate
|
158
|
-
? blogSchemaJS
|
159
|
-
: schemaJS,
|
160
201
|
'env.': useTypeScript ? envTS : envJS,
|
161
202
|
'lib': {
|
162
203
|
'client.': client,
|
@@ -164,8 +205,17 @@ export const sanityFolder = (
|
|
164
205
|
},
|
165
206
|
}
|
166
207
|
|
167
|
-
if (
|
168
|
-
structure.schemaTypes =
|
208
|
+
if (template === 'blog') {
|
209
|
+
structure.schemaTypes = {
|
210
|
+
...blogSchemaFolder,
|
211
|
+
'index.': useTypeScript ? blogSchemaTS : blogSchemaJS,
|
212
|
+
}
|
213
|
+
structure['structure.'] = useTypeScript ? blogStructureTS : blogStructureJS
|
214
|
+
} else {
|
215
|
+
structure.schemaTypes = {
|
216
|
+
'index.': useTypeScript ? schemaTS : schemaJS,
|
217
|
+
}
|
218
|
+
structure['structure.'] = useTypeScript ? structureTS : structureJS
|
169
219
|
}
|
170
220
|
|
171
221
|
return structure
|