@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,639 @@
1
+ // @fitness-ignore-file file-length-limit -- cohesive single-check module; splitting risks breaking the detector contract
2
+ /**
3
+ * @fileoverview TOCTOU Race Condition Detection Check
4
+ *
5
+ * Detects Time-of-Check-Time-of-Use race conditions where data is read,
6
+ * then updated without passing version/condition for atomic updates.
7
+ *
8
+ * Refinement notes (Wave E lane E6-redo):
9
+ * The original implementation was a regex-only test for the presence of
10
+ * `.get/.find/...` and `.update/.set/...` strings inside the same function
11
+ * body. That broad pattern produced false positives on:
12
+ * - Local `Map.get` / `Map.set` accumulator idioms (count++ via map).
13
+ * - In-process cache fields (`this.#cache.get` then `this.#cache.set`)
14
+ * used as single-threaded coalescing structures.
15
+ * - Read-only DB functions that build local Maps for grouping
16
+ * (`db.select(...)` → `new Map().set(...)`).
17
+ * - Single-statement atomic SQL writes (`tx.execute(sql`UPDATE...`)`).
18
+ *
19
+ * Refinement strategy: classify each `.get/.set/.update/...` call by its
20
+ * receiver. A function only flags as TOCTOU if there is at least one
21
+ * read+update pair on a *non-local* receiver (i.e. not a local Map/Set,
22
+ * not a "Cache"-named field, and not a tx/db where writes are atomic
23
+ * SQL). All-local-receiver patterns are excluded.
24
+ */
25
+ import { defineCheck, getCheckConfig, isTestFile } from '@opensip-cli/fitness';
26
+ import { getSharedSourceFile } from '@opensip-cli/lang-typescript';
27
+ import * as ts from 'typescript';
28
+ /** Patterns that indicate proper atomic update handling */
29
+ const ATOMIC_PATTERNS = [
30
+ /expectedVersion/i,
31
+ /version\s*:/,
32
+ /ConditionExpression/,
33
+ /conditionalUpdate/i,
34
+ /atomicUpdate/i,
35
+ /compareAndSwap/i,
36
+ /optimisticLock/i,
37
+ /CONCURRENCY SAFE/,
38
+ // Transaction patterns
39
+ /transaction/i,
40
+ /beginTransaction/i,
41
+ /withTransaction/i,
42
+ /runInTransaction/i,
43
+ // Lock patterns
44
+ /acquireLock/i,
45
+ /withLock/i,
46
+ /mutex/i,
47
+ // Idempotency patterns
48
+ /idempotent/i,
49
+ /idempotencyKey/i,
50
+ // Single-threaded/in-memory safety comments
51
+ /single-threaded/i,
52
+ /in-memory/i,
53
+ /atomic in.*Node/i,
54
+ // Documented coalescing/event-loop safety patterns commonly used in Node single-threaded code
55
+ /single-threaded coalesce/i, // explicit coalescing-cache documentation
56
+ /Node single-threaded/i, // explicit Node single-threaded documentation
57
+ /event-loop semantics/i, // explicit event-loop atomicity documentation
58
+ ];
59
+ /**
60
+ * Paths where TOCTOU is typically not a concern
61
+ * (in-memory caches, rate limiters, local state managers)
62
+ */
63
+ const SAFE_TOCTOU_PATHS = [
64
+ // In-memory data structures
65
+ /\/cache\//i,
66
+ /\/caching\//i,
67
+ /memory-backend/i,
68
+ /memory-cache/i,
69
+ /memory-store/i,
70
+ /in-memory/i,
71
+ // Filename conventions — `*-cache.ts` and `*-prefetcher.ts` are
72
+ // single-threaded coalescing structures by convention (Node event-loop
73
+ // semantics make the .get-then-.set pattern safe). The path-segment
74
+ // /cache/ skip above misses files at top of a package's src/ tree.
75
+ /-cache\.tsx?$/i,
76
+ /-prefetcher\.tsx?$/i,
77
+ // Rate limiting (bounded operations)
78
+ /rate-limit/i,
79
+ /rate_limit/i,
80
+ // Local state management
81
+ /local-storage/i,
82
+ /local-state/i,
83
+ /state-manager/i,
84
+ // CLI/scripts (single user, non-concurrent)
85
+ // CLI commands use local Map/Set operations that are not shared-state TOCTOU risks.
86
+ // Server lifecycle TOCTOU issues are better caught by the reentrancy-guard check.
87
+ /\/cli\//,
88
+ /\/scripts\//,
89
+ // Test utilities
90
+ /\/testing\//,
91
+ /test-utils/,
92
+ // Configuration/Registry (startup-time operations)
93
+ /\/config\//,
94
+ /\/registry\//,
95
+ /\/di-registration\//,
96
+ /\/factories\//,
97
+ // Route handlers — request-scoped Map/Set ops are not shared-state TOCTOU; route handlers are dominated by Zod.pick/parse and per-request local maps that the regex misreads as TOCTOU.
98
+ /\/routes\//,
99
+ // DI composition — fragment graphs construct a per-startup map of providers; not concurrent shared state.
100
+ /\/di\//,
101
+ // Schema declarations — Drizzle/Zod schema files are pure declarative builders, no runtime read/update race surface.
102
+ /\/schema\//,
103
+ // NOTE: opensip-specific paths (e.g. `/chain-walker/` for audit-chain
104
+ // walkers) are NOT defaults. They live in opensip's recipe under
105
+ // `checks.config['toctou-race-condition'].additionalSafeTOCTOUPaths`.
106
+ ];
107
+ /**
108
+ * Compile recipe-provided string entries to case-insensitive RegExp values.
109
+ */
110
+ function buildEffectiveSafePaths() {
111
+ const cfg = getCheckConfig('toctou-race-condition');
112
+ const extras = (cfg.additionalSafeTOCTOUPaths ?? []).map((src) => new RegExp(src, 'i'));
113
+ return [...SAFE_TOCTOU_PATHS, ...extras];
114
+ }
115
+ /**
116
+ * Check if a file path is in a safe TOCTOU context. Combines built-in
117
+ * defaults with the recipe-config augmentation.
118
+ */
119
+ function isSafeToctouPath(filePath, safePaths) {
120
+ return safePaths.some((pattern) => pattern.test(filePath));
121
+ }
122
+ /** Read operation method names */
123
+ const READ_METHODS = new Set([
124
+ 'get',
125
+ 'find',
126
+ 'findOne',
127
+ 'findFirst',
128
+ 'findMany',
129
+ 'getById',
130
+ 'fetch',
131
+ 'load',
132
+ 'read',
133
+ ]);
134
+ /** Update operation method names */
135
+ const UPDATE_METHODS = new Set(['update', 'save', 'put', 'set', 'patch', 'modify']);
136
+ /**
137
+ * Check if content has atomic patterns
138
+ */
139
+ function hasAtomicPatterns(content) {
140
+ return ATOMIC_PATTERNS.some((p) => p.test(content));
141
+ }
142
+ /**
143
+ * Get function name from a function-like node
144
+ */
145
+ function getFunctionNameFromNode(node, sourceFile) {
146
+ if (ts.isFunctionDeclaration(node) || ts.isMethodDeclaration(node)) {
147
+ return node.name?.getText(sourceFile) ?? 'anonymous';
148
+ }
149
+ if (ts.isArrowFunction(node) || ts.isFunctionExpression(node)) {
150
+ const parent = node.parent;
151
+ if (ts.isVariableDeclaration(parent) && ts.isIdentifier(parent.name)) {
152
+ return parent.name.getText(sourceFile);
153
+ }
154
+ }
155
+ return 'anonymous';
156
+ }
157
+ /**
158
+ * Check if node is a function-like node
159
+ */
160
+ function isFunctionLikeNode(node) {
161
+ return (ts.isFunctionDeclaration(node) ||
162
+ ts.isMethodDeclaration(node) ||
163
+ ts.isArrowFunction(node) ||
164
+ ts.isFunctionExpression(node));
165
+ }
166
+ /**
167
+ * Identify TypeNodes that name an in-memory keyed collection — these are
168
+ * not shared persistent state and read+set on them is not a TOCTOU risk.
169
+ */
170
+ const IN_MEMORY_COLLECTION_TYPE_NAMES = new Set([
171
+ 'Map',
172
+ 'WeakMap',
173
+ 'ReadonlyMap',
174
+ 'Set',
175
+ 'WeakSet',
176
+ 'ReadonlySet',
177
+ ]);
178
+ function isInMemoryCollectionTypeNode(typeNode) {
179
+ if (!typeNode)
180
+ return false;
181
+ if (ts.isTypeReferenceNode(typeNode)) {
182
+ const name = typeNode.typeName;
183
+ if (ts.isIdentifier(name)) {
184
+ if (IN_MEMORY_COLLECTION_TYPE_NAMES.has(name.text))
185
+ return true;
186
+ // Type names ending in `Cache` (e.g. `SecretsCache`) are an
187
+ // OpenSIP-wide convention for in-process keyed coalescing
188
+ // structures. Treating them as local-collection eliminates the
189
+ // FP class where a service-level `cache: XCache` parameter is
190
+ // read+written within a function body.
191
+ if (name.text.endsWith('Cache'))
192
+ return true;
193
+ }
194
+ }
195
+ return false;
196
+ }
197
+ /**
198
+ * Identify variable initializers that construct an in-memory collection,
199
+ * e.g. `const counts = new Map()`, `new Set<string>()`.
200
+ */
201
+ function isInMemoryCollectionInitializer(init) {
202
+ if (!init)
203
+ return false;
204
+ if (ts.isNewExpression(init) && ts.isIdentifier(init.expression)) {
205
+ return IN_MEMORY_COLLECTION_TYPE_NAMES.has(init.expression.text);
206
+ }
207
+ return false;
208
+ }
209
+ /**
210
+ * Heuristic: a property access like `this.#cache`, `this.headerCache`,
211
+ * `this._cache` is treated as an in-process cache field. The `*Cache`
212
+ * suffix and `_cache` / `#cache` conventions are strong signals that the
213
+ * field is a coalescing in-memory structure (single-threaded Node).
214
+ *
215
+ * This is intentionally narrow: only matches `this.<name>` shapes whose
216
+ * `<name>` has the `Cache` suffix or is exactly `cache`.
217
+ */
218
+ function isInMemoryCacheReceiverText(text) {
219
+ // strip a leading `#` (private field) and `_` (convention)
220
+ const normalized = text.replace(/^[#_]/, '');
221
+ if (normalized === 'cache')
222
+ return true;
223
+ if (normalized.endsWith('Cache'))
224
+ return true;
225
+ return false;
226
+ }
227
+ /**
228
+ * Collect names of local variables/parameters within a function that
229
+ * refer to in-memory keyed collections (`Map`, `Set`, etc.). Names are
230
+ * matched against the simple receiver of `<name>.get/set/...` calls.
231
+ */
232
+ function collectLocalCollectionNames(node) {
233
+ const names = new Set();
234
+ // Parameters typed as Map/Set
235
+ for (const param of node.parameters) {
236
+ if (ts.isIdentifier(param.name) && isInMemoryCollectionTypeNode(param.type)) {
237
+ names.add(param.name.text);
238
+ }
239
+ }
240
+ // Local `const x = new Map()` / `new Set()` declarations anywhere in body.
241
+ const visit = (n) => {
242
+ // Don't descend into nested functions — their locals belong to a
243
+ // different scope.
244
+ if (n !== node && isFunctionLikeNode(n))
245
+ return;
246
+ if (ts.isVariableDeclaration(n) &&
247
+ ts.isIdentifier(n.name) &&
248
+ (isInMemoryCollectionInitializer(n.initializer) || isInMemoryCollectionTypeNode(n.type))) {
249
+ names.add(n.name.text);
250
+ }
251
+ ts.forEachChild(n, visit);
252
+ };
253
+ if (node.body)
254
+ visit(node.body);
255
+ return names;
256
+ }
257
+ /**
258
+ * Collect class-level field names that are initialized to an in-memory
259
+ * collection (`new Map()` / `new Set()`). Used so that `this.#cache`-style
260
+ * access in a method does not look like shared persistent state.
261
+ *
262
+ * Walks up to the containing ClassDeclaration / ClassExpression. Returns
263
+ * the simple field name (no `#` prefix) for matching against
264
+ * `this.<name>.get/set` receivers.
265
+ */
266
+ // eslint-disable-next-line sonarjs/cognitive-complexity -- AST walk over class members: nested type checks reflect the TypeScript AST shape
267
+ function collectClassInMemoryFieldNames(node) {
268
+ const names = new Set();
269
+ let cls = node.parent;
270
+ while (cls && !ts.isClassDeclaration(cls) && !ts.isClassExpression(cls)) {
271
+ cls = cls.parent;
272
+ }
273
+ if (!cls)
274
+ return names;
275
+ const classNode = cls;
276
+ for (const member of classNode.members) {
277
+ if (ts.isPropertyDeclaration(member)) {
278
+ const memberName = member.name;
279
+ let fieldName;
280
+ if (ts.isIdentifier(memberName)) {
281
+ fieldName = memberName.text;
282
+ }
283
+ else if (ts.isPrivateIdentifier(memberName)) {
284
+ fieldName = memberName.text.replace(/^#/, '');
285
+ }
286
+ if (!fieldName)
287
+ continue;
288
+ if (isInMemoryCollectionInitializer(member.initializer) ||
289
+ isInMemoryCollectionTypeNode(member.type)) {
290
+ names.add(fieldName);
291
+ }
292
+ }
293
+ }
294
+ return names;
295
+ }
296
+ /**
297
+ * Index file-local `interface` / `type` declarations to the set of field
298
+ * names whose declared type is an in-memory keyed collection (`Map`/`Set`/…).
299
+ *
300
+ * Used to treat `<stateObj>.<mapField>.get/set(...)` as a *local-collection*
301
+ * access. The "state bag of Maps" pattern — an interface bundling several
302
+ * `Map`/`Set` fields, threaded as a parameter through the steps of an
303
+ * iterative graph / DP algorithm (e.g. Tarjan SCC's `TarjanState`) — is
304
+ * single-threaded in-memory work, not a shared-state read-then-update race.
305
+ * The receiver `state.lowlink` is a *chained* access that the simple-receiver
306
+ * classifier would otherwise treat conservatively as shared.
307
+ */
308
+ function collectInterfaceCollectionFields(sourceFile) {
309
+ const byType = new Map();
310
+ const fieldsFrom = (members) => {
311
+ const fields = new Set();
312
+ for (const member of members) {
313
+ if (ts.isPropertySignature(member) &&
314
+ ts.isIdentifier(member.name) &&
315
+ isInMemoryCollectionTypeNode(member.type)) {
316
+ fields.add(member.name.text);
317
+ }
318
+ }
319
+ return fields;
320
+ };
321
+ for (const stmt of sourceFile.statements) {
322
+ if (ts.isInterfaceDeclaration(stmt)) {
323
+ const fields = fieldsFrom(stmt.members);
324
+ if (fields.size > 0)
325
+ byType.set(stmt.name.text, fields);
326
+ }
327
+ else if (ts.isTypeAliasDeclaration(stmt) && ts.isTypeLiteralNode(stmt.type)) {
328
+ const fields = fieldsFrom(stmt.type.members);
329
+ if (fields.size > 0)
330
+ byType.set(stmt.name.text, fields);
331
+ }
332
+ }
333
+ return byType;
334
+ }
335
+ /**
336
+ * Collect `<receiver>.<field>` keys for parameters/locals whose declared type
337
+ * is a file-local interface/type that declares `Map`/`Set` fields. Those
338
+ * `<obj>.<field>` accesses behave like local collections (see
339
+ * {@link collectInterfaceCollectionFields}).
340
+ */
341
+ function collectLocalObjectCollectionFieldKeys(node, interfaceCollectionFields) {
342
+ const keys = new Set();
343
+ const addFor = (name, typeNode) => {
344
+ if (!typeNode || !ts.isTypeReferenceNode(typeNode))
345
+ return;
346
+ if (!ts.isIdentifier(typeNode.typeName))
347
+ return;
348
+ const fields = interfaceCollectionFields.get(typeNode.typeName.text);
349
+ if (!fields)
350
+ return;
351
+ for (const field of fields)
352
+ keys.add(`${name}.${field}`);
353
+ };
354
+ for (const param of node.parameters) {
355
+ if (ts.isIdentifier(param.name))
356
+ addFor(param.name.text, param.type);
357
+ }
358
+ const visit = (n) => {
359
+ if (n !== node && isFunctionLikeNode(n))
360
+ return;
361
+ if (ts.isVariableDeclaration(n) && ts.isIdentifier(n.name))
362
+ addFor(n.name.text, n.type);
363
+ ts.forEachChild(n, visit);
364
+ };
365
+ if (node.body)
366
+ visit(node.body);
367
+ return keys;
368
+ }
369
+ /** Call-site classification kinds — narrow string literal alias set. */
370
+ const KIND_READ_SHARED = 'read-shared';
371
+ const KIND_UPDATE_SHARED = 'update-shared';
372
+ const KIND_READ_LOCAL = 'read-local';
373
+ const KIND_UPDATE_LOCAL = 'update-local';
374
+ /**
375
+ * Return true if a call expression is `<tx-or-db>.execute(sql\`...\`)`
376
+ * with a single SQL statement — those writes are atomic at the DB layer
377
+ * (single statement, no separate read-then-update window).
378
+ */
379
+ function isAtomicSqlExecute(call) {
380
+ if (!ts.isPropertyAccessExpression(call.expression))
381
+ return false;
382
+ if (call.expression.name.text !== 'execute')
383
+ return false;
384
+ const arg = call.arguments[0];
385
+ if (!arg)
386
+ return false;
387
+ if (ts.isTaggedTemplateExpression(arg) && // `sql\`...\``
388
+ ts.isIdentifier(arg.tag) &&
389
+ arg.tag.text === 'sql')
390
+ return true;
391
+ return false;
392
+ }
393
+ /**
394
+ * Drizzle-style ORM writes. `db.update(table)`, `db.insert(table)`,
395
+ * `db.delete(table)` each produce a single atomic SQL statement when
396
+ * awaited — they are not separate-read-then-update sequences.
397
+ *
398
+ * We treat these as `atomic-sql-write` so the function is not flagged
399
+ * unless there is an *actual* read-then-update on a shared receiver
400
+ * elsewhere.
401
+ */
402
+ const DRIZZLE_ATOMIC_WRITE_METHODS = new Set(['update', 'insert', 'delete']);
403
+ function isDrizzleAtomicWrite(call) {
404
+ if (!ts.isPropertyAccessExpression(call.expression))
405
+ return false;
406
+ const methodName = call.expression.name.text;
407
+ if (!DRIZZLE_ATOMIC_WRITE_METHODS.has(methodName))
408
+ return false;
409
+ // Heuristic: receiver looks like a db/tx (named `db`, `tx`, ends in `Db`/`Tx`).
410
+ const receiver = call.expression.expression;
411
+ if (ts.isIdentifier(receiver)) {
412
+ const r = receiver.text;
413
+ if (r === 'db' || r === 'tx' || /Db$|Tx$/.test(r))
414
+ return true;
415
+ }
416
+ return false;
417
+ }
418
+ /**
419
+ * Get the simple receiver name from a call expression like
420
+ * `<receiver>.method(...)`. For `this.<name>.method(...)` returns
421
+ * `this.<name>` collapsed; for `<id>.method(...)` returns `<id>`.
422
+ * Returns null if the receiver isn't a simple identifier or this-property.
423
+ */
424
+ function getReceiverName(call) {
425
+ if (!ts.isPropertyAccessExpression(call.expression))
426
+ return null;
427
+ const receiver = call.expression.expression;
428
+ if (ts.isIdentifier(receiver)) {
429
+ return { name: receiver.text, isThisField: false };
430
+ }
431
+ if (ts.isPropertyAccessExpression(receiver) &&
432
+ receiver.expression.kind === ts.SyntaxKind.ThisKeyword) {
433
+ return { name: receiver.name.text, isThisField: true };
434
+ }
435
+ // `<id>.<field>.method()` — a dotted receiver key (e.g. `state.lowlink`).
436
+ // Keying per `<id>.<field>` is strictly more precise than the old
437
+ // "deep chain → unknown receiver" fallback: a read on `x.a` and an update
438
+ // on `x.b` no longer collide, and it lets the classifier match a
439
+ // state-object's Map/Set field against the local-collection key set.
440
+ if (ts.isPropertyAccessExpression(receiver) && ts.isIdentifier(receiver.expression)) {
441
+ return { name: `${receiver.expression.text}.${receiver.name.text}`, isThisField: false };
442
+ }
443
+ return null;
444
+ }
445
+ /**
446
+ * Classify a single call expression for TOCTOU purposes.
447
+ */
448
+ function classifyCall(call, ctx) {
449
+ // First, atomic SQL writes anywhere short-circuit.
450
+ if (isAtomicSqlExecute(call))
451
+ return { kind: 'atomic-sql-write' };
452
+ if (isDrizzleAtomicWrite(call))
453
+ return { kind: 'atomic-sql-write' };
454
+ if (!ts.isPropertyAccessExpression(call.expression))
455
+ return { kind: 'unrelated' };
456
+ const methodName = call.expression.name.text;
457
+ const isRead = READ_METHODS.has(methodName);
458
+ const isUpdate = UPDATE_METHODS.has(methodName);
459
+ if (!isRead && !isUpdate)
460
+ return { kind: 'unrelated' };
461
+ const receiver = getReceiverName(call);
462
+ if (!receiver) {
463
+ // chained / non-simple receiver — treat as shared
464
+ return { kind: isRead ? KIND_READ_SHARED : KIND_UPDATE_SHARED };
465
+ }
466
+ if (isLocalReceiver(receiver, ctx)) {
467
+ return { kind: isRead ? KIND_READ_LOCAL : KIND_UPDATE_LOCAL };
468
+ }
469
+ return { kind: isRead ? KIND_READ_SHARED : KIND_UPDATE_SHARED };
470
+ }
471
+ /**
472
+ * Decide whether a classified receiver refers to a local in-memory collection
473
+ * (so reads/updates on it are not shared-state TOCTOU). Covers: local
474
+ * `Map`/`Set` names, the `<stateObj>.<mapField>` "state bag" key, `this.<cache>`
475
+ * class fields, and the `cache`-named convention.
476
+ */
477
+ function isLocalReceiver(receiver, ctx) {
478
+ if (receiver.isThisField) {
479
+ return ctx.classCacheFields.has(receiver.name) || isInMemoryCacheReceiverText(receiver.name);
480
+ }
481
+ return (ctx.localCollections.has(receiver.name) ||
482
+ // `<stateObj>.<mapField>` dotted key resolved to a file-local interface/
483
+ // type whose field is a Map/Set — the "state bag" pattern.
484
+ ctx.localObjectCollectionKeys.has(receiver.name) ||
485
+ // bare `cache` / `<X>Cache` naming convention.
486
+ isInMemoryCacheReceiverText(receiver.name));
487
+ }
488
+ /**
489
+ * Walk a function body and classify every call expression.
490
+ *
491
+ * Tracks reads and updates *per receiver* — TOCTOU is fundamentally
492
+ * read-X-then-update-X on the same shared object. A function with a
493
+ * read on receiver A and an update on receiver B is not a TOCTOU.
494
+ */
495
+ /* eslint-disable sonarjs/cognitive-complexity -- TOCTOU classifier and its inner AST visitor: branches reflect AST node taxonomy; flatter shape would hide the read/update pairing logic */
496
+ function classifyFunctionCalls(node, localCollections, classCacheFields, localObjectCollectionKeys) {
497
+ const ctx = { localCollections, classCacheFields, localObjectCollectionKeys };
498
+ // receiver-key → { read, update }. Receiver-key is `<name>` for plain
499
+ // identifiers and `this.<name>` for this-field accesses.
500
+ const perReceiver = new Map();
501
+ let hasReadOnUnknownReceiver = false;
502
+ let hasUpdateOnUnknownReceiver = false;
503
+ const visit = (n) => {
504
+ if (n !== node && isFunctionLikeNode(n))
505
+ return;
506
+ if (ts.isCallExpression(n)) {
507
+ const cls = classifyCall(n, ctx);
508
+ if (cls.kind === 'read-shared' || cls.kind === 'update-shared') {
509
+ const recv = getReceiverName(n);
510
+ if (recv) {
511
+ const key = recv.isThisField ? `this.${recv.name}` : recv.name;
512
+ let entry = perReceiver.get(key);
513
+ if (!entry) {
514
+ entry = { read: false, update: false };
515
+ perReceiver.set(key, entry);
516
+ }
517
+ if (cls.kind === 'read-shared')
518
+ entry.read = true;
519
+ else
520
+ entry.update = true;
521
+ }
522
+ else {
523
+ if (cls.kind === 'read-shared')
524
+ hasReadOnUnknownReceiver = true;
525
+ else
526
+ hasUpdateOnUnknownReceiver = true;
527
+ }
528
+ }
529
+ }
530
+ ts.forEachChild(n, visit);
531
+ };
532
+ if (node.body)
533
+ visit(node.body);
534
+ for (const entry of perReceiver.values()) {
535
+ if (entry.read && entry.update) {
536
+ return { hasSharedReadAndUpdateOnSameReceiver: true };
537
+ }
538
+ }
539
+ // Conservative fallback: if we have unknown-receiver reads paired with
540
+ // unknown-receiver updates, treat as shared (chained / dynamic call).
541
+ if (hasReadOnUnknownReceiver && hasUpdateOnUnknownReceiver) {
542
+ return { hasSharedReadAndUpdateOnSameReceiver: true };
543
+ }
544
+ return { hasSharedReadAndUpdateOnSameReceiver: false };
545
+ }
546
+ /**
547
+ * Check a function for TOCTOU patterns
548
+ */
549
+ function checkFunctionForToctou(options) {
550
+ const { node, sourceFile, interfaceCollectionFields } = options;
551
+ if (!node.body)
552
+ return null;
553
+ // Atomic-comment escape hatch retained from the regex implementation —
554
+ // a function (or its surrounding scope) that documents single-threaded
555
+ // / coalescing semantics is treated as safe.
556
+ const funcText = node.getText(sourceFile);
557
+ if (hasAtomicPatterns(funcText))
558
+ return null;
559
+ const localCollections = collectLocalCollectionNames(node);
560
+ const classCacheFields = collectClassInMemoryFieldNames(node);
561
+ const localObjectCollectionKeys = collectLocalObjectCollectionFieldKeys(node, interfaceCollectionFields);
562
+ const { hasSharedReadAndUpdateOnSameReceiver } = classifyFunctionCalls(node, localCollections, classCacheFields, localObjectCollectionKeys);
563
+ if (!hasSharedReadAndUpdateOnSameReceiver)
564
+ return null;
565
+ const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
566
+ const lineNum = line + 1;
567
+ const funcName = getFunctionNameFromNode(node, sourceFile);
568
+ return {
569
+ line: lineNum,
570
+ column: character + 1,
571
+ message: `Function '${funcName}' has read-then-update pattern without atomic guarantees`,
572
+ severity: 'warning',
573
+ suggestion: 'Use optimistic locking: pass expectedVersion to update, or use ConditionExpression for DynamoDB, or wrap in a transaction with SELECT FOR UPDATE for SQL',
574
+ match: funcName,
575
+ };
576
+ }
577
+ /**
578
+ * Analyze a file for TOCTOU race conditions. Exported for the FP-regression
579
+ * suite (see `__tests__/toctou-fp.test.ts`).
580
+ */
581
+ export function analyzeFileForToctou(filePath, content) {
582
+ const violations = [];
583
+ // Skip files in safe TOCTOU paths (caches, rate limiters, CLI, etc.).
584
+ // Merge built-in defaults with recipe config once per file.
585
+ const safePaths = buildEffectiveSafePaths();
586
+ if (isSafeToctouPath(filePath, safePaths)) {
587
+ return violations;
588
+ }
589
+ // Skip if the whole file documents atomic / single-threaded semantics.
590
+ if (hasAtomicPatterns(content)) {
591
+ return violations;
592
+ }
593
+ const sourceFile = getSharedSourceFile(filePath, content);
594
+ if (!sourceFile)
595
+ return [];
596
+ const interfaceCollectionFields = collectInterfaceCollectionFields(sourceFile);
597
+ const visit = (node) => {
598
+ if (isFunctionLikeNode(node)) {
599
+ const violation = checkFunctionForToctou({ node, sourceFile, interfaceCollectionFields });
600
+ if (violation) {
601
+ violations.push(violation);
602
+ }
603
+ }
604
+ ts.forEachChild(node, visit);
605
+ };
606
+ visit(sourceFile);
607
+ return violations;
608
+ }
609
+ /**
610
+ * Check: quality/toctou-race-condition
611
+ *
612
+ * Detects read-then-update patterns without atomic guarantees.
613
+ */
614
+ export const toctouRaceCondition = defineCheck({
615
+ id: 'eb67d6f3-c984-485d-b077-1ebabea0d894',
616
+ slug: 'toctou-race-condition',
617
+ scope: { languages: ['typescript'], concerns: ['backend', 'server'] },
618
+ contentFilter: 'strip-strings',
619
+ confidence: 'high',
620
+ description: 'Detects read-then-update patterns without atomic guarantees',
621
+ longDescription: `**Purpose:** Detects Time-of-Check-Time-of-Use (TOCTOU) race conditions where data is read then updated without atomic guarantees.
622
+
623
+ **Detects:** Walks the TypeScript AST per-function. Flags a function only when both (a) at least one read call (\`.get(\`, \`.find(\`, \`.findOne(\`, \`.findFirst(\`, \`.findMany(\`, \`.getById(\`, \`.fetch(\`, \`.load(\`, \`.read(\`) and (b) at least one update call (\`.update(\`, \`.save(\`, \`.put(\`, \`.set(\`, \`.patch(\`, \`.modify(\`) target a *shared* receiver — i.e. neither a local \`Map\`/\`Set\` declared in the function nor a parameter typed \`Map<...>\`/\`Set<...>\`, nor a class field initialized to \`new Map()\`/\`new Set()\`, nor a cache-named field (\`this.cache\`, \`this.#cache\`, \`this.<X>Cache\`). Single-statement atomic SQL writes (\`tx.execute(sql\`UPDATE...\`)\`, \`tx.update(table)\`, \`tx.insert(table)\`, \`tx.delete(table)\`) are not counted as the "update" side. Skips safe contexts: in-memory caches, rate limiters, CLI/scripts, config/registry files, and functions whose body documents atomic / single-threaded semantics (\`single-threaded coalesce\`, \`Node single-threaded\`, \`event-loop semantics\`).
624
+
625
+ **Why it matters:** TOCTOU bugs allow concurrent requests to overwrite each other's changes, causing silent data loss that only manifests under load.
626
+
627
+ **Scope:** General best practice`,
628
+ tags: ['quality', 'performance', 'best-practices'],
629
+ fileTypes: ['ts'],
630
+ // @fitness-ignore-next-line no-hardcoded-timeouts -- framework default for fitness check execution
631
+ timeout: 180_000, // 3 minutes - analyzes read-then-update patterns
632
+ analyze(content, filePath) {
633
+ // Skip test files — TOCTOU patterns in tests are low-risk
634
+ if (isTestFile(filePath))
635
+ return [];
636
+ return analyzeFileForToctou(filePath, content);
637
+ },
638
+ });
639
+ //# sourceMappingURL=toctou-race-condition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toctou-race-condition.js","sourceRoot":"","sources":["../../../../src/checks/quality/patterns/toctou-race-condition.ts"],"names":[],"mappings":"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"}