@ornikar/kitt-universal 27.5.0 → 27.5.1-canary.4d3ec9b2bbb3371c254ae88141f81bb445a59f73.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/CHANGELOG.md +16 -0
- package/package.json +1 -1
- package/scripts/run-transformers.js +19 -21
- package/scripts/transformers/__testfixtures__/card-modal/basic.input.js +19 -0
- package/scripts/transformers/__testfixtures__/card-modal/basic.output.js +15 -0
- package/scripts/transformers/__testfixtures__/card-modal/withExpressions.input.js +23 -0
- package/scripts/transformers/__testfixtures__/card-modal/withExpressions.output.js +19 -0
- package/scripts/transformers/__testfixtures__/card-modal/wrongOrder.input.js +19 -0
- package/scripts/transformers/__testfixtures__/card-modal/wrongOrder.output.js +15 -0
- package/scripts/transformers/__testfixtures__/fullscreen-modal/basic.input.js +19 -0
- package/scripts/transformers/__testfixtures__/fullscreen-modal/basic.output.js +15 -0
- package/scripts/transformers/__testfixtures__/fullscreen-modal/withExpressions.input.js +23 -0
- package/scripts/transformers/__testfixtures__/fullscreen-modal/withExpressions.output.js +19 -0
- package/scripts/transformers/__testfixtures__/fullscreen-modal/wrongOrder.input.js +19 -0
- package/scripts/transformers/__testfixtures__/fullscreen-modal/wrongOrder.output.js +15 -0
- package/scripts/transformers/__testfixtures__/navigation-modal/basic.input.js +19 -0
- package/scripts/transformers/__testfixtures__/navigation-modal/basic.output.js +15 -0
- package/scripts/transformers/__testfixtures__/navigation-modal/withExpressions.input.js +23 -0
- package/scripts/transformers/__testfixtures__/navigation-modal/withExpressions.output.js +19 -0
- package/scripts/transformers/__testfixtures__/navigation-modal/wrongOrder.input.js +19 -0
- package/scripts/transformers/__testfixtures__/navigation-modal/wrongOrder.output.js +15 -0
- package/scripts/transformers/__tests__/card-modal.test.js +10 -0
- package/scripts/transformers/__tests__/fullscreen-modal.test.js +10 -0
- package/scripts/transformers/__tests__/navigation-modal.test.js +10 -0
- package/scripts/transformers/card-modal.js +136 -0
- package/scripts/transformers/fullscreen-modal.js +138 -0
- package/scripts/transformers/navigation-modal.js +138 -0
- package/scripts/transformers/modals.js +0 -102
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,22 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [27.5.1-canary.4d3ec9b2bbb3371c254ae88141f81bb445a59f73.0](https://github.com/ornikar/kitt/compare/@ornikar/kitt-universal@27.5.0...@ornikar/kitt-universal@27.5.1-canary.4d3ec9b2bbb3371c254ae88141f81bb445a59f73.0) (2025-09-08)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* codemod testing ([912aae9](https://github.com/ornikar/kitt/commit/912aae998fe103930e036c66d6303a0deab3beea))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### Bug Fixes
|
|
15
|
+
|
|
16
|
+
* improve copilot instructions ([4d3ec9b](https://github.com/ornikar/kitt/commit/4d3ec9b2bbb3371c254ae88141f81bb445a59f73))
|
|
17
|
+
* tests fixtures revamp ([cb0161a](https://github.com/ornikar/kitt/commit/cb0161a91981fe2e814cd671cde2eb4ef6933b8c))
|
|
18
|
+
* ts lint ([eac3fc1](https://github.com/ornikar/kitt/commit/eac3fc19869888632e3a59913cf9f700a72b0dad))
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
6
22
|
## [27.5.0](https://github.com/ornikar/kitt/compare/@ornikar/kitt-universal@27.4.0...@ornikar/kitt-universal@27.5.0) (2025-09-03)
|
|
7
23
|
|
|
8
24
|
|
package/package.json
CHANGED
|
@@ -70,29 +70,29 @@ for (const transformFile of transformFiles) {
|
|
|
70
70
|
const source = fs.readFileSync(filePath, 'utf8');
|
|
71
71
|
|
|
72
72
|
try {
|
|
73
|
-
|
|
73
|
+
transformer(
|
|
74
74
|
{ path: filePath, source },
|
|
75
75
|
{ jscodeshift: jscodeshift.withParser('tsx') },
|
|
76
76
|
{ printOptions: { quote: 'single', trailingComma: true } },
|
|
77
|
-
)
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
77
|
+
).then((transformed) => {
|
|
78
|
+
if (typeof transformed === 'string' && transformed !== source) {
|
|
79
|
+
if (isDryRun) {
|
|
80
|
+
console.log(`🔍 ${filePath}`);
|
|
81
|
+
const diff = diffLines(source, transformed);
|
|
82
|
+
diff.forEach((part) => {
|
|
83
|
+
const color = part.added ? '\u001B[32m' : part.removed ? '\u001B[31m' : '\u001B[0m';
|
|
84
|
+
const prefix = part.added ? '+' : part.removed ? '-' : ' ';
|
|
85
|
+
const lines = part.value.split('\n').map((line) => `${prefix} ${line}`);
|
|
86
|
+
process.stdout.write(`${color}${lines.join('\n')}\u001B[0m\n`);
|
|
87
|
+
});
|
|
88
|
+
} else {
|
|
89
|
+
fs.writeFileSync(filePath, transformed, 'utf8');
|
|
90
|
+
console.log(`✅ Updated: ${filePath}`);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
updatedFiles.add(filePath);
|
|
92
94
|
}
|
|
93
|
-
|
|
94
|
-
updatedFiles.add(filePath);
|
|
95
|
-
}
|
|
95
|
+
});
|
|
96
96
|
} catch (error) {
|
|
97
97
|
if (error.message.includes('TSSatisfiesExpression')) {
|
|
98
98
|
console.warn(`⚠️ Skipping unsupported file (satisfies): ${filePath}`);
|
|
@@ -101,8 +101,6 @@ for (const transformFile of transformFiles) {
|
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
103
|
}
|
|
104
|
-
|
|
105
|
-
console.log(`✅ Finished: ${transformFile}\n`);
|
|
106
104
|
}
|
|
107
105
|
|
|
108
106
|
if (isDryRun) {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
function Test() {
|
|
2
|
+
return (
|
|
3
|
+
<CardModal
|
|
4
|
+
header={<CardModal.Header title="With Header and Body" />}
|
|
5
|
+
body={
|
|
6
|
+
<CardModal.Body>
|
|
7
|
+
<LoremIpsum />
|
|
8
|
+
</CardModal.Body>
|
|
9
|
+
}
|
|
10
|
+
footer={
|
|
11
|
+
<CardModal.Footer shouldHandleBottomNotch={false}>
|
|
12
|
+
<Button stretch type="primary">
|
|
13
|
+
With Body and Footer
|
|
14
|
+
</Button>
|
|
15
|
+
</CardModal.Footer>
|
|
16
|
+
}
|
|
17
|
+
/>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
function Test() {
|
|
2
|
+
return (
|
|
3
|
+
<CardModal>
|
|
4
|
+
<CardModal.Header title="With Header and Body" />
|
|
5
|
+
<CardModal.Body>
|
|
6
|
+
<LoremIpsum />
|
|
7
|
+
</CardModal.Body>
|
|
8
|
+
<CardModal.Footer shouldHandleBottomNotch={false}>
|
|
9
|
+
<Button stretch type="primary">
|
|
10
|
+
With Body and Footer
|
|
11
|
+
</Button>
|
|
12
|
+
</CardModal.Footer>
|
|
13
|
+
</CardModal>
|
|
14
|
+
);
|
|
15
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
function Test() {
|
|
2
|
+
return (
|
|
3
|
+
<CardModal
|
|
4
|
+
header={shouldDisplayHeader ? <CardModal.Header title="With Header and Body" /> : null}
|
|
5
|
+
body={
|
|
6
|
+
shouldDisplayBody ? (
|
|
7
|
+
<View>
|
|
8
|
+
<LoremIpsum />
|
|
9
|
+
</View>
|
|
10
|
+
) : null
|
|
11
|
+
}
|
|
12
|
+
footer={
|
|
13
|
+
shouldDisplayFooter ? (
|
|
14
|
+
<CardModal.Footer shouldHandleBottomNotch={false}>
|
|
15
|
+
<Button stretch type="primary">
|
|
16
|
+
With Body and Footer
|
|
17
|
+
</Button>
|
|
18
|
+
</CardModal.Footer>
|
|
19
|
+
) : null
|
|
20
|
+
}
|
|
21
|
+
/>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
function Test() {
|
|
2
|
+
return (
|
|
3
|
+
<CardModal>
|
|
4
|
+
{shouldDisplayHeader ? <CardModal.Header title="With Header and Body" /> : null}
|
|
5
|
+
{shouldDisplayBody ? (
|
|
6
|
+
<View>
|
|
7
|
+
<LoremIpsum />
|
|
8
|
+
</View>
|
|
9
|
+
) : null}
|
|
10
|
+
{shouldDisplayFooter ? (
|
|
11
|
+
<CardModal.Footer shouldHandleBottomNotch={false}>
|
|
12
|
+
<Button stretch type="primary">
|
|
13
|
+
With Body and Footer
|
|
14
|
+
</Button>
|
|
15
|
+
</CardModal.Footer>
|
|
16
|
+
) : null}
|
|
17
|
+
</CardModal>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
function Test() {
|
|
2
|
+
return (
|
|
3
|
+
<CardModal
|
|
4
|
+
footer={
|
|
5
|
+
<CardModal.Footer shouldHandleBottomNotch={false}>
|
|
6
|
+
<Button stretch type="primary">
|
|
7
|
+
With Body and Footer
|
|
8
|
+
</Button>
|
|
9
|
+
</CardModal.Footer>
|
|
10
|
+
}
|
|
11
|
+
header={<CardModal.Header title="With Header and Body" />}
|
|
12
|
+
body={
|
|
13
|
+
<CardModal.Body>
|
|
14
|
+
<LoremIpsum />
|
|
15
|
+
</CardModal.Body>
|
|
16
|
+
}
|
|
17
|
+
/>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
function Test() {
|
|
2
|
+
return (
|
|
3
|
+
<CardModal>
|
|
4
|
+
<CardModal.Header title="With Header and Body" />
|
|
5
|
+
<CardModal.Body>
|
|
6
|
+
<LoremIpsum />
|
|
7
|
+
</CardModal.Body>
|
|
8
|
+
<CardModal.Footer shouldHandleBottomNotch={false}>
|
|
9
|
+
<Button stretch type="primary">
|
|
10
|
+
With Body and Footer
|
|
11
|
+
</Button>
|
|
12
|
+
</CardModal.Footer>
|
|
13
|
+
</CardModal>
|
|
14
|
+
);
|
|
15
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
function Test() {
|
|
2
|
+
return (
|
|
3
|
+
<FullscreenModal
|
|
4
|
+
header={<FullscreenModal.Header title="With Header and Body" />}
|
|
5
|
+
body={
|
|
6
|
+
<FullscreenModal.Body>
|
|
7
|
+
<LoremIpsum />
|
|
8
|
+
</FullscreenModal.Body>
|
|
9
|
+
}
|
|
10
|
+
footer={
|
|
11
|
+
<FullscreenModal.Footer shouldHandleBottomNotch={false}>
|
|
12
|
+
<Button stretch type="primary">
|
|
13
|
+
With Body and Footer
|
|
14
|
+
</Button>
|
|
15
|
+
</FullscreenModal.Footer>
|
|
16
|
+
}
|
|
17
|
+
/>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
function Test() {
|
|
2
|
+
return (
|
|
3
|
+
<FullscreenModal>
|
|
4
|
+
<FullscreenModal.Header title="With Header and Body" />
|
|
5
|
+
<FullscreenModal.Body>
|
|
6
|
+
<LoremIpsum />
|
|
7
|
+
</FullscreenModal.Body>
|
|
8
|
+
<FullscreenModal.Footer shouldHandleBottomNotch={false}>
|
|
9
|
+
<Button stretch type="primary">
|
|
10
|
+
With Body and Footer
|
|
11
|
+
</Button>
|
|
12
|
+
</FullscreenModal.Footer>
|
|
13
|
+
</FullscreenModal>
|
|
14
|
+
);
|
|
15
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
function Test() {
|
|
2
|
+
return (
|
|
3
|
+
<FullscreenModal
|
|
4
|
+
header={shouldDisplayHeader ? <FullscreenModal.Header title="With Header and Body" /> : null}
|
|
5
|
+
body={
|
|
6
|
+
shouldDisplayBody ? (
|
|
7
|
+
<View>
|
|
8
|
+
<LoremIpsum />
|
|
9
|
+
</View>
|
|
10
|
+
) : null
|
|
11
|
+
}
|
|
12
|
+
footer={
|
|
13
|
+
shouldDisplayFooter ? (
|
|
14
|
+
<FullscreenModal.Footer shouldHandleBottomNotch={false}>
|
|
15
|
+
<Button stretch type="primary">
|
|
16
|
+
With Body and Footer
|
|
17
|
+
</Button>
|
|
18
|
+
</FullscreenModal.Footer>
|
|
19
|
+
) : null
|
|
20
|
+
}
|
|
21
|
+
/>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
function Test() {
|
|
2
|
+
return (
|
|
3
|
+
<FullscreenModal>
|
|
4
|
+
{shouldDisplayHeader ? <FullscreenModal.Header title="With Header and Body" /> : null}
|
|
5
|
+
{shouldDisplayBody ? (
|
|
6
|
+
<View>
|
|
7
|
+
<LoremIpsum />
|
|
8
|
+
</View>
|
|
9
|
+
) : null}
|
|
10
|
+
{shouldDisplayFooter ? (
|
|
11
|
+
<FullscreenModal.Footer shouldHandleBottomNotch={false}>
|
|
12
|
+
<Button stretch type="primary">
|
|
13
|
+
With Body and Footer
|
|
14
|
+
</Button>
|
|
15
|
+
</FullscreenModal.Footer>
|
|
16
|
+
) : null}
|
|
17
|
+
</FullscreenModal>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
function Test() {
|
|
2
|
+
return (
|
|
3
|
+
<FullscreenModal
|
|
4
|
+
footer={
|
|
5
|
+
<FullscreenModal.Footer shouldHandleBottomNotch={false}>
|
|
6
|
+
<Button stretch type="primary">
|
|
7
|
+
With Body and Footer
|
|
8
|
+
</Button>
|
|
9
|
+
</FullscreenModal.Footer>
|
|
10
|
+
}
|
|
11
|
+
header={<FullscreenModal.Header title="With Header and Body" />}
|
|
12
|
+
body={
|
|
13
|
+
<FullscreenModal.Body>
|
|
14
|
+
<LoremIpsum />
|
|
15
|
+
</FullscreenModal.Body>
|
|
16
|
+
}
|
|
17
|
+
/>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
function Test() {
|
|
2
|
+
return (
|
|
3
|
+
<FullscreenModal>
|
|
4
|
+
<FullscreenModal.Header title="With Header and Body" />
|
|
5
|
+
<FullscreenModal.Body>
|
|
6
|
+
<LoremIpsum />
|
|
7
|
+
</FullscreenModal.Body>
|
|
8
|
+
<FullscreenModal.Footer shouldHandleBottomNotch={false}>
|
|
9
|
+
<Button stretch type="primary">
|
|
10
|
+
With Body and Footer
|
|
11
|
+
</Button>
|
|
12
|
+
</FullscreenModal.Footer>
|
|
13
|
+
</FullscreenModal>
|
|
14
|
+
);
|
|
15
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
function Test() {
|
|
2
|
+
return (
|
|
3
|
+
<NavigationModal
|
|
4
|
+
header={<NavigationModal.Header title="With Header and Body" />}
|
|
5
|
+
body={
|
|
6
|
+
<NavigationModal.Body>
|
|
7
|
+
<LoremIpsum />
|
|
8
|
+
</NavigationModal.Body>
|
|
9
|
+
}
|
|
10
|
+
footer={
|
|
11
|
+
<NavigationModal.Footer shouldHandleBottomNotch={false}>
|
|
12
|
+
<Button stretch type="primary">
|
|
13
|
+
With Body and Footer
|
|
14
|
+
</Button>
|
|
15
|
+
</NavigationModal.Footer>
|
|
16
|
+
}
|
|
17
|
+
/>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
function Test() {
|
|
2
|
+
return (
|
|
3
|
+
<NavigationModal>
|
|
4
|
+
<NavigationModal.Header title="With Header and Body" />
|
|
5
|
+
<NavigationModal.Body>
|
|
6
|
+
<LoremIpsum />
|
|
7
|
+
</NavigationModal.Body>
|
|
8
|
+
<NavigationModal.Footer shouldHandleBottomNotch={false}>
|
|
9
|
+
<Button stretch type="primary">
|
|
10
|
+
With Body and Footer
|
|
11
|
+
</Button>
|
|
12
|
+
</NavigationModal.Footer>
|
|
13
|
+
</NavigationModal>
|
|
14
|
+
);
|
|
15
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
function Test() {
|
|
2
|
+
return (
|
|
3
|
+
<NavigationModal
|
|
4
|
+
header={shouldDisplayHeader ? <NavigationModal.Header title="With Header and Body" /> : null}
|
|
5
|
+
body={
|
|
6
|
+
shouldDisplayBody ? (
|
|
7
|
+
<View>
|
|
8
|
+
<LoremIpsum />
|
|
9
|
+
</View>
|
|
10
|
+
) : null
|
|
11
|
+
}
|
|
12
|
+
footer={
|
|
13
|
+
shouldDisplayFooter ? (
|
|
14
|
+
<NavigationModal.Footer shouldHandleBottomNotch={false}>
|
|
15
|
+
<Button stretch type="primary">
|
|
16
|
+
With Body and Footer
|
|
17
|
+
</Button>
|
|
18
|
+
</NavigationModal.Footer>
|
|
19
|
+
) : null
|
|
20
|
+
}
|
|
21
|
+
/>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
function Test() {
|
|
2
|
+
return (
|
|
3
|
+
<NavigationModal>
|
|
4
|
+
{shouldDisplayHeader ? <NavigationModal.Header title="With Header and Body" /> : null}
|
|
5
|
+
{shouldDisplayBody ? (
|
|
6
|
+
<View>
|
|
7
|
+
<LoremIpsum />
|
|
8
|
+
</View>
|
|
9
|
+
) : null}
|
|
10
|
+
{shouldDisplayFooter ? (
|
|
11
|
+
<NavigationModal.Footer shouldHandleBottomNotch={false}>
|
|
12
|
+
<Button stretch type="primary">
|
|
13
|
+
With Body and Footer
|
|
14
|
+
</Button>
|
|
15
|
+
</NavigationModal.Footer>
|
|
16
|
+
) : null}
|
|
17
|
+
</NavigationModal>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
function Test() {
|
|
2
|
+
return (
|
|
3
|
+
<NavigationModal
|
|
4
|
+
footer={
|
|
5
|
+
<NavigationModal.Footer shouldHandleBottomNotch={false}>
|
|
6
|
+
<Button stretch type="primary">
|
|
7
|
+
With Body and Footer
|
|
8
|
+
</Button>
|
|
9
|
+
</NavigationModal.Footer>
|
|
10
|
+
}
|
|
11
|
+
header={<NavigationModal.Header title="With Header and Body" />}
|
|
12
|
+
body={
|
|
13
|
+
<NavigationModal.Body>
|
|
14
|
+
<LoremIpsum />
|
|
15
|
+
</NavigationModal.Body>
|
|
16
|
+
}
|
|
17
|
+
/>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
function Test() {
|
|
2
|
+
return (
|
|
3
|
+
<NavigationModal>
|
|
4
|
+
<NavigationModal.Header title="With Header and Body" />
|
|
5
|
+
<NavigationModal.Body>
|
|
6
|
+
<LoremIpsum />
|
|
7
|
+
</NavigationModal.Body>
|
|
8
|
+
<NavigationModal.Footer shouldHandleBottomNotch={false}>
|
|
9
|
+
<Button stretch type="primary">
|
|
10
|
+
With Body and Footer
|
|
11
|
+
</Button>
|
|
12
|
+
</NavigationModal.Footer>
|
|
13
|
+
</NavigationModal>
|
|
14
|
+
);
|
|
15
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
jest.autoMockOff();
|
|
4
|
+
const { defineTest } = require('jscodeshift/dist/testUtils');
|
|
5
|
+
|
|
6
|
+
const tests = ['basic', 'withExpressions', 'wrongOrder'];
|
|
7
|
+
|
|
8
|
+
describe('CardModal', () => {
|
|
9
|
+
tests.forEach((test) => defineTest(__dirname, 'card-modal', null, `card-modal/${test}`));
|
|
10
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
jest.autoMockOff();
|
|
4
|
+
const { defineTest } = require('jscodeshift/dist/testUtils');
|
|
5
|
+
|
|
6
|
+
const tests = ['basic', 'withExpressions', 'wrongOrder'];
|
|
7
|
+
|
|
8
|
+
describe('FullscreenModal', () => {
|
|
9
|
+
tests.forEach((test) => defineTest(__dirname, 'fullscreen-modal', null, `fullscreen-modal/${test}`));
|
|
10
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
jest.autoMockOff();
|
|
4
|
+
const { defineTest } = require('jscodeshift/dist/testUtils');
|
|
5
|
+
|
|
6
|
+
const tests = ['basic', 'withExpressions', 'wrongOrder'];
|
|
7
|
+
|
|
8
|
+
describe('NavigationModal', () => {
|
|
9
|
+
tests.forEach((test) => defineTest(__dirname, 'navigation-modal', null, `navigation-modal/${test}`));
|
|
10
|
+
});
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Transform CardModal components from prop-based API to children-based API
|
|
4
|
+
// Converts header, body, and footer props to direct children elements
|
|
5
|
+
|
|
6
|
+
// Use local jscodeshift instance directly
|
|
7
|
+
const jscodeshift = require('jscodeshift');
|
|
8
|
+
const prettier = require('prettier');
|
|
9
|
+
|
|
10
|
+
module.exports = async function transformer(fileInfo, api) {
|
|
11
|
+
// Use the jscodeshift API to parse the file
|
|
12
|
+
const j = api.jscodeshift || jscodeshift;
|
|
13
|
+
|
|
14
|
+
// Parse the source code of the file
|
|
15
|
+
const root = j(fileInfo.source);
|
|
16
|
+
|
|
17
|
+
let hasChanges = false;
|
|
18
|
+
|
|
19
|
+
// ----------- Start of transformer logic
|
|
20
|
+
|
|
21
|
+
// Find all JSX elements with the name CardModal
|
|
22
|
+
root
|
|
23
|
+
.find(j.JSXElement, {
|
|
24
|
+
openingElement: {
|
|
25
|
+
name: {
|
|
26
|
+
name: 'CardModal',
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
})
|
|
30
|
+
.forEach((path) => {
|
|
31
|
+
const element = path.value;
|
|
32
|
+
const openingElement = element.openingElement;
|
|
33
|
+
|
|
34
|
+
// Check if this CardModal has header, body, or footer props
|
|
35
|
+
const headerProp = openingElement.attributes.find(
|
|
36
|
+
(attr) => attr.type === 'JSXAttribute' && attr.name.name === 'header',
|
|
37
|
+
);
|
|
38
|
+
const bodyProp = openingElement.attributes.find(
|
|
39
|
+
(attr) => attr.type === 'JSXAttribute' && attr.name.name === 'body',
|
|
40
|
+
);
|
|
41
|
+
const footerProp = openingElement.attributes.find(
|
|
42
|
+
(attr) => attr.type === 'JSXAttribute' && attr.name.name === 'footer',
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
// Only transform if we have at least one of these props
|
|
46
|
+
if (!headerProp && !bodyProp && !footerProp) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
hasChanges = true;
|
|
51
|
+
|
|
52
|
+
// Create new children array in the correct order: header, body, footer
|
|
53
|
+
const newChildren = [];
|
|
54
|
+
|
|
55
|
+
// Add header child if it exists
|
|
56
|
+
if (headerProp && headerProp.value) {
|
|
57
|
+
if (headerProp.value.type === 'JSXExpressionContainer') {
|
|
58
|
+
const expression = headerProp.value.expression;
|
|
59
|
+
if (expression.type === 'JSXElement') {
|
|
60
|
+
// If it's a direct JSX element, add it as a direct child
|
|
61
|
+
newChildren.push(expression);
|
|
62
|
+
} else {
|
|
63
|
+
// If it's a conditional or other expression, keep it wrapped
|
|
64
|
+
newChildren.push(j.jsxExpressionContainer(expression));
|
|
65
|
+
}
|
|
66
|
+
} else {
|
|
67
|
+
// If it's a direct JSX element, add it directly
|
|
68
|
+
newChildren.push(headerProp.value);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Add body child if it exists
|
|
73
|
+
if (bodyProp && bodyProp.value) {
|
|
74
|
+
if (bodyProp.value.type === 'JSXExpressionContainer') {
|
|
75
|
+
const expression = bodyProp.value.expression;
|
|
76
|
+
if (expression.type === 'JSXElement') {
|
|
77
|
+
// If it's a direct JSX element, add it as a direct child
|
|
78
|
+
newChildren.push(expression);
|
|
79
|
+
} else {
|
|
80
|
+
// If it's a conditional or other expression, keep it wrapped
|
|
81
|
+
newChildren.push(j.jsxExpressionContainer(expression));
|
|
82
|
+
}
|
|
83
|
+
} else {
|
|
84
|
+
// If it's a direct JSX element, add it directly
|
|
85
|
+
newChildren.push(bodyProp.value);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Add footer child if it exists
|
|
90
|
+
if (footerProp && footerProp.value) {
|
|
91
|
+
if (footerProp.value.type === 'JSXExpressionContainer') {
|
|
92
|
+
const expression = footerProp.value.expression;
|
|
93
|
+
if (expression.type === 'JSXElement') {
|
|
94
|
+
// If it's a direct JSX element, add it as a direct child
|
|
95
|
+
newChildren.push(expression);
|
|
96
|
+
} else {
|
|
97
|
+
// If it's a conditional or other expression, keep it wrapped
|
|
98
|
+
newChildren.push(j.jsxExpressionContainer(expression));
|
|
99
|
+
}
|
|
100
|
+
} else {
|
|
101
|
+
// If it's a direct JSX element, add it directly
|
|
102
|
+
newChildren.push(footerProp.value);
|
|
103
|
+
}
|
|
104
|
+
} // Remove the header, body, and footer attributes
|
|
105
|
+
openingElement.attributes = openingElement.attributes.filter((attr) => {
|
|
106
|
+
if (attr.type !== 'JSXAttribute') return true;
|
|
107
|
+
const name = attr.name.name;
|
|
108
|
+
return name !== 'header' && name !== 'body' && name !== 'footer';
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
// Update the element's children
|
|
112
|
+
element.children = newChildren;
|
|
113
|
+
|
|
114
|
+
// If the element was self-closing, make it a regular element
|
|
115
|
+
if (openingElement.selfClosing) {
|
|
116
|
+
openingElement.selfClosing = false;
|
|
117
|
+
element.closingElement = j.jsxClosingElement(j.jsxIdentifier('CardModal'));
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
// ----------- End of transformer logic
|
|
122
|
+
|
|
123
|
+
// Return the modified source code after transformation
|
|
124
|
+
if (!hasChanges) {
|
|
125
|
+
return fileInfo.source;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const output = root.toSource({ quote: 'single' });
|
|
129
|
+
|
|
130
|
+
const prettierConfig = await prettier.resolveConfig(fileInfo.path);
|
|
131
|
+
|
|
132
|
+
return prettier.format(output, {
|
|
133
|
+
...prettierConfig,
|
|
134
|
+
filepath: fileInfo.path,
|
|
135
|
+
});
|
|
136
|
+
};
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Transform FullscreenModal components from prop-based API to children-based API
|
|
4
|
+
// Converts header, body, and footer props to direct children elements
|
|
5
|
+
|
|
6
|
+
// Use local jscodeshift instance directly
|
|
7
|
+
const jscodeshift = require('jscodeshift');
|
|
8
|
+
const prettier = require('prettier');
|
|
9
|
+
|
|
10
|
+
module.exports = async function transformer(fileInfo, api) {
|
|
11
|
+
// Use the jscodeshift API to parse the file
|
|
12
|
+
const j = api.jscodeshift || jscodeshift;
|
|
13
|
+
|
|
14
|
+
// Parse the source code of the file
|
|
15
|
+
const root = j(fileInfo.source);
|
|
16
|
+
|
|
17
|
+
let hasChanges = false;
|
|
18
|
+
|
|
19
|
+
// ----------- Start of transformer logic
|
|
20
|
+
|
|
21
|
+
// Find all JSX elements with the name FullscreenModal
|
|
22
|
+
root
|
|
23
|
+
.find(j.JSXElement, {
|
|
24
|
+
openingElement: {
|
|
25
|
+
name: {
|
|
26
|
+
name: 'FullscreenModal',
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
})
|
|
30
|
+
.forEach((path) => {
|
|
31
|
+
const element = path.value;
|
|
32
|
+
const openingElement = element.openingElement;
|
|
33
|
+
|
|
34
|
+
// Check if this FullscreenModal has header, body, or footer props
|
|
35
|
+
const headerProp = openingElement.attributes.find(
|
|
36
|
+
(attr) => attr.type === 'JSXAttribute' && attr.name.name === 'header',
|
|
37
|
+
);
|
|
38
|
+
const bodyProp = openingElement.attributes.find(
|
|
39
|
+
(attr) => attr.type === 'JSXAttribute' && attr.name.name === 'body',
|
|
40
|
+
);
|
|
41
|
+
const footerProp = openingElement.attributes.find(
|
|
42
|
+
(attr) => attr.type === 'JSXAttribute' && attr.name.name === 'footer',
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
// Only transform if we have at least one of these props
|
|
46
|
+
if (!headerProp && !bodyProp && !footerProp) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
hasChanges = true;
|
|
51
|
+
|
|
52
|
+
// Create new children array in the correct order: header, body, footer
|
|
53
|
+
const newChildren = [];
|
|
54
|
+
|
|
55
|
+
// Add header child if it exists
|
|
56
|
+
if (headerProp && headerProp.value) {
|
|
57
|
+
if (headerProp.value.type === 'JSXExpressionContainer') {
|
|
58
|
+
const expression = headerProp.value.expression;
|
|
59
|
+
if (expression.type === 'JSXElement') {
|
|
60
|
+
// If it's a direct JSX element, add it as a direct child
|
|
61
|
+
newChildren.push(expression);
|
|
62
|
+
} else {
|
|
63
|
+
// If it's a conditional or other expression, keep it wrapped
|
|
64
|
+
newChildren.push(j.jsxExpressionContainer(expression));
|
|
65
|
+
}
|
|
66
|
+
} else {
|
|
67
|
+
// If it's a direct JSX element, add it directly
|
|
68
|
+
newChildren.push(headerProp.value);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Add body child if it exists
|
|
73
|
+
if (bodyProp && bodyProp.value) {
|
|
74
|
+
if (bodyProp.value.type === 'JSXExpressionContainer') {
|
|
75
|
+
const expression = bodyProp.value.expression;
|
|
76
|
+
if (expression.type === 'JSXElement') {
|
|
77
|
+
// If it's a direct JSX element, add it as a direct child
|
|
78
|
+
newChildren.push(expression);
|
|
79
|
+
} else {
|
|
80
|
+
// If it's a conditional or other expression, keep it wrapped
|
|
81
|
+
newChildren.push(j.jsxExpressionContainer(expression));
|
|
82
|
+
}
|
|
83
|
+
} else {
|
|
84
|
+
// If it's a direct JSX element, add it directly
|
|
85
|
+
newChildren.push(bodyProp.value);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Add footer child if it exists
|
|
90
|
+
if (footerProp && footerProp.value) {
|
|
91
|
+
if (footerProp.value.type === 'JSXExpressionContainer') {
|
|
92
|
+
const expression = footerProp.value.expression;
|
|
93
|
+
if (expression.type === 'JSXElement') {
|
|
94
|
+
// If it's a direct JSX element, add it as a direct child
|
|
95
|
+
newChildren.push(expression);
|
|
96
|
+
} else {
|
|
97
|
+
// If it's a conditional or other expression, keep it wrapped
|
|
98
|
+
newChildren.push(j.jsxExpressionContainer(expression));
|
|
99
|
+
}
|
|
100
|
+
} else {
|
|
101
|
+
// If it's a direct JSX element, add it directly
|
|
102
|
+
newChildren.push(footerProp.value);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Remove the header, body, and footer attributes
|
|
107
|
+
openingElement.attributes = openingElement.attributes.filter((attr) => {
|
|
108
|
+
if (attr.type !== 'JSXAttribute') return true;
|
|
109
|
+
const name = attr.name.name;
|
|
110
|
+
return name !== 'header' && name !== 'body' && name !== 'footer';
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
// Update the element's children
|
|
114
|
+
element.children = newChildren;
|
|
115
|
+
|
|
116
|
+
// If the element was self-closing, make it a regular element
|
|
117
|
+
if (openingElement.selfClosing) {
|
|
118
|
+
openingElement.selfClosing = false;
|
|
119
|
+
element.closingElement = j.jsxClosingElement(j.jsxIdentifier('FullscreenModal'));
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
// ----------- End of transformer logic
|
|
124
|
+
|
|
125
|
+
// Return the modified source code after transformation
|
|
126
|
+
if (!hasChanges) {
|
|
127
|
+
return fileInfo.source;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const output = root.toSource({ quote: 'single' });
|
|
131
|
+
|
|
132
|
+
const prettierConfig = await prettier.resolveConfig(fileInfo.path);
|
|
133
|
+
|
|
134
|
+
return prettier.format(output, {
|
|
135
|
+
...prettierConfig,
|
|
136
|
+
filepath: fileInfo.path,
|
|
137
|
+
});
|
|
138
|
+
};
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Transform NavigationModal components from prop-based API to children-based API
|
|
4
|
+
// Converts header, body, and footer props to direct children elements
|
|
5
|
+
|
|
6
|
+
// Use local jscodeshift instance directly
|
|
7
|
+
const jscodeshift = require('jscodeshift');
|
|
8
|
+
const prettier = require('prettier');
|
|
9
|
+
|
|
10
|
+
module.exports = async function transformer(fileInfo, api) {
|
|
11
|
+
// Use the jscodeshift API to parse the file
|
|
12
|
+
const j = api.jscodeshift || jscodeshift;
|
|
13
|
+
|
|
14
|
+
// Parse the source code of the file
|
|
15
|
+
const root = j(fileInfo.source);
|
|
16
|
+
|
|
17
|
+
let hasChanges = false;
|
|
18
|
+
|
|
19
|
+
// ----------- Start of transformer logic
|
|
20
|
+
|
|
21
|
+
// Find all JSX elements with the name NavigationModal
|
|
22
|
+
root
|
|
23
|
+
.find(j.JSXElement, {
|
|
24
|
+
openingElement: {
|
|
25
|
+
name: {
|
|
26
|
+
name: 'NavigationModal',
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
})
|
|
30
|
+
.forEach((path) => {
|
|
31
|
+
const element = path.value;
|
|
32
|
+
const openingElement = element.openingElement;
|
|
33
|
+
|
|
34
|
+
// Check if this NavigationModal has header, body, or footer props
|
|
35
|
+
const headerProp = openingElement.attributes.find(
|
|
36
|
+
(attr) => attr.type === 'JSXAttribute' && attr.name.name === 'header',
|
|
37
|
+
);
|
|
38
|
+
const bodyProp = openingElement.attributes.find(
|
|
39
|
+
(attr) => attr.type === 'JSXAttribute' && attr.name.name === 'body',
|
|
40
|
+
);
|
|
41
|
+
const footerProp = openingElement.attributes.find(
|
|
42
|
+
(attr) => attr.type === 'JSXAttribute' && attr.name.name === 'footer',
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
// Only transform if we have at least one of these props
|
|
46
|
+
if (!headerProp && !bodyProp && !footerProp) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
hasChanges = true;
|
|
51
|
+
|
|
52
|
+
// Create new children array in the correct order: header, body, footer
|
|
53
|
+
const newChildren = [];
|
|
54
|
+
|
|
55
|
+
// Add header child if it exists
|
|
56
|
+
if (headerProp && headerProp.value) {
|
|
57
|
+
if (headerProp.value.type === 'JSXExpressionContainer') {
|
|
58
|
+
const expression = headerProp.value.expression;
|
|
59
|
+
if (expression.type === 'JSXElement') {
|
|
60
|
+
// If it's a direct JSX element, add it as a direct child
|
|
61
|
+
newChildren.push(expression);
|
|
62
|
+
} else {
|
|
63
|
+
// If it's a conditional or other expression, keep it wrapped
|
|
64
|
+
newChildren.push(j.jsxExpressionContainer(expression));
|
|
65
|
+
}
|
|
66
|
+
} else {
|
|
67
|
+
// If it's a direct JSX element, add it directly
|
|
68
|
+
newChildren.push(headerProp.value);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Add body child if it exists
|
|
73
|
+
if (bodyProp && bodyProp.value) {
|
|
74
|
+
if (bodyProp.value.type === 'JSXExpressionContainer') {
|
|
75
|
+
const expression = bodyProp.value.expression;
|
|
76
|
+
if (expression.type === 'JSXElement') {
|
|
77
|
+
// If it's a direct JSX element, add it as a direct child
|
|
78
|
+
newChildren.push(expression);
|
|
79
|
+
} else {
|
|
80
|
+
// If it's a conditional or other expression, keep it wrapped
|
|
81
|
+
newChildren.push(j.jsxExpressionContainer(expression));
|
|
82
|
+
}
|
|
83
|
+
} else {
|
|
84
|
+
// If it's a direct JSX element, add it directly
|
|
85
|
+
newChildren.push(bodyProp.value);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Add footer child if it exists
|
|
90
|
+
if (footerProp && footerProp.value) {
|
|
91
|
+
if (footerProp.value.type === 'JSXExpressionContainer') {
|
|
92
|
+
const expression = footerProp.value.expression;
|
|
93
|
+
if (expression.type === 'JSXElement') {
|
|
94
|
+
// If it's a direct JSX element, add it as a direct child
|
|
95
|
+
newChildren.push(expression);
|
|
96
|
+
} else {
|
|
97
|
+
// If it's a conditional or other expression, keep it wrapped
|
|
98
|
+
newChildren.push(j.jsxExpressionContainer(expression));
|
|
99
|
+
}
|
|
100
|
+
} else {
|
|
101
|
+
// If it's a direct JSX element, add it directly
|
|
102
|
+
newChildren.push(footerProp.value);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Remove the header, body, and footer attributes
|
|
107
|
+
openingElement.attributes = openingElement.attributes.filter((attr) => {
|
|
108
|
+
if (attr.type !== 'JSXAttribute') return true;
|
|
109
|
+
const name = attr.name.name;
|
|
110
|
+
return name !== 'header' && name !== 'body' && name !== 'footer';
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
// Update the element's children
|
|
114
|
+
element.children = newChildren;
|
|
115
|
+
|
|
116
|
+
// If the element was self-closing, make it a regular element
|
|
117
|
+
if (openingElement.selfClosing) {
|
|
118
|
+
openingElement.selfClosing = false;
|
|
119
|
+
element.closingElement = j.jsxClosingElement(j.jsxIdentifier('NavigationModal'));
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
// ----------- End of transformer logic
|
|
124
|
+
|
|
125
|
+
// Return the modified source code after transformation
|
|
126
|
+
if (!hasChanges) {
|
|
127
|
+
return fileInfo.source;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
const output = root.toSource({ quote: 'single' });
|
|
131
|
+
|
|
132
|
+
const prettierConfig = await prettier.resolveConfig(fileInfo.path);
|
|
133
|
+
|
|
134
|
+
return prettier.format(output, {
|
|
135
|
+
...prettierConfig,
|
|
136
|
+
filepath: fileInfo.path,
|
|
137
|
+
});
|
|
138
|
+
};
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/* eslint-disable prefer-destructuring */
|
|
4
|
-
/* eslint-disable unicorn/no-array-method-this-argument */
|
|
5
|
-
|
|
6
|
-
// Use local jscodeshift instance directly
|
|
7
|
-
const jscodeshift = require('jscodeshift');
|
|
8
|
-
|
|
9
|
-
// List of modal component names we want to transform
|
|
10
|
-
const MODAL_COMPONENTS = ['FullscreenModal', 'CardModal', 'NavigationModal'];
|
|
11
|
-
|
|
12
|
-
module.exports = function transformer(fileInfo, api) {
|
|
13
|
-
// Use the jscodeshift API to parse the file
|
|
14
|
-
const j = api.jscodeshift || jscodeshift;
|
|
15
|
-
|
|
16
|
-
// Parse the source code of the file
|
|
17
|
-
const root = j(fileInfo.source);
|
|
18
|
-
|
|
19
|
-
// Iterate over each modal component found in the source code
|
|
20
|
-
MODAL_COMPONENTS.forEach((componentName) => {
|
|
21
|
-
// Find instances of the modal component
|
|
22
|
-
root
|
|
23
|
-
.find(j.JSXElement, {
|
|
24
|
-
openingElement: {
|
|
25
|
-
name: { type: 'JSXIdentifier', name: componentName },
|
|
26
|
-
},
|
|
27
|
-
})
|
|
28
|
-
.forEach((path) => {
|
|
29
|
-
// Get the node (the JSXElement) from the path
|
|
30
|
-
const node = path.node;
|
|
31
|
-
|
|
32
|
-
// Check if the modal component already has children or if it is self-closing
|
|
33
|
-
const hasChildren = Array.isArray(node.children) && node.children.length > 0;
|
|
34
|
-
if (!node.openingElement.selfClosing && hasChildren) {
|
|
35
|
-
// If it already has children, do nothing and skip transformation
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// Extract the attributes from the JSX element (like `header`, `body`, `footer`)
|
|
40
|
-
const attributes = node.openingElement.attributes;
|
|
41
|
-
|
|
42
|
-
// Initialize a map to hold potential new children: header, body, footer
|
|
43
|
-
const newChildrenMap = {
|
|
44
|
-
header: null,
|
|
45
|
-
body: null,
|
|
46
|
-
footer: null,
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
// An array to keep attributes that are not `header`, `body`, or `footer`
|
|
50
|
-
const keptAttributes = [];
|
|
51
|
-
|
|
52
|
-
// Loop over the attributes to check if any match `header`, `body`, or `footer`
|
|
53
|
-
attributes.forEach((attr) => {
|
|
54
|
-
if (
|
|
55
|
-
attr.type === 'JSXAttribute' &&
|
|
56
|
-
attr.name &&
|
|
57
|
-
Object.prototype.hasOwnProperty.call(newChildrenMap, attr.name.name)
|
|
58
|
-
) {
|
|
59
|
-
const key = attr.name.name;
|
|
60
|
-
const value = attr.value;
|
|
61
|
-
|
|
62
|
-
// Check if the value of the attribute is an expression (like a ternary)
|
|
63
|
-
if (value?.type === 'JSXExpressionContainer') {
|
|
64
|
-
const expression = value.expression;
|
|
65
|
-
|
|
66
|
-
// If it's a JSXElement or JSXFragment, keep it as it is
|
|
67
|
-
if (j.JSXElement.check(expression) || j.JSXFragment.check(expression)) {
|
|
68
|
-
newChildrenMap[key] = expression;
|
|
69
|
-
} else {
|
|
70
|
-
// Otherwise, wrap it in an expression container to handle non-JSX expressions
|
|
71
|
-
newChildrenMap[key] = j.jsxExpressionContainer(expression);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
} else {
|
|
75
|
-
// Keep any other attributes (that are not header/body/footer)
|
|
76
|
-
keptAttributes.push(attr);
|
|
77
|
-
}
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
// If no new children were found (no `header`, `body`, or `footer`), do nothing
|
|
81
|
-
if (Object.values(newChildrenMap).every((v) => v === null)) {
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// If the modal component was self-closing, convert it to a regular JSX element with children
|
|
86
|
-
if (node.openingElement.selfClosing) {
|
|
87
|
-
node.openingElement.selfClosing = false;
|
|
88
|
-
node.closingElement = j.jsxClosingElement(j.jsxIdentifier(node.openingElement.name.name));
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// Retain all the other attributes and set the new ones
|
|
92
|
-
node.openingElement.attributes = keptAttributes;
|
|
93
|
-
|
|
94
|
-
// Force the order of children: header → body → footer
|
|
95
|
-
const orderedChildren = Object.values(newChildrenMap).filter(Boolean);
|
|
96
|
-
node.children = orderedChildren;
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
// Return the modified source code after transformation
|
|
101
|
-
return root.toSource({ quote: 'single' });
|
|
102
|
-
};
|