@workday/canvas-kit-codemod 16.0.0-alpha.0494-next.0 → 16.0.0-alpha.0499-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/es6/icon-migration/index.d.ts +4 -0
- package/dist/es6/icon-migration/index.d.ts.map +1 -0
- package/dist/es6/icon-migration/index.js +7 -0
- package/dist/es6/icon-migration/migrateIcons.d.ts +3 -0
- package/dist/es6/icon-migration/migrateIcons.d.ts.map +1 -0
- package/dist/es6/icon-migration/migrateIcons.js +135 -0
- package/dist/es6/icon-migration/utils/getImportRenameMap.d.ts +7 -0
- package/dist/es6/icon-migration/utils/getImportRenameMap.d.ts.map +1 -0
- package/dist/es6/icon-migration/utils/getImportRenameMap.js +46 -0
- package/index.js +11 -0
- package/package.json +7 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../lib/icon-migration/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,SAAS,EAAC,MAAM,aAAa,CAAC;AAItC,QAAA,MAAM,SAAS,EAAE,SAIhB,CAAC;AAEF,eAAe,SAAS,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import migrateIcons from './migrateIcons';
|
|
2
|
+
const transform = (file, api, options) => {
|
|
3
|
+
// These will run in order. If your transform depends on others, place yours after dependent transforms
|
|
4
|
+
const fixes = [migrateIcons];
|
|
5
|
+
return fixes.reduce((source, fix) => fix({ ...file, source }, api, options), file.source);
|
|
6
|
+
};
|
|
7
|
+
export default transform;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrateIcons.d.ts","sourceRoot":"","sources":["../../../lib/icon-migration/migrateIcons.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAC,MAAM,aAAa,CAAC;AA2CnD,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,OAAO,UA0I9E"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import deprecatedIcons from '@workday/canvas-system-icons-web/dist/metadata/system.deprecated.metadata.json';
|
|
2
|
+
import { getImportRenameMap } from './utils/getImportRenameMap';
|
|
3
|
+
const iconPackage = '@workday/canvas-system-icons-web';
|
|
4
|
+
const toCamelCase = (str) => str
|
|
5
|
+
.split('-')
|
|
6
|
+
.map((word, index) => (index === 0 ? word : word.charAt(0).toUpperCase() + word.slice(1)))
|
|
7
|
+
.join('');
|
|
8
|
+
// `wd-icon-clipboard-user.svg` -> `clipboard-user`
|
|
9
|
+
// `academicAppointmentTitleIcon` -> `clipboardUserIcon`
|
|
10
|
+
const migrations = deprecatedIcons.reduce((acc, icon) => {
|
|
11
|
+
const oldIcon = toCamelCase(icon.name) + 'Icon';
|
|
12
|
+
// `wd-icon-clipboard-user.svg` -> `clipboardUserIcon`
|
|
13
|
+
const newIcon = icon.fallback
|
|
14
|
+
? toCamelCase(icon.fallback.replace(/^wd-icon-|\.svg$/g, '')) + 'Icon'
|
|
15
|
+
: oldIcon;
|
|
16
|
+
if (oldIcon !== newIcon) {
|
|
17
|
+
acc[oldIcon] = newIcon;
|
|
18
|
+
}
|
|
19
|
+
return acc;
|
|
20
|
+
}, {});
|
|
21
|
+
// a fallback can itself be deprecated, so follow the chain until we land on a supported icon
|
|
22
|
+
Object.keys(migrations).forEach(oldIcon => {
|
|
23
|
+
const seen = new Set([oldIcon]);
|
|
24
|
+
while (migrations[migrations[oldIcon]] && !seen.has(migrations[oldIcon])) {
|
|
25
|
+
seen.add(migrations[oldIcon]);
|
|
26
|
+
migrations[oldIcon] = migrations[migrations[oldIcon]];
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
export default function transformer(file, api, _options) {
|
|
30
|
+
const j = api.jscodeshift;
|
|
31
|
+
const root = j(file.source);
|
|
32
|
+
const { containsCanvasImports } = getImportRenameMap(j, root, iconPackage);
|
|
33
|
+
// exit if the icon package isn't imported
|
|
34
|
+
if (!containsCanvasImports) {
|
|
35
|
+
return file.source;
|
|
36
|
+
}
|
|
37
|
+
const namespaceImportNames = new Set();
|
|
38
|
+
// usages reference the local name, so renames are keyed off of it, i.e. `academicIcon` ->
|
|
39
|
+
// `clipboardIcon` when the deprecated icon's fallback is already imported as `clipboardIcon`
|
|
40
|
+
const usageRenameMap = {};
|
|
41
|
+
root
|
|
42
|
+
.find(j.ImportDeclaration, {
|
|
43
|
+
source: {
|
|
44
|
+
value: (value) => value === iconPackage,
|
|
45
|
+
},
|
|
46
|
+
})
|
|
47
|
+
.forEach(nodePath => {
|
|
48
|
+
if (nodePath.value.specifiers && nodePath.value.specifiers.length) {
|
|
49
|
+
// collect namespace imports, i.e. `import * as systemIcons from ...`, so we can rename the
|
|
50
|
+
// icons accessed off of them later
|
|
51
|
+
nodePath.value.specifiers.forEach(currentSpecifier => {
|
|
52
|
+
if (currentSpecifier.type === 'ImportNamespaceSpecifier' && currentSpecifier.local) {
|
|
53
|
+
namespaceImportNames.add(currentSpecifier.local.name);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
// the local name each imported icon is available under, so we can point usages of a
|
|
57
|
+
// deprecated icon at an existing import of its fallback instead of importing it twice
|
|
58
|
+
const localNamesByImport = {};
|
|
59
|
+
nodePath.value.specifiers.forEach(currentSpecifier => {
|
|
60
|
+
var _a;
|
|
61
|
+
if (currentSpecifier.type === 'ImportSpecifier' &&
|
|
62
|
+
!migrations[currentSpecifier.imported.name]) {
|
|
63
|
+
localNamesByImport[currentSpecifier.imported.name] =
|
|
64
|
+
((_a = currentSpecifier.local) === null || _a === void 0 ? void 0 : _a.name) || currentSpecifier.imported.name;
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
nodePath.value.specifiers = nodePath.value.specifiers.filter(currentSpecifier => {
|
|
68
|
+
var _a;
|
|
69
|
+
if (currentSpecifier.type !== 'ImportSpecifier') {
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
const renamed = migrations[currentSpecifier.imported.name];
|
|
73
|
+
if (!renamed) {
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
const localName = ((_a = currentSpecifier.local) === null || _a === void 0 ? void 0 : _a.name) || currentSpecifier.imported.name;
|
|
77
|
+
const existingLocalName = localNamesByImport[renamed];
|
|
78
|
+
// the fallback is already imported, so drop this specifier and send its usages to the
|
|
79
|
+
// existing local name
|
|
80
|
+
if (existingLocalName) {
|
|
81
|
+
if (existingLocalName !== localName) {
|
|
82
|
+
usageRenameMap[localName] = existingLocalName;
|
|
83
|
+
}
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
// if imported with an alias, retain the alias as the local so usages don't have to change
|
|
87
|
+
const alias = localName !== currentSpecifier.imported.name ? currentSpecifier.local : null;
|
|
88
|
+
if (!alias) {
|
|
89
|
+
usageRenameMap[localName] = renamed;
|
|
90
|
+
}
|
|
91
|
+
localNamesByImport[renamed] = alias ? localName : renamed;
|
|
92
|
+
currentSpecifier.imported = j.identifier(renamed);
|
|
93
|
+
currentSpecifier.local = alias || j.identifier(renamed);
|
|
94
|
+
return true;
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
// rename usages of icons imported by name
|
|
99
|
+
root
|
|
100
|
+
.find(j.Identifier, { name: (name) => name in usageRenameMap })
|
|
101
|
+
.filter(nodePath => {
|
|
102
|
+
const parent = nodePath.parent.value;
|
|
103
|
+
// an identifier in a name position, i.e. `config.undoIcon` or `{undoIcon: true}`, only
|
|
104
|
+
// happens to match the icon's name and isn't a reference to the import
|
|
105
|
+
if ((parent.type === 'MemberExpression' || parent.type === 'OptionalMemberExpression') &&
|
|
106
|
+
!parent.computed) {
|
|
107
|
+
return parent.property !== nodePath.value;
|
|
108
|
+
}
|
|
109
|
+
if ((parent.type === 'Property' || parent.type === 'ObjectProperty') &&
|
|
110
|
+
!parent.computed &&
|
|
111
|
+
!parent.shorthand) {
|
|
112
|
+
return parent.key !== nodePath.value;
|
|
113
|
+
}
|
|
114
|
+
return true;
|
|
115
|
+
})
|
|
116
|
+
.replaceWith(nodePath => j.identifier(usageRenameMap[nodePath.value.name]));
|
|
117
|
+
// rename usages of icons accessed off a namespace import, i.e. `systemIcons.academicAppointmentTitleIcon`
|
|
118
|
+
root
|
|
119
|
+
.find(j.MemberExpression, {
|
|
120
|
+
computed: false,
|
|
121
|
+
object: { type: 'Identifier' },
|
|
122
|
+
property: { type: 'Identifier' },
|
|
123
|
+
})
|
|
124
|
+
.replaceWith(nodePath => {
|
|
125
|
+
const { object, property } = nodePath.value;
|
|
126
|
+
if (object.type === 'Identifier' &&
|
|
127
|
+
property.type === 'Identifier' &&
|
|
128
|
+
namespaceImportNames.has(object.name) &&
|
|
129
|
+
migrations[property.name]) {
|
|
130
|
+
return j.memberExpression(object, j.identifier(migrations[property.name]), false);
|
|
131
|
+
}
|
|
132
|
+
return nodePath.value;
|
|
133
|
+
});
|
|
134
|
+
return root.toSource({ objectCurlySpacing: false });
|
|
135
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Collection, JSCodeshift } from 'jscodeshift';
|
|
2
|
+
export declare function getImportRenameMap(j: JSCodeshift, root: Collection<any>, mainPackage?: string, packageName?: string): {
|
|
3
|
+
containsCanvasImports: boolean;
|
|
4
|
+
importMap: Record<string, string>;
|
|
5
|
+
styledMap: Record<string, string>;
|
|
6
|
+
};
|
|
7
|
+
//# sourceMappingURL=getImportRenameMap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getImportRenameMap.d.ts","sourceRoot":"","sources":["../../../../lib/icon-migration/utils/getImportRenameMap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,UAAU,EAAE,WAAW,EAAC,MAAM,aAAa,CAAC;AAEpE,wBAAgB,kBAAkB,CAChC,CAAC,EAAE,WAAW,EACd,IAAI,EAAE,UAAU,CAAC,GAAG,CAAC,EACrB,WAAW,SAAqC,EAChD,WAAW,SAAK;;;;EA2DjB"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export function getImportRenameMap(j, root, mainPackage = '@workday/canvas-system-icons-web', packageName = '') {
|
|
2
|
+
let containsCanvasImports = false;
|
|
3
|
+
// build import name remapping - in case someone renamed imports...
|
|
4
|
+
// i.e. `import { IconButton as StyledIconButton } ...`
|
|
5
|
+
const importMap = {};
|
|
6
|
+
const styledMap = {};
|
|
7
|
+
root.find(j.ImportDeclaration, node => {
|
|
8
|
+
// imports our module
|
|
9
|
+
const value = node.source.value;
|
|
10
|
+
if (typeof value === 'string' &&
|
|
11
|
+
(value === mainPackage || value.startsWith(mainPackage) || value === packageName)) {
|
|
12
|
+
containsCanvasImports = true;
|
|
13
|
+
(node.specifiers || []).forEach(specifier => {
|
|
14
|
+
if (specifier.type === 'ImportSpecifier') {
|
|
15
|
+
if (!specifier.local || specifier.local.name === specifier.imported.name) {
|
|
16
|
+
importMap[specifier.imported.name] = specifier.imported.name;
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
importMap[specifier.imported.name] = specifier.local.name;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
return false;
|
|
25
|
+
});
|
|
26
|
+
root
|
|
27
|
+
.find(j.CallExpression, (node) => node.callee.type === 'Identifier' &&
|
|
28
|
+
node.callee.name === 'styled' &&
|
|
29
|
+
node.arguments[0].type === 'Identifier')
|
|
30
|
+
.forEach(nodePath => {
|
|
31
|
+
// const StyledName = styled(OriginalName)({})
|
|
32
|
+
// const StyledName = styled(OriginalName)`` // Tagged template
|
|
33
|
+
if ((nodePath.parent.value.type === 'CallExpression' ||
|
|
34
|
+
nodePath.parent.value.type === 'TaggedTemplateExpression') &&
|
|
35
|
+
nodePath.parent.parent.value.type === 'VariableDeclarator' &&
|
|
36
|
+
nodePath.parent.parent.value.id.type === 'Identifier') {
|
|
37
|
+
const styledName = nodePath.parent.parent.value.id.name;
|
|
38
|
+
if (nodePath.value.arguments &&
|
|
39
|
+
nodePath.value.arguments.length &&
|
|
40
|
+
nodePath.value.arguments[0].type === 'Identifier') {
|
|
41
|
+
styledMap[nodePath.value.arguments[0].name] = styledName;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
return { containsCanvasImports, importMap, styledMap };
|
|
46
|
+
}
|
package/index.js
CHANGED
|
@@ -145,6 +145,17 @@ const {
|
|
|
145
145
|
describe: chalk.gray('The path to execute the transform in (recursively).'),
|
|
146
146
|
});
|
|
147
147
|
})
|
|
148
|
+
.command(
|
|
149
|
+
'icon-migration [path]',
|
|
150
|
+
chalk.gray('Deprecated system icons migration transform'),
|
|
151
|
+
yargs => {
|
|
152
|
+
yargs.positional('path', {
|
|
153
|
+
type: 'string',
|
|
154
|
+
default: '.',
|
|
155
|
+
describe: chalk.gray('The path to execute the transform in (recursively).'),
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
)
|
|
148
159
|
.demandCommand(1, chalk.red.bold('You must provide a transform to apply.'))
|
|
149
160
|
.strictCommands()
|
|
150
161
|
.fail((msg, err, yargs) => {
|
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": "16.0.0-alpha.
|
|
5
|
+
"version": "16.0.0-alpha.0499-next.0",
|
|
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,
|
|
@@ -29,13 +29,17 @@
|
|
|
29
29
|
"url": "https://github.com/Workday/canvas-kit/issues"
|
|
30
30
|
},
|
|
31
31
|
"homepage": "https://github.com/Workday/canvas-kit#readme",
|
|
32
|
+
"peerDependencies": {
|
|
33
|
+
"@workday/canvas-system-icons-web": "^5.0.3"
|
|
34
|
+
},
|
|
32
35
|
"dependencies": {
|
|
33
36
|
"chalk": "4.1.2",
|
|
34
37
|
"jscodeshift": "^17.1.0",
|
|
35
38
|
"yargs": "^16.2.0"
|
|
36
39
|
},
|
|
37
40
|
"devDependencies": {
|
|
38
|
-
"@types/jscodeshift": "^0.11.3"
|
|
41
|
+
"@types/jscodeshift": "^0.11.3",
|
|
42
|
+
"@workday/canvas-system-icons-web": "^5.0.3"
|
|
39
43
|
},
|
|
40
44
|
"scripts": {
|
|
41
45
|
"clean": "rimraf dist && rimraf .build-info && mkdirp dist",
|
|
@@ -46,5 +50,5 @@
|
|
|
46
50
|
"resolutions": {
|
|
47
51
|
"recast": "0.20.4"
|
|
48
52
|
},
|
|
49
|
-
"gitHead": "
|
|
53
|
+
"gitHead": "cd5cbb846495120a4bffea4ee17b3b0a482e68c0"
|
|
50
54
|
}
|