Skip to content

Commit

Permalink
Merge branch 'nicoalbanese:master' into 50_migrate_to_sonner
Browse files Browse the repository at this point in the history
  • Loading branch information
afogel authored Feb 6, 2024
2 parents f13c562 + aedfd57 commit b4df621
Show file tree
Hide file tree
Showing 10 changed files with 595 additions and 108 deletions.
2 changes: 1 addition & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
"semi": true,
"singleQuote": false,
"trailingComma": "es5"
}
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "kirimase",
"version": "0.0.51",
"version": "0.0.52",
"description": "A Rails-like CLI for building full-stack Next.js apps faster",
"main": "index.js",
"type": "module",
Expand Down
4 changes: 2 additions & 2 deletions src/commands/generate/generators/model/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { consola } from "consola";
import { DBType } from "../../../../types.js";
import { createFile, readConfigFile, replaceFile } from "../../../../utils.js";
import { prismaFormat, prismaGenerate } from "../../../add/orm/utils.js";
import { Schema } from "../../types.js";
import { ExtendedSchema, Schema } from "../../types.js";
import { toCamelCase } from "../../utils.js";
import { generateMutationContent } from "./mutations/index.js";
import { generateQueryContent } from "./queries/index.js";
Expand All @@ -16,7 +16,7 @@ import { existsSync, readFileSync } from "fs";
import { updateRootSchema } from "./utils.js";

export async function scaffoldModel(
schema: Schema,
schema: ExtendedSchema,
dbType: DBType,
hasSrc: boolean
) {
Expand Down
204 changes: 200 additions & 4 deletions src/commands/generate/generators/model/queries/generators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
getDbIndexPath,
getFilePaths,
} from "../../../../filePaths/index.js";
import { Schema } from "../../../types.js";
import { ExtendedSchema, Schema } from "../../../types.js";
import { formatTableName, toCamelCase } from "../../../utils.js";
import { generateAuthCheck } from "../utils.js";

Expand All @@ -18,6 +18,9 @@ const generateDrizzleImports = (schema: Schema, relations: DBField[]) => {
} = formatTableName(tableName);
const { shared } = getFilePaths();
const dbIndex = getDbIndexPath();

const children = schema.children.map((c) => formatTableName(c.tableName));

return `import { db } from "${formatFilePath(dbIndex, {
prefix: "alias",
removeExtension: true,
Expand Down Expand Up @@ -48,7 +51,21 @@ ${
)
.join("")
: ""
}`;
}${
children.length > 0
? children
.map(
(child) =>
`import { ${child.tableNameCamelCase}, type Complete${
child.tableNameSingularCapitalised
} } from "${formatFilePath(shared.orm.schemaDir, {
prefix: "alias",
removeExtension: false,
})}/${child.tableNameCamelCase}";\n`
)
.join("")
: ""
}`;
};

const generatePrismaImports = (schema: Schema) => {
Expand Down Expand Up @@ -88,7 +105,7 @@ const generateDrizzleGetQuery = (schema: Schema, relations: DBField[]) => {
} = formatTableName(tableName);
const getAuth = generateAuthCheck(schema.belongsToUser);
return `export const get${tableNamePluralCapitalised} = async () => {${getAuth}
const ${tableNameFirstChar} = await db.select(${
const rows = await db.select(${
relations.length > 0
? `{ ${tableNameSingular}: ${tableNameCamelCase}, ${relations
.map(
Expand Down Expand Up @@ -117,6 +134,18 @@ const generateDrizzleGetQuery = (schema: Schema, relations: DBField[]) => {
? `.where(eq(${tableNameCamelCase}.userId, session?.user.id!))`
: ""
};
const ${tableNameFirstChar} = rows${
relations.length > 0
? ` .map((r) => ({ ...r.${tableNameSingular}, ${relations
.map((relation) => {
const { tableNameSingular: tnSingular } = formatTableName(
relation.references
);
return `${tnSingular}: r.${tnSingular}`;
})
.join(", ")}})); `
: ""
}
return { ${tableNameCamelCase}: ${tableNameFirstChar} };
};
`;
Expand All @@ -133,7 +162,7 @@ const generateDrizzleGetByIdQuery = (schema: Schema, relations: DBField[]) => {
const getAuth = generateAuthCheck(schema.belongsToUser);
return `export const get${tableNameSingularCapitalised}ById = async (id: ${tableNameSingularCapitalised}Id) => {${getAuth}
const { id: ${tableNameSingular}Id } = ${tableNameSingular}IdSchema.parse({ id });
const [${tableNameFirstChar}] = await db.select(${
const [row] = await db.select(${
relations.length > 0
? `{ ${tableNameSingular}: ${tableNameCamelCase}, ${relations
.map(
Expand Down Expand Up @@ -164,11 +193,106 @@ const generateDrizzleGetByIdQuery = (schema: Schema, relations: DBField[]) => {
.join("")
: ""
};
if (row === undefined) return {};
const ${tableNameFirstChar} = ${
relations.length > 0
? ` { ...row.${tableNameSingular}, ${relations
.map((relation) => {
const { tableNameSingular: tnSingular } = formatTableName(
relation.references
);
return `${tnSingular}: row.${tnSingular}`;
})
.join(", ")} } `
: "row"
};
return { ${tableNameSingular}: ${tableNameFirstChar} };
};
`;
};

const generateDrizzleGetByIdWithChildrenQuery = (
schema: ExtendedSchema,
relations: DBField[]
) => {
const { tableName, belongsToUser, children } = schema;
const {
tableNameCamelCase,
tableNameFirstChar,
tableNameSingularCapitalised,
tableNameSingular,
} = formatTableName(tableName);
const childrenTableNames = children.map((c) => formatTableName(c.tableName));
const getAuth = generateAuthCheck(schema.belongsToUser);
return `export const get${tableNameSingularCapitalised}ByIdWith${childrenTableNames
.map((c) => c.tableNameCapitalised)
.join("And")} = async (id: ${tableNameSingularCapitalised}Id) => {${getAuth}
const { id: ${tableNameSingular}Id } = ${tableNameSingular}IdSchema.parse({ id });
const rows = await db.select(${
children.length > 0
? `{ ${tableNameSingular}: ${tableNameCamelCase}, ${children
.map(
(child) =>
`${pluralize.singular(
toCamelCase(child.tableName)
)}: ${toCamelCase(child.tableName)}`
)
.join(", ")} }`
: ""
}).from(${tableNameCamelCase}).where(${
belongsToUser ? "and(" : ""
}eq(${tableNameCamelCase}.id, ${tableNameSingular}Id)${
belongsToUser
? `, eq(${tableNameCamelCase}.userId, session?.user.id!))`
: ""
})${
children.length > 0
? children
.map((child) => {
const {
tableNameCamelCase: childNameCC,
tableNameSingular: childNameSingular,
} = formatTableName(child.tableName);
return `.leftJoin(${childNameCC}, eq(${tableNameCamelCase}.id, ${childNameCC}.${tableNameSingular}Id))`;
})
.join("")
: ""
};
if (rows.length === 0) return {};
const ${tableNameFirstChar} = rows[0].${tableNameSingular};
${
children.length > 0
? children
.map((c) => {
const {
tableNameCamelCase: childCC,
tableNameFirstChar: childFirstChar,
tableNameSingularCapitalised: childSingularCapitalised,
tableNameSingular: childSingular,
} = formatTableName(c.tableName);
return `const ${tableNameFirstChar}${childFirstChar} = rows.filter((r) => r.${childSingular} !== null).map((${childFirstChar}) => ${childFirstChar}.${childSingular}) as Complete${childSingularCapitalised}[];`;
})
.join("\n ")
: ""
}
return { ${tableNameSingular}: ${tableNameFirstChar}, ${
children.length > 0
? children
.map((c) => {
const {
tableNameFirstChar: childFirstChar,
tableNameCamelCase: childNameCC,
} = formatTableName(c.tableName);
return `${childNameCC}: ${tableNameFirstChar}${childFirstChar}`;
})
.join(", ")
: ""
} };
};
`;
};

const generatePrismaGetQuery = (schema: Schema, relations: DBField[]) => {
const { tableName, belongsToUser } = schema;
const {
Expand Down Expand Up @@ -224,15 +348,87 @@ const generatePrismaGetByIdQuery = (schema: Schema, relations: DBField[]) => {
`;
};

type TJoin = {
name: string;
type: "relation" | "child";
nameCapitalised?: string;
};
const generatePrismaGetByIdQueryWithChildren = (
schema: ExtendedSchema,
relations: DBField[]
) => {
// maybe we have an array of relations + children -> run a set to get unique values then just use the same logic there

const { tableName, belongsToUser, children } = schema;

const relationsTableNames: TJoin[] = relations.map((r) => ({
name: formatTableName(r.references).tableNameSingular,
type: "relation",
}));
const childrenTableNames: TJoin[] = children.map((c) => ({
name: formatTableName(c.tableName).tableNameCamelCase,
nameCapitalised: formatTableName(c.tableName).tableNameCapitalised,
type: "child",
}));
const joins = Array.from(
new Set([...relationsTableNames, ...childrenTableNames])
);

const {
tableNameSingular,
tableNameCamelCase,
tableNameSingularCapitalised,
tableNameFirstChar,
} = formatTableName(tableName);
const getAuth = generateAuthCheck(schema.belongsToUser);
return `export const get${tableNameSingularCapitalised}ByIdWith${childrenTableNames
.map((c) => c.nameCapitalised)
.join("And")} = async (id: ${tableNameSingularCapitalised}Id) => {${getAuth}
const { id: ${tableNameSingular}Id } = ${tableNameSingular}IdSchema.parse({ id });
const ${tableNameFirstChar} = await db.${tableNameSingular}.findFirst({
where: { id: ${tableNameSingular}Id${
belongsToUser ? `, userId: session?.user.id!` : ""
}}${
joins.length > 0
? `,\n include: { ${joins
.map(
(j) =>
`${j.name}: { include: {${
j.type === "child" ? tableNameSingular : tableNameCamelCase
}: true } }`
)
.join(", ")} }\n `
: ""
}});
${
childrenTableNames.length > 0
? `if (${tableNameFirstChar} === null) return { ${tableNameSingular}: null };
const { ${joins
.map((j) => `${j.name}`)
.join(", ")}, ...${tableNameSingular} } = ${tableNameFirstChar};
`
: ""
}
return { ${tableNameSingular}${
joins.length > 0
? `, ${joins.map((j) => `${j.name}:${j.name}`).join(", ")}`
: ""
} };
};
`;
};

export const generateQueries = {
prisma: {
imports: generatePrismaImports,
get: generatePrismaGetQuery,
getById: generatePrismaGetByIdQuery,
getByIdWithChildren: generatePrismaGetByIdQueryWithChildren,
},
drizzle: {
imports: generateDrizzleImports,
get: generateDrizzleGetQuery,
getById: generateDrizzleGetByIdQuery,
getByIdWithChildren: generateDrizzleGetByIdWithChildrenQuery,
},
};
9 changes: 7 additions & 2 deletions src/commands/generate/generators/model/queries/index.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
import { ORMType } from "../../../../../types.js";
import { Schema } from "../../../types.js";
import { ExtendedSchema, Schema } from "../../../types.js";
import { generateQueries } from "./generators.js";

export const generateQueryContent = (schema: Schema, orm: ORMType) => {
export const generateQueryContent = (schema: ExtendedSchema, orm: ORMType) => {
const relations = schema.fields.filter(
(field) => field.type.toLowerCase() === "references"
);

const imports = generateQueries[orm].imports(schema, relations);
const getQuery = generateQueries[orm].get(schema, relations);
const getByIdQuery = generateQueries[orm].getById(schema, relations);
const getByIdWithChildren =
schema.children && schema.children.length > 0
? generateQueries[orm].getByIdWithChildren(schema, relations)
: "";

return `${imports}
${getQuery}
${getByIdQuery}
${getByIdWithChildren}
`;
};
4 changes: 2 additions & 2 deletions src/commands/generate/generators/model/schema/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ const addUserReferenceIfBelongsToUser = (
references: "users",
cascade: true,
referenceIdType: "string",
}).concat(".notNull()")},`
}).concat(".notNull()")}`
: "";
const valueIfManaged = value.replace(
`.references(() => users.id, { onDelete: "cascade" })`,
Expand Down Expand Up @@ -207,7 +207,7 @@ ${userGeneratedFields}${addUserReferenceIfBelongsToUser(
authType
)}${
schema.includeTimestamps
? generateTimestampFieldsDrizzle().schemaContent
? ",\n ".concat(generateTimestampFieldsDrizzle().schemaContent)
: ""
}
}${indexFormatted});\n`;
Expand Down
Loading

0 comments on commit b4df621

Please sign in to comment.