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
105 lines (104 loc) • 4.11 kB
JavaScript
"use strict";
var codegen = require("@sanity/codegen"), debug = require("debug"), groqJs = require("groq-js"), worker_threads = require("worker_threads");
function _interopDefaultCompat(e) {
return e && typeof e == "object" && "default" in e ? e : { default: e };
}
var debug__default = /* @__PURE__ */ _interopDefaultCompat(debug);
const $info = debug__default.default("sanity:codegen:generate:info");
if (worker_threads.isMainThread || !worker_threads.parentPort)
throw new Error("This module must be run as a worker thread");
const opts = worker_threads.workerData;
codegen.registerBabel();
async function main() {
var _a, _b, _c, _d, _e;
const schema = await codegen.readSchema(opts.schemaPath), typeGenerator = new codegen.TypeGenerator(schema), schemaTypes = [
typeGenerator.generateSchemaTypes(),
codegen.TypeGenerator.generateKnownTypes()
].join(`
`), resolver = codegen.getResolver();
(_a = worker_threads.parentPort) == null || _a.postMessage({
type: "schema",
schema: schemaTypes,
filename: "schema.json",
length: schema.length
});
const queries = codegen.findQueriesInPath({
path: opts.searchPath,
resolver
});
for await (const result of queries) {
if (result.type === "error") {
(_b = worker_threads.parentPort) == null || _b.postMessage({
type: "error",
error: result.error,
fatal: !1,
filename: result.filename
});
continue;
}
$info(`Processing ${result.queries.length} queries in "${result.filename}"...`);
const fileQueryTypes = [];
for (const { name: queryName, result: query } of result.queries)
try {
const ast = groqJs.parse(query), queryTypes = groqJs.typeEvaluate(ast, schema), type = typeGenerator.generateTypeNodeTypes(`${queryName}Result`, queryTypes), queryTypeStats = walkAndCountQueryTypeNodeStats(queryTypes);
fileQueryTypes.push({
queryName,
query,
type,
unknownTypeNodesGenerated: queryTypeStats.unknownTypes,
typeNodesGenerated: queryTypeStats.allTypes
});
} catch (err) {
(_c = worker_threads.parentPort) == null || _c.postMessage({
type: "error",
error: new Error(
`Error generating types for query "${queryName}" in "${result.filename}": ${err.message}`,
{ cause: err }
),
fatal: !1,
query
});
}
fileQueryTypes.length > 0 && ($info(`Generated types for ${fileQueryTypes.length} queries in "${result.filename}"
`), (_d = worker_threads.parentPort) == null || _d.postMessage({
type: "types",
types: fileQueryTypes,
filename: result.filename
}));
}
(_e = worker_threads.parentPort) == null || _e.postMessage({
type: "complete"
});
}
function walkAndCountQueryTypeNodeStats(typeNode) {
switch (typeNode.type) {
case "unknown":
return { allTypes: 1, unknownTypes: 1 };
case "array": {
const acc = walkAndCountQueryTypeNodeStats(typeNode.of);
return acc.allTypes += 1, acc;
}
case "object": {
if (typeNode.rest && typeNode.rest.type === "unknown")
return { allTypes: 2, unknownTypes: 1 };
const restStats = typeNode.rest ? walkAndCountQueryTypeNodeStats(typeNode.rest) : { allTypes: 1, unknownTypes: 0 };
return Object.values(typeNode.attributes).reduce((acc, attribute) => {
const { allTypes, unknownTypes } = walkAndCountQueryTypeNodeStats(attribute.value);
return { allTypes: acc.allTypes + allTypes, unknownTypes: acc.unknownTypes + unknownTypes };
}, restStats);
}
case "union":
return typeNode.of.reduce(
(acc, type) => {
const { allTypes, unknownTypes } = walkAndCountQueryTypeNodeStats(type);
return { allTypes: acc.allTypes + allTypes, unknownTypes: acc.unknownTypes + unknownTypes };
},
{ allTypes: 1, unknownTypes: 0 }
// count the union type itself
);
default:
return { allTypes: 1, unknownTypes: 0 };
}
}
main();
//# sourceMappingURL=typegenGenerate.js.map