@ms-cloudpack/package-utilities 7.5.1 → 7.5.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.
@@ -4,6 +4,7 @@ import type { ResolveMapEntry } from '../types/ResolveMapEntry.js';
4
4
  /**
5
5
  * Given a linkedEntry, iterates through dependencies to ensure they are added to the packageMap,
6
6
  * preferring packageMap dependencies over linkedMap dependencies.
7
+ * Returns a list of duplicated packages that were added to the packageMap.
7
8
  */
8
9
  export declare function addLinkedEntryDependencies(options: {
9
10
  appMap: PackageMap;
@@ -12,5 +13,7 @@ export declare function addLinkedEntryDependencies(options: {
12
13
  resolutions?: PackageJson['resolutions'];
13
14
  }, context: {
14
15
  packages: PackageDefinitionsCache;
15
- }): Promise<void>;
16
+ }): Promise<{
17
+ duplicates: string[];
18
+ }>;
16
19
  //# sourceMappingURL=addLinkedEntryDependencies.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"addLinkedEntryDependencies.d.ts","sourceRoot":"","sources":["../../src/createResolveMap/addLinkedEntryDependencies.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAEvF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAGnE;;;GAGG;AACH,wBAAsB,0BAA0B,CAC9C,OAAO,EAAE;IACP,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,EAAE,UAAU,CAAC;IACpB,WAAW,EAAE,eAAe,CAAC;IAC7B,WAAW,CAAC,EAAE,WAAW,CAAC,aAAa,CAAC,CAAC;CAC1C,EACD,OAAO,EAAE;IACP,QAAQ,EAAE,uBAAuB,CAAC;CACnC,iBAuFF"}
1
+ {"version":3,"file":"addLinkedEntryDependencies.d.ts","sourceRoot":"","sources":["../../src/createResolveMap/addLinkedEntryDependencies.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAEvF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAGnE;;;;GAIG;AACH,wBAAsB,0BAA0B,CAC9C,OAAO,EAAE;IACP,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,EAAE,UAAU,CAAC;IACpB,WAAW,EAAE,eAAe,CAAC;IAC7B,WAAW,CAAC,EAAE,WAAW,CAAC,aAAa,CAAC,CAAC;CAC1C,EACD,OAAO,EAAE;IACP,QAAQ,EAAE,uBAAuB,CAAC;CACnC;;GA2FF"}
@@ -3,11 +3,13 @@ import { getDependencies } from '../getDependencies.js';
3
3
  /**
4
4
  * Given a linkedEntry, iterates through dependencies to ensure they are added to the packageMap,
5
5
  * preferring packageMap dependencies over linkedMap dependencies.
6
+ * Returns a list of duplicated packages that were added to the packageMap.
6
7
  */
7
8
  export async function addLinkedEntryDependencies(options, context) {
8
9
  const { appMap, linkMap, linkedEntry, resolutions } = options;
9
10
  const { packages } = context;
10
11
  const visitedEntryPaths = new Set(linkedEntry.path);
12
+ const duplicates = [];
11
13
  const entriesToVisit = [linkedEntry];
12
14
  function enqueue(newEntry) {
13
15
  if (!visitedEntryPaths.has(newEntry.path)) {
@@ -69,6 +71,7 @@ export async function addLinkedEntryDependencies(options, context) {
69
71
  appVersions[dependencyEntry.version] = dependencyEntry;
70
72
  entry.dependencies[dependencyName] = linkedDependencyVersion;
71
73
  dependencyEntry.requiredBy = { [`${name}@${version}`]: versionRequirement };
74
+ duplicates.push(`${dependencyName}@${dependencyEntry.version}`);
72
75
  // Recursive through the dependency's dependencies.
73
76
  enqueue(dependencyEntry);
74
77
  }
@@ -76,5 +79,6 @@ export async function addLinkedEntryDependencies(options, context) {
76
79
  }
77
80
  }
78
81
  }
82
+ return { duplicates };
79
83
  }
80
84
  //# sourceMappingURL=addLinkedEntryDependencies.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"addLinkedEntryDependencies.js","sourceRoot":"","sources":["../../src/createResolveMap/addLinkedEntryDependencies.ts"],"names":[],"mappings":"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","sourcesContent":["import type { PackageDefinitionsCache, PackageJson } from '@ms-cloudpack/common-types';\nimport { satisfies } from 'semver';\nimport type { PackageMap } from '../types/PackageMap.js';\nimport type { ResolveMapEntry } from '../types/ResolveMapEntry.js';\nimport { getDependencies } from '../getDependencies.js';\n\n/**\n * Given a linkedEntry, iterates through dependencies to ensure they are added to the packageMap,\n * preferring packageMap dependencies over linkedMap dependencies.\n */\nexport async function addLinkedEntryDependencies(\n options: {\n appMap: PackageMap;\n linkMap: PackageMap;\n linkedEntry: ResolveMapEntry;\n resolutions?: PackageJson['resolutions'];\n },\n context: {\n packages: PackageDefinitionsCache;\n },\n) {\n const { appMap, linkMap, linkedEntry, resolutions } = options;\n const { packages } = context;\n const visitedEntryPaths = new Set<string>(linkedEntry.path);\n const entriesToVisit: ResolveMapEntry[] = [linkedEntry];\n\n function enqueue(newEntry: ResolveMapEntry) {\n if (!visitedEntryPaths.has(newEntry.path)) {\n visitedEntryPaths.add(newEntry.path);\n entriesToVisit.push(newEntry);\n }\n }\n\n while (entriesToVisit.length) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- already checked the length\n const entry = entriesToVisit.pop()!;\n\n const { name, version, dependencies } = entry;\n\n const linkDefinition = await packages.get(entry.path);\n const versionRequirements = getDependencies(linkDefinition || {});\n\n // Iterate through the dependencies of the linked package.\n for (const [dependencyName, linkedDependencyVersion] of Object.entries(dependencies)) {\n const versionRequirement = versionRequirements[dependencyName];\n if (!versionRequirement) {\n continue;\n }\n\n const appVersions = appMap[dependencyName];\n\n if (!appVersions) {\n // The app does not have any version of this dependency, so we need to bring over the version\n // used by the linkedEntry.\n const dependencyEntry = linkMap[dependencyName]?.[linkedDependencyVersion];\n if (dependencyEntry) {\n appMap[dependencyName] = { [linkedDependencyVersion]: dependencyEntry };\n dependencyEntry.requiredBy = { [`${name}@${version}`]: versionRequirement };\n\n // Recurse through the dependency's dependencies.\n enqueue(dependencyEntry);\n }\n } else {\n // We have one or more versions of this dependency already. If a sufficient version\n // of the dependency is already in the appMap, we we just need to update the linkedEntry's\n // dependency and the dependency's requiredBy record for the parent.\n const appDependencyVersions = Object.values(appVersions);\n\n if (appDependencyVersions.length === 1 && !appDependencyVersions[0]?.isExternal) {\n continue;\n }\n\n // See if an existing version of the dependency satisfies the semver.\n const appDependencyEntry = appDependencyVersions.find(\n (e) =>\n // If the dependency is linked, use that.\n e.isLinked ||\n // If the dependency version is required as a resolution, use that.\n resolutions?.[dependencyName] ||\n // If the dependency satisfies the semver, use that.\n satisfies(e.version, versionRequirement),\n );\n\n if (appDependencyEntry) {\n // If the dependency satisfies the semver, use that!\n entry.dependencies[dependencyName] = appDependencyEntry.version;\n appDependencyEntry.requiredBy[`${name}@${version}`] = versionRequirement;\n\n enqueue(appDependencyEntry);\n } else {\n // We have at least one version of this dependency but nothing satisfies the requirement.\n // We need to introduce a duplicate. During the final pass, we will remove non-required deps.\n const dependencyEntry = Object.values(linkMap[dependencyName] || {}).find((e) =>\n satisfies(e.version, versionRequirement),\n );\n if (dependencyEntry) {\n appVersions[dependencyEntry.version] = dependencyEntry;\n entry.dependencies[dependencyName] = linkedDependencyVersion;\n dependencyEntry.requiredBy = { [`${name}@${version}`]: versionRequirement };\n // Recursive through the dependency's dependencies.\n enqueue(dependencyEntry);\n }\n }\n }\n }\n }\n}\n"]}
1
+ {"version":3,"file":"addLinkedEntryDependencies.js","sourceRoot":"","sources":["../../src/createResolveMap/addLinkedEntryDependencies.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAGnC,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,OAKC,EACD,OAEC;IAED,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;IAC9D,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IAC7B,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAS,WAAW,CAAC,IAAI,CAAC,CAAC;IAC5D,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,MAAM,cAAc,GAAsB,CAAC,WAAW,CAAC,CAAC;IAExD,SAAS,OAAO,CAAC,QAAyB;QACxC,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1C,iBAAiB,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YACrC,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IAED,OAAO,cAAc,CAAC,MAAM,EAAE,CAAC;QAC7B,kGAAkG;QAClG,MAAM,KAAK,GAAG,cAAc,CAAC,GAAG,EAAG,CAAC;QAEpC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,KAAK,CAAC;QAE9C,MAAM,cAAc,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACtD,MAAM,mBAAmB,GAAG,eAAe,CAAC,cAAc,IAAI,EAAE,CAAC,CAAC;QAElE,0DAA0D;QAC1D,KAAK,MAAM,CAAC,cAAc,EAAE,uBAAuB,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;YACrF,MAAM,kBAAkB,GAAG,mBAAmB,CAAC,cAAc,CAAC,CAAC;YAC/D,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBACxB,SAAS;YACX,CAAC;YAED,MAAM,WAAW,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC;YAE3C,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,6FAA6F;gBAC7F,2BAA2B;gBAC3B,MAAM,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC,uBAAuB,CAAC,CAAC;gBAC3E,IAAI,eAAe,EAAE,CAAC;oBACpB,MAAM,CAAC,cAAc,CAAC,GAAG,EAAE,CAAC,uBAAuB,CAAC,EAAE,eAAe,EAAE,CAAC;oBACxE,eAAe,CAAC,UAAU,GAAG,EAAE,CAAC,GAAG,IAAI,IAAI,OAAO,EAAE,CAAC,EAAE,kBAAkB,EAAE,CAAC;oBAE5E,iDAAiD;oBACjD,OAAO,CAAC,eAAe,CAAC,CAAC;gBAC3B,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,mFAAmF;gBACnF,0FAA0F;gBAC1F,oEAAoE;gBACpE,MAAM,qBAAqB,GAAG,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;gBAEzD,IAAI,qBAAqB,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC;oBAChF,SAAS;gBACX,CAAC;gBAED,qEAAqE;gBACrE,MAAM,kBAAkB,GAAG,qBAAqB,CAAC,IAAI,CACnD,CAAC,CAAC,EAAE,EAAE;gBACJ,yCAAyC;gBACzC,CAAC,CAAC,QAAQ;oBACV,mEAAmE;oBACnE,WAAW,EAAE,CAAC,cAAc,CAAC;oBAC7B,oDAAoD;oBACpD,SAAS,CAAC,CAAC,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAC3C,CAAC;gBAEF,IAAI,kBAAkB,EAAE,CAAC;oBACvB,oDAAoD;oBACpD,KAAK,CAAC,YAAY,CAAC,cAAc,CAAC,GAAG,kBAAkB,CAAC,OAAO,CAAC;oBAChE,kBAAkB,CAAC,UAAU,CAAC,GAAG,IAAI,IAAI,OAAO,EAAE,CAAC,GAAG,kBAAkB,CAAC;oBAEzE,OAAO,CAAC,kBAAkB,CAAC,CAAC;gBAC9B,CAAC;qBAAM,CAAC;oBACN,yFAAyF;oBACzF,6FAA6F;oBAC7F,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAC9E,SAAS,CAAC,CAAC,CAAC,OAAO,EAAE,kBAAkB,CAAC,CACzC,CAAC;oBACF,IAAI,eAAe,EAAE,CAAC;wBACpB,WAAW,CAAC,eAAe,CAAC,OAAO,CAAC,GAAG,eAAe,CAAC;wBACvD,KAAK,CAAC,YAAY,CAAC,cAAc,CAAC,GAAG,uBAAuB,CAAC;wBAC7D,eAAe,CAAC,UAAU,GAAG,EAAE,CAAC,GAAG,IAAI,IAAI,OAAO,EAAE,CAAC,EAAE,kBAAkB,EAAE,CAAC;wBAC5E,UAAU,CAAC,IAAI,CAAC,GAAG,cAAc,IAAI,eAAe,CAAC,OAAO,EAAE,CAAC,CAAC;wBAChE,mDAAmD;wBACnD,OAAO,CAAC,eAAe,CAAC,CAAC;oBAC3B,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,EAAE,UAAU,EAAE,CAAC;AACxB,CAAC","sourcesContent":["import type { PackageDefinitionsCache, PackageJson } from '@ms-cloudpack/common-types';\nimport { satisfies } from 'semver';\nimport type { PackageMap } from '../types/PackageMap.js';\nimport type { ResolveMapEntry } from '../types/ResolveMapEntry.js';\nimport { getDependencies } from '../getDependencies.js';\n\n/**\n * Given a linkedEntry, iterates through dependencies to ensure they are added to the packageMap,\n * preferring packageMap dependencies over linkedMap dependencies.\n * Returns a list of duplicated packages that were added to the packageMap.\n */\nexport async function addLinkedEntryDependencies(\n options: {\n appMap: PackageMap;\n linkMap: PackageMap;\n linkedEntry: ResolveMapEntry;\n resolutions?: PackageJson['resolutions'];\n },\n context: {\n packages: PackageDefinitionsCache;\n },\n) {\n const { appMap, linkMap, linkedEntry, resolutions } = options;\n const { packages } = context;\n const visitedEntryPaths = new Set<string>(linkedEntry.path);\n const duplicates: string[] = [];\n const entriesToVisit: ResolveMapEntry[] = [linkedEntry];\n\n function enqueue(newEntry: ResolveMapEntry) {\n if (!visitedEntryPaths.has(newEntry.path)) {\n visitedEntryPaths.add(newEntry.path);\n entriesToVisit.push(newEntry);\n }\n }\n\n while (entriesToVisit.length) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- already checked the length\n const entry = entriesToVisit.pop()!;\n\n const { name, version, dependencies } = entry;\n\n const linkDefinition = await packages.get(entry.path);\n const versionRequirements = getDependencies(linkDefinition || {});\n\n // Iterate through the dependencies of the linked package.\n for (const [dependencyName, linkedDependencyVersion] of Object.entries(dependencies)) {\n const versionRequirement = versionRequirements[dependencyName];\n if (!versionRequirement) {\n continue;\n }\n\n const appVersions = appMap[dependencyName];\n\n if (!appVersions) {\n // The app does not have any version of this dependency, so we need to bring over the version\n // used by the linkedEntry.\n const dependencyEntry = linkMap[dependencyName]?.[linkedDependencyVersion];\n if (dependencyEntry) {\n appMap[dependencyName] = { [linkedDependencyVersion]: dependencyEntry };\n dependencyEntry.requiredBy = { [`${name}@${version}`]: versionRequirement };\n\n // Recurse through the dependency's dependencies.\n enqueue(dependencyEntry);\n }\n } else {\n // We have one or more versions of this dependency already. If a sufficient version\n // of the dependency is already in the appMap, we we just need to update the linkedEntry's\n // dependency and the dependency's requiredBy record for the parent.\n const appDependencyVersions = Object.values(appVersions);\n\n if (appDependencyVersions.length === 1 && !appDependencyVersions[0]?.isExternal) {\n continue;\n }\n\n // See if an existing version of the dependency satisfies the semver.\n const appDependencyEntry = appDependencyVersions.find(\n (e) =>\n // If the dependency is linked, use that.\n e.isLinked ||\n // If the dependency version is required as a resolution, use that.\n resolutions?.[dependencyName] ||\n // If the dependency satisfies the semver, use that.\n satisfies(e.version, versionRequirement),\n );\n\n if (appDependencyEntry) {\n // If the dependency satisfies the semver, use that!\n entry.dependencies[dependencyName] = appDependencyEntry.version;\n appDependencyEntry.requiredBy[`${name}@${version}`] = versionRequirement;\n\n enqueue(appDependencyEntry);\n } else {\n // We have at least one version of this dependency but nothing satisfies the requirement.\n // We need to introduce a duplicate. During the final pass, we will remove non-required deps.\n const dependencyEntry = Object.values(linkMap[dependencyName] || {}).find((e) =>\n satisfies(e.version, versionRequirement),\n );\n if (dependencyEntry) {\n appVersions[dependencyEntry.version] = dependencyEntry;\n entry.dependencies[dependencyName] = linkedDependencyVersion;\n dependencyEntry.requiredBy = { [`${name}@${version}`]: versionRequirement };\n duplicates.push(`${dependencyName}@${dependencyEntry.version}`);\n // Recursive through the dependency's dependencies.\n enqueue(dependencyEntry);\n }\n }\n }\n }\n }\n\n return { duplicates };\n}\n"]}
@@ -0,0 +1,10 @@
1
+ import type { PackageMap } from '../types/PackageMap.js';
2
+ /**
3
+ * Deduplicates linked packages by removing all but the highest version,
4
+ * that satisfies the semver requirements of all the requiredBy entries.
5
+ */
6
+ export declare function dedupeLinkedPackages({ appMap, allDuplicates }: {
7
+ appMap: PackageMap;
8
+ allDuplicates: Set<string>;
9
+ }): void;
10
+ //# sourceMappingURL=dedupeLinkedPackages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dedupeLinkedPackages.d.ts","sourceRoot":"","sources":["../../src/createResolveMap/dedupeLinkedPackages.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAKzD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,EAAE;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CAAE,QA0DjH"}
@@ -0,0 +1,55 @@
1
+ import { satisfies, compare as semverCompare } from 'semver';
2
+ import { parseRequiredBy } from './parseRequiredBy.js';
3
+ import { detachEntry } from './detachEntry.js';
4
+ /**
5
+ * Deduplicates linked packages by removing all but the highest version,
6
+ * that satisfies the semver requirements of all the requiredBy entries.
7
+ */
8
+ export function dedupeLinkedPackages({ appMap, allDuplicates }) {
9
+ console.debug(`The following packages were duplicated by linking:\n ${Array.from(allDuplicates).join(', ')}`);
10
+ for (const duplicate of allDuplicates) {
11
+ const packageName = parseRequiredBy(duplicate).name;
12
+ const entries = appMap[packageName] || {};
13
+ // Sanity check to ensure that it is a duplicate.
14
+ if (Object.keys(entries).length <= 1) {
15
+ continue;
16
+ }
17
+ const availableVersions = Object.keys(entries);
18
+ const versionRequirements = new Set();
19
+ // Find if any of the duplicate entries satisfy the semver requirement of all the requiredBy entries.
20
+ const requiredBy = {};
21
+ for (const entry of Object.values(entries)) {
22
+ for (const [requiredById, range] of Object.entries(entry.requiredBy)) {
23
+ requiredBy[requiredById] = range;
24
+ // We only care about satisfying version requirements that are already satisfied.
25
+ if (satisfies(entry.version, range)) {
26
+ versionRequirements.add(range);
27
+ }
28
+ }
29
+ }
30
+ const satisfiedVersions = availableVersions
31
+ .filter((v) => [...versionRequirements].every((range) => satisfies(v, range)))
32
+ .sort(semverCompare);
33
+ if (satisfiedVersions.length === 0) {
34
+ console.debug(`Could not find a version of "${packageName}" that satisfies the semver requirements of all the requiredBy entries.`);
35
+ continue;
36
+ }
37
+ // Select the highest version that satisfies the semver requirements of all the requiredBy entries.
38
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
39
+ const highestSatisfiedVersion = satisfiedVersions.pop();
40
+ entries[highestSatisfiedVersion].requiredBy = requiredBy;
41
+ for (const version of availableVersions) {
42
+ if (version == highestSatisfiedVersion) {
43
+ continue;
44
+ }
45
+ detachEntry({ appMap, entry: entries[version] });
46
+ delete appMap[packageName][version];
47
+ }
48
+ for (const requiredById of Object.keys(requiredBy)) {
49
+ const { name: requiredByName, version: requiredByVersion } = parseRequiredBy(requiredById);
50
+ appMap[requiredByName][requiredByVersion].dependencies[packageName] = highestSatisfiedVersion;
51
+ }
52
+ console.debug(`Removed versions of "${packageName}" except for "${highestSatisfiedVersion}".`);
53
+ }
54
+ }
55
+ //# sourceMappingURL=dedupeLinkedPackages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dedupeLinkedPackages.js","sourceRoot":"","sources":["../../src/createResolveMap/dedupeLinkedPackages.ts"],"names":[],"mappings":"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","sourcesContent":["import { satisfies, compare as semverCompare } from 'semver';\nimport type { PackageMap } from '../types/PackageMap.js';\nimport type { ResolveMapEntry } from '../types/ResolveMapEntry.js';\nimport { parseRequiredBy } from './parseRequiredBy.js';\nimport { detachEntry } from './detachEntry.js';\n\n/**\n * Deduplicates linked packages by removing all but the highest version,\n * that satisfies the semver requirements of all the requiredBy entries.\n */\nexport function dedupeLinkedPackages({ appMap, allDuplicates }: { appMap: PackageMap; allDuplicates: Set<string> }) {\n console.debug(`The following packages were duplicated by linking:\\n ${Array.from(allDuplicates).join(', ')}`);\n for (const duplicate of allDuplicates) {\n const packageName = parseRequiredBy(duplicate).name;\n\n const entries = appMap[packageName] || {};\n\n // Sanity check to ensure that it is a duplicate.\n if (Object.keys(entries).length <= 1) {\n continue;\n }\n\n const availableVersions = Object.keys(entries);\n\n const versionRequirements = new Set<string>();\n // Find if any of the duplicate entries satisfy the semver requirement of all the requiredBy entries.\n const requiredBy: ResolveMapEntry['requiredBy'] = {};\n for (const entry of Object.values(entries)) {\n for (const [requiredById, range] of Object.entries(entry.requiredBy) as [`${string}@${string}`, string][]) {\n requiredBy[requiredById] = range;\n // We only care about satisfying version requirements that are already satisfied.\n if (satisfies(entry.version, range)) {\n versionRequirements.add(range);\n }\n }\n }\n\n const satisfiedVersions = availableVersions\n .filter((v) => [...versionRequirements].every((range) => satisfies(v, range)))\n .sort(semverCompare);\n\n if (satisfiedVersions.length === 0) {\n console.debug(\n `Could not find a version of \"${packageName}\" that satisfies the semver requirements of all the requiredBy entries.`,\n );\n continue;\n }\n\n // Select the highest version that satisfies the semver requirements of all the requiredBy entries.\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const highestSatisfiedVersion = satisfiedVersions.pop()!;\n entries[highestSatisfiedVersion].requiredBy = requiredBy;\n\n for (const version of availableVersions) {\n if (version == highestSatisfiedVersion) {\n continue;\n }\n detachEntry({ appMap, entry: entries[version] });\n delete appMap[packageName][version];\n }\n\n for (const requiredById of Object.keys(requiredBy)) {\n const { name: requiredByName, version: requiredByVersion } = parseRequiredBy(requiredById);\n appMap[requiredByName][requiredByVersion].dependencies[packageName] = highestSatisfiedVersion;\n }\n\n console.debug(`Removed versions of \"${packageName}\" except for \"${highestSatisfiedVersion}\".`);\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"findPackagesFromPath.d.ts","sourceRoot":"","sources":["../../src/createResolveMap/findPackagesFromPath.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAuC,MAAM,4BAA4B,CAAC;AAM/G,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAQzD;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE;IACP;;OAEG;IACH,WAAW,EAAE,MAAM,EAAE,CAAC;IAEtB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,EACD,OAAO,EAAE;IACP;;OAEG;IACH,QAAQ,EAAE,uBAAuB,CAAC;CACnC,GACA,OAAO,CAAC,UAAU,CAAC,CAiDrB"}
1
+ {"version":3,"file":"findPackagesFromPath.d.ts","sourceRoot":"","sources":["../../src/createResolveMap/findPackagesFromPath.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAuC,MAAM,4BAA4B,CAAC;AAM/G,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAQzD;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE;IACP;;OAEG;IACH,WAAW,EAAE,MAAM,EAAE,CAAC;IAEtB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,EACD,OAAO,EAAE;IACP;;OAEG;IACH,QAAQ,EAAE,uBAAuB,CAAC;CACnC,GACA,OAAO,CAAC,UAAU,CAAC,CAqDrB"}
@@ -14,6 +14,7 @@ export async function findPackagesFromPath(options, context) {
14
14
  const { searchPaths, discoverPackages } = options;
15
15
  const packageMap = {};
16
16
  const visitedPaths = new Set();
17
+ const realPathCache = {};
17
18
  for (const searchPath of searchPaths) {
18
19
  if (!(await isFolder(searchPath))) {
19
20
  throw new Error(`Path ${searchPath} is not a folder.\n\nMake sure the path exists and try again.`);
@@ -39,7 +40,7 @@ export async function findPackagesFromPath(options, context) {
39
40
  // be the same as a dependency that's forced with `resolutions` to a version violating semver.
40
41
  if (!visitedPaths.has(packagePath)) {
41
42
  visitedPaths.add(packagePath);
42
- const dependencyPaths = await visitPackage({ packagePath, packageMap, rootPath, importerContext }, context);
43
+ const dependencyPaths = await visitPackage({ packagePath, packageMap, rootPath, importerContext, realPathCache }, context);
43
44
  for (const dependencyPath of dependencyPaths) {
44
45
  // Let's avoid pushing tons of things into the work queue that we'll be skipping later.
45
46
  if (!visitedPaths.has(dependencyPath.packagePath)) {
@@ -56,7 +57,7 @@ export async function findPackagesFromPath(options, context) {
56
57
  * Returns a list of additional dependency paths to visit.
57
58
  */
58
59
  async function visitPackage(options, context) {
59
- const { packagePath, packageMap, rootPath, importerContext } = options;
60
+ const { packagePath, packageMap, rootPath, importerContext, realPathCache } = options;
60
61
  const { packages } = context;
61
62
  const packageDefinition = await packages.get(packagePath, { importerContext });
62
63
  if (!packageDefinition) {
@@ -83,7 +84,7 @@ async function visitPackage(options, context) {
83
84
  importedName: dependencyName,
84
85
  versionRequirement,
85
86
  };
86
- const dependencyPackage = await findPackage({ dependencyName, startPath: packagePath, rootPath, importerContext: depImporterContext }, context);
87
+ const dependencyPackage = await findPackage({ dependencyName, startPath: packagePath, rootPath, importerContext: depImporterContext, realPathCache }, context);
87
88
  if (!dependencyPackage) {
88
89
  if (packageDefinition.peerDependencies?.[dependencyName]) {
89
90
  // Ignore missing peer dependencies
@@ -1 +1 @@
1
- {"version":3,"file":"findPackagesFromPath.js","sourceRoot":"","sources":["../../src/createResolveMap/findPackagesFromPath.ts"],"names":[],"mappings":"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","sourcesContent":["import type { PackageDefinitionsCache, PackageImporterContext, PackageJson } from '@ms-cloudpack/common-types';\nimport { isFolder } from '@ms-cloudpack/path-utilities';\nimport glob from 'fast-glob';\nimport path from 'path';\nimport { findPackage } from '../findPackage.js';\nimport { isExternalPackage } from '../isExternalPackage.js';\nimport type { PackageMap } from '../types/PackageMap.js';\nimport type { ResolveMapEntry } from '../types/ResolveMapEntry.js';\nimport { getDependencies } from '../getDependencies.js';\nimport { findProjectRoot } from '../findProjectRoot.js';\nimport { bulletedList } from '@ms-cloudpack/task-reporter';\n\ntype PackagePathInfo = { packagePath: string; importerContext?: PackageImporterContext };\n\n/**\n * Find all packages from a given path. We do this by walking the dependency tree\n * of the app to build a map of all packages and their dependencies.\n */\nexport async function findPackagesFromPath(\n options: {\n /**\n * Paths to search for package.json files and traverse their dependencies to build a PackageMap.\n */\n searchPaths: string[];\n\n /**\n * Where to stop looking for packages (mainly used for testing).\n * If not specified, will look for the project/git root of the first path in the paths array.\n */\n rootPath?: string;\n\n /**\n * If true will glob for all package.json files in the path and add them to the map.\n */\n discoverPackages?: boolean;\n },\n context: {\n /**\n * Package cache.\n */\n packages: PackageDefinitionsCache;\n },\n): Promise<PackageMap> {\n const { searchPaths, discoverPackages } = options;\n const packageMap: PackageMap = {};\n const visitedPaths = new Set<string>();\n\n for (const searchPath of searchPaths) {\n if (!(await isFolder(searchPath))) {\n throw new Error(`Path ${searchPath} is not a folder.\\n\\nMake sure the path exists and try again.`);\n }\n\n const rootPath = options.rootPath || findProjectRoot(searchPath, { noPackageRoot: true });\n\n let pathsToVisit: PackagePathInfo[];\n\n if (discoverPackages) {\n const packagePaths = await glob('**/package.json', { cwd: searchPath, ignore: ['**/node_modules/**'] });\n\n pathsToVisit = packagePaths.map((p) => ({ packagePath: path.dirname(path.join(searchPath, p)) }));\n } else {\n pathsToVisit = [{ packagePath: searchPath }];\n }\n\n while (pathsToVisit.length) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- already checked length\n const { packagePath, importerContext } = pathsToVisit.shift()!;\n\n // There's a very slight possibility (not yet observed even in large repos) that both semver\n // and non-semver dependencies could resolve to the same package name and version and therefore\n // be installed at the same path. (If the non-semver dependency was encountered first, the\n // version and possibly name in the package definition would have been transformed to match by\n // getNonSemverTransform.) It would be possible to detect this case if needed, but for now we're\n // not going to bother because it's so rare/theoretical and the effect in practice will probably\n // be the same as a dependency that's forced with `resolutions` to a version violating semver.\n if (!visitedPaths.has(packagePath)) {\n visitedPaths.add(packagePath);\n\n const dependencyPaths = await visitPackage({ packagePath, packageMap, rootPath, importerContext }, context);\n\n for (const dependencyPath of dependencyPaths) {\n // Let's avoid pushing tons of things into the work queue that we'll be skipping later.\n if (!visitedPaths.has(dependencyPath.packagePath)) {\n pathsToVisit.push(dependencyPath);\n }\n }\n }\n }\n }\n\n return packageMap;\n}\n\n/**\n * Visit a package path, and add entries for the package and its dependencies to `packageMap`.\n * Returns a list of additional dependency paths to visit.\n */\nasync function visitPackage(\n options: PackagePathInfo & {\n packageMap: PackageMap;\n rootPath: string | undefined;\n },\n context: Parameters<typeof findPackagesFromPath>[1],\n) {\n const { packagePath, packageMap, rootPath, importerContext } = options;\n const { packages } = context;\n\n const packageDefinition = await packages.get(packagePath, { importerContext });\n if (!packageDefinition) {\n throw new Error(\n `Could not find package definition at \"${packagePath}\".\\n\\n` +\n `Make sure the package.json file exists and try again.\\n`,\n );\n }\n if (!(packageDefinition.name && packageDefinition.version)) {\n return [];\n }\n\n const { name, version } = packageDefinition;\n const entry = ensurePackageEntry({\n packageName: importerContext?.importedName || name,\n packagePath: packagePath,\n packageMap,\n definition: packageDefinition,\n });\n\n // Add all dependencies to the list of paths to visit.\n const dependencies = getDependencies(packageDefinition) as Record<string, string>;\n\n const dependencyPaths: PackagePathInfo[] = [];\n\n for (const [dependencyName, versionRequirement] of Object.entries(dependencies)) {\n const depImporterContext: PackageImporterContext = {\n parentName: name,\n parentVersion: version,\n importedName: dependencyName,\n versionRequirement,\n };\n\n const dependencyPackage = await findPackage(\n { dependencyName, startPath: packagePath, rootPath, importerContext: depImporterContext },\n context,\n );\n if (!dependencyPackage) {\n if (packageDefinition.peerDependencies?.[dependencyName]) {\n // Ignore missing peer dependencies\n continue;\n }\n\n throw new Error(\n [\n `A dependency could not be found:`,\n bulletedList([\n `Dependency: ${dependencyName} (Required: ${versionRequirement})`,\n `Required by: ${packagePath}`,\n ]),\n ``,\n `Make sure the dependency is installed and try again.`,\n ].join('\\n'),\n );\n }\n\n const { packagePath: dependencyPath, definition: dependencyDefinition } = dependencyPackage;\n\n if (!(dependencyDefinition.name && dependencyDefinition.version)) {\n throw new Error(`\"${dependencyPath}/package.json\" is missing a name or version.`);\n }\n\n const dependencyEntry = ensurePackageEntry({\n packagePath: dependencyPath,\n packageName: dependencyName,\n packageMap,\n definition: dependencyDefinition,\n });\n\n entry.dependencies[dependencyName] = dependencyDefinition.version;\n dependencyEntry.requiredBy[`${name}@${version}`] = versionRequirement;\n\n dependencyPaths.push({\n packagePath: dependencyPath,\n importerContext: depImporterContext,\n });\n }\n\n return dependencyPaths;\n}\n\n/**\n * If `packageMap` doesn't already have an entry for this package name and version, create one\n * and add it to `packageMap`. Returns the entry.\n */\nfunction ensurePackageEntry(options: {\n packagePath: string;\n packageName: string;\n packageMap: PackageMap;\n definition: PackageJson;\n}): ResolveMapEntry {\n const { packagePath = '', packageName: name, packageMap, definition } = options;\n // the caller verified that these are set\n const { version } = definition as Required<PackageJson>;\n\n packageMap[name] ??= {};\n\n let entry = packageMap[name][version];\n if (!entry) {\n entry = packageMap[name][version] = {\n name,\n version,\n path: packagePath,\n dependencies: {},\n requiredBy: {},\n };\n\n if (isExternalPackage(packagePath)) {\n entry.isExternal = true;\n }\n }\n\n return entry;\n}\n"]}
1
+ {"version":3,"file":"findPackagesFromPath.js","sourceRoot":"","sources":["../../src/createResolveMap/findPackagesFromPath.ts"],"names":[],"mappings":"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","sourcesContent":["import type { PackageDefinitionsCache, PackageImporterContext, PackageJson } from '@ms-cloudpack/common-types';\nimport { isFolder } from '@ms-cloudpack/path-utilities';\nimport glob from 'fast-glob';\nimport path from 'path';\nimport { findPackage } from '../findPackage.js';\nimport { isExternalPackage } from '../isExternalPackage.js';\nimport type { PackageMap } from '../types/PackageMap.js';\nimport type { ResolveMapEntry } from '../types/ResolveMapEntry.js';\nimport { getDependencies } from '../getDependencies.js';\nimport { findProjectRoot } from '../findProjectRoot.js';\nimport { bulletedList } from '@ms-cloudpack/task-reporter';\n\ntype PackagePathInfo = { packagePath: string; importerContext?: PackageImporterContext };\n\n/**\n * Find all packages from a given path. We do this by walking the dependency tree\n * of the app to build a map of all packages and their dependencies.\n */\nexport async function findPackagesFromPath(\n options: {\n /**\n * Paths to search for package.json files and traverse their dependencies to build a PackageMap.\n */\n searchPaths: string[];\n\n /**\n * Where to stop looking for packages (mainly used for testing).\n * If not specified, will look for the project/git root of the first path in the paths array.\n */\n rootPath?: string;\n\n /**\n * If true will glob for all package.json files in the path and add them to the map.\n */\n discoverPackages?: boolean;\n },\n context: {\n /**\n * Package cache.\n */\n packages: PackageDefinitionsCache;\n },\n): Promise<PackageMap> {\n const { searchPaths, discoverPackages } = options;\n const packageMap: PackageMap = {};\n const visitedPaths = new Set<string>();\n const realPathCache: Record<string, string | undefined> = {};\n\n for (const searchPath of searchPaths) {\n if (!(await isFolder(searchPath))) {\n throw new Error(`Path ${searchPath} is not a folder.\\n\\nMake sure the path exists and try again.`);\n }\n\n const rootPath = options.rootPath || findProjectRoot(searchPath, { noPackageRoot: true });\n\n let pathsToVisit: PackagePathInfo[];\n\n if (discoverPackages) {\n const packagePaths = await glob('**/package.json', { cwd: searchPath, ignore: ['**/node_modules/**'] });\n\n pathsToVisit = packagePaths.map((p) => ({ packagePath: path.dirname(path.join(searchPath, p)) }));\n } else {\n pathsToVisit = [{ packagePath: searchPath }];\n }\n\n while (pathsToVisit.length) {\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- already checked length\n const { packagePath, importerContext } = pathsToVisit.shift()!;\n\n // There's a very slight possibility (not yet observed even in large repos) that both semver\n // and non-semver dependencies could resolve to the same package name and version and therefore\n // be installed at the same path. (If the non-semver dependency was encountered first, the\n // version and possibly name in the package definition would have been transformed to match by\n // getNonSemverTransform.) It would be possible to detect this case if needed, but for now we're\n // not going to bother because it's so rare/theoretical and the effect in practice will probably\n // be the same as a dependency that's forced with `resolutions` to a version violating semver.\n if (!visitedPaths.has(packagePath)) {\n visitedPaths.add(packagePath);\n\n const dependencyPaths = await visitPackage(\n { packagePath, packageMap, rootPath, importerContext, realPathCache },\n context,\n );\n\n for (const dependencyPath of dependencyPaths) {\n // Let's avoid pushing tons of things into the work queue that we'll be skipping later.\n if (!visitedPaths.has(dependencyPath.packagePath)) {\n pathsToVisit.push(dependencyPath);\n }\n }\n }\n }\n }\n\n return packageMap;\n}\n\n/**\n * Visit a package path, and add entries for the package and its dependencies to `packageMap`.\n * Returns a list of additional dependency paths to visit.\n */\nasync function visitPackage(\n options: PackagePathInfo & {\n packageMap: PackageMap;\n rootPath: string | undefined;\n realPathCache?: Record<string, string | undefined>;\n },\n context: Parameters<typeof findPackagesFromPath>[1],\n) {\n const { packagePath, packageMap, rootPath, importerContext, realPathCache } = options;\n const { packages } = context;\n\n const packageDefinition = await packages.get(packagePath, { importerContext });\n if (!packageDefinition) {\n throw new Error(\n `Could not find package definition at \"${packagePath}\".\\n\\n` +\n `Make sure the package.json file exists and try again.\\n`,\n );\n }\n if (!(packageDefinition.name && packageDefinition.version)) {\n return [];\n }\n\n const { name, version } = packageDefinition;\n const entry = ensurePackageEntry({\n packageName: importerContext?.importedName || name,\n packagePath: packagePath,\n packageMap,\n definition: packageDefinition,\n });\n\n // Add all dependencies to the list of paths to visit.\n const dependencies = getDependencies(packageDefinition) as Record<string, string>;\n\n const dependencyPaths: PackagePathInfo[] = [];\n\n for (const [dependencyName, versionRequirement] of Object.entries(dependencies)) {\n const depImporterContext: PackageImporterContext = {\n parentName: name,\n parentVersion: version,\n importedName: dependencyName,\n versionRequirement,\n };\n\n const dependencyPackage = await findPackage(\n { dependencyName, startPath: packagePath, rootPath, importerContext: depImporterContext, realPathCache },\n context,\n );\n if (!dependencyPackage) {\n if (packageDefinition.peerDependencies?.[dependencyName]) {\n // Ignore missing peer dependencies\n continue;\n }\n\n throw new Error(\n [\n `A dependency could not be found:`,\n bulletedList([\n `Dependency: ${dependencyName} (Required: ${versionRequirement})`,\n `Required by: ${packagePath}`,\n ]),\n ``,\n `Make sure the dependency is installed and try again.`,\n ].join('\\n'),\n );\n }\n\n const { packagePath: dependencyPath, definition: dependencyDefinition } = dependencyPackage;\n\n if (!(dependencyDefinition.name && dependencyDefinition.version)) {\n throw new Error(`\"${dependencyPath}/package.json\" is missing a name or version.`);\n }\n\n const dependencyEntry = ensurePackageEntry({\n packagePath: dependencyPath,\n packageName: dependencyName,\n packageMap,\n definition: dependencyDefinition,\n });\n\n entry.dependencies[dependencyName] = dependencyDefinition.version;\n dependencyEntry.requiredBy[`${name}@${version}`] = versionRequirement;\n\n dependencyPaths.push({\n packagePath: dependencyPath,\n importerContext: depImporterContext,\n });\n }\n\n return dependencyPaths;\n}\n\n/**\n * If `packageMap` doesn't already have an entry for this package name and version, create one\n * and add it to `packageMap`. Returns the entry.\n */\nfunction ensurePackageEntry(options: {\n packagePath: string;\n packageName: string;\n packageMap: PackageMap;\n definition: PackageJson;\n}): ResolveMapEntry {\n const { packagePath = '', packageName: name, packageMap, definition } = options;\n // the caller verified that these are set\n const { version } = definition as Required<PackageJson>;\n\n packageMap[name] ??= {};\n\n let entry = packageMap[name][version];\n if (!entry) {\n entry = packageMap[name][version] = {\n name,\n version,\n path: packagePath,\n dependencies: {},\n requiredBy: {},\n };\n\n if (isExternalPackage(packagePath)) {\n entry.isExternal = true;\n }\n }\n\n return entry;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"linkPath.d.ts","sourceRoot":"","sources":["../../src/createResolveMap/linkPath.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAOzD,OAAO,KAAK,EAAE,uBAAuB,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAEvF;;GAEG;AACH,wBAAsB,QAAQ,CAC5B,OAAO,EAAE;IACP,UAAU,EAAE,UAAU,CAAC;IACvB,MAAM,EAAE,UAAU,CAAC;IACnB,cAAc,CAAC,EAAE,WAAW,CAAC;CAC9B,EACD,OAAO,EAAE;IACP,QAAQ,EAAE,uBAAuB,CAAC;CACnC,iBA4FF"}
1
+ {"version":3,"file":"linkPath.d.ts","sourceRoot":"","sources":["../../src/createResolveMap/linkPath.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAOzD,OAAO,KAAK,EAAE,uBAAuB,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAGvF;;GAEG;AACH,wBAAsB,QAAQ,CAC5B,OAAO,EAAE;IACP,UAAU,EAAE,UAAU,CAAC;IACvB,MAAM,EAAE,UAAU,CAAC;IACnB,cAAc,CAAC,EAAE,WAAW,CAAC;CAC9B,EACD,OAAO,EAAE;IACP,QAAQ,EAAE,uBAAuB,CAAC;CACnC,iBAsGF"}
@@ -3,6 +3,7 @@ import { detachEntry } from './detachEntry.js';
3
3
  import { findPackagesFromPath } from './findPackagesFromPath.js';
4
4
  import { parseRequiredBy } from './parseRequiredBy.js';
5
5
  import { slash } from '@ms-cloudpack/path-string-parsing';
6
+ import { dedupeLinkedPackages } from './dedupeLinkedPackages.js';
6
7
  /**
7
8
  * Given a linked path, an appMap, find packages from the linked path and add them to the appMap.
8
9
  */
@@ -74,9 +75,14 @@ export async function linkPath(options, context) {
74
75
  // Add the linked entry
75
76
  appMap[linkedEntry.name] = { [linkedEntry.version]: linkedEntry };
76
77
  }
78
+ const allDuplicates = [];
77
79
  // Once all linked entries have been added, ensure their dependencies are resolved.
78
80
  for (const linkedEntry of entriesToLink) {
79
- await addLinkedEntryDependencies({ linkedEntry, appMap: appMap, linkMap, resolutions }, context);
81
+ const { duplicates } = await addLinkedEntryDependencies({ linkedEntry, appMap: appMap, linkMap, resolutions }, context);
82
+ allDuplicates.push(...duplicates);
83
+ }
84
+ if (linkedPath.resolveStrategy !== 'duplicate') {
85
+ dedupeLinkedPackages({ appMap, allDuplicates: new Set(allDuplicates) });
80
86
  }
81
87
  }
82
88
  function isContainedInPath(path, basePath) {
@@ -1 +1 @@
1
- {"version":3,"file":"linkPath.js","sourceRoot":"","sources":["../../src/createResolveMap/linkPath.ts"],"names":[],"mappings":"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","sourcesContent":["import type { LinkedPath } from '../types/LinkedPath.js';\nimport type { PackageMap } from '../types/PackageMap.js';\nimport type { ResolveMapEntry } from '../types/ResolveMapEntry.js';\nimport { addLinkedEntryDependencies } from './addLinkedEntryDependencies.js';\nimport { detachEntry } from './detachEntry.js';\nimport { findPackagesFromPath } from './findPackagesFromPath.js';\nimport { parseRequiredBy } from './parseRequiredBy.js';\nimport { slash } from '@ms-cloudpack/path-string-parsing';\nimport type { PackageDefinitionsCache, PackageJson } from '@ms-cloudpack/common-types';\n\n/**\n * Given a linked path, an appMap, find packages from the linked path and add them to the appMap.\n */\nexport async function linkPath(\n options: {\n linkedPath: LinkedPath;\n appMap: PackageMap;\n repoDefinition?: PackageJson;\n },\n context: {\n packages: PackageDefinitionsCache;\n },\n) {\n const { linkedPath, appMap, repoDefinition } = options;\n const linkMap = await findPackagesFromPath(\n {\n searchPaths: [linkedPath.path],\n discoverPackages: true,\n },\n context,\n );\n const entriesToLink: ResolveMapEntry[] = [];\n const { path, ignoredPackages = [], includeAll } = linkedPath;\n const resolutions = linkedPath.ignoreResolutions ? undefined : repoDefinition?.resolutions;\n\n // Iterate through the linkMap, looking for internal packages to link to the appMap.\n for (const [packageName, packageVersions] of Object.entries(linkMap)) {\n const appEntries = Object.values(appMap[packageName] || {});\n\n if (!appEntries.length) {\n continue;\n }\n\n const linkedEntries = Object.values(packageVersions);\n const linkedEntry = linkedEntries.length === 1 ? linkedEntries[0] : undefined;\n\n // For linked dependencies, we don't want multiple versions referenced. Remove them\n // all and add them in a second pass.\n if (\n linkedEntry &&\n !linkedEntry.isExternal &&\n ignoredPackages.indexOf(packageName) === -1 &&\n (includeAll || isContainedInPath(linkedEntry.path, path))\n ) {\n // Linked packages use an asterisk for the version description. This keeps it semver compatible with\n // anything.\n linkedEntry.version += '-linked';\n linkedEntry.isLinked = true;\n\n entriesToLink.push(linkedEntry);\n }\n }\n\n // We now have a list of paths to link. Iterate through them, add them to the appMap,\n // and ensure their dependencies are satisfied.\n for (const linkedEntry of entriesToLink) {\n const { name } = linkedEntry;\n const existingEntries = Object.values(appMap[name]);\n\n linkedEntry.requiredBy = {};\n for (const entry of existingEntries) {\n for (const [requiredById, requirement] of Object.entries(entry.requiredBy)) {\n const requiredByName = parseRequiredBy(requiredById).name;\n const linkedParentEntry = Object.values(linkMap[requiredByName] || {})[0];\n const requiredByKey = linkedParentEntry?.isLinked\n ? (`${linkedParentEntry.name}@${linkedParentEntry.version}` as const)\n : requiredById;\n linkedEntry.requiredBy[requiredByKey as `${string}@${string}`] = requirement;\n }\n }\n }\n\n for (const linkedEntry of entriesToLink) {\n const { name } = linkedEntry;\n const existingEntries = Object.values(appMap[name]);\n\n // We need to detach all existing entries from the appMap, along with their dependencies. Note - detaching just means that\n // we disconnect the entry from its parent and children. If the children have no other parents, we disconnect them as well\n // and recurse through their children.\n for (const existingEntry of existingEntries) {\n detachEntry({ appMap, entry: existingEntry });\n }\n\n // Attach the linked entry to the parents' dependencies.\n for (const requiredById of Object.keys(linkedEntry.requiredBy)) {\n const { name: requiredByName, version: requiredByVersion } = parseRequiredBy(requiredById);\n let requiredByEntry = appMap[requiredByName][requiredByVersion];\n\n // If we can't find the requiredBy entry, it likely means that the entry was already replaced with a linked entry\n // in the app map. Fall back to the first entry.\n requiredByEntry ??= Object.values(appMap[requiredByName])[0];\n\n requiredByEntry.dependencies[name] = linkedEntry.version;\n }\n\n // Add the linked entry\n appMap[linkedEntry.name] = { [linkedEntry.version]: linkedEntry };\n }\n\n // Once all linked entries have been added, ensure their dependencies are resolved.\n for (const linkedEntry of entriesToLink) {\n await addLinkedEntryDependencies({ linkedEntry, appMap: appMap, linkMap, resolutions }, context);\n }\n}\n\nfunction isContainedInPath(path: string, basePath: string) {\n path = normalizePath(path);\n basePath = normalizePath(basePath);\n\n return path.startsWith(basePath);\n}\n\nfunction normalizePath(path: string) {\n let normalizedPath = slash(path);\n\n if (!normalizedPath.endsWith('/')) {\n normalizedPath += '/';\n }\n\n return normalizedPath;\n}\n"]}
1
+ {"version":3,"file":"linkPath.js","sourceRoot":"","sources":["../../src/createResolveMap/linkPath.ts"],"names":[],"mappings":"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","sourcesContent":["import type { LinkedPath } from '../types/LinkedPath.js';\nimport type { PackageMap } from '../types/PackageMap.js';\nimport type { ResolveMapEntry } from '../types/ResolveMapEntry.js';\nimport { addLinkedEntryDependencies } from './addLinkedEntryDependencies.js';\nimport { detachEntry } from './detachEntry.js';\nimport { findPackagesFromPath } from './findPackagesFromPath.js';\nimport { parseRequiredBy } from './parseRequiredBy.js';\nimport { slash } from '@ms-cloudpack/path-string-parsing';\nimport type { PackageDefinitionsCache, PackageJson } from '@ms-cloudpack/common-types';\nimport { dedupeLinkedPackages } from './dedupeLinkedPackages.js';\n\n/**\n * Given a linked path, an appMap, find packages from the linked path and add them to the appMap.\n */\nexport async function linkPath(\n options: {\n linkedPath: LinkedPath;\n appMap: PackageMap;\n repoDefinition?: PackageJson;\n },\n context: {\n packages: PackageDefinitionsCache;\n },\n) {\n const { linkedPath, appMap, repoDefinition } = options;\n const linkMap = await findPackagesFromPath(\n {\n searchPaths: [linkedPath.path],\n discoverPackages: true,\n },\n context,\n );\n const entriesToLink: ResolveMapEntry[] = [];\n const { path, ignoredPackages = [], includeAll } = linkedPath;\n const resolutions = linkedPath.ignoreResolutions ? undefined : repoDefinition?.resolutions;\n\n // Iterate through the linkMap, looking for internal packages to link to the appMap.\n for (const [packageName, packageVersions] of Object.entries(linkMap)) {\n const appEntries = Object.values(appMap[packageName] || {});\n\n if (!appEntries.length) {\n continue;\n }\n\n const linkedEntries = Object.values(packageVersions);\n const linkedEntry = linkedEntries.length === 1 ? linkedEntries[0] : undefined;\n\n // For linked dependencies, we don't want multiple versions referenced. Remove them\n // all and add them in a second pass.\n if (\n linkedEntry &&\n !linkedEntry.isExternal &&\n ignoredPackages.indexOf(packageName) === -1 &&\n (includeAll || isContainedInPath(linkedEntry.path, path))\n ) {\n // Linked packages use an asterisk for the version description. This keeps it semver compatible with\n // anything.\n linkedEntry.version += '-linked';\n linkedEntry.isLinked = true;\n\n entriesToLink.push(linkedEntry);\n }\n }\n\n // We now have a list of paths to link. Iterate through them, add them to the appMap,\n // and ensure their dependencies are satisfied.\n for (const linkedEntry of entriesToLink) {\n const { name } = linkedEntry;\n const existingEntries = Object.values(appMap[name]);\n\n linkedEntry.requiredBy = {};\n for (const entry of existingEntries) {\n for (const [requiredById, requirement] of Object.entries(entry.requiredBy)) {\n const requiredByName = parseRequiredBy(requiredById).name;\n const linkedParentEntry = Object.values(linkMap[requiredByName] || {})[0];\n const requiredByKey = linkedParentEntry?.isLinked\n ? (`${linkedParentEntry.name}@${linkedParentEntry.version}` as const)\n : requiredById;\n linkedEntry.requiredBy[requiredByKey as `${string}@${string}`] = requirement;\n }\n }\n }\n\n for (const linkedEntry of entriesToLink) {\n const { name } = linkedEntry;\n const existingEntries = Object.values(appMap[name]);\n\n // We need to detach all existing entries from the appMap, along with their dependencies. Note - detaching just means that\n // we disconnect the entry from its parent and children. If the children have no other parents, we disconnect them as well\n // and recurse through their children.\n for (const existingEntry of existingEntries) {\n detachEntry({ appMap, entry: existingEntry });\n }\n\n // Attach the linked entry to the parents' dependencies.\n for (const requiredById of Object.keys(linkedEntry.requiredBy)) {\n const { name: requiredByName, version: requiredByVersion } = parseRequiredBy(requiredById);\n let requiredByEntry = appMap[requiredByName][requiredByVersion];\n\n // If we can't find the requiredBy entry, it likely means that the entry was already replaced with a linked entry\n // in the app map. Fall back to the first entry.\n requiredByEntry ??= Object.values(appMap[requiredByName])[0];\n\n requiredByEntry.dependencies[name] = linkedEntry.version;\n }\n\n // Add the linked entry\n appMap[linkedEntry.name] = { [linkedEntry.version]: linkedEntry };\n }\n\n const allDuplicates = [];\n\n // Once all linked entries have been added, ensure their dependencies are resolved.\n for (const linkedEntry of entriesToLink) {\n const { duplicates } = await addLinkedEntryDependencies(\n { linkedEntry, appMap: appMap, linkMap, resolutions },\n context,\n );\n allDuplicates.push(...duplicates);\n }\n\n if (linkedPath.resolveStrategy !== 'duplicate') {\n dedupeLinkedPackages({ appMap, allDuplicates: new Set(allDuplicates) });\n }\n}\n\nfunction isContainedInPath(path: string, basePath: string) {\n path = normalizePath(path);\n basePath = normalizePath(basePath);\n\n return path.startsWith(basePath);\n}\n\nfunction normalizePath(path: string) {\n let normalizedPath = slash(path);\n\n if (!normalizedPath.endsWith('/')) {\n normalizedPath += '/';\n }\n\n return normalizedPath;\n}\n"]}
@@ -8,6 +8,7 @@ export declare function findPackage(options: {
8
8
  startPath: string;
9
9
  importerContext?: PackageImporterContext;
10
10
  rootPath?: string;
11
+ realPathCache?: Record<string, string | undefined>;
11
12
  }, context: {
12
13
  packages: PackageDefinitionsCache;
13
14
  }): Promise<{
@@ -1 +1 @@
1
- {"version":3,"file":"findPackage.d.ts","sourceRoot":"","sources":["../src/findPackage.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAE/G;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE;IACP,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,sBAAsB,CAAC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,EACD,OAAO,EAAE;IACP,QAAQ,EAAE,uBAAuB,CAAC;CACnC,GACA,OAAO,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,WAAW,CAAA;CAAE,GAAG,SAAS,CAAC,CAwCvE"}
1
+ {"version":3,"file":"findPackage.d.ts","sourceRoot":"","sources":["../src/findPackage.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAE/G;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE;IACP,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,sBAAsB,CAAC;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;CACpD,EACD,OAAO,EAAE;IACP,QAAQ,EAAE,uBAAuB,CAAC;CACnC,GACA,OAAO,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,WAAW,CAAA;CAAE,GAAG,SAAS,CAAC,CA2CvE"}
@@ -5,7 +5,7 @@ import fs from 'fs';
5
5
  * starting at `startPath` and ending at `rootPath` (usually the git root) or the filesystem root.
6
6
  */
7
7
  export async function findPackage(options, context) {
8
- const { dependencyName, rootPath, startPath, importerContext } = options;
8
+ const { dependencyName, rootPath, startPath, importerContext, realPathCache } = options;
9
9
  const { packages } = context;
10
10
  let packagePath = startPath;
11
11
  const isStoreLayout = /[\\/]\.(pnpm|store)[\\/]/.test(packagePath);
@@ -14,13 +14,16 @@ export async function findPackage(options, context) {
14
14
  let definition;
15
15
  let realPath;
16
16
  try {
17
- realPath = fs.realpathSync.native(resolvedPath);
17
+ realPath = realPathCache?.[resolvedPath] || fs.realpathSync.native(resolvedPath);
18
18
  definition = await packages.get(realPath, { importerContext });
19
19
  }
20
20
  catch (e) {
21
21
  // Ignore errors and keep looking.
22
22
  }
23
23
  if (realPath && definition) {
24
+ if (realPathCache && !realPathCache[resolvedPath]) {
25
+ realPathCache[resolvedPath] = realPath;
26
+ }
24
27
  return { packagePath: realPath, definition };
25
28
  }
26
29
  // We haven't found it. Try to move up a directory.
@@ -1 +1 @@
1
- {"version":3,"file":"findPackage.js","sourceRoot":"","sources":["../src/findPackage.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AAGpB;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,OAKC,EACD,OAEC;IAED,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,SAAS,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC;IACzE,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IAE7B,IAAI,WAAW,GAAG,SAAS,CAAC;IAC5B,MAAM,aAAa,GAAG,0BAA0B,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAEnE,GAAG,CAAC;QACF,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,EAAE,cAAc,CAAC,CAAC;QAC5E,IAAI,UAAmC,CAAC;QACxC,IAAI,QAA4B,CAAC;QAEjC,IAAI,CAAC;YACH,QAAQ,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;YAChD,UAAU,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,eAAe,EAAE,CAAC,CAAC;QACjE,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,kCAAkC;QACpC,CAAC;QAED,IAAI,QAAQ,IAAI,UAAU,EAAE,CAAC;YAC3B,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC;QAC/C,CAAC;QAED,mDAAmD;QACnD,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAExC,oDAAoD;QACpD,gGAAgG;QAChG,yFAAyF;QACzF,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACjE,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAC1C,CAAC;QAED,yCAAyC;QACzC,IAAI,WAAW,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;YACzC,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC,QAAQ,CAAC,CAAC,QAAQ,IAAI,WAAW,CAAC,MAAM,IAAI,QAAQ,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,WAAW,EAAE;IAE5G,OAAO,SAAS,CAAC;AACnB,CAAC","sourcesContent":["import path from 'path';\nimport fs from 'fs';\nimport type { PackageDefinitionsCache, PackageImporterContext, PackageJson } from '@ms-cloudpack/common-types';\n\n/**\n * Find the package.json contents for `dependencyName`, searching up under `node_modules` folders\n * starting at `startPath` and ending at `rootPath` (usually the git root) or the filesystem root.\n */\nexport async function findPackage(\n options: {\n dependencyName: string;\n startPath: string;\n importerContext?: PackageImporterContext;\n rootPath?: string;\n },\n context: {\n packages: PackageDefinitionsCache;\n },\n): Promise<{ packagePath: string; definition: PackageJson } | undefined> {\n const { dependencyName, rootPath, startPath, importerContext } = options;\n const { packages } = context;\n\n let packagePath = startPath;\n const isStoreLayout = /[\\\\/]\\.(pnpm|store)[\\\\/]/.test(packagePath);\n\n do {\n const resolvedPath = path.join(packagePath, 'node_modules', dependencyName);\n let definition: PackageJson | undefined;\n let realPath: string | undefined;\n\n try {\n realPath = fs.realpathSync.native(resolvedPath);\n definition = await packages.get(realPath, { importerContext });\n } catch (e) {\n // Ignore errors and keep looking.\n }\n\n if (realPath && definition) {\n return { packagePath: realPath, definition };\n }\n\n // We haven't found it. Try to move up a directory.\n packagePath = path.dirname(packagePath);\n\n // If we moved up into a scope folder, skip over it.\n // Exception: in a manager using a store layout, packages starting with @ are NOT scope folders;\n // e.g. @foo/bar will be in a folder like @foo-bar-npm-1.2.3-abcdef1234 or @foo-bar@1.2.3\n if (!isStoreLayout && path.basename(packagePath).startsWith('@')) {\n packagePath = path.dirname(packagePath);\n }\n\n // Skip over nested node_modules folders.\n if (packagePath.endsWith('node_modules')) {\n packagePath = path.dirname(packagePath);\n }\n } while ((!rootPath || packagePath.length >= rootPath.length) && path.dirname(packagePath) !== packagePath);\n\n return undefined;\n}\n"]}
1
+ {"version":3,"file":"findPackage.js","sourceRoot":"","sources":["../src/findPackage.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AAGpB;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,OAMC,EACD,OAEC;IAED,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,SAAS,EAAE,eAAe,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC;IACxF,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IAE7B,IAAI,WAAW,GAAG,SAAS,CAAC;IAC5B,MAAM,aAAa,GAAG,0BAA0B,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAEnE,GAAG,CAAC;QACF,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,EAAE,cAAc,CAAC,CAAC;QAC5E,IAAI,UAAmC,CAAC;QACxC,IAAI,QAA4B,CAAC;QAEjC,IAAI,CAAC;YACH,QAAQ,GAAG,aAAa,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;YACjF,UAAU,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,eAAe,EAAE,CAAC,CAAC;QACjE,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,kCAAkC;QACpC,CAAC;QAED,IAAI,QAAQ,IAAI,UAAU,EAAE,CAAC;YAC3B,IAAI,aAAa,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,EAAE,CAAC;gBAClD,aAAa,CAAC,YAAY,CAAC,GAAG,QAAQ,CAAC;YACzC,CAAC;YACD,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC;QAC/C,CAAC;QAED,mDAAmD;QACnD,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAExC,oDAAoD;QACpD,gGAAgG;QAChG,yFAAyF;QACzF,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACjE,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAC1C,CAAC;QAED,yCAAyC;QACzC,IAAI,WAAW,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;YACzC,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC,QAAQ,CAAC,CAAC,QAAQ,IAAI,WAAW,CAAC,MAAM,IAAI,QAAQ,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,WAAW,EAAE;IAE5G,OAAO,SAAS,CAAC;AACnB,CAAC","sourcesContent":["import path from 'path';\nimport fs from 'fs';\nimport type { PackageDefinitionsCache, PackageImporterContext, PackageJson } from '@ms-cloudpack/common-types';\n\n/**\n * Find the package.json contents for `dependencyName`, searching up under `node_modules` folders\n * starting at `startPath` and ending at `rootPath` (usually the git root) or the filesystem root.\n */\nexport async function findPackage(\n options: {\n dependencyName: string;\n startPath: string;\n importerContext?: PackageImporterContext;\n rootPath?: string;\n realPathCache?: Record<string, string | undefined>;\n },\n context: {\n packages: PackageDefinitionsCache;\n },\n): Promise<{ packagePath: string; definition: PackageJson } | undefined> {\n const { dependencyName, rootPath, startPath, importerContext, realPathCache } = options;\n const { packages } = context;\n\n let packagePath = startPath;\n const isStoreLayout = /[\\\\/]\\.(pnpm|store)[\\\\/]/.test(packagePath);\n\n do {\n const resolvedPath = path.join(packagePath, 'node_modules', dependencyName);\n let definition: PackageJson | undefined;\n let realPath: string | undefined;\n\n try {\n realPath = realPathCache?.[resolvedPath] || fs.realpathSync.native(resolvedPath);\n definition = await packages.get(realPath, { importerContext });\n } catch (e) {\n // Ignore errors and keep looking.\n }\n\n if (realPath && definition) {\n if (realPathCache && !realPathCache[resolvedPath]) {\n realPathCache[resolvedPath] = realPath;\n }\n return { packagePath: realPath, definition };\n }\n\n // We haven't found it. Try to move up a directory.\n packagePath = path.dirname(packagePath);\n\n // If we moved up into a scope folder, skip over it.\n // Exception: in a manager using a store layout, packages starting with @ are NOT scope folders;\n // e.g. @foo/bar will be in a folder like @foo-bar-npm-1.2.3-abcdef1234 or @foo-bar@1.2.3\n if (!isStoreLayout && path.basename(packagePath).startsWith('@')) {\n packagePath = path.dirname(packagePath);\n }\n\n // Skip over nested node_modules folders.\n if (packagePath.endsWith('node_modules')) {\n packagePath = path.dirname(packagePath);\n }\n } while ((!rootPath || packagePath.length >= rootPath.length) && path.dirname(packagePath) !== packagePath);\n\n return undefined;\n}\n"]}
@@ -22,5 +22,7 @@ export interface LinkedPath {
22
22
  * If true, ignores resolutions from the host repo definition to the linked packages.
23
23
  */
24
24
  ignoreResolutions?: boolean;
25
+ /** The strategy to use when resolving linked packages. Defaults to "dedupe". */
26
+ resolveStrategy?: 'dedupe' | 'duplicate';
25
27
  }
26
28
  //# sourceMappingURL=LinkedPath.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"LinkedPath.d.ts","sourceRoot":"","sources":["../../src/types/LinkedPath.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAE3B;;OAEG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B"}
1
+ {"version":3,"file":"LinkedPath.d.ts","sourceRoot":"","sources":["../../src/types/LinkedPath.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAE3B;;OAEG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B,gFAAgF;IAChF,eAAe,CAAC,EAAE,QAAQ,GAAG,WAAW,CAAC;CAC1C"}
@@ -1 +1 @@
1
- {"version":3,"file":"LinkedPath.js","sourceRoot":"","sources":["../../src/types/LinkedPath.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Represents a path linked to the resolve map.\n */\nexport interface LinkedPath {\n /**\n * Path to where the link originates.\n */\n path: string;\n\n /**\n * Optional git root to limit package resolution discovery.\n */\n rootPath?: string;\n\n /**\n * If true, transitive internal packages will be linked rather than only the matched packages.\n */\n includeAll?: boolean;\n\n /**\n * Package matches to ignore when linking.\n */\n ignoredPackages?: string[];\n\n /**\n * If true, ignores resolutions from the host repo definition to the linked packages.\n */\n ignoreResolutions?: boolean;\n}\n"]}
1
+ {"version":3,"file":"LinkedPath.js","sourceRoot":"","sources":["../../src/types/LinkedPath.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Represents a path linked to the resolve map.\n */\nexport interface LinkedPath {\n /**\n * Path to where the link originates.\n */\n path: string;\n\n /**\n * Optional git root to limit package resolution discovery.\n */\n rootPath?: string;\n\n /**\n * If true, transitive internal packages will be linked rather than only the matched packages.\n */\n includeAll?: boolean;\n\n /**\n * Package matches to ignore when linking.\n */\n ignoredPackages?: string[];\n\n /**\n * If true, ignores resolutions from the host repo definition to the linked packages.\n */\n ignoreResolutions?: boolean;\n\n /** The strategy to use when resolving linked packages. Defaults to \"dedupe\". */\n resolveStrategy?: 'dedupe' | 'duplicate';\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ms-cloudpack/package-utilities",
3
- "version": "7.5.1",
3
+ "version": "7.5.3",
4
4
  "description": "Utilities for resolving/parsing packages and their imports.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -14,11 +14,11 @@
14
14
  }
15
15
  },
16
16
  "dependencies": {
17
- "@ms-cloudpack/common-types": "^0.7.0",
17
+ "@ms-cloudpack/common-types": "^0.7.1",
18
18
  "@ms-cloudpack/json-utilities": "^0.1.4",
19
- "@ms-cloudpack/package-overrides": "^0.9.0",
19
+ "@ms-cloudpack/package-overrides": "^0.9.1",
20
20
  "@ms-cloudpack/path-string-parsing": "^1.2.3",
21
- "@ms-cloudpack/path-utilities": "^2.7.15",
21
+ "@ms-cloudpack/path-utilities": "^2.7.16",
22
22
  "@ms-cloudpack/task-reporter": "^0.14.1",
23
23
  "acorn": "^8.11.2",
24
24
  "acorn-walk": "^8.2.1",