@cyanheads/mcp-ts-core 0.7.6 → 0.8.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.
- package/CLAUDE.md +22 -7
- package/README.md +2 -2
- package/changelog/0.8.x/0.8.0.md +31 -0
- package/dist/core/context.d.ts +67 -0
- package/dist/core/context.d.ts.map +1 -1
- package/dist/core/context.js +46 -1
- package/dist/core/context.js.map +1 -1
- package/dist/core/index.d.ts +2 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +1 -0
- package/dist/core/index.js.map +1 -1
- package/dist/linter/rules/error-contract-rules.d.ts +45 -0
- package/dist/linter/rules/error-contract-rules.d.ts.map +1 -0
- package/dist/linter/rules/error-contract-rules.js +321 -0
- package/dist/linter/rules/error-contract-rules.js.map +1 -0
- package/dist/linter/rules/handler-body-rules.d.ts +18 -0
- package/dist/linter/rules/handler-body-rules.d.ts.map +1 -0
- package/dist/linter/rules/handler-body-rules.js +134 -0
- package/dist/linter/rules/handler-body-rules.js.map +1 -0
- package/dist/linter/rules/index.d.ts +2 -0
- package/dist/linter/rules/index.d.ts.map +1 -1
- package/dist/linter/rules/index.js +2 -0
- package/dist/linter/rules/index.js.map +1 -1
- package/dist/linter/rules/resource-rules.d.ts.map +1 -1
- package/dist/linter/rules/resource-rules.js +9 -0
- package/dist/linter/rules/resource-rules.js.map +1 -1
- package/dist/linter/rules/source-text.d.ts +19 -0
- package/dist/linter/rules/source-text.d.ts.map +1 -0
- package/dist/linter/rules/source-text.js +96 -0
- package/dist/linter/rules/source-text.js.map +1 -0
- package/dist/linter/rules/tool-rules.d.ts.map +1 -1
- package/dist/linter/rules/tool-rules.js +9 -0
- package/dist/linter/rules/tool-rules.js.map +1 -1
- package/dist/logs/combined.log +4 -4
- package/dist/logs/error.log +4 -4
- package/dist/mcp-server/apps/appBuilders.d.ts +9 -4
- package/dist/mcp-server/apps/appBuilders.d.ts.map +1 -1
- package/dist/mcp-server/apps/appBuilders.js +4 -0
- package/dist/mcp-server/apps/appBuilders.js.map +1 -1
- package/dist/mcp-server/resources/resource-registration.d.ts.map +1 -1
- package/dist/mcp-server/resources/resource-registration.js +3 -2
- package/dist/mcp-server/resources/resource-registration.js.map +1 -1
- package/dist/mcp-server/resources/utils/resourceDefinition.d.ts +13 -5
- package/dist/mcp-server/resources/utils/resourceDefinition.d.ts.map +1 -1
- package/dist/mcp-server/resources/utils/resourceDefinition.js.map +1 -1
- package/dist/mcp-server/resources/utils/resourceHandlerFactory.d.ts.map +1 -1
- package/dist/mcp-server/resources/utils/resourceHandlerFactory.js +5 -4
- package/dist/mcp-server/resources/utils/resourceHandlerFactory.js.map +1 -1
- package/dist/mcp-server/tools/tool-registration.d.ts.map +1 -1
- package/dist/mcp-server/tools/tool-registration.js +13 -7
- package/dist/mcp-server/tools/tool-registration.js.map +1 -1
- package/dist/mcp-server/tools/utils/toolDefinition.d.ts +64 -16
- package/dist/mcp-server/tools/utils/toolDefinition.d.ts.map +1 -1
- package/dist/mcp-server/tools/utils/toolDefinition.js +25 -11
- package/dist/mcp-server/tools/utils/toolDefinition.js.map +1 -1
- package/dist/mcp-server/tools/utils/toolHandlerFactory.d.ts.map +1 -1
- package/dist/mcp-server/tools/utils/toolHandlerFactory.js +6 -4
- package/dist/mcp-server/tools/utils/toolHandlerFactory.js.map +1 -1
- package/dist/testing/index.d.ts +8 -0
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +5 -1
- package/dist/testing/index.js.map +1 -1
- package/dist/types-global/errors.d.ts +82 -0
- package/dist/types-global/errors.d.ts.map +1 -1
- package/dist/types-global/errors.js +25 -0
- package/dist/types-global/errors.js.map +1 -1
- package/dist/utils/formatting/index.d.ts +1 -0
- package/dist/utils/formatting/index.d.ts.map +1 -1
- package/dist/utils/formatting/index.js +1 -0
- package/dist/utils/formatting/index.js.map +1 -1
- package/dist/utils/formatting/partialResult.d.ts +145 -0
- package/dist/utils/formatting/partialResult.d.ts.map +1 -0
- package/dist/utils/formatting/partialResult.js +145 -0
- package/dist/utils/formatting/partialResult.js.map +1 -0
- package/dist/utils/index.d.ts +2 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +2 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/network/httpError.d.ts +112 -0
- package/dist/utils/network/httpError.d.ts.map +1 -0
- package/dist/utils/network/httpError.js +153 -0
- package/dist/utils/network/httpError.js.map +1 -0
- package/dist/utils/network/retry.d.ts.map +1 -1
- package/dist/utils/network/retry.js +0 -1
- package/dist/utils/network/retry.js.map +1 -1
- package/package.json +5 -4
- package/scripts/split-changelog.ts +133 -0
- package/skills/add-app-tool/SKILL.md +12 -0
- package/skills/add-resource/SKILL.md +40 -0
- package/skills/add-service/SKILL.md +47 -0
- package/skills/add-test/SKILL.md +39 -0
- package/skills/add-tool/SKILL.md +39 -4
- package/skills/api-context/SKILL.md +75 -1
- package/skills/api-errors/SKILL.md +162 -4
- package/skills/api-linter/SKILL.md +223 -3
- package/skills/api-testing/SKILL.md +79 -4
- package/skills/api-utils/SKILL.md +4 -2
- package/skills/design-mcp-server/SKILL.md +13 -10
- package/skills/field-test/SKILL.md +8 -2
- package/skills/maintenance/SKILL.md +2 -2
- package/skills/report-issue-framework/SKILL.md +2 -2
- package/skills/security-pass/SKILL.md +6 -5
- package/templates/AGENTS.md +23 -8
- package/templates/CLAUDE.md +23 -8
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Lint rules for the declarative `errors[]` contract on tool and
|
|
3
|
+
* resource definitions. Validates structure (codes, reasons), uniqueness,
|
|
4
|
+
* and (when a contract is present) cross-checks handler bodies for thrown
|
|
5
|
+
* codes that aren't declared.
|
|
6
|
+
* @module src/linter/rules/error-contract-rules
|
|
7
|
+
*/
|
|
8
|
+
import { JsonRpcErrorCode } from '../../types-global/errors.js';
|
|
9
|
+
import { stripCommentsAndStrings } from './source-text.js';
|
|
10
|
+
/**
|
|
11
|
+
* Set of valid `JsonRpcErrorCode` numeric values, computed once at module load.
|
|
12
|
+
* Used to validate the `code` field on each contract entry.
|
|
13
|
+
*/
|
|
14
|
+
const VALID_CODES = new Set(Object.values(JsonRpcErrorCode).filter((v) => typeof v === 'number'));
|
|
15
|
+
const REASON_RE = /^[a-z][a-z0-9_]*$/;
|
|
16
|
+
/**
|
|
17
|
+
* Validates the `errors[]` contract on a tool/resource definition.
|
|
18
|
+
* Checks:
|
|
19
|
+
* - `errors` is an array
|
|
20
|
+
* - each entry is an object with required `code`, `reason`, `when`
|
|
21
|
+
* - `code` is a real `JsonRpcErrorCode` value
|
|
22
|
+
* - `reason` is snake_case and unique within the contract
|
|
23
|
+
* - `retryable` (when present) is a boolean
|
|
24
|
+
*/
|
|
25
|
+
export function lintErrorContract(errors, definitionType, definitionName) {
|
|
26
|
+
const diagnostics = [];
|
|
27
|
+
if (errors === undefined)
|
|
28
|
+
return diagnostics;
|
|
29
|
+
if (!Array.isArray(errors)) {
|
|
30
|
+
diagnostics.push({
|
|
31
|
+
rule: 'error-contract-type',
|
|
32
|
+
severity: 'error',
|
|
33
|
+
message: `${definitionType} '${definitionName}' has 'errors' but it is not an array.`,
|
|
34
|
+
definitionType,
|
|
35
|
+
definitionName,
|
|
36
|
+
});
|
|
37
|
+
return diagnostics;
|
|
38
|
+
}
|
|
39
|
+
if (errors.length === 0) {
|
|
40
|
+
diagnostics.push({
|
|
41
|
+
rule: 'error-contract-empty',
|
|
42
|
+
severity: 'warning',
|
|
43
|
+
message: `${definitionType} '${definitionName}' declares an empty 'errors: []' contract. ` +
|
|
44
|
+
'An empty contract is a no-op — drop the field entirely, or declare the actual ' +
|
|
45
|
+
'failure modes. Empty contracts give clients no useful failure-surface preview.',
|
|
46
|
+
definitionType,
|
|
47
|
+
definitionName,
|
|
48
|
+
});
|
|
49
|
+
return diagnostics;
|
|
50
|
+
}
|
|
51
|
+
const seenReasons = new Set();
|
|
52
|
+
for (let i = 0; i < errors.length; i++) {
|
|
53
|
+
const entry = errors[i];
|
|
54
|
+
const path = `errors[${i}]`;
|
|
55
|
+
if (typeof entry !== 'object' || entry === null) {
|
|
56
|
+
diagnostics.push({
|
|
57
|
+
rule: 'error-contract-entry-type',
|
|
58
|
+
severity: 'error',
|
|
59
|
+
message: `${definitionType} '${definitionName}' ${path} must be an object with { code, reason, when }.`,
|
|
60
|
+
definitionType,
|
|
61
|
+
definitionName,
|
|
62
|
+
});
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
const e = entry;
|
|
66
|
+
// code
|
|
67
|
+
if (typeof e.code !== 'number') {
|
|
68
|
+
diagnostics.push({
|
|
69
|
+
rule: 'error-contract-code-type',
|
|
70
|
+
severity: 'error',
|
|
71
|
+
message: `${definitionType} '${definitionName}' ${path}.code must be a JsonRpcErrorCode value (number).`,
|
|
72
|
+
definitionType,
|
|
73
|
+
definitionName,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
else if (!VALID_CODES.has(e.code)) {
|
|
77
|
+
diagnostics.push({
|
|
78
|
+
rule: 'error-contract-code-unknown',
|
|
79
|
+
severity: 'error',
|
|
80
|
+
message: `${definitionType} '${definitionName}' ${path}.code is ${e.code}, ` +
|
|
81
|
+
'which is not a valid JsonRpcErrorCode. Use the enum import.',
|
|
82
|
+
definitionType,
|
|
83
|
+
definitionName,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
else if (e.code === JsonRpcErrorCode.UnknownError) {
|
|
87
|
+
// `UnknownError` is the auto-classifier's giveup fallback — it tells
|
|
88
|
+
// clients literally nothing. Declaring it in a contract is meaningless;
|
|
89
|
+
// pick a more specific code (or omit the entry entirely).
|
|
90
|
+
diagnostics.push({
|
|
91
|
+
rule: 'error-contract-code-unknown-error',
|
|
92
|
+
severity: 'warning',
|
|
93
|
+
message: `${definitionType} '${definitionName}' ${path}.code is JsonRpcErrorCode.UnknownError. ` +
|
|
94
|
+
"This is the framework's giveup-fallback code — it conveys no useful information " +
|
|
95
|
+
'to clients. Pick a more specific code (e.g. InternalError, ServiceUnavailable) or ' +
|
|
96
|
+
'remove the entry.',
|
|
97
|
+
definitionType,
|
|
98
|
+
definitionName,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
// reason
|
|
102
|
+
if (typeof e.reason !== 'string' || e.reason.length === 0) {
|
|
103
|
+
diagnostics.push({
|
|
104
|
+
rule: 'error-contract-reason-required',
|
|
105
|
+
severity: 'error',
|
|
106
|
+
message: `${definitionType} '${definitionName}' ${path}.reason must be a non-empty string.`,
|
|
107
|
+
definitionType,
|
|
108
|
+
definitionName,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
if (!REASON_RE.test(e.reason)) {
|
|
113
|
+
diagnostics.push({
|
|
114
|
+
rule: 'error-contract-reason-format',
|
|
115
|
+
severity: 'warning',
|
|
116
|
+
message: `${definitionType} '${definitionName}' ${path}.reason '${e.reason}' should be snake_case ` +
|
|
117
|
+
'(start with a lowercase letter, then lowercase letters/digits/underscores). Treat reasons like API constants.',
|
|
118
|
+
definitionType,
|
|
119
|
+
definitionName,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
if (seenReasons.has(e.reason)) {
|
|
123
|
+
diagnostics.push({
|
|
124
|
+
rule: 'error-contract-reason-unique',
|
|
125
|
+
severity: 'error',
|
|
126
|
+
message: `${definitionType} '${definitionName}' has duplicate reason '${e.reason}' in errors[]. Reasons must be unique within a contract.`,
|
|
127
|
+
definitionType,
|
|
128
|
+
definitionName,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
seenReasons.add(e.reason);
|
|
132
|
+
}
|
|
133
|
+
// when
|
|
134
|
+
if (typeof e.when !== 'string' || e.when.length === 0) {
|
|
135
|
+
diagnostics.push({
|
|
136
|
+
rule: 'error-contract-when-required',
|
|
137
|
+
severity: 'error',
|
|
138
|
+
message: `${definitionType} '${definitionName}' ${path}.when must be a non-empty human-readable description.`,
|
|
139
|
+
definitionType,
|
|
140
|
+
definitionName,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
// retryable (optional)
|
|
144
|
+
if (e.retryable !== undefined && typeof e.retryable !== 'boolean') {
|
|
145
|
+
diagnostics.push({
|
|
146
|
+
rule: 'error-contract-retryable-type',
|
|
147
|
+
severity: 'warning',
|
|
148
|
+
message: `${definitionType} '${definitionName}' ${path}.retryable should be a boolean when present.`,
|
|
149
|
+
definitionType,
|
|
150
|
+
definitionName,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return diagnostics;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Map from `JsonRpcErrorCode` enum names → numeric values, computed once.
|
|
158
|
+
* Used by the conformance check to recognize `JsonRpcErrorCode.X` references in
|
|
159
|
+
* handler source.
|
|
160
|
+
*/
|
|
161
|
+
const CODE_NAME_TO_VALUE = (() => {
|
|
162
|
+
const out = {};
|
|
163
|
+
for (const [name, value] of Object.entries(JsonRpcErrorCode)) {
|
|
164
|
+
if (typeof value === 'number') {
|
|
165
|
+
out[name] = value;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return out;
|
|
169
|
+
})();
|
|
170
|
+
/**
|
|
171
|
+
* Map from factory function names → the codes they produce. Used by the
|
|
172
|
+
* conformance check to recognize `notFound(...)` style throws.
|
|
173
|
+
*/
|
|
174
|
+
const FACTORY_TO_CODE = {
|
|
175
|
+
invalidParams: JsonRpcErrorCode.InvalidParams,
|
|
176
|
+
invalidRequest: JsonRpcErrorCode.InvalidRequest,
|
|
177
|
+
notFound: JsonRpcErrorCode.NotFound,
|
|
178
|
+
forbidden: JsonRpcErrorCode.Forbidden,
|
|
179
|
+
unauthorized: JsonRpcErrorCode.Unauthorized,
|
|
180
|
+
validationError: JsonRpcErrorCode.ValidationError,
|
|
181
|
+
conflict: JsonRpcErrorCode.Conflict,
|
|
182
|
+
rateLimited: JsonRpcErrorCode.RateLimited,
|
|
183
|
+
timeout: JsonRpcErrorCode.Timeout,
|
|
184
|
+
serviceUnavailable: JsonRpcErrorCode.ServiceUnavailable,
|
|
185
|
+
configurationError: JsonRpcErrorCode.ConfigurationError,
|
|
186
|
+
internalError: JsonRpcErrorCode.InternalError,
|
|
187
|
+
serializationError: JsonRpcErrorCode.SerializationError,
|
|
188
|
+
databaseError: JsonRpcErrorCode.DatabaseError,
|
|
189
|
+
};
|
|
190
|
+
/**
|
|
191
|
+
* Codes that bubble up from anywhere — services, framework utilities,
|
|
192
|
+
* the auto-classifier — and are implicitly always-possible on any tool.
|
|
193
|
+
* The conformance check skips them so the contract can stay focused on
|
|
194
|
+
* the tool's *intentional* failure surface, not exhaustive infrastructure.
|
|
195
|
+
*
|
|
196
|
+
* Modeled after how OpenAPI-driven frameworks treat 5xx: implicit, not
|
|
197
|
+
* required to be enumerated per-endpoint.
|
|
198
|
+
*/
|
|
199
|
+
const BASELINE_CONFORMANCE_CODES = new Set([
|
|
200
|
+
JsonRpcErrorCode.InternalError,
|
|
201
|
+
JsonRpcErrorCode.ServiceUnavailable,
|
|
202
|
+
JsonRpcErrorCode.Timeout,
|
|
203
|
+
JsonRpcErrorCode.ValidationError,
|
|
204
|
+
JsonRpcErrorCode.SerializationError,
|
|
205
|
+
]);
|
|
206
|
+
/**
|
|
207
|
+
* Cross-checks a definition's declared `errors[]` contract against the codes
|
|
208
|
+
* that appear textually in its `handler` body. Fires only when a contract is
|
|
209
|
+
* present — definitions without an `errors[]` field are silently skipped.
|
|
210
|
+
*
|
|
211
|
+
* **Two distinct findings:**
|
|
212
|
+
*
|
|
213
|
+
* - `error-contract-conformance` — handler throws a non-baseline code that
|
|
214
|
+
* isn't in the contract. Suggests adding it to `errors[]`.
|
|
215
|
+
* - `error-contract-prefer-fail` — handler throws a code that IS in the
|
|
216
|
+
* contract directly (via factory or `new McpError`) instead of via
|
|
217
|
+
* `ctx.fail(reason, …)`. Encourages routing through the typed helper so
|
|
218
|
+
* observers see consistent `data.reason` values.
|
|
219
|
+
*
|
|
220
|
+
* **Baseline codes** (`InternalError`, `ServiceUnavailable`, `Timeout`,
|
|
221
|
+
* `ValidationError`, `SerializationError`) are skipped — they bubble from
|
|
222
|
+
* anywhere and don't need to be enumerated per-tool.
|
|
223
|
+
*
|
|
224
|
+
* Heuristic only: scans handler source text for `JsonRpcErrorCode.X` references
|
|
225
|
+
* and factory calls. Codes thrown from called services are invisible — so this
|
|
226
|
+
* is always a warning, never an error.
|
|
227
|
+
*/
|
|
228
|
+
export function lintErrorContractConformance(def, definitionType, definitionName) {
|
|
229
|
+
const diagnostics = [];
|
|
230
|
+
if (!Array.isArray(def.errors) || def.errors.length === 0)
|
|
231
|
+
return diagnostics;
|
|
232
|
+
if (typeof def.handler !== 'function')
|
|
233
|
+
return diagnostics;
|
|
234
|
+
let source;
|
|
235
|
+
try {
|
|
236
|
+
source = def.handler.toString();
|
|
237
|
+
}
|
|
238
|
+
catch {
|
|
239
|
+
return diagnostics;
|
|
240
|
+
}
|
|
241
|
+
// Strip strings/comments so a comment like `// throws NotFound` doesn't pollute.
|
|
242
|
+
const cleaned = stripCommentsAndStrings(source);
|
|
243
|
+
const observed = new Set();
|
|
244
|
+
// Direct references: `JsonRpcErrorCode.NotFound`
|
|
245
|
+
for (const m of cleaned.matchAll(/JsonRpcErrorCode\.(\w+)/g)) {
|
|
246
|
+
const value = m[1] ? CODE_NAME_TO_VALUE[m[1]] : undefined;
|
|
247
|
+
if (value !== undefined)
|
|
248
|
+
observed.add(value);
|
|
249
|
+
}
|
|
250
|
+
// Factory calls: `throw notFound(...)`, `throw serviceUnavailable(...)`
|
|
251
|
+
const factoryRe = new RegExp(String.raw `\bthrow\s+(${Object.keys(FACTORY_TO_CODE).join('|')})\s*\(`, 'g');
|
|
252
|
+
for (const m of cleaned.matchAll(factoryRe)) {
|
|
253
|
+
const code = m[1] ? FACTORY_TO_CODE[m[1]] : undefined;
|
|
254
|
+
if (code !== undefined)
|
|
255
|
+
observed.add(code);
|
|
256
|
+
}
|
|
257
|
+
// Build code → reason map from the contract so we can suggest the right
|
|
258
|
+
// ctx.fail('reason') call when a declared code is thrown directly.
|
|
259
|
+
const codeToReasons = new Map();
|
|
260
|
+
for (const entry of def.errors) {
|
|
261
|
+
if (entry && typeof entry.code === 'number' && typeof entry.reason === 'string') {
|
|
262
|
+
const reasons = codeToReasons.get(entry.code) ?? [];
|
|
263
|
+
reasons.push(entry.reason);
|
|
264
|
+
codeToReasons.set(entry.code, reasons);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
const undeclared = [];
|
|
268
|
+
const declaredButDirect = [];
|
|
269
|
+
for (const code of observed) {
|
|
270
|
+
if (BASELINE_CONFORMANCE_CODES.has(code))
|
|
271
|
+
continue;
|
|
272
|
+
const reasons = codeToReasons.get(code);
|
|
273
|
+
if (reasons && reasons.length > 0) {
|
|
274
|
+
declaredButDirect.push({ codeName: jsonRpcErrorCodeName(code), reasons });
|
|
275
|
+
}
|
|
276
|
+
else {
|
|
277
|
+
undeclared.push(jsonRpcErrorCodeName(code));
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
if (undeclared.length > 0) {
|
|
281
|
+
diagnostics.push({
|
|
282
|
+
rule: 'error-contract-conformance',
|
|
283
|
+
severity: 'warning',
|
|
284
|
+
message: `${definitionType} '${definitionName}' handler throws codes not in errors[]: ` +
|
|
285
|
+
`${undeclared.join(', ')}. Add them to the contract (with a stable reason) so ` +
|
|
286
|
+
'`tools/list` accurately advertises this failure mode. ' +
|
|
287
|
+
'Baseline codes (InternalError, ServiceUnavailable, Timeout, ValidationError, ' +
|
|
288
|
+
'SerializationError) are auto-allowed — only domain-specific codes need declaring.',
|
|
289
|
+
definitionType,
|
|
290
|
+
definitionName,
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
for (const entry of declaredButDirect) {
|
|
294
|
+
const reasonHint = entry.reasons.length === 1
|
|
295
|
+
? `'${entry.reasons[0]}'`
|
|
296
|
+
: `one of ${entry.reasons.map((r) => `'${r}'`).join(' / ')}`;
|
|
297
|
+
diagnostics.push({
|
|
298
|
+
rule: 'error-contract-prefer-fail',
|
|
299
|
+
severity: 'warning',
|
|
300
|
+
message: `${definitionType} '${definitionName}' throws ${entry.codeName} directly, but the ` +
|
|
301
|
+
`contract declares this code as reason ${reasonHint}. Consider routing through ` +
|
|
302
|
+
`\`ctx.fail(${reasonHint}, …)\` so observers see consistent \`data.reason\` values ` +
|
|
303
|
+
'and the failure is correlated with the contract entry.',
|
|
304
|
+
definitionType,
|
|
305
|
+
definitionName,
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
return diagnostics;
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Returns the enum name for a `JsonRpcErrorCode` value, or `String(code)` when
|
|
312
|
+
* the value is not a known member.
|
|
313
|
+
*/
|
|
314
|
+
function jsonRpcErrorCodeName(code) {
|
|
315
|
+
for (const [name, value] of Object.entries(JsonRpcErrorCode)) {
|
|
316
|
+
if (value === code)
|
|
317
|
+
return name;
|
|
318
|
+
}
|
|
319
|
+
return String(code);
|
|
320
|
+
}
|
|
321
|
+
//# sourceMappingURL=error-contract-rules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-contract-rules.js","sourceRoot":"","sources":["../../../src/linter/rules/error-contract-rules.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Heuristic source-text lint rules that scan the body of a
|
|
3
|
+
* tool/resource handler for common error-handling anti-patterns. These rules
|
|
4
|
+
* are intentionally cautious — false positives are warnings, not errors, and
|
|
5
|
+
* each rule fires at most once per definition to avoid noisy reports.
|
|
6
|
+
* @module src/linter/rules/handler-body-rules
|
|
7
|
+
*/
|
|
8
|
+
import type { LintDefinitionType, LintDiagnostic } from '../types.js';
|
|
9
|
+
/**
|
|
10
|
+
* Runs all handler-body lint rules against a tool or resource definition.
|
|
11
|
+
* Operates on `handler.toString()` — heuristic but adequate for catching the
|
|
12
|
+
* common anti-patterns documented in the framework conventions.
|
|
13
|
+
*/
|
|
14
|
+
export declare function lintHandlerBody(def: {
|
|
15
|
+
handler?: unknown;
|
|
16
|
+
name?: string;
|
|
17
|
+
}, definitionType: LintDefinitionType): LintDiagnostic[];
|
|
18
|
+
//# sourceMappingURL=handler-body-rules.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler-body-rules.d.ts","sourceRoot":"","sources":["../../../src/linter/rules/handler-body-rules.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAiCtE;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,EACzC,cAAc,EAAE,kBAAkB,GACjC,cAAc,EAAE,CAoGlB"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Heuristic source-text lint rules that scan the body of a
|
|
3
|
+
* tool/resource handler for common error-handling anti-patterns. These rules
|
|
4
|
+
* are intentionally cautious — false positives are warnings, not errors, and
|
|
5
|
+
* each rule fires at most once per definition to avoid noisy reports.
|
|
6
|
+
* @module src/linter/rules/handler-body-rules
|
|
7
|
+
*/
|
|
8
|
+
import { stripCommentsAndStrings } from './source-text.js';
|
|
9
|
+
/**
|
|
10
|
+
* Map from `JsonRpcErrorCode.X` enum names to their factory function names.
|
|
11
|
+
* Used by `prefer-error-factory` to suggest the right replacement.
|
|
12
|
+
*/
|
|
13
|
+
const CODE_TO_FACTORY = {
|
|
14
|
+
InvalidParams: 'invalidParams',
|
|
15
|
+
InvalidRequest: 'invalidRequest',
|
|
16
|
+
NotFound: 'notFound',
|
|
17
|
+
Forbidden: 'forbidden',
|
|
18
|
+
Unauthorized: 'unauthorized',
|
|
19
|
+
ValidationError: 'validationError',
|
|
20
|
+
Conflict: 'conflict',
|
|
21
|
+
RateLimited: 'rateLimited',
|
|
22
|
+
Timeout: 'timeout',
|
|
23
|
+
ServiceUnavailable: 'serviceUnavailable',
|
|
24
|
+
ConfigurationError: 'configurationError',
|
|
25
|
+
InternalError: 'internalError',
|
|
26
|
+
SerializationError: 'serializationError',
|
|
27
|
+
DatabaseError: 'databaseError',
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Names of factory functions and the `McpError` constructor — used to detect
|
|
31
|
+
* "is this a throw of a structured framework error?" inside a catch block.
|
|
32
|
+
*/
|
|
33
|
+
const FACTORY_NAMES = Object.values(CODE_TO_FACTORY).join('|');
|
|
34
|
+
const STRUCTURED_THROW_RE = new RegExp(String.raw `throw\s+(?:new\s+McpError\s*\(|(?:${FACTORY_NAMES})\s*\()`);
|
|
35
|
+
/**
|
|
36
|
+
* Runs all handler-body lint rules against a tool or resource definition.
|
|
37
|
+
* Operates on `handler.toString()` — heuristic but adequate for catching the
|
|
38
|
+
* common anti-patterns documented in the framework conventions.
|
|
39
|
+
*/
|
|
40
|
+
export function lintHandlerBody(def, definitionType) {
|
|
41
|
+
const diagnostics = [];
|
|
42
|
+
const definitionName = typeof def.name === 'string' && def.name ? def.name : '<unnamed>';
|
|
43
|
+
if (typeof def.handler !== 'function')
|
|
44
|
+
return diagnostics;
|
|
45
|
+
let source;
|
|
46
|
+
try {
|
|
47
|
+
source = def.handler.toString();
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
/* Some bound/native functions reject toString — nothing to lint. */
|
|
51
|
+
return diagnostics;
|
|
52
|
+
}
|
|
53
|
+
// Strip line/block comments and string contents so we don't fire on commented-out
|
|
54
|
+
// code or strings containing `throw new Error(`. Best-effort — preserves quote
|
|
55
|
+
// structure but blanks the inner text.
|
|
56
|
+
const cleaned = stripCommentsAndStrings(source);
|
|
57
|
+
// ── Rule 1: prefer-mcp-error-in-handler ──────────────────────────────────
|
|
58
|
+
// Plain `throw new Error(...)` doesn't carry a JSON-RPC code.
|
|
59
|
+
if (/throw\s+new\s+Error\s*\(/.test(cleaned)) {
|
|
60
|
+
diagnostics.push({
|
|
61
|
+
rule: 'prefer-mcp-error-in-handler',
|
|
62
|
+
severity: 'warning',
|
|
63
|
+
message: `${definitionType} '${definitionName}' throws a plain Error. ` +
|
|
64
|
+
'Use McpError or a factory (e.g. notFound(), serviceUnavailable(), serializationError()) ' +
|
|
65
|
+
'so the framework returns a specific JSON-RPC error code instead of the generic InternalError fallback.',
|
|
66
|
+
definitionType,
|
|
67
|
+
definitionName,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
// ── Rule 2: prefer-error-factory ─────────────────────────────────────────
|
|
71
|
+
// `new McpError(JsonRpcErrorCode.X, ...)` when `xFactory(...)` exists is verbose.
|
|
72
|
+
const factoryMatch = /new\s+McpError\s*\(\s*JsonRpcErrorCode\.(\w+)/.exec(cleaned);
|
|
73
|
+
if (factoryMatch) {
|
|
74
|
+
const codeName = factoryMatch[1];
|
|
75
|
+
const factory = codeName ? CODE_TO_FACTORY[codeName] : undefined;
|
|
76
|
+
if (factory) {
|
|
77
|
+
diagnostics.push({
|
|
78
|
+
rule: 'prefer-error-factory',
|
|
79
|
+
severity: 'warning',
|
|
80
|
+
message: `${definitionType} '${definitionName}' uses 'new McpError(JsonRpcErrorCode.${codeName}, …)'. ` +
|
|
81
|
+
`Prefer the factory '${factory}(…)' from @cyanheads/mcp-ts-core/errors for consistency and readability.`,
|
|
82
|
+
definitionType,
|
|
83
|
+
definitionName,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// ── Rule 3: preserve-cause-on-rethrow ────────────────────────────────────
|
|
88
|
+
// For each `catch (E)` block, if it throws a structured error without
|
|
89
|
+
// `{ cause: E }`, the original error chain is lost.
|
|
90
|
+
for (const catchMatch of cleaned.matchAll(/catch\s*\(\s*(\w+)/g)) {
|
|
91
|
+
const errorVar = catchMatch[1];
|
|
92
|
+
if (!errorVar || catchMatch.index === undefined)
|
|
93
|
+
continue;
|
|
94
|
+
// Bound the scan to the next ~800 chars — enough for a typical block,
|
|
95
|
+
// bounded so a long handler with many `catch` blocks doesn't compound.
|
|
96
|
+
const blockStart = catchMatch.index + catchMatch[0].length;
|
|
97
|
+
const block = cleaned.slice(blockStart, blockStart + 800);
|
|
98
|
+
if (!STRUCTURED_THROW_RE.test(block))
|
|
99
|
+
continue;
|
|
100
|
+
// `cause: errorVar` or `cause: e` somewhere in the block satisfies the rule.
|
|
101
|
+
const causeRe = new RegExp(String.raw `cause\s*:\s*${errorVar}\b`);
|
|
102
|
+
if (causeRe.test(block))
|
|
103
|
+
continue;
|
|
104
|
+
diagnostics.push({
|
|
105
|
+
rule: 'preserve-cause-on-rethrow',
|
|
106
|
+
severity: 'warning',
|
|
107
|
+
message: `${definitionType} '${definitionName}' wraps caught '${errorVar}' in McpError ` +
|
|
108
|
+
`without { cause: ${errorVar} }. Pass the cause via the 4th constructor arg ` +
|
|
109
|
+
'(or factory options) to preserve the error chain — observability platforms ' +
|
|
110
|
+
'and pino-pretty surface causes automatically.',
|
|
111
|
+
definitionType,
|
|
112
|
+
definitionName,
|
|
113
|
+
});
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
// ── Rule 4: no-stringify-upstream-error ──────────────────────────────────
|
|
117
|
+
// `throw new Error(\`... ${JSON.stringify(upstreamError)} ...\`)` risks leaking
|
|
118
|
+
// raw upstream blobs (stack traces, internal structure) into client-visible messages.
|
|
119
|
+
// Bound the scan length so unrelated calls in long handlers don't trigger false positives.
|
|
120
|
+
if (/throw\s+[^;]{0,400}?JSON\.stringify\s*\(/.test(cleaned)) {
|
|
121
|
+
diagnostics.push({
|
|
122
|
+
rule: 'no-stringify-upstream-error',
|
|
123
|
+
severity: 'warning',
|
|
124
|
+
message: `${definitionType} '${definitionName}' throws a message containing JSON.stringify(...). ` +
|
|
125
|
+
'Stringifying caught or upstream error blobs into the message risks leaking internal ' +
|
|
126
|
+
'traces (e.g., NCBI C++ exceptions, AWS internal ARNs) to clients. Sanitize first, or ' +
|
|
127
|
+
"attach the raw blob to the McpError's 'data' payload — never the message.",
|
|
128
|
+
definitionType,
|
|
129
|
+
definitionName,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
return diagnostics;
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=handler-body-rules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handler-body-rules.js","sourceRoot":"","sources":["../../../src/linter/rules/handler-body-rules.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
* @fileoverview Barrel export for all lint rule modules.
|
|
3
3
|
* @module src/linter/rules/index
|
|
4
4
|
*/
|
|
5
|
+
export { lintErrorContract, lintErrorContractConformance } from './error-contract-rules.js';
|
|
6
|
+
export { lintHandlerBody } from './handler-body-rules.js';
|
|
5
7
|
export { checkDuplicateNames, checkNameRequired, checkToolNameFormat } from './name-rules.js';
|
|
6
8
|
export { lintPromptDefinition } from './prompt-rules.js';
|
|
7
9
|
export { lintResourceDefinition } from './resource-rules.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/linter/rules/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAC9F,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EACL,sBAAsB,EACtB,gBAAgB,EAChB,uBAAuB,GACxB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,0BAA0B,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/linter/rules/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,iBAAiB,EAAE,4BAA4B,EAAE,MAAM,2BAA2B,CAAC;AAC5F,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAC9F,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EACL,sBAAsB,EACtB,gBAAgB,EAChB,uBAAuB,GACxB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,0BAA0B,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
* @fileoverview Barrel export for all lint rule modules.
|
|
3
3
|
* @module src/linter/rules/index
|
|
4
4
|
*/
|
|
5
|
+
export { lintErrorContract, lintErrorContractConformance } from './error-contract-rules.js';
|
|
6
|
+
export { lintHandlerBody } from './handler-body-rules.js';
|
|
5
7
|
export { checkDuplicateNames, checkNameRequired, checkToolNameFormat } from './name-rules.js';
|
|
6
8
|
export { lintPromptDefinition } from './prompt-rules.js';
|
|
7
9
|
export { lintResourceDefinition } from './resource-rules.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/linter/rules/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAC9F,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EACL,sBAAsB,EACtB,gBAAgB,EAChB,uBAAuB,GACxB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,0BAA0B,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/linter/rules/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,iBAAiB,EAAE,4BAA4B,EAAE,MAAM,2BAA2B,CAAC;AAC5F,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAC9F,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EACL,sBAAsB,EACtB,gBAAgB,EAChB,uBAAuB,GACxB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,0BAA0B,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resource-rules.d.ts","sourceRoot":"","sources":["../../../src/linter/rules/resource-rules.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"resource-rules.d.ts","sourceRoot":"","sources":["../../../src/linter/rules/resource-rules.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAWlD;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,OAAO,GAAG,cAAc,EAAE,CAiHrE"}
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
* Validates resource definitions against MCP spec and framework conventions.
|
|
4
4
|
* @module src/linter/rules/resource-rules
|
|
5
5
|
*/
|
|
6
|
+
import { lintErrorContract, lintErrorContractConformance } from './error-contract-rules.js';
|
|
7
|
+
import { lintHandlerBody } from './handler-body-rules.js';
|
|
6
8
|
import { checkNameRequired } from './name-rules.js';
|
|
7
9
|
import { checkFieldDescriptions, checkIsZodObject, checkSchemaSerializable, } from './schema-rules.js';
|
|
8
10
|
import { lintAuthScopes } from './tool-rules.js';
|
|
@@ -102,6 +104,13 @@ export function lintResourceDefinition(def) {
|
|
|
102
104
|
diagnostics.push(outputSerial);
|
|
103
105
|
}
|
|
104
106
|
}
|
|
107
|
+
// Handler body heuristic checks (error-handling anti-patterns)
|
|
108
|
+
diagnostics.push(...lintHandlerBody(d, 'resource'));
|
|
109
|
+
// Declarative error contract validation
|
|
110
|
+
if (d?.errors !== undefined) {
|
|
111
|
+
diagnostics.push(...lintErrorContract(d.errors, 'resource', displayName));
|
|
112
|
+
diagnostics.push(...lintErrorContractConformance(d, 'resource', displayName));
|
|
113
|
+
}
|
|
105
114
|
return diagnostics;
|
|
106
115
|
}
|
|
107
116
|
/** Extracts variable names from an RFC 6570 URI template (strips operators like +, #, ?, &, etc.). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resource-rules.js","sourceRoot":"","sources":["../../../src/linter/rules/resource-rules.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"resource-rules.js","sourceRoot":"","sources":["../../../src/linter/rules/resource-rules.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAE,iBAAiB,EAAE,4BAA4B,EAAE,MAAM,2BAA2B,CAAC;AAC5F,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EACL,sBAAsB,EACtB,gBAAgB,EAChB,uBAAuB,GACxB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjD;;GAEG;AACH,MAAM,UAAU,sBAAsB,CAAC,GAAY;IACjD,MAAM,WAAW,GAAqB,EAAE,CAAC;IACzC,MAAM,CAAC,GAAG,GAA8B,CAAC;IACzC,MAAM,WAAW,GAAG,OAAO,CAAC,EAAE,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5E,MAAM,IAAI,GAAG,OAAO,CAAC,EAAE,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC;IAChE,MAAM,WAAW,GAAG,IAAI,IAAI,WAAW,CAAC;IAExC,2BAA2B;IAC3B,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,WAAW,CAAC,IAAI,CAAC;YACf,IAAI,EAAE,uBAAuB;YAC7B,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,aAAa,WAAW,6BAA6B;YAC9D,cAAc,EAAE,UAAU;YAC1B,cAAc,EAAE,WAAW;SAC5B,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,sDAAsD;QACtD,MAAM,aAAa,GAAG,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QAC1D,IAAI,aAAa;YAAE,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IACrD,CAAC;IAED,wBAAwB;IACxB,IAAI,CAAC,CAAC,EAAE,IAAI,IAAI,WAAW,EAAE,CAAC;QAC5B,WAAW,CAAC,IAAI,CAAC;YACf,IAAI,EAAE,uBAAuB;YAC7B,QAAQ,EAAE,SAAS;YACnB,OAAO,EACL,aAAa,WAAW,4EAA4E;gBACpG,2DAA2D;YAC7D,cAAc,EAAE,UAAU;YAC1B,cAAc,EAAE,WAAW;SAC5B,CAAC,CAAC;IACL,CAAC;IAED,6CAA6C;IAC7C,IAAI,CAAC,EAAE,IAAI,KAAK,SAAS,EAAE,CAAC;QAC1B,MAAM,OAAO,GAAG,iBAAiB,CAAC,CAAC,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;QAC5D,IAAI,OAAO;YAAE,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACzC,CAAC;IAED,cAAc;IACd,IAAI,OAAO,CAAC,EAAE,WAAW,KAAK,QAAQ,IAAI,CAAC,CAAC,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrE,WAAW,CAAC,IAAI,CAAC;YACf,IAAI,EAAE,sBAAsB;YAC5B,QAAQ,EAAE,SAAS;YACnB,OAAO,EAAE,aAAa,WAAW,uBAAuB;YACxD,cAAc,EAAE,UAAU;YAC1B,cAAc,EAAE,WAAW;SAC5B,CAAC,CAAC;IACL,CAAC;IAED,UAAU;IACV,IAAI,OAAO,CAAC,EAAE,OAAO,KAAK,UAAU,EAAE,CAAC;QACrC,WAAW,CAAC,IAAI,CAAC;YACf,IAAI,EAAE,kBAAkB;YACxB,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,aAAa,WAAW,kCAAkC;YACnE,cAAc,EAAE,UAAU;YAC1B,cAAc,EAAE,WAAW;SAC5B,CAAC,CAAC;IACL,CAAC;IAED,+DAA+D;IAC/D,IAAI,CAAC,EAAE,MAAM,KAAK,SAAS,EAAE,CAAC;QAC5B,MAAM,WAAW,GAAG,gBAAgB,CAAC,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;QAClF,IAAI,WAAW,EAAE,CAAC;YAChB,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAChC,CAAC;aAAM,CAAC;YACN,WAAW,CAAC,IAAI,CAAC,GAAG,sBAAsB,CAAC,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC;YACzF,MAAM,YAAY,GAAG,uBAAuB,CAAC,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;YAC1F,IAAI,YAAY;gBAAE,WAAW,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAEjD,oEAAoE;YACpE,IAAI,WAAW,EAAE,CAAC;gBAChB,WAAW,CAAC,IAAI,CAAC,GAAG,4BAA4B,CAAC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;YACxF,CAAC;QACH,CAAC;IACH,CAAC;IAED,yBAAyB;IACzB,IAAI,CAAC,EAAE,IAAI,KAAK,SAAS,EAAE,CAAC;QAC1B,WAAW,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,IAAI,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC;IACvE,CAAC;IAED,+DAA+D;IAC/D,IAAI,CAAC,EAAE,MAAM,KAAK,SAAS,EAAE,CAAC;QAC5B,MAAM,WAAW,GAAG,gBAAgB,CAAC,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;QAClF,IAAI,WAAW,EAAE,CAAC;YAChB,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAChC,CAAC;aAAM,CAAC;YACN,WAAW,CAAC,IAAI,CAAC,GAAG,sBAAsB,CAAC,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC;YACzF,MAAM,YAAY,GAAG,uBAAuB,CAAC,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;YAC1F,IAAI,YAAY;gBAAE,WAAW,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;IAED,+DAA+D;IAC/D,WAAW,CAAC,IAAI,CAAC,GAAG,eAAe,CAAC,CAAyC,EAAE,UAAU,CAAC,CAAC,CAAC;IAE5F,wCAAwC;IACxC,IAAI,CAAC,EAAE,MAAM,KAAK,SAAS,EAAE,CAAC;QAC5B,WAAW,CAAC,IAAI,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC,MAAM,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC;QAC1E,WAAW,CAAC,IAAI,CACd,GAAG,4BAA4B,CAC7B,CAA4C,EAC5C,UAAU,EACV,WAAW,CACZ,CACF,CAAC;IACJ,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,sGAAsG;AACtG,SAAS,wBAAwB,CAAC,QAAgB;IAChD,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,QAAQ,CAAC,4BAA4B,CAAC,EAAE,CAAC;QACpE,yFAAyF;QACzF,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC/B,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YACtC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YACtD,IAAI,IAAI;gBAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,SAAS,4BAA4B,CACnC,QAAgB,EAChB,MAAe,EACf,YAAoB;IAEpB,MAAM,YAAY,GAAG,wBAAwB,CAAC,QAAQ,CAAC,CAAC;IACxD,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAEzC,MAAM,KAAK,GAAI,MAAiC,CAAC,KAAK,CAAC;IACvD,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAE/C,MAAM,WAAW,GAAqB,EAAE,CAAC;IACzC,KAAK,MAAM,OAAO,IAAI,YAAY,EAAE,CAAC;QACnC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YAC7B,WAAW,CAAC,IAAI,CAAC;gBACf,IAAI,EAAE,uBAAuB;gBAC7B,QAAQ,EAAE,OAAO;gBACjB,OAAO,EACL,aAAa,YAAY,6BAA6B,OAAO,2CAA2C;oBACxG,uBAAuB,CAAC,GAAG,UAAU,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,iDAAiD;gBACpG,cAAc,EAAE,UAAU;gBAC1B,cAAc,EAAE,YAAY;aAC7B,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;;GAGG;AACH,SAAS,gBAAgB,CAAC,QAAgB,EAAE,IAAY;IACtD,8BAA8B;IAC9B,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC5B,IAAI,IAAI,KAAK,GAAG;YAAE,KAAK,EAAE,CAAC;QAC1B,IAAI,IAAI,KAAK,GAAG;YAAE,KAAK,EAAE,CAAC;QAC1B,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACd,OAAO;gBACL,IAAI,EAAE,oBAAoB;gBAC1B,QAAQ,EAAE,OAAO;gBACjB,OAAO,EAAE,aAAa,IAAI,wDAAwD,QAAQ,IAAI;gBAC9F,cAAc,EAAE,UAAU;gBAC1B,cAAc,EAAE,IAAI;aACrB,CAAC;QACJ,CAAC;IACH,CAAC;IACD,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;QAChB,OAAO;YACL,IAAI,EAAE,oBAAoB;YAC1B,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,aAAa,IAAI,qDAAqD,QAAQ,IAAI;YAC3F,cAAc,EAAE,UAAU;YAC1B,cAAc,EAAE,IAAI;SACrB,CAAC;IACJ,CAAC;IAED,yCAAyC;IACzC,IAAI,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,OAAO;YACL,IAAI,EAAE,oBAAoB;YAC1B,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,aAAa,IAAI,0DAA0D,QAAQ,IAAI;YAChG,cAAc,EAAE,UAAU;YAC1B,cAAc,EAAE,IAAI;SACrB,CAAC;IACJ,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Shared text utilities for handler-source heuristic lint rules.
|
|
3
|
+
* @module src/linter/rules/source-text
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Replaces the contents of single-line comments, block comments, and string
|
|
7
|
+
* literals with same-length whitespace runs. Preserves line structure (so any
|
|
8
|
+
* future line-aware diagnostics still align) without falsely matching
|
|
9
|
+
* anti-pattern regexes against documentation or sample text inside literals.
|
|
10
|
+
*
|
|
11
|
+
* Used by the handler-body and error-contract conformance rules so a comment
|
|
12
|
+
* like `// throws NotFound` doesn't pollute the scan.
|
|
13
|
+
*
|
|
14
|
+
* Limitations: regex literals are not stripped. If a regex contains the literal
|
|
15
|
+
* text `throw new Error(`, it would still trigger a false positive — but that is
|
|
16
|
+
* a deliberate trade-off; full lexing is overkill for a heuristic warning.
|
|
17
|
+
*/
|
|
18
|
+
export declare function stripCommentsAndStrings(source: string): string;
|
|
19
|
+
//# sourceMappingURL=source-text.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source-text.d.ts","sourceRoot":"","sources":["../../../src/linter/rules/source-text.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;;GAYG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAiF9D"}
|