@putout/plugin-esm 7.0.0 → 7.1.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
@@ -36,6 +36,7 @@ npm i putout @putout/plugin-esm -D
36
36
 
37
37
  - ✅ [apply-namespace-import-file](#resolve-imported-file);
38
38
  - ✅ [apply-privately-imported-file](#apply-privately-imported-file);
39
+ - ✅ [apply-js-imported-file](#apply-js-imported-file);
39
40
  - ✅ [resolve-imported-file](#resolve-imported-file);
40
41
  - ✅ [shorten-imported-file](#shorten-imported-file);
41
42
 
@@ -57,6 +58,7 @@ npm i putout @putout/plugin-esm -D
57
58
  "ignore": []
58
59
  }],
59
60
  "esm/sort-imports-by-specifiers": "on",
61
+ "esm/apply-js-imported-file": "off",
60
62
  "esm/resolve-imported-file": "off",
61
63
  "esm/shorten-imported-file": "off",
62
64
  "esm/apply-namespace-of-file": "off",
@@ -534,6 +536,36 @@ import {parseProcessorNames} from '../processors/parse-processor-names.js';
534
536
  import {parseProcessorNames} from './parse-processor-names.js';
535
537
  ```
536
538
 
539
+ ### apply-js-imported-file
540
+
541
+ Check out in 🐊**Putout Editor**:
542
+
543
+ - ✅ [`get-imports`](https://putout.cloudcmd.io/#/gist/ee10100fed86e4db926885dd54298668/7538bca7a9ae006d976f41261c0ed4c0e1902ace);
544
+ - ✅ [`change-imports`](https://putout.cloudcmd.io/#/gist/23a6dc6741b772c03fbed95feda2b451/1fbecac6fc40282bcda0593aa666a8c213ef85b7);
545
+
546
+ Let's consider file structure:
547
+
548
+ ```
549
+ /
550
+ |-- lib/
551
+ | `-- index.js
552
+ | `-- a.js
553
+ ```
554
+
555
+ In this case `index.js` can be fixed:
556
+
557
+ #### ❌ Example of incorrect code
558
+
559
+ ```js
560
+ import a from './a.mjs';
561
+ ```
562
+
563
+ #### ✅ Example of correct code
564
+
565
+ ```js
566
+ import a from './a.js';
567
+ ```
568
+
537
569
  ## License
538
570
 
539
571
  MIT
@@ -0,0 +1,148 @@
1
+ import {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 * as getImports from '../shorten-imported-file/get-imports/index.js';
10
+ import * as changeImports from '../resolve-imported-file/change-imports/index.js';
11
+
12
+ const {
13
+ getFilename,
14
+ getFileType,
15
+ getParentDirectory,
16
+ readFileContent,
17
+ writeFileContent,
18
+ readDirectory,
19
+ } = operator;
20
+
21
+ const {parse: parseJson} = JSON;
22
+
23
+ const getMessage = (a) => a.message;
24
+ const applyJS = (a) => a.replace(/\.[cm]js$/, '.js');
25
+
26
+ export const report = (file, {from, to}) => `Apply 'js' imported source: '${from}' -> '${to}'`;
27
+ export const fix = (file, {content, ast, from, to}) => {
28
+ transform(ast, content, {
29
+ rules: {
30
+ 'change-imports': ['on', {
31
+ from,
32
+ to,
33
+ }],
34
+ },
35
+ plugins: [
36
+ ['change-imports', changeImports],
37
+ ],
38
+ });
39
+
40
+ const newContent = print(ast);
41
+
42
+ writeFileContent(file, newContent);
43
+ };
44
+
45
+ export const scan = (rootPath, {push, trackFile}) => {
46
+ const mask = [
47
+ '*.js',
48
+ '*.mjs',
49
+ ];
50
+
51
+ const getPackageType = createGetPackageType();
52
+
53
+ for (const file of trackFile(rootPath, mask)) {
54
+ const content = readFileContent(file);
55
+
56
+ if (!content.includes('import'))
57
+ continue;
58
+
59
+ const ast = parse(content);
60
+
61
+ const places = transform(ast, content, {
62
+ plugins: [
63
+ ['get-imports', getImports],
64
+ ],
65
+ });
66
+
67
+ const imports = places.map(getMessage);
68
+ const type = getPackageType(file);
69
+
70
+ if (!type)
71
+ continue;
72
+
73
+ for (const from of imports) {
74
+ const to = applyJS(from);
75
+
76
+ if (type === 'module' && from.endsWith('.mjs')) {
77
+ push(file, {
78
+ from,
79
+ to,
80
+ content,
81
+ ast,
82
+ });
83
+ continue;
84
+ }
85
+
86
+ if (type === 'commonjs' && from.endsWith('.cjs')) {
87
+ push(file, {
88
+ from,
89
+ to,
90
+ content,
91
+ ast,
92
+ });
93
+ continue;
94
+ }
95
+ }
96
+ }
97
+ };
98
+
99
+ const createGetPackageType = (importsCache = new Map()) => (file) => {
100
+ const filename = getFilename(file);
101
+ const dir = dirname(filename);
102
+
103
+ if (importsCache.has(dir))
104
+ return importsCache.get(dir);
105
+
106
+ const [, packagePath] = findPackage(file);
107
+
108
+ if (!packagePath) {
109
+ importsCache.set(dir, 'commonjs');
110
+ return 'commonjs';
111
+ }
112
+
113
+ const packageContent = readFileContent(packagePath);
114
+ const [error, packageJson] = tryCatch(parseJson, packageContent);
115
+
116
+ if (error) {
117
+ importsCache.set(dir, '');
118
+ return '';
119
+ }
120
+
121
+ const {type = 'commonjs'} = packageJson;
122
+
123
+ importsCache.set(dir, type);
124
+
125
+ return type;
126
+ };
127
+
128
+ function findPackage(file) {
129
+ const parentDirectory = getParentDirectory(file);
130
+ const directoryName = getFilename(parentDirectory);
131
+
132
+ for (const currentFile of readDirectory(parentDirectory)) {
133
+ const type = getFileType(currentFile);
134
+
135
+ if (type === 'directory')
136
+ continue;
137
+
138
+ const currentName = getFilename(currentFile);
139
+
140
+ if (currentName.endsWith('package.json'))
141
+ return [directoryName, currentFile];
142
+ }
143
+
144
+ if (directoryName === '/')
145
+ return [];
146
+
147
+ return findPackage(parentDirectory);
148
+ }
package/lib/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import * as applyExportFrom from './apply-export-from/index.js';
2
+ import * as applyJsImportedFile from './apply-js-imported-file/index.js';
2
3
  import * as mergeExportDeclarations from './merge-export-declarations/index.js';
3
4
  import * as removeUselessExportSpecifiers from './remove-useless-export-specifiers/index.js';
4
5
  import * as mergeDeclarationWithExport from './merge-declaration-with-export/index.js';
@@ -35,4 +36,5 @@ export const rules = {
35
36
  'shorten-imported-file': ['off', shortenImportedFile],
36
37
  'apply-namespace-import-to-file': ['off', applyNamespaceImportToFile],
37
38
  'apply-privately-imported-file': ['off', applyPrivatelyImportedFile],
39
+ 'apply-js-imported-file': ['off', applyJsImportedFile],
38
40
  };
@@ -12,5 +12,5 @@ export const filter = (path) => {
12
12
  if (!value.startsWith('.'))
13
13
  return false;
14
14
 
15
- return /\.m?js/.test(value);
15
+ return /\.[mc]?js/.test(value);
16
16
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@putout/plugin-esm",
3
- "version": "7.0.0",
3
+ "version": "7.1.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",