@opensip-cli/checks-universal 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 (620) 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 +17 -0
  5. package/dist/__tests__/all-checks-execute.test.d.ts.map +1 -0
  6. package/dist/__tests__/all-checks-execute.test.js +452 -0
  7. package/dist/__tests__/all-checks-execute.test.js.map +1 -0
  8. package/dist/__tests__/behavior-fixtures-10.test.d.ts +8 -0
  9. package/dist/__tests__/behavior-fixtures-10.test.d.ts.map +1 -0
  10. package/dist/__tests__/behavior-fixtures-10.test.js +200 -0
  11. package/dist/__tests__/behavior-fixtures-10.test.js.map +1 -0
  12. package/dist/__tests__/behavior-fixtures-11.test.d.ts +8 -0
  13. package/dist/__tests__/behavior-fixtures-11.test.d.ts.map +1 -0
  14. package/dist/__tests__/behavior-fixtures-11.test.js +120 -0
  15. package/dist/__tests__/behavior-fixtures-11.test.js.map +1 -0
  16. package/dist/__tests__/behavior-fixtures-12.test.d.ts +8 -0
  17. package/dist/__tests__/behavior-fixtures-12.test.d.ts.map +1 -0
  18. package/dist/__tests__/behavior-fixtures-12.test.js +157 -0
  19. package/dist/__tests__/behavior-fixtures-12.test.js.map +1 -0
  20. package/dist/__tests__/behavior-fixtures-2.test.d.ts +8 -0
  21. package/dist/__tests__/behavior-fixtures-2.test.d.ts.map +1 -0
  22. package/dist/__tests__/behavior-fixtures-2.test.js +785 -0
  23. package/dist/__tests__/behavior-fixtures-2.test.js.map +1 -0
  24. package/dist/__tests__/behavior-fixtures-3.test.d.ts +6 -0
  25. package/dist/__tests__/behavior-fixtures-3.test.d.ts.map +1 -0
  26. package/dist/__tests__/behavior-fixtures-3.test.js +663 -0
  27. package/dist/__tests__/behavior-fixtures-3.test.js.map +1 -0
  28. package/dist/__tests__/behavior-fixtures-4.test.d.ts +5 -0
  29. package/dist/__tests__/behavior-fixtures-4.test.d.ts.map +1 -0
  30. package/dist/__tests__/behavior-fixtures-4.test.js +612 -0
  31. package/dist/__tests__/behavior-fixtures-4.test.js.map +1 -0
  32. package/dist/__tests__/behavior-fixtures-5.test.d.ts +5 -0
  33. package/dist/__tests__/behavior-fixtures-5.test.d.ts.map +1 -0
  34. package/dist/__tests__/behavior-fixtures-5.test.js +469 -0
  35. package/dist/__tests__/behavior-fixtures-5.test.js.map +1 -0
  36. package/dist/__tests__/behavior-fixtures-6.test.d.ts +8 -0
  37. package/dist/__tests__/behavior-fixtures-6.test.d.ts.map +1 -0
  38. package/dist/__tests__/behavior-fixtures-6.test.js +591 -0
  39. package/dist/__tests__/behavior-fixtures-6.test.js.map +1 -0
  40. package/dist/__tests__/behavior-fixtures-7.test.d.ts +5 -0
  41. package/dist/__tests__/behavior-fixtures-7.test.d.ts.map +1 -0
  42. package/dist/__tests__/behavior-fixtures-7.test.js +662 -0
  43. package/dist/__tests__/behavior-fixtures-7.test.js.map +1 -0
  44. package/dist/__tests__/behavior-fixtures-8.test.d.ts +11 -0
  45. package/dist/__tests__/behavior-fixtures-8.test.d.ts.map +1 -0
  46. package/dist/__tests__/behavior-fixtures-8.test.js +634 -0
  47. package/dist/__tests__/behavior-fixtures-8.test.js.map +1 -0
  48. package/dist/__tests__/behavior-fixtures-9.test.d.ts +11 -0
  49. package/dist/__tests__/behavior-fixtures-9.test.d.ts.map +1 -0
  50. package/dist/__tests__/behavior-fixtures-9.test.js +271 -0
  51. package/dist/__tests__/behavior-fixtures-9.test.js.map +1 -0
  52. package/dist/__tests__/behavior-fixtures.test.d.ts +14 -0
  53. package/dist/__tests__/behavior-fixtures.test.d.ts.map +1 -0
  54. package/dist/__tests__/behavior-fixtures.test.js +1423 -0
  55. package/dist/__tests__/behavior-fixtures.test.js.map +1 -0
  56. package/dist/__tests__/checks.test.d.ts +2 -0
  57. package/dist/__tests__/checks.test.d.ts.map +1 -0
  58. package/dist/__tests__/checks.test.js +61 -0
  59. package/dist/__tests__/checks.test.js.map +1 -0
  60. package/dist/__tests__/env-var-validation.test.d.ts +14 -0
  61. package/dist/__tests__/env-var-validation.test.d.ts.map +1 -0
  62. package/dist/__tests__/env-var-validation.test.js +53 -0
  63. package/dist/__tests__/env-var-validation.test.js.map +1 -0
  64. package/dist/__tests__/file-length-limit.test.d.ts +2 -0
  65. package/dist/__tests__/file-length-limit.test.d.ts.map +1 -0
  66. package/dist/__tests__/file-length-limit.test.js +29 -0
  67. package/dist/__tests__/file-length-limit.test.js.map +1 -0
  68. package/dist/__tests__/fixture-coverage.allowlist.d.ts +18 -0
  69. package/dist/__tests__/fixture-coverage.allowlist.d.ts.map +1 -0
  70. package/dist/__tests__/fixture-coverage.allowlist.js +35 -0
  71. package/dist/__tests__/fixture-coverage.allowlist.js.map +1 -0
  72. package/dist/__tests__/fixture-coverage.test.d.ts +13 -0
  73. package/dist/__tests__/fixture-coverage.test.d.ts.map +1 -0
  74. package/dist/__tests__/fixture-coverage.test.js +57 -0
  75. package/dist/__tests__/fixture-coverage.test.js.map +1 -0
  76. package/dist/__tests__/iic.test.d.ts +15 -0
  77. package/dist/__tests__/iic.test.d.ts.map +1 -0
  78. package/dist/__tests__/iic.test.js +316 -0
  79. package/dist/__tests__/iic.test.js.map +1 -0
  80. package/dist/__tests__/no-skipped-tests.test.d.ts +14 -0
  81. package/dist/__tests__/no-skipped-tests.test.d.ts.map +1 -0
  82. package/dist/__tests__/no-skipped-tests.test.js +144 -0
  83. package/dist/__tests__/no-skipped-tests.test.js.map +1 -0
  84. package/dist/__tests__/no-todo-comments.test.d.ts +2 -0
  85. package/dist/__tests__/no-todo-comments.test.d.ts.map +1 -0
  86. package/dist/__tests__/no-todo-comments.test.js +31 -0
  87. package/dist/__tests__/no-todo-comments.test.js.map +1 -0
  88. package/dist/__tests__/no-unimplemented-markers.test.d.ts +2 -0
  89. package/dist/__tests__/no-unimplemented-markers.test.d.ts.map +1 -0
  90. package/dist/__tests__/no-unimplemented-markers.test.js +140 -0
  91. package/dist/__tests__/no-unimplemented-markers.test.js.map +1 -0
  92. package/dist/__tests__/public-api-jsdoc-scope.test.d.ts +10 -0
  93. package/dist/__tests__/public-api-jsdoc-scope.test.d.ts.map +1 -0
  94. package/dist/__tests__/public-api-jsdoc-scope.test.js +176 -0
  95. package/dist/__tests__/public-api-jsdoc-scope.test.js.map +1 -0
  96. package/dist/__tests__/resilience-fp.test.d.ts +14 -0
  97. package/dist/__tests__/resilience-fp.test.d.ts.map +1 -0
  98. package/dist/__tests__/resilience-fp.test.js +110 -0
  99. package/dist/__tests__/resilience-fp.test.js.map +1 -0
  100. package/dist/checks/architecture/__tests__/no-kebab-option-indexing.test.d.ts +2 -0
  101. package/dist/checks/architecture/__tests__/no-kebab-option-indexing.test.d.ts.map +1 -0
  102. package/dist/checks/architecture/__tests__/no-kebab-option-indexing.test.js +32 -0
  103. package/dist/checks/architecture/__tests__/no-kebab-option-indexing.test.js.map +1 -0
  104. package/dist/checks/architecture/__tests__/tool-has-manifest.test.d.ts +2 -0
  105. package/dist/checks/architecture/__tests__/tool-has-manifest.test.d.ts.map +1 -0
  106. package/dist/checks/architecture/__tests__/tool-has-manifest.test.js +152 -0
  107. package/dist/checks/architecture/__tests__/tool-has-manifest.test.js.map +1 -0
  108. package/dist/checks/architecture/__tests__/vitest-config-required-with-tests.test.d.ts +2 -0
  109. package/dist/checks/architecture/__tests__/vitest-config-required-with-tests.test.d.ts.map +1 -0
  110. package/dist/checks/architecture/__tests__/vitest-config-required-with-tests.test.js +129 -0
  111. package/dist/checks/architecture/__tests__/vitest-config-required-with-tests.test.js.map +1 -0
  112. package/dist/checks/architecture/_yaml-doc-bindings.d.ts +23 -0
  113. package/dist/checks/architecture/_yaml-doc-bindings.d.ts.map +1 -0
  114. package/dist/checks/architecture/_yaml-doc-bindings.js +29 -0
  115. package/dist/checks/architecture/_yaml-doc-bindings.js.map +1 -0
  116. package/dist/checks/architecture/dependencies/index.d.ts +2 -0
  117. package/dist/checks/architecture/dependencies/index.d.ts.map +1 -0
  118. package/dist/checks/architecture/dependencies/index.js +2 -0
  119. package/dist/checks/architecture/dependencies/index.js.map +1 -0
  120. package/dist/checks/architecture/dependencies/no-duplicate-packages.d.ts +11 -0
  121. package/dist/checks/architecture/dependencies/no-duplicate-packages.d.ts.map +1 -0
  122. package/dist/checks/architecture/dependencies/no-duplicate-packages.js +171 -0
  123. package/dist/checks/architecture/dependencies/no-duplicate-packages.js.map +1 -0
  124. package/dist/checks/architecture/docker-best-practices.d.ts +23 -0
  125. package/dist/checks/architecture/docker-best-practices.d.ts.map +1 -0
  126. package/dist/checks/architecture/docker-best-practices.js +427 -0
  127. package/dist/checks/architecture/docker-best-practices.js.map +1 -0
  128. package/dist/checks/architecture/docker-ignore-validation.d.ts +18 -0
  129. package/dist/checks/architecture/docker-ignore-validation.d.ts.map +1 -0
  130. package/dist/checks/architecture/docker-ignore-validation.js +117 -0
  131. package/dist/checks/architecture/docker-ignore-validation.js.map +1 -0
  132. package/dist/checks/architecture/docker-version-sync.d.ts +16 -0
  133. package/dist/checks/architecture/docker-version-sync.d.ts.map +1 -0
  134. package/dist/checks/architecture/docker-version-sync.js +193 -0
  135. package/dist/checks/architecture/docker-version-sync.js.map +1 -0
  136. package/dist/checks/architecture/env-var-validation.d.ts +14 -0
  137. package/dist/checks/architecture/env-var-validation.d.ts.map +1 -0
  138. package/dist/checks/architecture/env-var-validation.js +289 -0
  139. package/dist/checks/architecture/env-var-validation.js.map +1 -0
  140. package/dist/checks/architecture/heavy-import-detection.d.ts +11 -0
  141. package/dist/checks/architecture/heavy-import-detection.d.ts.map +1 -0
  142. package/dist/checks/architecture/heavy-import-detection.js +91 -0
  143. package/dist/checks/architecture/heavy-import-detection.js.map +1 -0
  144. package/dist/checks/architecture/index.d.ts +16 -0
  145. package/dist/checks/architecture/index.d.ts.map +1 -0
  146. package/dist/checks/architecture/index.js +16 -0
  147. package/dist/checks/architecture/index.js.map +1 -0
  148. package/dist/checks/architecture/modules/empty-package-detection.d.ts +11 -0
  149. package/dist/checks/architecture/modules/empty-package-detection.d.ts.map +1 -0
  150. package/dist/checks/architecture/modules/empty-package-detection.js +277 -0
  151. package/dist/checks/architecture/modules/empty-package-detection.js.map +1 -0
  152. package/dist/checks/architecture/modules/index.d.ts +3 -0
  153. package/dist/checks/architecture/modules/index.d.ts.map +1 -0
  154. package/dist/checks/architecture/modules/index.js +3 -0
  155. package/dist/checks/architecture/modules/index.js.map +1 -0
  156. package/dist/checks/architecture/modules/interface-implementation-consistency.d.ts +12 -0
  157. package/dist/checks/architecture/modules/interface-implementation-consistency.d.ts.map +1 -0
  158. package/dist/checks/architecture/modules/interface-implementation-consistency.js +555 -0
  159. package/dist/checks/architecture/modules/interface-implementation-consistency.js.map +1 -0
  160. package/dist/checks/architecture/no-custom-event-emitter.d.ts +11 -0
  161. package/dist/checks/architecture/no-custom-event-emitter.d.ts.map +1 -0
  162. package/dist/checks/architecture/no-custom-event-emitter.js +123 -0
  163. package/dist/checks/architecture/no-custom-event-emitter.js.map +1 -0
  164. package/dist/checks/architecture/no-kebab-option-indexing.d.ts +33 -0
  165. package/dist/checks/architecture/no-kebab-option-indexing.d.ts.map +1 -0
  166. package/dist/checks/architecture/no-kebab-option-indexing.js +81 -0
  167. package/dist/checks/architecture/no-kebab-option-indexing.js.map +1 -0
  168. package/dist/checks/architecture/node-version-consistency.d.ts +22 -0
  169. package/dist/checks/architecture/node-version-consistency.d.ts.map +1 -0
  170. package/dist/checks/architecture/node-version-consistency.js +225 -0
  171. package/dist/checks/architecture/node-version-consistency.js.map +1 -0
  172. package/dist/checks/architecture/project-readme-existence.d.ts +13 -0
  173. package/dist/checks/architecture/project-readme-existence.d.ts.map +1 -0
  174. package/dist/checks/architecture/project-readme-existence.js +55 -0
  175. package/dist/checks/architecture/project-readme-existence.js.map +1 -0
  176. package/dist/checks/architecture/stale-build-artifacts.d.ts +10 -0
  177. package/dist/checks/architecture/stale-build-artifacts.d.ts.map +1 -0
  178. package/dist/checks/architecture/stale-build-artifacts.js +55 -0
  179. package/dist/checks/architecture/stale-build-artifacts.js.map +1 -0
  180. package/dist/checks/architecture/tool-has-manifest.d.ts +27 -0
  181. package/dist/checks/architecture/tool-has-manifest.d.ts.map +1 -0
  182. package/dist/checks/architecture/tool-has-manifest.js +135 -0
  183. package/dist/checks/architecture/tool-has-manifest.js.map +1 -0
  184. package/dist/checks/architecture/vitest-config-extends-base.d.ts +15 -0
  185. package/dist/checks/architecture/vitest-config-extends-base.d.ts.map +1 -0
  186. package/dist/checks/architecture/vitest-config-extends-base.js +104 -0
  187. package/dist/checks/architecture/vitest-config-extends-base.js.map +1 -0
  188. package/dist/checks/architecture/vitest-config-required-with-tests.d.ts +49 -0
  189. package/dist/checks/architecture/vitest-config-required-with-tests.d.ts.map +1 -0
  190. package/dist/checks/architecture/vitest-config-required-with-tests.js +199 -0
  191. package/dist/checks/architecture/vitest-config-required-with-tests.js.map +1 -0
  192. package/dist/checks/documentation/_directives/eslint.d.ts +9 -0
  193. package/dist/checks/documentation/_directives/eslint.d.ts.map +1 -0
  194. package/dist/checks/documentation/_directives/eslint.js +168 -0
  195. package/dist/checks/documentation/_directives/eslint.js.map +1 -0
  196. package/dist/checks/documentation/_directives/fitness.d.ts +9 -0
  197. package/dist/checks/documentation/_directives/fitness.d.ts.map +1 -0
  198. package/dist/checks/documentation/_directives/fitness.js +64 -0
  199. package/dist/checks/documentation/_directives/fitness.js.map +1 -0
  200. package/dist/checks/documentation/_directives/graph.d.ts +10 -0
  201. package/dist/checks/documentation/_directives/graph.d.ts.map +1 -0
  202. package/dist/checks/documentation/_directives/graph.js +65 -0
  203. package/dist/checks/documentation/_directives/graph.js.map +1 -0
  204. package/dist/checks/documentation/_directives/graph.test.d.ts +2 -0
  205. package/dist/checks/documentation/_directives/graph.test.d.ts.map +1 -0
  206. package/dist/checks/documentation/_directives/graph.test.js +54 -0
  207. package/dist/checks/documentation/_directives/graph.test.js.map +1 -0
  208. package/dist/checks/documentation/_directives/semgrep.d.ts +8 -0
  209. package/dist/checks/documentation/_directives/semgrep.d.ts.map +1 -0
  210. package/dist/checks/documentation/_directives/semgrep.js +72 -0
  211. package/dist/checks/documentation/_directives/semgrep.js.map +1 -0
  212. package/dist/checks/documentation/_directives/types.d.ts +21 -0
  213. package/dist/checks/documentation/_directives/types.d.ts.map +1 -0
  214. package/dist/checks/documentation/_directives/types.js +9 -0
  215. package/dist/checks/documentation/_directives/types.js.map +1 -0
  216. package/dist/checks/documentation/_directives/typescript.d.ts +10 -0
  217. package/dist/checks/documentation/_directives/typescript.d.ts.map +1 -0
  218. package/dist/checks/documentation/_directives/typescript.js +54 -0
  219. package/dist/checks/documentation/_directives/typescript.js.map +1 -0
  220. package/dist/checks/documentation/_public-api-graph.d.ts +30 -0
  221. package/dist/checks/documentation/_public-api-graph.d.ts.map +1 -0
  222. package/dist/checks/documentation/_public-api-graph.js +304 -0
  223. package/dist/checks/documentation/_public-api-graph.js.map +1 -0
  224. package/dist/checks/documentation/directive-audit.d.ts +26 -0
  225. package/dist/checks/documentation/directive-audit.d.ts.map +1 -0
  226. package/dist/checks/documentation/directive-audit.js +144 -0
  227. package/dist/checks/documentation/directive-audit.js.map +1 -0
  228. package/dist/checks/documentation/index.d.ts +3 -0
  229. package/dist/checks/documentation/index.d.ts.map +1 -0
  230. package/dist/checks/documentation/index.js +3 -0
  231. package/dist/checks/documentation/index.js.map +1 -0
  232. package/dist/checks/documentation/public-api-jsdoc.d.ts +10 -0
  233. package/dist/checks/documentation/public-api-jsdoc.d.ts.map +1 -0
  234. package/dist/checks/documentation/public-api-jsdoc.js +131 -0
  235. package/dist/checks/documentation/public-api-jsdoc.js.map +1 -0
  236. package/dist/checks/file-length-limit.d.ts +16 -0
  237. package/dist/checks/file-length-limit.d.ts.map +1 -0
  238. package/dist/checks/file-length-limit.js +47 -0
  239. package/dist/checks/file-length-limit.js.map +1 -0
  240. package/dist/checks/index.d.ts +16 -0
  241. package/dist/checks/index.d.ts.map +1 -0
  242. package/dist/checks/index.js +16 -0
  243. package/dist/checks/index.js.map +1 -0
  244. package/dist/checks/no-todo-comments.d.ts +18 -0
  245. package/dist/checks/no-todo-comments.d.ts.map +1 -0
  246. package/dist/checks/no-todo-comments.js +79 -0
  247. package/dist/checks/no-todo-comments.js.map +1 -0
  248. package/dist/checks/no-unimplemented-markers.d.ts +24 -0
  249. package/dist/checks/no-unimplemented-markers.d.ts.map +1 -0
  250. package/dist/checks/no-unimplemented-markers.js +198 -0
  251. package/dist/checks/no-unimplemented-markers.js.map +1 -0
  252. package/dist/checks/quality/api/graphql-offset-pagination.d.ts +9 -0
  253. package/dist/checks/quality/api/graphql-offset-pagination.d.ts.map +1 -0
  254. package/dist/checks/quality/api/graphql-offset-pagination.js +63 -0
  255. package/dist/checks/quality/api/graphql-offset-pagination.js.map +1 -0
  256. package/dist/checks/quality/api/index.d.ts +3 -0
  257. package/dist/checks/quality/api/index.d.ts.map +1 -0
  258. package/dist/checks/quality/api/index.js +3 -0
  259. package/dist/checks/quality/api/index.js.map +1 -0
  260. package/dist/checks/quality/api/zod-openapi-sync.d.ts +13 -0
  261. package/dist/checks/quality/api/zod-openapi-sync.d.ts.map +1 -0
  262. package/dist/checks/quality/api/zod-openapi-sync.js +88 -0
  263. package/dist/checks/quality/api/zod-openapi-sync.js.map +1 -0
  264. package/dist/checks/quality/code-structure/dead-code.d.ts +12 -0
  265. package/dist/checks/quality/code-structure/dead-code.d.ts.map +1 -0
  266. package/dist/checks/quality/code-structure/dead-code.js +238 -0
  267. package/dist/checks/quality/code-structure/dead-code.js.map +1 -0
  268. package/dist/checks/quality/code-structure/index.d.ts +5 -0
  269. package/dist/checks/quality/code-structure/index.d.ts.map +1 -0
  270. package/dist/checks/quality/code-structure/index.js +5 -0
  271. package/dist/checks/quality/code-structure/index.js.map +1 -0
  272. package/dist/checks/quality/code-structure/no-ai-attribution.d.ts +25 -0
  273. package/dist/checks/quality/code-structure/no-ai-attribution.d.ts.map +1 -0
  274. package/dist/checks/quality/code-structure/no-ai-attribution.js +76 -0
  275. package/dist/checks/quality/code-structure/no-ai-attribution.js.map +1 -0
  276. package/dist/checks/quality/code-structure/no-console-log.d.ts +17 -0
  277. package/dist/checks/quality/code-structure/no-console-log.d.ts.map +1 -0
  278. package/dist/checks/quality/code-structure/no-console-log.js +106 -0
  279. package/dist/checks/quality/code-structure/no-console-log.js.map +1 -0
  280. package/dist/checks/quality/code-structure/no-process-artifacts.d.ts +25 -0
  281. package/dist/checks/quality/code-structure/no-process-artifacts.d.ts.map +1 -0
  282. package/dist/checks/quality/code-structure/no-process-artifacts.js +104 -0
  283. package/dist/checks/quality/code-structure/no-process-artifacts.js.map +1 -0
  284. package/dist/checks/quality/dependency-version-consistency.d.ts +20 -0
  285. package/dist/checks/quality/dependency-version-consistency.d.ts.map +1 -0
  286. package/dist/checks/quality/dependency-version-consistency.js +266 -0
  287. package/dist/checks/quality/dependency-version-consistency.js.map +1 -0
  288. package/dist/checks/quality/fitness-ignore-hygiene.d.ts +10 -0
  289. package/dist/checks/quality/fitness-ignore-hygiene.d.ts.map +1 -0
  290. package/dist/checks/quality/fitness-ignore-hygiene.js +93 -0
  291. package/dist/checks/quality/fitness-ignore-hygiene.js.map +1 -0
  292. package/dist/checks/quality/frontend/expo-vector-icons.d.ts +13 -0
  293. package/dist/checks/quality/frontend/expo-vector-icons.d.ts.map +1 -0
  294. package/dist/checks/quality/frontend/expo-vector-icons.js +80 -0
  295. package/dist/checks/quality/frontend/expo-vector-icons.js.map +1 -0
  296. package/dist/checks/quality/frontend/image-optimization.d.ts +13 -0
  297. package/dist/checks/quality/frontend/image-optimization.d.ts.map +1 -0
  298. package/dist/checks/quality/frontend/image-optimization.js +166 -0
  299. package/dist/checks/quality/frontend/image-optimization.js.map +1 -0
  300. package/dist/checks/quality/frontend/index.d.ts +4 -0
  301. package/dist/checks/quality/frontend/index.d.ts.map +1 -0
  302. package/dist/checks/quality/frontend/index.js +4 -0
  303. package/dist/checks/quality/frontend/index.js.map +1 -0
  304. package/dist/checks/quality/frontend/navigation-typing.d.ts +12 -0
  305. package/dist/checks/quality/frontend/navigation-typing.d.ts.map +1 -0
  306. package/dist/checks/quality/frontend/navigation-typing.js +77 -0
  307. package/dist/checks/quality/frontend/navigation-typing.js.map +1 -0
  308. package/dist/checks/quality/graph-ignore-hygiene.d.ts +10 -0
  309. package/dist/checks/quality/graph-ignore-hygiene.d.ts.map +1 -0
  310. package/dist/checks/quality/graph-ignore-hygiene.js +95 -0
  311. package/dist/checks/quality/graph-ignore-hygiene.js.map +1 -0
  312. package/dist/checks/quality/graph-ignore-hygiene.test.d.ts +14 -0
  313. package/dist/checks/quality/graph-ignore-hygiene.test.d.ts.map +1 -0
  314. package/dist/checks/quality/graph-ignore-hygiene.test.js +58 -0
  315. package/dist/checks/quality/graph-ignore-hygiene.test.js.map +1 -0
  316. package/dist/checks/quality/index.d.ts +16 -0
  317. package/dist/checks/quality/index.d.ts.map +1 -0
  318. package/dist/checks/quality/index.js +16 -0
  319. package/dist/checks/quality/index.js.map +1 -0
  320. package/dist/checks/quality/linting/eslint-justifications.d.ts +12 -0
  321. package/dist/checks/quality/linting/eslint-justifications.d.ts.map +1 -0
  322. package/dist/checks/quality/linting/eslint-justifications.js +328 -0
  323. package/dist/checks/quality/linting/eslint-justifications.js.map +1 -0
  324. package/dist/checks/quality/linting/index.d.ts +4 -0
  325. package/dist/checks/quality/linting/index.d.ts.map +1 -0
  326. package/dist/checks/quality/linting/index.js +4 -0
  327. package/dist/checks/quality/linting/index.js.map +1 -0
  328. package/dist/checks/quality/linting/semgrep-justifications.d.ts +16 -0
  329. package/dist/checks/quality/linting/semgrep-justifications.d.ts.map +1 -0
  330. package/dist/checks/quality/linting/semgrep-justifications.js +229 -0
  331. package/dist/checks/quality/linting/semgrep-justifications.js.map +1 -0
  332. package/dist/checks/quality/linting/typescript-directive-hygiene.d.ts +12 -0
  333. package/dist/checks/quality/linting/typescript-directive-hygiene.d.ts.map +1 -0
  334. package/dist/checks/quality/linting/typescript-directive-hygiene.js +142 -0
  335. package/dist/checks/quality/linting/typescript-directive-hygiene.js.map +1 -0
  336. package/dist/checks/quality/no-compatibility-layer-names.d.ts +13 -0
  337. package/dist/checks/quality/no-compatibility-layer-names.d.ts.map +1 -0
  338. package/dist/checks/quality/no-compatibility-layer-names.js +100 -0
  339. package/dist/checks/quality/no-compatibility-layer-names.js.map +1 -0
  340. package/dist/checks/quality/no-deprecated-tags.d.ts +11 -0
  341. package/dist/checks/quality/no-deprecated-tags.d.ts.map +1 -0
  342. package/dist/checks/quality/no-deprecated-tags.js +76 -0
  343. package/dist/checks/quality/no-deprecated-tags.js.map +1 -0
  344. package/dist/checks/quality/no-markdown-references.d.ts +16 -0
  345. package/dist/checks/quality/no-markdown-references.d.ts.map +1 -0
  346. package/dist/checks/quality/no-markdown-references.js +145 -0
  347. package/dist/checks/quality/no-markdown-references.js.map +1 -0
  348. package/dist/checks/quality/no-raw-regex-on-code.d.ts +9 -0
  349. package/dist/checks/quality/no-raw-regex-on-code.d.ts.map +1 -0
  350. package/dist/checks/quality/no-raw-regex-on-code.js +61 -0
  351. package/dist/checks/quality/no-raw-regex-on-code.js.map +1 -0
  352. package/dist/checks/quality/no-temporary-workarounds.d.ts +11 -0
  353. package/dist/checks/quality/no-temporary-workarounds.d.ts.map +1 -0
  354. package/dist/checks/quality/no-temporary-workarounds.js +69 -0
  355. package/dist/checks/quality/no-temporary-workarounds.js.map +1 -0
  356. package/dist/checks/quality/no-window-alert.d.ts +19 -0
  357. package/dist/checks/quality/no-window-alert.d.ts.map +1 -0
  358. package/dist/checks/quality/no-window-alert.js +74 -0
  359. package/dist/checks/quality/no-window-alert.js.map +1 -0
  360. package/dist/checks/quality/observability/index.d.ts +2 -0
  361. package/dist/checks/quality/observability/index.d.ts.map +1 -0
  362. package/dist/checks/quality/observability/index.js +2 -0
  363. package/dist/checks/quality/observability/index.js.map +1 -0
  364. package/dist/checks/quality/observability/pino-serializer-coverage.d.ts +15 -0
  365. package/dist/checks/quality/observability/pino-serializer-coverage.d.ts.map +1 -0
  366. package/dist/checks/quality/observability/pino-serializer-coverage.js +209 -0
  367. package/dist/checks/quality/observability/pino-serializer-coverage.js.map +1 -0
  368. package/dist/checks/quality/patterns/async-state-pattern.d.ts +14 -0
  369. package/dist/checks/quality/patterns/async-state-pattern.d.ts.map +1 -0
  370. package/dist/checks/quality/patterns/async-state-pattern.js +80 -0
  371. package/dist/checks/quality/patterns/async-state-pattern.js.map +1 -0
  372. package/dist/checks/quality/patterns/index.d.ts +4 -0
  373. package/dist/checks/quality/patterns/index.d.ts.map +1 -0
  374. package/dist/checks/quality/patterns/index.js +4 -0
  375. package/dist/checks/quality/patterns/index.js.map +1 -0
  376. package/dist/checks/quality/patterns/no-non-null-assertions.d.ts +10 -0
  377. package/dist/checks/quality/patterns/no-non-null-assertions.d.ts.map +1 -0
  378. package/dist/checks/quality/patterns/no-non-null-assertions.js +97 -0
  379. package/dist/checks/quality/patterns/no-non-null-assertions.js.map +1 -0
  380. package/dist/checks/quality/patterns/performance-anti-patterns.d.ts +16 -0
  381. package/dist/checks/quality/patterns/performance-anti-patterns.d.ts.map +1 -0
  382. package/dist/checks/quality/patterns/performance-anti-patterns.js +239 -0
  383. package/dist/checks/quality/patterns/performance-anti-patterns.js.map +1 -0
  384. package/dist/checks/resilience/_helpers/config-validation.d.ts +27 -0
  385. package/dist/checks/resilience/_helpers/config-validation.d.ts.map +1 -0
  386. package/dist/checks/resilience/_helpers/config-validation.js +61 -0
  387. package/dist/checks/resilience/_helpers/config-validation.js.map +1 -0
  388. package/dist/checks/resilience/batch-operations.d.ts +22 -0
  389. package/dist/checks/resilience/batch-operations.d.ts.map +1 -0
  390. package/dist/checks/resilience/batch-operations.js +422 -0
  391. package/dist/checks/resilience/batch-operations.js.map +1 -0
  392. package/dist/checks/resilience/cache-ttl-validation.d.ts +13 -0
  393. package/dist/checks/resilience/cache-ttl-validation.d.ts.map +1 -0
  394. package/dist/checks/resilience/cache-ttl-validation.js +222 -0
  395. package/dist/checks/resilience/cache-ttl-validation.js.map +1 -0
  396. package/dist/checks/resilience/catch-clause-safety.d.ts +12 -0
  397. package/dist/checks/resilience/catch-clause-safety.d.ts.map +1 -0
  398. package/dist/checks/resilience/catch-clause-safety.js +110 -0
  399. package/dist/checks/resilience/catch-clause-safety.js.map +1 -0
  400. package/dist/checks/resilience/dangerous-config-defaults.d.ts +11 -0
  401. package/dist/checks/resilience/dangerous-config-defaults.d.ts.map +1 -0
  402. package/dist/checks/resilience/dangerous-config-defaults.js +304 -0
  403. package/dist/checks/resilience/dangerous-config-defaults.js.map +1 -0
  404. package/dist/checks/resilience/error-code-registration.d.ts +11 -0
  405. package/dist/checks/resilience/error-code-registration.d.ts.map +1 -0
  406. package/dist/checks/resilience/error-code-registration.js +88 -0
  407. package/dist/checks/resilience/error-code-registration.js.map +1 -0
  408. package/dist/checks/resilience/event-patterns.d.ts +21 -0
  409. package/dist/checks/resilience/event-patterns.d.ts.map +1 -0
  410. package/dist/checks/resilience/event-patterns.js +232 -0
  411. package/dist/checks/resilience/event-patterns.js.map +1 -0
  412. package/dist/checks/resilience/exit-code-correctness.d.ts +12 -0
  413. package/dist/checks/resilience/exit-code-correctness.d.ts.map +1 -0
  414. package/dist/checks/resilience/exit-code-correctness.js +107 -0
  415. package/dist/checks/resilience/exit-code-correctness.js.map +1 -0
  416. package/dist/checks/resilience/index.d.ts +18 -0
  417. package/dist/checks/resilience/index.d.ts.map +1 -0
  418. package/dist/checks/resilience/index.js +18 -0
  419. package/dist/checks/resilience/index.js.map +1 -0
  420. package/dist/checks/resilience/no-hardcoded-timeouts.d.ts +10 -0
  421. package/dist/checks/resilience/no-hardcoded-timeouts.d.ts.map +1 -0
  422. package/dist/checks/resilience/no-hardcoded-timeouts.js +291 -0
  423. package/dist/checks/resilience/no-hardcoded-timeouts.js.map +1 -0
  424. package/dist/checks/resilience/no-process-exit-in-finally.d.ts +11 -0
  425. package/dist/checks/resilience/no-process-exit-in-finally.d.ts.map +1 -0
  426. package/dist/checks/resilience/no-process-exit-in-finally.js +89 -0
  427. package/dist/checks/resilience/no-process-exit-in-finally.js.map +1 -0
  428. package/dist/checks/resilience/readline-cleanup.d.ts +11 -0
  429. package/dist/checks/resilience/readline-cleanup.d.ts.map +1 -0
  430. package/dist/checks/resilience/readline-cleanup.js +107 -0
  431. package/dist/checks/resilience/readline-cleanup.js.map +1 -0
  432. package/dist/checks/resilience/recovery-patterns.d.ts +25 -0
  433. package/dist/checks/resilience/recovery-patterns.d.ts.map +1 -0
  434. package/dist/checks/resilience/recovery-patterns.js +273 -0
  435. package/dist/checks/resilience/recovery-patterns.js.map +1 -0
  436. package/dist/checks/resilience/reentrancy-guard.d.ts +12 -0
  437. package/dist/checks/resilience/reentrancy-guard.d.ts.map +1 -0
  438. package/dist/checks/resilience/reentrancy-guard.js +86 -0
  439. package/dist/checks/resilience/reentrancy-guard.js.map +1 -0
  440. package/dist/checks/resilience/retry-config-validation.d.ts +13 -0
  441. package/dist/checks/resilience/retry-config-validation.d.ts.map +1 -0
  442. package/dist/checks/resilience/retry-config-validation.js +159 -0
  443. package/dist/checks/resilience/retry-config-validation.js.map +1 -0
  444. package/dist/checks/resilience/sentry/_helpers/sentry.d.ts +25 -0
  445. package/dist/checks/resilience/sentry/_helpers/sentry.d.ts.map +1 -0
  446. package/dist/checks/resilience/sentry/_helpers/sentry.js +68 -0
  447. package/dist/checks/resilience/sentry/_helpers/sentry.js.map +1 -0
  448. package/dist/checks/resilience/sentry/index.d.ts +8 -0
  449. package/dist/checks/resilience/sentry/index.d.ts.map +1 -0
  450. package/dist/checks/resilience/sentry/index.js +8 -0
  451. package/dist/checks/resilience/sentry/index.js.map +1 -0
  452. package/dist/checks/resilience/sentry/sentry-dsn-configured.d.ts +12 -0
  453. package/dist/checks/resilience/sentry/sentry-dsn-configured.d.ts.map +1 -0
  454. package/dist/checks/resilience/sentry/sentry-dsn-configured.js +55 -0
  455. package/dist/checks/resilience/sentry/sentry-dsn-configured.js.map +1 -0
  456. package/dist/checks/resilience/sentry/sentry-environment-set.d.ts +12 -0
  457. package/dist/checks/resilience/sentry/sentry-environment-set.d.ts.map +1 -0
  458. package/dist/checks/resilience/sentry/sentry-environment-set.js +51 -0
  459. package/dist/checks/resilience/sentry/sentry-environment-set.js.map +1 -0
  460. package/dist/checks/resilience/sentry/sentry-error-boundary.d.ts +12 -0
  461. package/dist/checks/resilience/sentry/sentry-error-boundary.d.ts.map +1 -0
  462. package/dist/checks/resilience/sentry/sentry-error-boundary.js +75 -0
  463. package/dist/checks/resilience/sentry/sentry-error-boundary.js.map +1 -0
  464. package/dist/checks/resilience/sentry/sentry-pii-scrubbing.d.ts +13 -0
  465. package/dist/checks/resilience/sentry/sentry-pii-scrubbing.d.ts.map +1 -0
  466. package/dist/checks/resilience/sentry/sentry-pii-scrubbing.js +125 -0
  467. package/dist/checks/resilience/sentry/sentry-pii-scrubbing.js.map +1 -0
  468. package/dist/checks/resilience/sentry/sentry-release-set.d.ts +12 -0
  469. package/dist/checks/resilience/sentry/sentry-release-set.d.ts.map +1 -0
  470. package/dist/checks/resilience/sentry/sentry-release-set.js +51 -0
  471. package/dist/checks/resilience/sentry/sentry-release-set.js.map +1 -0
  472. package/dist/checks/resilience/sentry/sentry-sample-rate.d.ts +12 -0
  473. package/dist/checks/resilience/sentry/sentry-sample-rate.d.ts.map +1 -0
  474. package/dist/checks/resilience/sentry/sentry-sample-rate.js +78 -0
  475. package/dist/checks/resilience/sentry/sentry-sample-rate.js.map +1 -0
  476. package/dist/checks/resilience/sentry/sentry-source-maps.d.ts +12 -0
  477. package/dist/checks/resilience/sentry/sentry-source-maps.d.ts.map +1 -0
  478. package/dist/checks/resilience/sentry/sentry-source-maps.js +83 -0
  479. package/dist/checks/resilience/sentry/sentry-source-maps.js.map +1 -0
  480. package/dist/checks/resilience/service-patterns.d.ts +18 -0
  481. package/dist/checks/resilience/service-patterns.d.ts.map +1 -0
  482. package/dist/checks/resilience/service-patterns.js +230 -0
  483. package/dist/checks/resilience/service-patterns.js.map +1 -0
  484. package/dist/checks/resilience/timer-lifecycle.d.ts +10 -0
  485. package/dist/checks/resilience/timer-lifecycle.d.ts.map +1 -0
  486. package/dist/checks/resilience/timer-lifecycle.js +78 -0
  487. package/dist/checks/resilience/timer-lifecycle.js.map +1 -0
  488. package/dist/checks/resilience/transaction-patterns.d.ts +21 -0
  489. package/dist/checks/resilience/transaction-patterns.d.ts.map +1 -0
  490. package/dist/checks/resilience/transaction-patterns.js +258 -0
  491. package/dist/checks/resilience/transaction-patterns.js.map +1 -0
  492. package/dist/checks/security/__tests__/no-hardcoded-secrets.test.d.ts +9 -0
  493. package/dist/checks/security/__tests__/no-hardcoded-secrets.test.d.ts.map +1 -0
  494. package/dist/checks/security/__tests__/no-hardcoded-secrets.test.js +37 -0
  495. package/dist/checks/security/__tests__/no-hardcoded-secrets.test.js.map +1 -0
  496. package/dist/checks/security/__tests__/package-supply-chain-policy.test.d.ts +2 -0
  497. package/dist/checks/security/__tests__/package-supply-chain-policy.test.d.ts.map +1 -0
  498. package/dist/checks/security/__tests__/package-supply-chain-policy.test.js +128 -0
  499. package/dist/checks/security/__tests__/package-supply-chain-policy.test.js.map +1 -0
  500. package/dist/checks/security/api-key-rotation.d.ts +10 -0
  501. package/dist/checks/security/api-key-rotation.d.ts.map +1 -0
  502. package/dist/checks/security/api-key-rotation.js +186 -0
  503. package/dist/checks/security/api-key-rotation.js.map +1 -0
  504. package/dist/checks/security/auth-middleware-coverage.d.ts +11 -0
  505. package/dist/checks/security/auth-middleware-coverage.d.ts.map +1 -0
  506. package/dist/checks/security/auth-middleware-coverage.js +210 -0
  507. package/dist/checks/security/auth-middleware-coverage.js.map +1 -0
  508. package/dist/checks/security/auth-route-guard.d.ts +12 -0
  509. package/dist/checks/security/auth-route-guard.d.ts.map +1 -0
  510. package/dist/checks/security/auth-route-guard.js +70 -0
  511. package/dist/checks/security/auth-route-guard.js.map +1 -0
  512. package/dist/checks/security/cors-configuration.d.ts +11 -0
  513. package/dist/checks/security/cors-configuration.d.ts.map +1 -0
  514. package/dist/checks/security/cors-configuration.js +126 -0
  515. package/dist/checks/security/cors-configuration.js.map +1 -0
  516. package/dist/checks/security/csp-headers.d.ts +11 -0
  517. package/dist/checks/security/csp-headers.d.ts.map +1 -0
  518. package/dist/checks/security/csp-headers.js +192 -0
  519. package/dist/checks/security/csp-headers.js.map +1 -0
  520. package/dist/checks/security/dependency-vulnerability-audit.d.ts +15 -0
  521. package/dist/checks/security/dependency-vulnerability-audit.d.ts.map +1 -0
  522. package/dist/checks/security/dependency-vulnerability-audit.js +184 -0
  523. package/dist/checks/security/dependency-vulnerability-audit.js.map +1 -0
  524. package/dist/checks/security/env-secret-exposure.d.ts +11 -0
  525. package/dist/checks/security/env-secret-exposure.d.ts.map +1 -0
  526. package/dist/checks/security/env-secret-exposure.js +127 -0
  527. package/dist/checks/security/env-secret-exposure.js.map +1 -0
  528. package/dist/checks/security/hasura-production-config.d.ts +11 -0
  529. package/dist/checks/security/hasura-production-config.d.ts.map +1 -0
  530. package/dist/checks/security/hasura-production-config.js +122 -0
  531. package/dist/checks/security/hasura-production-config.js.map +1 -0
  532. package/dist/checks/security/index.d.ts +17 -0
  533. package/dist/checks/security/index.d.ts.map +1 -0
  534. package/dist/checks/security/index.js +17 -0
  535. package/dist/checks/security/index.js.map +1 -0
  536. package/dist/checks/security/jwt-validation.d.ts +11 -0
  537. package/dist/checks/security/jwt-validation.d.ts.map +1 -0
  538. package/dist/checks/security/jwt-validation.js +294 -0
  539. package/dist/checks/security/jwt-validation.js.map +1 -0
  540. package/dist/checks/security/no-eval.d.ts +16 -0
  541. package/dist/checks/security/no-eval.d.ts.map +1 -0
  542. package/dist/checks/security/no-eval.js +83 -0
  543. package/dist/checks/security/no-eval.js.map +1 -0
  544. package/dist/checks/security/no-hardcoded-secrets.d.ts +28 -0
  545. package/dist/checks/security/no-hardcoded-secrets.d.ts.map +1 -0
  546. package/dist/checks/security/no-hardcoded-secrets.js +209 -0
  547. package/dist/checks/security/no-hardcoded-secrets.js.map +1 -0
  548. package/dist/checks/security/package-supply-chain-policy.d.ts +12 -0
  549. package/dist/checks/security/package-supply-chain-policy.d.ts.map +1 -0
  550. package/dist/checks/security/package-supply-chain-policy.js +534 -0
  551. package/dist/checks/security/package-supply-chain-policy.js.map +1 -0
  552. package/dist/checks/security/rate-limit-coverage.d.ts +10 -0
  553. package/dist/checks/security/rate-limit-coverage.d.ts.map +1 -0
  554. package/dist/checks/security/rate-limit-coverage.js +143 -0
  555. package/dist/checks/security/rate-limit-coverage.js.map +1 -0
  556. package/dist/checks/security/semgrep-scan.d.ts +13 -0
  557. package/dist/checks/security/semgrep-scan.d.ts.map +1 -0
  558. package/dist/checks/security/semgrep-scan.js +86 -0
  559. package/dist/checks/security/semgrep-scan.js.map +1 -0
  560. package/dist/checks/security/use-centralized-crypto.d.ts +11 -0
  561. package/dist/checks/security/use-centralized-crypto.d.ts.map +1 -0
  562. package/dist/checks/security/use-centralized-crypto.js +129 -0
  563. package/dist/checks/security/use-centralized-crypto.js.map +1 -0
  564. package/dist/checks/security/webhook-signature-verification.d.ts +10 -0
  565. package/dist/checks/security/webhook-signature-verification.d.ts.map +1 -0
  566. package/dist/checks/security/webhook-signature-verification.js +183 -0
  567. package/dist/checks/security/webhook-signature-verification.js.map +1 -0
  568. package/dist/checks/testing/index.d.ts +6 -0
  569. package/dist/checks/testing/index.d.ts.map +1 -0
  570. package/dist/checks/testing/index.js +6 -0
  571. package/dist/checks/testing/index.js.map +1 -0
  572. package/dist/checks/testing/no-skipped-tests.d.ts +40 -0
  573. package/dist/checks/testing/no-skipped-tests.d.ts.map +1 -0
  574. package/dist/checks/testing/no-skipped-tests.js +174 -0
  575. package/dist/checks/testing/no-skipped-tests.js.map +1 -0
  576. package/dist/checks/testing/no-stub-tests.d.ts +11 -0
  577. package/dist/checks/testing/no-stub-tests.d.ts.map +1 -0
  578. package/dist/checks/testing/no-stub-tests.js +103 -0
  579. package/dist/checks/testing/no-stub-tests.js.map +1 -0
  580. package/dist/checks/testing/test-convention-consistency.d.ts +14 -0
  581. package/dist/checks/testing/test-convention-consistency.d.ts.map +1 -0
  582. package/dist/checks/testing/test-convention-consistency.js +93 -0
  583. package/dist/checks/testing/test-convention-consistency.js.map +1 -0
  584. package/dist/checks/testing/test-file-naming.d.ts +13 -0
  585. package/dist/checks/testing/test-file-naming.d.ts.map +1 -0
  586. package/dist/checks/testing/test-file-naming.js +218 -0
  587. package/dist/checks/testing/test-file-naming.js.map +1 -0
  588. package/dist/checks/testing/test-file-pairing.d.ts +13 -0
  589. package/dist/checks/testing/test-file-pairing.d.ts.map +1 -0
  590. package/dist/checks/testing/test-file-pairing.js +274 -0
  591. package/dist/checks/testing/test-file-pairing.js.map +1 -0
  592. package/dist/display/architecture.d.ts +9 -0
  593. package/dist/display/architecture.d.ts.map +1 -0
  594. package/dist/display/architecture.js +29 -0
  595. package/dist/display/architecture.js.map +1 -0
  596. package/dist/display/index.d.ts +20 -0
  597. package/dist/display/index.d.ts.map +1 -0
  598. package/dist/display/index.js +30 -0
  599. package/dist/display/index.js.map +1 -0
  600. package/dist/display/quality.d.ts +7 -0
  601. package/dist/display/quality.d.ts.map +1 -0
  602. package/dist/display/quality.js +34 -0
  603. package/dist/display/quality.js.map +1 -0
  604. package/dist/display/resilience.d.ts +7 -0
  605. package/dist/display/resilience.d.ts.map +1 -0
  606. package/dist/display/resilience.js +36 -0
  607. package/dist/display/resilience.js.map +1 -0
  608. package/dist/display/security-testing.d.ts +9 -0
  609. package/dist/display/security-testing.d.ts.map +1 -0
  610. package/dist/display/security-testing.js +31 -0
  611. package/dist/display/security-testing.js.map +1 -0
  612. package/dist/display/types.d.ts +6 -0
  613. package/dist/display/types.d.ts.map +1 -0
  614. package/dist/display/types.js +6 -0
  615. package/dist/display/types.js.map +1 -0
  616. package/dist/index.d.ts +19 -0
  617. package/dist/index.d.ts.map +1 -0
  618. package/dist/index.js +21 -0
  619. package/dist/index.js.map +1 -0
  620. package/package.json +52 -0
@@ -0,0 +1,93 @@
1
+ // @fitness-ignore-file fitness-ignore-hygiene -- check references internal slugs that may differ from registered slugs
2
+ /**
3
+ * @fileoverview Fitness ignore hygiene check
4
+ */
5
+ import { defineCheck } from '@opensip-cli/fitness';
6
+ /** Regex to match @fitness-ignore directives */
7
+ const FITNESS_IGNORE_REGEX = /@fitness-ignore(?:-file|-next-line)?\s+(\S+)/g;
8
+ /** Valid check slug format: kebab-case */
9
+ const VALID_SLUG_PATTERN = /^[a-z][a-z0-9-]*$/;
10
+ /**
11
+ * Analyze @fitness-ignore directives for hygiene issues
12
+ */
13
+ function analyzeIgnoreHygiene(content, _filePath) {
14
+ const violations = [];
15
+ const lines = content.split('\n');
16
+ let totalIgnoreDirectives = 0;
17
+ for (const [i, line_] of lines.entries()) {
18
+ const line = line_ ?? '';
19
+ // Only check actual comment lines — skip string literals, code, and template literals
20
+ // that happen to contain ignore-directive text (e.g., regex patterns, suggestion strings)
21
+ if (!line.trim().startsWith('//'))
22
+ continue;
23
+ FITNESS_IGNORE_REGEX.lastIndex = 0;
24
+ const ignoreMatches = [...line.matchAll(FITNESS_IGNORE_REGEX)];
25
+ for (const match of ignoreMatches) {
26
+ totalIgnoreDirectives++;
27
+ const checkSlug = match[1];
28
+ // Validate check slug format
29
+ if (checkSlug && !VALID_SLUG_PATTERN.test(checkSlug)) {
30
+ violations.push({
31
+ line: i + 1,
32
+ message: `@fitness-ignore references '${checkSlug}' which is not a valid check slug (expected kebab-case)`,
33
+ severity: 'warning',
34
+ suggestion: 'Use a valid check slug like "no-generic-error" or "file-length-limits"',
35
+ type: 'invalid-ignore-slug',
36
+ match: line.trim().slice(0, 120),
37
+ });
38
+ }
39
+ // Check for ignore directive without a reason comment
40
+ // Expected format: @fitness-ignore slug -- reason
41
+ const afterMatch = line.slice(match.index + match[0].length);
42
+ const hasReason = afterMatch.includes('--');
43
+ if (!hasReason) {
44
+ violations.push({
45
+ line: i + 1,
46
+ message: `@fitness-ignore directive for '${checkSlug ?? 'unknown'}' missing a reason comment`,
47
+ severity: 'warning',
48
+ suggestion: 'Add a reason: @fitness-ignore check-slug -- Reason why this is suppressed',
49
+ type: 'ignore-without-reason',
50
+ match: line.trim().slice(0, 120),
51
+ });
52
+ }
53
+ }
54
+ }
55
+ // Flag files with excessive ignore directives
56
+ if (totalIgnoreDirectives > 7) {
57
+ violations.push({
58
+ line: 1,
59
+ message: `File has ${totalIgnoreDirectives} @fitness-ignore directives — consider fixing the underlying issues instead of suppressing`,
60
+ severity: 'warning',
61
+ suggestion: 'Review each suppression to determine if the underlying issue can be fixed',
62
+ type: 'excessive-ignores',
63
+ });
64
+ }
65
+ return violations;
66
+ }
67
+ /**
68
+ * Check: quality/fitness-ignore-hygiene
69
+ *
70
+ * Validates that @fitness-ignore directives have valid check slugs and reason comments.
71
+ */
72
+ export const fitnessIgnoreHygiene = defineCheck({
73
+ id: '1d4028f6-6cd4-40b1-8b66-9846daa57e5a',
74
+ slug: 'fitness-ignore-hygiene',
75
+ scope: { languages: ['typescript'], concerns: ['fitness'] },
76
+ contentFilter: 'raw',
77
+ description: 'Validates that @fitness-ignore directives have valid check slugs and reason comments',
78
+ longDescription: `**Purpose:** Validates the quality of \`@fitness-ignore\` directives to prevent stale or undocumented suppressions.
79
+
80
+ **Detects:**
81
+ - Directives with invalid check slugs (not kebab-case)
82
+ - Directives missing a reason comment (\`-- reason\`)
83
+ - Files with more than 7 ignore directives (suggests fixing underlying issues)
84
+
85
+ **Why it matters:** Undocumented suppressions accumulate over time and can mask real issues when check scopes change.
86
+
87
+ **Scope:** All TypeScript files. Analyzes each file individually via regex.`,
88
+ tags: ['quality', 'fitness', 'hygiene'],
89
+ fileTypes: ['ts'],
90
+ confidence: 'medium',
91
+ analyze: analyzeIgnoreHygiene,
92
+ });
93
+ //# sourceMappingURL=fitness-ignore-hygiene.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fitness-ignore-hygiene.js","sourceRoot":"","sources":["../../../src/checks/quality/fitness-ignore-hygiene.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * @fileoverview Expo Vector Icons Check
3
+ *
4
+ * Ensures consistent icon library usage across the frontend codebase.
5
+ * Recommends using @expo/vector-icons for React Native compatibility.
6
+ */
7
+ /**
8
+ * Check: quality/expo-vector-icons
9
+ *
10
+ * Ensures consistent icon library usage with @expo/vector-icons.
11
+ */
12
+ export declare const expoVectorIcons: import("@opensip-cli/fitness").Check;
13
+ //# sourceMappingURL=expo-vector-icons.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expo-vector-icons.d.ts","sourceRoot":"","sources":["../../../../src/checks/quality/frontend/expo-vector-icons.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAwDH;;;;GAIG;AACH,eAAO,MAAM,eAAe,sCAsB1B,CAAC"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * @fileoverview Expo Vector Icons Check
3
+ *
4
+ * Ensures consistent icon library usage across the frontend codebase.
5
+ * Recommends using @expo/vector-icons for React Native compatibility.
6
+ */
7
+ import { defineCheck } from '@opensip-cli/fitness';
8
+ const PREFERRED_ICON_LIBRARY = '@expo/vector-icons';
9
+ const DISCOURAGED_LIBRARIES = [
10
+ 'react-native-vector-icons',
11
+ 'react-icons',
12
+ '@fortawesome/react-native-fontawesome',
13
+ ];
14
+ /**
15
+ * Escape special regex characters in a string
16
+ */
17
+ function escapeRegExp(str) {
18
+ // @fitness-ignore-next-line fitness-check-standards -- Character class regex is safe from ReDoS, no backtracking
19
+ return str.replaceAll(/[.*+?^${}()|[\]\\]/g, String.raw `\$&`);
20
+ }
21
+ /**
22
+ * Analyze a file for icon library issues
23
+ * @param {string} content - File content to analyze
24
+ * @param {string} filePath - Path to the file
25
+ * @returns {CheckViolation[]} Array of violations found
26
+ */
27
+ function analyzeFile(content, filePath) {
28
+ // Quick filter: skip if no discouraged library mentioned
29
+ if (!DISCOURAGED_LIBRARIES.some((lib) => content.includes(lib))) {
30
+ return [];
31
+ }
32
+ const violations = [];
33
+ for (const lib of DISCOURAGED_LIBRARIES) {
34
+ const escapedLib = escapeRegExp(lib);
35
+ const pattern = String.raw `import\s+.*\s+from\s+['"]${escapedLib}['"]`;
36
+ const regex = new RegExp(pattern, 'g');
37
+ let match;
38
+ while ((match = regex.exec(content)) !== null) {
39
+ const line = content.slice(0, Math.max(0, match.index)).split('\n').length;
40
+ violations.push({
41
+ filePath,
42
+ line,
43
+ column: 0,
44
+ message: `Using ${lib} instead of ${PREFERRED_ICON_LIBRARY}`,
45
+ severity: 'warning',
46
+ type: 'discouraged-library',
47
+ suggestion: `Replace import with: import { IconName } from '${PREFERRED_ICON_LIBRARY}/FontAwesome' or another icon family from @expo/vector-icons`,
48
+ match: lib,
49
+ });
50
+ }
51
+ }
52
+ return violations;
53
+ }
54
+ /**
55
+ * Check: quality/expo-vector-icons
56
+ *
57
+ * Ensures consistent icon library usage with @expo/vector-icons.
58
+ */
59
+ export const expoVectorIcons = defineCheck({
60
+ id: 'dccf8b44-b1be-40b5-82e7-631daa8c0013',
61
+ slug: 'expo-vector-icons',
62
+ disabled: true,
63
+ scope: { languages: ['typescript', 'tsx'], concerns: ['frontend', 'ui'] },
64
+ contentFilter: 'strip-strings',
65
+ confidence: 'medium',
66
+ description: 'Ensure consistent icon library usage with @expo/vector-icons',
67
+ longDescription: `**Purpose:** Enforces consistent icon library usage by flagging imports from discouraged icon packages in favor of \`@expo/vector-icons\`.
68
+
69
+ **Detects:** Analyzes each file individually using regex-based import scanning.
70
+ - Import statements from \`react-native-vector-icons\`, \`react-icons\`, or \`@fortawesome/react-native-fontawesome\`
71
+ - Matches the pattern \`import ... from '<library>'\` for each discouraged library
72
+
73
+ **Why it matters:** Using multiple icon libraries increases bundle size and creates visual inconsistency. \`@expo/vector-icons\` is the standard for React Native/Expo compatibility.
74
+
75
+ **Scope:** Codebase-specific convention`,
76
+ tags: ['quality', 'consistency', 'best-practices', 'react-native', 'icons'],
77
+ fileTypes: ['ts', 'tsx'],
78
+ analyze: analyzeFile,
79
+ });
80
+ //# sourceMappingURL=expo-vector-icons.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expo-vector-icons.js","sourceRoot":"","sources":["../../../../src/checks/quality/frontend/expo-vector-icons.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAuB,MAAM,sBAAsB,CAAC;AAExE,MAAM,sBAAsB,GAAG,oBAAoB,CAAC;AACpD,MAAM,qBAAqB,GAAG;IAC5B,2BAA2B;IAC3B,aAAa;IACb,uCAAuC;CACxC,CAAC;AAEF;;GAEG;AACH,SAAS,YAAY,CAAC,GAAW;IAC/B,iHAAiH;IACjH,OAAO,GAAG,CAAC,UAAU,CAAC,qBAAqB,EAAE,MAAM,CAAC,GAAG,CAAA,KAAK,CAAC,CAAC;AAChE,CAAC;AAED;;;;;GAKG;AACH,SAAS,WAAW,CAAC,OAAe,EAAE,QAAgB;IACpD,yDAAyD;IACzD,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;QAChE,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,UAAU,GAAqB,EAAE,CAAC;IAExC,KAAK,MAAM,GAAG,IAAI,qBAAqB,EAAE,CAAC;QACxC,MAAM,UAAU,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;QACrC,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAA,4BAA4B,UAAU,MAAM,CAAC;QACvE,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QACvC,IAAI,KAAK,CAAC;QACV,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YAC9C,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;YAC3E,UAAU,CAAC,IAAI,CAAC;gBACd,QAAQ;gBACR,IAAI;gBACJ,MAAM,EAAE,CAAC;gBACT,OAAO,EAAE,SAAS,GAAG,eAAe,sBAAsB,EAAE;gBAC5D,QAAQ,EAAE,SAAS;gBACnB,IAAI,EAAE,qBAAqB;gBAC3B,UAAU,EAAE,kDAAkD,sBAAsB,8DAA8D;gBAClJ,KAAK,EAAE,GAAG;aACX,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,WAAW,CAAC;IACzC,EAAE,EAAE,sCAAsC;IAC1C,IAAI,EAAE,mBAAmB;IACzB,QAAQ,EAAE,IAAI;IACd,KAAK,EAAE,EAAE,SAAS,EAAE,CAAC,YAAY,EAAE,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,EAAE;IACzE,aAAa,EAAE,eAAe;IAE9B,UAAU,EAAE,QAAQ;IACpB,WAAW,EAAE,8DAA8D;IAC3E,eAAe,EAAE;;;;;;;;wCAQqB;IACtC,IAAI,EAAE,CAAC,SAAS,EAAE,aAAa,EAAE,gBAAgB,EAAE,cAAc,EAAE,OAAO,CAAC;IAC3E,SAAS,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC;IAExB,OAAO,EAAE,WAAW;CACrB,CAAC,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * @fileoverview Image Optimization Check
3
+ *
4
+ * Detects unoptimized image imports and usage patterns in React Native code.
5
+ * Recommends using Expo Image or optimized image loading strategies.
6
+ */
7
+ /**
8
+ * Check: quality/image-optimization
9
+ *
10
+ * Detects unoptimized image usage and recommends best practices.
11
+ */
12
+ export declare const imageOptimization: import("@opensip-cli/fitness").Check;
13
+ //# sourceMappingURL=image-optimization.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-optimization.d.ts","sourceRoot":"","sources":["../../../../src/checks/quality/frontend/image-optimization.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA0JH;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,sCAsB5B,CAAC"}
@@ -0,0 +1,166 @@
1
+ /**
2
+ * @fileoverview Image Optimization Check
3
+ *
4
+ * Detects unoptimized image imports and usage patterns in React Native code.
5
+ * Recommends using Expo Image or optimized image loading strategies.
6
+ */
7
+ import { defineCheck } from '@opensip-cli/fitness';
8
+ /**
9
+ * Check if content contains a react-native Image import.
10
+ * Uses simple string search instead of regex for ReDoS safety.
11
+ *
12
+ * @param content - File content to check
13
+ * @returns True if react-native Image import is found
14
+ */
15
+ function hasReactNativeImageImport(content) {
16
+ const lines = content.split('\n');
17
+ for (const line of lines) {
18
+ const isImportStatement = line.includes('import') && line.includes('Image');
19
+ const isFromReactNative = line.includes('react-native');
20
+ const isNamedImport = line.includes('{') && line.includes('}');
21
+ if (isImportStatement && isFromReactNative && isNamedImport) {
22
+ return true;
23
+ }
24
+ }
25
+ return false;
26
+ }
27
+ /**
28
+ * Check if content contains an expo-image import.
29
+ *
30
+ * @param content - File content to check
31
+ * @returns True if expo-image import is found
32
+ */
33
+ function hasExpoImageImport(content) {
34
+ return content.includes("from 'expo-image'") || content.includes('from "expo-image"');
35
+ }
36
+ /**
37
+ * Find the line number of a react-native Image import.
38
+ *
39
+ * @param content - File content to search
40
+ * @returns Line number (1-based) and snippet, or null if not found
41
+ */
42
+ function findReactNativeImageLine(content) {
43
+ const lines = content.split('\n');
44
+ for (const [i, line] of lines.entries()) {
45
+ /* v8 ignore next 3 -- defensive: lines.entries() never yields undefined */
46
+ if (line === undefined) {
47
+ continue;
48
+ }
49
+ const isImportStatement = line.includes('import') && line.includes('Image');
50
+ const isFromReactNative = line.includes('react-native');
51
+ const isNamedImport = line.includes('{') && line.includes('}');
52
+ if (isImportStatement && isFromReactNative && isNamedImport) {
53
+ return { line: i + 1, snippet: line.trim() };
54
+ }
55
+ }
56
+ return null;
57
+ }
58
+ /**
59
+ * Find Image components without placeholder prop.
60
+ * Uses line-by-line analysis instead of regex for ReDoS safety.
61
+ *
62
+ * @param content - File content to search
63
+ * @returns Array of violations with line numbers
64
+ */
65
+ function findImagesWithoutPlaceholder(content) {
66
+ const results = [];
67
+ const lines = content.split('\n');
68
+ for (let i = 0; i < lines.length; i++) {
69
+ const line = lines[i];
70
+ /* v8 ignore next 3 -- defensive: index access on existing array never returns undefined */
71
+ if (line === undefined) {
72
+ continue;
73
+ }
74
+ // Look for <Image with source prop but without placeholder
75
+ if (line.includes('<Image') && line.includes('source=')) {
76
+ // Check this line and surrounding context for placeholder
77
+ const contextStart = Math.max(0, i - 2);
78
+ const contextEnd = Math.min(lines.length, i + 3);
79
+ const context = lines.slice(contextStart, contextEnd).join('\n');
80
+ if (!context.includes('placeholder')) {
81
+ results.push({ line: i + 1, snippet: line.trim().slice(0, 100) });
82
+ }
83
+ }
84
+ }
85
+ return results;
86
+ }
87
+ /**
88
+ * Analyzes a single file for image optimization issues
89
+ *
90
+ * @param content - File content to analyze
91
+ * @param filePath - Path to the file being analyzed
92
+ * @returns Array of violations found
93
+ */
94
+ function analyzeFile(content, filePath) {
95
+ // Only check TSX files
96
+ if (!filePath.endsWith('.tsx')) {
97
+ return [];
98
+ }
99
+ // Quick filter: skip files without Image
100
+ if (!content.includes('Image')) {
101
+ return [];
102
+ }
103
+ const violations = [];
104
+ // Check for react-native Image without expo-image
105
+ const hasRNImage = hasReactNativeImageImport(content);
106
+ const hasExpoImage = hasExpoImageImport(content);
107
+ if (hasRNImage && !hasExpoImage) {
108
+ const importInfo = findReactNativeImageLine(content);
109
+ if (importInfo) {
110
+ violations.push({
111
+ filePath,
112
+ line: importInfo.line,
113
+ column: 0,
114
+ message: 'Using react-native Image instead of expo-image',
115
+ severity: 'warning',
116
+ type: 'use-expo-image',
117
+ suggestion: "Replace with expo-image for better performance and caching: import { Image } from 'expo-image'. Expo Image provides automatic caching, better memory management, and supports modern image formats.",
118
+ match: 'react-native Image',
119
+ });
120
+ }
121
+ }
122
+ // Check for Image without placeholder prop (for expo-image)
123
+ if (hasExpoImage) {
124
+ const imagesWithoutPlaceholder = findImagesWithoutPlaceholder(content);
125
+ for (const img of imagesWithoutPlaceholder) {
126
+ violations.push({
127
+ filePath,
128
+ line: img.line,
129
+ column: 0,
130
+ message: 'Image missing placeholder for loading state',
131
+ severity: 'warning',
132
+ type: 'no-placeholder',
133
+ suggestion: 'Add placeholder prop for better UX during loading. Use a low-resolution placeholder or blurhash for smooth loading transitions.',
134
+ match: '<Image',
135
+ });
136
+ }
137
+ }
138
+ return violations;
139
+ }
140
+ /**
141
+ * Check: quality/image-optimization
142
+ *
143
+ * Detects unoptimized image usage and recommends best practices.
144
+ */
145
+ export const imageOptimization = defineCheck({
146
+ id: 'fe256cba-e891-466b-9361-c71b5af216d9',
147
+ slug: 'image-optimization',
148
+ disabled: true,
149
+ scope: { languages: ['typescript', 'tsx'], concerns: ['frontend', 'ui'] },
150
+ confidence: 'medium',
151
+ description: 'Detect unoptimized image usage and recommend best practices',
152
+ longDescription: `**Purpose:** Detects unoptimized image loading patterns and enforces usage of \`expo-image\` over React Native's built-in \`Image\` component.
153
+
154
+ **Detects:** Analyzes each file individually using line-by-line string matching.
155
+ - \`Image\` imported from \`react-native\` (named import with curly braces) when \`expo-image\` is not also imported
156
+ - \`<Image>\` elements using \`expo-image\` that have a \`source=\` prop but no \`placeholder\` prop within a 5-line context window
157
+ - Only scans \`.tsx\` files; excludes test files
158
+
159
+ **Why it matters:** React Native's \`Image\` lacks caching, modern format support, and memory management. Missing placeholders cause layout shifts during loading.
160
+
161
+ **Scope:** Codebase-specific convention`,
162
+ tags: ['quality', 'performance', 'best-practices', 'react-native', 'images'],
163
+ fileTypes: ['ts', 'tsx'],
164
+ analyze: analyzeFile,
165
+ });
166
+ //# sourceMappingURL=image-optimization.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-optimization.js","sourceRoot":"","sources":["../../../../src/checks/quality/frontend/image-optimization.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export * from './expo-vector-icons.js';
2
+ export * from './image-optimization.js';
3
+ export * from './navigation-typing.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/checks/quality/frontend/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC"}
@@ -0,0 +1,4 @@
1
+ export * from './expo-vector-icons.js';
2
+ export * from './image-optimization.js';
3
+ export * from './navigation-typing.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/checks/quality/frontend/index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,wBAAwB,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @fileoverview Navigation Typing Check
3
+ *
4
+ * Verifies that navigation params are properly typed for type-safe routing.
5
+ */
6
+ /**
7
+ * Check: quality/navigation-typing
8
+ *
9
+ * Verifies navigation params are properly typed for type-safe routing.
10
+ */
11
+ export declare const navigationTyping: import("@opensip-cli/fitness").Check;
12
+ //# sourceMappingURL=navigation-typing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navigation-typing.d.ts","sourceRoot":"","sources":["../../../../src/checks/quality/frontend/navigation-typing.ts"],"names":[],"mappings":"AACA;;;;GAIG;AAoDH;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,sCAuB3B,CAAC"}
@@ -0,0 +1,77 @@
1
+ // @fitness-ignore-file file-length-limit -- Complex module with tightly coupled logic; refactoring would risk breaking changes
2
+ /**
3
+ * @fileoverview Navigation Typing Check
4
+ *
5
+ * Verifies that navigation params are properly typed for type-safe routing.
6
+ */
7
+ import { defineCheck } from '@opensip-cli/fitness';
8
+ /**
9
+ * Analyzes a single file for navigation typing issues
10
+ */
11
+ function analyzeFile(content, filePath) {
12
+ const violations = [];
13
+ // Quick filter: skip files without navigation patterns
14
+ if (!content.includes('useLocalSearchParams') && !content.includes('router.push')) {
15
+ return violations;
16
+ }
17
+ // Check for untyped useLocalSearchParams
18
+ const untypedParamsRegex = /useLocalSearchParams\s*\(\s*\)/g;
19
+ let match;
20
+ while ((match = untypedParamsRegex.exec(content)) !== null) {
21
+ const line = content.slice(0, Math.max(0, match.index)).split('\n').length;
22
+ violations.push({
23
+ filePath,
24
+ line,
25
+ column: 0,
26
+ message: 'useLocalSearchParams without type parameter',
27
+ severity: 'warning',
28
+ type: 'untyped-params',
29
+ suggestion: 'Add type parameter: useLocalSearchParams<{ id: string }>() to get type-safe route params.',
30
+ match: 'useLocalSearchParams()',
31
+ });
32
+ }
33
+ // Check for untyped router.push with params
34
+ const untypedPushRegex = /router\.push\(\s*['"`][^'"`]+['"`]\s*,\s*\{/g;
35
+ while ((match = untypedPushRegex.exec(content)) !== null) {
36
+ const line = content.slice(0, Math.max(0, match.index)).split('\n').length;
37
+ violations.push({
38
+ filePath,
39
+ line,
40
+ column: 0,
41
+ message: 'router.push with inline params may lack type safety',
42
+ severity: 'warning',
43
+ type: 'untyped-push',
44
+ suggestion: 'Use typed route helpers or define route types for type-safe navigation params.',
45
+ match: 'router.push',
46
+ });
47
+ }
48
+ return violations;
49
+ }
50
+ /**
51
+ * Check: quality/navigation-typing
52
+ *
53
+ * Verifies navigation params are properly typed for type-safe routing.
54
+ */
55
+ export const navigationTyping = defineCheck({
56
+ id: '11547dc2-7666-4617-9705-be27528c4227',
57
+ slug: 'navigation-typing',
58
+ disabled: true,
59
+ scope: { languages: ['typescript', 'tsx'], concerns: ['frontend', 'ui'] },
60
+ contentFilter: 'strip-strings',
61
+ confidence: 'medium',
62
+ description: 'Verify navigation params are properly typed for type-safe routing',
63
+ longDescription: `**Purpose:** Ensures Expo Router navigation parameters are properly typed for compile-time type safety on route params.
64
+
65
+ **Detects:** Analyzes each file individually using regex-based pattern matching.
66
+ - \`useLocalSearchParams()\` called without a type parameter (matches \`/useLocalSearchParams\\s*\\(\\s*\\)/\`)
67
+ - \`router.push()\` called with a string route and inline object params (matches \`/router\\.push\\(\\s*['"\`][^'"\`]+['"\`]\\s*,\\s*\\{/\`)
68
+ - Uses a quick-filter optimization: skips files not containing \`useLocalSearchParams\` or \`router.push\`
69
+
70
+ **Why it matters:** Untyped navigation params silently accept wrong types at compile time, leading to runtime crashes when route params are missing or have unexpected shapes.
71
+
72
+ **Scope:** General best practice`,
73
+ tags: ['quality', 'type-safety', 'best-practices', 'react-native'],
74
+ fileTypes: ['ts', 'tsx'],
75
+ analyze: analyzeFile,
76
+ });
77
+ //# sourceMappingURL=navigation-typing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navigation-typing.js","sourceRoot":"","sources":["../../../../src/checks/quality/frontend/navigation-typing.ts"],"names":[],"mappings":"AAAA,+HAA+H;AAC/H;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAuB,MAAM,sBAAsB,CAAC;AAExE;;GAEG;AACH,SAAS,WAAW,CAAC,OAAe,EAAE,QAAgB;IACpD,MAAM,UAAU,GAAqB,EAAE,CAAC;IAExC,uDAAuD;IACvD,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;QAClF,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,yCAAyC;IACzC,MAAM,kBAAkB,GAAG,iCAAiC,CAAC;IAC7D,IAAI,KAAK,CAAC;IACV,OAAO,CAAC,KAAK,GAAG,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QAC3D,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;QAC3E,UAAU,CAAC,IAAI,CAAC;YACd,QAAQ;YACR,IAAI;YACJ,MAAM,EAAE,CAAC;YACT,OAAO,EAAE,6CAA6C;YACtD,QAAQ,EAAE,SAAS;YACnB,IAAI,EAAE,gBAAgB;YACtB,UAAU,EACR,2FAA2F;YAC7F,KAAK,EAAE,wBAAwB;SAChC,CAAC,CAAC;IACL,CAAC;IAED,4CAA4C;IAC5C,MAAM,gBAAgB,GAAG,8CAA8C,CAAC;IACxE,OAAO,CAAC,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QACzD,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;QAC3E,UAAU,CAAC,IAAI,CAAC;YACd,QAAQ;YACR,IAAI;YACJ,MAAM,EAAE,CAAC;YACT,OAAO,EAAE,qDAAqD;YAC9D,QAAQ,EAAE,SAAS;YACnB,IAAI,EAAE,cAAc;YACpB,UAAU,EAAE,gFAAgF;YAC5F,KAAK,EAAE,aAAa;SACrB,CAAC,CAAC;IACL,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,WAAW,CAAC;IAC1C,EAAE,EAAE,sCAAsC;IAC1C,IAAI,EAAE,mBAAmB;IACzB,QAAQ,EAAE,IAAI;IACd,KAAK,EAAE,EAAE,SAAS,EAAE,CAAC,YAAY,EAAE,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,EAAE;IACzE,aAAa,EAAE,eAAe;IAE9B,UAAU,EAAE,QAAQ;IACpB,WAAW,EAAE,mEAAmE;IAChF,eAAe,EAAE;;;;;;;;;iCASc;IAC/B,IAAI,EAAE,CAAC,SAAS,EAAE,aAAa,EAAE,gBAAgB,EAAE,cAAc,CAAC;IAClE,SAAS,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC;IAExB,OAAO,EAAE,WAAW;CACrB,CAAC,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @fileoverview Graph ignore hygiene check
3
+ */
4
+ /**
5
+ * Check: quality/graph-ignore-hygiene
6
+ *
7
+ * Validates that @graph-ignore directives have valid graph rule ids and reason comments.
8
+ */
9
+ export declare const graphIgnoreHygiene: import("@opensip-cli/fitness").Check;
10
+ //# sourceMappingURL=graph-ignore-hygiene.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph-ignore-hygiene.d.ts","sourceRoot":"","sources":["../../../src/checks/quality/graph-ignore-hygiene.ts"],"names":[],"mappings":"AACA;;GAEG;AA2EH;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,sCAuB7B,CAAC"}
@@ -0,0 +1,95 @@
1
+ // @fitness-ignore-file graph-ignore-hygiene -- check references internal slugs that may differ from registered slugs
2
+ /**
3
+ * @fileoverview Graph ignore hygiene check
4
+ */
5
+ import { defineCheck } from '@opensip-cli/fitness';
6
+ /** Regex to match @graph-ignore directives */
7
+ const GRAPH_IGNORE_REGEX = /@graph-ignore(?:-file|-next-line)?\s+(\S+)/g;
8
+ /** Valid graph rule id format: graph-namespaced kebab-case (e.g. `graph:cycle`) */
9
+ const VALID_GRAPH_ID = /^graph:[a-z][a-z0-9-]*$/;
10
+ /**
11
+ * Analyze @graph-ignore directives for hygiene issues
12
+ */
13
+ function analyzeIgnoreHygiene(content, _filePath) {
14
+ const violations = [];
15
+ const lines = content.split('\n');
16
+ let totalIgnoreDirectives = 0;
17
+ for (const [i, line_] of lines.entries()) {
18
+ const line = line_ ?? '';
19
+ // Only check actual comment lines — skip string literals, code, and template literals
20
+ // that happen to contain ignore-directive text (e.g., regex patterns, suggestion strings)
21
+ if (!line.trim().startsWith('//'))
22
+ continue;
23
+ GRAPH_IGNORE_REGEX.lastIndex = 0;
24
+ const ignoreMatches = [...line.matchAll(GRAPH_IGNORE_REGEX)];
25
+ for (const match of ignoreMatches) {
26
+ totalIgnoreDirectives++;
27
+ const ruleId = match[1];
28
+ // Validate graph rule id format (graph:<kebab>)
29
+ if (ruleId && !VALID_GRAPH_ID.test(ruleId)) {
30
+ violations.push({
31
+ line: i + 1,
32
+ message: `@graph-ignore references '${ruleId}' which is not a valid graph rule id (expected \`graph:<kebab>\`)`,
33
+ severity: 'warning',
34
+ suggestion: 'Use a valid graph rule id like "graph:cycle" or "graph:large-function"',
35
+ type: 'invalid-ignore-slug',
36
+ match: line.trim().slice(0, 120),
37
+ });
38
+ }
39
+ // Check for ignore directive without a reason comment
40
+ // Expected format: @graph-ignore graph:<rule> -- reason
41
+ const afterMatch = line.slice(match.index + match[0].length);
42
+ const hasReason = afterMatch.includes('--');
43
+ if (!hasReason) {
44
+ violations.push({
45
+ line: i + 1,
46
+ message: `@graph-ignore directive for '${ruleId ?? 'unknown'}' missing a reason comment`,
47
+ severity: 'warning',
48
+ suggestion: 'Add a reason: @graph-ignore graph:rule-id -- Reason why this is suppressed',
49
+ type: 'ignore-without-reason',
50
+ match: line.trim().slice(0, 120),
51
+ });
52
+ }
53
+ }
54
+ }
55
+ // Flag files with excessive ignore directives
56
+ if (totalIgnoreDirectives > 7) {
57
+ violations.push({
58
+ line: 1,
59
+ message: `File has ${totalIgnoreDirectives} @graph-ignore directives — consider fixing the underlying issues instead of suppressing`,
60
+ severity: 'warning',
61
+ suggestion: 'Review each suppression to determine if the underlying issue can be fixed',
62
+ type: 'excessive-ignores',
63
+ });
64
+ }
65
+ return violations;
66
+ }
67
+ /**
68
+ * Check: quality/graph-ignore-hygiene
69
+ *
70
+ * Validates that @graph-ignore directives have valid graph rule ids and reason comments.
71
+ */
72
+ export const graphIgnoreHygiene = defineCheck({
73
+ id: 'c39f899d-acba-40fd-af5c-299b3462c277',
74
+ slug: 'graph-ignore-hygiene',
75
+ // Broad TS source scope: @graph-ignore can appear in any production source
76
+ // the graph tool analyzes, so this is NOT scoped to `concerns: ['fitness']`.
77
+ scope: { languages: ['typescript'], concerns: ['backend', 'frontend', 'cli'] },
78
+ contentFilter: 'raw',
79
+ description: 'Validates that @graph-ignore directives have valid graph rule ids and reason comments',
80
+ longDescription: `**Purpose:** Validates the quality of \`@graph-ignore\` directives to prevent stale or undocumented suppressions.
81
+
82
+ **Detects:**
83
+ - Directives with invalid graph rule ids (not \`graph:<kebab>\`)
84
+ - Directives missing a reason comment (\`-- reason\`)
85
+ - Files with more than 7 ignore directives (suggests fixing underlying issues)
86
+
87
+ **Why it matters:** Undocumented suppressions accumulate over time and can mask real issues when graph rules change.
88
+
89
+ **Scope:** General TypeScript source. Analyzes each file individually via regex.`,
90
+ tags: ['quality', 'graph', 'hygiene'],
91
+ fileTypes: ['ts'],
92
+ confidence: 'medium',
93
+ analyze: analyzeIgnoreHygiene,
94
+ });
95
+ //# sourceMappingURL=graph-ignore-hygiene.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph-ignore-hygiene.js","sourceRoot":"","sources":["../../../src/checks/quality/graph-ignore-hygiene.ts"],"names":[],"mappings":"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"}