@saboosanket/code-generator
Version:
This npm package is a versatile setup tool tailored for Node.js projects, enabling users to generate customized project structures and functionalities. It supports integration with Google Cloud Platform (GCP), RabbitMQ, Redis, a Prisma query generator, an
213 lines (199 loc) • 7.75 kB
JavaScript
import {
createModuleAndFile,
writeFileWithoutPrompt
} from '../../utils/write_files.js'
import { customErrors } from '../../base_scaffolding/custom_error.js'
/**
* Generates CRUD operations for each model provided in the input.
*
* This function creates a JavaScript module for each model that includes
* functions to create, read, update, and delete records in the database
* using Prisma Client. Additionally, it includes a function to read all
* records with pagination support. The CRUD operations utilize the primary
* key specified in the model definition.
*
* @async
* @function createQueries
*
* @param {Array<Object>} models - An array of model objects, where each object
* contains:
* @property {string} model - The name of the model.
* @property {Array<string>} primary_key - An array of primary key field names.
* @property {Array<Object>} foreign_keys - An array of foreign key objects, each containing:
* @property {string} field - The field in the current model that holds the relationship.
* @property {string} foreignKey - The field in the current model that acts as the foreign key.
* @property {string} references - The field in the referenced model that the foreign key relates to.
*
* @throws {Error} Will throw an error if there is an issue writing the CRUD
* operations to the file.
*
* @example
* const models = [
* {
* model: 'User',
* primary_key: ['id'],
* foreign_keys: []
* },
* {
* model: 'Post',
* primary_key: ['id'],
* foreign_keys: [{ field: 'authorId', foreignKey: 'id', references: 'User' }]
* }
* ]
*
* await createQueries(models)
*
* // This will create the following files:
* // src/user.js - containing CRUD operations for the User model
* // src/post.js - containing CRUD operations for the Post model
*/
async function createQueries(models) {
const folderName = 'services/db'
const prismaConfig = `
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
export default prisma
`
// Generate CRUD operations for each model
for (const model of models) {
const modelName = model.model
const lowercaseModelName = modelName.toLowerCase()
const primaryKey = model.primary_key[0] // The primary key is used for CRUD operations
const crudCode = `
import { Prisma } from '@prisma/client'
import prisma from './config.js'
import { UnexpectedError, NotFoundError } from '../custom_error.js'
import { INTERNAL_SERVER_ERROR } from '../constants.js'
// Create
async function create${modelName}(data) {
try {
const new${modelName} = await prisma.${lowercaseModelName}.create({
data
})
console.log('Created new ${lowercaseModelName}:', new${modelName})
return new${modelName}
} catch (error) {
throw UnexpectedError('Error in creating entry', 500, { message: 'Error creating ${lowercaseModelName}', data: String(error) })
}
}
// Read
async function get${modelName}ById(${primaryKey}) {
try {
const ${lowercaseModelName} = await prisma.${lowercaseModelName}.findUnique({
where: { ${primaryKey} }
})
console.log('Found ${lowercaseModelName}:', ${lowercaseModelName})
return ${lowercaseModelName}
} catch (error) {
if (error.name && error.name === 'NotFoundError') {
throw error
}
if (
error instanceof Prisma.PrismaClientKnownRequestError &&
error.code === 'P2025'
) {
throw NotFoundError(
\`No record found with this id: ${primaryKey}\`,
404,
{ data: String(error) }
)
}
throw UnexpectedError(INTERNAL_SERVER_ERROR, 500, {
message: 'Error finding ${primaryKey} in ${lowercaseModelName}',
data: String(error)
})
}
}
/**
* Fetches a paginated list of domains for a given organization.
*
* @async
* @function getAll${modelName}s
* @param {number} [page=1] - The page number for pagination (default is 1).
* @param {number} [pageSize=10] - The number of domains to return per page (default is 10).
* @param {('asc'|'desc')} [orderBy='desc'] - The order of the results based on the creation date (default is 'desc').
*
* @returns {Promise<Object>} A promise that resolves to an object containing:
* - {Array<Object>} domains - The list of domain objects, each containing:
* - {string} domain_id - The unique identifier of the domain.
* - {string} url - The URL associated with the domain.
* - {Date} created_at - The timestamp when the domain was created.
* - {Date} updated_at - The timestamp when the domain was last updated.
* - {number} total - The total number of domains for the organization.
* - {number} page - The current page number.
* - {number} page_size - The number of domains per page.
* - {number} totalPages - The total number of pages based on the total domains and pageSize.
*
* @throws {UnexpectedError} Throws an UnexpectedError if there is an issue fetching the domains.
*/
async function getAll${modelName}s(page = 1, pageSize = 10, orderBy = 'desc') {
const skip = (page - 1) * pageSize
const condition = {}
try {
const total = await prisma.${lowercaseModelName}.count({ where: condition })
const ${lowercaseModelName}s = await prisma.${lowercaseModelName}.findMany({
skip,
where: condition,
take: pageSize,
orderBy: { created_at: orderBy },
select:{}
})
console.log('All ${lowercaseModelName}s with pagination:', ${lowercaseModelName}s)
return {
data: ${lowercaseModelName}s,
total,
page,
pageSize,
totalPages: Math.ceil(total / pageSize)
}
} catch (error) {
console.error('Error fetching ${lowercaseModelName}s:', error)
throw error
}
}
// Update
async function update${modelName}(${primaryKey}, data) {
try {
const updated${modelName} = await prisma.${lowercaseModelName}.update({
where: { ${primaryKey} },
data
})
console.log('Updated ${lowercaseModelName}:', updated${modelName})
return updated${modelName}
} catch (error) {
if (error instanceof Prisma.PrismaClientKnownRequestError && error.code === 'P2025') {
throw NotFoundError(\`No record found with this id: \${${primaryKey}}\`, 404)
}
throw UnexpectedError(INTERNAL_SERVER_ERROR, 500, { data: String(error) , id: ${primaryKey}})
}
}
// Delete
async function delete${modelName}(${primaryKey}) {
try {
const deleted${modelName} = await prisma.${lowercaseModelName}.delete({
where: { ${primaryKey} }
})
console.log('Deleted ${lowercaseModelName}:', deleted${modelName})
return deleted${modelName}
} catch (error) {
if (error instanceof Prisma.PrismaClientKnownRequestError && error.code === 'P2025') {
throw NotFoundError(\`No record found with this id: \${${primaryKey}}\`, 404)
}
throw UnexpectedError(INTERNAL_SERVER_ERROR, 500, { data: String(error) , id: ${primaryKey}})
}
}
export {
create${modelName},
get${modelName}ById,
getAll${modelName}s,
update${modelName},
delete${modelName}
}
`
const fileName = `${modelName}.services.js`
await createModuleAndFile(folderName, fileName, crudCode)
}
writeFileWithoutPrompt(folderName, 'config.js', prismaConfig)
writeFileWithoutPrompt('services', 'custom_error.js', customErrors)
}
export { createQueries }