baseguard 1.0.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 (244) hide show
  1. package/.eslintrc.json +25 -0
  2. package/.prettierrc +8 -0
  3. package/README.md +94 -0
  4. package/bin/base.js +494 -0
  5. package/dist/ai/fix-manager.d.ts +67 -0
  6. package/dist/ai/fix-manager.d.ts.map +1 -0
  7. package/dist/ai/fix-manager.js +326 -0
  8. package/dist/ai/fix-manager.js.map +1 -0
  9. package/dist/ai/gemini-analyzer.d.ts +116 -0
  10. package/dist/ai/gemini-analyzer.d.ts.map +1 -0
  11. package/dist/ai/gemini-analyzer.js +572 -0
  12. package/dist/ai/gemini-analyzer.js.map +1 -0
  13. package/dist/ai/index.d.ts +4 -0
  14. package/dist/ai/index.d.ts.map +1 -0
  15. package/dist/ai/index.js +5 -0
  16. package/dist/ai/index.js.map +1 -0
  17. package/dist/ai/jules-implementer.d.ts +115 -0
  18. package/dist/ai/jules-implementer.d.ts.map +1 -0
  19. package/dist/ai/jules-implementer.js +387 -0
  20. package/dist/ai/jules-implementer.js.map +1 -0
  21. package/dist/commands/automation.d.ts +5 -0
  22. package/dist/commands/automation.d.ts.map +1 -0
  23. package/dist/commands/automation.js +305 -0
  24. package/dist/commands/automation.js.map +1 -0
  25. package/dist/commands/check.d.ts +9 -0
  26. package/dist/commands/check.d.ts.map +1 -0
  27. package/dist/commands/check.js +113 -0
  28. package/dist/commands/check.js.map +1 -0
  29. package/dist/commands/config.d.ts +11 -0
  30. package/dist/commands/config.d.ts.map +1 -0
  31. package/dist/commands/config.js +324 -0
  32. package/dist/commands/config.js.map +1 -0
  33. package/dist/commands/fix.d.ts +9 -0
  34. package/dist/commands/fix.d.ts.map +1 -0
  35. package/dist/commands/fix.js +207 -0
  36. package/dist/commands/fix.js.map +1 -0
  37. package/dist/commands/index.d.ts +6 -0
  38. package/dist/commands/index.d.ts.map +1 -0
  39. package/dist/commands/index.js +7 -0
  40. package/dist/commands/index.js.map +1 -0
  41. package/dist/commands/init.d.ts +9 -0
  42. package/dist/commands/init.d.ts.map +1 -0
  43. package/dist/commands/init.js +125 -0
  44. package/dist/commands/init.js.map +1 -0
  45. package/dist/core/api-key-manager.d.ts +83 -0
  46. package/dist/core/api-key-manager.d.ts.map +1 -0
  47. package/dist/core/api-key-manager.js +244 -0
  48. package/dist/core/api-key-manager.js.map +1 -0
  49. package/dist/core/baseguard.d.ts +46 -0
  50. package/dist/core/baseguard.d.ts.map +1 -0
  51. package/dist/core/baseguard.js +132 -0
  52. package/dist/core/baseguard.js.map +1 -0
  53. package/dist/core/baseline-checker.d.ts +63 -0
  54. package/dist/core/baseline-checker.d.ts.map +1 -0
  55. package/dist/core/baseline-checker.js +502 -0
  56. package/dist/core/baseline-checker.js.map +1 -0
  57. package/dist/core/cache-manager.d.ts +88 -0
  58. package/dist/core/cache-manager.d.ts.map +1 -0
  59. package/dist/core/cache-manager.js +213 -0
  60. package/dist/core/cache-manager.js.map +1 -0
  61. package/dist/core/configuration.d.ts +140 -0
  62. package/dist/core/configuration.d.ts.map +1 -0
  63. package/dist/core/configuration.js +474 -0
  64. package/dist/core/configuration.js.map +1 -0
  65. package/dist/core/directory-filter.d.ts +90 -0
  66. package/dist/core/directory-filter.d.ts.map +1 -0
  67. package/dist/core/directory-filter.js +319 -0
  68. package/dist/core/directory-filter.js.map +1 -0
  69. package/dist/core/error-handler.d.ts +110 -0
  70. package/dist/core/error-handler.d.ts.map +1 -0
  71. package/dist/core/error-handler.js +392 -0
  72. package/dist/core/error-handler.js.map +1 -0
  73. package/dist/core/file-processor.d.ts +80 -0
  74. package/dist/core/file-processor.d.ts.map +1 -0
  75. package/dist/core/file-processor.js +259 -0
  76. package/dist/core/file-processor.js.map +1 -0
  77. package/dist/core/gitignore-manager.d.ts +44 -0
  78. package/dist/core/gitignore-manager.d.ts.map +1 -0
  79. package/dist/core/gitignore-manager.js +147 -0
  80. package/dist/core/gitignore-manager.js.map +1 -0
  81. package/dist/core/index.d.ts +13 -0
  82. package/dist/core/index.d.ts.map +1 -0
  83. package/dist/core/index.js +13 -0
  84. package/dist/core/index.js.map +1 -0
  85. package/dist/core/lazy-loader.d.ts +68 -0
  86. package/dist/core/lazy-loader.d.ts.map +1 -0
  87. package/dist/core/lazy-loader.js +260 -0
  88. package/dist/core/lazy-loader.js.map +1 -0
  89. package/dist/core/memory-manager.d.ts +1 -0
  90. package/dist/core/memory-manager.d.ts.map +1 -0
  91. package/dist/core/memory-manager.js +2 -0
  92. package/dist/core/memory-manager.js.map +1 -0
  93. package/dist/core/startup-optimizer.d.ts +45 -0
  94. package/dist/core/startup-optimizer.d.ts.map +1 -0
  95. package/dist/core/startup-optimizer.js +140 -0
  96. package/dist/core/startup-optimizer.js.map +1 -0
  97. package/dist/git/automation-engine.d.ts +58 -0
  98. package/dist/git/automation-engine.d.ts.map +1 -0
  99. package/dist/git/automation-engine.js +318 -0
  100. package/dist/git/automation-engine.js.map +1 -0
  101. package/dist/git/github-manager.d.ts +71 -0
  102. package/dist/git/github-manager.d.ts.map +1 -0
  103. package/dist/git/github-manager.js +226 -0
  104. package/dist/git/github-manager.js.map +1 -0
  105. package/dist/git/hook-manager.d.ts +43 -0
  106. package/dist/git/hook-manager.d.ts.map +1 -0
  107. package/dist/git/hook-manager.js +191 -0
  108. package/dist/git/hook-manager.js.map +1 -0
  109. package/dist/git/index.d.ts +4 -0
  110. package/dist/git/index.d.ts.map +1 -0
  111. package/dist/git/index.js +5 -0
  112. package/dist/git/index.js.map +1 -0
  113. package/dist/index.d.ts +8 -0
  114. package/dist/index.d.ts.map +1 -0
  115. package/dist/index.js +9 -0
  116. package/dist/index.js.map +1 -0
  117. package/dist/parsers/feature-validator.d.ts +60 -0
  118. package/dist/parsers/feature-validator.d.ts.map +1 -0
  119. package/dist/parsers/feature-validator.js +483 -0
  120. package/dist/parsers/feature-validator.js.map +1 -0
  121. package/dist/parsers/index.d.ts +8 -0
  122. package/dist/parsers/index.d.ts.map +1 -0
  123. package/dist/parsers/index.js +9 -0
  124. package/dist/parsers/index.js.map +1 -0
  125. package/dist/parsers/parser-manager.d.ts +103 -0
  126. package/dist/parsers/parser-manager.d.ts.map +1 -0
  127. package/dist/parsers/parser-manager.js +321 -0
  128. package/dist/parsers/parser-manager.js.map +1 -0
  129. package/dist/parsers/parser.d.ts +23 -0
  130. package/dist/parsers/parser.d.ts.map +1 -0
  131. package/dist/parsers/parser.js +6 -0
  132. package/dist/parsers/parser.js.map +1 -0
  133. package/dist/parsers/react-parser.d.ts +22 -0
  134. package/dist/parsers/react-parser.d.ts.map +1 -0
  135. package/dist/parsers/react-parser.js +307 -0
  136. package/dist/parsers/react-parser.js.map +1 -0
  137. package/dist/parsers/svelte-parser.d.ts +33 -0
  138. package/dist/parsers/svelte-parser.d.ts.map +1 -0
  139. package/dist/parsers/svelte-parser.js +408 -0
  140. package/dist/parsers/svelte-parser.js.map +1 -0
  141. package/dist/parsers/vanilla-parser.d.ts +31 -0
  142. package/dist/parsers/vanilla-parser.d.ts.map +1 -0
  143. package/dist/parsers/vanilla-parser.js +590 -0
  144. package/dist/parsers/vanilla-parser.js.map +1 -0
  145. package/dist/parsers/vue-parser.d.ts +9 -0
  146. package/dist/parsers/vue-parser.d.ts.map +1 -0
  147. package/dist/parsers/vue-parser.js +16 -0
  148. package/dist/parsers/vue-parser.js.map +1 -0
  149. package/dist/terminal-header.d.ts +12 -0
  150. package/dist/terminal-header.js +45 -0
  151. package/dist/types/index.d.ts +83 -0
  152. package/dist/types/index.d.ts.map +1 -0
  153. package/dist/types/index.js +5 -0
  154. package/dist/types/index.js.map +1 -0
  155. package/dist/ui/components.d.ts +133 -0
  156. package/dist/ui/components.d.ts.map +1 -0
  157. package/dist/ui/components.js +482 -0
  158. package/dist/ui/components.js.map +1 -0
  159. package/dist/ui/help.d.ts +11 -0
  160. package/dist/ui/help.d.ts.map +1 -0
  161. package/dist/ui/help.js +161 -0
  162. package/dist/ui/help.js.map +1 -0
  163. package/dist/ui/index.d.ts +5 -0
  164. package/dist/ui/index.d.ts.map +1 -0
  165. package/dist/ui/index.js +5 -0
  166. package/dist/ui/index.js.map +1 -0
  167. package/dist/ui/prompts.d.ts +63 -0
  168. package/dist/ui/prompts.d.ts.map +1 -0
  169. package/dist/ui/prompts.js +611 -0
  170. package/dist/ui/prompts.js.map +1 -0
  171. package/dist/ui/terminal-header.d.ts +13 -0
  172. package/dist/ui/terminal-header.d.ts.map +1 -0
  173. package/dist/ui/terminal-header.js +46 -0
  174. package/dist/ui/terminal-header.js.map +1 -0
  175. package/package.json +80 -0
  176. package/src/ai/__tests__/gemini-analyzer.test.ts +181 -0
  177. package/src/ai/fix-manager.ts +362 -0
  178. package/src/ai/gemini-analyzer.ts +671 -0
  179. package/src/ai/index.ts +4 -0
  180. package/src/ai/jules-implementer.ts +459 -0
  181. package/src/commands/automation.ts +344 -0
  182. package/src/commands/check.ts +299 -0
  183. package/src/commands/config.ts +365 -0
  184. package/src/commands/fix.ts +234 -0
  185. package/src/commands/index.ts +6 -0
  186. package/src/commands/init.ts +142 -0
  187. package/src/commands/status.ts +0 -0
  188. package/src/core/api-key-manager.ts +298 -0
  189. package/src/core/baseguard.ts +742 -0
  190. package/src/core/baseline-checker.ts +563 -0
  191. package/src/core/cache-manager.ts +270 -0
  192. package/src/core/configuration-recovery.ts +676 -0
  193. package/src/core/configuration.ts +559 -0
  194. package/src/core/debug-logger.ts +590 -0
  195. package/src/core/directory-filter.ts +421 -0
  196. package/src/core/error-handler.ts +517 -0
  197. package/src/core/file-processor.ts +331 -0
  198. package/src/core/gitignore-manager.ts +169 -0
  199. package/src/core/graceful-degradation-manager.ts +596 -0
  200. package/src/core/index.ts +13 -0
  201. package/src/core/lazy-loader.ts +307 -0
  202. package/src/core/logger.ts +0 -0
  203. package/src/core/memory-manager.ts +294 -0
  204. package/src/core/startup-optimizer.ts +173 -0
  205. package/src/core/system-error-handler.ts +746 -0
  206. package/src/git/automation-engine.ts +361 -0
  207. package/src/git/github-manager.ts +260 -0
  208. package/src/git/hook-manager.ts +210 -0
  209. package/src/git/index.ts +4 -0
  210. package/src/index.ts +8 -0
  211. package/src/parsers/feature-validator.ts +559 -0
  212. package/src/parsers/index.ts +8 -0
  213. package/src/parsers/parser-manager.ts +419 -0
  214. package/src/parsers/parser.ts +26 -0
  215. package/src/parsers/react-parser-optimized.ts +161 -0
  216. package/src/parsers/react-parser.ts +359 -0
  217. package/src/parsers/svelte-parser.ts +506 -0
  218. package/src/parsers/vanilla-parser.ts +682 -0
  219. package/src/parsers/vue-parser.ts +472 -0
  220. package/src/types/index.ts +92 -0
  221. package/src/ui/components.ts +567 -0
  222. package/src/ui/help.ts +193 -0
  223. package/src/ui/index.ts +4 -0
  224. package/src/ui/prompts.ts +688 -0
  225. package/src/ui/terminal-header.ts +59 -0
  226. package/test-config-commands.js +56 -0
  227. package/test-header-simple.js +33 -0
  228. package/test-terminal-header.js +12 -0
  229. package/test-ui.js +29 -0
  230. package/tests/e2e/baseguard.e2e.test.ts +516 -0
  231. package/tests/e2e/cross-platform.e2e.test.ts +420 -0
  232. package/tests/e2e/git-integration.e2e.test.ts +487 -0
  233. package/tests/fixtures/react-project/package.json +14 -0
  234. package/tests/fixtures/react-project/src/App.css +76 -0
  235. package/tests/fixtures/react-project/src/App.tsx +77 -0
  236. package/tests/fixtures/svelte-project/package.json +11 -0
  237. package/tests/fixtures/svelte-project/src/App.svelte +369 -0
  238. package/tests/fixtures/vanilla-project/index.html +76 -0
  239. package/tests/fixtures/vanilla-project/script.js +331 -0
  240. package/tests/fixtures/vanilla-project/styles.css +359 -0
  241. package/tests/fixtures/vue-project/package.json +12 -0
  242. package/tests/fixtures/vue-project/src/App.vue +216 -0
  243. package/tsconfig.json +36 -0
  244. package/vitest.config.ts +10 -0
@@ -0,0 +1,559 @@
1
+ import type { DetectedFeature } from '../types/index.js';
2
+ import webFeatures from 'web-features';
3
+
4
+ /**
5
+ * Comprehensive web-features validation and filtering system
6
+ * Validates detected features against the complete web-features package
7
+ * and filters out framework-specific features while capturing all web platform scope
8
+ */
9
+ export class FeatureValidator {
10
+ private readonly FEATURE_ID_MAP: Map<string, string>;
11
+ private readonly FRAMEWORK_SPECIFIC_PATTERNS: RegExp[];
12
+
13
+ constructor() {
14
+ this.FEATURE_ID_MAP = this.buildFeatureIdMap();
15
+ this.FRAMEWORK_SPECIFIC_PATTERNS = this.buildFrameworkPatterns();
16
+ }
17
+
18
+ /**
19
+ * Validate and filter detected features against web-features package
20
+ */
21
+ async validateFeatures(
22
+ detectedFeatures: DetectedFeature[],
23
+ concurrency: number = 10
24
+ ): Promise<DetectedFeature[]> {
25
+ const validFeatures: DetectedFeature[] = [];
26
+
27
+ // Process features in batches for performance
28
+ const batches = this.createBatches(detectedFeatures, concurrency);
29
+
30
+ for (const batch of batches) {
31
+ const batchResults = await Promise.all(
32
+ batch.map(feature => this.validateSingleFeature(feature))
33
+ );
34
+
35
+ validFeatures.push(...batchResults.filter(Boolean) as DetectedFeature[]);
36
+ }
37
+
38
+ return this.deduplicateFeatures(validFeatures);
39
+ }
40
+
41
+ /**
42
+ * Validate a single feature against web-features package
43
+ */
44
+ private async validateSingleFeature(feature: DetectedFeature): Promise<DetectedFeature | null> {
45
+ try {
46
+ // Skip framework-specific features
47
+ if (this.isFrameworkSpecific(feature.feature)) {
48
+ return null;
49
+ }
50
+
51
+ // Map feature to web-features ID
52
+ const webFeatureId = this.mapToWebFeatureId(feature.feature);
53
+ if (!webFeatureId) {
54
+ return null;
55
+ }
56
+
57
+ // Validate against web-features package
58
+ const webFeatureData = webFeatures[webFeatureId];
59
+ if (!webFeatureData) {
60
+ return null;
61
+ }
62
+
63
+ // Return validated feature with enhanced metadata
64
+ return {
65
+ ...feature,
66
+ feature: webFeatureId, // Use standardized web-features ID
67
+ context: this.enhanceContext(feature.context, feature.type)
68
+ };
69
+
70
+ } catch (error) {
71
+ console.warn(`Warning: Could not validate feature ${feature.feature}: ${error instanceof Error ? error.message : 'Unknown error'}`);
72
+ return null;
73
+ }
74
+ }
75
+
76
+ /**
77
+ * Build comprehensive feature ID mapping for ALL web platform technologies
78
+ */
79
+ private buildFeatureIdMap(): Map<string, string> {
80
+ const map = new Map<string, string>();
81
+
82
+ // CSS Properties mapping
83
+ const cssPropertyMap = {
84
+ // Container Queries
85
+ 'container-type': 'container-queries',
86
+ 'container-name': 'container-queries',
87
+ 'container': 'container-queries',
88
+
89
+ // Grid Layout
90
+ 'display': 'css-grid',
91
+ 'grid-template-columns': 'css-grid',
92
+ 'grid-template-rows': 'css-grid',
93
+ 'grid-template-areas': 'css-grid',
94
+ 'grid-column': 'css-grid',
95
+ 'grid-row': 'css-grid',
96
+ 'grid-area': 'css-grid',
97
+ 'gap': 'css-grid-gap',
98
+ 'grid-gap': 'css-grid-gap',
99
+ 'column-gap': 'css-grid-gap',
100
+ 'row-gap': 'css-grid-gap',
101
+
102
+ // Flexbox
103
+ 'flex': 'flexbox',
104
+ 'flex-direction': 'flexbox',
105
+ 'flex-wrap': 'flexbox',
106
+ 'justify-content': 'flexbox',
107
+ 'align-items': 'flexbox',
108
+ 'align-content': 'flexbox',
109
+ 'align-self': 'flexbox',
110
+
111
+ // Modern Layout
112
+ 'aspect-ratio': 'aspect-ratio',
113
+ 'object-fit': 'object-fit',
114
+ 'object-position': 'object-fit',
115
+
116
+ // Visual Effects
117
+ 'backdrop-filter': 'backdrop-filter',
118
+ 'filter': 'css-filters',
119
+ 'mix-blend-mode': 'css-mixblendmode',
120
+ 'clip-path': 'css-clip-path',
121
+ 'mask': 'css-masks',
122
+
123
+ // Color & Appearance
124
+ 'color-scheme': 'color-scheme',
125
+ 'accent-color': 'accent-color',
126
+
127
+ // Scrolling
128
+ 'scroll-behavior': 'scroll-behavior',
129
+ 'scroll-snap-type': 'scroll-snap',
130
+ 'scroll-snap-align': 'scroll-snap',
131
+ 'overscroll-behavior': 'overscroll-behavior',
132
+
133
+ // Interaction
134
+ 'touch-action': 'touch-action',
135
+ 'user-select': 'user-select',
136
+
137
+ // Custom Properties
138
+ '--': 'css-variables',
139
+ 'var(': 'css-variables',
140
+
141
+ // Functions
142
+ 'calc(': 'calc',
143
+ 'clamp(': 'css-math-functions',
144
+ 'min(': 'css-math-functions',
145
+ 'max(': 'css-math-functions',
146
+
147
+ // Transforms & Animations
148
+ 'transform': 'transforms2d',
149
+ 'transform-origin': 'transforms2d',
150
+ 'perspective': 'transforms3d',
151
+ 'animation': 'css-animation',
152
+ 'transition': 'css-transitions',
153
+ 'will-change': 'will-change',
154
+ 'contain': 'css-containment',
155
+ 'content-visibility': 'content-visibility'
156
+ };
157
+
158
+ // CSS Selectors mapping
159
+ const cssSelectorMap = {
160
+ ':has()': 'css-has',
161
+ ':is()': 'css-matches-pseudo',
162
+ ':where()': 'css-where-pseudo',
163
+ ':focus-visible': 'focus-visible',
164
+ ':focus-within': 'focus-within',
165
+ '::backdrop': 'backdrop',
166
+ '::placeholder': 'placeholder',
167
+ '::marker': 'css-marker-pseudo'
168
+ };
169
+
170
+ // JavaScript APIs mapping
171
+ const jsApiMap = {
172
+ // Canvas APIs
173
+ 'getContext': 'canvas',
174
+ 'CanvasRenderingContext2D': 'canvas',
175
+ 'WebGLRenderingContext': 'webgl',
176
+ 'WebGL2RenderingContext': 'webgl2',
177
+ 'OffscreenCanvas': 'offscreen-canvas',
178
+ 'ImageBitmap': 'createimagebitmap',
179
+ 'createImageBitmap': 'createimagebitmap',
180
+ 'Path2D': 'path2d',
181
+
182
+ // WebRTC APIs
183
+ 'RTCPeerConnection': 'rtcpeerconnection',
184
+ 'RTCDataChannel': 'rtcdatachannel',
185
+ 'getUserMedia': 'getusermedia',
186
+ 'getDisplayMedia': 'getdisplaymedia',
187
+ 'MediaStream': 'mediastream',
188
+
189
+ // WebAssembly
190
+ 'WebAssembly': 'wasm',
191
+ 'WebAssembly.instantiate': 'wasm',
192
+ 'WebAssembly.compile': 'wasm',
193
+
194
+ // Service Workers
195
+ 'ServiceWorker': 'serviceworkers',
196
+ 'navigator.serviceWorker': 'serviceworkers',
197
+ 'Cache': 'cache',
198
+ 'caches': 'cache',
199
+ 'PushManager': 'push-api',
200
+ 'Notification': 'notifications',
201
+
202
+ // DOM APIs
203
+ 'querySelector': 'queryselector',
204
+ 'querySelectorAll': 'queryselector',
205
+ 'addEventListener': 'addeventlistener',
206
+ 'CustomEvent': 'customevent',
207
+ 'MutationObserver': 'mutationobserver',
208
+ 'ResizeObserver': 'resizeobserver',
209
+ 'IntersectionObserver': 'intersectionobserver',
210
+ 'AbortController': 'abortcontroller',
211
+ 'FormData': 'formdata',
212
+ 'URLSearchParams': 'urlsearchparams',
213
+ 'URL': 'url',
214
+
215
+ // Fetch API
216
+ 'fetch': 'fetch',
217
+ 'Request': 'fetch',
218
+ 'Response': 'fetch',
219
+ 'Headers': 'fetch',
220
+
221
+ // File APIs
222
+ 'Blob': 'fileapi',
223
+ 'File': 'fileapi',
224
+ 'FileReader': 'filereader',
225
+
226
+ // Storage APIs
227
+ 'localStorage': 'localstorage',
228
+ 'sessionStorage': 'sessionstorage',
229
+ 'indexedDB': 'indexeddb',
230
+
231
+ // Crypto APIs
232
+ 'crypto': 'cryptography',
233
+ 'crypto.getRandomValues': 'getrandomvalues',
234
+ 'crypto.subtle': 'subtlecrypto',
235
+
236
+ // Performance APIs
237
+ 'performance': 'high-resolution-time',
238
+ 'performance.now': 'high-resolution-time',
239
+ 'PerformanceObserver': 'performance-observer',
240
+
241
+ // Audio/Video APIs
242
+ 'AudioContext': 'audio-api',
243
+ 'MediaRecorder': 'mediarecorder',
244
+ 'MediaSource': 'mediasource',
245
+ 'HTMLMediaElement': 'audio',
246
+
247
+ // Modern JavaScript APIs
248
+ 'structuredClone': 'structured-clone',
249
+ 'WeakRef': 'weakrefs',
250
+ 'FinalizationRegistry': 'weakrefs',
251
+ 'AggregateError': 'promise-any',
252
+
253
+ // ECMAScript features
254
+ 'optional-chaining': 'optional-chaining',
255
+ 'nullish-coalescing': 'nullish-coalescing',
256
+ 'private-fields': 'private-class-fields',
257
+ 'private-methods': 'private-class-methods',
258
+ 'top-level-await': 'top-level-await',
259
+ 'dynamic-import': 'es6-module-dynamic-import',
260
+ 'bigint': 'bigint',
261
+ 'numeric-separators': 'numeric-separators',
262
+
263
+ // Intl APIs
264
+ 'Intl.DateTimeFormat': 'internationalization',
265
+ 'Intl.NumberFormat': 'internationalization',
266
+ 'Intl.Collator': 'internationalization',
267
+ 'Intl.PluralRules': 'intl-pluralrules',
268
+ 'Intl.RelativeTimeFormat': 'intl-relativetimeformat',
269
+ 'Intl.ListFormat': 'intl-listformat',
270
+ 'Intl.Locale': 'intl-locale',
271
+
272
+ // Streams API
273
+ 'ReadableStream': 'streams',
274
+ 'WritableStream': 'streams',
275
+ 'TransformStream': 'streams',
276
+
277
+ // Web Components
278
+ 'customElements': 'custom-elementsv1',
279
+ 'ShadowRoot': 'shadowdomv1',
280
+ 'HTMLTemplateElement': 'template',
281
+
282
+ // Pointer Events
283
+ 'PointerEvent': 'pointer',
284
+ 'setPointerCapture': 'pointer',
285
+
286
+ // Touch Events
287
+ 'TouchEvent': 'touch',
288
+
289
+ // Gamepad API
290
+ 'navigator.getGamepads': 'gamepad',
291
+ 'Gamepad': 'gamepad',
292
+
293
+ // Battery API
294
+ 'navigator.getBattery': 'battery-status',
295
+ 'BatteryManager': 'battery-status',
296
+
297
+ // Device APIs
298
+ 'DeviceOrientationEvent': 'deviceorientation',
299
+ 'DeviceMotionEvent': 'devicemotion'
300
+ };
301
+
302
+ // HTML Elements mapping
303
+ const htmlElementMap = {
304
+ 'dialog': 'dialog',
305
+ 'details': 'details',
306
+ 'summary': 'details',
307
+ 'main': 'html5semantic',
308
+ 'article': 'html5semantic',
309
+ 'section': 'html5semantic',
310
+ 'nav': 'html5semantic',
311
+ 'aside': 'html5semantic',
312
+ 'header': 'html5semantic',
313
+ 'footer': 'html5semantic',
314
+ 'figure': 'html5semantic',
315
+ 'figcaption': 'html5semantic',
316
+ 'time': 'html5semantic',
317
+ 'mark': 'html5semantic',
318
+ 'progress': 'progressmeter',
319
+ 'meter': 'progressmeter',
320
+ 'canvas': 'canvas',
321
+ 'video': 'video',
322
+ 'audio': 'audio',
323
+ 'source': 'video',
324
+ 'track': 'video-track',
325
+ 'picture': 'picture',
326
+ 'datalist': 'datalist',
327
+ 'output': 'form-validation',
328
+ 'template': 'template',
329
+ 'slot': 'shadowdomv1'
330
+ };
331
+
332
+ // HTML Attributes mapping
333
+ const htmlAttributeMap = {
334
+ 'loading': 'loading-lazy-attr',
335
+ 'decoding': 'img-decode-async',
336
+ 'fetchpriority': 'priority-hints',
337
+ 'enterkeyhint': 'mdn-html_global_attributes_enterkeyhint',
338
+ 'inputmode': 'input-inputmode',
339
+ 'autocomplete': 'form-attribute-autocomplete',
340
+ 'crossorigin': 'cors',
341
+ 'integrity': 'subresource-integrity',
342
+ 'referrerpolicy': 'referrer-policy'
343
+ };
344
+
345
+ // At-rules mapping
346
+ const atRuleMap = {
347
+ '@supports': 'css-featurequeries',
348
+ '@container': 'container-queries',
349
+ '@media': 'css-mediaqueries',
350
+ '@import': 'css-import',
351
+ '@keyframes': 'css-animation',
352
+ '@font-face': 'fontface',
353
+ '@layer': 'css-cascade-layers'
354
+ };
355
+
356
+ // Combine all mappings
357
+ Object.entries(cssPropertyMap).forEach(([key, value]) => map.set(key, value));
358
+ Object.entries(cssSelectorMap).forEach(([key, value]) => map.set(key, value));
359
+ Object.entries(jsApiMap).forEach(([key, value]) => map.set(key, value));
360
+ Object.entries(htmlElementMap).forEach(([key, value]) => map.set(key, value));
361
+ Object.entries(htmlAttributeMap).forEach(([key, value]) => map.set(key, value));
362
+ Object.entries(atRuleMap).forEach(([key, value]) => map.set(key, value));
363
+
364
+ return map;
365
+ }
366
+
367
+ /**
368
+ * Build patterns to identify framework-specific features
369
+ */
370
+ private buildFrameworkPatterns(): RegExp[] {
371
+ return [
372
+ // React patterns
373
+ /^use[A-Z]/, // React hooks (useState, useEffect, etc.)
374
+ /^React/, // React namespace
375
+ /^jsx/, // JSX elements
376
+ /^_jsx/, // JSX runtime
377
+ /^Component$/, // React.Component
378
+ /^PureComponent$/, // React.PureComponent
379
+ /^Fragment$/, // React.Fragment
380
+ /^createElement$/, // React.createElement
381
+ /^cloneElement$/, // React.cloneElement
382
+ /^ReactDOM/, // ReactDOM namespace
383
+
384
+ // Vue patterns
385
+ /^ref$/, // Vue ref
386
+ /^reactive$/, // Vue reactive
387
+ /^computed$/, // Vue computed
388
+ /^watch$/, // Vue watch
389
+ /^onMounted$/, // Vue lifecycle
390
+ /^onUnmounted$/, // Vue lifecycle
391
+ /^defineComponent$/, // Vue defineComponent
392
+ /^defineProps$/, // Vue defineProps
393
+ /^defineEmits$/, // Vue defineEmits
394
+ /^nextTick$/, // Vue nextTick
395
+ /^provide$/, // Vue provide
396
+ /^inject$/, // Vue inject
397
+ /^toRef$/, // Vue toRef
398
+ /^toRefs$/, // Vue toRefs
399
+ /^unref$/, // Vue unref
400
+ /^isRef$/, // Vue isRef
401
+ /^useRouter$/, // Vue Router
402
+ /^useRoute$/, // Vue Router
403
+ /^useStore$/, // Vuex/Pinia
404
+
405
+ // Svelte patterns
406
+ /^writable$/, // Svelte stores
407
+ /^readable$/, // Svelte stores
408
+ /^derived$/, // Svelte stores
409
+ /^onMount$/, // Svelte lifecycle
410
+ /^onDestroy$/, // Svelte lifecycle
411
+ /^beforeUpdate$/, // Svelte lifecycle
412
+ /^afterUpdate$/, // Svelte lifecycle
413
+ /^tick$/, // Svelte tick
414
+ /^setContext$/, // Svelte context
415
+ /^getContext$/, // Svelte context
416
+ /^createEventDispatcher$/, // Svelte events
417
+ /^goto$/, // SvelteKit
418
+ /^page$/, // SvelteKit
419
+ /^navigating$/, // SvelteKit
420
+
421
+ // Angular patterns (for future support)
422
+ /^ng[A-Z]/, // Angular directives
423
+ /^Injectable$/, // Angular Injectable
424
+ /^Component$/, // Angular Component (when in Angular context)
425
+ /^Directive$/, // Angular Directive
426
+ /^Pipe$/, // Angular Pipe
427
+
428
+ // Framework directive patterns
429
+ /^v-/, // Vue directives
430
+ /^bind:/, // Svelte directives
431
+ /^on:/, // Svelte directives
432
+ /^use:/, // Svelte directives
433
+ /^\*ng/, // Angular structural directives
434
+ /^\[/, // Angular property binding
435
+ /^\(/, // Angular event binding
436
+ ];
437
+ }
438
+
439
+ /**
440
+ * Check if a feature is framework-specific
441
+ */
442
+ private isFrameworkSpecific(featureName: string): boolean {
443
+ return this.FRAMEWORK_SPECIFIC_PATTERNS.some(pattern => pattern.test(featureName));
444
+ }
445
+
446
+ /**
447
+ * Map detected feature to web-features ID
448
+ */
449
+ private mapToWebFeatureId(featureName: string): string | null {
450
+ // Direct mapping
451
+ if (this.FEATURE_ID_MAP.has(featureName)) {
452
+ return this.FEATURE_ID_MAP.get(featureName)!;
453
+ }
454
+
455
+ // Handle CSS custom properties
456
+ if (featureName.startsWith('--')) {
457
+ return 'css-variables';
458
+ }
459
+
460
+ // Handle member expressions (e.g., 'navigator.geolocation')
461
+ if (featureName.includes('.')) {
462
+ const parts = featureName.split('.');
463
+ const lastPart = parts[parts.length - 1];
464
+
465
+ // Try mapping the full expression first
466
+ if (this.FEATURE_ID_MAP.has(featureName)) {
467
+ return this.FEATURE_ID_MAP.get(featureName)!;
468
+ }
469
+
470
+ // Try mapping just the method/property name
471
+ if (lastPart && this.FEATURE_ID_MAP.has(lastPart)) {
472
+ return this.FEATURE_ID_MAP.get(lastPart)!;
473
+ }
474
+
475
+ // Try mapping the object name
476
+ const objectName = parts[0];
477
+ if (objectName && this.FEATURE_ID_MAP.has(objectName)) {
478
+ return this.FEATURE_ID_MAP.get(objectName)!;
479
+ }
480
+ }
481
+
482
+ // Check if the feature exists directly in web-features
483
+ if (webFeatures[featureName]) {
484
+ return featureName;
485
+ }
486
+
487
+ return null;
488
+ }
489
+
490
+ /**
491
+ * Enhance context information for better display
492
+ */
493
+ private enhanceContext(context: string, type: 'css' | 'js' | 'html'): string {
494
+ // Limit context length
495
+ const maxLength = 100;
496
+ if (context.length > maxLength) {
497
+ context = context.substring(0, maxLength) + '...';
498
+ }
499
+
500
+ // Add type-specific formatting
501
+ switch (type) {
502
+ case 'css':
503
+ return context.includes(':') ? context : `${context}: ...`;
504
+ case 'js':
505
+ return context;
506
+ case 'html':
507
+ return context.startsWith('<') ? context : `<${context}>`;
508
+ default:
509
+ return context;
510
+ }
511
+ }
512
+
513
+ /**
514
+ * Create batches for concurrent processing
515
+ */
516
+ private createBatches<T>(items: T[], batchSize: number): T[][] {
517
+ const batches: T[][] = [];
518
+ for (let i = 0; i < items.length; i += batchSize) {
519
+ batches.push(items.slice(i, i + batchSize));
520
+ }
521
+ return batches;
522
+ }
523
+
524
+ /**
525
+ * Remove duplicate features based on feature ID, file, and line
526
+ */
527
+ private deduplicateFeatures(features: DetectedFeature[]): DetectedFeature[] {
528
+ const seen = new Set<string>();
529
+ return features.filter(feature => {
530
+ const key = `${feature.feature}:${feature.file}:${feature.line}:${feature.column}`;
531
+ if (seen.has(key)) {
532
+ return false;
533
+ }
534
+ seen.add(key);
535
+ return true;
536
+ });
537
+ }
538
+
539
+ /**
540
+ * Get all supported web-features IDs for validation
541
+ */
542
+ getSupportedFeatures(): string[] {
543
+ return Object.keys(webFeatures);
544
+ }
545
+
546
+ /**
547
+ * Check if a specific feature ID is supported by web-features
548
+ */
549
+ isFeatureSupported(featureId: string): boolean {
550
+ return featureId in webFeatures;
551
+ }
552
+
553
+ /**
554
+ * Get feature data from web-features package
555
+ */
556
+ getFeatureData(featureId: string): any {
557
+ return webFeatures[featureId] || null;
558
+ }
559
+ }
@@ -0,0 +1,8 @@
1
+ // Parser exports
2
+ export * from './parser.js';
3
+ export * from './react-parser.js';
4
+ export * from './vue-parser.js';
5
+ export * from './svelte-parser.js';
6
+ export * from './vanilla-parser.js';
7
+ export * from './feature-validator.js';
8
+ export * from './parser-manager.js';