@monorepolint/rules 0.6.0-alpha.2 → 0.6.0-alpha.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.
Files changed (77) hide show
  1. package/.turbo/turbo-clean.log +1 -1
  2. package/.turbo/turbo-compile-typescript.log +1 -1
  3. package/.turbo/turbo-lint.log +1 -1
  4. package/.turbo/turbo-test.log +160 -100
  5. package/.turbo/turbo-transpile-typescript.log +4 -4
  6. package/CHANGELOG.md +9 -0
  7. package/build/js/index.js +399 -246
  8. package/build/js/index.js.map +1 -1
  9. package/build/tsconfig.tsbuildinfo +1 -1
  10. package/build/types/__tests__/utils.d.ts +0 -1
  11. package/build/types/__tests__/utils.d.ts.map +1 -1
  12. package/build/types/bannedDependencies.d.ts.map +1 -1
  13. package/build/types/fileContents.d.ts.map +1 -1
  14. package/build/types/index.d.ts +3 -3
  15. package/build/types/index.d.ts.map +1 -1
  16. package/build/types/mustSatisfyPeerDependencies.d.ts.map +1 -1
  17. package/build/types/nestedWorkspaces.d.ts.map +1 -1
  18. package/build/types/packageEntry.d.ts.map +1 -1
  19. package/build/types/packageOrder.d.ts.map +1 -1
  20. package/build/types/packageScript.d.ts.map +1 -1
  21. package/build/types/requireDependency.d.ts +12 -12
  22. package/build/types/requireDependency.d.ts.map +1 -1
  23. package/build/types/util/checkAlpha.d.ts.map +1 -1
  24. package/build/types/util/createRuleFactory.d.ts.map +1 -1
  25. package/build/types/util/packageDependencyGraphService.d.ts.map +1 -1
  26. package/coverage/clover.xml +1159 -818
  27. package/coverage/coverage-final.json +18 -18
  28. package/coverage/index.html +20 -20
  29. package/coverage/src/alphabeticalDependencies.ts.html +8 -8
  30. package/coverage/src/alphabeticalScripts.ts.html +5 -5
  31. package/coverage/src/bannedDependencies.ts.html +77 -26
  32. package/coverage/src/consistentDependencies.ts.html +58 -19
  33. package/coverage/src/consistentVersions.ts.html +169 -58
  34. package/coverage/src/fileContents.ts.html +47 -23
  35. package/coverage/src/index.html +67 -67
  36. package/coverage/src/index.ts.html +32 -32
  37. package/coverage/src/mustSatisfyPeerDependencies.ts.html +373 -85
  38. package/coverage/src/nestedWorkspaces.ts.html +59 -20
  39. package/coverage/src/packageEntry.ts.html +40 -19
  40. package/coverage/src/packageOrder.ts.html +30 -12
  41. package/coverage/src/packageScript.ts.html +81 -27
  42. package/coverage/src/requireDependency.ts.html +83 -32
  43. package/coverage/src/standardTsconfig.ts.html +81 -18
  44. package/coverage/src/util/checkAlpha.ts.html +18 -9
  45. package/coverage/src/util/createRuleFactory.ts.html +16 -4
  46. package/coverage/src/util/index.html +17 -17
  47. package/coverage/src/util/makeDirectory.ts.html +5 -5
  48. package/coverage/src/util/packageDependencyGraphService.ts.html +101 -20
  49. package/package.json +4 -5
  50. package/src/__tests__/alphabeticalScripts.spec.ts +12 -4
  51. package/src/__tests__/bannedDependencies.spec.ts +45 -16
  52. package/src/__tests__/consistentDependencies.spec.ts +11 -5
  53. package/src/__tests__/consistentVersions.spec.ts +72 -18
  54. package/src/__tests__/fileContents.spec.ts +9 -5
  55. package/src/__tests__/mustSatisfyPeerDependencies.spec.ts +191 -76
  56. package/src/__tests__/nestedWorkspaces.spec.ts +10 -6
  57. package/src/__tests__/packageEntry.spec.ts +54 -48
  58. package/src/__tests__/packageOrder.spec.ts +77 -71
  59. package/src/__tests__/packageScript.spec.ts +25 -11
  60. package/src/__tests__/requireDependency.spec.ts +12 -6
  61. package/src/__tests__/utils.ts +16 -7
  62. package/src/bannedDependencies.ts +32 -15
  63. package/src/consistentDependencies.ts +22 -9
  64. package/src/consistentVersions.ts +84 -47
  65. package/src/fileContents.ts +19 -11
  66. package/src/index.ts +3 -3
  67. package/src/mustSatisfyPeerDependencies.ts +162 -66
  68. package/src/nestedWorkspaces.ts +23 -10
  69. package/src/packageEntry.ts +18 -11
  70. package/src/packageOrder.ts +9 -3
  71. package/src/packageScript.ts +37 -19
  72. package/src/requireDependency.ts +28 -11
  73. package/src/standardTsconfig.ts +31 -10
  74. package/src/util/checkAlpha.ts +5 -2
  75. package/src/util/createRuleFactory.ts +6 -2
  76. package/src/util/packageDependencyGraphService.ts +41 -14
  77. package/vitest.config.mjs +10 -7
@@ -8,9 +8,9 @@
8
8
  import { Context } from "@monorepolint/config";
9
9
  import { Host, mutateJson, PackageJson } from "@monorepolint/utils";
10
10
  import * as path from "node:path";
11
+ import resolvePackagePath from "resolve-package-path";
11
12
  import * as r from "runtypes";
12
13
  import { coerce } from "semver";
13
- import resolvePackagePath from "resolve-package-path";
14
14
  import { createRuleFactory } from "./util/createRuleFactory.js";
15
15
 
16
16
  const Options = r.Union(
@@ -29,7 +29,7 @@ const Options = r.Union(
29
29
  dependencyWhitelist: r.Undefined,
30
30
  dependencyBlacklist: r.Undefined,
31
31
  enforceForDevDependencies: r.Undefined,
32
- })
32
+ }),
33
33
  ),
34
34
  r
35
35
  .Record({
@@ -40,7 +40,7 @@ const Options = r.Union(
40
40
  skipUnparseableRanges: r.Undefined,
41
41
  dependencyBlacklist: r.Undefined,
42
42
  enforceForDevDependencies: r.Undefined,
43
- })
43
+ }),
44
44
  ),
45
45
  r
46
46
  .Record({
@@ -51,7 +51,7 @@ const Options = r.Union(
51
51
  skipUnparseableRanges: r.Undefined,
52
52
  dependencyWhitelist: r.Undefined,
53
53
  enforceForDevDependencies: r.Undefined,
54
- })
54
+ }),
55
55
  ),
56
56
  r
57
57
  .Record({
@@ -62,7 +62,7 @@ const Options = r.Union(
62
62
  skipUnparseableRanges: r.Undefined,
63
63
  dependencyWhitelist: r.Undefined,
64
64
  dependencyBlacklist: r.Undefined,
65
- })
65
+ }),
66
66
  ),
67
67
  r
68
68
  .Record({
@@ -73,7 +73,7 @@ const Options = r.Union(
73
73
  r.Partial({
74
74
  dependencyBlacklist: r.Undefined,
75
75
  enforceForDevDependencies: r.Undefined,
76
- })
76
+ }),
77
77
  ),
78
78
  r
79
79
  .Record({
@@ -84,7 +84,7 @@ const Options = r.Union(
84
84
  r.Partial({
85
85
  dependencyWhitelist: r.Undefined,
86
86
  enforceForDevDependencies: r.Undefined,
87
- })
87
+ }),
88
88
  ),
89
89
  r
90
90
  .Record({
@@ -95,7 +95,7 @@ const Options = r.Union(
95
95
  r.Partial({
96
96
  dependencyWhitelist: r.Undefined,
97
97
  dependencyBlacklist: r.Undefined,
98
- })
98
+ }),
99
99
  ),
100
100
  r
101
101
  .Record({
@@ -106,7 +106,7 @@ const Options = r.Union(
106
106
  r.Partial({
107
107
  skipUnparseableRanges: r.Undefined,
108
108
  enforceForDevDependencies: r.Undefined,
109
- })
109
+ }),
110
110
  ),
111
111
  r
112
112
  .Record({
@@ -117,7 +117,7 @@ const Options = r.Union(
117
117
  r.Partial({
118
118
  skipUnparseableRanges: r.Undefined,
119
119
  dependencyBlacklist: r.Undefined,
120
- })
120
+ }),
121
121
  ),
122
122
  r
123
123
  .Record({
@@ -128,7 +128,7 @@ const Options = r.Union(
128
128
  r.Partial({
129
129
  skipUnparseableRanges: r.Undefined,
130
130
  dependencyWhitelist: r.Undefined,
131
- })
131
+ }),
132
132
  ),
133
133
  r
134
134
  .Record({
@@ -139,7 +139,7 @@ const Options = r.Union(
139
139
  .And(
140
140
  r.Partial({
141
141
  enforceForDevDependencies: r.Undefined,
142
- })
142
+ }),
143
143
  ),
144
144
  r
145
145
  .Record({
@@ -150,7 +150,7 @@ const Options = r.Union(
150
150
  .And(
151
151
  r.Partial({
152
152
  dependencyBlacklist: r.Undefined,
153
- })
153
+ }),
154
154
  ),
155
155
  r
156
156
  .Record({
@@ -161,7 +161,7 @@ const Options = r.Union(
161
161
  .And(
162
162
  r.Partial({
163
163
  dependencyWhitelist: r.Undefined,
164
- })
164
+ }),
165
165
  ),
166
166
  r
167
167
  .Record({
@@ -172,14 +172,14 @@ const Options = r.Union(
172
172
  .And(
173
173
  r.Partial({
174
174
  skipUnparseableRanges: r.Undefined,
175
- })
175
+ }),
176
176
  ),
177
177
  r.Record({
178
178
  skipUnparseableRanges: r.Boolean,
179
179
  dependencyWhitelist: r.Array(r.String),
180
180
  dependencyBlacklist: r.Array(r.String),
181
181
  enforceForDevDependencies: r.Boolean,
182
- })
182
+ }),
183
183
  );
184
184
 
185
185
  export type Options = r.Static<typeof Options>;
@@ -270,7 +270,12 @@ interface IResolvedPeerDependencyRequirement {
270
270
  }
271
271
 
272
272
  function checkSatisfyPeerDependencies(context: Context, opts: Options) {
273
- const { dependencyBlacklist, dependencyWhitelist, enforceForDevDependencies, skipUnparseableRanges } = opts;
273
+ const {
274
+ dependencyBlacklist,
275
+ dependencyWhitelist,
276
+ enforceForDevDependencies,
277
+ skipUnparseableRanges,
278
+ } = opts;
274
279
  const packageJsonPath = path.resolve(context.getPackageJsonPath());
275
280
  const packageJson = context.host.readJson(packageJsonPath) as PackageJson;
276
281
  const packageDependencies = packageJson.dependencies || {};
@@ -279,8 +284,18 @@ function checkSatisfyPeerDependencies(context: Context, opts: Options) {
279
284
  const packageName = packageJson.name || packageJsonPath;
280
285
 
281
286
  // check that no peer dependencies are also declared as regular dependencies
282
- for (const [peerDependencyName, peerDependencyRange] of Object.entries(packagePeerDependencies)) {
283
- if (shouldSkipPackage({ dependencyBlacklist, dependencyWhitelist, packageName: peerDependencyName })) {
287
+ for (
288
+ const [peerDependencyName, peerDependencyRange] of Object.entries(
289
+ packagePeerDependencies,
290
+ )
291
+ ) {
292
+ if (
293
+ shouldSkipPackage({
294
+ dependencyBlacklist,
295
+ dependencyWhitelist,
296
+ packageName: peerDependencyName,
297
+ })
298
+ ) {
284
299
  continue;
285
300
  }
286
301
 
@@ -289,36 +304,59 @@ function checkSatisfyPeerDependencies(context: Context, opts: Options) {
289
304
  context.addError({
290
305
  file: packageJsonPath,
291
306
  message:
292
- `[0] Package ${packageName} has overloaded ${peerDependencyName} dependencies.\n\t` +
293
- `Peer dependency '${peerDependencyRange}' and regular dependency '${dependencyRange}'.`,
307
+ `[0] Package ${packageName} has overloaded ${peerDependencyName} dependencies.\n\t`
308
+ + `Peer dependency '${peerDependencyRange}' and regular dependency '${dependencyRange}'.`,
294
309
  });
295
310
  }
296
311
  }
297
312
 
298
313
  // map of all inherited peer dependency requirements
299
- const allRequiredPeerDependencies: { [peerDependencyName: string]: IPeerDependencyRequirement[] } = {};
314
+ const allRequiredPeerDependencies: {
315
+ [peerDependencyName: string]: IPeerDependencyRequirement[];
316
+ } = {};
300
317
 
301
318
  // for each of this package's dependencies, add the dependency's peer requirements into `allRequiredPeerDependencies`
302
319
  const allDependencies = enforceForDevDependencies
303
- ? [...Object.keys(packageDependencies), ...Object.keys(packageDevDependencies)]
320
+ ? [
321
+ ...Object.keys(packageDependencies),
322
+ ...Object.keys(packageDevDependencies),
323
+ ]
304
324
  : Object.keys(packageDependencies);
305
325
  for (const dependency of allDependencies) {
306
- const dependencyPackageJsonPath = resolvePackagePath(dependency, path.dirname(packageJsonPath));
326
+ const dependencyPackageJsonPath = resolvePackagePath(
327
+ dependency,
328
+ path.dirname(packageJsonPath),
329
+ );
307
330
  if (dependencyPackageJsonPath == null) {
308
- throw new Error(`Could not resolve ${dependency} from ${path.dirname(packageJsonPath)}`);
331
+ throw new Error(
332
+ `Could not resolve ${dependency} from ${path.dirname(packageJsonPath)}`,
333
+ );
309
334
  }
310
- const dependencyPackageJson = context.host.readJson(dependencyPackageJsonPath) as PackageJson;
335
+ const dependencyPackageJson = context.host.readJson(
336
+ dependencyPackageJsonPath,
337
+ ) as PackageJson;
311
338
  const requiredPeerDependencies = dependencyPackageJson.peerDependencies;
312
339
  if (requiredPeerDependencies == null) {
313
340
  continue;
314
341
  }
315
- for (const [peerDependencyName, range] of Object.entries(requiredPeerDependencies)) {
316
- if (shouldSkipPackage({ dependencyBlacklist, dependencyWhitelist, packageName: peerDependencyName })) {
342
+ for (
343
+ const [peerDependencyName, range] of Object.entries(
344
+ requiredPeerDependencies,
345
+ )
346
+ ) {
347
+ if (
348
+ shouldSkipPackage({
349
+ dependencyBlacklist,
350
+ dependencyWhitelist,
351
+ packageName: peerDependencyName,
352
+ })
353
+ ) {
317
354
  continue;
318
355
  }
319
356
 
320
357
  if (!isValidRange(range)) {
321
- const message = `Unable to parse ${dependencyPackageJson.name}'s ${peerDependencyName} peer dependency range '${range}'.`;
358
+ const message =
359
+ `Unable to parse ${dependencyPackageJson.name}'s ${peerDependencyName} peer dependency range '${range}'.`;
322
360
  if (skipUnparseableRanges) {
323
361
  context.addWarning({ file: dependencyPackageJsonPath, message });
324
362
  continue;
@@ -328,26 +366,40 @@ function checkSatisfyPeerDependencies(context: Context, opts: Options) {
328
366
  if (allRequiredPeerDependencies[peerDependencyName] == null) {
329
367
  allRequiredPeerDependencies[peerDependencyName] = [];
330
368
  }
331
- allRequiredPeerDependencies[peerDependencyName].push({ fromPackageName: dependencyPackageJson.name!, range });
369
+ allRequiredPeerDependencies[peerDependencyName].push({
370
+ fromPackageName: dependencyPackageJson.name!,
371
+ range,
372
+ });
332
373
  }
333
374
  }
334
375
 
335
- for (const [peerDependencyName, peerDependencyRequirements] of Object.entries(allRequiredPeerDependencies)) {
376
+ for (
377
+ const [peerDependencyName, peerDependencyRequirements] of Object.entries(
378
+ allRequiredPeerDependencies,
379
+ )
380
+ ) {
336
381
  // for each inherited peer dependency, determine the strictest range
337
382
  let mostStrictPeerRequirement: IResolvedPeerDependencyRequirement = {
338
383
  fromPeerDependencyRequirements: [peerDependencyRequirements[0]],
339
384
  range: peerDependencyRequirements[0].range,
340
385
  };
341
386
  for (const peerRequirement of peerDependencyRequirements) {
342
- if (doesASatisfyB(mostStrictPeerRequirement.range, peerRequirement.range)) {
387
+ if (
388
+ doesASatisfyB(mostStrictPeerRequirement.range, peerRequirement.range)
389
+ ) {
343
390
  continue;
344
- } else if (doesASatisfyB(peerRequirement.range, mostStrictPeerRequirement.range)) {
391
+ } else if (
392
+ doesASatisfyB(peerRequirement.range, mostStrictPeerRequirement.range)
393
+ ) {
345
394
  mostStrictPeerRequirement = {
346
395
  fromPeerDependencyRequirements: [peerRequirement],
347
396
  range: peerRequirement.range,
348
397
  };
349
398
  } else {
350
- const maybeIntersection = findIntersection(peerRequirement.range, mostStrictPeerRequirement.range);
399
+ const maybeIntersection = findIntersection(
400
+ peerRequirement.range,
401
+ mostStrictPeerRequirement.range,
402
+ );
351
403
  if (maybeIntersection !== undefined) {
352
404
  mostStrictPeerRequirement = {
353
405
  fromPeerDependencyRequirements: [
@@ -360,9 +412,9 @@ function checkSatisfyPeerDependencies(context: Context, opts: Options) {
360
412
  context.addError({
361
413
  file: packageJsonPath,
362
414
  message:
363
- `[1] Package ${packageName} has conflicting inherited ${peerDependencyName} peer dependencies.\n\t` +
364
- `Dependency ${peerRequirement.fromPackageName} requires '${peerRequirement.range}' but\n\t` +
365
- getMostStrictStatement(mostStrictPeerRequirement),
415
+ `[1] Package ${packageName} has conflicting inherited ${peerDependencyName} peer dependencies.\n\t`
416
+ + `Dependency ${peerRequirement.fromPackageName} requires '${peerRequirement.range}' but\n\t`
417
+ + getMostStrictStatement(mostStrictPeerRequirement),
366
418
  });
367
419
  }
368
420
  }
@@ -373,31 +425,35 @@ function checkSatisfyPeerDependencies(context: Context, opts: Options) {
373
425
  const packageDependencyRange = packageDependencies[peerDependencyName];
374
426
  if (packageDependencyRange != null) {
375
427
  if (!isValidRange(packageDependencyRange)) {
376
- const message = `Unable to parse ${packageName}'s ${peerDependencyName} dependency range '${packageDependencyRange}'.`;
428
+ const message =
429
+ `Unable to parse ${packageName}'s ${peerDependencyName} dependency range '${packageDependencyRange}'.`;
377
430
  if (skipUnparseableRanges) {
378
431
  context.addWarning({ file: packageJsonPath, message });
379
432
  } else {
380
433
  throw new Error(message);
381
434
  }
382
- } else if (!doesASatisfyB(packageDependencyRange, mostStrictPeerRequirement.range)) {
435
+ } else if (
436
+ !doesASatisfyB(packageDependencyRange, mostStrictPeerRequirement.range)
437
+ ) {
383
438
  context.addError({
384
439
  file: packageJsonPath,
385
440
  message:
386
- `[2] Package ${packageName} dependency on ${peerDependencyName} '${packageDependencyRange}' does not satisfy inherited peer dependencies.\n\t` +
387
- getMostStrictStatement(mostStrictPeerRequirement),
441
+ `[2] Package ${packageName} dependency on ${peerDependencyName} '${packageDependencyRange}' does not satisfy inherited peer dependencies.\n\t`
442
+ + getMostStrictStatement(mostStrictPeerRequirement),
388
443
  });
389
444
  }
390
445
  }
391
446
 
392
447
  // for every inherited peer dependency, this package must declare a dependency or peer dependency
393
448
  // equal to or stricter than `mostStrictPeerRequirement`
394
- const packagePeerDependencyRange = packagePeerDependencies[peerDependencyName];
449
+ const packagePeerDependencyRange =
450
+ packagePeerDependencies[peerDependencyName];
395
451
  if (packageDependencyRange == null && packagePeerDependencyRange == null) {
396
452
  context.addError({
397
453
  file: packageJsonPath,
398
454
  message:
399
- `[3] Package ${packageName} is missing required ${peerDependencyName} dependency.\n\t` +
400
- getMostStrictStatement(mostStrictPeerRequirement),
455
+ `[3] Package ${packageName} is missing required ${peerDependencyName} dependency.\n\t`
456
+ + getMostStrictStatement(mostStrictPeerRequirement),
401
457
  fixer: getAddDependencyTypeFixer({
402
458
  packageJsonPath,
403
459
  dependencyType: "peerDependencies",
@@ -412,18 +468,24 @@ function checkSatisfyPeerDependencies(context: Context, opts: Options) {
412
468
  // the range must be equal to or stricter than `mostStrictPeerRequirement`
413
469
  if (packagePeerDependencyRange != null) {
414
470
  if (!isValidRange(packagePeerDependencyRange)) {
415
- const message = `Unable to parse ${packageName}'s ${peerDependencyName} peer dependency range '${packagePeerDependencyRange}'.`;
471
+ const message =
472
+ `Unable to parse ${packageName}'s ${peerDependencyName} peer dependency range '${packagePeerDependencyRange}'.`;
416
473
  if (skipUnparseableRanges) {
417
474
  context.addWarning({ file: packageJsonPath, message });
418
475
  } else {
419
476
  throw new Error(message);
420
477
  }
421
- } else if (!doesASatisfyB(packagePeerDependencyRange, mostStrictPeerRequirement.range)) {
478
+ } else if (
479
+ !doesASatisfyB(
480
+ packagePeerDependencyRange,
481
+ mostStrictPeerRequirement.range,
482
+ )
483
+ ) {
422
484
  context.addError({
423
485
  file: packageJsonPath,
424
486
  message:
425
- `[4] Package ${packageName} peer dependency on ${peerDependencyName} '${packagePeerDependencyRange}' is not strict enough.\n\t` +
426
- getMostStrictStatement(mostStrictPeerRequirement),
487
+ `[4] Package ${packageName} peer dependency on ${peerDependencyName} '${packagePeerDependencyRange}' is not strict enough.\n\t`
488
+ + getMostStrictStatement(mostStrictPeerRequirement),
427
489
  fixer: getAddDependencyTypeFixer({
428
490
  packageJsonPath,
429
491
  dependencyType: "peerDependencies",
@@ -448,28 +510,39 @@ function shouldSkipPackage({
448
510
  }) {
449
511
  // blacklist should take precedance
450
512
  if (
451
- (dependencyBlacklist != null && dependencyBlacklist.includes(packageName)) ||
452
- (dependencyWhitelist != null && !dependencyWhitelist.includes(packageName))
513
+ (dependencyBlacklist != null && dependencyBlacklist.includes(packageName))
514
+ || (dependencyWhitelist != null
515
+ && !dependencyWhitelist.includes(packageName))
453
516
  ) {
454
517
  return true;
455
518
  }
456
519
  return false;
457
520
  }
458
521
 
459
- function getMostStrictStatement(mostStrictPeerRequirement: IResolvedPeerDependencyRequirement) {
522
+ function getMostStrictStatement(
523
+ mostStrictPeerRequirement: IResolvedPeerDependencyRequirement,
524
+ ) {
460
525
  if (mostStrictPeerRequirement.fromPeerDependencyRequirements.length === 1) {
461
- const dependencyName = mostStrictPeerRequirement.fromPeerDependencyRequirements[0].fromPackageName;
526
+ const dependencyName =
527
+ mostStrictPeerRequirement.fromPeerDependencyRequirements[0]
528
+ .fromPackageName;
462
529
  return `Dependency ${dependencyName} requires '${mostStrictPeerRequirement.range}'.`;
463
530
  } else {
464
- const dependencyNames = mostStrictPeerRequirement.fromPeerDependencyRequirements
465
- .map((peerDependencyRequirement) => peerDependencyRequirement.fromPackageName)
531
+ const dependencyNames = mostStrictPeerRequirement
532
+ .fromPeerDependencyRequirements
533
+ .map((peerDependencyRequirement) =>
534
+ peerDependencyRequirement.fromPackageName
535
+ )
466
536
  .join(", ");
467
- const dependencyRequirements = mostStrictPeerRequirement.fromPeerDependencyRequirements
468
- .map((peerDependencyRequirement) => `'${peerDependencyRequirement.range}'`)
537
+ const dependencyRequirements = mostStrictPeerRequirement
538
+ .fromPeerDependencyRequirements
539
+ .map((peerDependencyRequirement) =>
540
+ `'${peerDependencyRequirement.range}'`
541
+ )
469
542
  .join(", ");
470
543
  return (
471
- `Dependencies [${dependencyNames}] require [${dependencyRequirements}] respectively, ` +
472
- `resolving to '${mostStrictPeerRequirement.range}'.`
544
+ `Dependencies [${dependencyNames}] require [${dependencyRequirements}] respectively, `
545
+ + `resolving to '${mostStrictPeerRequirement.range}'.`
473
546
  );
474
547
  }
475
548
  }
@@ -503,7 +576,10 @@ function getMostStrictStatement(mostStrictPeerRequirement: IResolvedPeerDependen
503
576
  * @param b version range that matches `RANGE_REGEX`
504
577
  * @returns the maximum intersecting `ValidRange`, or `undefined` if there is no intersection
505
578
  */
506
- export function findIntersection(a: ValidRange, b: ValidRange): ValidRange | undefined {
579
+ export function findIntersection(
580
+ a: ValidRange,
581
+ b: ValidRange,
582
+ ): ValidRange | undefined {
507
583
  if (doesASatisfyB(a, b)) {
508
584
  return a;
509
585
  } else if (doesASatisfyB(b, a)) {
@@ -536,7 +612,9 @@ export function findIntersection(a: ValidRange, b: ValidRange): ValidRange | und
536
612
  .map((bVersion) => {
537
613
  const bSemVer = coerce(bVersion)!;
538
614
  if (bVersion.startsWith("^") && bSemVer.major >= aSemVer.major) {
539
- return `^${bSemVer.compare(aSemVer) >= 0 ? bSemVer.raw : aSemVer.raw}`;
615
+ return `^${
616
+ bSemVer.compare(aSemVer) >= 0 ? bSemVer.raw : aSemVer.raw
617
+ }`;
540
618
  }
541
619
  return bSemVer.compare(aSemVer) !== -1 ? bVersion : undefined;
542
620
  })
@@ -555,7 +633,9 @@ export function findIntersection(a: ValidRange, b: ValidRange): ValidRange | und
555
633
  .map((aVersion) => {
556
634
  const aSemVer = coerce(aVersion)!;
557
635
  if (aVersion.startsWith("^") && aSemVer.major >= bSemVer.major) {
558
- return `^${aSemVer.compare(bSemVer) >= 0 ? aSemVer.raw : bSemVer.raw}`;
636
+ return `^${
637
+ aSemVer.compare(bSemVer) >= 0 ? aSemVer.raw : bSemVer.raw
638
+ }`;
559
639
  }
560
640
  return aSemVer.compare(bSemVer) !== -1 ? aVersion : undefined;
561
641
  })
@@ -569,14 +649,26 @@ export function findIntersection(a: ValidRange, b: ValidRange): ValidRange | und
569
649
  const compatibleVersions = aVersions
570
650
  .map((aVersion) => {
571
651
  const aSemVer = coerce(aVersion)!;
572
- const majorMatchingBVersion = bVersions.find((m) => coerce(m)!.major === aSemVer.major);
652
+ const majorMatchingBVersion = bVersions.find((m) =>
653
+ coerce(m)!.major === aSemVer.major
654
+ );
573
655
  if (majorMatchingBVersion === undefined) {
574
656
  // there is no intersecting `b` major version for this `a` major version
575
657
  return undefined;
576
658
  }
577
- if (doesASatisfyB(aVersion as ValidRange, majorMatchingBVersion as ValidRange)) {
659
+ if (
660
+ doesASatisfyB(
661
+ aVersion as ValidRange,
662
+ majorMatchingBVersion as ValidRange,
663
+ )
664
+ ) {
578
665
  return aVersion;
579
- } else if (doesASatisfyB(majorMatchingBVersion as ValidRange, aVersion as ValidRange)) {
666
+ } else if (
667
+ doesASatisfyB(
668
+ majorMatchingBVersion as ValidRange,
669
+ aVersion as ValidRange,
670
+ )
671
+ ) {
580
672
  return majorMatchingBVersion;
581
673
  } else {
582
674
  return undefined;
@@ -665,7 +757,9 @@ export function doesASatisfyB(a: ValidRange, b: ValidRange): boolean {
665
757
 
666
758
  return aVersions.every((aVersion) => {
667
759
  const aSemVer = coerce(aVersion)!;
668
- const majorMatchingBVersion = bVersions.find((m) => coerce(m)!.major === aSemVer.major);
760
+ const majorMatchingBVersion = bVersions.find((m) =>
761
+ coerce(m)!.major === aSemVer.major
762
+ );
669
763
  if (majorMatchingBVersion === undefined) {
670
764
  // `a` permits a major version that is not permitted by `b`, therefore `a` is "less strict"
671
765
  return false;
@@ -673,7 +767,9 @@ export function doesASatisfyB(a: ValidRange, b: ValidRange): boolean {
673
767
 
674
768
  const aVersionIsRange = isMajorVersionRange(aVersion);
675
769
  const majorMatchingBSemVer = coerce(majorMatchingBVersion)!;
676
- const majorMatchingBVersionIsRange = isMajorVersionRange(majorMatchingBVersion);
770
+ const majorMatchingBVersionIsRange = isMajorVersionRange(
771
+ majorMatchingBVersion,
772
+ );
677
773
 
678
774
  if (majorMatchingBVersionIsRange) {
679
775
  // `a` satisfies `b` so long as `aSemVer` is greater than or equal to `majorMatchingBSemVer`
@@ -21,38 +21,51 @@ export const nestedWorkspaces = createRuleFactory({
21
21
  const rootPackageJson = context.getWorkspaceContext().getPackageJson();
22
22
 
23
23
  // Expand a set of globs covering all package.json files in the entire repo (except the root)
24
- const packageJsonPaths = globby.globbySync(["*/**/package.json", "!**/node_modules/**"]);
24
+ const packageJsonPaths = globby.globbySync([
25
+ "*/**/package.json",
26
+ "!**/node_modules/**",
27
+ ]);
25
28
 
26
29
  const workspaces = Array.isArray(rootPackageJson.workspaces)
27
30
  ? rootPackageJson.workspaces
28
31
  : rootPackageJson.workspaces !== undefined
29
- ? rootPackageJson.workspaces.packages
30
- : undefined;
32
+ ? rootPackageJson.workspaces.packages
33
+ : undefined;
31
34
 
32
35
  if (workspaces === undefined && packageJsonPaths.length > 0) {
33
36
  context.addError({
34
37
  file: context.getPackageJsonPath(),
35
- message: 'The "workspace" field is missing, even though there are workspaces in the repository.',
38
+ message:
39
+ "The \"workspace\" field is missing, even though there are workspaces in the repository.",
36
40
  });
37
41
  return;
38
42
  }
39
43
 
40
44
  // Build a set of globs for each package.json that exists in packages specified by a workspace.
41
- const workspacePackageJsons = (workspaces || []).map((item) => `${item}/package.json`);
45
+ const workspacePackageJsons = (workspaces || []).map((item) =>
46
+ `${item}/package.json`
47
+ );
42
48
 
43
49
  // Expand the globs to get an array of all package.json files that are in packages specified by a workspace.
44
- const expandedWorkspacesGlobs = globby.globbySync([...workspacePackageJsons, "!**/node_modules/**"]);
50
+ const expandedWorkspacesGlobs = globby.globbySync([
51
+ ...workspacePackageJsons,
52
+ "!**/node_modules/**",
53
+ ]);
45
54
 
46
55
  // Ensure there are no package.jsons which are not included in the globbed workspaces set
47
- const difference = packageJsonPaths.filter((packageJsonPath) => !expandedWorkspacesGlobs.includes(packageJsonPath));
56
+ const difference = packageJsonPaths.filter((packageJsonPath) =>
57
+ !expandedWorkspacesGlobs.includes(packageJsonPath)
58
+ );
48
59
 
49
60
  if (difference.length !== 0) {
50
- const differencesList = difference.map((packageJsonPath) => path.dirname(packageJsonPath)).join(", ");
61
+ const differencesList = difference.map((packageJsonPath) =>
62
+ path.dirname(packageJsonPath)
63
+ ).join(", ");
51
64
  context.addError({
52
65
  file: context.getPackageJsonPath(),
53
66
  message:
54
- `The "workspace" field is missing one or more values: ${differencesList}. ` +
55
- 'You may be able to use a glob to avoid listing each workspace individually, e.g. "packages/nested-workspace/*".',
67
+ `The "workspace" field is missing one or more values: ${differencesList}. `
68
+ + "You may be able to use a glob to avoid listing each workspace individually, e.g. \"packages/nested-workspace/*\".",
56
69
  });
57
70
  }
58
71
  },
@@ -18,7 +18,7 @@ export const Options = r.Union(
18
18
  .And(
19
19
  r.Partial({
20
20
  entriesExist: r.Undefined,
21
- })
21
+ }),
22
22
  ),
23
23
  r
24
24
  .Record({
@@ -27,12 +27,12 @@ export const Options = r.Union(
27
27
  .And(
28
28
  r.Partial({
29
29
  entries: r.Undefined,
30
- })
30
+ }),
31
31
  ),
32
32
  r.Record({
33
33
  entries: r.Dictionary(r.Unknown), // string => unknown, enforces existence of keys and their values
34
34
  entriesExist: r.Array(r.String),
35
- })
35
+ }),
36
36
  );
37
37
 
38
38
  export type Options = r.Static<typeof Options>;
@@ -46,21 +46,28 @@ export const packageEntry = createRuleFactory<Options>({
46
46
  for (const key of Object.keys(options.entries)) {
47
47
  const value = options.entries[key];
48
48
 
49
- const entryDiff = diff(JSON.stringify(value) + "\n", (JSON.stringify(packageJson[key]) || "") + "\n");
49
+ const entryDiff = diff(
50
+ JSON.stringify(value) + "\n",
51
+ (JSON.stringify(packageJson[key]) || "") + "\n",
52
+ );
50
53
  if (
51
- (typeof value !== "object" && value !== packageJson[key]) ||
52
- entryDiff == null ||
53
- !entryDiff.includes("Compared values have no visual difference")
54
+ (typeof value !== "object" && value !== packageJson[key])
55
+ || entryDiff == null
56
+ || !entryDiff.includes("Compared values have no visual difference")
54
57
  ) {
55
58
  context.addError({
56
59
  file: context.getPackageJsonPath(),
57
60
  message: createStandardizedEntryErrorMessage(key),
58
61
  longMessage: entryDiff,
59
62
  fixer: () => {
60
- mutateJson<PackageJson>(context.getPackageJsonPath(), context.host, (input) => {
61
- input[key] = value;
62
- return input;
63
- });
63
+ mutateJson<PackageJson>(
64
+ context.getPackageJsonPath(),
65
+ context.host,
66
+ (input) => {
67
+ input[key] = value;
68
+ return input;
69
+ },
70
+ );
64
71
  },
65
72
  });
66
73
  }
@@ -57,9 +57,13 @@ export const packageOrder = createRuleFactory<Options>({
57
57
  const packageJson = context.getPackageJson();
58
58
  const packagePath = context.getPackageJsonPath();
59
59
 
60
- const order: string[] | OrderFunction = opts === undefined ? defaultKeyOrder : opts.order;
60
+ const order: string[] | OrderFunction = opts === undefined
61
+ ? defaultKeyOrder
62
+ : opts.order;
61
63
 
62
- const comparator = isOrderFunction(order) ? order(context) : createComparator(order);
64
+ const comparator = isOrderFunction(order)
65
+ ? order(context)
66
+ : createComparator(order);
63
67
 
64
68
  const actualOrder = Object.keys(packageJson);
65
69
  const expectedOrder = actualOrder.slice().sort(comparator); // sort mutates, so we need to copy the previous result
@@ -118,6 +122,8 @@ function createComparator(order: ReadonlyArray<string>) {
118
122
  };
119
123
  }
120
124
 
121
- function isOrderFunction(order: ReadonlyArray<string> | OrderFunction): order is OrderFunction {
125
+ function isOrderFunction(
126
+ order: ReadonlyArray<string> | OrderFunction,
127
+ ): order is OrderFunction {
122
128
  return !Array.isArray(order);
123
129
  }