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.
- package/.eslintrc.json +25 -0
- package/.prettierrc +8 -0
- package/README.md +94 -0
- package/bin/base.js +494 -0
- package/dist/ai/fix-manager.d.ts +67 -0
- package/dist/ai/fix-manager.d.ts.map +1 -0
- package/dist/ai/fix-manager.js +326 -0
- package/dist/ai/fix-manager.js.map +1 -0
- package/dist/ai/gemini-analyzer.d.ts +116 -0
- package/dist/ai/gemini-analyzer.d.ts.map +1 -0
- package/dist/ai/gemini-analyzer.js +572 -0
- package/dist/ai/gemini-analyzer.js.map +1 -0
- package/dist/ai/index.d.ts +4 -0
- package/dist/ai/index.d.ts.map +1 -0
- package/dist/ai/index.js +5 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/ai/jules-implementer.d.ts +115 -0
- package/dist/ai/jules-implementer.d.ts.map +1 -0
- package/dist/ai/jules-implementer.js +387 -0
- package/dist/ai/jules-implementer.js.map +1 -0
- package/dist/commands/automation.d.ts +5 -0
- package/dist/commands/automation.d.ts.map +1 -0
- package/dist/commands/automation.js +305 -0
- package/dist/commands/automation.js.map +1 -0
- package/dist/commands/check.d.ts +9 -0
- package/dist/commands/check.d.ts.map +1 -0
- package/dist/commands/check.js +113 -0
- package/dist/commands/check.js.map +1 -0
- package/dist/commands/config.d.ts +11 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +324 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/fix.d.ts +9 -0
- package/dist/commands/fix.d.ts.map +1 -0
- package/dist/commands/fix.js +207 -0
- package/dist/commands/fix.js.map +1 -0
- package/dist/commands/index.d.ts +6 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +7 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/init.d.ts +9 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +125 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/core/api-key-manager.d.ts +83 -0
- package/dist/core/api-key-manager.d.ts.map +1 -0
- package/dist/core/api-key-manager.js +244 -0
- package/dist/core/api-key-manager.js.map +1 -0
- package/dist/core/baseguard.d.ts +46 -0
- package/dist/core/baseguard.d.ts.map +1 -0
- package/dist/core/baseguard.js +132 -0
- package/dist/core/baseguard.js.map +1 -0
- package/dist/core/baseline-checker.d.ts +63 -0
- package/dist/core/baseline-checker.d.ts.map +1 -0
- package/dist/core/baseline-checker.js +502 -0
- package/dist/core/baseline-checker.js.map +1 -0
- package/dist/core/cache-manager.d.ts +88 -0
- package/dist/core/cache-manager.d.ts.map +1 -0
- package/dist/core/cache-manager.js +213 -0
- package/dist/core/cache-manager.js.map +1 -0
- package/dist/core/configuration.d.ts +140 -0
- package/dist/core/configuration.d.ts.map +1 -0
- package/dist/core/configuration.js +474 -0
- package/dist/core/configuration.js.map +1 -0
- package/dist/core/directory-filter.d.ts +90 -0
- package/dist/core/directory-filter.d.ts.map +1 -0
- package/dist/core/directory-filter.js +319 -0
- package/dist/core/directory-filter.js.map +1 -0
- package/dist/core/error-handler.d.ts +110 -0
- package/dist/core/error-handler.d.ts.map +1 -0
- package/dist/core/error-handler.js +392 -0
- package/dist/core/error-handler.js.map +1 -0
- package/dist/core/file-processor.d.ts +80 -0
- package/dist/core/file-processor.d.ts.map +1 -0
- package/dist/core/file-processor.js +259 -0
- package/dist/core/file-processor.js.map +1 -0
- package/dist/core/gitignore-manager.d.ts +44 -0
- package/dist/core/gitignore-manager.d.ts.map +1 -0
- package/dist/core/gitignore-manager.js +147 -0
- package/dist/core/gitignore-manager.js.map +1 -0
- package/dist/core/index.d.ts +13 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +13 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/lazy-loader.d.ts +68 -0
- package/dist/core/lazy-loader.d.ts.map +1 -0
- package/dist/core/lazy-loader.js +260 -0
- package/dist/core/lazy-loader.js.map +1 -0
- package/dist/core/memory-manager.d.ts +1 -0
- package/dist/core/memory-manager.d.ts.map +1 -0
- package/dist/core/memory-manager.js +2 -0
- package/dist/core/memory-manager.js.map +1 -0
- package/dist/core/startup-optimizer.d.ts +45 -0
- package/dist/core/startup-optimizer.d.ts.map +1 -0
- package/dist/core/startup-optimizer.js +140 -0
- package/dist/core/startup-optimizer.js.map +1 -0
- package/dist/git/automation-engine.d.ts +58 -0
- package/dist/git/automation-engine.d.ts.map +1 -0
- package/dist/git/automation-engine.js +318 -0
- package/dist/git/automation-engine.js.map +1 -0
- package/dist/git/github-manager.d.ts +71 -0
- package/dist/git/github-manager.d.ts.map +1 -0
- package/dist/git/github-manager.js +226 -0
- package/dist/git/github-manager.js.map +1 -0
- package/dist/git/hook-manager.d.ts +43 -0
- package/dist/git/hook-manager.d.ts.map +1 -0
- package/dist/git/hook-manager.js +191 -0
- package/dist/git/hook-manager.js.map +1 -0
- package/dist/git/index.d.ts +4 -0
- package/dist/git/index.d.ts.map +1 -0
- package/dist/git/index.js +5 -0
- package/dist/git/index.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/parsers/feature-validator.d.ts +60 -0
- package/dist/parsers/feature-validator.d.ts.map +1 -0
- package/dist/parsers/feature-validator.js +483 -0
- package/dist/parsers/feature-validator.js.map +1 -0
- package/dist/parsers/index.d.ts +8 -0
- package/dist/parsers/index.d.ts.map +1 -0
- package/dist/parsers/index.js +9 -0
- package/dist/parsers/index.js.map +1 -0
- package/dist/parsers/parser-manager.d.ts +103 -0
- package/dist/parsers/parser-manager.d.ts.map +1 -0
- package/dist/parsers/parser-manager.js +321 -0
- package/dist/parsers/parser-manager.js.map +1 -0
- package/dist/parsers/parser.d.ts +23 -0
- package/dist/parsers/parser.d.ts.map +1 -0
- package/dist/parsers/parser.js +6 -0
- package/dist/parsers/parser.js.map +1 -0
- package/dist/parsers/react-parser.d.ts +22 -0
- package/dist/parsers/react-parser.d.ts.map +1 -0
- package/dist/parsers/react-parser.js +307 -0
- package/dist/parsers/react-parser.js.map +1 -0
- package/dist/parsers/svelte-parser.d.ts +33 -0
- package/dist/parsers/svelte-parser.d.ts.map +1 -0
- package/dist/parsers/svelte-parser.js +408 -0
- package/dist/parsers/svelte-parser.js.map +1 -0
- package/dist/parsers/vanilla-parser.d.ts +31 -0
- package/dist/parsers/vanilla-parser.d.ts.map +1 -0
- package/dist/parsers/vanilla-parser.js +590 -0
- package/dist/parsers/vanilla-parser.js.map +1 -0
- package/dist/parsers/vue-parser.d.ts +9 -0
- package/dist/parsers/vue-parser.d.ts.map +1 -0
- package/dist/parsers/vue-parser.js +16 -0
- package/dist/parsers/vue-parser.js.map +1 -0
- package/dist/terminal-header.d.ts +12 -0
- package/dist/terminal-header.js +45 -0
- package/dist/types/index.d.ts +83 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +5 -0
- package/dist/types/index.js.map +1 -0
- package/dist/ui/components.d.ts +133 -0
- package/dist/ui/components.d.ts.map +1 -0
- package/dist/ui/components.js +482 -0
- package/dist/ui/components.js.map +1 -0
- package/dist/ui/help.d.ts +11 -0
- package/dist/ui/help.d.ts.map +1 -0
- package/dist/ui/help.js +161 -0
- package/dist/ui/help.js.map +1 -0
- package/dist/ui/index.d.ts +5 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +5 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/prompts.d.ts +63 -0
- package/dist/ui/prompts.d.ts.map +1 -0
- package/dist/ui/prompts.js +611 -0
- package/dist/ui/prompts.js.map +1 -0
- package/dist/ui/terminal-header.d.ts +13 -0
- package/dist/ui/terminal-header.d.ts.map +1 -0
- package/dist/ui/terminal-header.js +46 -0
- package/dist/ui/terminal-header.js.map +1 -0
- package/package.json +80 -0
- package/src/ai/__tests__/gemini-analyzer.test.ts +181 -0
- package/src/ai/fix-manager.ts +362 -0
- package/src/ai/gemini-analyzer.ts +671 -0
- package/src/ai/index.ts +4 -0
- package/src/ai/jules-implementer.ts +459 -0
- package/src/commands/automation.ts +344 -0
- package/src/commands/check.ts +299 -0
- package/src/commands/config.ts +365 -0
- package/src/commands/fix.ts +234 -0
- package/src/commands/index.ts +6 -0
- package/src/commands/init.ts +142 -0
- package/src/commands/status.ts +0 -0
- package/src/core/api-key-manager.ts +298 -0
- package/src/core/baseguard.ts +742 -0
- package/src/core/baseline-checker.ts +563 -0
- package/src/core/cache-manager.ts +270 -0
- package/src/core/configuration-recovery.ts +676 -0
- package/src/core/configuration.ts +559 -0
- package/src/core/debug-logger.ts +590 -0
- package/src/core/directory-filter.ts +421 -0
- package/src/core/error-handler.ts +517 -0
- package/src/core/file-processor.ts +331 -0
- package/src/core/gitignore-manager.ts +169 -0
- package/src/core/graceful-degradation-manager.ts +596 -0
- package/src/core/index.ts +13 -0
- package/src/core/lazy-loader.ts +307 -0
- package/src/core/logger.ts +0 -0
- package/src/core/memory-manager.ts +294 -0
- package/src/core/startup-optimizer.ts +173 -0
- package/src/core/system-error-handler.ts +746 -0
- package/src/git/automation-engine.ts +361 -0
- package/src/git/github-manager.ts +260 -0
- package/src/git/hook-manager.ts +210 -0
- package/src/git/index.ts +4 -0
- package/src/index.ts +8 -0
- package/src/parsers/feature-validator.ts +559 -0
- package/src/parsers/index.ts +8 -0
- package/src/parsers/parser-manager.ts +419 -0
- package/src/parsers/parser.ts +26 -0
- package/src/parsers/react-parser-optimized.ts +161 -0
- package/src/parsers/react-parser.ts +359 -0
- package/src/parsers/svelte-parser.ts +506 -0
- package/src/parsers/vanilla-parser.ts +682 -0
- package/src/parsers/vue-parser.ts +472 -0
- package/src/types/index.ts +92 -0
- package/src/ui/components.ts +567 -0
- package/src/ui/help.ts +193 -0
- package/src/ui/index.ts +4 -0
- package/src/ui/prompts.ts +688 -0
- package/src/ui/terminal-header.ts +59 -0
- package/test-config-commands.js +56 -0
- package/test-header-simple.js +33 -0
- package/test-terminal-header.js +12 -0
- package/test-ui.js +29 -0
- package/tests/e2e/baseguard.e2e.test.ts +516 -0
- package/tests/e2e/cross-platform.e2e.test.ts +420 -0
- package/tests/e2e/git-integration.e2e.test.ts +487 -0
- package/tests/fixtures/react-project/package.json +14 -0
- package/tests/fixtures/react-project/src/App.css +76 -0
- package/tests/fixtures/react-project/src/App.tsx +77 -0
- package/tests/fixtures/svelte-project/package.json +11 -0
- package/tests/fixtures/svelte-project/src/App.svelte +369 -0
- package/tests/fixtures/vanilla-project/index.html +76 -0
- package/tests/fixtures/vanilla-project/script.js +331 -0
- package/tests/fixtures/vanilla-project/styles.css +359 -0
- package/tests/fixtures/vue-project/package.json +12 -0
- package/tests/fixtures/vue-project/src/App.vue +216 -0
- package/tsconfig.json +36 -0
- 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';
|