@kaizen/components 1.69.1 → 1.70.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/codemods/migrateBrandMomentMoodToVariant/index.ts +5 -3
- package/codemods/migrateBrandMomentMoodToVariant/transformBrandMomentMoodToVariant.spec.ts +16 -5
- package/codemods/migrateCardVariantToColor/index.ts +5 -3
- package/codemods/migrateCardVariantToColor/transformCardVariantToColor.spec.ts +16 -5
- package/codemods/migrateConfirmationModalMoodsToVariant/index.ts +3 -1
- package/codemods/migrateConfirmationModalMoodsToVariant/transformConfirmationModalMoodsToVariant.spec.ts +27 -44
- package/codemods/migrateEmptyStateIllustrationTypeToVariant/index.ts +5 -3
- package/codemods/migrateEmptyStateIllustrationTypeToVariant/transformEmptyStateIllustrationTypeToVariant.spec.ts +16 -5
- package/codemods/migrateGlobalNotificationTypeToVariant/index.ts +5 -3
- package/codemods/migrateInformationTileMoodToVariant/index.ts +5 -3
- package/codemods/migrateInformationTileMoodToVariant/transformInformationTileMoodToVariant.spec.ts +16 -7
- package/codemods/migrateInlineNotificationTypeToVariant/index.ts +5 -3
- package/codemods/migrateMultiActionTileMoodToVariant/index.ts +5 -3
- package/codemods/migrateMultiActionTileMoodToVariant/transformMultiActionTileMoodToVariant.spec.ts +16 -7
- package/codemods/migrateNotificationTypeToVariant/migrateNotificationTypeToVariant.spec.ts +42 -43
- package/codemods/migrateProgressBarMoodToColor/index.ts +5 -3
- package/codemods/migrateProgressBarMoodToColor/transformProgressBarMoodToColor.spec.ts +16 -5
- package/codemods/migrateToastNotificationTypeToVariant/index.ts +6 -4
- package/codemods/migrateWellVariantToColor/index.ts +5 -3
- package/codemods/migrateWellVariantToColor/transformWellVariantToColor.spec.ts +26 -68
- package/codemods/migrateWellVariantToColor/transformWellVariantToColor.ts +10 -4
- package/codemods/removeInputEditModalMood/index.ts +3 -1
- package/codemods/removeInputEditModalMood/removeInputEditModalMood.spec.ts +23 -20
- package/codemods/removePopoverVariant/index.ts +1 -1
- package/codemods/removePopoverVariant/removePopoverVariant.spec.ts +23 -25
- package/codemods/upgradeIconV1/index.ts +2 -17
- package/codemods/upgradeIconV1/upgradeIconV1.spec.ts +18 -120
- package/codemods/upgradeIconV1/upgradeIconV1.ts +21 -28
- package/codemods/utils/__snapshots__/transformSource.spec.ts.snap +0 -10
- package/codemods/utils/getKaioTagName.spec.ts +167 -23
- package/codemods/utils/getKaioTagName.ts +71 -35
- package/codemods/utils/migrateStringProp.spec.ts +16 -5
- package/codemods/utils/migrateStringProp.ts +10 -3
- package/codemods/utils/removeProps.spec.ts +26 -25
- package/codemods/utils/removeProps.ts +10 -3
- package/codemods/utils/transformComponentsInDir.ts +40 -13
- package/codemods/utils/transformSource.spec.ts +1 -27
- package/codemods/utils/transformSource.ts +0 -26
- package/codemods/utils/updateKaioImports.ts +2 -0
- package/dist/cjs/LinkButton/LinkButton.cjs +59 -0
- package/dist/cjs/LinkButton/LinkButton.module.css.cjs +6 -0
- package/dist/cjs/__rc__/Button/Button.module.css.cjs +1 -1
- package/dist/cjs/index.cjs +2 -0
- package/dist/esm/LinkButton/LinkButton.mjs +53 -0
- package/dist/esm/LinkButton/LinkButton.module.css.mjs +4 -0
- package/dist/esm/__rc__/Button/Button.module.css.mjs +1 -1
- package/dist/esm/index.mjs +1 -0
- package/dist/styles.css +3259 -3229
- package/dist/types/LinkButton/LinkButton.d.ts +11 -0
- package/dist/types/LinkButton/index.d.ts +1 -0
- package/dist/types/__rc__/Button/Button.d.ts +6 -5
- package/dist/types/index.d.ts +1 -2
- package/package.json +1 -1
- package/src/LinkButton/LinkButton.module.css +4 -0
- package/src/LinkButton/LinkButton.tsx +71 -0
- package/src/LinkButton/_docs/LinkButton--api-specification.mdx +281 -0
- package/src/LinkButton/_docs/LinkButton--usage-guidelines.mdx +29 -0
- package/src/LinkButton/_docs/LinkButton.doc.stories.tsx +136 -0
- package/src/LinkButton/_docs/LinkButton.spec.stories.tsx +80 -0
- package/src/LinkButton/_docs/LinkButton.stickersheet.stories.tsx +130 -0
- package/src/LinkButton/index.ts +1 -0
- package/src/__rc__/Button/Button.module.css +44 -19
- package/src/__rc__/Button/Button.tsx +8 -4
- package/src/__rc__/Button/_docs/Button--api-specification.mdx +5 -5
- package/src/__rc__/Button/_docs/Button--usage-guidelines.mdx +2 -5
- package/src/index.ts +1 -2
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import ts from 'typescript'
|
|
2
2
|
import {
|
|
3
|
+
getKaioTagName,
|
|
3
4
|
setImportToAdd,
|
|
4
5
|
setImportToRemove,
|
|
5
6
|
updateKaioImports,
|
|
6
|
-
type
|
|
7
|
+
type TagImportAttributesMap,
|
|
7
8
|
type UpdateKaioImportsArgs,
|
|
8
9
|
} from '../utils'
|
|
9
10
|
import { getNewIconPropsFromOldIconName } from './getNewIconPropsFromOldIconName'
|
|
@@ -11,56 +12,51 @@ import { transformCaMonogramIconToBrand } from './transformCaMonogramIconToBrand
|
|
|
11
12
|
import { transformIcon } from './transformIcon'
|
|
12
13
|
import { transformSpinnerIconToLoadingSpinner } from './transformSpinnerIconToLoadingSpinner'
|
|
13
14
|
|
|
14
|
-
const reverseStringMap = <Key extends string, Value extends string>(
|
|
15
|
-
map: Map<Key, Value>,
|
|
16
|
-
): Map<Value, Key> => {
|
|
17
|
-
const reverseMap = new Map<Value, Key>()
|
|
18
|
-
map.forEach((value, key) => reverseMap.set(value, key))
|
|
19
|
-
return reverseMap
|
|
20
|
-
}
|
|
21
|
-
|
|
22
15
|
export const upgradeIconV1 =
|
|
23
|
-
(
|
|
16
|
+
(tagsMap: TagImportAttributesMap): ts.TransformerFactory<ts.SourceFile> =>
|
|
24
17
|
(context) =>
|
|
25
18
|
(rootNode) => {
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
const kaioTagNames = tagNames.get(oldImportSource)
|
|
29
|
-
if (!kaioTagNames) return rootNode
|
|
19
|
+
const importedBrandTagName = getKaioTagName(rootNode, 'Brand')
|
|
20
|
+
const importedLoadingSpinnerTagName = getKaioTagName(rootNode, 'LoadingSpinner')
|
|
30
21
|
|
|
31
|
-
const componentToAliasMap = reverseStringMap(kaioTagNames)
|
|
32
22
|
const importsToRemove = new Map() satisfies UpdateKaioImportsArgs['importsToRemove']
|
|
33
23
|
const importsToAdd = new Map() satisfies UpdateKaioImportsArgs['importsToAdd']
|
|
34
24
|
|
|
35
25
|
const visit = (node: ts.Node): ts.Node => {
|
|
36
26
|
if (ts.isJsxOpeningElement(node) || ts.isJsxSelfClosingElement(node)) {
|
|
37
27
|
const tagName = node.tagName.getText()
|
|
38
|
-
const
|
|
28
|
+
const tagImportAttributes = tagsMap.get(tagName)
|
|
29
|
+
|
|
30
|
+
if (!tagImportAttributes) return node
|
|
31
|
+
|
|
32
|
+
const kaioComponentName = tagImportAttributes.originalName
|
|
33
|
+
const oldImportSource = tagImportAttributes.importModuleName
|
|
39
34
|
|
|
40
35
|
if (kaioComponentName === 'CaMonogramIcon') {
|
|
41
36
|
setImportToRemove(importsToRemove, oldImportSource, kaioComponentName)
|
|
42
|
-
const alias = componentToAliasMap.get('Brand')!
|
|
43
37
|
|
|
44
|
-
if (!
|
|
38
|
+
if (!importedBrandTagName) {
|
|
45
39
|
setImportToAdd(importsToAdd, '@kaizen/components', {
|
|
46
40
|
componentName: 'Brand',
|
|
47
|
-
alias:
|
|
41
|
+
alias: importedBrandTagName !== 'Brand' ? importedBrandTagName : undefined,
|
|
48
42
|
})
|
|
49
43
|
}
|
|
50
|
-
return transformCaMonogramIconToBrand(node,
|
|
44
|
+
return transformCaMonogramIconToBrand(node, importedBrandTagName)
|
|
51
45
|
}
|
|
52
46
|
|
|
53
47
|
if (kaioComponentName === 'SpinnerIcon') {
|
|
54
48
|
setImportToRemove(importsToRemove, oldImportSource, kaioComponentName)
|
|
55
|
-
const alias = componentToAliasMap.get('LoadingSpinner')!
|
|
56
49
|
|
|
57
|
-
if (!
|
|
50
|
+
if (!importedLoadingSpinnerTagName) {
|
|
58
51
|
setImportToAdd(importsToAdd, '@kaizen/components', {
|
|
59
52
|
componentName: 'LoadingSpinner',
|
|
60
|
-
alias:
|
|
53
|
+
alias:
|
|
54
|
+
importedLoadingSpinnerTagName !== 'LoadingSpinner'
|
|
55
|
+
? importedLoadingSpinnerTagName
|
|
56
|
+
: undefined,
|
|
61
57
|
})
|
|
62
58
|
}
|
|
63
|
-
return transformSpinnerIconToLoadingSpinner(node,
|
|
59
|
+
return transformSpinnerIconToLoadingSpinner(node, importedLoadingSpinnerTagName)
|
|
64
60
|
}
|
|
65
61
|
|
|
66
62
|
if (kaioComponentName) {
|
|
@@ -83,8 +79,5 @@ export const upgradeIconV1 =
|
|
|
83
79
|
|
|
84
80
|
const node = ts.visitNode(rootNode, visit)
|
|
85
81
|
|
|
86
|
-
return updateKaioImports({
|
|
87
|
-
importsToRemove: importsToRemove.size > 0 ? importsToRemove : undefined,
|
|
88
|
-
importsToAdd: importsToAdd.size > 0 ? importsToAdd : undefined,
|
|
89
|
-
})(context)(node as ts.SourceFile)
|
|
82
|
+
return updateKaioImports({ importsToRemove, importsToAdd })(context)(node as ts.SourceFile)
|
|
90
83
|
}
|
|
@@ -9,13 +9,3 @@ export const KaioComponent = (): JSX.Element => <Pancakes topping="jam"/>;
|
|
|
9
9
|
|
|
10
10
|
"
|
|
11
11
|
`;
|
|
12
|
-
|
|
13
|
-
exports[`transformSourceForTagName > updates the value of Pancakes topping to jam 1`] = `
|
|
14
|
-
"import React from 'react';
|
|
15
|
-
// @ts-ignore
|
|
16
|
-
import { Pancakes } from '@kaizen/components';
|
|
17
|
-
|
|
18
|
-
export const KaioComponent = (): JSX.Element => <Pancakes topping="jam"/>;
|
|
19
|
-
|
|
20
|
-
"
|
|
21
|
-
`;
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { parseJsx } from '../__tests__/utils'
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
getKaioTagName,
|
|
4
|
+
getKaioTagNamesMapByComponentName,
|
|
5
|
+
getKaioTagNamesMapByPattern,
|
|
6
|
+
} from './getKaioTagName'
|
|
3
7
|
|
|
4
|
-
describe('getKaioTagName', () => {
|
|
8
|
+
describe('getKaioTagName()', () => {
|
|
5
9
|
it('returns the import name if it matches the target specifier', () => {
|
|
6
10
|
const input = parseJsx('import { Well } from "@kaizen/components"')
|
|
7
11
|
const tagName = getKaioTagName(input, 'Well')
|
|
@@ -21,61 +25,201 @@ describe('getKaioTagName', () => {
|
|
|
21
25
|
})
|
|
22
26
|
})
|
|
23
27
|
|
|
24
|
-
describe('
|
|
25
|
-
it('returns
|
|
28
|
+
describe('getKaioTagNamesMapByComponentName()', () => {
|
|
29
|
+
it('returns import attributes that match the component name', () => {
|
|
30
|
+
const input = parseJsx('import { Button } from "@kaizen/components"')
|
|
31
|
+
const tagNames = getKaioTagNamesMapByComponentName(input, ['Button'])
|
|
32
|
+
expect(tagNames).toEqual(
|
|
33
|
+
new Map([
|
|
34
|
+
[
|
|
35
|
+
'Button',
|
|
36
|
+
{
|
|
37
|
+
importModuleName: '@kaizen/components',
|
|
38
|
+
tagName: 'Button',
|
|
39
|
+
originalName: 'Button',
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
]),
|
|
43
|
+
)
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
it('returns import attributes that matches the component name when an alias exists', () => {
|
|
47
|
+
const input = parseJsx('import { Button as KzButton } from "@kaizen/components"')
|
|
48
|
+
const tagNames = getKaioTagNamesMapByComponentName(input, ['Button'])
|
|
49
|
+
expect(tagNames).toEqual(
|
|
50
|
+
new Map([
|
|
51
|
+
[
|
|
52
|
+
'KzButton',
|
|
53
|
+
{
|
|
54
|
+
importModuleName: '@kaizen/components',
|
|
55
|
+
tagName: 'KzButton',
|
|
56
|
+
originalName: 'Button',
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
]),
|
|
60
|
+
)
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
it('returns import attributes from different KAIO imports', () => {
|
|
64
|
+
const input = parseJsx(`
|
|
65
|
+
import { Button as KzButton } from "@kaizen/components"
|
|
66
|
+
import { Button as FutureButton } from "@kaizen/components/future"
|
|
67
|
+
`)
|
|
68
|
+
const tagNames = getKaioTagNamesMapByComponentName(input, ['Button'])
|
|
69
|
+
expect(tagNames).toEqual(
|
|
70
|
+
new Map([
|
|
71
|
+
[
|
|
72
|
+
'KzButton',
|
|
73
|
+
{
|
|
74
|
+
importModuleName: '@kaizen/components',
|
|
75
|
+
tagName: 'KzButton',
|
|
76
|
+
originalName: 'Button',
|
|
77
|
+
},
|
|
78
|
+
],
|
|
79
|
+
[
|
|
80
|
+
'FutureButton',
|
|
81
|
+
{
|
|
82
|
+
importModuleName: '@kaizen/components/future',
|
|
83
|
+
tagName: 'FutureButton',
|
|
84
|
+
originalName: 'Button',
|
|
85
|
+
},
|
|
86
|
+
],
|
|
87
|
+
]),
|
|
88
|
+
)
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
it('returns import attributes for multiple components', () => {
|
|
92
|
+
const input = parseJsx(`
|
|
93
|
+
import { Button, IconButton } from "@kaizen/components"
|
|
94
|
+
`)
|
|
95
|
+
const tagNames = getKaioTagNamesMapByComponentName(input, ['Button', 'IconButton'])
|
|
96
|
+
expect(tagNames).toEqual(
|
|
97
|
+
new Map([
|
|
98
|
+
[
|
|
99
|
+
'Button',
|
|
100
|
+
{
|
|
101
|
+
importModuleName: '@kaizen/components',
|
|
102
|
+
tagName: 'Button',
|
|
103
|
+
originalName: 'Button',
|
|
104
|
+
},
|
|
105
|
+
],
|
|
106
|
+
[
|
|
107
|
+
'IconButton',
|
|
108
|
+
{
|
|
109
|
+
importModuleName: '@kaizen/components',
|
|
110
|
+
tagName: 'IconButton',
|
|
111
|
+
originalName: 'IconButton',
|
|
112
|
+
},
|
|
113
|
+
],
|
|
114
|
+
]),
|
|
115
|
+
)
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
it('returns undefined if there is no exact match component name', () => {
|
|
119
|
+
const input = parseJsx(`
|
|
120
|
+
import { IconButton } from "@kaizen/components"
|
|
121
|
+
`)
|
|
122
|
+
const tagNames = getKaioTagNamesMapByComponentName(input, ['Button'])
|
|
123
|
+
expect(tagNames).toBe(undefined)
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
it('returns undefined if there is no match in KAIO', () => {
|
|
127
|
+
const input = parseJsx(`
|
|
128
|
+
import { Well } from "@kaizen/components"
|
|
129
|
+
import { Button } from "@kaizen/button"
|
|
130
|
+
`)
|
|
131
|
+
const tagNames = getKaioTagNamesMapByComponentName(input, ['Button'])
|
|
132
|
+
expect(tagNames).toBe(undefined)
|
|
133
|
+
})
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
describe('getKaioTagNamesMapByPattern()', () => {
|
|
137
|
+
it('returns import attributes if it matches the regex pattern', () => {
|
|
26
138
|
const input = parseJsx('import { AddIcon, ArrowDownIcon, Well } from "@kaizen/components"')
|
|
27
|
-
const tagNames =
|
|
139
|
+
const tagNames = getKaioTagNamesMapByPattern(input, 'Icon$')
|
|
28
140
|
expect(tagNames).toEqual(
|
|
29
141
|
new Map([
|
|
30
142
|
[
|
|
31
|
-
'
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
143
|
+
'AddIcon',
|
|
144
|
+
{
|
|
145
|
+
importModuleName: '@kaizen/components',
|
|
146
|
+
tagName: 'AddIcon',
|
|
147
|
+
originalName: 'AddIcon',
|
|
148
|
+
},
|
|
149
|
+
],
|
|
150
|
+
[
|
|
151
|
+
'ArrowDownIcon',
|
|
152
|
+
{
|
|
153
|
+
importModuleName: '@kaizen/components',
|
|
154
|
+
tagName: 'ArrowDownIcon',
|
|
155
|
+
originalName: 'ArrowDownIcon',
|
|
156
|
+
},
|
|
36
157
|
],
|
|
37
158
|
]),
|
|
38
159
|
)
|
|
39
160
|
})
|
|
40
161
|
|
|
41
|
-
it('returns
|
|
162
|
+
it('returns import attributes that matches the regex pattern when an alias exists', () => {
|
|
42
163
|
const input = parseJsx(
|
|
43
164
|
'import { AddIcon as KzAddIcon, ArrowDownIcon, Well } from "@kaizen/components"',
|
|
44
165
|
)
|
|
45
|
-
const tagNames =
|
|
166
|
+
const tagNames = getKaioTagNamesMapByPattern(input, 'Icon$')
|
|
46
167
|
expect(tagNames).toEqual(
|
|
47
168
|
new Map([
|
|
48
169
|
[
|
|
49
|
-
'
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
170
|
+
'KzAddIcon',
|
|
171
|
+
{
|
|
172
|
+
importModuleName: '@kaizen/components',
|
|
173
|
+
tagName: 'KzAddIcon',
|
|
174
|
+
originalName: 'AddIcon',
|
|
175
|
+
},
|
|
176
|
+
],
|
|
177
|
+
[
|
|
178
|
+
'ArrowDownIcon',
|
|
179
|
+
{
|
|
180
|
+
importModuleName: '@kaizen/components',
|
|
181
|
+
tagName: 'ArrowDownIcon',
|
|
182
|
+
originalName: 'ArrowDownIcon',
|
|
183
|
+
},
|
|
54
184
|
],
|
|
55
185
|
]),
|
|
56
186
|
)
|
|
57
187
|
})
|
|
58
188
|
|
|
59
|
-
it('returns
|
|
189
|
+
it('returns import attributes from different KAIO imports', () => {
|
|
60
190
|
const input = parseJsx(`
|
|
61
191
|
import { AddIcon, Well } from "@kaizen/components"
|
|
62
192
|
import { Icon } from "@kaizen/components/future"
|
|
63
193
|
`)
|
|
64
|
-
const tagNames =
|
|
194
|
+
const tagNames = getKaioTagNamesMapByPattern(input, 'Icon$')
|
|
65
195
|
expect(tagNames).toEqual(
|
|
66
196
|
new Map([
|
|
67
|
-
[
|
|
68
|
-
|
|
197
|
+
[
|
|
198
|
+
'AddIcon',
|
|
199
|
+
{
|
|
200
|
+
importModuleName: '@kaizen/components',
|
|
201
|
+
tagName: 'AddIcon',
|
|
202
|
+
originalName: 'AddIcon',
|
|
203
|
+
},
|
|
204
|
+
],
|
|
205
|
+
[
|
|
206
|
+
'Icon',
|
|
207
|
+
{
|
|
208
|
+
importModuleName: '@kaizen/components/future',
|
|
209
|
+
tagName: 'Icon',
|
|
210
|
+
originalName: 'Icon',
|
|
211
|
+
},
|
|
212
|
+
],
|
|
69
213
|
]),
|
|
70
214
|
)
|
|
71
215
|
})
|
|
72
216
|
|
|
73
|
-
it('returns undefined if there is no match to the
|
|
217
|
+
it('returns undefined if there is no match to the regex pattern in KAIO', () => {
|
|
74
218
|
const input = parseJsx(`
|
|
75
219
|
import { Well } from "@kaizen/components"
|
|
76
220
|
import { AddIcon } from "@kaizen/icons"
|
|
77
221
|
`)
|
|
78
|
-
const tagNames =
|
|
222
|
+
const tagNames = getKaioTagNamesMapByPattern(input, 'Icon')
|
|
79
223
|
expect(tagNames).toBe(undefined)
|
|
80
224
|
})
|
|
81
225
|
})
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import ts from 'typescript'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
10
|
-
| undefined => {
|
|
3
|
+
type ImportModuleNamedImports = {
|
|
4
|
+
importModuleName: string
|
|
5
|
+
namedImports: ts.NodeArray<ts.ImportSpecifier>
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const getKaioNamedImports = (visitedNode: ts.Node): ImportModuleNamedImports | undefined => {
|
|
11
9
|
if (ts.isImportDeclaration(visitedNode)) {
|
|
12
10
|
const moduleSpecifier = (visitedNode.moduleSpecifier as ts.StringLiteral).text
|
|
13
11
|
if (moduleSpecifier.includes('@kaizen/components')) {
|
|
@@ -72,27 +70,31 @@ export const getKaioTagName = (
|
|
|
72
70
|
return visitNode(node)
|
|
73
71
|
}
|
|
74
72
|
|
|
75
|
-
|
|
76
|
-
//
|
|
77
|
-
|
|
78
|
-
//
|
|
79
|
-
|
|
73
|
+
type TagImportAttributes = {
|
|
74
|
+
// Import module name (eg. `@kaizen/components/future`)
|
|
75
|
+
importModuleName: string
|
|
76
|
+
// Component name or alias
|
|
77
|
+
tagName: string
|
|
78
|
+
// Original component name
|
|
79
|
+
originalName: string
|
|
80
|
+
}
|
|
81
|
+
/** Key is the tag name (component name or alias) */
|
|
82
|
+
export type TagImportAttributesMap = Map<string, TagImportAttributes>
|
|
80
83
|
|
|
81
84
|
/**
|
|
82
|
-
* Recurses through AST to find all the import names or aliases in KAIO that match the provided
|
|
83
|
-
*
|
|
84
|
-
* @returns Map<string, Map<string, string>> | undefined
|
|
85
|
-
* - `Map<string, Map<string, string>>` = Map<importModuleName, Map<tagName, originalName>>
|
|
86
|
-
* - `importModuleName` = the module name of the KAIO import (eg. `@kaizen/components/future`)
|
|
87
|
-
* - `tagName` = the component name or alias (eg. `KaizenWell`)
|
|
88
|
-
* - `originalName` = the original component name (eg. `Well`)
|
|
89
|
-
* - `undefined` no imports that match the target
|
|
85
|
+
* Recurses through AST to find all the import names or aliases in KAIO that exactly match the provided strings.
|
|
90
86
|
*/
|
|
91
|
-
|
|
87
|
+
const getKaioTagNamesMap = (
|
|
92
88
|
node: ts.Node,
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
89
|
+
onFilterAndUpdateTagsMap: (
|
|
90
|
+
kaioNamedImports: ImportModuleNamedImports,
|
|
91
|
+
checkAndUpdateTagsMap: (
|
|
92
|
+
namedImport: ts.ImportSpecifier,
|
|
93
|
+
checkToAddToMap: (originalName: string) => boolean,
|
|
94
|
+
) => void,
|
|
95
|
+
) => void,
|
|
96
|
+
): TagImportAttributesMap | undefined => {
|
|
97
|
+
const tagsMap = new Map() as TagImportAttributesMap
|
|
96
98
|
|
|
97
99
|
const visitNode = (visitedNode: ts.Node): ts.Node | undefined => {
|
|
98
100
|
const kaioNamedImports = getKaioNamedImports(visitedNode)
|
|
@@ -101,23 +103,57 @@ export const getKaioTagNamesByRegex = (
|
|
|
101
103
|
return ts.forEachChild(visitedNode, visitNode)
|
|
102
104
|
}
|
|
103
105
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
const { tagName, originalName } = getNamesFromSpecifier(importSpecifier)
|
|
106
|
+
onFilterAndUpdateTagsMap(kaioNamedImports, (namedImport, checkToAddToMap) => {
|
|
107
|
+
const { originalName, tagName } = getNamesFromSpecifier(namedImport)
|
|
107
108
|
|
|
108
|
-
if (
|
|
109
|
-
|
|
109
|
+
if (checkToAddToMap(originalName)) {
|
|
110
|
+
tagsMap.set(tagName, {
|
|
111
|
+
importModuleName: kaioNamedImports.importModuleName,
|
|
112
|
+
tagName,
|
|
113
|
+
originalName,
|
|
114
|
+
})
|
|
115
|
+
return true
|
|
110
116
|
}
|
|
111
|
-
})
|
|
112
117
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
}
|
|
118
|
+
return false
|
|
119
|
+
})
|
|
116
120
|
|
|
117
121
|
return ts.forEachChild(visitedNode, visitNode)
|
|
118
122
|
}
|
|
119
123
|
|
|
120
124
|
visitNode(node)
|
|
121
125
|
|
|
122
|
-
return
|
|
126
|
+
return tagsMap.size === 0 ? undefined : tagsMap
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Recurses through AST to find all the import names or aliases in KAIO that exactly match the provided strings.
|
|
131
|
+
*/
|
|
132
|
+
export const getKaioTagNamesMapByComponentName = (
|
|
133
|
+
node: ts.Node,
|
|
134
|
+
importSpecifiers: string[],
|
|
135
|
+
): TagImportAttributesMap | undefined => {
|
|
136
|
+
return getKaioTagNamesMap(node, (kaioNamedImports, checkAndUpdateTagsMap) => {
|
|
137
|
+
importSpecifiers.forEach((importSpecifier) => {
|
|
138
|
+
kaioNamedImports.namedImports.find((namedImport) => {
|
|
139
|
+
checkAndUpdateTagsMap(namedImport, (originalName) => originalName === importSpecifier)
|
|
140
|
+
})
|
|
141
|
+
})
|
|
142
|
+
})
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Recurses through AST to find all the import names or aliases in KAIO that match the provided regex pattern.
|
|
147
|
+
*/
|
|
148
|
+
export const getKaioTagNamesMapByPattern = (
|
|
149
|
+
node: ts.Node,
|
|
150
|
+
importSpecifierPattern: RegExp | string,
|
|
151
|
+
): TagImportAttributesMap | undefined => {
|
|
152
|
+
return getKaioTagNamesMap(node, (kaioNamedImports, checkAndUpdateTagsMap) => {
|
|
153
|
+
kaioNamedImports.namedImports.forEach((namedImport) => {
|
|
154
|
+
checkAndUpdateTagsMap(namedImport, (originalName) =>
|
|
155
|
+
new RegExp(importSpecifierPattern).test(originalName),
|
|
156
|
+
)
|
|
157
|
+
})
|
|
158
|
+
})
|
|
123
159
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { parseJsx } from '../__tests__/utils'
|
|
2
|
-
import { printAst,
|
|
2
|
+
import { printAst, transformSource, type TransformSourceArgs } from '../utils'
|
|
3
3
|
import { migrateStringProp } from './migrateStringProp'
|
|
4
4
|
|
|
5
5
|
const transformTopping = (oldValue: string): string => {
|
|
@@ -11,12 +11,23 @@ const transformTopping = (oldValue: string): string => {
|
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
const testMigrateStringProp = (sourceFile:
|
|
15
|
-
|
|
14
|
+
const testMigrateStringProp = (sourceFile: TransformSourceArgs['sourceFile']): string => {
|
|
15
|
+
const tagsMap = new Map([
|
|
16
|
+
[
|
|
17
|
+
'Pancakes',
|
|
18
|
+
{
|
|
19
|
+
importModuleName: '@kaizen/components',
|
|
20
|
+
tagName: 'Pancakes',
|
|
21
|
+
originalName: 'Pancakes',
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
])
|
|
25
|
+
|
|
26
|
+
return transformSource({
|
|
16
27
|
sourceFile,
|
|
17
|
-
|
|
18
|
-
tagName: 'Pancakes',
|
|
28
|
+
transformers: [migrateStringProp('toppingOld', 'toppingNew', transformTopping)(tagsMap)],
|
|
19
29
|
})
|
|
30
|
+
}
|
|
20
31
|
|
|
21
32
|
describe('migrateStringProp()', () => {
|
|
22
33
|
describe('replaces old prop name and value with new prop name and value', () => {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import ts from 'typescript'
|
|
2
|
+
import { type TagImportAttributesMap } from './getKaioTagName'
|
|
2
3
|
import { getPropValueText } from './getPropValueText'
|
|
3
4
|
import { updateJsxElementWithNewProps } from './updateJsxElementWithNewProps'
|
|
4
5
|
|
|
@@ -8,11 +9,17 @@ export const migrateStringProp =
|
|
|
8
9
|
newPropName: string,
|
|
9
10
|
valueTransformer: (value: OldValue) => NewValue,
|
|
10
11
|
) =>
|
|
11
|
-
(
|
|
12
|
-
(
|
|
12
|
+
(tagsMap: TagImportAttributesMap): ts.TransformerFactory<ts.SourceFile> =>
|
|
13
|
+
(context) =>
|
|
14
|
+
(rootNode) => {
|
|
13
15
|
const visit = (node: ts.Node): ts.Node => {
|
|
14
16
|
if (ts.isJsxOpeningElement(node) || ts.isJsxSelfClosingElement(node)) {
|
|
15
|
-
|
|
17
|
+
const tagName = node.tagName.getText()
|
|
18
|
+
const tagImportAttributes = tagsMap.get(tagName)
|
|
19
|
+
|
|
20
|
+
if (!tagImportAttributes) return node
|
|
21
|
+
|
|
22
|
+
if (tagName === tagImportAttributes.tagName) {
|
|
16
23
|
const newAttributes = node.attributes.properties.map((attr) => {
|
|
17
24
|
if (ts.isJsxAttribute(attr) && attr.name.getText() === oldPropName) {
|
|
18
25
|
const oldValue = attr.initializer && getPropValueText(attr.initializer)
|
|
@@ -1,7 +1,28 @@
|
|
|
1
1
|
import { parseJsx } from '../__tests__/utils'
|
|
2
|
-
import { printAst,
|
|
2
|
+
import { printAst, transformSource, type TransformSourceArgs } from '../utils'
|
|
3
3
|
import { removeProps } from './removeProps'
|
|
4
4
|
|
|
5
|
+
const testRemoveProps = (
|
|
6
|
+
sourceFile: TransformSourceArgs['sourceFile'],
|
|
7
|
+
propsToRemove: string[] = ['topping'],
|
|
8
|
+
): string => {
|
|
9
|
+
const tagsMap = new Map([
|
|
10
|
+
[
|
|
11
|
+
'Pancakes',
|
|
12
|
+
{
|
|
13
|
+
importModuleName: '@kaizen/components',
|
|
14
|
+
tagName: 'Pancakes',
|
|
15
|
+
originalName: 'Pancakes',
|
|
16
|
+
},
|
|
17
|
+
],
|
|
18
|
+
])
|
|
19
|
+
|
|
20
|
+
return transformSource({
|
|
21
|
+
sourceFile,
|
|
22
|
+
transformers: [removeProps(propsToRemove)(tagsMap)],
|
|
23
|
+
})
|
|
24
|
+
}
|
|
25
|
+
|
|
5
26
|
describe('removeProps()', () => {
|
|
6
27
|
it('removes single specified prop', () => {
|
|
7
28
|
const inputAst = parseJsx(`
|
|
@@ -10,12 +31,7 @@ describe('removeProps()', () => {
|
|
|
10
31
|
const outputAst = parseJsx(`
|
|
11
32
|
export const TestComponent = () => <Pancakes />
|
|
12
33
|
`)
|
|
13
|
-
|
|
14
|
-
sourceFile: inputAst,
|
|
15
|
-
astTransformer: removeProps(['topping']),
|
|
16
|
-
tagName: 'Pancakes',
|
|
17
|
-
})
|
|
18
|
-
expect(transformed).toEqual(printAst(outputAst))
|
|
34
|
+
expect(testRemoveProps(inputAst)).toEqual(printAst(outputAst))
|
|
19
35
|
})
|
|
20
36
|
|
|
21
37
|
it('removes multiple specified props', () => {
|
|
@@ -25,12 +41,7 @@ describe('removeProps()', () => {
|
|
|
25
41
|
const outputAst = parseJsx(`
|
|
26
42
|
export const TestComponent = () => <Pancakes />
|
|
27
43
|
`)
|
|
28
|
-
|
|
29
|
-
sourceFile: inputAst,
|
|
30
|
-
astTransformer: removeProps(['topping', 'fruit']),
|
|
31
|
-
tagName: 'Pancakes',
|
|
32
|
-
})
|
|
33
|
-
expect(transformed).toEqual(printAst(outputAst))
|
|
44
|
+
expect(testRemoveProps(inputAst, ['topping', 'fruit'])).toEqual(printAst(outputAst))
|
|
34
45
|
})
|
|
35
46
|
|
|
36
47
|
it('handles multiple attributes and removes only specified props', () => {
|
|
@@ -40,12 +51,7 @@ describe('removeProps()', () => {
|
|
|
40
51
|
const outputAst = parseJsx(`
|
|
41
52
|
export const TestComponent = () => <Pancakes id="123"/>
|
|
42
53
|
`)
|
|
43
|
-
|
|
44
|
-
sourceFile: inputAst,
|
|
45
|
-
astTransformer: removeProps(['topping']),
|
|
46
|
-
tagName: 'Pancakes',
|
|
47
|
-
})
|
|
48
|
-
expect(transformed).toBe(printAst(outputAst))
|
|
54
|
+
expect(testRemoveProps(inputAst)).toEqual(printAst(outputAst))
|
|
49
55
|
})
|
|
50
56
|
|
|
51
57
|
it('transforms multiple Pancakess', () => {
|
|
@@ -55,11 +61,6 @@ describe('removeProps()', () => {
|
|
|
55
61
|
const outputAst = parseJsx(`
|
|
56
62
|
export const TestComponent = () => <div><Pancakes /><Pancakes /></div>
|
|
57
63
|
`)
|
|
58
|
-
|
|
59
|
-
sourceFile: inputAst,
|
|
60
|
-
astTransformer: removeProps(['topping']),
|
|
61
|
-
tagName: 'Pancakes',
|
|
62
|
-
})
|
|
63
|
-
expect(transformed).toBe(printAst(outputAst))
|
|
64
|
+
expect(testRemoveProps(inputAst)).toEqual(printAst(outputAst))
|
|
64
65
|
})
|
|
65
66
|
})
|
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
import ts from 'typescript'
|
|
2
|
+
import { type TagImportAttributesMap } from './getKaioTagName'
|
|
2
3
|
import { updateJsxElementWithNewProps } from './updateJsxElementWithNewProps'
|
|
3
4
|
|
|
4
5
|
export const removeProps =
|
|
5
6
|
(propsToRemove: string[]) =>
|
|
6
|
-
(
|
|
7
|
-
(
|
|
7
|
+
(tagsMap: TagImportAttributesMap): ts.TransformerFactory<ts.SourceFile> =>
|
|
8
|
+
(context) =>
|
|
9
|
+
(rootNode) => {
|
|
8
10
|
function visit(node: ts.Node): ts.Node {
|
|
9
11
|
if (ts.isJsxOpeningElement(node) || ts.isJsxSelfClosingElement(node)) {
|
|
10
|
-
|
|
12
|
+
const tagName = node.tagName.getText()
|
|
13
|
+
const tagImportAttributes = tagsMap.get(tagName)
|
|
14
|
+
|
|
15
|
+
if (!tagImportAttributes) return node
|
|
16
|
+
|
|
17
|
+
if (tagName === tagImportAttributes.tagName) {
|
|
11
18
|
const newAttributes = node.attributes.properties.reduce<ts.JsxAttributeLike[]>(
|
|
12
19
|
(acc, attr) => {
|
|
13
20
|
if (ts.isJsxAttribute(attr) && propsToRemove.includes(attr.name.getText())) {
|