Skip to content

Commit 323fe43

Browse files
committed
Refactor to move implementation to lib/
1 parent 1773849 commit 323fe43

File tree

3 files changed

+106
-100
lines changed

3 files changed

+106
-100
lines changed

index.js

Lines changed: 2 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1,103 +1,5 @@
11
/**
2-
* @typedef {import('unist').Node} UnistNode
3-
* @typedef {import('estree-jsx').Node} EstreeNode
4-
*
5-
* @typedef Options
6-
* Configuration (optional).
7-
* @property {boolean} [dirty=false]
8-
* Leave discouraged fields in the tree.
2+
* @typedef {import('./lib/index.js').Options} Options
93
*/
104

11-
import {positionFromEstree} from 'unist-util-position-from-estree'
12-
import {visit} from 'estree-util-visit'
13-
14-
const own = {}.hasOwnProperty
15-
16-
/**
17-
* @param {EstreeNode} estree
18-
* @param {Options} [options]
19-
* @returns {UnistNode}
20-
*/
21-
export function fromEstree(estree, options = {}) {
22-
/** @type {UnistNode|undefined} */
23-
let tail
24-
25-
visit(estree, {
26-
// eslint-disable-next-line complexity
27-
leave(node, field, index, parents) {
28-
const parent = parents[parents.length - 1]
29-
/** @type {EstreeNode} */
30-
// @ts-expect-error: indexable.
31-
const context = field === null || index === null ? parent : parent[field]
32-
/** @type {string|number|null} */
33-
const prop = index === null ? field : index
34-
/** @type {UnistNode} */
35-
const copy = {}
36-
/** @type {string} */
37-
let key
38-
39-
for (key in node) {
40-
if (
41-
own.call(node, key) &&
42-
(options.dirty ||
43-
(key !== 'start' &&
44-
key !== 'end' &&
45-
key !== 'loc' &&
46-
key !== 'raw'))
47-
) {
48-
if (
49-
node.type === 'JSXOpeningFragment' &&
50-
(key === 'attributes' || key === 'selfClosing')
51-
) {
52-
continue
53-
}
54-
55-
/** @type {unknown} */
56-
// @ts-expect-error: indexable.
57-
let value = node[key]
58-
59-
// If this is a bigint or regex literal, reset value.
60-
if (
61-
!options.dirty &&
62-
node.type === 'Literal' &&
63-
key === 'value' &&
64-
('bigint' in node || 'regex' in node)
65-
) {
66-
value = null
67-
}
68-
// Normalize `.bigint` to use int notation.
69-
else if (
70-
node.type === 'Literal' &&
71-
key === 'bigint' &&
72-
typeof value === 'string'
73-
) {
74-
const match = /0[box]/.exec(value.slice(0, 2).toLowerCase())
75-
76-
if (match) {
77-
const code = match[0].charCodeAt(1)
78-
value = Number.parseInt(
79-
value.slice(2),
80-
code === 98 /* `x` */ ? 2 : code === 111 /* `o` */ ? 8 : 16
81-
).toString()
82-
}
83-
}
84-
85-
// @ts-expect-error: indexable.
86-
copy[key] = value
87-
}
88-
}
89-
90-
copy.position = positionFromEstree(node)
91-
92-
if (prop === null) {
93-
tail = copy
94-
} else {
95-
// @ts-expect-error: indexable.
96-
context[prop] = copy
97-
}
98-
}
99-
})
100-
101-
// @ts-expect-error: always one node.
102-
return tail
103-
}
5+
export {fromEstree} from './lib/index.js'

lib/index.js

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/**
2+
* @typedef {import('unist').Node} UnistNode
3+
* @typedef {import('estree-jsx').Node} EstreeNode
4+
*
5+
* @typedef Options
6+
* Configuration (optional).
7+
* @property {boolean} [dirty=false]
8+
* Leave discouraged fields in the tree.
9+
*/
10+
11+
import {positionFromEstree} from 'unist-util-position-from-estree'
12+
import {visit} from 'estree-util-visit'
13+
14+
const own = {}.hasOwnProperty
15+
16+
/**
17+
* @param {EstreeNode} estree
18+
* @param {Options} [options]
19+
* @returns {UnistNode}
20+
*/
21+
export function fromEstree(estree, options = {}) {
22+
/** @type {UnistNode|undefined} */
23+
let tail
24+
25+
visit(estree, {
26+
// eslint-disable-next-line complexity
27+
leave(node, field, index, parents) {
28+
const parent = parents[parents.length - 1]
29+
/** @type {EstreeNode} */
30+
// @ts-expect-error: indexable.
31+
const context = field === null || index === null ? parent : parent[field]
32+
/** @type {string|number|null} */
33+
const prop = index === null ? field : index
34+
/** @type {UnistNode} */
35+
const copy = {}
36+
/** @type {string} */
37+
let key
38+
39+
for (key in node) {
40+
if (
41+
own.call(node, key) &&
42+
(options.dirty ||
43+
(key !== 'start' &&
44+
key !== 'end' &&
45+
key !== 'loc' &&
46+
key !== 'raw'))
47+
) {
48+
if (
49+
node.type === 'JSXOpeningFragment' &&
50+
(key === 'attributes' || key === 'selfClosing')
51+
) {
52+
continue
53+
}
54+
55+
/** @type {unknown} */
56+
// @ts-expect-error: indexable.
57+
let value = node[key]
58+
59+
// If this is a bigint or regex literal, reset value.
60+
if (
61+
!options.dirty &&
62+
node.type === 'Literal' &&
63+
key === 'value' &&
64+
('bigint' in node || 'regex' in node)
65+
) {
66+
value = null
67+
}
68+
// Normalize `.bigint` to use int notation.
69+
else if (
70+
node.type === 'Literal' &&
71+
key === 'bigint' &&
72+
typeof value === 'string'
73+
) {
74+
const match = /0[box]/.exec(value.slice(0, 2).toLowerCase())
75+
76+
if (match) {
77+
const code = match[0].charCodeAt(1)
78+
value = Number.parseInt(
79+
value.slice(2),
80+
code === 98 /* `x` */ ? 2 : code === 111 /* `o` */ ? 8 : 16
81+
).toString()
82+
}
83+
}
84+
85+
// @ts-expect-error: indexable.
86+
copy[key] = value
87+
}
88+
}
89+
90+
copy.position = positionFromEstree(node)
91+
92+
if (prop === null) {
93+
tail = copy
94+
} else {
95+
// @ts-expect-error: indexable.
96+
context[prop] = copy
97+
}
98+
}
99+
})
100+
101+
// @ts-expect-error: always one node.
102+
return tail
103+
}

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
"type": "module",
3232
"main": "index.js",
3333
"files": [
34+
"lib/",
3435
"index.js",
3536
"index.d.ts"
3637
],

0 commit comments

Comments
 (0)