@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,123 @@
1
+ /**
2
+ * @fileoverview No Custom Event Emitter check
3
+ */
4
+ import { defineCheck } from '@opensip-cli/fitness';
5
+ /**
6
+ * Creates a pre-compiled RegExp for pattern matching.
7
+ * These patterns operate on trusted source code files, not user input.
8
+ * @param pattern - The regex pattern string
9
+ * @param flags - Optional regex flags
10
+ * @returns Compiled RegExp object
11
+ */
12
+ function createPattern(pattern, flags) {
13
+ // @fitness-ignore-next-line semgrep-scan -- non-literal RegExp is intentional; patterns are hardcoded string constants for code analysis, not user input
14
+ return new RegExp(pattern, flags);
15
+ }
16
+ // Note: These regex patterns operate on trusted source code files, not user input.
17
+ // The patterns use bounded character classes ([^}]*) instead of .* to prevent ReDoS.
18
+ const EVENT_EMITTER_PATTERNS = [
19
+ {
20
+ // Fixed pattern - no backtracking issues
21
+ pattern: createPattern(String.raw `new\s+EventEmitter\s*\(`, 'g'),
22
+ type: 'new-event-emitter',
23
+ suggestion: 'Use a centralized event bus instead of direct EventEmitter instantiation',
24
+ severity: 'error',
25
+ },
26
+ {
27
+ // Fixed pattern - word boundary prevents issues
28
+ pattern: createPattern(String.raw `extends\s+EventEmitter\b`, 'g'),
29
+ type: 'extends-event-emitter',
30
+ suggestion: 'Implement event handling via a centralized event bus instead of extending EventEmitter',
31
+ severity: 'error',
32
+ },
33
+ {
34
+ // Use [^}]* (bounded by curly brace) instead of .* to prevent catastrophic backtracking
35
+ pattern: createPattern(String.raw `import\s+[^}]*\bEventEmitter\b[^}]*from\s+['"]events['"]`, 'g'),
36
+ type: 'import-event-emitter',
37
+ suggestion: 'Use a centralized event bus instead of importing EventEmitter directly',
38
+ severity: 'error',
39
+ },
40
+ {
41
+ // Use [^}]* (bounded by curly brace) instead of .* to prevent catastrophic backtracking
42
+ pattern: createPattern(String.raw `import\s+[^}]*\bEventEmitter\b[^}]*from\s+['"]node:events['"]`, 'g'),
43
+ type: 'import-event-emitter',
44
+ suggestion: 'Use a centralized event bus instead of importing EventEmitter directly',
45
+ severity: 'error',
46
+ },
47
+ ];
48
+ const EVENT_INFRA_PATTERNS = [
49
+ /infrastructure\/events\//,
50
+ /foundation\//,
51
+ /\/adapters\//,
52
+ /interfaces\//,
53
+ ];
54
+ function analyzeFile(filePath, content) {
55
+ const issues = [];
56
+ if (EVENT_INFRA_PATTERNS.some((p) => p.test(filePath))) {
57
+ return [];
58
+ }
59
+ const lines = content.split('\n');
60
+ for (const [i, line] of lines.entries()) {
61
+ if (!line)
62
+ continue;
63
+ for (const { pattern, type, suggestion, severity } of EVENT_EMITTER_PATTERNS) {
64
+ pattern.lastIndex = 0;
65
+ const match = pattern.exec(line);
66
+ if (match) {
67
+ issues.push({
68
+ file: filePath,
69
+ line: i + 1,
70
+ type,
71
+ match: match[0],
72
+ suggestion,
73
+ severity,
74
+ });
75
+ }
76
+ }
77
+ }
78
+ return issues;
79
+ }
80
+ /**
81
+ * Check: architecture/no-custom-event-emitter
82
+ *
83
+ * Detects direct EventEmitter usage that should use infrastructure/events module.
84
+ * Ensures consistent event handling patterns across the codebase.
85
+ */
86
+ export const noCustomEventEmitter = defineCheck({
87
+ id: '7a36c3b8-fb23-42fc-8f25-336e012aab57',
88
+ slug: 'no-custom-event-emitter',
89
+ disabled: true,
90
+ scope: { languages: ['typescript'], concerns: ['backend', 'server'] },
91
+ contentFilter: 'strip-strings',
92
+ confidence: 'medium',
93
+ description: 'Detects direct EventEmitter usage that should use infrastructure/events',
94
+ longDescription: `**Purpose:** Prevents direct usage of Node.js \`EventEmitter\` in favor of a centralized event bus.
95
+
96
+ **Detects:**
97
+ - Direct instantiation of Node.js event emitter
98
+ - Class inheritance from Node.js event emitter
99
+ - Imports of Node.js event emitter from 'events' or 'node:events'
100
+ - Excludes \`infrastructure/events/\`, \`foundation/\`, \`/adapters/\`, and \`interfaces/\` directories
101
+
102
+ **Why it matters:** Custom event emitters bypass centralized event bus patterns, making event flows untraceable and inconsistent across the platform.
103
+
104
+ **Scope:** Codebase-specific convention. Analyzes each file individually.`,
105
+ tags: ['architecture', 'best-practices'],
106
+ fileTypes: ['ts'],
107
+ analyze(content, filePath) {
108
+ // Skip if no EventEmitter usage
109
+ if (!content.includes('EventEmitter')) {
110
+ return [];
111
+ }
112
+ const issues = analyzeFile(filePath, content);
113
+ return issues.map((issue) => ({
114
+ line: issue.line,
115
+ message: `Custom event emitter: ${issue.type}. ${issue.suggestion}`,
116
+ severity: issue.severity,
117
+ suggestion: issue.suggestion,
118
+ match: issue.match,
119
+ type: issue.type,
120
+ }));
121
+ },
122
+ });
123
+ //# sourceMappingURL=no-custom-event-emitter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-custom-event-emitter.js","sourceRoot":"","sources":["../../../src/checks/architecture/no-custom-event-emitter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * @fileoverview A command handler must not index its parsed-options object by a
3
+ * KEBAB-CASE string literal — Commander camelCases long flags, so the kebab key
4
+ * is always `undefined`.
5
+ *
6
+ * WHY (the drift this freezes out):
7
+ * Commander stores `--summary-only` under `opts.summaryOnly`, `--report-to`
8
+ * under `opts.reportTo`, etc. — it camelCases the long flag when it builds the
9
+ * parsed-options object. A handler that reads `opts['summary-only']` therefore
10
+ * reads a key Commander NEVER sets: the value is silently `undefined`, the flag
11
+ * becomes a permanent no-op, and the bug is invisible (no crash, no warning).
12
+ * This is a recurring CLI footgun whenever a multi-word flag is wired by hand.
13
+ *
14
+ * DETECTION — regex on RAW content (the kebab string literal IS the signal, so it
15
+ * must NOT be stripped; comment lines are skipped manually). Flags an index
16
+ * access on a Commander-convention options identifier (`opts` / `rawOpts` /
17
+ * `cmdOpts` / `parsedOpts` / `cmdOptions`) whose key is a kebab-case string
18
+ * literal (`['a-b']`). camelCase keys, numeric keys, and non-options objects
19
+ * (`headers['content-type']`, `style['font-size']`) do not match.
20
+ *
21
+ * SCOPE — TypeScript backend/CLI sources. This is a generic Commander
22
+ * best-practice (a kebab-indexed parsed-options read is wrong in any
23
+ * Commander-based CLI), so there is no repo-specific path guard. Test files are
24
+ * skipped.
25
+ */
26
+ import { type CheckViolation } from '@opensip-cli/fitness';
27
+ /**
28
+ * Pure analysis over one source file. Returns a finding for each kebab-indexed
29
+ * parsed-options read. Exported for unit tests.
30
+ */
31
+ export declare function analyzeNoKebabOptionIndexing(content: string, filePath: string): CheckViolation[];
32
+ export declare const noKebabOptionIndexing: import("@opensip-cli/fitness").Check;
33
+ //# sourceMappingURL=no-kebab-option-indexing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-kebab-option-indexing.d.ts","sourceRoot":"","sources":["../../../src/checks/architecture/no-kebab-option-indexing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,EAAe,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAcxE;;;GAGG;AACH,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,cAAc,EAAE,CA4BhG;AAED,eAAO,MAAM,qBAAqB,sCAYhC,CAAC"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * @fileoverview A command handler must not index its parsed-options object by a
3
+ * KEBAB-CASE string literal — Commander camelCases long flags, so the kebab key
4
+ * is always `undefined`.
5
+ *
6
+ * WHY (the drift this freezes out):
7
+ * Commander stores `--summary-only` under `opts.summaryOnly`, `--report-to`
8
+ * under `opts.reportTo`, etc. — it camelCases the long flag when it builds the
9
+ * parsed-options object. A handler that reads `opts['summary-only']` therefore
10
+ * reads a key Commander NEVER sets: the value is silently `undefined`, the flag
11
+ * becomes a permanent no-op, and the bug is invisible (no crash, no warning).
12
+ * This is a recurring CLI footgun whenever a multi-word flag is wired by hand.
13
+ *
14
+ * DETECTION — regex on RAW content (the kebab string literal IS the signal, so it
15
+ * must NOT be stripped; comment lines are skipped manually). Flags an index
16
+ * access on a Commander-convention options identifier (`opts` / `rawOpts` /
17
+ * `cmdOpts` / `parsedOpts` / `cmdOptions`) whose key is a kebab-case string
18
+ * literal (`['a-b']`). camelCase keys, numeric keys, and non-options objects
19
+ * (`headers['content-type']`, `style['font-size']`) do not match.
20
+ *
21
+ * SCOPE — TypeScript backend/CLI sources. This is a generic Commander
22
+ * best-practice (a kebab-indexed parsed-options read is wrong in any
23
+ * Commander-based CLI), so there is no repo-specific path guard. Test files are
24
+ * skipped.
25
+ */
26
+ import { defineCheck } from '@opensip-cli/fitness';
27
+ /** Test-file fragments — skipped. */
28
+ const TEST_PATH = /(?:\.test\.tsx?$|\/__tests__\/)/;
29
+ /**
30
+ * `<optsVar>['<kebab-case>']` — a parsed-options index by a kebab string literal.
31
+ * The identifier set is the Commander parsed-options naming convention; the key
32
+ * must contain at least one `-` (kebab), which a camelCased Commander key never
33
+ * does.
34
+ */
35
+ const KEBAB_OPTION_INDEX_RE = /\b(?:opts|rawOpts|cmdOpts|parsedOpts|cmdOptions)\s*\[\s*(['"])([a-z][a-z0-9]*(?:-[a-z0-9]+)+)\1\s*\]/g;
36
+ /**
37
+ * Pure analysis over one source file. Returns a finding for each kebab-indexed
38
+ * parsed-options read. Exported for unit tests.
39
+ */
40
+ export function analyzeNoKebabOptionIndexing(content, filePath) {
41
+ if (TEST_PATH.test(filePath.replaceAll('\\', '/')))
42
+ return [];
43
+ const violations = [];
44
+ const lines = content.split('\n');
45
+ for (const [i, rawLine] of lines.entries()) {
46
+ // Skip comment lines so prose/examples mentioning the pattern don't fire
47
+ // (content is raw, so the kebab literal survives — we must comment-skip here).
48
+ const trimmed = rawLine.trimStart();
49
+ if (trimmed.startsWith('*') || trimmed.startsWith('//'))
50
+ continue;
51
+ KEBAB_OPTION_INDEX_RE.lastIndex = 0;
52
+ let m;
53
+ while ((m = KEBAB_OPTION_INDEX_RE.exec(rawLine)) !== null) {
54
+ const kebabKey = m[2];
55
+ const camel = kebabKey.replaceAll(/-([a-z0-9])/g, (_, c) => c.toUpperCase());
56
+ violations.push({
57
+ line: i + 1,
58
+ message: `Parsed options indexed by the kebab-case key '${kebabKey}'. Commander ` +
59
+ `camelCases long flags, so it stores this under '${camel}' — the kebab key is ` +
60
+ `always undefined and the flag is a silent no-op.`,
61
+ severity: 'error',
62
+ suggestion: `Read the camelCased key Commander actually sets: 'opts.${camel}'.`,
63
+ type: 'no-kebab-option-indexing',
64
+ });
65
+ }
66
+ }
67
+ return violations;
68
+ }
69
+ export const noKebabOptionIndexing = defineCheck({
70
+ id: '64bb7fa7-3e0d-4f4d-a1e6-d7b189df053c',
71
+ slug: 'no-kebab-option-indexing',
72
+ description: 'Command handlers must not index parsed options by a kebab-case key — Commander camelCases long flags, so the kebab key is always undefined (silent no-op flag)',
73
+ scope: { languages: ['typescript'], concerns: ['backend'] },
74
+ tags: ['architecture'],
75
+ fileTypes: ['ts'],
76
+ // raw: the kebab-case string literal IS the signal — strip-strings would blank
77
+ // it. Comment lines are skipped in the analyzer so prose does not false-fire.
78
+ contentFilter: 'raw',
79
+ analyze: (content, filePath) => analyzeNoKebabOptionIndexing(content, filePath),
80
+ });
81
+ //# sourceMappingURL=no-kebab-option-indexing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-kebab-option-indexing.js","sourceRoot":"","sources":["../../../src/checks/architecture/no-kebab-option-indexing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,EAAE,WAAW,EAAuB,MAAM,sBAAsB,CAAC;AAExE,qCAAqC;AACrC,MAAM,SAAS,GAAG,iCAAiC,CAAC;AAEpD;;;;;GAKG;AACH,MAAM,qBAAqB,GACzB,uGAAuG,CAAC;AAE1G;;;GAGG;AACH,MAAM,UAAU,4BAA4B,CAAC,OAAe,EAAE,QAAgB;IAC5E,IAAI,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAAE,OAAO,EAAE,CAAC;IAE9D,MAAM,UAAU,GAAqB,EAAE,CAAC;IACxC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClC,KAAK,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;QAC3C,yEAAyE;QACzE,+EAA+E;QAC/E,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;QACpC,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,SAAS;QAClE,qBAAqB,CAAC,SAAS,GAAG,CAAC,CAAC;QACpC,IAAI,CAAyB,CAAC;QAC9B,OAAO,CAAC,CAAC,GAAG,qBAAqB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YAC1D,MAAM,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACtB,MAAM,KAAK,GAAG,QAAQ,CAAC,UAAU,CAAC,cAAc,EAAE,CAAC,CAAC,EAAE,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;YACrF,UAAU,CAAC,IAAI,CAAC;gBACd,IAAI,EAAE,CAAC,GAAG,CAAC;gBACX,OAAO,EACL,iDAAiD,QAAQ,eAAe;oBACxE,mDAAmD,KAAK,uBAAuB;oBAC/E,kDAAkD;gBACpD,QAAQ,EAAE,OAAO;gBACjB,UAAU,EAAE,0DAA0D,KAAK,IAAI;gBAC/E,IAAI,EAAE,0BAA0B;aACjC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,MAAM,CAAC,MAAM,qBAAqB,GAAG,WAAW,CAAC;IAC/C,EAAE,EAAE,sCAAsC;IAC1C,IAAI,EAAE,0BAA0B;IAChC,WAAW,EACT,gKAAgK;IAClK,KAAK,EAAE,EAAE,SAAS,EAAE,CAAC,YAAY,CAAC,EAAE,QAAQ,EAAE,CAAC,SAAS,CAAC,EAAE;IAC3D,IAAI,EAAE,CAAC,cAAc,CAAC;IACtB,SAAS,EAAE,CAAC,IAAI,CAAC;IACjB,+EAA+E;IAC/E,8EAA8E;IAC9E,aAAa,EAAE,KAAK;IACpB,OAAO,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE,CAAC,4BAA4B,CAAC,OAAO,EAAE,QAAQ,CAAC;CAChF,CAAC,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @fileoverview Node version consistency fitness check
3
+ * @invariants
4
+ * - All engines.node fields must match root package.json
5
+ * - .nvmrc major version must match engines.node
6
+ * - @types/node major version must match engines.node
7
+ * - CI workflow node-version must match engines.node
8
+ * - Dockerfiles are NOT checked (covered by docker-version-sync)
9
+ */
10
+ /**
11
+ * Check: architecture/node-version-consistency
12
+ *
13
+ * Validates that Node.js version references are consistent across the codebase:
14
+ * 1. .nvmrc matches root package.json engines.node
15
+ * 2. All workspace package.json engines.node fields match root
16
+ * 3. @types/node major version matches engines.node major
17
+ * 4. CI workflow node-version matches engines.node
18
+ *
19
+ * Note: Dockerfile FROM node:XX checks are handled by docker-version-sync.
20
+ */
21
+ export declare const nodeVersionConsistency: import("@opensip-cli/fitness").Check;
22
+ //# sourceMappingURL=node-version-consistency.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-version-consistency.d.ts","sourceRoot":"","sources":["../../../src/checks/architecture/node-version-consistency.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAkMH;;;;;;;;;;GAUG;AACH,eAAO,MAAM,sBAAsB,sCAqEjC,CAAC"}
@@ -0,0 +1,225 @@
1
+ // @fitness-ignore-file fitness-check-standards -- Uses fs for package.json reading, not source file content
2
+ // @fitness-ignore-file detached-promises -- helpers (checkNvmrc, checkWorkspaceEngines, checkTypesNode, checkCiWorkflow) are synchronous violation-collectors; heuristic flags them despite returning void
3
+ /**
4
+ * @fileoverview Node version consistency fitness check
5
+ * @invariants
6
+ * - All engines.node fields must match root package.json
7
+ * - .nvmrc major version must match engines.node
8
+ * - @types/node major version must match engines.node
9
+ * - CI workflow node-version must match engines.node
10
+ * - Dockerfiles are NOT checked (covered by docker-version-sync)
11
+ */
12
+ import * as path from 'node:path';
13
+ import { defineCheck } from '@opensip-cli/fitness';
14
+ // =============================================================================
15
+ // REGEX PATTERNS
16
+ // =============================================================================
17
+ /** Extract major version from engines.node constraint like ">=24.0.0" -> 24 */
18
+ const ENGINES_NODE_MAJOR = /(\d+)/;
19
+ /** Match @types/node version like "^24.0.0" -> 24 */
20
+ const TYPES_NODE_MAJOR = /\^(\d+)/;
21
+ /** Match node-version in CI workflow YAML */
22
+ const CI_NODE_VERSION = /node-version:\s*['"]?(\d+)['"]?/;
23
+ // =============================================================================
24
+ // HELPERS
25
+ // =============================================================================
26
+ /**
27
+ * Extract major Node version from engines.node constraint.
28
+ * e.g. ">=24.0.0" -> 24
29
+ */
30
+ function extractNodeMajor(constraint) {
31
+ const match = ENGINES_NODE_MAJOR.exec(constraint);
32
+ /* v8 ignore next 3 -- defensive: regex (\d+) ensures group [1] is set when match succeeds */
33
+ const digit = match?.[1];
34
+ // @fitness-ignore-next-line numeric-validation -- regex guarantees digit-only string; null guard above
35
+ return digit ? Number.parseInt(digit, 10) : null;
36
+ }
37
+ // =============================================================================
38
+ // PER-FILE ANALYSIS HELPERS
39
+ // =============================================================================
40
+ function checkNvmrc(content, filePath, expectedMajor, violations) {
41
+ const trimmed = content.trim();
42
+ const nvmrcMajor = Number.parseInt(trimmed, 10);
43
+ /* v8 ignore next -- defensive: malformed .nvmrc not exercised in fixtures */
44
+ if (Number.isNaN(nvmrcMajor))
45
+ return;
46
+ if (nvmrcMajor !== expectedMajor) {
47
+ violations.push({
48
+ line: 1,
49
+ filePath,
50
+ message: `.nvmrc specifies Node ${nvmrcMajor} but root package.json engines.node requires ${expectedMajor}`,
51
+ severity: 'error',
52
+ suggestion: `Change .nvmrc from "${trimmed}" to "${expectedMajor}"`,
53
+ type: 'nvmrc-version-mismatch',
54
+ });
55
+ }
56
+ }
57
+ function checkWorkspaceEngines(content, filePath, expectedMajor, rootConstraint, violations) {
58
+ let pkg;
59
+ try {
60
+ pkg = JSON.parse(content);
61
+ }
62
+ catch {
63
+ /* v8 ignore next -- defensive: malformed workspace package.json not exercised in fixtures */
64
+ // @swallow-ok expected for non-JSON files or malformed package.json
65
+ return;
66
+ }
67
+ const enginesNode = pkg.engines?.node;
68
+ if (!enginesNode)
69
+ return;
70
+ const workspaceMajor = extractNodeMajor(enginesNode);
71
+ /* v8 ignore next -- defensive: enginesNode already checked, regex match guaranteed */
72
+ if (workspaceMajor === null)
73
+ return;
74
+ if (workspaceMajor !== expectedMajor) {
75
+ const relPath = path.relative(process.cwd(), filePath);
76
+ violations.push({
77
+ line: 1,
78
+ filePath,
79
+ message: `${relPath} engines.node is "${enginesNode}" but root package.json has "${rootConstraint}"`,
80
+ severity: 'error',
81
+ suggestion: `Change engines.node from "${enginesNode}" to "${rootConstraint}"`,
82
+ type: 'workspace-engines-mismatch',
83
+ });
84
+ }
85
+ }
86
+ function checkTypesNode(content, filePath, expectedMajor, violations) {
87
+ let pkg;
88
+ try {
89
+ pkg = JSON.parse(content);
90
+ }
91
+ catch {
92
+ /* v8 ignore next -- defensive: malformed workspace package.json not exercised in fixtures */
93
+ // @swallow-ok expected for non-JSON files or malformed package.json
94
+ return;
95
+ }
96
+ /* v8 ignore next -- defensive: pkg.dependencies fallback when devDependencies missing */
97
+ const typesNodeVersion = pkg.devDependencies?.['@types/node'] ?? pkg.dependencies?.['@types/node'];
98
+ if (!typesNodeVersion)
99
+ return;
100
+ const match = TYPES_NODE_MAJOR.exec(typesNodeVersion);
101
+ /* v8 ignore next 2 -- defensive: regex ^\d+ ensures group [1] is set when match succeeds */
102
+ const typesMajor = match?.[1];
103
+ if (!typesMajor)
104
+ return;
105
+ // @fitness-ignore-next-line numeric-validation -- regex ^\d+ guarantees digit-only string
106
+ const typesMajorNum = Number.parseInt(typesMajor, 10);
107
+ if (typesMajorNum !== expectedMajor) {
108
+ const relPath = path.relative(process.cwd(), filePath);
109
+ violations.push({
110
+ line: 1,
111
+ filePath,
112
+ message: `${relPath} has @types/node "${typesNodeVersion}" but engines.node major is ${expectedMajor}`,
113
+ severity: 'error',
114
+ suggestion: `Change @types/node from "${typesNodeVersion}" to "^${expectedMajor}.0.0"`,
115
+ type: 'types-node-mismatch',
116
+ });
117
+ }
118
+ }
119
+ function checkCiWorkflow(content, filePath, expectedMajor, violations) {
120
+ const lines = content.split('\n');
121
+ for (const [i, rawLine] of lines.entries()) {
122
+ /* v8 ignore next -- defensive: lines.entries() never yields undefined */
123
+ if (!rawLine)
124
+ continue;
125
+ const line = rawLine.trim();
126
+ const match = CI_NODE_VERSION.exec(line);
127
+ /* v8 ignore next 2 -- defensive: regex (\d+) ensures group [1] is set when match succeeds */
128
+ const ciVersion = match?.[1];
129
+ if (!ciVersion)
130
+ continue;
131
+ // @fitness-ignore-next-line numeric-validation -- regex (\d+) guarantees digit-only string
132
+ const ciMajor = Number.parseInt(ciVersion, 10);
133
+ if (ciMajor !== expectedMajor) {
134
+ violations.push({
135
+ line: i + 1,
136
+ filePath,
137
+ message: `CI workflow uses node-version: '${ciVersion}' but root package.json engines.node requires ${expectedMajor}`,
138
+ severity: 'error',
139
+ suggestion: `Change node-version from '${ciVersion}' to '${expectedMajor}'`,
140
+ type: 'ci-node-version-mismatch',
141
+ });
142
+ }
143
+ }
144
+ }
145
+ // =============================================================================
146
+ // CHECK DEFINITION
147
+ // =============================================================================
148
+ /**
149
+ * Check: architecture/node-version-consistency
150
+ *
151
+ * Validates that Node.js version references are consistent across the codebase:
152
+ * 1. .nvmrc matches root package.json engines.node
153
+ * 2. All workspace package.json engines.node fields match root
154
+ * 3. @types/node major version matches engines.node major
155
+ * 4. CI workflow node-version matches engines.node
156
+ *
157
+ * Note: Dockerfile FROM node:XX checks are handled by docker-version-sync.
158
+ */
159
+ export const nodeVersionConsistency = defineCheck({
160
+ id: 'e32068df-b100-4406-a8ba-caec5d53fa92',
161
+ slug: 'node-version-consistency',
162
+ scope: { languages: ['json', 'typescript', 'yaml'], concerns: ['config'] },
163
+ contentFilter: 'raw',
164
+ confidence: 'medium',
165
+ description: 'Validate Node.js version consistency across configs',
166
+ longDescription: `**Purpose:** Ensures all Node.js version references across the codebase stay in sync with the root \`package.json\` \`engines.node\` field.
167
+
168
+ **Detects:**
169
+ - \`.nvmrc\` major version mismatches against \`engines.node\`
170
+ - Workspace \`package.json\` \`engines.node\` fields that differ from root
171
+ - \`@types/node\` major version mismatches in any \`package.json\`
172
+ - CI workflow \`node-version:\` lines that don't match
173
+
174
+ **Why it matters:** Version drift between .nvmrc, CI, and package.json leads to "works on my machine" issues and inconsistent runtime behavior.
175
+
176
+ **Scope:** Codebase-specific convention. Cross-file analysis via \`analyzeAll\`. Dockerfiles are intentionally excluded (covered by \`docker-version-sync\`).`,
177
+ tags: ['node', 'version-sync', 'architecture'],
178
+ async analyzeAll(files) {
179
+ const violations = [];
180
+ // Find the root package.json from the scanned file set.
181
+ // The root is the shortest path (shallowest) package.json in the set.
182
+ const packageJsonPaths = files.paths.filter((p) => path.basename(p) === 'package.json');
183
+ if (packageJsonPaths.length === 0)
184
+ return violations;
185
+ const rootPkgPath = packageJsonPaths.reduce((shortest, p) => (p.length < shortest.length ? p : shortest),
186
+ /* v8 ignore next -- defensive: packageJsonPaths.length checked above */
187
+ packageJsonPaths[0]);
188
+ // Read root package.json for version truth
189
+ const rootContent = await files.read(rootPkgPath);
190
+ let rootPkg;
191
+ try {
192
+ rootPkg = JSON.parse(rootContent);
193
+ }
194
+ catch {
195
+ return violations;
196
+ }
197
+ const rootConstraint = rootPkg.engines?.node;
198
+ if (!rootConstraint)
199
+ return violations;
200
+ const expectedMajor = extractNodeMajor(rootConstraint);
201
+ /* v8 ignore next -- defensive: rootConstraint already checked, regex (\d+) ensures match */
202
+ if (expectedMajor === null)
203
+ return violations;
204
+ for (const filePath of files.paths) {
205
+ // @fitness-ignore-next-line performance-anti-patterns -- sequential file reading to control memory; FileAccessor is lazy
206
+ const content = await files.read(filePath);
207
+ const basename = path.basename(filePath);
208
+ if (basename === '.nvmrc') {
209
+ checkNvmrc(content, filePath, expectedMajor, violations);
210
+ }
211
+ else if (basename === 'package.json') {
212
+ // Skip root package.json (it's the source of truth)
213
+ if (filePath === rootPkgPath)
214
+ continue;
215
+ checkWorkspaceEngines(content, filePath, expectedMajor, rootConstraint, violations);
216
+ checkTypesNode(content, filePath, expectedMajor, violations);
217
+ }
218
+ else if (filePath.includes('.github/workflows/') && basename.endsWith('.yml')) {
219
+ checkCiWorkflow(content, filePath, expectedMajor, violations);
220
+ }
221
+ }
222
+ return violations;
223
+ },
224
+ });
225
+ //# sourceMappingURL=node-version-consistency.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-version-consistency.js","sourceRoot":"","sources":["../../../src/checks/architecture/node-version-consistency.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * @fileoverview Project README existence check
3
+ *
4
+ * Ensures every package, app, CLI, and service has a README.md file.
5
+ */
6
+ /**
7
+ * Check: architecture/project-readme-existence
8
+ *
9
+ * Ensures every package, app, CLI tool, and service has a README.md file
10
+ * for documentation and discoverability.
11
+ */
12
+ export declare const projectReadmeExistence: import("@opensip-cli/fitness").Check;
13
+ //# sourceMappingURL=project-readme-existence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-readme-existence.d.ts","sourceRoot":"","sources":["../../../src/checks/architecture/project-readme-existence.ts"],"names":[],"mappings":"AACA;;;;GAIG;AAOH;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,sCA6CjC,CAAC"}
@@ -0,0 +1,55 @@
1
+ // @fitness-ignore-file fitness-check-standards -- Uses fs for README existence checking, not source file content
2
+ /**
3
+ * @fileoverview Project README existence check
4
+ *
5
+ * Ensures every package, app, CLI, and service has a README.md file.
6
+ */
7
+ import * as fs from 'node:fs';
8
+ import * as path from 'node:path';
9
+ import { defineCheck } from '@opensip-cli/fitness';
10
+ /**
11
+ * Check: architecture/project-readme-existence
12
+ *
13
+ * Ensures every package, app, CLI tool, and service has a README.md file
14
+ * for documentation and discoverability.
15
+ */
16
+ export const projectReadmeExistence = defineCheck({
17
+ id: 'b7c3a2c2-0448-405f-86e3-8b5fca987bc7',
18
+ slug: 'project-readme-existence',
19
+ scope: { languages: ['typescript'], concerns: ['backend', 'frontend', 'cli'] },
20
+ confidence: 'medium',
21
+ description: 'Ensures every package has a README.md file',
22
+ longDescription: `**Purpose:** Ensures every package, app, CLI tool, and service has a README.md file for documentation and discoverability.
23
+
24
+ **Detects:**
25
+ - Missing \`README.md\` files in package directories
26
+ - Checks sibling directory of each \`package.json\`
27
+ - Skips the monorepo root \`package.json\` (via target patterns)
28
+
29
+ **Why it matters:** README files are essential for onboarding, discoverability, and maintaining documentation standards across the monorepo. Without them, developers must read source code to understand package purpose and usage.
30
+
31
+ **Scope:** Cross-file analysis via \`analyzeAll\`. Codebase-specific convention.`,
32
+ tags: ['architecture', 'documentation'],
33
+ // @fitness-ignore-next-line concurrency-safety -- async keyword required by analyzeAll interface contract; synchronous analysis implementation
34
+ // eslint-disable-next-line @typescript-eslint/require-await -- AnalyzeAllCheckConfig requires Promise<CheckViolation[]>; this implementation is synchronous
35
+ async analyzeAll(files) {
36
+ const violations = [];
37
+ // Only check directories that contain a package.json (actual packages)
38
+ const packageJsonPaths = files.paths.filter((fp) => path.basename(fp) === 'package.json');
39
+ for (const packageJsonPath of packageJsonPaths) {
40
+ const dirPath = path.dirname(packageJsonPath);
41
+ const readmePath = path.join(dirPath, 'README.md');
42
+ if (!fs.existsSync(readmePath)) {
43
+ violations.push({
44
+ filePath: packageJsonPath,
45
+ line: 1,
46
+ message: `Missing README.md in ${path.basename(dirPath)}`,
47
+ severity: 'warning',
48
+ suggestion: 'Create a README.md file with package description, usage, and API documentation',
49
+ });
50
+ }
51
+ }
52
+ return violations;
53
+ },
54
+ });
55
+ //# sourceMappingURL=project-readme-existence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-readme-existence.js","sourceRoot":"","sources":["../../../src/checks/architecture/project-readme-existence.ts"],"names":[],"mappings":"AAAA,iHAAiH;AACjH;;;;GAIG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,WAAW,EAA0C,MAAM,sBAAsB,CAAC;AAE3F;;;;;GAKG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,WAAW,CAAC;IAChD,EAAE,EAAE,sCAAsC;IAC1C,IAAI,EAAE,0BAA0B;IAChC,KAAK,EAAE,EAAE,SAAS,EAAE,CAAC,YAAY,CAAC,EAAE,QAAQ,EAAE,CAAC,SAAS,EAAE,UAAU,EAAE,KAAK,CAAC,EAAE;IAE9E,UAAU,EAAE,QAAQ;IACpB,WAAW,EAAE,4CAA4C;IACzD,eAAe,EAAE;;;;;;;;;iFAS8D;IAC/E,IAAI,EAAE,CAAC,cAAc,EAAE,eAAe,CAAC;IAEvC,+IAA+I;IAC/I,4JAA4J;IAC5J,KAAK,CAAC,UAAU,CAAC,KAAmB;QAClC,MAAM,UAAU,GAAqB,EAAE,CAAC;QAExC,uEAAuE;QACvE,MAAM,gBAAgB,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,cAAc,CAAC,CAAC;QAE1F,KAAK,MAAM,eAAe,IAAI,gBAAgB,EAAE,CAAC;YAC/C,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;YAC9C,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;YAEnD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC/B,UAAU,CAAC,IAAI,CAAC;oBACd,QAAQ,EAAE,eAAe;oBACzB,IAAI,EAAE,CAAC;oBACP,OAAO,EAAE,wBAAwB,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE;oBACzD,QAAQ,EAAE,SAAS;oBACnB,UAAU,EACR,gFAAgF;iBACnF,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,UAAU,CAAC;IACpB,CAAC;CACF,CAAC,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @fileoverview Stale build artifact detection
3
+ * @module checks-builtin/checks/architecture/stale-build-artifacts
4
+ *
5
+ * Detects .js, .d.ts, and .js.map files in source directories that should
6
+ * only exist in dist/. These cause confusing import resolution bugs where
7
+ * the compiled artifact shadows the source file.
8
+ */
9
+ export declare const staleBuildArtifacts: import("@opensip-cli/fitness").Check;
10
+ //# sourceMappingURL=stale-build-artifacts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stale-build-artifacts.d.ts","sourceRoot":"","sources":["../../../src/checks/architecture/stale-build-artifacts.ts"],"names":[],"mappings":"AACA;;;;;;;GAOG;AA0BH,eAAO,MAAM,mBAAmB,sCA6B9B,CAAC"}