UNPKG

drizzle-prisma-generator

Version:
877 lines (866 loc) 33.2 kB
#!/usr/bin/env node "use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var src_exports = {}; __export(src_exports, { default: () => src_default, generator: () => generator }); module.exports = __toCommonJS(src_exports); // src/globals/index.ts var generatorName = "Drizzle Prisma generator"; var defaultPath = "./src/drizzle/"; // src/index.ts var import_generator_helper4 = require("@prisma/generator-helper"); var import_path2 = __toESM(require("path")); // package.json var version = "0.1.7"; // src/util/escape/index.ts var backslashes = new RegExp(/\\/g); var s = (src, container = "'") => src.replace(backslashes, "\\\\").replace(new RegExp(container, "g"), `\\${container}`); // src/util/extract-many-to-many-models/index.ts var sorted = (list, sortFunction) => { const newList = [...list]; newList.sort(sortFunction); return newList; }; var generateModels = (manyToManyFields, models, manyToManyTables = []) => { const manyFirst = manyToManyFields.shift(); if (!manyFirst) { return manyToManyTables; } const manySecond = manyToManyFields.find((field) => field.relationName === manyFirst.relationName); if (!manySecond) { return manyToManyTables; } manyToManyTables.push({ dbName: `_${manyFirst.relationName}`, name: manyFirst.relationName || "", primaryKey: null, uniqueFields: [], uniqueIndexes: [], fields: generateJoinFields([manyFirst, manySecond], models) }); return generateModels( manyToManyFields.filter((field) => field.relationName !== manyFirst.relationName), models, manyToManyTables ); }; var generateJoinFields = (fields, models) => { const [A, B] = sorted(fields, (a, b) => a.type.localeCompare(b.type)); const aTableName = B.type; const bTableName = A.type; const manyTableName = `${A.type}To${B.type}`; A.isList = true; A.type = `${bTableName}To${aTableName}`; A.relationName = `${aTableName}To${manyTableName}`; A.relationFromFields = []; A.relationToFields = []; B.isList = true; B.type = `${bTableName}To${aTableName}`; B.relationName = `${bTableName}To${manyTableName}`; A.relationFromFields = []; A.relationToFields = []; return [ { name: `${aTableName}Id`, dbName: "A", type: getJoinIdType(aTableName, models), kind: "scalar", isRequired: true, isList: false, isUnique: false, isId: false, isReadOnly: true, hasDefaultValue: false }, { name: aTableName, type: aTableName, kind: "object", isRequired: true, isList: false, isUnique: false, isId: false, isReadOnly: true, hasDefaultValue: false, relationName: `${aTableName}To${manyTableName}`, relationFromFields: [`${aTableName}Id`], relationToFields: [getJoinIdName(aTableName, models)] }, { name: `${bTableName}Id`, dbName: "B", type: getJoinIdType(bTableName, models), kind: "scalar", isRequired: true, isList: false, isUnique: false, isId: false, isReadOnly: true, hasDefaultValue: false }, { name: bTableName, type: bTableName, kind: "object", isRequired: true, isList: false, isUnique: false, isId: false, isReadOnly: true, hasDefaultValue: false, relationName: `${bTableName}To${manyTableName}`, relationFromFields: [`${bTableName}Id`], relationToFields: [getJoinIdName(bTableName, models)] } ]; }; var getJoinIdType = (typeName, models) => { const joinedModel = models.find((m) => m.name === typeName); if (!joinedModel) { throw new Error("Could not find referenced model of many-to-many relation"); } const idField = joinedModel.fields.find((f) => f.isId); if (!idField) throw new Error("No ID field on referenced model of many-to-many relation"); return idField.type; }; var getJoinIdName = (typeName, models) => { const joinedModel = models.find((m) => m.name === typeName); if (!joinedModel) { throw new Error("Could not find referenced model of many-to-many relation"); } const idField = joinedModel.fields.find((f) => f.isId); if (!idField) throw new Error("No ID field on referenced model of many-to-many relation"); return idField.name; }; var filterManyToManyRelationFields = (models) => { const fields = models.flatMap((model) => model.fields); const relationFields = fields.filter( (field) => !!field.relationName ); const nonManyToManyRelationNames = relationFields.filter((field) => !field.isList).map((field) => field.relationName); const notManyToMany = new Set(nonManyToManyRelationNames); return relationFields.filter((field) => !notManyToMany.has(field.relationName)); }; var extractManyToManyModels = (models) => { const manyToManyFields = filterManyToManyRelationFields(models); if (!manyToManyFields.length) return []; return generateModels(manyToManyFields, models, []); }; // src/util/generators/mysql.ts var import_generator_helper = require("@prisma/generator-helper"); var mySqlImports = /* @__PURE__ */ new Set(["mysqlTable"]); var drizzleImports = /* @__PURE__ */ new Set([]); var prismaToDrizzleType = (type, colDbName, prismaEnum) => { if (prismaEnum) { mySqlImports.add("mysqlEnum"); return `mysqlEnum('${colDbName}', [${prismaEnum.values.map((val) => `'${val.dbName ?? val.name}'`).join(", ")}])`; } switch (type.toLowerCase()) { case "bigint": mySqlImports.add("bigint"); return `bigint('${colDbName}', { mode: 'bigint' })`; case "boolean": mySqlImports.add("boolean"); return `boolean('${colDbName}')`; case "bytes": throw new import_generator_helper.GeneratorError("Drizzle ORM doesn't support binary data type for MySQL"); case "datetime": mySqlImports.add("datetime"); return `datetime('${colDbName}', { fsp: 3 })`; case "decimal": mySqlImports.add("decimal"); return `decimal('${colDbName}', { precision: 65, scale: 30 })`; case "float": mySqlImports.add("double"); return `double('${colDbName}')`; case "json": mySqlImports.add("json"); return `json('${colDbName}')`; case "int": mySqlImports.add("int"); return `int('${colDbName}')`; case "string": mySqlImports.add("varchar"); return `varchar('${colDbName}', { length: 191 })`; default: return void 0; } }; var addColumnModifiers = (field, column) => { if (field.isRequired) column = column + `.notNull()`; if (field.isId) column = column + `.primaryKey()`; if (field.isUnique) column = column + `.unique()`; if (field.default) { const defVal = field.default; switch (typeof defVal) { case "number": case "string": case "symbol": case "boolean": column = column + `.default(${JSON.stringify(defVal)})`; break; case "object": if (Array.isArray(defVal)) { column = column + `.default([${defVal.map((e) => JSON.stringify(e)).join(", ")}])`; break; } const value = defVal; if (value.name === "now") { column = column + `.default(sql\`CURRENT_TIMESTAMP\`)`; break; } if (value.name === "autoincrement") { column = column + `.autoincrement()`; break; } if (value.name === "dbgenerated") { column = column + `.default(sql\`${s(value.args[0], "`")}\`)`; drizzleImports.add("sql"); break; } if (/^uuid\([0-9]*\)$/.test(value.name)) { column = column + `.default(sql\`uuid()\`)`; drizzleImports.add("sql"); break; } const stringified = `${value.name}${value.args.length ? "(" + value.args.map((e) => String(e)).join(", ") + ")" : value.name.endsWith(")") ? "" : "()"}`; const sequel = `sql\`${s(stringified, "`")}\``; drizzleImports.add("sql"); column = column + `.default(${sequel})`; break; } } return column; }; var prismaToDrizzleColumn = (field, enums) => { const colDbName = s(field.dbName ?? field.name); let column = ` ${field.name}: `; const drizzleType = prismaToDrizzleType( field.type, colDbName, field.kind === "enum" ? enums.find((e) => e.name === field.type) : void 0 ); if (!drizzleType) return void 0; column = column + drizzleType; column = addColumnModifiers(field, column); return column; }; var generateMySqlSchema = (options) => { const { models, enums } = options.dmmf.datamodel; const clonedModels = JSON.parse(JSON.stringify(models)); const manyToManyModels = extractManyToManyModels(clonedModels); const modelsWithImplicit = [...clonedModels, ...manyToManyModels]; const tables = []; const rqb = []; for (const schemaTable of modelsWithImplicit) { const tableDbName = s(schemaTable.dbName ?? schemaTable.name); const columnFields = Object.fromEntries( schemaTable.fields.map((e) => [e.name, prismaToDrizzleColumn(e, enums)]).filter((e) => e[1] !== void 0) ); const indexes = []; const relFields = schemaTable.fields.filter((field) => field.relationToFields && field.relationFromFields); const relations = relFields.map((field) => { if (!field?.relationFromFields?.length) return void 0; const fkeyName = s(`${schemaTable.dbName ?? schemaTable.name}_${field.dbName ?? field.name}_fkey`); let deleteAction; switch (field.relationOnDelete) { case void 0: case "Cascade": deleteAction = "cascade"; break; case "SetNull": deleteAction = "set null"; break; case "SetDefault": deleteAction = "set default"; break; case "Restrict": deleteAction = "restrict"; break; case "NoAction": deleteAction = "no action"; break; default: throw new import_generator_helper.GeneratorError(`Unknown delete action on relation ${fkeyName}: ${field.relationOnDelete}`); } mySqlImports.add("foreignKey"); return ` '${fkeyName}': foreignKey({ name: '${fkeyName}', columns: [${field.relationFromFields.map((rel) => `${schemaTable.name}.${rel}`).join(", ")}], foreignColumns: [${field.relationToFields.map((rel) => `${field.type}.${rel}`).join(", ")}] })${deleteAction && deleteAction !== "no action" ? ` .onDelete('${deleteAction}')` : ""} .onUpdate('cascade')`; }).filter((e) => e !== void 0); indexes.push(...relations); if (schemaTable.uniqueIndexes.length) { mySqlImports.add("uniqueIndex"); const uniques = schemaTable.uniqueIndexes.map((idx) => { const idxName = s(idx.name ?? `${schemaTable.name}_${idx.fields.join("_")}_key`); return ` '${idx.name ? idxName : `${idxName.slice(0, idxName.length - 4)}_unique_idx`}': uniqueIndex('${idxName}') .on(${idx.fields.map((f) => `${schemaTable.name}.${f}`).join(", ")})`; }); indexes.push(...uniques); } if (schemaTable.primaryKey) { mySqlImports.add("primaryKey"); const pk = schemaTable.primaryKey; const pkName = s(pk.name ?? `${schemaTable.name}_cpk`); const pkField = ` '${pkName}': primaryKey({ name: '${pkName}', columns: [${pk.fields.map((f) => `${schemaTable.name}.${f}`).join(", ")}] })`; indexes.push(pkField); } const table = `export const ${schemaTable.name} = mysqlTable('${tableDbName}', { ${Object.values(columnFields).join(",\n")} }${indexes.length ? `, (${schemaTable.name}) => ({ ${indexes.join(",\n")} })` : ""});`; tables.push(table); if (!relFields.length) continue; drizzleImports.add("relations"); const relationArgs = /* @__PURE__ */ new Set(); const rqbFields = relFields.map((field) => { relationArgs.add(field.relationFromFields?.length ? "one" : "many"); const relName = s(field.relationName ?? ""); return ` ${field.name}: ${field.relationFromFields?.length ? `one(${field.type}, { relationName: '${relName}', fields: [${field.relationFromFields.map((e) => `${schemaTable.name}.${e}`).join(", ")}], references: [${field.relationToFields.map((e) => `${field.type}.${e}`).join(", ")}] })` : `many(${field.type}, { relationName: '${relName}' })`}`; }).join(",\n"); const argString = Array.from(relationArgs.values()).join(", "); const rqbRelation = `export const ${schemaTable.name}Relations = relations(${schemaTable.name}, ({ ${argString} }) => ({ ${rqbFields} }));`; rqb.push(rqbRelation); } const drizzleImportsArr = Array.from(drizzleImports.values()).sort((a, b) => a.localeCompare(b)); const drizzleImportsStr = drizzleImportsArr.length ? `import { ${drizzleImportsArr.join(", ")} } from 'drizzle-orm'` : void 0; const mySqlImportsArr = Array.from(mySqlImports.values()).sort((a, b) => a.localeCompare(b)); const mySqlImportsStr = mySqlImportsArr.length ? `import { ${mySqlImportsArr.join(", ")} } from 'drizzle-orm/mysql-core'` : void 0; let importsStr = [drizzleImportsStr, mySqlImportsStr].filter((e) => e !== void 0).join("\n"); if (!importsStr.length) importsStr = void 0; const output = [importsStr, ...tables, ...rqb].filter((e) => e !== void 0).join("\n\n"); return output; }; // src/util/generators/pg.ts var import_generator_helper2 = require("@prisma/generator-helper"); var pgImports = /* @__PURE__ */ new Set(); var drizzleImports2 = /* @__PURE__ */ new Set(); pgImports.add("pgTable"); var prismaToDrizzleType2 = (type, colDbName, defVal) => { switch (type.toLowerCase()) { case "bigint": pgImports.add("bigint"); return `bigint('${colDbName}', { mode: 'bigint' })`; case "boolean": pgImports.add("boolean"); return `boolean('${colDbName}')`; case "bytes": throw new import_generator_helper2.GeneratorError("Drizzle ORM doesn't support binary data type for PostgreSQL"); case "datetime": pgImports.add("timestamp"); return `timestamp('${colDbName}', { precision: 3 })`; case "decimal": pgImports.add("decimal"); return `decimal('${colDbName}', { precision: 65, scale: 30 })`; case "float": pgImports.add("doublePrecision"); return `doublePrecision('${colDbName}')`; case "json": pgImports.add("jsonb"); return `jsonb('${colDbName}')`; case "int": if (defVal === "autoincrement") { pgImports.add("serial"); return `serial('${colDbName}')`; } pgImports.add("integer"); return `integer('${colDbName}')`; case "string": pgImports.add("text"); return `text('${colDbName}')`; default: return void 0; } }; var addColumnModifiers2 = (field, column) => { if (field.isList) column = column + `.array()`; if (field.isRequired) column = column + `.notNull()`; if (field.isId) column = column + `.primaryKey()`; if (field.isUnique) column = column + `.unique()`; if (field.default) { const defVal = field.default; switch (typeof defVal) { case "number": case "string": case "symbol": case "boolean": column = column + `.default(${JSON.stringify(defVal)})`; break; case "object": if (Array.isArray(defVal)) { column = column + `.default([${defVal.map((e) => JSON.stringify(e)).join(", ")}])`; break; } const value = defVal; if (value.name === "now") { column = column + `.defaultNow()`; break; } if (value.name === "autoincrement") { break; } if (value.name === "dbgenerated") { column = column + `.default(sql\`${s(value.args[0], "`")}\`)`; drizzleImports2.add("sql"); break; } if (/^uuid\([0-9]*\)$/.test(value.name)) { column = column + `.default(sql\`uuid()\`)`; drizzleImports2.add("sql"); break; } const stringified = `${value.name}${value.args.length ? "(" + value.args.map((e) => String(e)).join(", ") + ")" : value.name.endsWith(")") ? "" : "()"}`; const sequel = `sql\`${s(stringified, "`")}\``; drizzleImports2.add("sql"); column = column + `.default(${sequel})`; break; } } return column; }; var prismaToDrizzleColumn2 = (field) => { const colDbName = s(field.dbName ?? field.name); let column = ` ${field.name}: `; if (field.kind === "enum") { column = column + `${field.type}('${colDbName}')`; } else { const defVal = typeof field.default === "object" && !Array.isArray(field.default) ? field.default.name : void 0; const drizzleType = prismaToDrizzleType2(field.type, colDbName, defVal); if (!drizzleType) return void 0; column = column + drizzleType; } column = addColumnModifiers2(field, column); return column; }; var generatePgSchema = (options) => { const { models, enums } = options.dmmf.datamodel; const clonedModels = JSON.parse(JSON.stringify(models)); const manyToManyModels = extractManyToManyModels(clonedModels); const modelsWithImplicit = [...clonedModels, ...manyToManyModels]; const pgEnums = []; for (const schemaEnum of enums) { if (!schemaEnum.values.length) continue; const enumDbName = s(schemaEnum.dbName ?? schemaEnum.name); pgImports.add("pgEnum"); pgEnums.push( `export const ${schemaEnum.name} = pgEnum('${enumDbName}', [${schemaEnum.values.map((e) => `'${e.dbName ?? e.name}'`).join(", ")}])` ); } const tables = []; const rqb = []; for (const schemaTable of modelsWithImplicit) { const tableDbName = s(schemaTable.dbName ?? schemaTable.name); const columnFields = Object.fromEntries( schemaTable.fields.map((e) => [e.name, prismaToDrizzleColumn2(e)]).filter((e) => e[1] !== void 0) ); const indexes = []; const relFields = schemaTable.fields.filter((field) => field.relationToFields && field.relationFromFields); const relations = relFields.map((field) => { if (!field?.relationFromFields?.length) return void 0; const fkeyName = s(`${schemaTable.dbName ?? schemaTable.name}_${field.dbName ?? field.name}_fkey`); let deleteAction; switch (field.relationOnDelete) { case void 0: case "Cascade": deleteAction = "cascade"; break; case "SetNull": deleteAction = "set null"; break; case "SetDefault": deleteAction = "set default"; break; case "Restrict": deleteAction = "restrict"; break; case "NoAction": deleteAction = "no action"; break; default: throw new import_generator_helper2.GeneratorError(`Unknown delete action on relation ${fkeyName}: ${field.relationOnDelete}`); } pgImports.add("foreignKey"); return ` '${fkeyName}': foreignKey({ name: '${fkeyName}', columns: [${field.relationFromFields.map((rel) => `${schemaTable.name}.${rel}`).join(", ")}], foreignColumns: [${field.relationToFields.map((rel) => `${field.type}.${rel}`).join(", ")}] })${deleteAction && deleteAction !== "no action" ? ` .onDelete('${deleteAction}')` : ""} .onUpdate('cascade')`; }).filter((e) => e !== void 0); indexes.push(...relations); if (schemaTable.uniqueIndexes.length) { pgImports.add("uniqueIndex"); const uniques = schemaTable.uniqueIndexes.map((idx) => { const idxName = s(idx.name ?? `${schemaTable.name}_${idx.fields.join("_")}_key`); return ` '${idx.name ? idxName : `${idxName.slice(0, idxName.length - 4)}_unique_idx`}': uniqueIndex('${idxName}') .on(${idx.fields.map((f) => `${schemaTable.name}.${f}`).join(", ")})`; }); indexes.push(...uniques); } if (schemaTable.primaryKey) { pgImports.add("primaryKey"); const pk = schemaTable.primaryKey; const pkName = s(pk.name ?? `${schemaTable.name}_cpk`); const pkField = ` '${pkName}': primaryKey({ name: '${pkName}', columns: [${pk.fields.map((f) => `${schemaTable.name}.${f}`).join(", ")}] })`; indexes.push(pkField); } const table = `export const ${schemaTable.name} = pgTable('${tableDbName}', { ${Object.values(columnFields).join(",\n")} }${indexes.length ? `, (${schemaTable.name}) => ({ ${indexes.join(",\n")} })` : ""});`; tables.push(table); if (!relFields.length) continue; drizzleImports2.add("relations"); const relationArgs = /* @__PURE__ */ new Set(); const rqbFields = relFields.map((field) => { relationArgs.add(field.relationFromFields?.length ? "one" : "many"); const relName = s(field.relationName ?? ""); return ` ${field.name}: ${field.relationFromFields?.length ? `one(${field.type}, { relationName: '${relName}', fields: [${field.relationFromFields.map((e) => `${schemaTable.name}.${e}`).join(", ")}], references: [${field.relationToFields.map((e) => `${field.type}.${e}`).join(", ")}] })` : `many(${field.type}, { relationName: '${relName}' })`}`; }).join(",\n"); const argString = Array.from(relationArgs.values()).join(", "); const rqbRelation = `export const ${schemaTable.name}Relations = relations(${schemaTable.name}, ({ ${argString} }) => ({ ${rqbFields} }));`; rqb.push(rqbRelation); } const drizzleImportsArr = Array.from(drizzleImports2.values()).sort((a, b) => a.localeCompare(b)); const drizzleImportsStr = drizzleImportsArr.length ? `import { ${drizzleImportsArr.join(", ")} } from 'drizzle-orm'` : void 0; const pgImportsArr = Array.from(pgImports.values()).sort((a, b) => a.localeCompare(b)); const pgImportsStr = pgImportsArr.length ? `import { ${pgImportsArr.join(", ")} } from 'drizzle-orm/pg-core'` : void 0; let importsStr = [drizzleImportsStr, pgImportsStr].filter((e) => e !== void 0).join("\n"); if (!importsStr.length) importsStr = void 0; const output = [importsStr, ...pgEnums, ...tables, ...rqb].filter((e) => e !== void 0).join("\n\n"); return output; }; // src/util/generators/sqlite.ts var import_generator_helper3 = require("@prisma/generator-helper"); var sqliteImports = /* @__PURE__ */ new Set(["sqliteTable"]); var drizzleImports3 = /* @__PURE__ */ new Set([]); var prismaToDrizzleType3 = (type, colDbName) => { switch (type.toLowerCase()) { case "bigint": sqliteImports.add("int"); return `int('${colDbName}')`; case "boolean": sqliteImports.add("int"); return `int('${colDbName}', { mode: 'boolean' })`; case "bytes": sqliteImports.add("blob"); return `blob('${colDbName}', { mode: 'buffer' })`; case "datetime": sqliteImports.add("numeric"); return `numeric('${colDbName}')`; case "decimal": sqliteImports.add("numeric"); return `numeric('${colDbName}')`; case "float": sqliteImports.add("real"); return `real('${colDbName}')`; case "json": sqliteImports.add("text"); return `text('${colDbName}', { mode: 'json' })`; case "int": sqliteImports.add("int"); return `int('${colDbName}')`; case "string": sqliteImports.add("text"); return `text('${colDbName}')`; default: return void 0; } }; var addColumnModifiers3 = (field, column) => { if (field.isRequired) column = column + `.notNull()`; if (field.isId) column = column + `.primaryKey()`; if (field.isUnique) column = column + `.unique()`; if (field.default) { const defVal = field.default; switch (typeof defVal) { case "number": case "string": case "symbol": case "boolean": column = column + `.default(${JSON.stringify(defVal)})`; break; case "object": if (Array.isArray(defVal)) { column = column + `.default([${defVal.map((e) => JSON.stringify(e)).join(", ")}])`; break; } const value = defVal; if (value.name === "now") { column = column + `.default(sql\`DATE('now')\`)`; break; } if (value.name === "autoincrement") { break; } if (value.name === "dbgenerated") { column = column + `.default(sql\`${s(value.args[0], "`")}\`)`; drizzleImports3.add("sql"); break; } if (/^uuid\([0-9]*\)$/.test(value.name)) { column = column + `.default(sql\`uuid()\`)`; drizzleImports3.add("sql"); break; } const stringified = `${value.name}${value.args.length ? "(" + value.args.map((e) => String(e)).join(", ") + ")" : value.name.endsWith(")") ? "" : "()"}`; const sequel = `sql\`${s(stringified, "`")}\``; drizzleImports3.add("sql"); column = column + `.default(${sequel})`; break; } } return column; }; var prismaToDrizzleColumn3 = (field) => { const colDbName = s(field.dbName ?? field.name); let column = ` ${field.name}: `; const drizzleType = prismaToDrizzleType3(field.type, colDbName); if (!drizzleType) return void 0; column = column + drizzleType; column = addColumnModifiers3(field, column); return column; }; var generateSQLiteSchema = (options) => { const { models } = options.dmmf.datamodel; const clonedModels = JSON.parse(JSON.stringify(models)); const manyToManyModels = extractManyToManyModels(clonedModels); const modelsWithImplicit = [...clonedModels, ...manyToManyModels]; const tables = []; const rqb = []; for (const schemaTable of modelsWithImplicit) { const tableDbName = s(schemaTable.dbName ?? schemaTable.name); const columnFields = Object.fromEntries( schemaTable.fields.map((e) => [e.name, prismaToDrizzleColumn3(e)]).filter((e) => e[1] !== void 0) ); const indexes = []; const relFields = schemaTable.fields.filter((field) => field.relationToFields && field.relationFromFields); const relations = relFields.map((field) => { if (!field?.relationFromFields?.length) return void 0; const fkeyName = s(`${schemaTable.dbName ?? schemaTable.name}_${field.dbName ?? field.name}_fkey`); let deleteAction; switch (field.relationOnDelete) { case void 0: case "Cascade": deleteAction = "cascade"; break; case "SetNull": deleteAction = "set null"; break; case "SetDefault": deleteAction = "set default"; break; case "Restrict": deleteAction = "restrict"; break; case "NoAction": deleteAction = "no action"; break; default: throw new import_generator_helper3.GeneratorError(`Unknown delete action on relation ${fkeyName}: ${field.relationOnDelete}`); } sqliteImports.add("foreignKey"); return ` '${fkeyName}': foreignKey({ name: '${fkeyName}', columns: [${field.relationFromFields.map((rel) => `${schemaTable.name}.${rel}`).join(", ")}], foreignColumns: [${field.relationToFields.map((rel) => `${field.type}.${rel}`).join(", ")}] })${deleteAction && deleteAction !== "no action" ? ` .onDelete('${deleteAction}')` : ""} .onUpdate('cascade')`; }).filter((e) => e !== void 0); indexes.push(...relations); if (schemaTable.uniqueIndexes.length) { sqliteImports.add("uniqueIndex"); const uniques = schemaTable.uniqueIndexes.map((idx) => { const idxName = s(idx.name ?? `${schemaTable.name}_${idx.fields.join("_")}_key`); return ` '${idx.name ? idxName : `${idxName.slice(0, idxName.length - 4)}_unique_idx`}': uniqueIndex('${idxName}') .on(${idx.fields.map((f) => `${schemaTable.name}.${f}`).join(", ")})`; }); indexes.push(...uniques); } if (schemaTable.primaryKey) { sqliteImports.add("primaryKey"); const pk = schemaTable.primaryKey; const pkName = s(pk.name ?? `${schemaTable.name}_cpk`); const pkField = ` '${pkName}': primaryKey({ name: '${pkName}', columns: [${pk.fields.map((f) => `${schemaTable.name}.${f}`).join(", ")}] })`; indexes.push(pkField); } const table = `export const ${schemaTable.name} = sqliteTable('${tableDbName}', { ${Object.values(columnFields).join(",\n")} }${indexes.length ? `, (${schemaTable.name}) => ({ ${indexes.join(",\n")} })` : ""});`; tables.push(table); if (!relFields.length) continue; drizzleImports3.add("relations"); const relationArgs = /* @__PURE__ */ new Set(); const rqbFields = relFields.map((field) => { relationArgs.add(field.relationFromFields?.length ? "one" : "many"); const relName = s(field.relationName ?? ""); return ` ${field.name}: ${field.relationFromFields?.length ? `one(${field.type}, { relationName: '${relName}', fields: [${field.relationFromFields.map((e) => `${schemaTable.name}.${e}`).join(", ")}], references: [${field.relationToFields.map((e) => `${field.type}.${e}`).join(", ")}] })` : `many(${field.type}, { relationName: '${relName}' })`}`; }).join(",\n"); const argString = Array.from(relationArgs.values()).join(", "); const rqbRelation = `export const ${schemaTable.name}Relations = relations(${schemaTable.name}, ({ ${argString} }) => ({ ${rqbFields} }));`; rqb.push(rqbRelation); } const drizzleImportsArr = Array.from(drizzleImports3.values()).sort((a, b) => a.localeCompare(b)); const drizzleImportsStr = drizzleImportsArr.length ? `import { ${drizzleImportsArr.join(", ")} } from 'drizzle-orm'` : void 0; const sqliteImportsArr = Array.from(sqliteImports.values()).sort((a, b) => a.localeCompare(b)); const sqliteImportsStr = sqliteImportsArr.length ? `import { ${sqliteImportsArr.join(", ")} } from 'drizzle-orm/sqlite-core'` : void 0; let importsStr = [drizzleImportsStr, sqliteImportsStr].filter((e) => e !== void 0).join("\n"); if (!importsStr.length) importsStr = void 0; const output = [importsStr, ...tables, ...rqb].filter((e) => e !== void 0).join("\n\n"); return output; }; // src/util/recursive-write/index.ts var import_fs = __toESM(require("fs")); var import_path = __toESM(require("path")); var recursiveWrite = async (path2, content) => { import_fs.default.mkdirSync(import_path.default.dirname(path2), { recursive: true }); import_fs.default.writeFileSync(path2, content); }; // src/index.ts var generator = (0, import_generator_helper4.generatorHandler)({ onManifest() { return { version, defaultOutput: defaultPath, prettyName: generatorName }; }, onGenerate: async (options) => { const dbType = options.datasources[0]?.provider; let output; switch (dbType) { case "postgres": case "postgresql": { output = generatePgSchema(options); break; } case "mysql": { output = generateMySqlSchema(options); break; } case "sqlite": { output = generateSQLiteSchema(options); break; } case void 0: throw new import_generator_helper4.GeneratorError("Unable to determine database type.\nMake sure datasource.provider is specified."); default: throw new import_generator_helper4.GeneratorError( `Invalid database type for Drizzle schema generation: ${dbType}. Supported database types: PostgreSQL, MySQL, SQLite.` ); } const folderPath = import_path2.default.resolve( options.generator.output?.value ?? (!!options.generator.output?.fromEnvVar ? process.env[options.generator.output.fromEnvVar] ?? defaultPath : defaultPath) ); const schemaPath = folderPath.endsWith(".ts") ? folderPath : import_path2.default.join(folderPath, "/schema.ts"); recursiveWrite(schemaPath, output); } }); var src_default = generator; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { generator }); //# sourceMappingURL=index.js.map