@putout/plugin-esm 8.2.0 → 8.4.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
@@ -34,7 +34,8 @@ npm i putout @putout/plugin-esm -D
34
34
 
35
35
  ## File rules
36
36
 
37
- - ✅ [apply-import-by-type-to-file](#apply-import-by-type-to-file]);
37
+ - ✅ [apply-name-to-imported-file](#apply-name-to-imported-file]]);
38
+ - ✅ [apply-namespace-to-imported-file](#apply-namespace-to-imported-file]]);
38
39
  - ✅ [apply-privately-imported-file](#apply-privately-imported-file);
39
40
  - ✅ [apply-js-imported-file](#apply-js-imported-file);
40
41
  - ✅ [resolve-imported-file](#resolve-imported-file);
@@ -61,7 +62,8 @@ npm i putout @putout/plugin-esm -D
61
62
  "esm/apply-js-imported-file": "off",
62
63
  "esm/resolve-imported-file": "off",
63
64
  "esm/shorten-imported-file": "off",
64
- "esm/apply-import-by-type-to-file": "off",
65
+ "esm/apply-name-to-imported-file": "off",
66
+ "esm/apply-namespace-to-imported-file": "off",
65
67
  "esm/apply-privately-imported-file": "off",
66
68
  "esm/remove-useless-export-specifiers": "off"
67
69
  }
@@ -73,6 +75,7 @@ npm i putout @putout/plugin-esm -D
73
75
  ### add-index-to-import
74
76
 
75
77
  ESM doesn't add `index.js`, so it can be left after [`@putout/plugin-convert-esm-to-commonjs`](https://github.com/coderaiser/putout/blob/master/packages/plugin-convert-esm-to-commonjs#readme).
78
+
76
79
  Checkout in 🐊[**Putout Editor**](https://putout.cloudcmd.io/#/gist/b7c489710767efee95ecf3dd16e232a2/9f974f0a345ef4d0cb39b011097dff82e6c32b75).
77
80
 
78
81
  #### ❌ Example of incorrect code
@@ -399,7 +402,7 @@ import('foo.json', {
399
402
 
400
403
  ## File Rules
401
404
 
402
- ### apply-import-by-type-to-file
405
+ ### apply-namespace-to-imported-file
403
406
 
404
407
  The rule fixes:
405
408
 
@@ -407,38 +410,42 @@ The rule fixes:
407
410
 
408
411
  Check out in 🐊**Putout Editor**:
409
412
 
410
- - ✅ [`apply-namespace-import-to-file`](https://putout.cloudcmd.io/#/gist/1492d584559e5798325047de679222a0/c6a37a803b80823de1b64ab944f2427aecefb51b);
413
+ - ✅ [`apply-namespace-to-imported-file`](https://putout.cloudcmd.io/#/gist/1492d584559e5798325047de679222a0/c6a37a803b80823de1b64ab944f2427aecefb51b);
411
414
  - ✅ [`get-imports`](https://putout.cloudcmd.io/#/gist/5d7687215e9fbdf705935c444503dded/75a98d2db9d3847c73017e41637924b1cfd5a598);
412
415
  - ✅ [`has-export-default`](https://putout.cloudcmd.io/#/gist/b50ccfe5cc8c0c97e2fc98b37903ade4/fbc026e6f1027581f7aa4879dcafcaa7754bf8f4);
413
416
  - ✅ [`apply-namespace-import`](https://putout.cloudcmd.io/#/gist/23a6dc6741b772c03fbed95feda2b451/1fbecac6fc40282bcda0593aa666a8c213ef85b7);
414
417
  - ✅ [`is-esm`](https://putout.cloudcmd.io/#/gist/fa080be2bf3a6560e289d84b5873c2bc/2601091f6bf97148843767968c3afcb36dde31de);
415
418
 
416
- #### named import
417
-
418
419
  Let's consider file structure:
419
420
 
420
421
  ```
421
422
  /
422
423
  |-- lib/
423
424
  | `-- index.js "import a from './a.js';"
424
- | `-- a.js "export const a = 2;"
425
+ | `-- a.js "export const x = 2;"
425
426
  ```
426
427
 
427
428
  In this case `index.js` can be fixed:
428
429
 
429
- ##### ❌ Example of incorrect code
430
+ #### ❌ Example of incorrect code
430
431
 
431
432
  ```js
432
433
  import a from './a.js';
433
434
  ```
434
435
 
435
- ##### ✅ Example of correct code
436
+ #### ✅ Example of correct code
436
437
 
437
438
  ```js
438
- import {a} from './a.js';
439
+ import * as a from './a.js';
439
440
  ```
440
441
 
441
- #### namespace import
442
+ ### apply-name-to-imported-file
443
+
444
+ Checkout in 🐊**Putout Editor**:
445
+
446
+ - ✅ [`get-imports`](https://putout.cloudcmd.io/#/gist/5d7687215e9fbdf705935c444503dded/75a98d2db9d3847c73017e41637924b1cfd5a598);
447
+ - ✅ [`has-export-default`](https://putout.cloudcmd.io/#/gist/b50ccfe5cc8c0c97e2fc98b37903ade4/fbc026e6f1027581f7aa4879dcafcaa7754bf8f4);
448
+ - ✅ [`is-esm`](https://putout.cloudcmd.io/#/gist/fa080be2bf3a6560e289d84b5873c2bc/2601091f6bf97148843767968c3afcb36dde31de);
442
449
 
443
450
  Let's consider file structure:
444
451
 
@@ -446,7 +453,7 @@ Let's consider file structure:
446
453
  /
447
454
  |-- lib/
448
455
  | `-- index.js "import a from './a.js';"
449
- | `-- a.js "export const x = 2;"
456
+ | `-- a.js "export const a = 2;"
450
457
  ```
451
458
 
452
459
  In this case `index.js` can be fixed:
@@ -460,7 +467,7 @@ import a from './a.js';
460
467
  ##### ✅ Example of correct code
461
468
 
462
469
  ```js
463
- import * as a from './a.js';
470
+ import {a} from './a.js';
464
471
  ```
465
472
 
466
473
  ### apply-privately-imported-to-file
@@ -565,7 +572,7 @@ import {parseProcessorNames} from './parse-processor-names.js';
565
572
 
566
573
  ### apply-js-imported-file
567
574
 
568
- Check out in 🐊**Putout Editor**:
575
+ Checkout in 🐊**Putout Editor**:
569
576
 
570
577
  - ✅ [`get-imports`](https://putout.cloudcmd.io/#/gist/ee10100fed86e4db926885dd54298668/7538bca7a9ae006d976f41261c0ed4c0e1902ace);
571
578
  - ✅ [`change-imports`](https://putout.cloudcmd.io/#/gist/23a6dc6741b772c03fbed95feda2b451/1fbecac6fc40282bcda0593aa666a8c213ef85b7);
@@ -10,13 +10,15 @@ const {
10
10
  readFileContent,
11
11
  } = operator;
12
12
 
13
- export const determineImportType = ({name, rootPath, importedFilename, privateImports}) => {
13
+ export const determineImportType = ({name, rootPath, importedFilename, privateImports, crawled}) => {
14
14
  const parsedName = parseImportedFilename({
15
15
  importedFilename,
16
16
  privateImports,
17
17
  });
18
18
 
19
- const [importedFile] = findFile(rootPath, parsedName);
19
+ const [importedFile] = findFile(rootPath, parsedName, {
20
+ crawled,
21
+ });
20
22
 
21
23
  if (!importedFile)
22
24
  return '';
@@ -48,7 +50,7 @@ export const determineImportType = ({name, rootPath, importedFilename, privateIm
48
50
  return 'equal';
49
51
  }
50
52
 
51
- return 'named';
53
+ return 'namespace';
52
54
  };
53
55
 
54
56
  function parseImportedFilename({importedFilename, privateImports}) {
@@ -0,0 +1,45 @@
1
+ import {dirname, join} from 'node:path';
2
+ import {transform, operator} from 'putout';
3
+ import * as getImportsPlugin from '#get-default-imports';
4
+
5
+ const {getFilename} = operator;
6
+ const getMessage = (a) => a.message;
7
+
8
+ export const getImportsTuples = (file, content, ast) => {
9
+ if (!content.includes('import'))
10
+ return [];
11
+
12
+ const places = transform(ast, content, {
13
+ fix: false,
14
+ plugins: [
15
+ ['get-imports', getImportsPlugin],
16
+ ],
17
+ });
18
+
19
+ const filename = getFilename(file);
20
+ const dir = dirname(filename);
21
+
22
+ const imports = places.map(getMessage);
23
+
24
+ return buildImports(dir, imports);
25
+ };
26
+
27
+ function parseFull(dir, source) {
28
+ if (source.startsWith('#'))
29
+ return source;
30
+
31
+ return join(dir, source);
32
+ }
33
+
34
+ function buildImports(dir, imports) {
35
+ const list = [];
36
+
37
+ for (const current of imports) {
38
+ const [name, source] = current.split(' <- ');
39
+ const full = parseFull(dir, source);
40
+
41
+ list.push([name, source, full]);
42
+ }
43
+
44
+ return list;
45
+ }
@@ -0,0 +1,77 @@
1
+ import {tryCatch} from 'try-catch';
2
+ import {
3
+ parse,
4
+ print,
5
+ operator,
6
+ } from 'putout';
7
+ import {createGetPrivateImports} from '#private-imports';
8
+ import {determineImportType} from '#determine-import-type';
9
+ import {transformNamedImport} from './transform-named-import.js';
10
+ import {getImportsTuples} from './get-imports-tuples.js';
11
+
12
+ const {
13
+ getFilename,
14
+ readFileContent,
15
+ writeFileContent,
16
+ crawlDirectory,
17
+ } = operator;
18
+
19
+ export const report = (file, {name, source}) => {
20
+ const filename = getFilename(file);
21
+ return `Use \`import {${name}} from '${source}'\` in '${filename}'`;
22
+ };
23
+
24
+ export const fix = (file, {name, source, content, ast}) => {
25
+ transformNamedImport(ast, {
26
+ name,
27
+ source,
28
+ content,
29
+ });
30
+
31
+ const newContent = print(ast);
32
+
33
+ writeFileContent(file, newContent);
34
+ };
35
+
36
+ export const scan = (rootPath, {push, trackFile}) => {
37
+ const mask = [
38
+ '*.js',
39
+ '*.mjs',
40
+ ];
41
+
42
+ const getPrivateImports = createGetPrivateImports();
43
+ const crawled = crawlDirectory(rootPath);
44
+
45
+ for (const file of trackFile(rootPath, mask)) {
46
+ const content = readFileContent(file);
47
+ const [error, ast] = tryCatch(parse, content);
48
+
49
+ if (error)
50
+ continue;
51
+
52
+ const importsTuples = getImportsTuples(file, content, ast);
53
+
54
+ const privateImports = getPrivateImports(file, {
55
+ aliasBased: true,
56
+ });
57
+
58
+ for (const [name, source, importedFilename] of importsTuples) {
59
+ const importType = determineImportType({
60
+ name,
61
+ rootPath,
62
+ importedFilename,
63
+ privateImports,
64
+ crawled,
65
+ });
66
+
67
+ if (importType === 'equal')
68
+ push(file, {
69
+ importType,
70
+ name,
71
+ source,
72
+ ast,
73
+ content,
74
+ });
75
+ }
76
+ }
77
+ };
@@ -0,0 +1,77 @@
1
+ import {tryCatch} from 'try-catch';
2
+ import {
3
+ parse,
4
+ print,
5
+ operator,
6
+ } from 'putout';
7
+ import {createGetPrivateImports} from '#private-imports';
8
+ import {determineImportType} from '#determine-import-type';
9
+ import {transformNamespaceImport} from './transform-namespace-import.js';
10
+ import {getImportsTuples} from '../apply-name-to-imported-file/get-imports-tuples.js';
11
+
12
+ const {
13
+ getFilename,
14
+ readFileContent,
15
+ writeFileContent,
16
+ crawlDirectory,
17
+ } = operator;
18
+
19
+ export const report = (file, {name, source}) => {
20
+ const filename = getFilename(file);
21
+ return `Use \`import * as ${name} from '${source}'\` in '${filename}'`;
22
+ };
23
+
24
+ export const fix = (file, {name, source, content, ast}) => {
25
+ transformNamespaceImport(ast, {
26
+ name,
27
+ source,
28
+ content,
29
+ });
30
+
31
+ const newContent = print(ast);
32
+
33
+ writeFileContent(file, newContent);
34
+ };
35
+
36
+ export const scan = (rootPath, {push, trackFile}) => {
37
+ const mask = [
38
+ '*.js',
39
+ '*.mjs',
40
+ ];
41
+
42
+ const getPrivateImports = createGetPrivateImports();
43
+ const crawled = crawlDirectory(rootPath);
44
+
45
+ for (const file of trackFile(rootPath, mask)) {
46
+ const content = readFileContent(file);
47
+ const [error, ast] = tryCatch(parse, content);
48
+
49
+ if (error)
50
+ continue;
51
+
52
+ const importsTuples = getImportsTuples(file, content, ast);
53
+
54
+ const privateImports = getPrivateImports(file, {
55
+ aliasBased: true,
56
+ });
57
+
58
+ for (const [name, source, importedFilename] of importsTuples) {
59
+ const importType = determineImportType({
60
+ name,
61
+ rootPath,
62
+ importedFilename,
63
+ privateImports,
64
+ crawled,
65
+ });
66
+
67
+ if (importType === 'namespace')
68
+ push(file, {
69
+ importType,
70
+ name,
71
+ source,
72
+ ast,
73
+ content,
74
+ });
75
+ }
76
+ }
77
+ };
package/lib/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import * as applyExportFrom from './apply-export-from/index.js';
2
2
  import * as applyJsImportedFile from './apply-js-imported-file/index.js';
3
- import * as applyImportByTypeToFile from './apply-import-by-type-to-file/index.js';
3
+ import * as applyNameToImportedFile from './apply-name-to-imported-file/index.js';
4
+ import * as applyNamespaceToImportedFile from './apply-namespace-to-imported-file/index.js';
4
5
  import * as mergeExportDeclarations from './merge-export-declarations/index.js';
5
6
  import * as removeUselessExportSpecifiers from './remove-useless-export-specifiers/index.js';
6
7
  import * as mergeDeclarationWithExport from './merge-declaration-with-export/index.js';
@@ -34,7 +35,8 @@ export const rules = {
34
35
 
35
36
  'resolve-imported-file': ['off', resolveImportedFile],
36
37
  'shorten-imported-file': ['off', shortenImportedFile],
37
- 'apply-import-by-type-to-file': ['off', applyImportByTypeToFile],
38
+ 'apply-name-to-imported-file': ['off', applyNameToImportedFile],
39
+ 'apply-namespace-to-imported-file': ['off', applyNamespaceToImportedFile],
38
40
  'apply-privately-imported-file': ['off', applyPrivatelyImportedFile],
39
41
  'apply-js-imported-file': ['off', applyJsImportedFile],
40
42
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@putout/plugin-esm",
3
- "version": "8.2.0",
3
+ "version": "8.4.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",
@@ -12,12 +12,13 @@
12
12
  },
13
13
  "imports": {
14
14
  "#get-imports": "./lib/shorten-imported-file/get-imports/index.js",
15
- "#get-default-imports": "./lib/apply-import-by-type-to-file/get-imports/index.js",
15
+ "#get-imports-tuples": "./lib/shorten-imported-file/get-imports-tuples.js",
16
+ "#get-default-imports": "./lib/apply-name-to-imported-file/get-imports/index.js",
16
17
  "#change-imports": "./lib/resolve-imported-file/change-imports/index.js",
17
18
  "#private-imports": "./lib/apply-privately-imported-file/private-imports.js",
18
- "#is-esm": "./lib/apply-import-by-type-to-file/is-esm/index.js",
19
- "#has-export-default": "./lib/apply-import-by-type-to-file/has-export-default/index.js",
20
- "#determine-import-type": "./lib/apply-import-by-type-to-file/determine-import-type.js"
19
+ "#is-esm": "./lib/apply-name-to-imported-file/is-esm/index.js",
20
+ "#has-export-default": "./lib/apply-name-to-imported-file/has-export-default/index.js",
21
+ "#determine-import-type": "./lib/apply-name-to-imported-file/determine-import-type.js"
21
22
  },
22
23
  "release": false,
23
24
  "tag": false,
@@ -1,132 +0,0 @@
1
- import {join, dirname} from 'node:path';
2
- import {tryCatch} from 'try-catch';
3
- import {
4
- parse,
5
- print,
6
- transform,
7
- operator,
8
- } from 'putout';
9
- import {createGetPrivateImports} from '#private-imports';
10
- import * as getImportsPlugin from '#get-default-imports';
11
- import {determineImportType} from '#determine-import-type';
12
- import {transformNamedImport} from './transform-named-import.js';
13
- import {transformNamespaceImport} from './transform-namespace-import.js';
14
-
15
- const {
16
- getFilename,
17
- readFileContent,
18
- writeFileContent,
19
- } = operator;
20
-
21
- const getMessage = (a) => a.message;
22
-
23
- export const report = (file, {importType, name, source}) => {
24
- const filename = getFilename(file);
25
-
26
- if (importType === 'equal')
27
- return `Use \`import {${name}} from '${source}'\` in '${filename}'`;
28
-
29
- return `Use \`import * as ${name} from '${source}'\` in '${filename}'`;
30
- };
31
-
32
- export const fix = (file, {name, source, content, ast, importType}) => {
33
- if (importType === 'equal')
34
- transformNamedImport(ast, {
35
- name,
36
- source,
37
- content,
38
- });
39
-
40
- if (importType === 'named')
41
- transformNamespaceImport(ast, {
42
- name,
43
- source,
44
- content,
45
- });
46
-
47
- const newContent = print(ast);
48
-
49
- writeFileContent(file, newContent);
50
- };
51
-
52
- export const scan = (rootPath, {push, trackFile}) => {
53
- const mask = [
54
- '*.js',
55
- '*.mjs',
56
- ];
57
-
58
- const getPrivateImports = createGetPrivateImports();
59
-
60
- for (const file of trackFile(rootPath, mask)) {
61
- const content = readFileContent(file);
62
- const [error, ast] = tryCatch(parse, content);
63
-
64
- if (error)
65
- continue;
66
-
67
- const importsTuples = getImports(file, content, ast);
68
-
69
- const privateImports = getPrivateImports(file, {
70
- aliasBased: true,
71
- });
72
-
73
- for (const [name, source, importedFilename] of importsTuples) {
74
- const importType = determineImportType({
75
- name,
76
- rootPath,
77
- importedFilename,
78
- privateImports,
79
- });
80
-
81
- if (!importType)
82
- continue;
83
-
84
- push(file, {
85
- importType,
86
- name,
87
- source,
88
- ast,
89
- content,
90
- });
91
- }
92
- }
93
- };
94
-
95
- function getImports(file, content, ast) {
96
- if (!content.includes('import'))
97
- return [];
98
-
99
- const places = transform(ast, content, {
100
- fix: false,
101
- plugins: [
102
- ['get-imports', getImportsPlugin],
103
- ],
104
- });
105
-
106
- const filename = getFilename(file);
107
- const dir = dirname(filename);
108
-
109
- const imports = places.map(getMessage);
110
-
111
- return buildImports(dir, imports);
112
- }
113
-
114
- function parseFull(dir, source) {
115
- if (source.startsWith('#'))
116
- return source;
117
-
118
- return join(dir, source);
119
- }
120
-
121
- function buildImports(dir, imports) {
122
- const list = [];
123
-
124
- for (const current of imports) {
125
- const [name, source] = current.split(' <- ');
126
- const full = parseFull(dir, source);
127
-
128
- list.push([name, source, full]);
129
- }
130
-
131
- return list;
132
- }