UNPKG

3.75 kBPlain TextView Raw
1/* eslint-disable flowtype/require-valid-file-annotation */
2/*
3WIP This codemod was build during shipit it's changes should be carefully scrutinized before shipping ;)
4*/
5
6const themeIndexImports = [
7 'themed',
8 'withTheme',
9 'AtlaskitThemeProvider',
10 'getTheme',
11 'createTheme',
12 'GlobalThemeTokens',
13 'ThemeProp',
14];
15
16const constants = [
17 'gridSize',
18 'FLATTENED',
19 'CHANNEL',
20 'DEFAULT_THEME_MODE',
21 'THEME_MODES',
22 'borderRadius',
23 'gridSize',
24 'fontSize',
25 'fontSizeSmall',
26 'fontFamily',
27 'codeFontFamily',
28 'focusRing',
29 'noFocusRing',
30 'layers',
31 'assistive',
32];
33
34const akTheme = '@kalamazoo/theme';
35
36const constantsPredicate = (specifier: any) =>
37 !specifier ||
38 !specifier.imported ||
39 constants.indexOf(specifier.imported.name) > -1;
40
41function getConstantsImport(j: any, path: any) {
42 const constantsSpecifierspath = path.value.specifiers.filter(
43 constantsPredicate,
44 );
45
46 if (constantsSpecifierspath.length === 0) {
47 return null;
48 }
49
50 return j.importDeclaration(
51 constantsSpecifierspath,
52 j.literal(`${akTheme}/constants`),
53 );
54}
55const indexPredicate = (specifier: any) =>
56 !specifier ||
57 !specifier.imported ||
58 themeIndexImports.indexOf(specifier.imported.name) > -1;
59
60function getIndexImport(j: any, path: any) {
61 const mainIndexSpecifierspath = path.value.specifiers.filter(indexPredicate);
62
63 if (mainIndexSpecifierspath.length === 0) {
64 return null;
65 }
66
67 return j.importDeclaration(
68 mainIndexSpecifierspath,
69 j.literal(`${akTheme}/components`),
70 );
71}
72
73function getUsesOfImport(j: any, fileSource: any, importVarname: any) {
74 return fileSource
75 .find(j.MemberExpression)
76 .filter((spec: any) => spec.value.object.name === importVarname);
77}
78
79function getOtherImports(j: any, path: any, fileSource: any) {
80 return path.value.specifiers
81 .filter(
82 (specifier: any) =>
83 !indexPredicate(specifier) && !constantsPredicate(specifier),
84 )
85 .map((specifier: any) => {
86 const usesOfImport = getUsesOfImport(j, fileSource, specifier.local.name);
87
88 if (usesOfImport.size() > 0 && usesOfImport.size() < 7) {
89 const importSpecifiers: any[] = [];
90 const names: any[] = [];
91
92 usesOfImport.forEach((lowerPath: any) => {
93 // Make stupid lint rule happy
94 const propertyName = lowerPath.value.property.name;
95 if (!names.includes(propertyName)) {
96 names.push(propertyName);
97 }
98
99 j(lowerPath).replaceWith(j.identifier(lowerPath.value.property.name));
100 });
101
102 names.forEach(name => {
103 importSpecifiers.push(j.importSpecifier(j.identifier(name)));
104 });
105
106 return j.importDeclaration(
107 importSpecifiers,
108 j.literal(`${akTheme}/${specifier.imported.name}`),
109 );
110 }
111
112 return j.importDeclaration(
113 [j.importNamespaceSpecifier(j.identifier(specifier.local.name))],
114 j.literal(`${akTheme}/${specifier.imported.name}`),
115 );
116 });
117}
118
119export default function transformer(file: any, api: any) {
120 const j = api.jscodeshift;
121 const fileSource = j(file.source);
122
123 // Fixup imports
124 fileSource
125 .find(j.ImportDeclaration)
126 .filter((path: any) => path.node.source.value === akTheme)
127 .forEach((path: any) => {
128 const otherImports = getOtherImports(j, path, fileSource);
129 const [firstImport, ...importsAfter] = [
130 getIndexImport(j, path),
131 getConstantsImport(j, path),
132 ...otherImports,
133 ].filter(importStat => importStat);
134
135 if (!firstImport) {
136 return;
137 }
138
139 firstImport.comments = path.value.comments;
140
141 j(path)
142 .replaceWith(firstImport)
143 .insertAfter(importsAfter);
144 });
145
146 return fileSource.toSource();
147}