From 83b431467d6a7baca7ee76ed8fd8abc499550f2d Mon Sep 17 00:00:00 2001 From: Nico Albanese Date: Wed, 29 Nov 2023 00:09:03 +0000 Subject: [PATCH] identified and fixed relations and pluralise issues --- .../generators/model/queries/generators.ts | 60 ++++++++++-------- .../generate/generators/model/schema/index.ts | 62 +++++++++---------- .../generate/generators/model/utils.ts | 16 ++--- src/commands/generate/generators/views.ts | 12 +++- src/commands/generate/index.ts | 19 ++++-- src/commands/generate/utils.ts | 22 ++++--- 6 files changed, 108 insertions(+), 83 deletions(-) diff --git a/src/commands/generate/generators/model/queries/generators.ts b/src/commands/generate/generators/model/queries/generators.ts index 6e270a97..0b40d434 100644 --- a/src/commands/generate/generators/model/queries/generators.ts +++ b/src/commands/generate/generators/model/queries/generators.ts @@ -26,24 +26,24 @@ import { eq${belongsToUser ? ", and" : ""} } from "drizzle-orm";${ belongsToUser ? `\nimport { getUserAuth } from "${formatFilePath( shared.auth.authUtils, - { prefix: "alias", removeExtension: true } + { prefix: "alias", removeExtension: true }, )}";` : "" } import { type ${tableNameSingularCapitalised}Id, ${tableNameSingular}IdSchema, ${tableNameCamelCase} } from "${formatFilePath( shared.orm.schemaDir, - { prefix: "alias", removeExtension: false } + { prefix: "alias", removeExtension: false }, )}/${tableNameCamelCase}"; ${ relations.length > 0 ? relations.map( (relation) => `import { ${toCamelCase( - relation.references + relation.references, )} } from "${formatFilePath(shared.orm.schemaDir, { prefix: "alias", removeExtension: false, - })}/${toCamelCase(relation.references)}";\n` + })}/${toCamelCase(relation.references)}";\n`, ) : "" }`; @@ -65,13 +65,13 @@ const generatePrismaImports = (schema: Schema) => { belongsToUser ? `\nimport { getUserAuth } from "${formatFilePath( shared.auth.authUtils, - { prefix: "alias", removeExtension: true } + { prefix: "alias", removeExtension: true }, )}";` : "" } import { type ${tableNameSingularCapitalised}Id, ${tableNameSingular}IdSchema } from "${formatFilePath( shared.orm.schemaDir, - { removeExtension: false, prefix: "alias" } + { removeExtension: false, prefix: "alias" }, )}/${tableNameCamelCase}"; `; }; @@ -91,7 +91,9 @@ const generateDrizzleGetQuery = (schema: Schema, relations: DBField[]) => { ? `{ ${tableNameSingular}: ${tableNameCamelCase}, ${relations .map( (relation) => - `${relation.references.slice(0, -1)}: ${relation.references}` + `${pluralize.singular( + toCamelCase(relation.references), + )}: ${toCamelCase(relation.references)}`, ) .join(", ")} }` : "" @@ -99,11 +101,11 @@ const generateDrizzleGetQuery = (schema: Schema, relations: DBField[]) => { relations.length > 0 ? relations.map( (relation) => - `.leftJoin(${ - relation.references - }, eq(${tableNameCamelCase}.${toCamelCase( - relation.name - )}, ${toCamelCase(relation.references)}.id))` + `.leftJoin(${toCamelCase( + relation.references, + )}, eq(${tableNameCamelCase}.${toCamelCase( + relation.name, + )}, ${toCamelCase(relation.references)}.id))`, ) : "" }${ @@ -137,11 +139,11 @@ const generateDrizzleGetByIdQuery = (schema: Schema, relations: DBField[]) => { relations.length > 0 ? relations.map( (relation) => - `.leftJoin(${ - relation.references - }, eq(${tableNameCamelCase}.${toCamelCase( - relation.name - )}, ${toCamelCase(relation.references)}.id))` + `.leftJoin(${toCamelCase( + relation.references, + )}, eq(${tableNameCamelCase}.${toCamelCase( + relation.name, + )}, ${toCamelCase(relation.references)}.id))`, ) : "" }; @@ -165,7 +167,10 @@ const generatePrismaGetQuery = (schema: Schema, relations: DBField[]) => { }${belongsToUser && relations.length > 0 ? ", " : ""}${ relations.length > 0 ? `include: { ${relations - .map((relation) => `${pluralize.singular(relation.references)}: true`) + .map( + (relation) => + `${pluralize.singular(toCamelCase(relation.references))}: true`, + ) .join(", ")}}` : "" }}); @@ -187,14 +192,17 @@ const generatePrismaGetByIdQuery = (schema: Schema, relations: DBField[]) => { const { id: ${tableNameSingular}Id } = ${tableNameSingular}IdSchema.parse({ id }); const ${tableNameFirstChar} = await db.${tableNameSingular}.findFirst({ where: { id: ${tableNameSingular}Id${ - belongsToUser ? `, userId: session?.user.id!` : "" - }}${ - relations.length > 0 - ? `,\n include: { ${relations - .map((relation) => `${relation.references.slice(0, -1)}: true`) - .join(", ")} }\n ` - : "" - }}); + belongsToUser ? `, userId: session?.user.id!` : "" + }}${ + relations.length > 0 + ? `,\n include: { ${relations + .map( + (relation) => + `${pluralize.singular(toCamelCase(relation.references))}: true`, + ) + .join(", ")} }\n ` + : "" + }}); return { ${tableNameCamelCase}: ${tableNameFirstChar} }; }; `; diff --git a/src/commands/generate/generators/model/schema/index.ts b/src/commands/generate/generators/model/schema/index.ts index 0a2a2e10..44fc635e 100644 --- a/src/commands/generate/generators/model/schema/index.ts +++ b/src/commands/generate/generators/model/schema/index.ts @@ -28,7 +28,7 @@ const getUsedTypes = (fields: DBField[], mappings: TypeMap) => { return mappingFunction({ name: field.name }).split("(")[0]; }) .concat( - mappings.typeMappings["id"]({ name: "id" }).split("(")[0] + mappings.typeMappings["id"]({ name: "id" }).split("(")[0], ) as DrizzleColumnType[]; // Assuming number (int) is always used for the 'id' field }; @@ -37,22 +37,22 @@ const getReferenceImports = (fields: DBField[]) => { return referenceFields.map( (field) => `import { ${toCamelCase(field.references)} } from "./${toCamelCase( - field.references - )}"` + field.references, + )}"`, ); }; const getUniqueTypes = ( usedTypes: string[], belongsToUser: boolean, - dbType: DBType + dbType: DBType, ) => { return Array.from( new Set( usedTypes.concat( - belongsToUser ? [getReferenceFieldType("string")[dbType]] : [] - ) - ) + belongsToUser ? [getReferenceFieldType("string")[dbType]] : [], + ), + ), ); }; @@ -62,7 +62,7 @@ const generateImportStatement = ( mappings: TypeMap, authType: AuthType, dbType?: DBType, - provider?: DBProvider + provider?: DBProvider, ) => { const { alias } = readConfigFile(); const { fields, belongsToUser, tableName } = schema; @@ -79,7 +79,7 @@ const generateImportStatement = ( return `import { ${uniqueTypes .join(", ") .concat( - `, ${mappings.tableFunc}` + `, ${mappings.tableFunc}`, )} } from "drizzle-orm/${dbType}-core";\nimport { createInsertSchema, createSelectSchema } from "drizzle-zod";\nimport { z } from "zod";\n${ referenceImports.length > 0 ? referenceImports.join("\n") : "" }${ @@ -92,7 +92,7 @@ const generateImportStatement = ( } import { get${tableNameCapitalised} } from "${formatFilePath( shared.orm.servicesDir, - { prefix: "alias", removeExtension: false } + { prefix: "alias", removeExtension: false }, )}/${tableNameCamelCase}/queries";`; } if (orm === "prisma") @@ -100,7 +100,7 @@ import { get${tableNameCapitalised} } from "${formatFilePath( import { z } from "zod"; import { get${tableNameCapitalised} } from "${formatFilePath( shared.orm.servicesDir, - { prefix: "alias", removeExtension: false } + { prefix: "alias", removeExtension: false }, )}/${tableNameCamelCase}/queries"; `; }; @@ -110,8 +110,8 @@ const generateFieldsForSchema = (fields: DBField[], mappings: TypeMap) => { .map( (field) => ` ${toCamelCase(field.name)}: ${mappings.typeMappings[field.type]( - field - )}${field.notNull ? ".notNull()" : ""}` + field, + )}${field.notNull ? ".notNull()" : ""}`, ) .join(",\n"); }; @@ -123,10 +123,10 @@ const generateIndex = (schema: Schema) => { ? `, (${tableNameCamelCase}) => { return { ${toCamelCase( - index + index, )}Index: uniqueIndex('${index}_idx').on(${tableNameCamelCase}.${toCamelCase( - index - )}), + index, + )}), } }` : ""; @@ -135,7 +135,7 @@ const generateIndex = (schema: Schema) => { const addUserReferenceIfBelongsToUser = ( schema: Schema, mappings: TypeMap, - authType: AuthType + authType: AuthType, ) => { const authSubtype = AuthSubTypeMapping[authType]; const value = schema.belongsToUser @@ -148,7 +148,7 @@ const addUserReferenceIfBelongsToUser = ( : ""; const valueIfManaged = value.replace( `.references(() => users.id, { onDelete: "cascade" })`, - "" + "", ); return authSubtype === "managed" ? valueIfManaged : value; }; @@ -159,7 +159,7 @@ const generateDrizzleSchema = ( provider: DBProvider, dbType: DBType, zodSchemas: string, - authType: AuthType + authType: AuthType, ) => { const { tableName, fields } = schema; const { tableNameCamelCase } = formatTableName(tableName); @@ -170,7 +170,7 @@ const generateDrizzleSchema = ( mappings, authType, dbType, - provider + provider, ); const userGeneratedFields = generateFieldsForSchema(fields, mappings); @@ -183,7 +183,7 @@ const generateDrizzleSchema = ( ${userGeneratedFields}${addUserReferenceIfBelongsToUser( schema, mappings, - authType + authType, )} }${indexFormatted});\n`; @@ -193,7 +193,7 @@ ${userGeneratedFields}${addUserReferenceIfBelongsToUser( const generateIndexFields = ( schema: Schema, relations: DBField[], - usingPlanetscale: boolean + usingPlanetscale: boolean, ): string => { const { index, belongsToUser } = schema; // Handle the case where index is null and there are no relations and usingPlanetscale is false @@ -216,7 +216,7 @@ const generateIndexFields = ( // If using planetscale and there are relations, add relations to fields array if (usingPlanetscale && relations.length > 0) { fields = fields.concat( - relations.map((relation) => toCamelCase(relation.name)) + relations.map((relation) => toCamelCase(relation.name)), ); } @@ -232,14 +232,14 @@ const generatePrismaSchema = ( mappings: TypeMap, zodSchemas: string, usingPlanetscale: boolean, - authType: AuthType + authType: AuthType, ) => { const { tableNameSingularCapitalised, tableNameCamelCase } = formatTableName( - schema.tableName + schema.tableName, ); const authSubtype = AuthSubTypeMapping[authType]; const relations = schema.fields.filter( - (field) => field.type === "References" + (field) => field.type === "References", ); const prismaSchemaContent = `model ${tableNameSingularCapitalised} { id String @id @default(cuid()) @@ -260,7 +260,7 @@ const generatePrismaSchema = ( if (schema.belongsToUser && authSubtype === "self-hosted") addToPrismaModel( "User", - `${tableNameCamelCase} ${tableNameSingularCapitalised}[]` + `${tableNameCamelCase} ${tableNameSingularCapitalised}[]`, ); relations.forEach((relation) => { @@ -269,14 +269,14 @@ const generatePrismaSchema = ( formatTableName(references); addToPrismaModel( singularCapitalised, - `${tableNameCamelCase} ${tableNameSingularCapitalised}[]` + `${tableNameCamelCase} ${tableNameSingularCapitalised}[]`, ); }); const importStatement = generateImportStatement( "prisma", schema, mappings, - authType + authType, ); return `${importStatement}\n\n${zodSchemas}`; @@ -294,7 +294,7 @@ export function generateModelContent(schema: Schema, dbType: DBType) { provider, dbType, zodSchemas, - auth + auth, ); } if (orm === "prisma") { @@ -303,7 +303,7 @@ export function generateModelContent(schema: Schema, dbType: DBType) { mappings, zodSchemas, provider === "planetscale", - auth + auth, ); } } diff --git a/src/commands/generate/generators/model/utils.ts b/src/commands/generate/generators/model/utils.ts index 1772600e..3ac1c0ab 100644 --- a/src/commands/generate/generators/model/utils.ts +++ b/src/commands/generate/generators/model/utils.ts @@ -60,7 +60,7 @@ export const createOrmMappings = () => { }) => `${getReferenceFieldType(referenceIdType)["pg"]}("${name}"${ referenceIdType === "string" ? ", { length: 256 }" : "" - }).references(() => ${referencedTable}.id${ + }).references(() => ${toCamelCase(referencedTable)}.id${ cascade ? ', { onDelete: "cascade" }' : "" })`, // Add more types here as needed @@ -142,7 +142,7 @@ export const authForWhereClausePrisma = (belongsToUser: boolean) => { export const updateRootSchema = ( tableName: string, usingAuth?: boolean, - auth?: AuthType + auth?: AuthType, ) => { const tableNameCC = toCamelCase(tableName); const { drizzle } = getFilePaths(); @@ -176,7 +176,7 @@ export const updateRootSchema = ( const rootSchemaContents = readFileSync(rootSchemaPath, "utf-8"); const rootSchemaWithNewExport = rootSchemaContents.replace( "export {", - `export { ${tableNameCC},` + `export { ${tableNameCC},`, ); const importInsertionPoint = rootSchemaWithNewExport.lastIndexOf("import"); @@ -184,7 +184,7 @@ export const updateRootSchema = ( rootSchemaWithNewExport.indexOf("\n", importInsertionPoint) + 1; const beforeImport = rootSchemaWithNewExport.slice( 0, - nextLineAfterLastImport + nextLineAfterLastImport, ); const afterImport = rootSchemaWithNewExport.slice(nextLineAfterLastImport); @@ -196,7 +196,7 @@ export const updateRootSchema = ( rootSchemaPath, `${newImportStatement} -export { ${usingAuth ? tableNames : tableNameCC} }` +export { ${usingAuth ? tableNames : tableNameCC} }`, ); // and also update db/index.ts to add extended model import const indexDbPath = formatFilePath(drizzle.dbIndex, { @@ -207,11 +207,11 @@ export { ${usingAuth ? tableNames : tableNameCC} }` const updatedContentsWithImport = indexDbContents.replace( `import * as schema from "./schema";`, `import * as schema from "./schema"; -import * as extended from "~/server/db/schema/_root";` +import * as extended from "~/server/db/schema/_root";`, ); const updatedContentsFinal = updatedContentsWithImport.replace( `{ schema }`, - `{ schema: { ...schema, ...extended } }` + `{ schema: { ...schema, ...extended } }`, ); replaceFile(indexDbPath, updatedContentsFinal); @@ -220,7 +220,7 @@ import * as extended from "~/server/db/schema/_root";` const dConfigContents = readFileSync(drizzleConfigPath, "utf-8"); const updatedContents = dConfigContents.replace( `schema: "./src/server/db/schema.ts",`, - `schema: "./src/server/db/*",` + `schema: "./src/server/db/*",`, ); replaceFile(drizzleConfigPath, updatedContents); } diff --git a/src/commands/generate/generators/views.ts b/src/commands/generate/generators/views.ts index 2968b05d..aba40b58 100644 --- a/src/commands/generate/generators/views.ts +++ b/src/commands/generate/generators/views.ts @@ -231,20 +231,26 @@ const createformInputComponent = (field: DBField): string => { `; if (field.type.toLowerCase() == "references") { - const referencesSingular = pluralize.singular(field.references); + const referencesSingular = pluralize.singular( + toCamelCase(field.references), + ); + const { tableNameNormalEnglishSingularLowerCase } = formatTableName( + field.references, + ); const entity = queryHasJoins(toCamelCase(field.references)) ? `${referencesSingular}.${referencesSingular}` : referencesSingular; + const referencesPlural = toCamelCase(field.references); return `