unframer 2.25.4 → 2.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/babel-jsx.d.ts +15 -0
- package/dist/babel-jsx.d.ts.map +1 -0
- package/dist/babel-jsx.js +223 -0
- package/dist/babel-jsx.js.map +1 -0
- package/dist/babel-plugin-imports.d.ts +0 -6
- package/dist/babel-plugin-imports.d.ts.map +1 -1
- package/dist/babel-plugin-imports.js +2 -135
- package/dist/babel-plugin-imports.js.map +1 -1
- package/dist/cli.d.ts +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +31 -6
- package/dist/cli.js.map +1 -1
- package/dist/css.js +13 -13
- package/dist/esbuild.d.ts.map +1 -1
- package/dist/esbuild.js +82 -66
- package/dist/esbuild.js.map +1 -1
- package/dist/example-code.test.js +39 -39
- package/dist/example-code.test.js.map +1 -1
- package/dist/exporter.d.ts.map +1 -1
- package/dist/exporter.js +137 -87
- package/dist/exporter.js.map +1 -1
- package/dist/flat-cache-interceptor.d.ts +27 -0
- package/dist/flat-cache-interceptor.d.ts.map +1 -0
- package/dist/flat-cache-interceptor.js +99 -0
- package/dist/flat-cache-interceptor.js.map +1 -0
- package/dist/framer.d.ts.map +1 -1
- package/dist/framer.js +895 -741
- package/dist/framer.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +15 -3
- package/dist/react.js.map +1 -1
- package/dist/sentry.d.ts +1 -1
- package/dist/sentry.d.ts.map +1 -1
- package/dist/sentry.js +2 -17
- package/dist/sentry.js.map +1 -1
- package/dist/undici-dispatcher.d.ts +2 -0
- package/dist/undici-dispatcher.d.ts.map +1 -0
- package/dist/undici-dispatcher.js +13 -0
- package/dist/undici-dispatcher.js.map +1 -0
- package/dist/utils.d.ts +3 -3
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +4 -10
- package/dist/utils.js.map +1 -1
- package/dist/utils.test.d.ts +2 -0
- package/dist/utils.test.d.ts.map +1 -0
- package/dist/utils.test.js +143 -0
- package/dist/utils.test.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/esm/babel-jsx.d.ts +15 -0
- package/esm/babel-jsx.d.ts.map +1 -0
- package/esm/babel-jsx.js +219 -0
- package/esm/babel-jsx.js.map +1 -0
- package/esm/babel-plugin-imports.d.ts +0 -6
- package/esm/babel-plugin-imports.d.ts.map +1 -1
- package/esm/babel-plugin-imports.js +2 -134
- package/esm/babel-plugin-imports.js.map +1 -1
- package/esm/cli.d.ts +1 -0
- package/esm/cli.d.ts.map +1 -1
- package/esm/cli.js +31 -6
- package/esm/cli.js.map +1 -1
- package/esm/css.js +13 -13
- package/esm/esbuild.d.ts.map +1 -1
- package/esm/esbuild.js +82 -66
- package/esm/esbuild.js.map +1 -1
- package/esm/example-code.test.js +40 -40
- package/esm/example-code.test.js.map +1 -1
- package/esm/exporter.d.ts.map +1 -1
- package/esm/exporter.js +100 -50
- package/esm/exporter.js.map +1 -1
- package/esm/flat-cache-interceptor.d.ts +27 -0
- package/esm/flat-cache-interceptor.d.ts.map +1 -0
- package/esm/flat-cache-interceptor.js +95 -0
- package/esm/flat-cache-interceptor.js.map +1 -0
- package/esm/framer.d.ts.map +1 -1
- package/esm/framer.js +871 -729
- package/esm/framer.js.map +1 -1
- package/esm/index.d.ts +1 -1
- package/esm/index.d.ts.map +1 -1
- package/esm/react.d.ts.map +1 -1
- package/esm/react.js +15 -3
- package/esm/react.js.map +1 -1
- package/esm/sentry.d.ts +1 -1
- package/esm/sentry.d.ts.map +1 -1
- package/esm/sentry.js +2 -17
- package/esm/sentry.js.map +1 -1
- package/esm/undici-dispatcher.d.ts +2 -0
- package/esm/undici-dispatcher.d.ts.map +1 -0
- package/esm/undici-dispatcher.js +10 -0
- package/esm/undici-dispatcher.js.map +1 -0
- package/esm/utils.d.ts +3 -3
- package/esm/utils.d.ts.map +1 -1
- package/esm/utils.js +3 -9
- package/esm/utils.js.map +1 -1
- package/esm/utils.test.d.ts +2 -0
- package/esm/utils.test.d.ts.map +1 -0
- package/esm/utils.test.js +141 -0
- package/esm/utils.test.js.map +1 -0
- package/esm/version.d.ts +1 -1
- package/esm/version.js +1 -1
- package/package.json +8 -10
- package/src/babel-jsx.ts +277 -0
- package/src/babel-plugin-imports.ts +6 -169
- package/src/cli.ts +45 -6
- package/src/css.ts +13 -13
- package/src/esbuild.ts +93 -74
- package/src/example-code.test.ts +40 -41
- package/src/exporter.ts +124 -54
- package/src/flat-cache-interceptor.ts +114 -0
- package/src/framer.js +921 -764
- package/src/index.ts +1 -1
- package/src/react.tsx +15 -1
- package/src/sentry.ts +3 -22
- package/src/undici-dispatcher.ts +13 -0
- package/src/utils.test.ts +148 -0
- package/src/utils.ts +4 -17
- package/src/version.ts +1 -1
package/src/babel-jsx.ts
ADDED
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import type * as BabelTypes from '@babel/types'
|
|
2
|
+
import type { PluginObj } from '@babel/core'
|
|
3
|
+
|
|
4
|
+
const noContainerTypes = new Set([
|
|
5
|
+
'JSXElement',
|
|
6
|
+
// 'StringLiteral',
|
|
7
|
+
'NumericLiteral',
|
|
8
|
+
])
|
|
9
|
+
|
|
10
|
+
export function removeJsxExpressionContainer({
|
|
11
|
+
types: t,
|
|
12
|
+
}: {
|
|
13
|
+
types: typeof BabelTypes
|
|
14
|
+
}): PluginObj {
|
|
15
|
+
const plugin: PluginObj = {
|
|
16
|
+
name: 'remove-jsx-expression-container',
|
|
17
|
+
visitor: {
|
|
18
|
+
JSXExpressionContainer: {
|
|
19
|
+
exit(path) {
|
|
20
|
+
const expr = path.node.expression
|
|
21
|
+
|
|
22
|
+
if (t.isJSXElement(expr) || t.isJSXFragment(expr)) {
|
|
23
|
+
path.replaceWith(expr)
|
|
24
|
+
} else if (t.isArrayExpression(expr)) {
|
|
25
|
+
// Check if array contains only JSX elements/fragments
|
|
26
|
+
const allJsx = expr.elements.every(
|
|
27
|
+
(element) =>
|
|
28
|
+
element &&
|
|
29
|
+
(t.isJSXElement(element) ||
|
|
30
|
+
t.isJSXFragment(element)),
|
|
31
|
+
)
|
|
32
|
+
if (allJsx && 'elements' in expr && expr.elements) {
|
|
33
|
+
try {
|
|
34
|
+
const fragment: BabelTypes.JSXFragment = {
|
|
35
|
+
type: 'JSXFragment',
|
|
36
|
+
openingFragment: {
|
|
37
|
+
type: 'JSXOpeningFragment',
|
|
38
|
+
},
|
|
39
|
+
closingFragment: {
|
|
40
|
+
type: 'JSXClosingFragment',
|
|
41
|
+
},
|
|
42
|
+
children: expr.elements.filter(isTruthy) as any,
|
|
43
|
+
}
|
|
44
|
+
path.replaceWith(fragment)
|
|
45
|
+
} catch (e) {
|
|
46
|
+
console.error(
|
|
47
|
+
`cannot remove expression container for`,
|
|
48
|
+
expr,
|
|
49
|
+
e,
|
|
50
|
+
)
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
}
|
|
58
|
+
return plugin
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function isTruthy<T>(value: T): value is NonNullable<T> {
|
|
62
|
+
return value != null
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function babelPluginJsxTransform({
|
|
66
|
+
types: t,
|
|
67
|
+
}: {
|
|
68
|
+
types: typeof BabelTypes
|
|
69
|
+
}) {
|
|
70
|
+
const jsxFunctions = new Set<string>()
|
|
71
|
+
|
|
72
|
+
return {
|
|
73
|
+
name: 'jsx-transform',
|
|
74
|
+
visitor: {
|
|
75
|
+
ImportDeclaration(path) {
|
|
76
|
+
const source = path.node.source.value
|
|
77
|
+
|
|
78
|
+
// Track React JSX runtime imports
|
|
79
|
+
if (
|
|
80
|
+
source === 'react/jsx-runtime' ||
|
|
81
|
+
source === 'react/jsx-dev-runtime'
|
|
82
|
+
) {
|
|
83
|
+
path.node.specifiers.forEach((specifier) => {
|
|
84
|
+
if (
|
|
85
|
+
t.isImportSpecifier(specifier) &&
|
|
86
|
+
t.isIdentifier(specifier.imported)
|
|
87
|
+
) {
|
|
88
|
+
const importName = specifier.imported.name
|
|
89
|
+
const localName = specifier.local.name
|
|
90
|
+
|
|
91
|
+
// Track common JSX runtime functions
|
|
92
|
+
if (
|
|
93
|
+
importName === 'jsx' ||
|
|
94
|
+
importName === 'jsxs' ||
|
|
95
|
+
importName === 'Fragment'
|
|
96
|
+
) {
|
|
97
|
+
jsxFunctions.add(localName)
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
})
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Track React imports that could be JSX functions
|
|
104
|
+
if (source === 'react') {
|
|
105
|
+
path.node.specifiers.forEach((specifier) => {
|
|
106
|
+
if (
|
|
107
|
+
t.isImportSpecifier(specifier) &&
|
|
108
|
+
t.isIdentifier(specifier.imported)
|
|
109
|
+
) {
|
|
110
|
+
const importName = specifier.imported.name
|
|
111
|
+
const localName = specifier.local.name
|
|
112
|
+
|
|
113
|
+
// Track createElement and other JSX-related functions
|
|
114
|
+
if (
|
|
115
|
+
importName === 'createElement' ||
|
|
116
|
+
importName === 'Fragment'
|
|
117
|
+
) {
|
|
118
|
+
jsxFunctions.add(localName)
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
})
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
CallExpression(path) {
|
|
125
|
+
// Check if it's a JSX function call
|
|
126
|
+
if (
|
|
127
|
+
!path.node.callee ||
|
|
128
|
+
!path.node.callee.name ||
|
|
129
|
+
!jsxFunctions.has(path.node.callee.name)
|
|
130
|
+
) {
|
|
131
|
+
return
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Remove /* @__PURE__ */ comments
|
|
135
|
+
if (path.node.leadingComments) {
|
|
136
|
+
path.node.leadingComments =
|
|
137
|
+
path.node.leadingComments.filter(
|
|
138
|
+
(comment) => !comment.value.includes('@__PURE__'),
|
|
139
|
+
)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const [elementArg, propsArg] = path.node.arguments
|
|
143
|
+
|
|
144
|
+
// Get the element type name
|
|
145
|
+
let elementName = ''
|
|
146
|
+
if (elementArg.type === 'MemberExpression') {
|
|
147
|
+
elementName = `${elementArg.object.name}.${elementArg.property.name}`
|
|
148
|
+
} else if (elementArg.type === 'StringLiteral') {
|
|
149
|
+
elementName = elementArg.value
|
|
150
|
+
} else if (elementArg.type === 'Identifier') {
|
|
151
|
+
if (!canRenderAsJsx(elementArg.name)) {
|
|
152
|
+
return
|
|
153
|
+
}
|
|
154
|
+
elementName = elementArg.name
|
|
155
|
+
} else {
|
|
156
|
+
// Skip if we can't determine element name
|
|
157
|
+
return
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Convert to JSX element
|
|
161
|
+
const jsxElement: BabelTypes.JSXElement = {
|
|
162
|
+
type: 'JSXElement',
|
|
163
|
+
openingElement: {
|
|
164
|
+
type: 'JSXOpeningElement',
|
|
165
|
+
name: {
|
|
166
|
+
type: 'JSXIdentifier',
|
|
167
|
+
name: elementName,
|
|
168
|
+
},
|
|
169
|
+
attributes: [],
|
|
170
|
+
selfClosing: !propsArg.properties.find(
|
|
171
|
+
(p) => p.key?.name === 'children',
|
|
172
|
+
),
|
|
173
|
+
},
|
|
174
|
+
closingElement: propsArg.properties.find(
|
|
175
|
+
(p) => p.key?.name === 'children',
|
|
176
|
+
)
|
|
177
|
+
? {
|
|
178
|
+
type: 'JSXClosingElement',
|
|
179
|
+
name: {
|
|
180
|
+
type: 'JSXIdentifier',
|
|
181
|
+
name: elementName,
|
|
182
|
+
},
|
|
183
|
+
}
|
|
184
|
+
: null,
|
|
185
|
+
children: [],
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Add attributes
|
|
189
|
+
if (propsArg && propsArg.properties) {
|
|
190
|
+
propsArg.properties.forEach((prop) => {
|
|
191
|
+
if (prop.type === 'SpreadElement') {
|
|
192
|
+
jsxElement.openingElement.attributes.push({
|
|
193
|
+
type: 'JSXSpreadAttribute',
|
|
194
|
+
argument: prop.argument,
|
|
195
|
+
})
|
|
196
|
+
} else if (prop.key?.name === 'children') {
|
|
197
|
+
if (prop.value.type === 'ArrayExpression') {
|
|
198
|
+
jsxElement.children = prop.value.elements.map(
|
|
199
|
+
(element) => {
|
|
200
|
+
if (
|
|
201
|
+
noContainerTypes.has(element.type)
|
|
202
|
+
) {
|
|
203
|
+
return element
|
|
204
|
+
}
|
|
205
|
+
return {
|
|
206
|
+
type: 'JSXExpressionContainer',
|
|
207
|
+
expression: element,
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
)
|
|
211
|
+
} else {
|
|
212
|
+
if (noContainerTypes.has(prop.value.type)) {
|
|
213
|
+
jsxElement.children = [prop.value]
|
|
214
|
+
} else {
|
|
215
|
+
jsxElement.children = [
|
|
216
|
+
{
|
|
217
|
+
type: 'JSXExpressionContainer',
|
|
218
|
+
expression: prop.value,
|
|
219
|
+
},
|
|
220
|
+
]
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
} else {
|
|
224
|
+
let attrName = prop.key?.name
|
|
225
|
+
if (
|
|
226
|
+
!attrName &&
|
|
227
|
+
prop.key?.type === 'StringLiteral'
|
|
228
|
+
) {
|
|
229
|
+
attrName = prop.key.value
|
|
230
|
+
}
|
|
231
|
+
if (!attrName) {
|
|
232
|
+
console.log(
|
|
233
|
+
`no prop.key?.name for ${JSON.stringify(
|
|
234
|
+
prop,
|
|
235
|
+
)}`,
|
|
236
|
+
)
|
|
237
|
+
return
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
jsxElement.openingElement.attributes.push({
|
|
241
|
+
type: 'JSXAttribute',
|
|
242
|
+
name: {
|
|
243
|
+
type: 'JSXIdentifier',
|
|
244
|
+
name: attrName,
|
|
245
|
+
},
|
|
246
|
+
value: {
|
|
247
|
+
type: 'JSXExpressionContainer',
|
|
248
|
+
expression: prop.value,
|
|
249
|
+
},
|
|
250
|
+
})
|
|
251
|
+
}
|
|
252
|
+
})
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
path.replaceWith(jsxElement)
|
|
256
|
+
},
|
|
257
|
+
},
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
function jsonStringifyWithMaps(map) {
|
|
262
|
+
return JSON.stringify(
|
|
263
|
+
[...map],
|
|
264
|
+
(key, value) => (value instanceof Map ? [...value] : value),
|
|
265
|
+
2,
|
|
266
|
+
)
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
function canRenderAsJsx(name: string): boolean {
|
|
270
|
+
// 1. Valid JS identifier?
|
|
271
|
+
const isIdentifier = /^[$A-Za-z_][$\w]*$/.test(name)
|
|
272
|
+
if (!isIdentifier) return false
|
|
273
|
+
|
|
274
|
+
// 2. First char not lowercase letter?
|
|
275
|
+
const first = name[0]
|
|
276
|
+
return first.toUpperCase() === first
|
|
277
|
+
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import * as BabelTypes from '@babel/types'
|
|
2
2
|
|
|
3
3
|
import { PluginObj } from '@babel/core'
|
|
4
|
-
import {
|
|
4
|
+
import type {
|
|
5
|
+
ImportDeclaration,
|
|
6
|
+
ImportSpecifier
|
|
7
|
+
} from '@babel/types'
|
|
5
8
|
import BatchRenamer from './renamer'
|
|
6
|
-
import { logger } from './utils'
|
|
7
9
|
|
|
8
10
|
export function babelPluginDeduplicateImports({
|
|
9
11
|
types: t,
|
|
@@ -116,7 +118,7 @@ export function babelPluginDeduplicateImports({
|
|
|
116
118
|
},
|
|
117
119
|
Program: {
|
|
118
120
|
exit(path) {
|
|
119
|
-
console.log(`renaming imports...`)
|
|
121
|
+
// console.log(`renaming imports...`)
|
|
120
122
|
for (const [source, modMap] of importAliasMap) {
|
|
121
123
|
// rename import names to consolidated names
|
|
122
124
|
for (let [local, { consolidated, path: p }] of modMap) {
|
|
@@ -150,7 +152,7 @@ export function babelPluginDeduplicateImports({
|
|
|
150
152
|
|
|
151
153
|
const definedImports = new Set<string>()
|
|
152
154
|
const later = [] as Function[]
|
|
153
|
-
console.log(`removing duplicates...`)
|
|
155
|
+
// console.log(`removing duplicates...`)
|
|
154
156
|
for (let importDec of importDecs) {
|
|
155
157
|
const source = importDec.source.value
|
|
156
158
|
|
|
@@ -274,168 +276,3 @@ export function babelPluginRenameExports({
|
|
|
274
276
|
},
|
|
275
277
|
}
|
|
276
278
|
}
|
|
277
|
-
|
|
278
|
-
// Set of types that don't need expression containers
|
|
279
|
-
const noContainerTypes = new Set([
|
|
280
|
-
'JSXElement',
|
|
281
|
-
// 'StringLiteral',
|
|
282
|
-
'NumericLiteral',
|
|
283
|
-
])
|
|
284
|
-
|
|
285
|
-
export function babelPluginJsxTransform() {
|
|
286
|
-
return {
|
|
287
|
-
name: 'jsx-transform',
|
|
288
|
-
visitor: {
|
|
289
|
-
CallExpression(path) {
|
|
290
|
-
// Check if it's a _jsx or _jsxs call
|
|
291
|
-
if (
|
|
292
|
-
!path.node.callee ||
|
|
293
|
-
!path.node.callee.name?.startsWith('_jsx')
|
|
294
|
-
) {
|
|
295
|
-
return
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
// Remove /* @__PURE__ */ comments
|
|
299
|
-
if (path.node.leadingComments) {
|
|
300
|
-
path.node.leadingComments =
|
|
301
|
-
path.node.leadingComments.filter(
|
|
302
|
-
(comment) => !comment.value.includes('@__PURE__'),
|
|
303
|
-
)
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
const [elementArg, propsArg] = path.node.arguments
|
|
307
|
-
|
|
308
|
-
// Get the element type name
|
|
309
|
-
let elementName = ''
|
|
310
|
-
if (elementArg.type === 'MemberExpression') {
|
|
311
|
-
elementName = `${elementArg.object.name}.${elementArg.property.name}`
|
|
312
|
-
} else if (elementArg.type === 'StringLiteral') {
|
|
313
|
-
elementName = elementArg.value
|
|
314
|
-
} else if (elementArg.type === 'Identifier') {
|
|
315
|
-
elementName = elementArg.name
|
|
316
|
-
} else {
|
|
317
|
-
// Skip if we can't determine element name
|
|
318
|
-
return
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
// Convert to JSX element
|
|
322
|
-
const jsxElement: BabelTypes.JSXElement = {
|
|
323
|
-
type: 'JSXElement',
|
|
324
|
-
openingElement: {
|
|
325
|
-
type: 'JSXOpeningElement',
|
|
326
|
-
name: {
|
|
327
|
-
type: 'JSXIdentifier',
|
|
328
|
-
name: elementName,
|
|
329
|
-
},
|
|
330
|
-
attributes: [],
|
|
331
|
-
selfClosing: !propsArg.properties.find(
|
|
332
|
-
(p) => p.key?.name === 'children',
|
|
333
|
-
),
|
|
334
|
-
},
|
|
335
|
-
closingElement: propsArg.properties.find(
|
|
336
|
-
(p) => p.key?.name === 'children',
|
|
337
|
-
)
|
|
338
|
-
? {
|
|
339
|
-
type: 'JSXClosingElement',
|
|
340
|
-
name: {
|
|
341
|
-
type: 'JSXIdentifier',
|
|
342
|
-
name: elementName,
|
|
343
|
-
},
|
|
344
|
-
}
|
|
345
|
-
: null,
|
|
346
|
-
children: [],
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
// Add attributes
|
|
350
|
-
if (propsArg && propsArg.properties) {
|
|
351
|
-
propsArg.properties.forEach((prop) => {
|
|
352
|
-
if (prop.type === 'SpreadElement') {
|
|
353
|
-
jsxElement.openingElement.attributes.push({
|
|
354
|
-
type: 'JSXSpreadAttribute',
|
|
355
|
-
argument: prop.argument,
|
|
356
|
-
})
|
|
357
|
-
} else if (prop.key?.name === 'children') {
|
|
358
|
-
if (prop.value.type === 'ArrayExpression') {
|
|
359
|
-
jsxElement.children = prop.value.elements.map(
|
|
360
|
-
(element) => {
|
|
361
|
-
if (
|
|
362
|
-
noContainerTypes.has(
|
|
363
|
-
element.type,
|
|
364
|
-
) ||
|
|
365
|
-
(element.type ===
|
|
366
|
-
'CallExpression' &&
|
|
367
|
-
element.callee?.name?.startsWith(
|
|
368
|
-
'_jsx',
|
|
369
|
-
))
|
|
370
|
-
) {
|
|
371
|
-
return element
|
|
372
|
-
}
|
|
373
|
-
return {
|
|
374
|
-
type: 'JSXExpressionContainer',
|
|
375
|
-
expression: element,
|
|
376
|
-
}
|
|
377
|
-
},
|
|
378
|
-
)
|
|
379
|
-
} else {
|
|
380
|
-
if (
|
|
381
|
-
noContainerTypes.has(prop.value.type) ||
|
|
382
|
-
(prop.value.type === 'CallExpression' &&
|
|
383
|
-
prop.value.callee?.name?.startsWith(
|
|
384
|
-
'_jsx',
|
|
385
|
-
))
|
|
386
|
-
) {
|
|
387
|
-
jsxElement.children = [prop.value]
|
|
388
|
-
} else {
|
|
389
|
-
jsxElement.children = [
|
|
390
|
-
{
|
|
391
|
-
type: 'JSXExpressionContainer',
|
|
392
|
-
expression: prop.value,
|
|
393
|
-
},
|
|
394
|
-
]
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
} else {
|
|
398
|
-
let attrName = prop.key?.name
|
|
399
|
-
if (
|
|
400
|
-
!attrName &&
|
|
401
|
-
prop.key?.type === 'StringLiteral'
|
|
402
|
-
) {
|
|
403
|
-
attrName = prop.key.value
|
|
404
|
-
}
|
|
405
|
-
if (!attrName) {
|
|
406
|
-
console.log(
|
|
407
|
-
`no prop.key?.name for ${JSON.stringify(
|
|
408
|
-
prop,
|
|
409
|
-
)}`,
|
|
410
|
-
)
|
|
411
|
-
return
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
jsxElement.openingElement.attributes.push({
|
|
415
|
-
type: 'JSXAttribute',
|
|
416
|
-
name: {
|
|
417
|
-
type: 'JSXIdentifier',
|
|
418
|
-
name: attrName,
|
|
419
|
-
},
|
|
420
|
-
value: {
|
|
421
|
-
type: 'JSXExpressionContainer',
|
|
422
|
-
expression: prop.value,
|
|
423
|
-
},
|
|
424
|
-
})
|
|
425
|
-
}
|
|
426
|
-
})
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
path.replaceWith(jsxElement)
|
|
430
|
-
},
|
|
431
|
-
},
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
function jsonStringifyWithMaps(map) {
|
|
436
|
-
return JSON.stringify(
|
|
437
|
-
[...map],
|
|
438
|
-
(key, value) => (value instanceof Map ? [...value] : value),
|
|
439
|
-
2,
|
|
440
|
-
)
|
|
441
|
-
}
|
package/src/cli.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { setMaxListeners } from 'events'
|
|
2
2
|
import { fetch } from 'undici'
|
|
3
3
|
import './sentry.js'
|
|
4
|
-
|
|
4
|
+
|
|
5
5
|
import { bundle, StyleToken } from './exporter.js'
|
|
6
6
|
import { createClient } from './generated/api-client.js'
|
|
7
7
|
|
|
@@ -12,13 +12,13 @@ import path, { basename } from 'path'
|
|
|
12
12
|
import { BreakpointSizes, defaultBreakpointSizes } from './css.js'
|
|
13
13
|
import {
|
|
14
14
|
componentNameToPath,
|
|
15
|
-
dispatcher,
|
|
16
15
|
isTruthy,
|
|
17
16
|
logger,
|
|
18
17
|
sleep,
|
|
19
18
|
spinner,
|
|
20
19
|
} from './utils.js'
|
|
21
20
|
import { notifyError } from './sentry.js'
|
|
21
|
+
import { dispatcher } from './undici-dispatcher.js'
|
|
22
22
|
const configNames = ['unframer.config.json', 'unframer.json']
|
|
23
23
|
|
|
24
24
|
export const cli = cac('unframer')
|
|
@@ -35,6 +35,9 @@ cli.command('[projectId]', 'Run unframer with optional project ID')
|
|
|
35
35
|
},
|
|
36
36
|
)
|
|
37
37
|
.option('--watch', 'Watch for changes and rebuild', { default: false })
|
|
38
|
+
.option('--jsx', 'Output jsx code instead of minified .js code', {
|
|
39
|
+
default: false,
|
|
40
|
+
})
|
|
38
41
|
.option('--debug', 'Enable debug logging', { default: false })
|
|
39
42
|
.action(async function main(projectId, options) {
|
|
40
43
|
const external_ = options.external
|
|
@@ -59,8 +62,12 @@ cli.command('[projectId]', 'Run unframer with optional project ID')
|
|
|
59
62
|
outDir,
|
|
60
63
|
projectId,
|
|
61
64
|
})
|
|
65
|
+
let jsx = options.jsx
|
|
62
66
|
const { rebuild, buildContext } = await bundle({
|
|
63
|
-
config
|
|
67
|
+
config: {
|
|
68
|
+
jsx,
|
|
69
|
+
...config,
|
|
70
|
+
},
|
|
64
71
|
watch,
|
|
65
72
|
cwd,
|
|
66
73
|
signal,
|
|
@@ -105,8 +112,8 @@ cli.command('[projectId]', 'Run unframer with optional project ID')
|
|
|
105
112
|
fixOldUnframerPath()
|
|
106
113
|
const cwd = process.cwd()
|
|
107
114
|
logger.log(`Looking for ${configNames.join(', ')} in ${cwd}`)
|
|
108
|
-
|
|
109
|
-
const configPath =
|
|
115
|
+
|
|
116
|
+
const configPath = findUp(configNames, { cwd })
|
|
110
117
|
if (!configPath) {
|
|
111
118
|
logger.log(`No ${configNames.join(', ')} found`)
|
|
112
119
|
return
|
|
@@ -117,7 +124,12 @@ cli.command('[projectId]', 'Run unframer with optional project ID')
|
|
|
117
124
|
logger.log(`No ${configBasename} contents found`)
|
|
118
125
|
return
|
|
119
126
|
}
|
|
120
|
-
const
|
|
127
|
+
const configContentWithoutComments = configContent.replace(
|
|
128
|
+
/^\s*\/\/.*$/gm,
|
|
129
|
+
'',
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
const config = JSON.parse(configContentWithoutComments)
|
|
121
133
|
if (outDir !== defaultOutDir) {
|
|
122
134
|
config.outDir = outDir
|
|
123
135
|
}
|
|
@@ -177,6 +189,7 @@ cli.command('init', 'Init the unframer.config.json config').action(
|
|
|
177
189
|
)
|
|
178
190
|
|
|
179
191
|
export type Config = {
|
|
192
|
+
jsx?: boolean
|
|
180
193
|
components: {
|
|
181
194
|
[name: string]: string
|
|
182
195
|
}
|
|
@@ -282,6 +295,7 @@ export async function configFromFetch({
|
|
|
282
295
|
}) || []
|
|
283
296
|
const config: Config = {
|
|
284
297
|
...data,
|
|
298
|
+
|
|
285
299
|
breakpoints: defaultBreakpointSizes,
|
|
286
300
|
outDir,
|
|
287
301
|
externalPackages,
|
|
@@ -315,3 +329,28 @@ export async function configFromFetch({
|
|
|
315
329
|
}
|
|
316
330
|
return { websiteUrl, cwd, config }
|
|
317
331
|
}
|
|
332
|
+
|
|
333
|
+
function findUp(
|
|
334
|
+
configNames: string[],
|
|
335
|
+
{ cwd }: { cwd: string },
|
|
336
|
+
): string | null {
|
|
337
|
+
let currentDir = cwd
|
|
338
|
+
|
|
339
|
+
while (true) {
|
|
340
|
+
for (const configName of configNames) {
|
|
341
|
+
const configPath = path.join(currentDir, configName)
|
|
342
|
+
if (fs.existsSync(configPath)) {
|
|
343
|
+
return configPath
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
const parentDir = path.dirname(currentDir)
|
|
348
|
+
if (parentDir === currentDir) {
|
|
349
|
+
// Reached the root directory
|
|
350
|
+
break
|
|
351
|
+
}
|
|
352
|
+
currentDir = parentDir
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
return null
|
|
356
|
+
}
|