package-management 0.0.1 → 0.0.3

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/index.mjs CHANGED
@@ -1,39 +1,488 @@
1
- import { installPackage } from '@antfu/install-pkg';
2
- import 'node:fs';
3
- import { execa } from 'execa';
4
- import { isPackageExists } from 'local-pkg';
1
+ import ErrorStackParser from 'error-stack-parser';
2
+ import path$1, { normalize, basename, dirname, relative } from 'pathe';
3
+ import process from 'node:process';
4
+ import path from 'node:path';
5
+ import { readFileSync, existsSync } from 'node:fs';
6
+ import { execa, execaSync } from 'execa';
5
7
  import { asyncCacheFn } from 'async-cache-fn';
6
8
  import { findUp } from 'find-up';
7
9
  import { readFile } from 'node:fs/promises';
10
+ import { resolvePathSync } from 'mlly';
11
+ import { globbySync } from 'globby';
12
+ import gitignoreParser from 'parse-gitignore';
13
+ import * as WST from 'workspace-tools';
14
+ import { resolveAlias } from 'pathe/utils';
15
+ import os from 'node:os';
8
16
 
9
- async function resolveModule(m) {
10
- const resolved = await m;
17
+ const toArray = (data) => Array.isArray(data) ? data : [data];
18
+ const entriesOf = (o) => Object.entries(o);
19
+ const fromEntries = (entries) => Object.fromEntries(entries);
20
+ const notFalsy = (value) => [false, null, void 0].every((v) => v !== value);
21
+ const select = (obj, selection, mode) => {
22
+ if (!selection)
23
+ return obj;
24
+ const filtered = entriesOf(obj).filter(([key]) => {
25
+ return mode === "omit" ? !selection[key] : selection[key];
26
+ });
27
+ return fromEntries(filtered);
28
+ };
29
+ function normalizePath(path, option) {
30
+ if (typeof option === "function") {
31
+ return normalizePath(path);
32
+ }
33
+ if (option === false) {
34
+ return path;
35
+ }
36
+ return normalize(path);
37
+ }
38
+ const invariant = (predicate, message) => {
39
+ if (!predicate) {
40
+ throw new Error(message);
41
+ }
42
+ };
43
+ function getArrayItemAtOffset(arr, index, offset = 0) {
44
+ if (!index || !arr)
45
+ return void 0;
46
+ return arr[index + offset];
47
+ }
48
+ function isMatching(a, b) {
49
+ if (!a || !b)
50
+ return false;
51
+ return a === b;
52
+ }
53
+
54
+ function findCallerStackFrame(options) {
55
+ return findErrorStackFrame(options, (frame) => frame.isParentOfRootFunction);
56
+ }
57
+ function findErrorStackFrame(options, find) {
58
+ return getErrorStackFrames(options, find)[0];
59
+ }
60
+ function getErrorStackFrames(options, filter) {
61
+ const { error, rootFunctionName, startFrom = "top" } = options;
62
+ const frames = startFrom === "bottom" ? ErrorStackParser.parse(error).reverse() : ErrorStackParser.parse(error);
63
+ const { parsedFrames } = frames.reduce(
64
+ (acc, frame, index) => {
65
+ const parsed = parseFrame({
66
+ frame,
67
+ index,
68
+ rootFunctionName,
69
+ frames
70
+ });
71
+ const isValid = filter ? filter(parsed) : true;
72
+ if (isValid) {
73
+ acc.parsedFrames.push(parsed);
74
+ }
75
+ return acc;
76
+ },
77
+ { parsedFrames: [] }
78
+ );
79
+ return parsedFrames ?? [];
80
+ }
81
+ function parseFrame(options) {
82
+ const { frame, frames, index, rootFunctionName, cwd, debug } = options ?? {};
83
+ const functionName = parseFunctionName(frame.functionName);
84
+ const isRootFunction = isMatching(functionName, rootFunctionName);
85
+ const beforeFrameFunctionName = parseFunctionName(
86
+ getArrayItemAtOffset(frames, index, -1)?.functionName
87
+ );
88
+ const isParentOfRootFunction = isMatching(
89
+ beforeFrameFunctionName,
90
+ rootFunctionName
91
+ );
92
+ const fileData = frame.fileName ? getFilePathData({ filepath: frame.fileName, cwd }) : void 0;
93
+ const { isFileInCwd: isFrameInScope, ...restFileData } = fileData ?? {};
94
+ const data = {
95
+ ...restFileData,
96
+ functionName,
97
+ source: frame.source,
98
+ sourceFunctionName: frame.functionName,
99
+ isFrameInScope,
100
+ place: placeFormatter(index, frames?.length),
101
+ isRootFunction,
102
+ isParentOfRootFunction,
103
+ rootFunctionName
104
+ };
105
+ debug && console.log(data);
106
+ return data;
107
+ }
108
+ function getFilePathData({
109
+ filepath,
110
+ cwd
111
+ }) {
112
+ const workingDir = cwd ?? process.cwd();
113
+ const filePath = normalize(filepath);
114
+ const fileBasename = basename(filePath);
115
+ const dirPath = dirname(filePath);
116
+ const dirBasename = basename(dirPath);
117
+ const relativeFilePath = relative(workingDir, filePath);
118
+ const relativeDirPath = dirname(relativeFilePath);
119
+ const isFileInCwd = filePath.startsWith(workingDir);
120
+ return {
121
+ filePath,
122
+ dirPath,
123
+ relativeFilePath,
124
+ relativeDirPath,
125
+ fileBasename,
126
+ dirBasename,
127
+ isFileInCwd
128
+ };
129
+ }
130
+ function parseFunctionName(functionName) {
131
+ if (!functionName)
132
+ return void 0;
133
+ return removeStart(functionName, "Module.");
134
+ }
135
+ function removeStart(input, value) {
136
+ return input.startsWith(value) ? input.slice(value.length) : input;
137
+ }
138
+ function placeFormatter(index, total) {
139
+ if (!index || !total)
140
+ return void 0;
141
+ return [index, total].join("/");
142
+ }
143
+
144
+ const _filename = (options) => {
145
+ const { filePath } = findCallerStackFrame({ error: new Error(), ...options }) ?? {};
146
+ return filePath;
147
+ };
148
+ const _dirname = (options) => {
149
+ const { dirPath } = findCallerStackFrame({ error: new Error(), ...options }) ?? {};
150
+ return dirPath;
151
+ };
152
+
153
+ async function resolveModule(module) {
154
+ const resolved = await module;
11
155
  return resolved.default || resolved;
12
156
  }
157
+ function isPackageModuleFound(name, options) {
158
+ return Boolean(resolvePackageModulePath(name, options));
159
+ }
160
+ function resolvePackageModulePath(name, options) {
161
+ const resolvedPath = findResolvedModulePath(
162
+ [`${name}/package.json`, name],
163
+ options
164
+ );
165
+ if (resolvedPath === void 0) {
166
+ console.error(`Could not resolve package ${name}`);
167
+ return void 0;
168
+ }
169
+ return resolvedPath;
170
+ }
171
+ function findResolvedModulePath(paths, options) {
172
+ for (const path of paths) {
173
+ const resolvedPath = resolveModulePath(path, options);
174
+ if (resolvedPath === void 0)
175
+ continue;
176
+ return resolvedPath;
177
+ }
178
+ }
179
+ function resolveModulePath(modulePath, options) {
180
+ const { normalize = true, paths, ...rest } = options ?? {};
181
+ try {
182
+ const path = normalizePath(modulePath, normalize);
183
+ return resolvePathSync(path, {
184
+ url: paths,
185
+ ...rest
186
+ });
187
+ } catch (e) {
188
+ return void 0;
189
+ }
190
+ }
191
+
192
+ const tsconfig = (tsconfigDir) => ({
193
+ get paths() {
194
+ return globbySync(["tsconfig.json", "tsconfig.*.json"], {
195
+ cwd: tsconfigDir
196
+ }) ?? [];
197
+ }
198
+ });
199
+
200
+ function parseGitignoreFile(gitignorePath, options) {
201
+ return gitignoreParser(gitignorePath, options);
202
+ }
203
+ function getGitignoreData(gitignorePath) {
204
+ const gitignoreFileContent = readFileSync(gitignorePath, "utf-8");
205
+ const gitignores = parseGitignoreFile(gitignoreFileContent);
206
+ return gitignores;
207
+ }
208
+ const gitignore = (gitignorePath) => ({
209
+ get data() {
210
+ return getGitignoreData(gitignorePath);
211
+ },
212
+ get patterns() {
213
+ return getGitignoreData(gitignorePath).patterns;
214
+ }
215
+ });
216
+
217
+ const dependencyTypeMap = {
218
+ dependency: "dependencies",
219
+ devDependency: "devDependencies",
220
+ peerDependency: "peerDependencies",
221
+ optionalDependency: "optionalDependencies"
222
+ };
223
+
224
+ function isDependencyInPackageJson(options, packageJson) {
225
+ return Boolean(findDependencyInPackageJson(options, packageJson));
226
+ }
227
+ function findDependencyInPackageJson(option, packageJson) {
228
+ const { name, type } = typeof option === "string" ? { name: option, type: void 0 } : option;
229
+ if (!packageJson)
230
+ return void 0;
231
+ const allowedTypes = typeof type === "string" ? {
232
+ [type]: true
233
+ } : type ?? {
234
+ dependency: true,
235
+ devDependency: true
236
+ };
237
+ const allowedDependencyTypes = getAllowedDependencyTypeList(allowedTypes);
238
+ const matches = allowedDependencyTypes.map((type2) => {
239
+ return getPackageJsonDependencyItem({ name, type: type2 }, packageJson);
240
+ }).filter(notFalsy);
241
+ if (matches.length === 0)
242
+ return void 0;
243
+ return {
244
+ firstMatch: matches[0],
245
+ matches
246
+ };
247
+ }
248
+ function getPackageJsonDependencyItem({
249
+ name,
250
+ type
251
+ }, packageJson) {
252
+ if (!packageJson)
253
+ return void 0;
254
+ const dependencyMap = getPackageJsonDependencyMap(type, packageJson);
255
+ const version = dependencyMap?.[name];
256
+ if (version === void 0)
257
+ return void 0;
258
+ return {
259
+ name,
260
+ version,
261
+ type
262
+ };
263
+ }
264
+ function getAllowedDependencyTypeList(selected) {
265
+ return Object.keys(dependencyTypeMap).filter(
266
+ (key) => selected[key]
267
+ );
268
+ }
269
+ function getPackageJsonDependencyMap(type, packageJson) {
270
+ return packageJson[dependencyTypeMap[type]];
271
+ }
272
+
273
+ function getWorkspaceFolder(options) {
274
+ const {
275
+ cwd = process.cwd(),
276
+ fallbackToGitRoot = true,
277
+ throwIfNotFound = true
278
+ } = options ?? {};
279
+ const getFolder = fallbackToGitRoot ? WST.getWorkspaceRoot : WST.getWorkspaceRoot;
280
+ const folder = getFolder(cwd);
281
+ if (folder === void 0 && throwIfNotFound) {
282
+ throw new Error(`Could not find workspace folder`);
283
+ }
284
+ return folder;
285
+ }
286
+ getWorkspaceFolder();
287
+
288
+ function getPackageFolder(options) {
289
+ return WST.findPackageRoot(options?.cwd ?? process.cwd());
290
+ }
291
+
292
+ function getPackageInfo(options) {
293
+ const packageDir = getPackageFolder(options);
294
+ return readPackageInfo({ packageDir });
295
+ }
296
+ function readPackageInfo({
297
+ packageDir
298
+ }) {
299
+ const packageJsonPath = path.join(packageDir, "package.json");
300
+ const packageJson = JSON.parse(
301
+ readFileSync(packageJsonPath, "utf-8")
302
+ );
303
+ return {
304
+ name: packageJson.name,
305
+ path: packageJsonPath,
306
+ dirpath: packageDir,
307
+ packageJson
308
+ };
309
+ }
310
+
311
+ function getWorkspaceProjectInfo(options) {
312
+ try {
313
+ const workspaceDir = getWorkspaceFolder(options);
314
+ return readPackageInfo({ packageDir: workspaceDir });
315
+ } catch (e) {
316
+ console.error(e);
317
+ throw new Error("Root workspace not found");
318
+ }
319
+ }
320
+
321
+ function getWorkspacePackageInfoList(options) {
322
+ const { workspaceDir, resolveWstList } = common(options);
323
+ const wstList = WST.getWorkspaces(workspaceDir);
324
+ return resolveWstList(wstList);
325
+ }
326
+ function common(options) {
327
+ const { cwd, includeRoot: includeWorkspace } = options ?? {};
328
+ const workspaceDir = getWorkspaceFolder({ cwd });
329
+ function resolveWstList(list) {
330
+ if (!workspaceDir)
331
+ return [];
332
+ if (includeWorkspace)
333
+ return [getWorkspaceProjectInfo(), ...list];
334
+ return list;
335
+ }
336
+ return {
337
+ workspaceDir,
338
+ includeWorkspace,
339
+ resolveWstList
340
+ };
341
+ }
342
+
343
+ function getWorkspacePackageInfoMap(options) {
344
+ const workspaceInfo = getWorkspacePackageInfoList(options);
345
+ const entries = workspaceInfo.map((info) => [info.name, info]);
346
+ return Object.fromEntries(entries);
347
+ }
348
+
349
+ function getProjectInfoByName(name, options) {
350
+ const { cwd } = options ?? {};
351
+ return getWorkspacePackageInfoMap({ cwd })[name];
352
+ }
353
+
354
+ function getProjectInfo(folder, options) {
355
+ if (isWorkspaceFolderTypeOption(folder)) {
356
+ return getWorkspaceProjectInfo(
357
+ parseWorkspaceFolderTypeOptions(folder, options)
358
+ );
359
+ }
360
+ if (folder === "<package_folder>") {
361
+ return getPackageInfo(options);
362
+ }
363
+ if (folder === "<gitroot_folder>") {
364
+ return getPackageInfo(options);
365
+ }
366
+ return getProjectInfoByName(folder.packageName, options);
367
+ }
368
+ function isWorkspaceFolderTypeOption(option) {
369
+ return Boolean(
370
+ option === "<workspace_folder>" || typeof option === "object" && "<workspace_folder>" in option
371
+ );
372
+ }
373
+ function parseWorkspaceFolderTypeOptions(option, defaultOptions) {
374
+ if (typeof option === "string") {
375
+ return defaultOptions ?? {};
376
+ }
377
+ return { ...defaultOptions, ...option["<workspace_folder>"] };
378
+ }
379
+ getProjectInfo({
380
+ "<workspace_folder>": {}
381
+ });
382
+
383
+ const project = (...args) => {
384
+ const [source, projectOptions] = args;
385
+ const { packageJson, packageJsonPath, packageName, projectDir } = info();
386
+ const {
387
+ findPackageManager: findPackageManager2,
388
+ detectPackageManagers,
389
+ detectLockfilePackageManagers,
390
+ detectGlobalPackageManagers,
391
+ filterPackageManagers
392
+ } = definePackageManagerClient({ cwd: projectDir });
393
+ return {
394
+ packageJson,
395
+ packageJsonPath,
396
+ packageName,
397
+ projectDir,
398
+ findPackageManager: findPackageManager2,
399
+ detectPackageManagers,
400
+ detectGlobalPackageManagers,
401
+ detectLockfilePackageManagers,
402
+ tsconfig: tsconfig(projectDir ?? ""),
403
+ gitignore: gitignore(path$1.join(projectDir ?? "", ".gitignore")),
404
+ filterPackageManagers,
405
+ getPackageJson: () => get("packageJson"),
406
+ findDependencyInPackageJson: (options) => findDependencyInPackageJson(options, get("packageJson")),
407
+ isDependencyInPackageJson: (options) => isDependencyInPackageJson(options, get("packageJson"))
408
+ };
409
+ function info() {
410
+ const {
411
+ packageJson: packageJson2,
412
+ name: packageName2,
413
+ dirpath: projectDir2,
414
+ path: packageJsonPath2
415
+ } = getProjectInfo(source, projectOptions) ?? {};
416
+ return {
417
+ packageJson: packageJson2,
418
+ packageJsonPath: packageJsonPath2,
419
+ packageName: packageName2,
420
+ projectDir: projectDir2
421
+ };
422
+ }
423
+ function get(key) {
424
+ return info()[key];
425
+ }
426
+ };
427
+
428
+ function getWorkspacePackageNames(options) {
429
+ return getWorkspacePackageInfoList(options).map((e) => e.name);
430
+ }
431
+
432
+ const workspace = {
433
+ packageNames: getWorkspacePackageNames,
434
+ packageGraph: getWorkspacePackageInfoMap,
435
+ packageList: getWorkspacePackageInfoList,
436
+ workspaceRootDir: getWorkspaceFolder,
437
+ getProject: project
438
+ };
13
439
 
14
440
  function importer(imports, options) {
15
- const { install = true } = options ?? {};
441
+ const { install: defaultInstall = true, installer } = options ?? {};
16
442
  return Promise.all(
17
- imports.map(async (option) => {
18
- if (install && "name" in option) {
19
- await ensurePackage(option.name);
443
+ imports.map(async (e) => {
444
+ const importOpt = resolveImportOption(e);
445
+ const shouldInstall = importOpt.install ?? defaultInstall;
446
+ if (shouldInstall && importOpt.name) {
447
+ await installImport(importOpt.name, importOpt, installer);
20
448
  }
21
- const importStatement = getImportStatement(option);
22
- return resolveModule(importStatement);
449
+ const m = await importOpt.import();
450
+ return resolveModule(m);
23
451
  })
24
452
  );
25
453
  }
26
- function getImportStatement(option) {
454
+ const definePackage = (option) => {
455
+ const { name, ...rest } = typeof option === "string" ? { name: option } : option;
456
+ return {
457
+ name,
458
+ import: () => import(name),
459
+ ...rest
460
+ };
461
+ };
462
+ function resolveImportOption(option) {
27
463
  if (typeof option === "function") {
28
- return option();
464
+ return {
465
+ import: option
466
+ };
29
467
  }
30
- if (typeof option === "object" && "import" in option && "name" in option) {
31
- return option.import();
468
+ if (option instanceof Promise) {
469
+ return {
470
+ import: () => option
471
+ };
32
472
  }
33
473
  return option;
34
474
  }
475
+ async function installImport(packageName, options, installer) {
476
+ if (!packageName)
477
+ return;
478
+ const { checkExists } = options ?? {};
479
+ if (checkExists && isPackageDependency(packageName))
480
+ return;
481
+ const installerFn = installer ?? (await workspace.getProject("<package_folder>").findPackageManager()).installPackage;
482
+ await installerFn(packageName, options);
483
+ }
35
484
 
36
- async function importMap(importMap2, options) {
485
+ const importMap = async (importMap2, options) => {
37
486
  const keys = Object.keys(importMap2);
38
487
  const imported = await importer(
39
488
  keys.map((key) => importMap2[key]),
@@ -42,43 +491,55 @@ async function importMap(importMap2, options) {
42
491
  return Object.fromEntries(
43
492
  keys.map((key, index) => [key, imported[index]])
44
493
  );
45
- }
46
-
47
- const toArray = (data) => Array.isArray(data) ? data : [data];
48
- const entriesOf = (o) => Object.entries(o);
49
- const fromEntries = (entries) => Object.fromEntries(entries);
50
- const notFalsy = (value) => [false, null, void 0].every((v) => v !== value);
51
- const select = (obj, selection, mode) => {
52
- if (!selection)
53
- return obj;
54
- const filtered = entriesOf(obj).filter(([key]) => {
55
- return mode === "omit" ? !selection[key] : selection[key];
56
- });
57
- return fromEntries(filtered);
58
494
  };
59
- const invariant = (predicate, message) => {
60
- if (!predicate) {
61
- throw new Error(message);
62
- }
63
- };
64
-
65
- function isPackageDependency(packageName) {
66
- return toArray(packageName).every((name) => isPackageExists(name));
67
- }
68
-
69
- async function ensurePackage(name, options) {
70
- if (isPackageDependency(name))
71
- return;
72
- await installPackage(name, options);
73
- }
74
495
 
75
- function definePackageManager(config) {
496
+ function definePackageManager(config, options) {
497
+ const { cwd: defaultCwd } = options ?? {};
76
498
  const { command, args: agentArgs, options: agentOptions } = config;
77
- const findLockfilePath = asyncCacheFn(async (options) => {
78
- const { cwd } = options ?? {};
499
+ const findLockfilePath = asyncCacheFn(async (options2) => {
500
+ const { cwd = defaultCwd } = options2 ?? {};
79
501
  const lockfiles = toArray(config.meta.lockfile);
80
502
  return await findUp(lockfiles, { cwd });
81
503
  });
504
+ const installPackage = async (packageName, options2) => {
505
+ const install = agentArgs.install;
506
+ const { dev, preferOffline } = select(
507
+ install.options,
508
+ {
509
+ preferOffline: true,
510
+ cwd: defaultCwd,
511
+ ...options2
512
+ },
513
+ "pick"
514
+ );
515
+ const packageNames = toArray(packageName);
516
+ try {
517
+ await $$({
518
+ command,
519
+ args: [install.command, dev, preferOffline, ...packageNames],
520
+ cwd: defaultCwd,
521
+ ...options2
522
+ });
523
+ } catch (e) {
524
+ throw new Error(`Failed to install: ${packageNames.join(", ")}`);
525
+ }
526
+ };
527
+ const uninstallPackage = async (packageName, options2) => {
528
+ const uninstall = agentArgs.uninstall;
529
+ await Promise.all(
530
+ toArray(packageName).map(async (name) => {
531
+ try {
532
+ await $$({
533
+ command,
534
+ args: [uninstall.command, name],
535
+ cwd: defaultCwd,
536
+ ...options2
537
+ });
538
+ } catch (e) {
539
+ }
540
+ })
541
+ );
542
+ };
82
543
  return {
83
544
  id: config.id,
84
545
  config,
@@ -94,50 +555,27 @@ function definePackageManager(config) {
94
555
  return readFile(lockfilePath, "utf8");
95
556
  }),
96
557
  globalVersion: asyncCacheFn(async (...args) => {
97
- const [options] = args;
558
+ const [options2] = args;
98
559
  try {
99
560
  const { stdout } = await $$({
100
561
  command,
101
562
  args: [agentOptions.version],
102
- ...options
563
+ cwd: defaultCwd,
564
+ ...options2
103
565
  });
104
566
  return `${stdout}`;
105
567
  } catch (e) {
106
568
  return void 0;
107
569
  }
108
570
  }),
109
- installPackage: async (packageName, options) => {
110
- const install = agentArgs.install;
111
- const { isDevDependency, preferOffline } = select(
112
- install.options,
113
- options ?? {},
114
- "pick"
115
- );
116
- const packageNames = toArray(packageName);
117
- try {
118
- await $$({
119
- command,
120
- args: [
121
- install.command,
122
- isDevDependency,
123
- preferOffline,
124
- ...packageNames
125
- ],
126
- ...options
127
- });
128
- } catch (e) {
129
- throw new Error(`Failed to install: ${packageNames.join(", ")}`);
130
- }
131
- },
132
- uninstallPackage: async (packageName, options) => {
133
- const uninstall = agentArgs.uninstall;
134
- if (!isPackageDependency(packageName))
135
- return;
136
- await $$({
137
- command,
138
- args: [uninstall.command, ...toArray(packageName)],
139
- ...options
140
- }).catch((e) => {
571
+ definePackage,
572
+ installPackage,
573
+ uninstallPackage,
574
+ defineImportMap(imports, options2) {
575
+ const { install = true } = options2 ?? {};
576
+ return importMap(imports, {
577
+ install,
578
+ installer: installPackage
141
579
  });
142
580
  }
143
581
  };
@@ -151,7 +589,11 @@ async function $$(options) {
151
589
  });
152
590
  }
153
591
 
154
- const bun = definePackageManager({
592
+ function definePackageManagerConfig(config) {
593
+ return config;
594
+ }
595
+
596
+ const bun = definePackageManagerConfig({
155
597
  id: "bun",
156
598
  name: "Bun",
157
599
  command: "bun",
@@ -163,7 +605,7 @@ const bun = definePackageManager({
163
605
  install: {
164
606
  command: "install",
165
607
  options: {
166
- isDevDependency: "-D",
608
+ dev: "-D",
167
609
  preferOffline: "--prefer-offline"
168
610
  }
169
611
  },
@@ -176,7 +618,7 @@ const bun = definePackageManager({
176
618
  }
177
619
  });
178
620
 
179
- const npm = definePackageManager({
621
+ const npm = definePackageManagerConfig({
180
622
  id: "npm",
181
623
  name: "NPM",
182
624
  command: "npm",
@@ -188,7 +630,7 @@ const npm = definePackageManager({
188
630
  install: {
189
631
  command: "install",
190
632
  options: {
191
- isDevDependency: "-D",
633
+ dev: "-D",
192
634
  preferOffline: "--prefer-offline"
193
635
  }
194
636
  },
@@ -201,7 +643,7 @@ const npm = definePackageManager({
201
643
  }
202
644
  });
203
645
 
204
- const pnpm = definePackageManager({
646
+ const pnpm = definePackageManagerConfig({
205
647
  id: "pnpm",
206
648
  name: "PNPM",
207
649
  command: "pnpm",
@@ -213,12 +655,12 @@ const pnpm = definePackageManager({
213
655
  install: {
214
656
  command: "install",
215
657
  options: {
216
- isDevDependency: "-D",
658
+ dev: "-D",
217
659
  preferOffline: "--prefer-offline"
218
660
  }
219
661
  },
220
662
  uninstall: {
221
- command: "uninstall"
663
+ command: "remove"
222
664
  }
223
665
  },
224
666
  options: {
@@ -226,7 +668,7 @@ const pnpm = definePackageManager({
226
668
  }
227
669
  });
228
670
 
229
- const yarn = definePackageManager({
671
+ const yarn = definePackageManagerConfig({
230
672
  id: "yarn",
231
673
  name: "Yarn",
232
674
  command: "yarn",
@@ -238,7 +680,7 @@ const yarn = definePackageManager({
238
680
  install: {
239
681
  command: "add",
240
682
  options: {
241
- isDevDependency: "-D",
683
+ dev: "-D",
242
684
  preferOffline: "--prefer-offline"
243
685
  }
244
686
  },
@@ -251,51 +693,262 @@ const yarn = definePackageManager({
251
693
  }
252
694
  });
253
695
 
254
- const packageManagers = fromEntries(
255
- [pnpm, yarn, bun, npm].map((e) => [e.id, e])
256
- );
257
-
258
- async function findPackageManager(options) {
696
+ async function findPackageManager(packageManagers, options) {
259
697
  const { ...rest } = options ?? {};
260
- const packageManager = await findPackageManagerSafely(rest);
698
+ const packageManager = await findPackageManagerSafely(packageManagers, rest);
261
699
  invariant(packageManager, "No package manager found");
262
700
  return packageManager;
263
701
  }
264
- async function findPackageManagerSafely(options) {
265
- const lockfilePm = (await detectLockfilePackageManagers(options))[0];
702
+ async function findPackageManagerSafely(packageManagers, options) {
703
+ const lockfilePm = (await detectLockfilePackageManagers(packageManagers, options))[0];
266
704
  if (lockfilePm) {
267
705
  return lockfilePm;
268
706
  }
269
- const globalPm = (await detectGlobalPackageManagers(options))[0];
707
+ const globalPm = (await detectGlobalPackageManagers(packageManagers, options))[0];
270
708
  return globalPm;
271
709
  }
272
- async function detectPackageManagers(options) {
710
+ async function detectPackageManagers(packageManagers, options) {
273
711
  return [
274
- ...await detectLockfilePackageManagers(options),
275
- ...await detectGlobalPackageManagers(options)
712
+ ...await detectLockfilePackageManagers(packageManagers, options),
713
+ ...await detectGlobalPackageManagers(packageManagers, options)
276
714
  ];
277
715
  }
278
- async function detectLockfilePackageManagers(options) {
279
- ({ cwd: options?.cwd });
280
- return filterPackageManagers((e) => e.hasLockfile(options), options);
281
- }
282
- async function detectGlobalPackageManagers(options) {
283
- return filterPackageManagers(async (e) => e.globalVersion(options), options);
716
+ async function detectLockfilePackageManagers(packageManagers, options) {
717
+ return filterPackageManagers(
718
+ packageManagers,
719
+ (e) => e.hasLockfile(options),
720
+ options
721
+ );
284
722
  }
285
- async function filterPackageManagers(filterFn, options) {
286
- const allowedPackageManagers = Object.entries(packageManagers).filter(
287
- ([key]) => {
288
- if (!options?.allowed)
289
- return true;
290
- return key in options.allowed;
291
- }
723
+ async function detectGlobalPackageManagers(packageManagers, options) {
724
+ return filterPackageManagers(
725
+ packageManagers,
726
+ async (e) => Boolean(e.globalVersion(options)),
727
+ options
292
728
  );
729
+ }
730
+ async function filterPackageManagers(packageManagers, filterFn, options) {
731
+ const allowedPackageManagers = packageManagers.filter(({ id }) => {
732
+ if (!options?.allowed)
733
+ return true;
734
+ return id in options.allowed;
735
+ });
293
736
  return (await Promise.all(
294
- allowedPackageManagers.map(async ([key, pm]) => {
737
+ allowedPackageManagers.map(async (pm) => {
295
738
  const valid = await filterFn(pm);
296
739
  return valid ? pm : void 0;
297
740
  })
298
741
  )).filter(notFalsy);
299
742
  }
300
743
 
301
- export { detectGlobalPackageManagers, detectLockfilePackageManagers, detectPackageManagers, ensurePackage, filterPackageManagers, findPackageManager, findPackageManagerSafely, importMap, importer, isPackageDependency, packageManagers, resolveModule };
744
+ const packageManagerConfigs = [pnpm, yarn, bun, npm];
745
+ function definePackageManagerClient(options) {
746
+ const configs = packageManagerConfigs.map(
747
+ (config) => definePackageManager(config, options)
748
+ );
749
+ return {
750
+ configs,
751
+ findPackageManager: asyncCacheFn(
752
+ async (options2) => await findPackageManager(configs, options2)
753
+ ),
754
+ findPackageManagerSafely: asyncCacheFn(
755
+ async (options2) => await findPackageManagerSafely(configs, options2)
756
+ ),
757
+ detectPackageManagers: asyncCacheFn(
758
+ async (options2) => await detectPackageManagers(configs, options2)
759
+ ),
760
+ detectLockfilePackageManagers: asyncCacheFn(
761
+ async (options2) => detectLockfilePackageManagers(configs, options2)
762
+ ),
763
+ detectGlobalPackageManagers: asyncCacheFn(
764
+ async (options2) => detectGlobalPackageManagers(configs, options2)
765
+ ),
766
+ filterPackageManagers: async (filterFn, options2) => filterPackageManagers(configs, filterFn, options2)
767
+ };
768
+ }
769
+
770
+ function isPackageDependency(packageName) {
771
+ return toArray(packageName).every((name) => isDependencyInPackageJson(name));
772
+ }
773
+
774
+ function definePathAliases(aliasDefinitions) {
775
+ const aliasMap = getAliasMap(aliasDefinitions);
776
+ function getFilePath(options, aliases) {
777
+ return getAliasedFilePath(
778
+ { ...aliasMap, ...aliases },
779
+ options
780
+ );
781
+ }
782
+ return {
783
+ aliasDefinitions,
784
+ aliasMap,
785
+ getFilePath
786
+ };
787
+ }
788
+ function getAliasedFilePath(aliasMap, options) {
789
+ try {
790
+ if (typeof options === "string" || Array.isArray(options)) {
791
+ return resolvePathTo(options, { aliasMap });
792
+ }
793
+ const opts = { ...options, aliasMap };
794
+ if (opts.startingFrom) {
795
+ return resolveRelativePathTo(opts.to, opts.startingFrom, opts);
796
+ }
797
+ return resolvePathTo(opts.to, opts);
798
+ } catch (e) {
799
+ return void 0;
800
+ }
801
+ }
802
+ function resolveRelativePathTo(to, from, options) {
803
+ const pathFrom = resolvePathTo(from, options);
804
+ const pathTo = resolvePathTo(to, options);
805
+ return path$1.relative(pathFrom, pathTo);
806
+ }
807
+ function resolvePathTo(pathTo, { cwd, checkExistence, glob, aliasMap }) {
808
+ const normalized = normalizePathTo(pathTo, { cwd, aliasMap });
809
+ if (glob) {
810
+ const globPaths = globbySync(normalized, { cwd });
811
+ if (!globPaths[0])
812
+ throw new Error(`No paths found for glob: ${normalized}`);
813
+ return globPaths[0];
814
+ }
815
+ if (!glob && checkExistence && !existsSync(normalized))
816
+ throw new Error(`Path does not exist: ${normalized}`);
817
+ return normalized;
818
+ }
819
+ function normalizePathTo(pathTo, options) {
820
+ const { cwd, aliasMap } = options ?? {};
821
+ if (Array.isArray(pathTo)) {
822
+ const [baseDir] = pathTo;
823
+ const aliasedPath = path$1.join(...pathTo.filter(isNotNull));
824
+ return resolveAlias(aliasedPath, {
825
+ [baseDir]: executeMapFn(aliasMap, baseDir, [{ cwd }])
826
+ });
827
+ }
828
+ return pathTo;
829
+ }
830
+ function executeMapFn(map, key, args) {
831
+ if (!map || !key || !(key in map))
832
+ return void 0;
833
+ const fnArgs = Array.isArray(args) ? args : [args];
834
+ const resolver = map?.[key];
835
+ return typeof resolver === "function" ? resolver?.(...fnArgs) : resolver;
836
+ }
837
+ function getAliasMap(aliasDefs) {
838
+ return Object.fromEntries(
839
+ Object.entries(aliasDefs).flatMap(([alias, v]) => {
840
+ const { resolve, subpaths = [] } = v;
841
+ return [
842
+ [alias, resolve],
843
+ ...subpaths.map(({ to }) => {
844
+ const subpathAlias = path$1.join(alias, to);
845
+ return [
846
+ subpathAlias,
847
+ (opts) => resolveAlias(subpathAlias, { [alias]: resolve(opts) })
848
+ ];
849
+ })
850
+ ];
851
+ })
852
+ );
853
+ }
854
+ function isNotNull(value) {
855
+ return value !== null && value !== void 0;
856
+ }
857
+
858
+ const predefinedPathAliases = {
859
+ "<workspace_folder>": {
860
+ resolve: (opts) => getWorkspaceFolder(opts),
861
+ subpaths: [
862
+ {
863
+ to: "node_modules"
864
+ },
865
+ {
866
+ to: "node_modules/.bin"
867
+ }
868
+ ]
869
+ },
870
+ "<workspace_folder?>": {
871
+ resolve: (opts) => getWorkspaceFolder(opts),
872
+ subpaths: [
873
+ {
874
+ to: "node_modules"
875
+ },
876
+ {
877
+ to: "node_modules/.bin"
878
+ }
879
+ ]
880
+ },
881
+ "<package_folder>": {
882
+ resolve: (opts) => getPackageFolder(opts),
883
+ subpaths: [
884
+ {
885
+ to: "node_modules"
886
+ },
887
+ {
888
+ to: "node_modules/.bin"
889
+ },
890
+ {
891
+ to: "src"
892
+ }
893
+ ]
894
+ },
895
+ "<gitroot_folder>": {
896
+ resolve: (opts) => getGitRootFolder(opts),
897
+ subpaths: [
898
+ {
899
+ to: "node_modules"
900
+ },
901
+ {
902
+ to: "node_modules/.bin"
903
+ },
904
+ {
905
+ to: ".vscode"
906
+ }
907
+ ]
908
+ },
909
+ "<user_home>": {
910
+ resolve: () => os.homedir(),
911
+ subpaths: []
912
+ },
913
+ "<user_tmpdir>": {
914
+ resolve: () => os.tmpdir(),
915
+ subpaths: []
916
+ },
917
+ "<cwd>": {
918
+ resolve: () => process.cwd(),
919
+ subpaths: []
920
+ },
921
+ "<current_file>": {
922
+ // resolve: () => fileURLToPath(import.meta.url),
923
+ resolve: () => _filename({ rootFunctionName: "getFilePath" }) ?? "",
924
+ subpaths: []
925
+ },
926
+ "<current_folder>": {
927
+ // resolve: () => fileURLToPath(import.meta.url),
928
+ resolve: () => _dirname({ rootFunctionName: "getFilePath" }) ?? "",
929
+ subpaths: []
930
+ }
931
+ };
932
+
933
+ const getPath = definePathAliases(predefinedPathAliases).getFilePath;
934
+ getPath(["<workspace_folder>/node_modules/.bin"]);
935
+
936
+ function getFolderByPackageName(name, options) {
937
+ const infoMap = getWorkspacePackageInfoMap({ ...options, includeRoot: true });
938
+ const info = infoMap?.[name];
939
+ return info?.dirpath;
940
+ }
941
+
942
+ function getGitRootFolder(options) {
943
+ const output = execaSync(`git rev-parse --show-toplevel`, {
944
+ ...options,
945
+ reject: false
946
+ });
947
+ if (!output.stdout) {
948
+ console.warn(`Directory "${output.cwd}" is not in a git repository`);
949
+ return void 0;
950
+ }
951
+ return path$1.normalize(output.stdout);
952
+ }
953
+
954
+ export { _dirname, _filename, definePackage, definePackageManagerClient, definePathAliases, detectGlobalPackageManagers, detectLockfilePackageManagers, detectPackageManagers, filterPackageManagers, findPackageManager, findPackageManagerSafely, findResolvedModulePath, getAliasMap, getFolderByPackageName, getGitRootFolder, getPackageFolder, getPath, getWorkspaceFolder, importMap, importer, isPackageDependency, isPackageModuleFound, packageManagerConfigs, predefinedPathAliases, resolveModule, resolveModulePath, resolvePackageModulePath, workspace };