const { makeKyselyHook } = require("kanel-kysely"); const { makePgTsGenerator } = require("kanel"); const { generateZodSchemas, makeGenerateZodSchemas } = require("kanel-zod"); const ignoredTables = ["schema_migrations"]; /** * Allows for injection of custom types from the mapping of `table.field` * @param {import("kanel").TypeMap} mappings * @returns {import("kanel").PreRenderHook} */ const specificTypes = (mappings) => { /** @type {import("kanel").PreRenderHook} */ return async (outputAcc, instantiatedConfig) => { const output = { ...outputAcc }; for (const path of Object.keys(output)) { const file = outputAcc[path]; const declarations = file.declarations.map((decl) => { const declaration = { ...decl }; if (declaration.declarationType === "interface") { for (const field of declaration.properties) { const key = `${declaration.name}.${field.name}`; if (mappings[key]) { field.typeName = mappings[key].name; declaration.typeImports = [ ...(declaration.typeImports || []), ...mappings[key].typeImports, ]; } } } return declaration; }); output[path] = { ...file, declarations, }; } return output; }; } const kanelZodCastRegex = /as unknown as z.Schema<(.*?)(Mutator|Initializer)>/; const zodItemInitializer = /^export const \w+ = z\.object/ /** * @type {import("kanel").PostRenderHook} * * Renames the type of the `as unknown as z.Schema` casts from `kanel-zod` to * to be compatible with `kanel-kysely`, turning * 1. `as unknown as z.Schema` into `as unknown as z.Schema` * 2. `as unknown as z.Schema` into `as unknown as z.Schema` */ function kanelKyselyZodCompatibilityHook(path, lines) { return lines.map((line) => { if (zodItemInitializer.test(line)) { const parts = line.split(" "); if (parts[2].includes("Initializer")) { const nome = parts[2].replace("Initializer", ""); parts[2] = "New" + nome[0].toUpperCase() + nome.slice(1) + "Schema"; return parts.join(" "); } if (parts[2].includes("Mutator")) { const nome = parts[2].replace("Mutator", ""); parts[2] = nome[0].toUpperCase() + nome.slice(1) + "UpdateSchema"; return parts.join(" "); } const nome = parts[2]; parts[2] = nome[0].toUpperCase() + nome.slice(1) + "Schema"; return parts.join(" "); } if (line.includes("as unknown as z.Schema")) { const replacedLine = line.replace( kanelZodCastRegex, (_, typeName, mutatorOrInitializer) => { if (!mutatorOrInitializer) { return `as unknown as z.Schema<${typeName}>`; } if (mutatorOrInitializer === "Mutator") { return `as unknown as z.Schema<${typeName}Update>`; } return `as unknown as z.Schema`; } ); return replacedLine; } return line; }); } /** @type {import('kanel').Config} */ module.exports = { connection: { host: "localhost", user: "postgres", database: "postgres", password: "rootpost", port: 5433, }, filter: (pgTable) => !ignoredTables.includes(pgTable.name), outputPath: "./src/schemas", generators: [ makePgTsGenerator({ customTypeMap: { "pg_catalog.tsvector": "string", "pg_catalog.bpchar": "string", 'pg_catalog.numeric': 'number', //"pg_catalog.json": "string", }, preRenderHooks: [ specificTypes({ "Annunci.caratteristiche": { name: "Caratteristiche", typeImports: [{ name: "Caratteristiche", path: "src/utils/kanel-types.ts", importAsType: true, isAbsolute: false, isDefault: false }], }, }), makeKyselyHook(), makeGenerateZodSchemas({ castToSchema: false }), ], }), ], postRenderHooks: [kanelKyselyZodCompatibilityHook], preDeleteOutputFolder: true, typescriptConfig: { enumStyle: "enum", }, };