@monorepolint/rules 0.6.0-alpha.1 → 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.
- package/.turbo/turbo-clean.log +1 -1
- package/.turbo/turbo-compile-typescript.log +1 -1
- package/.turbo/turbo-lint.log +1 -1
- package/.turbo/turbo-test.log +272 -667
- package/.turbo/turbo-transpile-typescript.log +5 -5
- package/CHANGELOG.md +42 -0
- package/build/js/index.js +411 -263
- package/build/js/index.js.map +1 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/__tests__/utils.d.ts +4 -10
- package/build/types/__tests__/utils.d.ts.map +1 -1
- package/build/types/bannedDependencies.d.ts.map +1 -1
- package/build/types/fileContents.d.ts +1 -1
- package/build/types/fileContents.d.ts.map +1 -1
- package/build/types/index.d.ts +3 -3
- package/build/types/index.d.ts.map +1 -1
- package/build/types/mustSatisfyPeerDependencies.d.ts.map +1 -1
- package/build/types/nestedWorkspaces.d.ts.map +1 -1
- package/build/types/packageEntry.d.ts.map +1 -1
- package/build/types/packageOrder.d.ts.map +1 -1
- package/build/types/packageScript.d.ts.map +1 -1
- package/build/types/requireDependency.d.ts +12 -12
- package/build/types/requireDependency.d.ts.map +1 -1
- package/build/types/standardTsconfig.d.ts.map +1 -1
- package/build/types/util/checkAlpha.d.ts.map +1 -1
- package/build/types/util/createRuleFactory.d.ts.map +1 -1
- package/build/types/util/packageDependencyGraphService.d.ts.map +1 -1
- package/coverage/base.css +224 -0
- package/coverage/block-navigation.js +87 -0
- package/coverage/clover.xml +1887 -0
- package/coverage/coverage-final.json +19 -0
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +131 -0
- package/coverage/prettify.css +1 -0
- package/coverage/prettify.js +2 -0
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +196 -0
- package/coverage/src/alphabeticalDependencies.ts.html +142 -0
- package/coverage/src/alphabeticalScripts.ts.html +136 -0
- package/coverage/src/bannedDependencies.ts.html +610 -0
- package/coverage/src/consistentDependencies.ts.html +394 -0
- package/coverage/src/consistentVersions.ts.html +619 -0
- package/coverage/src/fileContents.ts.html +409 -0
- package/coverage/src/index.html +311 -0
- package/coverage/src/index.ts.html +169 -0
- package/coverage/src/mustSatisfyPeerDependencies.ts.html +2605 -0
- package/coverage/src/nestedWorkspaces.ts.html +304 -0
- package/coverage/src/packageEntry.ts.html +376 -0
- package/coverage/src/packageOrder.ts.html +472 -0
- package/coverage/src/packageScript.ts.html +436 -0
- package/coverage/src/requireDependency.ts.html +349 -0
- package/coverage/src/standardTsconfig.ts.html +553 -0
- package/coverage/src/util/checkAlpha.ts.html +271 -0
- package/coverage/src/util/createRuleFactory.ts.html +196 -0
- package/coverage/src/util/index.html +161 -0
- package/coverage/src/util/makeDirectory.ts.html +157 -0
- package/coverage/src/util/packageDependencyGraphService.ts.html +508 -0
- package/package.json +15 -20
- package/src/__tests__/alphabeticalScripts.spec.ts +13 -5
- package/src/__tests__/bannedDependencies.spec.ts +47 -18
- package/src/__tests__/consistentDependencies.spec.ts +12 -6
- package/src/__tests__/consistentVersions.spec.ts +74 -20
- package/src/__tests__/fileContents.spec.ts +11 -7
- package/src/__tests__/mustSatisfyPeerDependencies.spec.ts +193 -78
- package/src/__tests__/nestedWorkspaces.spec.ts +12 -8
- package/src/__tests__/packageEntry.spec.ts +55 -49
- package/src/__tests__/packageOrder.spec.ts +78 -72
- package/src/__tests__/packageScript.spec.ts +27 -13
- package/src/__tests__/requireDependency.spec.ts +13 -7
- package/src/__tests__/utils.ts +18 -9
- package/src/bannedDependencies.ts +32 -15
- package/src/consistentDependencies.ts +22 -9
- package/src/consistentVersions.ts +84 -47
- package/src/fileContents.ts +24 -10
- package/src/index.ts +3 -3
- package/src/mustSatisfyPeerDependencies.ts +162 -66
- package/src/nestedWorkspaces.ts +23 -10
- package/src/packageEntry.ts +18 -11
- package/src/packageOrder.ts +9 -3
- package/src/packageScript.ts +37 -19
- package/src/requireDependency.ts +28 -11
- package/src/standardTsconfig.ts +32 -10
- package/src/util/checkAlpha.ts +5 -2
- package/src/util/createRuleFactory.ts +6 -2
- package/src/util/packageDependencyGraphService.ts +41 -14
- package/vitest.config.mjs +17 -0
- package/jest.config.cjs +0 -4
package/build/js/index.js
CHANGED
|
@@ -113,11 +113,19 @@ var PackageDependencyGraphService = class {
|
|
|
113
113
|
if (maxDepth == null || nextDepth <= maxDepth) {
|
|
114
114
|
const dependencies = packageJson.dependencies != null ? Object.keys(packageJson.dependencies) : [];
|
|
115
115
|
for (const dependency of dependencies) {
|
|
116
|
-
const dependencyPackageJsonPath = resolvePackagePath(
|
|
116
|
+
const dependencyPackageJsonPath = resolvePackagePath(
|
|
117
|
+
dependency,
|
|
118
|
+
node.paths.rootDirectory
|
|
119
|
+
);
|
|
117
120
|
if (dependencyPackageJsonPath == null) {
|
|
118
|
-
throw new Error(
|
|
121
|
+
throw new Error(
|
|
122
|
+
`Could not resolve ${dependency} from ${node.paths.rootDirectory}`
|
|
123
|
+
);
|
|
119
124
|
}
|
|
120
|
-
node.dependencies.set(
|
|
125
|
+
node.dependencies.set(
|
|
126
|
+
dependency,
|
|
127
|
+
visit(dependencyPackageJsonPath, nextDepth)
|
|
128
|
+
);
|
|
121
129
|
}
|
|
122
130
|
}
|
|
123
131
|
return node;
|
|
@@ -178,17 +186,17 @@ var bannedDependencies = createRuleFactory({
|
|
|
178
186
|
const curDeps = packageJson.dependencies && Object.keys(packageJson.dependencies);
|
|
179
187
|
const curDevDeps = packageJson.devDependencies && Object.keys(packageJson.devDependencies);
|
|
180
188
|
const curPeerDeps = packageJson.peerDependencies && Object.keys(packageJson.peerDependencies);
|
|
181
|
-
const {
|
|
189
|
+
const {
|
|
190
|
+
bannedDependencies: banned,
|
|
191
|
+
bannedTransitiveDependencies: transitives
|
|
192
|
+
} = opts;
|
|
182
193
|
const globs = banned && (Array.isArray(banned) ? banned : banned.glob);
|
|
183
194
|
const exacts = banned && (Array.isArray(banned) ? void 0 : banned.exact);
|
|
184
195
|
const violations = /* @__PURE__ */ new Set();
|
|
185
196
|
if (globs) {
|
|
186
|
-
if (curDeps)
|
|
187
|
-
|
|
188
|
-
if (
|
|
189
|
-
populateProblemsGlobs(globs, curDevDeps, violations);
|
|
190
|
-
if (curPeerDeps)
|
|
191
|
-
populateProblemsGlobs(globs, curPeerDeps, violations);
|
|
197
|
+
if (curDeps) populateProblemsGlobs(globs, curDeps, violations);
|
|
198
|
+
if (curDevDeps) populateProblemsGlobs(globs, curDevDeps, violations);
|
|
199
|
+
if (curPeerDeps) populateProblemsGlobs(globs, curPeerDeps, violations);
|
|
192
200
|
}
|
|
193
201
|
if (exacts) {
|
|
194
202
|
let set = setCache.get(exacts);
|
|
@@ -196,12 +204,9 @@ var bannedDependencies = createRuleFactory({
|
|
|
196
204
|
set = new Set(exacts);
|
|
197
205
|
setCache.set(exacts, set);
|
|
198
206
|
}
|
|
199
|
-
if (curDeps)
|
|
200
|
-
|
|
201
|
-
if (
|
|
202
|
-
populateProblemsExact(set, curDevDeps, violations);
|
|
203
|
-
if (curPeerDeps)
|
|
204
|
-
populateProblemsExact(set, curPeerDeps, violations);
|
|
207
|
+
if (curDeps) populateProblemsExact(set, curDeps, violations);
|
|
208
|
+
if (curDevDeps) populateProblemsExact(set, curDevDeps, violations);
|
|
209
|
+
if (curPeerDeps) populateProblemsExact(set, curPeerDeps, violations);
|
|
205
210
|
}
|
|
206
211
|
if (violations.size > 0) {
|
|
207
212
|
context.addError({
|
|
@@ -241,12 +246,18 @@ function populateProblemsGlobs(bannedDependencyGlobs, dependencies, violations)
|
|
|
241
246
|
}
|
|
242
247
|
function checkTransitives(context, banned) {
|
|
243
248
|
const graphService = new PackageDependencyGraphService();
|
|
244
|
-
const root = graphService.buildDependencyGraph(
|
|
249
|
+
const root = graphService.buildDependencyGraph(
|
|
250
|
+
path2.resolve(context.getPackageJsonPath()),
|
|
251
|
+
context.host
|
|
252
|
+
);
|
|
245
253
|
for (const { dependencies, importPath } of graphService.traverse(root)) {
|
|
246
254
|
for (const [dependency] of dependencies) {
|
|
247
255
|
if (banned.has(dependency)) {
|
|
248
256
|
const [, ...importPathWithoutRoot] = importPath;
|
|
249
|
-
const pathing = [
|
|
257
|
+
const pathing = [
|
|
258
|
+
...importPathWithoutRoot.map(nameOrPackageJsonPath),
|
|
259
|
+
dependency
|
|
260
|
+
].join(" -> ");
|
|
250
261
|
context.addError({
|
|
251
262
|
file: root.paths.packageJsonPath,
|
|
252
263
|
message: `Banned transitive dependencies in repo: ${pathing}`
|
|
@@ -313,7 +324,9 @@ function filterKeys(ob, filterOb) {
|
|
|
313
324
|
}
|
|
314
325
|
function omit(obj, keysToOmit) {
|
|
315
326
|
const newObj = {};
|
|
316
|
-
const filtered = Object.entries(obj).filter(
|
|
327
|
+
const filtered = Object.entries(obj).filter(
|
|
328
|
+
([key]) => !keysToOmit.includes(key)
|
|
329
|
+
);
|
|
317
330
|
for (const [key, value] of filtered) {
|
|
318
331
|
newObj[key] = value;
|
|
319
332
|
}
|
|
@@ -337,16 +350,26 @@ function checkConsistentVersions(context, options) {
|
|
|
337
350
|
options.matchDependencyVersions
|
|
338
351
|
)) {
|
|
339
352
|
if (Array.isArray(expectedPackageDependencyValue)) {
|
|
340
|
-
ensurePackageMatchesSomeVersion(
|
|
353
|
+
ensurePackageMatchesSomeVersion(
|
|
354
|
+
context,
|
|
355
|
+
dependencyPackageName,
|
|
356
|
+
expectedPackageDependencyValue
|
|
357
|
+
);
|
|
341
358
|
} else {
|
|
342
|
-
ensurePackageIsCorrectVersion(
|
|
359
|
+
ensurePackageIsCorrectVersion(
|
|
360
|
+
context,
|
|
361
|
+
dependencyPackageName,
|
|
362
|
+
expectedPackageDependencyValue
|
|
363
|
+
);
|
|
343
364
|
}
|
|
344
365
|
}
|
|
345
366
|
}
|
|
346
367
|
var ensurePackageIsCorrectVersion = (context, dependencyPackageName, expectedPackageDependencyValue) => {
|
|
347
368
|
const packageJson = context.getPackageJson();
|
|
348
369
|
const packageJsonPath = context.getPackageJsonPath();
|
|
349
|
-
const expectedPackageDependencyVersion = coerce(
|
|
370
|
+
const expectedPackageDependencyVersion = coerce(
|
|
371
|
+
expectedPackageDependencyValue
|
|
372
|
+
);
|
|
350
373
|
if (expectedPackageDependencyVersion == null) {
|
|
351
374
|
throw new Error(
|
|
352
375
|
`Malformed expected package dependency version defined in monorepolint configuration: ${dependencyPackageName} @ '${expectedPackageDependencyValue}'`
|
|
@@ -365,7 +388,9 @@ var ensurePackageIsCorrectVersion = (context, dependencyPackageName, expectedPac
|
|
|
365
388
|
});
|
|
366
389
|
}
|
|
367
390
|
const actualPackageDevDependencyValue = packageJson.devDependencies && packageJson.devDependencies[dependencyPackageName];
|
|
368
|
-
const actualPackageDevDependencyVersion = coerce(
|
|
391
|
+
const actualPackageDevDependencyVersion = coerce(
|
|
392
|
+
actualPackageDevDependencyValue
|
|
393
|
+
);
|
|
369
394
|
if (actualPackageDevDependencyVersion != null && actualPackageDevDependencyVersion.raw !== expectedPackageDependencyVersion.raw) {
|
|
370
395
|
context.addError({
|
|
371
396
|
file: packageJsonPath,
|
|
@@ -382,7 +407,9 @@ var ensurePackageMatchesSomeVersion = (context, dependencyPackageName, acceptedP
|
|
|
382
407
|
const packageJsonPath = context.getPackageJsonPath();
|
|
383
408
|
const acceptedPackageDependencyVersions = acceptedPackageDependencyValues.map(
|
|
384
409
|
(acceptedPackageDependencyValue) => {
|
|
385
|
-
const acceptedPackageDependencyVersion = coerce(
|
|
410
|
+
const acceptedPackageDependencyVersion = coerce(
|
|
411
|
+
acceptedPackageDependencyValue
|
|
412
|
+
);
|
|
386
413
|
if (acceptedPackageDependencyVersion == null) {
|
|
387
414
|
throw new Error(
|
|
388
415
|
`Malformed accepted package dependency version defined in monorepolint configuration: ${dependencyPackageName} @ '${acceptedPackageDependencyValue}'`
|
|
@@ -404,7 +431,9 @@ var ensurePackageMatchesSomeVersion = (context, dependencyPackageName, acceptedP
|
|
|
404
431
|
});
|
|
405
432
|
}
|
|
406
433
|
const actualPackageDevDependencyValue = packageJson.devDependencies && packageJson.devDependencies[dependencyPackageName];
|
|
407
|
-
const actualPackageDevDependencyVersion = coerce(
|
|
434
|
+
const actualPackageDevDependencyVersion = coerce(
|
|
435
|
+
actualPackageDevDependencyValue
|
|
436
|
+
);
|
|
408
437
|
if (actualPackageDevDependencyVersion != null && acceptedPackageDependencyVersions.every(
|
|
409
438
|
(acceptedPackageDependencyVersion) => actualPackageDevDependencyVersion.raw !== acceptedPackageDependencyVersion.raw
|
|
410
439
|
)) {
|
|
@@ -431,7 +460,7 @@ var Options4 = r4.Union(
|
|
|
431
460
|
r4.Record({
|
|
432
461
|
file: r4.String,
|
|
433
462
|
generator: r4.Undefined.optional(),
|
|
434
|
-
template: r4.String,
|
|
463
|
+
template: r4.String.Or(r4.Undefined),
|
|
435
464
|
templateFile: r4.Undefined.optional()
|
|
436
465
|
}),
|
|
437
466
|
r4.Record({
|
|
@@ -449,17 +478,20 @@ var fileContents = createRuleFactory({
|
|
|
449
478
|
const pathExists = context.host.exists(fullPath);
|
|
450
479
|
const actualContent = pathExists ? context.host.readFile(fullPath, { encoding: "utf-8" }) : void 0;
|
|
451
480
|
if (actualContent !== expectedContent) {
|
|
481
|
+
const longMessage = pathExists && expectedContent == void 0 ? void 0 : diff3(expectedContent, actualContent, { expand: true });
|
|
482
|
+
const message = pathExists && expectedContent == void 0 ? "File should not exist" : "Expect file contents to match";
|
|
452
483
|
context.addError({
|
|
453
484
|
file: fullPath,
|
|
454
|
-
message
|
|
455
|
-
longMessage
|
|
485
|
+
message,
|
|
486
|
+
longMessage,
|
|
456
487
|
fixer: () => {
|
|
457
488
|
if (expectedContent === void 0) {
|
|
458
|
-
if (pathExists)
|
|
459
|
-
context.host.deleteFile(fullPath);
|
|
489
|
+
if (pathExists) context.host.deleteFile(fullPath);
|
|
460
490
|
} else {
|
|
461
491
|
context.host.mkdir(path3.dirname(fullPath), { recursive: true });
|
|
462
|
-
context.host.writeFile(fullPath, expectedContent, {
|
|
492
|
+
context.host.writeFile(fullPath, expectedContent, {
|
|
493
|
+
encoding: "utf-8"
|
|
494
|
+
});
|
|
463
495
|
}
|
|
464
496
|
}
|
|
465
497
|
});
|
|
@@ -494,9 +526,9 @@ async function getExpectedContents(context, opts) {
|
|
|
494
526
|
// src/mustSatisfyPeerDependencies.ts
|
|
495
527
|
import { mutateJson as mutateJson2 } from "@monorepolint/utils";
|
|
496
528
|
import * as path4 from "node:path";
|
|
529
|
+
import resolvePackagePath2 from "resolve-package-path";
|
|
497
530
|
import * as r5 from "runtypes";
|
|
498
531
|
import { coerce as coerce2 } from "semver";
|
|
499
|
-
import resolvePackagePath2 from "resolve-package-path";
|
|
500
532
|
var Options5 = r5.Union(
|
|
501
533
|
r5.Partial({
|
|
502
534
|
skipUnparseableRanges: r5.Undefined,
|
|
@@ -647,15 +679,26 @@ var MATCH_GREATER_OR_EQUAL_VERSION_RANGE = /^>= ?\d+(?:\.\d+|\.\d+\.\d+(?:-((?:0
|
|
|
647
679
|
var MATCH_MAJOR_VERSION_RANGE = /^(?:\^?\d+|\^?\d+\.x|\^?\d+\.x\.x|\^\d+\.\d+|\^\d+\.\d+\.x|\^\d+\.\d+\.\d+(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?)$/;
|
|
648
680
|
var RANGE_REGEX = /^(\*|x|>= ?\d+(?:\.\d+|\.\d+\.\d+(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?)?|\^?\d+(\.x|\.x\.x|\.\d+|\.\d+\.x|\.\d+\.\d+(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?)?( \|\| \^?\d+(\.x|\.x\.x|\.\d+|\.\d+\.x|\.\d+\.\d+(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?)?)*)$/;
|
|
649
681
|
function checkSatisfyPeerDependencies(context, opts) {
|
|
650
|
-
const {
|
|
682
|
+
const {
|
|
683
|
+
dependencyBlacklist,
|
|
684
|
+
dependencyWhitelist,
|
|
685
|
+
enforceForDevDependencies,
|
|
686
|
+
skipUnparseableRanges
|
|
687
|
+
} = opts;
|
|
651
688
|
const packageJsonPath = path4.resolve(context.getPackageJsonPath());
|
|
652
689
|
const packageJson = context.host.readJson(packageJsonPath);
|
|
653
690
|
const packageDependencies = packageJson.dependencies || {};
|
|
654
691
|
const packageDevDependencies = packageJson.devDependencies || {};
|
|
655
692
|
const packagePeerDependencies = packageJson.peerDependencies || {};
|
|
656
693
|
const packageName = packageJson.name || packageJsonPath;
|
|
657
|
-
for (const [peerDependencyName, peerDependencyRange] of Object.entries(
|
|
658
|
-
|
|
694
|
+
for (const [peerDependencyName, peerDependencyRange] of Object.entries(
|
|
695
|
+
packagePeerDependencies
|
|
696
|
+
)) {
|
|
697
|
+
if (shouldSkipPackage({
|
|
698
|
+
dependencyBlacklist,
|
|
699
|
+
dependencyWhitelist,
|
|
700
|
+
packageName: peerDependencyName
|
|
701
|
+
})) {
|
|
659
702
|
continue;
|
|
660
703
|
}
|
|
661
704
|
const dependencyRange = packageDependencies[peerDependencyName];
|
|
@@ -668,19 +711,35 @@ function checkSatisfyPeerDependencies(context, opts) {
|
|
|
668
711
|
}
|
|
669
712
|
}
|
|
670
713
|
const allRequiredPeerDependencies = {};
|
|
671
|
-
const allDependencies = enforceForDevDependencies ? [
|
|
714
|
+
const allDependencies = enforceForDevDependencies ? [
|
|
715
|
+
...Object.keys(packageDependencies),
|
|
716
|
+
...Object.keys(packageDevDependencies)
|
|
717
|
+
] : Object.keys(packageDependencies);
|
|
672
718
|
for (const dependency of allDependencies) {
|
|
673
|
-
const dependencyPackageJsonPath = resolvePackagePath2(
|
|
719
|
+
const dependencyPackageJsonPath = resolvePackagePath2(
|
|
720
|
+
dependency,
|
|
721
|
+
path4.dirname(packageJsonPath)
|
|
722
|
+
);
|
|
674
723
|
if (dependencyPackageJsonPath == null) {
|
|
675
|
-
throw new Error(
|
|
724
|
+
throw new Error(
|
|
725
|
+
`Could not resolve ${dependency} from ${path4.dirname(packageJsonPath)}`
|
|
726
|
+
);
|
|
676
727
|
}
|
|
677
|
-
const dependencyPackageJson = context.host.readJson(
|
|
728
|
+
const dependencyPackageJson = context.host.readJson(
|
|
729
|
+
dependencyPackageJsonPath
|
|
730
|
+
);
|
|
678
731
|
const requiredPeerDependencies = dependencyPackageJson.peerDependencies;
|
|
679
732
|
if (requiredPeerDependencies == null) {
|
|
680
733
|
continue;
|
|
681
734
|
}
|
|
682
|
-
for (const [peerDependencyName, range] of Object.entries(
|
|
683
|
-
|
|
735
|
+
for (const [peerDependencyName, range] of Object.entries(
|
|
736
|
+
requiredPeerDependencies
|
|
737
|
+
)) {
|
|
738
|
+
if (shouldSkipPackage({
|
|
739
|
+
dependencyBlacklist,
|
|
740
|
+
dependencyWhitelist,
|
|
741
|
+
packageName: peerDependencyName
|
|
742
|
+
})) {
|
|
684
743
|
continue;
|
|
685
744
|
}
|
|
686
745
|
if (!isValidRange(range)) {
|
|
@@ -694,10 +753,15 @@ function checkSatisfyPeerDependencies(context, opts) {
|
|
|
694
753
|
if (allRequiredPeerDependencies[peerDependencyName] == null) {
|
|
695
754
|
allRequiredPeerDependencies[peerDependencyName] = [];
|
|
696
755
|
}
|
|
697
|
-
allRequiredPeerDependencies[peerDependencyName].push({
|
|
756
|
+
allRequiredPeerDependencies[peerDependencyName].push({
|
|
757
|
+
fromPackageName: dependencyPackageJson.name,
|
|
758
|
+
range
|
|
759
|
+
});
|
|
698
760
|
}
|
|
699
761
|
}
|
|
700
|
-
for (const [peerDependencyName, peerDependencyRequirements] of Object.entries(
|
|
762
|
+
for (const [peerDependencyName, peerDependencyRequirements] of Object.entries(
|
|
763
|
+
allRequiredPeerDependencies
|
|
764
|
+
)) {
|
|
701
765
|
let mostStrictPeerRequirement = {
|
|
702
766
|
fromPeerDependencyRequirements: [peerDependencyRequirements[0]],
|
|
703
767
|
range: peerDependencyRequirements[0].range
|
|
@@ -711,7 +775,10 @@ function checkSatisfyPeerDependencies(context, opts) {
|
|
|
711
775
|
range: peerRequirement.range
|
|
712
776
|
};
|
|
713
777
|
} else {
|
|
714
|
-
const maybeIntersection = findIntersection(
|
|
778
|
+
const maybeIntersection = findIntersection(
|
|
779
|
+
peerRequirement.range,
|
|
780
|
+
mostStrictPeerRequirement.range
|
|
781
|
+
);
|
|
715
782
|
if (maybeIntersection !== void 0) {
|
|
716
783
|
mostStrictPeerRequirement = {
|
|
717
784
|
fromPeerDependencyRequirements: [
|
|
@@ -770,7 +837,10 @@ function checkSatisfyPeerDependencies(context, opts) {
|
|
|
770
837
|
} else {
|
|
771
838
|
throw new Error(message);
|
|
772
839
|
}
|
|
773
|
-
} else if (!doesASatisfyB(
|
|
840
|
+
} else if (!doesASatisfyB(
|
|
841
|
+
packagePeerDependencyRange,
|
|
842
|
+
mostStrictPeerRequirement.range
|
|
843
|
+
)) {
|
|
774
844
|
context.addError({
|
|
775
845
|
file: packageJsonPath,
|
|
776
846
|
message: `[4] Package ${packageName} peer dependency on ${peerDependencyName} '${packagePeerDependencyRange}' is not strict enough.
|
|
@@ -802,8 +872,12 @@ function getMostStrictStatement(mostStrictPeerRequirement) {
|
|
|
802
872
|
const dependencyName = mostStrictPeerRequirement.fromPeerDependencyRequirements[0].fromPackageName;
|
|
803
873
|
return `Dependency ${dependencyName} requires '${mostStrictPeerRequirement.range}'.`;
|
|
804
874
|
} else {
|
|
805
|
-
const dependencyNames = mostStrictPeerRequirement.fromPeerDependencyRequirements.map(
|
|
806
|
-
|
|
875
|
+
const dependencyNames = mostStrictPeerRequirement.fromPeerDependencyRequirements.map(
|
|
876
|
+
(peerDependencyRequirement) => peerDependencyRequirement.fromPackageName
|
|
877
|
+
).join(", ");
|
|
878
|
+
const dependencyRequirements = mostStrictPeerRequirement.fromPeerDependencyRequirements.map(
|
|
879
|
+
(peerDependencyRequirement) => `'${peerDependencyRequirement.range}'`
|
|
880
|
+
).join(", ");
|
|
807
881
|
return `Dependencies [${dependencyNames}] require [${dependencyRequirements}] respectively, resolving to '${mostStrictPeerRequirement.range}'.`;
|
|
808
882
|
}
|
|
809
883
|
}
|
|
@@ -853,13 +927,21 @@ function findIntersection(a, b) {
|
|
|
853
927
|
}
|
|
854
928
|
const compatibleVersions = aVersions.map((aVersion) => {
|
|
855
929
|
const aSemVer = coerce2(aVersion);
|
|
856
|
-
const majorMatchingBVersion = bVersions.find(
|
|
930
|
+
const majorMatchingBVersion = bVersions.find(
|
|
931
|
+
(m) => coerce2(m).major === aSemVer.major
|
|
932
|
+
);
|
|
857
933
|
if (majorMatchingBVersion === void 0) {
|
|
858
934
|
return void 0;
|
|
859
935
|
}
|
|
860
|
-
if (doesASatisfyB(
|
|
936
|
+
if (doesASatisfyB(
|
|
937
|
+
aVersion,
|
|
938
|
+
majorMatchingBVersion
|
|
939
|
+
)) {
|
|
861
940
|
return aVersion;
|
|
862
|
-
} else if (doesASatisfyB(
|
|
941
|
+
} else if (doesASatisfyB(
|
|
942
|
+
majorMatchingBVersion,
|
|
943
|
+
aVersion
|
|
944
|
+
)) {
|
|
863
945
|
return majorMatchingBVersion;
|
|
864
946
|
} else {
|
|
865
947
|
return void 0;
|
|
@@ -900,13 +982,17 @@ function doesASatisfyB(a, b) {
|
|
|
900
982
|
}
|
|
901
983
|
return aVersions.every((aVersion) => {
|
|
902
984
|
const aSemVer = coerce2(aVersion);
|
|
903
|
-
const majorMatchingBVersion = bVersions.find(
|
|
985
|
+
const majorMatchingBVersion = bVersions.find(
|
|
986
|
+
(m) => coerce2(m).major === aSemVer.major
|
|
987
|
+
);
|
|
904
988
|
if (majorMatchingBVersion === void 0) {
|
|
905
989
|
return false;
|
|
906
990
|
}
|
|
907
991
|
const aVersionIsRange = isMajorVersionRange(aVersion);
|
|
908
992
|
const majorMatchingBSemVer = coerce2(majorMatchingBVersion);
|
|
909
|
-
const majorMatchingBVersionIsRange = isMajorVersionRange(
|
|
993
|
+
const majorMatchingBVersionIsRange = isMajorVersionRange(
|
|
994
|
+
majorMatchingBVersion
|
|
995
|
+
);
|
|
910
996
|
if (majorMatchingBVersionIsRange) {
|
|
911
997
|
return aSemVer.compare(majorMatchingBSemVer) !== -1;
|
|
912
998
|
} else {
|
|
@@ -948,12 +1034,133 @@ function getAddDependencyTypeFixer({
|
|
|
948
1034
|
};
|
|
949
1035
|
}
|
|
950
1036
|
|
|
951
|
-
// src/
|
|
952
|
-
import
|
|
1037
|
+
// src/nestedWorkspaces.ts
|
|
1038
|
+
import * as globby from "globby";
|
|
1039
|
+
import * as path5 from "node:path";
|
|
953
1040
|
import * as r6 from "runtypes";
|
|
954
|
-
var Options6 = r6.
|
|
955
|
-
|
|
956
|
-
|
|
1041
|
+
var Options6 = r6.Undefined;
|
|
1042
|
+
var nestedWorkspaces = createRuleFactory({
|
|
1043
|
+
name: "nestedWorkspaces",
|
|
1044
|
+
check: (context) => {
|
|
1045
|
+
const rootPackageJson = context.getWorkspaceContext().getPackageJson();
|
|
1046
|
+
const packageJsonPaths = globby.globbySync([
|
|
1047
|
+
"*/**/package.json",
|
|
1048
|
+
"!**/node_modules/**"
|
|
1049
|
+
]);
|
|
1050
|
+
const workspaces = Array.isArray(rootPackageJson.workspaces) ? rootPackageJson.workspaces : rootPackageJson.workspaces !== void 0 ? rootPackageJson.workspaces.packages : void 0;
|
|
1051
|
+
if (workspaces === void 0 && packageJsonPaths.length > 0) {
|
|
1052
|
+
context.addError({
|
|
1053
|
+
file: context.getPackageJsonPath(),
|
|
1054
|
+
message: 'The "workspace" field is missing, even though there are workspaces in the repository.'
|
|
1055
|
+
});
|
|
1056
|
+
return;
|
|
1057
|
+
}
|
|
1058
|
+
const workspacePackageJsons = (workspaces || []).map(
|
|
1059
|
+
(item) => `${item}/package.json`
|
|
1060
|
+
);
|
|
1061
|
+
const expandedWorkspacesGlobs = globby.globbySync([
|
|
1062
|
+
...workspacePackageJsons,
|
|
1063
|
+
"!**/node_modules/**"
|
|
1064
|
+
]);
|
|
1065
|
+
const difference = packageJsonPaths.filter(
|
|
1066
|
+
(packageJsonPath) => !expandedWorkspacesGlobs.includes(packageJsonPath)
|
|
1067
|
+
);
|
|
1068
|
+
if (difference.length !== 0) {
|
|
1069
|
+
const differencesList = difference.map(
|
|
1070
|
+
(packageJsonPath) => path5.dirname(packageJsonPath)
|
|
1071
|
+
).join(", ");
|
|
1072
|
+
context.addError({
|
|
1073
|
+
file: context.getPackageJsonPath(),
|
|
1074
|
+
message: `The "workspace" field is missing one or more values: ${differencesList}. You may be able to use a glob to avoid listing each workspace individually, e.g. "packages/nested-workspace/*".`
|
|
1075
|
+
});
|
|
1076
|
+
}
|
|
1077
|
+
},
|
|
1078
|
+
validateOptions: Options6.check
|
|
1079
|
+
});
|
|
1080
|
+
|
|
1081
|
+
// src/packageEntry.ts
|
|
1082
|
+
import { mutateJson as mutateJson3 } from "@monorepolint/utils";
|
|
1083
|
+
import { diff as diff4 } from "jest-diff";
|
|
1084
|
+
import * as r7 from "runtypes";
|
|
1085
|
+
var Options7 = r7.Union(
|
|
1086
|
+
r7.Record({
|
|
1087
|
+
entries: r7.Dictionary(r7.Unknown)
|
|
1088
|
+
// string => unknown, enforces existence of keys and their values
|
|
1089
|
+
}).And(
|
|
1090
|
+
r7.Partial({
|
|
1091
|
+
entriesExist: r7.Undefined
|
|
1092
|
+
})
|
|
1093
|
+
),
|
|
1094
|
+
r7.Record({
|
|
1095
|
+
entriesExist: r7.Array(r7.String)
|
|
1096
|
+
// enforces existence of keys, but not values
|
|
1097
|
+
}).And(
|
|
1098
|
+
r7.Partial({
|
|
1099
|
+
entries: r7.Undefined
|
|
1100
|
+
})
|
|
1101
|
+
),
|
|
1102
|
+
r7.Record({
|
|
1103
|
+
entries: r7.Dictionary(r7.Unknown),
|
|
1104
|
+
// string => unknown, enforces existence of keys and their values
|
|
1105
|
+
entriesExist: r7.Array(r7.String)
|
|
1106
|
+
})
|
|
1107
|
+
);
|
|
1108
|
+
var packageEntry = createRuleFactory({
|
|
1109
|
+
name: "packageEntry",
|
|
1110
|
+
check: (context, options) => {
|
|
1111
|
+
const packageJson = context.getPackageJson();
|
|
1112
|
+
if (options.entries) {
|
|
1113
|
+
for (const key of Object.keys(options.entries)) {
|
|
1114
|
+
const value = options.entries[key];
|
|
1115
|
+
const entryDiff = diff4(
|
|
1116
|
+
JSON.stringify(value) + "\n",
|
|
1117
|
+
(JSON.stringify(packageJson[key]) || "") + "\n"
|
|
1118
|
+
);
|
|
1119
|
+
if (typeof value !== "object" && value !== packageJson[key] || entryDiff == null || !entryDiff.includes("Compared values have no visual difference")) {
|
|
1120
|
+
context.addError({
|
|
1121
|
+
file: context.getPackageJsonPath(),
|
|
1122
|
+
message: createStandardizedEntryErrorMessage(key),
|
|
1123
|
+
longMessage: entryDiff,
|
|
1124
|
+
fixer: () => {
|
|
1125
|
+
mutateJson3(
|
|
1126
|
+
context.getPackageJsonPath(),
|
|
1127
|
+
context.host,
|
|
1128
|
+
(input) => {
|
|
1129
|
+
input[key] = value;
|
|
1130
|
+
return input;
|
|
1131
|
+
}
|
|
1132
|
+
);
|
|
1133
|
+
}
|
|
1134
|
+
});
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
if (options.entriesExist) {
|
|
1139
|
+
for (const key of options.entriesExist) {
|
|
1140
|
+
if (packageJson[key] === void 0) {
|
|
1141
|
+
context.addError({
|
|
1142
|
+
file: context.getPackageJsonPath(),
|
|
1143
|
+
message: createExpectedEntryErrorMessage(key)
|
|
1144
|
+
});
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
},
|
|
1149
|
+
validateOptions: Options7.check
|
|
1150
|
+
});
|
|
1151
|
+
function createStandardizedEntryErrorMessage(key) {
|
|
1152
|
+
return `Expected standardized entry for '${key}'`;
|
|
1153
|
+
}
|
|
1154
|
+
function createExpectedEntryErrorMessage(key) {
|
|
1155
|
+
return `Expected entry for '${key}' to exist`;
|
|
1156
|
+
}
|
|
1157
|
+
|
|
1158
|
+
// src/packageOrder.ts
|
|
1159
|
+
import { diff as diff5 } from "jest-diff";
|
|
1160
|
+
import * as r8 from "runtypes";
|
|
1161
|
+
var Options8 = r8.Record({
|
|
1162
|
+
order: r8.Union(r8.Array(r8.String), r8.Function)
|
|
1163
|
+
}).Or(r8.Undefined);
|
|
957
1164
|
var defaultKeyOrder = [
|
|
958
1165
|
"name",
|
|
959
1166
|
"version",
|
|
@@ -998,7 +1205,7 @@ var packageOrder = createRuleFactory({
|
|
|
998
1205
|
context.addError({
|
|
999
1206
|
file: packagePath,
|
|
1000
1207
|
message: "Incorrect order of fields in package.json",
|
|
1001
|
-
longMessage:
|
|
1208
|
+
longMessage: diff5(expectedOrder, actualOrder, { expand: true }),
|
|
1002
1209
|
fixer: () => {
|
|
1003
1210
|
const expectedPackageJson = {};
|
|
1004
1211
|
expectedOrder.forEach((key) => {
|
|
@@ -1009,7 +1216,7 @@ var packageOrder = createRuleFactory({
|
|
|
1009
1216
|
});
|
|
1010
1217
|
}
|
|
1011
1218
|
},
|
|
1012
|
-
validateOptions:
|
|
1219
|
+
validateOptions: Options8.check
|
|
1013
1220
|
});
|
|
1014
1221
|
function arrayOrderCompare2(a, b) {
|
|
1015
1222
|
for (let index = 0; index < a.length; index++) {
|
|
@@ -1040,87 +1247,17 @@ function isOrderFunction(order) {
|
|
|
1040
1247
|
return !Array.isArray(order);
|
|
1041
1248
|
}
|
|
1042
1249
|
|
|
1043
|
-
// src/packageEntry.ts
|
|
1044
|
-
import { mutateJson as mutateJson3 } from "@monorepolint/utils";
|
|
1045
|
-
import { diff as diff5 } from "jest-diff";
|
|
1046
|
-
import * as r7 from "runtypes";
|
|
1047
|
-
var Options7 = r7.Union(
|
|
1048
|
-
r7.Record({
|
|
1049
|
-
entries: r7.Dictionary(r7.Unknown)
|
|
1050
|
-
// string => unknown, enforces existence of keys and their values
|
|
1051
|
-
}).And(
|
|
1052
|
-
r7.Partial({
|
|
1053
|
-
entriesExist: r7.Undefined
|
|
1054
|
-
})
|
|
1055
|
-
),
|
|
1056
|
-
r7.Record({
|
|
1057
|
-
entriesExist: r7.Array(r7.String)
|
|
1058
|
-
// enforces existence of keys, but not values
|
|
1059
|
-
}).And(
|
|
1060
|
-
r7.Partial({
|
|
1061
|
-
entries: r7.Undefined
|
|
1062
|
-
})
|
|
1063
|
-
),
|
|
1064
|
-
r7.Record({
|
|
1065
|
-
entries: r7.Dictionary(r7.Unknown),
|
|
1066
|
-
// string => unknown, enforces existence of keys and their values
|
|
1067
|
-
entriesExist: r7.Array(r7.String)
|
|
1068
|
-
})
|
|
1069
|
-
);
|
|
1070
|
-
var packageEntry = createRuleFactory({
|
|
1071
|
-
name: "packageEntry",
|
|
1072
|
-
check: (context, options) => {
|
|
1073
|
-
const packageJson = context.getPackageJson();
|
|
1074
|
-
if (options.entries) {
|
|
1075
|
-
for (const key of Object.keys(options.entries)) {
|
|
1076
|
-
const value = options.entries[key];
|
|
1077
|
-
const entryDiff = diff5(JSON.stringify(value) + "\n", (JSON.stringify(packageJson[key]) || "") + "\n");
|
|
1078
|
-
if (typeof value !== "object" && value !== packageJson[key] || entryDiff == null || !entryDiff.includes("Compared values have no visual difference")) {
|
|
1079
|
-
context.addError({
|
|
1080
|
-
file: context.getPackageJsonPath(),
|
|
1081
|
-
message: createStandardizedEntryErrorMessage(key),
|
|
1082
|
-
longMessage: entryDiff,
|
|
1083
|
-
fixer: () => {
|
|
1084
|
-
mutateJson3(context.getPackageJsonPath(), context.host, (input) => {
|
|
1085
|
-
input[key] = value;
|
|
1086
|
-
return input;
|
|
1087
|
-
});
|
|
1088
|
-
}
|
|
1089
|
-
});
|
|
1090
|
-
}
|
|
1091
|
-
}
|
|
1092
|
-
}
|
|
1093
|
-
if (options.entriesExist) {
|
|
1094
|
-
for (const key of options.entriesExist) {
|
|
1095
|
-
if (packageJson[key] === void 0) {
|
|
1096
|
-
context.addError({
|
|
1097
|
-
file: context.getPackageJsonPath(),
|
|
1098
|
-
message: createExpectedEntryErrorMessage(key)
|
|
1099
|
-
});
|
|
1100
|
-
}
|
|
1101
|
-
}
|
|
1102
|
-
}
|
|
1103
|
-
},
|
|
1104
|
-
validateOptions: Options7.check
|
|
1105
|
-
});
|
|
1106
|
-
function createStandardizedEntryErrorMessage(key) {
|
|
1107
|
-
return `Expected standardized entry for '${key}'`;
|
|
1108
|
-
}
|
|
1109
|
-
function createExpectedEntryErrorMessage(key) {
|
|
1110
|
-
return `Expected entry for '${key}' to exist`;
|
|
1111
|
-
}
|
|
1112
|
-
|
|
1113
1250
|
// src/packageScript.ts
|
|
1114
1251
|
import { mutateJson as mutateJson4 } from "@monorepolint/utils";
|
|
1115
1252
|
import { diff as diff6 } from "jest-diff";
|
|
1116
|
-
import * as
|
|
1117
|
-
var
|
|
1118
|
-
scripts:
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
options:
|
|
1123
|
-
fixValue:
|
|
1253
|
+
import * as r9 from "runtypes";
|
|
1254
|
+
var Options9 = r9.Record({
|
|
1255
|
+
scripts: r9.Dictionary(
|
|
1256
|
+
r9.Union(
|
|
1257
|
+
r9.String,
|
|
1258
|
+
r9.Record({
|
|
1259
|
+
options: r9.Array(r9.String.Or(r9.Undefined)),
|
|
1260
|
+
fixValue: r9.Union(r9.String, r9.Undefined, r9.Literal(false)).optional()
|
|
1124
1261
|
})
|
|
1125
1262
|
)
|
|
1126
1263
|
)
|
|
@@ -1136,10 +1273,14 @@ var packageScript = createRuleFactory({
|
|
|
1136
1273
|
file: context.getPackageJsonPath(),
|
|
1137
1274
|
message: MSG_NO_SCRIPTS_BLOCK,
|
|
1138
1275
|
fixer: () => {
|
|
1139
|
-
mutateJson4(
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1276
|
+
mutateJson4(
|
|
1277
|
+
context.getPackageJsonPath(),
|
|
1278
|
+
context.host,
|
|
1279
|
+
(input) => {
|
|
1280
|
+
input.scripts = {};
|
|
1281
|
+
return input;
|
|
1282
|
+
}
|
|
1283
|
+
);
|
|
1143
1284
|
}
|
|
1144
1285
|
});
|
|
1145
1286
|
return;
|
|
@@ -1168,43 +1309,127 @@ var packageScript = createRuleFactory({
|
|
|
1168
1309
|
if (fixValue !== false && (fixValue !== void 0 || fixToEmpty === true)) {
|
|
1169
1310
|
const q = fixValue;
|
|
1170
1311
|
fixer = () => {
|
|
1171
|
-
mutateJson4(
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1312
|
+
mutateJson4(
|
|
1313
|
+
context.getPackageJsonPath(),
|
|
1314
|
+
context.host,
|
|
1315
|
+
(input) => {
|
|
1316
|
+
if (fixToEmpty && q === void 0) {
|
|
1317
|
+
delete input.scripts[name];
|
|
1318
|
+
} else {
|
|
1319
|
+
input.scripts[name] = q;
|
|
1320
|
+
}
|
|
1321
|
+
return input;
|
|
1176
1322
|
}
|
|
1177
|
-
|
|
1178
|
-
});
|
|
1323
|
+
);
|
|
1179
1324
|
};
|
|
1180
1325
|
}
|
|
1181
1326
|
const validOptionsString = Array.from(allowedValues.values()).map((a) => a === void 0 ? "(empty)" : `'${a}'`).join(", ");
|
|
1182
1327
|
context.addError({
|
|
1183
1328
|
file: context.getPackageJsonPath(),
|
|
1184
1329
|
message: `Expected standardized script entry for '${name}'. Valid options: ${validOptionsString}`,
|
|
1185
|
-
longMessage: diff6(
|
|
1330
|
+
longMessage: diff6(
|
|
1331
|
+
validOptionsString + "\n",
|
|
1332
|
+
(packageJson.scripts[name] || "") + "\n"
|
|
1333
|
+
),
|
|
1186
1334
|
fixer
|
|
1187
1335
|
});
|
|
1188
1336
|
}
|
|
1189
1337
|
}
|
|
1190
1338
|
},
|
|
1191
|
-
validateOptions:
|
|
1339
|
+
validateOptions: Options9.check
|
|
1340
|
+
});
|
|
1341
|
+
|
|
1342
|
+
// src/requireDependency.ts
|
|
1343
|
+
import { mutateJson as mutateJson5 } from "@monorepolint/utils";
|
|
1344
|
+
import { diff as diff7 } from "jest-diff";
|
|
1345
|
+
import * as r10 from "runtypes";
|
|
1346
|
+
var Options10 = r10.Partial({
|
|
1347
|
+
dependencies: r10.Dictionary(r10.String.optional()),
|
|
1348
|
+
devDependencies: r10.Dictionary(r10.String.optional()),
|
|
1349
|
+
peerDependencies: r10.Dictionary(r10.String.optional()),
|
|
1350
|
+
optionalDependencies: r10.Dictionary(r10.String.optional())
|
|
1351
|
+
});
|
|
1352
|
+
var requireDependency = createRuleFactory({
|
|
1353
|
+
name: "requireDependency",
|
|
1354
|
+
check: function expectPackageEntry(context, options) {
|
|
1355
|
+
const packageJson = context.getPackageJson();
|
|
1356
|
+
const packageJsonPath = context.getPackageJsonPath();
|
|
1357
|
+
[
|
|
1358
|
+
"dependencies",
|
|
1359
|
+
"devDependencies",
|
|
1360
|
+
"peerDependencies",
|
|
1361
|
+
"optionalDependencies"
|
|
1362
|
+
].forEach((type) => {
|
|
1363
|
+
var _a;
|
|
1364
|
+
const expectedEntries = options[type];
|
|
1365
|
+
if (!expectedEntries) {
|
|
1366
|
+
return;
|
|
1367
|
+
}
|
|
1368
|
+
if (packageJson[type] === void 0) {
|
|
1369
|
+
context.addError({
|
|
1370
|
+
file: packageJsonPath,
|
|
1371
|
+
message: `No ${type} block, cannot add required ${type}.`,
|
|
1372
|
+
fixer: () => {
|
|
1373
|
+
mutateJson5(packageJsonPath, context.host, (input) => {
|
|
1374
|
+
input[type] = Object.fromEntries(
|
|
1375
|
+
Object.entries(expectedEntries).filter(
|
|
1376
|
+
([, v]) => v !== void 0
|
|
1377
|
+
)
|
|
1378
|
+
);
|
|
1379
|
+
return input;
|
|
1380
|
+
});
|
|
1381
|
+
}
|
|
1382
|
+
});
|
|
1383
|
+
return;
|
|
1384
|
+
}
|
|
1385
|
+
for (const [dep, version] of Object.entries(options[type])) {
|
|
1386
|
+
if (((_a = packageJson[type]) == null ? void 0 : _a[dep]) !== version) {
|
|
1387
|
+
context.addError({
|
|
1388
|
+
file: packageJsonPath,
|
|
1389
|
+
message: `Expected dependency ${dep}@${version}`,
|
|
1390
|
+
longMessage: diff7(
|
|
1391
|
+
`${dep}@${version}
|
|
1392
|
+
`,
|
|
1393
|
+
`${dep}@${packageJson[type][dep] || "missing"}
|
|
1394
|
+
`
|
|
1395
|
+
),
|
|
1396
|
+
fixer: () => {
|
|
1397
|
+
mutateJson5(
|
|
1398
|
+
packageJsonPath,
|
|
1399
|
+
context.host,
|
|
1400
|
+
(input) => {
|
|
1401
|
+
if (version === void 0) {
|
|
1402
|
+
input[type] = { ...input[type] };
|
|
1403
|
+
delete input[type][dep];
|
|
1404
|
+
} else {
|
|
1405
|
+
input[type] = { ...input[type], [dep]: version };
|
|
1406
|
+
}
|
|
1407
|
+
return input;
|
|
1408
|
+
}
|
|
1409
|
+
);
|
|
1410
|
+
}
|
|
1411
|
+
});
|
|
1412
|
+
}
|
|
1413
|
+
}
|
|
1414
|
+
});
|
|
1415
|
+
},
|
|
1416
|
+
validateOptions: Options10.check
|
|
1192
1417
|
});
|
|
1193
1418
|
|
|
1194
1419
|
// src/standardTsconfig.ts
|
|
1195
1420
|
import { matchesAnyGlob as matchesAnyGlob2 } from "@monorepolint/utils";
|
|
1196
|
-
import { diff as
|
|
1197
|
-
import * as
|
|
1198
|
-
import * as
|
|
1421
|
+
import { diff as diff8 } from "jest-diff";
|
|
1422
|
+
import * as path6 from "path";
|
|
1423
|
+
import * as r11 from "runtypes";
|
|
1199
1424
|
var DEFAULT_TSCONFIG_FILENAME = "tsconfig.json";
|
|
1200
|
-
var
|
|
1201
|
-
file:
|
|
1202
|
-
generator:
|
|
1203
|
-
tsconfigReferenceFile:
|
|
1204
|
-
template:
|
|
1205
|
-
templateFile:
|
|
1206
|
-
excludedReferences:
|
|
1207
|
-
additionalReferences:
|
|
1425
|
+
var Options11 = r11.Partial({
|
|
1426
|
+
file: r11.String,
|
|
1427
|
+
generator: r11.Function,
|
|
1428
|
+
tsconfigReferenceFile: r11.String,
|
|
1429
|
+
template: r11.Record({}).Or(r11.String),
|
|
1430
|
+
templateFile: r11.String,
|
|
1431
|
+
excludedReferences: r11.Array(r11.String).Or(r11.Undefined),
|
|
1432
|
+
additionalReferences: r11.Array(r11.String).Or(r11.Undefined)
|
|
1208
1433
|
}).withConstraint(({ generator, template, templateFile }) => {
|
|
1209
1434
|
let count = 0;
|
|
1210
1435
|
if (generator) {
|
|
@@ -1222,7 +1447,7 @@ var standardTsconfig = createRuleFactory({
|
|
|
1222
1447
|
name: "standardTsconfig",
|
|
1223
1448
|
check: async (context, opts) => {
|
|
1224
1449
|
const tsconfigFileName = opts.file ?? DEFAULT_TSCONFIG_FILENAME;
|
|
1225
|
-
const fullPath =
|
|
1450
|
+
const fullPath = path6.resolve(context.packageDir, tsconfigFileName);
|
|
1226
1451
|
const generator = getGenerator(context, opts);
|
|
1227
1452
|
const expectedContent = await generator(context);
|
|
1228
1453
|
const actualContent = context.host.exists(fullPath) ? context.host.readFile(fullPath, { encoding: "utf-8" }) : void 0;
|
|
@@ -1237,7 +1462,7 @@ var standardTsconfig = createRuleFactory({
|
|
|
1237
1462
|
context.addError({
|
|
1238
1463
|
file: fullPath,
|
|
1239
1464
|
message: "Expect file contents to match",
|
|
1240
|
-
longMessage:
|
|
1465
|
+
longMessage: diff8(expectedContent, actualContent, { expand: true }),
|
|
1241
1466
|
fixer: () => {
|
|
1242
1467
|
context.host.writeFile(fullPath, expectedContent, {
|
|
1243
1468
|
encoding: "utf-8"
|
|
@@ -1246,18 +1471,30 @@ var standardTsconfig = createRuleFactory({
|
|
|
1246
1471
|
});
|
|
1247
1472
|
}
|
|
1248
1473
|
},
|
|
1249
|
-
validateOptions:
|
|
1474
|
+
validateOptions: Options11.check
|
|
1250
1475
|
});
|
|
1251
1476
|
function getGenerator(context, opts) {
|
|
1252
1477
|
if (opts.generator) {
|
|
1253
1478
|
return opts.generator;
|
|
1254
1479
|
} else if (opts.templateFile) {
|
|
1255
1480
|
const { packageDir: workspacePackageDir } = context.getWorkspaceContext();
|
|
1256
|
-
const fullPath =
|
|
1257
|
-
const template = JSON.parse(
|
|
1258
|
-
|
|
1481
|
+
const fullPath = path6.resolve(workspacePackageDir, opts.templateFile);
|
|
1482
|
+
const template = JSON.parse(
|
|
1483
|
+
context.host.readFile(fullPath, { encoding: "utf-8" })
|
|
1484
|
+
);
|
|
1485
|
+
return makeGenerator(
|
|
1486
|
+
template,
|
|
1487
|
+
opts.excludedReferences,
|
|
1488
|
+
opts.additionalReferences,
|
|
1489
|
+
opts.tsconfigReferenceFile
|
|
1490
|
+
);
|
|
1259
1491
|
} else if (opts.template) {
|
|
1260
|
-
return makeGenerator(
|
|
1492
|
+
return makeGenerator(
|
|
1493
|
+
opts.template,
|
|
1494
|
+
opts.excludedReferences,
|
|
1495
|
+
opts.additionalReferences,
|
|
1496
|
+
opts.tsconfigReferenceFile
|
|
1497
|
+
);
|
|
1261
1498
|
} else {
|
|
1262
1499
|
throw new Error("Unable to make generator");
|
|
1263
1500
|
}
|
|
@@ -1270,13 +1507,16 @@ function makeGenerator(template, excludedReferences, additionalReferences, tscon
|
|
|
1270
1507
|
};
|
|
1271
1508
|
const nameToDirectory = await context.getWorkspaceContext().getPackageNameToDir();
|
|
1272
1509
|
const packageJson = context.getPackageJson();
|
|
1273
|
-
const deps = [
|
|
1510
|
+
const deps = [
|
|
1511
|
+
...Object.keys(packageJson.dependencies || {}),
|
|
1512
|
+
...Object.keys(packageJson.devDependencies || {})
|
|
1513
|
+
];
|
|
1274
1514
|
for (const dep of deps) {
|
|
1275
1515
|
const packageDir = nameToDirectory.get(dep);
|
|
1276
1516
|
if (packageDir !== void 0 && (excludedReferences === void 0 || !matchesAnyGlob2(dep, excludedReferences))) {
|
|
1277
|
-
const absoluteReferencePath = tsconfigReferenceFile !== void 0 ?
|
|
1517
|
+
const absoluteReferencePath = tsconfigReferenceFile !== void 0 ? path6.join(packageDir, tsconfigReferenceFile) : packageDir;
|
|
1278
1518
|
template.references.push({
|
|
1279
|
-
path:
|
|
1519
|
+
path: path6.relative(context.packageDir, absoluteReferencePath)
|
|
1280
1520
|
});
|
|
1281
1521
|
}
|
|
1282
1522
|
}
|
|
@@ -1290,98 +1530,6 @@ function makeGenerator(template, excludedReferences, additionalReferences, tscon
|
|
|
1290
1530
|
return JSON.stringify(template, void 0, 2) + "\n";
|
|
1291
1531
|
};
|
|
1292
1532
|
}
|
|
1293
|
-
|
|
1294
|
-
// src/nestedWorkspaces.ts
|
|
1295
|
-
import * as globby from "globby";
|
|
1296
|
-
import * as path6 from "node:path";
|
|
1297
|
-
import * as r10 from "runtypes";
|
|
1298
|
-
var Options10 = r10.Undefined;
|
|
1299
|
-
var nestedWorkspaces = createRuleFactory({
|
|
1300
|
-
name: "nestedWorkspaces",
|
|
1301
|
-
check: (context) => {
|
|
1302
|
-
const rootPackageJson = context.getWorkspaceContext().getPackageJson();
|
|
1303
|
-
const packageJsonPaths = globby.globbySync(["*/**/package.json", "!**/node_modules/**"]);
|
|
1304
|
-
const workspaces = Array.isArray(rootPackageJson.workspaces) ? rootPackageJson.workspaces : rootPackageJson.workspaces !== void 0 ? rootPackageJson.workspaces.packages : void 0;
|
|
1305
|
-
if (workspaces === void 0 && packageJsonPaths.length > 0) {
|
|
1306
|
-
context.addError({
|
|
1307
|
-
file: context.getPackageJsonPath(),
|
|
1308
|
-
message: 'The "workspace" field is missing, even though there are workspaces in the repository.'
|
|
1309
|
-
});
|
|
1310
|
-
return;
|
|
1311
|
-
}
|
|
1312
|
-
const workspacePackageJsons = (workspaces || []).map((item) => `${item}/package.json`);
|
|
1313
|
-
const expandedWorkspacesGlobs = globby.globbySync([...workspacePackageJsons, "!**/node_modules/**"]);
|
|
1314
|
-
const difference = packageJsonPaths.filter((packageJsonPath) => !expandedWorkspacesGlobs.includes(packageJsonPath));
|
|
1315
|
-
if (difference.length !== 0) {
|
|
1316
|
-
const differencesList = difference.map((packageJsonPath) => path6.dirname(packageJsonPath)).join(", ");
|
|
1317
|
-
context.addError({
|
|
1318
|
-
file: context.getPackageJsonPath(),
|
|
1319
|
-
message: `The "workspace" field is missing one or more values: ${differencesList}. You may be able to use a glob to avoid listing each workspace individually, e.g. "packages/nested-workspace/*".`
|
|
1320
|
-
});
|
|
1321
|
-
}
|
|
1322
|
-
},
|
|
1323
|
-
validateOptions: Options10.check
|
|
1324
|
-
});
|
|
1325
|
-
|
|
1326
|
-
// src/requireDependency.ts
|
|
1327
|
-
import { mutateJson as mutateJson5 } from "@monorepolint/utils";
|
|
1328
|
-
import { diff as diff8 } from "jest-diff";
|
|
1329
|
-
import * as r11 from "runtypes";
|
|
1330
|
-
var Options11 = r11.Partial({
|
|
1331
|
-
dependencies: r11.Dictionary(r11.String),
|
|
1332
|
-
devDependencies: r11.Dictionary(r11.String),
|
|
1333
|
-
peerDependencies: r11.Dictionary(r11.String),
|
|
1334
|
-
optionalDependencies: r11.Dictionary(r11.String)
|
|
1335
|
-
});
|
|
1336
|
-
var requireDependency = createRuleFactory({
|
|
1337
|
-
name: "requireDependency",
|
|
1338
|
-
check: function expectPackageEntry(context, options) {
|
|
1339
|
-
const packageJson = context.getPackageJson();
|
|
1340
|
-
const packageJsonPath = context.getPackageJsonPath();
|
|
1341
|
-
[
|
|
1342
|
-
"dependencies",
|
|
1343
|
-
"devDependencies",
|
|
1344
|
-
"peerDependencies",
|
|
1345
|
-
"optionalDependencies"
|
|
1346
|
-
].forEach((type) => {
|
|
1347
|
-
var _a;
|
|
1348
|
-
if (!options[type]) {
|
|
1349
|
-
return;
|
|
1350
|
-
}
|
|
1351
|
-
if (packageJson[type] === void 0) {
|
|
1352
|
-
context.addError({
|
|
1353
|
-
file: packageJsonPath,
|
|
1354
|
-
message: `No ${type} block, cannot add required ${type}.`,
|
|
1355
|
-
fixer: () => {
|
|
1356
|
-
mutateJson5(packageJsonPath, context.host, (input) => {
|
|
1357
|
-
input[type] = options[type];
|
|
1358
|
-
return input;
|
|
1359
|
-
});
|
|
1360
|
-
}
|
|
1361
|
-
});
|
|
1362
|
-
return;
|
|
1363
|
-
}
|
|
1364
|
-
for (const [dep, version] of Object.entries(options[type])) {
|
|
1365
|
-
if (((_a = packageJson[type]) == null ? void 0 : _a[dep]) !== version) {
|
|
1366
|
-
context.addError({
|
|
1367
|
-
file: packageJsonPath,
|
|
1368
|
-
message: `Expected dependency ${dep}@${version}`,
|
|
1369
|
-
longMessage: diff8(`${dep}@${version}
|
|
1370
|
-
`, `${dep}@${packageJson[type][dep] || "missing"}
|
|
1371
|
-
`),
|
|
1372
|
-
fixer: () => {
|
|
1373
|
-
mutateJson5(packageJsonPath, context.host, (input) => {
|
|
1374
|
-
input[type] = { ...input[type], [dep]: version };
|
|
1375
|
-
return input;
|
|
1376
|
-
});
|
|
1377
|
-
}
|
|
1378
|
-
});
|
|
1379
|
-
}
|
|
1380
|
-
}
|
|
1381
|
-
});
|
|
1382
|
-
},
|
|
1383
|
-
validateOptions: Options11.check
|
|
1384
|
-
});
|
|
1385
1533
|
export {
|
|
1386
1534
|
alphabeticalDependencies,
|
|
1387
1535
|
alphabeticalScripts,
|