import-sort-style-custom
Version:
Sort your imports using import-sort with aliases and custom configurations
313 lines (258 loc) • 9.23 kB
JavaScript
import { dirname } from 'path';
import escapeStringRegexp from 'escape-string-regexp';
import { tsconfigResolver, CacheStrategy } from 'tsconfig-resolver';
function _extends() {
_extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
return _extends.apply(this, arguments);
}
var defaultSettings = {
ignoreTsConfig: false,
spaceAfterAliases: true,
tsconfigName: 'tsconfig.json',
tsconfigFilePath: undefined,
cacheStrategy: CacheStrategy.Directory,
wildcardAtStart: false,
ignoredAliases: [],
extraAliases: [],
bottomAliases: []
};
var getSettings = function getSettings(rawSettings) {
if (rawSettings === void 0) {
rawSettings = {};
}
return _extends({}, defaultSettings, {}, rawSettings);
};
/**
* Converts a tsconfig pattern to a RegExp.
*/
var patternToRegExp = function patternToRegExp(pattern) {
return new RegExp(escapeStringRegexp(pattern).replace(/\\\*/g, '.+'));
};
/**
* Creates an isAliasedModule method which is used to check when the import is
* an alias.
*/
var isAliasedModuleCreator = function isAliasedModuleCreator(_ref, config) {
var _ref2, _config$compilerOptio;
var extraAliases = _ref.extraAliases,
wildcardAtStart = _ref.wildcardAtStart,
ignoredAliases = _ref.ignoredAliases;
var cache = new Map();
var regExps = [];
var ignoredRegExps = [];
var paths = (_ref2 = config === null || config === void 0 ? void 0 : (_config$compilerOptio = config.compilerOptions) === null || _config$compilerOptio === void 0 ? void 0 : _config$compilerOptio.paths) !== null && _ref2 !== void 0 ? _ref2 : {}; // Populate the array of aliases
for (var _i = 0, _arr = [].concat(Object.keys(paths), extraAliases); _i < _arr.length; _i++) {
var alias = _arr[_i];
if (!wildcardAtStart && alias.startsWith('*')) {
continue;
}
regExps.push(patternToRegExp(alias));
} // Populate the array of ignored patterns.
for (var _iterator = ignoredAliases, _isArray = Array.isArray(_iterator), _i2 = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
var _ref3;
if (_isArray) {
if (_i2 >= _iterator.length) break;
_ref3 = _iterator[_i2++];
} else {
_i2 = _iterator.next();
if (_i2.done) break;
_ref3 = _i2.value;
}
var _alias = _ref3;
ignoredRegExps.push(patternToRegExp(_alias));
}
var calculateReturn = function calculateReturn(imported) {
// No alias patterns to check. Return false for a negative match.
if (!regExps.length) {
return false;
} // Check to see if the pattern matches the ignored patterns. If this is the
// case return a negative match.
for (var _iterator2 = ignoredRegExps, _isArray2 = Array.isArray(_iterator2), _i3 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
var _ref4;
if (_isArray2) {
if (_i3 >= _iterator2.length) break;
_ref4 = _iterator2[_i3++];
} else {
_i3 = _iterator2.next();
if (_i3.done) break;
_ref4 = _i3.value;
}
var regExp = _ref4;
if (regExp.test(imported.moduleName)) {
return false;
}
} // Check if any alias patterns match the module name then return a positive
// match.
for (var _iterator3 = regExps, _isArray3 = Array.isArray(_iterator3), _i4 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) {
var _ref5;
if (_isArray3) {
if (_i4 >= _iterator3.length) break;
_ref5 = _iterator3[_i4++];
} else {
_i4 = _iterator3.next();
if (_i4.done) break;
_ref5 = _i4.value;
}
var _regExp = _ref5;
if (_regExp.test(imported.moduleName)) {
return true;
}
} // Nothing matched so return a negative match.
return false;
};
return function (imported) {
var cachedValue = cache.get(imported);
if (cachedValue !== undefined) {
return cachedValue;
}
var value = calculateReturn(imported);
cache.set(imported, value);
return value;
};
};
/**
* Creates a function that checks if the imported module should be placed at the
* bottom.
*/
var isBottomModuleCreator = function isBottomModuleCreator(bottomModules) {
var cache = new Map();
var regExps = []; // Populate the array of pattern matchers for bottom modules
for (var _iterator4 = bottomModules, _isArray4 = Array.isArray(_iterator4), _i5 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) {
var _ref6;
if (_isArray4) {
if (_i5 >= _iterator4.length) break;
_ref6 = _iterator4[_i5++];
} else {
_i5 = _iterator4.next();
if (_i5.done) break;
_ref6 = _i5.value;
}
var alias = _ref6;
regExps.push(patternToRegExp(alias));
}
var calculateReturn = function calculateReturn(imported) {
// No patterns to check. Return false to show this is import should not be
// placed at the bottom.
if (!regExps.length) {
return false;
} // Check if any alias patterns match the module name then return a positive
// match.
for (var _iterator5 = regExps, _isArray5 = Array.isArray(_iterator5), _i6 = 0, _iterator5 = _isArray5 ? _iterator5 : _iterator5[Symbol.iterator]();;) {
var _ref7;
if (_isArray5) {
if (_i6 >= _iterator5.length) break;
_ref7 = _iterator5[_i6++];
} else {
_i6 = _iterator5.next();
if (_i6.done) break;
_ref7 = _i6.value;
}
var regExp = _ref7;
if (regExp.test(imported.moduleName)) {
return true;
}
} // Nothing matched so return a negative match.
return false;
};
return function (imported) {
var cachedValue = cache.get(imported);
if (cachedValue !== undefined) {
return cachedValue;
}
var value = calculateReturn(imported);
cache.set(imported, value);
return value;
};
};
/**
* Sort the modules in the following order.
*
* - Imports with no members are left unsorted at the top of the file. These
* tend to have side effects and their order is important. `import 'tolu';`
* - Node module imports. `import { join } from 'path';`
* - Absolute module imports (but not aliased). `import main from 'main';`
* - Aliased imports taken from the `tsconfig.json`
* - Relative module imports
* - Bottom imports, which are set in the settings object as `bottomAliases`
*/
var sortStyleCustom = function sortStyleCustom(styleApi, fileName, rawSettings) {
// console.log({ fileName, settings });
var settings = getSettings(rawSettings);
var config = settings.ignoreTsConfig ? undefined : tsconfigResolver({
cacheStrategy: settings.cacheStrategy,
cwd: fileName ? dirname(fileName) : undefined,
searchName: settings.tsconfigName,
filePath: settings.tsconfigFilePath
}).config;
var isAliasedModule = isAliasedModuleCreator(settings, config);
var isBottomModule = isBottomModuleCreator(settings.bottomAliases);
var alias = styleApi.alias,
and = styleApi.and,
dotSegmentCount = styleApi.dotSegmentCount,
hasNoMember = styleApi.hasNoMember,
isAbsoluteModule = styleApi.isAbsoluteModule,
isNodeModule = styleApi.isNodeModule,
isRelativeModule = styleApi.isRelativeModule,
moduleName = styleApi.moduleName,
naturally = styleApi.naturally,
unicode = styleApi.unicode,
not = styleApi.not;
return [// No member - `import "foo"; import "./foo"; import "$aliased";`
{
match: and(hasNoMember, not(isBottomModule))
}, {
separator: true
}, // Builtin - `import … from "fs";`
{
match: and(isNodeModule, not(isBottomModule)),
sort: moduleName(naturally),
sortNamedMembers: alias(unicode)
}, {
separator: true
}, // Absolute - `import … from "foo";`
{
match: and(isAbsoluteModule, not(isBottomModule), not(isAliasedModule)),
sort: moduleName(naturally),
sortNamedMembers: alias(unicode)
}, {
separator: true
}, // Aliased - `import … from "$aliased";`
{
match: and(not(isRelativeModule), not(isBottomModule), isAliasedModule),
sort: moduleName(naturally),
sortNamedMembers: alias(unicode)
}].concat(settings.spaceAfterAliases ? [{
separator: true
}] : [], [// Relative - `import … from "./foo"; import … from "../foo";`
{
match: and(isRelativeModule, not(isBottomModule)),
sort: [dotSegmentCount, moduleName(naturally)],
sortNamedMembers: alias(unicode)
}, {
separator: true
}, // Bottom
{
match: and(isBottomModule, not(isRelativeModule)),
sort: [dotSegmentCount, moduleName(naturally)],
sortNamedMembers: alias(unicode)
}, // Relative bottom
{
match: isBottomModule,
sort: [dotSegmentCount, moduleName(naturally)],
sortNamedMembers: alias(unicode)
}, {
separator: true
}]);
};
export default sortStyleCustom;
//# sourceMappingURL=import-sort-style-custom.esm.js.map