Socket
Socket
Sign inDemoInstall

@trivago/prettier-plugin-sort-imports

Package Overview
Dependencies
Maintainers
4
Versions
36
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@trivago/prettier-plugin-sort-imports - npm Package Compare versions

Comparing version 2.0.4 to 3.0.0-0

lib/src/utils/__tests__/get-experimental-parser-plugins.spec.js

4

lib/src/constants.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.newLineNode = exports.newLineCharacters = exports.jsx = exports.classProperties = exports.decoratorsLegacy = exports.typescript = exports.flow = void 0;
exports.newLineNode = exports.newLineCharacters = exports.jsx = exports.typescript = exports.flow = void 0;
var types_1 = require("@babel/types");
exports.flow = 'flow';
exports.typescript = 'typescript';
exports.decoratorsLegacy = 'decorators-legacy';
exports.classProperties = 'classProperties';
exports.jsx = 'jsx';

@@ -10,0 +8,0 @@ exports.newLineCharacters = '\n\n';

@@ -19,2 +19,9 @@ "use strict";

var options = {
experimentalBabelParserPluginsList: {
type: 'path',
category: 'Global',
array: true,
default: [{ value: [] }],
description: 'Provide a list of plugins for special syntax',
},
importOrder: {

@@ -27,2 +34,8 @@ type: 'path',

},
importOrderCaseInsensitive: {
type: 'boolean',
category: 'Global',
default: true,
description: 'Provide a case sensitivity boolean flag',
},
importOrderSeparation: {

@@ -34,9 +47,8 @@ type: 'boolean',

},
experimentalBabelParserPluginsList: {
type: 'path',
sortModules: {
type: 'boolean',
category: 'Global',
array: true,
default: [{ value: [] }],
description: 'Provide a list of plugins for special syntax',
}
default: false,
description: 'Should modules be sorted ?',
},
};

@@ -43,0 +55,0 @@ module.exports = {

@@ -18,9 +18,11 @@ "use strict";

var get_parser_plugins_1 = require("./utils/get-parser-plugins");
var get_experimental_parser_plugins_1 = require("./utils/get-experimental-parser-plugins");
function preprocessor(code, options) {
var importOrder = options.importOrder, importOrderSeparation = options.importOrderSeparation, prettierParser = options.parser, _a = options.experimentalBabelParserPluginsList, experimentalBabelParserPluginsList = _a === void 0 ? [] : _a;
var _a = options.experimentalBabelParserPluginsList, experimentalBabelParserPluginsList = _a === void 0 ? [] : _a, importOrder = options.importOrder, importOrderCaseInsensitive = options.importOrderCaseInsensitive, importOrderSeparation = options.importOrderSeparation, prettierParser = options.parser, sortModules = options.sortModules;
var plugins = get_parser_plugins_1.getParserPlugins(prettierParser);
var parsedExperimentalBabelParserPluginsList = get_experimental_parser_plugins_1.getExperimentalParserPlugins(experimentalBabelParserPluginsList);
var importNodes = [];
var parserOptions = {
sourceType: 'module',
plugins: __spreadArray(__spreadArray([], plugins), experimentalBabelParserPluginsList),
plugins: __spreadArray(__spreadArray([], plugins), parsedExperimentalBabelParserPluginsList),
};

@@ -42,5 +44,10 @@ var ast = parser_1.parse(code, parserOptions);

return code;
var allImports = get_sorted_nodes_1.getSortedNodes(importNodes, importOrder, importOrderSeparation);
var allImports = get_sorted_nodes_1.getSortedNodes(importNodes, {
importOrder: importOrder,
importOrderCaseInsensitive: importOrderCaseInsensitive,
importOrderSeparation: importOrderSeparation,
sortModules: sortModules,
});
return get_code_from_ast_1.getCodeFromAst(allImports, code, interpreter);
}
exports.preprocessor = preprocessor;

@@ -35,3 +35,8 @@ "use strict";

});
return get_sorted_nodes_1.getSortedNodes(importNodes, [], false);
return get_sorted_nodes_1.getSortedNodes(importNodes, {
importOrder: [],
importOrderCaseInsensitive: false,
importOrderSeparation: false,
sortModules: false,
});
};

@@ -38,0 +43,0 @@ var getComments = function (commentNodes) {

@@ -41,5 +41,10 @@ "use strict";

var importNodes = getImportNodes(code);
var sortedNodes = get_sorted_nodes_1.getSortedNodes(importNodes, [], false);
var sortedNodes = get_sorted_nodes_1.getSortedNodes(importNodes, {
importOrder: [],
importOrderCaseInsensitive: false,
importOrderSeparation: false,
sortModules: false,
});
var formatted = get_code_from_ast_1.getCodeFromAst(sortedNodes, code, null);
expect(prettier_1.format(formatted, { parser: 'babel' })).toEqual("// first comment\n// second comment\nimport a from \"a\";\nimport c from \"c\";\nimport g from \"g\";\nimport k from \"k\";\nimport t from \"t\";\nimport z from \"z\";\n");
});

@@ -15,8 +15,3 @@ "use strict";

test('it should return ts related plugins', function () {
expect(get_parser_plugins_1.getParserPlugins('typescript')).toEqual([
'typescript',
'jsx',
'decorators-legacy',
'classProperties',
]);
expect(get_parser_plugins_1.getParserPlugins('typescript')).toEqual(['typescript', 'jsx']);
});

@@ -21,3 +21,3 @@ "use strict";

var get_sorted_nodes_1 = require("../get-sorted-nodes");
var code = "// first comment\n// second comment\nimport z from 'z';\nimport c from 'c';\nimport g from 'g';\nimport t from 't';\nimport k from 'k';\nimport a from 'a';\n";
var code = "// first comment\n// second comment\nimport z from 'z';\nimport c, { cD } from 'c';\nimport g from 'g';\nimport { tC, tA, tB } from 't';\nimport k, { kE, kB } from 'k';\nimport * as a from 'a';\nimport BY from 'BY';\nimport Ba from 'Ba';\nimport XY from 'XY';\nimport Xa from 'Xa';\n";
var getImportNodes = function (code, options) {

@@ -43,13 +43,240 @@ var importNodes = [];

}; // TODO: get from specifier
var getSortedNodesModulesNames = function (modules) {
return modules
.filter(function (m) {
return [
'ImportSpecifier',
'ImportDefaultSpecifier',
'ImportNamespaceSpecifier',
].includes(m.type);
})
.map(function (m) { return m.local.name; });
}; // TODO: get from specifier
test('it returns all sorted nodes', function () {
var result = getImportNodes(code);
var sorted = get_sorted_nodes_1.getSortedNodes(result, [], false);
var sorted = get_sorted_nodes_1.getSortedNodes(result, {
importOrder: [],
importOrderCaseInsensitive: false,
importOrderSeparation: false,
sortModules: false,
});
expect(sorted).toMatchSnapshot();
expect(getSortedNodesNames(sorted)).toEqual(['a', 'c', 'g', 'k', 't', 'z']);
expect(getSortedNodesNames(sorted)).toEqual([
'BY',
'Ba',
'XY',
'Xa',
'a',
'c',
'g',
'k',
't',
'z',
]);
expect(sorted
.filter(function (node) { return node.type === 'ImportDeclaration'; })
.map(function (importDeclaration) {
return getSortedNodesModulesNames(importDeclaration.specifiers);
})).toEqual([
['BY'],
['Ba'],
['XY'],
['Xa'],
['a'],
['c', 'cD'],
['g'],
['k', 'kE', 'kB'],
['tC', 'tA', 'tB'],
['z'],
]);
});
test('it returns all sorted nodes case-insensitive', function () {
var result = getImportNodes(code);
var sorted = get_sorted_nodes_1.getSortedNodes(result, {
importOrder: [],
importOrderCaseInsensitive: true,
importOrderSeparation: false,
sortModules: false,
});
expect(sorted).toMatchSnapshot();
expect(getSortedNodesNames(sorted)).toEqual([
'a',
'Ba',
'BY',
'c',
'g',
'k',
't',
'Xa',
'XY',
'z',
]);
expect(sorted
.filter(function (node) { return node.type === 'ImportDeclaration'; })
.map(function (importDeclaration) {
return getSortedNodesModulesNames(importDeclaration.specifiers);
})).toEqual([
['a'],
['Ba'],
['BY'],
['c', 'cD'],
['g'],
['k', 'kE', 'kB'],
['tC', 'tA', 'tB'],
['Xa'],
['XY'],
['z'],
]);
});
test('it returns all sorted nodes with sort order', function () {
var result = getImportNodes(code);
var sorted = get_sorted_nodes_1.getSortedNodes(result, ['^a$', '^t$', '^k$'], true);
var sorted = get_sorted_nodes_1.getSortedNodes(result, {
importOrder: ['^a$', '^t$', '^k$', '^B'],
importOrderCaseInsensitive: false,
importOrderSeparation: false,
sortModules: false,
});
expect(sorted).toMatchSnapshot();
expect(getSortedNodesNames(sorted)).toEqual(['c', 'g', 'z', 'a', 't', 'k']);
expect(getSortedNodesNames(sorted)).toEqual([
'XY',
'Xa',
'c',
'g',
'z',
'a',
't',
'k',
'BY',
'Ba',
]);
expect(sorted
.filter(function (node) { return node.type === 'ImportDeclaration'; })
.map(function (importDeclaration) {
return getSortedNodesModulesNames(importDeclaration.specifiers);
})).toEqual([
['XY'],
['Xa'],
['c', 'cD'],
['g'],
['z'],
['a'],
['tC', 'tA', 'tB'],
['k', 'kE', 'kB'],
['BY'],
['Ba'],
]);
});
test('it returns all sorted nodes with sort order case-insensitive', function () {
var result = getImportNodes(code);
var sorted = get_sorted_nodes_1.getSortedNodes(result, {
importOrder: ['^a$', '^t$', '^k$', '^B'],
importOrderCaseInsensitive: true,
importOrderSeparation: false,
sortModules: false,
});
expect(sorted).toMatchSnapshot();
expect(getSortedNodesNames(sorted)).toEqual([
'c',
'g',
'Xa',
'XY',
'z',
'a',
't',
'k',
'Ba',
'BY',
]);
expect(sorted
.filter(function (node) { return node.type === 'ImportDeclaration'; })
.map(function (importDeclaration) {
return getSortedNodesModulesNames(importDeclaration.specifiers);
})).toEqual([
['c', 'cD'],
['g'],
['Xa'],
['XY'],
['z'],
['a'],
['tC', 'tA', 'tB'],
['k', 'kE', 'kB'],
['Ba'],
['BY'],
]);
});
test('it returns all sorted nodes with sort order and sorted modules', function () {
var result = getImportNodes(code);
var sorted = get_sorted_nodes_1.getSortedNodes(result, {
importOrder: ['^a$', '^t$', '^k$', '^B'],
importOrderCaseInsensitive: false,
importOrderSeparation: false,
sortModules: true,
});
expect(sorted).toMatchSnapshot();
expect(getSortedNodesNames(sorted)).toEqual([
'XY',
'Xa',
'c',
'g',
'z',
'a',
't',
'k',
'BY',
'Ba',
]);
expect(sorted
.filter(function (node) { return node.type === 'ImportDeclaration'; })
.map(function (importDeclaration) {
return getSortedNodesModulesNames(importDeclaration.specifiers);
})).toEqual([
['XY'],
['Xa'],
['c', 'cD'],
['g'],
['z'],
['a'],
['tA', 'tB', 'tC'],
['k', 'kB', 'kE'],
['BY'],
['Ba'],
]);
});
test('it returns all sorted nodes with sort order case-insensitive and sorted modules', function () {
var result = getImportNodes(code);
var sorted = get_sorted_nodes_1.getSortedNodes(result, {
importOrder: ['^a$', '^t$', '^k$', '^B'],
importOrderCaseInsensitive: true,
importOrderSeparation: false,
sortModules: true,
});
expect(sorted).toMatchSnapshot();
expect(getSortedNodesNames(sorted)).toEqual([
'c',
'g',
'Xa',
'XY',
'z',
'a',
't',
'k',
'Ba',
'BY',
]);
expect(sorted
.filter(function (node) { return node.type === 'ImportDeclaration'; })
.map(function (importDeclaration) {
return getSortedNodesModulesNames(importDeclaration.specifiers);
})).toEqual([
['c', 'cD'],
['g'],
['Xa'],
['XY'],
['z'],
['a'],
['tA', 'tB', 'tC'],
['k', 'kB', 'kE'],
['Ba'],
['BY'],
]);
});

@@ -47,3 +47,8 @@ "use strict";

var importNodes = getImportNodes(code);
var sortedNodes = get_sorted_nodes_1.getSortedNodes(importNodes, [], false);
var sortedNodes = get_sorted_nodes_1.getSortedNodes(importNodes, {
importOrder: [],
importOrderCaseInsensitive: false,
importOrderSeparation: false,
sortModules: false,
});
var allCommentsFromImports = get_all_comments_from_nodes_1.getAllCommentsFromNodes(sortedNodes);

@@ -50,0 +55,0 @@ var commentAndImportsToRemoveFromCode = __spreadArray(__spreadArray([], sortedNodes), allCommentsFromImports);

@@ -19,7 +19,5 @@ "use strict";

// In case of typescript as prettier parser, we pass the following
// decoratorsLegacy, classProperties are passed in case of angular
// projects.
var tsPlugins = [constants_1.typescript, constants_1.jsx, constants_1.decoratorsLegacy, constants_1.classProperties];
var tsPlugins = [constants_1.typescript, constants_1.jsx];
return __spreadArray(__spreadArray([], (isFlow ? [constants_1.flow] : [])), (isTypescript ? tsPlugins : []));
};
exports.getParserPlugins = getParserPlugins;

@@ -20,12 +20,25 @@ "use strict";

/**
* This function returns import nodes with alphabeticaly sorted modules
* @param node Import declaration node
*/
var getSortedModulesImport = function (node) {
node.specifiers.sort(function (a, b) {
if (a.type !== b.type) {
return a.type === 'ImportDefaultSpecifier' ? -1 : 1;
}
return javascript_natural_sort_1.default(a.local.name, b.local.name);
});
return node;
};
/**
* This function returns all the nodes which are in the importOrder array.
* The plugin considered these import nodes as local import declarations.
* @param nodes all import nodes
* @param order import order
* @param importOrderSeparation boolean indicating if newline should be inserted after each import order
* @param options
*/
var getSortedNodes = function (nodes, order, importOrderSeparation) {
var getSortedNodes = function (nodes, options) {
javascript_natural_sort_1.default.insensitive = options.importOrderCaseInsensitive;
var originalNodes = nodes.map(lodash_1.clone);
var newLine = importOrderSeparation && nodes.length > 1 ? constants_1.newLineNode : null;
var sortedNodesByImportOrder = order.reduce(function (res, val) {
var newLine = options.importOrderSeparation && nodes.length > 1 ? constants_1.newLineNode : null;
var sortedNodesByImportOrder = options.importOrder.reduce(function (res, val) {
var x = originalNodes.filter(function (node) { return node.source.value.match(new RegExp(val)) !== null; });

@@ -43,7 +56,19 @@ // remove "found" imports from the list of nodes

}, []);
var sortedNodesNotInImportOrder = originalNodes.filter(function (node) { return !is_similar_text_in_array_1.isSimilarTextExistInArray(order, node.source.value); });
var sortedNodesNotInImportOrder = originalNodes.filter(function (node) {
return !is_similar_text_in_array_1.isSimilarTextExistInArray(options.importOrder, node.source.value);
});
sortedNodesNotInImportOrder.sort(function (a, b) {
return javascript_natural_sort_1.default(a.source.value, b.source.value);
});
var shouldAddNewLineInBetween = sortedNodesNotInImportOrder.length > 0 && importOrderSeparation;
var shouldAddNewLineInBetween = sortedNodesNotInImportOrder.length > 0 && options.importOrderSeparation;
if (options.sortModules) {
sortedNodesByImportOrder
.filter(function (node) {
return node.type === 'ImportDeclaration';
})
.forEach(function (node) { return getSortedModulesImport(node); });
sortedNodesNotInImportOrder.forEach(function (node) {
return getSortedModulesImport(node);
});
}
var allSortedNodes = lodash_1.compact(__spreadArray(__spreadArray(__spreadArray(__spreadArray([], sortedNodesNotInImportOrder), [

@@ -50,0 +75,0 @@ shouldAddNewLineInBetween ? constants_1.newLineNode : null

{
"name": "@trivago/prettier-plugin-sort-imports",
"version": "2.0.4",
"version": "3.0.0-0",
"description": "A prettier plugins to sort imports in provided RegEx order",

@@ -5,0 +5,0 @@ "main": "lib/src/index.js",

@@ -40,2 +40,3 @@ # Prettier plugin sort imports

"importOrderSeparation": true,
"importOrderCaseInsensitive": true,
}

@@ -52,2 +53,20 @@ ```

#### `importOrderCaseInsensitive`
A boolean value to enable case-insensitivity in the sorting algorithm
used to order imports within each match group.
For example, when false (or not specified):
```ecmascript 6
import ExampleView from './ExampleView';
import ExamplesList from './ExamplesList';
```
compared with `"importOrderCaseInsensitive": true`:
```ecmascript 6
import ExamplesList from './ExamplesList';
import ExampleView from './ExampleView';
```
#### `importOrderSeparation`

@@ -57,5 +76,11 @@ A boolean value to enable or disable the new line separation

#### `sortModules`
A boolean value to enable or disable sorting of the imports module declarations.
It is disabled by default
#### `experimentalBabelParserPluginsList`
A collection of parser names for babel parser. The plugin passes this list to babel parser so it can understand the syntaxes used in the file being formatted. The plugin uses prettier itself to figure out the parser it needs to use but if that fails, you can use this field to enforce the usage of the plugins babel needs.
Since prettier options are limited to strings, you can pass plugins with options as a JSON string of the plugin array: `"[\"plugin-name\", { \"pluginOption\": true }]"`.
```ecmascript 6

@@ -71,3 +96,4 @@ module.exports = {

"importOrderSeparation": true,
"experimentalBabelParserPluginsList" : ["jsx", "typescript"]
"importOrderCaseInsensitive": true,
"experimentalBabelParserPluginsList" : ["jsx", "typescript", "[\"decorators\", { \"decoratorsBeforeExport\": true }]"]
}

@@ -84,3 +110,4 @@ ```

After, the plugin sorts the _local imports_ and _3rd party imports_ using
[natural sort algorithm](https://en.wikipedia.org/wiki/Natural_sort_order).
[natural sort algorithm](https://en.wikipedia.org/wiki/Natural_sort_order),
with case-insensitivity specified by `importOrderCaseInsensitive` (or false by default).
In the end, the plugin returns final imports with _3rd party imports_ on top and

@@ -126,3 +153,3 @@ _local imports_ at the end.

#### Q. How to use the plugin with `*.d.ts` files ?
The plugin automatically ignores the `*.d.ts` files. We encourage you to declare the `*.d.ts` files in `.prettierignore`. (Read more here)[https://prettier.io/docs/en/ignore.html#ignoring-files-prettierignore].
The plugin automatically ignores the `*.d.ts` files. We encourage you to declare the `*.d.ts` files in `.prettierignore`. [Read more here](https://prettier.io/docs/en/ignore.html#ignoring-files-prettierignore).

@@ -156,3 +183,3 @@ #### Q. How does the plugin handle the first comment in the file.

| React | ✅ Everything | - |
| Angular | ❌ Experimental features are not supported | Any contribution is welcome. |
| Angular | 🔜 Experimental features are not supported | To be supported in v3.x.x, coming soon 😉 |
| Vue | ❌ Not supported | Any contribution is welcome. |

@@ -159,0 +186,0 @@ | Svelte | ❌ Not supported | Any contribution is welcome. |

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc