@@ -48,6 +48,72 @@ export function getJsonSchema(ctor: Function): JsonDefinition {
48
48
}
49
49
}
50
50
51
+ /**
52
+ * Gets the wrapper function of primitives string, number, and boolean
53
+ * @param type Name of type
54
+ */
55
+ export function stringTypeToWrapper ( type : string ) : Function {
56
+ type = type . toLowerCase ( ) ;
57
+ let wrapper ;
58
+ switch ( type ) {
59
+ case 'number' : {
60
+ wrapper = Number ;
61
+ break ;
62
+ }
63
+ case 'string' : {
64
+ wrapper = String ;
65
+ break ;
66
+ }
67
+ case 'boolean' : {
68
+ wrapper = Boolean ;
69
+ break ;
70
+ }
71
+ default : {
72
+ throw new Error ( 'Unsupported type' ) ;
73
+ }
74
+ }
75
+ return wrapper ;
76
+ }
77
+
78
+ /**
79
+ * Determines whether the given constructor is a custom type or not
80
+ * @param ctor Constructor
81
+ */
82
+ export function isComplexType ( ctor : Function ) {
83
+ return ! includes ( [ String , Number , Boolean , Object , Function ] , ctor ) ;
84
+ }
85
+
86
+ /**
87
+ * Converts property metadata into a JSON property definition
88
+ * @param meta
89
+ */
90
+ export function metaToJsonProperty ( meta : PropertyDefinition ) : JsonDefinition {
91
+ let ctor = meta . type as string | Function ;
92
+ let def : JsonDefinition = { } ;
93
+
94
+ // errors out if @property .array() is not used on a property of array
95
+ if ( ctor === Array ) {
96
+ throw new Error ( 'type is defined as an array' ) ;
97
+ }
98
+
99
+ if ( typeof ctor === 'string' ) {
100
+ ctor = stringTypeToWrapper ( ctor ) ;
101
+ }
102
+
103
+ const propDef = isComplexType ( ctor )
104
+ ? { $ref : `#definitions/${ ctor . name } ` }
105
+ : { type : ctor . name . toLowerCase ( ) } ;
106
+
107
+ if ( meta . array ) {
108
+ def . type = 'array' ;
109
+ def . items = propDef ;
110
+ } else {
111
+ Object . assign ( def , propDef ) ;
112
+ }
113
+
114
+ return def ;
115
+ }
116
+
51
117
// NOTE(shimks) no metadata for: union, optional, nested array, any, enum,
52
118
// string literal, anonymous types, and inherited properties
53
119
@@ -57,80 +123,59 @@ export function getJsonSchema(ctor: Function): JsonDefinition {
57
123
* @param ctor Constructor of class to convert from
58
124
*/
59
125
export function modelToJsonSchema ( ctor : Function ) : JsonDefinition {
60
- const meta : ModelDefinition = ModelMetadataHelper . getModelMetadata ( ctor ) ;
61
- const schema : JsonDefinition = { } ;
126
+ const meta : ModelDefinition | { } = ModelMetadataHelper . getModelMetadata ( ctor ) ;
127
+ const result : JsonDefinition = { } ;
62
128
63
- const isComplexType = ( constructor : Function ) =>
64
- ! includes ( [ String , Number , Boolean , Object ] , constructor ) ;
129
+ // returns an empty object if metadata is an empty object
130
+ if ( ! ( meta instanceof ModelDefinition ) ) {
131
+ return { } ;
132
+ }
65
133
66
- const determinePropertyDef = ( constructor : Function ) =>
67
- isComplexType ( constructor )
68
- ? { $ref : `#definitions/${ constructor . name } ` }
69
- : { type : constructor . name . toLowerCase ( ) } ;
134
+ result . title = meta . title || ctor . name ;
135
+
136
+ if ( meta . description ) {
137
+ result . description = meta . description ;
138
+ }
70
139
71
140
for ( const p in meta . properties ) {
72
- const propMeta = meta . properties [ p ] ;
73
- let propCtor = propMeta . type ;
74
- if ( typeof propCtor === 'string' ) {
75
- const type = propCtor . toLowerCase ( ) ;
76
- switch ( type ) {
77
- case 'number' : {
78
- propCtor = Number ;
79
- break ;
80
- }
81
- case 'string' : {
82
- propCtor = String ;
83
- break ;
84
- }
85
- case 'boolean' : {
86
- propCtor = Boolean ;
87
- break ;
88
- }
89
- default : {
90
- throw new Error ( 'Unsupported type' ) ;
91
- }
92
- }
141
+ if ( ! meta . properties [ p ] . type ) {
142
+ continue ;
93
143
}
94
- if ( propCtor && typeof propCtor === 'function' ) {
95
- // errors out if @property .array() is not used on a property of array
96
- if ( propCtor === Array ) {
97
- throw new Error ( 'type is defined as an array' ) ;
98
- }
99
144
100
- const propDef : JsonDefinition = determinePropertyDef ( propCtor ) ;
145
+ result . properties = result . properties || { } ;
146
+ result . properties [ p ] = result . properties [ p ] || { } ;
101
147
102
- if ( ! schema . properties ) {
103
- schema . properties = { } ;
104
- }
148
+ const property = result . properties [ p ] ;
149
+ const metaProperty = meta . properties [ p ] ;
150
+ const metaType = metaProperty . type ;
105
151
106
- if ( propMeta . array === true ) {
107
- schema . properties [ p ] = {
108
- type : 'array' ,
109
- items : propDef ,
110
- } ;
111
- } else {
112
- schema . properties [ p ] = propDef ;
113
- }
152
+ // populating "properties" key
153
+ result . properties [ p ] = metaToJsonProperty ( metaProperty ) ;
114
154
115
- if ( isComplexType ( propCtor ) ) {
116
- const propSchema = getJsonSchema ( propCtor ) ;
155
+ // populating JSON Schema 'definitions'
156
+ if ( typeof metaType === 'function' && isComplexType ( metaType ) ) {
157
+ const propSchema = getJsonSchema ( metaType ) ;
117
158
118
- if ( propSchema && Object . keys ( propSchema ) . length > 0 ) {
119
- if ( ! schema . definitions ) {
120
- schema . definitions = { } ;
121
- }
159
+ if ( propSchema && Object . keys ( propSchema ) . length > 0 ) {
160
+ result . definitions = result . definitions || { } ;
122
161
123
- if ( propSchema . definitions ) {
124
- for ( const key in propSchema . definitions ) {
125
- schema . definitions [ key ] = propSchema . definitions [ key ] ;
126
- }
127
- delete propSchema . definitions ;
162
+ // delete nested definition
163
+ if ( propSchema . definitions ) {
164
+ for ( const key in propSchema . definitions ) {
165
+ result . definitions [ key ] = propSchema . definitions [ key ] ;
128
166
}
129
-
130
- schema . definitions [ propCtor . name ] = propSchema ;
167
+ delete propSchema . definitions ;
131
168
}
169
+
170
+ result . definitions [ metaType . name ] = propSchema ;
132
171
}
133
172
}
173
+
174
+ // handling 'required' metadata
175
+ if ( metaProperty . required ) {
176
+ result . required = result . required || [ ] ;
177
+ result . required . push ( p ) ;
178
+ }
134
179
}
135
- return schema ;
180
+ return result ;
136
181
}
0 commit comments