@putout/plugin-esm 10.4.0 → 10.5.0

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/README.md CHANGED
@@ -31,6 +31,7 @@ npm i putout @putout/plugin-esm -D
31
31
  - ✅ [remove-quotes-from-import-assertions](#remove-quotes-from-import-assertions);
32
32
  - ✅ [remove-empty-import](#remove-empty-import);
33
33
  - ✅ [remove-empty-export](#remove-empty-export);
34
+ - ✅ [remove-imports-with-duplicate-source](#remove-imports-with-duplicate-source);
34
35
  - ✅ [remove-useless-export-specifiers](#remove-useless-export-specifiers);
35
36
  - ✅ [sort-imports-by-specifiers](#sort-imports-by-specifiers);
36
37
 
@@ -60,6 +61,7 @@ npm i putout @putout/plugin-esm -D
60
61
  "esm/merge-export-declaration": "on",
61
62
  "esm/remove-quotes-from-import-assertions": "on",
62
63
  "esm/remove-empty-export": "on",
64
+ "esm/remove-imports-with-duplicate-source": "on",
63
65
  "esm/remove-empty-import": ["on", {
64
66
  "ignore": []
65
67
  }],
@@ -225,8 +227,6 @@ export {
225
227
 
226
228
  Check out in 🐊[**Putout Editor**](https://putout.cloudcmd.io/#/gist/e5c3ea469437ade0f4467323dcec9a36/7c298c7078b004ae3aba2a29e38579bf8f48a098).
227
229
 
228
- #### ❌ Example of incorrect code
229
-
230
230
  ```diff
231
231
  export const hello = () => 'world';
232
232
  export const {
@@ -234,6 +234,23 @@ export const {
234
234
  }
235
235
  ```
236
236
 
237
+ ### remove-imports-with-duplicate-source
238
+
239
+ Check out in 🐊[**Putout Editor**](https://putout.cloudcmd.io/#/gist/f48250f577be00b53f923318a1d0a584/1a42dc1be8610fc35975ee397bce9fe4722b82dc).
240
+
241
+ ```diff
242
+ import * as convertCommonjsToEsm from '@putout/plugin-nodejs/convert-commonjs-to-esm';
243
+ -import * as convert from '@putout/plugin-nodejs/convert-commonjs-to-esm';
244
+
245
+ test('putout: plugin-destructuring: merge-properties: transform: exports', (t) => {
246
+ t.transform('exports', {
247
+ - 'node/convert-commonjs-to-esm': convert,
248
+ + 'node/convert-commonjs-to-esm': convertCommonjsToEsm,
249
+ });
250
+ t.end();
251
+ });
252
+ ```
253
+
237
254
  ### declare-imports-first
238
255
 
239
256
  Check out in 🐊[**Putout Editor**](https://putout.cloudcmd.io/#/gist/b1c18e5d726afe4ebb69d6b7a7dda82b/8189590815a1b8adb35bb8a846e28228e3c7fadf). For **CommonJS** use [nodejs/declare-after-require](https://github.com/coderaiser/putout/tree/master/packages/plugin-nodejs#declare-after-require).
package/lib/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ import * as removeImportsWithDuplicateSource from './remove-imports-with-duplicate-source/index.js';
1
2
  import * as convertConstToImport from './convert-const-to-import/index.js';
2
3
  import * as applyImportAttributes from './apply-import-attributes/index.js';
3
4
  import * as applyDefaultImport from './apply-default-import/index.js';
@@ -43,4 +44,5 @@ export const rules = {
43
44
  'apply-default-import': applyDefaultImport,
44
45
  'apply-import-attributes': applyImportAttributes,
45
46
  'convert-const-to-import': convertConstToImport,
47
+ 'remove-imports-with-duplicate-source': removeImportsWithDuplicateSource,
46
48
  };
@@ -0,0 +1,91 @@
1
+ import {operator, types} from 'putout';
2
+
3
+ const {
4
+ isImportDeclaration,
5
+ variableDeclaration,
6
+ variableDeclarator,
7
+ objectPattern,
8
+ objectProperty,
9
+ isImportNamespaceSpecifier,
10
+ } = types;
11
+
12
+ const {
13
+ replaceWith,
14
+ rename,
15
+ remove,
16
+ } = operator;
17
+
18
+ export const report = ({path}) => {
19
+ const {value} = path.node.source;
20
+ return `Avoid 'imports' with duplicate 'source': '${value}'`;
21
+ };
22
+
23
+ export const fix = ({path, original}) => {
24
+ const {specifiers} = path.node;
25
+ const originalSpecifiers = original.node.specifiers;
26
+
27
+ if (!originalSpecifiers.length) {
28
+ remove(original);
29
+ return;
30
+ }
31
+
32
+ const [firstOriginal] = originalSpecifiers;
33
+ const [first] = specifiers;
34
+
35
+ if (isImportNamespaceSpecifier(first) && firstOriginal.type === first.type) {
36
+ const {name} = first.local;
37
+ const originalName = firstOriginal.local.name;
38
+
39
+ rename(path, name, originalName);
40
+ remove(path);
41
+
42
+ return;
43
+ }
44
+
45
+ if (isImportNamespaceSpecifier(first)) {
46
+ convertImportToVariable(first.local, original);
47
+ return;
48
+ }
49
+
50
+ if (isImportNamespaceSpecifier(firstOriginal)) {
51
+ convertImportToVariable(firstOriginal.local, path);
52
+ return;
53
+ }
54
+ };
55
+
56
+ function convertImportToVariable(init, original) {
57
+ const properties = [];
58
+
59
+ for (const {local, imported} of original.node.specifiers) {
60
+ properties.push(objectProperty(local, imported));
61
+ }
62
+
63
+ const id = objectPattern(properties);
64
+ const declaration = variableDeclarator(id, init);
65
+ const variable = variableDeclaration('const', [declaration]);
66
+
67
+ replaceWith(original, variable);
68
+ }
69
+
70
+ export const traverse = ({push}) => ({
71
+ Program(path) {
72
+ const imports = path.get('body').filter(isImportDeclaration);
73
+ const sources = new Map();
74
+
75
+ for (const element of imports) {
76
+ const {value} = element.node.source;
77
+
78
+ if (!sources.has(value)) {
79
+ sources.set(value, element);
80
+ continue;
81
+ }
82
+
83
+ const original = sources.get(value);
84
+
85
+ push({
86
+ path: element,
87
+ original,
88
+ });
89
+ }
90
+ },
91
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@putout/plugin-esm",
3
- "version": "10.4.0",
3
+ "version": "10.5.0",
4
4
  "type": "module",
5
5
  "author": "coderaiser <mnemonic.enemy@gmail.com> (https://github.com/coderaiser)",
6
6
  "description": "🐊Putout plugin improves ability to transform ESM code",