@tamagui/babel-plugin-fully-specified 1.101.7 → 1.102.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/dist/cjs/index.js +98 -74
- package/dist/cjs/index.js.map +2 -2
- package/dist/cjs/index.native.js +98 -121
- package/dist/cjs/index.native.js.map +2 -2
- package/dist/esm/index.js +97 -79
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/index.mjs +105 -91
- package/dist/esm/index.native.js +97 -121
- package/dist/esm/index.native.js.map +2 -2
- package/package.json +6 -4
- package/src/__tests__/__snapshots__/index.test.ts.snap +21 -0
- package/src/__tests__/fixtures/force-extension/bar.js +1 -0
- package/src/__tests__/fixtures/force-extension/foo.js +1 -0
- package/src/__tests__/fixtures/multiple-extensions-exists/modules/module.cjs +2 -0
- package/src/__tests__/fixtures/multiple-extensions-exists/modules/module.js +2 -0
- package/src/__tests__/fixtures/multiple-extensions-exists/modules/module.mjs +4 -0
- package/src/__tests__/fixtures/multiple-extensions-exists/test.mjs +2 -0
- package/src/__tests__/fixtures/sample-project-1/modules/cjs-module.cjs +2 -0
- package/src/__tests__/fixtures/sample-project-1/modules/module.mjs +4 -0
- package/src/__tests__/fixtures/sample-project-1/node_modules/@my-org/my-pkg/lib/exampleFunction.js +3 -0
- package/src/__tests__/fixtures/sample-project-1/node_modules/@my-org/my-pkg/lib/index.js +1 -0
- package/src/__tests__/fixtures/sample-project-1/node_modules/@my-org/my-pkg/package.json +4 -0
- package/src/__tests__/fixtures/sample-project-1/node_modules/README.md +1 -0
- package/src/__tests__/fixtures/sample-project-1/test.mjs +13 -0
- package/src/__tests__/index.test.ts +139 -0
- package/src/index.ts +220 -140
- package/types/index.d.ts +14 -21
- package/types/index.d.ts.map +1 -1
package/dist/esm/index.js
CHANGED
|
@@ -1,41 +1,82 @@
|
|
|
1
1
|
import { existsSync, readFileSync, lstatSync } from "node:fs";
|
|
2
2
|
import { resolve, extname, dirname } from "node:path";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
return;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
3
|
+
const DEFAULT_OPTIONS = {
|
|
4
|
+
ensureFileExists: !1,
|
|
5
|
+
esExtensionDefault: ".js",
|
|
6
|
+
tryExtensions: [".js", ".mjs", ".cjs"],
|
|
7
|
+
esExtensions: [".js", ".mjs", ".cjs"],
|
|
8
|
+
includePackages: []
|
|
9
|
+
};
|
|
10
|
+
function FullySpecified(api, rawOptions) {
|
|
11
|
+
api.assertVersion(7);
|
|
12
|
+
const options = { ...DEFAULT_OPTIONS, ...rawOptions }, importDeclarationVisitor = (path, state) => {
|
|
13
|
+
const filePath = state.file.opts.filename;
|
|
14
|
+
if (!filePath) return;
|
|
15
|
+
const { node } = path;
|
|
16
|
+
if (node.importKind === "type") return;
|
|
17
|
+
const originalModuleSpecifier = node.source.value, fullySpecifiedModuleSpecifier = getFullySpecifiedModuleSpecifier(
|
|
18
|
+
originalModuleSpecifier,
|
|
19
|
+
{
|
|
20
|
+
filePath,
|
|
21
|
+
options
|
|
22
|
+
}
|
|
23
|
+
);
|
|
24
|
+
fullySpecifiedModuleSpecifier && (node.source.value = fullySpecifiedModuleSpecifier);
|
|
25
|
+
}, exportDeclarationVisitor = (path, state) => {
|
|
26
|
+
const filePath = state.file.opts.filename;
|
|
27
|
+
if (!filePath) return;
|
|
28
|
+
const { node } = path;
|
|
29
|
+
if (node.exportKind === "type") return;
|
|
30
|
+
const source = node.source;
|
|
31
|
+
if (!source) return;
|
|
32
|
+
const originalModuleSpecifier = source.value, fullySpecifiedModuleSpecifier = getFullySpecifiedModuleSpecifier(
|
|
33
|
+
originalModuleSpecifier,
|
|
34
|
+
{
|
|
35
|
+
filePath,
|
|
36
|
+
options
|
|
37
|
+
}
|
|
38
|
+
);
|
|
39
|
+
fullySpecifiedModuleSpecifier && (source.value = fullySpecifiedModuleSpecifier);
|
|
40
|
+
};
|
|
41
|
+
return {
|
|
42
|
+
name: "babel-plugin-fully-specified",
|
|
43
|
+
visitor: {
|
|
44
|
+
ImportDeclaration: importDeclarationVisitor,
|
|
45
|
+
ExportNamedDeclaration: exportDeclarationVisitor,
|
|
46
|
+
ExportAllDeclaration: exportDeclarationVisitor,
|
|
47
|
+
Import: (path, state) => {
|
|
48
|
+
const filePath = state.file.opts.filename;
|
|
49
|
+
if (!filePath) return;
|
|
50
|
+
const parent = path.parent;
|
|
51
|
+
if (parent.type !== "CallExpression")
|
|
52
|
+
return;
|
|
53
|
+
const firstArgOfImportCall = parent.arguments[0];
|
|
54
|
+
if (firstArgOfImportCall.type !== "StringLiteral")
|
|
55
|
+
return;
|
|
56
|
+
const originalModuleSpecifier = firstArgOfImportCall.value, fullySpecifiedModuleSpecifier = getFullySpecifiedModuleSpecifier(
|
|
57
|
+
originalModuleSpecifier,
|
|
58
|
+
{
|
|
59
|
+
filePath,
|
|
60
|
+
options
|
|
61
|
+
}
|
|
62
|
+
);
|
|
63
|
+
fullySpecifiedModuleSpecifier && (firstArgOfImportCall.value = fullySpecifiedModuleSpecifier);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function getFullySpecifiedModuleSpecifier(originalModuleSpecifier, {
|
|
69
|
+
filePath,
|
|
70
|
+
options
|
|
71
|
+
}) {
|
|
72
|
+
const fileExt = extname(filePath), fileDir = dirname(filePath), { includePackages } = options;
|
|
32
73
|
let packageData = null;
|
|
33
|
-
if (!isLocalFile(
|
|
34
|
-
return;
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
filenameDirectory,
|
|
38
|
-
filenameExtension,
|
|
74
|
+
if (!isLocalFile(originalModuleSpecifier) && (includePackages.some((name) => originalModuleSpecifier.startsWith(name)) && (packageData = getPackageData(originalModuleSpecifier, filePath)), !(packageData && packageData.isDeepImport)))
|
|
75
|
+
return null;
|
|
76
|
+
const isDirectory = isLocalDirectory(resolve(fileDir, originalModuleSpecifier)), currentModuleExtension = extname(originalModuleSpecifier), { tryExtensions, esExtensions, esExtensionDefault, ensureFileExists } = options, targetModule = evaluateTargetModule({
|
|
77
|
+
moduleSpecifier: originalModuleSpecifier,
|
|
78
|
+
filenameDirectory: fileDir,
|
|
79
|
+
filenameExtension: fileExt,
|
|
39
80
|
packageData,
|
|
40
81
|
currentModuleExtension,
|
|
41
82
|
isDirectory,
|
|
@@ -44,39 +85,13 @@ const makeDeclaration = ({
|
|
|
44
85
|
esExtensionDefault,
|
|
45
86
|
ensureFileExists
|
|
46
87
|
});
|
|
47
|
-
|
|
48
|
-
return;
|
|
49
|
-
const nodes = makeNodes(path);
|
|
50
|
-
path.replaceWith(
|
|
51
|
-
// @ts-ignore
|
|
52
|
-
declaration.apply(null, [...nodes, stringLiteral(targetModule.module)])
|
|
53
|
-
);
|
|
54
|
-
};
|
|
55
|
-
function FullySpecified(api, options) {
|
|
56
|
-
return api.assertVersion(7), {
|
|
57
|
-
name: "babel-plugin-fully-specified",
|
|
58
|
-
visitor: {
|
|
59
|
-
ImportDeclaration: makeDeclaration({
|
|
60
|
-
...options,
|
|
61
|
-
declaration: importDeclaration,
|
|
62
|
-
makeNodes: ({ node: { specifiers } }) => [specifiers]
|
|
63
|
-
}),
|
|
64
|
-
ExportNamedDeclaration: makeDeclaration({
|
|
65
|
-
...options,
|
|
66
|
-
declaration: exportNamedDeclaration,
|
|
67
|
-
makeNodes: ({ node: { declaration, specifiers } }) => [declaration, specifiers]
|
|
68
|
-
}),
|
|
69
|
-
ExportAllDeclaration: makeDeclaration({
|
|
70
|
-
...options,
|
|
71
|
-
declaration: exportAllDeclaration,
|
|
72
|
-
makeNodes: () => []
|
|
73
|
-
})
|
|
74
|
-
}
|
|
75
|
-
};
|
|
88
|
+
return targetModule === !1 || currentModuleExtension === targetModule.extension ? null : targetModule.module;
|
|
76
89
|
}
|
|
77
|
-
function getPackageData(
|
|
90
|
+
function getPackageData(moduleSpecifier, filePath) {
|
|
78
91
|
try {
|
|
79
|
-
const
|
|
92
|
+
const modulePath = require.resolve(moduleSpecifier, {
|
|
93
|
+
paths: filePath ? [filePath] : []
|
|
94
|
+
}), parts = modulePath.split("/");
|
|
80
95
|
let packageDir = "";
|
|
81
96
|
for (let i = parts.length; i >= 0; i--) {
|
|
82
97
|
const dir = dirname(parts.slice(0, i).join("/"));
|
|
@@ -88,19 +103,19 @@ function getPackageData(module) {
|
|
|
88
103
|
if (!packageDir)
|
|
89
104
|
throw new Error("no package dir");
|
|
90
105
|
const packageJson = JSON.parse(readFileSync(`${packageDir}/package.json`).toString());
|
|
91
|
-
return {
|
|
106
|
+
return { isDeepImport: !moduleSpecifier.endsWith(packageJson.name), modulePath };
|
|
92
107
|
} catch {
|
|
93
108
|
}
|
|
94
109
|
return null;
|
|
95
110
|
}
|
|
96
|
-
function isLocalFile(
|
|
97
|
-
return
|
|
111
|
+
function isLocalFile(moduleSpecifier) {
|
|
112
|
+
return moduleSpecifier.startsWith(".") || moduleSpecifier.startsWith("/");
|
|
98
113
|
}
|
|
99
114
|
function isLocalDirectory(absoluteDirectory) {
|
|
100
115
|
return existsSync(absoluteDirectory) && lstatSync(absoluteDirectory).isDirectory();
|
|
101
116
|
}
|
|
102
117
|
function evaluateTargetModule({
|
|
103
|
-
|
|
118
|
+
moduleSpecifier,
|
|
104
119
|
currentModuleExtension,
|
|
105
120
|
packageData,
|
|
106
121
|
isDirectory,
|
|
@@ -112,8 +127,8 @@ function evaluateTargetModule({
|
|
|
112
127
|
ensureFileExists
|
|
113
128
|
}) {
|
|
114
129
|
if (packageData)
|
|
115
|
-
return packageData.
|
|
116
|
-
module:
|
|
130
|
+
return packageData.modulePath.endsWith("index.js") && !moduleSpecifier.endsWith("index.js") && (moduleSpecifier = `${moduleSpecifier}/index`), {
|
|
131
|
+
module: moduleSpecifier + esExtensionDefault,
|
|
117
132
|
extension: esExtensionDefault
|
|
118
133
|
};
|
|
119
134
|
if (currentModuleExtension && !esExtensions.includes(currentModuleExtension))
|
|
@@ -121,24 +136,27 @@ function evaluateTargetModule({
|
|
|
121
136
|
isDirectory && !existsSync(
|
|
122
137
|
resolve(
|
|
123
138
|
filenameDirectory,
|
|
124
|
-
currentModuleExtension ?
|
|
139
|
+
currentModuleExtension ? moduleSpecifier : moduleSpecifier + esExtensionDefault
|
|
125
140
|
)
|
|
126
|
-
) && (
|
|
127
|
-
const targetFile = resolve(filenameDirectory,
|
|
141
|
+
) && (moduleSpecifier = `${moduleSpecifier}/index`);
|
|
142
|
+
const targetFile = resolve(filenameDirectory, moduleSpecifier);
|
|
128
143
|
if (ensureFileExists) {
|
|
129
144
|
if (esExtensions.includes(filenameExtension) && existsSync(targetFile + filenameExtension))
|
|
130
145
|
return {
|
|
131
|
-
module:
|
|
146
|
+
module: moduleSpecifier + (ensureFileExists.forceExtension || filenameExtension),
|
|
132
147
|
extension: filenameExtension
|
|
133
148
|
};
|
|
134
149
|
for (const extension of tryExtensions)
|
|
135
150
|
if (existsSync(targetFile + extension))
|
|
136
|
-
return {
|
|
151
|
+
return {
|
|
152
|
+
module: moduleSpecifier + (ensureFileExists.forceExtension || extension),
|
|
153
|
+
extension
|
|
154
|
+
};
|
|
137
155
|
} else return esExtensions.includes(filenameExtension) ? {
|
|
138
|
-
module:
|
|
156
|
+
module: moduleSpecifier + filenameExtension,
|
|
139
157
|
extension: filenameExtension
|
|
140
158
|
} : {
|
|
141
|
-
module:
|
|
159
|
+
module: moduleSpecifier + esExtensionDefault,
|
|
142
160
|
extension: esExtensionDefault
|
|
143
161
|
};
|
|
144
162
|
return !1;
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/index.ts"],
|
|
4
|
-
"mappings": "AAAA,SAAS,YAAY,cAAc,iBAAiB;AACpD,SAAS,SAAS,SAAS,eAAe;
|
|
4
|
+
"mappings": "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",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
package/dist/esm/index.mjs
CHANGED
|
@@ -1,47 +1,94 @@
|
|
|
1
1
|
import { existsSync, readFileSync, lstatSync } from "node:fs";
|
|
2
2
|
import { resolve, extname, dirname } from "node:path";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
3
|
+
const DEFAULT_OPTIONS = {
|
|
4
|
+
ensureFileExists: !1,
|
|
5
|
+
esExtensionDefault: ".js",
|
|
6
|
+
tryExtensions: [".js", ".mjs", ".cjs"],
|
|
7
|
+
esExtensions: [".js", ".mjs", ".cjs"],
|
|
8
|
+
includePackages: []
|
|
9
|
+
};
|
|
10
|
+
function FullySpecified(api, rawOptions) {
|
|
11
|
+
api.assertVersion(7);
|
|
12
|
+
const options = {
|
|
13
|
+
...DEFAULT_OPTIONS,
|
|
14
|
+
...rawOptions
|
|
15
|
+
},
|
|
16
|
+
importDeclarationVisitor = (path, state) => {
|
|
17
|
+
const filePath = state.file.opts.filename;
|
|
18
|
+
if (!filePath) return;
|
|
19
|
+
const {
|
|
20
|
+
node
|
|
21
|
+
} = path;
|
|
22
|
+
if (node.importKind === "type") return;
|
|
23
|
+
const originalModuleSpecifier = node.source.value,
|
|
24
|
+
fullySpecifiedModuleSpecifier = getFullySpecifiedModuleSpecifier(originalModuleSpecifier, {
|
|
25
|
+
filePath,
|
|
26
|
+
options
|
|
27
|
+
});
|
|
28
|
+
fullySpecifiedModuleSpecifier && (node.source.value = fullySpecifiedModuleSpecifier);
|
|
29
|
+
},
|
|
30
|
+
exportDeclarationVisitor = (path, state) => {
|
|
31
|
+
const filePath = state.file.opts.filename;
|
|
32
|
+
if (!filePath) return;
|
|
33
|
+
const {
|
|
34
|
+
node
|
|
35
|
+
} = path;
|
|
36
|
+
if (node.exportKind === "type") return;
|
|
37
|
+
const source = node.source;
|
|
38
|
+
if (!source) return;
|
|
39
|
+
const originalModuleSpecifier = source.value,
|
|
40
|
+
fullySpecifiedModuleSpecifier = getFullySpecifiedModuleSpecifier(originalModuleSpecifier, {
|
|
41
|
+
filePath,
|
|
42
|
+
options
|
|
43
|
+
});
|
|
44
|
+
fullySpecifiedModuleSpecifier && (source.value = fullySpecifiedModuleSpecifier);
|
|
45
|
+
};
|
|
46
|
+
return {
|
|
47
|
+
name: "babel-plugin-fully-specified",
|
|
48
|
+
visitor: {
|
|
49
|
+
ImportDeclaration: importDeclarationVisitor,
|
|
50
|
+
ExportNamedDeclaration: exportDeclarationVisitor,
|
|
51
|
+
ExportAllDeclaration: exportDeclarationVisitor,
|
|
52
|
+
Import: (path, state) => {
|
|
53
|
+
const filePath = state.file.opts.filename;
|
|
54
|
+
if (!filePath) return;
|
|
55
|
+
const parent = path.parent;
|
|
56
|
+
if (parent.type !== "CallExpression") return;
|
|
57
|
+
const firstArgOfImportCall = parent.arguments[0];
|
|
58
|
+
if (firstArgOfImportCall.type !== "StringLiteral") return;
|
|
59
|
+
const originalModuleSpecifier = firstArgOfImportCall.value,
|
|
60
|
+
fullySpecifiedModuleSpecifier = getFullySpecifiedModuleSpecifier(originalModuleSpecifier, {
|
|
61
|
+
filePath,
|
|
62
|
+
options
|
|
63
|
+
});
|
|
64
|
+
fullySpecifiedModuleSpecifier && (firstArgOfImportCall.value = fullySpecifiedModuleSpecifier);
|
|
65
|
+
}
|
|
19
66
|
}
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const {
|
|
32
|
-
value
|
|
33
|
-
} = source,
|
|
34
|
-
module = value;
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function getFullySpecifiedModuleSpecifier(originalModuleSpecifier, {
|
|
70
|
+
filePath,
|
|
71
|
+
options
|
|
72
|
+
}) {
|
|
73
|
+
const fileExt = extname(filePath),
|
|
74
|
+
fileDir = dirname(filePath),
|
|
75
|
+
{
|
|
76
|
+
includePackages
|
|
77
|
+
} = options;
|
|
35
78
|
let packageData = null;
|
|
36
|
-
if (!isLocalFile(
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
79
|
+
if (!isLocalFile(originalModuleSpecifier) && (includePackages.some(name => originalModuleSpecifier.startsWith(name)) && (packageData = getPackageData(originalModuleSpecifier, filePath)), !(packageData && packageData.isDeepImport))) return null;
|
|
80
|
+
const isDirectory = isLocalDirectory(resolve(fileDir, originalModuleSpecifier)),
|
|
81
|
+
currentModuleExtension = extname(originalModuleSpecifier),
|
|
82
|
+
{
|
|
83
|
+
tryExtensions,
|
|
84
|
+
esExtensions,
|
|
85
|
+
esExtensionDefault,
|
|
86
|
+
ensureFileExists
|
|
87
|
+
} = options,
|
|
41
88
|
targetModule = evaluateTargetModule({
|
|
42
|
-
|
|
43
|
-
filenameDirectory,
|
|
44
|
-
filenameExtension,
|
|
89
|
+
moduleSpecifier: originalModuleSpecifier,
|
|
90
|
+
filenameDirectory: fileDir,
|
|
91
|
+
filenameExtension: fileExt,
|
|
45
92
|
packageData,
|
|
46
93
|
currentModuleExtension,
|
|
47
94
|
isDirectory,
|
|
@@ -50,47 +97,14 @@ const makeDeclaration = ({
|
|
|
50
97
|
esExtensionDefault,
|
|
51
98
|
ensureFileExists
|
|
52
99
|
});
|
|
53
|
-
|
|
54
|
-
const nodes = makeNodes(path);
|
|
55
|
-
path.replaceWith(
|
|
56
|
-
// @ts-ignore
|
|
57
|
-
declaration.apply(null, [...nodes, stringLiteral(targetModule.module)]));
|
|
58
|
-
};
|
|
59
|
-
function FullySpecified(api, options) {
|
|
60
|
-
return api.assertVersion(7), {
|
|
61
|
-
name: "babel-plugin-fully-specified",
|
|
62
|
-
visitor: {
|
|
63
|
-
ImportDeclaration: makeDeclaration({
|
|
64
|
-
...options,
|
|
65
|
-
declaration: importDeclaration,
|
|
66
|
-
makeNodes: ({
|
|
67
|
-
node: {
|
|
68
|
-
specifiers
|
|
69
|
-
}
|
|
70
|
-
}) => [specifiers]
|
|
71
|
-
}),
|
|
72
|
-
ExportNamedDeclaration: makeDeclaration({
|
|
73
|
-
...options,
|
|
74
|
-
declaration: exportNamedDeclaration,
|
|
75
|
-
makeNodes: ({
|
|
76
|
-
node: {
|
|
77
|
-
declaration,
|
|
78
|
-
specifiers
|
|
79
|
-
}
|
|
80
|
-
}) => [declaration, specifiers]
|
|
81
|
-
}),
|
|
82
|
-
ExportAllDeclaration: makeDeclaration({
|
|
83
|
-
...options,
|
|
84
|
-
declaration: exportAllDeclaration,
|
|
85
|
-
makeNodes: () => []
|
|
86
|
-
})
|
|
87
|
-
}
|
|
88
|
-
};
|
|
100
|
+
return targetModule === !1 || currentModuleExtension === targetModule.extension ? null : targetModule.module;
|
|
89
101
|
}
|
|
90
|
-
function getPackageData(
|
|
102
|
+
function getPackageData(moduleSpecifier, filePath) {
|
|
91
103
|
try {
|
|
92
|
-
const
|
|
93
|
-
|
|
104
|
+
const modulePath = require.resolve(moduleSpecifier, {
|
|
105
|
+
paths: filePath ? [filePath] : []
|
|
106
|
+
}),
|
|
107
|
+
parts = modulePath.split("/");
|
|
94
108
|
let packageDir = "";
|
|
95
109
|
for (let i = parts.length; i >= 0; i--) {
|
|
96
110
|
const dir = dirname(parts.slice(0, i).join("/"));
|
|
@@ -102,20 +116,20 @@ function getPackageData(module) {
|
|
|
102
116
|
if (!packageDir) throw new Error("no package dir");
|
|
103
117
|
const packageJson = JSON.parse(readFileSync(`${packageDir}/package.json`).toString());
|
|
104
118
|
return {
|
|
105
|
-
|
|
106
|
-
|
|
119
|
+
isDeepImport: !moduleSpecifier.endsWith(packageJson.name),
|
|
120
|
+
modulePath
|
|
107
121
|
};
|
|
108
122
|
} catch {}
|
|
109
123
|
return null;
|
|
110
124
|
}
|
|
111
|
-
function isLocalFile(
|
|
112
|
-
return
|
|
125
|
+
function isLocalFile(moduleSpecifier) {
|
|
126
|
+
return moduleSpecifier.startsWith(".") || moduleSpecifier.startsWith("/");
|
|
113
127
|
}
|
|
114
128
|
function isLocalDirectory(absoluteDirectory) {
|
|
115
129
|
return existsSync(absoluteDirectory) && lstatSync(absoluteDirectory).isDirectory();
|
|
116
130
|
}
|
|
117
131
|
function evaluateTargetModule({
|
|
118
|
-
|
|
132
|
+
moduleSpecifier,
|
|
119
133
|
currentModuleExtension,
|
|
120
134
|
packageData,
|
|
121
135
|
isDirectory,
|
|
@@ -126,27 +140,27 @@ function evaluateTargetModule({
|
|
|
126
140
|
esExtensionDefault,
|
|
127
141
|
ensureFileExists
|
|
128
142
|
}) {
|
|
129
|
-
if (packageData) return packageData.
|
|
130
|
-
module:
|
|
143
|
+
if (packageData) return packageData.modulePath.endsWith("index.js") && !moduleSpecifier.endsWith("index.js") && (moduleSpecifier = `${moduleSpecifier}/index`), {
|
|
144
|
+
module: moduleSpecifier + esExtensionDefault,
|
|
131
145
|
extension: esExtensionDefault
|
|
132
146
|
};
|
|
133
147
|
if (currentModuleExtension && !esExtensions.includes(currentModuleExtension)) return !1;
|
|
134
|
-
isDirectory && !existsSync(resolve(filenameDirectory, currentModuleExtension ?
|
|
135
|
-
const targetFile = resolve(filenameDirectory,
|
|
148
|
+
isDirectory && !existsSync(resolve(filenameDirectory, currentModuleExtension ? moduleSpecifier : moduleSpecifier + esExtensionDefault)) && (moduleSpecifier = `${moduleSpecifier}/index`);
|
|
149
|
+
const targetFile = resolve(filenameDirectory, moduleSpecifier);
|
|
136
150
|
if (ensureFileExists) {
|
|
137
151
|
if (esExtensions.includes(filenameExtension) && existsSync(targetFile + filenameExtension)) return {
|
|
138
|
-
module:
|
|
152
|
+
module: moduleSpecifier + (ensureFileExists.forceExtension || filenameExtension),
|
|
139
153
|
extension: filenameExtension
|
|
140
154
|
};
|
|
141
155
|
for (const extension of tryExtensions) if (existsSync(targetFile + extension)) return {
|
|
142
|
-
module:
|
|
156
|
+
module: moduleSpecifier + (ensureFileExists.forceExtension || extension),
|
|
143
157
|
extension
|
|
144
158
|
};
|
|
145
159
|
} else return esExtensions.includes(filenameExtension) ? {
|
|
146
|
-
module:
|
|
160
|
+
module: moduleSpecifier + filenameExtension,
|
|
147
161
|
extension: filenameExtension
|
|
148
162
|
} : {
|
|
149
|
-
module:
|
|
163
|
+
module: moduleSpecifier + esExtensionDefault,
|
|
150
164
|
extension: esExtensionDefault
|
|
151
165
|
};
|
|
152
166
|
return !1;
|