@knighted/jsx 1.11.0 → 1.13.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 +70 -0
- package/dist/cjs/transform.d.cts +3 -0
- package/dist/transform.d.ts +3 -0
- package/dist/transform.js +70 -0
- package/package.json +2 -2
package/dist/cjs/transform.cjs
CHANGED
|
@@ -239,6 +239,57 @@ const collectTopLevelDeclarationMetadata = (body) => {
|
|
|
239
239
|
}
|
|
240
240
|
return declarations;
|
|
241
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 toJsxExpressionNode = (value) => {
|
|
262
|
+
const unwrapped = unwrapExpressionNode(value);
|
|
263
|
+
if (!isObjectRecord(unwrapped) || typeof unwrapped.type !== 'string') {
|
|
264
|
+
return null;
|
|
265
|
+
}
|
|
266
|
+
if (unwrapped.type === 'JSXElement' || unwrapped.type === 'JSXFragment') {
|
|
267
|
+
return unwrapped;
|
|
268
|
+
}
|
|
269
|
+
return null;
|
|
270
|
+
};
|
|
271
|
+
const createEmptyTopLevelJsxExpressionMetadata = () => ({
|
|
272
|
+
hasTopLevelJsxExpression: false,
|
|
273
|
+
topLevelJsxExpressionRange: null,
|
|
274
|
+
});
|
|
275
|
+
const collectTopLevelJsxExpressionMetadata = (body) => {
|
|
276
|
+
if (!Array.isArray(body)) {
|
|
277
|
+
return createEmptyTopLevelJsxExpressionMetadata();
|
|
278
|
+
}
|
|
279
|
+
for (const statement of body) {
|
|
280
|
+
if (!isObjectRecord(statement) || statement.type !== 'ExpressionStatement') {
|
|
281
|
+
continue;
|
|
282
|
+
}
|
|
283
|
+
const jsxNode = toJsxExpressionNode(statement.expression);
|
|
284
|
+
if (jsxNode) {
|
|
285
|
+
return {
|
|
286
|
+
hasTopLevelJsxExpression: true,
|
|
287
|
+
topLevelJsxExpressionRange: toSourceRange(jsxNode),
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
return createEmptyTopLevelJsxExpressionMetadata();
|
|
292
|
+
};
|
|
242
293
|
const ensureSupportedOptions = (options) => {
|
|
243
294
|
if (options.sourceType !== undefined &&
|
|
244
295
|
options.sourceType !== 'module' &&
|
|
@@ -259,6 +310,10 @@ const ensureSupportedOptions = (options) => {
|
|
|
259
310
|
typeof options.collectTopLevelDeclarations !== 'boolean') {
|
|
260
311
|
throw new Error(`[jsx] Unsupported collectTopLevelDeclarations value "${String(options.collectTopLevelDeclarations)}". Use true or false.`);
|
|
261
312
|
}
|
|
313
|
+
if (options.collectTopLevelJsxExpression !== undefined &&
|
|
314
|
+
typeof options.collectTopLevelJsxExpression !== 'boolean') {
|
|
315
|
+
throw new Error(`[jsx] Unsupported collectTopLevelJsxExpression value "${String(options.collectTopLevelJsxExpression)}". Use true or false.`);
|
|
316
|
+
}
|
|
262
317
|
};
|
|
263
318
|
function transformJsxSource(source, options = {}) {
|
|
264
319
|
const internalOptions = options;
|
|
@@ -272,6 +327,11 @@ function transformJsxSource(source, options = {}) {
|
|
|
272
327
|
const declarations = internalOptions.collectTopLevelDeclarations
|
|
273
328
|
? collectTopLevelDeclarationMetadata(parsed.program.body)
|
|
274
329
|
: undefined;
|
|
330
|
+
const topLevelJsxExpressionMetadata = internalOptions.collectTopLevelJsxExpression
|
|
331
|
+
? collectTopLevelJsxExpressionMetadata(parsed.program.body)
|
|
332
|
+
: undefined;
|
|
333
|
+
const hasTopLevelJsxExpression = topLevelJsxExpressionMetadata?.hasTopLevelJsxExpression;
|
|
334
|
+
const topLevelJsxExpressionRange = topLevelJsxExpressionMetadata?.topLevelJsxExpressionRange;
|
|
275
335
|
if (parserDiagnostics.length) {
|
|
276
336
|
return {
|
|
277
337
|
code: source,
|
|
@@ -279,6 +339,8 @@ function transformJsxSource(source, options = {}) {
|
|
|
279
339
|
imports,
|
|
280
340
|
diagnostics: parserDiagnostics,
|
|
281
341
|
declarations,
|
|
342
|
+
hasTopLevelJsxExpression,
|
|
343
|
+
topLevelJsxExpressionRange,
|
|
282
344
|
};
|
|
283
345
|
}
|
|
284
346
|
const transpileBaseOptions = {
|
|
@@ -295,6 +357,8 @@ function transformJsxSource(source, options = {}) {
|
|
|
295
357
|
imports,
|
|
296
358
|
diagnostics: parserDiagnostics,
|
|
297
359
|
declarations,
|
|
360
|
+
hasTopLevelJsxExpression,
|
|
361
|
+
topLevelJsxExpressionRange,
|
|
298
362
|
};
|
|
299
363
|
}
|
|
300
364
|
if (typescriptStripBackend === 'transpile-manual') {
|
|
@@ -308,6 +372,8 @@ function transformJsxSource(source, options = {}) {
|
|
|
308
372
|
imports,
|
|
309
373
|
diagnostics: parserDiagnostics,
|
|
310
374
|
declarations,
|
|
375
|
+
hasTopLevelJsxExpression,
|
|
376
|
+
topLevelJsxExpressionRange,
|
|
311
377
|
};
|
|
312
378
|
}
|
|
313
379
|
const transformed = (0, oxc_transform_1.transformSync)('transform-jsx-source.tsx', source, {
|
|
@@ -326,6 +392,8 @@ function transformJsxSource(source, options = {}) {
|
|
|
326
392
|
imports,
|
|
327
393
|
diagnostics,
|
|
328
394
|
declarations,
|
|
395
|
+
hasTopLevelJsxExpression,
|
|
396
|
+
topLevelJsxExpressionRange,
|
|
329
397
|
};
|
|
330
398
|
}
|
|
331
399
|
const jsxResult = (0, transpile_js_1.transpileJsxSource)(transformed.code, transpileBaseOptions);
|
|
@@ -335,5 +403,7 @@ function transformJsxSource(source, options = {}) {
|
|
|
335
403
|
imports,
|
|
336
404
|
diagnostics,
|
|
337
405
|
declarations,
|
|
406
|
+
hasTopLevelJsxExpression,
|
|
407
|
+
topLevelJsxExpressionRange,
|
|
338
408
|
};
|
|
339
409
|
}
|
package/dist/cjs/transform.d.cts
CHANGED
|
@@ -36,6 +36,7 @@ export type TransformTopLevelDeclaration = {
|
|
|
36
36
|
};
|
|
37
37
|
export type TransformJsxSourceOptions = TranspileJsxSourceOptions & {
|
|
38
38
|
collectTopLevelDeclarations?: boolean;
|
|
39
|
+
collectTopLevelJsxExpression?: boolean;
|
|
39
40
|
};
|
|
40
41
|
export type TransformJsxSourceResult = {
|
|
41
42
|
code: string;
|
|
@@ -43,6 +44,8 @@ export type TransformJsxSourceResult = {
|
|
|
43
44
|
imports: TransformImport[];
|
|
44
45
|
diagnostics: TransformDiagnostic[];
|
|
45
46
|
declarations?: TransformTopLevelDeclaration[];
|
|
47
|
+
hasTopLevelJsxExpression?: boolean;
|
|
48
|
+
topLevelJsxExpressionRange?: SourceRange | null;
|
|
46
49
|
};
|
|
47
50
|
export declare function transformJsxSource(source: string, options?: TransformJsxSourceOptions): TransformJsxSourceResult;
|
|
48
51
|
export {};
|
package/dist/transform.d.ts
CHANGED
|
@@ -36,6 +36,7 @@ export type TransformTopLevelDeclaration = {
|
|
|
36
36
|
};
|
|
37
37
|
export type TransformJsxSourceOptions = TranspileJsxSourceOptions & {
|
|
38
38
|
collectTopLevelDeclarations?: boolean;
|
|
39
|
+
collectTopLevelJsxExpression?: boolean;
|
|
39
40
|
};
|
|
40
41
|
export type TransformJsxSourceResult = {
|
|
41
42
|
code: string;
|
|
@@ -43,6 +44,8 @@ export type TransformJsxSourceResult = {
|
|
|
43
44
|
imports: TransformImport[];
|
|
44
45
|
diagnostics: TransformDiagnostic[];
|
|
45
46
|
declarations?: TransformTopLevelDeclaration[];
|
|
47
|
+
hasTopLevelJsxExpression?: boolean;
|
|
48
|
+
topLevelJsxExpressionRange?: SourceRange | null;
|
|
46
49
|
};
|
|
47
50
|
export declare function transformJsxSource(source: string, options?: TransformJsxSourceOptions): TransformJsxSourceResult;
|
|
48
51
|
export {};
|
package/dist/transform.js
CHANGED
|
@@ -236,6 +236,57 @@ const collectTopLevelDeclarationMetadata = (body) => {
|
|
|
236
236
|
}
|
|
237
237
|
return declarations;
|
|
238
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 toJsxExpressionNode = (value) => {
|
|
259
|
+
const unwrapped = unwrapExpressionNode(value);
|
|
260
|
+
if (!isObjectRecord(unwrapped) || typeof unwrapped.type !== 'string') {
|
|
261
|
+
return null;
|
|
262
|
+
}
|
|
263
|
+
if (unwrapped.type === 'JSXElement' || unwrapped.type === 'JSXFragment') {
|
|
264
|
+
return unwrapped;
|
|
265
|
+
}
|
|
266
|
+
return null;
|
|
267
|
+
};
|
|
268
|
+
const createEmptyTopLevelJsxExpressionMetadata = () => ({
|
|
269
|
+
hasTopLevelJsxExpression: false,
|
|
270
|
+
topLevelJsxExpressionRange: null,
|
|
271
|
+
});
|
|
272
|
+
const collectTopLevelJsxExpressionMetadata = (body) => {
|
|
273
|
+
if (!Array.isArray(body)) {
|
|
274
|
+
return createEmptyTopLevelJsxExpressionMetadata();
|
|
275
|
+
}
|
|
276
|
+
for (const statement of body) {
|
|
277
|
+
if (!isObjectRecord(statement) || statement.type !== 'ExpressionStatement') {
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
280
|
+
const jsxNode = toJsxExpressionNode(statement.expression);
|
|
281
|
+
if (jsxNode) {
|
|
282
|
+
return {
|
|
283
|
+
hasTopLevelJsxExpression: true,
|
|
284
|
+
topLevelJsxExpressionRange: toSourceRange(jsxNode),
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
return createEmptyTopLevelJsxExpressionMetadata();
|
|
289
|
+
};
|
|
239
290
|
const ensureSupportedOptions = (options) => {
|
|
240
291
|
if (options.sourceType !== undefined &&
|
|
241
292
|
options.sourceType !== 'module' &&
|
|
@@ -256,6 +307,10 @@ const ensureSupportedOptions = (options) => {
|
|
|
256
307
|
typeof options.collectTopLevelDeclarations !== 'boolean') {
|
|
257
308
|
throw new Error(`[jsx] Unsupported collectTopLevelDeclarations value "${String(options.collectTopLevelDeclarations)}". Use true or false.`);
|
|
258
309
|
}
|
|
310
|
+
if (options.collectTopLevelJsxExpression !== undefined &&
|
|
311
|
+
typeof options.collectTopLevelJsxExpression !== 'boolean') {
|
|
312
|
+
throw new Error(`[jsx] Unsupported collectTopLevelJsxExpression value "${String(options.collectTopLevelJsxExpression)}". Use true or false.`);
|
|
313
|
+
}
|
|
259
314
|
};
|
|
260
315
|
export function transformJsxSource(source, options = {}) {
|
|
261
316
|
const internalOptions = options;
|
|
@@ -269,6 +324,11 @@ export function transformJsxSource(source, options = {}) {
|
|
|
269
324
|
const declarations = internalOptions.collectTopLevelDeclarations
|
|
270
325
|
? collectTopLevelDeclarationMetadata(parsed.program.body)
|
|
271
326
|
: undefined;
|
|
327
|
+
const topLevelJsxExpressionMetadata = internalOptions.collectTopLevelJsxExpression
|
|
328
|
+
? collectTopLevelJsxExpressionMetadata(parsed.program.body)
|
|
329
|
+
: undefined;
|
|
330
|
+
const hasTopLevelJsxExpression = topLevelJsxExpressionMetadata?.hasTopLevelJsxExpression;
|
|
331
|
+
const topLevelJsxExpressionRange = topLevelJsxExpressionMetadata?.topLevelJsxExpressionRange;
|
|
272
332
|
if (parserDiagnostics.length) {
|
|
273
333
|
return {
|
|
274
334
|
code: source,
|
|
@@ -276,6 +336,8 @@ export function transformJsxSource(source, options = {}) {
|
|
|
276
336
|
imports,
|
|
277
337
|
diagnostics: parserDiagnostics,
|
|
278
338
|
declarations,
|
|
339
|
+
hasTopLevelJsxExpression,
|
|
340
|
+
topLevelJsxExpressionRange,
|
|
279
341
|
};
|
|
280
342
|
}
|
|
281
343
|
const transpileBaseOptions = {
|
|
@@ -292,6 +354,8 @@ export function transformJsxSource(source, options = {}) {
|
|
|
292
354
|
imports,
|
|
293
355
|
diagnostics: parserDiagnostics,
|
|
294
356
|
declarations,
|
|
357
|
+
hasTopLevelJsxExpression,
|
|
358
|
+
topLevelJsxExpressionRange,
|
|
295
359
|
};
|
|
296
360
|
}
|
|
297
361
|
if (typescriptStripBackend === 'transpile-manual') {
|
|
@@ -305,6 +369,8 @@ export function transformJsxSource(source, options = {}) {
|
|
|
305
369
|
imports,
|
|
306
370
|
diagnostics: parserDiagnostics,
|
|
307
371
|
declarations,
|
|
372
|
+
hasTopLevelJsxExpression,
|
|
373
|
+
topLevelJsxExpressionRange,
|
|
308
374
|
};
|
|
309
375
|
}
|
|
310
376
|
const transformed = transformSync('transform-jsx-source.tsx', source, {
|
|
@@ -323,6 +389,8 @@ export function transformJsxSource(source, options = {}) {
|
|
|
323
389
|
imports,
|
|
324
390
|
diagnostics,
|
|
325
391
|
declarations,
|
|
392
|
+
hasTopLevelJsxExpression,
|
|
393
|
+
topLevelJsxExpressionRange,
|
|
326
394
|
};
|
|
327
395
|
}
|
|
328
396
|
const jsxResult = transpileJsxSource(transformed.code, transpileBaseOptions);
|
|
@@ -332,5 +400,7 @@ export function transformJsxSource(source, options = {}) {
|
|
|
332
400
|
imports,
|
|
333
401
|
diagnostics,
|
|
334
402
|
declarations,
|
|
403
|
+
hasTopLevelJsxExpression,
|
|
404
|
+
topLevelJsxExpressionRange,
|
|
335
405
|
};
|
|
336
406
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@knighted/jsx",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.13.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",
|