Skip to content

Commit 85dfe25

Browse files
committed
modernise
1 parent 10c0371 commit 85dfe25

13 files changed

+319
-1216
lines changed

.travis.yml

Lines changed: 0 additions & 7 deletions
This file was deleted.

appveyor.yml

Lines changed: 0 additions & 30 deletions
This file was deleted.

src/index.ts renamed to devalue.js

Lines changed: 86 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$';
22
const unsafeChars = /[<>\b\f\n\r\t\0\u2028\u2029]/g;
3-
const reserved = /^(?:do|if|in|for|int|let|new|try|var|byte|case|char|else|enum|goto|long|this|void|with|await|break|catch|class|const|final|float|short|super|throw|while|yield|delete|double|export|import|native|return|switch|throws|typeof|boolean|default|extends|finally|package|private|abstract|continue|debugger|function|volatile|interface|protected|transient|implements|instanceof|synchronized)$/;
4-
const escaped: Record<string, string> = {
3+
const reserved =
4+
/^(?:do|if|in|for|int|let|new|try|var|byte|case|char|else|enum|goto|long|this|void|with|await|break|catch|class|const|final|float|short|super|throw|while|yield|delete|double|export|import|native|return|switch|throws|typeof|boolean|default|extends|finally|package|private|abstract|continue|debugger|function|volatile|interface|protected|transient|implements|instanceof|synchronized)$/;
5+
6+
/** @type {Record<string, string>} */
7+
const escaped = {
58
'<': '\\u003C',
6-
'>' : '\\u003E',
9+
'>': '\\u003E',
710
'/': '\\u002F',
811
'\\': '\\\\',
912
'\b': '\\b',
@@ -15,12 +18,19 @@ const escaped: Record<string, string> = {
1518
'\u2028': '\\u2028',
1619
'\u2029': '\\u2029'
1720
};
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) {
2130
const counts = new Map();
2231

23-
function walk(thing: any) {
32+
/** @param {any} thing */
33+
function walk(thing) {
2434
if (typeof thing === 'function') {
2535
throw new Error(`Cannot stringify a function`);
2636
}
@@ -58,7 +68,8 @@ export default function devalue(value: any) {
5868
if (
5969
proto !== Object.prototype &&
6070
proto !== null &&
61-
Object.getOwnPropertyNames(proto).sort().join('\0') !== objectProtoOwnPropertyNames
71+
Object.getOwnPropertyNames(proto).sort().join('\0') !==
72+
objectProtoOwnPropertyNames
6273
) {
6374
throw new Error(`Cannot stringify arbitrary non-POJOs`);
6475
}
@@ -67,7 +78,7 @@ export default function devalue(value: any) {
6778
throw new Error(`Cannot stringify POJOs with symbolic keys`);
6879
}
6980

70-
Object.keys(thing).forEach(key => walk(thing[key]));
81+
Object.keys(thing).forEach((key) => walk(thing[key]));
7182
}
7283
}
7384
}
@@ -77,13 +88,17 @@ export default function devalue(value: any) {
7788
const names = new Map();
7889

7990
Array.from(counts)
80-
.filter(entry => entry[1] > 1)
91+
.filter((entry) => entry[1] > 1)
8192
.sort((a, b) => b[1] - a[1])
8293
.forEach((entry, i) => {
8394
names.set(entry[0], getName(i));
8495
});
8596

86-
function stringify(thing: any): string {
97+
/**
98+
* @param {any} thing
99+
* @returns {string}
100+
*/
101+
function stringify(thing) {
87102
if (names.has(thing)) {
88103
return names.get(thing);
89104
}
@@ -107,16 +122,20 @@ export default function devalue(value: any) {
107122
return `new Date(${thing.getTime()})`;
108123

109124
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 ? '' : ',';
112129
return `[${members.join(',')}${tail}]`;
113130

114131
case 'Set':
115132
case 'Map':
116133
return `new ${type}([${Array.from(thing).map(stringify).join(',')}])`;
117134

118135
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(',')}}`;
120139
const proto = Object.getPrototypeOf(thing);
121140
if (proto === null) {
122141
return Object.keys(thing).length > 0
@@ -131,9 +150,14 @@ export default function devalue(value: any) {
131150
const str = stringify(value);
132151

133152
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 = [];
137161

138162
names.forEach((name, thing) => {
139163
params.push(name);
@@ -162,38 +186,51 @@ export default function devalue(value: any) {
162186

163187
case 'Array':
164188
values.push(`Array(${thing.length})`);
165-
thing.forEach((v: any, i: number) => {
189+
/** @type {any[]} */ (thing).forEach((v, i) => {
166190
statements.push(`${name}[${i}]=${stringify(v)}`);
167191
});
168192
break;
169193

170194
case 'Set':
171195
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+
);
173201
break;
174202

175203
case 'Map':
176204
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+
);
178210
break;
179211

180212
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) => {
183217
statements.push(`${name}${safeProp(key)}=${stringify(thing[key])}`);
184218
});
185219
}
186220
});
187221

188222
statements.push(`return ${str}`);
189223

190-
return `(function(${params.join(',')}){${statements.join(';')}}(${values.join(',')}))`
224+
return `(function(${params.join(',')}){${statements.join(
225+
';'
226+
)}}(${values.join(',')}))`;
191227
} else {
192228
return str;
193229
}
194230
}
195231

196-
function getName(num: number) {
232+
/** @param {number} num */
233+
function getName(num) {
197234
let name = '';
198235

199236
do {
@@ -204,11 +241,13 @@ function getName(num: number) {
204241
return reserved.test(name) ? `${name}_` : name;
205242
}
206243

207-
function isPrimitive(thing: any) {
244+
/** @param {any} thing */
245+
function isPrimitive(thing) {
208246
return Object(thing) !== thing;
209247
}
210248

211-
function stringifyPrimitive(thing: any) {
249+
/** @param {any} thing */
250+
function stringifyPrimitive(thing) {
212251
if (typeof thing === 'string') return stringifyString(thing);
213252
if (thing === void 0) return 'void 0';
214253
if (thing === 0 && 1 / thing < 0) return '-0';
@@ -217,27 +256,37 @@ function stringifyPrimitive(thing: any) {
217256
return str;
218257
}
219258

220-
function getType(thing: any) {
259+
/** @param {any} thing */
260+
function getType(thing) {
221261
return Object.prototype.toString.call(thing).slice(8, -1);
222262
}
223263

224-
function escapeUnsafeChar(c: string) {
225-
return escaped[c] || c
264+
/** @param {string} c */
265+
function escapeUnsafeChar(c) {
266+
return escaped[c] || c;
226267
}
227268

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);
230272
}
231273

232-
function safeKey(key: string) {
233-
return /^[_$a-zA-Z][_$a-zA-Z0-9]*$/.test(key) ? key : escapeUnsafeChars(JSON.stringify(key));
274+
/** @param {string} key */
275+
function safeKey(key) {
276+
return /^[_$a-zA-Z][_$a-zA-Z0-9]*$/.test(key)
277+
? key
278+
: escapeUnsafeChars(JSON.stringify(key));
234279
}
235280

236-
function safeProp(key: string) {
237-
return /^[_$a-zA-Z][_$a-zA-Z0-9]*$/.test(key) ? `.${key}` : `[${escapeUnsafeChars(JSON.stringify(key))}]`;
281+
/** @param {string} key */
282+
function safeProp(key) {
283+
return /^[_$a-zA-Z][_$a-zA-Z0-9]*$/.test(key)
284+
? `.${key}`
285+
: `[${escapeUnsafeChars(JSON.stringify(key))}]`;
238286
}
239287

240-
function stringifyString(str: string) {
288+
/** @param {string} str */
289+
function stringifyString(str) {
241290
let result = '"';
242291

243292
for (let i = 0; i < str.length; i += 1) {
@@ -253,7 +302,7 @@ function stringifyString(str: string) {
253302

254303
// If this is the beginning of a [high, low] surrogate pair,
255304
// add the next two characters, otherwise escape
256-
if (code <= 0xdbff && (next >= 0xdc00 && next <= 0xdfff)) {
305+
if (code <= 0xdbff && next >= 0xdc00 && next <= 0xdfff) {
257306
result += char + str[++i];
258307
} else {
259308
result += `\\u${code.toString(16).toUpperCase()}`;

0 commit comments

Comments
 (0)