package-management 0.0.9 → 0.0.11

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.cjs CHANGED
@@ -4,9 +4,10 @@ const ErrorStackParser = require('error-stack-parser');
4
4
  const path = require('pathe');
5
5
  const process = require('node:process');
6
6
  const path$1 = require('node:path');
7
+ const node_url = require('node:url');
7
8
  const node_fs = require('node:fs');
8
- const execa = require('execa');
9
9
  const asyncCacheFn = require('async-cache-fn');
10
+ const execa = require('execa');
10
11
  const findUp = require('find-up');
11
12
  const promises = require('node:fs/promises');
12
13
  const mlly = require('mlly');
@@ -16,6 +17,10 @@ const WST = require('workspace-tools');
16
17
  const utils = require('pathe/utils');
17
18
  const os = require('node:os');
18
19
  const jsoncParser = require('jsonc-parser');
20
+ const util = require('@arktype/util');
21
+ const unstorage = require('unstorage');
22
+ const defineMemoryDriver = require('unstorage/drivers/memory');
23
+ const defineFsLiteDriver = require('unstorage/drivers/fs-lite');
19
24
 
20
25
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
21
26
 
@@ -38,16 +43,17 @@ const path__default = /*#__PURE__*/_interopDefaultCompat(path$1);
38
43
  const gitignoreParser__default = /*#__PURE__*/_interopDefaultCompat(gitignoreParser);
39
44
  const WST__namespace = /*#__PURE__*/_interopNamespaceCompat(WST);
40
45
  const os__default = /*#__PURE__*/_interopDefaultCompat(os);
46
+ const defineMemoryDriver__default = /*#__PURE__*/_interopDefaultCompat(defineMemoryDriver);
47
+ const defineFsLiteDriver__default = /*#__PURE__*/_interopDefaultCompat(defineFsLiteDriver);
41
48
 
42
49
  const toArray = (data) => Array.isArray(data) ? data : [data];
43
50
  const entriesOf = (o) => Object.entries(o);
44
51
  const fromEntries = (entries) => Object.fromEntries(entries);
45
52
  const notFalsy = (value) => [false, null, void 0].every((v) => v !== value);
46
53
  const select = (obj, selection, mode) => {
47
- if (!selection)
48
- return obj;
54
+ if (!selection) return obj;
49
55
  const filtered = entriesOf(obj).filter(([key]) => {
50
- return mode === "omit" ? !selection[key] : selection[key];
56
+ return selection[key];
51
57
  });
52
58
  return fromEntries(filtered);
53
59
  };
@@ -66,15 +72,36 @@ const invariant = (predicate, message) => {
66
72
  }
67
73
  };
68
74
  function getArrayItemAtOffset(arr, index, offset = 0) {
69
- if (!index || !arr)
70
- return void 0;
75
+ if (arr === void 0 || index === void 0) return void 0;
71
76
  return arr[index + offset];
72
77
  }
73
78
  function isMatching(a, b) {
74
- if (!a || !b)
75
- return false;
79
+ if (!a || !b) return false;
76
80
  return a === b;
77
81
  }
82
+ function checkResult(cb, options) {
83
+ try {
84
+ return buildSingleProp({
85
+ key: options?.keys?.data ?? "data",
86
+ value: cb()
87
+ });
88
+ } catch (error) {
89
+ return buildSingleProp({
90
+ key: "error",
91
+ value: error
92
+ });
93
+ }
94
+ }
95
+ function isPropertyKey(input) {
96
+ return typeof input === "string" || typeof input === "number" || typeof input === "symbol";
97
+ }
98
+ function buildSingleProp(entry) {
99
+ const [key, value] = Array.isArray(entry) ? entry : [entry.key, entry.value];
100
+ if (!isPropertyKey(key)) {
101
+ return {};
102
+ }
103
+ return { [key]: value };
104
+ }
78
105
 
79
106
  function findCallerStackFrame(options) {
80
107
  return findErrorStackFrame(options, (frame) => frame.isParentOfRootFunction);
@@ -135,7 +162,7 @@ function getFilePathData({
135
162
  cwd
136
163
  }) {
137
164
  const workingDir = cwd ?? process__default.cwd();
138
- const filePath = path.normalize(filepath);
165
+ const filePath = path.normalize(toFilePath(filepath));
139
166
  const fileBasename = path.basename(filePath);
140
167
  const dirPath = path.dirname(filePath);
141
168
  const dirBasename = path.basename(dirPath);
@@ -152,17 +179,18 @@ function getFilePathData({
152
179
  isFileInCwd
153
180
  };
154
181
  }
182
+ function toFilePath(fileName) {
183
+ return fileName.startsWith("file:") ? node_url.fileURLToPath(fileName) : fileName;
184
+ }
155
185
  function parseFunctionName(functionName) {
156
- if (!functionName)
157
- return void 0;
186
+ if (!functionName) return void 0;
158
187
  return removeStart(functionName, "Module.");
159
188
  }
160
189
  function removeStart(input, value) {
161
190
  return input.startsWith(value) ? input.slice(value.length) : input;
162
191
  }
163
192
  function placeFormatter(index, total) {
164
- if (!index || !total)
165
- return void 0;
193
+ if (index === void 0 || !total) return void 0;
166
194
  return [index, total].join("/");
167
195
  }
168
196
 
@@ -196,8 +224,7 @@ function resolvePackageModulePath(name, options) {
196
224
  function findResolvedModulePath(paths, options) {
197
225
  for (const path of paths) {
198
226
  const resolvedPath = resolveModulePath(path, options);
199
- if (resolvedPath === void 0)
200
- continue;
227
+ if (resolvedPath === void 0) continue;
201
228
  return resolvedPath;
202
229
  }
203
230
  }
@@ -251,8 +278,7 @@ function isDependencyInPackageJson(options, packageJson) {
251
278
  }
252
279
  function findDependencyInPackageJson(option, packageJson) {
253
280
  const { name, type } = typeof option === "string" ? { name: option, type: void 0 } : option;
254
- if (!packageJson)
255
- return void 0;
281
+ if (!packageJson) return void 0;
256
282
  const allowedTypes = typeof type === "string" ? {
257
283
  [type]: true
258
284
  } : type ?? {
@@ -263,8 +289,7 @@ function findDependencyInPackageJson(option, packageJson) {
263
289
  const matches = allowedDependencyTypes.map((type2) => {
264
290
  return getPackageJsonDependencyItem({ name, type: type2 }, packageJson);
265
291
  }).filter(notFalsy);
266
- if (matches.length === 0)
267
- return void 0;
292
+ if (matches.length === 0) return void 0;
268
293
  return {
269
294
  firstMatch: matches[0],
270
295
  matches
@@ -274,12 +299,10 @@ function getPackageJsonDependencyItem({
274
299
  name,
275
300
  type
276
301
  }, packageJson) {
277
- if (!packageJson)
278
- return void 0;
302
+ if (!packageJson) return void 0;
279
303
  const dependencyMap = getPackageJsonDependencyMap(type, packageJson);
280
304
  const version = dependencyMap?.[name];
281
- if (version === void 0)
282
- return void 0;
305
+ if (version === void 0) return void 0;
283
306
  return {
284
307
  name,
285
308
  version,
@@ -301,7 +324,7 @@ function getWorkspaceFolder(options) {
301
324
  fallbackToGitRoot = true,
302
325
  throwIfNotFound = true
303
326
  } = options ?? {};
304
- const getFolder = fallbackToGitRoot ? WST__namespace.findProjectRoot : WST__namespace.getWorkspaceRoot;
327
+ const getFolder = fallbackToGitRoot ? WST__namespace.findProjectRoot : WST__namespace.getWorkspaceManagerRoot;
305
328
  const folder = getFolder(cwd);
306
329
  if (folder === void 0 && throwIfNotFound) {
307
330
  throw new Error(`Could not find workspace folder`);
@@ -344,17 +367,15 @@ function getWorkspaceProjectInfo(options) {
344
367
 
345
368
  function getWorkspacePackageInfoList(options) {
346
369
  const { workspaceDir, resolveWstList } = common(options);
347
- const wstList = WST__namespace.getWorkspaces(workspaceDir);
370
+ const wstList = WST__namespace.getWorkspaceInfos(workspaceDir);
348
371
  return resolveWstList(wstList);
349
372
  }
350
373
  function common(options) {
351
374
  const { cwd, includeRoot: includeWorkspace } = options ?? {};
352
375
  const workspaceDir = getWorkspaceFolder({ cwd });
353
376
  function resolveWstList(list) {
354
- if (!workspaceDir)
355
- return [];
356
- if (includeWorkspace)
357
- return [getWorkspaceProjectInfo(), ...list];
377
+ if (!workspaceDir || !list) return [];
378
+ if (includeWorkspace) return [getWorkspaceProjectInfo(), ...list];
358
379
  return list;
359
380
  }
360
381
  return {
@@ -375,6 +396,21 @@ function getProjectInfoByName(name, options) {
375
396
  return getWorkspacePackageInfoMap({ cwd })[name];
376
397
  }
377
398
 
399
+ function getGitRootFolder(options) {
400
+ const { cwd = process__default.cwd(), throwIfNotFound = true } = options ?? {};
401
+ const { stdout } = execa.execaSync("git", ["rev-parse", "--show-toplevel"], {
402
+ cwd,
403
+ reject: false
404
+ });
405
+ if (!stdout) {
406
+ if (throwIfNotFound) {
407
+ throw new Error(`Directory "${cwd}" is not in a git repository`);
408
+ }
409
+ return void 0;
410
+ }
411
+ return path__default$1.normalize(stdout);
412
+ }
413
+
378
414
  function getProjectInfo(folder, options) {
379
415
  if (isWorkspaceFolderTypeOption(folder)) {
380
416
  return getWorkspaceProjectInfo(
@@ -385,7 +421,7 @@ function getProjectInfo(folder, options) {
385
421
  return getPackageInfo(options);
386
422
  }
387
423
  if (folder === "<gitroot_folder>") {
388
- return getPackageInfo(options);
424
+ return readPackageInfo({ packageDir: getGitRootFolder(options) });
389
425
  }
390
426
  return getProjectInfoByName(folder.packageName, options);
391
427
  }
@@ -400,9 +436,6 @@ function parseWorkspaceFolderTypeOptions(option, defaultOptions) {
400
436
  }
401
437
  return { ...defaultOptions, ...option["<workspace_folder>"] };
402
438
  }
403
- getProjectInfo({
404
- "<workspace_folder>": {}
405
- });
406
439
 
407
440
  const project = (...args) => {
408
441
  const [source, projectOptions] = args;
@@ -412,7 +445,9 @@ const project = (...args) => {
412
445
  detectPackageManagers,
413
446
  detectLockfilePackageManagers,
414
447
  detectGlobalPackageManagers,
415
- filterPackageManagers
448
+ globalVersions,
449
+ filterPackageManagers,
450
+ mapPackageManagers
416
451
  } = definePackageManagerClient({ cwd: projectDir });
417
452
  return {
418
453
  packageJson,
@@ -423,6 +458,8 @@ const project = (...args) => {
423
458
  detectPackageManagers,
424
459
  detectGlobalPackageManagers,
425
460
  detectLockfilePackageManagers,
461
+ globalVersions,
462
+ mapPackageManagers,
426
463
  tsconfig: tsconfig(projectDir ?? ""),
427
464
  gitignore: gitignore(path__default$1.join(projectDir ?? "", ".gitignore")),
428
465
  filterPackageManagers,
@@ -497,11 +534,9 @@ function resolveImportOption(option) {
497
534
  return option;
498
535
  }
499
536
  async function installImport(packageName, options, installer) {
500
- if (!packageName)
501
- return;
537
+ if (!packageName) return;
502
538
  const { checkExists } = options ?? {};
503
- if (checkExists && isPackageDependency(packageName))
504
- return;
539
+ if (checkExists && isPackageDependency(packageName)) return;
505
540
  const installerFn = installer ?? (await workspace.getProject("<package_folder>").findPackageManager()).installPackage;
506
541
  await installerFn(packageName, options);
507
542
  }
@@ -533,9 +568,7 @@ function definePackageManager(config, options) {
533
568
  preferOffline: true,
534
569
  cwd: defaultCwd,
535
570
  ...options2
536
- },
537
- "pick"
538
- );
571
+ });
539
572
  const packageNames = toArray(packageName);
540
573
  try {
541
574
  await $$({
@@ -544,25 +577,32 @@ function definePackageManager(config, options) {
544
577
  cwd: defaultCwd,
545
578
  ...options2
546
579
  });
547
- } catch (e) {
548
- throw new Error(`Failed to install: ${packageNames.join(", ")}`);
580
+ } catch (error) {
581
+ throw new Error(`Failed to install: ${packageNames.join(", ")}`, {
582
+ cause: error
583
+ });
549
584
  }
550
585
  };
551
586
  const uninstallPackage = async (packageName, options2) => {
552
587
  const uninstall = agentArgs.uninstall;
553
- await Promise.all(
554
- toArray(packageName).map(async (name) => {
555
- try {
556
- await $$({
557
- command,
558
- args: [uninstall.command, name],
559
- cwd: defaultCwd,
560
- ...options2
561
- });
562
- } catch (e) {
563
- }
564
- })
588
+ const cwd = options2?.cwd ?? defaultCwd;
589
+ const { packageJson } = getPackageInfo({ cwd });
590
+ const installed = toArray(packageName).filter(
591
+ (name) => isDependencyInPackageJson(name, packageJson)
565
592
  );
593
+ if (installed.length === 0) return;
594
+ try {
595
+ await $$({
596
+ command,
597
+ args: [uninstall.command, ...installed],
598
+ cwd,
599
+ ...options2
600
+ });
601
+ } catch (error) {
602
+ throw new Error(`Failed to uninstall: ${installed.join(", ")}`, {
603
+ cause: error
604
+ });
605
+ }
566
606
  };
567
607
  return {
568
608
  id: config.id,
@@ -574,8 +614,7 @@ function definePackageManager(config, options) {
574
614
  }),
575
615
  readLockfile: asyncCacheFn.asyncCacheFn(async (...args) => {
576
616
  const lockfilePath = await findLockfilePath.noCache(...args);
577
- if (!lockfilePath)
578
- return void 0;
617
+ if (!lockfilePath) return void 0;
579
618
  return promises.readFile(lockfilePath, "utf8");
580
619
  }),
581
620
  globalVersion: asyncCacheFn.asyncCacheFn(async (...args) => {
@@ -609,7 +648,10 @@ async function $$(options) {
609
648
  return execa.execa(command, args.filter(notFalsy), {
610
649
  cwd,
611
650
  ...shellOptions,
612
- stdio: silent ? "ignore" : "inherit"
651
+ // `pipe` keeps output off the console while still capturing it: a failed
652
+ // command can report why it failed, and `globalVersion` can read stdout.
653
+ // `ignore` discards the reason along with the output.
654
+ stdio: silent ? "pipe" : "inherit"
613
655
  });
614
656
  }
615
657
 
@@ -718,18 +760,24 @@ const yarn = definePackageManagerConfig({
718
760
  });
719
761
 
720
762
  async function findPackageManager(packageManagers, options) {
721
- const { ...rest } = options ?? {};
722
- const packageManager = await findPackageManagerSafely(packageManagers, rest);
763
+ const packageManager = await findPackageManagerSafely(
764
+ packageManagers,
765
+ options
766
+ );
723
767
  invariant(packageManager, "No package manager found");
724
768
  return packageManager;
725
769
  }
726
770
  async function findPackageManagerSafely(packageManagers, options) {
727
- const lockfilePm = (await detectLockfilePackageManagers(packageManagers, options))[0];
728
- if (lockfilePm) {
729
- return lockfilePm;
730
- }
731
- const globalPm = (await detectGlobalPackageManagers(packageManagers, options))[0];
732
- return globalPm;
771
+ const [fromLockfile] = await detectLockfilePackageManagers(
772
+ packageManagers,
773
+ options
774
+ );
775
+ if (fromLockfile) return fromLockfile;
776
+ const [fromGlobal] = await detectGlobalPackageManagers(
777
+ packageManagers,
778
+ options
779
+ );
780
+ return fromGlobal;
733
781
  }
734
782
  async function detectPackageManagers(packageManagers, options) {
735
783
  return [
@@ -740,29 +788,47 @@ async function detectPackageManagers(packageManagers, options) {
740
788
  async function detectLockfilePackageManagers(packageManagers, options) {
741
789
  return filterPackageManagers(
742
790
  packageManagers,
743
- (e) => e.hasLockfile(options),
791
+ (packageManager) => packageManager.hasLockfile(options),
744
792
  options
745
793
  );
746
794
  }
747
795
  async function detectGlobalPackageManagers(packageManagers, options) {
748
796
  return filterPackageManagers(
749
797
  packageManagers,
750
- async (e) => Boolean(e.globalVersion(options)),
798
+ // Without the `await`, `Boolean` receives a pending promise and is always
799
+ // `true`, so every package manager passes the filter regardless of whether
800
+ // it is actually installed.
801
+ async (packageManager) => Boolean(await packageManager.globalVersion(options)),
751
802
  options
752
803
  );
753
804
  }
805
+ async function getGlobalVersions(packageManagers, options) {
806
+ const entries = await mapPackageManagers(
807
+ packageManagers,
808
+ async (packageManager) => [packageManager.id, await packageManager.globalVersion(options)],
809
+ options
810
+ );
811
+ return Object.fromEntries(entries);
812
+ }
813
+ async function mapPackageManagers(packageManagers, mapFn, options) {
814
+ return Promise.all(
815
+ selectAllowedPackageManagers(packageManagers, options).map(
816
+ (packageManager) => mapFn(packageManager)
817
+ )
818
+ );
819
+ }
754
820
  async function filterPackageManagers(packageManagers, filterFn, options) {
755
- const allowedPackageManagers = packageManagers.filter(({ id }) => {
756
- if (!options?.allowed)
757
- return true;
758
- return id in options.allowed;
759
- });
760
- return (await Promise.all(
761
- allowedPackageManagers.map(async (pm) => {
762
- const valid = await filterFn(pm);
763
- return valid ? pm : void 0;
764
- })
765
- )).filter(notFalsy);
821
+ const matches = await mapPackageManagers(
822
+ packageManagers,
823
+ async (packageManager) => await filterFn(packageManager) ? packageManager : void 0,
824
+ options
825
+ );
826
+ return matches.filter(notFalsy);
827
+ }
828
+ function selectAllowedPackageManagers(packageManagers, options) {
829
+ return packageManagers.filter(
830
+ ({ id }) => options?.allowed ? id in options.allowed : true
831
+ );
766
832
  }
767
833
 
768
834
  const packageManagerConfigs = [pnpm, yarn, bun, npm];
@@ -787,7 +853,11 @@ function definePackageManagerClient(options) {
787
853
  detectGlobalPackageManagers: asyncCacheFn.asyncCacheFn(
788
854
  async (options2) => detectGlobalPackageManagers(configs, options2)
789
855
  ),
790
- filterPackageManagers: async (filterFn, options2) => filterPackageManagers(configs, filterFn, options2)
856
+ globalVersions: asyncCacheFn.asyncCacheFn(
857
+ async (options2) => getGlobalVersions(configs, options2)
858
+ ),
859
+ filterPackageManagers: async (filterFn, options2) => filterPackageManagers(configs, filterFn, options2),
860
+ mapPackageManagers: async (mapFn, options2) => mapPackageManagers(configs, mapFn, options2)
791
861
  };
792
862
  }
793
863
 
@@ -810,17 +880,13 @@ function definePathAliases(aliasDefinitions) {
810
880
  };
811
881
  }
812
882
  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 };
813
885
  try {
814
- if (typeof options === "string" || Array.isArray(options)) {
815
- return resolvePathTo(options, { aliasMap });
816
- }
817
- const opts = { ...options, aliasMap };
818
- if (opts.startingFrom) {
819
- return resolveRelativePathTo(opts.to, opts.startingFrom, opts);
820
- }
821
- return resolvePathTo(opts.to, opts);
822
- } catch (e) {
823
- return void 0;
886
+ return startingFrom ? resolveRelativePathTo(to, startingFrom, resolveOptions) : resolvePathTo(to, resolveOptions);
887
+ } catch (error) {
888
+ if (checkExistence || glob) return void 0;
889
+ throw error;
824
890
  }
825
891
  }
826
892
  function resolveRelativePathTo(to, from, options) {
@@ -842,18 +908,20 @@ function resolvePathTo(pathTo, { cwd, checkExistence, glob, aliasMap }) {
842
908
  }
843
909
  function normalizePathTo(pathTo, options) {
844
910
  const { cwd, aliasMap } = options ?? {};
845
- if (Array.isArray(pathTo)) {
846
- const [baseDir] = pathTo;
847
- const aliasedPath = path__default$1.join(...pathTo.filter(isNotNull));
848
- return utils.resolveAlias(aliasedPath, {
849
- [baseDir]: executeMapFn(aliasMap, baseDir, [{ cwd }])
850
- });
911
+ const aliasedPath = Array.isArray(pathTo) ? path__default$1.join(...pathTo.filter(isNotNull)) : pathTo;
912
+ const baseDir = Array.isArray(pathTo) ? pathTo[0] : findAliasToken(aliasedPath, aliasMap);
913
+ if (baseDir === void 0) return aliasedPath;
914
+ const baseDirPath = executeMapFn(aliasMap, baseDir, [{ cwd }]);
915
+ if (typeof baseDirPath !== "string" || baseDirPath.length === 0) {
916
+ throw new Error(`Path alias resolved to no location: ${baseDir}`);
851
917
  }
852
- return pathTo;
918
+ return utils.resolveAlias(aliasedPath, { [baseDir]: baseDirPath });
919
+ }
920
+ function findAliasToken(pathTo, aliasMap) {
921
+ return Object.keys(aliasMap ?? {}).filter((alias) => pathTo === alias || pathTo.startsWith(`${alias}/`)).sort((a, b) => b.length - a.length)[0];
853
922
  }
854
923
  function executeMapFn(map, key, args) {
855
- if (!map || !key || !(key in map))
856
- return void 0;
924
+ if (!map || !key || !(key in map)) return void 0;
857
925
  const fnArgs = Array.isArray(args) ? args : [args];
858
926
  const resolver = map?.[key];
859
927
  return typeof resolver === "function" ? resolver?.(...fnArgs) : resolver;
@@ -892,7 +960,7 @@ const predefinedPathAliases = {
892
960
  ]
893
961
  },
894
962
  "<workspace_folder?>": {
895
- resolve: (opts) => getWorkspaceFolder(opts),
963
+ resolve: (opts) => getWorkspaceFolder({ ...opts, fallbackToGitRoot: false }),
896
964
  subpaths: [
897
965
  {
898
966
  to: "node_modules"
@@ -962,48 +1030,232 @@ function getFolderByPackageName(name, options) {
962
1030
  return info?.dirpath;
963
1031
  }
964
1032
 
965
- function getGitRootFolder(options) {
966
- const output = execa.execaSync(`git rev-parse --show-toplevel`, {
967
- ...options,
968
- reject: false
1033
+ const jsonSourceResolvers = {
1034
+ data: (json) => {
1035
+ return {
1036
+ text: () => JSON.stringify(json),
1037
+ data: () => json
1038
+ };
1039
+ },
1040
+ text: (text) => {
1041
+ return {
1042
+ text: () => text,
1043
+ data: () => JSON.parse(text)
1044
+ };
1045
+ },
1046
+ filepath: (filepath) => {
1047
+ const text = node_fs.readFileSync(filepath, "utf-8");
1048
+ return {
1049
+ text: () => text,
1050
+ data: () => JSON.parse(text)
1051
+ };
1052
+ }
1053
+ };
1054
+ function resolveJsonSource(source, as) {
1055
+ const [sourceType, sourceData] = Object.entries(source).find(([_, selected]) => selected !== void 0) ?? [];
1056
+ if (!sourceType || !(sourceType in jsonSourceResolvers) || !sourceData) {
1057
+ throw new Error("Invalid source data");
1058
+ }
1059
+ const sourceTypeResolvers = jsonSourceResolvers[sourceType](
1060
+ sourceData
1061
+ );
1062
+ const resolved = util.morph(sourceTypeResolvers, (key, v) => {
1063
+ try {
1064
+ const value = v();
1065
+ return !as || key === as ? [key, value] : [];
1066
+ } catch (e) {
1067
+ throw new Error(`Failed to resolve ${key} from ${sourceType}`);
1068
+ }
969
1069
  });
970
- if (!output.stdout) {
971
- console.warn(`Directory "${output.cwd}" is not in a git repository`);
972
- return void 0;
1070
+ if (as) {
1071
+ return resolved[as];
973
1072
  }
974
- return path__default$1.normalize(output.stdout);
1073
+ return resolved;
975
1074
  }
976
1075
 
977
- function modifyJSONCFileSync({
978
- edits,
979
- filepath,
980
- autoCommit = true
981
- }) {
982
- const jsoncContent = node_fs.readFileSync(filepath, "utf-8");
983
- const modifiers = Array.isArray(edits) ? edits : [edits];
984
- const editResult = modifiers.flatMap(
985
- (edit) => jsoncParser.modify(jsoncContent, edit.paths, edit.update, {
986
- formattingOptions: { tabSize: 0, insertSpaces: false }
1076
+ function resolveEditPath(path, options) {
1077
+ const { pathSeparator = "." } = {};
1078
+ const arr = toArray(path);
1079
+ return arr.map((path2) => {
1080
+ if (typeof path2 === "string") {
1081
+ return pathSeparator === false ? path2 : path2.split(pathSeparator);
1082
+ }
1083
+ return path2;
1084
+ }).flat();
1085
+ }
1086
+ function parseJSONCEdits(edits) {
1087
+ if (Array.isArray(edits)) {
1088
+ return edits.map(({ path, ...edit }) => ({
1089
+ path: resolveEditPath(path),
1090
+ ...edit
1091
+ }));
1092
+ }
1093
+ return Object.entries(edits).map(
1094
+ ([path, value]) => ({
1095
+ path: resolveEditPath(path),
1096
+ ...value
987
1097
  })
988
1098
  );
989
- const updatedFileContent = jsoncParser.applyEdits(jsoncContent, editResult);
990
- const commit = () => node_fs.writeFileSync(filepath, updatedFileContent);
991
- if (autoCommit) {
992
- commit();
993
- }
994
- return {
995
- updatedFileContent,
996
- commit
1099
+ }
1100
+ function modifyJSON({
1101
+ json,
1102
+ edits,
1103
+ defaultEditOptions
1104
+ }) {
1105
+ return checkResult(() => {
1106
+ const text = resolveJsonSource(json, "text");
1107
+ const jsoncEdits = parseJSONCEdits(edits);
1108
+ const editResult = jsoncEdits.flatMap(
1109
+ (edit) => jsoncParser.modify(text, edit.path, edit.value, {
1110
+ ...defaultEditOptions,
1111
+ ...edit.options
1112
+ })
1113
+ );
1114
+ const updated = jsoncParser.applyEdits(text, editResult);
1115
+ return resolveJsonSource({ text: updated });
1116
+ });
1117
+ }
1118
+ function modifyJSONFile(filepath, edits, options) {
1119
+ return checkResult(() => {
1120
+ const { autoCommit = true, defaultEditOptions } = options || {};
1121
+ const { data: json, error } = modifyJSON({
1122
+ json: { filepath },
1123
+ edits,
1124
+ defaultEditOptions
1125
+ });
1126
+ if (error) {
1127
+ throw error;
1128
+ }
1129
+ const commit = () => node_fs.writeFileSync(filepath, json.text);
1130
+ if (autoCommit) {
1131
+ commit();
1132
+ return json;
1133
+ }
1134
+ return {
1135
+ json,
1136
+ commit
1137
+ };
1138
+ });
1139
+ }
1140
+
1141
+ function isStorageValue(input) {
1142
+ return input === null || typeof input === "string" || typeof input === "number" || typeof input === "boolean" || typeof input === "object";
1143
+ }
1144
+
1145
+ const storage = unstorage.createStorage({ driver: defineMemoryDriver__default() });
1146
+ const tempFileSystem = defineFileSystemStorage({
1147
+ base: path.join(os__default.tmpdir(), ".package-manager")
1148
+ });
1149
+ function defineFileSystemEntries(definition) {
1150
+ const fileSystemEntries = Object.entries(definition).map(([k, v]) => {
1151
+ if (v instanceof Function) {
1152
+ const {
1153
+ file,
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
+ };
1171
+ }
1172
+ if (isStorageValue(v)) {
1173
+ return {
1174
+ key: k,
1175
+ value: JSON.stringify(v)
1176
+ };
1177
+ }
1178
+ return void 0;
1179
+ }).filter((v) => v !== void 0);
1180
+ const resolved = {
1181
+ definition,
1182
+ fileSystemEntries
997
1183
  };
1184
+ return resolved;
998
1185
  }
999
- const jsonc = (filepath) => {
1000
- return {
1001
- modify: (edits, options) => modifyJSONCFileSync({ edits, filepath, ...options })
1186
+ function defineFileSystemStorage(options) {
1187
+ const { base: root, initial, ...storageOptions } = options;
1188
+ let initialFileEntriesData = defineFileSystemEntries(initial ?? {});
1189
+ const storage2 = unstorage.createStorage({
1190
+ driver: defineFsLiteDriver__default({ base: root, ...storageOptions })
1191
+ });
1192
+ const fileStorage = {
1193
+ createFile: async (key, data) => {
1194
+ await storage2.setItem(key, data);
1195
+ return {
1196
+ key,
1197
+ filepath: path.join(root, key),
1198
+ get: async () => storage2.getItem(key),
1199
+ update: async (data2) => storage2.setItem(key, data2)
1200
+ };
1201
+ },
1202
+ async getFilePath(key) {
1203
+ return (await this.getFile(key)).filepath;
1204
+ },
1205
+ getFile: async (key) => {
1206
+ const storageData = await storage2.getItem(key);
1207
+ return {
1208
+ key,
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
+ },
1225
+ initializeFs: async (override) => {
1226
+ if (override) {
1227
+ initialFileEntriesData = defineFileSystemEntries(override);
1228
+ }
1229
+ await storage2.clear();
1230
+ return storage2.setItems(initialFileEntriesData.fileSystemEntries);
1231
+ },
1232
+ defineFileSystemEntries,
1233
+ removeAllFiles: storage2.clear,
1234
+ async deleteFileSystem() {
1235
+ await this.removeAllFiles();
1236
+ await storage2.unmount(root, true);
1237
+ await promises.rm(root, { recursive: true, force: true });
1238
+ },
1239
+ storage: storage2,
1240
+ meta: {
1241
+ fileEntriesData: initialFileEntriesData
1242
+ }
1002
1243
  };
1003
- };
1244
+ if (initial) {
1245
+ return {
1246
+ initialize: async () => {
1247
+ await fileStorage.initializeFs(initial);
1248
+ return fileStorage;
1249
+ }
1250
+ };
1251
+ }
1252
+ return fileStorage;
1253
+ }
1004
1254
 
1005
1255
  exports._dirname = _dirname;
1006
1256
  exports._filename = _filename;
1257
+ exports.defineFileSystemEntries = defineFileSystemEntries;
1258
+ exports.defineFileSystemStorage = defineFileSystemStorage;
1007
1259
  exports.definePackage = definePackage;
1008
1260
  exports.definePackageManagerClient = definePackageManagerClient;
1009
1261
  exports.definePathAliases = definePathAliases;
@@ -1018,6 +1270,7 @@ exports.findResolvedModulePath = findResolvedModulePath;
1018
1270
  exports.getAliasMap = getAliasMap;
1019
1271
  exports.getFolderByPackageName = getFolderByPackageName;
1020
1272
  exports.getGitRootFolder = getGitRootFolder;
1273
+ exports.getGlobalVersions = getGlobalVersions;
1021
1274
  exports.getPackageFolder = getPackageFolder;
1022
1275
  exports.getPath = getPath;
1023
1276
  exports.getWorkspaceFolder = getWorkspaceFolder;
@@ -1026,11 +1279,15 @@ exports.importer = importer;
1026
1279
  exports.isDependencyInPackageJson = isDependencyInPackageJson;
1027
1280
  exports.isPackageDependency = isPackageDependency;
1028
1281
  exports.isPackageModuleFound = isPackageModuleFound;
1029
- exports.jsonc = jsonc;
1282
+ exports.mapPackageManagers = mapPackageManagers;
1283
+ exports.modifyJSON = modifyJSON;
1284
+ exports.modifyJSONFile = modifyJSONFile;
1030
1285
  exports.packageManagerConfigs = packageManagerConfigs;
1031
1286
  exports.predefinedPathAliases = predefinedPathAliases;
1032
1287
  exports.project = project;
1033
1288
  exports.resolveModule = resolveModule;
1034
1289
  exports.resolveModulePath = resolveModulePath;
1035
1290
  exports.resolvePackageModulePath = resolvePackageModulePath;
1291
+ exports.storage = storage;
1292
+ exports.tempFileSystem = tempFileSystem;
1036
1293
  exports.workspace = workspace;