import { DMMF } from '@prisma/client/runtime/dmmf-types' ; import ml from 'multilines' ; import { EOL } from 'os' ; import { Scalar } from '../static/scalars' ; import { filterMap } from '../static/utils' ; param dmmf export function generateGeneratedSeedModelsType ( dmmf ) { const models = dmmf . datamodel . models ; const enums = dmmf . datamodel . enums ; const generatedGenerateSeedModelsType = ml `
  | "*": { amount: number }
  | ${ models . map ( generateSeedModelType ) . join ( EOL ) }
  ` ; return generatedGenerateSeedModelsType ; param model function generateSeedModelType ( model ) { const fields = model . fields ; /**
         * Factory has to be required on models that include non default
         * scalar fields.
         */ const hasSupportedScalars = fields . filter ( isScalar ) . every ( isSupportedScalar ) ; const generatedSeedModelType = ml `
    | ${ model . name }${ q ( hasSupportedScalars ) }: { 
    |   amount?: number, 
    |   factory${ q ( hasSupportedScalars ) }: {
    |     ${ filterMap ( fields , f => generateSeedModelFieldType ( model , f ) ) . join ( EOL ) } 
    |   }
    | }
    ` ; return generatedSeedModelType ; } param field function generateSeedModelFieldType ( model , field ) { switch ( field . kind ) { case 'enum' : { /**
                 * The field should generate a function which results in one
                 * of the enum values.
                 */ const { values } = enums . find ( e => e . name === field . type ) ! ; const union = values . map ( val => `"${ val }"` ) . join ( ` | ` ) ; return `${ field . name }?: (${ union }) | (() => ${ union })` ; } case 'object' : { /**
                 * The field should return a min or max number on abmigious
                 * fields.
                 */ const relationType = getRelationType ( model , field ) ; switch ( relationType ) { case '1-to-many' : { return `${ field . name }?: { min?: number, max?: number }` ; } case 'many-to-many' : { return `${ field . name }?: { min?: number, max?: number }` ; } case '1-to-1' : { if ( field . isRequired ) return null ; return `${ field . name }?: { min?: 0 | 1, max?: 0 | 1 }` ; } case 'many-to-1' : { if ( field . isRequired ) return null ; return `${ field . name }?: { min?: 0 | 1, max?: 0 | 1 }` ; } default : { const never = relationType ; throw new Error ( 'Not possible!' ) ; } } } case 'scalar' : { const scalar = getTSTypeFromDMMFScalar ( field . type ) ; const supported = isSupportedScalar ( field ) ; if ( field . isList ) { return `${ field . name }${ q ( supported ) }: ${ scalar }[] | (() => ${ scalar }[])` ; } /**
                 * The field should provide a function which results in a type
                 * of the scalar.
                 */ return `${ field . name }${ q ( supported ) }: ${ scalar } | (() => ${ scalar })` ; } default : { const never = field . kind ; throw new Error ( `Received unexpected field kind "${ field . kind }"` ) ; } } } param type function getTSTypeFromDMMFScalar ( type ) { switch ( type ) { case Scalar . string : { return 'string' ; } case Scalar . int : { return 'number' ; } case Scalar . float : { return 'number' ; } case Scalar . bool : { return 'boolean' ; } case Scalar . date : { return 'string' ; } default : { return 'any' ; } } } param field function getRelationType ( model , field ) { /**
         * Find the back relation.
         */ const relationModel = models . find ( m => m . name === field . type ) ! ; const relationField = relationModel . fields . find ( f => f . type === model . name ) ! ; if ( field . isList && relationField . isList ) { /**
             * many-to-many (A)
             *
             * model A {
             *  bs: [B]
             * }
             * model B {
             *  as: [A]
             * }
             */ return 'many-to-many' ; } else if ( ! field . isList && relationField . isList ) { /**
             * many-to-1 (A)
             *
             * model A {
             *  b: B
             * }
             * model B {
             *  as: [A]
             * }
             */ return 'many-to-1' ; } else if ( field . isList && ! relationField . isList ) { /**
             * 1-to-many (A)
             *
             * model A {
             *  bs: b[]
             * }
             *
             * model B {
             *  a: A
             * }
             */ return '1-to-many' ; } else { /**
             * 1-to-1 (A)
             *
             * model A {
             *  b: B
             * }
             * model B {
             *  a: A
             * }
             */ return '1-to-1' ; } } param isOptional function q ( isOptional ) { switch ( isOptional ) { case true : { return '?' ; } case false : { return '' ; } } } } param field export function isSupportedScalar ( field ) { return Object . values ( Scalar ) . some ( s => s === field . type ) ; } param field export function isScalar ( field ) { return field . kind === 'scalar' ; }