Skip to content

Commit

Permalink
[CLI] Refactor & simplify schema helpers (#11896)
Browse files Browse the repository at this point in the history
Co-authored-by: Tobbe Lundberg <tobbe@tlundberg.com>
  • Loading branch information
Philzen and Tobbe authored Jan 15, 2025
1 parent 56c712a commit 121a9b8
Showing 1 changed file with 57 additions and 59 deletions.
116 changes: 57 additions & 59 deletions packages/cli/src/lib/schemaHelpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,38 +10,38 @@ import { singularize, isPlural } from './rwPluralize'
import { getPaths } from './'

/**
* Used to memoize results from `getSchema` so we don't have to go through
* the work of open the file and parsing it from scratch each time getSchema()
* Used to memoize results from `getSchema()` so we don't have to go through
* the work of opening and parsing the file from scratch each time `getSchema()`
* is called with the same model name.
*/
const schemaMemo = {}

/**
* Searches for the given model (ignoring case) in schema.prisma
* Searches for the given model (ignoring case) in `schema.prisma`
* and returns the name as it is written by the user, or
* `undefined` if no model could be found
*/
const getExistingModelName = async (name) => {
if (!name) {
return undefined
}
// Support PascalCase, camelCase, kebab-case, UPPER_CASE, and lowercase model
// names
const modelName = name.replace(/[_-]/g, '').toLowerCase()

// Support PascalCase, camelCase, kebab-case, UPPER_CASE,
// and lowercase model names
const modelName = name.replace(/[_-]/g, '').toLowerCase()
for (let model of Object.values(schemaMemo)) {
if (model.name.toLowerCase() === modelName) {
return model.name
}
}

const schema = await getSchemaDefinitions()

for (let model of schema.datamodel.models) {
const schema = (await getSchemaDefinitions()).datamodel
for (let model of schema.models) {
if (model.name.toLowerCase() === modelName) {
return model.name
}
}

return undefined
}

Expand All @@ -51,64 +51,63 @@ const getExistingModelName = async (name) => {
* entire schema is returned.
*/
export const getSchema = async (name) => {
if (name) {
const modelName = await getExistingModelName(name)
if (!modelName) {
throw new Error(
`No schema definition found for \`${name}\` in schema.prisma file`,
)
}
if (!schemaMemo[modelName]) {
const schema = await getSchemaDefinitions()
const model = schema.datamodel.models.find((model) => {
return model.name === modelName
})

if (model) {
// look for any fields that are enums and attach the possible enum values
// so we can put them in generated test files
model.fields.forEach((field) => {
const fieldEnum = schema.datamodel.enums.find((e) => {
return field.type === e.name
})
if (fieldEnum) {
field.enumValues = fieldEnum.values
}
})

// memoize based on the model name
schemaMemo[modelName] = model
}
}
const schema = (await getSchemaDefinitions()).datamodel

if (!name) {
return schema
}

const modelName = await getExistingModelName(name)
if (!modelName) {
throw new Error(
`No schema definition found for \`${name}\` in schema.prisma file`,
)
}

if (schemaMemo[modelName]) {
return schemaMemo[modelName]
} else {
return (await getSchemaDefinitions()).datamodel
}

const model = schema.models.find((model) => model.name === modelName)
if (!model) {
// TODO: Can this happen, and if yes, should we prefer throwing an error?
return undefined
}

// Look for any fields that are enums and attach the possible enum values
// so we can put them in generated test files
model.fields.forEach((field) => {
const fieldEnum = schema.enums.find((e) => field.type === e.name)
if (fieldEnum) {
field.enumValues = fieldEnum.values
}
})

// Memoize based on the model name
schemaMemo[modelName] = model

return model
}

/**
* Returns the enum defined with the given `name` parsed from
* the schema.prisma of the target application. If no `name` is given then the
* all enum definitions are returned
* Returns the enum defined with the given `name` parsed from the
* `schema.prisma` of the target application. If no `name` is given
* then all enum definitions are returned
*/
export const getEnum = async (name) => {
const schema = await getSchemaDefinitions()
if (!name) {
return schema.metadata.datamodel.enums
}

if (name) {
const model = schema.datamodel.enums.find((model) => {
return model.name === name
})

if (model) {
return model
} else {
throw new Error(
`No enum schema definition found for \`${name}\` in schema.prisma file`,
)
}
const model = schema.datamodel.enums.find((model) => model.name === name)
if (!model) {
throw new Error(
`No enum schema definition found for \`${name}\` in schema.prisma file`,
)
}

return schema.metadata.datamodel.enums
return model
}

/*
Expand All @@ -128,11 +127,10 @@ export const getSchemaDefinitions = () => {
/*
* Returns the config info defined in `schema.prisma` (provider, datasource, etc.)
*/
export const getSchemaConfig = () => {
return getConfig({
export const getSchemaConfig = () =>
getConfig({
datamodel: getDataModel(),
})
}

export async function verifyModelName(options) {
const modelName =
Expand Down

0 comments on commit 121a9b8

Please sign in to comment.