@ttsc/lint 0.24.0 → 0.26.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.
@@ -1,33 +1,37 @@
1
- export declare const CONFIG_EVALUATOR_MAX_BUFFER: number;
2
- export declare const CONFIG_EVALUATOR_TIMEOUT_MS = 60000;
3
- export declare const CONFIG_EVALUATOR_TEARDOWN_GRACE_MS = 5000;
4
- export declare const CONFIG_EVALUATOR_STATUS_FD = 3;
5
- export declare const CONFIG_EVALUATOR_PROCESS_OPTIONS: Readonly<{
6
- killSignal: "SIGKILL";
7
- maxBuffer: number;
8
- timeout: number;
9
- }>;
10
1
  interface ConfigEvaluatorProcessResult {
11
2
  error?: Error;
12
- output?: readonly (string | null)[] | null;
13
3
  signal: NodeJS.Signals | null;
14
4
  status: number | null;
15
- stderr: string | null | undefined;
16
5
  }
17
6
  /**
18
7
  * Classify the ways the isolated lint-config evaluator can stop.
19
8
  *
20
- * Node reports both timeout and max-buffer termination with the configured
21
- * signal, so the process error code must take precedence over the signal. The
22
- * evaluator uses `SIGKILL`: Node's synchronous process API otherwise keeps
23
- * waiting when a POSIX child handles the default `SIGTERM` without exiting. A
24
- * bare signal is an external termination and a non-zero status is an evaluator
25
- * failure whose stderr tail contains the useful user-config diagnostic.
9
+ * The evaluator writes the child's own output straight to this process's
10
+ * stderr, so a diagnostic has already reached the user by the time anything
11
+ * here runs. What is left to say is only how the process ended: it never
12
+ * launched, something outside killed it, or it exited non-zero after printing
13
+ * its own reason.
14
+ *
15
+ * Nothing is bounded here — not time, not output. Both were the compiler
16
+ * deciding, on numbers nobody chose for this machine, that a user's own config
17
+ * had run too long or said too much. A slow config is a slow build the user can
18
+ * watch and interrupt; a loud one is output they asked for. Neither is this
19
+ * process's memory to spend either, because the child's streams are no longer
20
+ * collected into it.
26
21
  */
27
22
  export declare function configEvaluatorProcessFailure(result: ConfigEvaluatorProcessResult, configPath: string): Error | undefined;
28
23
  /**
29
- * Pass the semantic deadline and private status pipe through the `ttsx` wrapper
30
- * to the runtime child that actually executes the config.
24
+ * Read the failure envelope the evaluator writes to its result file when it
25
+ * stops on an error it can name.
26
+ *
27
+ * This is the other half of classifying how the evaluation ended, which is why
28
+ * it lives beside {@link configEvaluatorProcessFailure} rather than at the call
29
+ * site: the status says that it failed, and this says why.
30
+ *
31
+ * Only a well-formed envelope is honoured. A real evaluation payload never
32
+ * carries this key, and every other shape — an absent file, a build that failed
33
+ * before the loader ran, a half-written result, a payload written before a
34
+ * later non-zero exit — leaves the process status to speak for itself.
31
35
  */
32
- export declare function configEvaluatorBoundaryEnvironment(now?: number): NodeJS.ProcessEnv;
36
+ export declare function configEvaluatorFailureReason(outputPath: string): string;
33
37
  export {};
@@ -1,40 +1,28 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CONFIG_EVALUATOR_PROCESS_OPTIONS = exports.CONFIG_EVALUATOR_STATUS_FD = exports.CONFIG_EVALUATOR_TEARDOWN_GRACE_MS = exports.CONFIG_EVALUATOR_TIMEOUT_MS = exports.CONFIG_EVALUATOR_MAX_BUFFER = void 0;
4
6
  exports.configEvaluatorProcessFailure = configEvaluatorProcessFailure;
5
- exports.configEvaluatorBoundaryEnvironment = configEvaluatorBoundaryEnvironment;
6
- exports.CONFIG_EVALUATOR_MAX_BUFFER = 16 * 1024 * 1024;
7
- exports.CONFIG_EVALUATOR_TIMEOUT_MS = 60_000;
8
- exports.CONFIG_EVALUATOR_TEARDOWN_GRACE_MS = 5_000;
9
- exports.CONFIG_EVALUATOR_STATUS_FD = 3;
10
- exports.CONFIG_EVALUATOR_PROCESS_OPTIONS = Object.freeze({
11
- killSignal: "SIGKILL",
12
- maxBuffer: exports.CONFIG_EVALUATOR_MAX_BUFFER,
13
- timeout: exports.CONFIG_EVALUATOR_TIMEOUT_MS + exports.CONFIG_EVALUATOR_TEARDOWN_GRACE_MS,
14
- });
7
+ exports.configEvaluatorFailureReason = configEvaluatorFailureReason;
8
+ const node_fs_1 = __importDefault(require("node:fs"));
15
9
  /**
16
10
  * Classify the ways the isolated lint-config evaluator can stop.
17
11
  *
18
- * Node reports both timeout and max-buffer termination with the configured
19
- * signal, so the process error code must take precedence over the signal. The
20
- * evaluator uses `SIGKILL`: Node's synchronous process API otherwise keeps
21
- * waiting when a POSIX child handles the default `SIGTERM` without exiting. A
22
- * bare signal is an external termination and a non-zero status is an evaluator
23
- * failure whose stderr tail contains the useful user-config diagnostic.
12
+ * The evaluator writes the child's own output straight to this process's
13
+ * stderr, so a diagnostic has already reached the user by the time anything
14
+ * here runs. What is left to say is only how the process ended: it never
15
+ * launched, something outside killed it, or it exited non-zero after printing
16
+ * its own reason.
17
+ *
18
+ * Nothing is bounded here — not time, not output. Both were the compiler
19
+ * deciding, on numbers nobody chose for this machine, that a user's own config
20
+ * had run too long or said too much. A slow config is a slow build the user can
21
+ * watch and interrupt; a loud one is output they asked for. Neither is this
22
+ * process's memory to spend either, because the child's streams are no longer
23
+ * collected into it.
24
24
  */
25
25
  function configEvaluatorProcessFailure(result, configPath) {
26
- const code = result.error?.code;
27
- const nestedCode = result.output?.[exports.CONFIG_EVALUATOR_STATUS_FD]?.trim() ?? "";
28
- if (code === "ETIMEDOUT" || nestedCode === "ETIMEDOUT") {
29
- return new Error(`@ttsc/lint: ttsx evaluation of ${configPath} timed out after ` +
30
- `${exports.CONFIG_EVALUATOR_TIMEOUT_MS / 1_000} seconds. ` +
31
- "Simplify the config or move heavy work out of top-level.");
32
- }
33
- if (code === "ENOBUFS" || nestedCode === "ENOBUFS") {
34
- return new Error(`@ttsc/lint: ttsx evaluation of ${configPath} exceeded the ` +
35
- `${exports.CONFIG_EVALUATOR_MAX_BUFFER / (1024 * 1024)} MiB output limit. ` +
36
- "Reduce console output from the config and its dependencies.");
37
- }
38
26
  if (result.error) {
39
27
  return new Error(`@ttsc/lint: failed to spawn ttsx for ${configPath}: ${result.error.message}`);
40
28
  }
@@ -42,35 +30,34 @@ function configEvaluatorProcessFailure(result, configPath) {
42
30
  return new Error(`@ttsc/lint: ttsx evaluation of ${configPath} was killed by signal ${result.signal}.`);
43
31
  }
44
32
  if (result.status !== 0) {
45
- const reason = configEvaluatorFailureReason(result.stderr);
46
- return new Error(`@ttsc/lint: lint config ${configPath} evaluation failed with exit code ${String(result.status)}` +
47
- (reason === "" ? "" : "\n" + reason));
33
+ return new Error(`@ttsc/lint: lint config ${configPath} evaluation failed with exit code ${String(result.status)}`);
48
34
  }
49
35
  return undefined;
50
36
  }
51
37
  /**
52
- * Pass the semantic deadline and private status pipe through the `ttsx` wrapper
53
- * to the runtime child that actually executes the config.
54
- */
55
- function configEvaluatorBoundaryEnvironment(now = Date.now()) {
56
- return {
57
- TTSC_TTSX_EVALUATOR_DEADLINE_MS: String(now + exports.CONFIG_EVALUATOR_TIMEOUT_MS),
58
- TTSC_TTSX_EVALUATOR_MAX_BUFFER_BYTES: String(exports.CONFIG_EVALUATOR_MAX_BUFFER),
59
- TTSC_TTSX_EVALUATOR_STATUS_FD: String(exports.CONFIG_EVALUATOR_STATUS_FD),
60
- };
61
- }
62
- /**
63
- * Return the useful tail of evaluator stderr without turning an exception into
64
- * an unbounded duplicate of the already-forwarded child stream.
38
+ * Read the failure envelope the evaluator writes to its result file when it
39
+ * stops on an error it can name.
40
+ *
41
+ * This is the other half of classifying how the evaluation ended, which is why
42
+ * it lives beside {@link configEvaluatorProcessFailure} rather than at the call
43
+ * site: the status says that it failed, and this says why.
44
+ *
45
+ * Only a well-formed envelope is honoured. A real evaluation payload never
46
+ * carries this key, and every other shape — an absent file, a build that failed
47
+ * before the loader ran, a half-written result, a payload written before a
48
+ * later non-zero exit — leaves the process status to speak for itself.
65
49
  */
66
- function configEvaluatorFailureReason(stderr) {
67
- const bounded = (stderr ?? "").slice(-CONFIG_EVALUATOR_REASON_MAX_CHARS);
68
- const lines = bounded
69
- .split(/\r?\n/)
70
- .map((line) => line.trimEnd())
71
- .filter((line) => line.trim() !== "");
72
- return lines.slice(-CONFIG_EVALUATOR_REASON_LINES).join("\n");
50
+ function configEvaluatorFailureReason(outputPath) {
51
+ try {
52
+ const parsed = JSON.parse(node_fs_1.default.readFileSync(outputPath, "utf8"));
53
+ if (typeof parsed !== "object" || parsed === null)
54
+ return "";
55
+ const message = parsed
56
+ .__ttscLoaderError;
57
+ return typeof message === "string" ? message.trim() : "";
58
+ }
59
+ catch {
60
+ return "";
61
+ }
73
62
  }
74
- const CONFIG_EVALUATOR_REASON_LINES = 5;
75
- const CONFIG_EVALUATOR_REASON_MAX_CHARS = 8 * 1024;
76
63
  //# sourceMappingURL=configEvaluatorFailure.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"configEvaluatorFailure.js","sourceRoot":"","sources":["../../src/internal/configEvaluatorFailure.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"configEvaluatorFailure.js","sourceRoot":"","sources":["../../src/internal/configEvaluatorFailure.ts"],"names":[],"mappings":";;;;;;;AAAA,sDAAyB;AAQzB;;;;;;;;;;;;;;;GAeG;AACH,uCACE,MAAoC,EACpC,UAAkB;IAElB,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,OAAO,IAAI,KAAK,CACd,wCAAwC,UAAU,KAAK,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAC9E,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClB,OAAO,IAAI,KAAK,CACd,kCAAkC,UAAU,yBAAyB,MAAM,CAAC,MAAM,GAAG,CACtF,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,IAAI,KAAK,CACd,2BAA2B,UAAU,qCAAqC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAClG,CAAC;IACJ,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,sCAA6C,UAAkB;IAC7D,IAAI,CAAC;QACH,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,iBAAE,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;QACxE,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI;YAAE,OAAO,EAAE,CAAC;QAC7D,MAAM,OAAO,GAAI,MAA0C;aACxD,iBAAiB,CAAC;QACrB,OAAO,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}
@@ -67,52 +67,105 @@ export interface ITtscLintFunctionalNoThrowStatementsRuleOptions {
67
67
  }
68
68
  /** `functional/no-mixed-types` rule options. */
69
69
  export interface ITtscLintFunctionalNoMixedTypesRuleOptions {
70
- /** Check interface member kinds. */
70
+ /**
71
+ * Check interface member kinds.
72
+ *
73
+ * @default true
74
+ */
71
75
  checkInterfaces?: boolean;
72
- /** Check type-literal member kinds. */
76
+ /**
77
+ * Check type-literal member kinds.
78
+ *
79
+ * @default true
80
+ */
73
81
  checkTypeLiterals?: boolean;
74
82
  }
75
83
  /** `functional/no-return-void` rule options. */
76
84
  export interface ITtscLintFunctionalNoReturnVoidRuleOptions {
77
- /** Permit a function that returns `null` to satisfy the rule. */
85
+ /**
86
+ * Permit a function whose declared return type is `null`. Set `false` to
87
+ * reject it the way a declared `void` is rejected.
88
+ *
89
+ * @default true
90
+ */
78
91
  allowNull?: boolean;
79
- /** Permit a function that returns `undefined` to satisfy the rule. */
92
+ /**
93
+ * Permit a function whose declared return type is `undefined`. Set `false` to
94
+ * reject it the way a declared `void` is rejected.
95
+ *
96
+ * @default true
97
+ */
80
98
  allowUndefined?: boolean;
81
99
  /**
82
- * Skip functions whose return type is inferred to be `void` rather than
83
- * declared explicitly.
100
+ * Skip a bare `return;` inside a function that declares no return type. That
101
+ * statement is the one place the rule rejects a void-ness it inferred rather
102
+ * than read from an annotation.
103
+ *
104
+ * @default false
84
105
  */
85
106
  ignoreInferredTypes?: boolean;
86
107
  }
87
108
  /** `functional/prefer-immutable-types` rule options. */
88
109
  export interface ITtscLintFunctionalPreferImmutableTypesRuleOptions extends ITtscLintFunctionalPatternOptions {
89
110
  /**
90
- * Minimum accepted immutability. The native subset treats any configured
111
+ * Minimum accepted immutability. Reserved for upstream-compatible configs;
112
+ * the native subset computes no immutability level and treats any configured
91
113
  * value as readonly-required.
92
114
  */
93
115
  enforcement?: "ReadonlyShallow" | "ReadonlyDeep" | "Immutable" | "None" | false;
94
116
  }
95
117
  /** `functional/prefer-readonly-type` rule options. */
96
118
  export interface ITtscLintFunctionalPreferReadonlyTypeRuleOptions extends ITtscLintFunctionalPatternOptions {
97
- /** Permit mutation of locals while still policing exported types. */
119
+ /**
120
+ * Permit mutation of locals while still policing exported types. Reserved for
121
+ * upstream-compatible configs; the native subset reads type annotations and
122
+ * models no local-versus-exported distinction.
123
+ */
98
124
  allowLocalMutation?: boolean;
99
- /** Permit a mutable return type even when parameters must be readonly. */
125
+ /**
126
+ * Permit a mutable return type even when parameters must be readonly. Covers
127
+ * every signature that can declare one, including call and construct
128
+ * signatures, constructor types, and a get accessor.
129
+ *
130
+ * @default false
131
+ */
100
132
  allowMutableReturnType?: boolean;
101
- /** Also check property positions that have no explicit type annotation. */
133
+ /**
134
+ * Also check property positions that have no explicit type annotation.
135
+ * Reserved for upstream-compatible configs; judging an unannotated position
136
+ * needs the type checker, which this rule does not use.
137
+ */
102
138
  checkImplicit?: boolean;
103
- /** Skip array / tuple / `Map` / `Set` types. */
139
+ /**
140
+ * Skip array / tuple / `Map` / `Set` types.
141
+ *
142
+ * @default false
143
+ */
104
144
  ignoreCollections?: boolean;
105
145
  /**
106
- * Skip class fields. `"fieldsOnly"` keeps the rule active for non-field class
107
- * members.
146
+ * Skip class members. `true` skips anything under a class, its heritage
147
+ * clause and type parameters included; `"fieldsOnly"` narrows that to field
148
+ * declarations and keeps methods, accessors, and constructor parameters
149
+ * checked.
150
+ *
151
+ * @default false
108
152
  */
109
153
  ignoreClass?: boolean | "fieldsOnly";
110
- /** Skip interface members entirely. */
154
+ /**
155
+ * Skip interface members entirely.
156
+ *
157
+ * @default false
158
+ */
111
159
  ignoreInterface?: boolean;
112
160
  }
113
161
  /** `functional/prefer-tacit` rule options. */
114
162
  export interface ITtscLintFunctionalPreferTacitRuleOptions {
115
- /** Check member expressions such as `x => service.map(x)`. */
163
+ /**
164
+ * Check member expressions such as `x => service.map(x)`. Set `false` to keep
165
+ * the rule on bare-identifier callees only.
166
+ *
167
+ * @default true
168
+ */
116
169
  checkMemberExpressions?: boolean;
117
170
  }
118
171
  /** `functional/readonly-type` rule options. */
@@ -133,7 +186,11 @@ export interface ITtscLintFunctionalTypeDeclarationImmutabilityRule {
133
186
  * every value as readonly-required.
134
187
  */
135
188
  immutability?: "ReadonlyShallow" | "ReadonlyDeep" | "Immutable" | "Mutable";
136
- /** Comparator applied to the immutability level above. */
189
+ /**
190
+ * Comparator applied to the immutability level above. Reserved for
191
+ * upstream-compatible configs alongside `immutability`: the native subset
192
+ * computes no immutability level, so there is nothing to compare.
193
+ */
137
194
  comparator?: "Less" | "AtMost" | "Exactly" | "AtLeast" | "More" | -2 | -1 | 0 | 1 | 2;
138
195
  }
139
196
  /** `functional/type-declaration-immutability` rule options. */