driftdetect-detectors 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 (509) hide show
  1. package/dist/accessibility/alt-text.d.ts +63 -0
  2. package/dist/accessibility/alt-text.d.ts.map +1 -0
  3. package/dist/accessibility/alt-text.js +100 -0
  4. package/dist/accessibility/alt-text.js.map +1 -0
  5. package/dist/accessibility/aria-roles.d.ts +65 -0
  6. package/dist/accessibility/aria-roles.d.ts.map +1 -0
  7. package/dist/accessibility/aria-roles.js +87 -0
  8. package/dist/accessibility/aria-roles.js.map +1 -0
  9. package/dist/accessibility/focus-management.d.ts +62 -0
  10. package/dist/accessibility/focus-management.d.ts.map +1 -0
  11. package/dist/accessibility/focus-management.js +88 -0
  12. package/dist/accessibility/focus-management.js.map +1 -0
  13. package/dist/accessibility/heading-hierarchy.d.ts +66 -0
  14. package/dist/accessibility/heading-hierarchy.d.ts.map +1 -0
  15. package/dist/accessibility/heading-hierarchy.js +94 -0
  16. package/dist/accessibility/heading-hierarchy.js.map +1 -0
  17. package/dist/accessibility/index.d.ts +25 -0
  18. package/dist/accessibility/index.d.ts.map +1 -0
  19. package/dist/accessibility/index.js +21 -0
  20. package/dist/accessibility/index.js.map +1 -0
  21. package/dist/accessibility/keyboard-nav.d.ts +63 -0
  22. package/dist/accessibility/keyboard-nav.d.ts.map +1 -0
  23. package/dist/accessibility/keyboard-nav.js +86 -0
  24. package/dist/accessibility/keyboard-nav.js.map +1 -0
  25. package/dist/accessibility/semantic-html.d.ts +76 -0
  26. package/dist/accessibility/semantic-html.d.ts.map +1 -0
  27. package/dist/accessibility/semantic-html.js +204 -0
  28. package/dist/accessibility/semantic-html.js.map +1 -0
  29. package/dist/api/client-patterns.d.ts +121 -0
  30. package/dist/api/client-patterns.d.ts.map +1 -0
  31. package/dist/api/client-patterns.js +478 -0
  32. package/dist/api/client-patterns.js.map +1 -0
  33. package/dist/api/error-format.d.ts +140 -0
  34. package/dist/api/error-format.d.ts.map +1 -0
  35. package/dist/api/error-format.js +614 -0
  36. package/dist/api/error-format.js.map +1 -0
  37. package/dist/api/http-methods.d.ts +255 -0
  38. package/dist/api/http-methods.d.ts.map +1 -0
  39. package/dist/api/http-methods.js +890 -0
  40. package/dist/api/http-methods.js.map +1 -0
  41. package/dist/api/index.d.ts +16 -0
  42. package/dist/api/index.d.ts.map +1 -0
  43. package/dist/api/index.js +37 -0
  44. package/dist/api/index.js.map +1 -0
  45. package/dist/api/pagination.d.ts +133 -0
  46. package/dist/api/pagination.d.ts.map +1 -0
  47. package/dist/api/pagination.js +521 -0
  48. package/dist/api/pagination.js.map +1 -0
  49. package/dist/api/response-envelope.d.ts +261 -0
  50. package/dist/api/response-envelope.d.ts.map +1 -0
  51. package/dist/api/response-envelope.js +1050 -0
  52. package/dist/api/response-envelope.js.map +1 -0
  53. package/dist/api/retry-patterns.d.ts +117 -0
  54. package/dist/api/retry-patterns.d.ts.map +1 -0
  55. package/dist/api/retry-patterns.js +480 -0
  56. package/dist/api/retry-patterns.js.map +1 -0
  57. package/dist/api/route-structure.d.ts +128 -0
  58. package/dist/api/route-structure.d.ts.map +1 -0
  59. package/dist/api/route-structure.js +738 -0
  60. package/dist/api/route-structure.js.map +1 -0
  61. package/dist/auth/audit-logging.d.ts +80 -0
  62. package/dist/auth/audit-logging.d.ts.map +1 -0
  63. package/dist/auth/audit-logging.js +370 -0
  64. package/dist/auth/audit-logging.js.map +1 -0
  65. package/dist/auth/index.d.ts +33 -0
  66. package/dist/auth/index.d.ts.map +1 -0
  67. package/dist/auth/index.js +49 -0
  68. package/dist/auth/index.js.map +1 -0
  69. package/dist/auth/middleware-usage.d.ts +65 -0
  70. package/dist/auth/middleware-usage.d.ts.map +1 -0
  71. package/dist/auth/middleware-usage.js +192 -0
  72. package/dist/auth/middleware-usage.js.map +1 -0
  73. package/dist/auth/permission-checks.d.ts +60 -0
  74. package/dist/auth/permission-checks.d.ts.map +1 -0
  75. package/dist/auth/permission-checks.js +159 -0
  76. package/dist/auth/permission-checks.js.map +1 -0
  77. package/dist/auth/rbac-patterns.d.ts +68 -0
  78. package/dist/auth/rbac-patterns.d.ts.map +1 -0
  79. package/dist/auth/rbac-patterns.js +143 -0
  80. package/dist/auth/rbac-patterns.js.map +1 -0
  81. package/dist/auth/resource-ownership.d.ts +77 -0
  82. package/dist/auth/resource-ownership.d.ts.map +1 -0
  83. package/dist/auth/resource-ownership.js +324 -0
  84. package/dist/auth/resource-ownership.js.map +1 -0
  85. package/dist/auth/token-handling.d.ts +64 -0
  86. package/dist/auth/token-handling.d.ts.map +1 -0
  87. package/dist/auth/token-handling.js +151 -0
  88. package/dist/auth/token-handling.js.map +1 -0
  89. package/dist/base/ast-detector.d.ts +421 -0
  90. package/dist/base/ast-detector.d.ts.map +1 -0
  91. package/dist/base/ast-detector.js +699 -0
  92. package/dist/base/ast-detector.js.map +1 -0
  93. package/dist/base/base-detector.d.ts +366 -0
  94. package/dist/base/base-detector.d.ts.map +1 -0
  95. package/dist/base/base-detector.js +170 -0
  96. package/dist/base/base-detector.js.map +1 -0
  97. package/dist/base/index.d.ts +12 -0
  98. package/dist/base/index.d.ts.map +1 -0
  99. package/dist/base/index.js +17 -0
  100. package/dist/base/index.js.map +1 -0
  101. package/dist/base/regex-detector.d.ts +421 -0
  102. package/dist/base/regex-detector.d.ts.map +1 -0
  103. package/dist/base/regex-detector.js +537 -0
  104. package/dist/base/regex-detector.js.map +1 -0
  105. package/dist/base/structural-detector.d.ts +424 -0
  106. package/dist/base/structural-detector.d.ts.map +1 -0
  107. package/dist/base/structural-detector.js +731 -0
  108. package/dist/base/structural-detector.js.map +1 -0
  109. package/dist/base/types.d.ts +53 -0
  110. package/dist/base/types.d.ts.map +1 -0
  111. package/dist/base/types.js +5 -0
  112. package/dist/base/types.js.map +1 -0
  113. package/dist/components/component-structure.d.ts +163 -0
  114. package/dist/components/component-structure.d.ts.map +1 -0
  115. package/dist/components/component-structure.js +500 -0
  116. package/dist/components/component-structure.js.map +1 -0
  117. package/dist/components/composition.d.ts +287 -0
  118. package/dist/components/composition.d.ts.map +1 -0
  119. package/dist/components/composition.js +1123 -0
  120. package/dist/components/composition.js.map +1 -0
  121. package/dist/components/duplicate-detection.d.ts +251 -0
  122. package/dist/components/duplicate-detection.d.ts.map +1 -0
  123. package/dist/components/duplicate-detection.js +804 -0
  124. package/dist/components/duplicate-detection.js.map +1 -0
  125. package/dist/components/index.d.ts +16 -0
  126. package/dist/components/index.d.ts.map +1 -0
  127. package/dist/components/index.js +51 -0
  128. package/dist/components/index.js.map +1 -0
  129. package/dist/components/near-duplicate.d.ts +402 -0
  130. package/dist/components/near-duplicate.d.ts.map +1 -0
  131. package/dist/components/near-duplicate.js +1090 -0
  132. package/dist/components/near-duplicate.js.map +1 -0
  133. package/dist/components/props-patterns.d.ts +194 -0
  134. package/dist/components/props-patterns.d.ts.map +1 -0
  135. package/dist/components/props-patterns.js +795 -0
  136. package/dist/components/props-patterns.js.map +1 -0
  137. package/dist/components/ref-forwarding.d.ts +250 -0
  138. package/dist/components/ref-forwarding.d.ts.map +1 -0
  139. package/dist/components/ref-forwarding.js +832 -0
  140. package/dist/components/ref-forwarding.js.map +1 -0
  141. package/dist/components/state-patterns.d.ts +291 -0
  142. package/dist/components/state-patterns.d.ts.map +1 -0
  143. package/dist/components/state-patterns.js +970 -0
  144. package/dist/components/state-patterns.js.map +1 -0
  145. package/dist/config/config-validation.d.ts +74 -0
  146. package/dist/config/config-validation.d.ts.map +1 -0
  147. package/dist/config/config-validation.js +446 -0
  148. package/dist/config/config-validation.js.map +1 -0
  149. package/dist/config/default-values.d.ts +72 -0
  150. package/dist/config/default-values.d.ts.map +1 -0
  151. package/dist/config/default-values.js +386 -0
  152. package/dist/config/default-values.js.map +1 -0
  153. package/dist/config/env-naming.d.ts +73 -0
  154. package/dist/config/env-naming.d.ts.map +1 -0
  155. package/dist/config/env-naming.js +429 -0
  156. package/dist/config/env-naming.js.map +1 -0
  157. package/dist/config/environment-detection.d.ts +72 -0
  158. package/dist/config/environment-detection.d.ts.map +1 -0
  159. package/dist/config/environment-detection.js +400 -0
  160. package/dist/config/environment-detection.js.map +1 -0
  161. package/dist/config/feature-flags.d.ts +72 -0
  162. package/dist/config/feature-flags.d.ts.map +1 -0
  163. package/dist/config/feature-flags.js +384 -0
  164. package/dist/config/feature-flags.js.map +1 -0
  165. package/dist/config/index.d.ts +27 -0
  166. package/dist/config/index.d.ts.map +1 -0
  167. package/dist/config/index.js +43 -0
  168. package/dist/config/index.js.map +1 -0
  169. package/dist/config/required-optional.d.ts +71 -0
  170. package/dist/config/required-optional.d.ts.map +1 -0
  171. package/dist/config/required-optional.js +344 -0
  172. package/dist/config/required-optional.js.map +1 -0
  173. package/dist/data-access/connection-pooling.d.ts +63 -0
  174. package/dist/data-access/connection-pooling.d.ts.map +1 -0
  175. package/dist/data-access/connection-pooling.js +297 -0
  176. package/dist/data-access/connection-pooling.js.map +1 -0
  177. package/dist/data-access/dto-patterns.d.ts +64 -0
  178. package/dist/data-access/dto-patterns.d.ts.map +1 -0
  179. package/dist/data-access/dto-patterns.js +291 -0
  180. package/dist/data-access/dto-patterns.js.map +1 -0
  181. package/dist/data-access/index.d.ts +31 -0
  182. package/dist/data-access/index.d.ts.map +1 -0
  183. package/dist/data-access/index.js +49 -0
  184. package/dist/data-access/index.js.map +1 -0
  185. package/dist/data-access/n-plus-one.d.ts +60 -0
  186. package/dist/data-access/n-plus-one.d.ts.map +1 -0
  187. package/dist/data-access/n-plus-one.js +264 -0
  188. package/dist/data-access/n-plus-one.js.map +1 -0
  189. package/dist/data-access/query-patterns.d.ts +64 -0
  190. package/dist/data-access/query-patterns.d.ts.map +1 -0
  191. package/dist/data-access/query-patterns.js +314 -0
  192. package/dist/data-access/query-patterns.js.map +1 -0
  193. package/dist/data-access/repository-pattern.d.ts +62 -0
  194. package/dist/data-access/repository-pattern.d.ts.map +1 -0
  195. package/dist/data-access/repository-pattern.js +257 -0
  196. package/dist/data-access/repository-pattern.js.map +1 -0
  197. package/dist/data-access/transaction-patterns.d.ts +61 -0
  198. package/dist/data-access/transaction-patterns.d.ts.map +1 -0
  199. package/dist/data-access/transaction-patterns.js +277 -0
  200. package/dist/data-access/transaction-patterns.js.map +1 -0
  201. package/dist/data-access/validation-patterns.d.ts +62 -0
  202. package/dist/data-access/validation-patterns.d.ts.map +1 -0
  203. package/dist/data-access/validation-patterns.js +301 -0
  204. package/dist/data-access/validation-patterns.js.map +1 -0
  205. package/dist/documentation/deprecation.d.ts +62 -0
  206. package/dist/documentation/deprecation.d.ts.map +1 -0
  207. package/dist/documentation/deprecation.js +83 -0
  208. package/dist/documentation/deprecation.js.map +1 -0
  209. package/dist/documentation/example-code.d.ts +64 -0
  210. package/dist/documentation/example-code.d.ts.map +1 -0
  211. package/dist/documentation/example-code.js +79 -0
  212. package/dist/documentation/example-code.js.map +1 -0
  213. package/dist/documentation/index.d.ts +22 -0
  214. package/dist/documentation/index.d.ts.map +1 -0
  215. package/dist/documentation/index.js +19 -0
  216. package/dist/documentation/index.js.map +1 -0
  217. package/dist/documentation/jsdoc-patterns.d.ts +72 -0
  218. package/dist/documentation/jsdoc-patterns.d.ts.map +1 -0
  219. package/dist/documentation/jsdoc-patterns.js +92 -0
  220. package/dist/documentation/jsdoc-patterns.js.map +1 -0
  221. package/dist/documentation/readme-structure.d.ts +67 -0
  222. package/dist/documentation/readme-structure.d.ts.map +1 -0
  223. package/dist/documentation/readme-structure.js +76 -0
  224. package/dist/documentation/readme-structure.js.map +1 -0
  225. package/dist/documentation/todo-patterns.d.ts +67 -0
  226. package/dist/documentation/todo-patterns.d.ts.map +1 -0
  227. package/dist/documentation/todo-patterns.js +73 -0
  228. package/dist/documentation/todo-patterns.js.map +1 -0
  229. package/dist/errors/async-errors.d.ts +72 -0
  230. package/dist/errors/async-errors.d.ts.map +1 -0
  231. package/dist/errors/async-errors.js +214 -0
  232. package/dist/errors/async-errors.js.map +1 -0
  233. package/dist/errors/circuit-breaker.d.ts +53 -0
  234. package/dist/errors/circuit-breaker.d.ts.map +1 -0
  235. package/dist/errors/circuit-breaker.js +241 -0
  236. package/dist/errors/circuit-breaker.js.map +1 -0
  237. package/dist/errors/error-codes.d.ts +73 -0
  238. package/dist/errors/error-codes.d.ts.map +1 -0
  239. package/dist/errors/error-codes.js +211 -0
  240. package/dist/errors/error-codes.js.map +1 -0
  241. package/dist/errors/error-logging.d.ts +73 -0
  242. package/dist/errors/error-logging.d.ts.map +1 -0
  243. package/dist/errors/error-logging.js +256 -0
  244. package/dist/errors/error-logging.js.map +1 -0
  245. package/dist/errors/error-propagation.d.ts +73 -0
  246. package/dist/errors/error-propagation.d.ts.map +1 -0
  247. package/dist/errors/error-propagation.js +244 -0
  248. package/dist/errors/error-propagation.js.map +1 -0
  249. package/dist/errors/exception-hierarchy.d.ts +75 -0
  250. package/dist/errors/exception-hierarchy.d.ts.map +1 -0
  251. package/dist/errors/exception-hierarchy.js +259 -0
  252. package/dist/errors/exception-hierarchy.js.map +1 -0
  253. package/dist/errors/index.d.ts +31 -0
  254. package/dist/errors/index.d.ts.map +1 -0
  255. package/dist/errors/index.js +49 -0
  256. package/dist/errors/index.js.map +1 -0
  257. package/dist/errors/try-catch-placement.d.ts +73 -0
  258. package/dist/errors/try-catch-placement.d.ts.map +1 -0
  259. package/dist/errors/try-catch-placement.js +214 -0
  260. package/dist/errors/try-catch-placement.js.map +1 -0
  261. package/dist/index.d.ts +221 -0
  262. package/dist/index.d.ts.map +1 -0
  263. package/dist/index.js +245 -0
  264. package/dist/index.js.map +1 -0
  265. package/dist/logging/context-fields.d.ts +48 -0
  266. package/dist/logging/context-fields.d.ts.map +1 -0
  267. package/dist/logging/context-fields.js +160 -0
  268. package/dist/logging/context-fields.js.map +1 -0
  269. package/dist/logging/correlation-ids.d.ts +44 -0
  270. package/dist/logging/correlation-ids.d.ts.map +1 -0
  271. package/dist/logging/correlation-ids.js +144 -0
  272. package/dist/logging/correlation-ids.js.map +1 -0
  273. package/dist/logging/health-checks.d.ts +45 -0
  274. package/dist/logging/health-checks.d.ts.map +1 -0
  275. package/dist/logging/health-checks.js +165 -0
  276. package/dist/logging/health-checks.js.map +1 -0
  277. package/dist/logging/index.d.ts +31 -0
  278. package/dist/logging/index.d.ts.map +1 -0
  279. package/dist/logging/index.js +49 -0
  280. package/dist/logging/index.js.map +1 -0
  281. package/dist/logging/log-levels.d.ts +46 -0
  282. package/dist/logging/log-levels.d.ts.map +1 -0
  283. package/dist/logging/log-levels.js +178 -0
  284. package/dist/logging/log-levels.js.map +1 -0
  285. package/dist/logging/metric-naming.d.ts +46 -0
  286. package/dist/logging/metric-naming.d.ts.map +1 -0
  287. package/dist/logging/metric-naming.js +157 -0
  288. package/dist/logging/metric-naming.js.map +1 -0
  289. package/dist/logging/pii-redaction.d.ts +44 -0
  290. package/dist/logging/pii-redaction.d.ts.map +1 -0
  291. package/dist/logging/pii-redaction.js +166 -0
  292. package/dist/logging/pii-redaction.js.map +1 -0
  293. package/dist/logging/structured-format.d.ts +53 -0
  294. package/dist/logging/structured-format.d.ts.map +1 -0
  295. package/dist/logging/structured-format.js +235 -0
  296. package/dist/logging/structured-format.js.map +1 -0
  297. package/dist/performance/bundle-size.d.ts +79 -0
  298. package/dist/performance/bundle-size.d.ts.map +1 -0
  299. package/dist/performance/bundle-size.js +276 -0
  300. package/dist/performance/bundle-size.js.map +1 -0
  301. package/dist/performance/caching-patterns.d.ts +78 -0
  302. package/dist/performance/caching-patterns.d.ts.map +1 -0
  303. package/dist/performance/caching-patterns.js +257 -0
  304. package/dist/performance/caching-patterns.js.map +1 -0
  305. package/dist/performance/code-splitting.d.ts +86 -0
  306. package/dist/performance/code-splitting.d.ts.map +1 -0
  307. package/dist/performance/code-splitting.js +447 -0
  308. package/dist/performance/code-splitting.js.map +1 -0
  309. package/dist/performance/debounce-throttle.d.ts +75 -0
  310. package/dist/performance/debounce-throttle.d.ts.map +1 -0
  311. package/dist/performance/debounce-throttle.js +232 -0
  312. package/dist/performance/debounce-throttle.js.map +1 -0
  313. package/dist/performance/index.d.ts +28 -0
  314. package/dist/performance/index.d.ts.map +1 -0
  315. package/dist/performance/index.js +39 -0
  316. package/dist/performance/index.js.map +1 -0
  317. package/dist/performance/lazy-loading.d.ts +75 -0
  318. package/dist/performance/lazy-loading.d.ts.map +1 -0
  319. package/dist/performance/lazy-loading.js +233 -0
  320. package/dist/performance/lazy-loading.js.map +1 -0
  321. package/dist/performance/memoization.d.ts +75 -0
  322. package/dist/performance/memoization.d.ts.map +1 -0
  323. package/dist/performance/memoization.js +251 -0
  324. package/dist/performance/memoization.js.map +1 -0
  325. package/dist/registry/detector-registry.d.ts +266 -0
  326. package/dist/registry/detector-registry.d.ts.map +1 -0
  327. package/dist/registry/detector-registry.js +526 -0
  328. package/dist/registry/detector-registry.js.map +1 -0
  329. package/dist/registry/index.d.ts +10 -0
  330. package/dist/registry/index.d.ts.map +1 -0
  331. package/dist/registry/index.js +10 -0
  332. package/dist/registry/index.js.map +1 -0
  333. package/dist/registry/loader.d.ts +232 -0
  334. package/dist/registry/loader.d.ts.map +1 -0
  335. package/dist/registry/loader.js +419 -0
  336. package/dist/registry/loader.js.map +1 -0
  337. package/dist/registry/types.d.ts +111 -0
  338. package/dist/registry/types.d.ts.map +1 -0
  339. package/dist/registry/types.js +19 -0
  340. package/dist/registry/types.js.map +1 -0
  341. package/dist/security/csp-headers.d.ts +78 -0
  342. package/dist/security/csp-headers.d.ts.map +1 -0
  343. package/dist/security/csp-headers.js +401 -0
  344. package/dist/security/csp-headers.js.map +1 -0
  345. package/dist/security/csrf-protection.d.ts +72 -0
  346. package/dist/security/csrf-protection.d.ts.map +1 -0
  347. package/dist/security/csrf-protection.js +344 -0
  348. package/dist/security/csrf-protection.js.map +1 -0
  349. package/dist/security/index.d.ts +30 -0
  350. package/dist/security/index.d.ts.map +1 -0
  351. package/dist/security/index.js +48 -0
  352. package/dist/security/index.js.map +1 -0
  353. package/dist/security/input-sanitization.d.ts +74 -0
  354. package/dist/security/input-sanitization.d.ts.map +1 -0
  355. package/dist/security/input-sanitization.js +373 -0
  356. package/dist/security/input-sanitization.js.map +1 -0
  357. package/dist/security/rate-limiting.d.ts +81 -0
  358. package/dist/security/rate-limiting.d.ts.map +1 -0
  359. package/dist/security/rate-limiting.js +535 -0
  360. package/dist/security/rate-limiting.js.map +1 -0
  361. package/dist/security/secret-management.d.ts +83 -0
  362. package/dist/security/secret-management.d.ts.map +1 -0
  363. package/dist/security/secret-management.js +547 -0
  364. package/dist/security/secret-management.js.map +1 -0
  365. package/dist/security/sql-injection.d.ts +76 -0
  366. package/dist/security/sql-injection.d.ts.map +1 -0
  367. package/dist/security/sql-injection.js +383 -0
  368. package/dist/security/sql-injection.js.map +1 -0
  369. package/dist/security/xss-prevention.d.ts +80 -0
  370. package/dist/security/xss-prevention.d.ts.map +1 -0
  371. package/dist/security/xss-prevention.js +416 -0
  372. package/dist/security/xss-prevention.js.map +1 -0
  373. package/dist/structural/barrel-exports.d.ts +178 -0
  374. package/dist/structural/barrel-exports.d.ts.map +1 -0
  375. package/dist/structural/barrel-exports.js +553 -0
  376. package/dist/structural/barrel-exports.js.map +1 -0
  377. package/dist/structural/circular-deps.d.ts +140 -0
  378. package/dist/structural/circular-deps.d.ts.map +1 -0
  379. package/dist/structural/circular-deps.js +422 -0
  380. package/dist/structural/circular-deps.js.map +1 -0
  381. package/dist/structural/co-location.d.ts +202 -0
  382. package/dist/structural/co-location.d.ts.map +1 -0
  383. package/dist/structural/co-location.js +640 -0
  384. package/dist/structural/co-location.js.map +1 -0
  385. package/dist/structural/directory-structure.d.ts +151 -0
  386. package/dist/structural/directory-structure.d.ts.map +1 -0
  387. package/dist/structural/directory-structure.js +457 -0
  388. package/dist/structural/directory-structure.js.map +1 -0
  389. package/dist/structural/file-naming.d.ts +61 -0
  390. package/dist/structural/file-naming.d.ts.map +1 -0
  391. package/dist/structural/file-naming.js +231 -0
  392. package/dist/structural/file-naming.js.map +1 -0
  393. package/dist/structural/import-ordering.d.ts +212 -0
  394. package/dist/structural/import-ordering.d.ts.map +1 -0
  395. package/dist/structural/import-ordering.js +821 -0
  396. package/dist/structural/import-ordering.js.map +1 -0
  397. package/dist/structural/index.d.ts +23 -0
  398. package/dist/structural/index.d.ts.map +1 -0
  399. package/dist/structural/index.js +26 -0
  400. package/dist/structural/index.js.map +1 -0
  401. package/dist/structural/module-boundaries.d.ts +164 -0
  402. package/dist/structural/module-boundaries.d.ts.map +1 -0
  403. package/dist/structural/module-boundaries.js +616 -0
  404. package/dist/structural/module-boundaries.js.map +1 -0
  405. package/dist/structural/package-boundaries.d.ts +182 -0
  406. package/dist/structural/package-boundaries.d.ts.map +1 -0
  407. package/dist/structural/package-boundaries.js +602 -0
  408. package/dist/structural/package-boundaries.js.map +1 -0
  409. package/dist/styling/class-naming.d.ts +263 -0
  410. package/dist/styling/class-naming.d.ts.map +1 -0
  411. package/dist/styling/class-naming.js +892 -0
  412. package/dist/styling/class-naming.js.map +1 -0
  413. package/dist/styling/color-usage.d.ts +213 -0
  414. package/dist/styling/color-usage.d.ts.map +1 -0
  415. package/dist/styling/color-usage.js +732 -0
  416. package/dist/styling/color-usage.js.map +1 -0
  417. package/dist/styling/design-tokens.d.ts +212 -0
  418. package/dist/styling/design-tokens.d.ts.map +1 -0
  419. package/dist/styling/design-tokens.js +748 -0
  420. package/dist/styling/design-tokens.js.map +1 -0
  421. package/dist/styling/index.d.ts +16 -0
  422. package/dist/styling/index.d.ts.map +1 -0
  423. package/dist/styling/index.js +56 -0
  424. package/dist/styling/index.js.map +1 -0
  425. package/dist/styling/responsive.d.ts +304 -0
  426. package/dist/styling/responsive.d.ts.map +1 -0
  427. package/dist/styling/responsive.js +888 -0
  428. package/dist/styling/responsive.js.map +1 -0
  429. package/dist/styling/spacing-scale.d.ts +248 -0
  430. package/dist/styling/spacing-scale.d.ts.map +1 -0
  431. package/dist/styling/spacing-scale.js +865 -0
  432. package/dist/styling/spacing-scale.js.map +1 -0
  433. package/dist/styling/tailwind-patterns.d.ts +305 -0
  434. package/dist/styling/tailwind-patterns.d.ts.map +1 -0
  435. package/dist/styling/tailwind-patterns.js +1181 -0
  436. package/dist/styling/tailwind-patterns.js.map +1 -0
  437. package/dist/styling/typography.d.ts +281 -0
  438. package/dist/styling/typography.d.ts.map +1 -0
  439. package/dist/styling/typography.js +1004 -0
  440. package/dist/styling/typography.js.map +1 -0
  441. package/dist/styling/z-index-scale.d.ts +270 -0
  442. package/dist/styling/z-index-scale.d.ts.map +1 -0
  443. package/dist/styling/z-index-scale.js +714 -0
  444. package/dist/styling/z-index-scale.js.map +1 -0
  445. package/dist/testing/co-location.d.ts +42 -0
  446. package/dist/testing/co-location.d.ts.map +1 -0
  447. package/dist/testing/co-location.js +134 -0
  448. package/dist/testing/co-location.js.map +1 -0
  449. package/dist/testing/describe-naming.d.ts +47 -0
  450. package/dist/testing/describe-naming.d.ts.map +1 -0
  451. package/dist/testing/describe-naming.js +150 -0
  452. package/dist/testing/describe-naming.js.map +1 -0
  453. package/dist/testing/file-naming.d.ts +44 -0
  454. package/dist/testing/file-naming.d.ts.map +1 -0
  455. package/dist/testing/file-naming.js +131 -0
  456. package/dist/testing/file-naming.js.map +1 -0
  457. package/dist/testing/fixture-patterns.d.ts +52 -0
  458. package/dist/testing/fixture-patterns.d.ts.map +1 -0
  459. package/dist/testing/fixture-patterns.js +228 -0
  460. package/dist/testing/fixture-patterns.js.map +1 -0
  461. package/dist/testing/index.d.ts +31 -0
  462. package/dist/testing/index.d.ts.map +1 -0
  463. package/dist/testing/index.js +49 -0
  464. package/dist/testing/index.js.map +1 -0
  465. package/dist/testing/mock-patterns.d.ts +53 -0
  466. package/dist/testing/mock-patterns.d.ts.map +1 -0
  467. package/dist/testing/mock-patterns.js +264 -0
  468. package/dist/testing/mock-patterns.js.map +1 -0
  469. package/dist/testing/setup-teardown.d.ts +55 -0
  470. package/dist/testing/setup-teardown.d.ts.map +1 -0
  471. package/dist/testing/setup-teardown.js +262 -0
  472. package/dist/testing/setup-teardown.js.map +1 -0
  473. package/dist/testing/test-structure.d.ts +51 -0
  474. package/dist/testing/test-structure.d.ts.map +1 -0
  475. package/dist/testing/test-structure.js +225 -0
  476. package/dist/testing/test-structure.js.map +1 -0
  477. package/dist/types/any-usage.d.ts +99 -0
  478. package/dist/types/any-usage.d.ts.map +1 -0
  479. package/dist/types/any-usage.js +641 -0
  480. package/dist/types/any-usage.js.map +1 -0
  481. package/dist/types/file-location.d.ts +76 -0
  482. package/dist/types/file-location.d.ts.map +1 -0
  483. package/dist/types/file-location.js +395 -0
  484. package/dist/types/file-location.js.map +1 -0
  485. package/dist/types/generic-patterns.d.ts +97 -0
  486. package/dist/types/generic-patterns.d.ts.map +1 -0
  487. package/dist/types/generic-patterns.js +615 -0
  488. package/dist/types/generic-patterns.js.map +1 -0
  489. package/dist/types/index.d.ts +31 -0
  490. package/dist/types/index.d.ts.map +1 -0
  491. package/dist/types/index.js +43 -0
  492. package/dist/types/index.js.map +1 -0
  493. package/dist/types/interface-vs-type.d.ts +81 -0
  494. package/dist/types/interface-vs-type.d.ts.map +1 -0
  495. package/dist/types/interface-vs-type.js +440 -0
  496. package/dist/types/interface-vs-type.js.map +1 -0
  497. package/dist/types/naming-conventions.d.ts +84 -0
  498. package/dist/types/naming-conventions.d.ts.map +1 -0
  499. package/dist/types/naming-conventions.js +455 -0
  500. package/dist/types/naming-conventions.js.map +1 -0
  501. package/dist/types/type-assertions.d.ts +98 -0
  502. package/dist/types/type-assertions.d.ts.map +1 -0
  503. package/dist/types/type-assertions.js +639 -0
  504. package/dist/types/type-assertions.js.map +1 -0
  505. package/dist/types/utility-types.d.ts +110 -0
  506. package/dist/types/utility-types.d.ts.map +1 -0
  507. package/dist/types/utility-types.js +547 -0
  508. package/dist/types/utility-types.js.map +1 -0
  509. package/package.json +44 -0
@@ -0,0 +1,892 @@
1
+ /**
2
+ * Class Naming Detector - CSS class naming convention detection
3
+ *
4
+ * Detects CSS class naming patterns including:
5
+ * - BEM pattern (block__element--modifier)
6
+ * - Utility-first pattern (Tailwind-style: flex, items-center, p-4)
7
+ * - CSS Modules pattern (styles.className)
8
+ * - Semantic naming pattern (btn-primary, card-header)
9
+ * - SMACSS/OOCSS patterns
10
+ *
11
+ * Flags inconsistent class naming:
12
+ * - Mixed naming conventions in the same file
13
+ * - Non-standard BEM usage
14
+ * - Inconsistent utility class ordering
15
+ *
16
+ * @requirements 9.5 - THE Styling_Detector SHALL detect CSS class naming conventions (BEM, utility-first)
17
+ */
18
+ import { RegexDetector } from '../base/index.js';
19
+ // ============================================================================
20
+ // Constants
21
+ // ============================================================================
22
+ /**
23
+ * BEM pattern regex
24
+ * Matches: block, block__element, block--modifier, block__element--modifier
25
+ */
26
+ export const BEM_PATTERN = /\b([a-z][a-z0-9]*(?:-[a-z0-9]+)*)(?:__([a-z][a-z0-9]*(?:-[a-z0-9]+)*))?(?:--([a-z][a-z0-9]*(?:-[a-z0-9]+)*))?\b/gi;
27
+ /**
28
+ * Strict BEM pattern (requires at least __ or --)
29
+ */
30
+ export const STRICT_BEM_PATTERN = /\b([a-z][a-z0-9]*(?:-[a-z0-9]+)*)(?:__[a-z][a-z0-9]*(?:-[a-z0-9]+)*|--[a-z][a-z0-9]*(?:-[a-z0-9]+)*)+\b/gi;
31
+ /**
32
+ * Invalid BEM patterns (common mistakes)
33
+ */
34
+ export const INVALID_BEM_PATTERNS = [
35
+ // Double underscore followed by double dash (should be separate)
36
+ /\b[a-z][a-z0-9-]*__[a-z][a-z0-9-]*__[a-z][a-z0-9-]*\b/gi,
37
+ // Triple underscore
38
+ /\b[a-z][a-z0-9-]*___[a-z][a-z0-9-]*\b/gi,
39
+ // Triple dash
40
+ /\b[a-z][a-z0-9-]*---[a-z][a-z0-9-]*\b/gi,
41
+ // Uppercase in BEM (should be lowercase)
42
+ /\b[a-z][a-zA-Z0-9-]*__[A-Z][a-zA-Z0-9-]*\b/g,
43
+ /\b[a-z][a-zA-Z0-9-]*--[A-Z][a-zA-Z0-9-]*\b/g,
44
+ ];
45
+ /**
46
+ * Tailwind utility class patterns
47
+ */
48
+ export const TAILWIND_UTILITY_PATTERNS = [
49
+ // Layout
50
+ /\b(?:flex|grid|block|inline|hidden|container)\b/g,
51
+ /\b(?:flex-row|flex-col|flex-wrap|flex-nowrap|flex-1|flex-auto|flex-initial|flex-none)\b/g,
52
+ /\b(?:grid-cols-\d+|grid-rows-\d+|col-span-\d+|row-span-\d+)\b/g,
53
+ // Spacing
54
+ /\b(?:p|px|py|pt|pr|pb|pl|m|mx|my|mt|mr|mb|ml)-(?:\d+|auto|px)\b/g,
55
+ /\b(?:space-x|space-y|gap|gap-x|gap-y)-\d+\b/g,
56
+ // Sizing
57
+ /\b(?:w|h|min-w|min-h|max-w|max-h)-(?:\d+|full|screen|auto|min|max|fit)\b/g,
58
+ // Typography
59
+ /\b(?:text-(?:xs|sm|base|lg|xl|2xl|3xl|4xl|5xl|6xl|7xl|8xl|9xl))\b/g,
60
+ /\b(?:font-(?:thin|extralight|light|normal|medium|semibold|bold|extrabold|black))\b/g,
61
+ // Colors (simplified)
62
+ /\b(?:text|bg|border|ring)-(?:slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose|black|white)-(?:\d{2,3}|50)\b/g,
63
+ // Flexbox alignment
64
+ /\b(?:items|justify|content|self)-(?:start|end|center|between|around|evenly|stretch|baseline)\b/g,
65
+ // Border
66
+ /\b(?:border|border-t|border-r|border-b|border-l)(?:-\d+)?\b/g,
67
+ /\b(?:rounded|rounded-t|rounded-r|rounded-b|rounded-l|rounded-tl|rounded-tr|rounded-bl|rounded-br)(?:-(?:none|sm|md|lg|xl|2xl|3xl|full))?\b/g,
68
+ // Effects
69
+ /\b(?:shadow|shadow-sm|shadow-md|shadow-lg|shadow-xl|shadow-2xl|shadow-inner|shadow-none)\b/g,
70
+ /\b(?:opacity-\d+)\b/g,
71
+ // Positioning
72
+ /\b(?:relative|absolute|fixed|sticky|static)\b/g,
73
+ /\b(?:top|right|bottom|left|inset)-(?:\d+|auto|px|full)\b/g,
74
+ /\b(?:z-\d+|z-auto)\b/g,
75
+ // Display
76
+ /\b(?:overflow|overflow-x|overflow-y)-(?:auto|hidden|visible|scroll)\b/g,
77
+ // Transitions
78
+ /\b(?:transition|transition-all|transition-colors|transition-opacity|transition-shadow|transition-transform)\b/g,
79
+ /\b(?:duration-\d+)\b/g,
80
+ /\b(?:ease-linear|ease-in|ease-out|ease-in-out)\b/g,
81
+ ];
82
+ /**
83
+ * CSS Modules pattern
84
+ * Matches: styles.className, styles['class-name'], styles["class-name"]
85
+ */
86
+ export const CSS_MODULES_PATTERNS = [
87
+ /\bstyles\.([a-zA-Z_][a-zA-Z0-9_]*)\b/g,
88
+ /\bstyles\[['"]([a-zA-Z_][a-zA-Z0-9_-]*)['"]\]/g,
89
+ /\bclasses\.([a-zA-Z_][a-zA-Z0-9_]*)\b/g,
90
+ /\bclasses\[['"]([a-zA-Z_][a-zA-Z0-9_-]*)['"]\]/g,
91
+ /\bcss\.([a-zA-Z_][a-zA-Z0-9_]*)\b/g,
92
+ ];
93
+ /**
94
+ * Semantic naming patterns
95
+ * Matches: btn-primary, card-header, nav-item, etc.
96
+ */
97
+ export const SEMANTIC_NAMING_PATTERNS = [
98
+ // Button patterns
99
+ /\b(?:btn|button)-(?:primary|secondary|tertiary|success|danger|warning|info|light|dark|link|outline|ghost|disabled)\b/gi,
100
+ // Card patterns
101
+ /\b(?:card|panel)-(?:header|body|footer|title|subtitle|content|image|actions)\b/gi,
102
+ // Navigation patterns
103
+ /\b(?:nav|navbar|menu)-(?:item|link|brand|toggle|collapse|dropdown)\b/gi,
104
+ // Form patterns
105
+ /\b(?:form|input|field)-(?:group|control|label|error|help|text|check|radio|select)\b/gi,
106
+ // Layout patterns
107
+ /\b(?:container|wrapper|section|header|footer|sidebar|main|content)-(?:fluid|fixed|full|inner|outer)\b/gi,
108
+ // List patterns
109
+ /\b(?:list|item)-(?:group|item|inline|unstyled|ordered|unordered)\b/gi,
110
+ // Modal/Dialog patterns
111
+ /\b(?:modal|dialog)-(?:header|body|footer|title|content|backdrop|close)\b/gi,
112
+ // Alert patterns
113
+ /\b(?:alert|notification|toast)-(?:success|error|warning|info|primary|secondary|dismissible)\b/gi,
114
+ // Table patterns
115
+ /\b(?:table|row|cell|thead|tbody|tfoot)-(?:header|body|footer|striped|bordered|hover|responsive)\b/gi,
116
+ ];
117
+ /**
118
+ * SMACSS patterns
119
+ * Matches: l-*, is-*, has-*, js-*
120
+ */
121
+ export const SMACSS_PATTERNS = [
122
+ // Layout
123
+ /\bl-[a-z][a-z0-9-]*\b/gi,
124
+ // State
125
+ /\bis-[a-z][a-z0-9-]*\b/gi,
126
+ /\bhas-[a-z][a-z0-9-]*\b/gi,
127
+ // JavaScript hooks
128
+ /\bjs-[a-z][a-z0-9-]*\b/gi,
129
+ ];
130
+ /**
131
+ * OOCSS patterns (common object-oriented CSS patterns)
132
+ */
133
+ export const OOCSS_PATTERNS = [
134
+ // Media object
135
+ /\b(?:media|media-body|media-left|media-right|media-object)\b/gi,
136
+ // Flag object
137
+ /\b(?:flag|flag-body|flag-image)\b/gi,
138
+ // Box object
139
+ /\b(?:box|box-header|box-body|box-footer)\b/gi,
140
+ ];
141
+ /**
142
+ * File patterns to exclude from class naming detection
143
+ */
144
+ export const EXCLUDED_FILE_PATTERNS = [
145
+ /\.test\.[jt]sx?$/,
146
+ /\.spec\.[jt]sx?$/,
147
+ /\.stories\.[jt]sx?$/,
148
+ /\.config\.[jt]s$/,
149
+ /tailwind\.config/,
150
+ ];
151
+ /**
152
+ * Recommended utility class ordering (Tailwind convention)
153
+ */
154
+ export const UTILITY_CLASS_ORDER = [
155
+ 'container',
156
+ 'position',
157
+ 'display',
158
+ 'flex',
159
+ 'grid',
160
+ 'width',
161
+ 'height',
162
+ 'margin',
163
+ 'padding',
164
+ 'border',
165
+ 'background',
166
+ 'text',
167
+ 'font',
168
+ 'color',
169
+ 'opacity',
170
+ 'shadow',
171
+ 'transition',
172
+ 'animation',
173
+ ];
174
+ // ============================================================================
175
+ // Helper Functions
176
+ // ============================================================================
177
+ /**
178
+ * Check if a file should be excluded from class naming detection
179
+ */
180
+ export function shouldExcludeFile(filePath) {
181
+ return EXCLUDED_FILE_PATTERNS.some(pattern => pattern.test(filePath));
182
+ }
183
+ /**
184
+ * Check if a position is inside a comment
185
+ */
186
+ function isInsideComment(content, index) {
187
+ const beforeIndex = content.slice(0, index);
188
+ // Check for single-line comment
189
+ const lastNewline = beforeIndex.lastIndexOf('\n');
190
+ const currentLine = beforeIndex.slice(lastNewline + 1);
191
+ if (currentLine.includes('//')) {
192
+ const commentStart = currentLine.indexOf('//');
193
+ const positionInLine = index - lastNewline - 1;
194
+ if (positionInLine > commentStart) {
195
+ return true;
196
+ }
197
+ }
198
+ // Check for multi-line comment
199
+ const lastBlockCommentStart = beforeIndex.lastIndexOf('/*');
200
+ const lastBlockCommentEnd = beforeIndex.lastIndexOf('*/');
201
+ if (lastBlockCommentStart > lastBlockCommentEnd) {
202
+ return true;
203
+ }
204
+ return false;
205
+ }
206
+ /**
207
+ * Check if a class name follows BEM convention
208
+ */
209
+ export function isBEMClassName(className) {
210
+ // BEM: block__element--modifier
211
+ return /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*(?:__[a-z][a-z0-9]*(?:-[a-z0-9]+)*)?(?:--[a-z][a-z0-9]*(?:-[a-z0-9]+)*)?$/i.test(className);
212
+ }
213
+ /**
214
+ * Check if a class name is a Tailwind utility class
215
+ */
216
+ export function isTailwindUtilityClass(className) {
217
+ for (const pattern of TAILWIND_UTILITY_PATTERNS) {
218
+ const regex = new RegExp(pattern.source, pattern.flags);
219
+ if (regex.test(className)) {
220
+ return true;
221
+ }
222
+ }
223
+ return false;
224
+ }
225
+ /**
226
+ * Check if a class name follows semantic naming
227
+ */
228
+ export function isSemanticClassName(className) {
229
+ for (const pattern of SEMANTIC_NAMING_PATTERNS) {
230
+ const regex = new RegExp(pattern.source, pattern.flags);
231
+ if (regex.test(className)) {
232
+ return true;
233
+ }
234
+ }
235
+ return false;
236
+ }
237
+ /**
238
+ * Check if a class name follows SMACSS convention
239
+ */
240
+ export function isSMACSClassName(className) {
241
+ for (const pattern of SMACSS_PATTERNS) {
242
+ const regex = new RegExp(pattern.source, pattern.flags);
243
+ if (regex.test(className)) {
244
+ return true;
245
+ }
246
+ }
247
+ return false;
248
+ }
249
+ /**
250
+ * Validate BEM class name and return issues
251
+ */
252
+ export function validateBEMClassName(className) {
253
+ // Check for multiple element separators
254
+ if ((className.match(/__/g) || []).length > 1) {
255
+ return 'BEM class should have at most one element separator (__)';
256
+ }
257
+ // Check for uppercase letters
258
+ if (/[A-Z]/.test(className)) {
259
+ return 'BEM class names should be lowercase';
260
+ }
261
+ // Check for invalid characters
262
+ if (/[^a-z0-9_-]/i.test(className)) {
263
+ return 'BEM class names should only contain lowercase letters, numbers, hyphens, and underscores';
264
+ }
265
+ // Check for triple underscore or dash
266
+ if (/___/.test(className) || /---/.test(className)) {
267
+ return 'BEM class names should not have triple underscores or dashes';
268
+ }
269
+ return null;
270
+ }
271
+ /**
272
+ * Detect BEM patterns in content
273
+ */
274
+ export function detectBEMPatterns(content, file) {
275
+ const results = [];
276
+ const lines = content.split('\n');
277
+ const regex = new RegExp(STRICT_BEM_PATTERN.source, STRICT_BEM_PATTERN.flags);
278
+ let match;
279
+ while ((match = regex.exec(content)) !== null) {
280
+ // Skip if inside a comment
281
+ if (isInsideComment(content, match.index)) {
282
+ continue;
283
+ }
284
+ const beforeMatch = content.slice(0, match.index);
285
+ const lineNumber = beforeMatch.split('\n').length;
286
+ const lastNewline = beforeMatch.lastIndexOf('\n');
287
+ const column = match.index - lastNewline;
288
+ results.push({
289
+ type: 'bem',
290
+ file,
291
+ line: lineNumber,
292
+ column,
293
+ matchedText: match[0],
294
+ classNames: [match[0]],
295
+ context: lines[lineNumber - 1] || '',
296
+ });
297
+ }
298
+ return results;
299
+ }
300
+ /**
301
+ * Detect utility-first (Tailwind) patterns in content
302
+ */
303
+ export function detectUtilityFirstPatterns(content, file) {
304
+ const results = [];
305
+ const lines = content.split('\n');
306
+ const seenMatches = new Set();
307
+ for (const pattern of TAILWIND_UTILITY_PATTERNS) {
308
+ const regex = new RegExp(pattern.source, pattern.flags);
309
+ let match;
310
+ while ((match = regex.exec(content)) !== null) {
311
+ const key = `${match.index}-${match[0]}`;
312
+ if (seenMatches.has(key))
313
+ continue;
314
+ seenMatches.add(key);
315
+ // Skip if inside a comment
316
+ if (isInsideComment(content, match.index)) {
317
+ continue;
318
+ }
319
+ const beforeMatch = content.slice(0, match.index);
320
+ const lineNumber = beforeMatch.split('\n').length;
321
+ const lastNewline = beforeMatch.lastIndexOf('\n');
322
+ const column = match.index - lastNewline;
323
+ results.push({
324
+ type: 'utility-first',
325
+ file,
326
+ line: lineNumber,
327
+ column,
328
+ matchedText: match[0],
329
+ classNames: [match[0]],
330
+ context: lines[lineNumber - 1] || '',
331
+ });
332
+ }
333
+ }
334
+ return results;
335
+ }
336
+ /**
337
+ * Detect CSS Modules patterns in content
338
+ */
339
+ export function detectCSSModulesPatterns(content, file) {
340
+ const results = [];
341
+ const lines = content.split('\n');
342
+ for (const pattern of CSS_MODULES_PATTERNS) {
343
+ const regex = new RegExp(pattern.source, pattern.flags);
344
+ let match;
345
+ while ((match = regex.exec(content)) !== null) {
346
+ // Skip if inside a comment
347
+ if (isInsideComment(content, match.index)) {
348
+ continue;
349
+ }
350
+ const beforeMatch = content.slice(0, match.index);
351
+ const lineNumber = beforeMatch.split('\n').length;
352
+ const lastNewline = beforeMatch.lastIndexOf('\n');
353
+ const column = match.index - lastNewline;
354
+ results.push({
355
+ type: 'css-modules',
356
+ file,
357
+ line: lineNumber,
358
+ column,
359
+ matchedText: match[0],
360
+ classNames: [match[1] || match[0]],
361
+ context: lines[lineNumber - 1] || '',
362
+ });
363
+ }
364
+ }
365
+ return results;
366
+ }
367
+ /**
368
+ * Detect semantic naming patterns in content
369
+ */
370
+ export function detectSemanticPatterns(content, file) {
371
+ const results = [];
372
+ const lines = content.split('\n');
373
+ for (const pattern of SEMANTIC_NAMING_PATTERNS) {
374
+ const regex = new RegExp(pattern.source, pattern.flags);
375
+ let match;
376
+ while ((match = regex.exec(content)) !== null) {
377
+ // Skip if inside a comment
378
+ if (isInsideComment(content, match.index)) {
379
+ continue;
380
+ }
381
+ const beforeMatch = content.slice(0, match.index);
382
+ const lineNumber = beforeMatch.split('\n').length;
383
+ const lastNewline = beforeMatch.lastIndexOf('\n');
384
+ const column = match.index - lastNewline;
385
+ results.push({
386
+ type: 'semantic',
387
+ file,
388
+ line: lineNumber,
389
+ column,
390
+ matchedText: match[0],
391
+ classNames: [match[0]],
392
+ context: lines[lineNumber - 1] || '',
393
+ });
394
+ }
395
+ }
396
+ return results;
397
+ }
398
+ /**
399
+ * Detect SMACSS patterns in content
400
+ */
401
+ export function detectSMACSPatterns(content, file) {
402
+ const results = [];
403
+ const lines = content.split('\n');
404
+ for (const pattern of SMACSS_PATTERNS) {
405
+ const regex = new RegExp(pattern.source, pattern.flags);
406
+ let match;
407
+ while ((match = regex.exec(content)) !== null) {
408
+ // Skip if inside a comment
409
+ if (isInsideComment(content, match.index)) {
410
+ continue;
411
+ }
412
+ const beforeMatch = content.slice(0, match.index);
413
+ const lineNumber = beforeMatch.split('\n').length;
414
+ const lastNewline = beforeMatch.lastIndexOf('\n');
415
+ const column = match.index - lastNewline;
416
+ results.push({
417
+ type: 'smacss',
418
+ file,
419
+ line: lineNumber,
420
+ column,
421
+ matchedText: match[0],
422
+ classNames: [match[0]],
423
+ context: lines[lineNumber - 1] || '',
424
+ });
425
+ }
426
+ }
427
+ return results;
428
+ }
429
+ /**
430
+ * Detect invalid BEM patterns
431
+ */
432
+ export function detectInvalidBEMPatterns(content, file) {
433
+ const results = [];
434
+ const lines = content.split('\n');
435
+ for (const pattern of INVALID_BEM_PATTERNS) {
436
+ const regex = new RegExp(pattern.source, pattern.flags);
437
+ let match;
438
+ while ((match = regex.exec(content)) !== null) {
439
+ // Skip if inside a comment
440
+ if (isInsideComment(content, match.index)) {
441
+ continue;
442
+ }
443
+ const beforeMatch = content.slice(0, match.index);
444
+ const lineNumber = beforeMatch.split('\n').length;
445
+ const lastNewline = beforeMatch.lastIndexOf('\n');
446
+ const column = match.index - lastNewline;
447
+ const endColumn = column + match[0].length;
448
+ const issue = validateBEMClassName(match[0]) || 'Invalid BEM class name format';
449
+ results.push({
450
+ type: 'invalid-bem',
451
+ file,
452
+ line: lineNumber,
453
+ column,
454
+ endLine: lineNumber,
455
+ endColumn,
456
+ classNames: [match[0]],
457
+ issue,
458
+ suggestedFix: suggestBEMFix(match[0]),
459
+ lineContent: lines[lineNumber - 1] || '',
460
+ });
461
+ }
462
+ }
463
+ return results;
464
+ }
465
+ /**
466
+ * Detect mixed naming conventions in a file
467
+ */
468
+ export function detectMixedConventions(patterns, file) {
469
+ const results = [];
470
+ // Count patterns by type
471
+ const typeCounts = {
472
+ 'bem': 0,
473
+ 'utility-first': 0,
474
+ 'css-modules': 0,
475
+ 'semantic': 0,
476
+ 'smacss': 0,
477
+ 'oocss': 0,
478
+ };
479
+ for (const pattern of patterns) {
480
+ typeCounts[pattern.type]++;
481
+ }
482
+ // Find the dominant convention
483
+ const sortedTypes = Object.entries(typeCounts)
484
+ .filter(([_, count]) => count > 0)
485
+ .sort((a, b) => b[1] - a[1]);
486
+ if (sortedTypes.length <= 1) {
487
+ return results; // No mixed conventions
488
+ }
489
+ const dominantType = sortedTypes[0]?.[0];
490
+ const dominantCount = sortedTypes[0]?.[1] || 0;
491
+ // Flag patterns that don't match the dominant convention
492
+ // Only flag if there's a clear dominant pattern (>60% of patterns)
493
+ const totalPatterns = patterns.length;
494
+ if (dominantCount / totalPatterns < 0.6) {
495
+ // No clear dominant pattern, flag all as mixed
496
+ const firstPattern = patterns[0];
497
+ if (firstPattern) {
498
+ results.push({
499
+ type: 'mixed-conventions',
500
+ file,
501
+ line: firstPattern.line,
502
+ column: firstPattern.column,
503
+ endLine: firstPattern.line,
504
+ endColumn: firstPattern.column + firstPattern.matchedText.length,
505
+ classNames: patterns.map(p => p.matchedText),
506
+ issue: `File uses multiple naming conventions: ${sortedTypes.map(([t, c]) => `${t} (${c})`).join(', ')}`,
507
+ suggestedFix: `Consider standardizing on one naming convention (most common: ${dominantType})`,
508
+ lineContent: firstPattern.context || '',
509
+ });
510
+ }
511
+ }
512
+ else {
513
+ // Flag minority patterns
514
+ for (const pattern of patterns) {
515
+ if (pattern.type !== dominantType) {
516
+ results.push({
517
+ type: 'mixed-conventions',
518
+ file,
519
+ line: pattern.line,
520
+ column: pattern.column,
521
+ endLine: pattern.line,
522
+ endColumn: pattern.column + pattern.matchedText.length,
523
+ classNames: [pattern.matchedText],
524
+ issue: `Class '${pattern.matchedText}' uses ${pattern.type} convention, but file predominantly uses ${dominantType}`,
525
+ suggestedFix: `Consider converting to ${dominantType} convention`,
526
+ lineContent: pattern.context || '',
527
+ });
528
+ }
529
+ }
530
+ }
531
+ return results;
532
+ }
533
+ /**
534
+ * Suggest a BEM fix for an invalid class name
535
+ */
536
+ export function suggestBEMFix(className) {
537
+ // Convert to lowercase
538
+ let fixed = className.toLowerCase();
539
+ // Replace triple underscores/dashes with double
540
+ fixed = fixed.replace(/___/g, '__').replace(/---/g, '--');
541
+ // Remove extra element separators
542
+ const parts = fixed.split('__');
543
+ if (parts.length > 2) {
544
+ fixed = `${parts[0]}__${parts.slice(1).join('-')}`;
545
+ }
546
+ return fixed;
547
+ }
548
+ /**
549
+ * Determine the dominant naming convention
550
+ */
551
+ export function getDominantConvention(patterns) {
552
+ if (patterns.length === 0)
553
+ return null;
554
+ const typeCounts = {
555
+ 'bem': 0,
556
+ 'utility-first': 0,
557
+ 'css-modules': 0,
558
+ 'semantic': 0,
559
+ 'smacss': 0,
560
+ 'oocss': 0,
561
+ };
562
+ for (const pattern of patterns) {
563
+ typeCounts[pattern.type]++;
564
+ }
565
+ const sortedTypes = Object.entries(typeCounts)
566
+ .filter(([_, count]) => count > 0)
567
+ .sort((a, b) => b[1] - a[1]);
568
+ return sortedTypes[0]?.[0] || null;
569
+ }
570
+ /**
571
+ * Analyze class naming patterns in a file
572
+ */
573
+ export function analyzeClassNaming(content, file) {
574
+ // Skip excluded files
575
+ if (shouldExcludeFile(file)) {
576
+ return {
577
+ patterns: [],
578
+ violations: [],
579
+ usesBEM: false,
580
+ usesUtilityFirst: false,
581
+ usesCSSModules: false,
582
+ usesSemantic: false,
583
+ usesSMACSS: false,
584
+ dominantConvention: null,
585
+ namingConsistencyConfidence: 1.0,
586
+ };
587
+ }
588
+ // Detect all patterns
589
+ const bemPatterns = detectBEMPatterns(content, file);
590
+ const utilityPatterns = detectUtilityFirstPatterns(content, file);
591
+ const cssModulesPatterns = detectCSSModulesPatterns(content, file);
592
+ const semanticPatterns = detectSemanticPatterns(content, file);
593
+ const smacssPatterns = detectSMACSPatterns(content, file);
594
+ const allPatterns = [
595
+ ...bemPatterns,
596
+ ...utilityPatterns,
597
+ ...cssModulesPatterns,
598
+ ...semanticPatterns,
599
+ ...smacssPatterns,
600
+ ];
601
+ // Detect violations
602
+ const invalidBEMViolations = detectInvalidBEMPatterns(content, file);
603
+ const mixedConventionViolations = detectMixedConventions(allPatterns, file);
604
+ const allViolations = [
605
+ ...invalidBEMViolations,
606
+ ...mixedConventionViolations,
607
+ ];
608
+ // Calculate confidence
609
+ const hasPatterns = allPatterns.length > 0;
610
+ const hasViolations = allViolations.length > 0;
611
+ let namingConsistencyConfidence = 0;
612
+ if (hasPatterns && !hasViolations) {
613
+ namingConsistencyConfidence = 1.0;
614
+ }
615
+ else if (hasPatterns && hasViolations) {
616
+ const ratio = allPatterns.length / (allPatterns.length + allViolations.length);
617
+ namingConsistencyConfidence = ratio;
618
+ }
619
+ else if (!hasPatterns && hasViolations) {
620
+ namingConsistencyConfidence = 0;
621
+ }
622
+ else {
623
+ namingConsistencyConfidence = 0.5; // No class naming detected
624
+ }
625
+ return {
626
+ patterns: allPatterns,
627
+ violations: allViolations,
628
+ usesBEM: bemPatterns.length > 0,
629
+ usesUtilityFirst: utilityPatterns.length > 0,
630
+ usesCSSModules: cssModulesPatterns.length > 0,
631
+ usesSemantic: semanticPatterns.length > 0,
632
+ usesSMACSS: smacssPatterns.length > 0,
633
+ dominantConvention: getDominantConvention(allPatterns),
634
+ namingConsistencyConfidence,
635
+ };
636
+ }
637
+ // ============================================================================
638
+ // Class Naming Detector Class
639
+ // ============================================================================
640
+ /**
641
+ * Detector for CSS class naming conventions
642
+ *
643
+ * Identifies class naming patterns (BEM, utility-first, CSS Modules, semantic)
644
+ * and flags inconsistent naming conventions.
645
+ *
646
+ * @requirements 9.5 - THE Styling_Detector SHALL detect CSS class naming conventions (BEM, utility-first)
647
+ */
648
+ export class ClassNamingDetector extends RegexDetector {
649
+ id = 'styling/class-naming';
650
+ category = 'styling';
651
+ subcategory = 'class-naming';
652
+ name = 'Class Naming Detector';
653
+ description = 'Detects CSS class naming conventions (BEM, utility-first, CSS Modules) and flags inconsistent naming';
654
+ supportedLanguages = ['typescript', 'javascript', 'css'];
655
+ /**
656
+ * Detect class naming patterns and violations
657
+ */
658
+ async detect(context) {
659
+ const patterns = [];
660
+ const violations = [];
661
+ // Analyze the file
662
+ const analysis = analyzeClassNaming(context.content, context.file);
663
+ // Create pattern matches for naming conventions
664
+ if (analysis.usesBEM) {
665
+ patterns.push(this.createBEMPattern(context.file, analysis));
666
+ }
667
+ if (analysis.usesUtilityFirst) {
668
+ patterns.push(this.createUtilityFirstPattern(context.file, analysis));
669
+ }
670
+ if (analysis.usesCSSModules) {
671
+ patterns.push(this.createCSSModulesPattern(context.file, analysis));
672
+ }
673
+ if (analysis.usesSemantic) {
674
+ patterns.push(this.createSemanticPattern(context.file, analysis));
675
+ }
676
+ if (analysis.usesSMACSS) {
677
+ patterns.push(this.createSMACSPattern(context.file, analysis));
678
+ }
679
+ // Create violations
680
+ for (const violation of analysis.violations) {
681
+ violations.push(this.createClassNamingViolation(violation));
682
+ }
683
+ return this.createResult(patterns, violations, analysis.namingConsistencyConfidence);
684
+ }
685
+ /**
686
+ * Create a pattern match for BEM usage
687
+ */
688
+ createBEMPattern(file, analysis) {
689
+ const bemPatterns = analysis.patterns.filter(p => p.type === 'bem');
690
+ const firstPattern = bemPatterns[0];
691
+ return {
692
+ patternId: `${this.id}/bem`,
693
+ location: {
694
+ file,
695
+ line: firstPattern?.line || 1,
696
+ column: firstPattern?.column || 1,
697
+ },
698
+ confidence: 1.0,
699
+ isOutlier: false,
700
+ };
701
+ }
702
+ /**
703
+ * Create a pattern match for utility-first usage
704
+ */
705
+ createUtilityFirstPattern(file, analysis) {
706
+ const utilityPatterns = analysis.patterns.filter(p => p.type === 'utility-first');
707
+ const firstPattern = utilityPatterns[0];
708
+ return {
709
+ patternId: `${this.id}/utility-first`,
710
+ location: {
711
+ file,
712
+ line: firstPattern?.line || 1,
713
+ column: firstPattern?.column || 1,
714
+ },
715
+ confidence: 1.0,
716
+ isOutlier: false,
717
+ };
718
+ }
719
+ /**
720
+ * Create a pattern match for CSS Modules usage
721
+ */
722
+ createCSSModulesPattern(file, analysis) {
723
+ const cssModulesPatterns = analysis.patterns.filter(p => p.type === 'css-modules');
724
+ const firstPattern = cssModulesPatterns[0];
725
+ return {
726
+ patternId: `${this.id}/css-modules`,
727
+ location: {
728
+ file,
729
+ line: firstPattern?.line || 1,
730
+ column: firstPattern?.column || 1,
731
+ },
732
+ confidence: 1.0,
733
+ isOutlier: false,
734
+ };
735
+ }
736
+ /**
737
+ * Create a pattern match for semantic naming usage
738
+ */
739
+ createSemanticPattern(file, analysis) {
740
+ const semanticPatterns = analysis.patterns.filter(p => p.type === 'semantic');
741
+ const firstPattern = semanticPatterns[0];
742
+ return {
743
+ patternId: `${this.id}/semantic`,
744
+ location: {
745
+ file,
746
+ line: firstPattern?.line || 1,
747
+ column: firstPattern?.column || 1,
748
+ },
749
+ confidence: 1.0,
750
+ isOutlier: false,
751
+ };
752
+ }
753
+ /**
754
+ * Create a pattern match for SMACSS usage
755
+ */
756
+ createSMACSPattern(file, analysis) {
757
+ const smacssPatterns = analysis.patterns.filter(p => p.type === 'smacss');
758
+ const firstPattern = smacssPatterns[0];
759
+ return {
760
+ patternId: `${this.id}/smacss`,
761
+ location: {
762
+ file,
763
+ line: firstPattern?.line || 1,
764
+ column: firstPattern?.column || 1,
765
+ },
766
+ confidence: 1.0,
767
+ isOutlier: false,
768
+ };
769
+ }
770
+ /**
771
+ * Create a violation for a class naming issue
772
+ */
773
+ createClassNamingViolation(info) {
774
+ const typeDescriptions = {
775
+ 'mixed-conventions': 'Mixed naming conventions',
776
+ 'invalid-bem': 'Invalid BEM class name',
777
+ 'inconsistent-ordering': 'Inconsistent utility class ordering',
778
+ 'non-semantic-name': 'Non-semantic class name',
779
+ };
780
+ const typeDescription = typeDescriptions[info.type] || 'Class naming issue';
781
+ const violation = {
782
+ id: `${this.id}-${info.file}-${info.line}-${info.column}`,
783
+ patternId: this.id,
784
+ severity: info.type === 'invalid-bem' ? 'warning' : 'info',
785
+ file: info.file,
786
+ range: {
787
+ start: { line: info.line - 1, character: info.column - 1 },
788
+ end: { line: info.endLine - 1, character: info.endColumn - 1 },
789
+ },
790
+ message: `${typeDescription}: ${info.issue}`,
791
+ explanation: this.getExplanationForViolationType(info.type),
792
+ expected: info.suggestedFix || 'Consistent class naming convention',
793
+ actual: info.classNames.join(', '),
794
+ aiExplainAvailable: true,
795
+ aiFixAvailable: info.type === 'invalid-bem',
796
+ firstSeen: new Date(),
797
+ occurrences: 1,
798
+ };
799
+ const quickFix = this.createQuickFixForViolation(info);
800
+ if (quickFix !== undefined) {
801
+ violation.quickFix = quickFix;
802
+ }
803
+ return violation;
804
+ }
805
+ /**
806
+ * Get explanation for a violation type
807
+ */
808
+ getExplanationForViolationType(type) {
809
+ switch (type) {
810
+ case 'mixed-conventions':
811
+ return 'Using multiple naming conventions in the same file makes the codebase harder to maintain. Choose one convention and apply it consistently.';
812
+ case 'invalid-bem':
813
+ return 'BEM (Block Element Modifier) naming should follow the pattern: block__element--modifier. Class names should be lowercase with hyphens for multi-word names.';
814
+ case 'inconsistent-ordering':
815
+ return 'Utility classes should follow a consistent ordering (e.g., layout, spacing, typography, colors) for better readability.';
816
+ case 'non-semantic-name':
817
+ return 'Class names should describe the purpose or meaning of the element, not its appearance.';
818
+ default:
819
+ return 'Consistent class naming improves code maintainability and readability.';
820
+ }
821
+ }
822
+ /**
823
+ * Create a quick fix for a class naming violation
824
+ */
825
+ createQuickFixForViolation(info) {
826
+ if (info.type !== 'invalid-bem' || !info.suggestedFix) {
827
+ return undefined;
828
+ }
829
+ return {
830
+ title: `Fix BEM class name: ${info.suggestedFix}`,
831
+ kind: 'quickfix',
832
+ edit: {
833
+ changes: {
834
+ [info.file]: [
835
+ {
836
+ range: {
837
+ start: { line: info.line - 1, character: info.column - 1 },
838
+ end: { line: info.endLine - 1, character: info.endColumn - 1 },
839
+ },
840
+ newText: info.suggestedFix,
841
+ },
842
+ ],
843
+ },
844
+ },
845
+ isPreferred: true,
846
+ confidence: 0.8,
847
+ preview: `Replace '${info.classNames[0]}' with '${info.suggestedFix}'`,
848
+ };
849
+ }
850
+ /**
851
+ * Generate a quick fix for a violation
852
+ */
853
+ generateQuickFix(violation) {
854
+ // Check if this is a BEM violation
855
+ if (!violation.message.includes('BEM')) {
856
+ return null;
857
+ }
858
+ // Extract the class name from the message
859
+ const classMatch = violation.actual;
860
+ if (!classMatch) {
861
+ return null;
862
+ }
863
+ const suggestedFix = suggestBEMFix(classMatch);
864
+ return {
865
+ title: `Fix BEM class name: ${suggestedFix}`,
866
+ kind: 'quickfix',
867
+ edit: {
868
+ changes: {
869
+ [violation.file]: [
870
+ {
871
+ range: violation.range,
872
+ newText: suggestedFix,
873
+ },
874
+ ],
875
+ },
876
+ },
877
+ isPreferred: true,
878
+ confidence: 0.8,
879
+ preview: `Replace '${classMatch}' with '${suggestedFix}'`,
880
+ };
881
+ }
882
+ }
883
+ // ============================================================================
884
+ // Factory Function
885
+ // ============================================================================
886
+ /**
887
+ * Create a new ClassNamingDetector instance
888
+ */
889
+ export function createClassNamingDetector() {
890
+ return new ClassNamingDetector();
891
+ }
892
+ //# sourceMappingURL=class-naming.js.map