package-management 0.0.16 → 0.2.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/LICENSE +21 -0
- package/dist/index.cjs +548 -359
- package/dist/index.d.cts +249 -73
- package/dist/index.d.mts +249 -73
- package/dist/index.d.ts +249 -73
- package/dist/index.mjs +538 -361
- package/package.json +11 -13
package/dist/index.cjs
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const ErrorStackParser = require('error-stack-parser');
|
|
4
3
|
const path = require('pathe');
|
|
5
|
-
const
|
|
6
|
-
const path$1 = require('node:path');
|
|
4
|
+
const util = require('node:util');
|
|
7
5
|
const node_url = require('node:url');
|
|
8
6
|
const node_fs = require('node:fs');
|
|
9
7
|
const asyncCacheFn = require('async-cache-fn');
|
|
@@ -11,17 +9,20 @@ const execa = require('execa');
|
|
|
11
9
|
const findUp = require('find-up');
|
|
12
10
|
const promises = require('node:fs/promises');
|
|
13
11
|
const mlly = require('mlly');
|
|
12
|
+
const WST = require('workspace-tools');
|
|
13
|
+
const process = require('node:process');
|
|
14
|
+
const path$1 = require('node:path');
|
|
14
15
|
const globby = require('globby');
|
|
15
16
|
const gitignoreParser = require('parse-gitignore');
|
|
16
|
-
const WST = require('workspace-tools');
|
|
17
17
|
const utils = require('pathe/utils');
|
|
18
18
|
const os = require('node:os');
|
|
19
19
|
const jsoncParser = require('jsonc-parser');
|
|
20
|
-
const
|
|
20
|
+
const confbox = require('confbox');
|
|
21
21
|
const unstorage = require('unstorage');
|
|
22
22
|
const defineMemoryDriver = require('unstorage/drivers/memory');
|
|
23
23
|
const defineFsLiteDriver = require('unstorage/drivers/fs-lite');
|
|
24
24
|
|
|
25
|
+
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
25
26
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
|
26
27
|
|
|
27
28
|
function _interopNamespaceCompat(e) {
|
|
@@ -36,16 +37,87 @@ function _interopNamespaceCompat(e) {
|
|
|
36
37
|
return n;
|
|
37
38
|
}
|
|
38
39
|
|
|
39
|
-
const
|
|
40
|
-
const
|
|
40
|
+
const path__default = /*#__PURE__*/_interopDefaultCompat(path);
|
|
41
|
+
const util__default = /*#__PURE__*/_interopDefaultCompat(util);
|
|
42
|
+
const WST__namespace = /*#__PURE__*/_interopNamespaceCompat(WST);
|
|
41
43
|
const process__default = /*#__PURE__*/_interopDefaultCompat(process);
|
|
42
|
-
const path__default = /*#__PURE__*/_interopDefaultCompat(path$1);
|
|
44
|
+
const path__default$1 = /*#__PURE__*/_interopDefaultCompat(path$1);
|
|
43
45
|
const gitignoreParser__default = /*#__PURE__*/_interopDefaultCompat(gitignoreParser);
|
|
44
|
-
const WST__namespace = /*#__PURE__*/_interopNamespaceCompat(WST);
|
|
45
46
|
const os__default = /*#__PURE__*/_interopDefaultCompat(os);
|
|
46
47
|
const defineMemoryDriver__default = /*#__PURE__*/_interopDefaultCompat(defineMemoryDriver);
|
|
47
48
|
const defineFsLiteDriver__default = /*#__PURE__*/_interopDefaultCompat(defineFsLiteDriver);
|
|
48
49
|
|
|
50
|
+
const getCallSites = "getCallSites" in util__default ? util__default.getCallSites : void 0;
|
|
51
|
+
const MAX_FRAMES = 200;
|
|
52
|
+
function resolveCallerFile(options) {
|
|
53
|
+
const { from, boundaryFunctionName, internalScripts = [] } = options ?? {};
|
|
54
|
+
if (from) return toCallerPath(String(from));
|
|
55
|
+
if (getCallSites === void 0) return void 0;
|
|
56
|
+
const sites = getCallSites(MAX_FRAMES, { sourceMap: true });
|
|
57
|
+
const scriptName = boundaryFunctionName && frameAfterFunction(sites, boundaryFunctionName) || firstForeignFrame(sites, [OWN_SCRIPT, ...internalScripts]);
|
|
58
|
+
return scriptName ? toFilePath(scriptName) : void 0;
|
|
59
|
+
}
|
|
60
|
+
const OWN_SCRIPT = (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href));
|
|
61
|
+
function frameAfterFunction(sites, functionName) {
|
|
62
|
+
const boundary = sites.findIndex((site) => site.functionName === functionName);
|
|
63
|
+
return boundary === -1 ? void 0 : sites[boundary + 1]?.scriptName;
|
|
64
|
+
}
|
|
65
|
+
function firstForeignFrame(sites, internalScripts) {
|
|
66
|
+
const internal = new Set(internalScripts.map(toFilePath));
|
|
67
|
+
return sites.find(
|
|
68
|
+
(site) => (
|
|
69
|
+
// Frames from `node:` internals and evaluated code name no file, so they
|
|
70
|
+
// are never the caller's location however far out they appear.
|
|
71
|
+
isFileScript(site.scriptName) && !internal.has(toFilePath(site.scriptName))
|
|
72
|
+
)
|
|
73
|
+
)?.scriptName;
|
|
74
|
+
}
|
|
75
|
+
const isFileScript = (script) => Boolean(script) && (script.startsWith("file:") || path.isAbsolute(script));
|
|
76
|
+
const toFilePath = (script) => script.startsWith("file:") ? node_url.fileURLToPath(script) : script;
|
|
77
|
+
function toCallerPath(from) {
|
|
78
|
+
if (from.startsWith("file:")) return node_url.fileURLToPath(from);
|
|
79
|
+
if (path.isAbsolute(from)) return from;
|
|
80
|
+
throw new Error(
|
|
81
|
+
`\`from\` must be a file: URL or an absolute path, received ${JSON.stringify(from)}. Pass \`import.meta.url\`.`
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const _filename = (options) => resolveCallerFile(withOwnScript(options));
|
|
86
|
+
const _dirname = (options) => {
|
|
87
|
+
const filePath = resolveCallerFile(withOwnScript(options));
|
|
88
|
+
return filePath === void 0 ? void 0 : path.dirname(filePath);
|
|
89
|
+
};
|
|
90
|
+
const withOwnScript = (options) => ({
|
|
91
|
+
...options,
|
|
92
|
+
internalScripts: [...options?.internalScripts ?? [], (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))]
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
function createFile(filePath, data, options) {
|
|
96
|
+
const { encoding = "utf-8", ...rest } = typeof options === "string" ? { encoding: options } : options ?? {};
|
|
97
|
+
const dir = path__default.dirname(filePath);
|
|
98
|
+
const writeFileOptions = { encoding, ...rest };
|
|
99
|
+
if (!node_fs.existsSync(dir)) {
|
|
100
|
+
node_fs.mkdirSync(dir, { recursive: true });
|
|
101
|
+
}
|
|
102
|
+
node_fs.writeFileSync(filePath, data, writeFileOptions);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function readFile(filePath, options) {
|
|
106
|
+
return node_fs.readFileSync(filePath, options?.encoding ?? "utf-8");
|
|
107
|
+
}
|
|
108
|
+
function readFileSafely(filePath, options) {
|
|
109
|
+
return node_fs.existsSync(filePath) ? readFile(filePath, options) : void 0;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function isWritable(filename) {
|
|
113
|
+
try {
|
|
114
|
+
node_fs.accessSync(filename, node_fs.constants.W_OK);
|
|
115
|
+
return true;
|
|
116
|
+
} catch (e) {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
49
121
|
const toArray = (data) => Array.isArray(data) ? data : [data];
|
|
50
122
|
const entriesOf = (o) => Object.entries(o);
|
|
51
123
|
const fromEntries = (entries) => Object.fromEntries(entries);
|
|
@@ -59,7 +131,7 @@ const select = (obj, selection, mode) => {
|
|
|
59
131
|
};
|
|
60
132
|
function normalizePath(path$1, option) {
|
|
61
133
|
if (typeof option === "function") {
|
|
62
|
-
return
|
|
134
|
+
return option(path$1);
|
|
63
135
|
}
|
|
64
136
|
if (option === false) {
|
|
65
137
|
return path$1;
|
|
@@ -71,14 +143,6 @@ const invariant = (predicate, message) => {
|
|
|
71
143
|
throw new Error(message);
|
|
72
144
|
}
|
|
73
145
|
};
|
|
74
|
-
function getArrayItemAtOffset(arr, index, offset = 0) {
|
|
75
|
-
if (arr === void 0 || index === void 0) return void 0;
|
|
76
|
-
return arr[index + offset];
|
|
77
|
-
}
|
|
78
|
-
function isMatching(a, b) {
|
|
79
|
-
if (!a || !b) return false;
|
|
80
|
-
return a === b;
|
|
81
|
-
}
|
|
82
146
|
function checkResult(cb, options) {
|
|
83
147
|
try {
|
|
84
148
|
return buildSingleProp({
|
|
@@ -103,123 +167,16 @@ function buildSingleProp(entry) {
|
|
|
103
167
|
return { [key]: value };
|
|
104
168
|
}
|
|
105
169
|
|
|
106
|
-
function findCallerStackFrame(options) {
|
|
107
|
-
return findErrorStackFrame(options, (frame) => frame.isParentOfRootFunction);
|
|
108
|
-
}
|
|
109
|
-
function findErrorStackFrame(options, find) {
|
|
110
|
-
return getErrorStackFrames(options, find)[0];
|
|
111
|
-
}
|
|
112
|
-
function getErrorStackFrames(options, filter) {
|
|
113
|
-
const { error, rootFunctionName, startFrom = "top" } = options;
|
|
114
|
-
const frames = startFrom === "bottom" ? ErrorStackParser__default.parse(error).reverse() : ErrorStackParser__default.parse(error);
|
|
115
|
-
const { parsedFrames } = frames.reduce(
|
|
116
|
-
(acc, frame, index) => {
|
|
117
|
-
const parsed = parseFrame({
|
|
118
|
-
frame,
|
|
119
|
-
index,
|
|
120
|
-
rootFunctionName,
|
|
121
|
-
frames
|
|
122
|
-
});
|
|
123
|
-
const isValid = filter ? filter(parsed) : true;
|
|
124
|
-
if (isValid) {
|
|
125
|
-
acc.parsedFrames.push(parsed);
|
|
126
|
-
}
|
|
127
|
-
return acc;
|
|
128
|
-
},
|
|
129
|
-
{ parsedFrames: [] }
|
|
130
|
-
);
|
|
131
|
-
return parsedFrames ?? [];
|
|
132
|
-
}
|
|
133
|
-
function parseFrame(options) {
|
|
134
|
-
const { frame, frames, index, rootFunctionName, cwd, debug } = options ?? {};
|
|
135
|
-
const functionName = parseFunctionName(frame.functionName);
|
|
136
|
-
const isRootFunction = isMatching(functionName, rootFunctionName);
|
|
137
|
-
const beforeFrameFunctionName = parseFunctionName(
|
|
138
|
-
getArrayItemAtOffset(frames, index, -1)?.functionName
|
|
139
|
-
);
|
|
140
|
-
const isParentOfRootFunction = isMatching(
|
|
141
|
-
beforeFrameFunctionName,
|
|
142
|
-
rootFunctionName
|
|
143
|
-
);
|
|
144
|
-
const fileData = frame.fileName ? getFilePathData({ filepath: frame.fileName, cwd }) : void 0;
|
|
145
|
-
const { isFileInCwd: isFrameInScope, ...restFileData } = fileData ?? {};
|
|
146
|
-
const data = {
|
|
147
|
-
...restFileData,
|
|
148
|
-
functionName,
|
|
149
|
-
source: frame.source,
|
|
150
|
-
sourceFunctionName: frame.functionName,
|
|
151
|
-
isFrameInScope,
|
|
152
|
-
place: placeFormatter(index, frames?.length),
|
|
153
|
-
isRootFunction,
|
|
154
|
-
isParentOfRootFunction,
|
|
155
|
-
rootFunctionName
|
|
156
|
-
};
|
|
157
|
-
debug && console.log(data);
|
|
158
|
-
return data;
|
|
159
|
-
}
|
|
160
|
-
function getFilePathData({
|
|
161
|
-
filepath,
|
|
162
|
-
cwd
|
|
163
|
-
}) {
|
|
164
|
-
const workingDir = cwd ?? process__default.cwd();
|
|
165
|
-
const filePath = path.normalize(toFilePath(filepath));
|
|
166
|
-
const fileBasename = path.basename(filePath);
|
|
167
|
-
const dirPath = path.dirname(filePath);
|
|
168
|
-
const dirBasename = path.basename(dirPath);
|
|
169
|
-
const relativeFilePath = path.relative(workingDir, filePath);
|
|
170
|
-
const relativeDirPath = path.dirname(relativeFilePath);
|
|
171
|
-
const isFileInCwd = filePath.startsWith(workingDir);
|
|
172
|
-
return {
|
|
173
|
-
filePath,
|
|
174
|
-
dirPath,
|
|
175
|
-
relativeFilePath,
|
|
176
|
-
relativeDirPath,
|
|
177
|
-
fileBasename,
|
|
178
|
-
dirBasename,
|
|
179
|
-
isFileInCwd
|
|
180
|
-
};
|
|
181
|
-
}
|
|
182
|
-
function toFilePath(fileName) {
|
|
183
|
-
return fileName.startsWith("file:") ? node_url.fileURLToPath(fileName) : fileName;
|
|
184
|
-
}
|
|
185
|
-
function parseFunctionName(functionName) {
|
|
186
|
-
if (!functionName) return void 0;
|
|
187
|
-
return removeStart(functionName, "Module.");
|
|
188
|
-
}
|
|
189
|
-
function removeStart(input, value) {
|
|
190
|
-
return input.startsWith(value) ? input.slice(value.length) : input;
|
|
191
|
-
}
|
|
192
|
-
function placeFormatter(index, total) {
|
|
193
|
-
if (index === void 0 || !total) return void 0;
|
|
194
|
-
return [index, total].join("/");
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
const _filename = (options) => {
|
|
198
|
-
const { filePath } = findCallerStackFrame({ error: new Error(), ...options }) ?? {};
|
|
199
|
-
return filePath;
|
|
200
|
-
};
|
|
201
|
-
const _dirname = (options) => {
|
|
202
|
-
const { dirPath } = findCallerStackFrame({ error: new Error(), ...options }) ?? {};
|
|
203
|
-
return dirPath;
|
|
204
|
-
};
|
|
205
|
-
|
|
206
170
|
async function resolveModule(module) {
|
|
207
171
|
const resolved = await module;
|
|
208
|
-
|
|
172
|
+
const hasDefault = resolved !== null && typeof resolved === "object" && "default" in resolved;
|
|
173
|
+
return hasDefault ? resolved.default : resolved;
|
|
209
174
|
}
|
|
210
175
|
function isPackageModuleFound(name, options) {
|
|
211
176
|
return Boolean(resolvePackageModulePath(name, options));
|
|
212
177
|
}
|
|
213
178
|
function resolvePackageModulePath(name, options) {
|
|
214
|
-
|
|
215
|
-
[`${name}/package.json`, name],
|
|
216
|
-
options
|
|
217
|
-
);
|
|
218
|
-
if (resolvedPath === void 0) {
|
|
219
|
-
console.error(`Could not resolve package ${name}`);
|
|
220
|
-
return void 0;
|
|
221
|
-
}
|
|
222
|
-
return resolvedPath;
|
|
179
|
+
return findResolvedModulePath([`${name}/package.json`, name], options);
|
|
223
180
|
}
|
|
224
181
|
function findResolvedModulePath(paths, options) {
|
|
225
182
|
for (const path of paths) {
|
|
@@ -241,28 +198,68 @@ function resolveModulePath(modulePath, options) {
|
|
|
241
198
|
}
|
|
242
199
|
}
|
|
243
200
|
|
|
201
|
+
function getPackageFolder(options) {
|
|
202
|
+
return WST__namespace.findPackageRoot(options?.cwd ?? process__default.cwd());
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function getPackageInfo(options) {
|
|
206
|
+
const packageDir = getPackageFolder(options);
|
|
207
|
+
if (!packageDir) {
|
|
208
|
+
throw new Error(
|
|
209
|
+
`No package.json found searching up from "${options?.cwd ?? process__default.cwd()}"`
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
return readPackageInfo({ packageDir });
|
|
213
|
+
}
|
|
214
|
+
function readPackageInfo({
|
|
215
|
+
packageDir
|
|
216
|
+
}) {
|
|
217
|
+
const packageJsonPath = path__default$1.join(packageDir, "package.json");
|
|
218
|
+
const packageJson = readPackageJson(packageJsonPath);
|
|
219
|
+
return {
|
|
220
|
+
name: packageJson.name,
|
|
221
|
+
path: packageJsonPath,
|
|
222
|
+
dirpath: packageDir,
|
|
223
|
+
packageJson
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
const packageJsonCache = /* @__PURE__ */ new Map();
|
|
227
|
+
function readPackageJson(packageJsonPath) {
|
|
228
|
+
const { mtimeMs } = node_fs.statSync(packageJsonPath);
|
|
229
|
+
const cached = packageJsonCache.get(packageJsonPath);
|
|
230
|
+
if (cached?.mtimeMs === mtimeMs) return cached.packageJson;
|
|
231
|
+
const packageJson = JSON.parse(
|
|
232
|
+
node_fs.readFileSync(packageJsonPath, "utf-8")
|
|
233
|
+
);
|
|
234
|
+
packageJsonCache.set(packageJsonPath, { mtimeMs, packageJson });
|
|
235
|
+
return packageJson;
|
|
236
|
+
}
|
|
237
|
+
|
|
244
238
|
const tsconfig = (tsconfigDir) => ({
|
|
245
239
|
get paths() {
|
|
240
|
+
if (!tsconfigDir) return [];
|
|
246
241
|
return globby.globbySync(["tsconfig.json", "tsconfig.*.json"], {
|
|
247
|
-
cwd: tsconfigDir
|
|
248
|
-
|
|
242
|
+
cwd: tsconfigDir,
|
|
243
|
+
absolute: true
|
|
244
|
+
});
|
|
249
245
|
}
|
|
250
246
|
});
|
|
251
247
|
|
|
252
|
-
function
|
|
253
|
-
return gitignoreParser__default(
|
|
248
|
+
function parseGitignoreContent(gitignoreContent, options) {
|
|
249
|
+
return gitignoreParser__default(gitignoreContent, options);
|
|
254
250
|
}
|
|
255
|
-
function getGitignoreData(gitignorePath) {
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
251
|
+
function getGitignoreData(gitignorePath, options) {
|
|
252
|
+
if (!gitignorePath || !node_fs.existsSync(gitignorePath)) {
|
|
253
|
+
return parseGitignoreContent("", options);
|
|
254
|
+
}
|
|
255
|
+
return parseGitignoreContent(node_fs.readFileSync(gitignorePath, "utf-8"), options);
|
|
259
256
|
}
|
|
260
|
-
const gitignore = (gitignorePath) => ({
|
|
257
|
+
const gitignore = (gitignorePath, options) => ({
|
|
261
258
|
get data() {
|
|
262
|
-
return getGitignoreData(gitignorePath);
|
|
259
|
+
return getGitignoreData(gitignorePath, options);
|
|
263
260
|
},
|
|
264
261
|
get patterns() {
|
|
265
|
-
return getGitignoreData(gitignorePath).patterns;
|
|
262
|
+
return getGitignoreData(gitignorePath, options).patterns;
|
|
266
263
|
}
|
|
267
264
|
});
|
|
268
265
|
|
|
@@ -325,36 +322,13 @@ function getWorkspaceFolder(options) {
|
|
|
325
322
|
throwIfNotFound = true
|
|
326
323
|
} = options ?? {};
|
|
327
324
|
const getFolder = fallbackToGitRoot ? WST__namespace.findProjectRoot : WST__namespace.getWorkspaceManagerRoot;
|
|
328
|
-
const folder = getFolder(cwd);
|
|
325
|
+
const folder = checkResult(() => getFolder(cwd)).data;
|
|
329
326
|
if (folder === void 0 && throwIfNotFound) {
|
|
330
327
|
throw new Error(`Could not find workspace folder`);
|
|
331
328
|
}
|
|
332
329
|
return folder;
|
|
333
330
|
}
|
|
334
331
|
|
|
335
|
-
function getPackageFolder(options) {
|
|
336
|
-
return WST__namespace.findPackageRoot(options?.cwd ?? process__default.cwd());
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
function getPackageInfo(options) {
|
|
340
|
-
const packageDir = getPackageFolder(options);
|
|
341
|
-
return readPackageInfo({ packageDir });
|
|
342
|
-
}
|
|
343
|
-
function readPackageInfo({
|
|
344
|
-
packageDir
|
|
345
|
-
}) {
|
|
346
|
-
const packageJsonPath = path__default.join(packageDir, "package.json");
|
|
347
|
-
const packageJson = JSON.parse(
|
|
348
|
-
node_fs.readFileSync(packageJsonPath, "utf-8")
|
|
349
|
-
);
|
|
350
|
-
return {
|
|
351
|
-
name: packageJson.name,
|
|
352
|
-
path: packageJsonPath,
|
|
353
|
-
dirpath: packageDir,
|
|
354
|
-
packageJson
|
|
355
|
-
};
|
|
356
|
-
}
|
|
357
|
-
|
|
358
332
|
function getWorkspaceProjectInfo(options) {
|
|
359
333
|
try {
|
|
360
334
|
const workspaceDir = getWorkspaceFolder(options);
|
|
@@ -370,13 +344,21 @@ function getWorkspacePackageInfoList(options) {
|
|
|
370
344
|
const wstList = WST__namespace.getWorkspaceInfos(workspaceDir);
|
|
371
345
|
return resolveWstList(wstList);
|
|
372
346
|
}
|
|
347
|
+
function toPackageInfo(info) {
|
|
348
|
+
return {
|
|
349
|
+
name: info.name,
|
|
350
|
+
dirpath: info.path,
|
|
351
|
+
path: path.join(info.path, "package.json"),
|
|
352
|
+
packageJson: info.packageJson
|
|
353
|
+
};
|
|
354
|
+
}
|
|
373
355
|
function common(options) {
|
|
374
356
|
const { cwd, includeRoot: includeWorkspace } = options ?? {};
|
|
375
357
|
const workspaceDir = getWorkspaceFolder({ cwd });
|
|
376
358
|
function resolveWstList(list) {
|
|
377
359
|
if (!workspaceDir || !list) return [];
|
|
378
|
-
|
|
379
|
-
return
|
|
360
|
+
const packages = list.map(toPackageInfo);
|
|
361
|
+
return includeWorkspace ? [getWorkspaceProjectInfo({ cwd }), ...packages] : packages;
|
|
380
362
|
}
|
|
381
363
|
return {
|
|
382
364
|
workspaceDir,
|
|
@@ -393,7 +375,7 @@ function getWorkspacePackageInfoMap(options) {
|
|
|
393
375
|
|
|
394
376
|
function getProjectInfoByName(name, options) {
|
|
395
377
|
const { cwd } = options ?? {};
|
|
396
|
-
return getWorkspacePackageInfoMap({ cwd })[name];
|
|
378
|
+
return getWorkspacePackageInfoMap({ cwd, includeRoot: true })[name];
|
|
397
379
|
}
|
|
398
380
|
|
|
399
381
|
function getGitRootFolder(options) {
|
|
@@ -408,7 +390,7 @@ function getGitRootFolder(options) {
|
|
|
408
390
|
}
|
|
409
391
|
return void 0;
|
|
410
392
|
}
|
|
411
|
-
return path__default
|
|
393
|
+
return path__default.normalize(stdout);
|
|
412
394
|
}
|
|
413
395
|
|
|
414
396
|
function getProjectInfo(folder, options) {
|
|
@@ -439,9 +421,14 @@ function parseWorkspaceFolderTypeOptions(option, defaultOptions) {
|
|
|
439
421
|
|
|
440
422
|
const project = (...args) => {
|
|
441
423
|
const [source, projectOptions] = args;
|
|
442
|
-
const { packageJson, packageJsonPath, packageName, projectDir } = info();
|
|
443
424
|
const {
|
|
444
|
-
|
|
425
|
+
packageJson,
|
|
426
|
+
name: packageName,
|
|
427
|
+
dirpath: projectDir,
|
|
428
|
+
path: packageJsonPath
|
|
429
|
+
} = getProjectInfo(source, projectOptions) ?? {};
|
|
430
|
+
const {
|
|
431
|
+
findPackageManager,
|
|
445
432
|
detectPackageManagers,
|
|
446
433
|
detectLockfilePackageManagers,
|
|
447
434
|
detectGlobalPackageManagers,
|
|
@@ -449,41 +436,29 @@ const project = (...args) => {
|
|
|
449
436
|
filterPackageManagers,
|
|
450
437
|
mapPackageManagers
|
|
451
438
|
} = definePackageManagerClient({ cwd: projectDir });
|
|
439
|
+
const getPackageJson = () => projectDir ? readPackageInfo({ packageDir: projectDir }).packageJson : packageJson;
|
|
452
440
|
return {
|
|
453
441
|
packageJson,
|
|
454
442
|
packageJsonPath,
|
|
455
443
|
packageName,
|
|
456
444
|
projectDir,
|
|
457
|
-
findPackageManager
|
|
445
|
+
findPackageManager,
|
|
458
446
|
detectPackageManagers,
|
|
459
447
|
detectGlobalPackageManagers,
|
|
460
448
|
detectLockfilePackageManagers,
|
|
461
449
|
globalVersions,
|
|
462
450
|
mapPackageManagers,
|
|
463
|
-
|
|
464
|
-
|
|
451
|
+
// Passed through as-is: substituting "" for an unresolved project made
|
|
452
|
+
// both of these read from the calling process's directory instead.
|
|
453
|
+
tsconfig: tsconfig(projectDir),
|
|
454
|
+
gitignore: gitignore(
|
|
455
|
+
projectDir ? path__default.join(projectDir, ".gitignore") : void 0
|
|
456
|
+
),
|
|
465
457
|
filterPackageManagers,
|
|
466
|
-
getPackageJson
|
|
467
|
-
findDependencyInPackageJson: (options) => findDependencyInPackageJson(options,
|
|
468
|
-
isDependencyInPackageJson: (options) => isDependencyInPackageJson(options,
|
|
458
|
+
getPackageJson,
|
|
459
|
+
findDependencyInPackageJson: (options) => findDependencyInPackageJson(options, getPackageJson()),
|
|
460
|
+
isDependencyInPackageJson: (options) => isDependencyInPackageJson(options, getPackageJson())
|
|
469
461
|
};
|
|
470
|
-
function info() {
|
|
471
|
-
const {
|
|
472
|
-
packageJson: packageJson2,
|
|
473
|
-
name: packageName2,
|
|
474
|
-
dirpath: projectDir2,
|
|
475
|
-
path: packageJsonPath2
|
|
476
|
-
} = getProjectInfo(source, projectOptions) ?? {};
|
|
477
|
-
return {
|
|
478
|
-
packageJson: packageJson2,
|
|
479
|
-
packageJsonPath: packageJsonPath2,
|
|
480
|
-
packageName: packageName2,
|
|
481
|
-
projectDir: projectDir2
|
|
482
|
-
};
|
|
483
|
-
}
|
|
484
|
-
function get(key) {
|
|
485
|
-
return info()[key];
|
|
486
|
-
}
|
|
487
462
|
};
|
|
488
463
|
|
|
489
464
|
function getWorkspacePackageNames(options) {
|
|
@@ -498,18 +473,24 @@ const workspace = {
|
|
|
498
473
|
getProject: project
|
|
499
474
|
};
|
|
500
475
|
|
|
501
|
-
function importer(imports, options) {
|
|
476
|
+
async function importer(imports, options) {
|
|
502
477
|
const { install: defaultInstall = true, installer } = options ?? {};
|
|
478
|
+
const resolved = imports.map((option) => resolveImportOption(option));
|
|
479
|
+
const missing = resolved.filter(
|
|
480
|
+
(option) => Boolean(option.name) && (option.install ?? defaultInstall) && !((option.checkExists ?? true) && isSatisfied(option.name))
|
|
481
|
+
);
|
|
482
|
+
await installMissing(
|
|
483
|
+
missing.filter(({ dev }) => !dev).map(({ name }) => name),
|
|
484
|
+
{ dev: false },
|
|
485
|
+
installer
|
|
486
|
+
);
|
|
487
|
+
await installMissing(
|
|
488
|
+
missing.filter(({ dev }) => dev).map(({ name }) => name),
|
|
489
|
+
{ dev: true },
|
|
490
|
+
installer
|
|
491
|
+
);
|
|
503
492
|
return Promise.all(
|
|
504
|
-
|
|
505
|
-
const importOpt = resolveImportOption(e);
|
|
506
|
-
const shouldInstall = importOpt.install ?? defaultInstall;
|
|
507
|
-
if (shouldInstall && importOpt.name) {
|
|
508
|
-
await installImport(importOpt.name, importOpt, installer);
|
|
509
|
-
}
|
|
510
|
-
const m = await importOpt.import();
|
|
511
|
-
return resolveModule(m);
|
|
512
|
-
})
|
|
493
|
+
resolved.map(async (option) => resolveModule(await option.import()))
|
|
513
494
|
);
|
|
514
495
|
}
|
|
515
496
|
const definePackage = (option) => {
|
|
@@ -533,12 +514,11 @@ function resolveImportOption(option) {
|
|
|
533
514
|
}
|
|
534
515
|
return option;
|
|
535
516
|
}
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
if (checkExists && isPackageDependency(packageName)) return;
|
|
517
|
+
const isSatisfied = (packageName) => isPackageDependency(packageName) && isPackageModuleFound(packageName);
|
|
518
|
+
async function installMissing(packageNames, options, installer) {
|
|
519
|
+
if (packageNames.length === 0) return;
|
|
540
520
|
const installerFn = installer ?? (await workspace.getProject("<package_folder>").findPackageManager()).installPackage;
|
|
541
|
-
await installerFn(
|
|
521
|
+
await installerFn(packageNames, options);
|
|
542
522
|
}
|
|
543
523
|
|
|
544
524
|
const importMap = async (importMap2, options) => {
|
|
@@ -560,20 +540,36 @@ function definePackageManager(config, options) {
|
|
|
560
540
|
const lockfiles = toArray(config.meta.lockfile);
|
|
561
541
|
return await findUp.findUp(lockfiles, { cwd });
|
|
562
542
|
});
|
|
543
|
+
const globalVersion = asyncCacheFn.asyncCacheFn(
|
|
544
|
+
async (options2) => {
|
|
545
|
+
try {
|
|
546
|
+
const { stdout } = await $$({
|
|
547
|
+
command,
|
|
548
|
+
args: [agentOptions.version],
|
|
549
|
+
cwd: defaultCwd,
|
|
550
|
+
...options2
|
|
551
|
+
});
|
|
552
|
+
return `${stdout}`.trim();
|
|
553
|
+
} catch {
|
|
554
|
+
return void 0;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
);
|
|
563
558
|
const installPackage = async (packageName, options2) => {
|
|
564
559
|
const install = agentArgs.install;
|
|
565
|
-
const { dev, preferOffline } =
|
|
566
|
-
|
|
567
|
-
{
|
|
568
|
-
preferOffline: true,
|
|
569
|
-
cwd: defaultCwd,
|
|
570
|
-
...options2
|
|
571
|
-
});
|
|
560
|
+
const { dev = false, preferOffline = true } = options2 ?? {};
|
|
561
|
+
const flags = select(install.options, { dev, preferOffline });
|
|
572
562
|
const packageNames = toArray(packageName);
|
|
563
|
+
assertInstallableNames(packageNames);
|
|
573
564
|
try {
|
|
574
565
|
await $$({
|
|
575
566
|
command,
|
|
576
|
-
args: [
|
|
567
|
+
args: [
|
|
568
|
+
install.command,
|
|
569
|
+
flags.dev,
|
|
570
|
+
flags.preferOffline,
|
|
571
|
+
...packageNames
|
|
572
|
+
],
|
|
577
573
|
cwd: defaultCwd,
|
|
578
574
|
...options2
|
|
579
575
|
});
|
|
@@ -617,19 +613,12 @@ function definePackageManager(config, options) {
|
|
|
617
613
|
if (!lockfilePath) return void 0;
|
|
618
614
|
return promises.readFile(lockfilePath, "utf8");
|
|
619
615
|
}),
|
|
620
|
-
globalVersion
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
cwd: defaultCwd,
|
|
627
|
-
...options2
|
|
628
|
-
});
|
|
629
|
-
return `${stdout}`;
|
|
630
|
-
} catch (e) {
|
|
631
|
-
return void 0;
|
|
632
|
-
}
|
|
616
|
+
globalVersion,
|
|
617
|
+
matchesVersion: asyncCacheFn.asyncCacheFn(async (...args) => {
|
|
618
|
+
const { matchesVersion } = config.meta;
|
|
619
|
+
if (!matchesVersion) return true;
|
|
620
|
+
const version = await globalVersion.noCache(...args);
|
|
621
|
+
return version ? matchesVersion(version) : false;
|
|
633
622
|
}),
|
|
634
623
|
definePackage,
|
|
635
624
|
installPackage,
|
|
@@ -643,6 +632,16 @@ function definePackageManager(config, options) {
|
|
|
643
632
|
}
|
|
644
633
|
};
|
|
645
634
|
}
|
|
635
|
+
function assertInstallableNames(packageNames) {
|
|
636
|
+
const rejected = packageNames.filter(
|
|
637
|
+
(name) => name.length === 0 || name.startsWith("-")
|
|
638
|
+
);
|
|
639
|
+
if (rejected.length > 0) {
|
|
640
|
+
throw new Error(
|
|
641
|
+
`Not a package name: ${rejected.map((name) => JSON.stringify(name)).join(", ")}. A package name cannot be empty or begin with "-".`
|
|
642
|
+
);
|
|
643
|
+
}
|
|
644
|
+
}
|
|
646
645
|
async function $$(options) {
|
|
647
646
|
const { command, args = [], silent = true, cwd, shellOptions } = options;
|
|
648
647
|
return execa.execa(command, args.filter(notFalsy), {
|
|
@@ -665,7 +664,9 @@ const bun = definePackageManagerConfig({
|
|
|
665
664
|
command: "bun",
|
|
666
665
|
runner: "bunx",
|
|
667
666
|
meta: {
|
|
668
|
-
lockfile
|
|
667
|
+
// Bun wrote a binary lockfile originally and a text one from 1.2 onwards,
|
|
668
|
+
// so a project using either must still be detected.
|
|
669
|
+
lockfile: ["bun.lock", "bun.lockb"]
|
|
669
670
|
},
|
|
670
671
|
args: {
|
|
671
672
|
install: {
|
|
@@ -676,7 +677,7 @@ const bun = definePackageManagerConfig({
|
|
|
676
677
|
}
|
|
677
678
|
},
|
|
678
679
|
uninstall: {
|
|
679
|
-
command: "
|
|
680
|
+
command: "remove"
|
|
680
681
|
}
|
|
681
682
|
},
|
|
682
683
|
options: {
|
|
@@ -740,7 +741,9 @@ const yarn = definePackageManagerConfig({
|
|
|
740
741
|
command: "yarn",
|
|
741
742
|
runner: "yarn dlx",
|
|
742
743
|
meta: {
|
|
743
|
-
lockfile: "yarn.lock"
|
|
744
|
+
lockfile: "yarn.lock",
|
|
745
|
+
// Berry shares this command and lockfile, so the version decides.
|
|
746
|
+
matchesVersion: (version) => version.startsWith("1.")
|
|
744
747
|
},
|
|
745
748
|
args: {
|
|
746
749
|
install: {
|
|
@@ -759,6 +762,33 @@ const yarn = definePackageManagerConfig({
|
|
|
759
762
|
}
|
|
760
763
|
});
|
|
761
764
|
|
|
765
|
+
const yarnBerry = definePackageManagerConfig({
|
|
766
|
+
id: "yarn-berry",
|
|
767
|
+
name: "Yarn Berry",
|
|
768
|
+
command: "yarn",
|
|
769
|
+
runner: "yarn dlx",
|
|
770
|
+
meta: {
|
|
771
|
+
lockfile: "yarn.lock",
|
|
772
|
+
// Classic shares this command and lockfile; everything past 1.x is Berry.
|
|
773
|
+
matchesVersion: (version) => !version.startsWith("1.")
|
|
774
|
+
},
|
|
775
|
+
args: {
|
|
776
|
+
install: {
|
|
777
|
+
command: "add",
|
|
778
|
+
options: {
|
|
779
|
+
dev: "-D",
|
|
780
|
+
preferOffline: "--cached"
|
|
781
|
+
}
|
|
782
|
+
},
|
|
783
|
+
uninstall: {
|
|
784
|
+
command: "remove"
|
|
785
|
+
}
|
|
786
|
+
},
|
|
787
|
+
options: {
|
|
788
|
+
version: "--version"
|
|
789
|
+
}
|
|
790
|
+
});
|
|
791
|
+
|
|
762
792
|
async function findPackageManager(packageManagers, options) {
|
|
763
793
|
const packageManager = await findPackageManagerSafely(
|
|
764
794
|
packageManagers,
|
|
@@ -788,7 +818,9 @@ async function detectPackageManagers(packageManagers, options) {
|
|
|
788
818
|
async function detectLockfilePackageManagers(packageManagers, options) {
|
|
789
819
|
return filterPackageManagers(
|
|
790
820
|
packageManagers,
|
|
791
|
-
|
|
821
|
+
// Yarn Classic and Berry share a lockfile name, so a lockfile match alone
|
|
822
|
+
// would report both. The version check settles which one it is.
|
|
823
|
+
async (packageManager) => await packageManager.hasLockfile(options) && await packageManager.matchesVersion(options),
|
|
792
824
|
options
|
|
793
825
|
);
|
|
794
826
|
}
|
|
@@ -798,7 +830,7 @@ async function detectGlobalPackageManagers(packageManagers, options) {
|
|
|
798
830
|
// Without the `await`, `Boolean` receives a pending promise and is always
|
|
799
831
|
// `true`, so every package manager passes the filter regardless of whether
|
|
800
832
|
// it is actually installed.
|
|
801
|
-
async (packageManager) => Boolean(await packageManager.globalVersion(options)),
|
|
833
|
+
async (packageManager) => Boolean(await packageManager.globalVersion(options)) && await packageManager.matchesVersion(options),
|
|
802
834
|
options
|
|
803
835
|
);
|
|
804
836
|
}
|
|
@@ -831,7 +863,7 @@ function selectAllowedPackageManagers(packageManagers, options) {
|
|
|
831
863
|
);
|
|
832
864
|
}
|
|
833
865
|
|
|
834
|
-
const packageManagerConfigs = [pnpm, yarn, bun, npm];
|
|
866
|
+
const packageManagerConfigs = [pnpm, yarn, yarnBerry, bun, npm];
|
|
835
867
|
function definePackageManagerClient(options) {
|
|
836
868
|
const configs = packageManagerConfigs.map(
|
|
837
869
|
(config) => definePackageManager(config, options)
|
|
@@ -861,8 +893,11 @@ function definePackageManagerClient(options) {
|
|
|
861
893
|
};
|
|
862
894
|
}
|
|
863
895
|
|
|
864
|
-
function isPackageDependency(packageName) {
|
|
865
|
-
|
|
896
|
+
function isPackageDependency(packageName, options) {
|
|
897
|
+
const { packageJson } = getPackageInfo(options);
|
|
898
|
+
return toArray(packageName).every(
|
|
899
|
+
(name) => isDependencyInPackageJson(name, packageJson)
|
|
900
|
+
);
|
|
866
901
|
}
|
|
867
902
|
|
|
868
903
|
function definePathAliases(aliasDefinitions) {
|
|
@@ -880,42 +915,49 @@ function definePathAliases(aliasDefinitions) {
|
|
|
880
915
|
};
|
|
881
916
|
}
|
|
882
917
|
function getAliasedFilePath(aliasMap, options) {
|
|
883
|
-
const { to, startingFrom, cwd, checkExistence, glob } = typeof options === "string" || Array.isArray(options) ? { to: options } : options;
|
|
884
|
-
const resolveOptions = { cwd, checkExistence, glob, aliasMap };
|
|
918
|
+
const { to, startingFrom, cwd, from, checkExistence, glob } = typeof options === "string" || Array.isArray(options) ? { to: options } : options;
|
|
919
|
+
const resolveOptions = { cwd, from, checkExistence, glob, aliasMap };
|
|
885
920
|
try {
|
|
886
921
|
return startingFrom ? resolveRelativePathTo(to, startingFrom, resolveOptions) : resolvePathTo(to, resolveOptions);
|
|
887
922
|
} catch (error) {
|
|
888
|
-
if (
|
|
923
|
+
if (error instanceof PathNotFoundError) return void 0;
|
|
889
924
|
throw error;
|
|
890
925
|
}
|
|
891
926
|
}
|
|
927
|
+
class PathNotFoundError extends Error {
|
|
928
|
+
}
|
|
892
929
|
function resolveRelativePathTo(to, from, options) {
|
|
893
930
|
const pathFrom = resolvePathTo(from, options);
|
|
894
931
|
const pathTo = resolvePathTo(to, options);
|
|
895
|
-
return path__default
|
|
932
|
+
return path__default.relative(pathFrom, pathTo);
|
|
896
933
|
}
|
|
897
|
-
function resolvePathTo(pathTo, { cwd, checkExistence, glob, aliasMap }) {
|
|
898
|
-
const normalized = normalizePathTo(pathTo, { cwd, aliasMap });
|
|
934
|
+
function resolvePathTo(pathTo, { cwd, from, checkExistence, glob, aliasMap }) {
|
|
935
|
+
const normalized = normalizePathTo(pathTo, { cwd, from, aliasMap });
|
|
899
936
|
if (glob) {
|
|
900
937
|
const globPaths = globby.globbySync(normalized, { cwd });
|
|
901
938
|
if (!globPaths[0])
|
|
902
|
-
throw new
|
|
939
|
+
throw new PathNotFoundError(`No paths found for glob: ${normalized}`);
|
|
903
940
|
return globPaths[0];
|
|
904
941
|
}
|
|
905
942
|
if (!glob && checkExistence && !node_fs.existsSync(normalized))
|
|
906
|
-
throw new
|
|
943
|
+
throw new PathNotFoundError(`Path does not exist: ${normalized}`);
|
|
907
944
|
return normalized;
|
|
908
945
|
}
|
|
909
946
|
function normalizePathTo(pathTo, options) {
|
|
910
|
-
const { cwd, aliasMap } = options ?? {};
|
|
911
|
-
const
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
947
|
+
const { cwd, from, aliasMap } = options ?? {};
|
|
948
|
+
const baseDir = Array.isArray(pathTo) ? pathTo[0] : findAliasToken(pathTo, aliasMap);
|
|
949
|
+
if (baseDir === void 0) return pathTo;
|
|
950
|
+
const baseDirPath = assertResolved(
|
|
951
|
+
baseDir,
|
|
952
|
+
executeMapFn(aliasMap, baseDir, [{ cwd, from }])
|
|
953
|
+
);
|
|
954
|
+
return Array.isArray(pathTo) ? path__default.join(baseDirPath, ...pathTo.slice(1).filter(isNotNull)) : utils.resolveAlias(pathTo, { [baseDir]: baseDirPath });
|
|
955
|
+
}
|
|
956
|
+
function assertResolved(alias, resolved) {
|
|
957
|
+
if (typeof resolved !== "string" || resolved.length === 0) {
|
|
958
|
+
throw new Error(`Path alias resolved to no location: ${alias}`);
|
|
917
959
|
}
|
|
918
|
-
return
|
|
960
|
+
return resolved;
|
|
919
961
|
}
|
|
920
962
|
function findAliasToken(pathTo, aliasMap) {
|
|
921
963
|
return Object.keys(aliasMap ?? {}).filter((alias) => pathTo === alias || pathTo.startsWith(`${alias}/`)).sort((a, b) => b.length - a.length)[0];
|
|
@@ -933,10 +975,17 @@ function getAliasMap(aliasDefs) {
|
|
|
933
975
|
return [
|
|
934
976
|
[alias, resolve],
|
|
935
977
|
...subpaths.map(({ to }) => {
|
|
936
|
-
const subpathAlias = path__default
|
|
978
|
+
const subpathAlias = path__default.join(alias, to);
|
|
937
979
|
return [
|
|
938
980
|
subpathAlias,
|
|
939
|
-
(opts) =>
|
|
981
|
+
(opts) => (
|
|
982
|
+
// The same assertion the bare alias gets. Without it an
|
|
983
|
+
// unresolvable parent produced `join(undefined, "/node_modules")`
|
|
984
|
+
// — a path at the filesystem root — instead of failing.
|
|
985
|
+
utils.resolveAlias(subpathAlias, {
|
|
986
|
+
[alias]: assertResolved(alias, resolve(opts))
|
|
987
|
+
})
|
|
988
|
+
)
|
|
940
989
|
];
|
|
941
990
|
})
|
|
942
991
|
];
|
|
@@ -1011,13 +1060,13 @@ const predefinedPathAliases = {
|
|
|
1011
1060
|
subpaths: []
|
|
1012
1061
|
},
|
|
1013
1062
|
"<current_file>": {
|
|
1014
|
-
//
|
|
1015
|
-
|
|
1063
|
+
// `from` is the caller naming itself, which is exact. Without it the stack
|
|
1064
|
+
// is read, which is a best effort and Node-only.
|
|
1065
|
+
resolve: (opts) => _filename({ from: opts?.from, boundaryFunctionName: "getFilePath" }),
|
|
1016
1066
|
subpaths: []
|
|
1017
1067
|
},
|
|
1018
1068
|
"<current_folder>": {
|
|
1019
|
-
|
|
1020
|
-
resolve: () => _dirname({ rootFunctionName: "getFilePath" }) ?? "",
|
|
1069
|
+
resolve: (opts) => _dirname({ from: opts?.from, boundaryFunctionName: "getFilePath" }),
|
|
1021
1070
|
subpaths: []
|
|
1022
1071
|
}
|
|
1023
1072
|
};
|
|
@@ -1040,59 +1089,65 @@ const jsonSourceResolvers = {
|
|
|
1040
1089
|
text: (text) => {
|
|
1041
1090
|
return {
|
|
1042
1091
|
text: () => text,
|
|
1043
|
-
|
|
1092
|
+
// `jsonc-parser`'s parse, not `JSON.parse`: the whole point of this
|
|
1093
|
+
// module is editing files like tsconfig.json, which carry comments.
|
|
1094
|
+
data: () => jsoncParser.parse(text)
|
|
1044
1095
|
};
|
|
1045
1096
|
},
|
|
1046
1097
|
filepath: (filepath) => {
|
|
1047
1098
|
const text = node_fs.readFileSync(filepath, "utf-8");
|
|
1048
1099
|
return {
|
|
1049
1100
|
text: () => text,
|
|
1050
|
-
|
|
1101
|
+
// `jsonc-parser`'s parse, not `JSON.parse`: the whole point of this
|
|
1102
|
+
// module is editing files like tsconfig.json, which carry comments.
|
|
1103
|
+
data: () => jsoncParser.parse(text)
|
|
1051
1104
|
};
|
|
1052
1105
|
}
|
|
1053
1106
|
};
|
|
1054
1107
|
function resolveJsonSource(source, as) {
|
|
1055
1108
|
const [sourceType, sourceData] = Object.entries(source).find(([_, selected]) => selected !== void 0) ?? [];
|
|
1056
|
-
if (!sourceType || !(sourceType in jsonSourceResolvers) ||
|
|
1109
|
+
if (!sourceType || !(sourceType in jsonSourceResolvers) || sourceData === void 0) {
|
|
1057
1110
|
throw new Error("Invalid source data");
|
|
1058
1111
|
}
|
|
1059
1112
|
const sourceTypeResolvers = jsonSourceResolvers[sourceType](
|
|
1060
1113
|
sourceData
|
|
1061
1114
|
);
|
|
1062
|
-
const resolved =
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1115
|
+
const resolved = fromEntries(
|
|
1116
|
+
entriesOf(sourceTypeResolvers).flatMap(([key, v]) => {
|
|
1117
|
+
if (as && key !== as) return [];
|
|
1118
|
+
try {
|
|
1119
|
+
return [[key, v()]];
|
|
1120
|
+
} catch (error) {
|
|
1121
|
+
throw new Error(`Failed to resolve ${key} from ${sourceType}`, {
|
|
1122
|
+
cause: error
|
|
1123
|
+
});
|
|
1124
|
+
}
|
|
1125
|
+
})
|
|
1126
|
+
);
|
|
1070
1127
|
if (as) {
|
|
1071
1128
|
return resolved[as];
|
|
1072
1129
|
}
|
|
1073
1130
|
return resolved;
|
|
1074
1131
|
}
|
|
1075
1132
|
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
const
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
}
|
|
1086
|
-
function parseJSONCEdits(edits) {
|
|
1133
|
+
const toPathSegment$1 = (segment) => /^\d+$/.test(segment) ? Number(segment) : segment;
|
|
1134
|
+
function resolveEditPath$1(path, options) {
|
|
1135
|
+
const { pathSeparator = "." } = options || {};
|
|
1136
|
+
if (Array.isArray(path)) return path;
|
|
1137
|
+
if (typeof path === "number" || pathSeparator === false) return [path];
|
|
1138
|
+
return path.split(pathSeparator).map(toPathSegment$1);
|
|
1139
|
+
}
|
|
1140
|
+
function parseJSONCEdits(edits, defaultEditOptions) {
|
|
1141
|
+
const resolve = (path, options) => resolveEditPath$1(path, { ...defaultEditOptions, ...options });
|
|
1087
1142
|
if (Array.isArray(edits)) {
|
|
1088
1143
|
return edits.map(({ path, ...edit }) => ({
|
|
1089
|
-
path:
|
|
1144
|
+
path: resolve(path, edit.options),
|
|
1090
1145
|
...edit
|
|
1091
1146
|
}));
|
|
1092
1147
|
}
|
|
1093
1148
|
return Object.entries(edits).map(
|
|
1094
1149
|
([path, value]) => ({
|
|
1095
|
-
path:
|
|
1150
|
+
path: resolve(path, value.options),
|
|
1096
1151
|
...value
|
|
1097
1152
|
})
|
|
1098
1153
|
);
|
|
@@ -1104,14 +1159,17 @@ function modifyJSON({
|
|
|
1104
1159
|
}) {
|
|
1105
1160
|
return checkResult(() => {
|
|
1106
1161
|
const text = resolveJsonSource(json, "text");
|
|
1107
|
-
const jsoncEdits = parseJSONCEdits(edits);
|
|
1108
|
-
const
|
|
1109
|
-
(edit) => jsoncParser.
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1162
|
+
const jsoncEdits = parseJSONCEdits(edits, defaultEditOptions);
|
|
1163
|
+
const updated = jsoncEdits.reduce(
|
|
1164
|
+
(current, edit) => jsoncParser.applyEdits(
|
|
1165
|
+
current,
|
|
1166
|
+
jsoncParser.modify(current, edit.path, edit.value, {
|
|
1167
|
+
...defaultEditOptions,
|
|
1168
|
+
...edit.options
|
|
1169
|
+
})
|
|
1170
|
+
),
|
|
1171
|
+
text
|
|
1113
1172
|
);
|
|
1114
|
-
const updated = jsoncParser.applyEdits(text, editResult);
|
|
1115
1173
|
return resolveJsonSource({ text: updated });
|
|
1116
1174
|
});
|
|
1117
1175
|
}
|
|
@@ -1138,6 +1196,154 @@ function modifyJSONFile(filepath, edits, options) {
|
|
|
1138
1196
|
});
|
|
1139
1197
|
}
|
|
1140
1198
|
|
|
1199
|
+
const configLanguages = {
|
|
1200
|
+
json: { parse: confbox.parseJSONC, stringify: confbox.stringifyJSONC, surgical: true },
|
|
1201
|
+
jsonc: { parse: confbox.parseJSONC, stringify: confbox.stringifyJSONC, surgical: true },
|
|
1202
|
+
json5: { parse: confbox.parseJSON5, stringify: confbox.stringifyJSON5, surgical: false },
|
|
1203
|
+
yaml: { parse: confbox.parseYAML, stringify: confbox.stringifyYAML, surgical: false },
|
|
1204
|
+
toml: { parse: confbox.parseTOML, stringify: confbox.stringifyTOML, surgical: false }
|
|
1205
|
+
};
|
|
1206
|
+
const extensionFormats = {
|
|
1207
|
+
".json": "json",
|
|
1208
|
+
".jsonc": "jsonc",
|
|
1209
|
+
".json5": "json5",
|
|
1210
|
+
".yaml": "yaml",
|
|
1211
|
+
".yml": "yaml",
|
|
1212
|
+
".toml": "toml"
|
|
1213
|
+
};
|
|
1214
|
+
function isConfigFormat(value) {
|
|
1215
|
+
return value in configLanguages;
|
|
1216
|
+
}
|
|
1217
|
+
function getConfigFormat(filepath) {
|
|
1218
|
+
const extension = path.extname(filepath).toLowerCase();
|
|
1219
|
+
return extension in extensionFormats ? extensionFormats[extension] : void 0;
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1222
|
+
function resolveFormat(source) {
|
|
1223
|
+
if (source.format) return source.format;
|
|
1224
|
+
const inferred = source.filepath ? getConfigFormat(source.filepath) : void 0;
|
|
1225
|
+
if (!inferred) {
|
|
1226
|
+
throw new Error(
|
|
1227
|
+
source.filepath ? `Unsupported config format: ${source.filepath}` : "A `format` is required for a text or data source"
|
|
1228
|
+
);
|
|
1229
|
+
}
|
|
1230
|
+
return inferred;
|
|
1231
|
+
}
|
|
1232
|
+
function resolveConfigSource(source, as) {
|
|
1233
|
+
const format = resolveFormat(source);
|
|
1234
|
+
const language = configLanguages[format];
|
|
1235
|
+
const { text: sourceText, data: sourceData, filepath } = source;
|
|
1236
|
+
const resolvers = {
|
|
1237
|
+
data: () => ({
|
|
1238
|
+
text: () => language.stringify(sourceData),
|
|
1239
|
+
data: () => sourceData
|
|
1240
|
+
}),
|
|
1241
|
+
text: () => ({
|
|
1242
|
+
text: () => sourceText,
|
|
1243
|
+
data: () => language.parse(sourceText)
|
|
1244
|
+
}),
|
|
1245
|
+
filepath: () => {
|
|
1246
|
+
const text = node_fs.readFileSync(filepath, "utf-8");
|
|
1247
|
+
return {
|
|
1248
|
+
text: () => text,
|
|
1249
|
+
data: () => language.parse(text)
|
|
1250
|
+
};
|
|
1251
|
+
}
|
|
1252
|
+
};
|
|
1253
|
+
const selected = ["data", "text", "filepath"].find(
|
|
1254
|
+
(key) => source[key] !== void 0
|
|
1255
|
+
);
|
|
1256
|
+
if (!selected) {
|
|
1257
|
+
throw new Error("Invalid source data");
|
|
1258
|
+
}
|
|
1259
|
+
const sourceResolvers = resolvers[selected]();
|
|
1260
|
+
const resolved = fromEntries(
|
|
1261
|
+
entriesOf(sourceResolvers).flatMap(([key, value]) => {
|
|
1262
|
+
if (as && key !== as) return [];
|
|
1263
|
+
try {
|
|
1264
|
+
return [[key, value()]];
|
|
1265
|
+
} catch (error) {
|
|
1266
|
+
throw new Error(`Failed to resolve ${key} from ${selected}`, {
|
|
1267
|
+
cause: error
|
|
1268
|
+
});
|
|
1269
|
+
}
|
|
1270
|
+
})
|
|
1271
|
+
);
|
|
1272
|
+
if (as) {
|
|
1273
|
+
return resolved[as];
|
|
1274
|
+
}
|
|
1275
|
+
return resolved;
|
|
1276
|
+
}
|
|
1277
|
+
|
|
1278
|
+
const toPathSegment = (segment) => /^\d+$/.test(segment) ? Number(segment) : segment;
|
|
1279
|
+
function resolveEditPath(path, options) {
|
|
1280
|
+
const { pathSeparator = "." } = options || {};
|
|
1281
|
+
if (Array.isArray(path)) return path;
|
|
1282
|
+
if (typeof path === "number" || pathSeparator === false) return [path];
|
|
1283
|
+
return path.split(pathSeparator).map(toPathSegment);
|
|
1284
|
+
}
|
|
1285
|
+
function toEditList(edits, defaultEditOptions) {
|
|
1286
|
+
const entries = Array.isArray(edits) ? edits : Object.entries(edits).map(([path, edit]) => ({ path, ...edit }));
|
|
1287
|
+
return entries.map(({ path, value, options }) => ({
|
|
1288
|
+
path: resolveEditPath(path, { ...defaultEditOptions, ...options }),
|
|
1289
|
+
value
|
|
1290
|
+
}));
|
|
1291
|
+
}
|
|
1292
|
+
function setPath(target, path, value) {
|
|
1293
|
+
const [head, ...rest] = path;
|
|
1294
|
+
if (head === void 0) return value;
|
|
1295
|
+
const container = Array.isArray(target) ? [...target] : { ...target ?? {} };
|
|
1296
|
+
container[head] = setPath(container[head], rest, value);
|
|
1297
|
+
return container;
|
|
1298
|
+
}
|
|
1299
|
+
function modifyConfig({
|
|
1300
|
+
config,
|
|
1301
|
+
edits,
|
|
1302
|
+
defaultEditOptions
|
|
1303
|
+
}) {
|
|
1304
|
+
return checkResult(() => {
|
|
1305
|
+
const format = config.format ?? (config.filepath ? getConfigFormat(config.filepath) : void 0) ?? "json";
|
|
1306
|
+
const language = configLanguages[format];
|
|
1307
|
+
if (language.surgical) {
|
|
1308
|
+
const { data, error } = modifyJSON({
|
|
1309
|
+
json: config.filepath ? { filepath: config.filepath } : config.text !== void 0 ? { text: config.text } : { data: config.data },
|
|
1310
|
+
edits,
|
|
1311
|
+
defaultEditOptions
|
|
1312
|
+
});
|
|
1313
|
+
if (error) throw error;
|
|
1314
|
+
return data;
|
|
1315
|
+
}
|
|
1316
|
+
const current = resolveConfigSource(config, "data");
|
|
1317
|
+
const updated = toEditList(edits, defaultEditOptions).reduce(
|
|
1318
|
+
(result, edit) => setPath(result, edit.path, edit.value),
|
|
1319
|
+
current
|
|
1320
|
+
);
|
|
1321
|
+
return resolveConfigSource({ text: language.stringify(updated), format });
|
|
1322
|
+
});
|
|
1323
|
+
}
|
|
1324
|
+
function modifyConfigFile(filepath, edits, options) {
|
|
1325
|
+
return checkResult(() => {
|
|
1326
|
+
const { autoCommit = true, defaultEditOptions, format } = options || {};
|
|
1327
|
+
const { data: config, error } = modifyConfig({
|
|
1328
|
+
config: format ? { filepath, format } : { filepath },
|
|
1329
|
+
edits,
|
|
1330
|
+
defaultEditOptions
|
|
1331
|
+
});
|
|
1332
|
+
if (error) {
|
|
1333
|
+
throw error;
|
|
1334
|
+
}
|
|
1335
|
+
const commit = () => node_fs.writeFileSync(filepath, config.text);
|
|
1336
|
+
if (autoCommit) {
|
|
1337
|
+
commit();
|
|
1338
|
+
return config;
|
|
1339
|
+
}
|
|
1340
|
+
return {
|
|
1341
|
+
config,
|
|
1342
|
+
commit
|
|
1343
|
+
};
|
|
1344
|
+
});
|
|
1345
|
+
}
|
|
1346
|
+
|
|
1141
1347
|
function isStorageValue(input) {
|
|
1142
1348
|
return input === null || typeof input === "string" || typeof input === "number" || typeof input === "boolean" || typeof input === "object";
|
|
1143
1349
|
}
|
|
@@ -1146,117 +1352,92 @@ const storage = unstorage.createStorage({ driver: defineMemoryDriver__default()
|
|
|
1146
1352
|
const tempFileSystem = defineFileSystemStorage({
|
|
1147
1353
|
base: path.join(os__default.tmpdir(), ".package-manager")
|
|
1148
1354
|
});
|
|
1355
|
+
const encodeEntry = (value) => typeof value === "string" ? value : JSON.stringify(value);
|
|
1149
1356
|
function defineFileSystemEntries(definition) {
|
|
1150
|
-
const fileSystemEntries = Object.entries(definition).map(([
|
|
1151
|
-
if (
|
|
1152
|
-
const {
|
|
1153
|
-
|
|
1154
|
-
options,
|
|
1155
|
-
serialize = (input) => JSON.stringify(input),
|
|
1156
|
-
deserialize = (input) => {
|
|
1157
|
-
try {
|
|
1158
|
-
return JSON.parse(input);
|
|
1159
|
-
} catch {
|
|
1160
|
-
return input;
|
|
1161
|
-
}
|
|
1162
|
-
}
|
|
1163
|
-
} = v();
|
|
1164
|
-
return {
|
|
1165
|
-
key: k,
|
|
1166
|
-
value: serialize(file),
|
|
1167
|
-
options,
|
|
1168
|
-
serialize,
|
|
1169
|
-
deserialize
|
|
1170
|
-
};
|
|
1357
|
+
const fileSystemEntries = Object.entries(definition).map(([key, value]) => {
|
|
1358
|
+
if (typeof value === "function") {
|
|
1359
|
+
const { file, options } = value();
|
|
1360
|
+
return { key, value: encodeEntry(file), options };
|
|
1171
1361
|
}
|
|
1172
|
-
if (isStorageValue(
|
|
1173
|
-
|
|
1174
|
-
key:
|
|
1175
|
-
|
|
1176
|
-
};
|
|
1362
|
+
if (!isStorageValue(value)) {
|
|
1363
|
+
throw new Error(
|
|
1364
|
+
`Cannot store a ${typeof value} at "${key}": file system entries must be a storage value or a function returning one.`
|
|
1365
|
+
);
|
|
1177
1366
|
}
|
|
1178
|
-
return
|
|
1179
|
-
})
|
|
1367
|
+
return { key, value: encodeEntry(value) };
|
|
1368
|
+
});
|
|
1180
1369
|
const resolved = {
|
|
1181
1370
|
definition,
|
|
1182
1371
|
fileSystemEntries
|
|
1183
1372
|
};
|
|
1184
1373
|
return resolved;
|
|
1185
1374
|
}
|
|
1375
|
+
const keyToFilePath = (root, key) => path.join(root, ...key.split(/[:/\\]+/).filter(Boolean));
|
|
1186
1376
|
function defineFileSystemStorage(options) {
|
|
1187
1377
|
const { base: root, initial, ...storageOptions } = options;
|
|
1188
|
-
let
|
|
1378
|
+
let entriesData = defineFileSystemEntries(initial ?? {});
|
|
1189
1379
|
const storage2 = unstorage.createStorage({
|
|
1190
1380
|
driver: defineFsLiteDriver__default({ base: root, ...storageOptions })
|
|
1191
1381
|
});
|
|
1382
|
+
const getFilePath = (key) => keyToFilePath(root, key);
|
|
1383
|
+
const getFile = async (key) => ({
|
|
1384
|
+
key,
|
|
1385
|
+
filepath: getFilePath(key),
|
|
1386
|
+
data: await storage2.getItem(key),
|
|
1387
|
+
// `getItemRaw` resolves to null for a missing file rather than throwing.
|
|
1388
|
+
read: async () => (await storage2.getItemRaw(key))?.toString()
|
|
1389
|
+
});
|
|
1390
|
+
const removeAllFiles = async () => storage2.clear();
|
|
1192
1391
|
const fileStorage = {
|
|
1193
1392
|
createFile: async (key, data) => {
|
|
1194
1393
|
await storage2.setItem(key, data);
|
|
1195
1394
|
return {
|
|
1196
1395
|
key,
|
|
1197
|
-
filepath:
|
|
1396
|
+
filepath: getFilePath(key),
|
|
1198
1397
|
get: async () => storage2.getItem(key),
|
|
1199
1398
|
update: async (data2) => storage2.setItem(key, data2)
|
|
1200
1399
|
};
|
|
1201
1400
|
},
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
filepath: path.join(root, key),
|
|
1210
|
-
data: storageData,
|
|
1211
|
-
read: async () => (await storage2.getItemRaw(key))?.toString()
|
|
1212
|
-
};
|
|
1213
|
-
},
|
|
1214
|
-
async readFile(key) {
|
|
1215
|
-
const { read } = await this.getFile(key);
|
|
1216
|
-
const content = await read();
|
|
1217
|
-
return content;
|
|
1218
|
-
},
|
|
1219
|
-
snapshotFs: async (base = root) => {
|
|
1220
|
-
return unstorage.snapshot(storage2, base);
|
|
1221
|
-
},
|
|
1222
|
-
restoreFs: async (snapshot2) => {
|
|
1223
|
-
return unstorage.restoreSnapshot(storage2, snapshot2);
|
|
1224
|
-
},
|
|
1401
|
+
getFilePath,
|
|
1402
|
+
getFile,
|
|
1403
|
+
readFile: async (key) => (await getFile(key)).read(),
|
|
1404
|
+
// `base` is a key prefix. Defaulting it to the filesystem root would match
|
|
1405
|
+
// no key at all and silently report an empty filesystem.
|
|
1406
|
+
snapshotFs: async (base = "") => unstorage.snapshot(storage2, base),
|
|
1407
|
+
restoreFs: async (snapshot2, base) => unstorage.restoreSnapshot(storage2, snapshot2, base),
|
|
1225
1408
|
initializeFs: async (override) => {
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
await storage2.
|
|
1230
|
-
return storage2.setItems(initialFileEntriesData.fileSystemEntries);
|
|
1409
|
+
const previousKeys = entriesData.fileSystemEntries.map(({ key }) => key);
|
|
1410
|
+
if (override) entriesData = defineFileSystemEntries(override);
|
|
1411
|
+
await Promise.all(previousKeys.map((key) => storage2.removeItem(key)));
|
|
1412
|
+
await storage2.setItems(entriesData.fileSystemEntries);
|
|
1231
1413
|
},
|
|
1232
1414
|
defineFileSystemEntries,
|
|
1233
|
-
removeAllFiles
|
|
1415
|
+
removeAllFiles,
|
|
1234
1416
|
async deleteFileSystem() {
|
|
1235
|
-
await
|
|
1236
|
-
await storage2.
|
|
1417
|
+
await removeAllFiles();
|
|
1418
|
+
await storage2.dispose();
|
|
1237
1419
|
await promises.rm(root, { recursive: true, force: true });
|
|
1238
1420
|
},
|
|
1239
1421
|
storage: storage2,
|
|
1240
1422
|
meta: {
|
|
1241
|
-
|
|
1423
|
+
// A getter, so that `initializeFs(override)` is reflected here rather
|
|
1424
|
+
// than this reporting whatever the definition was at construction.
|
|
1425
|
+
get fileEntriesData() {
|
|
1426
|
+
return entriesData;
|
|
1427
|
+
}
|
|
1242
1428
|
}
|
|
1243
1429
|
};
|
|
1244
|
-
if (initial) {
|
|
1245
|
-
return {
|
|
1246
|
-
initialize: async () => {
|
|
1247
|
-
await fileStorage.initializeFs(initial);
|
|
1248
|
-
return fileStorage;
|
|
1249
|
-
}
|
|
1250
|
-
};
|
|
1251
|
-
}
|
|
1252
1430
|
return fileStorage;
|
|
1253
1431
|
}
|
|
1254
1432
|
|
|
1255
1433
|
exports._dirname = _dirname;
|
|
1256
1434
|
exports._filename = _filename;
|
|
1435
|
+
exports.configLanguages = configLanguages;
|
|
1436
|
+
exports.createFile = createFile;
|
|
1257
1437
|
exports.defineFileSystemEntries = defineFileSystemEntries;
|
|
1258
1438
|
exports.defineFileSystemStorage = defineFileSystemStorage;
|
|
1259
1439
|
exports.definePackage = definePackage;
|
|
1440
|
+
exports.definePackageManager = definePackageManager;
|
|
1260
1441
|
exports.definePackageManagerClient = definePackageManagerClient;
|
|
1261
1442
|
exports.definePathAliases = definePathAliases;
|
|
1262
1443
|
exports.detectGlobalPackageManagers = detectGlobalPackageManagers;
|
|
@@ -1268,6 +1449,7 @@ exports.findPackageManager = findPackageManager;
|
|
|
1268
1449
|
exports.findPackageManagerSafely = findPackageManagerSafely;
|
|
1269
1450
|
exports.findResolvedModulePath = findResolvedModulePath;
|
|
1270
1451
|
exports.getAliasMap = getAliasMap;
|
|
1452
|
+
exports.getConfigFormat = getConfigFormat;
|
|
1271
1453
|
exports.getFolderByPackageName = getFolderByPackageName;
|
|
1272
1454
|
exports.getGitRootFolder = getGitRootFolder;
|
|
1273
1455
|
exports.getGlobalVersions = getGlobalVersions;
|
|
@@ -1276,15 +1458,22 @@ exports.getPath = getPath;
|
|
|
1276
1458
|
exports.getWorkspaceFolder = getWorkspaceFolder;
|
|
1277
1459
|
exports.importMap = importMap;
|
|
1278
1460
|
exports.importer = importer;
|
|
1461
|
+
exports.isConfigFormat = isConfigFormat;
|
|
1279
1462
|
exports.isDependencyInPackageJson = isDependencyInPackageJson;
|
|
1280
1463
|
exports.isPackageDependency = isPackageDependency;
|
|
1281
1464
|
exports.isPackageModuleFound = isPackageModuleFound;
|
|
1465
|
+
exports.isWritable = isWritable;
|
|
1282
1466
|
exports.mapPackageManagers = mapPackageManagers;
|
|
1467
|
+
exports.modifyConfig = modifyConfig;
|
|
1468
|
+
exports.modifyConfigFile = modifyConfigFile;
|
|
1283
1469
|
exports.modifyJSON = modifyJSON;
|
|
1284
1470
|
exports.modifyJSONFile = modifyJSONFile;
|
|
1285
1471
|
exports.packageManagerConfigs = packageManagerConfigs;
|
|
1286
1472
|
exports.predefinedPathAliases = predefinedPathAliases;
|
|
1287
1473
|
exports.project = project;
|
|
1474
|
+
exports.readFile = readFile;
|
|
1475
|
+
exports.readFileSafely = readFileSafely;
|
|
1476
|
+
exports.resolveConfigSource = resolveConfigSource;
|
|
1288
1477
|
exports.resolveModule = resolveModule;
|
|
1289
1478
|
exports.resolveModulePath = resolveModulePath;
|
|
1290
1479
|
exports.resolvePackageModulePath = resolvePackageModulePath;
|