wcag-scanner 1.2.60 → 1.2.61

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/README.md CHANGED
@@ -32,17 +32,30 @@ WCAG Scanner is a powerful accessibility testing tool that helps developers iden
32
32
 
33
33
  ## 📦 Installation
34
34
 
35
- ### Using npm
36
-
37
35
  ```bash
38
- npm i wcag-scanner
39
- ```
36
+ # npm
37
+ npm install wcag-scanner
40
38
 
41
- ### Using yarn
42
- ```bash
39
+ # yarn
43
40
  yarn add wcag-scanner
41
+
42
+ # pnpm
43
+ pnpm add wcag-scanner
44
+ ```
45
+
46
+ > **React users:** React and React DOM are peer dependencies and are already installed in your project — no extra steps needed.
47
+
48
+ ### For the React Dev Overlay
49
+
50
+ Add one line to your app entry point (`main.ts`, `index.js`, `App.tsx`, etc.):
51
+
52
+ ```ts
53
+ import { initWcagOverlay } from 'wcag-scanner/react';
54
+ initWcagOverlay(); // shows a live WCAG inspector in the browser, dev only
44
55
  ```
45
56
 
57
+ The overlay is automatically disabled in production (`NODE_ENV=production`) and never ships to your users.
58
+
46
59
  ## How to use
47
60
  ### CLI Usage Example:
48
61
 
@@ -0,0 +1,11 @@
1
+ import { Violation, FixSuggestion } from "../types";
2
+ /**
3
+ * Generate fix suggestions for accessibility violations
4
+ * @param violation WCAG violation to fix
5
+ * @returns Promise<FixSuggestion> Suggested fix
6
+ */
7
+ export declare function generateFixSuggestion(violation: Violation): Promise<FixSuggestion>;
8
+ declare const _default: {
9
+ generateFixSuggestion: typeof generateFixSuggestion;
10
+ };
11
+ export default _default;
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.generateFixSuggestion = generateFixSuggestion;
7
+ const generative_ai_1 = require("@google/generative-ai");
8
+ const dotenv_1 = __importDefault(require("dotenv"));
9
+ /**
10
+ * @TODO working on AI-powered suggestions, it's still working in progress.
11
+ */
12
+ // Load environment variables from .env file
13
+ dotenv_1.default.config();
14
+ // Get API key from environment
15
+ const apiKey = process.env.GEMINI_API_KEY;
16
+ // Initialize Gemini if API key is available
17
+ let genAI = null;
18
+ let model = null;
19
+ if (apiKey) {
20
+ try {
21
+ genAI = new generative_ai_1.GoogleGenerativeAI(apiKey);
22
+ model = genAI.getGenerativeModel({ model: 'gemini-1.0-pro' });
23
+ console.log('Gemini AI initialized');
24
+ }
25
+ catch (error) {
26
+ console.error('Error initializing Gemini AI:', error);
27
+ }
28
+ }
29
+ /**
30
+ * Generate fix suggestions for accessibility violations
31
+ * @param violation WCAG violation to fix
32
+ * @returns Promise<FixSuggestion> Suggested fix
33
+ */
34
+ async function generateFixSuggestion(violation) {
35
+ // Ig Gemini is not available, use rule-based suggestion
36
+ if (!model) {
37
+ console.log('Gemini AI not available, using rule-based suggestion');
38
+ return generateRuleBasedSuggestion(violation);
39
+ }
40
+ try {
41
+ // Create prompt for Gemini
42
+ const prompt = `
43
+ As a web accessibility expert, I need a fix for this WCAG issue:
44
+ Rule: ${violation.rule || ''}
45
+ Description: ${violation.description || ''}
46
+
47
+ HTML code with issue:
48
+ ${violation.snippet || ''}
49
+
50
+ Please provide a corrected version of the code and a brief explanation.
51
+ `;
52
+ // Generate content with Gemini
53
+ const result = await model.generateContent(prompt);
54
+ const response = result.response.text();
55
+ // Extract code and explanation from response
56
+ const codeMatch = response.match(/```(?:html)?\s*([\s\S]*?)\s*```/);
57
+ const code = codeMatch ? codeMatch[1].trim() : '';
58
+ // Remove code block for clean explanation
59
+ const explanation = response
60
+ .replace(/```(?:html)?\s*[\s\S]*?\s*```/g, '')
61
+ .trim();
62
+ return {
63
+ code: code || 'Unable to generate specific code fix',
64
+ description: 'AI-suggested fix',
65
+ explanation: explanation || 'Fix the accessibility issue as suggested by the AI'
66
+ };
67
+ }
68
+ catch (error) {
69
+ console.error('Error generating fix suggestion with Gemini AI:', error);
70
+ return generateRuleBasedSuggestion(violation);
71
+ }
72
+ }
73
+ /**
74
+ * Generate basic rule-based suggestion as fallback
75
+ * @param violation WCAG violation
76
+ * @returns FixSuggestion
77
+ */
78
+ function generateRuleBasedSuggestion(violation) {
79
+ var _a;
80
+ const rule = violation.rule || '';
81
+ if (rule.includes('img-alt')) {
82
+ return {
83
+ code: ((_a = violation.snippet) === null || _a === void 0 ? void 0 : _a.replace(/<img/i, '<img alt="Descriptive text"')) || '',
84
+ description: 'Add alt text to image',
85
+ explanation: 'Images need alternative text for screen readers'
86
+ };
87
+ }
88
+ if (rule.includes('contrast')) {
89
+ return {
90
+ code: '/* Increase color contrast to at least 4.5:1 ratio */',
91
+ description: 'Increase color contrast',
92
+ explanation: 'Text needs sufficient contrast with its background'
93
+ };
94
+ }
95
+ return {
96
+ code: '',
97
+ description: 'Fix needed',
98
+ explanation: violation.help || 'Fix this issue to improve accessibility'
99
+ };
100
+ }
101
+ exports.default = {
102
+ generateFixSuggestion
103
+ };
package/dist/cli/index.js CHANGED
@@ -8,9 +8,6 @@ const commander_1 = require("commander");
8
8
  const __1 = require("..");
9
9
  const fs_1 = __importDefault(require("fs"));
10
10
  const path_1 = __importDefault(require("path"));
11
- const http_1 = __importDefault(require("http"));
12
- const https_1 = __importDefault(require("https"));
13
- const url_1 = require("url");
14
11
  const __2 = require("..");
15
12
  // Try to load package.json for version information
16
13
  let version = '0.1.0';
@@ -155,73 +152,9 @@ commander_1.program
155
152
  process.exit(1);
156
153
  }
157
154
  });
158
- // Helper function to fetch URL content
159
- async function fetchUrl(urlString) {
160
- return new Promise((resolve, reject) => {
161
- const url = new url_1.URL(urlString);
162
- const client = url.protocol === 'https:' ? https_1.default : http_1.default;
163
- const req = client.get(urlString, (res) => {
164
- if (res.statusCode !== 200) {
165
- reject(new Error(`Request failed with status code ${res.statusCode}`));
166
- return;
167
- }
168
- let data = '';
169
- res.on('data', (chunk) => {
170
- data += chunk;
171
- });
172
- res.on('end', () => {
173
- resolve(data);
174
- });
175
- });
176
- req.on('error', (err) => {
177
- reject(err);
178
- });
179
- req.end();
180
- });
181
- }
182
155
  // If no arguments provided, show help
183
156
  if (process.argv.length <= 2) {
184
157
  commander_1.program.help();
185
158
  }
186
159
  // Parse command line arguments
187
160
  commander_1.program.parse(process.argv);
188
- /**
189
- * Fallback function to fetch a URL when the primary method fails
190
- * @param urlString The URL to fetch
191
- * @returns Promise<string> HTML content
192
- */
193
- async function fetchUrlWithFallback(urlString) {
194
- return new Promise((resolve, reject) => {
195
- try {
196
- // Use a simpler approach that ignores some errors
197
- const url = new url_1.URL(urlString);
198
- const options = {
199
- method: 'GET',
200
- headers: {
201
- 'User-Agent': 'Mozilla/5.0 (WCAG Scanner Bot) Chrome/91.0.4472.124'
202
- },
203
- timeout: 10000
204
- };
205
- const client = url.protocol === 'https:' ? https_1.default : http_1.default;
206
- const req = client.request(url, options, (res) => {
207
- let data = '';
208
- res.on('data', (chunk) => {
209
- data += chunk;
210
- });
211
- res.on('end', () => {
212
- // Return whatever we got, even if status code isn't 200
213
- resolve(data || '<html><body><p>Failed to fetch content</p></body></html>');
214
- });
215
- });
216
- req.on('error', () => {
217
- // Provide minimal HTML if we can't fetch anything
218
- resolve('<html><body><p>Failed to fetch content</p></body></html>');
219
- });
220
- req.end();
221
- }
222
- catch (error) {
223
- // Return minimal HTML on any error
224
- resolve('<html><body><p>Failed to fetch content</p></body></html>');
225
- }
226
- });
227
- }
package/dist/index.js CHANGED
@@ -52,9 +52,6 @@ const middleware_1 = __importDefault(require("./middleware"));
52
52
  exports.middleware = middleware_1.default;
53
53
  const fs_1 = __importDefault(require("fs"));
54
54
  const path_1 = __importDefault(require("path"));
55
- const url_1 = require("url");
56
- const http_1 = __importDefault(require("http"));
57
- const https_1 = __importDefault(require("https"));
58
55
  const crypto_1 = __importDefault(require("crypto"));
59
56
  const os_1 = __importDefault(require("os"));
60
57
  /**
@@ -174,34 +171,6 @@ function formatReport(results, format = 'json', options = {}) {
174
171
  function saveReport(report, filePath) {
175
172
  fs_1.default.writeFileSync(filePath, report);
176
173
  }
177
- /**
178
- * Helper function to fetch URL content
179
- * @param urlString URL to fetch
180
- * @returns Promise<string> HTML content
181
- */
182
- async function fetchUrl(urlString) {
183
- return new Promise((resolve, reject) => {
184
- const url = new url_1.URL(urlString);
185
- const client = url.protocol === 'https:' ? https_1.default : http_1.default;
186
- const req = client.get(urlString, (res) => {
187
- if (res.statusCode !== 200) {
188
- reject(new Error(`Request failed with status code ${res.statusCode}`));
189
- return;
190
- }
191
- let data = '';
192
- res.on('data', (chunk) => {
193
- data += chunk;
194
- });
195
- res.on('end', () => {
196
- resolve(data);
197
- });
198
- });
199
- req.on('error', (err) => {
200
- reject(err);
201
- });
202
- req.end();
203
- });
204
- }
205
174
  __exportStar(require("./types"), exports);
206
175
  // Default export with all main functions
207
176
  exports.default = {
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+ export interface WcagDevOverlayProps {
3
+ /** WCAG conformance level (default: 'AA') */
4
+ level?: 'A' | 'AA' | 'AAA';
5
+ /** Subset of rules to run. Omit to run all. */
6
+ rules?: string[];
7
+ /** Corner to anchor the overlay (default: 'bottom-right') */
8
+ position?: 'bottom-right' | 'bottom-left';
9
+ /** Delay in ms between DOM mutation and re-scan (default: 750) */
10
+ debounce?: number;
11
+ }
12
+ export declare const WcagDevOverlay: React.FC<WcagDevOverlayProps>;
13
+ export default WcagDevOverlay;