@qualety/typescript 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 (75) hide show
  1. package/LICENSE +21 -0
  2. package/dist/exhaustive-switch.d.ts +8 -0
  3. package/dist/exhaustive-switch.d.ts.map +1 -0
  4. package/dist/exhaustive-switch.js +198 -0
  5. package/dist/exhaustive-switch.js.map +1 -0
  6. package/dist/explicit-public-return-types.d.ts +8 -0
  7. package/dist/explicit-public-return-types.d.ts.map +1 -0
  8. package/dist/explicit-public-return-types.js +123 -0
  9. package/dist/explicit-public-return-types.js.map +1 -0
  10. package/dist/index.d.ts +5 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +70 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/narrowing.d.ts +36 -0
  15. package/dist/narrowing.d.ts.map +1 -0
  16. package/dist/narrowing.js +776 -0
  17. package/dist/narrowing.js.map +1 -0
  18. package/dist/no-constant-condition.d.ts +8 -0
  19. package/dist/no-constant-condition.d.ts.map +1 -0
  20. package/dist/no-constant-condition.js +59 -0
  21. package/dist/no-constant-condition.js.map +1 -0
  22. package/dist/no-empty-catch.d.ts +7 -0
  23. package/dist/no-empty-catch.d.ts.map +1 -0
  24. package/dist/no-empty-catch.js +23 -0
  25. package/dist/no-empty-catch.js.map +1 -0
  26. package/dist/no-export-star.d.ts +7 -0
  27. package/dist/no-export-star.d.ts.map +1 -0
  28. package/dist/no-export-star.js +30 -0
  29. package/dist/no-export-star.js.map +1 -0
  30. package/dist/no-floating-promises.d.ts +14 -0
  31. package/dist/no-floating-promises.d.ts.map +1 -0
  32. package/dist/no-floating-promises.js +129 -0
  33. package/dist/no-floating-promises.js.map +1 -0
  34. package/dist/no-misused-promises.d.ts +8 -0
  35. package/dist/no-misused-promises.d.ts.map +1 -0
  36. package/dist/no-misused-promises.js +188 -0
  37. package/dist/no-misused-promises.js.map +1 -0
  38. package/dist/no-non-null-assertion.d.ts +7 -0
  39. package/dist/no-non-null-assertion.d.ts.map +1 -0
  40. package/dist/no-non-null-assertion.js +24 -0
  41. package/dist/no-non-null-assertion.js.map +1 -0
  42. package/dist/no-public-any.d.ts +8 -0
  43. package/dist/no-public-any.d.ts.map +1 -0
  44. package/dist/no-public-any.js +92 -0
  45. package/dist/no-public-any.js.map +1 -0
  46. package/dist/no-unnecessary-abstraction.d.ts +8 -0
  47. package/dist/no-unnecessary-abstraction.d.ts.map +1 -0
  48. package/dist/no-unnecessary-abstraction.js +452 -0
  49. package/dist/no-unnecessary-abstraction.js.map +1 -0
  50. package/dist/no-unsafe-assertion.d.ts +7 -0
  51. package/dist/no-unsafe-assertion.d.ts.map +1 -0
  52. package/dist/no-unsafe-assertion.js +38 -0
  53. package/dist/no-unsafe-assertion.js.map +1 -0
  54. package/dist/parse-flow.d.ts +16 -0
  55. package/dist/parse-flow.d.ts.map +1 -0
  56. package/dist/parse-flow.js +136 -0
  57. package/dist/parse-flow.js.map +1 -0
  58. package/dist/public-exports-tested.d.ts +8 -0
  59. package/dist/public-exports-tested.d.ts.map +1 -0
  60. package/dist/public-exports-tested.js +170 -0
  61. package/dist/public-exports-tested.js.map +1 -0
  62. package/dist/ts-source.d.ts +5 -0
  63. package/dist/ts-source.d.ts.map +1 -0
  64. package/dist/ts-source.js +28 -0
  65. package/dist/ts-source.js.map +1 -0
  66. package/dist/type-narrowing-checks.d.ts +8 -0
  67. package/dist/type-narrowing-checks.d.ts.map +1 -0
  68. package/dist/type-narrowing-checks.js +99 -0
  69. package/dist/type-narrowing-checks.js.map +1 -0
  70. package/dist/zod-boundary.d.ts +8 -0
  71. package/dist/zod-boundary.d.ts.map +1 -0
  72. package/dist/zod-boundary.js +110 -0
  73. package/dist/zod-boundary.js.map +1 -0
  74. package/package.json +44 -0
  75. package/tsconfig/recommended.json +11 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-non-null-assertion.js","sourceRoot":"","sources":["../src/no-non-null-assertion.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEzD,MAAM,GAAG,GAAG,4DAA4D,CAAC;AACzE,MAAM,IAAI,GAAG,wDAAwD,CAAC;AAEtE,MAAM,CAAC,MAAM,kBAAkB,GAAG,UAAU,CAAC;IAC3C,IAAI,EAAE;QACJ,QAAQ,EAAE,CAAC,YAAY,CAAC;QACxB,IAAI,EAAE;YACJ,WAAW,EAAE,mDAAmD;SACjE;KACF;IACD,MAAM,CAAC,OAAO;QACZ,MAAM,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;QACnD,aAAa,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE;YAC7C,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,oBAAoB,CAAC,UAAU,CAAC,iBAAiB,CAAC,EAAE,CAAC;gBAC3E,IAAI,IAAI,CAAC,OAAO,EAAE,KAAK,UAAU,CAAC,iBAAiB,EAAE,CAAC;oBACpD,QAAQ,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;gBAC3C,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;CACF,CAAC,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { type RuleContext } from "qualety";
2
+ export declare const noPublicAny: {
3
+ meta: import("qualety").RuleMeta & {
4
+ requires?: readonly ["typescript"] | undefined;
5
+ };
6
+ create(context: RuleContext<readonly ["typescript"]>): void | import("qualety").RuleListener;
7
+ };
8
+ //# sourceMappingURL=no-public-any.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-public-any.d.ts","sourceRoot":"","sources":["../src/no-public-any.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,WAAW,EAAE,MAAM,SAAS,CAAC;AAQvD,eAAO,MAAM,WAAW;;;;;CAsBtB,CAAC"}
@@ -0,0 +1,92 @@
1
+ import { defineRule } from "qualety";
2
+ import { Node } from "ts-morph";
3
+ import { unwrapParens } from "./narrowing.js";
4
+ import { isFunctionLike } from "./parse-flow.js";
5
+ import { reportAt, walkTsSources } from "./ts-source.js";
6
+ const HINT = "Replace any with a real type or unknown, then narrow.";
7
+ export const noPublicAny = defineRule({
8
+ meta: {
9
+ requires: ["typescript"],
10
+ docs: {
11
+ description: "Public value exports must not be annotated as any or any[].",
12
+ },
13
+ },
14
+ create(context) {
15
+ const sources = context.getArtifact("typescript").sources;
16
+ walkTsSources(sources, (unit, file) => {
17
+ for (const stmt of unit.getStatements()) {
18
+ if (Node.isFunctionDeclaration(stmt) ||
19
+ Node.isVariableStatement(stmt) ||
20
+ Node.isExportAssignment(stmt)) {
21
+ scanFile(unit, file, context);
22
+ break;
23
+ }
24
+ }
25
+ });
26
+ },
27
+ });
28
+ function scanFile(sourceFile, file, context) {
29
+ for (const stmt of sourceFile.getStatements()) {
30
+ if (Node.isFunctionDeclaration(stmt) && stmt.hasExportKeyword()) {
31
+ const name = stmt.isDefaultExport() ? "default" : (stmt.getName() ?? "default");
32
+ scanFn(stmt, name, file, context);
33
+ continue;
34
+ }
35
+ if (Node.isVariableStatement(stmt) && stmt.hasExportKeyword()) {
36
+ scanVars(stmt, file, context);
37
+ continue;
38
+ }
39
+ if (Node.isExportAssignment(stmt) && !stmt.isExportEquals()) {
40
+ scanDefault(stmt, file, context);
41
+ }
42
+ }
43
+ }
44
+ function scanVars(stmt, file, context) {
45
+ if (!Node.isVariableStatement(stmt)) {
46
+ return;
47
+ }
48
+ for (const decl of stmt.getDeclarations()) {
49
+ const name = decl.getName();
50
+ reportIfAny(decl.getTypeNode(), name, file, context);
51
+ const init = decl.getInitializer();
52
+ if (init === undefined) {
53
+ continue;
54
+ }
55
+ const expr = unwrapParens(init);
56
+ if (Node.isAsExpression(expr)) {
57
+ reportIfAny(expr.getTypeNode(), name, file, context);
58
+ }
59
+ if (isFunctionLike(expr)) {
60
+ scanFn(expr, name, file, context);
61
+ }
62
+ }
63
+ }
64
+ function scanDefault(stmt, file, context) {
65
+ if (!Node.isExportAssignment(stmt)) {
66
+ return;
67
+ }
68
+ const expr = unwrapParens(stmt.getExpression());
69
+ if (Node.isAsExpression(expr)) {
70
+ reportIfAny(expr.getTypeNode(), "default", file, context);
71
+ }
72
+ if (isFunctionLike(expr)) {
73
+ scanFn(expr, "default", file, context);
74
+ }
75
+ }
76
+ function scanFn(fn, name, file, context) {
77
+ for (const param of fn.getParameters()) {
78
+ reportIfAny(param.getTypeNode(), name, file, context);
79
+ }
80
+ reportIfAny(fn.getReturnTypeNode(), name, file, context);
81
+ }
82
+ function reportIfAny(typeNode, name, file, context) {
83
+ if (typeNode === undefined) {
84
+ return;
85
+ }
86
+ const text = typeNode.getText().trim();
87
+ if (text !== "any" && text !== "any[]") {
88
+ return;
89
+ }
90
+ reportAt(context, file, typeNode, `Public export "${name}" is typed as any.`, HINT);
91
+ }
92
+ //# sourceMappingURL=no-public-any.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-public-any.js","sourceRoot":"","sources":["../src/no-public-any.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { type RuleContext } from "qualety";
2
+ export declare const noUnnecessaryAbstraction: {
3
+ meta: import("qualety").RuleMeta & {
4
+ requires?: readonly ["typescript"] | undefined;
5
+ };
6
+ create(context: RuleContext<readonly ["typescript"]>): void | import("qualety").RuleListener;
7
+ };
8
+ //# sourceMappingURL=no-unnecessary-abstraction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-unnecessary-abstraction.d.ts","sourceRoot":"","sources":["../src/no-unnecessary-abstraction.ts"],"names":[],"mappings":"AACA,OAAO,EAAc,KAAK,WAAW,EAAE,MAAM,SAAS,CAAC;AAuCvD,eAAO,MAAM,wBAAwB;;;;;CAoCnC,CAAC"}
@@ -0,0 +1,452 @@
1
+ import { basename, dirname, join, resolve } from "node:path";
2
+ import { defineRule } from "qualety";
3
+ import { Node, Project, SourceFile, SyntaxKind, } from "ts-morph";
4
+ import { functionLikeName, isFunctionLike } from "./parse-flow.js";
5
+ const FUNCTION_SUGGESTION = "Inline at its only call site, or keep only if the name still hides real complexity; wait for a second real call site before keeping a pass-through.";
6
+ const UNUSED_FN_HINT = "Remove this helper, or wait for a second real call site before keeping the indirection.";
7
+ const TYPE_SUGGESTION = "Inline the type at its only use.";
8
+ const UNUSED_TYPE_HINT = "Remove this type, or wait for a second real use.";
9
+ const MAX_NONBLANK_LINES = 10;
10
+ const INDEX_NAMES = new Set(["index.ts", "index.tsx", "index.mts", "index.cts"]);
11
+ const REACT_PACKAGES = new Set(["react", "react-dom", "preact"]);
12
+ const EXPORT_CONDITION_KEYS = new Set(["import", "require", "default", "types"]);
13
+ export const noUnnecessaryAbstraction = defineRule({
14
+ meta: {
15
+ requires: ["typescript"],
16
+ docs: {
17
+ description: "Do not keep a local abstraction that does not pay for its indirection (single-use helpers and types).",
18
+ },
19
+ },
20
+ create(context) {
21
+ const artifact = context.getArtifact("typescript");
22
+ if (!(artifact.project instanceof Project)) {
23
+ return;
24
+ }
25
+ const fileSystem = artifact.project.getFileSystem();
26
+ const packages = new Map();
27
+ const workspace = readPackageJson(fileSystem, join(context.getCwd(), "package.json"), packages);
28
+ const scannedByPackage = new Map();
29
+ for (const [abs, unit] of artifact.sources) {
30
+ if (!(unit instanceof SourceFile) || isSkippedSource(abs, context.getCwd())) {
31
+ continue;
32
+ }
33
+ const owning = findOwningPackage(fileSystem, dirname(abs), packages);
34
+ const quiet = INDEX_NAMES.has(basename(abs)) || owning?.exportTargets.has(resolve(abs)) === true;
35
+ const react = (owning?.react ?? false) || (workspace?.react ?? false);
36
+ const key = owning?.dir ?? abs;
37
+ const group = scannedByPackage.get(key) ?? [];
38
+ if (group.length === 0) {
39
+ scannedByPackage.set(key, group);
40
+ }
41
+ group.push({ sourceFile: unit, file: abs, quiet, react });
42
+ }
43
+ for (const group of scannedByPackage.values()) {
44
+ scanPackageGroup(group, context);
45
+ }
46
+ },
47
+ });
48
+ function scanPackageGroup(group, context) {
49
+ const callCounts = new Map();
50
+ const typeCounts = new Map();
51
+ countPackageUses(group.map((item) => item.sourceFile), callCounts, typeCounts);
52
+ for (const item of group) {
53
+ item.sourceFile.forEachDescendant((node) => {
54
+ if (isFunctionLike(node)) {
55
+ considerFunction(node, item.file, context, item.quiet, item.react, callCounts);
56
+ }
57
+ if (Node.isTypeAliasDeclaration(node) || Node.isInterfaceDeclaration(node)) {
58
+ considerType(node, item.file, context, item.quiet, typeCounts);
59
+ }
60
+ });
61
+ }
62
+ }
63
+ function isSkippedSource(file, cwd) {
64
+ const normalizedAbs = file.split("\\").join("/");
65
+ const normalizedCwd = cwd.split("\\").join("/");
66
+ const relative = normalizedAbs === normalizedCwd
67
+ ? basename(normalizedAbs)
68
+ : normalizedAbs.startsWith(`${normalizedCwd}/`)
69
+ ? normalizedAbs.slice(normalizedCwd.length + 1)
70
+ : normalizedAbs;
71
+ const base = basename(relative);
72
+ const parts = relative.split("/");
73
+ return (/\.d\.(?:ts|mts|cts)$/.test(base) ||
74
+ /\.(?:test|spec)\./.test(base) ||
75
+ parts.includes("__tests__") ||
76
+ parts.includes("fixtures"));
77
+ }
78
+ function countPackageUses(files, callCounts, typeCounts) {
79
+ for (const sourceFile of files) {
80
+ for (const ident of sourceFile.getDescendantsOfKind(SyntaxKind.Identifier)) {
81
+ tallyCall(ident, callCounts);
82
+ tallyType(ident, typeCounts);
83
+ }
84
+ }
85
+ }
86
+ function tallyCall(ident, counts) {
87
+ if (!isCalleeIdentifier(ident)) {
88
+ return;
89
+ }
90
+ const symbol = unwrapSymbol(ident.getSymbol());
91
+ if (symbol === undefined ||
92
+ symbol.getDeclarations().some((decl) => {
93
+ const fn = functionLikeOf(decl);
94
+ return (fn !== undefined &&
95
+ fn.getSourceFile().getFilePath() === ident.getSourceFile().getFilePath() &&
96
+ fn.containsRange(ident.getStart(), ident.getEnd()));
97
+ })) {
98
+ return;
99
+ }
100
+ const key = symbolKey(symbol);
101
+ if (key !== undefined) {
102
+ counts.set(key, (counts.get(key) ?? 0) + 1);
103
+ }
104
+ }
105
+ function tallyType(ident, counts) {
106
+ if (isImportOrExportName(ident)) {
107
+ return;
108
+ }
109
+ const symbol = unwrapSymbol(ident.getSymbol());
110
+ if (symbol === undefined) {
111
+ return;
112
+ }
113
+ const key = symbolKey(symbol);
114
+ const decl = symbol.getDeclarations()[0];
115
+ if (key === undefined ||
116
+ decl === undefined ||
117
+ !(Node.isTypeAliasDeclaration(decl) || Node.isInterfaceDeclaration(decl))) {
118
+ return;
119
+ }
120
+ if (decl.getNameNode() === ident || decl === ident.getParent()) {
121
+ return;
122
+ }
123
+ counts.set(key, (counts.get(key) ?? 0) + 1);
124
+ }
125
+ function considerFunction(fn, file, context, quiet, react, callCounts) {
126
+ if (quiet || shouldSkipFunction(fn)) {
127
+ return;
128
+ }
129
+ const name = functionLikeName(fn);
130
+ if (name === undefined) {
131
+ return;
132
+ }
133
+ if (skipReactFunction(name, fn, react)) {
134
+ return;
135
+ }
136
+ const symbol = unwrapSymbol(nameNodeOf(fn)?.getSymbol() ?? fn.getSymbol());
137
+ const key = symbol === undefined ? undefined : symbolKey(symbol);
138
+ const uses = key === undefined ? 0 : (callCounts.get(key) ?? 0);
139
+ if (uses > 1 || (!isPassThrough(fn) && !isSmallAndFlat(fn))) {
140
+ return;
141
+ }
142
+ const fnAt = nameNodeOf(fn) ?? fn;
143
+ const fnFile = fnAt.getSourceFile();
144
+ context.report({
145
+ severity: "error",
146
+ file,
147
+ range: {
148
+ start: fnFile.getLineAndColumnAtPos(fnAt.getStart()),
149
+ end: fnFile.getLineAndColumnAtPos(fnAt.getEnd()),
150
+ },
151
+ message: uses === 0
152
+ ? `"${name}" is not called and does not pay for the indirection.`
153
+ : `"${name}" is only called once and does not pay for the indirection.`,
154
+ suggestion: uses === 0 ? UNUSED_FN_HINT : FUNCTION_SUGGESTION,
155
+ });
156
+ }
157
+ function considerType(decl, file, context, quiet, typeCounts) {
158
+ if (quiet || shouldSkipType(decl)) {
159
+ return;
160
+ }
161
+ const symbol = decl.getNameNode().getSymbol() ?? decl.getSymbol();
162
+ if (symbol === undefined || symbol.getDeclarations().length !== 1) {
163
+ return;
164
+ }
165
+ const uses = typeCounts.get(symbolKey(symbol) ?? "") ?? 0;
166
+ if (uses > 1) {
167
+ return;
168
+ }
169
+ const typeAt = decl.getNameNode();
170
+ const typeFile = typeAt.getSourceFile();
171
+ context.report({
172
+ severity: "error",
173
+ file,
174
+ range: {
175
+ start: typeFile.getLineAndColumnAtPos(typeAt.getStart()),
176
+ end: typeFile.getLineAndColumnAtPos(typeAt.getEnd()),
177
+ },
178
+ message: uses === 0
179
+ ? `"${decl.getName()}" is not referenced.`
180
+ : `"${decl.getName()}" is only referenced once.`,
181
+ suggestion: uses === 0 ? UNUSED_TYPE_HINT : TYPE_SUGGESTION,
182
+ });
183
+ }
184
+ function shouldSkipType(decl) {
185
+ if (decl.hasDeclareKeyword()) {
186
+ return true;
187
+ }
188
+ if (Node.isInterfaceDeclaration(decl)) {
189
+ if (decl.getExtends().length > 0) {
190
+ return true;
191
+ }
192
+ }
193
+ if (Node.isTypeAliasDeclaration(decl)) {
194
+ const typeNode = decl.getTypeNode();
195
+ if (typeNode === undefined ||
196
+ Node.isIntersectionTypeNode(typeNode) ||
197
+ typeNode.getDescendantsOfKind(SyntaxKind.UniqueKeyword).length > 0) {
198
+ return true;
199
+ }
200
+ }
201
+ return false;
202
+ }
203
+ function skipReactFunction(name, fn, react) {
204
+ if (!react) {
205
+ return false;
206
+ }
207
+ if (/^use[A-Z]/.test(name)) {
208
+ return true;
209
+ }
210
+ if (/^[A-Z]/.test(name)) {
211
+ if (isComponentShaped(fn)) {
212
+ return true;
213
+ }
214
+ }
215
+ return false;
216
+ }
217
+ function shouldSkipFunction(fn) {
218
+ if (Node.isFunctionDeclaration(fn) && (fn.hasDeclareKeyword() || fn.isOverload())) {
219
+ return true;
220
+ }
221
+ return ((Node.isFunctionDeclaration(fn) ||
222
+ Node.isFunctionExpression(fn) ||
223
+ Node.isMethodDeclaration(fn)) &&
224
+ (fn.isGenerator() || fn.getBody() === undefined));
225
+ }
226
+ function isComponentShaped(fn) {
227
+ const parent = fn.getParent();
228
+ const typeNode = Node.isFunctionDeclaration(fn) || Node.isMethodDeclaration(fn)
229
+ ? fn.getReturnTypeNode()
230
+ : Node.isVariableDeclaration(parent)
231
+ ? parent.getTypeNode()
232
+ : undefined;
233
+ if (typeNode !== undefined && /(?:React\.)?(?:FC|FunctionComponent)\b/.test(typeNode.getText())) {
234
+ return true;
235
+ }
236
+ const body = fn.getBody();
237
+ if (body === undefined) {
238
+ return false;
239
+ }
240
+ return [body, ...body.getDescendants()].some((node) => Node.isJsxElement(node) || Node.isJsxSelfClosingElement(node) || Node.isJsxFragment(node));
241
+ }
242
+ function isPassThrough(fn) {
243
+ const body = fn.getBody();
244
+ if (body === undefined) {
245
+ return false;
246
+ }
247
+ if (!Node.isBlock(body)) {
248
+ return isUnwrappedCall(body);
249
+ }
250
+ const statements = body.getStatements();
251
+ if (statements.length !== 1) {
252
+ return false;
253
+ }
254
+ const statement = statements[0];
255
+ if (Node.isReturnStatement(statement)) {
256
+ const expr = statement.getExpression();
257
+ return expr !== undefined && isUnwrappedCall(expr);
258
+ }
259
+ return Node.isExpressionStatement(statement) && isUnwrappedCall(statement.getExpression());
260
+ }
261
+ function isUnwrappedCall(node) {
262
+ let current = node;
263
+ while (Node.isParenthesizedExpression(current) ||
264
+ Node.isAwaitExpression(current) ||
265
+ Node.isVoidExpression(current)) {
266
+ current = current.getExpression();
267
+ }
268
+ return Node.isCallExpression(current);
269
+ }
270
+ function isSmallAndFlat(fn) {
271
+ const body = fn.getBody();
272
+ if (body === undefined) {
273
+ return false;
274
+ }
275
+ // Non-blank lines of getBody() text (`split(/\n/)`, trim, drop empty). Braces count if they occupy their own line.
276
+ const lines = body
277
+ .getText()
278
+ .split("\n")
279
+ .filter((line) => line.trim() !== "").length;
280
+ if (lines > MAX_NONBLANK_LINES) {
281
+ return false;
282
+ }
283
+ return !body
284
+ .getDescendants()
285
+ .some((node) => isControlFlow(node) && hasControlAncestor(node, body));
286
+ }
287
+ function hasControlAncestor(node, body) {
288
+ let ancestor = node.getParent();
289
+ while (ancestor !== undefined && ancestor !== body) {
290
+ const elseIf = Node.isIfStatement(node) &&
291
+ Node.isIfStatement(ancestor) &&
292
+ ancestor.getElseStatement() === node;
293
+ if (isControlFlow(ancestor) && !elseIf) {
294
+ return true;
295
+ }
296
+ ancestor = ancestor.getParent();
297
+ }
298
+ return false;
299
+ }
300
+ function isControlFlow(node) {
301
+ return (Node.isIfStatement(node) ||
302
+ Node.isForStatement(node) ||
303
+ Node.isForOfStatement(node) ||
304
+ Node.isForInStatement(node) ||
305
+ Node.isWhileStatement(node) ||
306
+ Node.isDoStatement(node) ||
307
+ Node.isTryStatement(node) ||
308
+ Node.isSwitchStatement(node));
309
+ }
310
+ function isCalleeIdentifier(ident) {
311
+ const parent = ident.getParent();
312
+ if (parent === undefined) {
313
+ return false;
314
+ }
315
+ if (Node.isCallExpression(parent) && parent.getExpression() === ident) {
316
+ return true;
317
+ }
318
+ if (!Node.isPropertyAccessExpression(parent) || parent.getNameNode() !== ident) {
319
+ return false;
320
+ }
321
+ const call = parent.getParent();
322
+ return Node.isCallExpression(call) && call.getExpression() === parent;
323
+ }
324
+ function nameNodeOf(fn) {
325
+ if (Node.isFunctionDeclaration(fn) || Node.isMethodDeclaration(fn)) {
326
+ return fn.getNameNode();
327
+ }
328
+ const parent = fn.getParent();
329
+ return Node.isVariableDeclaration(parent) ? parent.getNameNode() : undefined;
330
+ }
331
+ function symbolKey(symbol) {
332
+ const decl = symbol.getDeclarations()[0];
333
+ if (decl === undefined) {
334
+ return undefined;
335
+ }
336
+ return `${decl.getSourceFile().getFilePath()}:${decl.getStart()}`;
337
+ }
338
+ function functionLikeOf(decl) {
339
+ if (isFunctionLike(decl)) {
340
+ return decl;
341
+ }
342
+ if (Node.isVariableDeclaration(decl)) {
343
+ const init = decl.getInitializer();
344
+ if (init !== undefined && isFunctionLike(init)) {
345
+ return init;
346
+ }
347
+ }
348
+ return undefined;
349
+ }
350
+ function unwrapSymbol(symbol) {
351
+ return symbol === undefined ? undefined : (symbol.getAliasedSymbol() ?? symbol);
352
+ }
353
+ function isImportOrExportName(ident) {
354
+ const parent = ident.getParent();
355
+ if (parent === undefined) {
356
+ return false;
357
+ }
358
+ return (Node.isImportSpecifier(parent) ||
359
+ Node.isExportSpecifier(parent) ||
360
+ Node.isImportClause(parent) ||
361
+ Node.isNamespaceImport(parent) ||
362
+ Node.isNamespaceExport(parent));
363
+ }
364
+ function findOwningPackage(fileSystem, startDir, packages) {
365
+ let dir = startDir;
366
+ while (true) {
367
+ const info = readPackageJson(fileSystem, join(dir, "package.json"), packages);
368
+ if (info !== undefined) {
369
+ return info;
370
+ }
371
+ const parent = dirname(dir);
372
+ if (parent === dir) {
373
+ return undefined;
374
+ }
375
+ dir = parent;
376
+ }
377
+ }
378
+ function readPackageJson(fileSystem, path, packages) {
379
+ if (packages.has(path)) {
380
+ return packages.get(path);
381
+ }
382
+ const info = parsePackageFile(fileSystem, path);
383
+ packages.set(path, info);
384
+ return info;
385
+ }
386
+ function parsePackageFile(fileSystem, path) {
387
+ if (!fileSystem.fileExistsSync(path)) {
388
+ return undefined;
389
+ }
390
+ let raw;
391
+ try {
392
+ raw = JSON.parse(fileSystem.readFileSync(path));
393
+ }
394
+ catch {
395
+ return undefined;
396
+ }
397
+ if (!isObject(raw)) {
398
+ return undefined;
399
+ }
400
+ return {
401
+ dir: dirname(path),
402
+ exportTargets: collectExportTargets(dirname(path), raw.exports),
403
+ react: hasReactDependency(raw),
404
+ };
405
+ }
406
+ function hasReactDependency(pkg) {
407
+ for (const key of ["dependencies", "peerDependencies", "devDependencies"]) {
408
+ const block = pkg[key];
409
+ if (isObject(block) && Object.keys(block).some((name) => REACT_PACKAGES.has(name))) {
410
+ return true;
411
+ }
412
+ }
413
+ return false;
414
+ }
415
+ function collectExportTargets(pkgDir, exportsValue) {
416
+ const targets = new Set();
417
+ if (typeof exportsValue === "string") {
418
+ addExportTarget(targets, pkgDir, exportsValue);
419
+ return targets;
420
+ }
421
+ if (!isObject(exportsValue)) {
422
+ return targets;
423
+ }
424
+ for (const value of Object.values(exportsValue)) {
425
+ addExportEntry(targets, pkgDir, value);
426
+ }
427
+ return targets;
428
+ }
429
+ function addExportEntry(targets, pkgDir, value) {
430
+ if (typeof value === "string") {
431
+ addExportTarget(targets, pkgDir, value);
432
+ return;
433
+ }
434
+ if (!isObject(value)) {
435
+ return;
436
+ }
437
+ for (const key of EXPORT_CONDITION_KEYS) {
438
+ const inner = value[key];
439
+ if (typeof inner === "string") {
440
+ addExportTarget(targets, pkgDir, inner);
441
+ }
442
+ }
443
+ }
444
+ function addExportTarget(targets, pkgDir, spec) {
445
+ if (spec.startsWith(".")) {
446
+ targets.add(resolve(pkgDir, spec));
447
+ }
448
+ }
449
+ function isObject(value) {
450
+ return value !== null && typeof value === "object" && !Array.isArray(value);
451
+ }
452
+ //# sourceMappingURL=no-unnecessary-abstraction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-unnecessary-abstraction.js","sourceRoot":"","sources":["../src/no-unnecessary-abstraction.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export declare const noUnsafeAssertion: {
2
+ meta: import("qualety").RuleMeta & {
3
+ requires?: readonly ["typescript"] | undefined;
4
+ };
5
+ create(context: import("qualety").RuleContext<readonly ["typescript"]>): void | import("qualety").RuleListener;
6
+ };
7
+ //# sourceMappingURL=no-unsafe-assertion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-unsafe-assertion.d.ts","sourceRoot":"","sources":["../src/no-unsafe-assertion.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,iBAAiB;;;;;CAiB5B,CAAC"}
@@ -0,0 +1,38 @@
1
+ import { defineRule } from "qualety";
2
+ import { Node, SyntaxKind } from "ts-morph";
3
+ import { unwrapParens } from "./narrowing.js";
4
+ import { reportAt, walkTsSources } from "./ts-source.js";
5
+ const HINT = "Narrow with a type guard, schema parse, or fix the upstream type.";
6
+ export const noUnsafeAssertion = defineRule({
7
+ meta: {
8
+ requires: ["typescript"],
9
+ docs: {
10
+ description: "Do not use as any or as unknown as T assertions that erase type safety.",
11
+ },
12
+ },
13
+ create(context) {
14
+ const sources = context.getArtifact("typescript").sources;
15
+ walkTsSources(sources, (unit, file) => {
16
+ for (const node of unit.getDescendantsOfKind(SyntaxKind.AsExpression)) {
17
+ if (isUnsafeAssertion(node)) {
18
+ reportAt(context, file, node, "Unsafe type assertion erases type safety.", HINT);
19
+ }
20
+ }
21
+ });
22
+ },
23
+ });
24
+ function isUnsafeAssertion(node) {
25
+ if (!Node.isAsExpression(node)) {
26
+ return false;
27
+ }
28
+ const typeNode = node.getTypeNode();
29
+ if (typeNode === undefined) {
30
+ return false;
31
+ }
32
+ if (typeNode.getKind() === SyntaxKind.AnyKeyword) {
33
+ return true;
34
+ }
35
+ const inner = unwrapParens(node.getExpression());
36
+ return Node.isAsExpression(inner) && inner.getTypeNode()?.getKind() === SyntaxKind.UnknownKeyword;
37
+ }
38
+ //# sourceMappingURL=no-unsafe-assertion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-unsafe-assertion.js","sourceRoot":"","sources":["../src/no-unsafe-assertion.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEzD,MAAM,IAAI,GAAG,mEAAmE,CAAC;AAEjF,MAAM,CAAC,MAAM,iBAAiB,GAAG,UAAU,CAAC;IAC1C,IAAI,EAAE;QACJ,QAAQ,EAAE,CAAC,YAAY,CAAC;QACxB,IAAI,EAAE;YACJ,WAAW,EAAE,yEAAyE;SACvF;KACF;IACD,MAAM,CAAC,OAAO;QACZ,MAAM,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC;QAC1D,aAAa,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE;YACpC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,oBAAoB,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;gBACtE,IAAI,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC5B,QAAQ,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,2CAA2C,EAAE,IAAI,CAAC,CAAC;gBACnF,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;CACF,CAAC,CAAC;AAEH,SAAS,iBAAiB,CAAC,IAAU;IACnC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACpC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,QAAQ,CAAC,OAAO,EAAE,KAAK,UAAU,CAAC,UAAU,EAAE,CAAC;QACjD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC;IACjD,OAAO,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,OAAO,EAAE,KAAK,UAAU,CAAC,cAAc,CAAC;AACpG,CAAC"}