sanity
Version:
Sanity is a real-time content infrastructure with a scalable, hosted backend featuring a Graph Oriented Query Language (GROQ), asset pipelines and fast edge caches
117 lines (114 loc) • 4.5 kB
JavaScript
import { open, constants } from "node:fs/promises";
import { join, dirname } from "node:path";
import { readConfig } from "@sanity/codegen";
import readPkgUp from "read-pkg-up";
import { Worker } from "worker_threads";
import { defineTrace } from "@sanity/telemetry";
const TypesGeneratedTrace = defineTrace({
name: "Types Generated",
version: 0,
description: "Trace emitted when generating TypeScript types for queries"
}), generatedFileWarning = `/**
* ---------------------------------------------------------------------------------
* This file has been generated by Sanity TypeGen.
* Command: \`sanity typegen generate\`
*
* Any modifications made directly to this file will be overwritten the next time
* the TypeScript definitions are generated. Please make changes to the Sanity
* schema definitions and/or GROQ queries if you need to update these types.
*
* For more information on how to use Sanity TypeGen, visit the official documentation:
* https://www.sanity.io/docs/sanity-typegen
* ---------------------------------------------------------------------------------
*/
`;
async function typegenGenerateAction(args, context) {
var _a;
const flags = args.extOptions, { output, workDir, telemetry } = context, trace = telemetry.trace(TypesGeneratedTrace);
trace.start();
const codegenConfig = await readConfig(flags.configPath || "sanity-typegen.json"), rootPkgPath = (_a = readPkgUp.sync({ cwd: __dirname })) == null ? void 0 : _a.path;
if (!rootPkgPath)
throw new Error("Could not find the root directory for the `sanity` package");
const workerPath = join(
dirname(rootPkgPath),
"lib",
"_internal",
"cli",
"threads",
"typegenGenerate.js"
), spinner = output.spinner({}).start("Generating types"), worker = new Worker(workerPath, {
workerData: {
workDir,
schemaPath: codegenConfig.schema,
searchPath: codegenConfig.path
},
// eslint-disable-next-line no-process-env
env: process.env
}), typeFile = await open(
join(process.cwd(), codegenConfig.generates),
// eslint-disable-next-line no-bitwise
constants.O_TRUNC | constants.O_CREAT | constants.O_WRONLY
);
typeFile.write(generatedFileWarning);
const stats = {
queryFilesCount: 0,
errors: 0,
queriesCount: 0,
schemaTypesCount: 0,
unknownTypeNodesGenerated: 0,
typeNodesGenerated: 0,
size: 0
};
await new Promise((resolve, reject) => {
worker.addListener("message", (msg) => {
if (msg.type === "error") {
if (msg.fatal) {
trace.error(msg.error), reject(msg.error);
return;
}
const errorMessage = msg.filename ? `${msg.error.message} in "${msg.filename}"` : msg.error.message;
spinner.fail(errorMessage), stats.errors++;
return;
}
if (msg.type === "complete") {
resolve();
return;
}
let fileTypeString = `// Source: ${msg.filename}
`;
if (msg.type === "schema") {
stats.schemaTypesCount += msg.length, fileTypeString += `${msg.schema}
`, typeFile.write(fileTypeString);
return;
}
stats.queryFilesCount++;
for (const {
queryName,
query,
type,
typeNodesGenerated,
unknownTypeNodesGenerated
} of msg.types)
fileTypeString += `// Variable: ${queryName}
`, fileTypeString += `// Query: ${query.replace(/(\r\n|\n|\r)/gm, "")}
`, fileTypeString += `${type}
`, stats.queriesCount++, stats.typeNodesGenerated += typeNodesGenerated, stats.unknownTypeNodesGenerated += unknownTypeNodesGenerated;
typeFile.write(`${fileTypeString}
`), stats.size += Buffer.byteLength(fileTypeString);
}), worker.addListener("error", reject);
}), typeFile.close(), trace.log({
outputSize: stats.size,
queriesCount: stats.queriesCount,
schemaTypesCount: stats.schemaTypesCount,
queryFilesCount: stats.queryFilesCount,
filesWithErrors: stats.errors,
typeNodesGenerated: stats.typeNodesGenerated,
unknownTypeNodesGenerated: stats.unknownTypeNodesGenerated
}), trace.complete(), stats.errors > 0 && spinner.warn(`Encountered errors in ${stats.errors} files while generating types`), spinner.succeed(
`Generated TypeScript types for ${stats.schemaTypesCount} schema types and ${stats.queriesCount} GROQ queries in ${stats.queryFilesCount} files into: ${codegenConfig.generates}`
);
}
export {
typegenGenerateAction as default
};
//# sourceMappingURL=generateAction.js.map