sourceverity 1.0.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 (192) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +188 -0
  3. package/bin/sourceverity.js +12 -0
  4. package/dist/analysis/controlFlow.d.ts +10 -0
  5. package/dist/analysis/controlFlow.d.ts.map +1 -0
  6. package/dist/analysis/controlFlow.js +278 -0
  7. package/dist/analysis/controlFlow.js.map +1 -0
  8. package/dist/analysis/frameworks.d.ts +11 -0
  9. package/dist/analysis/frameworks.d.ts.map +1 -0
  10. package/dist/analysis/frameworks.js +189 -0
  11. package/dist/analysis/frameworks.js.map +1 -0
  12. package/dist/analysis/functions.d.ts +27 -0
  13. package/dist/analysis/functions.d.ts.map +1 -0
  14. package/dist/analysis/functions.js +628 -0
  15. package/dist/analysis/functions.js.map +1 -0
  16. package/dist/analysis/promiseFlow.d.ts +44 -0
  17. package/dist/analysis/promiseFlow.d.ts.map +1 -0
  18. package/dist/analysis/promiseFlow.js +261 -0
  19. package/dist/analysis/promiseFlow.js.map +1 -0
  20. package/dist/analysis/values.d.ts +24 -0
  21. package/dist/analysis/values.d.ts.map +1 -0
  22. package/dist/analysis/values.js +189 -0
  23. package/dist/analysis/values.js.map +1 -0
  24. package/dist/baseline/manager.d.ts +20 -0
  25. package/dist/baseline/manager.d.ts.map +1 -0
  26. package/dist/baseline/manager.js +77 -0
  27. package/dist/baseline/manager.js.map +1 -0
  28. package/dist/baseline/types.d.ts +20 -0
  29. package/dist/baseline/types.d.ts.map +1 -0
  30. package/dist/baseline/types.js +2 -0
  31. package/dist/baseline/types.js.map +1 -0
  32. package/dist/cli/args.d.ts +26 -0
  33. package/dist/cli/args.d.ts.map +1 -0
  34. package/dist/cli/args.js +126 -0
  35. package/dist/cli/args.js.map +1 -0
  36. package/dist/cli/exitCodes.d.ts +8 -0
  37. package/dist/cli/exitCodes.d.ts.map +1 -0
  38. package/dist/cli/exitCodes.js +7 -0
  39. package/dist/cli/exitCodes.js.map +1 -0
  40. package/dist/cli/help.d.ts +5 -0
  41. package/dist/cli/help.d.ts.map +1 -0
  42. package/dist/cli/help.js +46 -0
  43. package/dist/cli/help.js.map +1 -0
  44. package/dist/cli/main.d.ts +7 -0
  45. package/dist/cli/main.d.ts.map +1 -0
  46. package/dist/cli/main.js +156 -0
  47. package/dist/cli/main.js.map +1 -0
  48. package/dist/core/fingerprint.d.ts +18 -0
  49. package/dist/core/fingerprint.d.ts.map +1 -0
  50. package/dist/core/fingerprint.js +26 -0
  51. package/dist/core/fingerprint.js.map +1 -0
  52. package/dist/core/paths.d.ts +10 -0
  53. package/dist/core/paths.d.ts.map +1 -0
  54. package/dist/core/paths.js +30 -0
  55. package/dist/core/paths.js.map +1 -0
  56. package/dist/core/suppressions.d.ts +24 -0
  57. package/dist/core/suppressions.d.ts.map +1 -0
  58. package/dist/core/suppressions.js +100 -0
  59. package/dist/core/suppressions.js.map +1 -0
  60. package/dist/core/terminal.d.ts +18 -0
  61. package/dist/core/terminal.d.ts.map +1 -0
  62. package/dist/core/terminal.js +39 -0
  63. package/dist/core/terminal.js.map +1 -0
  64. package/dist/core/types.d.ts +119 -0
  65. package/dist/core/types.d.ts.map +1 -0
  66. package/dist/core/types.js +2 -0
  67. package/dist/core/types.js.map +1 -0
  68. package/dist/engine/context.d.ts +16 -0
  69. package/dist/engine/context.d.ts.map +1 -0
  70. package/dist/engine/context.js +57 -0
  71. package/dist/engine/context.js.map +1 -0
  72. package/dist/engine/registry.d.ts +26 -0
  73. package/dist/engine/registry.d.ts.map +1 -0
  74. package/dist/engine/registry.js +38 -0
  75. package/dist/engine/registry.js.map +1 -0
  76. package/dist/engine/runner.d.ts +14 -0
  77. package/dist/engine/runner.d.ts.map +1 -0
  78. package/dist/engine/runner.js +166 -0
  79. package/dist/engine/runner.js.map +1 -0
  80. package/dist/engine/symbols.d.ts +46 -0
  81. package/dist/engine/symbols.d.ts.map +1 -0
  82. package/dist/engine/symbols.js +278 -0
  83. package/dist/engine/symbols.js.map +1 -0
  84. package/dist/index.d.ts +20 -0
  85. package/dist/index.d.ts.map +1 -0
  86. package/dist/index.js +32 -0
  87. package/dist/index.js.map +1 -0
  88. package/dist/reporters/agent.d.ts +45 -0
  89. package/dist/reporters/agent.d.ts.map +1 -0
  90. package/dist/reporters/agent.js +40 -0
  91. package/dist/reporters/agent.js.map +1 -0
  92. package/dist/reporters/json.d.ts +6 -0
  93. package/dist/reporters/json.d.ts.map +1 -0
  94. package/dist/reporters/json.js +7 -0
  95. package/dist/reporters/json.js.map +1 -0
  96. package/dist/reporters/sarif.d.ts +6 -0
  97. package/dist/reporters/sarif.d.ts.map +1 -0
  98. package/dist/reporters/sarif.js +60 -0
  99. package/dist/reporters/sarif.js.map +1 -0
  100. package/dist/reporters/terminal.d.ts +10 -0
  101. package/dist/reporters/terminal.d.ts.map +1 -0
  102. package/dist/reporters/terminal.js +105 -0
  103. package/dist/reporters/terminal.js.map +1 -0
  104. package/dist/repository/detector.d.ts +6 -0
  105. package/dist/repository/detector.d.ts.map +1 -0
  106. package/dist/repository/detector.js +231 -0
  107. package/dist/repository/detector.js.map +1 -0
  108. package/dist/repository/fileFilter.d.ts +10 -0
  109. package/dist/repository/fileFilter.d.ts.map +1 -0
  110. package/dist/repository/fileFilter.js +78 -0
  111. package/dist/repository/fileFilter.js.map +1 -0
  112. package/dist/repository/git.d.ts +7 -0
  113. package/dist/repository/git.d.ts.map +1 -0
  114. package/dist/repository/git.js +53 -0
  115. package/dist/repository/git.js.map +1 -0
  116. package/dist/repository/tsLoader.d.ts +15 -0
  117. package/dist/repository/tsLoader.d.ts.map +1 -0
  118. package/dist/repository/tsLoader.js +27 -0
  119. package/dist/repository/tsLoader.js.map +1 -0
  120. package/dist/repository/types.d.ts +38 -0
  121. package/dist/repository/types.d.ts.map +1 -0
  122. package/dist/repository/types.js +2 -0
  123. package/dist/repository/types.js.map +1 -0
  124. package/dist/rules/async/asyncForeach.d.ts +3 -0
  125. package/dist/rules/async/asyncForeach.d.ts.map +1 -0
  126. package/dist/rules/async/asyncForeach.js +76 -0
  127. package/dist/rules/async/asyncForeach.js.map +1 -0
  128. package/dist/rules/async/floatingPromise.d.ts +3 -0
  129. package/dist/rules/async/floatingPromise.d.ts.map +1 -0
  130. package/dist/rules/async/floatingPromise.js +359 -0
  131. package/dist/rules/async/floatingPromise.js.map +1 -0
  132. package/dist/rules/browser/eventListenerCleanup.d.ts +3 -0
  133. package/dist/rules/browser/eventListenerCleanup.d.ts.map +1 -0
  134. package/dist/rules/browser/eventListenerCleanup.js +378 -0
  135. package/dist/rules/browser/eventListenerCleanup.js.map +1 -0
  136. package/dist/rules/browser/observerCleanup.d.ts +3 -0
  137. package/dist/rules/browser/observerCleanup.d.ts.map +1 -0
  138. package/dist/rules/browser/observerCleanup.js +184 -0
  139. package/dist/rules/browser/observerCleanup.js.map +1 -0
  140. package/dist/rules/browser/timerCleanup.d.ts +3 -0
  141. package/dist/rules/browser/timerCleanup.d.ts.map +1 -0
  142. package/dist/rules/browser/timerCleanup.js +115 -0
  143. package/dist/rules/browser/timerCleanup.js.map +1 -0
  144. package/dist/rules/index.d.ts +19 -0
  145. package/dist/rules/index.d.ts.map +1 -0
  146. package/dist/rules/index.js +41 -0
  147. package/dist/rules/index.js.map +1 -0
  148. package/dist/rules/network/fetchStatusUnchecked.d.ts +3 -0
  149. package/dist/rules/network/fetchStatusUnchecked.d.ts.map +1 -0
  150. package/dist/rules/network/fetchStatusUnchecked.js +96 -0
  151. package/dist/rules/network/fetchStatusUnchecked.js.map +1 -0
  152. package/dist/rules/react/asyncEffectCallback.d.ts +3 -0
  153. package/dist/rules/react/asyncEffectCallback.d.ts.map +1 -0
  154. package/dist/rules/react/asyncEffectCallback.js +62 -0
  155. package/dist/rules/react/asyncEffectCallback.js.map +1 -0
  156. package/dist/rules/react/derivedStateEffect.d.ts +3 -0
  157. package/dist/rules/react/derivedStateEffect.d.ts.map +1 -0
  158. package/dist/rules/react/derivedStateEffect.js +172 -0
  159. package/dist/rules/react/derivedStateEffect.js.map +1 -0
  160. package/dist/rules/react/missingEffectCleanup.d.ts +3 -0
  161. package/dist/rules/react/missingEffectCleanup.d.ts.map +1 -0
  162. package/dist/rules/react/missingEffectCleanup.js +86 -0
  163. package/dist/rules/react/missingEffectCleanup.js.map +1 -0
  164. package/dist/rules/typescript/nonNullAssertionRisk.d.ts +3 -0
  165. package/dist/rules/typescript/nonNullAssertionRisk.d.ts.map +1 -0
  166. package/dist/rules/typescript/nonNullAssertionRisk.js +65 -0
  167. package/dist/rules/typescript/nonNullAssertionRisk.js.map +1 -0
  168. package/dist/rules/typescript/uncheckedIndexAccess.d.ts +3 -0
  169. package/dist/rules/typescript/uncheckedIndexAccess.d.ts.map +1 -0
  170. package/dist/rules/typescript/uncheckedIndexAccess.js +79 -0
  171. package/dist/rules/typescript/uncheckedIndexAccess.js.map +1 -0
  172. package/dist/rules/typescript/unsafeUnvalidatedAssertion.d.ts +3 -0
  173. package/dist/rules/typescript/unsafeUnvalidatedAssertion.d.ts.map +1 -0
  174. package/dist/rules/typescript/unsafeUnvalidatedAssertion.js +94 -0
  175. package/dist/rules/typescript/unsafeUnvalidatedAssertion.js.map +1 -0
  176. package/dist/strictness/evaluator.d.ts +28 -0
  177. package/dist/strictness/evaluator.d.ts.map +1 -0
  178. package/dist/strictness/evaluator.js +141 -0
  179. package/dist/strictness/evaluator.js.map +1 -0
  180. package/dist/strictness/matrix.d.ts +8 -0
  181. package/dist/strictness/matrix.d.ts.map +1 -0
  182. package/dist/strictness/matrix.js +63 -0
  183. package/dist/strictness/matrix.js.map +1 -0
  184. package/dist/typescript/programManager.d.ts +18 -0
  185. package/dist/typescript/programManager.d.ts.map +1 -0
  186. package/dist/typescript/programManager.js +46 -0
  187. package/dist/typescript/programManager.js.map +1 -0
  188. package/dist/typescript/projectResolver.d.ts +17 -0
  189. package/dist/typescript/projectResolver.d.ts.map +1 -0
  190. package/dist/typescript/projectResolver.js +75 -0
  191. package/dist/typescript/projectResolver.js.map +1 -0
  192. package/package.json +56 -0
@@ -0,0 +1,86 @@
1
+ import { getNodeSourceRange, resolveReactHook } from "../../engine/symbols.js";
2
+ export const missingEffectCleanupRule = {
3
+ meta: {
4
+ id: "react/missing-effect-cleanup",
5
+ category: "react",
6
+ defaultSeverity: "warning",
7
+ defaultConfidence: "high",
8
+ description: "Detects external subscriptions created in useEffect without returned cleanup.",
9
+ requiresTypeInformation: false,
10
+ },
11
+ analyze(context) {
12
+ const { sourceFile, checker, ts } = context;
13
+ if (!ts)
14
+ return;
15
+ context.visitNodes((node) => {
16
+ if (!ts.isCallExpression(node))
17
+ return;
18
+ let isEffectHook = false;
19
+ if (checker && (resolveReactHook(node, checker, "useEffect") || resolveReactHook(node, checker, "useLayoutEffect"))) {
20
+ isEffectHook = true;
21
+ }
22
+ else if (ts.isIdentifier(node.expression) && (node.expression.text === "useEffect" || node.expression.text === "useLayoutEffect")) {
23
+ isEffectHook = true;
24
+ }
25
+ if (!isEffectHook)
26
+ return;
27
+ const args = node.arguments;
28
+ if (!args || args.length === 0)
29
+ return;
30
+ const callback = args[0];
31
+ if (!callback || (!ts.isArrowFunction(callback) && !ts.isFunctionExpression(callback))) {
32
+ return;
33
+ }
34
+ const subscriptions = [];
35
+ let hasCleanupReturn = false;
36
+ function inspectEffectBody(n) {
37
+ // Look for: new WebSocket(...), new EventSource(...), new BroadcastChannel(...)
38
+ if (ts && ts.isNewExpression(n) && ts.isIdentifier(n.expression)) {
39
+ const className = n.expression.text;
40
+ if (className === "WebSocket" || className === "EventSource" || className === "BroadcastChannel") {
41
+ subscriptions.push({ node: n, name: className });
42
+ }
43
+ }
44
+ // Look for: client.subscribe(...)
45
+ if (ts &&
46
+ ts.isCallExpression(n) &&
47
+ ts.isPropertyAccessExpression(n.expression) &&
48
+ n.expression.name.text === "subscribe") {
49
+ subscriptions.push({ node: n, name: ".subscribe()" });
50
+ }
51
+ // Check for return statement
52
+ if (ts && ts.isReturnStatement(n) && n.expression) {
53
+ hasCleanupReturn = true;
54
+ }
55
+ if (ts && n !== callback && (ts.isFunctionDeclaration(n) || ts.isArrowFunction(n) || ts.isFunctionExpression(n))) {
56
+ return;
57
+ }
58
+ n.forEachChild(inspectEffectBody);
59
+ }
60
+ inspectEffectBody(callback.body);
61
+ if (subscriptions.length > 0 && !hasCleanupReturn) {
62
+ for (const sub of subscriptions) {
63
+ const range = getNodeSourceRange(sub.node, sourceFile);
64
+ context.report({
65
+ ruleId: "react/missing-effect-cleanup",
66
+ category: "react",
67
+ severity: "warning",
68
+ confidence: "high",
69
+ message: `Subscription resource '${sub.name}' created in useEffect without returning a cleanup function.`,
70
+ file: sourceFile.fileName,
71
+ range,
72
+ evidence: [
73
+ {
74
+ message: "Unsubscribed listeners or open socket connections persist when the component unmounts.",
75
+ range,
76
+ },
77
+ ],
78
+ suggestedAction: "Return a cleanup function from useEffect that closes or unsubscribes the resource.",
79
+ safeAutomaticFix: false,
80
+ });
81
+ }
82
+ }
83
+ });
84
+ },
85
+ };
86
+ //# sourceMappingURL=missingEffectCleanup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"missingEffectCleanup.js","sourceRoot":"","sources":["../../../src/rules/react/missingEffectCleanup.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Rule } from "../../core/types.js";
2
+ export declare const nonNullAssertionRiskRule: Rule;
3
+ //# sourceMappingURL=nonNullAssertionRisk.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nonNullAssertionRisk.d.ts","sourceRoot":"","sources":["../../../src/rules/typescript/nonNullAssertionRisk.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAe,MAAM,qBAAqB,CAAC;AAe7D,eAAO,MAAM,wBAAwB,EAAE,IAkDtC,CAAC"}
@@ -0,0 +1,65 @@
1
+ import { getNodeSourceRange } from "../../engine/symbols.js";
2
+ import { isGuardedNonNullAssertion } from "../../analysis/controlFlow.js";
3
+ /**
4
+ * Checks if a type contains null or undefined in its flags or union members.
5
+ */
6
+ function isNullableType(type, ts) {
7
+ if (type.flags & (ts.TypeFlags.Null | ts.TypeFlags.Undefined | ts.TypeFlags.Void)) {
8
+ return true;
9
+ }
10
+ if (type.isUnion()) {
11
+ return type.types.some((t) => isNullableType(t, ts));
12
+ }
13
+ return false;
14
+ }
15
+ export const nonNullAssertionRiskRule = {
16
+ meta: {
17
+ id: "typescript/non-null-assertion-risk",
18
+ category: "typescript",
19
+ defaultSeverity: "warning",
20
+ defaultConfidence: "high",
21
+ description: "Detects non-null assertions on types that contain null or undefined.",
22
+ requiresTypeInformation: true,
23
+ },
24
+ analyze(context) {
25
+ const { sourceFile, checker, ts } = context;
26
+ if (!checker || !ts)
27
+ return;
28
+ context.visitNodes((node) => {
29
+ if (!ts.isNonNullExpression(node))
30
+ return;
31
+ // 1. Conservative control-flow & bounds check
32
+ const guardCheck = isGuardedNonNullAssertion(node, ts, checker);
33
+ if (guardCheck.isGuarded) {
34
+ return;
35
+ }
36
+ try {
37
+ const innerType = checker.getTypeAtLocation(node.expression);
38
+ if (isNullableType(innerType, ts)) {
39
+ const range = getNodeSourceRange(node, sourceFile);
40
+ context.report({
41
+ ruleId: "typescript/non-null-assertion-risk",
42
+ category: "typescript",
43
+ severity: "warning",
44
+ confidence: "high",
45
+ message: "Non-null assertion on nullable type risks unhandled runtime TypeError.",
46
+ file: sourceFile.fileName,
47
+ range,
48
+ evidence: [
49
+ {
50
+ message: "The operand type includes null or undefined at this location.",
51
+ range,
52
+ },
53
+ ],
54
+ suggestedAction: "Use optional chaining (?.), nullish coalescing (??), or an explicit presence guard.",
55
+ safeAutomaticFix: false,
56
+ });
57
+ }
58
+ }
59
+ catch {
60
+ // Ignore type resolution failures
61
+ }
62
+ });
63
+ },
64
+ };
65
+ //# sourceMappingURL=nonNullAssertionRisk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nonNullAssertionRisk.js","sourceRoot":"","sources":["../../../src/rules/typescript/nonNullAssertionRisk.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAG1E;;GAEG;AACH,SAAS,cAAc,CAAC,IAAiB,EAAE,EAAiB;IAC1D,IAAI,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,GAAG,EAAE,CAAC,SAAS,CAAC,SAAS,GAAG,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;QAClF,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;QACnB,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,CAAC,MAAM,wBAAwB,GAAS;IAC5C,IAAI,EAAE;QACJ,EAAE,EAAE,oCAAoC;QACxC,QAAQ,EAAE,YAAY;QACtB,eAAe,EAAE,SAAS;QAC1B,iBAAiB,EAAE,MAAM;QACzB,WAAW,EAAE,sEAAsE;QACnF,uBAAuB,EAAE,IAAI;KAC9B;IAED,OAAO,CAAC,OAAoB;QAC1B,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC;QAC5C,IAAI,CAAC,OAAO,IAAI,CAAC,EAAE;YAAE,OAAO;QAE5B,OAAO,CAAC,UAAU,CAAC,CAAC,IAAiB,EAAE,EAAE;YACvC,IAAI,CAAC,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC;gBAAE,OAAO;YAE1C,8CAA8C;YAC9C,MAAM,UAAU,GAAG,yBAAyB,CAAC,IAAI,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;YAChE,IAAI,UAAU,CAAC,SAAS,EAAE,CAAC;gBACzB,OAAO;YACT,CAAC;YAED,IAAI,CAAC;gBACH,MAAM,SAAS,GAAG,OAAO,CAAC,iBAAiB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;gBAC7D,IAAI,cAAc,CAAC,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC;oBAClC,MAAM,KAAK,GAAG,kBAAkB,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;oBACnD,OAAO,CAAC,MAAM,CAAC;wBACb,MAAM,EAAE,oCAAoC;wBAC5C,QAAQ,EAAE,YAAY;wBACtB,QAAQ,EAAE,SAAS;wBACnB,UAAU,EAAE,MAAM;wBAClB,OAAO,EAAE,wEAAwE;wBACjF,IAAI,EAAE,UAAU,CAAC,QAAQ;wBACzB,KAAK;wBACL,QAAQ,EAAE;4BACR;gCACE,OAAO,EAAE,+DAA+D;gCACxE,KAAK;6BACN;yBACF;wBACD,eAAe,EAAE,qFAAqF;wBACtG,gBAAgB,EAAE,KAAK;qBACxB,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,kCAAkC;YACpC,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;CACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Rule } from "../../core/types.js";
2
+ export declare const uncheckedIndexAccessRule: Rule;
3
+ //# sourceMappingURL=uncheckedIndexAccess.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uncheckedIndexAccess.d.ts","sourceRoot":"","sources":["../../../src/rules/typescript/uncheckedIndexAccess.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAe,MAAM,qBAAqB,CAAC;AAE7D,eAAO,MAAM,wBAAwB,EAAE,IAkFtC,CAAC"}
@@ -0,0 +1,79 @@
1
+ import { getNodeSourceRange } from "../../engine/symbols.js";
2
+ export const uncheckedIndexAccessRule = {
3
+ meta: {
4
+ id: "typescript/unchecked-index-access",
5
+ category: "typescript",
6
+ defaultSeverity: "warning",
7
+ defaultConfidence: "medium",
8
+ description: "Detects dynamic index accesses dereferenced without presence checks in loose compiler configurations.",
9
+ requiresTypeInformation: true,
10
+ },
11
+ analyze(context) {
12
+ const { sourceFile, checker, program, ts } = context;
13
+ if (!checker || !program || !ts)
14
+ return;
15
+ const compilerOpts = program.getCompilerOptions();
16
+ // Only active when noUncheckedIndexedAccess is false or omitted
17
+ if (compilerOpts.noUncheckedIndexedAccess) {
18
+ return;
19
+ }
20
+ context.visitNodes((node) => {
21
+ // ElementAccessExpression: obj[key]
22
+ if (!ts.isElementAccessExpression(node))
23
+ return;
24
+ const parent = node.parent;
25
+ if (!parent)
26
+ return;
27
+ // Check if element access is immediately dereferenced
28
+ let isDereferenced = false;
29
+ // Case 1: items[i].prop (PropertyAccessExpression where expression is node)
30
+ if (ts.isPropertyAccessExpression(parent) && parent.expression === node) {
31
+ // Exclude optional chaining: items[i]?.prop
32
+ if (!parent.questionDotToken) {
33
+ isDereferenced = true;
34
+ }
35
+ }
36
+ // Case 2: items[i]() (CallExpression where expression is node)
37
+ if (ts.isCallExpression(parent) && parent.expression === node) {
38
+ if (!parent.questionDotToken) {
39
+ isDereferenced = true;
40
+ }
41
+ }
42
+ if (isDereferenced) {
43
+ try {
44
+ const containerType = checker.getTypeAtLocation(node.expression);
45
+ // Check if container type is an Array, Tuple, or Record
46
+ const isArrayOrRecord = checker.isArrayType(containerType) ||
47
+ checker.isTupleType(containerType) ||
48
+ containerType.getStringIndexType() !== undefined ||
49
+ containerType.getNumberIndexType() !== undefined;
50
+ if (isArrayOrRecord) {
51
+ const range = getNodeSourceRange(node, sourceFile);
52
+ context.report({
53
+ ruleId: "typescript/unchecked-index-access",
54
+ category: "typescript",
55
+ severity: "warning",
56
+ confidence: "medium",
57
+ message: "Index access is dereferenced directly without verifying presence.",
58
+ file: sourceFile.fileName,
59
+ range,
60
+ evidence: [
61
+ {
62
+ message: "The repository configuration does not enable noUncheckedIndexedAccess, so out-of-bounds indexing returns undefined at runtime.",
63
+ range,
64
+ },
65
+ ],
66
+ suggestedAction: "Use optional chaining (items[i]?.property) or guard with a presence check.",
67
+ safeAutomaticFix: false,
68
+ repositoryAccepted: true,
69
+ });
70
+ }
71
+ }
72
+ catch {
73
+ // Ignore resolution failure
74
+ }
75
+ }
76
+ });
77
+ },
78
+ };
79
+ //# sourceMappingURL=uncheckedIndexAccess.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uncheckedIndexAccess.js","sourceRoot":"","sources":["../../../src/rules/typescript/uncheckedIndexAccess.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAG7D,MAAM,CAAC,MAAM,wBAAwB,GAAS;IAC5C,IAAI,EAAE;QACJ,EAAE,EAAE,mCAAmC;QACvC,QAAQ,EAAE,YAAY;QACtB,eAAe,EAAE,SAAS;QAC1B,iBAAiB,EAAE,QAAQ;QAC3B,WAAW,EAAE,uGAAuG;QACpH,uBAAuB,EAAE,IAAI;KAC9B;IAED,OAAO,CAAC,OAAoB;QAC1B,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC;QACrD,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,IAAI,CAAC,EAAE;YAAE,OAAO;QAExC,MAAM,YAAY,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;QAClD,gEAAgE;QAChE,IAAI,YAAY,CAAC,wBAAwB,EAAE,CAAC;YAC1C,OAAO;QACT,CAAC;QAED,OAAO,CAAC,UAAU,CAAC,CAAC,IAAiB,EAAE,EAAE;YACvC,oCAAoC;YACpC,IAAI,CAAC,EAAE,CAAC,yBAAyB,CAAC,IAAI,CAAC;gBAAE,OAAO;YAEhD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;YAC3B,IAAI,CAAC,MAAM;gBAAE,OAAO;YAEpB,sDAAsD;YACtD,IAAI,cAAc,GAAG,KAAK,CAAC;YAE3B,4EAA4E;YAC5E,IAAI,EAAE,CAAC,0BAA0B,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;gBACxE,4CAA4C;gBAC5C,IAAI,CAAC,MAAM,CAAC,gBAAgB,EAAE,CAAC;oBAC7B,cAAc,GAAG,IAAI,CAAC;gBACxB,CAAC;YACH,CAAC;YAED,+DAA+D;YAC/D,IAAI,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;gBAC9D,IAAI,CAAC,MAAM,CAAC,gBAAgB,EAAE,CAAC;oBAC7B,cAAc,GAAG,IAAI,CAAC;gBACxB,CAAC;YACH,CAAC;YAED,IAAI,cAAc,EAAE,CAAC;gBACnB,IAAI,CAAC;oBACH,MAAM,aAAa,GAAG,OAAO,CAAC,iBAAiB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;oBACjE,wDAAwD;oBACxD,MAAM,eAAe,GACnB,OAAO,CAAC,WAAW,CAAC,aAAa,CAAC;wBAClC,OAAO,CAAC,WAAW,CAAC,aAAa,CAAC;wBAClC,aAAa,CAAC,kBAAkB,EAAE,KAAK,SAAS;wBAChD,aAAa,CAAC,kBAAkB,EAAE,KAAK,SAAS,CAAC;oBAEnD,IAAI,eAAe,EAAE,CAAC;wBACpB,MAAM,KAAK,GAAG,kBAAkB,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;wBACnD,OAAO,CAAC,MAAM,CAAC;4BACb,MAAM,EAAE,mCAAmC;4BAC3C,QAAQ,EAAE,YAAY;4BACtB,QAAQ,EAAE,SAAS;4BACnB,UAAU,EAAE,QAAQ;4BACpB,OAAO,EAAE,mEAAmE;4BAC5E,IAAI,EAAE,UAAU,CAAC,QAAQ;4BACzB,KAAK;4BACL,QAAQ,EAAE;gCACR;oCACE,OAAO,EAAE,gIAAgI;oCACzI,KAAK;iCACN;6BACF;4BACD,eAAe,EAAE,4EAA4E;4BAC7F,gBAAgB,EAAE,KAAK;4BACvB,kBAAkB,EAAE,IAAI;yBACzB,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC;oBACP,4BAA4B;gBAC9B,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;CACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Rule } from "../../core/types.js";
2
+ export declare const unsafeUnvalidatedAssertionRule: Rule;
3
+ //# sourceMappingURL=unsafeUnvalidatedAssertion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unsafeUnvalidatedAssertion.d.ts","sourceRoot":"","sources":["../../../src/rules/typescript/unsafeUnvalidatedAssertion.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAe,MAAM,qBAAqB,CAAC;AAU7D,eAAO,MAAM,8BAA8B,EAAE,IA+F5C,CAAC"}
@@ -0,0 +1,94 @@
1
+ import { getNodeSourceRange } from "../../engine/symbols.js";
2
+ function unwrapExpression(expr, ts) {
3
+ let current = expr;
4
+ while (ts.isParenthesizedExpression(current) || ts.isAwaitExpression(current)) {
5
+ current = current.expression;
6
+ }
7
+ return current;
8
+ }
9
+ export const unsafeUnvalidatedAssertionRule = {
10
+ meta: {
11
+ id: "typescript/unsafe-unvalidated-assertion",
12
+ category: "typescript",
13
+ defaultSeverity: "error",
14
+ defaultConfidence: "high",
15
+ description: "Detects runtime boundary data asserted directly to domain types without validation.",
16
+ requiresTypeInformation: false,
17
+ },
18
+ analyze(context) {
19
+ const { sourceFile, ts } = context;
20
+ if (!ts)
21
+ return;
22
+ context.visitNodes((node) => {
23
+ let expr;
24
+ let typeNode;
25
+ if (ts.isAsExpression(node)) {
26
+ expr = node.expression;
27
+ typeNode = node.type;
28
+ }
29
+ else if (ts.isTypeAssertionExpression(node)) {
30
+ expr = node.expression;
31
+ typeNode = node.type;
32
+ }
33
+ if (!expr || !typeNode)
34
+ return;
35
+ // Check if target type is any, unknown, or primitive (safe boundary / widening)
36
+ if (typeNode.kind === ts.SyntaxKind.AnyKeyword ||
37
+ typeNode.kind === ts.SyntaxKind.UnknownKeyword ||
38
+ typeNode.kind === ts.SyntaxKind.StringKeyword ||
39
+ typeNode.kind === ts.SyntaxKind.NumberKeyword ||
40
+ typeNode.kind === ts.SyntaxKind.BooleanKeyword) {
41
+ return;
42
+ }
43
+ // Check if the inner expression is a runtime boundary call
44
+ let isRuntimeBoundary = false;
45
+ let boundaryName = "";
46
+ const targetExpr = unwrapExpression(expr, ts);
47
+ if (ts.isCallExpression(targetExpr)) {
48
+ const callTarget = targetExpr.expression;
49
+ // 1. JSON.parse(...)
50
+ if (ts.isPropertyAccessExpression(callTarget)) {
51
+ if (ts.isIdentifier(callTarget.expression) &&
52
+ callTarget.expression.text === "JSON" &&
53
+ callTarget.name.text === "parse") {
54
+ isRuntimeBoundary = true;
55
+ boundaryName = "JSON.parse()";
56
+ }
57
+ else if (callTarget.name.text === "json") {
58
+ // 2. response.json()
59
+ isRuntimeBoundary = true;
60
+ boundaryName = "response.json()";
61
+ }
62
+ else if (callTarget.name.text === "getItem" &&
63
+ ts.isIdentifier(callTarget.expression) &&
64
+ (callTarget.expression.text === "localStorage" || callTarget.expression.text === "sessionStorage")) {
65
+ // 3. localStorage.getItem(...)
66
+ isRuntimeBoundary = true;
67
+ boundaryName = `${callTarget.expression.text}.getItem()`;
68
+ }
69
+ }
70
+ }
71
+ if (isRuntimeBoundary) {
72
+ const range = getNodeSourceRange(node, sourceFile);
73
+ context.report({
74
+ ruleId: "typescript/unsafe-unvalidated-assertion",
75
+ category: "typescript",
76
+ severity: "error",
77
+ confidence: "high",
78
+ message: `Runtime boundary data from ${boundaryName} is asserted to type without runtime validation.`,
79
+ file: sourceFile.fileName,
80
+ range,
81
+ evidence: [
82
+ {
83
+ message: "Type assertions bypass compiler checking without verifying that runtime structure satisfies the target type.",
84
+ range,
85
+ },
86
+ ],
87
+ suggestedAction: "Validate payload with a runtime schema validator before asserting or casting.",
88
+ safeAutomaticFix: false,
89
+ });
90
+ }
91
+ });
92
+ },
93
+ };
94
+ //# sourceMappingURL=unsafeUnvalidatedAssertion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unsafeUnvalidatedAssertion.js","sourceRoot":"","sources":["../../../src/rules/typescript/unsafeUnvalidatedAssertion.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { RepositoryContext } from "../repository/types.js";
2
+ import type { TypeScriptInstance } from "../repository/tsLoader.js";
3
+ export interface StrictnessFlagStatus {
4
+ readonly name: string;
5
+ readonly enabled: boolean;
6
+ readonly potentialDiagnosticCount: number;
7
+ }
8
+ export interface StrictnessReport {
9
+ readonly currentFlags: readonly StrictnessFlagStatus[];
10
+ readonly topAffectedFiles: ReadonlyArray<{
11
+ readonly file: string;
12
+ readonly diagnostics: number;
13
+ }>;
14
+ readonly totalMigrationImpact: number;
15
+ }
16
+ /**
17
+ * Runs strictness gap analysis using the repository's TypeScript compiler.
18
+ * Compares derived compiler diagnostics against current baseline diagnostics
19
+ * to count only newly introduced migration issues.
20
+ */
21
+ export declare function evaluateStrictnessGap(repo: RepositoryContext, tsInst: TypeScriptInstance): StrictnessReport;
22
+ /**
23
+ * Formats a StrictnessReport for terminal output.
24
+ */
25
+ export declare function renderStrictnessReport(report: StrictnessReport, options?: {
26
+ readonly color?: boolean | undefined;
27
+ } | undefined): string;
28
+ //# sourceMappingURL=evaluator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluator.d.ts","sourceRoot":"","sources":["../../src/strictness/evaluator.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAEpE,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,wBAAwB,EAAE,MAAM,CAAC;CAC3C;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,YAAY,EAAE,SAAS,oBAAoB,EAAE,CAAC;IACvD,QAAQ,CAAC,gBAAgB,EAAE,aAAa,CAAC;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClG,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;CACvC;AAiBD;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,iBAAiB,EACvB,MAAM,EAAE,kBAAkB,GACzB,gBAAgB,CA+FlB;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,gBAAgB,EACxB,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;CAAE,GAAG,SAAS,GAC7D,MAAM,CA0CR"}
@@ -0,0 +1,141 @@
1
+ import { normalizePath } from "../core/paths.js";
2
+ import { createStyler } from "../core/terminal.js";
3
+ import { resolveTsProjects } from "../typescript/projectResolver.js";
4
+ import { STRICTNESS_FLAGS } from "./matrix.js";
5
+ /**
6
+ * Generates a stable semantic identity key for a compiler diagnostic.
7
+ */
8
+ function getDiagnosticSemanticKey(diag, repoRoot) {
9
+ const fileKey = diag.file ? normalizePath(diag.file.fileName, repoRoot) : "<global>";
10
+ const start = diag.start ?? -1;
11
+ const length = diag.length ?? -1;
12
+ const code = diag.code;
13
+ const message = typeof diag.messageText === "string"
14
+ ? diag.messageText
15
+ : diag.messageText?.messageText ?? "";
16
+ return `${fileKey}::${code}::${start}::${length}::${message}`;
17
+ }
18
+ /**
19
+ * Runs strictness gap analysis using the repository's TypeScript compiler.
20
+ * Compares derived compiler diagnostics against current baseline diagnostics
21
+ * to count only newly introduced migration issues.
22
+ */
23
+ export function evaluateStrictnessGap(repo, tsInst) {
24
+ const ts = tsInst.ts;
25
+ const projects = resolveTsProjects(repo, tsInst);
26
+ const flagResults = [];
27
+ const fileDiagnosticCounts = new Map();
28
+ // 1. Gather baseline diagnostics per project under current repository settings
29
+ const projectBaselineKeys = new Map();
30
+ for (const proj of projects) {
31
+ if (proj.fileNames.length === 0)
32
+ continue;
33
+ const baseHost = ts.createCompilerHost(proj.rawCompilerOptions, true);
34
+ const baseProgram = ts.createProgram({
35
+ rootNames: proj.fileNames,
36
+ options: proj.rawCompilerOptions,
37
+ host: baseHost,
38
+ });
39
+ const baseDiagnostics = baseProgram.getSemanticDiagnostics();
40
+ const baseKeys = new Set();
41
+ for (const diag of baseDiagnostics) {
42
+ baseKeys.add(getDiagnosticSemanticKey(diag, repo.rootDir));
43
+ }
44
+ projectBaselineKeys.set(proj.configPath, baseKeys);
45
+ }
46
+ let totalImpact = 0;
47
+ // 2. Evaluate migration impact for each strictness flag individually
48
+ for (const flagDef of STRICTNESS_FLAGS) {
49
+ const key = flagDef.compilerKey;
50
+ let isGloballyEnabled = true;
51
+ let flagDeltaCount = 0;
52
+ for (const proj of projects) {
53
+ if (proj.fileNames.length === 0)
54
+ continue;
55
+ const opts = proj.rawCompilerOptions;
56
+ // In TypeScript, strict: true enables several sub-flags if not explicitly false
57
+ const currentVal = Boolean(opts[key]);
58
+ if (!currentVal) {
59
+ isGloballyEnabled = false;
60
+ // Create derived in-memory compiler options
61
+ const derivedOptions = {
62
+ ...opts,
63
+ [key]: true,
64
+ };
65
+ const host = ts.createCompilerHost(derivedOptions, true);
66
+ const derivedProgram = ts.createProgram({
67
+ rootNames: proj.fileNames,
68
+ options: derivedOptions,
69
+ host,
70
+ });
71
+ const allDiagnostics = derivedProgram.getSemanticDiagnostics();
72
+ const baseKeys = projectBaselineKeys.get(proj.configPath) ?? new Set();
73
+ // Only count diagnostics that are NEWLY introduced by enabling this flag
74
+ const newDiagnostics = allDiagnostics.filter((diag) => !baseKeys.has(getDiagnosticSemanticKey(diag, repo.rootDir)));
75
+ flagDeltaCount += newDiagnostics.length;
76
+ for (const diag of newDiagnostics) {
77
+ if (diag.file) {
78
+ const relFile = normalizePath(diag.file.fileName, repo.rootDir);
79
+ fileDiagnosticCounts.set(relFile, (fileDiagnosticCounts.get(relFile) ?? 0) + 1);
80
+ }
81
+ }
82
+ }
83
+ }
84
+ totalImpact += flagDeltaCount;
85
+ flagResults.push({
86
+ name: flagDef.name,
87
+ enabled: isGloballyEnabled,
88
+ potentialDiagnosticCount: flagDeltaCount,
89
+ });
90
+ }
91
+ // Sort top affected files descending
92
+ const topAffectedFiles = Array.from(fileDiagnosticCounts.entries())
93
+ .map(([file, diagnostics]) => ({ file, diagnostics }))
94
+ .sort((a, b) => b.diagnostics - a.diagnostics)
95
+ .slice(0, 10);
96
+ return {
97
+ currentFlags: flagResults,
98
+ topAffectedFiles,
99
+ totalMigrationImpact: totalImpact,
100
+ };
101
+ }
102
+ /**
103
+ * Formats a StrictnessReport for terminal output.
104
+ */
105
+ export function renderStrictnessReport(report, options) {
106
+ const styler = createStyler(options?.color !== undefined ? { color: options.color } : undefined);
107
+ const lines = [];
108
+ lines.push(styler.bold("TypeScript strictness gap"));
109
+ lines.push("");
110
+ lines.push("Current configuration:");
111
+ lines.push("");
112
+ for (const flag of report.currentFlags) {
113
+ const paddedName = flag.name.padEnd(30, " ");
114
+ const status = flag.enabled ? styler.green("true") : styler.dim("false");
115
+ lines.push(` ${paddedName} ${status}`);
116
+ }
117
+ lines.push("");
118
+ lines.push("Potential migration impact:");
119
+ lines.push("");
120
+ for (const flag of report.currentFlags) {
121
+ if (!flag.enabled) {
122
+ const paddedName = flag.name.padEnd(30, " ");
123
+ const countStr = flag.potentialDiagnosticCount > 0
124
+ ? styler.yellow(`${flag.potentialDiagnosticCount} findings`)
125
+ : "0 findings";
126
+ lines.push(` ${paddedName} ${countStr}`);
127
+ }
128
+ }
129
+ if (report.topAffectedFiles.length > 0) {
130
+ lines.push("");
131
+ lines.push("Most affected files:");
132
+ lines.push("");
133
+ for (const f of report.topAffectedFiles) {
134
+ const paddedFile = f.file.padEnd(32, " ");
135
+ lines.push(` ${paddedFile} ${f.diagnostics}`);
136
+ }
137
+ }
138
+ lines.push("");
139
+ return lines.join("\n");
140
+ }
141
+ //# sourceMappingURL=evaluator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluator.js","sourceRoot":"","sources":["../../src/strictness/evaluator.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAgB/C;;GAEG;AACH,SAAS,wBAAwB,CAAC,IAAuB,EAAE,QAAgB;IACzE,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;IACrF,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC;IAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC;IACjC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;IACvB,MAAM,OAAO,GACX,OAAO,IAAI,CAAC,WAAW,KAAK,QAAQ;QAClC,CAAC,CAAC,IAAI,CAAC,WAAW;QAClB,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,IAAI,EAAE,CAAC;IAC1C,OAAO,GAAG,OAAO,KAAK,IAAI,KAAK,KAAK,KAAK,MAAM,KAAK,OAAO,EAAE,CAAC;AAChE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CACnC,IAAuB,EACvB,MAA0B;IAE1B,MAAM,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC;IACrB,MAAM,QAAQ,GAAG,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACjD,MAAM,WAAW,GAA2B,EAAE,CAAC;IAC/C,MAAM,oBAAoB,GAAG,IAAI,GAAG,EAAkB,CAAC;IAEvD,+EAA+E;IAC/E,MAAM,mBAAmB,GAAG,IAAI,GAAG,EAAuB,CAAC;IAC3D,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC5B,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QAE1C,MAAM,QAAQ,GAAG,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,kBAAkB,EAAE,IAAI,CAAC,CAAC;QACtE,MAAM,WAAW,GAAG,EAAE,CAAC,aAAa,CAAC;YACnC,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,OAAO,EAAE,IAAI,CAAC,kBAAkB;YAChC,IAAI,EAAE,QAAQ;SACf,CAAC,CAAC;QAEH,MAAM,eAAe,GAAG,WAAW,CAAC,sBAAsB,EAAE,CAAC;QAC7D,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;QACnC,KAAK,MAAM,IAAI,IAAI,eAAe,EAAE,CAAC;YACnC,QAAQ,CAAC,GAAG,CAAC,wBAAwB,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QAC7D,CAAC;QACD,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IACrD,CAAC;IAED,IAAI,WAAW,GAAG,CAAC,CAAC;IAEpB,qEAAqE;IACrE,KAAK,MAAM,OAAO,IAAI,gBAAgB,EAAE,CAAC;QACvC,MAAM,GAAG,GAAG,OAAO,CAAC,WAAW,CAAC;QAChC,IAAI,iBAAiB,GAAG,IAAI,CAAC;QAC7B,IAAI,cAAc,GAAG,CAAC,CAAC;QAEvB,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;YAC5B,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC;gBAAE,SAAS;YAE1C,MAAM,IAAI,GAAG,IAAI,CAAC,kBAAkB,CAAC;YACrC,gFAAgF;YAChF,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,GAAmC,CAAC,CAAC,CAAC;YAEtE,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,iBAAiB,GAAG,KAAK,CAAC;gBAE1B,4CAA4C;gBAC5C,MAAM,cAAc,GAA2B;oBAC7C,GAAG,IAAI;oBACP,CAAC,GAAG,CAAC,EAAE,IAAI;iBACZ,CAAC;gBAEF,MAAM,IAAI,GAAG,EAAE,CAAC,kBAAkB,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;gBACzD,MAAM,cAAc,GAAG,EAAE,CAAC,aAAa,CAAC;oBACtC,SAAS,EAAE,IAAI,CAAC,SAAS;oBACzB,OAAO,EAAE,cAAc;oBACvB,IAAI;iBACL,CAAC,CAAC;gBAEH,MAAM,cAAc,GAAG,cAAc,CAAC,sBAAsB,EAAE,CAAC;gBAC/D,MAAM,QAAQ,GAAG,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,IAAI,GAAG,EAAU,CAAC;gBAE/E,yEAAyE;gBACzE,MAAM,cAAc,GAAG,cAAc,CAAC,MAAM,CAC1C,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,wBAAwB,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CACtE,CAAC;gBAEF,cAAc,IAAI,cAAc,CAAC,MAAM,CAAC;gBAExC,KAAK,MAAM,IAAI,IAAI,cAAc,EAAE,CAAC;oBAClC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;wBACd,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;wBAChE,oBAAoB,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,oBAAoB,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;oBAClF,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,WAAW,IAAI,cAAc,CAAC;QAC9B,WAAW,CAAC,IAAI,CAAC;YACf,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,OAAO,EAAE,iBAAiB;YAC1B,wBAAwB,EAAE,cAAc;SACzC,CAAC,CAAC;IACL,CAAC;IAED,qCAAqC;IACrC,MAAM,gBAAgB,GAAG,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,OAAO,EAAE,CAAC;SAChE,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;SACrD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,WAAW,CAAC;SAC7C,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAEhB,OAAO;QACL,YAAY,EAAE,WAAW;QACzB,gBAAgB;QAChB,oBAAoB,EAAE,WAAW;KAClC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,sBAAsB,CACpC,MAAwB,EACxB,OAA8D;IAE9D,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACjG,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC,CAAC;IACrD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;IACrC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;QACvC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;QAC7C,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACzE,KAAK,CAAC,IAAI,CAAC,KAAK,UAAU,IAAI,MAAM,EAAE,CAAC,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;IAC1C,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;QACvC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAClB,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;YAC7C,MAAM,QAAQ,GACZ,IAAI,CAAC,wBAAwB,GAAG,CAAC;gBAC/B,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,wBAAwB,WAAW,CAAC;gBAC5D,CAAC,CAAC,YAAY,CAAC;YACnB,KAAK,CAAC,IAAI,CAAC,KAAK,UAAU,KAAK,QAAQ,EAAE,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;IAED,IAAI,MAAM,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QACnC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,gBAAgB,EAAE,CAAC;YACxC,MAAM,UAAU,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;YAC1C,KAAK,CAAC,IAAI,CAAC,KAAK,UAAU,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,8 @@
1
+ export interface StrictnessFlagDefinition {
2
+ readonly name: string;
3
+ readonly compilerKey: string;
4
+ readonly description: string;
5
+ readonly category: "strict-family" | "null-safety" | "index-safety" | "typing-rigor";
6
+ }
7
+ export declare const STRICTNESS_FLAGS: readonly StrictnessFlagDefinition[];
8
+ //# sourceMappingURL=matrix.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matrix.d.ts","sourceRoot":"","sources":["../../src/strictness/matrix.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,eAAe,GAAG,aAAa,GAAG,cAAc,GAAG,cAAc,CAAC;CACtF;AAED,eAAO,MAAM,gBAAgB,EAAE,SAAS,wBAAwB,EA6DtD,CAAC"}
@@ -0,0 +1,63 @@
1
+ export const STRICTNESS_FLAGS = [
2
+ {
3
+ name: "strict",
4
+ compilerKey: "strict",
5
+ description: "Enables all strict type-checking options family.",
6
+ category: "strict-family",
7
+ },
8
+ {
9
+ name: "strictNullChecks",
10
+ compilerKey: "strictNullChecks",
11
+ description: "Considers null and undefined in type checks.",
12
+ category: "null-safety",
13
+ },
14
+ {
15
+ name: "noImplicitAny",
16
+ compilerKey: "noImplicitAny",
17
+ description: "Raises error on expressions and declarations with an implied any type.",
18
+ category: "typing-rigor",
19
+ },
20
+ {
21
+ name: "strictFunctionTypes",
22
+ compilerKey: "strictFunctionTypes",
23
+ description: "Enforces contravariant parameter checking on function types.",
24
+ category: "typing-rigor",
25
+ },
26
+ {
27
+ name: "strictBindCallApply",
28
+ compilerKey: "strictBindCallApply",
29
+ description: "Enforces strict type checks on bind, call, and apply methods.",
30
+ category: "typing-rigor",
31
+ },
32
+ {
33
+ name: "strictPropertyInitialization",
34
+ compilerKey: "strictPropertyInitialization",
35
+ description: "Ensures non-undefined class properties are initialized in the constructor.",
36
+ category: "null-safety",
37
+ },
38
+ {
39
+ name: "useUnknownInCatchVariables",
40
+ compilerKey: "useUnknownInCatchVariables",
41
+ description: "Types catch clause variables as unknown rather than any.",
42
+ category: "typing-rigor",
43
+ },
44
+ {
45
+ name: "noUncheckedIndexedAccess",
46
+ compilerKey: "noUncheckedIndexedAccess",
47
+ description: "Adds undefined to index signatures and array lookups.",
48
+ category: "index-safety",
49
+ },
50
+ {
51
+ name: "exactOptionalPropertyTypes",
52
+ compilerKey: "exactOptionalPropertyTypes",
53
+ description: "Differentiates optional properties from properties set to undefined.",
54
+ category: "typing-rigor",
55
+ },
56
+ {
57
+ name: "noImplicitOverride",
58
+ compilerKey: "noImplicitOverride",
59
+ description: "Requires override keyword on subclass overridden methods.",
60
+ category: "typing-rigor",
61
+ },
62
+ ];
63
+ //# sourceMappingURL=matrix.js.map