67 lines
2.3 KiB
JavaScript
67 lines
2.3 KiB
JavaScript
import { readdir, readFile, writeFile } from "node:fs/promises";
|
|
import path from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
import { codegen } from "@graphql-codegen/core";
|
|
import { plugin as typedDocumentNodePlugin } from "@graphql-codegen/typed-document-node";
|
|
import { plugin as typescriptOperationsPlugin } from "@graphql-codegen/typescript-operations";
|
|
import { plugin as typescriptPlugin } from "@graphql-codegen/typescript";
|
|
import { buildASTSchema, parse } from "graphql";
|
|
import { parse as parseYaml } from "yaml";
|
|
|
|
const frontendRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
const configPath = path.join(frontendRoot, "codegen.yml");
|
|
const config = parseYaml(await readFile(configPath, "utf8"));
|
|
const schemaDocument = parse(await readFile(path.resolve(frontendRoot, config.schema), "utf8"));
|
|
const outputEntries = Object.entries(config.generates ?? {});
|
|
|
|
if (outputEntries.length !== 1) {
|
|
throw new Error(`Expected one GraphQL Codegen output in ${configPath}`);
|
|
}
|
|
|
|
const [outputName, outputConfig] = outputEntries[0];
|
|
const outputPath = path.resolve(frontendRoot, outputName);
|
|
const sourceRoot = path.join(frontendRoot, "src");
|
|
const plugins = outputConfig.plugins.map((plugin) =>
|
|
typeof plugin === "string" ? { [plugin]: {} } : plugin,
|
|
);
|
|
|
|
async function findGraphqlFiles(directory) {
|
|
const entries = await readdir(directory, { withFileTypes: true });
|
|
const nestedFiles = await Promise.all(
|
|
entries.map((entry) => {
|
|
const entryPath = path.join(directory, entry.name);
|
|
if (entry.isDirectory()) return findGraphqlFiles(entryPath);
|
|
return entry.isFile() && entry.name.endsWith(".graphql") ? [entryPath] : [];
|
|
}),
|
|
);
|
|
return nestedFiles.flat();
|
|
}
|
|
|
|
const documents = await Promise.all(
|
|
(await findGraphqlFiles(sourceRoot))
|
|
.sort()
|
|
.map(async (location) => ({
|
|
location,
|
|
document: parse(await readFile(location, "utf8")),
|
|
})),
|
|
);
|
|
|
|
const pluginMap = {
|
|
typescript: { plugin: typescriptPlugin },
|
|
"typescript-operations": { plugin: typescriptOperationsPlugin },
|
|
"typed-document-node": { plugin: typedDocumentNodePlugin },
|
|
};
|
|
|
|
const generated = await codegen({
|
|
filename: outputPath,
|
|
schema: schemaDocument,
|
|
schemaAst: buildASTSchema(schemaDocument),
|
|
documents,
|
|
config: {},
|
|
plugins,
|
|
pluginMap,
|
|
});
|
|
|
|
await writeFile(outputPath, generated);
|