metacoding 1.5.1 → 2.0.1
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/CHANGELOG.md +45 -0
- package/README.md +108 -514
- package/lib/cli.d.ts.map +1 -1
- package/lib/cli.js +18 -19
- package/lib/cli.js.map +1 -1
- package/lib/commands/init.d.ts +8 -14
- package/lib/commands/init.d.ts.map +1 -1
- package/lib/commands/init.js +105 -387
- package/lib/commands/init.js.map +1 -1
- package/lib/commands/update.d.ts +9 -9
- package/lib/commands/update.d.ts.map +1 -1
- package/lib/commands/update.js +141 -320
- package/lib/commands/update.js.map +1 -1
- package/lib/services/backup.d.ts +1 -1
- package/lib/services/backup.d.ts.map +1 -1
- package/lib/services/backup.js +10 -6
- package/lib/services/backup.js.map +1 -1
- package/lib/services/filesystem.d.ts.map +1 -1
- package/lib/services/filesystem.js +11 -5
- package/lib/services/filesystem.js.map +1 -1
- package/lib/services/gitignore-manager.js +5 -5
- package/lib/services/gitignore-manager.js.map +1 -1
- package/lib/services/project-detector.d.ts +9 -8
- package/lib/services/project-detector.d.ts.map +1 -1
- package/lib/services/project-detector.js +79 -197
- package/lib/services/project-detector.js.map +1 -1
- package/lib/services/skill-manager.d.ts +23 -0
- package/lib/services/skill-manager.d.ts.map +1 -0
- package/lib/services/skill-manager.js +212 -0
- package/lib/services/skill-manager.js.map +1 -0
- package/lib/types/index.d.ts +5 -15
- package/lib/types/index.d.ts.map +1 -1
- package/package.json +9 -17
- package/skills/metacoding-workflow/SKILL.md +52 -0
- package/skills/metacoding-workflow/agents/openai.yaml +4 -0
- package/skills/metacoding-workflow/assets/templates/changelog-entry.md +6 -0
- package/skills/metacoding-workflow/assets/templates/project-context.md +18 -0
- package/skills/metacoding-workflow/assets/templates/repeated-task-checklist.md +8 -0
- package/skills/metacoding-workflow/assets/templates/task-entry.md +9 -0
- package/skills/metacoding-workflow/assets/templates/test-plan.md +8 -0
- package/skills/metacoding-workflow/references/javascript.md +7 -0
- package/skills/metacoding-workflow/references/node.md +7 -0
- package/skills/metacoding-workflow/references/platform-adaptation.md +37 -0
- package/skills/metacoding-workflow/references/python.md +7 -0
- package/skills/metacoding-workflow/references/react.md +7 -0
- package/skills/metacoding-workflow/references/repository-organization.md +84 -0
- package/skills/metacoding-workflow/references/typescript.md +7 -0
- package/skills/metacoding-workflow/references/workflow-rules.md +54 -0
- package/skills/vendor-templates/claude-agent.md.template +41 -0
- package/lib/services/assistant-adapter.d.ts +0 -18
- package/lib/services/assistant-adapter.d.ts.map +0 -1
- package/lib/services/assistant-adapter.js +0 -246
- package/lib/services/assistant-adapter.js.map +0 -1
- package/lib/services/cursor.d.ts +0 -47
- package/lib/services/cursor.d.ts.map +0 -1
- package/lib/services/cursor.js +0 -314
- package/lib/services/cursor.js.map +0 -1
- package/lib/services/template-manager.d.ts +0 -23
- package/lib/services/template-manager.d.ts.map +0 -1
- package/lib/services/template-manager.js +0 -374
- package/lib/services/template-manager.js.map +0 -1
- package/lib/services/vscode.d.ts +0 -10
- package/lib/services/vscode.d.ts.map +0 -1
- package/lib/services/vscode.js +0 -108
- package/lib/services/vscode.js.map +0 -1
- package/templates/assistants/AGENTS.md +0 -203
- package/templates/assistants/CLAUDE.md +0 -156
- package/templates/assistants/GEMINI.md +0 -193
- package/templates/general/code-review.instructions.md +0 -265
- package/templates/general/copilot-instructions.md +0 -427
- package/templates/general/docs-update.instructions.md +0 -275
- package/templates/general/release.instructions.md +0 -242
- package/templates/general/template.json +0 -9
- package/templates/general/test-runner.instructions.md +0 -188
- package/templates/javascript/javascript.coding.instructions.md +0 -500
- package/templates/javascript/javascript.docs.instructions.md +0 -563
- package/templates/javascript/javascript.testing.instructions.md +0 -686
- package/templates/javascript/template.json +0 -36
- package/templates/node/nodejs.coding.instructions.md +0 -249
- package/templates/node/nodejs.docs.instructions.md +0 -261
- package/templates/node/nodejs.testing.instructions.md +0 -373
- package/templates/node/template.json +0 -23
- package/templates/python/python.coding.instructions.md +0 -338
- package/templates/python/python.docs.instructions.md +0 -1178
- package/templates/python/python.testing.instructions.md +0 -1073
- package/templates/python/template.json +0 -75
- package/templates/react/react.coding.instructions.md +0 -694
- package/templates/react/react.docs.instructions.md +0 -451
- package/templates/react/react.testing.instructions.md +0 -192
- package/templates/react/template.json +0 -14
- package/templates/react/test-runner.instructions.md +0 -135
- package/templates/typescript/template.json +0 -16
- package/templates/typescript/typescript.coding.instructions.md +0 -368
- package/templates/typescript/typescript.docs.instructions.md +0 -760
- package/templates/typescript/typescript.testing.instructions.md +0 -739
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: 'Universal testing guidelines and workflow for all project types'
|
|
3
|
-
applyTo: 'test/**/*'
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Universal Test Execution Guidelines
|
|
7
|
-
|
|
8
|
-
## Pre-Commit Testing Workflow
|
|
9
|
-
|
|
10
|
-
- **Run all tests before committing changes:** Use project-appropriate test command
|
|
11
|
-
- **Ensure tests pass in both development and CI environments**
|
|
12
|
-
- **Fix failing tests before proceeding with commits**
|
|
13
|
-
- **Run specific test suites for targeted changes when appropriate**
|
|
14
|
-
- **Verify test coverage meets project standards**
|
|
15
|
-
|
|
16
|
-
## Test Development Standards
|
|
17
|
-
|
|
18
|
-
- **New Features:** Ensure all new features have corresponding unit tests
|
|
19
|
-
- **Test Coverage:** Aim for high coverage of critical functionality paths
|
|
20
|
-
- **Test Documentation:** Follow standardized table format in `test/test-documentation.md` for all test cases
|
|
21
|
-
- **Test Organization:** Group related tests with clear hierarchy and descriptive names
|
|
22
|
-
- **Language-Specific Patterns:** Follow testing patterns appropriate for the project language
|
|
23
|
-
|
|
24
|
-
## Language-Specific Testing Guidelines
|
|
25
|
-
|
|
26
|
-
For detailed testing frameworks and patterns, refer to language-specific instruction files:
|
|
27
|
-
|
|
28
|
-
- **TypeScript/Node.js:** See `typescript.coding.instructions.md` for Jest patterns and best practices
|
|
29
|
-
- **Python:** See `python.coding.instructions.md` for pytest patterns and fixtures
|
|
30
|
-
- **React/Frontend:** See `react.coding.instructions.md` for React Testing Library and component testing
|
|
31
|
-
|
|
32
|
-
## Test Case Documentation Format
|
|
33
|
-
|
|
34
|
-
All test cases must be documented using the standardized table format across all project types:
|
|
35
|
-
|
|
36
|
-
```markdown
|
|
37
|
-
| Test Case ID | Description | Type | Status |
|
|
38
|
-
| :------------ | :------------------------------------------ | :--- | :-------- |
|
|
39
|
-
| AREA-TYPE-001 | Brief but descriptive test case description | Unit | Completed |
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
## Universal Test Case Naming Conventions
|
|
43
|
-
|
|
44
|
-
### Test Case ID Format: `[AREA]-[TYPE]-[NUMBER]`
|
|
45
|
-
|
|
46
|
-
**Area Prefixes (adapt to your project):**
|
|
47
|
-
|
|
48
|
-
- `CORE` - Core application logic tests
|
|
49
|
-
- `API` - API/Service layer tests
|
|
50
|
-
- `UI` - User interface component tests
|
|
51
|
-
- `DB` - Database/Data layer tests
|
|
52
|
-
- `AUTH` - Authentication/Authorization tests
|
|
53
|
-
- `UTIL` - Utility function tests
|
|
54
|
-
- `CONFIG` - Configuration management tests
|
|
55
|
-
- `DOC` - Documentation Quality tests
|
|
56
|
-
- `E2E` - End-to-End workflow tests
|
|
57
|
-
- `INT` - Integration tests
|
|
58
|
-
|
|
59
|
-
**Type Suffixes:**
|
|
60
|
-
|
|
61
|
-
- `UNIT` - Unit tests (isolated component testing)
|
|
62
|
-
- `INT` - Integration tests (component interaction testing)
|
|
63
|
-
- `E2E` - End-to-end tests (full workflow testing)
|
|
64
|
-
|
|
65
|
-
**Examples:**
|
|
66
|
-
|
|
67
|
-
- `CORE-UNIT-001` - First unit test for Core Logic
|
|
68
|
-
- `API-UNIT-001` - First unit test for API Layer
|
|
69
|
-
- `DB-INT-001` - First integration test for Database
|
|
70
|
-
- `E2E-WF-001` - First end-to-end workflow test
|
|
71
|
-
|
|
72
|
-
### Test Method Naming
|
|
73
|
-
|
|
74
|
-
Use language-appropriate naming conventions:
|
|
75
|
-
|
|
76
|
-
- **TypeScript/JavaScript:** `methodName_scenario_expectedOutcome`
|
|
77
|
-
- **Python:** `test_method_name_scenario_expected_outcome`
|
|
78
|
-
- **Consistent Pattern:** Always include what's being tested, the scenario, and expected result
|
|
79
|
-
|
|
80
|
-
## Test Data Management
|
|
81
|
-
|
|
82
|
-
- **Fixtures:** Update test fixtures when data structures change
|
|
83
|
-
- **Realistic Data:** Use realistic data in integration tests to catch real-world issues
|
|
84
|
-
- **Mock Strategy:** Mock external dependencies in unit tests for isolation
|
|
85
|
-
- **Test Environment:** Use separate test environment/database for integration tests
|
|
86
|
-
- **Temporary File Cleanup:** Clean up all temporary test files, debug outputs, and mock data after test execution
|
|
87
|
-
- **Fixture Organization:** Move reusable test data to `/test/fixtures/` directory for proper organization
|
|
88
|
-
|
|
89
|
-
## Test File Hygiene
|
|
90
|
-
|
|
91
|
-
- **No Orphaned Files:** Remove temporary test files created during debugging or development
|
|
92
|
-
- **Debug Output Cleanup:** Remove console output statements and debug files before committing
|
|
93
|
-
- **Test Artifact Management:** Ensure test screenshots, logs, and reports are properly managed or cleaned up
|
|
94
|
-
- **Resource Management:** Properly dispose of file handles, database connections, and other test resources
|
|
95
|
-
- **Documentation Updates:** Remove temporary test documentation and move useful content to proper locations
|
|
96
|
-
|
|
97
|
-
## Test Types and Patterns
|
|
98
|
-
|
|
99
|
-
### Unit Tests
|
|
100
|
-
|
|
101
|
-
- **Purpose:** Test individual functions, methods, and components in isolation
|
|
102
|
-
- **Scope:** Single unit of functionality
|
|
103
|
-
- **Dependencies:** Mock all external dependencies
|
|
104
|
-
- **Speed:** Fast execution (milliseconds per test)
|
|
105
|
-
- **Coverage:** Focus on logic branches and edge cases
|
|
106
|
-
|
|
107
|
-
### Integration Tests
|
|
108
|
-
|
|
109
|
-
- **Purpose:** Test feature workflows and component interactions
|
|
110
|
-
- **Scope:** Multiple components working together
|
|
111
|
-
- **Dependencies:** Use real implementations where practical
|
|
112
|
-
- **Speed:** Moderate execution time
|
|
113
|
-
- **Coverage:** Focus on interface contracts and data flow
|
|
114
|
-
|
|
115
|
-
### End-to-End Tests
|
|
116
|
-
|
|
117
|
-
- **Purpose:** Test complete user scenarios and workflows
|
|
118
|
-
- **Scope:** Full application stack
|
|
119
|
-
- **Dependencies:** Real or production-like environment
|
|
120
|
-
- **Speed:** Slower execution time
|
|
121
|
-
- **Coverage:** Focus on user journeys and critical paths
|
|
122
|
-
|
|
123
|
-
## Performance Testing
|
|
124
|
-
|
|
125
|
-
- **Test Execution Speed:** Keep unit tests fast (language-specific timing guidelines in coding instructions)
|
|
126
|
-
- **Parallel Execution:** Structure tests to run safely in parallel
|
|
127
|
-
- **Resource Cleanup:** Ensure proper cleanup of test resources and temporary data
|
|
128
|
-
- **Memory Management:** Monitor and prevent memory leaks in long-running test suites
|
|
129
|
-
- **CI/CD Optimization:** Consider test execution time in continuous integration
|
|
130
|
-
|
|
131
|
-
## Test Maintenance
|
|
132
|
-
|
|
133
|
-
- **Regular Review:** Periodically review and refactor outdated tests
|
|
134
|
-
- **Documentation:** Document complex test scenarios and their purposes
|
|
135
|
-
- **Continuous Updates:** Update tests when requirements or APIs change
|
|
136
|
-
- **Test Quality:** Apply the same code quality standards to test code as production code
|
|
137
|
-
- **Update test-documentation.md:** Add new test cases to the appropriate table section
|
|
138
|
-
- **Status Tracking:** Update test status as development progresses
|
|
139
|
-
- **Table Format:** Maintain consistent table formatting and column alignment
|
|
140
|
-
- **ID Assignment:** Assign sequential IDs within each area (AREA-TYPE-001, AREA-TYPE-002, etc.)
|
|
141
|
-
|
|
142
|
-
## Cross-Platform Testing Considerations
|
|
143
|
-
|
|
144
|
-
- **Environment Consistency:** Ensure tests pass across development environments
|
|
145
|
-
- **Path Handling:** Use appropriate path handling for different operating systems
|
|
146
|
-
- **Dependency Versions:** Account for version differences across environments
|
|
147
|
-
- **Resource Availability:** Handle different resource constraints across platforms
|
|
148
|
-
|
|
149
|
-
## Test Automation and CI/CD
|
|
150
|
-
|
|
151
|
-
- **Automated Test Execution:** All tests must run automatically in CI/CD pipeline
|
|
152
|
-
- **Test Result Reporting:** Generate and store test reports for analysis
|
|
153
|
-
- **Failure Notification:** Immediate notification for test failures
|
|
154
|
-
- **Coverage Reporting:** Track and report test coverage over time
|
|
155
|
-
- **Quality Gates:** Use test results as quality gates for deployments
|
|
156
|
-
|
|
157
|
-
## Security Testing
|
|
158
|
-
|
|
159
|
-
- **Input Validation Testing:** Test with malicious and edge-case inputs
|
|
160
|
-
- **Authentication Testing:** Verify authentication mechanisms work correctly
|
|
161
|
-
- **Authorization Testing:** Ensure proper access controls
|
|
162
|
-
- **Data Protection Testing:** Verify sensitive data handling
|
|
163
|
-
- **Vulnerability Testing:** Include security-focused test cases
|
|
164
|
-
|
|
165
|
-
## Error Handling and Edge Case Testing
|
|
166
|
-
|
|
167
|
-
- **Boundary Conditions:** Test at the edges of valid input ranges
|
|
168
|
-
- **Error Scenarios:** Test error handling and recovery mechanisms
|
|
169
|
-
- **Network Failures:** Test behavior during network connectivity issues
|
|
170
|
-
- **Resource Exhaustion:** Test behavior under resource constraints
|
|
171
|
-
- **Invalid Input:** Test with malformed or unexpected input data
|
|
172
|
-
|
|
173
|
-
## Test Documentation and Reporting
|
|
174
|
-
|
|
175
|
-
- **Test Case Purpose:** Document why each test exists and what it validates
|
|
176
|
-
- **Test Setup Requirements:** Document any special setup or configuration needed
|
|
177
|
-
- **Known Issues:** Document known test limitations or flaky behaviors
|
|
178
|
-
- **Test Metrics:** Track test execution time, coverage, and success rates
|
|
179
|
-
- **Regular Reporting:** Generate regular test health reports
|
|
180
|
-
|
|
181
|
-
## Best Practices for Test Development
|
|
182
|
-
|
|
183
|
-
- **Test Independence:** Each test should be able to run independently
|
|
184
|
-
- **Descriptive Names:** Use clear, descriptive names for tests and test groups
|
|
185
|
-
- **Single Assertion Focus:** Each test should focus on one specific behavior
|
|
186
|
-
- **Arrange-Act-Assert Pattern:** Structure tests with clear setup, execution, and validation phases
|
|
187
|
-
- **Test Data Isolation:** Avoid test data conflicts between different test runs
|
|
188
|
-
- **Maintainable Tests:** Write tests that are easy to understand and modify
|
|
@@ -1,500 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: 'Modern JavaScript coding standards and best practices for browser and Node.js environments'
|
|
3
|
-
applyTo: 'src/**/*.{js,mjs}'
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Modern JavaScript Development Guidelines
|
|
7
|
-
|
|
8
|
-
## Language and Framework Preferences
|
|
9
|
-
|
|
10
|
-
- **Primary Language:** Modern JavaScript (ES6+/ES2020+)
|
|
11
|
-
- **Code Style:** Follow project's ESLint/Prettier configuration
|
|
12
|
-
- **Target Compatibility:** Node.js 18+, modern browsers (ES2020+)
|
|
13
|
-
- **Module System:** ES modules (import/export) preferred over CommonJS
|
|
14
|
-
|
|
15
|
-
## Core JavaScript Principles
|
|
16
|
-
|
|
17
|
-
- **Modern Syntax:** Use ES6+ features (arrow functions, destructuring, async/await)
|
|
18
|
-
- **Immutability:** Prefer immutable patterns and functional programming concepts
|
|
19
|
-
- **Async Programming:** Use async/await for asynchronous operations, avoid callback hell
|
|
20
|
-
- **Error Handling:** Implement comprehensive error handling with try/catch blocks
|
|
21
|
-
- **Performance:** Consider performance implications of operations and memory usage
|
|
22
|
-
|
|
23
|
-
## Naming Conventions
|
|
24
|
-
|
|
25
|
-
- **Files:** Use kebab-case for file names (e.g., `user-service.js`, `api-client.js`)
|
|
26
|
-
- **Classes:** PascalCase (e.g., `UserService`, `ApiClient`)
|
|
27
|
-
- **Functions/Methods:** camelCase (e.g., `getUserById`, `validateInput`)
|
|
28
|
-
- **Variables:** camelCase (e.g., `userId`, `isValid`, `userProfile`)
|
|
29
|
-
- **Constants:** SCREAMING_SNAKE_CASE (e.g., `MAX_RETRY_ATTEMPTS`, `API_BASE_URL`)
|
|
30
|
-
- **Private Methods:** Prefix with underscore (e.g., `_validateData`, `_handleError`)
|
|
31
|
-
|
|
32
|
-
## Modern JavaScript Best Practices
|
|
33
|
-
|
|
34
|
-
### ES6+ Features and Patterns
|
|
35
|
-
|
|
36
|
-
```javascript
|
|
37
|
-
// ✅ Good: Use const/let instead of var
|
|
38
|
-
const API_URL = 'https://api.example.com';
|
|
39
|
-
let userCount = 0;
|
|
40
|
-
|
|
41
|
-
// ✅ Good: Arrow functions for concise syntax
|
|
42
|
-
const users = data.map((user) => user.name);
|
|
43
|
-
const filteredUsers = users.filter((user) => user.active);
|
|
44
|
-
|
|
45
|
-
// ✅ Good: Destructuring assignment
|
|
46
|
-
const {
|
|
47
|
-
name,
|
|
48
|
-
email,
|
|
49
|
-
address: { city },
|
|
50
|
-
} = user;
|
|
51
|
-
const [first, second, ...rest] = items;
|
|
52
|
-
|
|
53
|
-
// ✅ Good: Template literals
|
|
54
|
-
const message = `Welcome ${user.name}, you have ${count} notifications`;
|
|
55
|
-
|
|
56
|
-
// ✅ Good: Spread operator
|
|
57
|
-
const newUser = { ...existingUser, status: 'active' };
|
|
58
|
-
const mergedArray = [...array1, ...array2];
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
### Async/Await Patterns
|
|
62
|
-
|
|
63
|
-
```javascript
|
|
64
|
-
// ✅ Good: Async/await with proper error handling
|
|
65
|
-
async function fetchUserData(userId) {
|
|
66
|
-
try {
|
|
67
|
-
const response = await fetch(`/api/users/${userId}`);
|
|
68
|
-
if (!response.ok) {
|
|
69
|
-
throw new Error(`HTTP error! status: ${response.status}`);
|
|
70
|
-
}
|
|
71
|
-
const userData = await response.json();
|
|
72
|
-
return userData;
|
|
73
|
-
} catch (error) {
|
|
74
|
-
console.error('Failed to fetch user data:', error);
|
|
75
|
-
throw error; // Re-throw to allow caller to handle
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// ✅ Good: Promise.all for concurrent operations
|
|
80
|
-
async function fetchMultipleUsers(userIds) {
|
|
81
|
-
try {
|
|
82
|
-
const userPromises = userIds.map((id) => fetchUserData(id));
|
|
83
|
-
const users = await Promise.all(userPromises);
|
|
84
|
-
return users;
|
|
85
|
-
} catch (error) {
|
|
86
|
-
console.error('Failed to fetch multiple users:', error);
|
|
87
|
-
throw error;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
### Functional Programming Patterns
|
|
93
|
-
|
|
94
|
-
```javascript
|
|
95
|
-
// ✅ Good: Pure functions
|
|
96
|
-
const calculateTotal = (items) =>
|
|
97
|
-
items.reduce((total, item) => total + item.price, 0);
|
|
98
|
-
|
|
99
|
-
// ✅ Good: Higher-order functions
|
|
100
|
-
const withRetry =
|
|
101
|
-
(fn, maxAttempts = 3) =>
|
|
102
|
-
async (...args) => {
|
|
103
|
-
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
104
|
-
try {
|
|
105
|
-
return await fn(...args);
|
|
106
|
-
} catch (error) {
|
|
107
|
-
if (attempt === maxAttempts) throw error;
|
|
108
|
-
await new Promise((resolve) => setTimeout(resolve, 1000 * attempt));
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
// ✅ Good: Composition and chaining
|
|
114
|
-
const processUsers = (users) =>
|
|
115
|
-
users
|
|
116
|
-
.filter((user) => user.active)
|
|
117
|
-
.map((user) => ({
|
|
118
|
-
...user,
|
|
119
|
-
displayName: `${user.firstName} ${user.lastName}`,
|
|
120
|
-
}))
|
|
121
|
-
.sort((a, b) => a.displayName.localeCompare(b.displayName));
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
## Browser-Specific Development
|
|
125
|
-
|
|
126
|
-
### DOM Manipulation Best Practices
|
|
127
|
-
|
|
128
|
-
```javascript
|
|
129
|
-
// ✅ Good: Modern DOM querying
|
|
130
|
-
const userElement = document.querySelector('[data-user-id="123"]');
|
|
131
|
-
const allButtons = document.querySelectorAll('.btn');
|
|
132
|
-
|
|
133
|
-
// ✅ Good: Event delegation
|
|
134
|
-
document.addEventListener('click', (event) => {
|
|
135
|
-
if (event.target.matches('.btn-submit')) {
|
|
136
|
-
handleSubmit(event);
|
|
137
|
-
}
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
// ✅ Good: Modern event handling
|
|
141
|
-
const button = document.getElementById('submit-btn');
|
|
142
|
-
button.addEventListener('click', async (event) => {
|
|
143
|
-
event.preventDefault();
|
|
144
|
-
await handleFormSubmission();
|
|
145
|
-
});
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
### Web APIs and Browser Features
|
|
149
|
-
|
|
150
|
-
```javascript
|
|
151
|
-
// ✅ Good: Fetch API with error handling
|
|
152
|
-
async function apiRequest(url, options = {}) {
|
|
153
|
-
const config = {
|
|
154
|
-
headers: {
|
|
155
|
-
'Content-Type': 'application/json',
|
|
156
|
-
},
|
|
157
|
-
...options,
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
try {
|
|
161
|
-
const response = await fetch(url, config);
|
|
162
|
-
if (!response.ok) {
|
|
163
|
-
throw new Error(`API request failed: ${response.status}`);
|
|
164
|
-
}
|
|
165
|
-
return await response.json();
|
|
166
|
-
} catch (error) {
|
|
167
|
-
console.error('API request error:', error);
|
|
168
|
-
throw error;
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
// ✅ Good: Local storage with error handling
|
|
173
|
-
function saveToStorage(key, data) {
|
|
174
|
-
try {
|
|
175
|
-
localStorage.setItem(key, JSON.stringify(data));
|
|
176
|
-
} catch (error) {
|
|
177
|
-
console.error('Failed to save to localStorage:', error);
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
function loadFromStorage(key) {
|
|
182
|
-
try {
|
|
183
|
-
const data = localStorage.getItem(key);
|
|
184
|
-
return data ? JSON.parse(data) : null;
|
|
185
|
-
} catch (error) {
|
|
186
|
-
console.error('Failed to load from localStorage:', error);
|
|
187
|
-
return null;
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
## Node.js-Specific Development
|
|
193
|
-
|
|
194
|
-
### Module Patterns
|
|
195
|
-
|
|
196
|
-
```javascript
|
|
197
|
-
// ✅ Good: ES module exports
|
|
198
|
-
export const config = {
|
|
199
|
-
port: process.env.PORT || 3000,
|
|
200
|
-
dbUrl: process.env.DATABASE_URL,
|
|
201
|
-
};
|
|
202
|
-
|
|
203
|
-
export class UserService {
|
|
204
|
-
constructor(database) {
|
|
205
|
-
this.db = database;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
async findById(id) {
|
|
209
|
-
return await this.db.users.findById(id);
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
export default UserService;
|
|
214
|
-
|
|
215
|
-
// ✅ Good: Named imports
|
|
216
|
-
import { config } from './config.js';
|
|
217
|
-
import UserService from './user-service.js';
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
### File System and Path Operations
|
|
221
|
-
|
|
222
|
-
```javascript
|
|
223
|
-
import { promises as fs } from 'fs';
|
|
224
|
-
import path from 'path';
|
|
225
|
-
import { fileURLToPath } from 'url';
|
|
226
|
-
|
|
227
|
-
// ✅ Good: ES module __dirname equivalent
|
|
228
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
229
|
-
const __dirname = path.dirname(__filename);
|
|
230
|
-
|
|
231
|
-
// ✅ Good: Async file operations
|
|
232
|
-
async function readConfigFile(filename) {
|
|
233
|
-
try {
|
|
234
|
-
const configPath = path.join(__dirname, 'config', filename);
|
|
235
|
-
const data = await fs.readFile(configPath, 'utf8');
|
|
236
|
-
return JSON.parse(data);
|
|
237
|
-
} catch (error) {
|
|
238
|
-
console.error(`Failed to read config file ${filename}:`, error);
|
|
239
|
-
return null;
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
```
|
|
243
|
-
|
|
244
|
-
## Error Handling Patterns
|
|
245
|
-
|
|
246
|
-
### Comprehensive Error Management
|
|
247
|
-
|
|
248
|
-
```javascript
|
|
249
|
-
// ✅ Good: Custom error classes
|
|
250
|
-
class ValidationError extends Error {
|
|
251
|
-
constructor(message, field) {
|
|
252
|
-
super(message);
|
|
253
|
-
this.name = 'ValidationError';
|
|
254
|
-
this.field = field;
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
class ApiError extends Error {
|
|
259
|
-
constructor(message, statusCode, originalError) {
|
|
260
|
-
super(message);
|
|
261
|
-
this.name = 'ApiError';
|
|
262
|
-
this.statusCode = statusCode;
|
|
263
|
-
this.originalError = originalError;
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
// ✅ Good: Error boundary patterns
|
|
268
|
-
async function withErrorHandling(operation, context = '') {
|
|
269
|
-
try {
|
|
270
|
-
return await operation();
|
|
271
|
-
} catch (error) {
|
|
272
|
-
console.error(`Error in ${context}:`, error);
|
|
273
|
-
|
|
274
|
-
// Re-throw known errors
|
|
275
|
-
if (error instanceof ValidationError || error instanceof ApiError) {
|
|
276
|
-
throw error;
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
// Wrap unknown errors
|
|
280
|
-
throw new Error(`Unexpected error in ${context}: ${error.message}`);
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
```
|
|
284
|
-
|
|
285
|
-
## Security Best Practices
|
|
286
|
-
|
|
287
|
-
### Input Validation and Sanitization
|
|
288
|
-
|
|
289
|
-
```javascript
|
|
290
|
-
// ✅ Good: Input validation
|
|
291
|
-
function validateEmail(email) {
|
|
292
|
-
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
293
|
-
return emailRegex.test(email);
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
function sanitizeInput(input) {
|
|
297
|
-
if (typeof input !== 'string') return '';
|
|
298
|
-
return input.trim().replace(/[<>]/g, '');
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
// ✅ Good: Data validation with schema
|
|
302
|
-
function validateUserData(userData) {
|
|
303
|
-
const errors = [];
|
|
304
|
-
|
|
305
|
-
if (!userData.name || typeof userData.name !== 'string') {
|
|
306
|
-
errors.push('Name is required and must be a string');
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
if (!validateEmail(userData.email)) {
|
|
310
|
-
errors.push('Valid email address is required');
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
if (errors.length > 0) {
|
|
314
|
-
throw new ValidationError('Validation failed', errors);
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
return {
|
|
318
|
-
name: sanitizeInput(userData.name),
|
|
319
|
-
email: userData.email.toLowerCase(),
|
|
320
|
-
};
|
|
321
|
-
}
|
|
322
|
-
```
|
|
323
|
-
|
|
324
|
-
## Performance Optimization
|
|
325
|
-
|
|
326
|
-
### Efficient Data Operations
|
|
327
|
-
|
|
328
|
-
```javascript
|
|
329
|
-
// ✅ Good: Efficient array operations
|
|
330
|
-
const processLargeDataset = (items) => {
|
|
331
|
-
// Use for...of for better performance with large arrays
|
|
332
|
-
const results = [];
|
|
333
|
-
for (const item of items) {
|
|
334
|
-
if (item.active) {
|
|
335
|
-
results.push(transformItem(item));
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
return results;
|
|
339
|
-
};
|
|
340
|
-
|
|
341
|
-
// ✅ Good: Debouncing for performance
|
|
342
|
-
function debounce(func, wait) {
|
|
343
|
-
let timeout;
|
|
344
|
-
return function executedFunction(...args) {
|
|
345
|
-
const later = () => {
|
|
346
|
-
clearTimeout(timeout);
|
|
347
|
-
func.apply(this, args);
|
|
348
|
-
};
|
|
349
|
-
clearTimeout(timeout);
|
|
350
|
-
timeout = setTimeout(later, wait);
|
|
351
|
-
};
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
// ✅ Good: Memoization for expensive operations
|
|
355
|
-
function memoize(fn) {
|
|
356
|
-
const cache = new Map();
|
|
357
|
-
return function memoized(...args) {
|
|
358
|
-
const key = JSON.stringify(args);
|
|
359
|
-
if (cache.has(key)) {
|
|
360
|
-
return cache.get(key);
|
|
361
|
-
}
|
|
362
|
-
const result = fn.apply(this, args);
|
|
363
|
-
cache.set(key, result);
|
|
364
|
-
return result;
|
|
365
|
-
};
|
|
366
|
-
}
|
|
367
|
-
```
|
|
368
|
-
|
|
369
|
-
## Build Tools and Development Workflow
|
|
370
|
-
|
|
371
|
-
### Package.json Best Practices
|
|
372
|
-
|
|
373
|
-
```javascript
|
|
374
|
-
// ✅ Good: Well-structured package.json scripts
|
|
375
|
-
{
|
|
376
|
-
"scripts": {
|
|
377
|
-
"dev": "vite",
|
|
378
|
-
"build": "vite build",
|
|
379
|
-
"preview": "vite preview",
|
|
380
|
-
"test": "jest",
|
|
381
|
-
"test:watch": "jest --watch",
|
|
382
|
-
"test:coverage": "jest --coverage",
|
|
383
|
-
"lint": "eslint src/**/*.js",
|
|
384
|
-
"lint:fix": "eslint src/**/*.js --fix",
|
|
385
|
-
"format": "prettier --write src/**/*.js"
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
```
|
|
389
|
-
|
|
390
|
-
### Environment Configuration
|
|
391
|
-
|
|
392
|
-
```javascript
|
|
393
|
-
// ✅ Good: Environment configuration
|
|
394
|
-
const config = {
|
|
395
|
-
development: {
|
|
396
|
-
apiUrl: 'http://localhost:3000/api',
|
|
397
|
-
debug: true,
|
|
398
|
-
},
|
|
399
|
-
production: {
|
|
400
|
-
apiUrl: 'https://api.production.com',
|
|
401
|
-
debug: false,
|
|
402
|
-
},
|
|
403
|
-
test: {
|
|
404
|
-
apiUrl: 'http://localhost:3001/api',
|
|
405
|
-
debug: false,
|
|
406
|
-
},
|
|
407
|
-
};
|
|
408
|
-
|
|
409
|
-
export default config[process.env.NODE_ENV || 'development'];
|
|
410
|
-
```
|
|
411
|
-
|
|
412
|
-
## Anti-Patterns to Avoid
|
|
413
|
-
|
|
414
|
-
### Common JavaScript Pitfalls
|
|
415
|
-
|
|
416
|
-
```javascript
|
|
417
|
-
// ❌ Bad: Callback hell
|
|
418
|
-
getData(function (a) {
|
|
419
|
-
getMoreData(a, function (b) {
|
|
420
|
-
getEvenMoreData(b, function (c) {
|
|
421
|
-
// Nested callbacks are hard to maintain
|
|
422
|
-
});
|
|
423
|
-
});
|
|
424
|
-
});
|
|
425
|
-
|
|
426
|
-
// ❌ Bad: Modifying function parameters
|
|
427
|
-
function updateUser(user) {
|
|
428
|
-
user.lastUpdated = new Date(); // Mutates input parameter
|
|
429
|
-
return user;
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
// ❌ Bad: Using var and global variables
|
|
433
|
-
var globalCounter = 0; // Avoid var and globals
|
|
434
|
-
function incrementCounter() {
|
|
435
|
-
globalCounter++; // Side effects are hard to track
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
// ❌ Bad: Not handling promise rejections
|
|
439
|
-
fetch('/api/data'); // Unhandled promise
|
|
440
|
-
|
|
441
|
-
// ❌ Bad: Mixing async patterns
|
|
442
|
-
async function mixedPatterns() {
|
|
443
|
-
const data = await fetch('/api/data');
|
|
444
|
-
data.then((result) => {
|
|
445
|
-
// Don't mix async/await with .then()
|
|
446
|
-
console.log(result);
|
|
447
|
-
});
|
|
448
|
-
}
|
|
449
|
-
```
|
|
450
|
-
|
|
451
|
-
## Documentation Standards
|
|
452
|
-
|
|
453
|
-
### JSDoc Documentation
|
|
454
|
-
|
|
455
|
-
```javascript
|
|
456
|
-
/**
|
|
457
|
-
* Calculates the total price including tax
|
|
458
|
-
* @param {number} basePrice - The base price before tax
|
|
459
|
-
* @param {number} taxRate - The tax rate as a decimal (e.g., 0.08 for 8%)
|
|
460
|
-
* @returns {number} The total price including tax
|
|
461
|
-
* @throws {Error} When basePrice or taxRate is negative
|
|
462
|
-
* @example
|
|
463
|
-
* const total = calculateTotalPrice(100, 0.08); // Returns 108
|
|
464
|
-
*/
|
|
465
|
-
function calculateTotalPrice(basePrice, taxRate) {
|
|
466
|
-
if (basePrice < 0 || taxRate < 0) {
|
|
467
|
-
throw new Error('Price and tax rate must be non-negative');
|
|
468
|
-
}
|
|
469
|
-
return basePrice * (1 + taxRate);
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
/**
|
|
473
|
-
* User service for managing user data
|
|
474
|
-
* @class
|
|
475
|
-
*/
|
|
476
|
-
class UserService {
|
|
477
|
-
/**
|
|
478
|
-
* Creates a new UserService instance
|
|
479
|
-
* @param {Object} database - Database connection instance
|
|
480
|
-
*/
|
|
481
|
-
constructor(database) {
|
|
482
|
-
this.db = database;
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
/**
|
|
486
|
-
* Retrieves a user by ID
|
|
487
|
-
* @param {string} userId - The unique user identifier
|
|
488
|
-
* @returns {Promise<Object|null>} User object or null if not found
|
|
489
|
-
* @async
|
|
490
|
-
*/
|
|
491
|
-
async getUserById(userId) {
|
|
492
|
-
try {
|
|
493
|
-
return await this.db.users.findById(userId);
|
|
494
|
-
} catch (error) {
|
|
495
|
-
console.error(`Failed to fetch user ${userId}:`, error);
|
|
496
|
-
return null;
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
```
|