@shivaedev/quality 0.0.0 → 0.1.0

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 (159) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/LICENSE +21 -0
  3. package/README.md +127 -1
  4. package/dist/baseline/compare.d.ts +26 -0
  5. package/dist/baseline/compare.d.ts.map +1 -0
  6. package/dist/baseline/compare.js +42 -0
  7. package/dist/baseline/compare.js.map +1 -0
  8. package/dist/baseline/format.d.ts +13 -0
  9. package/dist/baseline/format.d.ts.map +1 -0
  10. package/dist/baseline/format.js +32 -0
  11. package/dist/baseline/format.js.map +1 -0
  12. package/dist/baseline/update.d.ts +24 -0
  13. package/dist/baseline/update.d.ts.map +1 -0
  14. package/dist/baseline/update.js +60 -0
  15. package/dist/baseline/update.js.map +1 -0
  16. package/dist/cli/args.d.ts +25 -0
  17. package/dist/cli/args.d.ts.map +1 -0
  18. package/dist/cli/args.js +64 -0
  19. package/dist/cli/args.js.map +1 -0
  20. package/dist/cli/baseline.d.ts +5 -0
  21. package/dist/cli/baseline.d.ts.map +1 -0
  22. package/dist/cli/baseline.js +37 -0
  23. package/dist/cli/baseline.js.map +1 -0
  24. package/dist/cli/lint.d.ts +5 -0
  25. package/dist/cli/lint.d.ts.map +1 -0
  26. package/dist/cli/lint.js +20 -0
  27. package/dist/cli/lint.js.map +1 -0
  28. package/dist/cli/run-main.d.ts +3 -0
  29. package/dist/cli/run-main.d.ts.map +1 -0
  30. package/dist/cli/run-main.js +24 -0
  31. package/dist/cli/run-main.js.map +1 -0
  32. package/dist/cli.d.ts +3 -0
  33. package/dist/cli.d.ts.map +1 -0
  34. package/dist/cli.js +27 -0
  35. package/dist/cli.js.map +1 -0
  36. package/dist/config/decode.d.ts +19 -0
  37. package/dist/config/decode.d.ts.map +1 -0
  38. package/dist/config/decode.js +25 -0
  39. package/dist/config/decode.js.map +1 -0
  40. package/dist/config/load.d.ts +13 -0
  41. package/dist/config/load.d.ts.map +1 -0
  42. package/dist/config/load.js +47 -0
  43. package/dist/config/load.js.map +1 -0
  44. package/dist/config/resolve.d.ts +11 -0
  45. package/dist/config/resolve.d.ts.map +1 -0
  46. package/dist/config/resolve.js +31 -0
  47. package/dist/config/resolve.js.map +1 -0
  48. package/dist/config.d.ts +31 -0
  49. package/dist/config.d.ts.map +1 -0
  50. package/dist/config.js +2 -0
  51. package/dist/config.js.map +1 -0
  52. package/dist/decoded.d.ts +13 -0
  53. package/dist/decoded.d.ts.map +1 -0
  54. package/dist/decoded.js +11 -0
  55. package/dist/decoded.js.map +1 -0
  56. package/dist/engine/evaluate.d.ts +18 -0
  57. package/dist/engine/evaluate.d.ts.map +1 -0
  58. package/dist/engine/evaluate.js +20 -0
  59. package/dist/engine/evaluate.js.map +1 -0
  60. package/dist/engine/run-rules.d.ts +12 -0
  61. package/dist/engine/run-rules.d.ts.map +1 -0
  62. package/dist/engine/run-rules.js +19 -0
  63. package/dist/engine/run-rules.js.map +1 -0
  64. package/dist/engine/session.d.ts +19 -0
  65. package/dist/engine/session.d.ts.map +1 -0
  66. package/dist/engine/session.js +25 -0
  67. package/dist/engine/session.js.map +1 -0
  68. package/dist/engine/violation.d.ts +12 -0
  69. package/dist/engine/violation.d.ts.map +1 -0
  70. package/dist/engine/violation.js +23 -0
  71. package/dist/engine/violation.js.map +1 -0
  72. package/dist/exceptions/registry.d.ts +24 -0
  73. package/dist/exceptions/registry.d.ts.map +1 -0
  74. package/dist/exceptions/registry.js +33 -0
  75. package/dist/exceptions/registry.js.map +1 -0
  76. package/dist/failure.d.ts +21 -0
  77. package/dist/failure.d.ts.map +1 -0
  78. package/dist/failure.js +12 -0
  79. package/dist/failure.js.map +1 -0
  80. package/dist/index.d.ts +6 -0
  81. package/dist/index.d.ts.map +1 -0
  82. package/dist/index.js +3 -0
  83. package/dist/index.js.map +1 -0
  84. package/dist/inventory/collect.d.ts +15 -0
  85. package/dist/inventory/collect.d.ts.map +1 -0
  86. package/dist/inventory/collect.js +34 -0
  87. package/dist/inventory/collect.js.map +1 -0
  88. package/dist/inventory/filesystem.d.ts +16 -0
  89. package/dist/inventory/filesystem.d.ts.map +1 -0
  90. package/dist/inventory/filesystem.js +26 -0
  91. package/dist/inventory/filesystem.js.map +1 -0
  92. package/dist/inventory/ignore-scope.d.ts +17 -0
  93. package/dist/inventory/ignore-scope.d.ts.map +1 -0
  94. package/dist/inventory/ignore-scope.js +26 -0
  95. package/dist/inventory/ignore-scope.js.map +1 -0
  96. package/dist/inventory/walk.d.ts +8 -0
  97. package/dist/inventory/walk.d.ts.map +1 -0
  98. package/dist/inventory/walk.js +38 -0
  99. package/dist/inventory/walk.js.map +1 -0
  100. package/dist/report/plural.d.ts +2 -0
  101. package/dist/report/plural.d.ts.map +1 -0
  102. package/dist/report/plural.js +2 -0
  103. package/dist/report/plural.js.map +1 -0
  104. package/dist/report/render.d.ts +11 -0
  105. package/dist/report/render.d.ts.map +1 -0
  106. package/dist/report/render.js +55 -0
  107. package/dist/report/render.js.map +1 -0
  108. package/dist/report/stale.d.ts +8 -0
  109. package/dist/report/stale.d.ts.map +1 -0
  110. package/dist/report/stale.js +9 -0
  111. package/dist/report/stale.js.map +1 -0
  112. package/dist/rule.d.ts +56 -0
  113. package/dist/rule.d.ts.map +1 -0
  114. package/dist/rule.js +23 -0
  115. package/dist/rule.js.map +1 -0
  116. package/dist/rules/built-in.d.ts +6 -0
  117. package/dist/rules/built-in.d.ts.map +1 -0
  118. package/dist/rules/built-in.js +3 -0
  119. package/dist/rules/built-in.js.map +1 -0
  120. package/dist/rules/max-lines.d.ts +6 -0
  121. package/dist/rules/max-lines.d.ts.map +1 -0
  122. package/dist/rules/max-lines.js +26 -0
  123. package/dist/rules/max-lines.js.map +1 -0
  124. package/dist/standard-schema.d.ts +25 -0
  125. package/dist/standard-schema.d.ts.map +1 -0
  126. package/dist/standard-schema.js +3 -0
  127. package/dist/standard-schema.js.map +1 -0
  128. package/package.json +53 -4
  129. package/src/baseline/compare.ts +81 -0
  130. package/src/baseline/format.ts +53 -0
  131. package/src/baseline/update.ts +83 -0
  132. package/src/cli/args.ts +81 -0
  133. package/src/cli/baseline.ts +52 -0
  134. package/src/cli/lint.ts +27 -0
  135. package/src/cli/run-main.ts +29 -0
  136. package/src/cli.ts +29 -0
  137. package/src/config/decode.ts +35 -0
  138. package/src/config/load.ts +58 -0
  139. package/src/config/resolve.ts +60 -0
  140. package/src/config.ts +33 -0
  141. package/src/decoded.ts +15 -0
  142. package/src/engine/evaluate.ts +39 -0
  143. package/src/engine/run-rules.ts +40 -0
  144. package/src/engine/session.ts +40 -0
  145. package/src/engine/violation.ts +35 -0
  146. package/src/exceptions/registry.ts +58 -0
  147. package/src/failure.ts +13 -0
  148. package/src/index.ts +5 -0
  149. package/src/inventory/collect.ts +53 -0
  150. package/src/inventory/filesystem.ts +47 -0
  151. package/src/inventory/ignore-scope.ts +44 -0
  152. package/src/inventory/walk.ts +58 -0
  153. package/src/report/plural.ts +1 -0
  154. package/src/report/render.ts +85 -0
  155. package/src/report/stale.ts +30 -0
  156. package/src/rule.ts +90 -0
  157. package/src/rules/built-in.ts +3 -0
  158. package/src/rules/max-lines.ts +31 -0
  159. package/src/standard-schema.ts +22 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-main.d.ts","sourceRoot":"","sources":["../../src/cli/run-main.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,MAAM,EAAQ,KAAK,UAAU,EAAW,MAAM,QAAQ,CAAC;AAwBhF,eAAO,MAAM,OAAO,GAAI,KAAK,EAAE,KAAK,EAAE,SAAS,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,UAAU,CAAC,UAAU,CAAC,KAAG,IAGnG,CAAC"}
@@ -0,0 +1,24 @@
1
+ import { NodeFileSystem, NodeRuntime } from "@effect/platform-node";
2
+ import { Cause, Console, Effect, Exit, Runtime } from "effect";
3
+ import { SetupFailure } from "../failure.js";
4
+ const INTERRUPTED = 130;
5
+ const COULD_NOT_RUN = 2;
6
+ const explain = (cause) => {
7
+ const error = Cause.squash(cause);
8
+ if (error instanceof SetupFailure) {
9
+ return Console.error(`quality: ${error.message}`);
10
+ }
11
+ return Runtime.getErrorReported(error) ? Console.error(`quality: internal error\n${Cause.pretty(cause)}`) : Effect.void;
12
+ };
13
+ const exitCodeOf = (error) => typeof error === "object" && error !== null && Runtime.errorExitCode in error ? Runtime.getErrorExitCode(error) : COULD_NOT_RUN;
14
+ const teardown = (exit, onExit) => {
15
+ if (Exit.isSuccess(exit)) {
16
+ return onExit(0);
17
+ }
18
+ return onExit(Cause.hasInterruptsOnly(exit.cause) ? INTERRUPTED : exitCodeOf(Cause.squash(exit.cause)));
19
+ };
20
+ export const runMain = (program) => {
21
+ const explained = Effect.tapCause(program, (cause) => (Cause.hasInterruptsOnly(cause) ? Effect.void : explain(cause)));
22
+ NodeRuntime.runMain(Effect.provide(explained, NodeFileSystem.layer), { disableErrorReporting: true, teardown });
23
+ };
24
+ //# sourceMappingURL=run-main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-main.js","sourceRoot":"","sources":["../../src/cli/run-main.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAmB,OAAO,EAAE,MAAM,QAAQ,CAAC;AAChF,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C,MAAM,WAAW,GAAG,GAAG,CAAC;AACxB,MAAM,aAAa,GAAG,CAAC,CAAC;AAExB,MAAM,OAAO,GAAG,CAAC,KAA2B,EAAuB,EAAE;IACpE,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAClC,IAAI,KAAK,YAAY,YAAY,EAAE,CAAC;QACnC,OAAO,OAAO,CAAC,KAAK,CAAC,YAAY,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,OAAO,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,4BAA4B,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC;AACzH,CAAC,CAAC;AAEF,MAAM,UAAU,GAAG,CAAC,KAAc,EAAU,EAAE,CAC7C,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,CAAC,aAAa,IAAI,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC;AAEjI,MAAM,QAAQ,GAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE;IACnD,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1B,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,OAAO,MAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACzG,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,OAAO,GAAG,CAAe,OAA2D,EAAQ,EAAE;IAC1G,MAAM,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACvH,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,cAAc,CAAC,KAAK,CAAC,EAAE,EAAE,qBAAqB,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;AACjH,CAAC,CAAC"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env node
2
+ import process from "node:process";
3
+ import { Console, Effect } from "effect";
4
+ import { parseCommand, USAGE } from "./cli/args.js";
5
+ import { pruneBaseline, writeBaseline } from "./cli/baseline.js";
6
+ import { lint } from "./cli/lint.js";
7
+ import { runMain } from "./cli/run-main.js";
8
+ import { SetupFailure } from "./failure.js";
9
+ const parsed = parseCommand(process.argv.slice(2));
10
+ const program = Effect.gen(function* () {
11
+ if (parsed._tag === "Usage") {
12
+ return yield* new SetupFailure({ message: `${parsed.problem}\n\n${USAGE}` });
13
+ }
14
+ const command = parsed.command;
15
+ switch (command._tag) {
16
+ case "Help":
17
+ return yield* Console.log(USAGE);
18
+ case "Lint":
19
+ return yield* lint(process.cwd(), command.config, command.warnings);
20
+ case "BaselineWrite":
21
+ return yield* writeBaseline(process.cwd(), command.config, command.rules);
22
+ case "BaselinePrune":
23
+ return yield* pruneBaseline(process.cwd(), command.config);
24
+ }
25
+ });
26
+ runMain(program);
27
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,OAAO,MAAM,cAAc,CAAC;AACnC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACjE,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAEnD,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IACnC,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC7B,OAAO,KAAK,CAAC,CAAC,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC,OAAO,OAAO,KAAK,EAAE,EAAE,CAAC,CAAC;IAC9E,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;IAC/B,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;QACtB,KAAK,MAAM;YACV,OAAO,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAClC,KAAK,MAAM;YACV,OAAO,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;QACrE,KAAK,eAAe;YACnB,OAAO,KAAK,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;QAC3E,KAAK,eAAe;YACnB,OAAO,KAAK,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7D,CAAC;AACF,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,OAAO,CAAC,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { Schema } from "effect";
2
+ import { type Decoded } from "../decoded.ts";
3
+ import type { Rule } from "../rule.ts";
4
+ declare const ConfigInput: Schema.Struct<{
5
+ readonly sources: Schema.optionalKey<Schema.$Array<Schema.String>>;
6
+ readonly exclude: Schema.optionalKey<Schema.$Array<Schema.String>>;
7
+ readonly extensions: Schema.optionalKey<Schema.$Array<Schema.String>>;
8
+ readonly registry: Schema.optionalKey<Schema.String>;
9
+ readonly baseline: Schema.optionalKey<Schema.String>;
10
+ readonly local: Schema.optionalKey<Schema.$Array<Schema.declare<Rule<string, unknown>, Rule<string, unknown>>>>;
11
+ readonly rules: Schema.optionalKey<Schema.$Record<Schema.String, Schema.Union<readonly [Schema.Literals<readonly ["error", "warn", "off"]>, Schema.Struct<{
12
+ readonly level: Schema.optionalKey<Schema.Literals<readonly ["error", "warn", "off"]>>;
13
+ readonly options: Schema.optionalKey<Schema.Unknown>;
14
+ }>]>>>;
15
+ }>;
16
+ export type ConfigInput = typeof ConfigInput.Type;
17
+ export declare const decodeConfig: (value: unknown) => Promise<Decoded<ConfigInput>>;
18
+ export {};
19
+ //# sourceMappingURL=decode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decode.d.ts","sourceRoot":"","sources":["../../src/config/decode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,KAAK,OAAO,EAAc,MAAM,eAAe,CAAC;AACzD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAkBvC,QAAA,MAAM,WAAW;;;;;;;;;;;EAQf,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,OAAO,WAAW,CAAC,IAAI,CAAC;AAIlD,eAAO,MAAM,YAAY,GAAI,OAAO,OAAO,KAAG,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAgC,CAAC"}
@@ -0,0 +1,25 @@
1
+ import { Schema } from "effect";
2
+ import { decodeWith } from "../decoded.js";
3
+ const isRule = (value) => typeof value === "object" &&
4
+ value !== null &&
5
+ "id" in value &&
6
+ typeof value.id === "string" &&
7
+ "description" in value &&
8
+ typeof value.description === "string" &&
9
+ "configure" in value &&
10
+ typeof value.configure === "function";
11
+ const Level = Schema.Literals(["error", "warn", "off"]);
12
+ const Setting = Schema.Union([Level, Schema.Struct({ level: Schema.optionalKey(Level), options: Schema.optionalKey(Schema.Unknown) })]);
13
+ const LocalRule = Schema.declare(isRule, { expected: "a rule made with defineRule" });
14
+ const ConfigInput = Schema.Struct({
15
+ sources: Schema.optionalKey(Schema.Array(Schema.String)),
16
+ exclude: Schema.optionalKey(Schema.Array(Schema.String)),
17
+ extensions: Schema.optionalKey(Schema.Array(Schema.String)),
18
+ registry: Schema.optionalKey(Schema.String),
19
+ baseline: Schema.optionalKey(Schema.String),
20
+ local: Schema.optionalKey(Schema.Array(LocalRule)),
21
+ rules: Schema.optionalKey(Schema.Record(Schema.String, Setting)),
22
+ });
23
+ const standard = Schema.toStandardSchemaV1(ConfigInput, { parseOptions: { errors: "all", onExcessProperty: "error" } });
24
+ export const decodeConfig = (value) => decodeWith(standard, value);
25
+ //# sourceMappingURL=decode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decode.js","sourceRoot":"","sources":["../../src/config/decode.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAgB,UAAU,EAAE,MAAM,eAAe,CAAC;AAGzD,MAAM,MAAM,GAAG,CAAC,KAAc,EAAiB,EAAE,CAChD,OAAO,KAAK,KAAK,QAAQ;IACzB,KAAK,KAAK,IAAI;IACd,IAAI,IAAI,KAAK;IACb,OAAO,KAAK,CAAC,EAAE,KAAK,QAAQ;IAC5B,aAAa,IAAI,KAAK;IACtB,OAAO,KAAK,CAAC,WAAW,KAAK,QAAQ;IACrC,WAAW,IAAI,KAAK;IACpB,OAAO,KAAK,CAAC,SAAS,KAAK,UAAU,CAAC;AAEvC,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;AAExD,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAExI,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,6BAA6B,EAAE,CAAC,CAAC;AAEtF,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC;IACjC,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACxD,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACxD,UAAU,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC3D,QAAQ,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC;IAC3C,QAAQ,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC;IAC3C,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAClD,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChE,CAAC,CAAC;AAIH,MAAM,QAAQ,GAAG,MAAM,CAAC,kBAAkB,CAAC,WAAW,EAAE,EAAE,YAAY,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;AAExH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,KAAc,EAAiC,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { Effect, FileSystem } from "effect";
2
+ import { SetupFailure } from "../failure.ts";
3
+ import type { InventoryScope } from "../inventory/collect.ts";
4
+ import { type ResolvedRules } from "./resolve.ts";
5
+ export declare const CONFIG_FILE = "quality.config.ts";
6
+ export interface ResolvedConfig extends ResolvedRules, InventoryScope {
7
+ readonly root: string;
8
+ readonly file: string;
9
+ readonly registry: string;
10
+ readonly baseline: string;
11
+ }
12
+ export declare const loadConfig: (cwd: string, path: string | undefined) => Effect.Effect<ResolvedConfig, SetupFailure, FileSystem.FileSystem>;
13
+ //# sourceMappingURL=load.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../../src/config/load.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAE5C,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAE9D,OAAO,EAAE,KAAK,aAAa,EAAgB,MAAM,cAAc,CAAC;AAEhE,eAAO,MAAM,WAAW,sBAAsB,CAAC;AAI/C,MAAM,WAAW,cAAe,SAAQ,aAAa,EAAE,cAAc;IACpE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC1B;AA2BD,eAAO,MAAM,UAAU,GAAI,KAAK,MAAM,EAAE,MAAM,MAAM,GAAG,SAAS,KAAG,MAAM,CAAC,MAAM,CAAC,cAAc,EAAE,YAAY,EAAE,UAAU,CAAC,UAAU,CAYjI,CAAC"}
@@ -0,0 +1,47 @@
1
+ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
2
+ if (typeof path === "string" && /^\.\.?\//.test(path)) {
3
+ return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
4
+ return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
5
+ });
6
+ }
7
+ return path;
8
+ };
9
+ import { dirname, resolve } from "node:path";
10
+ import { pathToFileURL } from "node:url";
11
+ import { Effect, FileSystem } from "effect";
12
+ import { validOrFail } from "../decoded.js";
13
+ import { SetupFailure } from "../failure.js";
14
+ import { decodeConfig } from "./decode.js";
15
+ import { resolveRules } from "./resolve.js";
16
+ export const CONFIG_FILE = "quality.config.ts";
17
+ const DEFAULT_EXTENSIONS = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"];
18
+ const messageOf = (cause) => (cause instanceof Error ? cause.message : String(cause));
19
+ const importDefault = (file) => Effect.flatMap(Effect.tryPromise({
20
+ try: async () => import(__rewriteRelativeImportExtension(pathToFileURL(file).href)),
21
+ catch: (cause) => new SetupFailure({ message: `cannot load ${file}: ${messageOf(cause)}` }),
22
+ }), (loaded) => typeof loaded === "object" && loaded !== null && "default" in loaded
23
+ ? Effect.succeed(loaded.default)
24
+ : Effect.fail(new SetupFailure({ message: `${file} has no default export. Export defineConfig({ ... }) as the default.` })));
25
+ const resolved = (root, file, config, rules) => ({
26
+ ...rules,
27
+ baseline: config.baseline ?? "quality/baseline.json",
28
+ exclude: config.exclude ?? [],
29
+ extensions: config.extensions ?? DEFAULT_EXTENSIONS,
30
+ file,
31
+ registry: config.registry ?? "quality/registry.json",
32
+ root,
33
+ sources: config.sources ?? ["."],
34
+ });
35
+ export const loadConfig = (cwd, path) => Effect.gen(function* () {
36
+ const fs = yield* FileSystem.FileSystem;
37
+ const file = resolve(cwd, path ?? CONFIG_FILE);
38
+ const present = yield* Effect.orElseSucceed(fs.exists(file), () => false);
39
+ if (!present) {
40
+ return yield* new SetupFailure({ message: `no config at ${file}. Create ${CONFIG_FILE} exporting defineConfig({ ... }), or pass --config.` });
41
+ }
42
+ const loaded = yield* importDefault(file);
43
+ const config = yield* validOrFail(file, yield* Effect.promise(() => decodeConfig(loaded)));
44
+ const rules = yield* validOrFail(file, yield* resolveRules(config));
45
+ return resolved(dirname(file), file, config, rules);
46
+ });
47
+ //# sourceMappingURL=load.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load.js","sourceRoot":"","sources":["../../src/config/load.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { Effect } from "effect";
2
+ import type { Level } from "../config.ts";
3
+ import type { Decoded } from "../decoded.ts";
4
+ import type { ActiveRule } from "../engine/run-rules.ts";
5
+ import type { ConfigInput } from "./decode.ts";
6
+ export interface ResolvedRules {
7
+ readonly active: ReadonlyArray<ActiveRule>;
8
+ readonly levels: ReadonlyMap<string, Level>;
9
+ }
10
+ export declare const resolveRules: (config: ConfigInput) => Effect.Effect<Decoded<ResolvedRules>>;
11
+ //# sourceMappingURL=resolve.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/config/resolve.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;IAC3C,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;CAC5C;AAiCD,eAAO,MAAM,YAAY,GAAI,QAAQ,WAAW,KAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAepF,CAAC"}
@@ -0,0 +1,31 @@
1
+ import { Effect } from "effect";
2
+ import { builtInRules } from "../rules/built-in.js";
3
+ const messageOf = (cause) => (cause instanceof Error ? cause.message : String(cause));
4
+ const levelOf = (setting) => (typeof setting === "string" ? setting : (setting?.level ?? "error"));
5
+ const optionsOf = (setting) => (typeof setting === "object" ? setting.options : undefined);
6
+ const duplicateIssues = (rules) => rules.flatMap((rule, index) => rules.findIndex((other) => other.id === rule.id) === index ? [] : [`local: rule id "${rule.id}" is already defined`]);
7
+ const activate = (rule, setting) => {
8
+ const level = levelOf(setting);
9
+ if (level === "off") {
10
+ return Effect.succeed({ _tag: "Valid", value: undefined });
11
+ }
12
+ return Effect.tryPromise({ catch: messageOf, try: () => rule.configure(optionsOf(setting)) }).pipe(Effect.map((configured) => configured._tag === "Invalid"
13
+ ? { _tag: "Invalid", issues: configured.issues.map((issue) => `rules.${rule.id}.options: ${issue}`) }
14
+ : { _tag: "Valid", value: { check: configured.check, description: rule.description, id: rule.id, level } }), Effect.catch((failure) => Effect.succeed({ _tag: "Invalid", issues: [`rules.${rule.id}.options: validation threw: ${failure}`] })));
15
+ };
16
+ export const resolveRules = (config) => Effect.gen(function* () {
17
+ const rules = [...builtInRules, ...(config.local ?? [])];
18
+ const settings = config.rules ?? {};
19
+ const known = new Set(rules.map((rule) => rule.id));
20
+ const unknown = Object.keys(settings)
21
+ .filter((id) => !known.has(id))
22
+ .map((id) => `rules.${id}: no built-in or local rule has this id`);
23
+ const activated = yield* Effect.forEach(rules, (rule) => activate(rule, settings[rule.id]));
24
+ const issues = [...duplicateIssues(rules), ...unknown, ...activated.flatMap((result) => (result._tag === "Invalid" ? result.issues : []))];
25
+ if (issues.length > 0) {
26
+ return { _tag: "Invalid", issues };
27
+ }
28
+ const active = activated.flatMap((result) => (result._tag === "Valid" && result.value !== undefined ? [result.value] : []));
29
+ return { _tag: "Valid", value: { active, levels: new Map(rules.map((rule) => [rule.id, levelOf(settings[rule.id])])) } };
30
+ });
31
+ //# sourceMappingURL=resolve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/config/resolve.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import type { Rule } from "./rule.ts";
2
+ import type { builtInRules } from "./rules/built-in.ts";
3
+ /** Every rule defaults to `error`. `warn` is for the transition to a rule and is meant to be temporary. */
4
+ export type Level = "error" | "warn" | "off";
5
+ export type RuleSetting<Input> = Level | {
6
+ readonly level?: Level;
7
+ readonly options?: Input;
8
+ };
9
+ type InputOf<Candidate> = Candidate extends Rule<string, infer Input> ? Input : never;
10
+ export type RuleSettings<Rules extends ReadonlyArray<Rule>> = {
11
+ readonly [Candidate in Rules[number] as Candidate["id"]]?: RuleSetting<InputOf<Candidate>>;
12
+ };
13
+ export type BuiltInRules = typeof builtInRules;
14
+ export interface QualityConfig<Local extends ReadonlyArray<Rule> = ReadonlyArray<Rule>> {
15
+ /** Directories or files to check, relative to the config file. Defaults to the whole repository. */
16
+ readonly sources?: ReadonlyArray<string>;
17
+ /** Paths never checked, in .gitignore syntax. Ignored files are always skipped. */
18
+ readonly exclude?: ReadonlyArray<string>;
19
+ /** Extensions of the source files rules read. Defaults to TypeScript and JavaScript modules. */
20
+ readonly extensions?: ReadonlyArray<string>;
21
+ /** Permanent exceptions, each with a reason. Defaults to `quality/registry.json`. */
22
+ readonly registry?: string;
23
+ /** Existing violations that may only shrink. Defaults to `quality/baseline.json`. */
24
+ readonly baseline?: string;
25
+ /** Repository rules, reported, registered and baselined like the built-in ones. */
26
+ readonly local?: Local;
27
+ readonly rules?: RuleSettings<readonly [...BuiltInRules, ...Local]>;
28
+ }
29
+ export declare const defineConfig: <const Local extends ReadonlyArray<Rule> = readonly []>(config: QualityConfig<Local>) => QualityConfig<Local>;
30
+ export {};
31
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,2GAA2G;AAC3G,MAAM,MAAM,KAAK,GAAG,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC;AAE7C,MAAM,MAAM,WAAW,CAAC,KAAK,IAAI,KAAK,GAAG;IAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC;AAE9F,KAAK,OAAO,CAAC,SAAS,IAAI,SAAS,SAAS,IAAI,CAAC,MAAM,EAAE,MAAM,KAAK,CAAC,GAAG,KAAK,GAAG,KAAK,CAAC;AAEtF,MAAM,MAAM,YAAY,CAAC,KAAK,SAAS,aAAa,CAAC,IAAI,CAAC,IAAI;IAC7D,QAAQ,EAAE,SAAS,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;CAC1F,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,OAAO,YAAY,CAAC;AAE/C,MAAM,WAAW,aAAa,CAAC,KAAK,SAAS,aAAa,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,IAAI,CAAC;IACrF,oGAAoG;IACpG,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACzC,mFAAmF;IACnF,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACzC,gGAAgG;IAChG,QAAQ,CAAC,UAAU,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC5C,qFAAqF;IACrF,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,qFAAqF;IACrF,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,mFAAmF;IACnF,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;IACvB,QAAQ,CAAC,KAAK,CAAC,EAAE,YAAY,CAAC,SAAS,CAAC,GAAG,YAAY,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC;CACpE;AAED,eAAO,MAAM,YAAY,GAAI,KAAK,CAAC,KAAK,SAAS,aAAa,CAAC,IAAI,CAAC,GAAG,SAAS,EAAE,EAAE,QAAQ,aAAa,CAAC,KAAK,CAAC,KAAG,aAAa,CAAC,KAAK,CAAW,CAAC"}
package/dist/config.js ADDED
@@ -0,0 +1,2 @@
1
+ export const defineConfig = (config) => config;
2
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAgCA,MAAM,CAAC,MAAM,YAAY,GAAG,CAAwD,MAA4B,EAAwB,EAAE,CAAC,MAAM,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { Effect } from "effect";
2
+ import { SetupFailure } from "./failure.ts";
3
+ import { type StandardSchemaV1 } from "./standard-schema.ts";
4
+ export type Decoded<Value> = {
5
+ readonly _tag: "Valid";
6
+ readonly value: Value;
7
+ } | {
8
+ readonly _tag: "Invalid";
9
+ readonly issues: ReadonlyArray<string>;
10
+ };
11
+ export declare const decodeWith: <Output>(schema: StandardSchemaV1<unknown, Output>, value: unknown) => Promise<Decoded<Output>>;
12
+ export declare const validOrFail: <Value>(file: string, decoded: Decoded<Value>) => Effect.Effect<Value, SetupFailure>;
13
+ //# sourceMappingURL=decoded.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decoded.d.ts","sourceRoot":"","sources":["../src/decoded.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAiB,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAE5E,MAAM,MAAM,OAAO,CAAC,KAAK,IAAI;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;CAAE,CAAC;AAEtJ,eAAO,MAAM,UAAU,GAAU,MAAM,EAAE,QAAQ,gBAAgB,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,OAAO,OAAO,KAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAG3H,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,KAAK,EAAE,MAAM,MAAM,EAAE,SAAS,OAAO,CAAC,KAAK,CAAC,KAAG,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,YAAY,CAGsB,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { Effect } from "effect";
2
+ import { SetupFailure } from "./failure.js";
3
+ import { describeIssue } from "./standard-schema.js";
4
+ export const decodeWith = async (schema, value) => {
5
+ const result = await schema["~standard"].validate(value);
6
+ return result.issues === undefined ? { _tag: "Valid", value: result.value } : { _tag: "Invalid", issues: result.issues.map(describeIssue) };
7
+ };
8
+ export const validOrFail = (file, decoded) => decoded._tag === "Valid"
9
+ ? Effect.succeed(decoded.value)
10
+ : Effect.fail(new SetupFailure({ message: `${file} is invalid:\n${decoded.issues.map((issue) => ` - ${issue}`).join("\n")}` }));
11
+ //# sourceMappingURL=decoded.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decoded.js","sourceRoot":"","sources":["../src/decoded.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAyB,MAAM,sBAAsB,CAAC;AAI5E,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,EAAU,MAAyC,EAAE,KAAc,EAA4B,EAAE;IAC/H,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACzD,OAAO,MAAM,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE,CAAC;AAC7I,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG,CAAQ,IAAY,EAAE,OAAuB,EAAsC,EAAE,CAC/G,OAAO,CAAC,IAAI,KAAK,OAAO;IACvB,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC;IAC/B,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,GAAG,IAAI,iBAAiB,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { type Regression, type StaleBaselineEntry } from "../baseline/compare.ts";
2
+ import type { BaselineEntry } from "../baseline/format.ts";
3
+ import type { Level } from "../config.ts";
4
+ import { type RegistryEntry, type StaleRegistryEntry } from "../exceptions/registry.ts";
5
+ import { type Violation } from "./violation.ts";
6
+ export interface Outcome {
7
+ readonly errors: ReadonlyArray<Violation>;
8
+ readonly warnings: ReadonlyArray<Violation>;
9
+ readonly regressions: ReadonlyArray<Regression>;
10
+ readonly staleBaseline: ReadonlyArray<StaleBaselineEntry>;
11
+ readonly staleRegistry: ReadonlyArray<StaleRegistryEntry>;
12
+ readonly baselined: number;
13
+ readonly registered: number;
14
+ }
15
+ /** Registered exceptions apply first; the baseline then covers what is left, per rule and file. */
16
+ export declare const evaluate: (violations: ReadonlyArray<Violation>, registry: ReadonlyArray<RegistryEntry>, baseline: ReadonlyArray<BaselineEntry>, levels: ReadonlyMap<string, Level>) => Outcome;
17
+ export declare const passes: (outcome: Outcome) => boolean;
18
+ //# sourceMappingURL=evaluate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluate.d.ts","sourceRoot":"","sources":["../../src/engine/evaluate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,UAAU,EAAE,KAAK,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjG,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAiB,KAAK,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACvG,OAAO,EAAc,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE5D,MAAM,WAAW,OAAO;IACvB,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IAC1C,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IAC5C,QAAQ,CAAC,WAAW,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;IAChD,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC;IAC1D,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC;IAC1D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC5B;AAED,mGAAmG;AACnG,eAAO,MAAM,QAAQ,GACpB,YAAY,aAAa,CAAC,SAAS,CAAC,EACpC,UAAU,aAAa,CAAC,aAAa,CAAC,EACtC,UAAU,aAAa,CAAC,aAAa,CAAC,EACtC,QAAQ,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,KAChC,OAaF,CAAC;AAEF,eAAO,MAAM,MAAM,GAAI,SAAS,OAAO,KAAG,OAC8D,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { applyBaseline } from "../baseline/compare.js";
2
+ import { applyRegistry } from "../exceptions/registry.js";
3
+ import { byLocation } from "./violation.js";
4
+ /** Registered exceptions apply first; the baseline then covers what is left, per rule and file. */
5
+ export const evaluate = (violations, registry, baseline, levels) => {
6
+ const registered = applyRegistry(violations, registry, levels);
7
+ const baselined = applyBaseline(registered.kept, baseline, levels);
8
+ const kept = [...baselined.kept].sort(byLocation);
9
+ return {
10
+ baselined: baselined.baselined,
11
+ errors: kept.filter((violation) => violation.level === "error"),
12
+ regressions: baselined.regressions,
13
+ registered: registered.registered,
14
+ staleBaseline: baselined.stale,
15
+ staleRegistry: registered.stale,
16
+ warnings: kept.filter((violation) => violation.level === "warn"),
17
+ };
18
+ };
19
+ export const passes = (outcome) => outcome.errors.length === 0 && outcome.staleBaseline.length === 0 && outcome.staleRegistry.length === 0;
20
+ //# sourceMappingURL=evaluate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluate.js","sourceRoot":"","sources":["../../src/engine/evaluate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAA4C,MAAM,wBAAwB,CAAC;AAGjG,OAAO,EAAE,aAAa,EAA+C,MAAM,2BAA2B,CAAC;AACvG,OAAO,EAAE,UAAU,EAAkB,MAAM,gBAAgB,CAAC;AAY5D,mGAAmG;AACnG,MAAM,CAAC,MAAM,QAAQ,GAAG,CACvB,UAAoC,EACpC,QAAsC,EACtC,QAAsC,EACtC,MAAkC,EACxB,EAAE;IACZ,MAAM,UAAU,GAAG,aAAa,CAAC,UAAU,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC/D,MAAM,SAAS,GAAG,aAAa,CAAC,UAAU,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IACnE,MAAM,IAAI,GAAG,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAClD,OAAO;QACN,SAAS,EAAE,SAAS,CAAC,SAAS;QAC9B,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,KAAK,KAAK,OAAO,CAAC;QAC/D,WAAW,EAAE,SAAS,CAAC,WAAW;QAClC,UAAU,EAAE,UAAU,CAAC,UAAU;QACjC,aAAa,EAAE,SAAS,CAAC,KAAK;QAC9B,aAAa,EAAE,UAAU,CAAC,KAAK;QAC/B,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,KAAK,KAAK,MAAM,CAAC;KAChE,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,OAAgB,EAAW,EAAE,CACnD,OAAO,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { Effect } from "effect";
2
+ import { SetupFailure } from "../failure.ts";
3
+ import type { Findings, RuleInputs } from "../rule.ts";
4
+ import type { ActiveLevel, Violation } from "./violation.ts";
5
+ export interface ActiveRule {
6
+ readonly id: string;
7
+ readonly description: string;
8
+ readonly level: ActiveLevel;
9
+ readonly check: (inputs: RuleInputs) => Promise<Findings>;
10
+ }
11
+ export declare const runRules: (rules: ReadonlyArray<ActiveRule>, inputs: RuleInputs) => Effect.Effect<ReadonlyArray<Violation>, SetupFailure>;
12
+ //# sourceMappingURL=run-rules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-rules.d.ts","sourceRoot":"","sources":["../../src/engine/run-rules.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C,OAAO,KAAK,EAAW,QAAQ,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE7D,MAAM,WAAW,UAAU;IAC1B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;CAC1D;AAuBD,eAAO,MAAM,QAAQ,GAAI,OAAO,aAAa,CAAC,UAAU,CAAC,EAAE,QAAQ,UAAU,KAAG,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,EAAE,YAAY,CAIlI,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { isAbsolute, relative } from "node:path";
2
+ import { Effect } from "effect";
3
+ import { SetupFailure } from "../failure.js";
4
+ import { posix } from "../inventory/ignore-scope.js";
5
+ const messageOf = (cause) => (cause instanceof Error ? cause.message : String(cause));
6
+ // Registry and baseline entries match on the path, so every finding names its file the same way.
7
+ const repositoryPath = (root, file) => posix(isAbsolute(file) ? relative(root, file) : file).replace(/^(\.\/)+/, "");
8
+ const violationOf = (rule, root, finding) => ({
9
+ ...finding,
10
+ file: repositoryPath(root, finding.file),
11
+ level: rule.level,
12
+ rule: rule.id,
13
+ });
14
+ const runRule = (rule, inputs) => Effect.map(Effect.tryPromise({
15
+ try: () => rule.check(inputs),
16
+ catch: (cause) => new SetupFailure({ message: `rule ${rule.id} failed: ${messageOf(cause)}` }),
17
+ }), (findings) => findings.map((finding) => violationOf(rule, inputs.root, finding)));
18
+ export const runRules = (rules, inputs) => Effect.map(Effect.forEach(rules, (rule) => runRule(rule, inputs), { concurrency: "unbounded" }), (results) => results.flat());
19
+ //# sourceMappingURL=run-rules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-rules.js","sourceRoot":"","sources":["../../src/engine/run-rules.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,8BAA8B,CAAC;AAWrD,MAAM,SAAS,GAAG,CAAC,KAAc,EAAU,EAAE,CAAC,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AAEvG,iGAAiG;AACjG,MAAM,cAAc,GAAG,CAAC,IAAY,EAAE,IAAY,EAAU,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;AAE7I,MAAM,WAAW,GAAG,CAAC,IAAgB,EAAE,IAAY,EAAE,OAAgB,EAAa,EAAE,CAAC,CAAC;IACrF,GAAG,OAAO;IACV,IAAI,EAAE,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC;IACxC,KAAK,EAAE,IAAI,CAAC,KAAK;IACjB,IAAI,EAAE,IAAI,CAAC,EAAE;CACb,CAAC,CAAC;AAEH,MAAM,OAAO,GAAG,CAAC,IAAgB,EAAE,MAAkB,EAAyD,EAAE,CAC/G,MAAM,CAAC,GAAG,CACT,MAAM,CAAC,UAAU,CAAC;IACjB,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;IAC7B,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,YAAY,CAAC,EAAE,OAAO,EAAE,QAAQ,IAAI,CAAC,EAAE,YAAY,SAAS,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;CAC9F,CAAC,EACF,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAChF,CAAC;AAEH,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,KAAgC,EAAE,MAAkB,EAAyD,EAAE,CACvI,MAAM,CAAC,GAAG,CACT,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC,EACpF,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,CAC3B,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { Effect, type FileSystem } from "effect";
2
+ import { type BaselineEntry } from "../baseline/format.ts";
3
+ import { type ResolvedConfig } from "../config/load.ts";
4
+ import { type RegistryEntry } from "../exceptions/registry.ts";
5
+ import { SetupFailure } from "../failure.ts";
6
+ import { type Inventory } from "../inventory/collect.ts";
7
+ import type { Violation } from "./violation.ts";
8
+ export interface Session {
9
+ readonly config: ResolvedConfig;
10
+ readonly inventory: Inventory;
11
+ readonly violations: ReadonlyArray<Violation>;
12
+ readonly registry: ReadonlyArray<RegistryEntry>;
13
+ readonly baseline: {
14
+ readonly raw: string | undefined;
15
+ readonly entries: ReadonlyArray<BaselineEntry>;
16
+ };
17
+ }
18
+ export declare const openSession: (cwd: string, configPath: string | undefined) => Effect.Effect<Session, SetupFailure, FileSystem.FileSystem>;
19
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/engine/session.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,KAAK,UAAU,EAAE,MAAM,QAAQ,CAAC;AACjD,OAAO,EAAE,KAAK,aAAa,EAAkB,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEpE,OAAO,EAAkB,KAAK,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/E,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAoB,KAAK,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAG3E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,MAAM,WAAW,OAAO;IACvB,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IAC9C,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC,aAAa,CAAC,CAAC;IAChD,QAAQ,CAAC,QAAQ,EAAE;QAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,aAAa,CAAC,CAAA;KAAE,CAAC;CACxG;AASD,eAAO,MAAM,WAAW,GAAI,KAAK,MAAM,EAAE,YAAY,MAAM,GAAG,SAAS,KAAG,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,YAAY,EAAE,UAAU,CAAC,UAAU,CAYjI,CAAC"}
@@ -0,0 +1,25 @@
1
+ import { join, resolve } from "node:path";
2
+ import { Effect } from "effect";
3
+ import { decodeBaseline } from "../baseline/format.js";
4
+ import { loadConfig } from "../config/load.js";
5
+ import { validOrFail } from "../decoded.js";
6
+ import { decodeRegistry } from "../exceptions/registry.js";
7
+ import { SetupFailure } from "../failure.js";
8
+ import { collectInventory } from "../inventory/collect.js";
9
+ import { readOptionalText } from "../inventory/filesystem.js";
10
+ import { runRules } from "./run-rules.js";
11
+ const setup = (effect) => Effect.mapError(effect, (failure) => new SetupFailure({ message: failure.message }));
12
+ const readInput = (root, path) => setup(readOptionalText(join(root, path)));
13
+ export const openSession = (cwd, configPath) => Effect.gen(function* () {
14
+ const config = yield* loadConfig(cwd, configPath);
15
+ const inventory = yield* setup(collectInventory(config.root, config));
16
+ const registryRaw = yield* readInput(config.root, config.registry);
17
+ const registry = yield* validOrFail(config.registry, yield* Effect.promise(() => decodeRegistry(registryRaw)));
18
+ const baselineRaw = yield* readInput(config.root, config.baseline);
19
+ const baseline = yield* validOrFail(config.baseline, yield* Effect.promise(() => decodeBaseline(baselineRaw)));
20
+ const services = yield* Effect.context();
21
+ const readText = (path) => Effect.runPromiseWith(services)(readOptionalText(resolve(config.root, path)));
22
+ const violations = yield* runRules(config.active, { files: inventory.files, readText, root: config.root, sources: inventory.sources });
23
+ return { baseline: { entries: baseline, raw: baselineRaw }, config, inventory, registry, violations };
24
+ });
25
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/engine/session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { Level } from "../config.ts";
2
+ import type { Finding } from "../rule.ts";
3
+ export type ActiveLevel = "error" | "warn";
4
+ export interface Violation extends Finding {
5
+ readonly rule: string;
6
+ readonly level: ActiveLevel;
7
+ }
8
+ export declare const keyOf: (rule: string, file: string) => string;
9
+ export declare const byLocation: (left: Violation, right: Violation) => number;
10
+ export declare const groupBy: <Item>(items: ReadonlyArray<Item>, key: (item: Item) => string) => ReadonlyMap<string, ReadonlyArray<Item>>;
11
+ export declare const unusedEntryProblem: (levels: ReadonlyMap<string, Level>, rule: string, unused: string) => string;
12
+ //# sourceMappingURL=violation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"violation.d.ts","sourceRoot":"","sources":["../../src/engine/violation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,MAAM,CAAC;AAE3C,MAAM,WAAW,SAAU,SAAQ,OAAO;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;CAC5B;AAED,eAAO,MAAM,KAAK,GAAI,MAAM,MAAM,EAAE,MAAM,MAAM,KAAG,MAAgC,CAAC;AAEpF,eAAO,MAAM,UAAU,GAAI,MAAM,SAAS,EAAE,OAAO,SAAS,KAAG,MACoD,CAAC;AAEpH,eAAO,MAAM,OAAO,GAAI,IAAI,EAAE,OAAO,aAAa,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,KAAG,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,IAAI,CAAC,CAW9H,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,QAAQ,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,MAAM,EAAE,QAAQ,MAAM,KAAG,MAMrG,CAAC"}
@@ -0,0 +1,23 @@
1
+ export const keyOf = (rule, file) => `${rule}\u0000${file}`;
2
+ export const byLocation = (left, right) => left.rule.localeCompare(right.rule) || left.file.localeCompare(right.file) || (left.line ?? 0) - (right.line ?? 0);
3
+ export const groupBy = (items, key) => {
4
+ const groups = new Map();
5
+ for (const item of items) {
6
+ const group = groups.get(key(item));
7
+ if (group === undefined) {
8
+ groups.set(key(item), [item]);
9
+ }
10
+ else {
11
+ group.push(item);
12
+ }
13
+ }
14
+ return groups;
15
+ };
16
+ export const unusedEntryProblem = (levels, rule, unused) => {
17
+ const level = levels.get(rule);
18
+ if (level === undefined) {
19
+ return "names no known rule";
20
+ }
21
+ return level === "off" ? "names a rule that is off" : unused;
22
+ };
23
+ //# sourceMappingURL=violation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"violation.js","sourceRoot":"","sources":["../../src/engine/violation.ts"],"names":[],"mappings":"AAUA,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,IAAY,EAAE,IAAY,EAAU,EAAE,CAAC,GAAG,IAAI,SAAS,IAAI,EAAE,CAAC;AAEpF,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,IAAe,EAAE,KAAgB,EAAU,EAAE,CACvE,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC;AAEpH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAO,KAA0B,EAAE,GAA2B,EAA4C,EAAE;IAClI,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC1B,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;QACpC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACzB,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;QAC/B,CAAC;aAAM,CAAC;YACP,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClB,CAAC;IACF,CAAC;IACD,OAAO,MAAM,CAAC;AACf,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,MAAkC,EAAE,IAAY,EAAE,MAAc,EAAU,EAAE;IAC9G,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,qBAAqB,CAAC;IAC9B,CAAC;IACD,OAAO,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,MAAM,CAAC;AAC9D,CAAC,CAAC"}
@@ -0,0 +1,24 @@
1
+ import { Schema } from "effect";
2
+ import type { Level } from "../config.ts";
3
+ import { type Decoded } from "../decoded.ts";
4
+ import { type Violation } from "../engine/violation.ts";
5
+ declare const RegistryEntry: Schema.Struct<{
6
+ readonly rule: Schema.NonEmptyString;
7
+ readonly file: Schema.NonEmptyString;
8
+ readonly subject: Schema.optionalKey<Schema.NonEmptyString>;
9
+ readonly reason: Schema.String;
10
+ }>;
11
+ export type RegistryEntry = typeof RegistryEntry.Type;
12
+ export declare const decodeRegistry: (raw: string | undefined) => Promise<Decoded<ReadonlyArray<RegistryEntry>>>;
13
+ export interface StaleRegistryEntry {
14
+ readonly entry: RegistryEntry;
15
+ readonly problem: string;
16
+ }
17
+ export interface RegistryCheck {
18
+ readonly kept: ReadonlyArray<Violation>;
19
+ readonly registered: number;
20
+ readonly stale: ReadonlyArray<StaleRegistryEntry>;
21
+ }
22
+ export declare const applyRegistry: (violations: ReadonlyArray<Violation>, entries: ReadonlyArray<RegistryEntry>, levels: ReadonlyMap<string, Level>) => RegistryCheck;
23
+ export {};
24
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/exceptions/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,KAAK,OAAO,EAAc,MAAM,eAAe,CAAC;AACzD,OAAO,EAAsB,KAAK,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAE5E,QAAA,MAAM,aAAa;;;;;EAKjB,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,OAAO,aAAa,CAAC,IAAI,CAAC;AAMtD,eAAO,MAAM,cAAc,GAAI,KAAK,MAAM,GAAG,SAAS,KAAG,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,CACR,CAAC;AAE/F,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IACxC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC;CAClD;AAUD,eAAO,MAAM,aAAa,GACzB,YAAY,aAAa,CAAC,SAAS,CAAC,EACpC,SAAS,aAAa,CAAC,aAAa,CAAC,EACrC,QAAQ,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,KAChC,aAaF,CAAC"}