UNPKG

@compas/code-gen

Version:

Generate various boring parts of your server

212 lines (176 loc) 6.52 kB
import { mkdirSync, rmSync, writeFileSync } from "fs"; import { AppError, isNil, pathJoin } from "@compas/stdlib"; import { apiClientGenerator } from "./api-client/generator.js"; import { crudEventsGenerate } from "./crud/events.js"; import { crudHandlersGenerate } from "./crud/handlers.js"; import { databaseGenerator } from "./database/generator.js"; import { fileContextConvertToOutputFiles } from "./file/context.js"; import { validateExperimentalStructure } from "./generated/experimental/validators.js"; import { openApiGenerate } from "./open-api/generator.js"; import { anyOfPreProcess } from "./processors/any-of.js"; import { crudTypesCreate } from "./processors/crud-types.js"; import { crudValidation } from "./processors/crud-validation.js"; import { docStringCleanup } from "./processors/doc-string.js"; import { modelKeyAddDateKeys, modelKeyAddPrimary, } from "./processors/model-keys.js"; import { modelNameValidation } from "./processors/model-name.js"; import { modelPartialInsertTypes, modelPartialOrderByTypes, modelPartialReturningTypes, modelPartialUpdateTypes, } from "./processors/model-partials.js"; import { modelQueryBuilderTypes, modelQueryResultTypes, } from "./processors/model-query.js"; import { modelRelationAddKeys, modelRelationBuildRelationInformationCache, modelRelationCheckAllRelations, } from "./processors/model-relation.js"; import { modelSortAllKeys, modelSortAllRelations, } from "./processors/model-sort.js"; import { modelWhereBuildWhereInformation, modelWhereBuildWhereTypes, } from "./processors/model-where.js"; import { objectExpansionExecute } from "./processors/object-expansion.js"; import { routeInvalidationsCheck } from "./processors/route-invalidation.js"; import { routeStructureCreate } from "./processors/route-structure.js"; import { routeTrieBuild } from "./processors/route-trie.js"; import { structureNameChecks } from "./processors/structure-name-checks.js"; import { structureCopyAndSort, structureValidateReferences, } from "./processors/structure.js"; import { routerGenerator } from "./router/generator.js"; import { structureGenerator } from "./structure/generator.js"; import { targetValidateCombinations } from "./target/validation.js"; import { typesGeneratorFinalize, typesGeneratorInit, } from "./types/generator.js"; import { validatorGeneratorGenerateBaseTypes } from "./validators/generator.js"; /** * @typedef {object} OutputFile * @property {string} contents * @property {string} relativePath */ /** * @typedef {object} GenerateContext * @property {import("@compas/stdlib").Logger} log * @property {import("./generated/common/types.js").ExperimentalGenerateOptions} options * @property {import("./generated/common/types.js").ExperimentalStructure} structure * @property {import("./file/context").GenerateFileMap} files */ /** * Execute the generators based on de provided Generator instance and included options. * * TODO: expand docs * * - flat structure, no resolved references * - Preprocess everything * - talk about caching * - targetLanguageSwitch & targetCustomSwitch * * @param {import("./generator").Generator} generator * @param {import("./generated/common/types").ExperimentalGenerateOptions} options * @returns {OutputFile[]} */ export function generateExecute(generator, options) { const validationResultStructure = validateExperimentalStructure( generator.internalStructure, ); if (validationResultStructure.error) { throw AppError.serverError({ message: "Static validation on the structure failed", error: validationResultStructure.error, }); } structureValidateReferences(generator.internalStructure); const structure = structureCopyAndSort(generator.internalStructure); const generateContext = { log: generator.logger, options: options, structure, files: new Map(), }; targetValidateCombinations(generateContext); structureGenerator(generateContext); structureNameChecks(generateContext); objectExpansionExecute(generateContext); modelNameValidation(generateContext); modelKeyAddPrimary(generateContext); modelKeyAddDateKeys(generateContext); modelRelationCheckAllRelations(generateContext); modelRelationAddKeys(generateContext); modelRelationBuildRelationInformationCache(generateContext); modelSortAllRelations(generateContext); modelSortAllKeys(generateContext); modelWhereBuildWhereInformation(generateContext); modelWhereBuildWhereTypes(generateContext); modelPartialReturningTypes(generateContext); modelPartialInsertTypes(generateContext); modelPartialUpdateTypes(generateContext); modelPartialOrderByTypes(generateContext); modelQueryBuilderTypes(generateContext); modelQueryResultTypes(generateContext); crudValidation(generateContext); crudTypesCreate(generateContext); routeInvalidationsCheck(generateContext); routeStructureCreate(generateContext); routeTrieBuild(generateContext); anyOfPreProcess(generateContext); docStringCleanup(generateContext); typesGeneratorInit(generateContext); databaseGenerator(generateContext); routerGenerator(generateContext); apiClientGenerator(generateContext); openApiGenerate(generateContext); crudEventsGenerate(generateContext); crudHandlersGenerate(generateContext); validatorGeneratorGenerateBaseTypes(generateContext); typesGeneratorFinalize(generateContext); const outputFiles = fileContextConvertToOutputFiles(generateContext); generateWriteOutputFiles(generateContext, outputFiles); return outputFiles; } /** * Write output files if an output directory is provided * * @param {GenerateContext} generateContext * @param {OutputFile[]} outputFiles */ export function generateWriteOutputFiles(generateContext, outputFiles) { if (isNil(generateContext.options.outputDirectory)) { return; } rmSync(generateContext.options.outputDirectory, { recursive: true, force: true, }); mkdirSync(generateContext.options.outputDirectory, { recursive: true, }); for (const file of outputFiles) { if (file.relativePath.includes("/")) { const subDirectory = file.relativePath.split("/").slice(0, -1).join("/"); mkdirSync( pathJoin(generateContext.options.outputDirectory, subDirectory), { recursive: true, }, ); } writeFileSync( pathJoin(generateContext.options.outputDirectory, file.relativePath), file.contents, "utf-8", ); } }