@monorepolint/rules 0.6.0-alpha.4 → 0.6.0-alpha.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/.turbo/turbo-clean.log +1 -1
  2. package/.turbo/turbo-compile-typescript.log +1 -1
  3. package/.turbo/turbo-lint.log +1 -1
  4. package/.turbo/turbo-test.log +443 -92
  5. package/.turbo/turbo-transpile-typescript.log +5 -5
  6. package/CHANGELOG.md +112 -0
  7. package/build/js/index.js +413 -368
  8. package/build/js/index.js.map +1 -1
  9. package/build/tsconfig.tsbuildinfo +1 -1
  10. package/build/types/REMOVE.d.ts +2 -0
  11. package/build/types/REMOVE.d.ts.map +1 -0
  12. package/build/types/__tests__/alphabeticalDependencies.spec.d.ts +8 -0
  13. package/build/types/__tests__/alphabeticalDependencies.spec.d.ts.map +1 -0
  14. package/build/types/__tests__/forceError.spec.d.ts +8 -0
  15. package/build/types/__tests__/forceError.spec.d.ts.map +1 -0
  16. package/build/types/__tests__/oncePerPackage.spec.d.ts +8 -0
  17. package/build/types/__tests__/oncePerPackage.spec.d.ts.map +1 -0
  18. package/build/types/__tests__/standardTsconfig.spec.d.ts +8 -0
  19. package/build/types/__tests__/standardTsconfig.spec.d.ts.map +1 -0
  20. package/build/types/bannedDependencies.d.ts +9 -33
  21. package/build/types/bannedDependencies.d.ts.map +1 -1
  22. package/build/types/consistentDependencies.d.ts +6 -6
  23. package/build/types/consistentDependencies.d.ts.map +1 -1
  24. package/build/types/consistentVersions.d.ts +6 -10
  25. package/build/types/consistentVersions.d.ts.map +1 -1
  26. package/build/types/fileContents.d.ts +3 -2
  27. package/build/types/fileContents.d.ts.map +1 -1
  28. package/build/types/index.d.ts +1 -0
  29. package/build/types/index.d.ts.map +1 -1
  30. package/build/types/mustSatisfyPeerDependencies.d.ts +12 -190
  31. package/build/types/mustSatisfyPeerDependencies.d.ts.map +1 -1
  32. package/build/types/nestedWorkspaces.d.ts +2 -2
  33. package/build/types/nestedWorkspaces.d.ts.map +1 -1
  34. package/build/types/oncePerPackage.d.ts +6 -6
  35. package/build/types/oncePerPackage.d.ts.map +1 -1
  36. package/build/types/packageEntry.d.ts +11 -33
  37. package/build/types/packageEntry.d.ts.map +1 -1
  38. package/build/types/packageOrder.d.ts +2 -1
  39. package/build/types/packageOrder.d.ts.map +1 -1
  40. package/build/types/packageScript.d.ts +13 -22
  41. package/build/types/packageScript.d.ts.map +1 -1
  42. package/build/types/requireDependency.d.ts +5 -20
  43. package/build/types/requireDependency.d.ts.map +1 -1
  44. package/build/types/standardTsconfig.d.ts +12 -19
  45. package/build/types/standardTsconfig.d.ts.map +1 -1
  46. package/build/types/util/zodSchemas.d.ts +14 -0
  47. package/build/types/util/zodSchemas.d.ts.map +1 -0
  48. package/coverage/block-navigation.js +1 -1
  49. package/coverage/clover.xml +1420 -1452
  50. package/coverage/coverage-final.json +21 -19
  51. package/coverage/index.html +27 -27
  52. package/coverage/sorter.js +21 -7
  53. package/coverage/src/REMOVE.ts.html +88 -0
  54. package/coverage/src/alphabeticalDependencies.ts.html +15 -15
  55. package/coverage/src/alphabeticalScripts.ts.html +5 -5
  56. package/coverage/src/bannedDependencies.ts.html +20 -53
  57. package/coverage/src/consistentDependencies.ts.html +20 -14
  58. package/coverage/src/consistentVersions.ts.html +330 -183
  59. package/coverage/src/fileContents.ts.html +223 -88
  60. package/coverage/src/forceError.ts.html +31 -31
  61. package/coverage/src/index.html +104 -89
  62. package/coverage/src/index.ts.html +11 -5
  63. package/coverage/src/mustSatisfyPeerDependencies.ts.html +15 -501
  64. package/coverage/src/nestedWorkspaces.ts.html +5 -5
  65. package/coverage/src/oncePerPackage.ts.html +31 -31
  66. package/coverage/src/packageEntry.ts.html +121 -91
  67. package/coverage/src/packageOrder.ts.html +44 -14
  68. package/coverage/src/packageScript.ts.html +235 -88
  69. package/coverage/src/requireDependency.ts.html +241 -82
  70. package/coverage/src/standardTsconfig.ts.html +212 -212
  71. package/coverage/src/util/checkAlpha.ts.html +40 -40
  72. package/coverage/src/util/createRuleFactory.ts.html +19 -19
  73. package/coverage/src/util/index.html +30 -15
  74. package/coverage/src/util/makeDirectory.ts.html +11 -11
  75. package/coverage/src/util/packageDependencyGraphService.ts.html +1 -1
  76. package/coverage/src/util/zodSchemas.ts.html +130 -0
  77. package/package.json +15 -15
  78. package/src/REMOVE.ts +1 -0
  79. package/src/__tests__/alphabeticalDependencies.spec.ts +102 -0
  80. package/src/__tests__/alphabeticalScripts.spec.ts +18 -0
  81. package/src/__tests__/bannedDependencies.spec.ts +49 -0
  82. package/src/__tests__/consistentDependencies.spec.ts +23 -0
  83. package/src/__tests__/consistentVersions.spec.ts +142 -0
  84. package/src/__tests__/fileContents.spec.ts +348 -0
  85. package/src/__tests__/forceError.spec.ts +70 -0
  86. package/src/__tests__/mustSatisfyPeerDependencies.spec.ts +44 -0
  87. package/src/__tests__/nestedWorkspaces.spec.ts +14 -0
  88. package/src/__tests__/oncePerPackage.spec.ts +75 -0
  89. package/src/__tests__/packageEntry.spec.ts +177 -0
  90. package/src/__tests__/packageOrder.spec.ts +22 -0
  91. package/src/__tests__/packageScript.spec.ts +549 -0
  92. package/src/__tests__/requireDependency.spec.ts +259 -2
  93. package/src/__tests__/standardTsconfig.spec.ts +91 -0
  94. package/src/bannedDependencies.ts +14 -25
  95. package/src/consistentDependencies.ts +10 -8
  96. package/src/consistentVersions.ts +132 -83
  97. package/src/fileContents.ts +80 -35
  98. package/src/index.ts +2 -0
  99. package/src/mustSatisfyPeerDependencies.ts +10 -172
  100. package/src/nestedWorkspaces.ts +4 -4
  101. package/src/oncePerPackage.ts +6 -6
  102. package/src/packageEntry.ts +60 -50
  103. package/src/packageOrder.ts +19 -9
  104. package/src/packageScript.ts +67 -18
  105. package/src/requireDependency.ts +84 -31
  106. package/src/standardTsconfig.ts +26 -26
  107. package/src/util/zodSchemas.ts +15 -0
package/build/js/index.js CHANGED
@@ -83,13 +83,12 @@ var alphabeticalScripts = createRuleFactory({
83
83
  });
84
84
 
85
85
  // src/bannedDependencies.ts
86
- import { matchesAnyGlob } from "@monorepolint/utils";
87
- import { AggregateTiming } from "@monorepolint/utils";
88
- import * as path2 from "node:path";
89
- import * as r from "runtypes";
86
+ import { AggregateTiming, matchesAnyGlob } from "@monorepolint/utils";
87
+ import * as path2 from "path";
88
+ import { z } from "zod";
90
89
 
91
90
  // src/util/packageDependencyGraphService.ts
92
- import * as path from "node:path";
91
+ import * as path from "path";
93
92
  import resolvePackagePath from "resolve-package-path";
94
93
  var PackageDependencyGraphService = class {
95
94
  /** Construct a graph of package dependencies and return the root node. */
@@ -154,27 +153,17 @@ var PackageDependencyGraphService = class {
154
153
  };
155
154
 
156
155
  // src/bannedDependencies.ts
157
- var bannedDepGlobsField = r.Union(
158
- r.Array(r.String),
159
- r.Record({
160
- glob: r.Array(r.String).optional(),
161
- exact: r.Array(r.String).optional()
156
+ var bannedDepGlobsField = z.union([
157
+ z.array(z.string()),
158
+ z.object({
159
+ glob: z.array(z.string()).optional(),
160
+ exact: z.array(z.string()).optional()
162
161
  })
163
- );
164
- var Options = r.Union(
165
- r.Record({
166
- bannedDependencies: bannedDepGlobsField,
167
- bannedTransitiveDependencies: r.Undefined.optional()
168
- }),
169
- r.Record({
170
- bannedDependencies: bannedDepGlobsField.optional(),
171
- bannedTransitiveDependencies: r.Array(r.String)
172
- }),
173
- r.Record({
174
- bannedDependencies: bannedDepGlobsField.optional(),
175
- bannedTransitiveDependencies: r.Array(r.String).optional()
176
- })
177
- );
162
+ ]);
163
+ var Options = z.object({
164
+ bannedDependencies: bannedDepGlobsField.optional(),
165
+ bannedTransitiveDependencies: z.array(z.string()).optional()
166
+ });
178
167
  var setCache = /* @__PURE__ */ new Map();
179
168
  var aggregateTiming = new AggregateTiming(":bannedDependencies stats");
180
169
  var bannedDependencies = createRuleFactory({
@@ -225,7 +214,7 @@ var bannedDependencies = createRuleFactory({
225
214
  }
226
215
  aggregateTiming.stop();
227
216
  },
228
- validateOptions: Options.check,
217
+ validateOptions: Options.parse,
229
218
  printStats: () => {
230
219
  aggregateTiming.printResults();
231
220
  }
@@ -272,10 +261,13 @@ function nameOrPackageJsonPath(node) {
272
261
 
273
262
  // src/consistentDependencies.ts
274
263
  import { diff as diff2 } from "jest-diff";
275
- import * as r2 from "runtypes";
276
- var Options2 = r2.Record({
277
- ignoredDependencies: r2.Array(r2.String).Or(r2.Undefined)
278
- }).Or(r2.Undefined);
264
+ import { z as z2 } from "zod";
265
+ var Options2 = z2.union([
266
+ z2.undefined(),
267
+ z2.object({
268
+ ignoredDependencies: z2.array(z2.string())
269
+ })
270
+ ]);
279
271
  var skippedVersions = ["*", "latest"];
280
272
  var consistentDependencies = createRuleFactory({
281
273
  name: "consistentDependencies",
@@ -283,7 +275,7 @@ var consistentDependencies = createRuleFactory({
283
275
  checkDeps(context, args, "dependencies");
284
276
  checkDeps(context, args, "devDependencies");
285
277
  },
286
- validateOptions: Options2.check
278
+ validateOptions: Options2.parse
287
279
  });
288
280
  function checkDeps(context, args, block) {
289
281
  const packageJson = context.getPackageJson();
@@ -333,15 +325,15 @@ function omit(obj, keysToOmit) {
333
325
 
334
326
  // src/consistentVersions.ts
335
327
  import { mutateJson } from "@monorepolint/utils";
336
- import * as r3 from "runtypes";
337
328
  import { coerce } from "semver";
338
- var Options3 = r3.Record({
339
- matchDependencyVersions: r3.Dictionary(r3.Union(r3.String, r3.Array(r3.String)))
329
+ import { z as z3 } from "zod";
330
+ var Options3 = z3.object({
331
+ matchDependencyVersions: z3.record(z3.string(), z3.union([z3.string(), z3.array(z3.string())]))
340
332
  });
341
333
  var consistentVersions = createRuleFactory({
342
334
  name: "consistentVersions",
343
335
  check: checkConsistentVersions,
344
- validateOptions: Options3.check
336
+ validateOptions: Options3.parse
345
337
  });
346
338
  function checkConsistentVersions(context, options) {
347
339
  for (const [dependencyPackageName, expectedPackageDependencyValue] of Object.entries(
@@ -362,48 +354,83 @@ function checkConsistentVersions(context, options) {
362
354
  }
363
355
  }
364
356
  }
357
+ var shouldUpdateVersion = (actualValue, expectedValue, isProtocolVersionString, expectedSemVer) => {
358
+ if (isProtocolVersionString) {
359
+ return actualValue !== expectedValue;
360
+ }
361
+ const actualSemVer = coerce(actualValue);
362
+ return actualSemVer != null && actualSemVer.raw !== expectedSemVer.raw;
363
+ };
364
+ var matchesAnyVersion = (actualValue, protocolVersions, acceptedSemVerVersions) => {
365
+ if (protocolVersions.includes(actualValue)) {
366
+ return true;
367
+ }
368
+ const actualSemVer = coerce(actualValue);
369
+ if (actualSemVer == null) {
370
+ return false;
371
+ }
372
+ return acceptedSemVerVersions.some(
373
+ (acceptedSemVer) => actualSemVer.raw === acceptedSemVer.raw
374
+ );
375
+ };
365
376
  var ensurePackageIsCorrectVersion = (context, dependencyPackageName, expectedPackageDependencyValue) => {
366
377
  const packageJson = context.getPackageJson();
367
378
  const packageJsonPath = context.getPackageJsonPath();
368
- const expectedPackageDependencyVersion = coerce(
369
- expectedPackageDependencyValue
370
- );
371
- if (expectedPackageDependencyVersion == null) {
372
- throw new Error(
373
- `Malformed expected package dependency version defined in monorepolint configuration: ${dependencyPackageName} @ '${expectedPackageDependencyValue}'`
374
- );
379
+ const isProtocolVersion = expectedPackageDependencyValue.endsWith(":");
380
+ let expectedPackageDependencyVersion = null;
381
+ if (!isProtocolVersion) {
382
+ expectedPackageDependencyVersion = coerce(expectedPackageDependencyValue);
383
+ if (expectedPackageDependencyVersion == null) {
384
+ throw new Error(
385
+ `Malformed expected package dependency version defined in monorepolint configuration: ${dependencyPackageName} @ '${expectedPackageDependencyValue}'`
386
+ );
387
+ }
375
388
  }
376
389
  const actualPackageDependencyValue = packageJson.dependencies && packageJson.dependencies[dependencyPackageName];
377
- const actualPackageDependencyVersion = coerce(actualPackageDependencyValue);
378
- if (actualPackageDependencyVersion != null && actualPackageDependencyVersion.raw !== expectedPackageDependencyVersion.raw) {
379
- context.addError({
380
- file: packageJsonPath,
381
- message: `Expected dependency on ${dependencyPackageName} to match version defined in monorepolint configuration '${expectedPackageDependencyValue}', got '${actualPackageDependencyValue}' instead.`,
382
- fixer: () => mutateJson(packageJsonPath, context.host, (input) => {
383
- input.dependencies[dependencyPackageName] = expectedPackageDependencyValue;
384
- return input;
385
- })
386
- });
390
+ if (actualPackageDependencyValue != null) {
391
+ const shouldUpdate = shouldUpdateVersion(
392
+ actualPackageDependencyValue,
393
+ expectedPackageDependencyValue,
394
+ isProtocolVersion,
395
+ expectedPackageDependencyVersion
396
+ );
397
+ if (shouldUpdate) {
398
+ context.addError({
399
+ file: packageJsonPath,
400
+ message: `Expected dependency on ${dependencyPackageName} to match version defined in monorepolint configuration '${expectedPackageDependencyValue}', got '${actualPackageDependencyValue}' instead.`,
401
+ fixer: () => mutateJson(packageJsonPath, context.host, (input) => {
402
+ input.dependencies[dependencyPackageName] = expectedPackageDependencyValue;
403
+ return input;
404
+ })
405
+ });
406
+ }
387
407
  }
388
408
  const actualPackageDevDependencyValue = packageJson.devDependencies && packageJson.devDependencies[dependencyPackageName];
389
- const actualPackageDevDependencyVersion = coerce(
390
- actualPackageDevDependencyValue
391
- );
392
- if (actualPackageDevDependencyVersion != null && actualPackageDevDependencyVersion.raw !== expectedPackageDependencyVersion.raw) {
393
- context.addError({
394
- file: packageJsonPath,
395
- message: `Expected devDependency on ${dependencyPackageName} to match version defined in monorepolint configuration '${expectedPackageDependencyValue}', got '${actualPackageDevDependencyValue}' instead`,
396
- fixer: () => mutateJson(packageJsonPath, context.host, (input) => {
397
- input.devDependencies[dependencyPackageName] = expectedPackageDependencyValue;
398
- return input;
399
- })
400
- });
409
+ if (actualPackageDevDependencyValue != null) {
410
+ const shouldUpdateDev = shouldUpdateVersion(
411
+ actualPackageDevDependencyValue,
412
+ expectedPackageDependencyValue,
413
+ isProtocolVersion,
414
+ expectedPackageDependencyVersion
415
+ );
416
+ if (shouldUpdateDev) {
417
+ context.addError({
418
+ file: packageJsonPath,
419
+ message: `Expected devDependency on ${dependencyPackageName} to match version defined in monorepolint configuration '${expectedPackageDependencyValue}', got '${actualPackageDevDependencyValue}' instead`,
420
+ fixer: () => mutateJson(packageJsonPath, context.host, (input) => {
421
+ input.devDependencies[dependencyPackageName] = expectedPackageDependencyValue;
422
+ return input;
423
+ })
424
+ });
425
+ }
401
426
  }
402
427
  };
403
428
  var ensurePackageMatchesSomeVersion = (context, dependencyPackageName, acceptedPackageDependencyValues) => {
404
429
  const packageJson = context.getPackageJson();
405
430
  const packageJsonPath = context.getPackageJsonPath();
406
- const acceptedPackageDependencyVersions = acceptedPackageDependencyValues.map(
431
+ const protocolVersions = acceptedPackageDependencyValues.filter((val) => val.endsWith(":"));
432
+ const regularVersions = acceptedPackageDependencyValues.filter((val) => !val.endsWith(":"));
433
+ const acceptedPackageDependencyVersions = regularVersions.map(
407
434
  (acceptedPackageDependencyValue) => {
408
435
  const acceptedPackageDependencyVersion = coerce(
409
436
  acceptedPackageDependencyValue
@@ -417,75 +444,101 @@ var ensurePackageMatchesSomeVersion = (context, dependencyPackageName, acceptedP
417
444
  }
418
445
  );
419
446
  const actualPackageDependencyValue = packageJson.dependencies && packageJson.dependencies[dependencyPackageName];
420
- const actualPackageDependencyVersion = coerce(actualPackageDependencyValue);
421
- if (actualPackageDependencyVersion != null && acceptedPackageDependencyVersions.every(
422
- (acceptedPackageDependencyVersion) => actualPackageDependencyVersion.raw !== acceptedPackageDependencyVersion.raw
423
- )) {
424
- context.addError({
425
- file: packageJsonPath,
426
- message: `Expected dependency on ${dependencyPackageName} to match one of '${JSON.stringify(
427
- acceptedPackageDependencyValues
428
- )}', got '${actualPackageDependencyValue}' instead.`
429
- });
447
+ if (actualPackageDependencyValue != null) {
448
+ const matches = matchesAnyVersion(
449
+ actualPackageDependencyValue,
450
+ protocolVersions,
451
+ acceptedPackageDependencyVersions
452
+ );
453
+ if (!matches) {
454
+ context.addError({
455
+ file: packageJsonPath,
456
+ message: `Expected dependency on ${dependencyPackageName} to match one of '${JSON.stringify(
457
+ acceptedPackageDependencyValues
458
+ )}', got '${actualPackageDependencyValue}' instead.`
459
+ });
460
+ }
430
461
  }
431
462
  const actualPackageDevDependencyValue = packageJson.devDependencies && packageJson.devDependencies[dependencyPackageName];
432
- const actualPackageDevDependencyVersion = coerce(
433
- actualPackageDevDependencyValue
434
- );
435
- if (actualPackageDevDependencyVersion != null && acceptedPackageDependencyVersions.every(
436
- (acceptedPackageDependencyVersion) => actualPackageDevDependencyVersion.raw !== acceptedPackageDependencyVersion.raw
437
- )) {
438
- context.addError({
439
- file: packageJsonPath,
440
- message: `Expected devDependency on ${dependencyPackageName} to match one of '${JSON.stringify(
441
- acceptedPackageDependencyValues
442
- )}', got '${actualPackageDevDependencyValue}' instead.`
443
- });
463
+ if (actualPackageDevDependencyValue != null) {
464
+ const matches = matchesAnyVersion(
465
+ actualPackageDevDependencyValue,
466
+ protocolVersions,
467
+ acceptedPackageDependencyVersions
468
+ );
469
+ if (!matches) {
470
+ context.addError({
471
+ file: packageJsonPath,
472
+ message: `Expected devDependency on ${dependencyPackageName} to match one of '${JSON.stringify(
473
+ acceptedPackageDependencyValues
474
+ )}', got '${actualPackageDevDependencyValue}' instead.`
475
+ });
476
+ }
444
477
  }
445
478
  };
446
479
 
447
480
  // src/fileContents.ts
448
481
  import { diff as diff3 } from "jest-diff";
449
482
  import * as path3 from "path";
450
- import * as r4 from "runtypes";
451
- var Options4 = r4.Union(
452
- r4.Record({
453
- file: r4.String,
454
- generator: r4.Function.withGuard((x) => x != void 0),
455
- template: r4.Undefined.optional(),
456
- templateFile: r4.Undefined.optional()
483
+ import { z as z5 } from "zod";
484
+
485
+ // src/REMOVE.ts
486
+ var REMOVE = Symbol.for("monorepolint/REMOVE");
487
+
488
+ // src/util/zodSchemas.ts
489
+ import { z as z4 } from "zod";
490
+ var ZodRemove = z4.custom((x) => x === REMOVE);
491
+
492
+ // src/fileContents.ts
493
+ var Options4 = z5.union([
494
+ z5.object({
495
+ file: z5.string(),
496
+ generator: z5.custom((val) => {
497
+ return typeof val === "function";
498
+ }),
499
+ template: z5.undefined().optional(),
500
+ templateFile: z5.undefined().optional()
457
501
  }),
458
- r4.Record({
459
- file: r4.String,
460
- generator: r4.Undefined.optional(),
461
- template: r4.String.Or(r4.Undefined),
462
- templateFile: r4.Undefined.optional()
502
+ z5.object({
503
+ file: z5.string(),
504
+ generator: z5.undefined().optional(),
505
+ template: z5.union([
506
+ z5.string(),
507
+ ZodRemove
508
+ ]),
509
+ templateFile: z5.undefined().optional()
463
510
  }),
464
- r4.Record({
465
- file: r4.String,
466
- generator: r4.Undefined.optional(),
467
- template: r4.Undefined.optional(),
468
- templateFile: r4.String
511
+ z5.object({
512
+ file: z5.string(),
513
+ generator: z5.undefined().optional(),
514
+ template: z5.undefined().optional(),
515
+ templateFile: z5.string()
469
516
  })
470
- );
517
+ ]);
471
518
  var fileContents = createRuleFactory({
472
519
  name: "fileContents",
473
520
  check: async (context, opts) => {
474
521
  const fullPath = path3.join(context.packageDir, opts.file);
522
+ if (fullPath.includes("\0")) {
523
+ throw new Error(`Invalid file path: path contains null bytes`);
524
+ }
475
525
  const expectedContent = await getExpectedContents(context, opts);
526
+ if (expectedContent === Symbol.for("GENERATOR_ERROR")) {
527
+ return;
528
+ }
476
529
  const pathExists = context.host.exists(fullPath);
477
- const actualContent = pathExists ? context.host.readFile(fullPath, { encoding: "utf-8" }) : void 0;
530
+ const actualContent = pathExists ? context.host.readFile(fullPath, { encoding: "utf-8" }) : REMOVE;
478
531
  if (actualContent !== expectedContent) {
479
- const longMessage = pathExists && expectedContent == void 0 ? void 0 : diff3(expectedContent, actualContent, { expand: true });
480
- const message = pathExists && expectedContent == void 0 ? "File should not exist" : "Expect file contents to match";
532
+ const longMessage = pathExists && (expectedContent === void 0 || expectedContent === REMOVE) ? void 0 : diff3(expectedContent, actualContent, { expand: true });
533
+ const message = pathExists && (expectedContent === void 0 || expectedContent === REMOVE) ? "File should not exist" : "Expect file contents to match";
481
534
  context.addError({
482
535
  file: fullPath,
483
536
  message,
484
537
  longMessage,
485
538
  fixer: () => {
486
- if (expectedContent === void 0) {
539
+ if (expectedContent === REMOVE) {
487
540
  if (pathExists) context.host.deleteFile(fullPath);
488
- } else {
541
+ } else if (expectedContent !== void 0 && typeof expectedContent === "string") {
489
542
  context.host.mkdir(path3.dirname(fullPath), { recursive: true });
490
543
  context.host.writeFile(fullPath, expectedContent, {
491
544
  encoding: "utf-8"
@@ -495,7 +548,7 @@ var fileContents = createRuleFactory({
495
548
  });
496
549
  }
497
550
  },
498
- validateOptions: Options4.check
551
+ validateOptions: Options4.parse
499
552
  });
500
553
  var optionsCache = /* @__PURE__ */ new Map();
501
554
  async function getExpectedContents(context, opts) {
@@ -508,16 +561,35 @@ async function getExpectedContents(context, opts) {
508
561
  }
509
562
  if (opts.generator) {
510
563
  optionsCache.set(opts, opts.generator);
511
- return opts.generator(context);
564
+ try {
565
+ const result = await opts.generator(context);
566
+ if (typeof result !== "string" && result !== REMOVE) {
567
+ throw new Error(`Generator function must return a string or REMOVE, got ${typeof result}`);
568
+ }
569
+ return result;
570
+ } catch (error) {
571
+ const errorMessage = error instanceof Error ? error.message : String(error);
572
+ const fullPath = path3.join(context.packageDir, opts.file);
573
+ context.addError({
574
+ file: fullPath,
575
+ message: `Generator function failed: ${errorMessage}`,
576
+ longMessage: `The generator function for file "${opts.file}" threw an error:
577
+
578
+ ${errorMessage}`
579
+ });
580
+ return Symbol.for("GENERATOR_ERROR");
581
+ }
512
582
  } else if (opts.templateFile) {
513
583
  const { packageDir: workspacePackageDir } = context.getWorkspaceContext();
514
584
  const fullPath = path3.resolve(workspacePackageDir, opts.templateFile);
515
585
  const template = context.host.readFile(fullPath, { encoding: "utf-8" });
516
586
  optionsCache.set(opts, template);
517
587
  return template;
518
- } else {
588
+ } else if (opts.template !== void 0) {
519
589
  optionsCache.set(opts, opts.template);
520
590
  return opts.template;
591
+ } else {
592
+ throw new Error("Unable to get expected contents");
521
593
  }
522
594
  }
523
595
 
@@ -548,154 +620,20 @@ var forceError = createRuleFactory({
548
620
 
549
621
  // src/mustSatisfyPeerDependencies.ts
550
622
  import { mutateJson as mutateJson2 } from "@monorepolint/utils";
551
- import * as path4 from "node:path";
623
+ import * as path4 from "path";
552
624
  import resolvePackagePath2 from "resolve-package-path";
553
- import * as r5 from "runtypes";
554
625
  import { coerce as coerce2 } from "semver";
555
- var Options5 = r5.Union(
556
- r5.Partial({
557
- skipUnparseableRanges: r5.Undefined,
558
- dependencyWhitelist: r5.Undefined,
559
- dependencyBlacklist: r5.Undefined,
560
- enforceForDevDependencies: r5.Undefined
561
- }),
562
- r5.Record({
563
- skipUnparseableRanges: r5.Boolean
564
- }).And(
565
- r5.Partial({
566
- dependencyWhitelist: r5.Undefined,
567
- dependencyBlacklist: r5.Undefined,
568
- enforceForDevDependencies: r5.Undefined
569
- })
570
- ),
571
- r5.Record({
572
- dependencyWhitelist: r5.Array(r5.String)
573
- }).And(
574
- r5.Partial({
575
- skipUnparseableRanges: r5.Undefined,
576
- dependencyBlacklist: r5.Undefined,
577
- enforceForDevDependencies: r5.Undefined
578
- })
579
- ),
580
- r5.Record({
581
- dependencyBlacklist: r5.Array(r5.String)
582
- }).And(
583
- r5.Partial({
584
- skipUnparseableRanges: r5.Undefined,
585
- dependencyWhitelist: r5.Undefined,
586
- enforceForDevDependencies: r5.Undefined
587
- })
588
- ),
589
- r5.Record({
590
- enforceForDevDependencies: r5.Boolean
591
- }).And(
592
- r5.Partial({
593
- skipUnparseableRanges: r5.Undefined,
594
- dependencyWhitelist: r5.Undefined,
595
- dependencyBlacklist: r5.Undefined
596
- })
597
- ),
598
- r5.Record({
599
- skipUnparseableRanges: r5.Boolean,
600
- dependencyWhitelist: r5.Array(r5.String)
601
- }).And(
602
- r5.Partial({
603
- dependencyBlacklist: r5.Undefined,
604
- enforceForDevDependencies: r5.Undefined
605
- })
606
- ),
607
- r5.Record({
608
- skipUnparseableRanges: r5.Boolean,
609
- dependencyBlacklist: r5.Array(r5.String)
610
- }).And(
611
- r5.Partial({
612
- dependencyWhitelist: r5.Undefined,
613
- enforceForDevDependencies: r5.Undefined
614
- })
615
- ),
616
- r5.Record({
617
- skipUnparseableRanges: r5.Boolean,
618
- enforceForDevDependencies: r5.Boolean
619
- }).And(
620
- r5.Partial({
621
- dependencyWhitelist: r5.Undefined,
622
- dependencyBlacklist: r5.Undefined
623
- })
624
- ),
625
- r5.Record({
626
- dependencyWhitelist: r5.Array(r5.String),
627
- dependencyBlacklist: r5.Array(r5.String)
628
- }).And(
629
- r5.Partial({
630
- skipUnparseableRanges: r5.Undefined,
631
- enforceForDevDependencies: r5.Undefined
632
- })
633
- ),
634
- r5.Record({
635
- dependencyWhitelist: r5.Array(r5.String),
636
- enforceForDevDependencies: r5.Boolean
637
- }).And(
638
- r5.Partial({
639
- skipUnparseableRanges: r5.Undefined,
640
- dependencyBlacklist: r5.Undefined
641
- })
642
- ),
643
- r5.Record({
644
- dependencyBlacklist: r5.Array(r5.String),
645
- enforceForDevDependencies: r5.Boolean
646
- }).And(
647
- r5.Partial({
648
- skipUnparseableRanges: r5.Undefined,
649
- dependencyWhitelist: r5.Undefined
650
- })
651
- ),
652
- r5.Record({
653
- skipUnparseableRanges: r5.Boolean,
654
- dependencyWhitelist: r5.Array(r5.String),
655
- dependencyBlacklist: r5.Array(r5.String)
656
- }).And(
657
- r5.Partial({
658
- enforceForDevDependencies: r5.Undefined
659
- })
660
- ),
661
- r5.Record({
662
- skipUnparseableRanges: r5.Boolean,
663
- dependencyWhitelist: r5.Array(r5.String),
664
- enforceForDevDependencies: r5.Boolean
665
- }).And(
666
- r5.Partial({
667
- dependencyBlacklist: r5.Undefined
668
- })
669
- ),
670
- r5.Record({
671
- skipUnparseableRanges: r5.Boolean,
672
- dependencyBlacklist: r5.Array(r5.String),
673
- enforceForDevDependencies: r5.Boolean
674
- }).And(
675
- r5.Partial({
676
- dependencyWhitelist: r5.Undefined
677
- })
678
- ),
679
- r5.Record({
680
- dependencyWhitelist: r5.Array(r5.String),
681
- dependencyBlacklist: r5.Array(r5.String),
682
- enforceForDevDependencies: r5.Boolean
683
- }).And(
684
- r5.Partial({
685
- skipUnparseableRanges: r5.Undefined
686
- })
687
- ),
688
- r5.Record({
689
- skipUnparseableRanges: r5.Boolean,
690
- dependencyWhitelist: r5.Array(r5.String),
691
- dependencyBlacklist: r5.Array(r5.String),
692
- enforceForDevDependencies: r5.Boolean
693
- })
694
- );
626
+ import { z as z6 } from "zod";
627
+ var Options5 = z6.object({
628
+ skipUnparseableRanges: z6.boolean().optional(),
629
+ dependencyWhitelist: z6.array(z6.string()).optional(),
630
+ dependencyBlacklist: z6.array(z6.string()).optional(),
631
+ enforceForDevDependencies: z6.boolean().optional()
632
+ });
695
633
  var mustSatisfyPeerDependencies = createRuleFactory({
696
634
  name: "mustSatisfyPeerDependencies",
697
635
  check: checkSatisfyPeerDependencies,
698
- validateOptions: Options5.check
636
+ validateOptions: Options5.parse
699
637
  });
700
638
  var MATCH_ANY_VERSION_RANGE = /^(\*|x)$/;
701
639
  var MATCH_GREATER_OR_EQUAL_VERSION_RANGE = /^>= ?\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-]+)*))?)?$/;
@@ -1051,9 +989,9 @@ function getAddDependencyTypeFixer({
1051
989
 
1052
990
  // src/nestedWorkspaces.ts
1053
991
  import * as globby from "globby";
1054
- import * as path5 from "node:path";
1055
- import * as r6 from "runtypes";
1056
- var Options6 = r6.Undefined;
992
+ import * as path5 from "path";
993
+ import { z as z7 } from "zod";
994
+ var Options6 = z7.undefined();
1057
995
  var nestedWorkspaces = createRuleFactory({
1058
996
  name: "nestedWorkspaces",
1059
997
  check: (context) => {
@@ -1086,14 +1024,14 @@ var nestedWorkspaces = createRuleFactory({
1086
1024
  });
1087
1025
  }
1088
1026
  },
1089
- validateOptions: Options6.check
1027
+ validateOptions: Options6.parse
1090
1028
  });
1091
1029
 
1092
1030
  // 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()
1031
+ import { z as z8 } from "zod";
1032
+ var Options7 = z8.object({
1033
+ singletonKey: z8.union([z8.string(), z8.symbol()]),
1034
+ customMessage: z8.string().optional()
1097
1035
  });
1098
1036
  var visitedMap = /* @__PURE__ */ new Map();
1099
1037
  var oncePerPackage = createRuleFactory({
@@ -1110,35 +1048,21 @@ var oncePerPackage = createRuleFactory({
1110
1048
  visited.add(context.getName());
1111
1049
  }
1112
1050
  },
1113
- validateOptions: Options7.assert
1051
+ validateOptions: Options7.parse
1114
1052
  });
1115
1053
 
1116
1054
  // src/packageEntry.ts
1117
1055
  import { mutateJson as mutateJson3 } from "@monorepolint/utils";
1118
1056
  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
- })
1057
+ import { z as z9 } from "zod";
1058
+ var Options8 = z9.object({
1059
+ entries: z9.record(z9.string(), z9.union([z9.unknown(), ZodRemove])).optional(),
1060
+ // string => unknown | REMOVE, enforces existence of keys and their values or removal
1061
+ entriesExist: z9.array(z9.string()).optional()
1062
+ // enforces existence of keys, but not values
1063
+ }).refine(
1064
+ (data) => data.entries !== void 0 || data.entriesExist !== void 0,
1065
+ { message: "At least one of 'entries' or 'entriesExist' must be provided" }
1142
1066
  );
1143
1067
  var packageEntry = createRuleFactory({
1144
1068
  name: "packageEntry",
@@ -1147,26 +1071,45 @@ var packageEntry = createRuleFactory({
1147
1071
  if (options.entries) {
1148
1072
  for (const key of Object.keys(options.entries)) {
1149
1073
  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
- });
1074
+ if (value === REMOVE) {
1075
+ if (packageJson[key] !== void 0) {
1076
+ context.addError({
1077
+ file: context.getPackageJsonPath(),
1078
+ message: createRemovalEntryErrorMessage(key),
1079
+ fixer: () => {
1080
+ mutateJson3(
1081
+ context.getPackageJsonPath(),
1082
+ context.host,
1083
+ (input) => {
1084
+ delete input[key];
1085
+ return input;
1086
+ }
1087
+ );
1088
+ }
1089
+ });
1090
+ }
1091
+ } else {
1092
+ const entryDiff = diff4(
1093
+ JSON.stringify(value) + "\n",
1094
+ (JSON.stringify(packageJson[key]) || "") + "\n"
1095
+ );
1096
+ if (typeof value !== "object" && value !== packageJson[key] || entryDiff == null || !entryDiff.includes("Compared values have no visual difference")) {
1097
+ context.addError({
1098
+ file: context.getPackageJsonPath(),
1099
+ message: createStandardizedEntryErrorMessage(key),
1100
+ longMessage: entryDiff,
1101
+ fixer: () => {
1102
+ mutateJson3(
1103
+ context.getPackageJsonPath(),
1104
+ context.host,
1105
+ (input) => {
1106
+ input[key] = value;
1107
+ return input;
1108
+ }
1109
+ );
1110
+ }
1111
+ });
1112
+ }
1170
1113
  }
1171
1114
  }
1172
1115
  }
@@ -1181,7 +1124,7 @@ var packageEntry = createRuleFactory({
1181
1124
  }
1182
1125
  }
1183
1126
  },
1184
- validateOptions: Options8.check
1127
+ validateOptions: Options8.parse
1185
1128
  });
1186
1129
  function createStandardizedEntryErrorMessage(key) {
1187
1130
  return `Expected standardized entry for '${key}'`;
@@ -1189,13 +1132,28 @@ function createStandardizedEntryErrorMessage(key) {
1189
1132
  function createExpectedEntryErrorMessage(key) {
1190
1133
  return `Expected entry for '${key}' to exist`;
1191
1134
  }
1135
+ function createRemovalEntryErrorMessage(key) {
1136
+ return `Entry '${key}' should be removed`;
1137
+ }
1192
1138
 
1193
1139
  // src/packageOrder.ts
1194
1140
  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);
1141
+ import { z as z10 } from "zod";
1142
+ var Options9 = z10.union([
1143
+ z10.undefined(),
1144
+ z10.object({
1145
+ order: z10.union([
1146
+ z10.array(z10.string()),
1147
+ z10.function({
1148
+ input: [z10.any()],
1149
+ output: z10.function({
1150
+ input: [z10.string(), z10.string()],
1151
+ output: z10.number()
1152
+ })
1153
+ })
1154
+ ])
1155
+ })
1156
+ ]);
1199
1157
  var defaultKeyOrder = [
1200
1158
  "name",
1201
1159
  "version",
@@ -1251,7 +1209,7 @@ var packageOrder = createRuleFactory({
1251
1209
  });
1252
1210
  }
1253
1211
  },
1254
- validateOptions: Options9.check
1212
+ validateOptions: Options9.parse
1255
1213
  });
1256
1214
  function arrayOrderCompare2(a, b) {
1257
1215
  for (let index = 0; index < a.length; index++) {
@@ -1285,18 +1243,30 @@ function isOrderFunction(order) {
1285
1243
  // src/packageScript.ts
1286
1244
  import { mutateJson as mutateJson4 } from "@monorepolint/utils";
1287
1245
  import { diff as diff6 } from "jest-diff";
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()
1246
+ import { z as z11 } from "zod";
1247
+ var Options10 = z11.object({
1248
+ scripts: z11.record(
1249
+ z11.string(),
1250
+ z11.union([
1251
+ z11.string(),
1252
+ ZodRemove,
1253
+ // Allow direct REMOVE values like { "build": REMOVE }
1254
+ z11.object({
1255
+ options: z11.array(z11.union([
1256
+ z11.string(),
1257
+ z11.undefined(),
1258
+ ZodRemove
1259
+ ])),
1260
+ fixValue: z11.union([
1261
+ z11.string(),
1262
+ z11.undefined(),
1263
+ z11.literal(false),
1264
+ ZodRemove
1265
+ ]).optional()
1296
1266
  })
1297
- )
1267
+ ])
1298
1268
  )
1299
- // string => string
1269
+ // string => string | REMOVE | object
1300
1270
  });
1301
1271
  var MSG_NO_SCRIPTS_BLOCK = "No scripts block in package.json";
1302
1272
  var packageScript = createRuleFactory({
@@ -1325,30 +1295,58 @@ var packageScript = createRuleFactory({
1325
1295
  let fixValue;
1326
1296
  let allowEmpty = false;
1327
1297
  let fixToEmpty = false;
1298
+ let fixToRemove = false;
1328
1299
  if (typeof value === "string") {
1329
1300
  allowedValues.add(value);
1330
1301
  fixValue = value;
1302
+ } else if (value === REMOVE) {
1303
+ allowedValues.add(REMOVE);
1304
+ fixValue = REMOVE;
1305
+ fixToRemove = true;
1331
1306
  } else {
1332
1307
  for (const q of value.options) {
1333
1308
  if (q === void 0) {
1334
1309
  allowEmpty = true;
1310
+ } else if (q === REMOVE) {
1311
+ allowEmpty = true;
1335
1312
  }
1336
1313
  allowedValues.add(q);
1337
1314
  }
1338
1315
  fixToEmpty = Object.prototype.hasOwnProperty.call(value, "fixValue") && value.fixValue === void 0;
1316
+ fixToRemove = Object.prototype.hasOwnProperty.call(value, "fixValue") && value.fixValue === REMOVE;
1339
1317
  fixValue = value.fixValue;
1340
1318
  }
1341
1319
  const actualValue = packageJson.scripts[name];
1320
+ if (value === REMOVE) {
1321
+ if (actualValue !== void 0) {
1322
+ const fixer = () => {
1323
+ mutateJson4(
1324
+ context.getPackageJsonPath(),
1325
+ context.host,
1326
+ (input) => {
1327
+ delete input.scripts[name];
1328
+ return input;
1329
+ }
1330
+ );
1331
+ };
1332
+ context.addError({
1333
+ file: context.getPackageJsonPath(),
1334
+ message: `Script '${name}' should be removed`,
1335
+ fixer
1336
+ });
1337
+ }
1338
+ continue;
1339
+ }
1342
1340
  if (!allowedValues.has(actualValue) && !(allowEmpty === true && actualValue === void 0)) {
1343
1341
  let fixer;
1344
- if (fixValue !== false && (fixValue !== void 0 || fixToEmpty === true)) {
1342
+ if (fixValue !== false && (fixValue !== void 0 || fixToEmpty === true || fixToRemove === true)) {
1345
1343
  const q = fixValue;
1346
1344
  fixer = () => {
1347
1345
  mutateJson4(
1348
1346
  context.getPackageJsonPath(),
1349
1347
  context.host,
1350
1348
  (input) => {
1351
- if (fixToEmpty && q === void 0) {
1349
+ if (fixToEmpty && q === void 0 || fixToRemove && q === REMOVE) {
1352
1350
  delete input.scripts[name];
1353
1351
  } else {
1354
1352
  input.scripts[name] = q;
@@ -1358,7 +1356,7 @@ var packageScript = createRuleFactory({
1358
1356
  );
1359
1357
  };
1360
1358
  }
1361
- const validOptionsString = Array.from(allowedValues.values()).map((a) => a === void 0 ? "(empty)" : `'${a}'`).join(", ");
1359
+ const validOptionsString = Array.from(allowedValues.values()).map((a) => a === void 0 || a === REMOVE ? "(empty)" : `'${a}'`).join(", ");
1362
1360
  context.addError({
1363
1361
  file: context.getPackageJsonPath(),
1364
1362
  message: `Expected standardized script entry for '${name}'. Valid options: ${validOptionsString}`,
@@ -1371,19 +1369,43 @@ var packageScript = createRuleFactory({
1371
1369
  }
1372
1370
  }
1373
1371
  },
1374
- validateOptions: Options10.check
1372
+ validateOptions: Options10.parse
1375
1373
  });
1376
1374
 
1377
1375
  // src/requireDependency.ts
1378
1376
  import { mutateJson as mutateJson5 } from "@monorepolint/utils";
1379
1377
  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
- });
1378
+ import { z as z12 } from "zod";
1379
+ var Options11 = z12.object({
1380
+ dependencies: z12.record(
1381
+ z12.string(),
1382
+ z12.union([
1383
+ z12.string(),
1384
+ ZodRemove
1385
+ ]).optional()
1386
+ ).optional(),
1387
+ devDependencies: z12.record(
1388
+ z12.string(),
1389
+ z12.union([
1390
+ z12.string(),
1391
+ ZodRemove
1392
+ ]).optional()
1393
+ ).optional(),
1394
+ peerDependencies: z12.record(
1395
+ z12.string(),
1396
+ z12.union([
1397
+ z12.string(),
1398
+ ZodRemove
1399
+ ]).optional()
1400
+ ).optional(),
1401
+ optionalDependencies: z12.record(
1402
+ z12.string(),
1403
+ z12.union([
1404
+ z12.string(),
1405
+ ZodRemove
1406
+ ]).optional()
1407
+ ).optional()
1408
+ }).partial();
1387
1409
  var requireDependency = createRuleFactory({
1388
1410
  name: "requireDependency",
1389
1411
  check: function expectPackageEntry(context, options) {
@@ -1395,27 +1417,33 @@ var requireDependency = createRuleFactory({
1395
1417
  "peerDependencies",
1396
1418
  "optionalDependencies"
1397
1419
  ].forEach((type) => {
1398
- var _a;
1420
+ var _a, _b;
1399
1421
  const expectedEntries = options[type];
1400
1422
  if (!expectedEntries) {
1401
1423
  return;
1402
1424
  }
1425
+ const dependenciesToAdd = Object.entries(expectedEntries).filter(
1426
+ ([, version]) => version !== REMOVE && version !== void 0
1427
+ );
1428
+ const dependenciesToRemove = Object.entries(expectedEntries).filter(
1429
+ ([, version]) => version === REMOVE
1430
+ );
1403
1431
  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
- });
1432
+ if (dependenciesToAdd.length > 0) {
1433
+ context.addError({
1434
+ file: packageJsonPath,
1435
+ message: `No ${type} block, cannot add required ${type}.`,
1436
+ fixer: () => {
1437
+ mutateJson5(packageJsonPath, context.host, (input) => {
1438
+ input[type] = Object.fromEntries(dependenciesToAdd);
1439
+ return input;
1440
+ });
1441
+ }
1442
+ });
1443
+ }
1416
1444
  return;
1417
1445
  }
1418
- for (const [dep, version] of Object.entries(options[type])) {
1446
+ for (const [dep, version] of dependenciesToAdd) {
1419
1447
  if (((_a = packageJson[type]) == null ? void 0 : _a[dep]) !== version) {
1420
1448
  context.addError({
1421
1449
  file: packageJsonPath,
@@ -1431,12 +1459,26 @@ var requireDependency = createRuleFactory({
1431
1459
  packageJsonPath,
1432
1460
  context.host,
1433
1461
  (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
- }
1462
+ input[type] = { ...input[type], [dep]: version };
1463
+ return input;
1464
+ }
1465
+ );
1466
+ }
1467
+ });
1468
+ }
1469
+ }
1470
+ for (const [dep] of dependenciesToRemove) {
1471
+ if (((_b = packageJson[type]) == null ? void 0 : _b[dep]) !== void 0) {
1472
+ context.addError({
1473
+ file: packageJsonPath,
1474
+ message: `Dependency ${dep} should be removed`,
1475
+ fixer: () => {
1476
+ mutateJson5(
1477
+ packageJsonPath,
1478
+ context.host,
1479
+ (input) => {
1480
+ input[type] = { ...input[type] };
1481
+ delete input[type][dep];
1440
1482
  return input;
1441
1483
  }
1442
1484
  );
@@ -1446,24 +1488,24 @@ var requireDependency = createRuleFactory({
1446
1488
  }
1447
1489
  });
1448
1490
  },
1449
- validateOptions: Options11.check
1491
+ validateOptions: Options11.parse
1450
1492
  });
1451
1493
 
1452
1494
  // src/standardTsconfig.ts
1453
1495
  import { matchesAnyGlob as matchesAnyGlob2 } from "@monorepolint/utils";
1454
1496
  import { diff as diff8 } from "jest-diff";
1455
1497
  import * as path6 from "path";
1456
- import * as r12 from "runtypes";
1498
+ import { z as z13 } from "zod";
1457
1499
  var DEFAULT_TSCONFIG_FILENAME = "tsconfig.json";
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)
1466
- }).withConstraint(({ generator, template, templateFile }) => {
1500
+ var Options12 = z13.object({
1501
+ file: z13.string().optional(),
1502
+ generator: z13.custom().optional(),
1503
+ tsconfigReferenceFile: z13.string().optional(),
1504
+ template: z13.record(z13.string(), z13.unknown()).optional(),
1505
+ templateFile: z13.string().optional(),
1506
+ excludedReferences: z13.array(z13.string()).optional(),
1507
+ additionalReferences: z13.array(z13.string()).optional()
1508
+ }).partial().refine(({ generator, template, templateFile }) => {
1467
1509
  let count = 0;
1468
1510
  if (generator) {
1469
1511
  count++;
@@ -1474,7 +1516,9 @@ var Options12 = r12.Partial({
1474
1516
  if (templateFile) {
1475
1517
  count++;
1476
1518
  }
1477
- return count === 1 || "Expect one of { generator, template, templateFile }";
1519
+ return count === 1;
1520
+ }, {
1521
+ message: "Expect one of { generator, template, templateFile }"
1478
1522
  });
1479
1523
  var standardTsconfig = createRuleFactory({
1480
1524
  name: "standardTsconfig",
@@ -1504,7 +1548,7 @@ var standardTsconfig = createRuleFactory({
1504
1548
  });
1505
1549
  }
1506
1550
  },
1507
- validateOptions: Options12.check
1551
+ validateOptions: Options12.parse
1508
1552
  });
1509
1553
  function getGenerator(context, opts) {
1510
1554
  if (opts.generator) {
@@ -1564,6 +1608,7 @@ function makeGenerator(template, excludedReferences, additionalReferences, tscon
1564
1608
  };
1565
1609
  }
1566
1610
  export {
1611
+ REMOVE,
1567
1612
  alphabeticalDependencies,
1568
1613
  alphabeticalScripts,
1569
1614
  bannedDependencies,