@atlaskit/codemod-cli 0.11.3 → 0.11.5
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 +13 -0
- package/dist/cjs/cli.js +0 -10
- package/dist/cjs/filepath.js +1 -15
- package/dist/cjs/index.js +0 -3
- package/dist/cjs/main.js +7 -113
- package/dist/cjs/presets/css-to-design-tokens/css-to-design-tokens.js +21 -70
- package/dist/cjs/presets/css-to-design-tokens/utils/legacy-colors.js +0 -1
- package/dist/cjs/presets/css-to-design-tokens/utils/meta.js +0 -10
- package/dist/cjs/presets/index.js +1 -6
- package/dist/cjs/presets/styled-to-emotion/styled-to-emotion.js +1 -6
- package/dist/cjs/presets/theme-to-design-tokens/theme-to-design-tokens.js +4 -23
- package/dist/cjs/presets/theme-to-design-tokens/utils/ast-meta.js +2 -16
- package/dist/cjs/presets/theme-to-design-tokens/utils/ast.js +0 -2
- package/dist/cjs/presets/theme-to-design-tokens/utils/color.js +2 -17
- package/dist/cjs/presets/theme-to-design-tokens/utils/fuzzy-search.js +38 -96
- package/dist/cjs/presets/theme-to-design-tokens/utils/tokens.js +0 -6
- package/dist/cjs/sinceRef.js +2 -23
- package/dist/cjs/transforms.js +4 -31
- package/dist/cjs/types.js +0 -19
- package/dist/cjs/utils.js +1 -14
- package/dist/cjs/version.json +1 -1
- package/dist/es2019/filepath.js +7 -5
- package/dist/es2019/main.js +17 -51
- package/dist/es2019/presets/css-to-design-tokens/css-to-design-tokens.js +19 -51
- package/dist/es2019/presets/css-to-design-tokens/utils/legacy-colors.js +0 -1
- package/dist/es2019/presets/css-to-design-tokens/utils/meta.js +0 -6
- package/dist/es2019/presets/index.js +1 -1
- package/dist/es2019/presets/styled-to-emotion/styled-to-emotion.js +1 -4
- package/dist/es2019/presets/theme-to-design-tokens/theme-to-design-tokens.js +4 -14
- package/dist/es2019/presets/theme-to-design-tokens/utils/ast-meta.js +2 -11
- package/dist/es2019/presets/theme-to-design-tokens/utils/color.js +2 -7
- package/dist/es2019/presets/theme-to-design-tokens/utils/fuzzy-search.js +38 -95
- package/dist/es2019/presets/theme-to-design-tokens/utils/tokens.js +0 -1
- package/dist/es2019/sinceRef.js +2 -11
- package/dist/es2019/transforms.js +3 -13
- package/dist/es2019/types.js +1 -0
- package/dist/es2019/utils.js +1 -12
- package/dist/es2019/version.json +1 -1
- package/dist/esm/cli.js +0 -2
- package/dist/esm/filepath.js +1 -9
- package/dist/esm/main.js +7 -98
- package/dist/esm/presets/css-to-design-tokens/css-to-design-tokens.js +22 -58
- package/dist/esm/presets/css-to-design-tokens/utils/legacy-colors.js +0 -1
- package/dist/esm/presets/css-to-design-tokens/utils/meta.js +0 -6
- package/dist/esm/presets/index.js +1 -1
- package/dist/esm/presets/styled-to-emotion/styled-to-emotion.js +1 -4
- package/dist/esm/presets/theme-to-design-tokens/theme-to-design-tokens.js +4 -15
- package/dist/esm/presets/theme-to-design-tokens/utils/ast-meta.js +2 -11
- package/dist/esm/presets/theme-to-design-tokens/utils/color.js +2 -7
- package/dist/esm/presets/theme-to-design-tokens/utils/fuzzy-search.js +38 -95
- package/dist/esm/presets/theme-to-design-tokens/utils/tokens.js +0 -1
- package/dist/esm/sinceRef.js +2 -16
- package/dist/esm/transforms.js +4 -14
- package/dist/esm/types.js +1 -11
- package/dist/esm/utils.js +1 -12
- package/dist/esm/version.json +1 -1
- package/package.json +3 -3
package/dist/cjs/utils.js
CHANGED
|
@@ -4,61 +4,48 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.fixLineEnding = void 0;
|
|
7
|
-
|
|
8
7
|
/* Utility functions to be used in codemod-cli. */
|
|
8
|
+
|
|
9
9
|
var returnLineEnding = function returnLineEnding(source) {
|
|
10
10
|
var cr = source.split('\r').length;
|
|
11
11
|
var lf = source.split('\n').length;
|
|
12
12
|
var crlf = source.split('\r\n').length;
|
|
13
|
-
|
|
14
13
|
if (cr + lf === 0) {
|
|
15
14
|
return 'NONE';
|
|
16
15
|
}
|
|
17
|
-
|
|
18
16
|
if (crlf === cr && crlf === lf) {
|
|
19
17
|
return 'CRLF';
|
|
20
18
|
}
|
|
21
|
-
|
|
22
19
|
if (cr > lf) {
|
|
23
20
|
return 'CR';
|
|
24
21
|
} else {
|
|
25
22
|
return 'LF';
|
|
26
23
|
}
|
|
27
24
|
};
|
|
28
|
-
|
|
29
25
|
var getLineEndingRegex = function getLineEndingRegex(type) {
|
|
30
26
|
if (['CR', 'LF', 'CRLF'].indexOf(type) === -1) {
|
|
31
27
|
throw new Error("Line ending '" + type + "' is not supported, use CR, LF or CRLF");
|
|
32
28
|
}
|
|
33
|
-
|
|
34
29
|
if (type === 'LF') {
|
|
35
30
|
return '\n';
|
|
36
31
|
}
|
|
37
|
-
|
|
38
32
|
if (type === 'CR') {
|
|
39
33
|
return '\r';
|
|
40
34
|
}
|
|
41
|
-
|
|
42
35
|
if (type === 'CRLF') {
|
|
43
36
|
return '\r\n';
|
|
44
37
|
}
|
|
45
38
|
};
|
|
46
|
-
|
|
47
39
|
var fixLineEnding = function fixLineEnding(source, lineEnding) {
|
|
48
40
|
var current = returnLineEnding(source);
|
|
49
|
-
|
|
50
41
|
if (current === lineEnding) {
|
|
51
42
|
return source;
|
|
52
43
|
}
|
|
53
|
-
|
|
54
44
|
var regexCurrentLineEnding = getLineEndingRegex(current);
|
|
55
45
|
var regexLineEnding = getLineEndingRegex(lineEnding);
|
|
56
|
-
|
|
57
46
|
if (current && regexLineEnding && regexCurrentLineEnding) {
|
|
58
47
|
return source.replace(new RegExp(regexCurrentLineEnding, 'g'), regexLineEnding);
|
|
59
48
|
}
|
|
60
|
-
|
|
61
49
|
return source;
|
|
62
50
|
};
|
|
63
|
-
|
|
64
51
|
exports.fixLineEnding = fixLineEnding;
|
package/dist/cjs/version.json
CHANGED
package/dist/es2019/filepath.js
CHANGED
|
@@ -3,30 +3,32 @@ import { promises } from 'fs';
|
|
|
3
3
|
const {
|
|
4
4
|
readFile
|
|
5
5
|
} = promises;
|
|
6
|
-
/** Return products packages filePaths for running codemods from specified dependent package */
|
|
7
6
|
|
|
7
|
+
/** Return products packages filePaths for running codemods from specified dependent package */
|
|
8
8
|
export async function findDependentPackagePaths(crawlPaths, dependencyPackage) {
|
|
9
9
|
// Get file paths leading to package.jsons
|
|
10
10
|
const searchStrings = crawlPaths.map(crawlPath => {
|
|
11
11
|
//Replace leading './' due to bug with node-glob not properly ignoring files https://github.com/isaacs/node-glob/issues/309
|
|
12
12
|
return `${crawlPath.replace(/^\.\//, '')}/**/package.json`;
|
|
13
|
-
});
|
|
13
|
+
});
|
|
14
14
|
|
|
15
|
+
// Convert array into glob string
|
|
15
16
|
const globString = searchStrings.length > 1 ? `{${searchStrings.join(',')}}` : searchStrings[0];
|
|
16
17
|
const packageJsonPaths = glob.sync(globString, {
|
|
17
18
|
ignore: '**/node_modules/**',
|
|
18
19
|
nodir: true
|
|
19
20
|
});
|
|
20
21
|
let productPackageJsonPathPromises = packageJsonPaths.map(async filePath => {
|
|
21
|
-
const fileContents = readFile(filePath, 'utf8');
|
|
22
|
-
|
|
22
|
+
const fileContents = readFile(filePath, 'utf8');
|
|
23
|
+
// Grep for installedPackage
|
|
23
24
|
const isMatch = (await fileContents).toString().split(/\n/).some(function (line) {
|
|
24
25
|
return line.match(dependencyPackage);
|
|
25
26
|
});
|
|
26
27
|
return isMatch && filePath;
|
|
27
28
|
});
|
|
28
|
-
const productPackageJsonPaths = (await Promise.all(productPackageJsonPathPromises)).filter(path => path !== false);
|
|
29
|
+
const productPackageJsonPaths = (await Promise.all(productPackageJsonPathPromises)).filter(path => path !== false);
|
|
29
30
|
|
|
31
|
+
// Get directory
|
|
30
32
|
const productPackagePaths = productPackageJsonPaths.map(line => line.replace('/package.json', ''));
|
|
31
33
|
return productPackagePaths;
|
|
32
34
|
}
|
package/dist/es2019/main.js
CHANGED
|
@@ -3,40 +3,35 @@ import fs from 'fs';
|
|
|
3
3
|
import spawn from 'projector-spawn';
|
|
4
4
|
import { AutoComplete } from 'enquirer';
|
|
5
5
|
import semver from 'semver';
|
|
6
|
-
|
|
7
6
|
const jscodeshift = require.resolve('.bin/jscodeshift');
|
|
8
|
-
|
|
9
7
|
import { fixLineEnding } from './utils';
|
|
10
8
|
import { getTransforms, getTransformPath, hasTransform, parseTransformPath, getTransformModule } from './transforms';
|
|
11
9
|
import { ValidationError, NoTransformsExistError } from './types';
|
|
12
10
|
import { getPackagesSinceRef } from './sinceRef';
|
|
13
11
|
import { findDependentPackagePaths } from './filepath';
|
|
14
|
-
|
|
15
12
|
const applyTransformMeta = transforms => transforms.map(transform => {
|
|
16
13
|
const moduleMatch = transform.dir.match(/\/@atlaskit\/[^\/]+\//);
|
|
17
|
-
|
|
18
14
|
if (moduleMatch) {
|
|
19
15
|
const moduleName = moduleMatch[0].substring(1, moduleMatch[0].length - 1);
|
|
20
16
|
const transformName = transform.name === 'index' ? transform.dir.slice(transform.dir.lastIndexOf('/') + 1) : transform.name;
|
|
21
|
-
return {
|
|
17
|
+
return {
|
|
18
|
+
...transform,
|
|
22
19
|
id: `${moduleName}: ${transformName}`
|
|
23
20
|
};
|
|
24
21
|
}
|
|
25
|
-
|
|
26
22
|
const presetMatch = transform.dir.match(/\/codemod-cli\/.+\/presets/);
|
|
27
|
-
|
|
28
23
|
if (presetMatch) {
|
|
29
24
|
const transformName = transform.name === 'index' ? transform.dir.slice(transform.dir.lastIndexOf('/') + 1) : transform.name;
|
|
30
|
-
return {
|
|
25
|
+
return {
|
|
26
|
+
...transform,
|
|
31
27
|
id: `@atlaskit/codemod-cli: ${transformName}`
|
|
32
28
|
};
|
|
33
29
|
}
|
|
34
|
-
|
|
35
|
-
|
|
30
|
+
return {
|
|
31
|
+
...transform,
|
|
36
32
|
id: `${transform.dir}/${transform.name}`
|
|
37
33
|
};
|
|
38
34
|
});
|
|
39
|
-
|
|
40
35
|
const getTransformPrompt = async transforms => {
|
|
41
36
|
const transformMeta = applyTransformMeta(transforms);
|
|
42
37
|
return await new AutoComplete({
|
|
@@ -53,13 +48,11 @@ const getTransformPrompt = async transforms => {
|
|
|
53
48
|
}) => id === choice || dir === choice)
|
|
54
49
|
}).run();
|
|
55
50
|
};
|
|
56
|
-
|
|
57
51
|
const resolveTransform = async (flags, transforms) => {
|
|
58
52
|
if (flags.preset) {
|
|
59
53
|
const transform = transforms.find(({
|
|
60
54
|
name
|
|
61
55
|
}) => name === flags.preset);
|
|
62
|
-
|
|
63
56
|
if (!transform) {
|
|
64
57
|
console.warn(`No preset found for: ${chalk.bgRed(flags.preset)}`);
|
|
65
58
|
} else {
|
|
@@ -70,25 +63,20 @@ const resolveTransform = async (flags, transforms) => {
|
|
|
70
63
|
if (flags.transform && hasTransform(flags.transform)) {
|
|
71
64
|
return parseTransformPath(flags.transform);
|
|
72
65
|
}
|
|
73
|
-
|
|
74
66
|
if (flags.transform && !hasTransform(flags.transform)) {
|
|
75
67
|
console.warn(`No available transform found for: ${chalk.bgRed(flags.transform)}`);
|
|
76
68
|
}
|
|
77
|
-
|
|
78
69
|
return await getTransformPrompt(transforms);
|
|
79
70
|
};
|
|
80
|
-
|
|
81
71
|
const runTransform = async (filePaths, transform, flags) => {
|
|
82
72
|
const {
|
|
83
73
|
logger
|
|
84
74
|
} = flags;
|
|
85
75
|
logger.log(chalk.green(`Running transform '${chalk.bold(transform.name)}' over ${chalk.bold(filePaths.join(', '))}...`));
|
|
86
76
|
let codemodDirs = filePaths;
|
|
87
|
-
|
|
88
77
|
if (flags.filterPaths) {
|
|
89
78
|
logger.log(chalk.green(`Running filtering logic for module ${transform.module}...`));
|
|
90
79
|
codemodDirs = await findDependentPackagePaths(filePaths, transform.module);
|
|
91
|
-
|
|
92
80
|
if (codemodDirs.length === 0) {
|
|
93
81
|
// Fallback to non-filter logic if filtering returns no directories
|
|
94
82
|
logger.log(chalk.yellow(`Could not filter source paths for ${transform.module}, falling back to running over all specified paths. (See --no-filter-paths flag)`));
|
|
@@ -97,19 +85,18 @@ const runTransform = async (filePaths, transform, flags) => {
|
|
|
97
85
|
logger.log(chalk.green(`Running transform '${chalk.bold(transform.name)}' over filtered dirs ${chalk.bold(codemodDirs.join(', '))}...`));
|
|
98
86
|
}
|
|
99
87
|
}
|
|
100
|
-
|
|
101
88
|
logger.log(chalk.green(`Transforming files matching these extensions '${chalk.bold(flags.extensions)}'...`));
|
|
102
|
-
const transformPath = getTransformPath(transform);
|
|
89
|
+
const transformPath = getTransformPath(transform);
|
|
103
90
|
|
|
91
|
+
// Limit CPUs to 8 to prevent issues when running on CI with a large amount of cpus
|
|
104
92
|
const args = [`--transform=${transformPath}`, `--ignore-pattern=${flags.ignorePattern}`, `--parser=${flags.parser}`, `--extensions=${flags.extensions}`, '--cpus=8', ...codemodDirs];
|
|
105
|
-
|
|
106
93
|
if (flags.failOnError) {
|
|
107
94
|
args.unshift('--fail-on-error');
|
|
108
|
-
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// To avoid https://github.com/facebook/jscodeshift/issues/424 where the jscodeshift.js file is `CRLF` ending.
|
|
109
98
|
// The workaround to use only the `node_modules` indicated in this ticket will not work as we run this code as CLI in products repository
|
|
110
99
|
// that may not have jscodeshift installed.
|
|
111
|
-
|
|
112
|
-
|
|
113
100
|
const jscodeshiftContent = fs.readFileSync(jscodeshift, 'utf8');
|
|
114
101
|
const jscodeshiftContentNew = fixLineEnding(jscodeshiftContent, 'LF');
|
|
115
102
|
fs.writeFileSync(jscodeshift, jscodeshiftContentNew);
|
|
@@ -117,40 +104,32 @@ const runTransform = async (filePaths, transform, flags) => {
|
|
|
117
104
|
stdio: 'inherit'
|
|
118
105
|
});
|
|
119
106
|
};
|
|
120
|
-
|
|
121
107
|
const parsePkg = pkg => {
|
|
122
108
|
if (!pkg.startsWith('@')) {
|
|
123
109
|
throw new ValidationError('Package names must be fully qualified and begin with "@"');
|
|
124
110
|
}
|
|
125
|
-
|
|
126
111
|
let name = pkg;
|
|
127
112
|
let version = null;
|
|
128
113
|
const parts = pkg.split('@');
|
|
129
|
-
|
|
130
114
|
if (parts.length > 2) {
|
|
131
115
|
name = `@${parts[1]}`;
|
|
132
116
|
version = parts[parts.length - 1];
|
|
133
117
|
}
|
|
134
|
-
|
|
135
118
|
return {
|
|
136
119
|
name,
|
|
137
120
|
version
|
|
138
121
|
};
|
|
139
122
|
};
|
|
140
|
-
|
|
141
123
|
const parsePackagesFlag = packages => {
|
|
142
124
|
return packages.split(',').map(parsePkg);
|
|
143
125
|
};
|
|
144
|
-
|
|
145
126
|
const validatePackages = (packages, errorCallback) => {
|
|
146
127
|
if (!packages) {
|
|
147
128
|
return;
|
|
148
129
|
}
|
|
149
|
-
|
|
150
130
|
const errors = [];
|
|
151
131
|
const transformedPackages = packages.map(pkg => {
|
|
152
132
|
let version = null;
|
|
153
|
-
|
|
154
133
|
if (pkg.version != null) {
|
|
155
134
|
if (semver.validRange(pkg.version)) {
|
|
156
135
|
version = semver.valid(semver.minVersion(pkg.version));
|
|
@@ -158,26 +137,21 @@ const validatePackages = (packages, errorCallback) => {
|
|
|
158
137
|
errors.push(`Invalid version "${pkg.version}" for package "${pkg.name}"`);
|
|
159
138
|
}
|
|
160
139
|
}
|
|
161
|
-
|
|
162
|
-
|
|
140
|
+
return {
|
|
141
|
+
...pkg,
|
|
163
142
|
version
|
|
164
143
|
};
|
|
165
144
|
});
|
|
166
|
-
|
|
167
145
|
if (errors.length > 0) {
|
|
168
146
|
errorCallback && errorCallback(errors);
|
|
169
147
|
}
|
|
170
|
-
|
|
171
148
|
return transformedPackages;
|
|
172
149
|
};
|
|
173
|
-
|
|
174
150
|
const parseArgs = async (input, flags) => {
|
|
175
151
|
let packages;
|
|
176
|
-
|
|
177
152
|
if (!input[0]) {
|
|
178
153
|
throw new ValidationError('Please supply a path to the source files you wish to modify');
|
|
179
154
|
}
|
|
180
|
-
|
|
181
155
|
if (flags.packages) {
|
|
182
156
|
const unvalidatedPackages = parsePackagesFlag(flags.packages);
|
|
183
157
|
packages = validatePackages(unvalidatedPackages, errors => {
|
|
@@ -189,12 +163,10 @@ const parseArgs = async (input, flags) => {
|
|
|
189
163
|
throw new Error(`Detected invalid previous versions of packages upgraded since "${flags.sinceRef}". Previous versions must be valid semver.\n${errors.join('\n')}`);
|
|
190
164
|
});
|
|
191
165
|
}
|
|
192
|
-
|
|
193
166
|
return {
|
|
194
167
|
packages
|
|
195
168
|
};
|
|
196
169
|
};
|
|
197
|
-
|
|
198
170
|
const defaultFlags = {
|
|
199
171
|
parser: 'babel',
|
|
200
172
|
extensions: 'js',
|
|
@@ -202,7 +174,8 @@ const defaultFlags = {
|
|
|
202
174
|
logger: console
|
|
203
175
|
};
|
|
204
176
|
export default async function main(input, userFlags) {
|
|
205
|
-
const flags = {
|
|
177
|
+
const flags = {
|
|
178
|
+
...defaultFlags,
|
|
206
179
|
...userFlags
|
|
207
180
|
};
|
|
208
181
|
const logger = flags.logger;
|
|
@@ -213,36 +186,29 @@ export default async function main(input, userFlags) {
|
|
|
213
186
|
_PACKAGE_VERSION_ = '0.0.0-dev'
|
|
214
187
|
} = process.env;
|
|
215
188
|
logger.log(chalk.bgBlue(chalk.black(`📚 Atlassian-Frontend codemod library @ ${_PACKAGE_VERSION_} 📚`)));
|
|
216
|
-
|
|
217
189
|
if (packages && packages.length > 0) {
|
|
218
190
|
logger.log(chalk.gray(`Searching for codemods for newer versions of the following packages: ${packages.map(pkg => `${pkg.name}${pkg.version ? '@' + pkg.version : ''}`)}`));
|
|
219
191
|
}
|
|
220
|
-
|
|
221
192
|
const shouldHavePackages = flags.sinceRef || flags.packages && flags.packages.length > 0;
|
|
222
|
-
|
|
223
193
|
if (shouldHavePackages && (packages === null || packages === void 0 ? void 0 : packages.length) === 0) {
|
|
224
194
|
logger.log(chalk.gray(`Did not find updated packages, exiting`));
|
|
225
195
|
return {
|
|
226
196
|
transforms: []
|
|
227
197
|
};
|
|
228
198
|
}
|
|
229
|
-
|
|
230
199
|
const availableTransforms = getTransforms(packages);
|
|
231
|
-
|
|
232
200
|
if (availableTransforms.length === 0) {
|
|
233
201
|
throw new NoTransformsExistError('No codemods available. Please make sure you have the latest version of the packages you are trying to upgrade before running the codemod');
|
|
234
202
|
}
|
|
235
|
-
|
|
236
203
|
const transforms = packages ? availableTransforms : [await resolveTransform(flags, availableTransforms)];
|
|
237
|
-
const transformsWithModule = transforms.map(transform => ({
|
|
204
|
+
const transformsWithModule = transforms.map(transform => ({
|
|
205
|
+
...transform,
|
|
238
206
|
module: getTransformModule(transform)
|
|
239
207
|
}));
|
|
240
208
|
logger.log(chalk.cyan(`Running the following transforms \n${chalk.bold(transformsWithModule.map(transform => `${transform.module}: ${transform.name}`).join('\n'))}`));
|
|
241
|
-
|
|
242
209
|
for (const transform of transformsWithModule) {
|
|
243
210
|
await runTransform(input, transform, flags);
|
|
244
211
|
}
|
|
245
|
-
|
|
246
212
|
return {
|
|
247
213
|
transforms: transformsWithModule
|
|
248
214
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import postcss from 'postcss';
|
|
2
|
-
|
|
1
|
+
import postcss from 'postcss';
|
|
2
|
+
// @ts-ignore
|
|
3
3
|
import lessSyntax from 'postcss-less';
|
|
4
4
|
import { light as rawTokens } from '@atlaskit/tokens/tokens-raw';
|
|
5
5
|
import designTokens from '@atlaskit/tokens/token-names';
|
|
@@ -8,82 +8,63 @@ import { knownVariables, knownColors, knownRawColors } from './utils/legacy-colo
|
|
|
8
8
|
import { cleanMeta } from './utils/meta';
|
|
9
9
|
const tokens = rawTokens.filter(t => t.attributes.state === 'active').map(t => t.name.replace(/\.\[default\]/g, '')).filter(t => !t.includes('UNSAFE') && !t.includes('interaction'));
|
|
10
10
|
const search = Search(tokens, false);
|
|
11
|
-
|
|
12
11
|
function isRule(node) {
|
|
13
12
|
return node.type === 'rule';
|
|
14
13
|
}
|
|
15
|
-
|
|
16
14
|
function getParentSelectors(node) {
|
|
17
15
|
if (isRule(node)) {
|
|
18
16
|
// @ts-expect-error
|
|
19
17
|
return getParentSelectors(node.parent) + ' ' + node.selector;
|
|
20
18
|
}
|
|
21
|
-
|
|
22
19
|
if (node.parent) {
|
|
23
20
|
return getParentSelectors(node.parent);
|
|
24
21
|
}
|
|
25
|
-
|
|
26
22
|
return '';
|
|
27
23
|
}
|
|
28
|
-
|
|
29
24
|
function stripVar(prop) {
|
|
30
25
|
return prop.substring(prop.indexOf('(') + 1).split(/\,|\)/)[0];
|
|
31
26
|
}
|
|
32
|
-
|
|
33
27
|
function stripLessVar(prop) {
|
|
34
28
|
return prop.substring(1);
|
|
35
29
|
}
|
|
36
|
-
|
|
37
30
|
function isColorProperty(prop) {
|
|
38
31
|
return prop === 'color' || prop === 'background' || prop === 'background-color' || prop === 'box-shadow' || prop === 'border' || prop === 'border-left' || prop === 'border-right' || prop === 'border-top' || prop === 'border-bottom' || prop === 'border-color';
|
|
39
32
|
}
|
|
40
|
-
|
|
41
33
|
function getDeclarationMeta(decl) {
|
|
42
34
|
if (decl.prop === 'color') {
|
|
43
35
|
return 'text';
|
|
44
36
|
}
|
|
45
|
-
|
|
46
37
|
if (decl.prop.startsWith('background')) {
|
|
47
38
|
return 'background';
|
|
48
39
|
}
|
|
49
|
-
|
|
50
40
|
if (decl.prop.includes('shadow')) {
|
|
51
41
|
return 'shadow';
|
|
52
42
|
}
|
|
53
|
-
|
|
54
43
|
if (decl.prop.includes('border')) {
|
|
55
44
|
return 'border';
|
|
56
45
|
}
|
|
57
|
-
|
|
58
46
|
return '';
|
|
59
47
|
}
|
|
60
|
-
|
|
61
48
|
function isDesignToken(tokenName) {
|
|
62
49
|
return Boolean(Object.entries(designTokens).find(([_, value]) => tokenName === value));
|
|
63
50
|
}
|
|
64
|
-
|
|
65
51
|
function getMetaFromCssVar(tokenName) {
|
|
66
52
|
const meta = knownVariables[tokenName];
|
|
67
|
-
|
|
68
53
|
if (!meta || meta.length === 0) {
|
|
69
54
|
return tokenName.split('-');
|
|
70
55
|
}
|
|
71
|
-
|
|
72
56
|
return meta;
|
|
73
57
|
}
|
|
74
|
-
|
|
75
58
|
function getMetaFromRawColor(rawColor) {
|
|
76
59
|
let cleanColor = rawColor.toLowerCase();
|
|
77
|
-
|
|
78
60
|
if (cleanColor.length === 4) {
|
|
79
61
|
cleanColor = cleanColor + cleanColor.substring(cleanColor.indexOf('#') + 1);
|
|
80
62
|
}
|
|
81
|
-
|
|
82
63
|
return knownRawColors[cleanColor];
|
|
83
|
-
}
|
|
84
|
-
// https://astexplorer.net/#/2uBU1BLuJ1
|
|
85
|
-
|
|
64
|
+
}
|
|
86
65
|
|
|
66
|
+
// https://github.com/postcss/postcss/blob/main/docs/writing-a-plugin.md
|
|
67
|
+
// https://astexplorer.net/#/2uBU1BLuJ1
|
|
87
68
|
const plugin = () => {
|
|
88
69
|
const processed = Symbol('processed');
|
|
89
70
|
return {
|
|
@@ -93,80 +74,67 @@ const plugin = () => {
|
|
|
93
74
|
if (decl[processed]) {
|
|
94
75
|
return;
|
|
95
76
|
}
|
|
96
|
-
|
|
97
77
|
if (!isColorProperty(decl.prop)) {
|
|
98
78
|
return;
|
|
99
79
|
}
|
|
100
|
-
|
|
101
80
|
const searchTerms = [getDeclarationMeta(decl), ...getParentSelectors(decl).split(/\-|\.|\,|\ |\:|\&/).filter(el => !!el)];
|
|
102
81
|
let match;
|
|
103
82
|
const cssVarRe = /var\([^\)]+\)/g;
|
|
104
83
|
const lessVarRe = /@[a-zA-Z0-9-]+/g;
|
|
105
|
-
const rawColorRe = /(#([0-9a-f]{3}){1,2}|(rgba|hsla)\(\d{1,3}%?(,\s?\d{1,3}%?){2},\s?(1|0|0?\.\d+)\)|(rgb|hsl)\(\d{1,3}%?(,\s?\d{1,3}%?){2}\))/i;
|
|
84
|
+
const rawColorRe = /(#([0-9a-f]{3}){1,2}|(rgba|hsla)\(\d{1,3}%?(,\s?\d{1,3}%?){2},\s?(1|0|0?\.\d+)\)|(rgb|hsl)\(\d{1,3}%?(,\s?\d{1,3}%?){2}\))/i;
|
|
106
85
|
|
|
86
|
+
// CSS variables
|
|
107
87
|
const cssVarMatch = decl.value.match(cssVarRe);
|
|
108
|
-
|
|
109
88
|
if (cssVarMatch) {
|
|
110
89
|
var _getMetaFromCssVar;
|
|
111
|
-
|
|
112
90
|
match = cssVarMatch[0];
|
|
113
|
-
|
|
114
91
|
if (isDesignToken(stripVar(match))) {
|
|
115
92
|
return;
|
|
116
93
|
}
|
|
117
|
-
|
|
118
94
|
searchTerms.push(...((_getMetaFromCssVar = getMetaFromCssVar(stripVar(match))) !== null && _getMetaFromCssVar !== void 0 ? _getMetaFromCssVar : []));
|
|
119
|
-
}
|
|
120
|
-
|
|
95
|
+
}
|
|
121
96
|
|
|
97
|
+
// Less variables
|
|
122
98
|
const lassVarMatch = decl.value.match(lessVarRe);
|
|
123
|
-
|
|
124
99
|
if (lassVarMatch) {
|
|
125
100
|
var _getMetaFromCssVar2;
|
|
126
|
-
|
|
127
101
|
match = lassVarMatch[0];
|
|
128
102
|
searchTerms.push(...((_getMetaFromCssVar2 = getMetaFromCssVar(`--${stripLessVar(match)}`)) !== null && _getMetaFromCssVar2 !== void 0 ? _getMetaFromCssVar2 : []));
|
|
129
|
-
}
|
|
130
|
-
|
|
103
|
+
}
|
|
131
104
|
|
|
105
|
+
// Raw colors
|
|
132
106
|
const rawColorMatch = decl.value.match(rawColorRe);
|
|
133
|
-
|
|
134
107
|
if (rawColorMatch) {
|
|
135
108
|
var _getMetaFromRawColor;
|
|
136
|
-
|
|
137
109
|
match = rawColorMatch[0];
|
|
138
110
|
searchTerms.push(...((_getMetaFromRawColor = getMetaFromRawColor(match)) !== null && _getMetaFromRawColor !== void 0 ? _getMetaFromRawColor : []));
|
|
139
|
-
}
|
|
140
|
-
|
|
111
|
+
}
|
|
141
112
|
|
|
113
|
+
// Named colors
|
|
142
114
|
if (knownColors.hasOwnProperty(decl.value)) {
|
|
143
115
|
var _knownColors$decl$val;
|
|
144
|
-
|
|
145
116
|
match = decl.value;
|
|
146
117
|
searchTerms.push(...((_knownColors$decl$val = knownColors[decl.value.toLowerCase()]) !== null && _knownColors$decl$val !== void 0 ? _knownColors$decl$val : []));
|
|
147
118
|
}
|
|
148
|
-
|
|
149
119
|
if (!match) {
|
|
150
120
|
console.warn(`Unable to find match for declaration: ${decl.prop}: ${decl.value}`);
|
|
151
121
|
return;
|
|
152
122
|
}
|
|
153
|
-
|
|
154
123
|
const cleanSearchTerms = cleanMeta(searchTerms).join(' ');
|
|
155
124
|
const results = search.get(cleanSearchTerms);
|
|
156
|
-
const
|
|
157
|
-
|
|
125
|
+
const candidates = results.map(result => result[1]);
|
|
126
|
+
const replacement = candidates.length ? designTokens[candidates[0]] : 'MISSING_TOKEN';
|
|
158
127
|
if (decl.prop === 'box-shadow') {
|
|
159
|
-
decl.value = `var(${
|
|
128
|
+
decl.value = `var(${replacement}, ${decl.value})`;
|
|
160
129
|
} else {
|
|
161
|
-
decl.value = decl.value.split(match).join(`var(${
|
|
162
|
-
}
|
|
163
|
-
|
|
130
|
+
decl.value = decl.value.split(match).join(`var(${replacement}, ${match})`);
|
|
131
|
+
}
|
|
164
132
|
|
|
133
|
+
// @ts-expect-error
|
|
165
134
|
decl[processed] = true;
|
|
166
135
|
}
|
|
167
136
|
};
|
|
168
137
|
};
|
|
169
|
-
|
|
170
138
|
export default async function transformer(file) {
|
|
171
139
|
return await postcss([plugin()]).process(file.source, {
|
|
172
140
|
syntax: lessSyntax
|
|
@@ -150,7 +150,6 @@ export const knownVariables = {
|
|
|
150
150
|
'--adg3-color-green-light': ['accent', 'subtler', 'green'],
|
|
151
151
|
'--adg3-color-green-dark': ['accent', 'bolder', 'green'],
|
|
152
152
|
'--adg3-color-N20-transparent': [],
|
|
153
|
-
|
|
154
153
|
/* Alias variables */
|
|
155
154
|
'--jpo-theme-color': ['brand'],
|
|
156
155
|
'--jpo-text-default-color': ['text'],
|
|
@@ -3,10 +3,8 @@ const getUniqueWordsFromTokens = Object.keys(designTokens).reduce((accum, val) =
|
|
|
3
3
|
if (!accum.includes(val)) {
|
|
4
4
|
accum.push(val);
|
|
5
5
|
}
|
|
6
|
-
|
|
7
6
|
return accum;
|
|
8
7
|
}, []);
|
|
9
|
-
|
|
10
8
|
function filterDuplciateFoundations(meta) {
|
|
11
9
|
const foundations = ['text', 'background', 'shadow', 'border'];
|
|
12
10
|
let hasFoundation = false;
|
|
@@ -15,15 +13,12 @@ function filterDuplciateFoundations(meta) {
|
|
|
15
13
|
hasFoundation = true;
|
|
16
14
|
return true;
|
|
17
15
|
}
|
|
18
|
-
|
|
19
16
|
if (hasFoundation && foundations.includes(val)) {
|
|
20
17
|
return false;
|
|
21
18
|
}
|
|
22
|
-
|
|
23
19
|
return true;
|
|
24
20
|
});
|
|
25
21
|
}
|
|
26
|
-
|
|
27
22
|
export function cleanMeta(meta) {
|
|
28
23
|
const cleanMeta = meta.reduce((accum, val) => [...accum, ...(typeof val === 'string' ? val.split(/(?=[A-Z])/g).map(e => e.toLowerCase()) : [])], []).reduce((accum, val) => {
|
|
29
24
|
accum.push(val.replace(/:/g, '').replace(/,/g, '').replace('grey', 'neutral').replace('texts', 'text').replace('red', 'danger').replace('error', 'danger').replace('invalid', 'danger').replace('removed', 'danger').replace('removal', 'danger').replace('remove', 'danger').replace('focus', 'focused').replace('valid', 'success').replace('successful', 'success').replace('risk', 'warning').replace('caution', 'warning').replace('warn', 'warning').replace('primary', 'bold').replace('info', 'bold').replace('secondary', 'subtle').replace('hyperlink', 'link').replace('anchor', 'link').replace('active', 'pressed').replace('hover', 'hovered').replace('dragged', 'overlay').replace('dragging', 'overlay').replace('drag', 'overlay').replace('background-color', 'background').replace('color', 'text').replace('icons', 'icon').replace('arrow', 'icon').replace('glyph', 'icon').replace('stroke', 'border').replace('border-left', 'border').replace('border-right', 'border').replace('border-top', 'border').replace('border-bottom', 'border').replace('box-shadow', 'shadow'));
|
|
@@ -32,7 +27,6 @@ export function cleanMeta(meta) {
|
|
|
32
27
|
if (!accum.includes(val)) {
|
|
33
28
|
accum.push(val);
|
|
34
29
|
}
|
|
35
|
-
|
|
36
30
|
return accum;
|
|
37
31
|
}, []);
|
|
38
32
|
return filterDuplciateFoundations(cleanMeta);
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
|
+
|
|
2
3
|
/**
|
|
3
4
|
* Manually import presets to make sure typescript includes them
|
|
4
5
|
* in the final bundle
|
|
5
6
|
*/
|
|
6
|
-
|
|
7
7
|
import './styled-to-emotion/styled-to-emotion';
|
|
8
8
|
import './theme-to-design-tokens/theme-to-design-tokens';
|
|
9
9
|
import './css-to-design-tokens/css-to-design-tokens';
|
|
@@ -6,12 +6,10 @@ function buildCoreImportDeclaration(j, path) {
|
|
|
6
6
|
});
|
|
7
7
|
return specifiers.length ? j.importDeclaration(specifiers, j.literal('@emotion/core')) : null;
|
|
8
8
|
}
|
|
9
|
-
|
|
10
9
|
function buildStyledImportDeclaration(j, path) {
|
|
11
10
|
const specifier = j(path).find(j.ImportDefaultSpecifier).filter(specifier => specifier.value.local.name === 'styled');
|
|
12
11
|
return specifier && specifier.length ? j.importDeclaration([j.importDefaultSpecifier(j.identifier(specifier.get(0).node.local.name))], j.literal('@emotion/styled')) : null;
|
|
13
12
|
}
|
|
14
|
-
|
|
15
13
|
function buildThemingImportDeclaration(j, path) {
|
|
16
14
|
const themingExports = ['ThemeProvider', 'withTheme'];
|
|
17
15
|
const specifiers = [];
|
|
@@ -20,11 +18,10 @@ function buildThemingImportDeclaration(j, path) {
|
|
|
20
18
|
});
|
|
21
19
|
return specifiers && specifiers.length ? j.importDeclaration(specifiers, j.literal('emotion-theming')) : null;
|
|
22
20
|
}
|
|
21
|
+
|
|
23
22
|
/**
|
|
24
23
|
* Converts all imports of `styled-components` to `@emotion/styled`
|
|
25
24
|
*/
|
|
26
|
-
|
|
27
|
-
|
|
28
25
|
export default function transformer(fileInfo, {
|
|
29
26
|
jscodeshift: j
|
|
30
27
|
}, options) {
|