1
1
const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$' ;
2
2
const unsafeChars = / [ < > \b \f \n \r \t \0 \u2028 \u2029 ] / g;
3
- const reserved = / ^ (?: d o | i f | i n | f o r | i n t | l e t | n e w | t r y | v a r | b y t e | c a s e | c h a r | e l s e | e n u m | g o t o | l o n g | t h i s | v o i d | w i t h | a w a i t | b r e a k | c a t c h | c l a s s | c o n s t | f i n a l | f l o a t | s h o r t | s u p e r | t h r o w | w h i l e | y i e l d | d e l e t e | d o u b l e | e x p o r t | i m p o r t | n a t i v e | r e t u r n | s w i t c h | t h r o w s | t y p e o f | b o o l e a n | d e f a u l t | e x t e n d s | f i n a l l y | p a c k a g e | p r i v a t e | a b s t r a c t | c o n t i n u e | d e b u g g e r | f u n c t i o n | v o l a t i l e | i n t e r f a c e | p r o t e c t e d | t r a n s i e n t | i m p l e m e n t s | i n s t a n c e o f | s y n c h r o n i z e d ) $ / ;
4
- const escaped : Record < string , string > = {
3
+ const reserved =
4
+ / ^ (?: d o | i f | i n | f o r | i n t | l e t | n e w | t r y | v a r | b y t e | c a s e | c h a r | e l s e | e n u m | g o t o | l o n g | t h i s | v o i d | w i t h | a w a i t | b r e a k | c a t c h | c l a s s | c o n s t | f i n a l | f l o a t | s h o r t | s u p e r | t h r o w | w h i l e | y i e l d | d e l e t e | d o u b l e | e x p o r t | i m p o r t | n a t i v e | r e t u r n | s w i t c h | t h r o w s | t y p e o f | b o o l e a n | d e f a u l t | e x t e n d s | f i n a l l y | p a c k a g e | p r i v a t e | a b s t r a c t | c o n t i n u e | d e b u g g e r | f u n c t i o n | v o l a t i l e | i n t e r f a c e | p r o t e c t e d | t r a n s i e n t | i m p l e m e n t s | i n s t a n c e o f | s y n c h r o n i z e d ) $ / ;
5
+
6
+ /** @type {Record<string, string> } */
7
+ const escaped = {
5
8
'<' : '\\u003C' ,
6
- '>' : '\\u003E' ,
9
+ '>' : '\\u003E' ,
7
10
'/' : '\\u002F' ,
8
11
'\\' : '\\\\' ,
9
12
'\b' : '\\b' ,
@@ -15,12 +18,19 @@ const escaped: Record<string, string> = {
15
18
'\u2028' : '\\u2028' ,
16
19
'\u2029' : '\\u2029'
17
20
} ;
18
- const objectProtoOwnPropertyNames = Object . getOwnPropertyNames ( Object . prototype ) . sort ( ) . join ( '\0' ) ;
19
-
20
- export default function devalue ( value : any ) {
21
+ const objectProtoOwnPropertyNames = Object . getOwnPropertyNames ( Object . prototype )
22
+ . sort ( )
23
+ . join ( '\0' ) ;
24
+
25
+ /**
26
+ * Turn a value into the JavaScript that creates an equivalent value
27
+ * @param {any } value
28
+ */
29
+ export default function devalue ( value ) {
21
30
const counts = new Map ( ) ;
22
31
23
- function walk ( thing : any ) {
32
+ /** @param {any } thing */
33
+ function walk ( thing ) {
24
34
if ( typeof thing === 'function' ) {
25
35
throw new Error ( `Cannot stringify a function` ) ;
26
36
}
@@ -58,7 +68,8 @@ export default function devalue(value: any) {
58
68
if (
59
69
proto !== Object . prototype &&
60
70
proto !== null &&
61
- Object . getOwnPropertyNames ( proto ) . sort ( ) . join ( '\0' ) !== objectProtoOwnPropertyNames
71
+ Object . getOwnPropertyNames ( proto ) . sort ( ) . join ( '\0' ) !==
72
+ objectProtoOwnPropertyNames
62
73
) {
63
74
throw new Error ( `Cannot stringify arbitrary non-POJOs` ) ;
64
75
}
@@ -67,7 +78,7 @@ export default function devalue(value: any) {
67
78
throw new Error ( `Cannot stringify POJOs with symbolic keys` ) ;
68
79
}
69
80
70
- Object . keys ( thing ) . forEach ( key => walk ( thing [ key ] ) ) ;
81
+ Object . keys ( thing ) . forEach ( ( key ) => walk ( thing [ key ] ) ) ;
71
82
}
72
83
}
73
84
}
@@ -77,13 +88,17 @@ export default function devalue(value: any) {
77
88
const names = new Map ( ) ;
78
89
79
90
Array . from ( counts )
80
- . filter ( entry => entry [ 1 ] > 1 )
91
+ . filter ( ( entry ) => entry [ 1 ] > 1 )
81
92
. sort ( ( a , b ) => b [ 1 ] - a [ 1 ] )
82
93
. forEach ( ( entry , i ) => {
83
94
names . set ( entry [ 0 ] , getName ( i ) ) ;
84
95
} ) ;
85
96
86
- function stringify ( thing : any ) : string {
97
+ /**
98
+ * @param {any } thing
99
+ * @returns {string }
100
+ */
101
+ function stringify ( thing ) {
87
102
if ( names . has ( thing ) ) {
88
103
return names . get ( thing ) ;
89
104
}
@@ -107,16 +122,20 @@ export default function devalue(value: any) {
107
122
return `new Date(${ thing . getTime ( ) } )` ;
108
123
109
124
case 'Array' :
110
- const members = thing . map ( ( v : any , i : number ) => i in thing ? stringify ( v ) : '' ) ;
111
- const tail = thing . length === 0 || ( thing . length - 1 in thing ) ? '' : ',' ;
125
+ const members = /** @type {any[] } */ ( thing ) . map ( ( v , i ) =>
126
+ i in thing ? stringify ( v ) : ''
127
+ ) ;
128
+ const tail = thing . length === 0 || thing . length - 1 in thing ? '' : ',' ;
112
129
return `[${ members . join ( ',' ) } ${ tail } ]` ;
113
130
114
131
case 'Set' :
115
132
case 'Map' :
116
133
return `new ${ type } ([${ Array . from ( thing ) . map ( stringify ) . join ( ',' ) } ])` ;
117
134
118
135
default :
119
- const obj = `{${ Object . keys ( thing ) . map ( key => `${ safeKey ( key ) } :${ stringify ( thing [ key ] ) } ` ) . join ( ',' ) } }` ;
136
+ const obj = `{${ Object . keys ( thing )
137
+ . map ( ( key ) => `${ safeKey ( key ) } :${ stringify ( thing [ key ] ) } ` )
138
+ . join ( ',' ) } }`;
120
139
const proto = Object . getPrototypeOf ( thing ) ;
121
140
if ( proto === null ) {
122
141
return Object . keys ( thing ) . length > 0
@@ -131,9 +150,14 @@ export default function devalue(value: any) {
131
150
const str = stringify ( value ) ;
132
151
133
152
if ( names . size ) {
134
- const params : string [ ] = [ ] ;
135
- const statements : string [ ] = [ ] ;
136
- const values : string [ ] = [ ] ;
153
+ /** @type {string[] } */
154
+ const params = [ ] ;
155
+
156
+ /** @type {string[] } */
157
+ const statements = [ ] ;
158
+
159
+ /** @type {string[] } */
160
+ const values = [ ] ;
137
161
138
162
names . forEach ( ( name , thing ) => {
139
163
params . push ( name ) ;
@@ -162,38 +186,51 @@ export default function devalue(value: any) {
162
186
163
187
case 'Array' :
164
188
values . push ( `Array(${ thing . length } )` ) ;
165
- thing . forEach ( ( v : any , i : number ) => {
189
+ /** @type { any[] } */ ( thing ) . forEach ( ( v , i ) => {
166
190
statements . push ( `${ name } [${ i } ]=${ stringify ( v ) } ` ) ;
167
191
} ) ;
168
192
break ;
169
193
170
194
case 'Set' :
171
195
values . push ( `new Set` ) ;
172
- statements . push ( `${ name } .${ Array . from ( thing ) . map ( v => `add(${ stringify ( v ) } )` ) . join ( '.' ) } ` ) ;
196
+ statements . push (
197
+ `${ name } .${ Array . from ( thing )
198
+ . map ( ( v ) => `add(${ stringify ( v ) } )` )
199
+ . join ( '.' ) } `
200
+ ) ;
173
201
break ;
174
202
175
203
case 'Map' :
176
204
values . push ( `new Map` ) ;
177
- statements . push ( `${ name } .${ Array . from ( thing ) . map ( ( [ k , v ] ) => `set(${ stringify ( k ) } , ${ stringify ( v ) } )` ) . join ( '.' ) } ` ) ;
205
+ statements . push (
206
+ `${ name } .${ Array . from ( thing )
207
+ . map ( ( [ k , v ] ) => `set(${ stringify ( k ) } , ${ stringify ( v ) } )` )
208
+ . join ( '.' ) } `
209
+ ) ;
178
210
break ;
179
211
180
212
default :
181
- values . push ( Object . getPrototypeOf ( thing ) === null ? 'Object.create(null)' : '{}' ) ;
182
- Object . keys ( thing ) . forEach ( key => {
213
+ values . push (
214
+ Object . getPrototypeOf ( thing ) === null ? 'Object.create(null)' : '{}'
215
+ ) ;
216
+ Object . keys ( thing ) . forEach ( ( key ) => {
183
217
statements . push ( `${ name } ${ safeProp ( key ) } =${ stringify ( thing [ key ] ) } ` ) ;
184
218
} ) ;
185
219
}
186
220
} ) ;
187
221
188
222
statements . push ( `return ${ str } ` ) ;
189
223
190
- return `(function(${ params . join ( ',' ) } ){${ statements . join ( ';' ) } }(${ values . join ( ',' ) } ))`
224
+ return `(function(${ params . join ( ',' ) } ){${ statements . join (
225
+ ';'
226
+ ) } }(${ values . join ( ',' ) } ))`;
191
227
} else {
192
228
return str ;
193
229
}
194
230
}
195
231
196
- function getName ( num : number ) {
232
+ /** @param {number } num */
233
+ function getName ( num ) {
197
234
let name = '' ;
198
235
199
236
do {
@@ -204,11 +241,13 @@ function getName(num: number) {
204
241
return reserved . test ( name ) ? `${ name } _` : name ;
205
242
}
206
243
207
- function isPrimitive ( thing : any ) {
244
+ /** @param {any } thing */
245
+ function isPrimitive ( thing ) {
208
246
return Object ( thing ) !== thing ;
209
247
}
210
248
211
- function stringifyPrimitive ( thing : any ) {
249
+ /** @param {any } thing */
250
+ function stringifyPrimitive ( thing ) {
212
251
if ( typeof thing === 'string' ) return stringifyString ( thing ) ;
213
252
if ( thing === void 0 ) return 'void 0' ;
214
253
if ( thing === 0 && 1 / thing < 0 ) return '-0' ;
@@ -217,27 +256,37 @@ function stringifyPrimitive(thing: any) {
217
256
return str ;
218
257
}
219
258
220
- function getType ( thing : any ) {
259
+ /** @param {any } thing */
260
+ function getType ( thing ) {
221
261
return Object . prototype . toString . call ( thing ) . slice ( 8 , - 1 ) ;
222
262
}
223
263
224
- function escapeUnsafeChar ( c : string ) {
225
- return escaped [ c ] || c
264
+ /** @param {string } c */
265
+ function escapeUnsafeChar ( c ) {
266
+ return escaped [ c ] || c ;
226
267
}
227
268
228
- function escapeUnsafeChars ( str : string ) {
229
- return str . replace ( unsafeChars , escapeUnsafeChar )
269
+ /** @param {string } str */
270
+ function escapeUnsafeChars ( str ) {
271
+ return str . replace ( unsafeChars , escapeUnsafeChar ) ;
230
272
}
231
273
232
- function safeKey ( key : string ) {
233
- return / ^ [ _ $ a - z A - Z ] [ _ $ a - z A - Z 0 - 9 ] * $ / . test ( key ) ? key : escapeUnsafeChars ( JSON . stringify ( key ) ) ;
274
+ /** @param {string } key */
275
+ function safeKey ( key ) {
276
+ return / ^ [ _ $ a - z A - Z ] [ _ $ a - z A - Z 0 - 9 ] * $ / . test ( key )
277
+ ? key
278
+ : escapeUnsafeChars ( JSON . stringify ( key ) ) ;
234
279
}
235
280
236
- function safeProp ( key : string ) {
237
- return / ^ [ _ $ a - z A - Z ] [ _ $ a - z A - Z 0 - 9 ] * $ / . test ( key ) ? `.${ key } ` : `[${ escapeUnsafeChars ( JSON . stringify ( key ) ) } ]` ;
281
+ /** @param {string } key */
282
+ function safeProp ( key ) {
283
+ return / ^ [ _ $ a - z A - Z ] [ _ $ a - z A - Z 0 - 9 ] * $ / . test ( key )
284
+ ? `.${ key } `
285
+ : `[${ escapeUnsafeChars ( JSON . stringify ( key ) ) } ]` ;
238
286
}
239
287
240
- function stringifyString ( str : string ) {
288
+ /** @param {string } str */
289
+ function stringifyString ( str ) {
241
290
let result = '"' ;
242
291
243
292
for ( let i = 0 ; i < str . length ; i += 1 ) {
@@ -253,7 +302,7 @@ function stringifyString(str: string) {
253
302
254
303
// If this is the beginning of a [high, low] surrogate pair,
255
304
// add the next two characters, otherwise escape
256
- if ( code <= 0xdbff && ( next >= 0xdc00 && next <= 0xdfff ) ) {
305
+ if ( code <= 0xdbff && next >= 0xdc00 && next <= 0xdfff ) {
257
306
result += char + str [ ++ i ] ;
258
307
} else {
259
308
result += `\\u${ code . toString ( 16 ) . toUpperCase ( ) } ` ;
0 commit comments