1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.Configuration = exports.PackageExtensionType = exports.ProjectLookup = exports.coreDefinitions = exports.FormatType = exports.SettingsType = exports.SECRET = exports.DEFAULT_LOCK_FILENAME = exports.DEFAULT_RC_FILENAME = exports.ENVIRONMENT_PREFIX = void 0;
|
4 | const tslib_1 = require("tslib");
|
5 | const fslib_1 = require("@yarnpkg/fslib");
|
6 | const fslib_2 = require("@yarnpkg/fslib");
|
7 | const parsers_1 = require("@yarnpkg/parsers");
|
8 | const camelcase_1 = tslib_1.__importDefault(require("camelcase"));
|
9 | const ci_info_1 = require("ci-info");
|
10 | const clipanion_1 = require("clipanion");
|
11 | const p_limit_1 = tslib_1.__importDefault(require("p-limit"));
|
12 | const semver_1 = tslib_1.__importDefault(require("semver"));
|
13 | const stream_1 = require("stream");
|
14 | const CorePlugin_1 = require("./CorePlugin");
|
15 | const Manifest_1 = require("./Manifest");
|
16 | const MultiFetcher_1 = require("./MultiFetcher");
|
17 | const MultiResolver_1 = require("./MultiResolver");
|
18 | const ProtocolResolver_1 = require("./ProtocolResolver");
|
19 | const VirtualFetcher_1 = require("./VirtualFetcher");
|
20 | const VirtualResolver_1 = require("./VirtualResolver");
|
21 | const WorkspaceFetcher_1 = require("./WorkspaceFetcher");
|
22 | const WorkspaceResolver_1 = require("./WorkspaceResolver");
|
23 | const folderUtils = tslib_1.__importStar(require("./folderUtils"));
|
24 | const formatUtils = tslib_1.__importStar(require("./formatUtils"));
|
25 | const miscUtils = tslib_1.__importStar(require("./miscUtils"));
|
26 | const nodeUtils = tslib_1.__importStar(require("./nodeUtils"));
|
27 | const semverUtils = tslib_1.__importStar(require("./semverUtils"));
|
28 | const structUtils = tslib_1.__importStar(require("./structUtils"));
|
29 | const IGNORED_ENV_VARIABLES = new Set([
|
30 |
|
31 |
|
32 | `binFolder`,
|
33 |
|
34 |
|
35 | `version`,
|
36 |
|
37 |
|
38 | `flags`,
|
39 |
|
40 |
|
41 | `profile`,
|
42 | `gpg`,
|
43 |
|
44 | `ignoreNode`,
|
45 |
|
46 |
|
47 | `wrapOutput`,
|
48 | ]);
|
49 | exports.ENVIRONMENT_PREFIX = `yarn_`;
|
50 | exports.DEFAULT_RC_FILENAME = `.yarnrc.yml`;
|
51 | exports.DEFAULT_LOCK_FILENAME = `yarn.lock`;
|
52 | exports.SECRET = `********`;
|
53 | var SettingsType;
|
54 | (function (SettingsType) {
|
55 | SettingsType["ANY"] = "ANY";
|
56 | SettingsType["BOOLEAN"] = "BOOLEAN";
|
57 | SettingsType["ABSOLUTE_PATH"] = "ABSOLUTE_PATH";
|
58 | SettingsType["LOCATOR"] = "LOCATOR";
|
59 | SettingsType["LOCATOR_LOOSE"] = "LOCATOR_LOOSE";
|
60 | SettingsType["NUMBER"] = "NUMBER";
|
61 | SettingsType["STRING"] = "STRING";
|
62 | SettingsType["SECRET"] = "SECRET";
|
63 | SettingsType["SHAPE"] = "SHAPE";
|
64 | SettingsType["MAP"] = "MAP";
|
65 | })(SettingsType = exports.SettingsType || (exports.SettingsType = {}));
|
66 | exports.FormatType = formatUtils.Type;
|
67 |
|
68 |
|
69 |
|
70 |
|
71 |
|
72 |
|
73 |
|
74 |
|
75 |
|
76 |
|
77 |
|
78 |
|
79 |
|
80 |
|
81 |
|
82 |
|
83 |
|
84 | exports.coreDefinitions = {
|
85 |
|
86 | lastUpdateCheck: {
|
87 | description: `Last timestamp we checked whether new Yarn versions were available`,
|
88 | type: SettingsType.STRING,
|
89 | default: null,
|
90 | },
|
91 |
|
92 | yarnPath: {
|
93 | description: `Path to the local executable that must be used over the global one`,
|
94 | type: SettingsType.ABSOLUTE_PATH,
|
95 | default: null,
|
96 | },
|
97 | ignorePath: {
|
98 | description: `If true, the local executable will be ignored when using the global one`,
|
99 | type: SettingsType.BOOLEAN,
|
100 | default: false,
|
101 | },
|
102 | ignoreCwd: {
|
103 | description: `If true, the \`--cwd\` flag will be ignored`,
|
104 | type: SettingsType.BOOLEAN,
|
105 | default: false,
|
106 | },
|
107 |
|
108 | cacheKeyOverride: {
|
109 | description: `A global cache key override; used only for test purposes`,
|
110 | type: SettingsType.STRING,
|
111 | default: null,
|
112 | },
|
113 | globalFolder: {
|
114 | description: `Folder where are stored the system-wide settings`,
|
115 | type: SettingsType.ABSOLUTE_PATH,
|
116 | default: folderUtils.getDefaultGlobalFolder(),
|
117 | },
|
118 | cacheFolder: {
|
119 | description: `Folder where the cache files must be written`,
|
120 | type: SettingsType.ABSOLUTE_PATH,
|
121 | default: `./.yarn/cache`,
|
122 | },
|
123 | compressionLevel: {
|
124 | description: `Zip files compression level, from 0 to 9 or mixed (a variant of 9, which stores some files uncompressed, when compression doesn't yield good results)`,
|
125 | type: SettingsType.NUMBER,
|
126 | values: [`mixed`, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
|
127 | default: fslib_1.DEFAULT_COMPRESSION_LEVEL,
|
128 | },
|
129 | virtualFolder: {
|
130 | description: `Folder where the virtual packages (cf doc) will be mapped on the disk (must be named $$virtual)`,
|
131 | type: SettingsType.ABSOLUTE_PATH,
|
132 | default: `./.yarn/$$virtual`,
|
133 | },
|
134 | bstatePath: {
|
135 | description: `Path of the file where the current state of the built packages must be stored`,
|
136 | type: SettingsType.ABSOLUTE_PATH,
|
137 | default: `./.yarn/build-state.yml`,
|
138 | },
|
139 | lockfileFilename: {
|
140 | description: `Name of the files where the Yarn dependency tree entries must be stored`,
|
141 | type: SettingsType.STRING,
|
142 | default: exports.DEFAULT_LOCK_FILENAME,
|
143 | },
|
144 | installStatePath: {
|
145 | description: `Path of the file where the install state will be persisted`,
|
146 | type: SettingsType.ABSOLUTE_PATH,
|
147 | default: `./.yarn/install-state.gz`,
|
148 | },
|
149 | immutablePatterns: {
|
150 | description: `Array of glob patterns; files matching them won't be allowed to change during immutable installs`,
|
151 | type: SettingsType.STRING,
|
152 | default: [],
|
153 | isArray: true,
|
154 | },
|
155 | rcFilename: {
|
156 | description: `Name of the files where the configuration can be found`,
|
157 | type: SettingsType.STRING,
|
158 | default: getRcFilename(),
|
159 | },
|
160 | enableGlobalCache: {
|
161 | description: `If true, the system-wide cache folder will be used regardless of \`cache-folder\``,
|
162 | type: SettingsType.BOOLEAN,
|
163 | default: false,
|
164 | },
|
165 | enableAbsoluteVirtuals: {
|
166 | description: `If true, the virtual symlinks will use absolute paths if required [non portable!!]`,
|
167 | type: SettingsType.BOOLEAN,
|
168 | default: false,
|
169 | },
|
170 |
|
171 | enableColors: {
|
172 | description: `If true, the CLI is allowed to use colors in its output`,
|
173 | type: SettingsType.BOOLEAN,
|
174 | default: formatUtils.supportsColor,
|
175 | defaultText: `<dynamic>`,
|
176 | },
|
177 | enableHyperlinks: {
|
178 | description: `If true, the CLI is allowed to use hyperlinks in its output`,
|
179 | type: SettingsType.BOOLEAN,
|
180 | default: formatUtils.supportsHyperlinks,
|
181 | defaultText: `<dynamic>`,
|
182 | },
|
183 | enableInlineBuilds: {
|
184 | description: `If true, the CLI will print the build output on the command line`,
|
185 | type: SettingsType.BOOLEAN,
|
186 | default: ci_info_1.isCI,
|
187 | defaultText: `<dynamic>`,
|
188 | },
|
189 | enableProgressBars: {
|
190 | description: `If true, the CLI is allowed to show a progress bar for long-running events`,
|
191 | type: SettingsType.BOOLEAN,
|
192 | default: !ci_info_1.isCI && process.stdout.isTTY && process.stdout.columns > 22,
|
193 | defaultText: `<dynamic>`,
|
194 | },
|
195 | enableTimers: {
|
196 | description: `If true, the CLI is allowed to print the time spent executing commands`,
|
197 | type: SettingsType.BOOLEAN,
|
198 | default: true,
|
199 | },
|
200 | preferAggregateCacheInfo: {
|
201 | description: `If true, the CLI will only print a one-line report of any cache changes`,
|
202 | type: SettingsType.BOOLEAN,
|
203 | default: ci_info_1.isCI,
|
204 | },
|
205 | preferInteractive: {
|
206 | description: `If true, the CLI will automatically use the interactive mode when called from a TTY`,
|
207 | type: SettingsType.BOOLEAN,
|
208 | default: false,
|
209 | },
|
210 | preferTruncatedLines: {
|
211 | description: `If true, the CLI will truncate lines that would go beyond the size of the terminal`,
|
212 | type: SettingsType.BOOLEAN,
|
213 | default: false,
|
214 | },
|
215 | progressBarStyle: {
|
216 | description: `Which style of progress bar should be used (only when progress bars are enabled)`,
|
217 | type: SettingsType.STRING,
|
218 | default: undefined,
|
219 | defaultText: `<dynamic>`,
|
220 | },
|
221 |
|
222 | defaultLanguageName: {
|
223 | description: `Default language mode that should be used when a package doesn't offer any insight`,
|
224 | type: SettingsType.STRING,
|
225 | default: `node`,
|
226 | },
|
227 | defaultProtocol: {
|
228 | description: `Default resolution protocol used when resolving pure semver and tag ranges`,
|
229 | type: SettingsType.STRING,
|
230 | default: `npm:`,
|
231 | },
|
232 | enableTransparentWorkspaces: {
|
233 | description: `If false, Yarn won't automatically resolve workspace dependencies unless they use the \`workspace:\` protocol`,
|
234 | type: SettingsType.BOOLEAN,
|
235 | default: true,
|
236 | },
|
237 |
|
238 | enableMirror: {
|
239 | description: `If true, the downloaded packages will be retrieved and stored in both the local and global folders`,
|
240 | type: SettingsType.BOOLEAN,
|
241 | default: true,
|
242 | },
|
243 | enableNetwork: {
|
244 | description: `If false, the package manager will refuse to use the network if required to`,
|
245 | type: SettingsType.BOOLEAN,
|
246 | default: true,
|
247 | },
|
248 | httpProxy: {
|
249 | description: `URL of the http proxy that must be used for outgoing http requests`,
|
250 | type: SettingsType.STRING,
|
251 | default: null,
|
252 | },
|
253 | httpsProxy: {
|
254 | description: `URL of the http proxy that must be used for outgoing https requests`,
|
255 | type: SettingsType.STRING,
|
256 | default: null,
|
257 | },
|
258 | unsafeHttpWhitelist: {
|
259 | description: `List of the hostnames for which http queries are allowed (glob patterns are supported)`,
|
260 | type: SettingsType.STRING,
|
261 | default: [],
|
262 | isArray: true,
|
263 | },
|
264 | httpTimeout: {
|
265 | description: `Timeout of each http request in milliseconds`,
|
266 | type: SettingsType.NUMBER,
|
267 | default: 60000,
|
268 | },
|
269 | httpRetry: {
|
270 | description: `Retry times on http failure`,
|
271 | type: SettingsType.NUMBER,
|
272 | default: 3,
|
273 | },
|
274 | networkConcurrency: {
|
275 | description: `Maximal number of concurrent requests`,
|
276 | type: SettingsType.NUMBER,
|
277 | default: Infinity,
|
278 | },
|
279 |
|
280 | enableTelemetry: {
|
281 | description: `If true, telemetry will be periodically sent, following the rules in https://yarnpkg.com/advanced/telemetry`,
|
282 | type: SettingsType.BOOLEAN,
|
283 | default: true,
|
284 | },
|
285 | telemetryInterval: {
|
286 | description: `Minimal amount of time between two telemetry uploads, in days`,
|
287 | type: SettingsType.NUMBER,
|
288 | default: 7,
|
289 | },
|
290 | telemetryUserId: {
|
291 | description: `If you desire to tell us which project you are, you can set this field. Completely optional and opt-in.`,
|
292 | type: SettingsType.STRING,
|
293 | default: null,
|
294 | },
|
295 |
|
296 | enableScripts: {
|
297 | description: `If true, packages are allowed to have install scripts by default`,
|
298 | type: SettingsType.BOOLEAN,
|
299 | default: true,
|
300 | },
|
301 | enableImmutableCache: {
|
302 | description: `If true, the cache is reputed immutable and actions that would modify it will throw`,
|
303 | type: SettingsType.BOOLEAN,
|
304 | default: false,
|
305 | },
|
306 | checksumBehavior: {
|
307 | description: `Enumeration defining what to do when a checksum doesn't match expectations`,
|
308 | type: SettingsType.STRING,
|
309 | default: `throw`,
|
310 | },
|
311 |
|
312 | packageExtensions: {
|
313 | description: `Map of package corrections to apply on the dependency tree`,
|
314 | type: SettingsType.MAP,
|
315 | valueDefinition: {
|
316 | description: ``,
|
317 | type: SettingsType.ANY,
|
318 | },
|
319 | },
|
320 | };
|
321 | function parseBoolean(value) {
|
322 | switch (value) {
|
323 | case `true`:
|
324 | case `1`:
|
325 | case 1:
|
326 | case true:
|
327 | {
|
328 | return true;
|
329 | }
|
330 | break;
|
331 | case `false`:
|
332 | case `0`:
|
333 | case 0:
|
334 | case false:
|
335 | {
|
336 | return false;
|
337 | }
|
338 | break;
|
339 | default:
|
340 | {
|
341 | throw new Error(`Couldn't parse "${value}" as a boolean`);
|
342 | }
|
343 | break;
|
344 | }
|
345 | }
|
346 | function parseValue(configuration, path, value, definition, folder) {
|
347 | if (definition.isArray) {
|
348 | if (!Array.isArray(value)) {
|
349 | return String(value).split(/,/).map(segment => {
|
350 | return parseSingleValue(configuration, path, segment, definition, folder);
|
351 | });
|
352 | }
|
353 | else {
|
354 | return value.map((sub, i) => parseSingleValue(configuration, `${path}[${i}]`, sub, definition, folder));
|
355 | }
|
356 | }
|
357 | else {
|
358 | if (Array.isArray(value)) {
|
359 | throw new Error(`Non-array configuration settings "${path}" cannot be an array`);
|
360 | }
|
361 | else {
|
362 | return parseSingleValue(configuration, path, value, definition, folder);
|
363 | }
|
364 | }
|
365 | }
|
366 | function parseSingleValue(configuration, path, value, definition, folder) {
|
367 | var _a;
|
368 | switch (definition.type) {
|
369 | case SettingsType.ANY:
|
370 | return value;
|
371 | case SettingsType.SHAPE:
|
372 | return parseShape(configuration, path, value, definition, folder);
|
373 | case SettingsType.MAP:
|
374 | return parseMap(configuration, path, value, definition, folder);
|
375 | }
|
376 | if (value === null && !definition.isNullable && definition.default !== null)
|
377 | throw new Error(`Non-nullable configuration settings "${path}" cannot be set to null`);
|
378 | if ((_a = definition.values) === null || _a === void 0 ? void 0 : _a.includes(value))
|
379 | return value;
|
380 | const interpretValue = () => {
|
381 | if (definition.type === SettingsType.BOOLEAN)
|
382 | return parseBoolean(value);
|
383 | if (typeof value !== `string`)
|
384 | throw new Error(`Expected value (${value}) to be a string`);
|
385 | const valueWithReplacedVariables = miscUtils.replaceEnvVariables(value, {
|
386 | env: process.env,
|
387 | });
|
388 | switch (definition.type) {
|
389 | case SettingsType.ABSOLUTE_PATH:
|
390 | return fslib_2.ppath.resolve(folder, fslib_2.npath.toPortablePath(valueWithReplacedVariables));
|
391 | case SettingsType.LOCATOR_LOOSE:
|
392 | return structUtils.parseLocator(valueWithReplacedVariables, false);
|
393 | case SettingsType.NUMBER:
|
394 | return parseInt(valueWithReplacedVariables);
|
395 | case SettingsType.LOCATOR:
|
396 | return structUtils.parseLocator(valueWithReplacedVariables);
|
397 | default:
|
398 | return valueWithReplacedVariables;
|
399 | }
|
400 | };
|
401 | const interpreted = interpretValue();
|
402 | if (definition.values && !definition.values.includes(interpreted))
|
403 | throw new Error(`Invalid value, expected one of ${definition.values.join(`, `)}`);
|
404 | return interpreted;
|
405 | }
|
406 | function parseShape(configuration, path, value, definition, folder) {
|
407 | if (typeof value !== `object` || Array.isArray(value))
|
408 | throw new clipanion_1.UsageError(`Object configuration settings "${path}" must be an object`);
|
409 | const result = getDefaultValue(configuration, definition);
|
410 | if (value === null)
|
411 | return result;
|
412 | for (const [propKey, propValue] of Object.entries(value)) {
|
413 | const subPath = `${path}.${propKey}`;
|
414 | const subDefinition = definition.properties[propKey];
|
415 | if (!subDefinition)
|
416 | throw new clipanion_1.UsageError(`Unrecognized configuration settings found: ${path}.${propKey} - run "yarn config -v" to see the list of settings supported in Yarn`);
|
417 | result.set(propKey, parseValue(configuration, subPath, propValue, definition.properties[propKey], folder));
|
418 | }
|
419 | return result;
|
420 | }
|
421 | function parseMap(configuration, path, value, definition, folder) {
|
422 | const result = new Map();
|
423 | if (typeof value !== `object` || Array.isArray(value))
|
424 | throw new clipanion_1.UsageError(`Map configuration settings "${path}" must be an object`);
|
425 | if (value === null)
|
426 | return result;
|
427 | for (const [propKey, propValue] of Object.entries(value)) {
|
428 | const normalizedKey = definition.normalizeKeys ? definition.normalizeKeys(propKey) : propKey;
|
429 | const subPath = `${path}['${normalizedKey}']`;
|
430 |
|
431 |
|
432 | const valueDefinition = definition.valueDefinition;
|
433 | result.set(normalizedKey, parseValue(configuration, subPath, propValue, valueDefinition, folder));
|
434 | }
|
435 | return result;
|
436 | }
|
437 | function getDefaultValue(configuration, definition) {
|
438 | switch (definition.type) {
|
439 | case SettingsType.SHAPE:
|
440 | {
|
441 | const result = new Map();
|
442 | for (const [propKey, propDefinition] of Object.entries(definition.properties))
|
443 | result.set(propKey, getDefaultValue(configuration, propDefinition));
|
444 | return result;
|
445 | }
|
446 | break;
|
447 | case SettingsType.MAP:
|
448 | {
|
449 | return new Map();
|
450 | }
|
451 | break;
|
452 | case SettingsType.ABSOLUTE_PATH:
|
453 | {
|
454 | if (definition.default === null)
|
455 | return null;
|
456 | if (configuration.projectCwd === null) {
|
457 | if (fslib_2.ppath.isAbsolute(definition.default)) {
|
458 | return fslib_2.ppath.normalize(definition.default);
|
459 | }
|
460 | else if (definition.isNullable) {
|
461 | return null;
|
462 | }
|
463 | else {
|
464 |
|
465 |
|
466 | return undefined;
|
467 | }
|
468 | }
|
469 | else {
|
470 | if (Array.isArray(definition.default)) {
|
471 | return definition.default.map((entry) => fslib_2.ppath.resolve(configuration.projectCwd, entry));
|
472 | }
|
473 | else {
|
474 | return fslib_2.ppath.resolve(configuration.projectCwd, definition.default);
|
475 | }
|
476 | }
|
477 | }
|
478 | break;
|
479 | default:
|
480 | {
|
481 | return definition.default;
|
482 | }
|
483 | break;
|
484 | }
|
485 | }
|
486 | function transformConfiguration(rawValue, definition, transforms) {
|
487 | if (definition.type === SettingsType.SECRET && typeof rawValue === `string` && transforms.hideSecrets)
|
488 | return exports.SECRET;
|
489 | if (definition.type === SettingsType.ABSOLUTE_PATH && typeof rawValue === `string` && transforms.getNativePaths)
|
490 | return fslib_2.npath.fromPortablePath(rawValue);
|
491 | if (definition.isArray && Array.isArray(rawValue)) {
|
492 | const newValue = [];
|
493 | for (const value of rawValue)
|
494 | newValue.push(transformConfiguration(value, definition, transforms));
|
495 | return newValue;
|
496 | }
|
497 | if (definition.type === SettingsType.MAP && rawValue instanceof Map) {
|
498 | const newValue = new Map();
|
499 | for (const [key, value] of rawValue.entries())
|
500 | newValue.set(key, transformConfiguration(value, definition.valueDefinition, transforms));
|
501 | return newValue;
|
502 | }
|
503 | if (definition.type === SettingsType.SHAPE && rawValue instanceof Map) {
|
504 | const newValue = new Map();
|
505 | for (const [key, value] of rawValue.entries()) {
|
506 | const propertyDefinition = definition.properties[key];
|
507 | newValue.set(key, transformConfiguration(value, propertyDefinition, transforms));
|
508 | }
|
509 | return newValue;
|
510 | }
|
511 | return rawValue;
|
512 | }
|
513 | function getEnvironmentSettings() {
|
514 | const environmentSettings = {};
|
515 | for (let [key, value] of Object.entries(process.env)) {
|
516 | key = key.toLowerCase();
|
517 | if (!key.startsWith(exports.ENVIRONMENT_PREFIX))
|
518 | continue;
|
519 | key = camelcase_1.default(key.slice(exports.ENVIRONMENT_PREFIX.length));
|
520 | environmentSettings[key] = value;
|
521 | }
|
522 | return environmentSettings;
|
523 | }
|
524 | function getRcFilename() {
|
525 | const rcKey = `${exports.ENVIRONMENT_PREFIX}rc_filename`;
|
526 | for (const [key, value] of Object.entries(process.env))
|
527 | if (key.toLowerCase() === rcKey && typeof value === `string`)
|
528 | return value;
|
529 | return exports.DEFAULT_RC_FILENAME;
|
530 | }
|
531 | var ProjectLookup;
|
532 | (function (ProjectLookup) {
|
533 | ProjectLookup[ProjectLookup["LOCKFILE"] = 0] = "LOCKFILE";
|
534 | ProjectLookup[ProjectLookup["MANIFEST"] = 1] = "MANIFEST";
|
535 | ProjectLookup[ProjectLookup["NONE"] = 2] = "NONE";
|
536 | })(ProjectLookup = exports.ProjectLookup || (exports.ProjectLookup = {}));
|
537 | var PackageExtensionType;
|
538 | (function (PackageExtensionType) {
|
539 | PackageExtensionType["Dependency"] = "Dependency";
|
540 | PackageExtensionType["PeerDependency"] = "PeerDependency";
|
541 | PackageExtensionType["PeerDependencyMeta"] = "PeerDependencyMeta";
|
542 | })(PackageExtensionType = exports.PackageExtensionType || (exports.PackageExtensionType = {}));
|
543 | class Configuration {
|
544 | constructor(startingCwd) {
|
545 | this.projectCwd = null;
|
546 | this.plugins = new Map();
|
547 | this.settings = new Map();
|
548 | this.values = new Map();
|
549 | this.sources = new Map();
|
550 | this.invalid = new Map();
|
551 | this.packageExtensions = new Map();
|
552 | this.limits = new Map();
|
553 | this.startingCwd = startingCwd;
|
554 | }
|
555 | static create(startingCwd, projectCwdOrPlugins, maybePlugins) {
|
556 | const configuration = new Configuration(startingCwd);
|
557 | if (typeof projectCwdOrPlugins !== `undefined` && !(projectCwdOrPlugins instanceof Map))
|
558 | configuration.projectCwd = projectCwdOrPlugins;
|
559 | configuration.importSettings(exports.coreDefinitions);
|
560 | const plugins = typeof maybePlugins !== `undefined`
|
561 | ? maybePlugins
|
562 | : projectCwdOrPlugins instanceof Map
|
563 | ? projectCwdOrPlugins
|
564 | : new Map();
|
565 | for (const [name, plugin] of plugins)
|
566 | configuration.activatePlugin(name, plugin);
|
567 | return configuration;
|
568 | }
|
569 | |
570 |
|
571 |
|
572 |
|
573 |
|
574 |
|
575 |
|
576 |
|
577 |
|
578 |
|
579 |
|
580 |
|
581 |
|
582 |
|
583 |
|
584 |
|
585 |
|
586 |
|
587 |
|
588 |
|
589 |
|
590 |
|
591 |
|
592 |
|
593 |
|
594 |
|
595 | static async find(startingCwd, pluginConfiguration, { lookup = ProjectLookup.LOCKFILE, strict = true, usePath = false, useRc = true } = {}) {
|
596 | const environmentSettings = getEnvironmentSettings();
|
597 | delete environmentSettings.rcFilename;
|
598 | const rcFiles = await Configuration.findRcFiles(startingCwd);
|
599 | const homeRcFile = await Configuration.findHomeRcFile();
|
600 | const pickCoreFields = ({ ignoreCwd, yarnPath, ignorePath, lockfileFilename }) => ({ ignoreCwd, yarnPath, ignorePath, lockfileFilename });
|
601 | const excludeCoreFields = ({ ignoreCwd, yarnPath, ignorePath, lockfileFilename, ...rest }) => rest;
|
602 | const configuration = new Configuration(startingCwd);
|
603 | configuration.importSettings(pickCoreFields(exports.coreDefinitions));
|
604 | configuration.useWithSource(`<environment>`, pickCoreFields(environmentSettings), startingCwd, { strict: false });
|
605 | for (const { path, cwd, data } of rcFiles)
|
606 | configuration.useWithSource(path, pickCoreFields(data), cwd, { strict: false });
|
607 | if (homeRcFile)
|
608 | configuration.useWithSource(homeRcFile.path, pickCoreFields(homeRcFile.data), homeRcFile.cwd, { strict: false });
|
609 | if (usePath) {
|
610 | const yarnPath = configuration.get(`yarnPath`);
|
611 | const ignorePath = configuration.get(`ignorePath`);
|
612 | if (yarnPath !== null && !ignorePath) {
|
613 | return configuration;
|
614 | }
|
615 | }
|
616 |
|
617 |
|
618 | const lockfileFilename = configuration.get(`lockfileFilename`);
|
619 | let projectCwd;
|
620 | switch (lookup) {
|
621 | case ProjectLookup.LOCKFILE:
|
622 | {
|
623 | projectCwd = await Configuration.findProjectCwd(startingCwd, lockfileFilename);
|
624 | }
|
625 | break;
|
626 | case ProjectLookup.MANIFEST:
|
627 | {
|
628 | projectCwd = await Configuration.findProjectCwd(startingCwd, null);
|
629 | }
|
630 | break;
|
631 | case ProjectLookup.NONE:
|
632 | {
|
633 | if (fslib_2.xfs.existsSync(fslib_2.ppath.join(startingCwd, `package.json`))) {
|
634 | projectCwd = fslib_2.ppath.resolve(startingCwd);
|
635 | }
|
636 | else {
|
637 | projectCwd = null;
|
638 | }
|
639 | }
|
640 | break;
|
641 | }
|
642 |
|
643 |
|
644 | configuration.startingCwd = startingCwd;
|
645 | configuration.projectCwd = projectCwd;
|
646 | configuration.importSettings(excludeCoreFields(exports.coreDefinitions));
|
647 |
|
648 |
|
649 | const plugins = new Map([
|
650 | [`@@core`, CorePlugin_1.CorePlugin],
|
651 | ]);
|
652 | const interop = (obj) => obj.__esModule
|
653 | ? obj.default
|
654 | : obj;
|
655 | if (pluginConfiguration !== null) {
|
656 | for (const request of pluginConfiguration.plugins.keys())
|
657 | plugins.set(request, interop(pluginConfiguration.modules.get(request)));
|
658 | const requireEntries = new Map();
|
659 | for (const request of nodeUtils.builtinModules())
|
660 | requireEntries.set(request, () => nodeUtils.dynamicRequire(request));
|
661 | for (const [request, embedModule] of pluginConfiguration.modules)
|
662 | requireEntries.set(request, () => embedModule);
|
663 | const dynamicPlugins = new Set();
|
664 | const getDefault = (object) => {
|
665 | return object.default || object;
|
666 | };
|
667 | const importPlugin = (pluginPath, source) => {
|
668 | const { factory, name } = nodeUtils.dynamicRequire(fslib_2.npath.fromPortablePath(pluginPath));
|
669 |
|
670 |
|
671 | if (dynamicPlugins.has(name))
|
672 | return;
|
673 | const pluginRequireEntries = new Map(requireEntries);
|
674 | const pluginRequire = (request) => {
|
675 | if (pluginRequireEntries.has(request)) {
|
676 | return pluginRequireEntries.get(request)();
|
677 | }
|
678 | else {
|
679 | throw new clipanion_1.UsageError(`This plugin cannot access the package referenced via ${request} which is neither a builtin, nor an exposed entry`);
|
680 | }
|
681 | };
|
682 | const plugin = miscUtils.prettifySyncErrors(() => {
|
683 | return getDefault(factory(pluginRequire));
|
684 | }, message => {
|
685 | return `${message} (when initializing ${name}, defined in ${source})`;
|
686 | });
|
687 | requireEntries.set(name, () => plugin);
|
688 | dynamicPlugins.add(name);
|
689 | plugins.set(name, plugin);
|
690 | };
|
691 | if (environmentSettings.plugins) {
|
692 | for (const userProvidedPath of environmentSettings.plugins.split(`;`)) {
|
693 | const pluginPath = fslib_2.ppath.resolve(startingCwd, fslib_2.npath.toPortablePath(userProvidedPath));
|
694 | importPlugin(pluginPath, `<environment>`);
|
695 | }
|
696 | }
|
697 | for (const { path, cwd, data } of rcFiles) {
|
698 | if (!useRc)
|
699 | continue;
|
700 | if (!Array.isArray(data.plugins))
|
701 | continue;
|
702 | for (const userPluginEntry of data.plugins) {
|
703 | const userProvidedPath = typeof userPluginEntry !== `string`
|
704 | ? userPluginEntry.path
|
705 | : userPluginEntry;
|
706 | const pluginPath = fslib_2.ppath.resolve(cwd, fslib_2.npath.toPortablePath(userProvidedPath));
|
707 | importPlugin(pluginPath, path);
|
708 | }
|
709 | }
|
710 | }
|
711 | for (const [name, plugin] of plugins)
|
712 | configuration.activatePlugin(name, plugin);
|
713 | configuration.useWithSource(`<environment>`, excludeCoreFields(environmentSettings), startingCwd, { strict });
|
714 | for (const { path, cwd, data } of rcFiles)
|
715 | configuration.useWithSource(path, excludeCoreFields(data), cwd, { strict });
|
716 |
|
717 |
|
718 | if (homeRcFile)
|
719 | configuration.useWithSource(homeRcFile.path, excludeCoreFields(homeRcFile.data), homeRcFile.cwd, { strict: false });
|
720 | if (configuration.get(`enableGlobalCache`)) {
|
721 | configuration.values.set(`cacheFolder`, `${configuration.get(`globalFolder`)}/cache`);
|
722 | configuration.sources.set(`cacheFolder`, `<internal>`);
|
723 | }
|
724 | await configuration.refreshPackageExtensions();
|
725 | return configuration;
|
726 | }
|
727 | static async findRcFiles(startingCwd) {
|
728 | const rcFilename = getRcFilename();
|
729 | const rcFiles = [];
|
730 | let nextCwd = startingCwd;
|
731 | let currentCwd = null;
|
732 | while (nextCwd !== currentCwd) {
|
733 | currentCwd = nextCwd;
|
734 | const rcPath = fslib_2.ppath.join(currentCwd, rcFilename);
|
735 | if (fslib_2.xfs.existsSync(rcPath)) {
|
736 | const content = await fslib_2.xfs.readFilePromise(rcPath, `utf8`);
|
737 | let data;
|
738 | try {
|
739 | data = parsers_1.parseSyml(content);
|
740 | }
|
741 | catch (error) {
|
742 | let tip = ``;
|
743 | if (content.match(/^\s+(?!-)[^:]+\s+\S+/m))
|
744 | tip = ` (in particular, make sure you list the colons after each key name)`;
|
745 | throw new clipanion_1.UsageError(`Parse error when loading ${rcPath}; please check it's proper Yaml${tip}`);
|
746 | }
|
747 | rcFiles.push({ path: rcPath, cwd: currentCwd, data });
|
748 | }
|
749 | nextCwd = fslib_2.ppath.dirname(currentCwd);
|
750 | }
|
751 | return rcFiles;
|
752 | }
|
753 | static async findHomeRcFile() {
|
754 | const rcFilename = getRcFilename();
|
755 | const homeFolder = folderUtils.getHomeFolder();
|
756 | const homeRcFilePath = fslib_2.ppath.join(homeFolder, rcFilename);
|
757 | if (fslib_2.xfs.existsSync(homeRcFilePath)) {
|
758 | const content = await fslib_2.xfs.readFilePromise(homeRcFilePath, `utf8`);
|
759 | const data = parsers_1.parseSyml(content);
|
760 | return { path: homeRcFilePath, cwd: homeFolder, data };
|
761 | }
|
762 | return null;
|
763 | }
|
764 | static async findProjectCwd(startingCwd, lockfileFilename) {
|
765 | let projectCwd = null;
|
766 | let nextCwd = startingCwd;
|
767 | let currentCwd = null;
|
768 | while (nextCwd !== currentCwd) {
|
769 | currentCwd = nextCwd;
|
770 | if (fslib_2.xfs.existsSync(fslib_2.ppath.join(currentCwd, `package.json`)))
|
771 | projectCwd = currentCwd;
|
772 | if (lockfileFilename !== null) {
|
773 | if (fslib_2.xfs.existsSync(fslib_2.ppath.join(currentCwd, lockfileFilename))) {
|
774 | projectCwd = currentCwd;
|
775 | break;
|
776 | }
|
777 | }
|
778 | else {
|
779 | if (projectCwd !== null) {
|
780 | break;
|
781 | }
|
782 | }
|
783 | nextCwd = fslib_2.ppath.dirname(currentCwd);
|
784 | }
|
785 | return projectCwd;
|
786 | }
|
787 | static async updateConfiguration(cwd, patch) {
|
788 | const rcFilename = getRcFilename();
|
789 | const configurationPath = fslib_2.ppath.join(cwd, rcFilename);
|
790 | const current = fslib_2.xfs.existsSync(configurationPath)
|
791 | ? parsers_1.parseSyml(await fslib_2.xfs.readFilePromise(configurationPath, `utf8`))
|
792 | : {};
|
793 | let patched = false;
|
794 | let replacement;
|
795 | if (typeof patch === `function`) {
|
796 | try {
|
797 | replacement = patch(current);
|
798 | }
|
799 | catch (_a) {
|
800 | replacement = patch({});
|
801 | }
|
802 | if (replacement === current) {
|
803 | return;
|
804 | }
|
805 | }
|
806 | else {
|
807 | replacement = current;
|
808 | for (const key of Object.keys(patch)) {
|
809 | const currentValue = current[key];
|
810 | const patchField = patch[key];
|
811 | let nextValue;
|
812 | if (typeof patchField === `function`) {
|
813 | try {
|
814 | nextValue = patchField(currentValue);
|
815 | }
|
816 | catch (_b) {
|
817 | nextValue = patchField(undefined);
|
818 | }
|
819 | }
|
820 | else {
|
821 | nextValue = patchField;
|
822 | }
|
823 | if (currentValue === nextValue)
|
824 | continue;
|
825 | replacement[key] = nextValue;
|
826 | patched = true;
|
827 | }
|
828 | if (!patched) {
|
829 | return;
|
830 | }
|
831 | }
|
832 | await fslib_2.xfs.changeFilePromise(configurationPath, parsers_1.stringifySyml(replacement), {
|
833 | automaticNewlines: true,
|
834 | });
|
835 | }
|
836 | static async updateHomeConfiguration(patch) {
|
837 | const homeFolder = folderUtils.getHomeFolder();
|
838 | return await Configuration.updateConfiguration(homeFolder, patch);
|
839 | }
|
840 | activatePlugin(name, plugin) {
|
841 | this.plugins.set(name, plugin);
|
842 | if (typeof plugin.configuration !== `undefined`) {
|
843 | this.importSettings(plugin.configuration);
|
844 | }
|
845 | }
|
846 | importSettings(definitions) {
|
847 | for (const [name, definition] of Object.entries(definitions)) {
|
848 | if (definition == null)
|
849 | continue;
|
850 | if (this.settings.has(name))
|
851 | throw new Error(`Cannot redefine settings "${name}"`);
|
852 | this.settings.set(name, definition);
|
853 | this.values.set(name, getDefaultValue(this, definition));
|
854 | }
|
855 | }
|
856 | useWithSource(source, data, folder, opts) {
|
857 | try {
|
858 | this.use(source, data, folder, opts);
|
859 | }
|
860 | catch (error) {
|
861 | error.message += ` (in ${formatUtils.pretty(this, source, formatUtils.Type.PATH)})`;
|
862 | throw error;
|
863 | }
|
864 | }
|
865 | use(source, data, folder, { strict = true, overwrite = false } = {}) {
|
866 | for (const key of Object.keys(data)) {
|
867 | const value = data[key];
|
868 | if (typeof value === `undefined`)
|
869 | continue;
|
870 |
|
871 | if (key === `plugins`)
|
872 | continue;
|
873 |
|
874 | if (source === `<environment>` && IGNORED_ENV_VARIABLES.has(key))
|
875 | continue;
|
876 |
|
877 | if (key === `rcFilename`)
|
878 | throw new clipanion_1.UsageError(`The rcFilename settings can only be set via ${`${exports.ENVIRONMENT_PREFIX}RC_FILENAME`.toUpperCase()}, not via a rc file`);
|
879 | const definition = this.settings.get(key);
|
880 | if (!definition) {
|
881 | if (strict) {
|
882 | throw new clipanion_1.UsageError(`Unrecognized or legacy configuration settings found: ${key} - run "yarn config -v" to see the list of settings supported in Yarn`);
|
883 | }
|
884 | else {
|
885 | this.invalid.set(key, source);
|
886 | continue;
|
887 | }
|
888 | }
|
889 | if (this.sources.has(key) && !(overwrite || definition.type === SettingsType.MAP))
|
890 | continue;
|
891 | let parsed;
|
892 | try {
|
893 | parsed = parseValue(this, key, data[key], definition, folder);
|
894 | }
|
895 | catch (error) {
|
896 | error.message += ` in ${formatUtils.pretty(this, source, formatUtils.Type.PATH)}`;
|
897 | throw error;
|
898 | }
|
899 | if (definition.type === SettingsType.MAP) {
|
900 | const previousValue = this.values.get(key);
|
901 | this.values.set(key, new Map(overwrite
|
902 | ? [...previousValue, ...parsed]
|
903 | : [...parsed, ...previousValue]));
|
904 | this.sources.set(key, `${this.sources.get(key)}, ${source}`);
|
905 | }
|
906 | else {
|
907 | this.values.set(key, parsed);
|
908 | this.sources.set(key, source);
|
909 | }
|
910 | }
|
911 | }
|
912 | get(key) {
|
913 | if (!this.values.has(key))
|
914 | throw new Error(`Invalid configuration key "${key}"`);
|
915 | return this.values.get(key);
|
916 | }
|
917 | getSpecial(key, { hideSecrets = false, getNativePaths = false }) {
|
918 | const rawValue = this.get(key);
|
919 | const definition = this.settings.get(key);
|
920 | if (typeof definition === `undefined`)
|
921 | throw new clipanion_1.UsageError(`Couldn't find a configuration settings named "${key}"`);
|
922 | return transformConfiguration(rawValue, definition, {
|
923 | hideSecrets,
|
924 | getNativePaths,
|
925 | });
|
926 | }
|
927 | getSubprocessStreams(logFile, { header, prefix, report }) {
|
928 | let stdout;
|
929 | let stderr;
|
930 | const logStream = fslib_2.xfs.createWriteStream(logFile);
|
931 | if (this.get(`enableInlineBuilds`)) {
|
932 | const stdoutLineReporter = report.createStreamReporter(`${prefix} ${formatUtils.pretty(this, `STDOUT`, `green`)}`);
|
933 | const stderrLineReporter = report.createStreamReporter(`${prefix} ${formatUtils.pretty(this, `STDERR`, `red`)}`);
|
934 | stdout = new stream_1.PassThrough();
|
935 | stdout.pipe(stdoutLineReporter);
|
936 | stdout.pipe(logStream);
|
937 | stderr = new stream_1.PassThrough();
|
938 | stderr.pipe(stderrLineReporter);
|
939 | stderr.pipe(logStream);
|
940 | }
|
941 | else {
|
942 | stdout = logStream;
|
943 | stderr = logStream;
|
944 | if (typeof header !== `undefined`) {
|
945 | stdout.write(`${header}\n`);
|
946 | }
|
947 | }
|
948 | return { stdout, stderr };
|
949 | }
|
950 | makeResolver() {
|
951 | const pluginResolvers = [];
|
952 | for (const plugin of this.plugins.values())
|
953 | for (const resolver of plugin.resolvers || [])
|
954 | pluginResolvers.push(new resolver());
|
955 | return new MultiResolver_1.MultiResolver([
|
956 | new VirtualResolver_1.VirtualResolver(),
|
957 | new WorkspaceResolver_1.WorkspaceResolver(),
|
958 | new ProtocolResolver_1.ProtocolResolver(),
|
959 | ...pluginResolvers,
|
960 | ]);
|
961 | }
|
962 | makeFetcher() {
|
963 | const pluginFetchers = [];
|
964 | for (const plugin of this.plugins.values())
|
965 | for (const fetcher of plugin.fetchers || [])
|
966 | pluginFetchers.push(new fetcher());
|
967 | return new MultiFetcher_1.MultiFetcher([
|
968 | new VirtualFetcher_1.VirtualFetcher(),
|
969 | new WorkspaceFetcher_1.WorkspaceFetcher(),
|
970 | ...pluginFetchers,
|
971 | ]);
|
972 | }
|
973 | getLinkers() {
|
974 | const linkers = [];
|
975 | for (const plugin of this.plugins.values())
|
976 | for (const linker of plugin.linkers || [])
|
977 | linkers.push(new linker());
|
978 | return linkers;
|
979 | }
|
980 | async refreshPackageExtensions() {
|
981 | this.packageExtensions = new Map();
|
982 | const packageExtensions = this.packageExtensions;
|
983 | const registerPackageExtension = (descriptor, extensionData) => {
|
984 | if (!semver_1.default.validRange(descriptor.range))
|
985 | throw new Error(`Only semver ranges are allowed as keys for the lockfileExtensions setting`);
|
986 | const extension = new Manifest_1.Manifest();
|
987 | extension.load(extensionData);
|
988 | const extensionsPerIdent = miscUtils.getArrayWithDefault(packageExtensions, descriptor.identHash);
|
989 | const extensionsPerRange = [];
|
990 | extensionsPerIdent.push([descriptor.range, extensionsPerRange]);
|
991 | for (const dependency of extension.dependencies.values())
|
992 | extensionsPerRange.push({ type: PackageExtensionType.Dependency, descriptor: dependency, active: false, description: `${structUtils.stringifyIdent(descriptor)} > ${structUtils.stringifyIdent(dependency)}` });
|
993 | for (const peerDependency of extension.peerDependencies.values())
|
994 | extensionsPerRange.push({ type: PackageExtensionType.PeerDependency, descriptor: peerDependency, active: false, description: `${structUtils.stringifyIdent(descriptor)} >> ${structUtils.stringifyIdent(peerDependency)}` });
|
995 | for (const [selector, meta] of extension.peerDependenciesMeta) {
|
996 | for (const [key, value] of Object.entries(meta)) {
|
997 | extensionsPerRange.push({ type: PackageExtensionType.PeerDependencyMeta, selector, key: key, value, active: false, description: `${structUtils.stringifyIdent(descriptor)} >> ${selector} / ${key}` });
|
998 | }
|
999 | }
|
1000 | };
|
1001 | for (const [descriptorString, extensionData] of this.get(`packageExtensions`))
|
1002 | registerPackageExtension(structUtils.parseDescriptor(descriptorString, true), extensionData);
|
1003 | await this.triggerHook(hooks => {
|
1004 | return hooks.registerPackageExtensions;
|
1005 | }, this, registerPackageExtension);
|
1006 | }
|
1007 | normalizePackage(original) {
|
1008 | const pkg = structUtils.copyPackage(original);
|
1009 |
|
1010 |
|
1011 | if (this.packageExtensions == null)
|
1012 | throw new Error(`refreshPackageExtensions has to be called before normalizing packages`);
|
1013 | const extensionsPerIdent = this.packageExtensions.get(original.identHash);
|
1014 | if (typeof extensionsPerIdent !== `undefined`) {
|
1015 | const version = original.version;
|
1016 | if (version !== null) {
|
1017 | for (const [range, extensionsPerRange] of extensionsPerIdent) {
|
1018 | if (!semverUtils.satisfiesWithPrereleases(version, range))
|
1019 | continue;
|
1020 | for (const extension of extensionsPerRange) {
|
1021 | switch (extension.type) {
|
1022 | case PackageExtensionType.Dependency:
|
1023 | {
|
1024 | pkg.dependencies.set(extension.descriptor.identHash, extension.descriptor);
|
1025 | extension.active = true;
|
1026 | }
|
1027 | break;
|
1028 | case PackageExtensionType.PeerDependency:
|
1029 | {
|
1030 | pkg.peerDependencies.set(extension.descriptor.identHash, extension.descriptor);
|
1031 | extension.active = true;
|
1032 | }
|
1033 | break;
|
1034 | case PackageExtensionType.PeerDependencyMeta:
|
1035 | {
|
1036 | miscUtils.getFactoryWithDefault(pkg.peerDependenciesMeta, extension.selector, () => ({}))[extension.key] = extension.value;
|
1037 | extension.active = true;
|
1038 | }
|
1039 | break;
|
1040 | default:
|
1041 | {
|
1042 | miscUtils.assertNever(extension);
|
1043 | }
|
1044 | break;
|
1045 | }
|
1046 | }
|
1047 | }
|
1048 | }
|
1049 | }
|
1050 |
|
1051 |
|
1052 |
|
1053 |
|
1054 | const getTypesName = (descriptor) => {
|
1055 | return descriptor.scope
|
1056 | ? `${descriptor.scope}__${descriptor.name}`
|
1057 | : `${descriptor.name}`;
|
1058 | };
|
1059 | for (const descriptor of pkg.peerDependencies.values()) {
|
1060 | if (descriptor.scope === `@types`)
|
1061 | continue;
|
1062 | const typesName = getTypesName(descriptor);
|
1063 | const typesIdent = structUtils.makeIdent(`types`, typesName);
|
1064 | if (pkg.peerDependencies.has(typesIdent.identHash) || pkg.peerDependenciesMeta.has(typesIdent.identHash))
|
1065 | continue;
|
1066 | pkg.peerDependenciesMeta.set(structUtils.stringifyIdent(typesIdent), {
|
1067 | optional: true,
|
1068 | });
|
1069 | }
|
1070 |
|
1071 |
|
1072 |
|
1073 | for (const identString of pkg.peerDependenciesMeta.keys()) {
|
1074 | const ident = structUtils.parseIdent(identString);
|
1075 | if (!pkg.peerDependencies.has(ident.identHash)) {
|
1076 | pkg.peerDependencies.set(ident.identHash, structUtils.makeDescriptor(ident, `*`));
|
1077 | }
|
1078 | }
|
1079 |
|
1080 |
|
1081 | pkg.dependencies = new Map(miscUtils.sortMap(pkg.dependencies, ([, descriptor]) => structUtils.stringifyDescriptor(descriptor)));
|
1082 | pkg.peerDependencies = new Map(miscUtils.sortMap(pkg.peerDependencies, ([, descriptor]) => structUtils.stringifyDescriptor(descriptor)));
|
1083 | return pkg;
|
1084 | }
|
1085 | getLimit(key) {
|
1086 | return miscUtils.getFactoryWithDefault(this.limits, key, () => {
|
1087 | return p_limit_1.default(this.get(key));
|
1088 | });
|
1089 | }
|
1090 | async triggerHook(get, ...args) {
|
1091 | for (const plugin of this.plugins.values()) {
|
1092 | const hooks = plugin.hooks;
|
1093 | if (!hooks)
|
1094 | continue;
|
1095 | const hook = get(hooks);
|
1096 | if (!hook)
|
1097 | continue;
|
1098 | await hook(...args);
|
1099 | }
|
1100 | }
|
1101 | async triggerMultipleHooks(get, argsList) {
|
1102 | for (const args of argsList) {
|
1103 | await this.triggerHook(get, ...args);
|
1104 | }
|
1105 | }
|
1106 | async reduceHook(get, initialValue, ...args) {
|
1107 | let value = initialValue;
|
1108 | for (const plugin of this.plugins.values()) {
|
1109 | const hooks = plugin.hooks;
|
1110 | if (!hooks)
|
1111 | continue;
|
1112 | const hook = get(hooks);
|
1113 | if (!hook)
|
1114 | continue;
|
1115 | value = await hook(value, ...args);
|
1116 | }
|
1117 | return value;
|
1118 | }
|
1119 | async firstHook(get, ...args) {
|
1120 | for (const plugin of this.plugins.values()) {
|
1121 | const hooks = plugin.hooks;
|
1122 | if (!hooks)
|
1123 | continue;
|
1124 | const hook = get(hooks);
|
1125 | if (!hook)
|
1126 | continue;
|
1127 | const ret = await hook(...args);
|
1128 | if (typeof ret !== `undefined`) {
|
1129 |
|
1130 | return ret;
|
1131 | }
|
1132 | }
|
1133 | return null;
|
1134 | }
|
1135 | |
1136 |
|
1137 |
|
1138 | format(value, formatType) {
|
1139 | return formatUtils.pretty(this, value, formatType);
|
1140 | }
|
1141 | }
|
1142 | exports.Configuration = Configuration;
|
1143 | Configuration.telemetry = null;
|