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,748 @@
1
+ /**
2
+ * Design Tokens Detector - Token usage detection
3
+ *
4
+ * Detects design token usage patterns including:
5
+ * - Imports from design-tokens/ directory
6
+ * - CSS custom properties (--token-name)
7
+ * - Theme object usage (theme.colors, theme.spacing, etc.)
8
+ * - Token variable usage in styled-components, emotion, etc.
9
+ *
10
+ * Flags hardcoded values that should use design tokens:
11
+ * - Hardcoded colors (hex, rgb, hsl)
12
+ * - Hardcoded spacing values (px, rem, em)
13
+ * - Hardcoded font sizes
14
+ * - Hardcoded border radius
15
+ *
16
+ * @requirements 9.1 - THE Styling_Detector SHALL detect design token usage vs hardcoded values
17
+ */
18
+ import { RegexDetector } from '../base/index.js';
19
+ // ============================================================================
20
+ // Constants
21
+ // ============================================================================
22
+ /**
23
+ * Regex patterns for detecting design token imports
24
+ */
25
+ export const DESIGN_TOKEN_IMPORT_PATTERNS = [
26
+ // Import from design-tokens directory
27
+ /import\s+(?:\{[^}]+\}|\*\s+as\s+\w+|\w+)\s+from\s+['"](?:@\/|\.\.?\/)*design-tokens(?:\/[^'"]*)?['"]/g,
28
+ // Import from tokens directory
29
+ /import\s+(?:\{[^}]+\}|\*\s+as\s+\w+|\w+)\s+from\s+['"](?:@\/|\.\.?\/)*tokens(?:\/[^'"]*)?['"]/g,
30
+ // Import from theme directory
31
+ /import\s+(?:\{[^}]+\}|\*\s+as\s+\w+|\w+)\s+from\s+['"](?:@\/|\.\.?\/)*theme(?:\/[^'"]*)?['"]/g,
32
+ // Import from styles/tokens
33
+ /import\s+(?:\{[^}]+\}|\*\s+as\s+\w+|\w+)\s+from\s+['"](?:@\/|\.\.?\/)*styles\/tokens(?:\/[^'"]*)?['"]/g,
34
+ ];
35
+ /**
36
+ * Regex pattern for CSS custom properties
37
+ */
38
+ export const CSS_CUSTOM_PROPERTY_PATTERN = /var\(\s*--([a-zA-Z0-9_-]+)\s*(?:,\s*[^)]+)?\)/g;
39
+ /**
40
+ * Regex patterns for theme object usage
41
+ */
42
+ export const THEME_OBJECT_PATTERNS = [
43
+ // theme.colors.*, theme.spacing.*, etc.
44
+ /theme\.(?:colors?|spacing|typography|fontSizes?|borderRadius|shadows?|zIndex|breakpoints?)\.[a-zA-Z0-9_.[\]]+/g,
45
+ // ${theme.colors.*} in template literals
46
+ /\$\{theme\.(?:colors?|spacing|typography|fontSizes?|borderRadius|shadows?|zIndex|breakpoints?)\.[a-zA-Z0-9_.[\]]+\}/g,
47
+ // props.theme.* pattern
48
+ /props\.theme\.(?:colors?|spacing|typography|fontSizes?|borderRadius|shadows?|zIndex|breakpoints?)\.[a-zA-Z0-9_.[\]]+/g,
49
+ ];
50
+ /**
51
+ * Regex patterns for hardcoded color values
52
+ */
53
+ export const HARDCODED_COLOR_PATTERNS = {
54
+ // Hex colors: #fff, #ffffff, #ffffffff (with alpha)
55
+ hex: /#(?:[0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})\b/g,
56
+ // RGB colors: rgb(255, 255, 255)
57
+ rgb: /rgb\(\s*\d{1,3}\s*,\s*\d{1,3}\s*,\s*\d{1,3}\s*\)/gi,
58
+ // RGBA colors: rgba(255, 255, 255, 0.5)
59
+ rgba: /rgba\(\s*\d{1,3}\s*,\s*\d{1,3}\s*,\s*\d{1,3}\s*,\s*[\d.]+\s*\)/gi,
60
+ // HSL colors: hsl(0, 0%, 100%)
61
+ hsl: /hsl\(\s*\d{1,3}\s*,\s*\d{1,3}%\s*,\s*\d{1,3}%\s*\)/gi,
62
+ // HSLA colors: hsla(0, 0%, 100%, 0.5)
63
+ hsla: /hsla\(\s*\d{1,3}\s*,\s*\d{1,3}%\s*,\s*\d{1,3}%\s*,\s*[\d.]+\s*\)/gi,
64
+ };
65
+ /**
66
+ * Regex patterns for hardcoded spacing values
67
+ */
68
+ export const HARDCODED_SPACING_PATTERNS = {
69
+ // Pixel values: 10px, 20px (excluding 0px and 1px which are often intentional)
70
+ px: /(?<![a-zA-Z0-9_-])(?:[2-9]|[1-9]\d+)px\b/g,
71
+ // Rem values: 1rem, 2rem (excluding common values like 0rem)
72
+ rem: /(?<![a-zA-Z0-9_-])(?:0?\.\d+|\d+(?:\.\d+)?)rem\b/g,
73
+ // Em values: 1em, 2em
74
+ em: /(?<![a-zA-Z0-9_-])(?:0?\.\d+|\d+(?:\.\d+)?)em\b/g,
75
+ };
76
+ /**
77
+ * CSS properties that commonly use design tokens
78
+ */
79
+ export const TOKEN_PROPERTIES = [
80
+ // Color properties
81
+ 'color',
82
+ 'background-color',
83
+ 'background',
84
+ 'border-color',
85
+ 'border',
86
+ 'outline-color',
87
+ 'fill',
88
+ 'stroke',
89
+ 'box-shadow',
90
+ 'text-shadow',
91
+ // Spacing properties
92
+ 'margin',
93
+ 'margin-top',
94
+ 'margin-right',
95
+ 'margin-bottom',
96
+ 'margin-left',
97
+ 'padding',
98
+ 'padding-top',
99
+ 'padding-right',
100
+ 'padding-bottom',
101
+ 'padding-left',
102
+ 'gap',
103
+ 'row-gap',
104
+ 'column-gap',
105
+ // Typography properties
106
+ 'font-size',
107
+ 'line-height',
108
+ 'letter-spacing',
109
+ // Border properties
110
+ 'border-radius',
111
+ 'border-width',
112
+ // Z-index
113
+ 'z-index',
114
+ ];
115
+ /**
116
+ * Allowed hardcoded values (common exceptions)
117
+ * Note: Values are stored in lowercase for case-insensitive comparison
118
+ */
119
+ export const ALLOWED_HARDCODED_VALUES = new Set([
120
+ '0',
121
+ '0px',
122
+ '1px',
123
+ '100%',
124
+ 'inherit',
125
+ 'initial',
126
+ 'unset',
127
+ 'auto',
128
+ 'none',
129
+ 'transparent',
130
+ 'currentcolor', // lowercase for case-insensitive comparison
131
+ '#000',
132
+ '#000000',
133
+ '#fff',
134
+ '#ffffff',
135
+ 'black',
136
+ 'white',
137
+ ]);
138
+ /**
139
+ * File patterns to exclude from hardcoded value detection
140
+ */
141
+ export const EXCLUDED_FILE_PATTERNS = [
142
+ /\.test\.[jt]sx?$/,
143
+ /\.spec\.[jt]sx?$/,
144
+ /\.stories\.[jt]sx?$/,
145
+ /design-tokens?\//,
146
+ /tokens?\//,
147
+ /theme\//,
148
+ /\.config\.[jt]s$/,
149
+ /tailwind\.config/,
150
+ ];
151
+ // ============================================================================
152
+ // Helper Functions
153
+ // ============================================================================
154
+ /**
155
+ * Check if a file should be excluded from hardcoded value detection
156
+ */
157
+ export function shouldExcludeFile(filePath) {
158
+ return EXCLUDED_FILE_PATTERNS.some(pattern => pattern.test(filePath));
159
+ }
160
+ /**
161
+ * Check if a value is in the allowed hardcoded values list
162
+ */
163
+ export function isAllowedHardcodedValue(value) {
164
+ return ALLOWED_HARDCODED_VALUES.has(value.toLowerCase().trim());
165
+ }
166
+ /**
167
+ * Detect design token imports in content
168
+ */
169
+ export function detectTokenImports(content, file) {
170
+ const results = [];
171
+ const lines = content.split('\n');
172
+ for (const pattern of DESIGN_TOKEN_IMPORT_PATTERNS) {
173
+ // Reset regex lastIndex
174
+ const regex = new RegExp(pattern.source, pattern.flags);
175
+ let match;
176
+ while ((match = regex.exec(content)) !== null) {
177
+ const beforeMatch = content.slice(0, match.index);
178
+ const lineNumber = beforeMatch.split('\n').length;
179
+ const lastNewline = beforeMatch.lastIndexOf('\n');
180
+ const column = match.index - lastNewline;
181
+ results.push({
182
+ type: 'design-tokens-import',
183
+ file,
184
+ line: lineNumber,
185
+ column,
186
+ matchedText: match[0],
187
+ tokenName: extractImportPath(match[0]),
188
+ context: lines[lineNumber - 1] || '',
189
+ });
190
+ }
191
+ }
192
+ return results;
193
+ }
194
+ /**
195
+ * Extract import path from import statement
196
+ */
197
+ function extractImportPath(importStatement) {
198
+ const match = importStatement.match(/from\s+['"]([^'"]+)['"]/);
199
+ return match ? match[1] || '' : '';
200
+ }
201
+ /**
202
+ * Detect CSS custom property usage in content
203
+ */
204
+ export function detectCSSCustomProperties(content, file) {
205
+ const results = [];
206
+ const lines = content.split('\n');
207
+ const regex = new RegExp(CSS_CUSTOM_PROPERTY_PATTERN.source, CSS_CUSTOM_PROPERTY_PATTERN.flags);
208
+ let match;
209
+ while ((match = regex.exec(content)) !== null) {
210
+ const beforeMatch = content.slice(0, match.index);
211
+ const lineNumber = beforeMatch.split('\n').length;
212
+ const lastNewline = beforeMatch.lastIndexOf('\n');
213
+ const column = match.index - lastNewline;
214
+ results.push({
215
+ type: 'css-custom-property',
216
+ file,
217
+ line: lineNumber,
218
+ column,
219
+ matchedText: match[0],
220
+ tokenName: match[1] || '',
221
+ context: lines[lineNumber - 1] || '',
222
+ });
223
+ }
224
+ return results;
225
+ }
226
+ /**
227
+ * Detect theme object usage in content
228
+ */
229
+ export function detectThemeObjectUsage(content, file) {
230
+ const results = [];
231
+ const lines = content.split('\n');
232
+ for (const pattern of THEME_OBJECT_PATTERNS) {
233
+ const regex = new RegExp(pattern.source, pattern.flags);
234
+ let match;
235
+ while ((match = regex.exec(content)) !== null) {
236
+ const beforeMatch = content.slice(0, match.index);
237
+ const lineNumber = beforeMatch.split('\n').length;
238
+ const lastNewline = beforeMatch.lastIndexOf('\n');
239
+ const column = match.index - lastNewline;
240
+ results.push({
241
+ type: 'theme-object',
242
+ file,
243
+ line: lineNumber,
244
+ column,
245
+ matchedText: match[0],
246
+ tokenName: match[0],
247
+ context: lines[lineNumber - 1] || '',
248
+ });
249
+ }
250
+ }
251
+ return results;
252
+ }
253
+ /**
254
+ * Detect hardcoded color values in content
255
+ */
256
+ export function detectHardcodedColors(content, file) {
257
+ const results = [];
258
+ const lines = content.split('\n');
259
+ // Check each color pattern type
260
+ const colorPatterns = [
261
+ { pattern: HARDCODED_COLOR_PATTERNS.hex, type: 'color-hex' },
262
+ { pattern: HARDCODED_COLOR_PATTERNS.rgb, type: 'color-rgb' },
263
+ { pattern: HARDCODED_COLOR_PATTERNS.rgba, type: 'color-rgba' },
264
+ { pattern: HARDCODED_COLOR_PATTERNS.hsl, type: 'color-hsl' },
265
+ { pattern: HARDCODED_COLOR_PATTERNS.hsla, type: 'color-hsla' },
266
+ ];
267
+ for (const { pattern, type } of colorPatterns) {
268
+ const regex = new RegExp(pattern.source, pattern.flags);
269
+ let match;
270
+ while ((match = regex.exec(content)) !== null) {
271
+ const value = match[0];
272
+ // Skip allowed values
273
+ if (isAllowedHardcodedValue(value)) {
274
+ continue;
275
+ }
276
+ // Skip if inside a CSS custom property definition
277
+ const beforeMatch = content.slice(0, match.index);
278
+ const lineNumber = beforeMatch.split('\n').length;
279
+ const lineContent = lines[lineNumber - 1] || '';
280
+ // Skip CSS custom property definitions (--color-name: #fff)
281
+ if (/^\s*--[a-zA-Z0-9_-]+\s*:/.test(lineContent)) {
282
+ continue;
283
+ }
284
+ // Skip if inside a comment
285
+ if (isInsideComment(content, match.index)) {
286
+ continue;
287
+ }
288
+ const lastNewline = beforeMatch.lastIndexOf('\n');
289
+ const column = match.index - lastNewline;
290
+ const endColumn = column + value.length;
291
+ const property = extractCSSProperty(lineContent);
292
+ const hardcodedInfo = {
293
+ type,
294
+ file,
295
+ line: lineNumber,
296
+ column,
297
+ endLine: lineNumber,
298
+ endColumn,
299
+ value,
300
+ suggestedToken: suggestColorToken(value),
301
+ lineContent,
302
+ };
303
+ if (property !== undefined) {
304
+ hardcodedInfo.property = property;
305
+ }
306
+ results.push(hardcodedInfo);
307
+ }
308
+ }
309
+ return results;
310
+ }
311
+ /**
312
+ * Detect hardcoded spacing values in content
313
+ */
314
+ export function detectHardcodedSpacing(content, file) {
315
+ const results = [];
316
+ const lines = content.split('\n');
317
+ const spacingPatterns = [
318
+ { pattern: HARDCODED_SPACING_PATTERNS.px, type: 'spacing-px' },
319
+ { pattern: HARDCODED_SPACING_PATTERNS.rem, type: 'spacing-rem' },
320
+ { pattern: HARDCODED_SPACING_PATTERNS.em, type: 'spacing-em' },
321
+ ];
322
+ for (const { pattern, type } of spacingPatterns) {
323
+ const regex = new RegExp(pattern.source, pattern.flags);
324
+ let match;
325
+ while ((match = regex.exec(content)) !== null) {
326
+ const value = match[0];
327
+ // Skip allowed values
328
+ if (isAllowedHardcodedValue(value)) {
329
+ continue;
330
+ }
331
+ const beforeMatch = content.slice(0, match.index);
332
+ const lineNumber = beforeMatch.split('\n').length;
333
+ const lineContent = lines[lineNumber - 1] || '';
334
+ // Skip CSS custom property definitions
335
+ if (/^\s*--[a-zA-Z0-9_-]+\s*:/.test(lineContent)) {
336
+ continue;
337
+ }
338
+ // Skip if inside a comment
339
+ if (isInsideComment(content, match.index)) {
340
+ continue;
341
+ }
342
+ // Skip if it's part of a media query breakpoint
343
+ if (/@media.*\(.*\d+px/.test(lineContent)) {
344
+ continue;
345
+ }
346
+ const lastNewline = beforeMatch.lastIndexOf('\n');
347
+ const column = match.index - lastNewline;
348
+ const endColumn = column + value.length;
349
+ const property = extractCSSProperty(lineContent);
350
+ const hardcodedInfo = {
351
+ type,
352
+ file,
353
+ line: lineNumber,
354
+ column,
355
+ endLine: lineNumber,
356
+ endColumn,
357
+ value,
358
+ suggestedToken: suggestSpacingToken(value),
359
+ lineContent,
360
+ };
361
+ if (property !== undefined) {
362
+ hardcodedInfo.property = property;
363
+ }
364
+ results.push(hardcodedInfo);
365
+ }
366
+ }
367
+ return results;
368
+ }
369
+ /**
370
+ * Check if a position is inside a comment
371
+ */
372
+ function isInsideComment(content, index) {
373
+ const beforeIndex = content.slice(0, index);
374
+ // Check for single-line comment
375
+ const lastNewline = beforeIndex.lastIndexOf('\n');
376
+ const currentLine = beforeIndex.slice(lastNewline + 1);
377
+ if (currentLine.includes('//')) {
378
+ const commentStart = currentLine.indexOf('//');
379
+ const positionInLine = index - lastNewline - 1;
380
+ if (positionInLine > commentStart) {
381
+ return true;
382
+ }
383
+ }
384
+ // Check for multi-line comment
385
+ const lastBlockCommentStart = beforeIndex.lastIndexOf('/*');
386
+ const lastBlockCommentEnd = beforeIndex.lastIndexOf('*/');
387
+ if (lastBlockCommentStart > lastBlockCommentEnd) {
388
+ return true;
389
+ }
390
+ return false;
391
+ }
392
+ /**
393
+ * Extract CSS property name from a line
394
+ */
395
+ function extractCSSProperty(line) {
396
+ // Match CSS property: property-name: value
397
+ const cssMatch = line.match(/([a-zA-Z-]+)\s*:/);
398
+ if (cssMatch && cssMatch[1]) {
399
+ return cssMatch[1];
400
+ }
401
+ // Match JS object property: propertyName: value
402
+ const jsMatch = line.match(/([a-zA-Z]+)\s*:/);
403
+ if (jsMatch && jsMatch[1]) {
404
+ // Convert camelCase to kebab-case
405
+ return jsMatch[1].replace(/([A-Z])/g, '-$1').toLowerCase();
406
+ }
407
+ return undefined;
408
+ }
409
+ /**
410
+ * Suggest a token name for a color value
411
+ */
412
+ function suggestColorToken(value) {
413
+ // Normalize the value
414
+ const normalized = value.toLowerCase();
415
+ // Common color mappings
416
+ if (normalized === '#000' || normalized === '#000000') {
417
+ return 'colors.black or --color-black';
418
+ }
419
+ if (normalized === '#fff' || normalized === '#ffffff') {
420
+ return 'colors.white or --color-white';
421
+ }
422
+ // Generic suggestion
423
+ return 'Use a design token from your color palette (e.g., colors.primary, --color-primary)';
424
+ }
425
+ /**
426
+ * Suggest a token name for a spacing value
427
+ */
428
+ function suggestSpacingToken(value) {
429
+ // Extract numeric value
430
+ const numMatch = value.match(/^(\d+(?:\.\d+)?)/);
431
+ if (!numMatch) {
432
+ return 'Use a spacing token (e.g., spacing.md, --spacing-4)';
433
+ }
434
+ const num = parseFloat(numMatch[1] || '0');
435
+ // Common spacing scale suggestions
436
+ if (value.endsWith('px')) {
437
+ if (num <= 4)
438
+ return 'spacing.xs or --spacing-1';
439
+ if (num <= 8)
440
+ return 'spacing.sm or --spacing-2';
441
+ if (num <= 16)
442
+ return 'spacing.md or --spacing-4';
443
+ if (num <= 24)
444
+ return 'spacing.lg or --spacing-6';
445
+ if (num <= 32)
446
+ return 'spacing.xl or --spacing-8';
447
+ return 'spacing.2xl or --spacing-10';
448
+ }
449
+ if (value.endsWith('rem')) {
450
+ if (num <= 0.25)
451
+ return 'spacing.xs or --spacing-1';
452
+ if (num <= 0.5)
453
+ return 'spacing.sm or --spacing-2';
454
+ if (num <= 1)
455
+ return 'spacing.md or --spacing-4';
456
+ if (num <= 1.5)
457
+ return 'spacing.lg or --spacing-6';
458
+ if (num <= 2)
459
+ return 'spacing.xl or --spacing-8';
460
+ return 'spacing.2xl or --spacing-10';
461
+ }
462
+ return 'Use a spacing token (e.g., spacing.md, --spacing-4)';
463
+ }
464
+ /**
465
+ * Analyze design token patterns in a file
466
+ */
467
+ export function analyzeDesignTokens(content, file) {
468
+ // Skip excluded files for hardcoded value detection
469
+ const skipHardcodedDetection = shouldExcludeFile(file);
470
+ // Detect token usages
471
+ const tokenImports = detectTokenImports(content, file);
472
+ const cssCustomProperties = detectCSSCustomProperties(content, file);
473
+ const themeObjectUsages = detectThemeObjectUsage(content, file);
474
+ const tokenUsages = [
475
+ ...tokenImports,
476
+ ...cssCustomProperties,
477
+ ...themeObjectUsages,
478
+ ];
479
+ // Detect hardcoded values (unless file is excluded)
480
+ let hardcodedValues = [];
481
+ if (!skipHardcodedDetection) {
482
+ const hardcodedColors = detectHardcodedColors(content, file);
483
+ const hardcodedSpacing = detectHardcodedSpacing(content, file);
484
+ hardcodedValues = [...hardcodedColors, ...hardcodedSpacing];
485
+ }
486
+ // Calculate confidence
487
+ const hasTokenUsage = tokenUsages.length > 0;
488
+ const hasHardcodedValues = hardcodedValues.length > 0;
489
+ let tokenUsageConfidence = 0;
490
+ if (hasTokenUsage && !hasHardcodedValues) {
491
+ tokenUsageConfidence = 1.0;
492
+ }
493
+ else if (hasTokenUsage && hasHardcodedValues) {
494
+ const ratio = tokenUsages.length / (tokenUsages.length + hardcodedValues.length);
495
+ tokenUsageConfidence = ratio;
496
+ }
497
+ else if (!hasTokenUsage && hasHardcodedValues) {
498
+ tokenUsageConfidence = 0;
499
+ }
500
+ else {
501
+ tokenUsageConfidence = 0.5; // No styling detected
502
+ }
503
+ return {
504
+ tokenUsages,
505
+ hardcodedValues,
506
+ hasDesignTokenImport: tokenImports.length > 0,
507
+ usesCSSCustomProperties: cssCustomProperties.length > 0,
508
+ usesThemeObject: themeObjectUsages.length > 0,
509
+ tokenUsageConfidence,
510
+ };
511
+ }
512
+ // ============================================================================
513
+ // Design Tokens Detector Class
514
+ // ============================================================================
515
+ /**
516
+ * Detector for design token usage patterns
517
+ *
518
+ * Identifies design token usage and flags hardcoded values that should
519
+ * use design tokens instead.
520
+ *
521
+ * @requirements 9.1 - THE Styling_Detector SHALL detect design token usage vs hardcoded values
522
+ */
523
+ export class DesignTokensDetector extends RegexDetector {
524
+ id = 'styling/design-tokens';
525
+ category = 'styling';
526
+ subcategory = 'design-tokens';
527
+ name = 'Design Tokens Detector';
528
+ description = 'Detects design token usage patterns and flags hardcoded values that should use tokens';
529
+ supportedLanguages = ['typescript', 'javascript', 'css'];
530
+ /**
531
+ * Detect design token patterns and violations
532
+ */
533
+ async detect(context) {
534
+ const patterns = [];
535
+ const violations = [];
536
+ // Analyze the file
537
+ const analysis = analyzeDesignTokens(context.content, context.file);
538
+ // Create pattern matches for token usages
539
+ if (analysis.hasDesignTokenImport) {
540
+ patterns.push(this.createTokenImportPattern(context.file, analysis));
541
+ }
542
+ if (analysis.usesCSSCustomProperties) {
543
+ patterns.push(this.createCSSCustomPropertyPattern(context.file, analysis));
544
+ }
545
+ if (analysis.usesThemeObject) {
546
+ patterns.push(this.createThemeObjectPattern(context.file, analysis));
547
+ }
548
+ // Create violations for hardcoded values
549
+ for (const hardcoded of analysis.hardcodedValues) {
550
+ violations.push(this.createHardcodedValueViolation(hardcoded));
551
+ }
552
+ return this.createResult(patterns, violations, analysis.tokenUsageConfidence);
553
+ }
554
+ /**
555
+ * Create a pattern match for design token imports
556
+ */
557
+ createTokenImportPattern(file, analysis) {
558
+ const tokenImports = analysis.tokenUsages.filter(t => t.type === 'design-tokens-import');
559
+ const firstImport = tokenImports[0];
560
+ return {
561
+ patternId: `${this.id}/import`,
562
+ location: {
563
+ file,
564
+ line: firstImport?.line || 1,
565
+ column: firstImport?.column || 1,
566
+ },
567
+ confidence: 1.0,
568
+ isOutlier: false,
569
+ };
570
+ }
571
+ /**
572
+ * Create a pattern match for CSS custom property usage
573
+ */
574
+ createCSSCustomPropertyPattern(file, analysis) {
575
+ const cssProps = analysis.tokenUsages.filter(t => t.type === 'css-custom-property');
576
+ const firstProp = cssProps[0];
577
+ return {
578
+ patternId: `${this.id}/css-custom-property`,
579
+ location: {
580
+ file,
581
+ line: firstProp?.line || 1,
582
+ column: firstProp?.column || 1,
583
+ },
584
+ confidence: 1.0,
585
+ isOutlier: false,
586
+ };
587
+ }
588
+ /**
589
+ * Create a pattern match for theme object usage
590
+ */
591
+ createThemeObjectPattern(file, analysis) {
592
+ const themeUsages = analysis.tokenUsages.filter(t => t.type === 'theme-object');
593
+ const firstUsage = themeUsages[0];
594
+ return {
595
+ patternId: `${this.id}/theme-object`,
596
+ location: {
597
+ file,
598
+ line: firstUsage?.line || 1,
599
+ column: firstUsage?.column || 1,
600
+ },
601
+ confidence: 1.0,
602
+ isOutlier: false,
603
+ };
604
+ }
605
+ /**
606
+ * Create a violation for a hardcoded value
607
+ */
608
+ createHardcodedValueViolation(hardcoded) {
609
+ const typeDescriptions = {
610
+ 'color-hex': 'hex color',
611
+ 'color-rgb': 'RGB color',
612
+ 'color-rgba': 'RGBA color',
613
+ 'color-hsl': 'HSL color',
614
+ 'color-hsla': 'HSLA color',
615
+ 'spacing-px': 'pixel spacing value',
616
+ 'spacing-rem': 'rem spacing value',
617
+ 'spacing-em': 'em spacing value',
618
+ 'font-size': 'font size',
619
+ 'border-radius': 'border radius',
620
+ 'z-index': 'z-index value',
621
+ };
622
+ const typeDescription = typeDescriptions[hardcoded.type] || 'hardcoded value';
623
+ const propertyInfo = hardcoded.property ? ` in '${hardcoded.property}'` : '';
624
+ const violation = {
625
+ id: `${this.id}-${hardcoded.file}-${hardcoded.line}-${hardcoded.column}`,
626
+ patternId: this.id,
627
+ severity: 'warning',
628
+ file: hardcoded.file,
629
+ range: {
630
+ start: { line: hardcoded.line - 1, character: hardcoded.column - 1 },
631
+ end: { line: hardcoded.endLine - 1, character: hardcoded.endColumn - 1 },
632
+ },
633
+ message: `Hardcoded ${typeDescription} '${hardcoded.value}'${propertyInfo} should use a design token`,
634
+ explanation: `Using hardcoded values instead of design tokens makes it difficult to maintain consistent styling across the application. Design tokens provide a single source of truth for colors, spacing, and other design values.`,
635
+ expected: hardcoded.suggestedToken || 'A design token',
636
+ actual: hardcoded.value,
637
+ aiExplainAvailable: true,
638
+ aiFixAvailable: true,
639
+ firstSeen: new Date(),
640
+ occurrences: 1,
641
+ };
642
+ const quickFix = this.createQuickFixForHardcodedValue(hardcoded);
643
+ if (quickFix !== undefined) {
644
+ violation.quickFix = quickFix;
645
+ }
646
+ return violation;
647
+ }
648
+ /**
649
+ * Create a quick fix for replacing a hardcoded value with a token
650
+ */
651
+ createQuickFixForHardcodedValue(hardcoded) {
652
+ // Only provide quick fix if we have a suggested token
653
+ if (!hardcoded.suggestedToken) {
654
+ return undefined;
655
+ }
656
+ // Extract the first suggested token (before "or")
657
+ const suggestedToken = hardcoded.suggestedToken.split(' or ')[0] || hardcoded.suggestedToken;
658
+ // Determine the replacement based on context
659
+ let replacement;
660
+ if (hardcoded.lineContent.includes('var(')) {
661
+ // Already using CSS custom properties, suggest a different custom property
662
+ replacement = `var(--${suggestedToken.replace(/\./g, '-').replace('colors', 'color').replace('spacing', 'spacing')})`;
663
+ }
664
+ else if (hardcoded.lineContent.includes('${') || hardcoded.lineContent.includes('`')) {
665
+ // Template literal context (styled-components, emotion)
666
+ replacement = `\${${suggestedToken}}`;
667
+ }
668
+ else {
669
+ // Default: suggest the token directly
670
+ replacement = suggestedToken;
671
+ }
672
+ return {
673
+ title: `Replace with design token: ${suggestedToken}`,
674
+ kind: 'quickfix',
675
+ edit: {
676
+ changes: {
677
+ [hardcoded.file]: [
678
+ {
679
+ range: {
680
+ start: { line: hardcoded.line - 1, character: hardcoded.column - 1 },
681
+ end: { line: hardcoded.endLine - 1, character: hardcoded.endColumn - 1 },
682
+ },
683
+ newText: replacement,
684
+ },
685
+ ],
686
+ },
687
+ },
688
+ isPreferred: true,
689
+ confidence: 0.7,
690
+ preview: `Replace '${hardcoded.value}' with '${replacement}'`,
691
+ };
692
+ }
693
+ /**
694
+ * Generate a quick fix for a violation
695
+ */
696
+ generateQuickFix(violation) {
697
+ // Check if this is a hardcoded value violation
698
+ if (!violation.message.includes('Hardcoded')) {
699
+ return null;
700
+ }
701
+ // Extract the value from the message
702
+ const valueMatch = violation.message.match(/Hardcoded [^']+ '([^']+)'/);
703
+ if (!valueMatch || !valueMatch[1]) {
704
+ return null;
705
+ }
706
+ const value = valueMatch[1];
707
+ const isColor = violation.message.includes('color');
708
+ const isSpacing = violation.message.includes('spacing');
709
+ let suggestedToken;
710
+ if (isColor) {
711
+ suggestedToken = suggestColorToken(value);
712
+ }
713
+ else if (isSpacing) {
714
+ suggestedToken = suggestSpacingToken(value);
715
+ }
716
+ else {
717
+ return null;
718
+ }
719
+ const firstSuggestion = suggestedToken.split(' or ')[0] || suggestedToken;
720
+ return {
721
+ title: `Replace with design token: ${firstSuggestion}`,
722
+ kind: 'quickfix',
723
+ edit: {
724
+ changes: {
725
+ [violation.file]: [
726
+ {
727
+ range: violation.range,
728
+ newText: firstSuggestion,
729
+ },
730
+ ],
731
+ },
732
+ },
733
+ isPreferred: true,
734
+ confidence: 0.7,
735
+ preview: `Replace '${value}' with '${firstSuggestion}'`,
736
+ };
737
+ }
738
+ }
739
+ // ============================================================================
740
+ // Factory Function
741
+ // ============================================================================
742
+ /**
743
+ * Create a new DesignTokensDetector instance
744
+ */
745
+ export function createDesignTokensDetector() {
746
+ return new DesignTokensDetector();
747
+ }
748
+ //# sourceMappingURL=design-tokens.js.map