@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,298 @@
1
+ // @fitness-ignore-file correlation-id-coverage -- Fitness check implementation, not an API handler
2
+ // @fitness-ignore-file fastify-schema-coverage -- schema definitions to be added in schema coverage sprint
3
+ // @fitness-ignore-file duplicate-utility-functions -- reviewed: route-analysis and validation-detection helpers are check-specific logic, not general-purpose utilities
4
+ /**
5
+ * @fileoverview Fastify Route Validation Check
6
+ *
7
+ * Ensures all Fastify POST/PATCH/PUT route handlers validate request bodies
8
+ * using Zod schemas.
9
+ */
10
+ import { defineCheck, isTestFile } from '@opensip-cli/fitness';
11
+ import { getSharedSourceFile } from '@opensip-cli/lang-typescript';
12
+ import * as ts from 'typescript';
13
+ /**
14
+ * Quick filter regex to check if file might contain Fastify routes
15
+ */
16
+ const QUICK_FILTER_PATTERNS = /fastify\.(post|patch|put)|\.post\(|\.patch\(|\.put\(/i;
17
+ /**
18
+ * Patterns that indicate Zod validation is present
19
+ */
20
+ const ZOD_VALIDATION_PATTERNS = [
21
+ /\.parse\s*\(/,
22
+ /\.safeParse\s*\(/,
23
+ /Schema\.parse/,
24
+ /Schema\.safeParse/,
25
+ /z\.\w+\(\)/,
26
+ ];
27
+ /**
28
+ * Patterns that indicate other validation libraries are present
29
+ */
30
+ const OTHER_VALIDATION_PATTERNS = [
31
+ /\.validate\s*\(/,
32
+ /validateBody\s*\(/,
33
+ /validateRequest\s*\(/,
34
+ /validateInput\s*\(/,
35
+ ];
36
+ /**
37
+ * Extract route information from a call expression
38
+ * @param node - TypeScript CallExpression node to extract from
39
+ * @param sourceFile - TypeScript SourceFile for position information
40
+ * @returns RouteInfo object if this is a route call, null otherwise
41
+ */
42
+ // eslint-disable-next-line sonarjs/cognitive-complexity -- AST traversal with multiple node-type checks and nested property extraction
43
+ function extractRouteInfo(node, sourceFile) {
44
+ if (!ts.isPropertyAccessExpression(node.expression)) {
45
+ return null;
46
+ }
47
+ const methodName = node.expression.name.text.toLowerCase();
48
+ if (!['post', 'patch', 'put'].includes(methodName)) {
49
+ return null;
50
+ }
51
+ const method = methodName.toUpperCase();
52
+ const args = node.arguments;
53
+ if (args.length < 2) {
54
+ return null;
55
+ }
56
+ let routePath = 'unknown';
57
+ const firstArg = args[0];
58
+ if (firstArg && ts.isStringLiteral(firstArg)) {
59
+ routePath = firstArg.text;
60
+ }
61
+ let handlerNode = null;
62
+ let hasSchemaOption = false;
63
+ const secondArg = args[1];
64
+ if (secondArg) {
65
+ if (ts.isArrowFunction(secondArg) || ts.isFunctionExpression(secondArg)) {
66
+ handlerNode = secondArg;
67
+ }
68
+ else if (ts.isObjectLiteralExpression(secondArg)) {
69
+ // Check for schema: { body: ... } in the options object (fastify-type-provider-zod pattern)
70
+ hasSchemaOption = secondArg.properties.some((prop) => {
71
+ /* v8 ignore next -- defensive AST/type guard */
72
+ if (!ts.isPropertyAssignment(prop))
73
+ return false;
74
+ const name = prop.name;
75
+ /* v8 ignore next -- defensive AST/type guard */
76
+ if (!ts.isIdentifier(name) || name.text !== 'schema')
77
+ return false;
78
+ // Check if the schema object has a 'body' property
79
+ if (ts.isObjectLiteralExpression(prop.initializer)) {
80
+ return prop.initializer.properties.some((schemaProp) => ts.isPropertyAssignment(schemaProp) &&
81
+ ts.isIdentifier(schemaProp.name) &&
82
+ schemaProp.name.text === 'body');
83
+ }
84
+ return false;
85
+ });
86
+ if (args[2]) {
87
+ const thirdArg = args[2];
88
+ /* v8 ignore next -- defensive AST/type guard */
89
+ if (ts.isArrowFunction(thirdArg) || ts.isFunctionExpression(thirdArg)) {
90
+ handlerNode = thirdArg;
91
+ }
92
+ }
93
+ }
94
+ else {
95
+ // Other argument types - handler not found
96
+ }
97
+ }
98
+ const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
99
+ return {
100
+ method,
101
+ path: routePath,
102
+ line: line + 1,
103
+ handlerNode,
104
+ hasSchemaOption,
105
+ };
106
+ }
107
+ /**
108
+ * Check if text matches any validation pattern
109
+ * @param text - Text to check against patterns
110
+ * @param patterns - Array of patterns to test
111
+ * @returns true if any pattern matches
112
+ */
113
+ function matchesAnyPattern(text, patterns) {
114
+ return patterns.some((pattern) => pattern.test(text));
115
+ }
116
+ /**
117
+ * Check if handler has validation after request.body access
118
+ * @param handlerText - Handler text to analyze
119
+ * @returns true if validation found after body access
120
+ */
121
+ function hasValidationAfterBodyAccess(handlerText) {
122
+ if (!handlerText.includes('request.body')) {
123
+ return false;
124
+ }
125
+ const bodyAccessIndex = handlerText.indexOf('request.body');
126
+ const afterBodyAccess = handlerText.slice(bodyAccessIndex);
127
+ const allPatterns = [...ZOD_VALIDATION_PATTERNS, ...OTHER_VALIDATION_PATTERNS];
128
+ if (matchesAnyPattern(afterBodyAccess, allPatterns)) {
129
+ return true;
130
+ }
131
+ // Check for manual validation with if statement - simple non-backtracking check
132
+ return afterBodyAccess.includes('if') && afterBodyAccess.includes('!');
133
+ }
134
+ /**
135
+ * Check if handler has 400 status response with validation message
136
+ * @param handlerText - Handler text to analyze
137
+ * @returns true if validation response pattern found
138
+ */
139
+ function hasValidationResponse(handlerText) {
140
+ // Use indexOf for simple string checks to avoid regex complexity
141
+ const has400Code = handlerText.includes('reply.code') && handlerText.includes('400');
142
+ const hasValidationMessage = handlerText.includes('Missing') ||
143
+ handlerText.includes('Invalid') ||
144
+ handlerText.includes('required');
145
+ /* v8 ignore next -- defensive AST/type guard */
146
+ return has400Code && hasValidationMessage;
147
+ }
148
+ /**
149
+ * Check if a handler has validation
150
+ * @param handlerNode - TypeScript node of the handler or null
151
+ * @param sourceFile - TypeScript SourceFile for context
152
+ * @param fullContent - Full file content as string
153
+ * @returns true if validation is found, false otherwise
154
+ */
155
+ function checkForValidation(handlerNode, sourceFile, fullContent) {
156
+ if (!handlerNode) {
157
+ return hasValidationInContent(fullContent);
158
+ }
159
+ const handlerText = handlerNode.getText(sourceFile);
160
+ if (matchesAnyPattern(handlerText, ZOD_VALIDATION_PATTERNS)) {
161
+ return true;
162
+ }
163
+ if (matchesAnyPattern(handlerText, OTHER_VALIDATION_PATTERNS)) {
164
+ return true;
165
+ }
166
+ if (hasValidationAfterBodyAccess(handlerText)) {
167
+ return true;
168
+ }
169
+ return hasValidationResponse(handlerText);
170
+ }
171
+ function hasValidationInContent(content) {
172
+ if (content.includes('contracts') && content.includes('Schema')) {
173
+ return true;
174
+ }
175
+ if (content.includes('zod') && content.includes('.parse(')) {
176
+ return true;
177
+ }
178
+ return false;
179
+ }
180
+ /**
181
+ * Create a violation for a route missing validation
182
+ * @param routeInfo - Route information
183
+ * @param filePath - Path to the file
184
+ * @returns CheckViolation object
185
+ */
186
+ function createMissingValidationViolation(routeInfo, filePath) {
187
+ return {
188
+ filePath,
189
+ line: routeInfo.line,
190
+ column: 0,
191
+ message: `${routeInfo.method} ${routeInfo.path} - Route handler accepts request body without Zod schema validation`,
192
+ severity: 'error',
193
+ type: 'missing-validation',
194
+ suggestion: 'Add Zod schema validation for request body. Import schema from shared contract schemas and use schema.parse(request.body).',
195
+ match: `${routeInfo.method} ${routeInfo.path}`,
196
+ };
197
+ }
198
+ /**
199
+ * Check a single call expression for route validation issues
200
+ * @param options - The options for the check
201
+ * @returns Violation if found, null otherwise
202
+ */
203
+ function checkCallExpressionForViolation(options) {
204
+ const { node, sourceFile, content, filePath } = options;
205
+ const routeInfo = extractRouteInfo(node, sourceFile);
206
+ if (!routeInfo) {
207
+ return null;
208
+ }
209
+ // Routes using fastify-type-provider-zod pass schema in options — validation is automatic
210
+ if (routeInfo.hasSchemaOption) {
211
+ return null;
212
+ }
213
+ const hasValidation = checkForValidation(routeInfo.handlerNode, sourceFile, content);
214
+ if (hasValidation) {
215
+ return null;
216
+ }
217
+ return createMissingValidationViolation(routeInfo, filePath);
218
+ }
219
+ /**
220
+ * Analyze a file for Fastify routes missing validation
221
+ * @param content - File content to analyze
222
+ * @param filePath - Path to the file being analyzed
223
+ * @returns Array of violations found in the file
224
+ */
225
+ function analyzeFile(content, filePath) {
226
+ const violations = [];
227
+ try {
228
+ const sourceFile = getSharedSourceFile(filePath, content);
229
+ /* v8 ignore next -- defensive guard */
230
+ if (!sourceFile)
231
+ return [];
232
+ const visit = (node) => {
233
+ if (ts.isCallExpression(node)) {
234
+ const violation = checkCallExpressionForViolation({ node, sourceFile, content, filePath });
235
+ if (violation) {
236
+ violations.push(violation);
237
+ }
238
+ }
239
+ ts.forEachChild(node, visit);
240
+ };
241
+ visit(sourceFile);
242
+ /* v8 ignore next 1 -- defensive catch: parse failures already handled */
243
+ }
244
+ catch {
245
+ // @swallow-ok Skip files that fail to parse
246
+ }
247
+ return violations;
248
+ }
249
+ /**
250
+ * Check if file is a route file
251
+ */
252
+ function isRouteFile(file) {
253
+ return file.includes('/routes/') && !isTestFile(file) && !file.endsWith('.d.ts');
254
+ }
255
+ /**
256
+ * Check: quality/fastify-route-validation
257
+ *
258
+ * Ensures all Fastify POST/PATCH/PUT route handlers validate request bodies
259
+ * with Zod schemas.
260
+ */
261
+ export const fastifyRouteValidation = defineCheck({
262
+ id: '0de8bce9-e6fd-45c2-83ea-013bedfd3346',
263
+ slug: 'fastify-route-validation',
264
+ scope: { languages: ['typescript'], concerns: ['backend', 'server'] },
265
+ // 'raw', not 'strip-strings': the check extracts the route *path string literal*
266
+ // value (first arg to fastify.post/patch/put) to embed the real path in the
267
+ // violation message, and uses content includes() on import/usage strings for
268
+ // fallback validation detection when no inline handler. Stripping blanks those,
269
+ // producing useless messages (e.g. "POST - ...") and false violations.
270
+ // See auth-route-guard.ts for identical rationale on route paths.
271
+ contentFilter: 'raw',
272
+ confidence: 'high',
273
+ description: 'Ensure all Fastify POST/PATCH/PUT routes validate request bodies with Zod schemas',
274
+ longDescription: `**Purpose:** Ensures every Fastify POST, PATCH, and PUT route handler validates the request body using Zod or an equivalent validation library.
275
+
276
+ **Detects:**
277
+ - Route handlers registered via \`fastify.post(\`, \`.patch(\`, \`.put(\` (matched by \`/fastify\\.(post|patch|put)|\\.(post|patch|put)\\(/i\`) that lack validation
278
+ - Missing Zod calls (\`.parse(\`, \`.safeParse(\`, \`z.\\w+()\`) and alternative validators (\`.validate(\`, \`validateBody(\`, \`validateRequest(\`, \`validateInput(\`)
279
+ - Handlers that access \`request.body\` without subsequent validation or 400-status error responses
280
+
281
+ **Why it matters:** Unvalidated request bodies allow malformed or malicious payloads to reach business logic, causing runtime errors and security vulnerabilities.
282
+
283
+ **Scope:** General best practice. Analyzes each file individually using TypeScript AST parsing. Only processes files under \`/routes/\` directories.`,
284
+ tags: ['quality', 'security', 'code-quality', 'fastify', 'validation'],
285
+ fileTypes: ['ts'],
286
+ analyze(content, filePath) {
287
+ // Filter to only route files
288
+ if (!isRouteFile(filePath)) {
289
+ return [];
290
+ }
291
+ // Quick filter: skip files that don't contain route patterns
292
+ if (!QUICK_FILTER_PATTERNS.test(content)) {
293
+ return [];
294
+ }
295
+ return analyzeFile(content, filePath);
296
+ },
297
+ });
298
+ //# sourceMappingURL=fastify-route-validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fastify-route-validation.js","sourceRoot":"","sources":["../../../../src/checks/quality/api/fastify-route-validation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @fileoverview Fastify Schema Coverage Check
3
+ *
4
+ * Validates Fastify routes have proper schema coverage:
5
+ * - Routes without schema option (unless Zod validation is present)
6
+ * - Routes with body but missing body schema
7
+ * - Routes with response but missing response schema
8
+ * - Recognizes Zod .parse()/.safeParse() on request properties as equivalent coverage
9
+ */
10
+ export declare const fastifySchemaCoverage: import("@opensip-cli/fitness").Check;
11
+ //# sourceMappingURL=fastify-schema-coverage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fastify-schema-coverage.d.ts","sourceRoot":"","sources":["../../../../src/checks/quality/api/fastify-schema-coverage.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAkUH,eAAO,MAAM,qBAAqB,sCAwChC,CAAC"}
@@ -0,0 +1,261 @@
1
+ // @fitness-ignore-file correlation-id-coverage -- Fitness check implementation, not an API handler
2
+ // @fitness-ignore-file fastify-schema-coverage -- Fitness check definition file; references Fastify schema patterns for detection, not actual routes
3
+ /**
4
+ * @fileoverview Fastify Schema Coverage Check
5
+ *
6
+ * Validates Fastify routes have proper schema coverage:
7
+ * - Routes without schema option (unless Zod validation is present)
8
+ * - Routes with body but missing body schema
9
+ * - Routes with response but missing response schema
10
+ * - Recognizes Zod .parse()/.safeParse() on request properties as equivalent coverage
11
+ */
12
+ import { defineCheck, isTestFile } from '@opensip-cli/fitness';
13
+ import { getSharedSourceFile } from '@opensip-cli/lang-typescript';
14
+ import * as ts from 'typescript';
15
+ const BODY_METHODS = new Set(['POST', 'PUT', 'PATCH']);
16
+ function createSchemaViolation(options, type, message, suggestion) {
17
+ const { method, line, filePath, routePath } = options;
18
+ return {
19
+ filePath,
20
+ line,
21
+ column: 0,
22
+ message,
23
+ severity: 'warning',
24
+ type,
25
+ suggestion,
26
+ match: `${method} ${routePath}`,
27
+ };
28
+ }
29
+ function hasProperty(routeText, propertyName) {
30
+ return routeText.includes(`${propertyName}:`) || routeText.includes(`${propertyName} :`);
31
+ }
32
+ function detectZodValidation(routeText) {
33
+ const bodyPattern = /\.(?:safe)?[Pp]arse\(\s{0,5}(?:request|req)\.body\s{0,5}\)/;
34
+ const queryPattern = /\.(?:safe)?[Pp]arse\(\s{0,5}(?:request|req)\.query\s{0,5}\)/;
35
+ const paramsPattern = /\.(?:safe)?[Pp]arse\(\s{0,5}(?:request|req)\.params\s{0,5}\)/;
36
+ const responsePattern = /[A-Z]\w{0,60}Schema\.parse\(/;
37
+ const generalPattern = /[A-Z]\w{0,60}Schema\.(?:safe)?[Pp]arse\(/;
38
+ const hasBody = bodyPattern.test(routeText);
39
+ const hasQuery = queryPattern.test(routeText);
40
+ const hasParams = paramsPattern.test(routeText);
41
+ const hasResponse = responsePattern.test(routeText);
42
+ const hasGeneral = generalPattern.test(routeText);
43
+ return {
44
+ hasAny: hasBody || hasQuery || hasParams || hasResponse || hasGeneral,
45
+ hasBody,
46
+ hasQuery,
47
+ hasParams,
48
+ hasResponse,
49
+ };
50
+ }
51
+ function checkMissingSchema(options, zodResult) {
52
+ if (hasProperty(options.routeText, 'schema')) {
53
+ return null;
54
+ }
55
+ if (zodResult.hasAny) {
56
+ return null;
57
+ }
58
+ return createSchemaViolation(options, 'missing-schema', `Route ${options.method} ${options.routePath} has no schema option`, 'Add schema option with body, response, params, and querystring as needed for request validation and OpenAPI documentation. Alternatively, use Zod Schema.parse() or Schema.safeParse() on request properties in the handler.');
59
+ }
60
+ function handlerReadsBody(routeText) {
61
+ // The route's text passed in here covers the full call expression,
62
+ // including the handler body. If neither `request.body` nor `req.body`
63
+ // appears, the handler doesn't consume a request body — POST/PUT/PATCH
64
+ // routes triggered purely by URL params (state-transition actions like
65
+ // `/dispatch`, `/replay`, `/dismiss`) legitimately have no body schema
66
+ // because there is no body. Flagging those is a false positive.
67
+ return routeText.includes('request.body') || routeText.includes('req.body');
68
+ }
69
+ function checkMissingBodySchema(options, zodResult) {
70
+ if (!BODY_METHODS.has(options.method)) {
71
+ return null;
72
+ }
73
+ if (hasProperty(options.routeText, 'body')) {
74
+ return null;
75
+ }
76
+ if (zodResult.hasBody) {
77
+ return null;
78
+ }
79
+ if (!handlerReadsBody(options.routeText)) {
80
+ return null;
81
+ }
82
+ return createSchemaViolation(options, 'missing-body-schema', `Route ${options.method} ${options.routePath} missing body schema`, 'Add body schema to validate request payload. Use Zod schema from shared contract schemas.');
83
+ }
84
+ function checkMissingResponseSchema(options, zodResult) {
85
+ if (hasProperty(options.routeText, 'response')) {
86
+ return null;
87
+ }
88
+ if (zodResult.hasResponse) {
89
+ return null;
90
+ }
91
+ return createSchemaViolation(options, 'missing-response-schema', `Route ${options.method} ${options.routePath} missing response schema`, 'Add response schema for proper API documentation and type safety. Define schemas for 200, 400, 500 status codes.');
92
+ }
93
+ function checkMissingParamsSchema(options, zodResult) {
94
+ const hasParams = options.routePath.includes(':');
95
+ if (!hasParams) {
96
+ return null;
97
+ }
98
+ if (hasProperty(options.routeText, 'params')) {
99
+ return null;
100
+ }
101
+ if (zodResult.hasParams) {
102
+ return null;
103
+ }
104
+ return createSchemaViolation(options, 'missing-params-schema', `Route ${options.method} ${options.routePath} has path params but no params schema`, 'Add params schema to validate path parameters. Use Zod schema to validate param types.');
105
+ }
106
+ function checkMissingQuerySchema(options, zodResult) {
107
+ const accessesQuery = options.routeText.includes('request.query') || options.routeText.includes('req.query');
108
+ if (!accessesQuery) {
109
+ return null;
110
+ }
111
+ if (hasProperty(options.routeText, 'querystring')) {
112
+ return null;
113
+ }
114
+ if (zodResult.hasQuery) {
115
+ return null;
116
+ }
117
+ return createSchemaViolation(options, 'missing-querystring-schema', `Route ${options.method} ${options.routePath} accesses query but no querystring schema`, 'Add querystring schema to validate query parameters. Use Zod schema to validate and coerce query string values.');
118
+ }
119
+ function checkRouteSchema(options) {
120
+ const violations = [];
121
+ const zodResult = detectZodValidation(options.routeText);
122
+ const missingSchemaViolation = checkMissingSchema(options, zodResult);
123
+ if (missingSchemaViolation) {
124
+ violations.push(missingSchemaViolation);
125
+ return violations;
126
+ }
127
+ const bodyViolation = checkMissingBodySchema(options, zodResult);
128
+ if (bodyViolation) {
129
+ violations.push(bodyViolation);
130
+ }
131
+ const responseViolation = checkMissingResponseSchema(options, zodResult);
132
+ if (responseViolation) {
133
+ violations.push(responseViolation);
134
+ }
135
+ const paramsViolation = checkMissingParamsSchema(options, zodResult);
136
+ if (paramsViolation) {
137
+ violations.push(paramsViolation);
138
+ }
139
+ const queryViolation = checkMissingQuerySchema(options, zodResult);
140
+ if (queryViolation) {
141
+ violations.push(queryViolation);
142
+ }
143
+ return violations;
144
+ }
145
+ function matchObjectMethod(nodeText) {
146
+ const match = /method\s{0,5}:\s{0,5}['"]?(GET|POST|PUT|PATCH|DELETE)['"]?/i.exec(nodeText);
147
+ return match?.[1]?.toUpperCase() ?? null;
148
+ }
149
+ function matchObjectUrl(nodeText) {
150
+ const match = /url\s{0,5}:\s{0,5}['"`]([^'"`]{1,200})['"`]/.exec(nodeText);
151
+ return match?.[1] ?? null;
152
+ }
153
+ function matchShorthandMethod(callText) {
154
+ const match = /(?:fastify|app|server)\.(get|post|put|patch|delete)\s{0,5}\(/i.exec(callText);
155
+ return match?.[1]?.toUpperCase() ?? null;
156
+ }
157
+ function matchPathArgument(callText) {
158
+ const match = /\(\s{0,5}['"`]([^'"`]{1,200})['"`]/.exec(callText);
159
+ /* v8 ignore next -- defensive AST/type guard */
160
+ return match?.[1] ?? null;
161
+ }
162
+ function analyzeObjectLiteral(node, sourceFile, filePath) {
163
+ const nodeText = node.getText(sourceFile);
164
+ const method = matchObjectMethod(nodeText);
165
+ const routePath = matchObjectUrl(nodeText);
166
+ if (!method || !routePath) {
167
+ return [];
168
+ }
169
+ const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
170
+ return checkRouteSchema({
171
+ routeText: nodeText,
172
+ method,
173
+ line: line + 1,
174
+ filePath,
175
+ routePath,
176
+ });
177
+ }
178
+ function analyzeCallExpression(node, sourceFile, filePath) {
179
+ const callText = node.getText(sourceFile);
180
+ const method = matchShorthandMethod(callText);
181
+ if (!method) {
182
+ return [];
183
+ }
184
+ const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
185
+ /* v8 ignore next -- defensive nullish fallback */
186
+ const routePath = matchPathArgument(callText) ?? '';
187
+ return checkRouteSchema({
188
+ routeText: callText,
189
+ method,
190
+ line: line + 1,
191
+ filePath,
192
+ routePath,
193
+ });
194
+ }
195
+ function analyzeFile(content, filePath) {
196
+ const violations = [];
197
+ try {
198
+ const sourceFile = getSharedSourceFile(filePath, content);
199
+ /* v8 ignore next -- defensive guard */
200
+ if (!sourceFile)
201
+ return [];
202
+ const visit = (node) => {
203
+ if (ts.isObjectLiteralExpression(node)) {
204
+ violations.push(...analyzeObjectLiteral(node, sourceFile, filePath));
205
+ }
206
+ else if (ts.isCallExpression(node)) {
207
+ violations.push(...analyzeCallExpression(node, sourceFile, filePath));
208
+ }
209
+ ts.forEachChild(node, visit);
210
+ };
211
+ visit(sourceFile);
212
+ /* v8 ignore next 1 -- defensive catch: parse failures already handled */
213
+ }
214
+ catch {
215
+ // @swallow-ok Skip files that fail to parse
216
+ }
217
+ return violations;
218
+ }
219
+ function isRouteFile(file) {
220
+ const hasRouteKeyword = file.includes('route') || file.includes('controller') || file.includes('endpoint');
221
+ const isTypeFile = file.endsWith('.d.ts');
222
+ return hasRouteKeyword && !isTestFile(file) && !isTypeFile;
223
+ }
224
+ export const fastifySchemaCoverage = defineCheck({
225
+ id: '16f14276-7a70-43bb-8097-181dd277371c',
226
+ slug: 'fastify-schema-coverage',
227
+ scope: { languages: ['typescript'], concerns: ['backend', 'server'] },
228
+ contentFilter: 'strip-strings',
229
+ confidence: 'high',
230
+ description: 'Validate that Fastify routes have proper request/response schema validation',
231
+ longDescription: `**Purpose:** Validates that Fastify route definitions include complete schema options for request and response validation.
232
+
233
+ **Detects:**
234
+ - Routes (both object-literal \`{ method: 'POST', url: '...' }\` and shorthand \`fastify.post(...)\` styles) missing the \`schema\` option entirely
235
+ - POST/PUT/PATCH routes missing a \`body:\` schema property when the handler reads \`request.body\` (state-transition routes triggered by URL params with no body access are not flagged)
236
+ - Routes missing a \`response:\` schema property
237
+ - Routes with path parameters (containing \`:\`) missing a \`params:\` schema property
238
+ - Routes accessing \`request.query\`/\`req.query\` missing a \`querystring:\` schema property
239
+
240
+ **Zod validation support:** Routes using Zod-based validation in the handler body are recognized as having equivalent schema coverage:
241
+ - \`Schema.safeParse(request.body)\` / \`Schema.parse(request.body)\` — counts as body validation
242
+ - \`Schema.safeParse(request.query)\` / \`Schema.parse(request.query)\` — counts as querystring validation
243
+ - \`Schema.safeParse(request.params)\` / \`Schema.parse(request.params)\` — counts as params validation
244
+ - \`Schema.parse(result)\` (any \`*Schema.parse()\` call) — counts as response validation
245
+
246
+ **Why it matters:** Missing schema properties disable Fastify's built-in request validation and omit routes from OpenAPI documentation, leading to undocumented and unvalidated endpoints.
247
+
248
+ **Scope:** General best practice. Analyzes each file individually using TypeScript AST parsing. Only processes route/controller/endpoint files.`,
249
+ tags: ['quality', 'code-quality', 'best-practices', 'security', 'fastify', 'schema'],
250
+ fileTypes: ['ts'],
251
+ analyze(content, filePath) {
252
+ if (!isRouteFile(filePath)) {
253
+ return [];
254
+ }
255
+ if (!content.includes('fastify') && !content.includes('route')) {
256
+ return [];
257
+ }
258
+ return analyzeFile(content, filePath);
259
+ },
260
+ });
261
+ //# sourceMappingURL=fastify-schema-coverage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fastify-schema-coverage.js","sourceRoot":"","sources":["../../../../src/checks/quality/api/fastify-schema-coverage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export * from './api-contract-validation.js';
2
+ export * from './api-response-validation.js';
3
+ export * from './fastify-route-validation.js';
4
+ export * from './fastify-schema-coverage.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/checks/quality/api/index.ts"],"names":[],"mappings":"AAAA,cAAc,8BAA8B,CAAC;AAC7C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,8BAA8B,CAAC"}
@@ -0,0 +1,5 @@
1
+ export * from './api-contract-validation.js';
2
+ export * from './api-response-validation.js';
3
+ export * from './fastify-route-validation.js';
4
+ export * from './fastify-schema-coverage.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/checks/quality/api/index.ts"],"names":[],"mappings":"AAAA,cAAc,8BAA8B,CAAC;AAC7C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,8BAA8B,CAAC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @fileoverview Duplicate Utility Functions check
3
+ *
4
+ * Detects duplicate utility functions that should be consolidated.
5
+ * Flags TWO types of issues:
6
+ * 1. Identical implementations - true duplicates that must be deduplicated
7
+ * 2. Same-named functions with different implementations - consolidation opportunities
8
+ */
9
+ /**
10
+ * Recipe-config shape for the duplicate-utility-functions check. Augments
11
+ * the built-in {@link DOMAIN_SPECIFIC_FUNCTIONS} list with project-specific
12
+ * names that are deliberately distinct implementations sharing a name.
13
+ *
14
+ * Project-specific functions like `getCurrentCorrelationId`, `formatDuration`,
15
+ * `getRemoteUrl`, `sanitizeForPrompt`, etc. belong in a recipe's
16
+ * `checks.config['duplicate-utility-functions'].additionalDomainSpecificFunctions`
17
+ * block, NOT in built-in defaults.
18
+ */
19
+ export interface DuplicateUtilityFunctionsConfig extends Record<string, unknown> {
20
+ /** Function names that should be skipped (treated as domain-specific by design). */
21
+ additionalDomainSpecificFunctions?: readonly string[];
22
+ }
23
+ /**
24
+ * Check: quality/duplicate-utility-functions
25
+ *
26
+ * Detects utility functions that should be consolidated across the codebase.
27
+ * Reports two types of issues:
28
+ * - IDENTICAL: Same name, same implementation (true duplicates)
29
+ * - SIMILAR: Same name, different implementation (consolidation opportunities)
30
+ */
31
+ export declare const duplicateUtilityFunctions: import("@opensip-cli/fitness").Check;
32
+ //# sourceMappingURL=duplicate-utility-functions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"duplicate-utility-functions.d.ts","sourceRoot":"","sources":["../../../../src/checks/quality/code-structure/duplicate-utility-functions.ts"],"names":[],"mappings":"AAGA;;;;;;;GAOG;AAcH;;;;;;;;;GASG;AACH,MAAM,WAAW,+BAAgC,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC9E,oFAAoF;IACpF,iCAAiC,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACvD;AAmdD;;;;;;;GAOG;AACH,eAAO,MAAM,yBAAyB,sCAkCpC,CAAC"}