@putout/plugin-esm 8.3.0 → 8.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
@@ -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
  }
@@ -72,7 +74,12 @@ npm i putout @putout/plugin-esm -D
72
74
 
73
75
  ### add-index-to-import
74
76
 
77
+ > `import` a directory URL is unsupported. Instead
78
+ >
79
+ > (c) [nodejs.org](https://nodejs.org/api/errors.html#err_unsupported_dir_import)
80
+
75
81
  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).
82
+
76
83
  Checkout in 🐊[**Putout Editor**](https://putout.cloudcmd.io/#/gist/b7c489710767efee95ecf3dd16e232a2/9f974f0a345ef4d0cb39b011097dff82e6c32b75).
77
84
 
78
85
  #### ❌ Example of incorrect code
@@ -81,6 +88,8 @@ Checkout in 🐊[**Putout Editor**](https://putout.cloudcmd.io/#/gist/b7c4897107
81
88
  import insertRust from './insert-rust';
82
89
  import addAction from './add-action';
83
90
 
91
+ export * as read from './vfs/read';
92
+
84
93
  export const rules = {};
85
94
  ```
86
95
 
@@ -90,6 +99,8 @@ export const rules = {};
90
99
  import insertRust from './insert-rust/index.js';
91
100
  import addAction from './add-action/index.js';
92
101
 
102
+ export * as read from './vfs/read/index.js';
103
+
93
104
  export const rules = {};
94
105
  ```
95
106
 
@@ -399,7 +410,7 @@ import('foo.json', {
399
410
 
400
411
  ## File Rules
401
412
 
402
- ### apply-import-by-type-to-file
413
+ ### apply-namespace-to-imported-file
403
414
 
404
415
  The rule fixes:
405
416
 
@@ -407,38 +418,42 @@ The rule fixes:
407
418
 
408
419
  Check out in 🐊**Putout Editor**:
409
420
 
410
- - ✅ [`apply-namespace-import-to-file`](https://putout.cloudcmd.io/#/gist/1492d584559e5798325047de679222a0/c6a37a803b80823de1b64ab944f2427aecefb51b);
421
+ - ✅ [`apply-namespace-to-imported-file`](https://putout.cloudcmd.io/#/gist/1492d584559e5798325047de679222a0/c6a37a803b80823de1b64ab944f2427aecefb51b);
411
422
  - ✅ [`get-imports`](https://putout.cloudcmd.io/#/gist/5d7687215e9fbdf705935c444503dded/75a98d2db9d3847c73017e41637924b1cfd5a598);
412
423
  - ✅ [`has-export-default`](https://putout.cloudcmd.io/#/gist/b50ccfe5cc8c0c97e2fc98b37903ade4/fbc026e6f1027581f7aa4879dcafcaa7754bf8f4);
413
424
  - ✅ [`apply-namespace-import`](https://putout.cloudcmd.io/#/gist/23a6dc6741b772c03fbed95feda2b451/1fbecac6fc40282bcda0593aa666a8c213ef85b7);
414
425
  - ✅ [`is-esm`](https://putout.cloudcmd.io/#/gist/fa080be2bf3a6560e289d84b5873c2bc/2601091f6bf97148843767968c3afcb36dde31de);
415
426
 
416
- #### named import
417
-
418
427
  Let's consider file structure:
419
428
 
420
429
  ```
421
430
  /
422
431
  |-- lib/
423
432
  | `-- index.js "import a from './a.js';"
424
- | `-- a.js "export const a = 2;"
433
+ | `-- a.js "export const x = 2;"
425
434
  ```
426
435
 
427
436
  In this case `index.js` can be fixed:
428
437
 
429
- ##### ❌ Example of incorrect code
438
+ #### ❌ Example of incorrect code
430
439
 
431
440
  ```js
432
441
  import a from './a.js';
433
442
  ```
434
443
 
435
- ##### ✅ Example of correct code
444
+ #### ✅ Example of correct code
436
445
 
437
446
  ```js
438
- import {a} from './a.js';
447
+ import * as a from './a.js';
439
448
  ```
440
449
 
441
- #### namespace import
450
+ ### apply-name-to-imported-file
451
+
452
+ Checkout in 🐊**Putout Editor**:
453
+
454
+ - ✅ [`get-imports`](https://putout.cloudcmd.io/#/gist/5d7687215e9fbdf705935c444503dded/75a98d2db9d3847c73017e41637924b1cfd5a598);
455
+ - ✅ [`has-export-default`](https://putout.cloudcmd.io/#/gist/b50ccfe5cc8c0c97e2fc98b37903ade4/fbc026e6f1027581f7aa4879dcafcaa7754bf8f4);
456
+ - ✅ [`is-esm`](https://putout.cloudcmd.io/#/gist/fa080be2bf3a6560e289d84b5873c2bc/2601091f6bf97148843767968c3afcb36dde31de);
442
457
 
443
458
  Let's consider file structure:
444
459
 
@@ -446,7 +461,7 @@ Let's consider file structure:
446
461
  /
447
462
  |-- lib/
448
463
  | `-- index.js "import a from './a.js';"
449
- | `-- a.js "export const x = 2;"
464
+ | `-- a.js "export const a = 2;"
450
465
  ```
451
466
 
452
467
  In this case `index.js` can be fixed:
@@ -460,10 +475,10 @@ import a from './a.js';
460
475
  ##### ✅ Example of correct code
461
476
 
462
477
  ```js
463
- import * as a from './a.js';
478
+ import {a} from './a.js';
464
479
  ```
465
480
 
466
- ### apply-privately-imported-to-file
481
+ ### apply-privately-imported-file
467
482
 
468
483
  > Entries in the imports field must be strings starting with `#`.
469
484
  > Package imports permit mapping to external packages.
@@ -565,7 +580,7 @@ import {parseProcessorNames} from './parse-processor-names.js';
565
580
 
566
581
  ### apply-js-imported-file
567
582
 
568
- Check out in 🐊**Putout Editor**:
583
+ Checkout in 🐊**Putout Editor**:
569
584
 
570
585
  - ✅ [`get-imports`](https://putout.cloudcmd.io/#/gist/ee10100fed86e4db926885dd54298668/7538bca7a9ae006d976f41261c0ed4c0e1902ace);
571
586
  - ✅ [`change-imports`](https://putout.cloudcmd.io/#/gist/23a6dc6741b772c03fbed95feda2b451/1fbecac6fc40282bcda0593aa666a8c213ef85b7);
@@ -16,8 +16,14 @@ export const fix = (path) => {
16
16
  };
17
17
 
18
18
  export const traverse = ({push}) => ({
19
- ImportDeclaration: (path) => {
20
- const {value} = path.node.source;
19
+ 'ImportDeclaration|ExportNamedDeclaration': (path) => {
20
+ const {node} = path;
21
+ const {source} = node;
22
+
23
+ if (!source)
24
+ return;
25
+
26
+ const {value} = source;
21
27
  const ext = extname(value);
22
28
 
23
29
  if (ext)
@@ -50,7 +50,7 @@ export const determineImportType = ({name, rootPath, importedFilename, privateIm
50
50
  return 'equal';
51
51
  }
52
52
 
53
- return 'named';
53
+ return 'namespace';
54
54
  };
55
55
 
56
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.3.0",
3
+ "version": "8.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",
@@ -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,135 +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
- crawlDirectory,
20
- } = operator;
21
-
22
- const getMessage = (a) => a.message;
23
-
24
- export const report = (file, {importType, name, source}) => {
25
- const filename = getFilename(file);
26
-
27
- if (importType === 'equal')
28
- return `Use \`import {${name}} from '${source}'\` in '${filename}'`;
29
-
30
- return `Use \`import * as ${name} from '${source}'\` in '${filename}'`;
31
- };
32
-
33
- export const fix = (file, {name, source, content, ast, importType}) => {
34
- if (importType === 'equal')
35
- transformNamedImport(ast, {
36
- name,
37
- source,
38
- content,
39
- });
40
-
41
- if (importType === 'named')
42
- transformNamespaceImport(ast, {
43
- name,
44
- source,
45
- content,
46
- });
47
-
48
- const newContent = print(ast);
49
-
50
- writeFileContent(file, newContent);
51
- };
52
-
53
- export const scan = (rootPath, {push, trackFile}) => {
54
- const mask = [
55
- '*.js',
56
- '*.mjs',
57
- ];
58
-
59
- const getPrivateImports = createGetPrivateImports();
60
- const crawled = crawlDirectory(rootPath);
61
-
62
- for (const file of trackFile(rootPath, mask)) {
63
- const content = readFileContent(file);
64
- const [error, ast] = tryCatch(parse, content);
65
-
66
- if (error)
67
- continue;
68
-
69
- const importsTuples = getImports(file, content, ast);
70
-
71
- const privateImports = getPrivateImports(file, {
72
- aliasBased: true,
73
- });
74
-
75
- for (const [name, source, importedFilename] of importsTuples) {
76
- const importType = determineImportType({
77
- name,
78
- rootPath,
79
- importedFilename,
80
- privateImports,
81
- crawled,
82
- });
83
-
84
- if (!importType)
85
- continue;
86
-
87
- push(file, {
88
- importType,
89
- name,
90
- source,
91
- ast,
92
- content,
93
- });
94
- }
95
- }
96
- };
97
-
98
- function getImports(file, content, ast) {
99
- if (!content.includes('import'))
100
- return [];
101
-
102
- const places = transform(ast, content, {
103
- fix: false,
104
- plugins: [
105
- ['get-imports', getImportsPlugin],
106
- ],
107
- });
108
-
109
- const filename = getFilename(file);
110
- const dir = dirname(filename);
111
-
112
- const imports = places.map(getMessage);
113
-
114
- return buildImports(dir, imports);
115
- }
116
-
117
- function parseFull(dir, source) {
118
- if (source.startsWith('#'))
119
- return source;
120
-
121
- return join(dir, source);
122
- }
123
-
124
- function buildImports(dir, imports) {
125
- const list = [];
126
-
127
- for (const current of imports) {
128
- const [name, source] = current.split(' <- ');
129
- const full = parseFull(dir, source);
130
-
131
- list.push([name, source, full]);
132
- }
133
-
134
- return list;
135
- }