Contribution Guide
Relevant source files
The following files were used as context for generating this wiki page:This guide provides instructions and best practices for contributing to the QR-Tool project. The project is a professional QR code generator built with React and Vite, emphasizing security, a rich feature set, and a high degree of customization. All processing is performed client-side, with no backend server required.
Contributions are welcome, but please adhere to the guidelines outlined in this document to ensure code quality, consistency, and security. For a high-level overview of the project, please see the README.md. For security-specific information, refer to the Security Policy.
Sources: README.md
Getting Started
To begin contributing, you need to set up the development environment on your local machine.
Sources: README.md:37-55
Prerequisites
- Node.js >= 16.x
- npm, yarn, or pnpm
Sources: README.md:38-40
Installation and Setup
- Fork & Clone: Fork the repository and then clone it to your local machine.
git clone <your-fork-url> cd QR-Tool - Install Dependencies: Install the project's dependencies using npm.
npm install - Run Development Server: Start the Vite development server.
npm run dev - Access the Application: Open your browser and navigate to the local address provided by Vite (typically
http://localhost:5173).
Sources: README.md:43-55
Available Scripts
The project includes several npm scripts to aid in development, testing, and building.
| Script | Description |
|---|---|
npm run dev | Starts the Vite development server. |
npm run build | Builds the application for production in the dist/ directory. |
npm run preview | Serves the production build locally for previewing. |
npm run lint | Runs ESLint to check for code style and quality issues. |
npm test | Runs the Vitest test suite once. |
npm run test:watch | Runs the Vitest test suite in watch mode. |
npm audit | Checks for security vulnerabilities in dependencies. |
Sources: package.json:6-12, README.md:144-151
Contribution Workflow
The standard contribution workflow follows the fork-and-pull model.
This diagram illustrates the recommended steps for submitting a contribution.
Sources: README.md:162-167
Project Structure
The project follows a standard Vite/React application structure.
qr-tool-vite/
├── public/ # Static assets (e.g., _headers for CSP)
├── src/
│ ├── assets/ # Images, fonts
│ ├── components/ # Reusable React components
│ ├── hooks/ # Custom React hooks
│ ├── utils/ # Utility functions (helpers, scanner logic)
│ ├── App.jsx # Main application component
│ ├── main.jsx # Application entry point
│ └── index.css # Global styles
├── tests/ # Test files for utilities
├── index.html
├── package.json
└── vite.config.js
Sources: README.md:68-86
Key Components
The application's UI is built from several key React components.
This diagram shows how the main App.jsx component orchestrates state and passes data to child components like QrPreview and ExportPanel.
Sources: src/App.jsx, src/components/QrPreview.jsx, src/components/ExportPanel.jsx
Core Logic
State Management
The primary state is managed within the App.jsx component using React.useState. User preferences and settings are persisted in localStorage via the useLocalStorage custom hook. This hook serializes state to JSON and handles potential storage errors gracefully.
Sources: src/App.jsx:264-278, 287-308
QR Content Generation
The core logic for creating the QR code's string value resides in the generateQRContent function. It takes a type and a data object and returns a formatted string based on the selected QR type.
This flowchart shows the logic of the generateQRContent function.
Sources: src/App.jsx:61-131, src/App.test.js:20-297
Utility Functions
The src/utils/qr-helpers.js file contains essential helper functions for validation, color calculations, and QR code generation logic. When adding new features, check if a suitable utility already exists.
| Function | Description | File |
|---|---|---|
isValidURL() | Validates a URL string. | qr-helpers.js |
isSafeHttpUrl() | Checks if a URL uses http: or https: protocols. | qr-helpers.js |
isValidEmail() | Validates an email address format. | qr-helpers.js |
isValidPhone() | Validates a phone number format. | qr-helpers.js |
isValidLatLng() | Validates latitude and longitude coordinates. | qr-helpers.js |
relLum() | Calculates the relative luminance of a hex color. | qr-helpers.js |
getContrastRatio() | Calculates the WCAG contrast ratio between two luminances. | qr-helpers.js |
pickECC() | Automatically selects the ECC level based on logo size and color contrast. | qr-helpers.js |
estimateDimension() | Estimates the required QR code version (size in modules) based on data length. | qr-helpers.js |
buildDataURL() | Creates a data URL for a canvas, with options for padding and rounded corners. | qr-helpers.js |
buildSVGBlob() | Creates a Blob for an SVG, with options for padding. | qr-helpers.js |
Sources: src/utils/qr-helpers.js, tests/qr-helpers.test.js
Testing
The project uses Vitest for unit testing. Tests are located in the tests/ directory and alongside source files (e.g., src/App.test.js).
- Run all tests:
npm test - Run tests in watch mode:
npm run test:watch
All new logic, especially utility functions and content generation formats, must be accompanied by unit tests. The existing test files (tests/qr-helpers.test.js, src/App.test.js) serve as excellent examples.
Sources: package.json:11-12, README.md:138-142, tests/qr-helpers.test.js, src/App.test.js
Security Guidelines
Security is a top priority. The application has undergone a security audit and implements several protective measures. Contributors must adhere to these security principles.
Sources: SECURITY_AUDIT_REPORT.md, SECURITY.md
Reporting Vulnerabilities
Do NOT open a public GitHub issue for security vulnerabilities. Instead, create a private "Security advisory" on GitHub or contact the author directly at vophuthinhcm@gmail.com.
Sources: SECURITY.md:18-21
Contributor Best Practices
- Input Validation: All user-provided input must be validated. Use the existing helper functions in
qr-helpers.jswhere possible. The security audit confirms that validation is in place for URL, email, phone, and coordinates. - Prevent XSS: The project relies on React's built-in escaping to prevent XSS. Avoid using
dangerouslySetInnerHTML,eval(), or direct DOM manipulation. - Dependency Audits: Run
npm auditto check for vulnerabilities in dependencies before submitting a pull request. - No Sensitive Data in QR: Do not add features that encourage embedding plaintext secrets (passwords, tokens) into QR codes.
- Content Security Policy (CSP): The project uses a strict CSP defined in
public/_headers. Be mindful of this when adding new resources or scripts.
Sources: SECURITY.md:52-73, SECURITY_AUDIT_REPORT.md:70-104, 116-129