@opensip-cli/checks-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 (404) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +8 -0
  3. package/README.md +31 -0
  4. package/dist/__tests__/all-checks-execute.test.d.ts +12 -0
  5. package/dist/__tests__/all-checks-execute.test.d.ts.map +1 -0
  6. package/dist/__tests__/all-checks-execute.test.js +846 -0
  7. package/dist/__tests__/all-checks-execute.test.js.map +1 -0
  8. package/dist/__tests__/behavior-fixtures-2.test.d.ts +9 -0
  9. package/dist/__tests__/behavior-fixtures-2.test.d.ts.map +1 -0
  10. package/dist/__tests__/behavior-fixtures-2.test.js +625 -0
  11. package/dist/__tests__/behavior-fixtures-2.test.js.map +1 -0
  12. package/dist/__tests__/behavior-fixtures-3.test.d.ts +7 -0
  13. package/dist/__tests__/behavior-fixtures-3.test.d.ts.map +1 -0
  14. package/dist/__tests__/behavior-fixtures-3.test.js +658 -0
  15. package/dist/__tests__/behavior-fixtures-3.test.js.map +1 -0
  16. package/dist/__tests__/behavior-fixtures-4.test.d.ts +8 -0
  17. package/dist/__tests__/behavior-fixtures-4.test.d.ts.map +1 -0
  18. package/dist/__tests__/behavior-fixtures-4.test.js +590 -0
  19. package/dist/__tests__/behavior-fixtures-4.test.js.map +1 -0
  20. package/dist/__tests__/behavior-fixtures-5.test.d.ts +7 -0
  21. package/dist/__tests__/behavior-fixtures-5.test.d.ts.map +1 -0
  22. package/dist/__tests__/behavior-fixtures-5.test.js +548 -0
  23. package/dist/__tests__/behavior-fixtures-5.test.js.map +1 -0
  24. package/dist/__tests__/behavior-fixtures-6.test.d.ts +18 -0
  25. package/dist/__tests__/behavior-fixtures-6.test.d.ts.map +1 -0
  26. package/dist/__tests__/behavior-fixtures-6.test.js +1700 -0
  27. package/dist/__tests__/behavior-fixtures-6.test.js.map +1 -0
  28. package/dist/__tests__/behavior-fixtures.test.d.ts +10 -0
  29. package/dist/__tests__/behavior-fixtures.test.d.ts.map +1 -0
  30. package/dist/__tests__/behavior-fixtures.test.js +812 -0
  31. package/dist/__tests__/behavior-fixtures.test.js.map +1 -0
  32. package/dist/__tests__/branch-fixtures-2.test.d.ts +6 -0
  33. package/dist/__tests__/branch-fixtures-2.test.d.ts.map +1 -0
  34. package/dist/__tests__/branch-fixtures-2.test.js +1369 -0
  35. package/dist/__tests__/branch-fixtures-2.test.js.map +1 -0
  36. package/dist/__tests__/branch-fixtures-3.test.d.ts +7 -0
  37. package/dist/__tests__/branch-fixtures-3.test.d.ts.map +1 -0
  38. package/dist/__tests__/branch-fixtures-3.test.js +877 -0
  39. package/dist/__tests__/branch-fixtures-3.test.js.map +1 -0
  40. package/dist/__tests__/branch-fixtures.test.d.ts +6 -0
  41. package/dist/__tests__/branch-fixtures.test.d.ts.map +1 -0
  42. package/dist/__tests__/branch-fixtures.test.js +1072 -0
  43. package/dist/__tests__/branch-fixtures.test.js.map +1 -0
  44. package/dist/__tests__/checks.test.d.ts +2 -0
  45. package/dist/__tests__/checks.test.d.ts.map +1 -0
  46. package/dist/__tests__/checks.test.js +39 -0
  47. package/dist/__tests__/checks.test.js.map +1 -0
  48. package/dist/__tests__/fixture-coverage.allowlist.d.ts +19 -0
  49. package/dist/__tests__/fixture-coverage.allowlist.d.ts.map +1 -0
  50. package/dist/__tests__/fixture-coverage.allowlist.js +27 -0
  51. package/dist/__tests__/fixture-coverage.allowlist.js.map +1 -0
  52. package/dist/__tests__/fixture-coverage.test.d.ts +13 -0
  53. package/dist/__tests__/fixture-coverage.test.d.ts.map +1 -0
  54. package/dist/__tests__/fixture-coverage.test.js +57 -0
  55. package/dist/__tests__/fixture-coverage.test.js.map +1 -0
  56. package/dist/__tests__/no-bootstrap-tool-import.test.d.ts +2 -0
  57. package/dist/__tests__/no-bootstrap-tool-import.test.d.ts.map +1 -0
  58. package/dist/__tests__/no-bootstrap-tool-import.test.js +75 -0
  59. package/dist/__tests__/no-bootstrap-tool-import.test.js.map +1 -0
  60. package/dist/__tests__/phantom-dependency-detection.test.d.ts +12 -0
  61. package/dist/__tests__/phantom-dependency-detection.test.d.ts.map +1 -0
  62. package/dist/__tests__/phantom-dependency-detection.test.js +112 -0
  63. package/dist/__tests__/phantom-dependency-detection.test.js.map +1 -0
  64. package/dist/__tests__/typescript-frontend.test.d.ts +8 -0
  65. package/dist/__tests__/typescript-frontend.test.d.ts.map +1 -0
  66. package/dist/__tests__/typescript-frontend.test.js +57 -0
  67. package/dist/__tests__/typescript-frontend.test.js.map +1 -0
  68. package/dist/checks/architecture/circular-import-detection.d.ts +14 -0
  69. package/dist/checks/architecture/circular-import-detection.d.ts.map +1 -0
  70. package/dist/checks/architecture/circular-import-detection.js +55 -0
  71. package/dist/checks/architecture/circular-import-detection.js.map +1 -0
  72. package/dist/checks/architecture/contracts-schema-consistency.d.ts +11 -0
  73. package/dist/checks/architecture/contracts-schema-consistency.d.ts.map +1 -0
  74. package/dist/checks/architecture/contracts-schema-consistency.js +75 -0
  75. package/dist/checks/architecture/contracts-schema-consistency.js.map +1 -0
  76. package/dist/checks/architecture/drizzle-orm-migration-guardrails.d.ts +12 -0
  77. package/dist/checks/architecture/drizzle-orm-migration-guardrails.d.ts.map +1 -0
  78. package/dist/checks/architecture/drizzle-orm-migration-guardrails.js +92 -0
  79. package/dist/checks/architecture/drizzle-orm-migration-guardrails.js.map +1 -0
  80. package/dist/checks/architecture/index.d.ts +10 -0
  81. package/dist/checks/architecture/index.d.ts.map +1 -0
  82. package/dist/checks/architecture/index.js +10 -0
  83. package/dist/checks/architecture/index.js.map +1 -0
  84. package/dist/checks/architecture/missing-type-exports.d.ts +13 -0
  85. package/dist/checks/architecture/missing-type-exports.d.ts.map +1 -0
  86. package/dist/checks/architecture/missing-type-exports.js +245 -0
  87. package/dist/checks/architecture/missing-type-exports.js.map +1 -0
  88. package/dist/checks/architecture/module-coupling-fan-out.d.ts +20 -0
  89. package/dist/checks/architecture/module-coupling-fan-out.d.ts.map +1 -0
  90. package/dist/checks/architecture/module-coupling-fan-out.js +120 -0
  91. package/dist/checks/architecture/module-coupling-fan-out.js.map +1 -0
  92. package/dist/checks/architecture/no-bootstrap-tool-import.d.ts +38 -0
  93. package/dist/checks/architecture/no-bootstrap-tool-import.d.ts.map +1 -0
  94. package/dist/checks/architecture/no-bootstrap-tool-import.js +95 -0
  95. package/dist/checks/architecture/no-bootstrap-tool-import.js.map +1 -0
  96. package/dist/checks/architecture/package-json-exports-field.d.ts +10 -0
  97. package/dist/checks/architecture/package-json-exports-field.d.ts.map +1 -0
  98. package/dist/checks/architecture/package-json-exports-field.js +56 -0
  99. package/dist/checks/architecture/package-json-exports-field.js.map +1 -0
  100. package/dist/checks/architecture/phantom-dependency-detection.d.ts +22 -0
  101. package/dist/checks/architecture/phantom-dependency-detection.d.ts.map +1 -0
  102. package/dist/checks/architecture/phantom-dependency-detection.js +330 -0
  103. package/dist/checks/architecture/phantom-dependency-detection.js.map +1 -0
  104. package/dist/checks/architecture/tsconfig-extends-validation.d.ts +10 -0
  105. package/dist/checks/architecture/tsconfig-extends-validation.d.ts.map +1 -0
  106. package/dist/checks/architecture/tsconfig-extends-validation.js +78 -0
  107. package/dist/checks/architecture/tsconfig-extends-validation.js.map +1 -0
  108. package/dist/checks/index.d.ts +6 -0
  109. package/dist/checks/index.d.ts.map +1 -0
  110. package/dist/checks/index.js +6 -0
  111. package/dist/checks/index.js.map +1 -0
  112. package/dist/checks/quality/api/api-contract-validation.d.ts +15 -0
  113. package/dist/checks/quality/api/api-contract-validation.d.ts.map +1 -0
  114. package/dist/checks/quality/api/api-contract-validation.js +316 -0
  115. package/dist/checks/quality/api/api-contract-validation.js.map +1 -0
  116. package/dist/checks/quality/api/api-response-validation.d.ts +14 -0
  117. package/dist/checks/quality/api/api-response-validation.d.ts.map +1 -0
  118. package/dist/checks/quality/api/api-response-validation.js +209 -0
  119. package/dist/checks/quality/api/api-response-validation.js.map +1 -0
  120. package/dist/checks/quality/api/fastify-route-validation.d.ts +14 -0
  121. package/dist/checks/quality/api/fastify-route-validation.d.ts.map +1 -0
  122. package/dist/checks/quality/api/fastify-route-validation.js +298 -0
  123. package/dist/checks/quality/api/fastify-route-validation.js.map +1 -0
  124. package/dist/checks/quality/api/fastify-schema-coverage.d.ts +11 -0
  125. package/dist/checks/quality/api/fastify-schema-coverage.d.ts.map +1 -0
  126. package/dist/checks/quality/api/fastify-schema-coverage.js +261 -0
  127. package/dist/checks/quality/api/fastify-schema-coverage.js.map +1 -0
  128. package/dist/checks/quality/api/index.d.ts +5 -0
  129. package/dist/checks/quality/api/index.d.ts.map +1 -0
  130. package/dist/checks/quality/api/index.js +5 -0
  131. package/dist/checks/quality/api/index.js.map +1 -0
  132. package/dist/checks/quality/code-structure/duplicate-utility-functions.d.ts +32 -0
  133. package/dist/checks/quality/code-structure/duplicate-utility-functions.d.ts.map +1 -0
  134. package/dist/checks/quality/code-structure/duplicate-utility-functions.js +451 -0
  135. package/dist/checks/quality/code-structure/duplicate-utility-functions.js.map +1 -0
  136. package/dist/checks/quality/code-structure/index.d.ts +3 -0
  137. package/dist/checks/quality/code-structure/index.d.ts.map +1 -0
  138. package/dist/checks/quality/code-structure/index.js +3 -0
  139. package/dist/checks/quality/code-structure/index.js.map +1 -0
  140. package/dist/checks/quality/code-structure/no-any-types.d.ts +13 -0
  141. package/dist/checks/quality/code-structure/no-any-types.d.ts.map +1 -0
  142. package/dist/checks/quality/code-structure/no-any-types.js +116 -0
  143. package/dist/checks/quality/code-structure/no-any-types.js.map +1 -0
  144. package/dist/checks/quality/data-integrity/__tests__/null-safety-fp.test.d.ts +15 -0
  145. package/dist/checks/quality/data-integrity/__tests__/null-safety-fp.test.d.ts.map +1 -0
  146. package/dist/checks/quality/data-integrity/__tests__/null-safety-fp.test.js +51 -0
  147. package/dist/checks/quality/data-integrity/__tests__/null-safety-fp.test.js.map +1 -0
  148. package/dist/checks/quality/data-integrity/array-validation.d.ts +16 -0
  149. package/dist/checks/quality/data-integrity/array-validation.d.ts.map +1 -0
  150. package/dist/checks/quality/data-integrity/array-validation.js +508 -0
  151. package/dist/checks/quality/data-integrity/array-validation.js.map +1 -0
  152. package/dist/checks/quality/data-integrity/database-index-coverage.d.ts +14 -0
  153. package/dist/checks/quality/data-integrity/database-index-coverage.d.ts.map +1 -0
  154. package/dist/checks/quality/data-integrity/database-index-coverage.js +235 -0
  155. package/dist/checks/quality/data-integrity/database-index-coverage.js.map +1 -0
  156. package/dist/checks/quality/data-integrity/database-schema-validation.d.ts +16 -0
  157. package/dist/checks/quality/data-integrity/database-schema-validation.d.ts.map +1 -0
  158. package/dist/checks/quality/data-integrity/database-schema-validation.js +328 -0
  159. package/dist/checks/quality/data-integrity/database-schema-validation.js.map +1 -0
  160. package/dist/checks/quality/data-integrity/in-memory-repository-detection.d.ts +14 -0
  161. package/dist/checks/quality/data-integrity/in-memory-repository-detection.d.ts.map +1 -0
  162. package/dist/checks/quality/data-integrity/in-memory-repository-detection.js +157 -0
  163. package/dist/checks/quality/data-integrity/in-memory-repository-detection.js.map +1 -0
  164. package/dist/checks/quality/data-integrity/index.d.ts +8 -0
  165. package/dist/checks/quality/data-integrity/index.d.ts.map +1 -0
  166. package/dist/checks/quality/data-integrity/index.js +8 -0
  167. package/dist/checks/quality/data-integrity/index.js.map +1 -0
  168. package/dist/checks/quality/data-integrity/missing-input-validation.d.ts +12 -0
  169. package/dist/checks/quality/data-integrity/missing-input-validation.d.ts.map +1 -0
  170. package/dist/checks/quality/data-integrity/missing-input-validation.js +180 -0
  171. package/dist/checks/quality/data-integrity/missing-input-validation.js.map +1 -0
  172. package/dist/checks/quality/data-integrity/null-safety.d.ts +33 -0
  173. package/dist/checks/quality/data-integrity/null-safety.d.ts.map +1 -0
  174. package/dist/checks/quality/data-integrity/null-safety.js +766 -0
  175. package/dist/checks/quality/data-integrity/null-safety.js.map +1 -0
  176. package/dist/checks/quality/data-integrity/numeric-validation.d.ts +12 -0
  177. package/dist/checks/quality/data-integrity/numeric-validation.d.ts.map +1 -0
  178. package/dist/checks/quality/data-integrity/numeric-validation.js +409 -0
  179. package/dist/checks/quality/data-integrity/numeric-validation.js.map +1 -0
  180. package/dist/checks/quality/frontend/a11y-form-labels.d.ts +14 -0
  181. package/dist/checks/quality/frontend/a11y-form-labels.d.ts.map +1 -0
  182. package/dist/checks/quality/frontend/a11y-form-labels.js +93 -0
  183. package/dist/checks/quality/frontend/a11y-form-labels.js.map +1 -0
  184. package/dist/checks/quality/frontend/a11y-semantic-html.d.ts +14 -0
  185. package/dist/checks/quality/frontend/a11y-semantic-html.d.ts.map +1 -0
  186. package/dist/checks/quality/frontend/a11y-semantic-html.js +88 -0
  187. package/dist/checks/quality/frontend/a11y-semantic-html.js.map +1 -0
  188. package/dist/checks/quality/frontend/index.d.ts +4 -0
  189. package/dist/checks/quality/frontend/index.d.ts.map +1 -0
  190. package/dist/checks/quality/frontend/index.js +4 -0
  191. package/dist/checks/quality/frontend/index.js.map +1 -0
  192. package/dist/checks/quality/frontend/test-only-frontend-modules.d.ts +13 -0
  193. package/dist/checks/quality/frontend/test-only-frontend-modules.d.ts.map +1 -0
  194. package/dist/checks/quality/frontend/test-only-frontend-modules.js +159 -0
  195. package/dist/checks/quality/frontend/test-only-frontend-modules.js.map +1 -0
  196. package/dist/checks/quality/incomplete-regex-escaping.d.ts +13 -0
  197. package/dist/checks/quality/incomplete-regex-escaping.d.ts.map +1 -0
  198. package/dist/checks/quality/incomplete-regex-escaping.js +207 -0
  199. package/dist/checks/quality/incomplete-regex-escaping.js.map +1 -0
  200. package/dist/checks/quality/index.d.ts +11 -0
  201. package/dist/checks/quality/index.d.ts.map +1 -0
  202. package/dist/checks/quality/index.js +11 -0
  203. package/dist/checks/quality/index.js.map +1 -0
  204. package/dist/checks/quality/linting/index.d.ts +2 -0
  205. package/dist/checks/quality/linting/index.d.ts.map +1 -0
  206. package/dist/checks/quality/linting/index.js +2 -0
  207. package/dist/checks/quality/linting/index.js.map +1 -0
  208. package/dist/checks/quality/linting/typescript-frontend.d.ts +25 -0
  209. package/dist/checks/quality/linting/typescript-frontend.d.ts.map +1 -0
  210. package/dist/checks/quality/linting/typescript-frontend.js +159 -0
  211. package/dist/checks/quality/linting/typescript-frontend.js.map +1 -0
  212. package/dist/checks/quality/observability/index.d.ts +5 -0
  213. package/dist/checks/quality/observability/index.d.ts.map +1 -0
  214. package/dist/checks/quality/observability/index.js +5 -0
  215. package/dist/checks/quality/observability/index.js.map +1 -0
  216. package/dist/checks/quality/observability/logger-event-name-format.d.ts +12 -0
  217. package/dist/checks/quality/observability/logger-event-name-format.d.ts.map +1 -0
  218. package/dist/checks/quality/observability/logger-event-name-format.js +124 -0
  219. package/dist/checks/quality/observability/logger-event-name-format.js.map +1 -0
  220. package/dist/checks/quality/observability/no-hardcoded-correlation-id.d.ts +5 -0
  221. package/dist/checks/quality/observability/no-hardcoded-correlation-id.d.ts.map +1 -0
  222. package/dist/checks/quality/observability/no-hardcoded-correlation-id.js +77 -0
  223. package/dist/checks/quality/observability/no-hardcoded-correlation-id.js.map +1 -0
  224. package/dist/checks/quality/observability/observability-coverage/__tests__/analyzer.test.d.ts +11 -0
  225. package/dist/checks/quality/observability/observability-coverage/__tests__/analyzer.test.d.ts.map +1 -0
  226. package/dist/checks/quality/observability/observability-coverage/__tests__/analyzer.test.js +107 -0
  227. package/dist/checks/quality/observability/observability-coverage/__tests__/analyzer.test.js.map +1 -0
  228. package/dist/checks/quality/observability/observability-coverage/__tests__/logger-detector.test.d.ts +12 -0
  229. package/dist/checks/quality/observability/observability-coverage/__tests__/logger-detector.test.d.ts.map +1 -0
  230. package/dist/checks/quality/observability/observability-coverage/__tests__/logger-detector.test.js +94 -0
  231. package/dist/checks/quality/observability/observability-coverage/__tests__/logger-detector.test.js.map +1 -0
  232. package/dist/checks/quality/observability/observability-coverage/analyzer.d.ts +13 -0
  233. package/dist/checks/quality/observability/observability-coverage/analyzer.d.ts.map +1 -0
  234. package/dist/checks/quality/observability/observability-coverage/analyzer.js +117 -0
  235. package/dist/checks/quality/observability/observability-coverage/analyzer.js.map +1 -0
  236. package/dist/checks/quality/observability/observability-coverage/index.d.ts +4 -0
  237. package/dist/checks/quality/observability/observability-coverage/index.d.ts.map +1 -0
  238. package/dist/checks/quality/observability/observability-coverage/index.js +4 -0
  239. package/dist/checks/quality/observability/observability-coverage/index.js.map +1 -0
  240. package/dist/checks/quality/observability/observability-coverage/logger-detector.d.ts +29 -0
  241. package/dist/checks/quality/observability/observability-coverage/logger-detector.d.ts.map +1 -0
  242. package/dist/checks/quality/observability/observability-coverage/logger-detector.js +111 -0
  243. package/dist/checks/quality/observability/observability-coverage/logger-detector.js.map +1 -0
  244. package/dist/checks/quality/observability/observability-coverage/types.d.ts +64 -0
  245. package/dist/checks/quality/observability/observability-coverage/types.d.ts.map +1 -0
  246. package/dist/checks/quality/observability/observability-coverage/types.js +6 -0
  247. package/dist/checks/quality/observability/observability-coverage/types.js.map +1 -0
  248. package/dist/checks/quality/observability/pii-exposure-in-logs.d.ts +22 -0
  249. package/dist/checks/quality/observability/pii-exposure-in-logs.d.ts.map +1 -0
  250. package/dist/checks/quality/observability/pii-exposure-in-logs.js +212 -0
  251. package/dist/checks/quality/observability/pii-exposure-in-logs.js.map +1 -0
  252. package/dist/checks/quality/observability/pii-exposure-in-logs.test.d.ts +11 -0
  253. package/dist/checks/quality/observability/pii-exposure-in-logs.test.d.ts.map +1 -0
  254. package/dist/checks/quality/observability/pii-exposure-in-logs.test.js +46 -0
  255. package/dist/checks/quality/observability/pii-exposure-in-logs.test.js.map +1 -0
  256. package/dist/checks/quality/patterns/__tests__/toctou-fp.test.d.ts +14 -0
  257. package/dist/checks/quality/patterns/__tests__/toctou-fp.test.d.ts.map +1 -0
  258. package/dist/checks/quality/patterns/__tests__/toctou-fp.test.js +61 -0
  259. package/dist/checks/quality/patterns/__tests__/toctou-fp.test.js.map +1 -0
  260. package/dist/checks/quality/patterns/async-waterfall-detection.d.ts +26 -0
  261. package/dist/checks/quality/patterns/async-waterfall-detection.d.ts.map +1 -0
  262. package/dist/checks/quality/patterns/async-waterfall-detection.js +410 -0
  263. package/dist/checks/quality/patterns/async-waterfall-detection.js.map +1 -0
  264. package/dist/checks/quality/patterns/dispose-pattern-completeness.d.ts +13 -0
  265. package/dist/checks/quality/patterns/dispose-pattern-completeness.d.ts.map +1 -0
  266. package/dist/checks/quality/patterns/dispose-pattern-completeness.js +220 -0
  267. package/dist/checks/quality/patterns/dispose-pattern-completeness.js.map +1 -0
  268. package/dist/checks/quality/patterns/error-handling-quality.d.ts +17 -0
  269. package/dist/checks/quality/patterns/error-handling-quality.d.ts.map +1 -0
  270. package/dist/checks/quality/patterns/error-handling-quality.js +335 -0
  271. package/dist/checks/quality/patterns/error-handling-quality.js.map +1 -0
  272. package/dist/checks/quality/patterns/index.d.ts +10 -0
  273. package/dist/checks/quality/patterns/index.d.ts.map +1 -0
  274. package/dist/checks/quality/patterns/index.js +10 -0
  275. package/dist/checks/quality/patterns/index.js.map +1 -0
  276. package/dist/checks/quality/patterns/lifecycle-cleanup-enforcement.d.ts +16 -0
  277. package/dist/checks/quality/patterns/lifecycle-cleanup-enforcement.d.ts.map +1 -0
  278. package/dist/checks/quality/patterns/lifecycle-cleanup-enforcement.js +205 -0
  279. package/dist/checks/quality/patterns/lifecycle-cleanup-enforcement.js.map +1 -0
  280. package/dist/checks/quality/patterns/result-pattern-consistency.d.ts +16 -0
  281. package/dist/checks/quality/patterns/result-pattern-consistency.d.ts.map +1 -0
  282. package/dist/checks/quality/patterns/result-pattern-consistency.js +328 -0
  283. package/dist/checks/quality/patterns/result-pattern-consistency.js.map +1 -0
  284. package/dist/checks/quality/patterns/silent-early-returns.d.ts +23 -0
  285. package/dist/checks/quality/patterns/silent-early-returns.d.ts.map +1 -0
  286. package/dist/checks/quality/patterns/silent-early-returns.js +266 -0
  287. package/dist/checks/quality/patterns/silent-early-returns.js.map +1 -0
  288. package/dist/checks/quality/patterns/stream-buffer-size-limits.d.ts +13 -0
  289. package/dist/checks/quality/patterns/stream-buffer-size-limits.d.ts.map +1 -0
  290. package/dist/checks/quality/patterns/stream-buffer-size-limits.js +163 -0
  291. package/dist/checks/quality/patterns/stream-buffer-size-limits.js.map +1 -0
  292. package/dist/checks/quality/patterns/throws-documentation.d.ts +23 -0
  293. package/dist/checks/quality/patterns/throws-documentation.d.ts.map +1 -0
  294. package/dist/checks/quality/patterns/throws-documentation.js +519 -0
  295. package/dist/checks/quality/patterns/throws-documentation.js.map +1 -0
  296. package/dist/checks/quality/patterns/toctou-race-condition.d.ts +48 -0
  297. package/dist/checks/quality/patterns/toctou-race-condition.d.ts.map +1 -0
  298. package/dist/checks/quality/patterns/toctou-race-condition.js +639 -0
  299. package/dist/checks/quality/patterns/toctou-race-condition.js.map +1 -0
  300. package/dist/checks/quality/stubbed-implementation-detection.d.ts +24 -0
  301. package/dist/checks/quality/stubbed-implementation-detection.d.ts.map +1 -0
  302. package/dist/checks/quality/stubbed-implementation-detection.js +355 -0
  303. package/dist/checks/quality/stubbed-implementation-detection.js.map +1 -0
  304. package/dist/checks/quality/unused-config-options.d.ts +12 -0
  305. package/dist/checks/quality/unused-config-options.d.ts.map +1 -0
  306. package/dist/checks/quality/unused-config-options.js +245 -0
  307. package/dist/checks/quality/unused-config-options.js.map +1 -0
  308. package/dist/checks/resilience/__tests__/callback-invocation-safe.test.d.ts +2 -0
  309. package/dist/checks/resilience/__tests__/callback-invocation-safe.test.d.ts.map +1 -0
  310. package/dist/checks/resilience/__tests__/callback-invocation-safe.test.js +79 -0
  311. package/dist/checks/resilience/__tests__/callback-invocation-safe.test.js.map +1 -0
  312. package/dist/checks/resilience/__tests__/context-leakage-fp.test.d.ts +12 -0
  313. package/dist/checks/resilience/__tests__/context-leakage-fp.test.d.ts.map +1 -0
  314. package/dist/checks/resilience/__tests__/context-leakage-fp.test.js +34 -0
  315. package/dist/checks/resilience/__tests__/context-leakage-fp.test.js.map +1 -0
  316. package/dist/checks/resilience/__tests__/context-mutation.test.d.ts +11 -0
  317. package/dist/checks/resilience/__tests__/context-mutation.test.d.ts.map +1 -0
  318. package/dist/checks/resilience/__tests__/context-mutation.test.js +54 -0
  319. package/dist/checks/resilience/__tests__/context-mutation.test.js.map +1 -0
  320. package/dist/checks/resilience/callback-invocation-safe.d.ts +34 -0
  321. package/dist/checks/resilience/callback-invocation-safe.d.ts.map +1 -0
  322. package/dist/checks/resilience/callback-invocation-safe.js +247 -0
  323. package/dist/checks/resilience/callback-invocation-safe.js.map +1 -0
  324. package/dist/checks/resilience/context-leakage.d.ts +25 -0
  325. package/dist/checks/resilience/context-leakage.d.ts.map +1 -0
  326. package/dist/checks/resilience/context-leakage.js +435 -0
  327. package/dist/checks/resilience/context-leakage.js.map +1 -0
  328. package/dist/checks/resilience/context-mutation.d.ts +21 -0
  329. package/dist/checks/resilience/context-mutation.d.ts.map +1 -0
  330. package/dist/checks/resilience/context-mutation.js +368 -0
  331. package/dist/checks/resilience/context-mutation.js.map +1 -0
  332. package/dist/checks/resilience/detached-promises.d.ts +40 -0
  333. package/dist/checks/resilience/detached-promises.d.ts.map +1 -0
  334. package/dist/checks/resilience/detached-promises.js +646 -0
  335. package/dist/checks/resilience/detached-promises.js.map +1 -0
  336. package/dist/checks/resilience/index.d.ts +7 -0
  337. package/dist/checks/resilience/index.d.ts.map +1 -0
  338. package/dist/checks/resilience/index.js +7 -0
  339. package/dist/checks/resilience/index.js.map +1 -0
  340. package/dist/checks/resilience/no-raw-fetch.d.ts +11 -0
  341. package/dist/checks/resilience/no-raw-fetch.d.ts.map +1 -0
  342. package/dist/checks/resilience/no-raw-fetch.js +110 -0
  343. package/dist/checks/resilience/no-raw-fetch.js.map +1 -0
  344. package/dist/checks/resilience/no-unbounded-concurrency.d.ts +11 -0
  345. package/dist/checks/resilience/no-unbounded-concurrency.d.ts.map +1 -0
  346. package/dist/checks/resilience/no-unbounded-concurrency.js +117 -0
  347. package/dist/checks/resilience/no-unbounded-concurrency.js.map +1 -0
  348. package/dist/checks/security/__tests__/sql-injection.test.d.ts +17 -0
  349. package/dist/checks/security/__tests__/sql-injection.test.d.ts.map +1 -0
  350. package/dist/checks/security/__tests__/sql-injection.test.js +97 -0
  351. package/dist/checks/security/__tests__/sql-injection.test.js.map +1 -0
  352. package/dist/checks/security/index.d.ts +4 -0
  353. package/dist/checks/security/index.d.ts.map +1 -0
  354. package/dist/checks/security/index.js +4 -0
  355. package/dist/checks/security/index.js.map +1 -0
  356. package/dist/checks/security/input-sanitization.d.ts +20 -0
  357. package/dist/checks/security/input-sanitization.d.ts.map +1 -0
  358. package/dist/checks/security/input-sanitization.js +255 -0
  359. package/dist/checks/security/input-sanitization.js.map +1 -0
  360. package/dist/checks/security/sql-injection.d.ts +24 -0
  361. package/dist/checks/security/sql-injection.d.ts.map +1 -0
  362. package/dist/checks/security/sql-injection.js +330 -0
  363. package/dist/checks/security/sql-injection.js.map +1 -0
  364. package/dist/checks/security/unsafe-secret-comparison.d.ts +17 -0
  365. package/dist/checks/security/unsafe-secret-comparison.d.ts.map +1 -0
  366. package/dist/checks/security/unsafe-secret-comparison.js +227 -0
  367. package/dist/checks/security/unsafe-secret-comparison.js.map +1 -0
  368. package/dist/checks/testing/index.d.ts +2 -0
  369. package/dist/checks/testing/index.d.ts.map +1 -0
  370. package/dist/checks/testing/index.js +2 -0
  371. package/dist/checks/testing/index.js.map +1 -0
  372. package/dist/checks/testing/mock-implementations-in-production.d.ts +12 -0
  373. package/dist/checks/testing/mock-implementations-in-production.d.ts.map +1 -0
  374. package/dist/checks/testing/mock-implementations-in-production.js +211 -0
  375. package/dist/checks/testing/mock-implementations-in-production.js.map +1 -0
  376. package/dist/display/architecture.d.ts +9 -0
  377. package/dist/display/architecture.d.ts.map +1 -0
  378. package/dist/display/architecture.js +18 -0
  379. package/dist/display/architecture.js.map +1 -0
  380. package/dist/display/index.d.ts +20 -0
  381. package/dist/display/index.d.ts.map +1 -0
  382. package/dist/display/index.js +30 -0
  383. package/dist/display/index.js.map +1 -0
  384. package/dist/display/quality.d.ts +7 -0
  385. package/dist/display/quality.d.ts.map +1 -0
  386. package/dist/display/quality.js +39 -0
  387. package/dist/display/quality.js.map +1 -0
  388. package/dist/display/resilience.d.ts +7 -0
  389. package/dist/display/resilience.d.ts.map +1 -0
  390. package/dist/display/resilience.js +13 -0
  391. package/dist/display/resilience.js.map +1 -0
  392. package/dist/display/security-testing.d.ts +9 -0
  393. package/dist/display/security-testing.d.ts.map +1 -0
  394. package/dist/display/security-testing.js +14 -0
  395. package/dist/display/security-testing.js.map +1 -0
  396. package/dist/display/types.d.ts +6 -0
  397. package/dist/display/types.d.ts.map +1 -0
  398. package/dist/display/types.js +6 -0
  399. package/dist/display/types.js.map +1 -0
  400. package/dist/index.d.ts +19 -0
  401. package/dist/index.d.ts.map +1 -0
  402. package/dist/index.js +21 -0
  403. package/dist/index.js.map +1 -0
  404. package/package.json +55 -0
@@ -0,0 +1,435 @@
1
+ /**
2
+ * @fileoverview Context leakage detection — flags request-scoped state stored
3
+ * in module or class scope that can leak between concurrent requests.
4
+ */
5
+ import { logger } from '@opensip-cli/core';
6
+ import { defineCheck, isTestFile } from '@opensip-cli/fitness';
7
+ import { getSharedSourceFile } from '@opensip-cli/lang-typescript';
8
+ import * as ts from 'typescript';
9
+ // =============================================================================
10
+ // REQUEST CONTEXT LEAKAGE (AST-based)
11
+ // =============================================================================
12
+ /**
13
+ * Names that look like a request-scoped context variable.
14
+ * Matches whole-word boundaries (case-insensitive): "ctx", "context", "request"
15
+ * but excludes generic suffixes that aren't request state (e.g. `parserContext`
16
+ * is still flagged, but that is fine — it's evaluated together with the type).
17
+ */
18
+ function variableNameLooksContextual(name) {
19
+ const lower = name.toLowerCase();
20
+ // Whole-word: ends with "context"/"ctx" or starts with "request"/"req"
21
+ return (lower.endsWith('context') ||
22
+ lower.endsWith('ctx') ||
23
+ lower === 'request' ||
24
+ lower === 'req' ||
25
+ lower.startsWith('request') ||
26
+ (lower.startsWith('req') && lower.length <= 12));
27
+ }
28
+ /**
29
+ * Type-name suffixes that indicate a request-scoped context type.
30
+ * Matches identifier types whose name ends with "Context" or "Ctx".
31
+ * Excludes well-known process-scoped wrappers (`Injector<…>`, `SyncStrategy<…>`,
32
+ * `Promise<…>`) — those are detected by inspecting the OUTER type identifier
33
+ * and refusing to recurse into its generic arguments.
34
+ */
35
+ function isContextTypeName(name) {
36
+ return /(?:Context|Ctx)$/.test(name);
37
+ }
38
+ /**
39
+ * Type identifiers that, regardless of generic arguments, are NOT request
40
+ * state. If the outer type is one of these, we ignore generic args entirely.
41
+ */
42
+ const PROCESS_SCOPED_WRAPPER_TYPES = new Set([
43
+ 'Injector',
44
+ 'SyncStrategy',
45
+ 'Promise',
46
+ 'PromiseLike',
47
+ 'Awaited',
48
+ 'Array',
49
+ 'ReadonlyArray',
50
+ 'Map',
51
+ 'ReadonlyMap',
52
+ 'Set',
53
+ 'ReadonlySet',
54
+ 'Record',
55
+ 'Partial',
56
+ 'Required',
57
+ 'Readonly',
58
+ 'Pick',
59
+ 'Omit',
60
+ 'Result',
61
+ 'Either',
62
+ 'Observable',
63
+ 'AsyncIterable',
64
+ 'Iterable',
65
+ 'WeakMap',
66
+ 'WeakSet',
67
+ ]);
68
+ /**
69
+ * OTel and project metric instrument type names. A module-level
70
+ * `let counter: Counter | null = null` lazy-init pattern with one of these
71
+ * as the declared type is process-scoped per-instrument state, not request state.
72
+ */
73
+ const METRIC_INSTRUMENT_TYPES = new Set([
74
+ 'Counter',
75
+ 'Histogram',
76
+ 'UpDownCounter',
77
+ 'Gauge',
78
+ 'ObservableCounter',
79
+ 'ObservableGauge',
80
+ 'ObservableUpDownCounter',
81
+ 'Meter',
82
+ 'Tracer',
83
+ 'TracerProvider',
84
+ 'MeterProvider',
85
+ ]);
86
+ /**
87
+ * Path patterns where the check is structurally inappropriate.
88
+ * - DBOS steps register process-scoped DI via `static ctx`; that's the framework's
89
+ * contract, not request leakage.
90
+ */
91
+ const SKIP_PATH_PATTERNS = [/[/\\]dbos[/\\]steps[/\\]/];
92
+ function isSkippedPath(filePath) {
93
+ return SKIP_PATH_PATTERNS.some((p) => p.test(filePath));
94
+ }
95
+ /**
96
+ * Walk a TypeNode and decide whether it references a request-scoped context
97
+ * type *as the outer / value-shape* (not as an inner generic argument of a
98
+ * process-scoped wrapper like `Injector<AuditContext>`).
99
+ */
100
+ /** Get the simple name of a type reference's `typeName` (handles qualified names). */
101
+ function getTypeRefName(typeName) {
102
+ if (ts.isIdentifier(typeName))
103
+ return typeName.text;
104
+ if (ts.isQualifiedName(typeName))
105
+ return typeName.right.text;
106
+ return '';
107
+ }
108
+ /** Outer type-reference name(s) of a TypeNode, including each union branch. */
109
+ function typeRefNames(type) {
110
+ if (!type)
111
+ return [];
112
+ if (ts.isUnionTypeNode(type))
113
+ return type.types.flatMap((t) => typeRefNames(t));
114
+ if (ts.isTypeReferenceNode(type))
115
+ return [getTypeRefName(type.typeName)];
116
+ return [];
117
+ }
118
+ /**
119
+ * Collect names imported from `@opentelemetry/*` packages. OTel's `Context`
120
+ * (the W3C trace-propagation context) and its siblings are process-scoped SDK
121
+ * types — a module-level `let parentContext: Context` holding propagation
122
+ * state is NOT the per-request tenant context this check targets. Inspecting
123
+ * the import source (rather than the bare `Context`/`Ctx` name) keeps the
124
+ * exclusion sound: only OTel's own types are spared, not every type ending
125
+ * in "Context".
126
+ */
127
+ function isOtelImport(stmt) {
128
+ return (ts.isImportDeclaration(stmt) &&
129
+ ts.isStringLiteral(stmt.moduleSpecifier) &&
130
+ stmt.moduleSpecifier.text.startsWith('@opentelemetry/'));
131
+ }
132
+ /** Names bound by an import clause (default + named bindings). */
133
+ function importClauseNames(clause) {
134
+ const names = [];
135
+ if (clause.name)
136
+ names.push(clause.name.text);
137
+ const bindings = clause.namedBindings;
138
+ if (bindings && ts.isNamedImports(bindings)) {
139
+ for (const el of bindings.elements)
140
+ names.push(el.name.text);
141
+ }
142
+ return names;
143
+ }
144
+ function collectOtelImportedNames(sourceFile) {
145
+ const names = new Set();
146
+ for (const stmt of sourceFile.statements) {
147
+ if (!isOtelImport(stmt) || !stmt.importClause)
148
+ continue;
149
+ for (const name of importClauseNames(stmt.importClause))
150
+ names.add(name);
151
+ }
152
+ return names;
153
+ }
154
+ function typeLooksLikeRequestContext(type) {
155
+ if (!type)
156
+ return false;
157
+ // Union: any branch that looks like context counts (excluding `null`/`undefined`)
158
+ if (ts.isUnionTypeNode(type)) {
159
+ return type.types.some((t) => typeLooksLikeRequestContext(t));
160
+ }
161
+ if (ts.isTypeReferenceNode(type)) {
162
+ const name = getTypeRefName(type.typeName);
163
+ // @fitness-ignore-next-line silent-early-returns -- boolean predicate function: `false` IS the contract value meaning "this wrapper is process-scoped, not request-scoped"; the caller branches on it.
164
+ if (PROCESS_SCOPED_WRAPPER_TYPES.has(name)) {
165
+ // The outer wrapper is process-scoped; ignore its generic arguments.
166
+ return false;
167
+ }
168
+ return isContextTypeName(name);
169
+ }
170
+ // Other shapes (TypeLiteral, intersection of inline shapes, etc.) — be lenient
171
+ // and don't flag. Inline-typed module-level state would still be caught if
172
+ // the variable name itself is contextual (handled separately).
173
+ return false;
174
+ }
175
+ /**
176
+ * Detect the `let foo: <MetricType> | null = null` lazy-init shape that is
177
+ * common for OTel instruments. These declarations are process-scoped per
178
+ * metric, not request state, so we skip them.
179
+ */
180
+ function isMetricLazyInit(decl) {
181
+ const t = decl.type;
182
+ if (!t)
183
+ return false;
184
+ if (decl.initializer?.kind !== ts.SyntaxKind.NullKeyword)
185
+ return false;
186
+ // Require a `<Something> | null` (or `<Something> | undefined`) shape.
187
+ const candidates = ts.isUnionTypeNode(t) ? [...t.types] : [t];
188
+ const hasNullBranch = candidates.some((c) => c.kind === ts.SyntaxKind.NullKeyword ||
189
+ c.kind === ts.SyntaxKind.UndefinedKeyword ||
190
+ (ts.isLiteralTypeNode(c) && c.literal.kind === ts.SyntaxKind.NullKeyword));
191
+ if (!hasNullBranch)
192
+ return false;
193
+ return candidates.some((c) => {
194
+ if (!ts.isTypeReferenceNode(c))
195
+ return false;
196
+ return METRIC_INSTRUMENT_TYPES.has(getTypeRefName(c.typeName));
197
+ });
198
+ }
199
+ /**
200
+ * Detect AsyncLocalStorage-typed declarations; these are the *correct* way to
201
+ * store request-scoped state and should never be flagged.
202
+ */
203
+ function isAsyncLocalStorageType(type) {
204
+ if (!type)
205
+ return false;
206
+ if (ts.isTypeReferenceNode(type)) {
207
+ return getTypeRefName(type.typeName) === 'AsyncLocalStorage';
208
+ }
209
+ if (ts.isUnionTypeNode(type)) {
210
+ return type.types.some(isAsyncLocalStorageType);
211
+ }
212
+ return false;
213
+ }
214
+ /**
215
+ * A class is "request-scoped" if any of its public methods take a `tenantId`
216
+ * parameter (typed or named), or it has a `requestId` field. This is a heuristic
217
+ * — process-scoped DI classes (composition roots, providers) typically don't
218
+ * pass tenantId around as a method param; request handlers do.
219
+ */
220
+ function classLooksRequestScoped(cls) {
221
+ for (const member of cls.members) {
222
+ // Field named requestId / correlationId
223
+ if (ts.isPropertyDeclaration(member) && ts.isIdentifier(member.name)) {
224
+ const fieldName = member.name.text;
225
+ if (fieldName === 'requestId' || fieldName === 'correlationId')
226
+ return true;
227
+ }
228
+ // Method with `tenantId` parameter
229
+ if ((ts.isMethodDeclaration(member) || ts.isConstructorDeclaration(member)) &&
230
+ member.parameters.some((p) => ts.isIdentifier(p.name) && (p.name.text === 'tenantId' || p.name.text === 'tenant_id'))) {
231
+ return true;
232
+ }
233
+ }
234
+ return false;
235
+ }
236
+ /**
237
+ * A class declaration is a DBOS step host if any member carries a `@DBOS.step()`
238
+ * decorator (or `@DBOS.workflow()`). These are process-scoped DI containers.
239
+ */
240
+ function classIsDbosStepHost(cls) {
241
+ const checkDecorators = (mods) => {
242
+ if (!mods)
243
+ return false;
244
+ for (const m of mods) {
245
+ if (!ts.isDecorator(m))
246
+ continue;
247
+ const exprText = m.expression.getText();
248
+ if (exprText.startsWith('DBOS.step') || exprText.startsWith('DBOS.workflow'))
249
+ return true;
250
+ }
251
+ return false;
252
+ };
253
+ if (checkDecorators(ts.getModifiers(cls)))
254
+ return true;
255
+ for (const member of cls.members) {
256
+ if (ts.canHaveDecorators(member) && checkDecorators(ts.getDecorators(member))) {
257
+ return true;
258
+ }
259
+ }
260
+ return false;
261
+ }
262
+ /**
263
+ * Walk top-level statements and class declarations of a SourceFile and collect
264
+ * findings for genuine module-level / request-scoped class-level leakage.
265
+ */
266
+ // eslint-disable-next-line sonarjs/cognitive-complexity -- module/class-level walk; branches map to AST node kinds and are easier to read inline than as a fragmented dispatcher
267
+ function collectContextLeakage(sourceFile) {
268
+ const findings = [];
269
+ const otelImportedNames = collectOtelImportedNames(sourceFile);
270
+ // 1. Module-level `let`/`var` declarations
271
+ for (const stmt of sourceFile.statements) {
272
+ if (!ts.isVariableStatement(stmt))
273
+ continue;
274
+ const flags = stmt.declarationList.flags;
275
+ // Skip `const` — request-scoped state cannot be assigned more than once
276
+ // anyway. The leakage shape requires a re-assignable binding.
277
+ if (flags & ts.NodeFlags.Const)
278
+ continue;
279
+ for (const decl of stmt.declarationList.declarations) {
280
+ if (!ts.isIdentifier(decl.name))
281
+ continue;
282
+ const varName = decl.name.text;
283
+ // AsyncLocalStorage — the correct request-scoping primitive
284
+ if (isAsyncLocalStorageType(decl.type))
285
+ continue;
286
+ // Lazy-init metric instrument: process-scoped per metric, not per request
287
+ if (isMetricLazyInit(decl))
288
+ continue;
289
+ // OTel SDK types (Context, Span, …) are process/propagation scoped.
290
+ if (typeRefNames(decl.type).some((n) => otelImportedNames.has(n)))
291
+ continue;
292
+ const typeIsContextual = typeLooksLikeRequestContext(decl.type);
293
+ const nameIsContextual = variableNameLooksContextual(varName);
294
+ // Require BOTH name AND type to point at request context (or at least the
295
+ // type — the regex check used to flag "request" in metric names; we now
296
+ // require an explicit type-shape signal).
297
+ if (!typeIsContextual && !nameIsContextual)
298
+ continue;
299
+ // If the variable has a non-null initializer that's an object literal /
300
+ // function call producing a known process-scoped value (e.g. `new Map()`),
301
+ // and the type isn't contextual, skip.
302
+ if (!typeIsContextual && nameIsContextual) {
303
+ // Name-only signal is too weak by itself — require initializer to be `null`
304
+ // and a contextual-looking type. If the user wrote `let req = …` without a
305
+ // type, modern TS will infer it; we don't have type info here, so we punt.
306
+ continue;
307
+ }
308
+ const start = decl.getStart(sourceFile);
309
+ const { line, character } = sourceFile.getLineAndCharacterOfPosition(start);
310
+ findings.push({
311
+ line: line + 1,
312
+ column: character + 1,
313
+ match: `let ${varName}: <Context>`,
314
+ });
315
+ }
316
+ }
317
+ // 2. Class fields — non-readonly, non-static `PropertyDeclaration` whose
318
+ // type is a request-scoped context AND the class itself is request-scoped.
319
+ for (const stmt of sourceFile.statements) {
320
+ if (!ts.isClassDeclaration(stmt))
321
+ continue;
322
+ if (classIsDbosStepHost(stmt))
323
+ continue;
324
+ if (!classLooksRequestScoped(stmt))
325
+ continue;
326
+ for (const member of stmt.members) {
327
+ if (!ts.isPropertyDeclaration(member))
328
+ continue;
329
+ if (!ts.isIdentifier(member.name))
330
+ continue;
331
+ const mods = ts.getModifiers(member);
332
+ const isReadonly = mods?.some((m) => m.kind === ts.SyntaxKind.ReadonlyKeyword) ?? false;
333
+ const isStatic = mods?.some((m) => m.kind === ts.SyntaxKind.StaticKeyword) ?? false;
334
+ if (isReadonly || isStatic)
335
+ continue;
336
+ // OTel SDK types are process/propagation scoped, not request state.
337
+ if (typeRefNames(member.type).some((n) => otelImportedNames.has(n)))
338
+ continue;
339
+ if (!typeLooksLikeRequestContext(member.type))
340
+ continue;
341
+ const start = member.getStart(sourceFile);
342
+ const { line, character } = sourceFile.getLineAndCharacterOfPosition(start);
343
+ findings.push({
344
+ line: line + 1,
345
+ column: character + 1,
346
+ match: `private ${member.name.text}: <Context>`,
347
+ });
348
+ }
349
+ }
350
+ return findings;
351
+ }
352
+ /**
353
+ * Check: resilience/context-leakage
354
+ *
355
+ * Detects request context stored in module or class scope, which could cause
356
+ * cross-request pollution in multi-tenant / concurrent server environments.
357
+ *
358
+ * Implemented as a TypeScript AST walk. The previous regex implementation flagged:
359
+ * - type-only references (`SyncStrategy<InitialSyncContext>`),
360
+ * - method-parameter types (`(ctx: SomeContext) => …`),
361
+ * - module-level lazy-init metric instruments (`let counter: Counter | null = null`).
362
+ * The AST rewrite eliminates those false positives by inspecting the actual
363
+ * declaration shape rather than line text.
364
+ */
365
+ export const contextLeakage = defineCheck({
366
+ id: '037b58ef-7b7d-404c-896b-2d40efe02a95',
367
+ slug: 'context-leakage',
368
+ scope: { languages: ['typescript'], concerns: ['backend', 'frontend', 'cli'] },
369
+ description: 'Detect potential request context leakage',
370
+ longDescription: `**Purpose:** Detects request context stored in module or class scope, which can leak between concurrent requests.
371
+
372
+ **Detects (AST-based):**
373
+ - Module-level mutable bindings (\`let\`/\`var\`) whose declared type ends in \`Context\` or \`Ctx\` (e.g. \`let activeContext: RequestContext | null = null\`).
374
+ - Class \`PropertyDeclaration\` (non-\`readonly\`, non-\`static\`) whose type ends in \`Context\` or \`Ctx\` AND whose enclosing class is heuristically request-scoped (a method takes a \`tenantId\` parameter, or the class declares a \`requestId\` field).
375
+
376
+ **Explicitly excluded:**
377
+ - Type-only generic-argument references (\`SyncStrategy<InitialSyncContext>\`, \`Injector<AuditContext>\`, \`Promise<Foo>\`) — the outer wrapper identifier suppresses recursion into generics.
378
+ - Method-parameter types (\`(ctx: SomeContext) => …\`) — parameters are never module-level declarations.
379
+ - Function-local bindings — only top-level \`SourceFile.statements\` are walked.
380
+ - DBOS step \`static ctx\` slots — files under \`**/dbos/steps/**\` are skipped, and classes whose members carry \`@DBOS.step()\` / \`@DBOS.workflow()\` decorators are skipped.
381
+ - Module-level OTel lazy-init shape: \`let <name>: <MetricType> | null = null\` where \`<MetricType>\` is one of \`Counter\`, \`Histogram\`, \`UpDownCounter\`, \`Gauge\`, \`Observable*\`, \`Meter\`, \`Tracer\`, \`TracerProvider\`, \`MeterProvider\` — these are process-scoped per-instrument caches, not per-request state.
382
+ - \`AsyncLocalStorage\`-typed declarations — the correct request-scoping primitive.
383
+
384
+ **Why it matters:** Storing per-request context in shared scope causes cross-request pollution in multi-tenant or concurrent server environments.
385
+
386
+ **Known limitations:**
387
+ - The "class is request-scoped" check is a syntactic heuristic — it does not consult the type checker. A request handler that doesn't take \`tenantId\` directly (e.g. takes a \`FastifyRequest\` and reads tenant from inside) will not match. Prefer adding a \`requestId\` field on such classes if you want them in scope.
388
+ - Inline-typed module bindings (\`let foo = someValue\` with no annotation) are not flagged — the AST has no type information without the type checker. If you want stricter detection, declare the type explicitly.
389
+
390
+ **Scope:** General best practice. Analyzes each file individually via a single AST walk.`,
391
+ tags: ['resilience', 'context', 'security'],
392
+ fileTypes: ['ts', 'tsx'],
393
+ analyze: analyzeContextLeakage,
394
+ });
395
+ /**
396
+ * Analyze a file for request-context leakage. Exported for the FP-regression
397
+ * suite (see `__tests__/context-leakage-fp.test.ts`).
398
+ */
399
+ export function analyzeContextLeakage(content, filePath) {
400
+ if (isTestFile(filePath))
401
+ return [];
402
+ if (isSkippedPath(filePath))
403
+ return [];
404
+ logger.debug({
405
+ evt: 'fitness.checks.context_leakage.context_leakage_analyze',
406
+ msg: 'Analyzing file for request context leakage (AST)',
407
+ });
408
+ // Quick text bail-out: if the file mentions neither "context" nor "ctx",
409
+ // there is nothing to find. Saves the parse-cache hit.
410
+ const lower = content.toLowerCase();
411
+ if (!lower.includes('context') && !lower.includes('ctx'))
412
+ return [];
413
+ let sourceFile;
414
+ try {
415
+ sourceFile = getSharedSourceFile(filePath, content);
416
+ }
417
+ catch {
418
+ // @swallow-ok Skip files that fail to parse — no signal to emit.
419
+ return [];
420
+ }
421
+ if (!sourceFile)
422
+ return [];
423
+ const findings = collectContextLeakage(sourceFile);
424
+ return findings.map((f) => ({
425
+ line: f.line,
426
+ column: f.column,
427
+ message: 'Request context stored in module/class scope may leak between requests',
428
+ severity: 'warning',
429
+ suggestion: 'Use AsyncLocalStorage for request-scoped context or pass context as a parameter. Storing context in module/class scope can cause cross-request pollution.',
430
+ match: f.match,
431
+ type: 'context-leakage',
432
+ filePath,
433
+ }));
434
+ }
435
+ //# sourceMappingURL=context-leakage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-leakage.js","sourceRoot":"","sources":["../../../src/checks/resilience/context-leakage.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,UAAU,EAAuB,MAAM,sBAAsB,CAAC;AACpF,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAEjC,gFAAgF;AAChF,sCAAsC;AACtC,gFAAgF;AAEhF;;;;;GAKG;AACH,SAAS,2BAA2B,CAAC,IAAY;IAC/C,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACjC,uEAAuE;IACvE,OAAO,CACL,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC;QACzB,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC;QACrB,KAAK,KAAK,SAAS;QACnB,KAAK,KAAK,KAAK;QACf,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC;QAC3B,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC,CAChD,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,SAAS,iBAAiB,CAAC,IAAY;IACrC,OAAO,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACvC,CAAC;AAED;;;GAGG;AACH,MAAM,4BAA4B,GAAG,IAAI,GAAG,CAAC;IAC3C,UAAU;IACV,cAAc;IACd,SAAS;IACT,aAAa;IACb,SAAS;IACT,OAAO;IACP,eAAe;IACf,KAAK;IACL,aAAa;IACb,KAAK;IACL,aAAa;IACb,QAAQ;IACR,SAAS;IACT,UAAU;IACV,UAAU;IACV,MAAM;IACN,MAAM;IACN,QAAQ;IACR,QAAQ;IACR,YAAY;IACZ,eAAe;IACf,UAAU;IACV,SAAS;IACT,SAAS;CACV,CAAC,CAAC;AAEH;;;;GAIG;AACH,MAAM,uBAAuB,GAAG,IAAI,GAAG,CAAC;IACtC,SAAS;IACT,WAAW;IACX,eAAe;IACf,OAAO;IACP,mBAAmB;IACnB,iBAAiB;IACjB,yBAAyB;IACzB,OAAO;IACP,QAAQ;IACR,gBAAgB;IAChB,eAAe;CAChB,CAAC,CAAC;AAEH;;;;GAIG;AACH,MAAM,kBAAkB,GAAa,CAAC,0BAA0B,CAAC,CAAC;AAElE,SAAS,aAAa,CAAC,QAAgB;IACrC,OAAO,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC1D,CAAC;AAED;;;;GAIG;AACH,sFAAsF;AACtF,SAAS,cAAc,CAAC,QAAuB;IAC7C,IAAI,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC;QAAE,OAAO,QAAQ,CAAC,IAAI,CAAC;IACpD,IAAI,EAAE,CAAC,eAAe,CAAC,QAAQ,CAAC;QAAE,OAAO,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC;IAC7D,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,+EAA+E;AAC/E,SAAS,YAAY,CAAC,IAA6B;IACjD,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IACrB,IAAI,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;IAChF,IAAI,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC;QAAE,OAAO,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;IACzE,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,YAAY,CAAC,IAAkB;IACtC,OAAO,CACL,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC;QAC5B,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,eAAe,CAAC;QACxC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,iBAAiB,CAAC,CACxD,CAAC;AACJ,CAAC;AAED,kEAAkE;AAClE,SAAS,iBAAiB,CAAC,MAAuB;IAChD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,MAAM,CAAC,IAAI;QAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9C,MAAM,QAAQ,GAAG,MAAM,CAAC,aAAa,CAAC;IACtC,IAAI,QAAQ,IAAI,EAAE,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5C,KAAK,MAAM,EAAE,IAAI,QAAQ,CAAC,QAAQ;YAAE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/D,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,wBAAwB,CAAC,UAAyB;IACzD,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,KAAK,MAAM,IAAI,IAAI,UAAU,CAAC,UAAU,EAAE,CAAC;QACzC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY;YAAE,SAAS;QACxD,KAAK,MAAM,IAAI,IAAI,iBAAiB,CAAC,IAAI,CAAC,YAAY,CAAC;YAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC3E,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,2BAA2B,CAAC,IAA6B;IAChE,IAAI,CAAC,IAAI;QAAE,OAAO,KAAK,CAAC;IAExB,kFAAkF;IAClF,IAAI,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,2BAA2B,CAAC,CAAC,CAAC,CAAC,CAAC;IAChE,CAAC;IAED,IAAI,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,GAAG,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC3C,uMAAuM;QACvM,IAAI,4BAA4B,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3C,qEAAqE;YACrE,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAED,+EAA+E;IAC/E,2EAA2E;IAC3E,+DAA+D;IAC/D,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,SAAS,gBAAgB,CAAC,IAA4B;IACpD,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC;IACpB,IAAI,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACrB,IAAI,IAAI,CAAC,WAAW,EAAE,IAAI,KAAK,EAAE,CAAC,UAAU,CAAC,WAAW;QAAE,OAAO,KAAK,CAAC;IAEvE,uEAAuE;IACvE,MAAM,UAAU,GAAkB,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7E,MAAM,aAAa,GAAG,UAAU,CAAC,IAAI,CACnC,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,UAAU,CAAC,WAAW;QACpC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,UAAU,CAAC,gBAAgB;QACzC,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,CAC5E,CAAC;IACF,IAAI,CAAC,aAAa;QAAE,OAAO,KAAK,CAAC;IAEjC,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE;QAC3B,IAAI,CAAC,EAAE,CAAC,mBAAmB,CAAC,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;QAC7C,OAAO,uBAAuB,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,SAAS,uBAAuB,CAAC,IAA6B;IAC5D,IAAI,CAAC,IAAI;QAAE,OAAO,KAAK,CAAC;IACxB,IAAI,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC;QACjC,OAAO,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,mBAAmB,CAAC;IAC/D,CAAC;IACD,IAAI,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;IAClD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;GAKG;AACH,SAAS,uBAAuB,CAAC,GAAwB;IACvD,KAAK,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;QACjC,wCAAwC;QACxC,IAAI,EAAE,CAAC,qBAAqB,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;YACrE,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;YACnC,IAAI,SAAS,KAAK,WAAW,IAAI,SAAS,KAAK,eAAe;gBAAE,OAAO,IAAI,CAAC;QAC9E,CAAC;QACD,mCAAmC;QACnC,IACE,CAAC,EAAE,CAAC,mBAAmB,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,wBAAwB,CAAC,MAAM,CAAC,CAAC;YACvE,MAAM,CAAC,UAAU,CAAC,IAAI,CACpB,CAAC,CAAC,EAAE,EAAE,CACJ,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,UAAU,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,WAAW,CAAC,CACzF,EACD,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,SAAS,mBAAmB,CAAC,GAAwB;IACnD,MAAM,eAAe,GAAG,CAAC,IAA4C,EAAW,EAAE;QAChF,IAAI,CAAC,IAAI;YAAE,OAAO,KAAK,CAAC;QACxB,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;YACrB,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;gBAAE,SAAS;YACjC,MAAM,QAAQ,GAAG,CAAC,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;YACxC,IAAI,QAAQ,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,QAAQ,CAAC,UAAU,CAAC,eAAe,CAAC;gBAAE,OAAO,IAAI,CAAC;QAC5F,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;IACF,IAAI,eAAe,CAAC,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACvD,KAAK,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;QACjC,IAAI,EAAE,CAAC,iBAAiB,CAAC,MAAM,CAAC,IAAI,eAAe,CAAC,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;YAC9E,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAQD;;;GAGG;AACH,iLAAiL;AACjL,SAAS,qBAAqB,CAAC,UAAyB;IACtD,MAAM,QAAQ,GAA4B,EAAE,CAAC;IAC7C,MAAM,iBAAiB,GAAG,wBAAwB,CAAC,UAAU,CAAC,CAAC;IAE/D,2CAA2C;IAC3C,KAAK,MAAM,IAAI,IAAI,UAAU,CAAC,UAAU,EAAE,CAAC;QACzC,IAAI,CAAC,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC;YAAE,SAAS;QAE5C,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC;QACzC,wEAAwE;QACxE,8DAA8D;QAC9D,IAAI,KAAK,GAAG,EAAE,CAAC,SAAS,CAAC,KAAK;YAAE,SAAS;QAEzC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,eAAe,CAAC,YAAY,EAAE,CAAC;YACrD,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;gBAAE,SAAS;YAC1C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;YAE/B,4DAA4D;YAC5D,IAAI,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC;gBAAE,SAAS;YAEjD,0EAA0E;YAC1E,IAAI,gBAAgB,CAAC,IAAI,CAAC;gBAAE,SAAS;YAErC,oEAAoE;YACpE,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;gBAAE,SAAS;YAE5E,MAAM,gBAAgB,GAAG,2BAA2B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAChE,MAAM,gBAAgB,GAAG,2BAA2B,CAAC,OAAO,CAAC,CAAC;YAE9D,0EAA0E;YAC1E,wEAAwE;YACxE,0CAA0C;YAC1C,IAAI,CAAC,gBAAgB,IAAI,CAAC,gBAAgB;gBAAE,SAAS;YAErD,wEAAwE;YACxE,2EAA2E;YAC3E,uCAAuC;YACvC,IAAI,CAAC,gBAAgB,IAAI,gBAAgB,EAAE,CAAC;gBAC1C,4EAA4E;gBAC5E,2EAA2E;gBAC3E,2EAA2E;gBAC3E,SAAS;YACX,CAAC;YAED,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;YACxC,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,UAAU,CAAC,6BAA6B,CAAC,KAAK,CAAC,CAAC;YAC5E,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,IAAI,GAAG,CAAC;gBACd,MAAM,EAAE,SAAS,GAAG,CAAC;gBACrB,KAAK,EAAE,OAAO,OAAO,aAAa;aACnC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,yEAAyE;IACzE,8EAA8E;IAC9E,KAAK,MAAM,IAAI,IAAI,UAAU,CAAC,UAAU,EAAE,CAAC;QACzC,IAAI,CAAC,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC;YAAE,SAAS;QAC3C,IAAI,mBAAmB,CAAC,IAAI,CAAC;YAAE,SAAS;QACxC,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC;YAAE,SAAS;QAE7C,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAClC,IAAI,CAAC,EAAE,CAAC,qBAAqB,CAAC,MAAM,CAAC;gBAAE,SAAS;YAChD,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC;gBAAE,SAAS;YAE5C,MAAM,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;YACrC,MAAM,UAAU,GAAG,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,UAAU,CAAC,eAAe,CAAC,IAAI,KAAK,CAAC;YACxF,MAAM,QAAQ,GAAG,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC;YACpF,IAAI,UAAU,IAAI,QAAQ;gBAAE,SAAS;YAErC,oEAAoE;YACpE,IAAI,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;gBAAE,SAAS;YAE9E,IAAI,CAAC,2BAA2B,CAAC,MAAM,CAAC,IAAI,CAAC;gBAAE,SAAS;YAExD,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;YAC1C,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,UAAU,CAAC,6BAA6B,CAAC,KAAK,CAAC,CAAC;YAC5E,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,IAAI,GAAG,CAAC;gBACd,MAAM,EAAE,SAAS,GAAG,CAAC;gBACrB,KAAK,EAAE,WAAW,MAAM,CAAC,IAAI,CAAC,IAAI,aAAa;aAChD,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,WAAW,CAAC;IACxC,EAAE,EAAE,sCAAsC;IAC1C,IAAI,EAAE,iBAAiB;IACvB,KAAK,EAAE,EAAE,SAAS,EAAE,CAAC,YAAY,CAAC,EAAE,QAAQ,EAAE,CAAC,SAAS,EAAE,UAAU,EAAE,KAAK,CAAC,EAAE;IAC9E,WAAW,EAAE,0CAA0C;IACvD,eAAe,EAAE;;;;;;;;;;;;;;;;;;;;yFAoBsE;IACvF,IAAI,EAAE,CAAC,YAAY,EAAE,SAAS,EAAE,UAAU,CAAC;IAC3C,SAAS,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC;IAExB,OAAO,EAAE,qBAAqB;CAC/B,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,OAAe,EAAE,QAAgB;IACrE,IAAI,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,EAAE,CAAC;IACpC,IAAI,aAAa,CAAC,QAAQ,CAAC;QAAE,OAAO,EAAE,CAAC;IAEvC,MAAM,CAAC,KAAK,CAAC;QACX,GAAG,EAAE,wDAAwD;QAC7D,GAAG,EAAE,kDAAkD;KACxD,CAAC,CAAC;IAEH,yEAAyE;IACzE,uDAAuD;IACvD,MAAM,KAAK,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IACpC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAEpE,IAAI,UAAgC,CAAC;IACrC,IAAI,CAAC;QACH,UAAU,GAAG,mBAAmB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACtD,CAAC;IAAC,MAAM,CAAC;QACP,iEAAiE;QACjE,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,CAAC,UAAU;QAAE,OAAO,EAAE,CAAC;IAE3B,MAAM,QAAQ,GAAG,qBAAqB,CAAC,UAAU,CAAC,CAAC;IACnD,OAAO,QAAQ,CAAC,GAAG,CAAiB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC1C,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,OAAO,EAAE,wEAAwE;QACjF,QAAQ,EAAE,SAAS;QACnB,UAAU,EACR,2JAA2J;QAC7J,KAAK,EAAE,CAAC,CAAC,KAAK;QACd,IAAI,EAAE,iBAAiB;QACvB,QAAQ;KACT,CAAC,CAAC,CAAC;AACN,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * @fileoverview Context mutation safety check — flags direct mutation of
3
+ * request/execution context objects, which causes side effects across
4
+ * middleware in concurrent server environments.
5
+ */
6
+ import { type CheckViolation } from '@opensip-cli/fitness';
7
+ /**
8
+ * Pure analysis function. Exported so unit tests can exercise the
9
+ * detection logic without standing up the full Check framework
10
+ * (defineCheck wraps `analyze` into an `execute` closure that requires
11
+ * an ExecutionContext to invoke).
12
+ */
13
+ export declare function analyzeContextMutation(content: string, filePath: string): CheckViolation[];
14
+ /**
15
+ * Check: resilience/context-mutation
16
+ *
17
+ * Detects potentially unsafe mutations of request/execution context objects.
18
+ * Context should be immutable to prevent side effects across middleware.
19
+ */
20
+ export declare const contextMutationCheck: import("@opensip-cli/fitness").Check;
21
+ //# sourceMappingURL=context-mutation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-mutation.d.ts","sourceRoot":"","sources":["../../../src/checks/resilience/context-mutation.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AAGH,OAAO,EAA8B,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AA8SvF;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,cAAc,EAAE,CAwC1F;AAED;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,sCA0B/B,CAAC"}