@@ -2,6 +2,7 @@ import type { DMMF } from '@prisma/generator-helper';
22
33const transformField = ( field : DMMF . Field ) => {
44 const tokens = [ field . name + ':' ] ;
5+ const deps = new Set ( ) ;
56
67 if ( [ 'Int' , 'Float' ] . includes ( field . type ) ) {
78 tokens . push ( 'Type.Number()' ) ;
@@ -10,28 +11,32 @@ const transformField = (field: DMMF.Field) => {
1011 } else if ( field . type === 'Boolean' ) {
1112 tokens . push ( 'Type.Boolean()' ) ;
1213 } else {
13- return '' ;
14+ tokens . push ( `::${ field . type } ::` ) ;
15+ deps . add ( field . type ) ;
1416 }
1517
1618 if ( field . isList ) {
1719 tokens . splice ( 1 , 0 , 'Type.Array(' ) ;
1820 tokens . splice ( tokens . length , 0 , ')' ) ;
1921 }
2022
21- if ( ! field . isRequired ) {
23+ if ( ! field . isRequired || field . hasDefaultValue ) {
2224 tokens . splice ( 1 , 0 , 'Type.Optional(' ) ;
2325 tokens . splice ( tokens . length , 0 , ')' ) ;
2426 }
2527
26- return tokens . join ( ' ' ) . concat ( '\n' ) ;
28+ return { str : tokens . join ( ' ' ) . concat ( '\n' ) , deps } ;
2729} ;
2830
2931const transformFields = ( fields : DMMF . Field [ ] ) => {
3032 let dependencies = new Set ( ) ;
3133 const _fields : string [ ] = [ ] ;
3234
3335 fields . map ( transformField ) . forEach ( ( field ) => {
34- _fields . push ( field ) ;
36+ _fields . push ( field . str ) ;
37+ [ ...field . deps ] . forEach ( ( d ) => {
38+ dependencies . add ( d ) ;
39+ } ) ;
3540 } ) ;
3641
3742 return {
@@ -40,16 +45,23 @@ const transformFields = (fields: DMMF.Field[]) => {
4045 } ;
4146} ;
4247
43- const transformModel = ( model : DMMF . Model ) => {
48+ const transformModel = ( model : DMMF . Model , dependant : string | null = null ) => {
4449 const fields = transformFields ( model . fields ) ;
45-
46- return [
47- `import {Type, Static} from '@sinclair/typebox'\n` ,
48- `\nexport const ${ model . name } = Type.Object({\n\t` ,
50+ let raw = [
51+ `${ dependant ? '' : `export const ${ model . name } = ` } Type.Object({\n\t` ,
4952 fields . rawString ,
50- '})\n' ,
51- `\nexport type ${ model . name } Type = Static<typeof ${ model . name } >` ,
52- ] . join ( '' ) ;
53+ '})' ,
54+ ] . join ( '\n' ) ;
55+
56+ if ( typeof dependant === 'string' ) {
57+ const re = new RegExp ( `.+::${ dependant } .+\n` ) ;
58+ raw = raw . replace ( re , '' ) ;
59+ }
60+
61+ return {
62+ raw,
63+ deps : fields . dependencies ,
64+ } ;
5365} ;
5466
5567export const transformEnum = ( enm : DMMF . DatamodelEnum ) => {
@@ -58,7 +70,6 @@ export const transformEnum = (enm: DMMF.DatamodelEnum) => {
5870 . join ( '' ) ;
5971
6072 return [
61- "import {Type, Static} from '@sinclair/typebox'\n" ,
6273 `export const ${ enm . name } Const = {` ,
6374 values ,
6475 '}\n' ,
@@ -69,18 +80,46 @@ export const transformEnum = (enm: DMMF.DatamodelEnum) => {
6980
7081export function transformDMMF ( dmmf : DMMF . Document ) {
7182 const { models, enums } = dmmf . datamodel ;
83+ const importStatements = new Set ( [
84+ 'import {Type, Static} from "@sinclair/typebox"' ,
85+ ] ) ;
7286
7387 return [
7488 ...models . map ( ( model ) => {
89+ let { raw, deps } = transformModel ( model ) ;
90+
91+ [ ...deps ] . forEach ( ( d ) => {
92+ const depsModel = models . find ( ( m ) => m . name === d ) as DMMF . Model ;
93+ if ( depsModel ) {
94+ const replacer = transformModel ( depsModel , model . name ) ;
95+ const re = new RegExp ( `::${ d } ::` , 'gm' ) ;
96+ raw = raw . replace ( re , replacer . raw ) ;
97+ }
98+ } ) ;
99+
100+ enums . forEach ( ( enm ) => {
101+ const re = new RegExp ( `::${ enm . name } ::` , 'gm' ) ;
102+ if ( raw . match ( re ) ) {
103+ raw = raw . replace ( re , enm . name ) ;
104+ importStatements . add ( `import { ${ enm . name } } from './${ enm . name } '` ) ;
105+ }
106+ } ) ;
107+
75108 return {
76109 name : model . name ,
77- rawString : transformModel ( model ) ,
110+ rawString : [
111+ [ ...importStatements ] . join ( '\n' ) ,
112+ raw ,
113+ `export type ${ model . name } Type = Static<typeof ${ model . name } >` ,
114+ ] . join ( '\n\n' ) ,
78115 } ;
79116 } ) ,
80117 ...enums . map ( ( enm ) => {
81118 return {
82119 name : enm . name ,
83- rawString : transformEnum ( enm ) ,
120+ rawString :
121+ 'import {Type, Static} from "@sinclair/typebox"\n\n' +
122+ transformEnum ( enm ) ,
84123 } ;
85124 } ) ,
86125 ] ;
0 commit comments