Skip to content
This repository was archived by the owner on Jan 1, 2023. It is now read-only.

Commit cb50d49

Browse files
committed
✨ convert array expression
1 parent 394da6e commit cb50d49

File tree

7 files changed

+93
-55
lines changed

7 files changed

+93
-55
lines changed

example/input.js

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,30 @@ const data = { foo: 42, bar: 1337 }
33

44
/* valid */
55
const valid1 = { foo: 'foo' };
6-
const valid2 = { foo: "fo'o" }
7-
const valid3 = { foo: "fo\'o" }
6+
const valid2 = { foo: "foo" };
87

9-
const valid4 = { foo: 10 };
8+
const valid3 = { foo: "fo'o" };
9+
const valid4 = { foo: "fo\'o" };
10+
const valid5 = { foo: "fo\"o" };
1011

11-
const valid5 = { foo: true };
12+
const valid6 = { foo: 'fo"o' };
13+
const valid7 = { foo: 'fo\"o' };
14+
const valid8 = { foo: 'fo\'o' };
1215

13-
const valid6 = { foo: null };
16+
const valid9 = { foo: 10 };
1417

15-
const valid7 = { foo: [null, 10, 'foo'] };
18+
const valid10 = { foo: true };
1619

17-
const valid8 = { foo: [null, [10, 2], [{ foo: 'foo' }]] };
20+
const valid11 = { foo: null };
1821

19-
const valid9 = { foo: { bar: 1337 } };
20-
const valid10 = { 1: "123", 23: 45, b: "b_val" };
22+
const valid12 = { foo: [null, 10, 'foo'] };
23+
24+
const valid13 = { foo: [null, [10, 2], [{ foo: 'foo' }]] };
25+
26+
const valid14 = { foo: { bar: 1337 } };
27+
const valid15 = { 1: "123", 23: 45, b: "b_val" };
28+
29+
const valid16 = [1, "two", {three: 3}];
2130

2231

2332
/* invalidValue */
@@ -32,6 +41,3 @@ const inValid2 = {
3241

3342
const inValid3 = { ...data, foo: 'foo' };
3443
const inValid4 = { bar: data, foo: 'foo' };
35-
36-
const inValid5 = { foo: 'fo\"o' }
37-
const inValid6 = { foo: 'fo"o' }

example/output.js

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,21 @@ const data = JSON.parse('{"foo":42,"bar":1337}');
33
/* valid */
44

55
const valid1 = JSON.parse('{"foo":"foo"}');
6-
const valid2 = JSON.parse('{"foo":"fo\'o"}');
6+
const valid2 = JSON.parse('{"foo":"foo"}');
77
const valid3 = JSON.parse('{"foo":"fo\'o"}');
8-
const valid4 = JSON.parse('{"foo":10}');
9-
const valid5 = JSON.parse('{"foo":true}');
10-
const valid6 = JSON.parse('{"foo":null}');
11-
const valid7 = JSON.parse('{"foo":[null,10,"foo"]}');
12-
const valid8 = JSON.parse('{"foo":[null,[10,2],[{"foo":"foo"}]]}');
13-
const valid9 = JSON.parse('{"foo":{"bar":1337}}');
14-
const valid10 = JSON.parse('{"1":"123","23":45,"b":"b_val"}');
8+
const valid4 = JSON.parse('{"foo":"fo\'o"}');
9+
const valid5 = JSON.parse('{"foo":"fo\\\"o"}');
10+
const valid6 = JSON.parse('{"foo":"fo\\\"o"}');
11+
const valid7 = JSON.parse('{"foo":"fo\\\"o"}');
12+
const valid8 = JSON.parse('{"foo":"fo\'o"}');
13+
const valid9 = JSON.parse('{"foo":10}');
14+
const valid10 = JSON.parse('{"foo":true}');
15+
const valid11 = JSON.parse('{"foo":null}');
16+
const valid12 = JSON.parse('{"foo":[null,10,"foo"]}');
17+
const valid13 = JSON.parse('{"foo":[null,[10,2],[{"foo":"foo"}]]}');
18+
const valid14 = JSON.parse('{"foo":{"bar":1337}}');
19+
const valid15 = JSON.parse('{"1":"123","23":45,"b":"b_val"}');
20+
const valid16 = JSON.parse('[1,"two",{"three":3}]');
1521
/* invalidValue */
1622

1723
const inValid1 = {
@@ -31,9 +37,3 @@ const inValid4 = {
3137
bar: data,
3238
foo: 'foo'
3339
};
34-
const inValid5 = {
35-
foo: 'fo\"o'
36-
};
37-
const inValid6 = {
38-
foo: 'fo"o'
39-
};

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"main": "dist/index.js",
55
"scripts": {
66
"build": "rm -rf dist/** && tsc",
7-
"example": "babel ./example/input.js -o ./example/output.js",
7+
"example": "babel example/input.js -o example/output.js && node example/output.js",
88
"fmt": "prettier --write \"src/**/*.ts\"",
99
"lint": "eslint 'src/**/*.ts' --fix",
1010
"test": "jest"

src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { buildPlugin } from './plugin'
22
import { ObjectExpression } from './visitors/object_expression'
3+
import { ArrayExpression } from './visitors/array_expression'
34

4-
export = buildPlugin([ObjectExpression])
5+
export = buildPlugin([ObjectExpression, ArrayExpression])

src/plugin.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
export function buildPlugin(visitors: Function[]) {
22
const visitorMap: { [name: string]: Function } = {}
33
for (const visitor of visitors) {
4-
// @ts-ignore
54
visitorMap[visitor.name] = visitor
65
}
76

src/visitors/array_expression.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { ArrayExpression } from '@babel/types'
2+
import { NodePath } from '@babel/traverse'
3+
import { converter } from '../utils'
4+
5+
interface PluginState {
6+
opts: {
7+
minJSONStringSize: number
8+
}
9+
}
10+
11+
const DEFAULT_THRESHOLD = 1024
12+
13+
/* eslint-disable no-redeclare */
14+
export function ArrayExpression(
15+
path: NodePath<ArrayExpression>,
16+
state: PluginState
17+
): void {
18+
try {
19+
const obj = converter(path.node)
20+
const json = JSON.stringify(obj)
21+
// escaping for single quotes
22+
const escapedJson = json.replace(/'/g, "\\'")
23+
// it simply isn't worth it to convert into the AST objects that are too small.
24+
// so, this plugin only convert large objects by default.
25+
const { minJSONStringSize } = state.opts
26+
const threshold = minJSONStringSize ?? DEFAULT_THRESHOLD
27+
if (escapedJson.length < threshold) {
28+
return
29+
}
30+
path.replaceWithSourceString(`JSON.parse('${escapedJson}')`)
31+
} catch (e) {
32+
// disable error message
33+
// const { loc } = path.parent
34+
// const line = loc && loc.start.line
35+
// console.error(
36+
// `At ${line} line (start) : The object wasn't converted (${e.message})`
37+
// )
38+
}
39+
}

test/visitors/object_expression.test.ts

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import pluginTester from 'babel-plugin-tester'
22
import { buildPlugin } from '../../src/plugin'
33
import { ObjectExpression } from '../../src/visitors/object_expression'
4+
import { ArrayExpression } from '../../src/visitors/array_expression'
45

56
pluginTester({
6-
plugin: buildPlugin([ObjectExpression]),
7+
plugin: buildPlugin([ObjectExpression, ArrayExpression]),
78
tests: [{
89
title: 'empty object',
910
pluginOptions: {
@@ -59,8 +60,8 @@ pluginTester({
5960
const a = {
6061
method(arg) {
6162
return arg
62-
},
63-
b: 1
63+
},
64+
b: 1
6465
}
6566
`,
6667
output: `
@@ -95,28 +96,6 @@ pluginTester({
9596
['c']: 'c_val'
9697
}
9798
`
98-
}, {
99-
title: 'does not convert objects which have double quotes in string',
100-
pluginOptions: {
101-
minJSONStringSize: 0
102-
},
103-
code: `const a = { b: 'ab\"c' }`,
104-
output: `
105-
const a = {
106-
b: 'ab\"c'
107-
}
108-
`
109-
}, {
110-
title: 'does not convert objects which have double quotes in string',
111-
pluginOptions: {
112-
minJSONStringSize: 0
113-
},
114-
code: `const a = { b: 'ab"c' }`,
115-
output: `
116-
const a = {
117-
b: 'ab"c'
118-
}
119-
`
12099
}, {
121100
title: 'does not convert objects which have invalid numeric key',
122101
pluginOptions: {
@@ -149,6 +128,13 @@ pluginTester({
149128
},
150129
code: `const a = { b: "ab\'c" }`,
151130
output: `const a = JSON.parse('{"b":"ab\\'c"}')`
131+
}, {
132+
title: 'string (include double quote)',
133+
pluginOptions: {
134+
minJSONStringSize: 0
135+
},
136+
code: `const a = { b: 'ab"c' }`,
137+
output: `const a = JSON.parse('{"b":"ab\\\\\"c"}')`
152138
}, {
153139
title: 'number',
154140
pluginOptions: {
@@ -171,7 +157,7 @@ pluginTester({
171157
code: `const a = { b: false }`,
172158
output: `const a = JSON.parse('{"b":false}')`
173159
}, {
174-
title: 'Array',
160+
title: 'Object (with Array)',
175161
pluginOptions: {
176162
minJSONStringSize: 0
177163
},
@@ -198,5 +184,12 @@ pluginTester({
198184
},
199185
code: `const a = { 1: "123", 23: 45, b: "b_val" }`,
200186
output: `const a = JSON.parse('{"1":"123","23":45,"b":"b_val"}')`
187+
}, {
188+
title: 'Array',
189+
pluginOptions: {
190+
minJSONStringSize: 0
191+
},
192+
code: `const a = [1, "two", {three: 3}]`,
193+
output: `const a = JSON.parse('[1,"two",{"three":3}]')`
201194
},]
202195
})

0 commit comments

Comments
 (0)