@@ -29,13 +29,19 @@ import isPlainObject from 'lodash.isplainobject';
29
29
import Introspecter from './Introspecter' ;
30
30
import type { InputGuesserProps , IntrospectedInputGuesserProps } from './types' ;
31
31
32
+ const convertEmptyStringToNull = ( value : string ) =>
33
+ value === '' ? null : value ;
34
+
35
+ const convertNullToEmptyString = ( value : string | null ) => value ?? '' ;
36
+
32
37
export const IntrospectedInputGuesser = ( {
33
38
fields,
34
39
readableFields,
35
40
writableFields,
36
41
schema,
37
42
schemaAnalyzer,
38
43
validate,
44
+ sanitizeEmptyValue = true ,
39
45
...props
40
46
} : IntrospectedInputGuesserProps ) => {
41
47
const field = fields . find ( ( { name } ) => name === props . source ) ;
@@ -82,6 +88,12 @@ export const IntrospectedInputGuesser = ({
82
88
) ;
83
89
}
84
90
91
+ const defaultValueSanitize = sanitizeEmptyValue ? null : '' ;
92
+ const formatSanitize = ( value : string | null ) =>
93
+ convertNullToEmptyString ( value ) ;
94
+ const parseSanitize = ( value : string ) =>
95
+ sanitizeEmptyValue ? convertEmptyStringToNull ( value ) : value ;
96
+
85
97
let { format, parse } = props ;
86
98
const fieldType = schemaAnalyzer . getFieldType ( field ) ;
87
99
@@ -100,9 +112,20 @@ export const IntrospectedInputGuesser = ({
100
112
} ;
101
113
}
102
114
103
- const formatEmbedded = ( value : string | object ) =>
104
- typeof value === 'string' ? value : JSON . stringify ( value ) ;
105
- const parseEmbedded = ( value : string ) => {
115
+ const formatEmbedded = ( value : string | object | null ) => {
116
+ if ( value === null ) {
117
+ return '' ;
118
+ }
119
+ if ( typeof value === 'string' ) {
120
+ return value ;
121
+ }
122
+
123
+ return JSON . stringify ( value ) ;
124
+ } ;
125
+ const parseEmbedded = ( value : string | null ) => {
126
+ if ( value === null ) {
127
+ return null ;
128
+ }
106
129
try {
107
130
const parsed = JSON . parse ( value ) ;
108
131
if ( ! isPlainObject ( parsed ) ) {
@@ -113,20 +136,22 @@ export const IntrospectedInputGuesser = ({
113
136
return value ;
114
137
}
115
138
} ;
139
+ const parseEmbeddedSanitize = ( value : string ) =>
140
+ parseEmbedded ( parseSanitize ( value ) ) ;
116
141
117
142
if ( field . embedded !== null && field . maxCardinality === 1 ) {
118
143
format = formatEmbedded ;
119
- parse = parseEmbedded ;
144
+ parse = parseEmbeddedSanitize ;
120
145
}
121
146
122
- let textInputFormat = ( value : string ) => value ;
123
- let textInputParse = ( value : string ) => value ;
147
+ let textInputFormat = formatSanitize ;
148
+ let textInputParse = parseSanitize ;
124
149
125
150
switch ( fieldType ) {
126
151
case 'array' :
127
152
if ( field . embedded !== null && field . maxCardinality !== 1 ) {
128
153
textInputFormat = formatEmbedded ;
129
- textInputParse = parseEmbedded ;
154
+ textInputParse = parseEmbeddedSanitize ;
130
155
}
131
156
132
157
return (
@@ -138,6 +163,7 @@ export const IntrospectedInputGuesser = ({
138
163
< SimpleFormIterator >
139
164
< TextInput
140
165
source = ""
166
+ defaultValue = { defaultValueSanitize }
141
167
format = { textInputFormat }
142
168
parse = { textInputParse }
143
169
/>
@@ -212,9 +238,10 @@ export const IntrospectedInputGuesser = ({
212
238
< TextInput
213
239
key = { field . name }
214
240
validate = { guessedValidate }
241
+ defaultValue = { defaultValueSanitize }
215
242
{ ...( props as TextInputProps ) }
216
- format = { format }
217
- parse = { parse }
243
+ format = { format ?? formatSanitize }
244
+ parse = { parse ?? parseSanitize }
218
245
source = { field . name }
219
246
/>
220
247
) ;
0 commit comments