@knighted/jsx 1.10.0 → 1.12.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/cjs/transform.cjs +183 -0
- package/dist/cjs/transform.d.cts +17 -1
- package/dist/transform.d.ts +17 -1
- package/dist/transform.js +183 -0
- package/package.json +2 -2
package/dist/cjs/transform.cjs
CHANGED
|
@@ -120,6 +120,165 @@ const collectImportMetadata = (body) => {
|
|
|
120
120
|
});
|
|
121
121
|
return imports;
|
|
122
122
|
};
|
|
123
|
+
const toIdentifierName = (value) => {
|
|
124
|
+
if (!isObjectRecord(value)) {
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
if (value.type !== 'Identifier') {
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
return typeof value.name === 'string' ? value.name : null;
|
|
131
|
+
};
|
|
132
|
+
const toVariableInitializerKind = (value) => {
|
|
133
|
+
if (!isObjectRecord(value) || typeof value.type !== 'string') {
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
if (value.type === 'ArrowFunctionExpression') {
|
|
137
|
+
return 'arrow-function';
|
|
138
|
+
}
|
|
139
|
+
if (value.type === 'FunctionExpression') {
|
|
140
|
+
return 'function-expression';
|
|
141
|
+
}
|
|
142
|
+
if (value.type === 'ClassExpression') {
|
|
143
|
+
return 'class-expression';
|
|
144
|
+
}
|
|
145
|
+
return 'other';
|
|
146
|
+
};
|
|
147
|
+
const pushTopLevelDeclarationMetadata = ({ declaration, exportKind, statementRange, declarations, }) => {
|
|
148
|
+
if (declaration.type === 'FunctionDeclaration') {
|
|
149
|
+
const name = toIdentifierName(declaration.id);
|
|
150
|
+
if (!name) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
declarations.push({
|
|
154
|
+
name,
|
|
155
|
+
kind: 'function',
|
|
156
|
+
exportKind,
|
|
157
|
+
range: toSourceRange(declaration),
|
|
158
|
+
statementRange,
|
|
159
|
+
initializerKind: null,
|
|
160
|
+
});
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
if (declaration.type === 'ClassDeclaration') {
|
|
164
|
+
const name = toIdentifierName(declaration.id);
|
|
165
|
+
if (!name) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
declarations.push({
|
|
169
|
+
name,
|
|
170
|
+
kind: 'class',
|
|
171
|
+
exportKind,
|
|
172
|
+
range: toSourceRange(declaration),
|
|
173
|
+
statementRange,
|
|
174
|
+
initializerKind: null,
|
|
175
|
+
});
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
if (!Array.isArray(declaration.declarations)) {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
for (const declarator of declaration.declarations) {
|
|
182
|
+
if (!isObjectRecord(declarator)) {
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
const name = toIdentifierName(declarator.id);
|
|
186
|
+
if (!name) {
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
declarations.push({
|
|
190
|
+
name,
|
|
191
|
+
kind: 'variable',
|
|
192
|
+
exportKind,
|
|
193
|
+
range: toSourceRange(declarator),
|
|
194
|
+
statementRange,
|
|
195
|
+
initializerKind: toVariableInitializerKind(declarator.init),
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
const collectTopLevelDeclarationMetadata = (body) => {
|
|
200
|
+
if (!Array.isArray(body)) {
|
|
201
|
+
return [];
|
|
202
|
+
}
|
|
203
|
+
const declarations = [];
|
|
204
|
+
for (const statement of body) {
|
|
205
|
+
if (!isObjectRecord(statement) || typeof statement.type !== 'string') {
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
const statementRange = toSourceRange(statement);
|
|
209
|
+
if (statement.type === 'ExportNamedDeclaration') {
|
|
210
|
+
if (!isObjectRecord(statement.declaration)) {
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
pushTopLevelDeclarationMetadata({
|
|
214
|
+
declaration: statement.declaration,
|
|
215
|
+
exportKind: 'named',
|
|
216
|
+
statementRange,
|
|
217
|
+
declarations,
|
|
218
|
+
});
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
if (statement.type === 'ExportDefaultDeclaration') {
|
|
222
|
+
if (!isObjectRecord(statement.declaration)) {
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
225
|
+
pushTopLevelDeclarationMetadata({
|
|
226
|
+
declaration: statement.declaration,
|
|
227
|
+
exportKind: 'default',
|
|
228
|
+
statementRange,
|
|
229
|
+
declarations,
|
|
230
|
+
});
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
pushTopLevelDeclarationMetadata({
|
|
234
|
+
declaration: statement,
|
|
235
|
+
exportKind: 'none',
|
|
236
|
+
statementRange,
|
|
237
|
+
declarations,
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
return declarations;
|
|
241
|
+
};
|
|
242
|
+
const unwrapExpressionNode = (value) => {
|
|
243
|
+
let current = value;
|
|
244
|
+
while (isObjectRecord(current) && typeof current.type === 'string') {
|
|
245
|
+
if (current.type === 'ParenthesizedExpression') {
|
|
246
|
+
current = current.expression;
|
|
247
|
+
continue;
|
|
248
|
+
}
|
|
249
|
+
if (current.type === 'TSAsExpression' ||
|
|
250
|
+
current.type === 'TSSatisfiesExpression' ||
|
|
251
|
+
current.type === 'TSInstantiationExpression' ||
|
|
252
|
+
current.type === 'TSNonNullExpression' ||
|
|
253
|
+
current.type === 'TSTypeAssertion') {
|
|
254
|
+
current = current.expression;
|
|
255
|
+
continue;
|
|
256
|
+
}
|
|
257
|
+
break;
|
|
258
|
+
}
|
|
259
|
+
return current;
|
|
260
|
+
};
|
|
261
|
+
const isJsxExpressionNode = (value) => {
|
|
262
|
+
const unwrapped = unwrapExpressionNode(value);
|
|
263
|
+
if (!isObjectRecord(unwrapped) || typeof unwrapped.type !== 'string') {
|
|
264
|
+
return false;
|
|
265
|
+
}
|
|
266
|
+
return unwrapped.type === 'JSXElement' || unwrapped.type === 'JSXFragment';
|
|
267
|
+
};
|
|
268
|
+
const collectTopLevelJsxExpressionMetadata = (body) => {
|
|
269
|
+
if (!Array.isArray(body)) {
|
|
270
|
+
return false;
|
|
271
|
+
}
|
|
272
|
+
for (const statement of body) {
|
|
273
|
+
if (!isObjectRecord(statement) || statement.type !== 'ExpressionStatement') {
|
|
274
|
+
continue;
|
|
275
|
+
}
|
|
276
|
+
if (isJsxExpressionNode(statement.expression)) {
|
|
277
|
+
return true;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
return false;
|
|
281
|
+
};
|
|
123
282
|
const ensureSupportedOptions = (options) => {
|
|
124
283
|
if (options.sourceType !== undefined &&
|
|
125
284
|
options.sourceType !== 'module' &&
|
|
@@ -136,6 +295,14 @@ const ensureSupportedOptions = (options) => {
|
|
|
136
295
|
options.typescriptStripBackend !== 'transpile-manual') {
|
|
137
296
|
throw new Error(`[jsx] Unsupported typescriptStripBackend "${String(options.typescriptStripBackend)}". Use "oxc-transform" or "transpile-manual".`);
|
|
138
297
|
}
|
|
298
|
+
if (options.collectTopLevelDeclarations !== undefined &&
|
|
299
|
+
typeof options.collectTopLevelDeclarations !== 'boolean') {
|
|
300
|
+
throw new Error(`[jsx] Unsupported collectTopLevelDeclarations value "${String(options.collectTopLevelDeclarations)}". Use true or false.`);
|
|
301
|
+
}
|
|
302
|
+
if (options.collectTopLevelJsxExpression !== undefined &&
|
|
303
|
+
typeof options.collectTopLevelJsxExpression !== 'boolean') {
|
|
304
|
+
throw new Error(`[jsx] Unsupported collectTopLevelJsxExpression value "${String(options.collectTopLevelJsxExpression)}". Use true or false.`);
|
|
305
|
+
}
|
|
139
306
|
};
|
|
140
307
|
function transformJsxSource(source, options = {}) {
|
|
141
308
|
const internalOptions = options;
|
|
@@ -146,12 +313,20 @@ function transformJsxSource(source, options = {}) {
|
|
|
146
313
|
const parsed = (0, oxc_parser_1.parseSync)('transform-jsx-source.tsx', source, createParserOptions(sourceType));
|
|
147
314
|
const parserDiagnostics = parsed.errors.map(error => toDiagnostic('parser', error));
|
|
148
315
|
const imports = collectImportMetadata(parsed.program.body);
|
|
316
|
+
const declarations = internalOptions.collectTopLevelDeclarations
|
|
317
|
+
? collectTopLevelDeclarationMetadata(parsed.program.body)
|
|
318
|
+
: undefined;
|
|
319
|
+
const hasTopLevelJsxExpression = internalOptions.collectTopLevelJsxExpression
|
|
320
|
+
? collectTopLevelJsxExpressionMetadata(parsed.program.body)
|
|
321
|
+
: undefined;
|
|
149
322
|
if (parserDiagnostics.length) {
|
|
150
323
|
return {
|
|
151
324
|
code: source,
|
|
152
325
|
changed: false,
|
|
153
326
|
imports,
|
|
154
327
|
diagnostics: parserDiagnostics,
|
|
328
|
+
declarations,
|
|
329
|
+
hasTopLevelJsxExpression,
|
|
155
330
|
};
|
|
156
331
|
}
|
|
157
332
|
const transpileBaseOptions = {
|
|
@@ -167,6 +342,8 @@ function transformJsxSource(source, options = {}) {
|
|
|
167
342
|
changed: result.changed,
|
|
168
343
|
imports,
|
|
169
344
|
diagnostics: parserDiagnostics,
|
|
345
|
+
declarations,
|
|
346
|
+
hasTopLevelJsxExpression,
|
|
170
347
|
};
|
|
171
348
|
}
|
|
172
349
|
if (typescriptStripBackend === 'transpile-manual') {
|
|
@@ -179,6 +356,8 @@ function transformJsxSource(source, options = {}) {
|
|
|
179
356
|
changed: result.changed,
|
|
180
357
|
imports,
|
|
181
358
|
diagnostics: parserDiagnostics,
|
|
359
|
+
declarations,
|
|
360
|
+
hasTopLevelJsxExpression,
|
|
182
361
|
};
|
|
183
362
|
}
|
|
184
363
|
const transformed = (0, oxc_transform_1.transformSync)('transform-jsx-source.tsx', source, {
|
|
@@ -196,6 +375,8 @@ function transformJsxSource(source, options = {}) {
|
|
|
196
375
|
changed: fallbackCode !== source,
|
|
197
376
|
imports,
|
|
198
377
|
diagnostics,
|
|
378
|
+
declarations,
|
|
379
|
+
hasTopLevelJsxExpression,
|
|
199
380
|
};
|
|
200
381
|
}
|
|
201
382
|
const jsxResult = (0, transpile_js_1.transpileJsxSource)(transformed.code, transpileBaseOptions);
|
|
@@ -204,5 +385,7 @@ function transformJsxSource(source, options = {}) {
|
|
|
204
385
|
changed: jsxResult.code !== source,
|
|
205
386
|
imports,
|
|
206
387
|
diagnostics,
|
|
388
|
+
declarations,
|
|
389
|
+
hasTopLevelJsxExpression,
|
|
207
390
|
};
|
|
208
391
|
}
|
package/dist/cjs/transform.d.cts
CHANGED
|
@@ -23,12 +23,28 @@ export type TransformImport = {
|
|
|
23
23
|
bindings: TransformImportBinding[];
|
|
24
24
|
range: SourceRange | null;
|
|
25
25
|
};
|
|
26
|
-
export type
|
|
26
|
+
export type TransformTopLevelDeclarationKind = 'function' | 'class' | 'variable';
|
|
27
|
+
export type TransformTopLevelDeclarationExportKind = 'none' | 'named' | 'default';
|
|
28
|
+
export type TransformVariableInitializerKind = 'arrow-function' | 'function-expression' | 'class-expression' | 'other' | null;
|
|
29
|
+
export type TransformTopLevelDeclaration = {
|
|
30
|
+
name: string;
|
|
31
|
+
kind: TransformTopLevelDeclarationKind;
|
|
32
|
+
exportKind: TransformTopLevelDeclarationExportKind;
|
|
33
|
+
range: SourceRange | null;
|
|
34
|
+
statementRange: SourceRange | null;
|
|
35
|
+
initializerKind: TransformVariableInitializerKind;
|
|
36
|
+
};
|
|
37
|
+
export type TransformJsxSourceOptions = TranspileJsxSourceOptions & {
|
|
38
|
+
collectTopLevelDeclarations?: boolean;
|
|
39
|
+
collectTopLevelJsxExpression?: boolean;
|
|
40
|
+
};
|
|
27
41
|
export type TransformJsxSourceResult = {
|
|
28
42
|
code: string;
|
|
29
43
|
changed: boolean;
|
|
30
44
|
imports: TransformImport[];
|
|
31
45
|
diagnostics: TransformDiagnostic[];
|
|
46
|
+
declarations?: TransformTopLevelDeclaration[];
|
|
47
|
+
hasTopLevelJsxExpression?: boolean;
|
|
32
48
|
};
|
|
33
49
|
export declare function transformJsxSource(source: string, options?: TransformJsxSourceOptions): TransformJsxSourceResult;
|
|
34
50
|
export {};
|
package/dist/transform.d.ts
CHANGED
|
@@ -23,12 +23,28 @@ export type TransformImport = {
|
|
|
23
23
|
bindings: TransformImportBinding[];
|
|
24
24
|
range: SourceRange | null;
|
|
25
25
|
};
|
|
26
|
-
export type
|
|
26
|
+
export type TransformTopLevelDeclarationKind = 'function' | 'class' | 'variable';
|
|
27
|
+
export type TransformTopLevelDeclarationExportKind = 'none' | 'named' | 'default';
|
|
28
|
+
export type TransformVariableInitializerKind = 'arrow-function' | 'function-expression' | 'class-expression' | 'other' | null;
|
|
29
|
+
export type TransformTopLevelDeclaration = {
|
|
30
|
+
name: string;
|
|
31
|
+
kind: TransformTopLevelDeclarationKind;
|
|
32
|
+
exportKind: TransformTopLevelDeclarationExportKind;
|
|
33
|
+
range: SourceRange | null;
|
|
34
|
+
statementRange: SourceRange | null;
|
|
35
|
+
initializerKind: TransformVariableInitializerKind;
|
|
36
|
+
};
|
|
37
|
+
export type TransformJsxSourceOptions = TranspileJsxSourceOptions & {
|
|
38
|
+
collectTopLevelDeclarations?: boolean;
|
|
39
|
+
collectTopLevelJsxExpression?: boolean;
|
|
40
|
+
};
|
|
27
41
|
export type TransformJsxSourceResult = {
|
|
28
42
|
code: string;
|
|
29
43
|
changed: boolean;
|
|
30
44
|
imports: TransformImport[];
|
|
31
45
|
diagnostics: TransformDiagnostic[];
|
|
46
|
+
declarations?: TransformTopLevelDeclaration[];
|
|
47
|
+
hasTopLevelJsxExpression?: boolean;
|
|
32
48
|
};
|
|
33
49
|
export declare function transformJsxSource(source: string, options?: TransformJsxSourceOptions): TransformJsxSourceResult;
|
|
34
50
|
export {};
|
package/dist/transform.js
CHANGED
|
@@ -117,6 +117,165 @@ const collectImportMetadata = (body) => {
|
|
|
117
117
|
});
|
|
118
118
|
return imports;
|
|
119
119
|
};
|
|
120
|
+
const toIdentifierName = (value) => {
|
|
121
|
+
if (!isObjectRecord(value)) {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
if (value.type !== 'Identifier') {
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
return typeof value.name === 'string' ? value.name : null;
|
|
128
|
+
};
|
|
129
|
+
const toVariableInitializerKind = (value) => {
|
|
130
|
+
if (!isObjectRecord(value) || typeof value.type !== 'string') {
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
if (value.type === 'ArrowFunctionExpression') {
|
|
134
|
+
return 'arrow-function';
|
|
135
|
+
}
|
|
136
|
+
if (value.type === 'FunctionExpression') {
|
|
137
|
+
return 'function-expression';
|
|
138
|
+
}
|
|
139
|
+
if (value.type === 'ClassExpression') {
|
|
140
|
+
return 'class-expression';
|
|
141
|
+
}
|
|
142
|
+
return 'other';
|
|
143
|
+
};
|
|
144
|
+
const pushTopLevelDeclarationMetadata = ({ declaration, exportKind, statementRange, declarations, }) => {
|
|
145
|
+
if (declaration.type === 'FunctionDeclaration') {
|
|
146
|
+
const name = toIdentifierName(declaration.id);
|
|
147
|
+
if (!name) {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
declarations.push({
|
|
151
|
+
name,
|
|
152
|
+
kind: 'function',
|
|
153
|
+
exportKind,
|
|
154
|
+
range: toSourceRange(declaration),
|
|
155
|
+
statementRange,
|
|
156
|
+
initializerKind: null,
|
|
157
|
+
});
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
if (declaration.type === 'ClassDeclaration') {
|
|
161
|
+
const name = toIdentifierName(declaration.id);
|
|
162
|
+
if (!name) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
declarations.push({
|
|
166
|
+
name,
|
|
167
|
+
kind: 'class',
|
|
168
|
+
exportKind,
|
|
169
|
+
range: toSourceRange(declaration),
|
|
170
|
+
statementRange,
|
|
171
|
+
initializerKind: null,
|
|
172
|
+
});
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
if (!Array.isArray(declaration.declarations)) {
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
for (const declarator of declaration.declarations) {
|
|
179
|
+
if (!isObjectRecord(declarator)) {
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
const name = toIdentifierName(declarator.id);
|
|
183
|
+
if (!name) {
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
declarations.push({
|
|
187
|
+
name,
|
|
188
|
+
kind: 'variable',
|
|
189
|
+
exportKind,
|
|
190
|
+
range: toSourceRange(declarator),
|
|
191
|
+
statementRange,
|
|
192
|
+
initializerKind: toVariableInitializerKind(declarator.init),
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
const collectTopLevelDeclarationMetadata = (body) => {
|
|
197
|
+
if (!Array.isArray(body)) {
|
|
198
|
+
return [];
|
|
199
|
+
}
|
|
200
|
+
const declarations = [];
|
|
201
|
+
for (const statement of body) {
|
|
202
|
+
if (!isObjectRecord(statement) || typeof statement.type !== 'string') {
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
const statementRange = toSourceRange(statement);
|
|
206
|
+
if (statement.type === 'ExportNamedDeclaration') {
|
|
207
|
+
if (!isObjectRecord(statement.declaration)) {
|
|
208
|
+
continue;
|
|
209
|
+
}
|
|
210
|
+
pushTopLevelDeclarationMetadata({
|
|
211
|
+
declaration: statement.declaration,
|
|
212
|
+
exportKind: 'named',
|
|
213
|
+
statementRange,
|
|
214
|
+
declarations,
|
|
215
|
+
});
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
if (statement.type === 'ExportDefaultDeclaration') {
|
|
219
|
+
if (!isObjectRecord(statement.declaration)) {
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
pushTopLevelDeclarationMetadata({
|
|
223
|
+
declaration: statement.declaration,
|
|
224
|
+
exportKind: 'default',
|
|
225
|
+
statementRange,
|
|
226
|
+
declarations,
|
|
227
|
+
});
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
230
|
+
pushTopLevelDeclarationMetadata({
|
|
231
|
+
declaration: statement,
|
|
232
|
+
exportKind: 'none',
|
|
233
|
+
statementRange,
|
|
234
|
+
declarations,
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
return declarations;
|
|
238
|
+
};
|
|
239
|
+
const unwrapExpressionNode = (value) => {
|
|
240
|
+
let current = value;
|
|
241
|
+
while (isObjectRecord(current) && typeof current.type === 'string') {
|
|
242
|
+
if (current.type === 'ParenthesizedExpression') {
|
|
243
|
+
current = current.expression;
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
if (current.type === 'TSAsExpression' ||
|
|
247
|
+
current.type === 'TSSatisfiesExpression' ||
|
|
248
|
+
current.type === 'TSInstantiationExpression' ||
|
|
249
|
+
current.type === 'TSNonNullExpression' ||
|
|
250
|
+
current.type === 'TSTypeAssertion') {
|
|
251
|
+
current = current.expression;
|
|
252
|
+
continue;
|
|
253
|
+
}
|
|
254
|
+
break;
|
|
255
|
+
}
|
|
256
|
+
return current;
|
|
257
|
+
};
|
|
258
|
+
const isJsxExpressionNode = (value) => {
|
|
259
|
+
const unwrapped = unwrapExpressionNode(value);
|
|
260
|
+
if (!isObjectRecord(unwrapped) || typeof unwrapped.type !== 'string') {
|
|
261
|
+
return false;
|
|
262
|
+
}
|
|
263
|
+
return unwrapped.type === 'JSXElement' || unwrapped.type === 'JSXFragment';
|
|
264
|
+
};
|
|
265
|
+
const collectTopLevelJsxExpressionMetadata = (body) => {
|
|
266
|
+
if (!Array.isArray(body)) {
|
|
267
|
+
return false;
|
|
268
|
+
}
|
|
269
|
+
for (const statement of body) {
|
|
270
|
+
if (!isObjectRecord(statement) || statement.type !== 'ExpressionStatement') {
|
|
271
|
+
continue;
|
|
272
|
+
}
|
|
273
|
+
if (isJsxExpressionNode(statement.expression)) {
|
|
274
|
+
return true;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
return false;
|
|
278
|
+
};
|
|
120
279
|
const ensureSupportedOptions = (options) => {
|
|
121
280
|
if (options.sourceType !== undefined &&
|
|
122
281
|
options.sourceType !== 'module' &&
|
|
@@ -133,6 +292,14 @@ const ensureSupportedOptions = (options) => {
|
|
|
133
292
|
options.typescriptStripBackend !== 'transpile-manual') {
|
|
134
293
|
throw new Error(`[jsx] Unsupported typescriptStripBackend "${String(options.typescriptStripBackend)}". Use "oxc-transform" or "transpile-manual".`);
|
|
135
294
|
}
|
|
295
|
+
if (options.collectTopLevelDeclarations !== undefined &&
|
|
296
|
+
typeof options.collectTopLevelDeclarations !== 'boolean') {
|
|
297
|
+
throw new Error(`[jsx] Unsupported collectTopLevelDeclarations value "${String(options.collectTopLevelDeclarations)}". Use true or false.`);
|
|
298
|
+
}
|
|
299
|
+
if (options.collectTopLevelJsxExpression !== undefined &&
|
|
300
|
+
typeof options.collectTopLevelJsxExpression !== 'boolean') {
|
|
301
|
+
throw new Error(`[jsx] Unsupported collectTopLevelJsxExpression value "${String(options.collectTopLevelJsxExpression)}". Use true or false.`);
|
|
302
|
+
}
|
|
136
303
|
};
|
|
137
304
|
export function transformJsxSource(source, options = {}) {
|
|
138
305
|
const internalOptions = options;
|
|
@@ -143,12 +310,20 @@ export function transformJsxSource(source, options = {}) {
|
|
|
143
310
|
const parsed = parseSync('transform-jsx-source.tsx', source, createParserOptions(sourceType));
|
|
144
311
|
const parserDiagnostics = parsed.errors.map(error => toDiagnostic('parser', error));
|
|
145
312
|
const imports = collectImportMetadata(parsed.program.body);
|
|
313
|
+
const declarations = internalOptions.collectTopLevelDeclarations
|
|
314
|
+
? collectTopLevelDeclarationMetadata(parsed.program.body)
|
|
315
|
+
: undefined;
|
|
316
|
+
const hasTopLevelJsxExpression = internalOptions.collectTopLevelJsxExpression
|
|
317
|
+
? collectTopLevelJsxExpressionMetadata(parsed.program.body)
|
|
318
|
+
: undefined;
|
|
146
319
|
if (parserDiagnostics.length) {
|
|
147
320
|
return {
|
|
148
321
|
code: source,
|
|
149
322
|
changed: false,
|
|
150
323
|
imports,
|
|
151
324
|
diagnostics: parserDiagnostics,
|
|
325
|
+
declarations,
|
|
326
|
+
hasTopLevelJsxExpression,
|
|
152
327
|
};
|
|
153
328
|
}
|
|
154
329
|
const transpileBaseOptions = {
|
|
@@ -164,6 +339,8 @@ export function transformJsxSource(source, options = {}) {
|
|
|
164
339
|
changed: result.changed,
|
|
165
340
|
imports,
|
|
166
341
|
diagnostics: parserDiagnostics,
|
|
342
|
+
declarations,
|
|
343
|
+
hasTopLevelJsxExpression,
|
|
167
344
|
};
|
|
168
345
|
}
|
|
169
346
|
if (typescriptStripBackend === 'transpile-manual') {
|
|
@@ -176,6 +353,8 @@ export function transformJsxSource(source, options = {}) {
|
|
|
176
353
|
changed: result.changed,
|
|
177
354
|
imports,
|
|
178
355
|
diagnostics: parserDiagnostics,
|
|
356
|
+
declarations,
|
|
357
|
+
hasTopLevelJsxExpression,
|
|
179
358
|
};
|
|
180
359
|
}
|
|
181
360
|
const transformed = transformSync('transform-jsx-source.tsx', source, {
|
|
@@ -193,6 +372,8 @@ export function transformJsxSource(source, options = {}) {
|
|
|
193
372
|
changed: fallbackCode !== source,
|
|
194
373
|
imports,
|
|
195
374
|
diagnostics,
|
|
375
|
+
declarations,
|
|
376
|
+
hasTopLevelJsxExpression,
|
|
196
377
|
};
|
|
197
378
|
}
|
|
198
379
|
const jsxResult = transpileJsxSource(transformed.code, transpileBaseOptions);
|
|
@@ -201,5 +382,7 @@ export function transformJsxSource(source, options = {}) {
|
|
|
201
382
|
changed: jsxResult.code !== source,
|
|
202
383
|
imports,
|
|
203
384
|
diagnostics,
|
|
385
|
+
declarations,
|
|
386
|
+
hasTopLevelJsxExpression,
|
|
204
387
|
};
|
|
205
388
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@knighted/jsx",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.12.0",
|
|
4
4
|
"description": "Runtime JSX tagged template that renders DOM or React trees anywhere with or without a build step.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"jsx runtime",
|
|
@@ -173,7 +173,7 @@
|
|
|
173
173
|
"jsdom": "^27.2.0",
|
|
174
174
|
"lint-staged": "^16.2.7",
|
|
175
175
|
"lit": "^3.2.1",
|
|
176
|
-
"next": "^16.1.
|
|
176
|
+
"next": "^16.1.7",
|
|
177
177
|
"oxlint": "^1.51.0",
|
|
178
178
|
"prettier": "^3.7.3",
|
|
179
179
|
"react": "^19.0.0",
|