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,732 @@
1
+ /**
2
+ * Color Usage Detector - Color pattern detection
3
+ *
4
+ * Detects color usage patterns including:
5
+ * - CSS custom properties for colors (--color-*, var(--color-*))
6
+ * - Theme color objects (theme.colors.*, colors.primary, etc.)
7
+ * - Tailwind color classes (text-blue-500, bg-red-100, border-gray-300, etc.)
8
+ * - Named CSS colors (red, blue, green, etc.)
9
+ *
10
+ * Flags hardcoded color values:
11
+ * - Hex colors (#fff, #ffffff, #ffffffff)
12
+ * - RGB colors (rgb(255, 255, 255))
13
+ * - RGBA colors (rgba(255, 255, 255, 0.5))
14
+ * - HSL colors (hsl(0, 0%, 100%))
15
+ * - HSLA colors (hsla(0, 0%, 100%, 0.5))
16
+ *
17
+ * @requirements 9.3 - THE Styling_Detector SHALL detect color usage patterns (system colors vs hex)
18
+ */
19
+ import { RegexDetector } from '../base/index.js';
20
+ // ============================================================================
21
+ // Constants
22
+ // ============================================================================
23
+ /**
24
+ * Regex pattern for CSS custom properties for colors
25
+ */
26
+ export const CSS_COLOR_PROPERTY_PATTERN = /var\(\s*--(?:color|clr|c)[-_]?([a-zA-Z0-9_-]*)\s*(?:,\s*[^)]+)?\)/g;
27
+ /**
28
+ * Regex patterns for theme color object usage
29
+ */
30
+ export const THEME_COLOR_PATTERNS = [
31
+ // theme.colors.*, theme.color.*
32
+ /theme\.colors?\.([a-zA-Z0-9_.[\]]+)/g,
33
+ // ${theme.colors.*} in template literals
34
+ /\$\{theme\.colors?\.([a-zA-Z0-9_.[\]]+)\}/g,
35
+ // props.theme.colors.*
36
+ /props\.theme\.colors?\.([a-zA-Z0-9_.[\]]+)/g,
37
+ // colors.primary, colors.secondary, etc. (standalone color object)
38
+ /\bcolors\.([a-zA-Z0-9_.[\]]+)/g,
39
+ ];
40
+ /**
41
+ * Tailwind color class patterns
42
+ */
43
+ export const TAILWIND_COLOR_PATTERNS = [
44
+ // Text colors: text-red-500, text-blue-100
45
+ /\btext-(?: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,
46
+ // Background colors: bg-red-500, bg-blue-100
47
+ /\bbg-(?: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,
48
+ // Border colors: border-red-500, border-blue-100
49
+ /\bborder-(?: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,
50
+ // Ring colors: ring-red-500, ring-blue-100
51
+ /\bring-(?: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,
52
+ // Divide colors: divide-red-500, divide-blue-100
53
+ /\bdivide-(?: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,
54
+ // Outline colors: outline-red-500, outline-blue-100
55
+ /\boutline-(?: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,
56
+ // Fill colors: fill-red-500, fill-blue-100
57
+ /\bfill-(?: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,
58
+ // Stroke colors: stroke-red-500, stroke-blue-100
59
+ /\bstroke-(?: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,
60
+ // Accent colors: accent-red-500, accent-blue-100
61
+ /\baccent-(?: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,
62
+ // Caret colors: caret-red-500, caret-blue-100
63
+ /\bcaret-(?: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,
64
+ // Shadow colors: shadow-red-500, shadow-blue-100
65
+ /\bshadow-(?: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,
66
+ // Decoration colors: decoration-red-500, decoration-blue-100
67
+ /\bdecoration-(?: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,
68
+ ];
69
+ /**
70
+ * Regex patterns for hardcoded color values
71
+ */
72
+ export const HARDCODED_COLOR_PATTERNS = {
73
+ // Hex colors: #fff, #ffffff, #ffffffff (with alpha)
74
+ hex: /#(?:[0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})\b/g,
75
+ // RGB colors: rgb(255, 255, 255)
76
+ rgb: /rgb\(\s*\d{1,3}\s*,\s*\d{1,3}\s*,\s*\d{1,3}\s*\)/gi,
77
+ // RGBA colors: rgba(255, 255, 255, 0.5)
78
+ rgba: /rgba\(\s*\d{1,3}\s*,\s*\d{1,3}\s*,\s*\d{1,3}\s*,\s*[\d.]+\s*\)/gi,
79
+ // HSL colors: hsl(0, 0%, 100%)
80
+ hsl: /hsl\(\s*\d{1,3}\s*,\s*\d{1,3}%\s*,\s*\d{1,3}%\s*\)/gi,
81
+ // HSLA colors: hsla(0, 0%, 100%, 0.5)
82
+ hsla: /hsla\(\s*\d{1,3}\s*,\s*\d{1,3}%\s*,\s*\d{1,3}%\s*,\s*[\d.]+\s*\)/gi,
83
+ };
84
+ /**
85
+ * Named CSS colors to detect
86
+ */
87
+ export const NAMED_CSS_COLORS = [
88
+ 'aliceblue', 'antiquewhite', 'aqua', 'aquamarine', 'azure',
89
+ 'beige', 'bisque', 'blanchedalmond', 'blue', 'blueviolet',
90
+ 'brown', 'burlywood', 'cadetblue', 'chartreuse', 'chocolate',
91
+ 'coral', 'cornflowerblue', 'cornsilk', 'crimson', 'cyan',
92
+ 'darkblue', 'darkcyan', 'darkgoldenrod', 'darkgray', 'darkgreen',
93
+ 'darkgrey', 'darkkhaki', 'darkmagenta', 'darkolivegreen', 'darkorange',
94
+ 'darkorchid', 'darkred', 'darksalmon', 'darkseagreen', 'darkslateblue',
95
+ 'darkslategray', 'darkslategrey', 'darkturquoise', 'darkviolet', 'deeppink',
96
+ 'deepskyblue', 'dimgray', 'dimgrey', 'dodgerblue', 'firebrick',
97
+ 'floralwhite', 'forestgreen', 'fuchsia', 'gainsboro', 'ghostwhite',
98
+ 'gold', 'goldenrod', 'gray', 'green', 'greenyellow',
99
+ 'grey', 'honeydew', 'hotpink', 'indianred', 'indigo',
100
+ 'ivory', 'khaki', 'lavender', 'lavenderblush', 'lawngreen',
101
+ 'lemonchiffon', 'lightblue', 'lightcoral', 'lightcyan', 'lightgoldenrodyellow',
102
+ 'lightgray', 'lightgreen', 'lightgrey', 'lightpink', 'lightsalmon',
103
+ 'lightseagreen', 'lightskyblue', 'lightslategray', 'lightslategrey', 'lightsteelblue',
104
+ 'lightyellow', 'lime', 'limegreen', 'linen', 'magenta',
105
+ 'maroon', 'mediumaquamarine', 'mediumblue', 'mediumorchid', 'mediumpurple',
106
+ 'mediumseagreen', 'mediumslateblue', 'mediumspringgreen', 'mediumturquoise', 'mediumvioletred',
107
+ 'midnightblue', 'mintcream', 'mistyrose', 'moccasin', 'navajowhite',
108
+ 'navy', 'oldlace', 'olive', 'olivedrab', 'orange',
109
+ 'orangered', 'orchid', 'palegoldenrod', 'palegreen', 'paleturquoise',
110
+ 'palevioletred', 'papayawhip', 'peachpuff', 'peru', 'pink',
111
+ 'plum', 'powderblue', 'purple', 'rebeccapurple', 'red',
112
+ 'rosybrown', 'royalblue', 'saddlebrown', 'salmon', 'sandybrown',
113
+ 'seagreen', 'seashell', 'sienna', 'silver', 'skyblue',
114
+ 'slateblue', 'slategray', 'slategrey', 'snow', 'springgreen',
115
+ 'steelblue', 'tan', 'teal', 'thistle', 'tomato',
116
+ 'turquoise', 'violet', 'wheat', 'whitesmoke', 'yellow', 'yellowgreen',
117
+ ];
118
+ /**
119
+ * CSS properties that commonly use color values
120
+ */
121
+ export const COLOR_PROPERTIES = [
122
+ 'color',
123
+ 'background-color',
124
+ 'background',
125
+ 'border-color',
126
+ 'border',
127
+ 'border-top-color',
128
+ 'border-right-color',
129
+ 'border-bottom-color',
130
+ 'border-left-color',
131
+ 'outline-color',
132
+ 'outline',
133
+ 'fill',
134
+ 'stroke',
135
+ 'box-shadow',
136
+ 'text-shadow',
137
+ 'text-decoration-color',
138
+ 'caret-color',
139
+ 'accent-color',
140
+ 'column-rule-color',
141
+ ];
142
+ /**
143
+ * Allowed hardcoded color values (common exceptions)
144
+ * Note: Values are stored in lowercase for case-insensitive comparison
145
+ */
146
+ export const ALLOWED_HARDCODED_COLORS = new Set([
147
+ 'transparent',
148
+ 'currentcolor',
149
+ 'inherit',
150
+ 'initial',
151
+ 'unset',
152
+ '#000',
153
+ '#000000',
154
+ '#fff',
155
+ '#ffffff',
156
+ 'black',
157
+ 'white',
158
+ ]);
159
+ /**
160
+ * File patterns to exclude from hardcoded color detection
161
+ */
162
+ export const EXCLUDED_FILE_PATTERNS = [
163
+ /\.test\.[jt]sx?$/,
164
+ /\.spec\.[jt]sx?$/,
165
+ /\.stories\.[jt]sx?$/,
166
+ /design-tokens?\//,
167
+ /tokens?\//,
168
+ /theme\//,
169
+ /\.config\.[jt]s$/,
170
+ /tailwind\.config/,
171
+ /colors?\.[jt]s$/,
172
+ /palette\.[jt]s$/,
173
+ ];
174
+ // ============================================================================
175
+ // Helper Functions
176
+ // ============================================================================
177
+ /**
178
+ * Check if a file should be excluded from hardcoded color detection
179
+ */
180
+ export function shouldExcludeFile(filePath) {
181
+ return EXCLUDED_FILE_PATTERNS.some(pattern => pattern.test(filePath));
182
+ }
183
+ /**
184
+ * Check if a value is in the allowed hardcoded colors list
185
+ */
186
+ export function isAllowedHardcodedColor(value) {
187
+ return ALLOWED_HARDCODED_COLORS.has(value.toLowerCase().trim());
188
+ }
189
+ /**
190
+ * Check if a position is inside a comment
191
+ */
192
+ function isInsideComment(content, index) {
193
+ const beforeIndex = content.slice(0, index);
194
+ // Check for single-line comment
195
+ const lastNewline = beforeIndex.lastIndexOf('\n');
196
+ const currentLine = beforeIndex.slice(lastNewline + 1);
197
+ if (currentLine.includes('//')) {
198
+ const commentStart = currentLine.indexOf('//');
199
+ const positionInLine = index - lastNewline - 1;
200
+ if (positionInLine > commentStart) {
201
+ return true;
202
+ }
203
+ }
204
+ // Check for multi-line comment
205
+ const lastBlockCommentStart = beforeIndex.lastIndexOf('/*');
206
+ const lastBlockCommentEnd = beforeIndex.lastIndexOf('*/');
207
+ if (lastBlockCommentStart > lastBlockCommentEnd) {
208
+ return true;
209
+ }
210
+ return false;
211
+ }
212
+ /**
213
+ * Extract CSS property name from a line
214
+ */
215
+ function extractCSSProperty(line) {
216
+ // Match CSS property: property-name: value
217
+ const cssMatch = line.match(/([a-zA-Z-]+)\s*:/);
218
+ if (cssMatch && cssMatch[1]) {
219
+ return cssMatch[1];
220
+ }
221
+ // Match JS object property: propertyName: value
222
+ const jsMatch = line.match(/([a-zA-Z]+)\s*:/);
223
+ if (jsMatch && jsMatch[1]) {
224
+ // Convert camelCase to kebab-case
225
+ return jsMatch[1].replace(/([A-Z])/g, '-$1').toLowerCase();
226
+ }
227
+ return undefined;
228
+ }
229
+ /**
230
+ * Detect CSS custom property usage for colors
231
+ */
232
+ export function detectCSSColorProperties(content, file) {
233
+ const results = [];
234
+ const lines = content.split('\n');
235
+ const regex = new RegExp(CSS_COLOR_PROPERTY_PATTERN.source, CSS_COLOR_PROPERTY_PATTERN.flags);
236
+ let match;
237
+ while ((match = regex.exec(content)) !== null) {
238
+ const beforeMatch = content.slice(0, match.index);
239
+ const lineNumber = beforeMatch.split('\n').length;
240
+ const lastNewline = beforeMatch.lastIndexOf('\n');
241
+ const column = match.index - lastNewline;
242
+ results.push({
243
+ type: 'css-color-property',
244
+ file,
245
+ line: lineNumber,
246
+ column,
247
+ matchedText: match[0],
248
+ colorName: match[1] || '',
249
+ context: lines[lineNumber - 1] || '',
250
+ });
251
+ }
252
+ return results;
253
+ }
254
+ /**
255
+ * Detect theme color object usage
256
+ */
257
+ export function detectThemeColors(content, file) {
258
+ const results = [];
259
+ const lines = content.split('\n');
260
+ for (const pattern of THEME_COLOR_PATTERNS) {
261
+ const regex = new RegExp(pattern.source, pattern.flags);
262
+ let match;
263
+ while ((match = regex.exec(content)) !== null) {
264
+ const beforeMatch = content.slice(0, match.index);
265
+ const lineNumber = beforeMatch.split('\n').length;
266
+ const lastNewline = beforeMatch.lastIndexOf('\n');
267
+ const column = match.index - lastNewline;
268
+ results.push({
269
+ type: 'theme-color',
270
+ file,
271
+ line: lineNumber,
272
+ column,
273
+ matchedText: match[0],
274
+ colorName: match[1] || match[0],
275
+ context: lines[lineNumber - 1] || '',
276
+ });
277
+ }
278
+ }
279
+ return results;
280
+ }
281
+ /**
282
+ * Detect Tailwind color classes
283
+ */
284
+ export function detectTailwindColors(content, file) {
285
+ const results = [];
286
+ const lines = content.split('\n');
287
+ for (const pattern of TAILWIND_COLOR_PATTERNS) {
288
+ const regex = new RegExp(pattern.source, pattern.flags);
289
+ let match;
290
+ while ((match = regex.exec(content)) !== null) {
291
+ const beforeMatch = content.slice(0, match.index);
292
+ const lineNumber = beforeMatch.split('\n').length;
293
+ const lastNewline = beforeMatch.lastIndexOf('\n');
294
+ const column = match.index - lastNewline;
295
+ results.push({
296
+ type: 'tailwind-color',
297
+ file,
298
+ line: lineNumber,
299
+ column,
300
+ matchedText: match[0],
301
+ colorName: match[0],
302
+ context: lines[lineNumber - 1] || '',
303
+ });
304
+ }
305
+ }
306
+ return results;
307
+ }
308
+ /**
309
+ * Detect named CSS colors
310
+ */
311
+ export function detectNamedCSSColors(content, file) {
312
+ const results = [];
313
+ const lines = content.split('\n');
314
+ // Create a pattern that matches named colors as whole words in CSS context
315
+ const colorPattern = new RegExp(`\\b(${NAMED_CSS_COLORS.join('|')})\\b(?=\\s*[;,})])`, 'gi');
316
+ let match;
317
+ while ((match = colorPattern.exec(content)) !== null) {
318
+ const colorName = match[1]?.toLowerCase() || '';
319
+ // Skip black and white as they're allowed
320
+ if (colorName === 'black' || colorName === 'white') {
321
+ continue;
322
+ }
323
+ // Skip if inside a comment
324
+ if (isInsideComment(content, match.index)) {
325
+ continue;
326
+ }
327
+ const beforeMatch = content.slice(0, match.index);
328
+ const lineNumber = beforeMatch.split('\n').length;
329
+ const lastNewline = beforeMatch.lastIndexOf('\n');
330
+ const column = match.index - lastNewline;
331
+ results.push({
332
+ type: 'named-css-color',
333
+ file,
334
+ line: lineNumber,
335
+ column,
336
+ matchedText: match[0],
337
+ colorName: colorName,
338
+ context: lines[lineNumber - 1] || '',
339
+ });
340
+ }
341
+ return results;
342
+ }
343
+ /**
344
+ * Detect hardcoded color values
345
+ */
346
+ export function detectHardcodedColors(content, file) {
347
+ const results = [];
348
+ const lines = content.split('\n');
349
+ // Check each color pattern type
350
+ const colorPatterns = [
351
+ { pattern: HARDCODED_COLOR_PATTERNS.hex, type: 'color-hex' },
352
+ { pattern: HARDCODED_COLOR_PATTERNS.rgb, type: 'color-rgb' },
353
+ { pattern: HARDCODED_COLOR_PATTERNS.rgba, type: 'color-rgba' },
354
+ { pattern: HARDCODED_COLOR_PATTERNS.hsl, type: 'color-hsl' },
355
+ { pattern: HARDCODED_COLOR_PATTERNS.hsla, type: 'color-hsla' },
356
+ ];
357
+ for (const { pattern, type } of colorPatterns) {
358
+ const regex = new RegExp(pattern.source, pattern.flags);
359
+ let match;
360
+ while ((match = regex.exec(content)) !== null) {
361
+ const value = match[0];
362
+ // Skip allowed values
363
+ if (isAllowedHardcodedColor(value)) {
364
+ continue;
365
+ }
366
+ // Skip if inside a CSS custom property definition
367
+ const beforeMatch = content.slice(0, match.index);
368
+ const lineNumber = beforeMatch.split('\n').length;
369
+ const lineContent = lines[lineNumber - 1] || '';
370
+ // Skip CSS custom property definitions (--color-name: #fff)
371
+ if (/^\s*--[a-zA-Z0-9_-]+\s*:/.test(lineContent)) {
372
+ continue;
373
+ }
374
+ // Skip if inside a comment
375
+ if (isInsideComment(content, match.index)) {
376
+ continue;
377
+ }
378
+ const lastNewline = beforeMatch.lastIndexOf('\n');
379
+ const column = match.index - lastNewline;
380
+ const endColumn = column + value.length;
381
+ const property = extractCSSProperty(lineContent);
382
+ const hardcodedInfo = {
383
+ type,
384
+ file,
385
+ line: lineNumber,
386
+ column,
387
+ endLine: lineNumber,
388
+ endColumn,
389
+ value,
390
+ suggestedToken: suggestColorToken(value),
391
+ lineContent,
392
+ };
393
+ if (property !== undefined) {
394
+ hardcodedInfo.property = property;
395
+ }
396
+ results.push(hardcodedInfo);
397
+ }
398
+ }
399
+ return results;
400
+ }
401
+ /**
402
+ * Suggest a color token for a hardcoded color value
403
+ */
404
+ export function suggestColorToken(value) {
405
+ // Normalize the value
406
+ const normalized = value.toLowerCase();
407
+ // Common color mappings based on hex values
408
+ if (normalized === '#000' || normalized === '#000000') {
409
+ return 'colors.black or --color-black';
410
+ }
411
+ if (normalized === '#fff' || normalized === '#ffffff') {
412
+ return 'colors.white or --color-white';
413
+ }
414
+ // Try to identify color family from hex
415
+ if (normalized.startsWith('#')) {
416
+ const colorFamily = identifyColorFamily(normalized);
417
+ if (colorFamily) {
418
+ return `colors.${colorFamily} or --color-${colorFamily}`;
419
+ }
420
+ }
421
+ // Generic suggestion
422
+ return 'Use a design token from your color palette (e.g., colors.primary, --color-primary)';
423
+ }
424
+ /**
425
+ * Identify color family from hex value
426
+ */
427
+ function identifyColorFamily(hex) {
428
+ // Normalize to 6-digit hex
429
+ let normalizedHex = hex.toLowerCase().replace('#', '');
430
+ if (normalizedHex.length === 3) {
431
+ normalizedHex = normalizedHex.split('').map(c => c + c).join('');
432
+ }
433
+ if (normalizedHex.length === 8) {
434
+ normalizedHex = normalizedHex.slice(0, 6);
435
+ }
436
+ const r = parseInt(normalizedHex.slice(0, 2), 16);
437
+ const g = parseInt(normalizedHex.slice(2, 4), 16);
438
+ const b = parseInt(normalizedHex.slice(4, 6), 16);
439
+ // Simple heuristics for color family identification
440
+ if (r > 200 && g < 100 && b < 100)
441
+ return 'red';
442
+ if (r < 100 && g > 200 && b < 100)
443
+ return 'green';
444
+ if (r < 100 && g < 100 && b > 200)
445
+ return 'blue';
446
+ if (r > 200 && g > 200 && b < 100)
447
+ return 'yellow';
448
+ if (r > 200 && g < 150 && b > 200)
449
+ return 'pink';
450
+ if (r > 200 && g > 100 && b < 100)
451
+ return 'orange';
452
+ if (r > 100 && g < 100 && b > 200)
453
+ return 'purple';
454
+ if (r < 100 && g > 200 && b > 200)
455
+ return 'cyan';
456
+ if (Math.abs(r - g) < 30 && Math.abs(g - b) < 30 && Math.abs(r - b) < 30) {
457
+ if (r < 50)
458
+ return 'black';
459
+ if (r > 200)
460
+ return 'white';
461
+ return 'gray';
462
+ }
463
+ return null;
464
+ }
465
+ /**
466
+ * Analyze color usage patterns in a file
467
+ */
468
+ export function analyzeColorUsage(content, file) {
469
+ // Skip excluded files for hardcoded color detection
470
+ const skipHardcodedDetection = shouldExcludeFile(file);
471
+ // Detect color patterns
472
+ const cssColorProperties = detectCSSColorProperties(content, file);
473
+ const themeColors = detectThemeColors(content, file);
474
+ const tailwindColors = detectTailwindColors(content, file);
475
+ const namedCSSColors = detectNamedCSSColors(content, file);
476
+ const colorPatterns = [
477
+ ...cssColorProperties,
478
+ ...themeColors,
479
+ ...tailwindColors,
480
+ ...namedCSSColors,
481
+ ];
482
+ // Detect hardcoded colors (unless file is excluded)
483
+ let hardcodedColors = [];
484
+ if (!skipHardcodedDetection) {
485
+ hardcodedColors = detectHardcodedColors(content, file);
486
+ }
487
+ // Calculate confidence
488
+ const hasColorPatterns = colorPatterns.length > 0;
489
+ const hasHardcodedColors = hardcodedColors.length > 0;
490
+ let colorTokenConfidence = 0;
491
+ if (hasColorPatterns && !hasHardcodedColors) {
492
+ colorTokenConfidence = 1.0;
493
+ }
494
+ else if (hasColorPatterns && hasHardcodedColors) {
495
+ const ratio = colorPatterns.length / (colorPatterns.length + hardcodedColors.length);
496
+ colorTokenConfidence = ratio;
497
+ }
498
+ else if (!hasColorPatterns && hasHardcodedColors) {
499
+ colorTokenConfidence = 0;
500
+ }
501
+ else {
502
+ colorTokenConfidence = 0.5; // No color styling detected
503
+ }
504
+ return {
505
+ colorPatterns,
506
+ hardcodedColors,
507
+ usesCSSColorProperties: cssColorProperties.length > 0,
508
+ usesThemeColors: themeColors.length > 0,
509
+ usesTailwindColors: tailwindColors.length > 0,
510
+ colorTokenConfidence,
511
+ };
512
+ }
513
+ // ============================================================================
514
+ // Color Usage Detector Class
515
+ // ============================================================================
516
+ /**
517
+ * Detector for color usage patterns
518
+ *
519
+ * Identifies color token usage and flags hardcoded color values that should
520
+ * use design tokens instead.
521
+ *
522
+ * @requirements 9.3 - THE Styling_Detector SHALL detect color usage patterns (system colors vs hex)
523
+ */
524
+ export class ColorUsageDetector extends RegexDetector {
525
+ id = 'styling/color-usage';
526
+ category = 'styling';
527
+ subcategory = 'color-usage';
528
+ name = 'Color Usage Detector';
529
+ description = 'Detects color usage patterns and flags hardcoded color values that should use design tokens';
530
+ supportedLanguages = ['typescript', 'javascript', 'css'];
531
+ /**
532
+ * Detect color patterns and violations
533
+ */
534
+ async detect(context) {
535
+ const patterns = [];
536
+ const violations = [];
537
+ // Analyze the file
538
+ const analysis = analyzeColorUsage(context.content, context.file);
539
+ // Create pattern matches for color usages
540
+ if (analysis.usesCSSColorProperties) {
541
+ patterns.push(this.createCSSColorPropertyPattern(context.file, analysis));
542
+ }
543
+ if (analysis.usesThemeColors) {
544
+ patterns.push(this.createThemeColorPattern(context.file, analysis));
545
+ }
546
+ if (analysis.usesTailwindColors) {
547
+ patterns.push(this.createTailwindColorPattern(context.file, analysis));
548
+ }
549
+ // Create violations for hardcoded colors
550
+ for (const hardcoded of analysis.hardcodedColors) {
551
+ violations.push(this.createHardcodedColorViolation(hardcoded));
552
+ }
553
+ return this.createResult(patterns, violations, analysis.colorTokenConfidence);
554
+ }
555
+ /**
556
+ * Create a pattern match for CSS color property usage
557
+ */
558
+ createCSSColorPropertyPattern(file, analysis) {
559
+ const cssPatterns = analysis.colorPatterns.filter(p => p.type === 'css-color-property');
560
+ const firstPattern = cssPatterns[0];
561
+ return {
562
+ patternId: `${this.id}/css-color-property`,
563
+ location: {
564
+ file,
565
+ line: firstPattern?.line || 1,
566
+ column: firstPattern?.column || 1,
567
+ },
568
+ confidence: 1.0,
569
+ isOutlier: false,
570
+ };
571
+ }
572
+ /**
573
+ * Create a pattern match for theme color usage
574
+ */
575
+ createThemeColorPattern(file, analysis) {
576
+ const themePatterns = analysis.colorPatterns.filter(p => p.type === 'theme-color');
577
+ const firstPattern = themePatterns[0];
578
+ return {
579
+ patternId: `${this.id}/theme-color`,
580
+ location: {
581
+ file,
582
+ line: firstPattern?.line || 1,
583
+ column: firstPattern?.column || 1,
584
+ },
585
+ confidence: 1.0,
586
+ isOutlier: false,
587
+ };
588
+ }
589
+ /**
590
+ * Create a pattern match for Tailwind color usage
591
+ */
592
+ createTailwindColorPattern(file, analysis) {
593
+ const tailwindPatterns = analysis.colorPatterns.filter(p => p.type === 'tailwind-color');
594
+ const firstPattern = tailwindPatterns[0];
595
+ return {
596
+ patternId: `${this.id}/tailwind-color`,
597
+ location: {
598
+ file,
599
+ line: firstPattern?.line || 1,
600
+ column: firstPattern?.column || 1,
601
+ },
602
+ confidence: 1.0,
603
+ isOutlier: false,
604
+ };
605
+ }
606
+ /**
607
+ * Create a violation for a hardcoded color value
608
+ */
609
+ createHardcodedColorViolation(hardcoded) {
610
+ const typeDescriptions = {
611
+ 'color-hex': 'hex color',
612
+ 'color-rgb': 'RGB color',
613
+ 'color-rgba': 'RGBA color',
614
+ 'color-hsl': 'HSL color',
615
+ 'color-hsla': 'HSLA color',
616
+ };
617
+ const typeDescription = typeDescriptions[hardcoded.type] || 'hardcoded color';
618
+ const propertyInfo = hardcoded.property ? ` in '${hardcoded.property}'` : '';
619
+ const violation = {
620
+ id: `${this.id}-${hardcoded.file}-${hardcoded.line}-${hardcoded.column}`,
621
+ patternId: this.id,
622
+ severity: 'warning',
623
+ file: hardcoded.file,
624
+ range: {
625
+ start: { line: hardcoded.line - 1, character: hardcoded.column - 1 },
626
+ end: { line: hardcoded.endLine - 1, character: hardcoded.endColumn - 1 },
627
+ },
628
+ message: `Hardcoded ${typeDescription} '${hardcoded.value}'${propertyInfo} should use a color token`,
629
+ explanation: `Using hardcoded color values instead of design tokens makes it difficult to maintain consistent colors across the application. Color tokens provide a single source of truth for your color palette.`,
630
+ expected: hardcoded.suggestedToken || 'A color token',
631
+ actual: hardcoded.value,
632
+ aiExplainAvailable: true,
633
+ aiFixAvailable: true,
634
+ firstSeen: new Date(),
635
+ occurrences: 1,
636
+ };
637
+ const quickFix = this.createQuickFixForHardcodedColor(hardcoded);
638
+ if (quickFix !== undefined) {
639
+ violation.quickFix = quickFix;
640
+ }
641
+ return violation;
642
+ }
643
+ /**
644
+ * Create a quick fix for replacing a hardcoded color with a token
645
+ */
646
+ createQuickFixForHardcodedColor(hardcoded) {
647
+ // Only provide quick fix if we have a suggested token
648
+ if (!hardcoded.suggestedToken) {
649
+ return undefined;
650
+ }
651
+ // Extract the first suggested token (before "or")
652
+ const suggestedToken = hardcoded.suggestedToken.split(' or ')[0] || hardcoded.suggestedToken;
653
+ // Determine the replacement based on context
654
+ let replacement;
655
+ if (hardcoded.lineContent.includes('var(')) {
656
+ // Already using CSS custom properties, suggest a different custom property
657
+ replacement = `var(--${suggestedToken.replace(/\./g, '-').replace('colors', 'color')})`;
658
+ }
659
+ else if (hardcoded.lineContent.includes('${') || hardcoded.lineContent.includes('`')) {
660
+ // Template literal context (styled-components, emotion)
661
+ replacement = `\${${suggestedToken}}`;
662
+ }
663
+ else {
664
+ // Default: suggest the token directly
665
+ replacement = suggestedToken;
666
+ }
667
+ return {
668
+ title: `Replace with color token: ${suggestedToken}`,
669
+ kind: 'quickfix',
670
+ edit: {
671
+ changes: {
672
+ [hardcoded.file]: [
673
+ {
674
+ range: {
675
+ start: { line: hardcoded.line - 1, character: hardcoded.column - 1 },
676
+ end: { line: hardcoded.endLine - 1, character: hardcoded.endColumn - 1 },
677
+ },
678
+ newText: replacement,
679
+ },
680
+ ],
681
+ },
682
+ },
683
+ isPreferred: true,
684
+ confidence: 0.7,
685
+ preview: `Replace '${hardcoded.value}' with '${replacement}'`,
686
+ };
687
+ }
688
+ /**
689
+ * Generate a quick fix for a violation
690
+ */
691
+ generateQuickFix(violation) {
692
+ // Check if this is a hardcoded color violation
693
+ if (!violation.message.includes('Hardcoded') || !violation.message.includes('color')) {
694
+ return null;
695
+ }
696
+ // Extract the value from the message
697
+ const valueMatch = violation.message.match(/Hardcoded [^']+ '([^']+)'/);
698
+ if (!valueMatch || !valueMatch[1]) {
699
+ return null;
700
+ }
701
+ const value = valueMatch[1];
702
+ const suggestedToken = suggestColorToken(value);
703
+ const firstSuggestion = suggestedToken.split(' or ')[0] || suggestedToken;
704
+ return {
705
+ title: `Replace with color token: ${firstSuggestion}`,
706
+ kind: 'quickfix',
707
+ edit: {
708
+ changes: {
709
+ [violation.file]: [
710
+ {
711
+ range: violation.range,
712
+ newText: firstSuggestion,
713
+ },
714
+ ],
715
+ },
716
+ },
717
+ isPreferred: true,
718
+ confidence: 0.7,
719
+ preview: `Replace '${value}' with '${firstSuggestion}'`,
720
+ };
721
+ }
722
+ }
723
+ // ============================================================================
724
+ // Factory Function
725
+ // ============================================================================
726
+ /**
727
+ * Create a new ColorUsageDetector instance
728
+ */
729
+ export function createColorUsageDetector() {
730
+ return new ColorUsageDetector();
731
+ }
732
+ //# sourceMappingURL=color-usage.js.map