@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,227 @@
1
+ /**
2
+ * @fileoverview Detect unsafe equality comparisons on secret/token values
3
+ *
4
+ * Finds binary equality operators (=== / !==) applied to variables whose names
5
+ * suggest they hold cryptographic secrets (token, secret, signature, password,
6
+ * key). Such comparisons are vulnerable to timing attacks and must use a
7
+ * constant-time comparison function like safeCompare().
8
+ */
9
+ import { defineCheck } from '@opensip-cli/fitness';
10
+ import { parseSource, walkNodes, getIdentifierName, isLiteral, isPropertyAccess, getLineNumber, } from '@opensip-cli/lang-typescript';
11
+ import * as ts from 'typescript';
12
+ /**
13
+ * Identifier patterns that indicate a secret value.
14
+ *
15
+ * Two heuristics work together:
16
+ *
17
+ * 1. **Standalone match** β€” the whole identifier (case-insensitive)
18
+ * is an unambiguously secret-bearing name from
19
+ * `STANDALONE_SECRET_NAMES`.
20
+ *
21
+ * 2. **Compound CamelCase match** β€” the identifier splits into a
22
+ * `<securityPrefix><CamelSuffix>` shape where the prefix is in
23
+ * `SECRET_PREFIXES` and the trailing CamelCase noun ends with a
24
+ * word in `SECRET_SUFFIXES` (e.g., `apiKey`, `passwordHash`,
25
+ * `webhookSignature`).
26
+ *
27
+ * The earlier broad substring heuristic (`/secret|token|key|hash|.../i`)
28
+ * was retired because it over-fired on content-identity / cache /
29
+ * dedup variables like `cacheKey`, `bodyHash`, `ownerHash`,
30
+ * `contentHash`, `mapKey` β€” none of which are security boundaries
31
+ * (both sides are locally computed; no attacker timing channel). For
32
+ * the cases the tighter heuristic misses, mark the suspect site with
33
+ * `// @fitness-ignore-next-line unsafe-secret-comparison -- <reason>`
34
+ * (false positive) or refactor to `crypto.timingSafeEqual()` (real
35
+ * secret comparison).
36
+ *
37
+ * Sets are used instead of one big regex because the alternation
38
+ * count was tripping `sonarjs/regex-complexity` (≀ 20 alternatives).
39
+ */
40
+ const STANDALONE_SECRET_NAMES = new Set([
41
+ 'secret',
42
+ 'password',
43
+ 'token',
44
+ 'signature',
45
+ 'jwt',
46
+ 'hmac',
47
+ 'bearer',
48
+ 'sessionid',
49
+ 'csrftoken',
50
+ 'sessiontoken',
51
+ 'accesstoken',
52
+ 'refreshtoken',
53
+ 'idtoken',
54
+ 'bearertoken',
55
+ 'apikey',
56
+ 'apitoken',
57
+ 'apisecret',
58
+ 'signingkey',
59
+ 'encryptionkey',
60
+ 'privatekey',
61
+ 'publickey',
62
+ 'secretkey',
63
+ 'hmackey',
64
+ 'cookiesecret',
65
+ 'webhooksignature',
66
+ 'paymentsignature',
67
+ 'passwordhash',
68
+ 'authtoken',
69
+ ]);
70
+ const SECRET_PREFIXES = new Set([
71
+ 'secret',
72
+ 'api',
73
+ 'access',
74
+ 'refresh',
75
+ 'id',
76
+ 'bearer',
77
+ 'csrf',
78
+ 'session',
79
+ 'signing',
80
+ 'encryption',
81
+ 'private',
82
+ 'public',
83
+ 'password',
84
+ 'jwt',
85
+ 'oauth',
86
+ 'auth',
87
+ 'cookie',
88
+ 'webhook',
89
+ 'payment',
90
+ 'hmac',
91
+ 'otp',
92
+ 'mfa',
93
+ ]);
94
+ const SECRET_SUFFIXES = new Set([
95
+ 'Key',
96
+ 'Token',
97
+ 'Secret',
98
+ 'Hash',
99
+ 'Hmac',
100
+ 'Digest',
101
+ 'Signature',
102
+ 'Code',
103
+ 'Cookie',
104
+ ]);
105
+ /** Split `apiKey` β†’ `['api', 'Key']`; `accessRefreshToken` β†’ `['access', 'Refresh', 'Token']`. */
106
+ const CAMEL_SPLIT_PATTERN = /(?=[A-Z])/;
107
+ function looksLikeSecret(name) {
108
+ if (!name)
109
+ return false;
110
+ if (STANDALONE_SECRET_NAMES.has(name.toLowerCase()))
111
+ return true;
112
+ // Compound: first word is a security prefix; final word is a sensitive suffix.
113
+ const parts = name.split(CAMEL_SPLIT_PATTERN);
114
+ const last = parts.at(-1);
115
+ return (parts.length >= 2 &&
116
+ SECRET_PREFIXES.has(parts[0]) &&
117
+ last !== undefined &&
118
+ SECRET_SUFFIXES.has(last));
119
+ }
120
+ /**
121
+ * Names that look like secrets but are actually safe to compare with ===.
122
+ * E.g. `key.length`, `token !== undefined`, `tokenType === 'bearer'`.
123
+ */
124
+ const SAFE_COMPARAND_PATTERNS = [/^undefined$/, /^null$/, /^true$/, /^false$/];
125
+ /** Properties that don't carry secret data */
126
+ const SAFE_PROPERTY_NAMES = ['length', 'type', 'status', 'kind', 'name', 'id', 'count', 'size'];
127
+ /**
128
+ * Check if a comparand is a literal value or safe property access,
129
+ * which would make the comparison safe (not comparing two secret values).
130
+ */
131
+ function isLiteralOrSafe(node) {
132
+ if (isLiteral(node))
133
+ return true;
134
+ /* v8 ignore next -- defensive AST/type guard */
135
+ if (ts.isTypeOfExpression(node))
136
+ return true;
137
+ /* v8 ignore next -- defensive AST/type guard */
138
+ if (SAFE_PROPERTY_NAMES.some((prop) => isPropertyAccess(node, prop)))
139
+ return true;
140
+ const text = getIdentifierName(node);
141
+ /* v8 ignore next -- defensive AST/type guard */
142
+ if (text && SAFE_COMPARAND_PATTERNS.some((p) => p.test(text)))
143
+ return true;
144
+ return false;
145
+ }
146
+ /**
147
+ * Check if either operand has a secret-like name.
148
+ * Returns the secret-bearing operand name for the violation message, or null.
149
+ */
150
+ function findSecretOperand(left, right) {
151
+ const leftName = getIdentifierName(left);
152
+ const rightName = getIdentifierName(right);
153
+ const leftIsSecret = looksLikeSecret(leftName);
154
+ const rightIsSecret = looksLikeSecret(rightName);
155
+ if (!leftIsSecret && !rightIsSecret)
156
+ return null;
157
+ // If one side is secret but the other is a literal/safe value, skip
158
+ if (leftIsSecret && isLiteralOrSafe(right))
159
+ return null;
160
+ /* v8 ignore next -- defensive AST/type guard */
161
+ if (rightIsSecret && isLiteralOrSafe(left))
162
+ return null;
163
+ /* v8 ignore next -- defensive AST/type guard */
164
+ return leftIsSecret ? leftName : rightName;
165
+ }
166
+ /**
167
+ * Check: security/unsafe-secret-comparison
168
+ *
169
+ * Detects usage of === or !== to compare variables whose names suggest they
170
+ * hold cryptographic secrets. Such comparisons are vulnerable to timing
171
+ * side-channel attacks.
172
+ */
173
+ export const unsafeSecretComparison = defineCheck({
174
+ id: '0249cfc8-5342-480a-a9d0-fbf7ad89a6cf',
175
+ slug: 'unsafe-secret-comparison',
176
+ scope: { languages: ['typescript'], concerns: ['backend', 'server'] },
177
+ contentFilter: 'strip-strings',
178
+ confidence: 'high',
179
+ description: 'Detect timing-unsafe equality comparisons on secret/token values',
180
+ longDescription: `**Purpose:** Detects \`===\` or \`!==\` comparisons on variables whose names suggest they hold cryptographic secrets, which are vulnerable to timing side-channel attacks.
181
+
182
+ **Detects:**
183
+ - Binary expressions using \`===\` or \`!==\` where either operand name matches:
184
+ - **Standalone:** \`secret\`, \`password\`, \`token\`, \`signature\`, \`jwt\`, \`hmac\`, \`bearer\`, \`apiKey\`, \`apiToken\`, \`apiSecret\`, \`accessToken\`, \`refreshToken\`, \`idToken\`, \`bearerToken\`, \`sessionToken\`, \`sessionId\`, \`csrfToken\`, \`signingKey\`, \`encryptionKey\`, \`privateKey\`, \`publicKey\`, \`secretKey\`, \`hmacKey\`, \`cookieSecret\`, \`webhookSignature\`, \`paymentSignature\`, \`passwordHash\`, \`authToken\` (case-insensitive)
185
+ - **Compound CamelCase:** a security-context prefix (\`secret\`, \`api\`, \`access\`, \`refresh\`, \`id\`, \`bearer\`, \`csrf\`, \`session\`, \`signing\`, \`encryption\`, \`private\`, \`public\`, \`password\`, \`jwt\`, \`oauth\`, \`auth\`, \`cookie\`, \`webhook\`, \`payment\`, \`hmac\`, \`otp\`, \`mfa\`) paired with a sensitive-data suffix (\`Key\`, \`Token\`, \`Secret\`, \`Hash\`, \`Hmac\`, \`Digest\`, \`Signature\`, \`Code\`, \`Cookie\`).
186
+ - Excludes comparisons against literals, \`undefined\`, \`null\`, \`true\`, \`false\`, \`typeof\`, and safe property accesses (.length, .type, .status, .kind, .name, .id, .count, .size)
187
+ - **Does NOT fire on** generic identity / cache / dedup hashes like \`cacheKey\`, \`bodyHash\`, \`ownerHash\`, \`contentHash\`, \`mapKey\` β€” both sides are locally computed, no attacker timing channel.
188
+
189
+ **Why it matters:** Standard equality operators short-circuit on the first differing byte, leaking information about how much of a secret value matches. Attackers can reconstruct secrets one byte at a time using timing measurements.
190
+
191
+ **False negatives:** If you compare a real secret under a name the heuristic doesn't recognize (e.g., a custom domain term), the check will miss it β€” switching to \`crypto.timingSafeEqual()\` everywhere you compare attacker-influenced values against trusted ones is the durable fix; this check is a tripwire, not a guarantee.
192
+
193
+ **False positives:** If the check fires on a content-identity variable the heuristic doesn't yet skip, annotate with \`// @fitness-ignore-next-line unsafe-secret-comparison -- <reason>\` (preferred) or rename the variable to make the non-secret intent explicit.
194
+
195
+ **Scope:** General best practice. Analyzes each file individually using TypeScript AST. Targets auth, middleware, token service, and crypto directories β€” i.e., wherever the project's targets attach a \`backend\` or \`server\` concern.`,
196
+ tags: ['security', 'timing-attack', 'crypto'],
197
+ fileTypes: ['ts'],
198
+ analyze(content, filePath) {
199
+ const sourceFile = parseSource(content, filePath);
200
+ /* v8 ignore next -- defensive guard */
201
+ if (!sourceFile)
202
+ return [];
203
+ const violations = [];
204
+ walkNodes(sourceFile, (node) => {
205
+ if (ts.isBinaryExpression(node) &&
206
+ (node.operatorToken.kind === ts.SyntaxKind.EqualsEqualsEqualsToken ||
207
+ node.operatorToken.kind === ts.SyntaxKind.ExclamationEqualsEqualsToken)) {
208
+ const secretName = findSecretOperand(node.left, node.right);
209
+ if (secretName) {
210
+ const line = getLineNumber(node, sourceFile);
211
+ const operator = node.operatorToken.kind === ts.SyntaxKind.EqualsEqualsEqualsToken ? '===' : '!==';
212
+ violations.push({
213
+ line,
214
+ column: node.operatorToken.getStart() - node.getStart(),
215
+ message: `Timing-unsafe ${operator} comparison on '${secretName}' β€” use crypto.timingSafeEqual() (Node.js built-in)`,
216
+ severity: 'error',
217
+ suggestion: `Replace \`a ${operator} b\` with \`${operator === '!==' ? '!' : ''}safeCompare(a, b)\` to prevent timing side-channel attacks.`,
218
+ match: node.getText(),
219
+ filePath,
220
+ });
221
+ }
222
+ }
223
+ });
224
+ return violations;
225
+ },
226
+ });
227
+ //# sourceMappingURL=unsafe-secret-comparison.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unsafe-secret-comparison.js","sourceRoot":"","sources":["../../../src/checks/security/unsafe-secret-comparison.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export * from './mock-implementations-in-production.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/checks/testing/index.ts"],"names":[],"mappings":"AAAA,cAAc,yCAAyC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from './mock-implementations-in-production.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/checks/testing/index.ts"],"names":[],"mappings":"AAAA,cAAc,yCAAyC,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @fileoverview Detects mock, stub, or fake implementations in production code
3
+ *
4
+ * Mock implementations should only exist in test files, not production code.
5
+ */
6
+ /**
7
+ * Check: testing/mock-implementations-in-production
8
+ *
9
+ * Detects mock, stub, or fake implementations in production code.
10
+ */
11
+ export declare const mockImplementationsInProduction: import("@opensip-cli/fitness").Check;
12
+ //# sourceMappingURL=mock-implementations-in-production.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock-implementations-in-production.d.ts","sourceRoot":"","sources":["../../../src/checks/testing/mock-implementations-in-production.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAwMH;;;;GAIG;AACH,eAAO,MAAM,+BAA+B,sCA6B1C,CAAC"}
@@ -0,0 +1,211 @@
1
+ /**
2
+ * @fileoverview Detects mock, stub, or fake implementations in production code
3
+ *
4
+ * Mock implementations should only exist in test files, not production code.
5
+ */
6
+ import { logger } from '@opensip-cli/core';
7
+ import { defineCheck, isTestFile } from '@opensip-cli/fitness';
8
+ import { getSharedSourceFile } from '@opensip-cli/lang-typescript';
9
+ import * as ts from 'typescript';
10
+ /**
11
+ * Pre-compiled regex patterns for detecting mock implementations.
12
+ * These patterns are intentional and safe for static code analysis.
13
+ * Using explicit anchors and bounded quantifiers to prevent ReDoS.
14
+ */
15
+ // Pattern: MockXxx or XxxMock class names (grouped for proper anchor precedence)
16
+ const MOCK_CLASS_PATTERN = /^(?:(?:Mock|Fake|Stub|Dummy)[A-Z]|[A-Z]\w{0,100}(?:Mock|Fake|Stub|Dummy))$/;
17
+ // Pattern: mock/fake/stub/dummy method names
18
+ const MOCK_METHOD_PATTERN = /^(?:mock|fake|stub|dummy)/i;
19
+ // Pattern: mock function names (grouped for proper anchor precedence)
20
+ const MOCK_FUNCTION_PATTERN = /^(?:(?:mock|fake|stub|dummy)[A-Z]|create(?:Mock|Fake|Stub|Dummy))/i;
21
+ // Pattern: stub implementations that throw "Not implemented" errors
22
+ const STUB_IMPL_PATTERN = /throw new Error\(['"]Not implemented['"]\)/i;
23
+ // Pattern: mock/test data returns - using bounded quantifier to prevent backtracking
24
+ const MOCK_DATA_PATTERN = /return\s{0,10}\{[^}]{0,500}\b(?:mock|test|fake)\s{0,10}:/i;
25
+ /**
26
+ * Check if a file should be analyzed for mock implementations
27
+ * @param filePath - Path to check
28
+ * @returns True if the file should be analyzed
29
+ */
30
+ function shouldAnalyzeFile(filePath) {
31
+ logger.debug({
32
+ evt: 'fitness.checks.mock_in_production.should_analyze_file',
33
+ msg: 'Checking if file should be analyzed for mock implementations',
34
+ });
35
+ // Skip test files and test directories (mocks are allowed in tests)
36
+ if (isTestFile(filePath)) {
37
+ return false;
38
+ }
39
+ // Skip type definition files
40
+ if (filePath.endsWith('.d.ts')) {
41
+ return false;
42
+ }
43
+ // Only check TypeScript files
44
+ return filePath.endsWith('.ts') || filePath.endsWith('.tsx');
45
+ }
46
+ /**
47
+ * Analyze a file for mock implementations
48
+ */
49
+ function analyzeFile(content, filePath) {
50
+ logger.debug({
51
+ evt: 'fitness.checks.mock_in_production.analyze_file',
52
+ msg: 'Analyzing file for mock implementations',
53
+ });
54
+ const violations = [];
55
+ if (!shouldAnalyzeFile(filePath)) {
56
+ return violations;
57
+ }
58
+ try {
59
+ const sourceFile = getSharedSourceFile(filePath, content);
60
+ /* v8 ignore next -- defensive guard */
61
+ if (!sourceFile)
62
+ return [];
63
+ const checkClassForMock = (node) => {
64
+ logger.debug({
65
+ evt: 'fitness.checks.mock_in_production.check_class_for_mock',
66
+ msg: 'Checking class declaration for mock patterns',
67
+ });
68
+ /* v8 ignore next -- defensive AST/type guard */
69
+ if (!node.name)
70
+ return;
71
+ const className = node.name.text;
72
+ // Check class name patterns
73
+ if (MOCK_CLASS_PATTERN.test(className)) {
74
+ const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
75
+ violations.push({
76
+ line: line + 1,
77
+ message: `Mock class '${className}' found in production code (should be in test files only)`,
78
+ severity: 'error',
79
+ type: 'mock-class',
80
+ suggestion: `Move '${className}' to a test file (e.g., __tests__/unit/) or test utilities directory`,
81
+ match: className,
82
+ });
83
+ return;
84
+ }
85
+ // Check if class has methods that return mock data
86
+ for (const member of node.members) {
87
+ if (ts.isMethodDeclaration(member) && ts.isIdentifier(member.name)) {
88
+ checkMethodForMock(member, className, sourceFile);
89
+ }
90
+ }
91
+ };
92
+ const checkMethodForMock = (member, className, sf) => {
93
+ logger.debug({
94
+ evt: 'fitness.checks.mock_in_production.check_method_for_mock',
95
+ msg: 'Checking method declaration for mock patterns',
96
+ });
97
+ const methodName = member.name.text;
98
+ // Check for mock/stub methods
99
+ if (MOCK_METHOD_PATTERN.test(methodName)) {
100
+ const { line } = sf.getLineAndCharacterOfPosition(member.getStart());
101
+ violations.push({
102
+ line: line + 1,
103
+ message: `Mock method '${className}.${methodName}' found in production code`,
104
+ severity: 'error',
105
+ type: 'mock-function',
106
+ suggestion: `Move '${methodName}' method to a test file or rename it to not use mock/fake/stub/dummy prefix`,
107
+ match: methodName,
108
+ });
109
+ }
110
+ // Check method body for stub implementations
111
+ if (member.body) {
112
+ const bodyText = member.body.getText(sf);
113
+ // Check for "Not implemented" stub patterns
114
+ if (STUB_IMPL_PATTERN.test(bodyText)) {
115
+ const { line } = sf.getLineAndCharacterOfPosition(member.getStart());
116
+ violations.push({
117
+ line: line + 1,
118
+ message: `Stub implementation in '${className}.${methodName}' (throws "Not implemented")`,
119
+ severity: 'error',
120
+ type: 'stub-implementation',
121
+ suggestion: `Implement the method '${methodName}' properly or move stub to test files if it's for testing only`,
122
+ match: `${className}.${methodName}`,
123
+ });
124
+ }
125
+ // Check for methods that always return mock data
126
+ if (MOCK_DATA_PATTERN.test(bodyText)) {
127
+ const { line } = sf.getLineAndCharacterOfPosition(member.getStart());
128
+ violations.push({
129
+ line: line + 1,
130
+ message: `Method '${className}.${methodName}' returns hardcoded mock/test data`,
131
+ severity: 'error',
132
+ type: 'fake-data',
133
+ suggestion: `Replace hardcoded mock/test data in '${methodName}' with real implementation or move to test files`,
134
+ match: `${className}.${methodName}`,
135
+ });
136
+ }
137
+ }
138
+ };
139
+ const checkFunctionForMock = (node) => {
140
+ logger.debug({
141
+ evt: 'fitness.checks.mock_in_production.check_function_for_mock',
142
+ msg: 'Checking function declaration for mock patterns',
143
+ });
144
+ /* v8 ignore next -- defensive AST/type guard */
145
+ if (!node.name)
146
+ return;
147
+ const functionName = node.name.text;
148
+ // Check function name patterns
149
+ if (MOCK_FUNCTION_PATTERN.test(functionName)) {
150
+ const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
151
+ violations.push({
152
+ line: line + 1,
153
+ message: `Mock function '${functionName}' found in production code (should be in test utilities only)`,
154
+ severity: 'error',
155
+ type: 'mock-function',
156
+ suggestion: `Move '${functionName}' to a test file (e.g., __tests__/unit/) or test utilities directory`,
157
+ match: functionName,
158
+ });
159
+ }
160
+ };
161
+ const visit = (node) => {
162
+ if (ts.isClassDeclaration(node) && node.name) {
163
+ checkClassForMock(node);
164
+ }
165
+ if (ts.isFunctionDeclaration(node) && node.name) {
166
+ checkFunctionForMock(node);
167
+ }
168
+ ts.forEachChild(node, visit);
169
+ };
170
+ visit(sourceFile);
171
+ /* v8 ignore next 1 -- defensive catch: parse failures already handled */
172
+ }
173
+ catch {
174
+ // @swallow-ok If AST parsing fails, skip this file
175
+ }
176
+ return violations;
177
+ }
178
+ /**
179
+ * Check: testing/mock-implementations-in-production
180
+ *
181
+ * Detects mock, stub, or fake implementations in production code.
182
+ */
183
+ export const mockImplementationsInProduction = defineCheck({
184
+ id: 'f7507280-993b-4dde-9270-52b30478cca8',
185
+ slug: 'mock-implementations-in-production',
186
+ scope: { languages: ['typescript'], concerns: ['backend', 'server'] },
187
+ // 'raw', not 'strip-strings': STUB_IMPL_PATTERN matches the exact sentinel
188
+ // string inside `throw new Error("Not implemented")` (and MOCK_DATA looks
189
+ // for keys in object returns). Stripping blanks the string content in the
190
+ // parsed source used for body.getText(), so the patterns would never match
191
+ // even for real placeholder stubs in prod code.
192
+ contentFilter: 'raw',
193
+ confidence: 'high',
194
+ description: 'Detects mock, stub, or fake implementations in production code',
195
+ longDescription: `**Purpose:** Ensures mock, stub, fake, and dummy implementations exist only in test files, not in production source code.
196
+
197
+ **Detects:**
198
+ - Classes named with Mock/Fake/Stub/Dummy prefixes or suffixes via \`/^(?:(?:Mock|Fake|Stub|Dummy)[A-Z]|[A-Z]\\w{0,100}(?:Mock|Fake|Stub|Dummy))$/\`
199
+ - Methods prefixed with mock/fake/stub/dummy via \`/^(?:mock|fake|stub|dummy)/i\`
200
+ - Functions named \`mockXxx\`, \`fakeXxx\`, \`createMock\`, \`createFake\`, etc. via \`/^(?:(?:mock|fake|stub|dummy)[A-Z]|create(?:Mock|Fake|Stub|Dummy))/i\`
201
+ - Stub methods that \`throw new Error('Not implemented')\`
202
+ - Methods returning hardcoded objects with \`mock\`, \`test\`, or \`fake\` keys
203
+
204
+ **Why it matters:** Mock implementations in production code indicate incomplete refactoring or testing artifacts leaking into shipped code, leading to unreliable runtime behavior.
205
+
206
+ **Scope:** General best practice. Analyzes each file individually via TypeScript AST parsing, skipping test files, \`.d.ts\` files, and excluded test directories.`,
207
+ tags: ['testing', 'code-quality'],
208
+ fileTypes: ['ts', 'tsx'],
209
+ analyze: analyzeFile,
210
+ });
211
+ //# sourceMappingURL=mock-implementations-in-production.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock-implementations-in-production.js","sourceRoot":"","sources":["../../../src/checks/testing/mock-implementations-in-production.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @fileoverview Display entries for TypeScript-specific architecture checks
3
+ */
4
+ import type { CheckDisplayEntry } from './types.js';
5
+ /** Architecture check display entries (TS_AST only) */
6
+ export declare const ARCHITECTURE_DISPLAY: Readonly<Record<string, CheckDisplayEntry>>;
7
+ /** No documentation TS_AST checks; export empty object for symmetry */
8
+ export declare const DOCUMENTATION_DISPLAY: Readonly<Record<string, CheckDisplayEntry>>;
9
+ //# sourceMappingURL=architecture.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"architecture.d.ts","sourceRoot":"","sources":["../../src/display/architecture.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,uDAAuD;AACvD,eAAO,MAAM,oBAAoB,6CAU/B,CAAC;AAEH,uEAAuE;AACvE,eAAO,MAAM,qBAAqB,6CAAuD,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @fileoverview Display entries for TypeScript-specific architecture checks
3
+ */
4
+ /** Architecture check display entries (TS_AST only) */
5
+ export const ARCHITECTURE_DISPLAY = Object.freeze({
6
+ 'circular-import-detection': ['πŸ”', 'Circular Import Detection'],
7
+ 'contracts-schema-consistency': ['πŸ“‹', 'Contracts Schema Consistency'],
8
+ 'drizzle-orm-migration-guardrails': ['πŸ›‘οΈ', 'Drizzle ORM Migration Guardrails'],
9
+ 'missing-type-exports': ['πŸ“€', 'Missing Type Exports'],
10
+ 'module-coupling-fan-out': ['πŸ•ΈοΈ', 'Module Coupling Fan-Out'],
11
+ 'no-bootstrap-tool-import': ['πŸ”Œ', 'No Bootstrap Tool Import'],
12
+ 'package-json-exports-field': ['πŸ“¦', 'package.json Exports Field'],
13
+ 'phantom-dependency-detection': ['πŸ“¦', 'Phantom Dependency Detection'],
14
+ 'tsconfig-extends-validation': ['βš™οΈ', 'tsconfig Extends Validation'],
15
+ });
16
+ /** No documentation TS_AST checks; export empty object for symmetry */
17
+ export const DOCUMENTATION_DISPLAY = Object.freeze({});
18
+ //# sourceMappingURL=architecture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"architecture.js","sourceRoot":"","sources":["../../src/display/architecture.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,uDAAuD;AACvD,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAM,CAAC,MAAM,CAAoC;IACnF,2BAA2B,EAAE,CAAC,IAAI,EAAE,2BAA2B,CAAC;IAChE,8BAA8B,EAAE,CAAC,IAAI,EAAE,8BAA8B,CAAC;IACtE,kCAAkC,EAAE,CAAC,KAAK,EAAE,kCAAkC,CAAC;IAC/E,sBAAsB,EAAE,CAAC,IAAI,EAAE,sBAAsB,CAAC;IACtD,yBAAyB,EAAE,CAAC,KAAK,EAAE,yBAAyB,CAAC;IAC7D,0BAA0B,EAAE,CAAC,IAAI,EAAE,0BAA0B,CAAC;IAC9D,4BAA4B,EAAE,CAAC,IAAI,EAAE,4BAA4B,CAAC;IAClE,8BAA8B,EAAE,CAAC,IAAI,EAAE,8BAA8B,CAAC;IACtE,6BAA6B,EAAE,CAAC,IAAI,EAAE,6BAA6B,CAAC;CACrE,CAAC,CAAC;AAEH,uEAAuE;AACvE,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAM,CAAC,MAAM,CAAoC,EAAE,CAAC,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * @fileoverview Display configuration for fitness checks
3
+ *
4
+ * Maps check slugs to display entries (icon + display name) for CLI and dashboard output.
5
+ * Falls back to kebab-to-title-case conversion for unknown slugs.
6
+ *
7
+ * The lookup logic itself lives in @opensip-cli/fitness/check-utils; this
8
+ * file owns only the per-pack CHECK_DISPLAY map and binds the shared helpers
9
+ * to it.
10
+ */
11
+ import type { CheckDisplayEntry } from './types.js';
12
+ /** Combined check display configuration */
13
+ export declare const CHECK_DISPLAY: Readonly<Record<string, CheckDisplayEntry>>;
14
+ /**
15
+ * Slug-only display lookups bound to this pack's CHECK_DISPLAY map. The lookup
16
+ * logic lives in @opensip-cli/fitness; this file owns only the data.
17
+ */
18
+ export declare const getCheckIcon: (checkSlug: string) => string, getCheckDisplayName: (checkSlug: string) => string;
19
+ export { type CheckDisplayEntry } from './types.js';
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/display/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AASH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,2CAA2C;AAC3C,eAAO,MAAM,aAAa,6CAOxB,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAQ,YAAY,iCAAE,mBAAmB,+BAAsC,CAAC;AAEvF,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * @fileoverview Display configuration for fitness checks
3
+ *
4
+ * Maps check slugs to display entries (icon + display name) for CLI and dashboard output.
5
+ * Falls back to kebab-to-title-case conversion for unknown slugs.
6
+ *
7
+ * The lookup logic itself lives in @opensip-cli/fitness/check-utils; this
8
+ * file owns only the per-pack CHECK_DISPLAY map and binds the shared helpers
9
+ * to it.
10
+ */
11
+ import { makeDisplayHelpers } from '@opensip-cli/fitness';
12
+ import { ARCHITECTURE_DISPLAY, DOCUMENTATION_DISPLAY } from './architecture.js';
13
+ import { QUALITY_DISPLAY } from './quality.js';
14
+ import { RESILIENCE_DISPLAY } from './resilience.js';
15
+ import { SECURITY_DISPLAY, TESTING_DISPLAY } from './security-testing.js';
16
+ /** Combined check display configuration */
17
+ export const CHECK_DISPLAY = Object.freeze({
18
+ ...ARCHITECTURE_DISPLAY,
19
+ ...DOCUMENTATION_DISPLAY,
20
+ ...QUALITY_DISPLAY,
21
+ ...RESILIENCE_DISPLAY,
22
+ ...SECURITY_DISPLAY,
23
+ ...TESTING_DISPLAY,
24
+ });
25
+ /**
26
+ * Slug-only display lookups bound to this pack's CHECK_DISPLAY map. The lookup
27
+ * logic lives in @opensip-cli/fitness; this file owns only the data.
28
+ */
29
+ export const { getCheckIcon, getCheckDisplayName } = makeDisplayHelpers(CHECK_DISPLAY);
30
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/display/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAChF,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAI1E,2CAA2C;AAC3C,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAoC;IAC5E,GAAG,oBAAoB;IACvB,GAAG,qBAAqB;IACxB,GAAG,eAAe;IAClB,GAAG,kBAAkB;IACrB,GAAG,gBAAgB;IACnB,GAAG,eAAe;CACnB,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,EAAE,YAAY,EAAE,mBAAmB,EAAE,GAAG,kBAAkB,CAAC,aAAa,CAAC,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @fileoverview Display entries for TypeScript-specific quality checks
3
+ */
4
+ import type { CheckDisplayEntry } from './types.js';
5
+ /** Quality check display entries (TS_AST only, sorted alphabetically by slug) */
6
+ export declare const QUALITY_DISPLAY: Readonly<Record<string, CheckDisplayEntry>>;
7
+ //# sourceMappingURL=quality.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quality.d.ts","sourceRoot":"","sources":["../../src/display/quality.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,iFAAiF;AACjF,eAAO,MAAM,eAAe,6CAiC1B,CAAC"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * @fileoverview Display entries for TypeScript-specific quality checks
3
+ */
4
+ /** Quality check display entries (TS_AST only, sorted alphabetically by slug) */
5
+ export const QUALITY_DISPLAY = Object.freeze({
6
+ 'a11y-form-labels': ['β™Ώ', 'A11y Form Labels'],
7
+ 'a11y-semantic-html': ['β™Ώ', 'A11y Semantic HTML'],
8
+ 'api-contract-validation': ['πŸ”Œ', 'API Contract Validation'],
9
+ 'api-response-validation': ['πŸ”Œ', 'API Response Validation'],
10
+ 'array-validation': ['πŸ“¦', 'Array Parameter Validation'],
11
+ 'async-waterfall-detection': ['⚑', 'Async Waterfall Detection'],
12
+ 'database-index-coverage': ['πŸ—„οΈ', 'Database Index Coverage'],
13
+ 'database-schema-validation': ['πŸ—„οΈ', 'Database Schema Validation'],
14
+ 'dispose-pattern-completeness': ['🧹', 'Dispose Pattern Completeness'],
15
+ 'duplicate-utility-functions': ['πŸ”', 'Duplicate Utility Functions'],
16
+ 'error-handling-quality': ['⚠️', 'Error Handling Quality'],
17
+ 'fastify-route-validation': ['πŸ”Œ', 'Fastify Route Validation'],
18
+ 'fastify-schema-coverage': ['πŸ”Œ', 'Fastify Schema Coverage'],
19
+ 'in-memory-repository-detection': ['πŸ’Ύ', 'In-Memory Repository Detection'],
20
+ 'incomplete-regex-escaping': ['πŸ”’', 'Incomplete Regex Escaping'],
21
+ 'lifecycle-cleanup-enforcement': ['🧹', 'Lifecycle Cleanup Enforcement'],
22
+ 'logger-event-name-format': ['πŸ“Š', 'Logger Event Name Format'],
23
+ 'missing-input-validation': ['πŸ›‘οΈ', 'Missing Input Validation'],
24
+ 'no-any-types': ['πŸ“˜', 'No Any Types'],
25
+ 'no-hardcoded-correlation-id': ['πŸ”—', 'No Hardcoded Correlation Id'],
26
+ 'null-safety': ['πŸ›‘οΈ', 'Null/Undefined Safety'],
27
+ 'numeric-validation': ['πŸ”’', 'Numeric Parameter Validation'],
28
+ 'pii-exposure-in-logs': ['πŸ”’', 'PII Exposure in Logs'],
29
+ 'result-pattern-consistency': ['πŸ“‹', 'Result Pattern Consistency'],
30
+ 'silent-early-returns': ['πŸ”', 'Silent Early Returns'],
31
+ 'stream-buffer-size-limits': ['πŸ›‘οΈ', 'Stream Buffer Size Limits'],
32
+ 'stubbed-implementation-detection': ['πŸ”', 'Stubbed Implementation Detection'],
33
+ 'test-only-frontend-modules': ['πŸ§ͺ', 'Test-Only Frontend Modules'],
34
+ 'throws-documentation': ['πŸ“', 'Missing @throws JSDoc Detection'],
35
+ 'toctou-race-condition': ['⚑', 'TOCTOU Race Condition Detection'],
36
+ 'typescript-frontend': ['πŸ“˜', 'TypeScript Frontend'],
37
+ 'unused-config-options': ['βš™οΈ', 'Unused Configuration Options'],
38
+ });
39
+ //# sourceMappingURL=quality.js.map