@bpmn-io/codemods 0.3.0 → 0.3.1
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/esm/lib/resolve.js +71 -2
- package/package.json +1 -1
package/esm/lib/resolve.js
CHANGED
|
@@ -72,6 +72,11 @@ export function resolveImport(specifier, fromFile, options = {}) {
|
|
|
72
72
|
return { status: 'skip', specifier };
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
+
// bare subpath covered by package.json exports → already valid for ESM
|
|
76
|
+
if (bare && isSubpathExported(specifier, fromFile)) {
|
|
77
|
+
return { status: 'skip', specifier };
|
|
78
|
+
}
|
|
79
|
+
|
|
75
80
|
const rewritten = bare
|
|
76
81
|
? resolveBare(specifier, fromFile)
|
|
77
82
|
: resolveRelative(specifier, fromFile);
|
|
@@ -110,7 +115,20 @@ function resolveBare(specifier, fromFile) {
|
|
|
110
115
|
return null;
|
|
111
116
|
}
|
|
112
117
|
|
|
113
|
-
|
|
118
|
+
const basePath = path.join(pkgDir, subpath);
|
|
119
|
+
|
|
120
|
+
const direct = resolveCandidates(basePath, specifier, BARE_CANDIDATES);
|
|
121
|
+
if (direct) return direct;
|
|
122
|
+
|
|
123
|
+
if (isDirectory(basePath)) {
|
|
124
|
+
return resolveCandidates(
|
|
125
|
+
path.join(basePath, 'index'),
|
|
126
|
+
specifier + '/index',
|
|
127
|
+
BARE_CANDIDATES
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return null;
|
|
114
132
|
}
|
|
115
133
|
|
|
116
134
|
function resolveCandidates(basePath, specifier, candidates) {
|
|
@@ -125,7 +143,8 @@ function resolveCandidates(basePath, specifier, candidates) {
|
|
|
125
143
|
|
|
126
144
|
/**
|
|
127
145
|
* Locate a package directory by walking up the `node_modules` chain, starting
|
|
128
|
-
* from the importing file's directory.
|
|
146
|
+
* from the importing file's directory. Also handles self-referencing: if a
|
|
147
|
+
* directory's own `package.json` names the package, that directory is returned.
|
|
129
148
|
*/
|
|
130
149
|
function findPackageDir(pkg, fromDir) {
|
|
131
150
|
let dir = fromDir;
|
|
@@ -137,6 +156,10 @@ function findPackageDir(pkg, fromDir) {
|
|
|
137
156
|
return candidate;
|
|
138
157
|
}
|
|
139
158
|
|
|
159
|
+
if (readJson(path.join(dir, 'package.json'))?.name === pkg) {
|
|
160
|
+
return dir;
|
|
161
|
+
}
|
|
162
|
+
|
|
140
163
|
const parent = path.dirname(dir);
|
|
141
164
|
|
|
142
165
|
if (parent === dir) {
|
|
@@ -201,3 +224,49 @@ function isDirectory(p) {
|
|
|
201
224
|
return false;
|
|
202
225
|
}
|
|
203
226
|
}
|
|
227
|
+
|
|
228
|
+
function readJson(filePath) {
|
|
229
|
+
try {
|
|
230
|
+
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
231
|
+
} catch {
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Returns true if the bare subpath import is declared in the package's
|
|
238
|
+
* `exports` field, meaning it is already valid for ESM and should not be
|
|
239
|
+
* rewritten.
|
|
240
|
+
*/
|
|
241
|
+
function isSubpathExported(specifier, fromFile) {
|
|
242
|
+
const { pkg, subpath } = parseBare(specifier);
|
|
243
|
+
if (!subpath) return false;
|
|
244
|
+
|
|
245
|
+
const pkgDir = findPackageDir(pkg, path.dirname(fromFile));
|
|
246
|
+
if (!pkgDir) return false;
|
|
247
|
+
|
|
248
|
+
const exports = readJson(path.join(pkgDir, 'package.json'))?.exports;
|
|
249
|
+
if (!exports || typeof exports !== 'object') return false;
|
|
250
|
+
|
|
251
|
+
const key = './' + subpath;
|
|
252
|
+
|
|
253
|
+
if (key in exports) return true;
|
|
254
|
+
|
|
255
|
+
for (const [ pattern, valueTemplate ] of Object.entries(exports)) {
|
|
256
|
+
if (!pattern.includes('*') || typeof valueTemplate !== 'string') {
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, '\\$&').replace(/\*/g, '(.*)');
|
|
261
|
+
const match = new RegExp('^' + escaped + '$').exec(key);
|
|
262
|
+
|
|
263
|
+
if (!match) continue;
|
|
264
|
+
|
|
265
|
+
// wildcard matched: only treat as already-valid if the resolved target
|
|
266
|
+
// is an actual file — a directory target still needs rewriting to index.js
|
|
267
|
+
const resolved = valueTemplate.replace(/\*/g, match[1]);
|
|
268
|
+
if (isFile(path.join(pkgDir, resolved))) return true;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
return false;
|
|
272
|
+
}
|