UNPKG

5.6 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const _findKey = require("lodash.findkey");
4const _get = require("lodash.get");
5const _invert = require("lodash.invert");
6const _isEmpty = require("lodash.isempty");
7const types_1 = require("../types");
8const _ = {
9 get: _get,
10 isEmpty: _isEmpty,
11 invert: _invert,
12 findKey: _findKey,
13};
14class ComposerParser {
15 static getVersion(depObj) {
16 // check for `version` property. may not exist
17 const versionFound = _.get(depObj, 'version', '');
18 // even if found, may be an alias, so check
19 const availableAliases = _.get(depObj, "extra['branch-alias']", []);
20 // if the version matches the alias (either as is, or without 'dev-'), use the aliases version.
21 // otherwise, use the version as is, and if not, the first found alias
22 return _.get(availableAliases, versionFound) ||
23 _.get(_.invert(availableAliases), versionFound.replace('dev-', '')) &&
24 versionFound.replace('dev-', '') ||
25 versionFound ||
26 _.findKey(_.invert(availableAliases), '0'); // first available alias
27 }
28 static buildDependencies(composerJsonObj, composerLockObj, depObj, systemPackages, includeDev = false, isDevTree = false, depRecursiveArray = [], packageRefCount = {}) {
29 const result = {};
30 // find depObj properties
31 const depName = _.get(depObj, 'name');
32 const require = _.get(depObj, 'require', {});
33 const requireDev = includeDev ? _.get(depObj, 'require-dev', {}) : {};
34 // recursion tests
35 const inRecursiveArray = depRecursiveArray.indexOf(depName) > -1;
36 const exceedsMaxRepeats = packageRefCount[depName] >= this.MAX_PACKAGE_REPEATS;
37 const hasNoDependencies = _.isEmpty(require) && _.isEmpty(requireDev);
38 // break recursion when
39 if (inRecursiveArray || exceedsMaxRepeats || hasNoDependencies) {
40 return result;
41 }
42 // prevent circular dependencies
43 depRecursiveArray.push(depName);
44 // get locked packages
45 const packages = _.get(composerLockObj, 'packages', []);
46 const packagesDev = includeDev ? _.get(composerLockObj, 'packages-dev', []) : [];
47 const allPackages = [
48 ...packages,
49 ...packagesDev,
50 ];
51 // parse require dependencies
52 for (const name of Object.keys(require)) {
53 let version = '';
54 // lets find if this dependency has an object in composer.lock
55 const lockedPackage = allPackages.find((dep) => dep.name === name);
56 if (lockedPackage) {
57 version = this.getVersion(lockedPackage);
58 }
59 else {
60 // here we use the system version or composer json - not a locked version
61 version = _.get(systemPackages, name) || _.get(require, name);
62 }
63 // remove any starting 'v' from version numbers
64 version = version.replace(/^v(\d)/, '$1');
65 // bump package reference count (or assign to 1 if we haven't seen this before)
66 packageRefCount[name] = (packageRefCount[name] || 0) + 1;
67 result[name] = {
68 name,
69 version,
70 dependencies: this.buildDependencies(composerJsonObj, composerLockObj, lockedPackage, // undefined if transitive dependency
71 systemPackages, includeDev, false, depRecursiveArray, packageRefCount),
72 labels: {
73 scope: isDevTree ? types_1.Scope.dev : types_1.Scope.prod,
74 },
75 };
76 }
77 // parse require-dev dependencies
78 for (const name of Object.keys(requireDev)) {
79 let version = '';
80 // lets find if this dependency has an object in composer.lock
81 const lockedPackage = allPackages.find((dep) => dep.name === name);
82 if (lockedPackage) {
83 version = this.getVersion(lockedPackage);
84 }
85 else {
86 // here we use the system version or composer json - not a locked version
87 version = _.get(systemPackages, name) || _.get(requireDev, name);
88 }
89 // remove any starting 'v' from version numbers
90 version = version.replace(/^v(\d)/, '$1');
91 // bump package reference count (or assign to 1 if we haven't seen this before)
92 packageRefCount[name] = (packageRefCount[name] || 0) + 1;
93 result[name] = {
94 name,
95 version,
96 dependencies: this.buildDependencies(composerJsonObj, composerLockObj, lockedPackage, // undefined if transitive dependency
97 systemPackages, includeDev, true, depRecursiveArray, packageRefCount),
98 labels: {
99 scope: types_1.Scope.dev,
100 },
101 };
102 }
103 // remove from recursive check
104 depRecursiveArray.pop();
105 // return dep tree
106 return result;
107 }
108}
109exports.ComposerParser = ComposerParser;
110// After this threshold, a package node in the dep tree won't have expanded dependencies.
111// This is a cheap protection against combinatorial explosion when there's N packages
112// that depend on each other (producing N! branches of the dep tree).
113// The value of 150 was chosen as a lowest one that doesn't break existing tests.
114// Switching to dependency graph would render this trick obsolete.
115ComposerParser.MAX_PACKAGE_REPEATS = 150;
116//# sourceMappingURL=composer-parser.js.map
\No newline at end of file