@tsrx/prettier-plugin 0.3.74 → 0.3.76
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/package.json +2 -2
- package/src/index.js +9 -24
- package/src/index.test.js +40 -92
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tsrx/prettier-plugin",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.76",
|
|
4
4
|
"description": "Ripple plugin for Prettier",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "src/index.js",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"prettier": "^3.8.3"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@tsrx/core": "0.1.
|
|
30
|
+
"@tsrx/core": "0.1.24"
|
|
31
31
|
},
|
|
32
32
|
"files": [
|
|
33
33
|
"src/"
|
package/src/index.js
CHANGED
|
@@ -42,16 +42,16 @@ const { replaceEndOfLine, willBreak } = utils;
|
|
|
42
42
|
/** @type {import('prettier').Plugin['languages']} */
|
|
43
43
|
export const languages = [
|
|
44
44
|
{
|
|
45
|
-
name: '
|
|
46
|
-
parsers: ['
|
|
45
|
+
name: 'tsrx',
|
|
46
|
+
parsers: ['tsrx'],
|
|
47
47
|
extensions: ['.tsrx'],
|
|
48
|
-
vscodeLanguageIds: ['ripple'],
|
|
48
|
+
vscodeLanguageIds: ['tsrx', 'ripple'],
|
|
49
49
|
},
|
|
50
50
|
];
|
|
51
51
|
|
|
52
52
|
/** @type {import('prettier').Plugin['parsers']} */
|
|
53
53
|
export const parsers = {
|
|
54
|
-
|
|
54
|
+
tsrx: {
|
|
55
55
|
astFormat: 'ripple-ast',
|
|
56
56
|
/**
|
|
57
57
|
* @param {string} text
|
|
@@ -1732,18 +1732,12 @@ function printRippleNode(node, path, options, print, args) {
|
|
|
1732
1732
|
}
|
|
1733
1733
|
case 'Identifier': {
|
|
1734
1734
|
// Simple case - just return the name directly like Prettier core
|
|
1735
|
-
const trackedPrefix = node.tracked ? '@' : '';
|
|
1736
1735
|
let identifierContent;
|
|
1737
1736
|
if (node.typeAnnotation) {
|
|
1738
1737
|
const optionalMarker = node.optional ? '?' : '';
|
|
1739
|
-
identifierContent = [
|
|
1740
|
-
trackedPrefix + node.name,
|
|
1741
|
-
optionalMarker,
|
|
1742
|
-
': ',
|
|
1743
|
-
path.call(print, 'typeAnnotation'),
|
|
1744
|
-
];
|
|
1738
|
+
identifierContent = [node.name, optionalMarker, ': ', path.call(print, 'typeAnnotation')];
|
|
1745
1739
|
} else {
|
|
1746
|
-
identifierContent =
|
|
1740
|
+
identifierContent = node.name;
|
|
1747
1741
|
}
|
|
1748
1742
|
// Preserve parentheses for type-cast identifiers, but only if:
|
|
1749
1743
|
// 1. The identifier itself is marked as parenthesized
|
|
@@ -4010,7 +4004,6 @@ function printMemberExpression(node, path, options, print) {
|
|
|
4010
4004
|
|
|
4011
4005
|
let result;
|
|
4012
4006
|
if (node.computed) {
|
|
4013
|
-
// Check if the MemberExpression itself is tracked to add @ symbol
|
|
4014
4007
|
const openBracket = node.optional ? '?.[' : '[';
|
|
4015
4008
|
result = [objectPart, openBracket, propertyPart, ']'];
|
|
4016
4009
|
} else {
|
|
@@ -6464,7 +6457,7 @@ function printJSXAttribute(attr, path, options, print) {
|
|
|
6464
6457
|
*/
|
|
6465
6458
|
function printJSXElementName(node) {
|
|
6466
6459
|
if (node.type === 'JSXIdentifier') {
|
|
6467
|
-
return
|
|
6460
|
+
return node.name;
|
|
6468
6461
|
}
|
|
6469
6462
|
if (node.type === 'JSXMemberExpression') {
|
|
6470
6463
|
return printJSXElementName(node.object) + '.' + printJSXElementName(node.property);
|
|
@@ -6477,14 +6470,6 @@ function printJSXElementName(node) {
|
|
|
6477
6470
|
return 'Unknown';
|
|
6478
6471
|
}
|
|
6479
6472
|
|
|
6480
|
-
/**
|
|
6481
|
-
* @param {ESTreeJSX.JSXIdentifier} node
|
|
6482
|
-
* @returns {boolean}
|
|
6483
|
-
*/
|
|
6484
|
-
function isDynamicJSXIdentifier(node) {
|
|
6485
|
-
return /** @type {{ dynamic?: boolean }} */ (node).dynamic === true;
|
|
6486
|
-
}
|
|
6487
|
-
|
|
6488
6473
|
/**
|
|
6489
6474
|
* Print a member expression as simple string (for element tag names)
|
|
6490
6475
|
* @param {AST.Node} node - The node to print
|
|
@@ -6494,7 +6479,7 @@ function isDynamicJSXIdentifier(node) {
|
|
|
6494
6479
|
*/
|
|
6495
6480
|
function printMemberExpressionSimple(node, options, computed = false) {
|
|
6496
6481
|
if (node.type === 'JSXIdentifier') {
|
|
6497
|
-
return
|
|
6482
|
+
return node.name;
|
|
6498
6483
|
}
|
|
6499
6484
|
|
|
6500
6485
|
if (node.type === 'JSXMemberExpression') {
|
|
@@ -6510,7 +6495,7 @@ function printMemberExpressionSimple(node, options, computed = false) {
|
|
|
6510
6495
|
}
|
|
6511
6496
|
|
|
6512
6497
|
if (node.type === 'Identifier') {
|
|
6513
|
-
return
|
|
6498
|
+
return node.name;
|
|
6514
6499
|
}
|
|
6515
6500
|
|
|
6516
6501
|
if (node.type === 'MemberExpression') {
|
package/src/index.test.js
CHANGED
|
@@ -2,7 +2,7 @@ import { describe, it, expect } from 'vitest';
|
|
|
2
2
|
import prettier from 'prettier';
|
|
3
3
|
import { fileURLToPath } from 'url';
|
|
4
4
|
import { dirname, join } from 'path';
|
|
5
|
-
import { languages } from './index.js';
|
|
5
|
+
import { languages, parsers } from './index.js';
|
|
6
6
|
|
|
7
7
|
const __filename = fileURLToPath(import.meta.url);
|
|
8
8
|
const __dirname = dirname(__filename);
|
|
@@ -40,13 +40,16 @@ expect.extend({
|
|
|
40
40
|
|
|
41
41
|
describe('prettier-plugin', () => {
|
|
42
42
|
it('registers .tsrx as a supported file extension', () => {
|
|
43
|
-
const
|
|
43
|
+
const tsrx_language = languages?.[0];
|
|
44
44
|
|
|
45
|
-
if (!
|
|
46
|
-
throw new Error('Missing
|
|
45
|
+
if (!tsrx_language) {
|
|
46
|
+
throw new Error('Missing TSRX language metadata');
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
expect(
|
|
49
|
+
expect(tsrx_language.extensions).toContain('.tsrx');
|
|
50
|
+
expect(tsrx_language.parsers).toContain('tsrx');
|
|
51
|
+
expect(parsers?.tsrx).toBeDefined();
|
|
52
|
+
expect(parsers?.ripple).toBeUndefined();
|
|
50
53
|
});
|
|
51
54
|
|
|
52
55
|
/**
|
|
@@ -55,7 +58,7 @@ describe('prettier-plugin', () => {
|
|
|
55
58
|
*/
|
|
56
59
|
const format = async (code, options = {}) => {
|
|
57
60
|
return await prettier.format(code, {
|
|
58
|
-
parser: '
|
|
61
|
+
parser: 'tsrx',
|
|
59
62
|
plugins: [join(__dirname, 'index.js')],
|
|
60
63
|
...options,
|
|
61
64
|
});
|
|
@@ -233,10 +236,10 @@ const items=[1,2,3];
|
|
|
233
236
|
});
|
|
234
237
|
|
|
235
238
|
it('keeps native fragments expression based', async () => {
|
|
236
|
-
const input = `function App(){return <><div>
|
|
239
|
+
const input = `function App(){return <><div>Hello world</div>{value}</>}`;
|
|
237
240
|
const expected = `function App() {
|
|
238
241
|
return <>
|
|
239
|
-
<div>
|
|
242
|
+
<div>Hello world</div>
|
|
240
243
|
{value}
|
|
241
244
|
</>;
|
|
242
245
|
}`;
|
|
@@ -277,17 +280,17 @@ const items=[1,2,3];
|
|
|
277
280
|
const input = `export function App() {
|
|
278
281
|
let [count] = track(0);
|
|
279
282
|
return <div>
|
|
280
|
-
<p>
|
|
281
|
-
<p>
|
|
282
|
-
<button onClick={() => count++}>
|
|
283
|
+
<p>Count: {count}</p>
|
|
284
|
+
<p>Count: {count}</p>
|
|
285
|
+
<button onClick={() => count++}>Increment</button>
|
|
283
286
|
</div>;
|
|
284
287
|
}`;
|
|
285
288
|
const expected = `export function App() {
|
|
286
289
|
let [count] = track(0);
|
|
287
290
|
return <div>
|
|
288
|
-
<p>
|
|
289
|
-
<p>
|
|
290
|
-
<button onClick={() => count++}>
|
|
291
|
+
<p>Count: {count}</p>
|
|
292
|
+
<p>Count: {count}</p>
|
|
293
|
+
<button onClick={() => count++}>Increment</button>
|
|
291
294
|
</div>;
|
|
292
295
|
}`;
|
|
293
296
|
|
|
@@ -400,28 +403,6 @@ function App() {
|
|
|
400
403
|
expect(result).toBeWithNewline(expected);
|
|
401
404
|
});
|
|
402
405
|
|
|
403
|
-
it('preserves dynamic component syntax', async () => {
|
|
404
|
-
const input = `function App(){return <>@{
|
|
405
|
-
function Basic(){return <><div>{"Basic Component"}</div></>;}
|
|
406
|
-
const obj={Basic};
|
|
407
|
-
const comp=obj.Basic;
|
|
408
|
-
<@comp />
|
|
409
|
-
}</>}`;
|
|
410
|
-
const expected = `function App() {
|
|
411
|
-
return <>@{
|
|
412
|
-
function Basic() {
|
|
413
|
-
return <><div>{"Basic Component"}</div></>;
|
|
414
|
-
}
|
|
415
|
-
const obj = { Basic };
|
|
416
|
-
const comp = obj.Basic;
|
|
417
|
-
<@comp />
|
|
418
|
-
}</>;
|
|
419
|
-
}`;
|
|
420
|
-
|
|
421
|
-
const result = await format(input);
|
|
422
|
-
expect(result).toBeWithNewline(expected);
|
|
423
|
-
});
|
|
424
|
-
|
|
425
406
|
it('formats raw HTML props inside native elements', async () => {
|
|
426
407
|
const input = `function App(){return <article innerHTML={source}/>}`;
|
|
427
408
|
const expected = `function App() {
|
|
@@ -608,10 +589,10 @@ const items=[1,2,3];
|
|
|
608
589
|
});
|
|
609
590
|
|
|
610
591
|
it('should keep sibling children in tsrx expression fragments on separate lines', async () => {
|
|
611
|
-
const input = `function Test(p1,p2){return <><div>
|
|
592
|
+
const input = `function Test(p1,p2){return <><div>Hello</div><div>{p1}</div><div>{p2}</div></>}`;
|
|
612
593
|
const expected = `function Test(p1, p2) {
|
|
613
594
|
return <>
|
|
614
|
-
<div>
|
|
595
|
+
<div>Hello</div>
|
|
615
596
|
<div>{p1}</div>
|
|
616
597
|
<div>{p2}</div>
|
|
617
598
|
</>;
|
|
@@ -706,9 +687,9 @@ const items=[1,2,3];
|
|
|
706
687
|
});
|
|
707
688
|
|
|
708
689
|
it('keeps fitting single-child fragments inline and expands non-fitting single-child fragments', async () => {
|
|
709
|
-
const input = `function Test(){const short=<><span>
|
|
690
|
+
const input = `function Test(){const short=<><span>Ready</span></>;const long=<><ReallyLongComponentName first={alpha} second={beta} third={gamma}/></>;}`;
|
|
710
691
|
const expected = `function Test() {
|
|
711
|
-
const short = <><span>
|
|
692
|
+
const short = <><span>Ready</span></>;
|
|
712
693
|
const long = <>
|
|
713
694
|
<ReallyLongComponentName
|
|
714
695
|
first={alpha}
|
|
@@ -723,16 +704,16 @@ const items=[1,2,3];
|
|
|
723
704
|
});
|
|
724
705
|
|
|
725
706
|
it('expands multi-child fragments while keeping fitting openers on the first line', async () => {
|
|
726
|
-
const input = `function Test(){const short=<><div>
|
|
707
|
+
const input = `function Test(){const short=<><div>A</div><div>B</div></>;const thisNameIsRidiculouslyLongEnoughToMissThePrintWidth=<><div>A</div><div>B</div></>;}`;
|
|
727
708
|
const expected = `function Test() {
|
|
728
709
|
const short = <>
|
|
729
|
-
<div>
|
|
730
|
-
<div>
|
|
710
|
+
<div>A</div>
|
|
711
|
+
<div>B</div>
|
|
731
712
|
</>;
|
|
732
713
|
const thisNameIsRidiculouslyLongEnoughToMissThePrintWidth =
|
|
733
714
|
<>
|
|
734
|
-
<div>
|
|
735
|
-
<div>
|
|
715
|
+
<div>A</div>
|
|
716
|
+
<div>B</div>
|
|
736
717
|
</>;
|
|
737
718
|
}`;
|
|
738
719
|
|
|
@@ -816,7 +797,7 @@ const items=[1,2,3];
|
|
|
816
797
|
*/
|
|
817
798
|
const format = async (code, options = {}) => {
|
|
818
799
|
return await prettier.format(code, {
|
|
819
|
-
parser: '
|
|
800
|
+
parser: 'tsrx',
|
|
820
801
|
plugins: [join(__dirname, 'index.js')],
|
|
821
802
|
...options,
|
|
822
803
|
});
|
|
@@ -829,7 +810,7 @@ const items=[1,2,3];
|
|
|
829
810
|
*/
|
|
830
811
|
const formatWithCursorHelper = async (code, options) =>
|
|
831
812
|
await prettier.formatWithCursor(code, {
|
|
832
|
-
parser: '
|
|
813
|
+
parser: 'tsrx',
|
|
833
814
|
plugins: [join(__dirname, 'index.js')],
|
|
834
815
|
...options,
|
|
835
816
|
});
|
|
@@ -882,13 +863,14 @@ const items=[1,2,3];
|
|
|
882
863
|
});
|
|
883
864
|
|
|
884
865
|
it('registers .tsrx as a supported file extension', () => {
|
|
885
|
-
const
|
|
866
|
+
const tsrx_language = languages?.[0];
|
|
886
867
|
|
|
887
|
-
if (!
|
|
888
|
-
throw new Error('Missing
|
|
868
|
+
if (!tsrx_language) {
|
|
869
|
+
throw new Error('Missing TSRX language metadata');
|
|
889
870
|
}
|
|
890
871
|
|
|
891
|
-
expect(
|
|
872
|
+
expect(tsrx_language.extensions).toContain('.tsrx');
|
|
873
|
+
expect(tsrx_language.parsers).toContain('tsrx');
|
|
892
874
|
});
|
|
893
875
|
|
|
894
876
|
it('should format a simple component', async () => {
|
|
@@ -966,23 +948,12 @@ const items=[1,2,3];
|
|
|
966
948
|
expect(result).toBeWithNewline(expected);
|
|
967
949
|
});
|
|
968
950
|
|
|
969
|
-
it('should format a function with a dynamic function using props member access', async () => {
|
|
970
|
-
const expected = `function Card(props) {
|
|
971
|
-
<div class="card">
|
|
972
|
-
<@props.children />
|
|
973
|
-
</div>
|
|
974
|
-
}`;
|
|
975
|
-
|
|
976
|
-
const result = await format(expected, { singleQuote: true });
|
|
977
|
-
expect(result).toBeWithNewline(expected);
|
|
978
|
-
});
|
|
979
|
-
|
|
980
951
|
it('should respect print width when using ternary expressions', async () => {
|
|
981
952
|
const input = `function printMemberExpressionSimple(node, options, computed = false) {
|
|
982
953
|
if (node.type === 'MemberExpression') {
|
|
983
954
|
const prop = node.computed
|
|
984
|
-
? (node.
|
|
985
|
-
: (node.
|
|
955
|
+
? (node.optional ? '?.[' : '[') + printMemberExpressionSimple(node.property, options, node.computed) + ']'
|
|
956
|
+
: (node.optional ? '?.' : '.') + printMemberExpressionSimple(node.property, options, node.computed);
|
|
986
957
|
}
|
|
987
958
|
}`;
|
|
988
959
|
|
|
@@ -993,14 +964,14 @@ const items=[1,2,3];
|
|
|
993
964
|
) {
|
|
994
965
|
if (node.type === 'MemberExpression') {
|
|
995
966
|
const prop = node.computed
|
|
996
|
-
? (node.
|
|
967
|
+
? (node.optional ? '?.[' : '[') +
|
|
997
968
|
printMemberExpressionSimple(
|
|
998
969
|
node.property,
|
|
999
970
|
options,
|
|
1000
971
|
node.computed,
|
|
1001
972
|
) +
|
|
1002
973
|
']'
|
|
1003
|
-
: (node.
|
|
974
|
+
: (node.optional ? '?.' : '.') +
|
|
1004
975
|
printMemberExpressionSimple(
|
|
1005
976
|
node.property,
|
|
1006
977
|
options,
|
|
@@ -1398,11 +1369,11 @@ export function Test({ a, b }: Props) {}`;
|
|
|
1398
1369
|
|
|
1399
1370
|
it('should not force attribute-less elements to break with singleAttributePerLine', async () => {
|
|
1400
1371
|
const input = `function One() @{
|
|
1401
|
-
<div>
|
|
1372
|
+
<div>Hello</div>
|
|
1402
1373
|
}`;
|
|
1403
1374
|
|
|
1404
1375
|
const expected = `function One() @{
|
|
1405
|
-
<div>
|
|
1376
|
+
<div>Hello</div>
|
|
1406
1377
|
}`;
|
|
1407
1378
|
|
|
1408
1379
|
const result = await format(input, {
|
|
@@ -1462,18 +1433,6 @@ export function Test({ a, b }: Props) {}`;
|
|
|
1462
1433
|
expect(result).toBeWithNewline(expected);
|
|
1463
1434
|
});
|
|
1464
1435
|
|
|
1465
|
-
it('should not strip @ from dynamic @tag', async () => {
|
|
1466
|
-
const expected = `export function Four() {
|
|
1467
|
-
let tag = track('div');
|
|
1468
|
-
|
|
1469
|
-
<@tag {href} {...props}>
|
|
1470
|
-
<@children />
|
|
1471
|
-
</@tag>
|
|
1472
|
-
}`;
|
|
1473
|
-
const result = await format(expected, { singleQuote: true, printWidth: 100 });
|
|
1474
|
-
expect(result).toBeWithNewline(expected);
|
|
1475
|
-
});
|
|
1476
|
-
|
|
1477
1436
|
it('should not include a comma after the last rest parameter', async () => {
|
|
1478
1437
|
const expected = `function Foo({
|
|
1479
1438
|
lorem,
|
|
@@ -1490,15 +1449,6 @@ export function Test({ a, b }: Props) {}`;
|
|
|
1490
1449
|
expect(result).toBeWithNewline(expected);
|
|
1491
1450
|
});
|
|
1492
1451
|
|
|
1493
|
-
it('should not strip @ from dynamic self-closing components', async () => {
|
|
1494
|
-
const expected = `function App() {
|
|
1495
|
-
<@ripple_object.tracked_basic />
|
|
1496
|
-
}`;
|
|
1497
|
-
|
|
1498
|
-
const result = await format(expected, { singleQuote: true, printWidth: 100 });
|
|
1499
|
-
expect(result).toBeWithNewline(expected);
|
|
1500
|
-
});
|
|
1501
|
-
|
|
1502
1452
|
it('keeps a new line between comments above and code if one is present', async () => {
|
|
1503
1453
|
const expected = `// comment
|
|
1504
1454
|
|
|
@@ -5604,7 +5554,7 @@ render(App);`;
|
|
|
5604
5554
|
expect(result).toBeWithNewline(expected);
|
|
5605
5555
|
});
|
|
5606
5556
|
|
|
5607
|
-
it('should preserve the order of try / pending / catch
|
|
5557
|
+
it('should preserve the order of try / pending / catch blocks', async () => {
|
|
5608
5558
|
const expected = `function Test() {
|
|
5609
5559
|
let items: RippleArray<string> | null = null;
|
|
5610
5560
|
let error: string | null = null;
|
|
@@ -5622,8 +5572,6 @@ render(App);`;
|
|
|
5622
5572
|
<div>{'Loading...'}</div>
|
|
5623
5573
|
} @catch (e) {
|
|
5624
5574
|
error = (e as Error).message;
|
|
5625
|
-
} finally {
|
|
5626
|
-
<div>finally block</div>
|
|
5627
5575
|
};
|
|
5628
5576
|
}`;
|
|
5629
5577
|
|