-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathimport-absolute.js
More file actions
93 lines (76 loc) · 2.25 KB
/
Copy pathimport-absolute.js
File metadata and controls
93 lines (76 loc) · 2.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import path from 'path';
import {
applySpec,
ascend,
compose,
descend,
identity,
indexOf,
lensPath,
map,
nth,
prop,
propOr,
replace,
reverse,
set,
sortWith,
takeLast,
when,
} from 'ramda';
import resolveImportType from 'eslint-plugin-import/lib/core/importType';
// Get the import type via `eslint-plugin-import`
const getType = x => resolveImportType(x, { report: () => ({}), settings: {} });
// Airbnb sorting order
const order = ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'];
// Sort imports on type and then by name
const sortImports = sortWith([
descend(([, x]) => indexOf(x, reverse(order), x)),
ascend(([x]) => x.source.value),
]);
// Last 3 items of order should be absolute paths
const shouldReplace = type => takeLast(3, order).includes(type);
// Function to rename the import value
const renamePath = (filePath, modifier) => p => {
const importValue = p.source.value;
const importType = getType(importValue);
if (shouldReplace(importType)) {
const absolutePath = path.join(filePath, importValue);
return set(lensPath(['source', 'value']), modifier(absolutePath), p);
}
return p;
};
// Options with defaults
const getOptions = applySpec({
absolutePath: prop('absolutePath'),
replace: prop('replace'),
replaceWith: propOr('', 'replaceWith'),
sort: propOr(true, 'sort'),
});
export default (file, api, options) => {
const j = api.jscodeshift;
const root = j(file.source);
const opts = getOptions(options);
const modifier = opts.replace
? replace(opts.replace, opts.replaceWith)
: identity;
const currDir = process.cwd();
// Get absolute path
const filePath = compose(
when(() => opts.absolutePath, replace(currDir, opts.absolutePath)),
x => path.resolve(currDir, path.dirname(x.path))
)(file);
const imports = root.find(j.ImportDeclaration);
// Rename imports with absolute path, also sort if option given
const newImports = compose(
map(compose(renamePath(filePath, modifier), nth(0))),
opts.sort ? sortImports : identity,
map(x => [x, getType(x.source.value)]),
x => x.nodes()
)(imports);
// Insert new imports
j(imports.at(0).get()).insertBefore(newImports);
// Remove old imports
imports.remove();
return root.toSource();
};