@prisma-extensions/factory
Version:
Factory enables you to easily create and build database records for testing or seeding purposes.
58 lines (45 loc) • 1.65 kB
text/typescript
import { mergeDeepWith } from 'immutable'
import type { ArgReturnType, ExtractData } from './types'
function mergeCallback<T>(_oldVal: unknown, newVal: T): T {
return newVal
}
function evaluateInput<T>(input: T): ArgReturnType<T> {
return typeof input === 'function' ? input() : input
}
export function mergeData<Model, Data extends ExtractData<Model> = ExtractData<Model>>(
baseInput: Data,
input: Partial<Data>,
) {
const evaluatedBaseInput = { ...baseInput } // Create a copy
const evaluatedInput = { ...input } // Create a copy
const newKeys = new Set(Object.keys(input))
const newKeysToEvalute = []
for (const key in baseInput) {
if (newKeys.has(key)) {
newKeysToEvalute.push(key)
continue
}
evaluatedBaseInput[key] = evaluateInput(evaluatedBaseInput[key])
}
for (const key of newKeysToEvalute) {
evaluatedInput[key] = evaluateInput(evaluatedInput[key])
}
return mergeDeepWith(mergeCallback, evaluatedBaseInput, evaluatedInput)
}
export function buildIncludes<Model>(
data: ExtractData<Model>,
): Record<string, boolean> | undefined {
const include: Record<string, any> = {}
for (const key in data) {
const value = data[key]
const isObject = typeof value === 'object' && value !== null
const hasRelation =
isObject &&
(Object.prototype.hasOwnProperty.call(value, 'create') ||
Object.prototype.hasOwnProperty.call(value, 'connect') ||
Object.prototype.hasOwnProperty.call(value, 'connectOrCreate'))
if (hasRelation) include[key] = true
}
const hasInclude = Object.keys(include).length
return hasInclude ? include : undefined
}