|
1 | 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. |
| 2 | + * @typedef {import('./lib/index.js').Options} Options |
9 | 3 | */ |
10 | 4 |
|
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' |
0 commit comments