2
2
// SPDX-License-Identifier: MIT
3
3
// Copyright (c) vis.gl contributors
4
4
5
- import { JSONConfiguration } from './json-configuration' ;
5
+ import { JSONConfiguration , JSONConfigurationProps } from './json-configuration' ;
6
6
import { FUNCTION_IDENTIFIER , CONSTANT_IDENTIFIER , FUNCTION_KEY } from './syntactic-sugar' ;
7
7
import { instantiateClass } from './helpers/instantiate-class' ;
8
8
import { executeFunction } from './helpers/execute-function' ;
9
- import { assert } from './utils/assert' ;
10
9
import { parseJSON } from './helpers/parse-json' ;
11
10
12
11
function isObject ( value : unknown ) : value is Record < string , unknown > {
13
- return ! ! value && typeof value === 'object' ;
12
+ return Boolean ( value ) && typeof value === 'object' ;
14
13
}
15
14
16
- export type JSONConverterProps = JSONConfiguration & {
15
+ export type JSONConverterProps = {
16
+ configuration : JSONConfiguration | JSONConfigurationProps ;
17
17
onJSONChange : ( ) => void ;
18
18
} ;
19
19
@@ -43,14 +43,14 @@ export class JSONConverter {
43
43
// eslint-disable-next-line @typescript-eslint/no-empty-function
44
44
finalize ( ) { }
45
45
46
- setProps ( props : JSONConverterProps ) {
46
+ setProps ( props : JSONConverterProps | JSONConfiguration ) {
47
47
// HANDLE CONFIGURATION PROPS
48
48
if ( 'configuration' in props ) {
49
49
// Accept object or `JSONConfiguration`
50
50
this . configuration =
51
51
props . configuration instanceof JSONConfiguration
52
52
? props . configuration
53
- : new JSONConfiguration ( props . config ) ;
53
+ : new JSONConfiguration ( props . configuration ) ;
54
54
}
55
55
56
56
if ( 'onJSONChange' in props ) {
@@ -72,6 +72,9 @@ export class JSONConverter {
72
72
73
73
// Accept JSON strings by parsing them
74
74
const parsedJSON = parseJSON ( json ) ;
75
+ if ( ! isObject ( parsedJSON ) ) {
76
+ throw new Error ( 'JSONConverter: expected an object' ) ;
77
+ }
75
78
76
79
// Convert the JSON
77
80
let convertedJson = convertJSON ( parsedJSON , this . configuration ) ;
@@ -88,9 +91,9 @@ export class JSONConverter {
88
91
}
89
92
}
90
93
91
- function convertJSON ( json : unknown , configuration : JSONConfiguration ) {
94
+ function convertJSON ( json : Record < string , unknown > , configuration : JSONConfiguration ) {
92
95
// Fixup configuration
93
- configuration = new JSONConfiguration ( configuration ) ;
96
+ configuration = new JSONConfiguration ( configuration . config ) ;
94
97
return convertJSONRecursively ( json , '' , configuration ) ;
95
98
}
96
99
@@ -100,12 +103,12 @@ function convertJSONRecursively(json: unknown, key, configuration) {
100
103
return json . map ( ( element , i ) => convertJSONRecursively ( element , String ( i ) , configuration ) ) ;
101
104
}
102
105
103
- // If object.type is in configuration, instantiate
104
- if ( isClassInstance ( json , configuration ) ) {
105
- return convertClassInstance ( json , configuration ) ;
106
- }
107
-
108
106
if ( isObject ( json ) ) {
107
+ // If object.type is in configuration, instantiate
108
+ if ( isClassInstance ( json , configuration ) ) {
109
+ return convertClassInstance ( json , configuration ) ;
110
+ }
111
+
109
112
// If object.function is in configuration, convert object to function
110
113
if ( FUNCTION_KEY in json ) {
111
114
return convertFunctionObject ( json , configuration ) ;
@@ -123,15 +126,15 @@ function convertJSONRecursively(json: unknown, key, configuration) {
123
126
}
124
127
125
128
/** Returns true if an object has a `type` field */
126
- function isClassInstance ( json : unknown , configuration : JSONConfiguration ) {
127
- const { typeKey} = configuration ;
129
+ function isClassInstance ( json : Record < string , unknown > , configuration : JSONConfiguration ) {
130
+ const { typeKey} = configuration . config ;
128
131
const isClass = isObject ( json ) && Boolean ( json [ typeKey ] ) ;
129
132
return isClass ;
130
133
}
131
134
132
- function convertClassInstance ( json : unknown , configuration : JSONConfiguration ) {
135
+ function convertClassInstance ( json : Record < string , unknown > , configuration : JSONConfiguration ) {
133
136
// Extract the class type field
134
- const { typeKey} = configuration ;
137
+ const { typeKey} = configuration . config ;
135
138
const type = json [ typeKey ] ;
136
139
137
140
// Prepare a props object and ensure all values have been converted
@@ -144,9 +147,9 @@ function convertClassInstance(json: unknown, configuration: JSONConfiguration) {
144
147
}
145
148
146
149
/** Plain JS object, embed functions. */
147
- function convertFunctionObject ( json , configuration :JSONConfiguration ) {
150
+ function convertFunctionObject ( json , configuration : JSONConfiguration ) {
148
151
// Extract the target function field
149
- const { functionKey} = configuration ;
152
+ const { functionKey} = configuration . config ;
150
153
const targetFunction = json [ functionKey ] ;
151
154
152
155
// Prepare a props object and ensure all values have been converted
@@ -165,8 +168,7 @@ function convertPlainObject(json: unknown, configuration: JSONConfiguration) {
165
168
}
166
169
167
170
const result = { } ;
168
- for ( const key in json ) {
169
- const value = json [ key ] ;
171
+ for ( const [ key , value ] of Object . entries ( json ) ) {
170
172
result [ key ] = convertJSONRecursively ( value , key , configuration ) ;
171
173
}
172
174
return result ;
@@ -175,20 +177,20 @@ function convertPlainObject(json: unknown, configuration: JSONConfiguration) {
175
177
/** Convert one string value in an object
176
178
* @todo We could also support string syntax for hydrating other types, like regexps... But no current use case
177
179
*/
178
- function convertString ( string , key , configuration : JSONConfiguration ) {
180
+ function convertString ( string : string , key : string , configuration : JSONConfiguration ) {
179
181
// Here the JSON value is supposed to be treated as a function
180
182
if ( string . startsWith ( FUNCTION_IDENTIFIER ) && configuration . convertFunction ) {
181
183
string = string . replace ( FUNCTION_IDENTIFIER , '' ) ;
182
184
return configuration . convertFunction ( string , configuration ) ;
183
185
}
184
186
if ( string . startsWith ( CONSTANT_IDENTIFIER ) ) {
185
187
string = string . replace ( CONSTANT_IDENTIFIER , '' ) ;
186
- if ( configuration . constants [ string ] ) {
187
- return configuration . constants [ string ] ;
188
+ if ( configuration . config . constants [ string ] ) {
189
+ return configuration . config . constants [ string ] ;
188
190
}
189
191
// enum
190
192
const [ enumVarName , enumValName ] = string . split ( '.' ) ;
191
- return configuration . enumerations [ enumVarName ] [ enumValName ] ;
193
+ return configuration . config . enumerations [ enumVarName ] [ enumValName ] ;
192
194
}
193
195
return string ;
194
196
}
0 commit comments