@workday/canvas-kit-codemod 7.1.4 → 7.2.0-427-next.2
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/README.md +41 -5
- package/dist/es6/v5/compoundCard.js +19 -22
- package/dist/es6/v5/getImportRenameMap.js +11 -12
- package/dist/es6/v5/index.js +2 -13
- package/dist/es6/v5/mapTypeTokensToNewHierarchy.js +62 -62
- package/dist/es6/v5/maps.js +2 -2
- package/dist/es6/v5/moveInputProvider.js +6 -6
- package/dist/es6/v5/recategorizeButtons.js +34 -35
- package/dist/es6/v5/removeButtonEnums.js +26 -28
- package/dist/es6/v5/removeDefaultImports.js +7 -7
- package/dist/es6/v5/renameButtonRefs.js +8 -8
- package/dist/es6/v5/renameCoreImports.js +10 -10
- package/dist/es6/v5/renameInputRefs.js +17 -21
- package/dist/es6/v5/renamePreviewTokenImports.js +10 -10
- package/dist/es6/v5/renameSpacing.js +18 -18
- package/dist/es6/v5/slashImports.js +31 -33
- package/dist/es6/v6/deprecateCookieBanner.js +3 -3
- package/dist/es6/v6/deprecateHeader.js +4 -4
- package/dist/es6/v6/deprecatePageHeader.js +3 -3
- package/dist/es6/v6/index.js +3 -14
- package/dist/es6/v6/moveAndRenameSearchBar.js +23 -29
- package/dist/es6/v6/renameCanvasDepthValue.js +3 -3
- package/dist/es6/v6/utils/index.js +28 -31
- package/dist/es6/v7/compoundActionBar.js +27 -39
- package/dist/es6/v7/compoundBanner.js +40 -43
- package/dist/es6/v7/index.js +3 -14
- package/dist/es6/v7/recategorizeIconButtons.js +27 -31
- package/dist/es6/v7/removePropFromPopper.js +14 -18
- package/dist/es6/v7/renameIconPosition.js +13 -17
- package/dist/es6/v7/renameIconRef.js +17 -21
- package/dist/es6/v7/renameLayoutImports.js +14 -14
- package/dist/es6/v7/updateDisclosureShowHide.js +22 -22
- package/dist/es6/v7/updateModelSignatures.js +21 -21
- package/dist/es6/v7/updateSegmentedControl.js +8 -11
- package/dist/es6/v7/updateTabs.js +8 -8
- package/dist/es6/v7/utils/getImportRenameMap.js +11 -12
- package/dist/es6/v7/utils/hasImportSpecifiers.js +9 -11
- package/dist/es6/v8/index.d.ts +4 -0
- package/dist/es6/v8/index.d.ts.map +1 -0
- package/dist/es6/v8/index.js +25 -0
- package/dist/es6/v8/promoteBreadcrumbs.d.ts +4 -0
- package/dist/es6/v8/promoteBreadcrumbs.d.ts.map +1 -0
- package/dist/es6/v8/promoteBreadcrumbs.js +56 -0
- package/dist/es6/v8/promoteComponentsToTesting.d.ts +4 -0
- package/dist/es6/v8/promoteComponentsToTesting.d.ts.map +1 -0
- package/dist/es6/v8/promoteComponentsToTesting.js +76 -0
- package/dist/es6/v8/refactorActionBarOverflowButton.d.ts +3 -0
- package/dist/es6/v8/refactorActionBarOverflowButton.d.ts.map +1 -0
- package/dist/es6/v8/refactorActionBarOverflowButton.js +46 -0
- package/dist/es6/v8/removeDefaultImports.d.ts +3 -0
- package/dist/es6/v8/removeDefaultImports.d.ts.map +1 -0
- package/dist/es6/v8/removeDefaultImports.js +52 -0
- package/dist/es6/v8/renameLoadingAnimation.d.ts +3 -0
- package/dist/es6/v8/renameLoadingAnimation.d.ts.map +1 -0
- package/dist/es6/v8/renameLoadingAnimation.js +62 -0
- package/dist/es6/v8/restructureBreadcrumbs.d.ts +3 -0
- package/dist/es6/v8/restructureBreadcrumbs.d.ts.map +1 -0
- package/dist/es6/v8/restructureBreadcrumbs.js +55 -0
- package/dist/es6/v8/softDeprecateDrawer.d.ts +3 -0
- package/dist/es6/v8/softDeprecateDrawer.d.ts.map +1 -0
- package/dist/es6/v8/softDeprecateDrawer.js +103 -0
- package/dist/es6/v8/softDeprecateLayout.d.ts +3 -0
- package/dist/es6/v8/softDeprecateLayout.d.ts.map +1 -0
- package/dist/es6/v8/softDeprecateLayout.js +76 -0
- package/dist/es6/v8/softDeprecatePreviewMenu.d.ts +3 -0
- package/dist/es6/v8/softDeprecatePreviewMenu.d.ts.map +1 -0
- package/dist/es6/v8/softDeprecatePreviewMenu.js +79 -0
- package/dist/es6/v9/compoundToast.d.ts +3 -0
- package/dist/es6/v9/compoundToast.d.ts.map +1 -0
- package/dist/es6/v9/compoundToast.js +121 -0
- package/dist/es6/v9/deprecateStack.d.ts +3 -0
- package/dist/es6/v9/deprecateStack.d.ts.map +1 -0
- package/dist/es6/v9/deprecateStack.js +275 -0
- package/dist/es6/v9/index.d.ts +4 -0
- package/dist/es6/v9/index.d.ts.map +1 -0
- package/dist/es6/v9/index.js +16 -0
- package/dist/es6/v9/promoteToast.d.ts +4 -0
- package/dist/es6/v9/promoteToast.d.ts.map +1 -0
- package/dist/es6/v9/promoteToast.js +56 -0
- package/dist/es6/v9/promoteUseThemedRing.d.ts +4 -0
- package/dist/es6/v9/promoteUseThemedRing.d.ts.map +1 -0
- package/dist/es6/v9/promoteUseThemedRing.js +56 -0
- package/index.js +40 -5
- package/package.json +2 -2
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { getImportRenameMap } from '../v7/utils/getImportRenameMap';
|
|
2
|
+
import { hasImportSpecifiers } from '../v6/utils';
|
|
3
|
+
const toastPackage = '@workday/canvas-kit-react/toast';
|
|
4
|
+
export default function transformer(file, api, options) {
|
|
5
|
+
const j = api.jscodeshift;
|
|
6
|
+
const root = j(file.source);
|
|
7
|
+
if (!hasImportSpecifiers(api, root, toastPackage, ['Toast'])) {
|
|
8
|
+
return file.source;
|
|
9
|
+
}
|
|
10
|
+
const { importMap, styledMap } = getImportRenameMap(j, root, '@workday/canvas-kit-react/toast');
|
|
11
|
+
root
|
|
12
|
+
.find(j.JSXElement, (value) => value.openingElement.name.type === 'JSXIdentifier' &&
|
|
13
|
+
(value.openingElement.name.name === importMap.Toast ||
|
|
14
|
+
value.openingElement.name.name === styledMap.Toast))
|
|
15
|
+
.forEach(nodePath => {
|
|
16
|
+
var _a, _b, _c;
|
|
17
|
+
// Toast Body JSX
|
|
18
|
+
const ToastBodyJSX = j.jsxMemberExpression(j.jsxIdentifier(importMap.Toast), j.jsxIdentifier('Body'));
|
|
19
|
+
// Toast CloseIcon JSX
|
|
20
|
+
const ToastCloseJSX = j.jsxMemberExpression(j.jsxIdentifier(importMap.Toast), j.jsxIdentifier('Close'));
|
|
21
|
+
// Toast Message JSX
|
|
22
|
+
const ToastMessageJSX = j.jsxMemberExpression(j.jsxIdentifier(importMap.Toast), j.jsxIdentifier('Message'));
|
|
23
|
+
// Toast Icon JSX
|
|
24
|
+
const ToastIconJSX = j.jsxMemberExpression(j.jsxIdentifier(importMap.Toast), j.jsxIdentifier('Icon'));
|
|
25
|
+
// Toast Link JSX
|
|
26
|
+
const ToastLinkJSX = j.jsxMemberExpression(j.jsxIdentifier(importMap.Toast), j.jsxIdentifier('Link'));
|
|
27
|
+
// Attributes
|
|
28
|
+
const attributes = nodePath.value.openingElement.attributes;
|
|
29
|
+
const defaultIconAttributes = [
|
|
30
|
+
j.jsxAttribute(j.jsxIdentifier('color'), j.stringLiteral('greenApple400')),
|
|
31
|
+
j.jsxAttribute(j.jsxIdentifier('icon'), j.jsxExpressionContainer(j.jsxIdentifier('checkIcon'))),
|
|
32
|
+
];
|
|
33
|
+
const unchangedIconAttributes = attributes === null || attributes === void 0 ? void 0 : attributes.filter(attr => attr.type === 'JSXAttribute' &&
|
|
34
|
+
typeof attr.name.name === 'string' &&
|
|
35
|
+
/icon|iconColor/g.test(attr.name.name));
|
|
36
|
+
const updatedIconAttrs = unchangedIconAttributes === null || unchangedIconAttributes === void 0 ? void 0 : unchangedIconAttributes.map(specifier => {
|
|
37
|
+
if (specifier.type === 'JSXAttribute' && specifier.name.name === 'iconColor') {
|
|
38
|
+
specifier.name.name = 'color';
|
|
39
|
+
}
|
|
40
|
+
return specifier;
|
|
41
|
+
});
|
|
42
|
+
const chooseIconAttrs = unchangedIconAttributes && unchangedIconAttributes.length
|
|
43
|
+
? updatedIconAttrs
|
|
44
|
+
: defaultIconAttributes;
|
|
45
|
+
const closeAttributes = attributes === null || attributes === void 0 ? void 0 : attributes.filter(attr => attr.type === 'JSXAttribute' && attr.name.name === 'onClose');
|
|
46
|
+
const linkAttributes = attributes === null || attributes === void 0 ? void 0 : attributes.filter(attr => attr.type === 'JSXAttribute' &&
|
|
47
|
+
(attr.name.name === 'actionText' || attr.name.name === 'onActionClick'));
|
|
48
|
+
// Elements
|
|
49
|
+
const OpeningIconJSX = j.jsxOpeningElement(ToastIconJSX, chooseIconAttrs, true);
|
|
50
|
+
const IconElement = j.jsxElement(OpeningIconJSX);
|
|
51
|
+
// Add `import {checkIcon} from '@workday/canvas-system-icons-web'`
|
|
52
|
+
// when there's a default toast
|
|
53
|
+
const lastImport = root.find(j.ImportDeclaration).at(-1);
|
|
54
|
+
if (lastImport && !(unchangedIconAttributes === null || unchangedIconAttributes === void 0 ? void 0 : unchangedIconAttributes.length)) {
|
|
55
|
+
lastImport.insertAfter(j.importDeclaration([j.importSpecifier(j.identifier('checkIcon'))], j.stringLiteral('@workday/canvas-system-icons-web')));
|
|
56
|
+
}
|
|
57
|
+
const lineBreakStart = j.jsxText('\n ');
|
|
58
|
+
const lineBreakEnd = j.jsxText('\n');
|
|
59
|
+
// Filter out all old props
|
|
60
|
+
const filteredAttrNames = [
|
|
61
|
+
'actionText',
|
|
62
|
+
'icon',
|
|
63
|
+
'iconColor',
|
|
64
|
+
'onActionClick',
|
|
65
|
+
'onClose',
|
|
66
|
+
'color',
|
|
67
|
+
];
|
|
68
|
+
const filterAttr = (_a = nodePath.value.openingElement.attributes) === null || _a === void 0 ? void 0 : _a.filter(attr => {
|
|
69
|
+
return !(attr.type === 'JSXAttribute' &&
|
|
70
|
+
typeof attr.name.name === 'string' &&
|
|
71
|
+
filteredAttrNames.includes(attr.name.name));
|
|
72
|
+
});
|
|
73
|
+
nodePath.value.openingElement.attributes = filterAttr;
|
|
74
|
+
const OpeningCloseElement = j.jsxOpeningElement(ToastCloseJSX, closeAttributes, true);
|
|
75
|
+
const CloseElement = j.jsxElement(OpeningCloseElement);
|
|
76
|
+
// grab the onActionClick attr
|
|
77
|
+
const onActionClickAttr = linkAttributes === null || linkAttributes === void 0 ? void 0 : linkAttributes.filter(attr => attr.type === 'JSXAttribute' && attr.name.name === 'onActionClick');
|
|
78
|
+
// rename onActionClick to onClick for the Toast.Link component
|
|
79
|
+
const renameOnActionClick = onActionClickAttr === null || onActionClickAttr === void 0 ? void 0 : onActionClickAttr.map(attr => {
|
|
80
|
+
if (attr.type === 'JSXAttribute') {
|
|
81
|
+
attr.name.name = 'onClick';
|
|
82
|
+
}
|
|
83
|
+
return attr;
|
|
84
|
+
});
|
|
85
|
+
// grab the actionText prop
|
|
86
|
+
const actionTextAttr = linkAttributes === null || linkAttributes === void 0 ? void 0 : linkAttributes.find(attr => attr.type === 'JSXAttribute' && attr.name.name === 'actionText');
|
|
87
|
+
const actionText = actionTextAttr &&
|
|
88
|
+
actionTextAttr.type === 'JSXAttribute' &&
|
|
89
|
+
((_b = actionTextAttr.value) === null || _b === void 0 ? void 0 : _b.type) === 'StringLiteral'
|
|
90
|
+
? [actionTextAttr.value]
|
|
91
|
+
: [];
|
|
92
|
+
const LinkElement = j.jsxElement(j.jsxOpeningElement(ToastLinkJSX, renameOnActionClick), j.jsxClosingElement(ToastLinkJSX), actionText);
|
|
93
|
+
// Toast Message JSX inclduing children which should be the string
|
|
94
|
+
const MessageElement = j.jsxElement(j.jsxOpeningElement(ToastMessageJSX), j.jsxClosingElement(ToastMessageJSX), nodePath.value.children);
|
|
95
|
+
if (linkAttributes && (linkAttributes === null || linkAttributes === void 0 ? void 0 : linkAttributes.length)) {
|
|
96
|
+
// If there's a link, add mode="dialog" to the main Toast component for accessibility
|
|
97
|
+
nodePath.value.openingElement.attributes = [
|
|
98
|
+
j.jsxAttribute(j.jsxIdentifier('mode'), j.stringLiteral('dialog')),
|
|
99
|
+
];
|
|
100
|
+
}
|
|
101
|
+
// Body element including Message and its children
|
|
102
|
+
const BodyElement = j.jsxElement(j.jsxOpeningElement(ToastBodyJSX), j.jsxClosingElement(ToastBodyJSX), [lineBreakStart, MessageElement, lineBreakEnd]);
|
|
103
|
+
// If there's an actionText or onActionClick, add the Toast.Link with its attributes inside Toast.Body
|
|
104
|
+
if (linkAttributes && linkAttributes.length) {
|
|
105
|
+
(_c = BodyElement.children) === null || _c === void 0 ? void 0 : _c.push(LinkElement, lineBreakEnd);
|
|
106
|
+
}
|
|
107
|
+
// Default Toast with no Close or Link
|
|
108
|
+
nodePath.value.children = [
|
|
109
|
+
lineBreakStart,
|
|
110
|
+
IconElement,
|
|
111
|
+
lineBreakEnd,
|
|
112
|
+
BodyElement,
|
|
113
|
+
lineBreakEnd,
|
|
114
|
+
];
|
|
115
|
+
// If there's an onClose, add the Toast.Close with its attributes
|
|
116
|
+
if (closeAttributes && (closeAttributes === null || closeAttributes === void 0 ? void 0 : closeAttributes.length)) {
|
|
117
|
+
nodePath.value.children.push(CloseElement, lineBreakEnd);
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
return root.toSource();
|
|
121
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deprecateStack.d.ts","sourceRoot":"","sources":["../../../lib/v9/deprecateStack.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,GAAG,EAAE,QAAQ,EAA+C,OAAO,EAAC,MAAM,aAAa,CAAC;AAUhG,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,UAgT7E"}
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
const mainPackage = '@workday/canvas-kit-react';
|
|
2
|
+
const stackPackage = '@workday/canvas-kit-react/layout';
|
|
3
|
+
const stackImportNames = ['Stack', 'HStack', 'VStack'];
|
|
4
|
+
const stackImportProps = ['StackProps', 'HStackProps', 'VStackProps', 'StackStyleProps'];
|
|
5
|
+
const altImportSpecifier = ['ActionBar', 'Menu', 'Pagination', 'Tabs'];
|
|
6
|
+
const altImportNamesIncludes = ['action-bar', 'menu', 'pagination', 'tabs'];
|
|
7
|
+
const altPackages = altImportNamesIncludes.map(name => `${mainPackage}/${name}`);
|
|
8
|
+
export default function transformer(file, api, options) {
|
|
9
|
+
const j = api.jscodeshift;
|
|
10
|
+
const root = j(file.source);
|
|
11
|
+
let hasStackImports = false;
|
|
12
|
+
const importedComponentNames = [];
|
|
13
|
+
// This toggles the failsafe that prevents us from accidentally transforming something unintentionally.
|
|
14
|
+
root.find(j.ImportDeclaration, (nodePath) => {
|
|
15
|
+
const value = nodePath.source.value;
|
|
16
|
+
// If there's an import from ActionBar, Menu, Pagination or Tabs package,
|
|
17
|
+
// set the import boolean check to true
|
|
18
|
+
// If there's an import from the main package, check to see if Stack, ActionBar,
|
|
19
|
+
// Menu, Pagination or Tabs or Stackprops are among the named imports
|
|
20
|
+
// e.g. import {Stack} from '@workday/canvas-kit-react/layout';
|
|
21
|
+
// e.g. import {Menu} from '@workday/canvas-kit-react/menu';
|
|
22
|
+
if (typeof value === 'string' &&
|
|
23
|
+
(value === mainPackage || value === stackPackage || altPackages.includes(value))) {
|
|
24
|
+
(nodePath.specifiers || []).forEach(specifier => {
|
|
25
|
+
if ((specifier.type === 'ImportSpecifier' &&
|
|
26
|
+
stackImportNames.includes(specifier.imported.name)) ||
|
|
27
|
+
(specifier.type === 'ImportSpecifier' &&
|
|
28
|
+
stackImportProps.includes(specifier.imported.name)) ||
|
|
29
|
+
(specifier.type === 'ImportSpecifier' &&
|
|
30
|
+
altImportSpecifier.includes(specifier.imported.name))) {
|
|
31
|
+
importedComponentNames.push(specifier.imported.name);
|
|
32
|
+
hasStackImports = true;
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
return false;
|
|
37
|
+
});
|
|
38
|
+
// Failsafe to skip transforms unless a specific import is detected
|
|
39
|
+
if (!hasStackImports) {
|
|
40
|
+
return root.toSource();
|
|
41
|
+
}
|
|
42
|
+
root
|
|
43
|
+
.find(j.ImportDeclaration, {
|
|
44
|
+
source: { value: (value) => value.includes(mainPackage) },
|
|
45
|
+
})
|
|
46
|
+
.forEach(nodePath => {
|
|
47
|
+
var _a, _b;
|
|
48
|
+
(_a = nodePath.value.specifiers) === null || _a === void 0 ? void 0 : _a.forEach(specifier => {
|
|
49
|
+
if (specifier.type === 'ImportSpecifier') {
|
|
50
|
+
// `import {Stack}` becomes `import {Flex}`
|
|
51
|
+
// `import {HStack}` becomes `import {Flex}`
|
|
52
|
+
// `import {VStack}` becomes `import {Flex}`
|
|
53
|
+
if (stackImportNames.includes(specifier.imported.name)) {
|
|
54
|
+
specifier.imported.name = 'Flex';
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return specifier;
|
|
58
|
+
});
|
|
59
|
+
nodePath.value.specifiers = (_b = nodePath.value.specifiers) === null || _b === void 0 ? void 0 : _b.filter((specifier, index, specifiers) => {
|
|
60
|
+
if (specifier.type === 'ImportSpecifier' &&
|
|
61
|
+
specifier.imported &&
|
|
62
|
+
specifier.imported.type === 'Identifier') {
|
|
63
|
+
return (specifiers.findIndex(s => {
|
|
64
|
+
return (s.type === 'ImportSpecifier' &&
|
|
65
|
+
s.imported.type === 'Identifier' &&
|
|
66
|
+
s.imported.name === specifier.imported.name);
|
|
67
|
+
}) === index);
|
|
68
|
+
}
|
|
69
|
+
return true;
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
root
|
|
73
|
+
.find(j.ImportDeclaration, {
|
|
74
|
+
source: { value: (value) => value.includes(mainPackage) },
|
|
75
|
+
})
|
|
76
|
+
.forEach(nodePath => {
|
|
77
|
+
var _a, _b;
|
|
78
|
+
(_a = nodePath.value.specifiers) === null || _a === void 0 ? void 0 : _a.forEach(specifier => {
|
|
79
|
+
if (specifier.type === 'ImportSpecifier') {
|
|
80
|
+
// `import {StackProps}` becomes `import {FlexProps}`
|
|
81
|
+
// `import {HStackProps}` becomes `import {FlexProps}`
|
|
82
|
+
// `import {VStackProps}` becomes `import {FlexProps}`
|
|
83
|
+
// `import {StackStyleProps}` becomes `import {FlexProps}`
|
|
84
|
+
if (stackImportProps.includes(specifier.imported.name)) {
|
|
85
|
+
specifier.imported.name = `FlexProps`;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return specifier;
|
|
89
|
+
});
|
|
90
|
+
nodePath.value.specifiers = (_b = nodePath.value.specifiers) === null || _b === void 0 ? void 0 : _b.filter((specifier, index, specifiers) => {
|
|
91
|
+
if (specifier.type === 'ImportSpecifier' &&
|
|
92
|
+
specifier.imported &&
|
|
93
|
+
specifier.imported.type === 'Identifier') {
|
|
94
|
+
return (specifiers.findIndex(s => {
|
|
95
|
+
return (s.type === 'ImportSpecifier' &&
|
|
96
|
+
s.imported.type === 'Identifier' &&
|
|
97
|
+
s.imported.name === specifier.imported.name);
|
|
98
|
+
}) === index);
|
|
99
|
+
}
|
|
100
|
+
return true;
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
// Transform StackProps type references
|
|
104
|
+
// e.g. `type CustomProps = StackProps;` becomes `type CustomProps = FlexProps;`
|
|
105
|
+
// Transform HStackProps type references
|
|
106
|
+
// e.g. `type CustomProps = HStackProps;` becomes `type CustomProps = FlexProps;`
|
|
107
|
+
// Transform VStackProps type references
|
|
108
|
+
// e.g. `type CustomProps = VStackProps;` becomes `type CustomProps = FlexProps;`
|
|
109
|
+
const typeNames = ['StackProps', 'HStackProps', 'VStackProps', 'StackStyleProps'];
|
|
110
|
+
root
|
|
111
|
+
.find(j.TSTypeReference, {
|
|
112
|
+
typeName: {
|
|
113
|
+
type: 'Identifier',
|
|
114
|
+
name: (value) => typeNames.includes(value),
|
|
115
|
+
},
|
|
116
|
+
})
|
|
117
|
+
.forEach(nodePath => {
|
|
118
|
+
const identifier = nodePath.value.typeName;
|
|
119
|
+
identifier.name = `FlexProps`;
|
|
120
|
+
});
|
|
121
|
+
// Transform StackProps type interface declaration references
|
|
122
|
+
// e.g. `interface CustomProps extends StackProps` becomes `interface CustomProps extends FlexProps`
|
|
123
|
+
root.find(j.TSInterfaceDeclaration).forEach(nodePath => {
|
|
124
|
+
var _a;
|
|
125
|
+
// If the interface is extending StackProps, transform the extension name to FlexProps
|
|
126
|
+
(_a = nodePath.node.extends) === null || _a === void 0 ? void 0 : _a.forEach(typeExtension => {
|
|
127
|
+
if (typeExtension.expression.type === 'Identifier') {
|
|
128
|
+
const typeExtensionName = typeExtension.expression.name;
|
|
129
|
+
if (typeExtension.expression.type === 'Identifier' &&
|
|
130
|
+
typeNames.includes(typeExtensionName)) {
|
|
131
|
+
typeExtension.expression.name = `FlexProps`;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
// Transform `spacing` key that are in type interface declaration references
|
|
137
|
+
// e.g. `interface CustomProps extends StackProps {
|
|
138
|
+
// spacing: SystemPropValues['space']
|
|
139
|
+
// }`
|
|
140
|
+
// becomes `interface CustomProps extends FlexProps {
|
|
141
|
+
// gap: FlexProps['gap']
|
|
142
|
+
// }`
|
|
143
|
+
const spacingName = ['spacing'];
|
|
144
|
+
// Transform `spacing` key that is in type interface
|
|
145
|
+
// e.g. `spacing: SystemPropValues['space']`
|
|
146
|
+
// becomes `gap: FlexProps['gap']`
|
|
147
|
+
root.find(j.TSLiteralType, { type: 'TSLiteralType' }).forEach(nodePath => {
|
|
148
|
+
if (nodePath.node.literal.type === 'StringLiteral') {
|
|
149
|
+
if (spacingName.includes(nodePath.node.literal.value)) {
|
|
150
|
+
nodePath.node.literal.value = 'gap';
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
// Transforms `as` prop Stack, HStack or VStack values to `Flex`
|
|
155
|
+
// e.g. <Card as={Stack} spacing="s" />
|
|
156
|
+
// becomes <Card as={Flex} gap="s" />
|
|
157
|
+
root.find(j.JSXOpeningElement, { type: 'JSXOpeningElement' }).forEach(nodePath => {
|
|
158
|
+
var _a, _b;
|
|
159
|
+
let isCastAsStack = false;
|
|
160
|
+
(_a = nodePath.node.attributes) === null || _a === void 0 ? void 0 : _a.forEach(attr => {
|
|
161
|
+
var _a;
|
|
162
|
+
if (attr.type === 'JSXAttribute') {
|
|
163
|
+
if (attr.name.name === 'as') {
|
|
164
|
+
if (((_a = attr.value) === null || _a === void 0 ? void 0 : _a.type) === 'JSXExpressionContainer') {
|
|
165
|
+
if (attr.value.expression.type === 'Identifier') {
|
|
166
|
+
if (stackImportNames.includes(attr.value.expression.name)) {
|
|
167
|
+
isCastAsStack = true;
|
|
168
|
+
attr.value.expression.name = 'Flex';
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
if (isCastAsStack) {
|
|
176
|
+
(_b = nodePath.node.attributes) === null || _b === void 0 ? void 0 : _b.forEach(attr => {
|
|
177
|
+
if (attr.type === 'JSXAttribute') {
|
|
178
|
+
if (attr.name.name === 'spacing') {
|
|
179
|
+
attr.name.name = 'gap';
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
// Transform Stack, HStack and VStack JSXElements
|
|
186
|
+
// Transform `<Stack spacing="l">` to `<Flex gap="l">`
|
|
187
|
+
// Transform `<Stack shouldWrapChildren>` to `<Flex >`
|
|
188
|
+
root.find(j.JSXOpeningElement).forEach(nodePath => {
|
|
189
|
+
var _a;
|
|
190
|
+
if (nodePath.node.type === 'JSXOpeningElement') {
|
|
191
|
+
if (nodePath.node.name.type === 'JSXIdentifier') {
|
|
192
|
+
if (importedComponentNames.includes(nodePath.node.name.name)) {
|
|
193
|
+
(_a = nodePath.node.attributes) === null || _a === void 0 ? void 0 : _a.forEach(path => {
|
|
194
|
+
if (path.type === 'JSXAttribute') {
|
|
195
|
+
if (path.name.name === 'spacing') {
|
|
196
|
+
path.name.name = 'gap';
|
|
197
|
+
}
|
|
198
|
+
if (path.name.name === 'shouldWrapChildren') {
|
|
199
|
+
path.name.name = '';
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
// Transform spacing on JSXMemberExpression
|
|
208
|
+
// Transform `<Stack.Item spacing="l">` to `<Flex.Item gap="l">`
|
|
209
|
+
root.find(j.JSXOpeningElement).forEach(nodePath => {
|
|
210
|
+
var _a;
|
|
211
|
+
if (nodePath.node.type === 'JSXOpeningElement') {
|
|
212
|
+
if (nodePath.node.name.type === 'JSXMemberExpression') {
|
|
213
|
+
if (nodePath.node.name.object.type === 'JSXIdentifier') {
|
|
214
|
+
const nodePathName = nodePath.node.name.object.name;
|
|
215
|
+
if (altImportSpecifier.includes(nodePathName)) {
|
|
216
|
+
if (nodePath.node.name.property.name === 'List' ||
|
|
217
|
+
nodePath.node.name.property.name === 'Item') {
|
|
218
|
+
(_a = nodePath.node.attributes) === null || _a === void 0 ? void 0 : _a.forEach(path => {
|
|
219
|
+
if (path.type === 'JSXAttribute') {
|
|
220
|
+
if (path.name.name === 'spacing') {
|
|
221
|
+
path.name.name = 'gap';
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
// Transform styled compoents
|
|
232
|
+
// e.g. `const StyledStack = styled(Stack)({});`
|
|
233
|
+
// becomes `const StyledStack = styled(Flex)({});`
|
|
234
|
+
root.find(j.VariableDeclarator).forEach(nodePath => {
|
|
235
|
+
var _a;
|
|
236
|
+
if (((_a = nodePath.value.init) === null || _a === void 0 ? void 0 : _a.type) === 'CallExpression' &&
|
|
237
|
+
nodePath.value.init.callee.type === 'CallExpression' &&
|
|
238
|
+
nodePath.value.init.callee.callee.type === 'Identifier' &&
|
|
239
|
+
nodePath.value.init.callee.callee.name === 'styled' &&
|
|
240
|
+
nodePath.value.init.callee.arguments[0].type === 'Identifier' &&
|
|
241
|
+
stackImportNames.includes(nodePath.value.init.callee.arguments[0].name)) {
|
|
242
|
+
nodePath.value.init.callee.arguments[0].name = 'Flex';
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
// Transform Stack JSXElements
|
|
246
|
+
// Transform `<Stack>` to `<Flex>`
|
|
247
|
+
root.find(j.JSXIdentifier, { name: 'Stack' }).forEach(nodePath => {
|
|
248
|
+
nodePath.node.name = 'Flex';
|
|
249
|
+
});
|
|
250
|
+
// Transform Stack JSXElements
|
|
251
|
+
// e.g. `<HStack>` becomes `<Flex>`
|
|
252
|
+
root.find(j.JSXIdentifier, { name: 'HStack' }).forEach(nodePath => {
|
|
253
|
+
nodePath.node.name = 'Flex';
|
|
254
|
+
});
|
|
255
|
+
// Creating new JSXAttribute to push in attribute array for VStack
|
|
256
|
+
// Since we're replacing VStack with Flex, it will need a
|
|
257
|
+
// flexDirection="column" added
|
|
258
|
+
const newVStackProp = {
|
|
259
|
+
type: 'JSXAttribute',
|
|
260
|
+
name: { type: 'JSXIdentifier', name: 'flexDirection' },
|
|
261
|
+
value: { type: 'Literal', value: 'column' },
|
|
262
|
+
};
|
|
263
|
+
root
|
|
264
|
+
.find(j.JSXOpeningElement, { name: { type: 'JSXIdentifier', name: 'VStack' } })
|
|
265
|
+
.forEach(nodePath => {
|
|
266
|
+
var _a;
|
|
267
|
+
(_a = nodePath.node.attributes) === null || _a === void 0 ? void 0 : _a.push(newVStackProp);
|
|
268
|
+
});
|
|
269
|
+
// Transform VStack JSXElements
|
|
270
|
+
// e.g. `<VStack>` becomes `<Flex>`
|
|
271
|
+
root.find(j.JSXIdentifier, { name: 'VStack' }).forEach(nodePath => {
|
|
272
|
+
nodePath.node.name = 'Flex';
|
|
273
|
+
});
|
|
274
|
+
return root.toSource();
|
|
275
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../lib/v9/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAC,MAAM,aAAa,CAAC;AAOtC,QAAA,MAAM,SAAS,EAAE,SAUhB,CAAC;AAEF,eAAe,SAAS,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import deprecateStack from './deprecateStack';
|
|
2
|
+
import promoteToast from './promoteToast';
|
|
3
|
+
import compoundToast from './compoundToast';
|
|
4
|
+
import promoteUseThemedRing from './promoteUseThemedRing';
|
|
5
|
+
const transform = (file, api, options) => {
|
|
6
|
+
// These will run in order. If your transform depends on others, place yours after dependent transforms
|
|
7
|
+
const fixes = [
|
|
8
|
+
// add codemods here
|
|
9
|
+
deprecateStack,
|
|
10
|
+
compoundToast,
|
|
11
|
+
promoteToast,
|
|
12
|
+
promoteUseThemedRing,
|
|
13
|
+
];
|
|
14
|
+
return fixes.reduce((source, fix) => fix({ ...file, source }, api, options), file.source);
|
|
15
|
+
};
|
|
16
|
+
export default transform;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promoteToast.d.ts","sourceRoot":"","sources":["../../../lib/v9/promoteToast.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAA6B,MAAM,aAAa,CAAC;AAIlE,QAAA,MAAM,SAAS,EAAE,SAyEhB,CAAC;AAEF,eAAe,SAAS,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
const transform = (file, api) => {
|
|
2
|
+
const j = api.jscodeshift;
|
|
3
|
+
const root = j(file.source);
|
|
4
|
+
const toastSpecifiers = [];
|
|
5
|
+
const foundImport = [];
|
|
6
|
+
root
|
|
7
|
+
.find(j.ImportDeclaration, {
|
|
8
|
+
source: { value: (value) => value.includes('@workday/canvas-kit-labs-react') },
|
|
9
|
+
})
|
|
10
|
+
.forEach(nodePath => {
|
|
11
|
+
var _a;
|
|
12
|
+
nodePath.value.specifiers = (_a = nodePath.value.specifiers) === null || _a === void 0 ? void 0 : _a.filter(specifier => {
|
|
13
|
+
if (specifier.type === 'ImportSpecifier' &&
|
|
14
|
+
specifier.local &&
|
|
15
|
+
specifier.imported.name === 'Toast') {
|
|
16
|
+
toastSpecifiers.push({
|
|
17
|
+
importedName: specifier.imported.name,
|
|
18
|
+
name: specifier.local.name,
|
|
19
|
+
});
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
return true;
|
|
23
|
+
});
|
|
24
|
+
if (toastSpecifiers.length) {
|
|
25
|
+
foundImport.push(nodePath);
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
const existingToastImports = root.find(j.ImportDeclaration, {
|
|
29
|
+
source: { value: '@workday/canvas-kit-react/toast' },
|
|
30
|
+
});
|
|
31
|
+
const mapToSpecifiers = (specifier) => {
|
|
32
|
+
return j.importSpecifier(j.identifier(specifier.importedName), specifier.name ? j.identifier(specifier.name) : undefined);
|
|
33
|
+
};
|
|
34
|
+
// add to existing import
|
|
35
|
+
if (existingToastImports.length) {
|
|
36
|
+
existingToastImports.forEach(nodePath => {
|
|
37
|
+
var _a;
|
|
38
|
+
nodePath.value.specifiers = (_a = nodePath.value.specifiers) === null || _a === void 0 ? void 0 : _a.concat(toastSpecifiers.map(mapToSpecifiers));
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
// create new import
|
|
43
|
+
if (foundImport.length) {
|
|
44
|
+
foundImport[0].insertBefore(j.importDeclaration(toastSpecifiers.map(mapToSpecifiers), j.stringLiteral('@workday/canvas-kit-react/toast')));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
foundImport.forEach(importPath => {
|
|
48
|
+
var _a;
|
|
49
|
+
if (!((_a = importPath.value.specifiers) === null || _a === void 0 ? void 0 : _a.length) ||
|
|
50
|
+
importPath.value.source.value === '@workday/canvas-kit-labs-react/toast') {
|
|
51
|
+
importPath.prune();
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
return root.toSource();
|
|
55
|
+
};
|
|
56
|
+
export default transform;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promoteUseThemedRing.d.ts","sourceRoot":"","sources":["../../../lib/v9/promoteUseThemedRing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAA6B,MAAM,aAAa,CAAC;AAIlE,QAAA,MAAM,SAAS,EAAE,SAuEhB,CAAC;AAEF,eAAe,SAAS,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
const transform = (file, api) => {
|
|
2
|
+
const j = api.jscodeshift;
|
|
3
|
+
const root = j(file.source);
|
|
4
|
+
const common = [];
|
|
5
|
+
const foundImport = [];
|
|
6
|
+
root
|
|
7
|
+
.find(j.ImportDeclaration, {
|
|
8
|
+
source: { value: (value) => value.includes('@workday/canvas-kit-labs-react') },
|
|
9
|
+
})
|
|
10
|
+
.forEach(nodePath => {
|
|
11
|
+
var _a;
|
|
12
|
+
nodePath.value.specifiers = (_a = nodePath.value.specifiers) === null || _a === void 0 ? void 0 : _a.filter(specifier => {
|
|
13
|
+
if (specifier.type === 'ImportSpecifier' &&
|
|
14
|
+
specifier.local &&
|
|
15
|
+
specifier.imported.name === 'useThemedRing') {
|
|
16
|
+
common.push({
|
|
17
|
+
importedName: specifier.imported.name,
|
|
18
|
+
name: specifier.local.name,
|
|
19
|
+
});
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
return true;
|
|
23
|
+
});
|
|
24
|
+
if (common.length) {
|
|
25
|
+
foundImport.push(nodePath);
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
const existingCommonImports = root.find(j.ImportDeclaration, {
|
|
29
|
+
source: { value: '@workday/canvas-kit-react/common' },
|
|
30
|
+
});
|
|
31
|
+
const mapToSpecifiers = (specifier) => {
|
|
32
|
+
return j.importSpecifier(j.identifier(specifier.importedName), specifier.name ? j.identifier(specifier.name) : undefined);
|
|
33
|
+
};
|
|
34
|
+
// add to existing import
|
|
35
|
+
if (existingCommonImports.length) {
|
|
36
|
+
existingCommonImports.forEach(nodePath => {
|
|
37
|
+
var _a;
|
|
38
|
+
nodePath.value.specifiers = (_a = nodePath.value.specifiers) === null || _a === void 0 ? void 0 : _a.concat(common.map(mapToSpecifiers));
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
// create new import
|
|
43
|
+
if (foundImport.length) {
|
|
44
|
+
foundImport[0].insertBefore(j.importDeclaration(common.map(mapToSpecifiers), j.stringLiteral('@workday/canvas-kit-react/common')));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
foundImport.forEach(importPath => {
|
|
48
|
+
var _a;
|
|
49
|
+
if (!((_a = importPath.value.specifiers) === null || _a === void 0 ? void 0 : _a.length) ||
|
|
50
|
+
importPath.value.source.value === '@workday/canvas-kit-labs-react/common') {
|
|
51
|
+
importPath.prune();
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
return root.toSource();
|
|
55
|
+
};
|
|
56
|
+
export default transform;
|
package/index.js
CHANGED
|
@@ -4,9 +4,28 @@
|
|
|
4
4
|
const {spawn} = require('child_process');
|
|
5
5
|
const chalk = require('chalk');
|
|
6
6
|
|
|
7
|
-
const {_: commands, path} = require('yargs')
|
|
7
|
+
const {_: commands, path, ignoreConfig, ignorePattern, verbose} = require('yargs')
|
|
8
8
|
.scriptName('canvas-kit-codemod')
|
|
9
9
|
.usage(chalk.bold.blueBright('$0 <transform> [path]'))
|
|
10
|
+
.options({
|
|
11
|
+
'ignore-config': {
|
|
12
|
+
type: 'string',
|
|
13
|
+
describe:
|
|
14
|
+
'Ignore files if they match patterns sourced from a configuration file (e.g. a .gitignore)',
|
|
15
|
+
default: '',
|
|
16
|
+
},
|
|
17
|
+
'ignore-pattern': {
|
|
18
|
+
type: 'string',
|
|
19
|
+
describe: 'Ignore files that match a provided glob expression (e.g. **/dist/**)',
|
|
20
|
+
default: '**/node_modules/**',
|
|
21
|
+
},
|
|
22
|
+
verbose: {
|
|
23
|
+
type: 'number',
|
|
24
|
+
describe: 'Show more information about the transform process',
|
|
25
|
+
default: 0,
|
|
26
|
+
choices: [0, 1, 2],
|
|
27
|
+
},
|
|
28
|
+
})
|
|
10
29
|
.command('v5 [path]', chalk.gray('Canvas Kit v4 > v5 migration transform'), yargs => {
|
|
11
30
|
yargs.positional('path', {
|
|
12
31
|
type: 'string',
|
|
@@ -14,14 +33,28 @@ const {_: commands, path} = require('yargs')
|
|
|
14
33
|
describe: chalk.gray('The path to execute the transform in (recursively).'),
|
|
15
34
|
});
|
|
16
35
|
})
|
|
17
|
-
.command('v6 [path]', chalk.gray('Canvas Kit v5 > v6
|
|
36
|
+
.command('v6 [path]', chalk.gray('Canvas Kit v5 > v6 upgrade transform'), yargs => {
|
|
37
|
+
yargs.positional('path', {
|
|
38
|
+
type: 'string',
|
|
39
|
+
default: '.',
|
|
40
|
+
describe: chalk.gray('The path to execute the transform in (recursively).'),
|
|
41
|
+
});
|
|
42
|
+
})
|
|
43
|
+
.command('v7 [path]', chalk.gray('Canvas Kit v6 > v7 upgrade transform'), yargs => {
|
|
44
|
+
yargs.positional('path', {
|
|
45
|
+
type: 'string',
|
|
46
|
+
default: '.',
|
|
47
|
+
describe: chalk.gray('The path to execute the transform in (recursively).'),
|
|
48
|
+
});
|
|
49
|
+
})
|
|
50
|
+
.command('v8 [path]', chalk.gray('Canvas Kit v7 > v8 upgrade transform'), yargs => {
|
|
18
51
|
yargs.positional('path', {
|
|
19
52
|
type: 'string',
|
|
20
53
|
default: '.',
|
|
21
54
|
describe: chalk.gray('The path to execute the transform in (recursively).'),
|
|
22
55
|
});
|
|
23
56
|
})
|
|
24
|
-
.command('
|
|
57
|
+
.command('v9 [path]', chalk.gray('Canvas Kit v8 > v9 upgrade transform'), yargs => {
|
|
25
58
|
yargs.positional('path', {
|
|
26
59
|
type: 'string',
|
|
27
60
|
default: '.',
|
|
@@ -46,10 +79,12 @@ const {_: commands, path} = require('yargs')
|
|
|
46
79
|
.help().argv;
|
|
47
80
|
|
|
48
81
|
const transform = commands[0];
|
|
49
|
-
|
|
82
|
+
// Only add an ignore-config if one is provided
|
|
83
|
+
const ignoreConfigArg = ignoreConfig ? `--ignore-config=${ignoreConfig}` : '';
|
|
84
|
+
console.log(ignorePattern);
|
|
50
85
|
|
|
51
86
|
console.log(chalk.blueBright(`\nApplying ${transform} transform to '${path}'\n`));
|
|
52
|
-
const args = `-t ${__dirname}/dist/es6/${transform} ${path} --parser tsx --extensions js,jsx,ts,tsx`.split(
|
|
87
|
+
const args = `-t ${__dirname}/dist/es6/${transform} ${path} --parser tsx --extensions js,jsx,ts,tsx ${ignoreConfigArg} --ignore-pattern=${ignorePattern} --verbose=${verbose}`.split(
|
|
53
88
|
' '
|
|
54
89
|
);
|
|
55
90
|
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@workday/canvas-kit-codemod",
|
|
3
3
|
"author": "Workday, Inc. (https://www.workday.com)",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
|
-
"version": "7.
|
|
5
|
+
"version": "7.2.0-427-next.2+2c79134a",
|
|
6
6
|
"description": "A collection of codemods for use on Workday Canvas Kit packages.",
|
|
7
7
|
"main": "dist/es6/index.js",
|
|
8
8
|
"sideEffects": false,
|
|
@@ -43,5 +43,5 @@
|
|
|
43
43
|
"test": "TZ=UTC jest -c ../../jest.config.js",
|
|
44
44
|
"typecheck:src": "tsc -p . --noEmit --incremental false"
|
|
45
45
|
},
|
|
46
|
-
"gitHead": "
|
|
46
|
+
"gitHead": "2c79134aa48ef0efde9cdf883b529b8157337a28"
|
|
47
47
|
}
|