@monorepolint/rules 0.6.0-alpha.2 → 0.6.0-alpha.4
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 +161 -102
- package/.turbo/turbo-transpile-typescript.log +4 -4
- package/CHANGELOG.md +19 -0
- package/build/js/index.js +429 -241
- package/build/js/index.js.map +1 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/__tests__/utils.d.ts +0 -1
- 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.map +1 -1
- package/build/types/forceError.d.ts +4 -0
- package/build/types/forceError.d.ts.map +1 -0
- package/build/types/index.d.ts +5 -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/oncePerPackage.d.ts +11 -0
- package/build/types/oncePerPackage.d.ts.map +1 -0
- 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/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/clover.xml +1201 -813
- package/coverage/coverage-final.json +20 -18
- package/coverage/index.html +20 -20
- package/coverage/src/alphabeticalDependencies.ts.html +11 -11
- package/coverage/src/alphabeticalScripts.ts.html +5 -5
- package/coverage/src/bannedDependencies.ts.html +76 -28
- package/coverage/src/consistentDependencies.ts.html +51 -18
- package/coverage/src/consistentVersions.ts.html +144 -48
- package/coverage/src/fileContents.ts.html +47 -23
- package/coverage/src/forceError.ts.html +184 -0
- package/coverage/src/index.html +96 -66
- package/coverage/src/index.ts.html +39 -33
- package/coverage/src/mustSatisfyPeerDependencies.ts.html +323 -80
- package/coverage/src/nestedWorkspaces.ts.html +47 -20
- package/coverage/src/oncePerPackage.ts.html +181 -0
- package/coverage/src/packageEntry.ts.html +40 -19
- package/coverage/src/packageOrder.ts.html +30 -12
- package/coverage/src/packageScript.ts.html +81 -27
- package/coverage/src/requireDependency.ts.html +77 -32
- package/coverage/src/standardTsconfig.ts.html +84 -21
- package/coverage/src/util/checkAlpha.ts.html +18 -9
- package/coverage/src/util/createRuleFactory.ts.html +16 -4
- package/coverage/src/util/index.html +17 -17
- package/coverage/src/util/makeDirectory.ts.html +5 -5
- package/coverage/src/util/packageDependencyGraphService.ts.html +94 -19
- package/package.json +4 -5
- package/src/__tests__/alphabeticalScripts.spec.ts +12 -4
- package/src/__tests__/bannedDependencies.spec.ts +45 -16
- package/src/__tests__/consistentDependencies.spec.ts +11 -5
- package/src/__tests__/consistentVersions.spec.ts +72 -18
- package/src/__tests__/fileContents.spec.ts +5 -5
- package/src/__tests__/mustSatisfyPeerDependencies.spec.ts +191 -76
- package/src/__tests__/nestedWorkspaces.spec.ts +10 -7
- package/src/__tests__/packageEntry.spec.ts +48 -47
- package/src/__tests__/packageOrder.spec.ts +72 -71
- package/src/__tests__/packageScript.spec.ts +19 -10
- package/src/__tests__/requireDependency.spec.ts +12 -6
- package/src/__tests__/utils.ts +16 -7
- package/src/bannedDependencies.ts +32 -16
- package/src/consistentDependencies.ts +19 -8
- package/src/consistentVersions.ts +70 -38
- package/src/fileContents.ts +19 -11
- package/src/forceError.ts +33 -0
- package/src/index.ts +5 -3
- package/src/mustSatisfyPeerDependencies.ts +141 -60
- package/src/nestedWorkspaces.ts +19 -10
- package/src/oncePerPackage.ts +32 -0
- package/src/packageEntry.ts +18 -11
- package/src/packageOrder.ts +9 -3
- package/src/packageScript.ts +37 -19
- package/src/requireDependency.ts +26 -11
- package/src/standardTsconfig.ts +31 -10
- package/src/util/checkAlpha.ts +5 -2
- package/src/util/createRuleFactory.ts +6 -2
- package/src/util/packageDependencyGraphService.ts +38 -13
- package/vitest.config.mjs +6 -7
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,7 +186,10 @@ 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();
|
|
@@ -235,12 +246,18 @@ function populateProblemsGlobs(bannedDependencyGlobs, dependencies, violations)
|
|
|
235
246
|
}
|
|
236
247
|
function checkTransitives(context, banned) {
|
|
237
248
|
const graphService = new PackageDependencyGraphService();
|
|
238
|
-
const root = graphService.buildDependencyGraph(
|
|
249
|
+
const root = graphService.buildDependencyGraph(
|
|
250
|
+
path2.resolve(context.getPackageJsonPath()),
|
|
251
|
+
context.host
|
|
252
|
+
);
|
|
239
253
|
for (const { dependencies, importPath } of graphService.traverse(root)) {
|
|
240
254
|
for (const [dependency] of dependencies) {
|
|
241
255
|
if (banned.has(dependency)) {
|
|
242
256
|
const [, ...importPathWithoutRoot] = importPath;
|
|
243
|
-
const pathing = [
|
|
257
|
+
const pathing = [
|
|
258
|
+
...importPathWithoutRoot.map(nameOrPackageJsonPath),
|
|
259
|
+
dependency
|
|
260
|
+
].join(" -> ");
|
|
244
261
|
context.addError({
|
|
245
262
|
file: root.paths.packageJsonPath,
|
|
246
263
|
message: `Banned transitive dependencies in repo: ${pathing}`
|
|
@@ -331,16 +348,26 @@ function checkConsistentVersions(context, options) {
|
|
|
331
348
|
options.matchDependencyVersions
|
|
332
349
|
)) {
|
|
333
350
|
if (Array.isArray(expectedPackageDependencyValue)) {
|
|
334
|
-
ensurePackageMatchesSomeVersion(
|
|
351
|
+
ensurePackageMatchesSomeVersion(
|
|
352
|
+
context,
|
|
353
|
+
dependencyPackageName,
|
|
354
|
+
expectedPackageDependencyValue
|
|
355
|
+
);
|
|
335
356
|
} else {
|
|
336
|
-
ensurePackageIsCorrectVersion(
|
|
357
|
+
ensurePackageIsCorrectVersion(
|
|
358
|
+
context,
|
|
359
|
+
dependencyPackageName,
|
|
360
|
+
expectedPackageDependencyValue
|
|
361
|
+
);
|
|
337
362
|
}
|
|
338
363
|
}
|
|
339
364
|
}
|
|
340
365
|
var ensurePackageIsCorrectVersion = (context, dependencyPackageName, expectedPackageDependencyValue) => {
|
|
341
366
|
const packageJson = context.getPackageJson();
|
|
342
367
|
const packageJsonPath = context.getPackageJsonPath();
|
|
343
|
-
const expectedPackageDependencyVersion = coerce(
|
|
368
|
+
const expectedPackageDependencyVersion = coerce(
|
|
369
|
+
expectedPackageDependencyValue
|
|
370
|
+
);
|
|
344
371
|
if (expectedPackageDependencyVersion == null) {
|
|
345
372
|
throw new Error(
|
|
346
373
|
`Malformed expected package dependency version defined in monorepolint configuration: ${dependencyPackageName} @ '${expectedPackageDependencyValue}'`
|
|
@@ -359,7 +386,9 @@ var ensurePackageIsCorrectVersion = (context, dependencyPackageName, expectedPac
|
|
|
359
386
|
});
|
|
360
387
|
}
|
|
361
388
|
const actualPackageDevDependencyValue = packageJson.devDependencies && packageJson.devDependencies[dependencyPackageName];
|
|
362
|
-
const actualPackageDevDependencyVersion = coerce(
|
|
389
|
+
const actualPackageDevDependencyVersion = coerce(
|
|
390
|
+
actualPackageDevDependencyValue
|
|
391
|
+
);
|
|
363
392
|
if (actualPackageDevDependencyVersion != null && actualPackageDevDependencyVersion.raw !== expectedPackageDependencyVersion.raw) {
|
|
364
393
|
context.addError({
|
|
365
394
|
file: packageJsonPath,
|
|
@@ -376,7 +405,9 @@ var ensurePackageMatchesSomeVersion = (context, dependencyPackageName, acceptedP
|
|
|
376
405
|
const packageJsonPath = context.getPackageJsonPath();
|
|
377
406
|
const acceptedPackageDependencyVersions = acceptedPackageDependencyValues.map(
|
|
378
407
|
(acceptedPackageDependencyValue) => {
|
|
379
|
-
const acceptedPackageDependencyVersion = coerce(
|
|
408
|
+
const acceptedPackageDependencyVersion = coerce(
|
|
409
|
+
acceptedPackageDependencyValue
|
|
410
|
+
);
|
|
380
411
|
if (acceptedPackageDependencyVersion == null) {
|
|
381
412
|
throw new Error(
|
|
382
413
|
`Malformed accepted package dependency version defined in monorepolint configuration: ${dependencyPackageName} @ '${acceptedPackageDependencyValue}'`
|
|
@@ -398,7 +429,9 @@ var ensurePackageMatchesSomeVersion = (context, dependencyPackageName, acceptedP
|
|
|
398
429
|
});
|
|
399
430
|
}
|
|
400
431
|
const actualPackageDevDependencyValue = packageJson.devDependencies && packageJson.devDependencies[dependencyPackageName];
|
|
401
|
-
const actualPackageDevDependencyVersion = coerce(
|
|
432
|
+
const actualPackageDevDependencyVersion = coerce(
|
|
433
|
+
actualPackageDevDependencyValue
|
|
434
|
+
);
|
|
402
435
|
if (actualPackageDevDependencyVersion != null && acceptedPackageDependencyVersions.every(
|
|
403
436
|
(acceptedPackageDependencyVersion) => actualPackageDevDependencyVersion.raw !== acceptedPackageDependencyVersion.raw
|
|
404
437
|
)) {
|
|
@@ -454,7 +487,9 @@ var fileContents = createRuleFactory({
|
|
|
454
487
|
if (pathExists) context.host.deleteFile(fullPath);
|
|
455
488
|
} else {
|
|
456
489
|
context.host.mkdir(path3.dirname(fullPath), { recursive: true });
|
|
457
|
-
context.host.writeFile(fullPath, expectedContent, {
|
|
490
|
+
context.host.writeFile(fullPath, expectedContent, {
|
|
491
|
+
encoding: "utf-8"
|
|
492
|
+
});
|
|
458
493
|
}
|
|
459
494
|
}
|
|
460
495
|
});
|
|
@@ -486,12 +521,37 @@ async function getExpectedContents(context, opts) {
|
|
|
486
521
|
}
|
|
487
522
|
}
|
|
488
523
|
|
|
524
|
+
// src/forceError.ts
|
|
525
|
+
var forceError = createRuleFactory({
|
|
526
|
+
name: "forceError",
|
|
527
|
+
check: async (context, opts) => {
|
|
528
|
+
context.addError({
|
|
529
|
+
message: (opts == null ? void 0 : opts.customMessage) ?? "Forced error (often used to debug package selection)",
|
|
530
|
+
file: context.getPackageJsonPath()
|
|
531
|
+
});
|
|
532
|
+
},
|
|
533
|
+
validateOptions: (opts) => {
|
|
534
|
+
if (opts == null) return;
|
|
535
|
+
if (typeof opts !== "object") {
|
|
536
|
+
throw new Error("options must be an object if provided");
|
|
537
|
+
}
|
|
538
|
+
const numKeys = Object.keys(opts).length;
|
|
539
|
+
if (numKeys === 0) return;
|
|
540
|
+
if (Object.keys(opts).length > 1 || !("customMessage" in opts)) {
|
|
541
|
+
throw new Error("options must only have `customMessage` property");
|
|
542
|
+
}
|
|
543
|
+
if (typeof opts.customMessage !== "string") {
|
|
544
|
+
throw new Error("customMessage must be a string");
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
});
|
|
548
|
+
|
|
489
549
|
// src/mustSatisfyPeerDependencies.ts
|
|
490
550
|
import { mutateJson as mutateJson2 } from "@monorepolint/utils";
|
|
491
551
|
import * as path4 from "node:path";
|
|
552
|
+
import resolvePackagePath2 from "resolve-package-path";
|
|
492
553
|
import * as r5 from "runtypes";
|
|
493
554
|
import { coerce as coerce2 } from "semver";
|
|
494
|
-
import resolvePackagePath2 from "resolve-package-path";
|
|
495
555
|
var Options5 = r5.Union(
|
|
496
556
|
r5.Partial({
|
|
497
557
|
skipUnparseableRanges: r5.Undefined,
|
|
@@ -642,15 +702,26 @@ var MATCH_GREATER_OR_EQUAL_VERSION_RANGE = /^>= ?\d+(?:\.\d+|\.\d+\.\d+(?:-((?:0
|
|
|
642
702
|
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-]+)*))?)$/;
|
|
643
703
|
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-]+)*))?)?)*)$/;
|
|
644
704
|
function checkSatisfyPeerDependencies(context, opts) {
|
|
645
|
-
const {
|
|
705
|
+
const {
|
|
706
|
+
dependencyBlacklist,
|
|
707
|
+
dependencyWhitelist,
|
|
708
|
+
enforceForDevDependencies,
|
|
709
|
+
skipUnparseableRanges
|
|
710
|
+
} = opts;
|
|
646
711
|
const packageJsonPath = path4.resolve(context.getPackageJsonPath());
|
|
647
712
|
const packageJson = context.host.readJson(packageJsonPath);
|
|
648
713
|
const packageDependencies = packageJson.dependencies || {};
|
|
649
714
|
const packageDevDependencies = packageJson.devDependencies || {};
|
|
650
715
|
const packagePeerDependencies = packageJson.peerDependencies || {};
|
|
651
716
|
const packageName = packageJson.name || packageJsonPath;
|
|
652
|
-
for (const [peerDependencyName, peerDependencyRange] of Object.entries(
|
|
653
|
-
|
|
717
|
+
for (const [peerDependencyName, peerDependencyRange] of Object.entries(
|
|
718
|
+
packagePeerDependencies
|
|
719
|
+
)) {
|
|
720
|
+
if (shouldSkipPackage({
|
|
721
|
+
dependencyBlacklist,
|
|
722
|
+
dependencyWhitelist,
|
|
723
|
+
packageName: peerDependencyName
|
|
724
|
+
})) {
|
|
654
725
|
continue;
|
|
655
726
|
}
|
|
656
727
|
const dependencyRange = packageDependencies[peerDependencyName];
|
|
@@ -663,19 +734,35 @@ function checkSatisfyPeerDependencies(context, opts) {
|
|
|
663
734
|
}
|
|
664
735
|
}
|
|
665
736
|
const allRequiredPeerDependencies = {};
|
|
666
|
-
const allDependencies = enforceForDevDependencies ? [
|
|
737
|
+
const allDependencies = enforceForDevDependencies ? [
|
|
738
|
+
...Object.keys(packageDependencies),
|
|
739
|
+
...Object.keys(packageDevDependencies)
|
|
740
|
+
] : Object.keys(packageDependencies);
|
|
667
741
|
for (const dependency of allDependencies) {
|
|
668
|
-
const dependencyPackageJsonPath = resolvePackagePath2(
|
|
742
|
+
const dependencyPackageJsonPath = resolvePackagePath2(
|
|
743
|
+
dependency,
|
|
744
|
+
path4.dirname(packageJsonPath)
|
|
745
|
+
);
|
|
669
746
|
if (dependencyPackageJsonPath == null) {
|
|
670
|
-
throw new Error(
|
|
747
|
+
throw new Error(
|
|
748
|
+
`Could not resolve ${dependency} from ${path4.dirname(packageJsonPath)}`
|
|
749
|
+
);
|
|
671
750
|
}
|
|
672
|
-
const dependencyPackageJson = context.host.readJson(
|
|
751
|
+
const dependencyPackageJson = context.host.readJson(
|
|
752
|
+
dependencyPackageJsonPath
|
|
753
|
+
);
|
|
673
754
|
const requiredPeerDependencies = dependencyPackageJson.peerDependencies;
|
|
674
755
|
if (requiredPeerDependencies == null) {
|
|
675
756
|
continue;
|
|
676
757
|
}
|
|
677
|
-
for (const [peerDependencyName, range] of Object.entries(
|
|
678
|
-
|
|
758
|
+
for (const [peerDependencyName, range] of Object.entries(
|
|
759
|
+
requiredPeerDependencies
|
|
760
|
+
)) {
|
|
761
|
+
if (shouldSkipPackage({
|
|
762
|
+
dependencyBlacklist,
|
|
763
|
+
dependencyWhitelist,
|
|
764
|
+
packageName: peerDependencyName
|
|
765
|
+
})) {
|
|
679
766
|
continue;
|
|
680
767
|
}
|
|
681
768
|
if (!isValidRange(range)) {
|
|
@@ -689,10 +776,15 @@ function checkSatisfyPeerDependencies(context, opts) {
|
|
|
689
776
|
if (allRequiredPeerDependencies[peerDependencyName] == null) {
|
|
690
777
|
allRequiredPeerDependencies[peerDependencyName] = [];
|
|
691
778
|
}
|
|
692
|
-
allRequiredPeerDependencies[peerDependencyName].push({
|
|
779
|
+
allRequiredPeerDependencies[peerDependencyName].push({
|
|
780
|
+
fromPackageName: dependencyPackageJson.name,
|
|
781
|
+
range
|
|
782
|
+
});
|
|
693
783
|
}
|
|
694
784
|
}
|
|
695
|
-
for (const [peerDependencyName, peerDependencyRequirements] of Object.entries(
|
|
785
|
+
for (const [peerDependencyName, peerDependencyRequirements] of Object.entries(
|
|
786
|
+
allRequiredPeerDependencies
|
|
787
|
+
)) {
|
|
696
788
|
let mostStrictPeerRequirement = {
|
|
697
789
|
fromPeerDependencyRequirements: [peerDependencyRequirements[0]],
|
|
698
790
|
range: peerDependencyRequirements[0].range
|
|
@@ -706,7 +798,10 @@ function checkSatisfyPeerDependencies(context, opts) {
|
|
|
706
798
|
range: peerRequirement.range
|
|
707
799
|
};
|
|
708
800
|
} else {
|
|
709
|
-
const maybeIntersection = findIntersection(
|
|
801
|
+
const maybeIntersection = findIntersection(
|
|
802
|
+
peerRequirement.range,
|
|
803
|
+
mostStrictPeerRequirement.range
|
|
804
|
+
);
|
|
710
805
|
if (maybeIntersection !== void 0) {
|
|
711
806
|
mostStrictPeerRequirement = {
|
|
712
807
|
fromPeerDependencyRequirements: [
|
|
@@ -765,7 +860,10 @@ function checkSatisfyPeerDependencies(context, opts) {
|
|
|
765
860
|
} else {
|
|
766
861
|
throw new Error(message);
|
|
767
862
|
}
|
|
768
|
-
} else if (!doesASatisfyB(
|
|
863
|
+
} else if (!doesASatisfyB(
|
|
864
|
+
packagePeerDependencyRange,
|
|
865
|
+
mostStrictPeerRequirement.range
|
|
866
|
+
)) {
|
|
769
867
|
context.addError({
|
|
770
868
|
file: packageJsonPath,
|
|
771
869
|
message: `[4] Package ${packageName} peer dependency on ${peerDependencyName} '${packagePeerDependencyRange}' is not strict enough.
|
|
@@ -852,9 +950,15 @@ function findIntersection(a, b) {
|
|
|
852
950
|
if (majorMatchingBVersion === void 0) {
|
|
853
951
|
return void 0;
|
|
854
952
|
}
|
|
855
|
-
if (doesASatisfyB(
|
|
953
|
+
if (doesASatisfyB(
|
|
954
|
+
aVersion,
|
|
955
|
+
majorMatchingBVersion
|
|
956
|
+
)) {
|
|
856
957
|
return aVersion;
|
|
857
|
-
} else if (doesASatisfyB(
|
|
958
|
+
} else if (doesASatisfyB(
|
|
959
|
+
majorMatchingBVersion,
|
|
960
|
+
aVersion
|
|
961
|
+
)) {
|
|
858
962
|
return majorMatchingBVersion;
|
|
859
963
|
} else {
|
|
860
964
|
return void 0;
|
|
@@ -901,7 +1005,9 @@ function doesASatisfyB(a, b) {
|
|
|
901
1005
|
}
|
|
902
1006
|
const aVersionIsRange = isMajorVersionRange(aVersion);
|
|
903
1007
|
const majorMatchingBSemVer = coerce2(majorMatchingBVersion);
|
|
904
|
-
const majorMatchingBVersionIsRange = isMajorVersionRange(
|
|
1008
|
+
const majorMatchingBVersionIsRange = isMajorVersionRange(
|
|
1009
|
+
majorMatchingBVersion
|
|
1010
|
+
);
|
|
905
1011
|
if (majorMatchingBVersionIsRange) {
|
|
906
1012
|
return aSemVer.compare(majorMatchingBSemVer) !== -1;
|
|
907
1013
|
} else {
|
|
@@ -943,12 +1049,153 @@ function getAddDependencyTypeFixer({
|
|
|
943
1049
|
};
|
|
944
1050
|
}
|
|
945
1051
|
|
|
946
|
-
// src/
|
|
947
|
-
import
|
|
1052
|
+
// src/nestedWorkspaces.ts
|
|
1053
|
+
import * as globby from "globby";
|
|
1054
|
+
import * as path5 from "node:path";
|
|
948
1055
|
import * as r6 from "runtypes";
|
|
949
|
-
var Options6 = r6.
|
|
950
|
-
|
|
951
|
-
|
|
1056
|
+
var Options6 = r6.Undefined;
|
|
1057
|
+
var nestedWorkspaces = createRuleFactory({
|
|
1058
|
+
name: "nestedWorkspaces",
|
|
1059
|
+
check: (context) => {
|
|
1060
|
+
const rootPackageJson = context.getWorkspaceContext().getPackageJson();
|
|
1061
|
+
const packageJsonPaths = globby.globbySync([
|
|
1062
|
+
"*/**/package.json",
|
|
1063
|
+
"!**/node_modules/**"
|
|
1064
|
+
]);
|
|
1065
|
+
const workspaces = Array.isArray(rootPackageJson.workspaces) ? rootPackageJson.workspaces : rootPackageJson.workspaces !== void 0 ? rootPackageJson.workspaces.packages : void 0;
|
|
1066
|
+
if (workspaces === void 0 && packageJsonPaths.length > 0) {
|
|
1067
|
+
context.addError({
|
|
1068
|
+
file: context.getPackageJsonPath(),
|
|
1069
|
+
message: 'The "workspace" field is missing, even though there are workspaces in the repository.'
|
|
1070
|
+
});
|
|
1071
|
+
return;
|
|
1072
|
+
}
|
|
1073
|
+
const workspacePackageJsons = (workspaces || []).map((item) => `${item}/package.json`);
|
|
1074
|
+
const expandedWorkspacesGlobs = globby.globbySync([
|
|
1075
|
+
...workspacePackageJsons,
|
|
1076
|
+
"!**/node_modules/**"
|
|
1077
|
+
]);
|
|
1078
|
+
const difference = packageJsonPaths.filter(
|
|
1079
|
+
(packageJsonPath) => !expandedWorkspacesGlobs.includes(packageJsonPath)
|
|
1080
|
+
);
|
|
1081
|
+
if (difference.length !== 0) {
|
|
1082
|
+
const differencesList = difference.map((packageJsonPath) => path5.dirname(packageJsonPath)).join(", ");
|
|
1083
|
+
context.addError({
|
|
1084
|
+
file: context.getPackageJsonPath(),
|
|
1085
|
+
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/*".`
|
|
1086
|
+
});
|
|
1087
|
+
}
|
|
1088
|
+
},
|
|
1089
|
+
validateOptions: Options6.check
|
|
1090
|
+
});
|
|
1091
|
+
|
|
1092
|
+
// src/oncePerPackage.ts
|
|
1093
|
+
import * as r7 from "runtypes";
|
|
1094
|
+
var Options7 = r7.Record({
|
|
1095
|
+
singletonKey: r7.String.Or(r7.Symbol),
|
|
1096
|
+
customMessage: r7.String.optional()
|
|
1097
|
+
});
|
|
1098
|
+
var visitedMap = /* @__PURE__ */ new Map();
|
|
1099
|
+
var oncePerPackage = createRuleFactory({
|
|
1100
|
+
name: "oncePerPackage",
|
|
1101
|
+
check: async (context, options) => {
|
|
1102
|
+
const visited = visitedMap.get(options.singletonKey) ?? /* @__PURE__ */ new Set();
|
|
1103
|
+
visitedMap.set(options.singletonKey, visited);
|
|
1104
|
+
if (visited.has(context.getName())) {
|
|
1105
|
+
context.addError({
|
|
1106
|
+
message: "This package has already been visited for this key: " + options.singletonKey.toString(),
|
|
1107
|
+
file: context.getPackageJsonPath()
|
|
1108
|
+
});
|
|
1109
|
+
} else {
|
|
1110
|
+
visited.add(context.getName());
|
|
1111
|
+
}
|
|
1112
|
+
},
|
|
1113
|
+
validateOptions: Options7.assert
|
|
1114
|
+
});
|
|
1115
|
+
|
|
1116
|
+
// src/packageEntry.ts
|
|
1117
|
+
import { mutateJson as mutateJson3 } from "@monorepolint/utils";
|
|
1118
|
+
import { diff as diff4 } from "jest-diff";
|
|
1119
|
+
import * as r8 from "runtypes";
|
|
1120
|
+
var Options8 = r8.Union(
|
|
1121
|
+
r8.Record({
|
|
1122
|
+
entries: r8.Dictionary(r8.Unknown)
|
|
1123
|
+
// string => unknown, enforces existence of keys and their values
|
|
1124
|
+
}).And(
|
|
1125
|
+
r8.Partial({
|
|
1126
|
+
entriesExist: r8.Undefined
|
|
1127
|
+
})
|
|
1128
|
+
),
|
|
1129
|
+
r8.Record({
|
|
1130
|
+
entriesExist: r8.Array(r8.String)
|
|
1131
|
+
// enforces existence of keys, but not values
|
|
1132
|
+
}).And(
|
|
1133
|
+
r8.Partial({
|
|
1134
|
+
entries: r8.Undefined
|
|
1135
|
+
})
|
|
1136
|
+
),
|
|
1137
|
+
r8.Record({
|
|
1138
|
+
entries: r8.Dictionary(r8.Unknown),
|
|
1139
|
+
// string => unknown, enforces existence of keys and their values
|
|
1140
|
+
entriesExist: r8.Array(r8.String)
|
|
1141
|
+
})
|
|
1142
|
+
);
|
|
1143
|
+
var packageEntry = createRuleFactory({
|
|
1144
|
+
name: "packageEntry",
|
|
1145
|
+
check: (context, options) => {
|
|
1146
|
+
const packageJson = context.getPackageJson();
|
|
1147
|
+
if (options.entries) {
|
|
1148
|
+
for (const key of Object.keys(options.entries)) {
|
|
1149
|
+
const value = options.entries[key];
|
|
1150
|
+
const entryDiff = diff4(
|
|
1151
|
+
JSON.stringify(value) + "\n",
|
|
1152
|
+
(JSON.stringify(packageJson[key]) || "") + "\n"
|
|
1153
|
+
);
|
|
1154
|
+
if (typeof value !== "object" && value !== packageJson[key] || entryDiff == null || !entryDiff.includes("Compared values have no visual difference")) {
|
|
1155
|
+
context.addError({
|
|
1156
|
+
file: context.getPackageJsonPath(),
|
|
1157
|
+
message: createStandardizedEntryErrorMessage(key),
|
|
1158
|
+
longMessage: entryDiff,
|
|
1159
|
+
fixer: () => {
|
|
1160
|
+
mutateJson3(
|
|
1161
|
+
context.getPackageJsonPath(),
|
|
1162
|
+
context.host,
|
|
1163
|
+
(input) => {
|
|
1164
|
+
input[key] = value;
|
|
1165
|
+
return input;
|
|
1166
|
+
}
|
|
1167
|
+
);
|
|
1168
|
+
}
|
|
1169
|
+
});
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
if (options.entriesExist) {
|
|
1174
|
+
for (const key of options.entriesExist) {
|
|
1175
|
+
if (packageJson[key] === void 0) {
|
|
1176
|
+
context.addError({
|
|
1177
|
+
file: context.getPackageJsonPath(),
|
|
1178
|
+
message: createExpectedEntryErrorMessage(key)
|
|
1179
|
+
});
|
|
1180
|
+
}
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
},
|
|
1184
|
+
validateOptions: Options8.check
|
|
1185
|
+
});
|
|
1186
|
+
function createStandardizedEntryErrorMessage(key) {
|
|
1187
|
+
return `Expected standardized entry for '${key}'`;
|
|
1188
|
+
}
|
|
1189
|
+
function createExpectedEntryErrorMessage(key) {
|
|
1190
|
+
return `Expected entry for '${key}' to exist`;
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
// src/packageOrder.ts
|
|
1194
|
+
import { diff as diff5 } from "jest-diff";
|
|
1195
|
+
import * as r9 from "runtypes";
|
|
1196
|
+
var Options9 = r9.Record({
|
|
1197
|
+
order: r9.Union(r9.Array(r9.String), r9.Function)
|
|
1198
|
+
}).Or(r9.Undefined);
|
|
952
1199
|
var defaultKeyOrder = [
|
|
953
1200
|
"name",
|
|
954
1201
|
"version",
|
|
@@ -993,7 +1240,7 @@ var packageOrder = createRuleFactory({
|
|
|
993
1240
|
context.addError({
|
|
994
1241
|
file: packagePath,
|
|
995
1242
|
message: "Incorrect order of fields in package.json",
|
|
996
|
-
longMessage:
|
|
1243
|
+
longMessage: diff5(expectedOrder, actualOrder, { expand: true }),
|
|
997
1244
|
fixer: () => {
|
|
998
1245
|
const expectedPackageJson = {};
|
|
999
1246
|
expectedOrder.forEach((key) => {
|
|
@@ -1004,7 +1251,7 @@ var packageOrder = createRuleFactory({
|
|
|
1004
1251
|
});
|
|
1005
1252
|
}
|
|
1006
1253
|
},
|
|
1007
|
-
validateOptions:
|
|
1254
|
+
validateOptions: Options9.check
|
|
1008
1255
|
});
|
|
1009
1256
|
function arrayOrderCompare2(a, b) {
|
|
1010
1257
|
for (let index = 0; index < a.length; index++) {
|
|
@@ -1035,87 +1282,17 @@ function isOrderFunction(order) {
|
|
|
1035
1282
|
return !Array.isArray(order);
|
|
1036
1283
|
}
|
|
1037
1284
|
|
|
1038
|
-
// src/packageEntry.ts
|
|
1039
|
-
import { mutateJson as mutateJson3 } from "@monorepolint/utils";
|
|
1040
|
-
import { diff as diff5 } from "jest-diff";
|
|
1041
|
-
import * as r7 from "runtypes";
|
|
1042
|
-
var Options7 = r7.Union(
|
|
1043
|
-
r7.Record({
|
|
1044
|
-
entries: r7.Dictionary(r7.Unknown)
|
|
1045
|
-
// string => unknown, enforces existence of keys and their values
|
|
1046
|
-
}).And(
|
|
1047
|
-
r7.Partial({
|
|
1048
|
-
entriesExist: r7.Undefined
|
|
1049
|
-
})
|
|
1050
|
-
),
|
|
1051
|
-
r7.Record({
|
|
1052
|
-
entriesExist: r7.Array(r7.String)
|
|
1053
|
-
// enforces existence of keys, but not values
|
|
1054
|
-
}).And(
|
|
1055
|
-
r7.Partial({
|
|
1056
|
-
entries: r7.Undefined
|
|
1057
|
-
})
|
|
1058
|
-
),
|
|
1059
|
-
r7.Record({
|
|
1060
|
-
entries: r7.Dictionary(r7.Unknown),
|
|
1061
|
-
// string => unknown, enforces existence of keys and their values
|
|
1062
|
-
entriesExist: r7.Array(r7.String)
|
|
1063
|
-
})
|
|
1064
|
-
);
|
|
1065
|
-
var packageEntry = createRuleFactory({
|
|
1066
|
-
name: "packageEntry",
|
|
1067
|
-
check: (context, options) => {
|
|
1068
|
-
const packageJson = context.getPackageJson();
|
|
1069
|
-
if (options.entries) {
|
|
1070
|
-
for (const key of Object.keys(options.entries)) {
|
|
1071
|
-
const value = options.entries[key];
|
|
1072
|
-
const entryDiff = diff5(JSON.stringify(value) + "\n", (JSON.stringify(packageJson[key]) || "") + "\n");
|
|
1073
|
-
if (typeof value !== "object" && value !== packageJson[key] || entryDiff == null || !entryDiff.includes("Compared values have no visual difference")) {
|
|
1074
|
-
context.addError({
|
|
1075
|
-
file: context.getPackageJsonPath(),
|
|
1076
|
-
message: createStandardizedEntryErrorMessage(key),
|
|
1077
|
-
longMessage: entryDiff,
|
|
1078
|
-
fixer: () => {
|
|
1079
|
-
mutateJson3(context.getPackageJsonPath(), context.host, (input) => {
|
|
1080
|
-
input[key] = value;
|
|
1081
|
-
return input;
|
|
1082
|
-
});
|
|
1083
|
-
}
|
|
1084
|
-
});
|
|
1085
|
-
}
|
|
1086
|
-
}
|
|
1087
|
-
}
|
|
1088
|
-
if (options.entriesExist) {
|
|
1089
|
-
for (const key of options.entriesExist) {
|
|
1090
|
-
if (packageJson[key] === void 0) {
|
|
1091
|
-
context.addError({
|
|
1092
|
-
file: context.getPackageJsonPath(),
|
|
1093
|
-
message: createExpectedEntryErrorMessage(key)
|
|
1094
|
-
});
|
|
1095
|
-
}
|
|
1096
|
-
}
|
|
1097
|
-
}
|
|
1098
|
-
},
|
|
1099
|
-
validateOptions: Options7.check
|
|
1100
|
-
});
|
|
1101
|
-
function createStandardizedEntryErrorMessage(key) {
|
|
1102
|
-
return `Expected standardized entry for '${key}'`;
|
|
1103
|
-
}
|
|
1104
|
-
function createExpectedEntryErrorMessage(key) {
|
|
1105
|
-
return `Expected entry for '${key}' to exist`;
|
|
1106
|
-
}
|
|
1107
|
-
|
|
1108
1285
|
// src/packageScript.ts
|
|
1109
1286
|
import { mutateJson as mutateJson4 } from "@monorepolint/utils";
|
|
1110
1287
|
import { diff as diff6 } from "jest-diff";
|
|
1111
|
-
import * as
|
|
1112
|
-
var
|
|
1113
|
-
scripts:
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
options:
|
|
1118
|
-
fixValue:
|
|
1288
|
+
import * as r10 from "runtypes";
|
|
1289
|
+
var Options10 = r10.Record({
|
|
1290
|
+
scripts: r10.Dictionary(
|
|
1291
|
+
r10.Union(
|
|
1292
|
+
r10.String,
|
|
1293
|
+
r10.Record({
|
|
1294
|
+
options: r10.Array(r10.String.Or(r10.Undefined)),
|
|
1295
|
+
fixValue: r10.Union(r10.String, r10.Undefined, r10.Literal(false)).optional()
|
|
1119
1296
|
})
|
|
1120
1297
|
)
|
|
1121
1298
|
)
|
|
@@ -1131,10 +1308,14 @@ var packageScript = createRuleFactory({
|
|
|
1131
1308
|
file: context.getPackageJsonPath(),
|
|
1132
1309
|
message: MSG_NO_SCRIPTS_BLOCK,
|
|
1133
1310
|
fixer: () => {
|
|
1134
|
-
mutateJson4(
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1311
|
+
mutateJson4(
|
|
1312
|
+
context.getPackageJsonPath(),
|
|
1313
|
+
context.host,
|
|
1314
|
+
(input) => {
|
|
1315
|
+
input.scripts = {};
|
|
1316
|
+
return input;
|
|
1317
|
+
}
|
|
1318
|
+
);
|
|
1138
1319
|
}
|
|
1139
1320
|
});
|
|
1140
1321
|
return;
|
|
@@ -1163,43 +1344,125 @@ var packageScript = createRuleFactory({
|
|
|
1163
1344
|
if (fixValue !== false && (fixValue !== void 0 || fixToEmpty === true)) {
|
|
1164
1345
|
const q = fixValue;
|
|
1165
1346
|
fixer = () => {
|
|
1166
|
-
mutateJson4(
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1347
|
+
mutateJson4(
|
|
1348
|
+
context.getPackageJsonPath(),
|
|
1349
|
+
context.host,
|
|
1350
|
+
(input) => {
|
|
1351
|
+
if (fixToEmpty && q === void 0) {
|
|
1352
|
+
delete input.scripts[name];
|
|
1353
|
+
} else {
|
|
1354
|
+
input.scripts[name] = q;
|
|
1355
|
+
}
|
|
1356
|
+
return input;
|
|
1171
1357
|
}
|
|
1172
|
-
|
|
1173
|
-
});
|
|
1358
|
+
);
|
|
1174
1359
|
};
|
|
1175
1360
|
}
|
|
1176
1361
|
const validOptionsString = Array.from(allowedValues.values()).map((a) => a === void 0 ? "(empty)" : `'${a}'`).join(", ");
|
|
1177
1362
|
context.addError({
|
|
1178
1363
|
file: context.getPackageJsonPath(),
|
|
1179
1364
|
message: `Expected standardized script entry for '${name}'. Valid options: ${validOptionsString}`,
|
|
1180
|
-
longMessage: diff6(
|
|
1365
|
+
longMessage: diff6(
|
|
1366
|
+
validOptionsString + "\n",
|
|
1367
|
+
(packageJson.scripts[name] || "") + "\n"
|
|
1368
|
+
),
|
|
1181
1369
|
fixer
|
|
1182
1370
|
});
|
|
1183
1371
|
}
|
|
1184
1372
|
}
|
|
1185
1373
|
},
|
|
1186
|
-
validateOptions:
|
|
1374
|
+
validateOptions: Options10.check
|
|
1375
|
+
});
|
|
1376
|
+
|
|
1377
|
+
// src/requireDependency.ts
|
|
1378
|
+
import { mutateJson as mutateJson5 } from "@monorepolint/utils";
|
|
1379
|
+
import { diff as diff7 } from "jest-diff";
|
|
1380
|
+
import * as r11 from "runtypes";
|
|
1381
|
+
var Options11 = r11.Partial({
|
|
1382
|
+
dependencies: r11.Dictionary(r11.String.optional()),
|
|
1383
|
+
devDependencies: r11.Dictionary(r11.String.optional()),
|
|
1384
|
+
peerDependencies: r11.Dictionary(r11.String.optional()),
|
|
1385
|
+
optionalDependencies: r11.Dictionary(r11.String.optional())
|
|
1386
|
+
});
|
|
1387
|
+
var requireDependency = createRuleFactory({
|
|
1388
|
+
name: "requireDependency",
|
|
1389
|
+
check: function expectPackageEntry(context, options) {
|
|
1390
|
+
const packageJson = context.getPackageJson();
|
|
1391
|
+
const packageJsonPath = context.getPackageJsonPath();
|
|
1392
|
+
[
|
|
1393
|
+
"dependencies",
|
|
1394
|
+
"devDependencies",
|
|
1395
|
+
"peerDependencies",
|
|
1396
|
+
"optionalDependencies"
|
|
1397
|
+
].forEach((type) => {
|
|
1398
|
+
var _a;
|
|
1399
|
+
const expectedEntries = options[type];
|
|
1400
|
+
if (!expectedEntries) {
|
|
1401
|
+
return;
|
|
1402
|
+
}
|
|
1403
|
+
if (packageJson[type] === void 0) {
|
|
1404
|
+
context.addError({
|
|
1405
|
+
file: packageJsonPath,
|
|
1406
|
+
message: `No ${type} block, cannot add required ${type}.`,
|
|
1407
|
+
fixer: () => {
|
|
1408
|
+
mutateJson5(packageJsonPath, context.host, (input) => {
|
|
1409
|
+
input[type] = Object.fromEntries(
|
|
1410
|
+
Object.entries(expectedEntries).filter(([, v]) => v !== void 0)
|
|
1411
|
+
);
|
|
1412
|
+
return input;
|
|
1413
|
+
});
|
|
1414
|
+
}
|
|
1415
|
+
});
|
|
1416
|
+
return;
|
|
1417
|
+
}
|
|
1418
|
+
for (const [dep, version] of Object.entries(options[type])) {
|
|
1419
|
+
if (((_a = packageJson[type]) == null ? void 0 : _a[dep]) !== version) {
|
|
1420
|
+
context.addError({
|
|
1421
|
+
file: packageJsonPath,
|
|
1422
|
+
message: `Expected dependency ${dep}@${version}`,
|
|
1423
|
+
longMessage: diff7(
|
|
1424
|
+
`${dep}@${version}
|
|
1425
|
+
`,
|
|
1426
|
+
`${dep}@${packageJson[type][dep] || "missing"}
|
|
1427
|
+
`
|
|
1428
|
+
),
|
|
1429
|
+
fixer: () => {
|
|
1430
|
+
mutateJson5(
|
|
1431
|
+
packageJsonPath,
|
|
1432
|
+
context.host,
|
|
1433
|
+
(input) => {
|
|
1434
|
+
if (version === void 0) {
|
|
1435
|
+
input[type] = { ...input[type] };
|
|
1436
|
+
delete input[type][dep];
|
|
1437
|
+
} else {
|
|
1438
|
+
input[type] = { ...input[type], [dep]: version };
|
|
1439
|
+
}
|
|
1440
|
+
return input;
|
|
1441
|
+
}
|
|
1442
|
+
);
|
|
1443
|
+
}
|
|
1444
|
+
});
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1447
|
+
});
|
|
1448
|
+
},
|
|
1449
|
+
validateOptions: Options11.check
|
|
1187
1450
|
});
|
|
1188
1451
|
|
|
1189
1452
|
// src/standardTsconfig.ts
|
|
1190
1453
|
import { matchesAnyGlob as matchesAnyGlob2 } from "@monorepolint/utils";
|
|
1191
|
-
import { diff as
|
|
1192
|
-
import * as
|
|
1193
|
-
import * as
|
|
1454
|
+
import { diff as diff8 } from "jest-diff";
|
|
1455
|
+
import * as path6 from "path";
|
|
1456
|
+
import * as r12 from "runtypes";
|
|
1194
1457
|
var DEFAULT_TSCONFIG_FILENAME = "tsconfig.json";
|
|
1195
|
-
var
|
|
1196
|
-
file:
|
|
1197
|
-
generator:
|
|
1198
|
-
tsconfigReferenceFile:
|
|
1199
|
-
template:
|
|
1200
|
-
templateFile:
|
|
1201
|
-
excludedReferences:
|
|
1202
|
-
additionalReferences:
|
|
1458
|
+
var Options12 = r12.Partial({
|
|
1459
|
+
file: r12.String,
|
|
1460
|
+
generator: r12.Function,
|
|
1461
|
+
tsconfigReferenceFile: r12.String,
|
|
1462
|
+
template: r12.Record({}).Or(r12.String),
|
|
1463
|
+
templateFile: r12.String,
|
|
1464
|
+
excludedReferences: r12.Array(r12.String).Or(r12.Undefined),
|
|
1465
|
+
additionalReferences: r12.Array(r12.String).Or(r12.Undefined)
|
|
1203
1466
|
}).withConstraint(({ generator, template, templateFile }) => {
|
|
1204
1467
|
let count = 0;
|
|
1205
1468
|
if (generator) {
|
|
@@ -1217,7 +1480,7 @@ var standardTsconfig = createRuleFactory({
|
|
|
1217
1480
|
name: "standardTsconfig",
|
|
1218
1481
|
check: async (context, opts) => {
|
|
1219
1482
|
const tsconfigFileName = opts.file ?? DEFAULT_TSCONFIG_FILENAME;
|
|
1220
|
-
const fullPath =
|
|
1483
|
+
const fullPath = path6.resolve(context.packageDir, tsconfigFileName);
|
|
1221
1484
|
const generator = getGenerator(context, opts);
|
|
1222
1485
|
const expectedContent = await generator(context);
|
|
1223
1486
|
const actualContent = context.host.exists(fullPath) ? context.host.readFile(fullPath, { encoding: "utf-8" }) : void 0;
|
|
@@ -1232,7 +1495,7 @@ var standardTsconfig = createRuleFactory({
|
|
|
1232
1495
|
context.addError({
|
|
1233
1496
|
file: fullPath,
|
|
1234
1497
|
message: "Expect file contents to match",
|
|
1235
|
-
longMessage:
|
|
1498
|
+
longMessage: diff8(expectedContent, actualContent, { expand: true }),
|
|
1236
1499
|
fixer: () => {
|
|
1237
1500
|
context.host.writeFile(fullPath, expectedContent, {
|
|
1238
1501
|
encoding: "utf-8"
|
|
@@ -1241,18 +1504,30 @@ var standardTsconfig = createRuleFactory({
|
|
|
1241
1504
|
});
|
|
1242
1505
|
}
|
|
1243
1506
|
},
|
|
1244
|
-
validateOptions:
|
|
1507
|
+
validateOptions: Options12.check
|
|
1245
1508
|
});
|
|
1246
1509
|
function getGenerator(context, opts) {
|
|
1247
1510
|
if (opts.generator) {
|
|
1248
1511
|
return opts.generator;
|
|
1249
1512
|
} else if (opts.templateFile) {
|
|
1250
1513
|
const { packageDir: workspacePackageDir } = context.getWorkspaceContext();
|
|
1251
|
-
const fullPath =
|
|
1252
|
-
const template = JSON.parse(
|
|
1253
|
-
|
|
1514
|
+
const fullPath = path6.resolve(workspacePackageDir, opts.templateFile);
|
|
1515
|
+
const template = JSON.parse(
|
|
1516
|
+
context.host.readFile(fullPath, { encoding: "utf-8" })
|
|
1517
|
+
);
|
|
1518
|
+
return makeGenerator(
|
|
1519
|
+
template,
|
|
1520
|
+
opts.excludedReferences,
|
|
1521
|
+
opts.additionalReferences,
|
|
1522
|
+
opts.tsconfigReferenceFile
|
|
1523
|
+
);
|
|
1254
1524
|
} else if (opts.template) {
|
|
1255
|
-
return makeGenerator(
|
|
1525
|
+
return makeGenerator(
|
|
1526
|
+
opts.template,
|
|
1527
|
+
opts.excludedReferences,
|
|
1528
|
+
opts.additionalReferences,
|
|
1529
|
+
opts.tsconfigReferenceFile
|
|
1530
|
+
);
|
|
1256
1531
|
} else {
|
|
1257
1532
|
throw new Error("Unable to make generator");
|
|
1258
1533
|
}
|
|
@@ -1265,13 +1540,16 @@ function makeGenerator(template, excludedReferences, additionalReferences, tscon
|
|
|
1265
1540
|
};
|
|
1266
1541
|
const nameToDirectory = await context.getWorkspaceContext().getPackageNameToDir();
|
|
1267
1542
|
const packageJson = context.getPackageJson();
|
|
1268
|
-
const deps = [
|
|
1543
|
+
const deps = [
|
|
1544
|
+
...Object.keys(packageJson.dependencies || {}),
|
|
1545
|
+
...Object.keys(packageJson.devDependencies || {})
|
|
1546
|
+
];
|
|
1269
1547
|
for (const dep of deps) {
|
|
1270
1548
|
const packageDir = nameToDirectory.get(dep);
|
|
1271
1549
|
if (packageDir !== void 0 && (excludedReferences === void 0 || !matchesAnyGlob2(dep, excludedReferences))) {
|
|
1272
|
-
const absoluteReferencePath = tsconfigReferenceFile !== void 0 ?
|
|
1550
|
+
const absoluteReferencePath = tsconfigReferenceFile !== void 0 ? path6.join(packageDir, tsconfigReferenceFile) : packageDir;
|
|
1273
1551
|
template.references.push({
|
|
1274
|
-
path:
|
|
1552
|
+
path: path6.relative(context.packageDir, absoluteReferencePath)
|
|
1275
1553
|
});
|
|
1276
1554
|
}
|
|
1277
1555
|
}
|
|
@@ -1285,98 +1563,6 @@ function makeGenerator(template, excludedReferences, additionalReferences, tscon
|
|
|
1285
1563
|
return JSON.stringify(template, void 0, 2) + "\n";
|
|
1286
1564
|
};
|
|
1287
1565
|
}
|
|
1288
|
-
|
|
1289
|
-
// src/nestedWorkspaces.ts
|
|
1290
|
-
import * as globby from "globby";
|
|
1291
|
-
import * as path6 from "node:path";
|
|
1292
|
-
import * as r10 from "runtypes";
|
|
1293
|
-
var Options10 = r10.Undefined;
|
|
1294
|
-
var nestedWorkspaces = createRuleFactory({
|
|
1295
|
-
name: "nestedWorkspaces",
|
|
1296
|
-
check: (context) => {
|
|
1297
|
-
const rootPackageJson = context.getWorkspaceContext().getPackageJson();
|
|
1298
|
-
const packageJsonPaths = globby.globbySync(["*/**/package.json", "!**/node_modules/**"]);
|
|
1299
|
-
const workspaces = Array.isArray(rootPackageJson.workspaces) ? rootPackageJson.workspaces : rootPackageJson.workspaces !== void 0 ? rootPackageJson.workspaces.packages : void 0;
|
|
1300
|
-
if (workspaces === void 0 && packageJsonPaths.length > 0) {
|
|
1301
|
-
context.addError({
|
|
1302
|
-
file: context.getPackageJsonPath(),
|
|
1303
|
-
message: 'The "workspace" field is missing, even though there are workspaces in the repository.'
|
|
1304
|
-
});
|
|
1305
|
-
return;
|
|
1306
|
-
}
|
|
1307
|
-
const workspacePackageJsons = (workspaces || []).map((item) => `${item}/package.json`);
|
|
1308
|
-
const expandedWorkspacesGlobs = globby.globbySync([...workspacePackageJsons, "!**/node_modules/**"]);
|
|
1309
|
-
const difference = packageJsonPaths.filter((packageJsonPath) => !expandedWorkspacesGlobs.includes(packageJsonPath));
|
|
1310
|
-
if (difference.length !== 0) {
|
|
1311
|
-
const differencesList = difference.map((packageJsonPath) => path6.dirname(packageJsonPath)).join(", ");
|
|
1312
|
-
context.addError({
|
|
1313
|
-
file: context.getPackageJsonPath(),
|
|
1314
|
-
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/*".`
|
|
1315
|
-
});
|
|
1316
|
-
}
|
|
1317
|
-
},
|
|
1318
|
-
validateOptions: Options10.check
|
|
1319
|
-
});
|
|
1320
|
-
|
|
1321
|
-
// src/requireDependency.ts
|
|
1322
|
-
import { mutateJson as mutateJson5 } from "@monorepolint/utils";
|
|
1323
|
-
import { diff as diff8 } from "jest-diff";
|
|
1324
|
-
import * as r11 from "runtypes";
|
|
1325
|
-
var Options11 = r11.Partial({
|
|
1326
|
-
dependencies: r11.Dictionary(r11.String),
|
|
1327
|
-
devDependencies: r11.Dictionary(r11.String),
|
|
1328
|
-
peerDependencies: r11.Dictionary(r11.String),
|
|
1329
|
-
optionalDependencies: r11.Dictionary(r11.String)
|
|
1330
|
-
});
|
|
1331
|
-
var requireDependency = createRuleFactory({
|
|
1332
|
-
name: "requireDependency",
|
|
1333
|
-
check: function expectPackageEntry(context, options) {
|
|
1334
|
-
const packageJson = context.getPackageJson();
|
|
1335
|
-
const packageJsonPath = context.getPackageJsonPath();
|
|
1336
|
-
[
|
|
1337
|
-
"dependencies",
|
|
1338
|
-
"devDependencies",
|
|
1339
|
-
"peerDependencies",
|
|
1340
|
-
"optionalDependencies"
|
|
1341
|
-
].forEach((type) => {
|
|
1342
|
-
var _a;
|
|
1343
|
-
if (!options[type]) {
|
|
1344
|
-
return;
|
|
1345
|
-
}
|
|
1346
|
-
if (packageJson[type] === void 0) {
|
|
1347
|
-
context.addError({
|
|
1348
|
-
file: packageJsonPath,
|
|
1349
|
-
message: `No ${type} block, cannot add required ${type}.`,
|
|
1350
|
-
fixer: () => {
|
|
1351
|
-
mutateJson5(packageJsonPath, context.host, (input) => {
|
|
1352
|
-
input[type] = options[type];
|
|
1353
|
-
return input;
|
|
1354
|
-
});
|
|
1355
|
-
}
|
|
1356
|
-
});
|
|
1357
|
-
return;
|
|
1358
|
-
}
|
|
1359
|
-
for (const [dep, version] of Object.entries(options[type])) {
|
|
1360
|
-
if (((_a = packageJson[type]) == null ? void 0 : _a[dep]) !== version) {
|
|
1361
|
-
context.addError({
|
|
1362
|
-
file: packageJsonPath,
|
|
1363
|
-
message: `Expected dependency ${dep}@${version}`,
|
|
1364
|
-
longMessage: diff8(`${dep}@${version}
|
|
1365
|
-
`, `${dep}@${packageJson[type][dep] || "missing"}
|
|
1366
|
-
`),
|
|
1367
|
-
fixer: () => {
|
|
1368
|
-
mutateJson5(packageJsonPath, context.host, (input) => {
|
|
1369
|
-
input[type] = { ...input[type], [dep]: version };
|
|
1370
|
-
return input;
|
|
1371
|
-
});
|
|
1372
|
-
}
|
|
1373
|
-
});
|
|
1374
|
-
}
|
|
1375
|
-
}
|
|
1376
|
-
});
|
|
1377
|
-
},
|
|
1378
|
-
validateOptions: Options11.check
|
|
1379
|
-
});
|
|
1380
1566
|
export {
|
|
1381
1567
|
alphabeticalDependencies,
|
|
1382
1568
|
alphabeticalScripts,
|
|
@@ -1385,8 +1571,10 @@ export {
|
|
|
1385
1571
|
consistentVersions,
|
|
1386
1572
|
createRuleFactory,
|
|
1387
1573
|
fileContents,
|
|
1574
|
+
forceError,
|
|
1388
1575
|
mustSatisfyPeerDependencies,
|
|
1389
1576
|
nestedWorkspaces,
|
|
1577
|
+
oncePerPackage,
|
|
1390
1578
|
packageEntry,
|
|
1391
1579
|
packageOrder,
|
|
1392
1580
|
packageScript,
|