paymongo-cli 1.2.0 → 1.4.2
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/.github/copilot-instructions.md +95 -0
- package/.github/workflows/ci-cd.yml +2 -46
- package/.github/workflows/ci.yml +1 -1
- package/.github/workflows/release.yml +16 -1
- package/AGENTS.md +418 -0
- package/CHANGELOG.md +331 -185
- package/README.md +94 -13
- package/TESTING.md +222 -0
- package/coverage/base.css +224 -0
- package/coverage/block-navigation.js +87 -0
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +281 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +281 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +210 -0
- package/coverage/lcov.info +5053 -0
- package/coverage/prettify.css +1 -0
- package/coverage/prettify.js +2 -0
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +210 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/commands/config.d.ts +17 -0
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +268 -55
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/dev.d.ts +13 -1
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +40 -56
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/env.d.ts +4 -0
- package/dist/commands/env.d.ts.map +1 -0
- package/dist/commands/env.js +106 -0
- package/dist/commands/env.js.map +1 -0
- package/dist/commands/generate.js +1184 -0
- package/dist/commands/init.d.ts +11 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +33 -33
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/login.d.ts +17 -1
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +2 -17
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/payments.d.ts +37 -0
- package/dist/commands/payments.d.ts.map +1 -1
- package/dist/commands/payments.js +367 -32
- package/dist/commands/payments.js.map +1 -1
- package/dist/commands/team/index.d.ts.map +1 -1
- package/dist/commands/team/index.js +192 -95
- package/dist/commands/team/index.js.map +1 -1
- package/dist/commands/trigger.d.ts.map +1 -1
- package/dist/commands/trigger.js +239 -75
- package/dist/commands/trigger.js.map +1 -1
- package/dist/commands/webhooks.d.ts +19 -0
- package/dist/commands/webhooks.d.ts.map +1 -1
- package/dist/commands/webhooks.js +246 -70
- package/dist/commands/webhooks.js.map +1 -1
- package/dist/index.js +56 -32
- package/dist/index.js.map +1 -1
- package/dist/services/analytics/service.js +6 -8
- package/dist/services/api/client.d.ts +6 -8
- package/dist/services/api/client.d.ts.map +1 -1
- package/dist/services/api/client.js +20 -131
- package/dist/services/api/client.js.map +1 -1
- package/dist/services/api/rate-limiter.d.ts +64 -0
- package/dist/services/api/rate-limiter.d.ts.map +1 -0
- package/dist/services/api/rate-limiter.js +83 -0
- package/dist/services/api/rate-limiter.js.map +1 -0
- package/dist/services/api/undici-client.d.ts +39 -0
- package/dist/services/api/undici-client.d.ts.map +1 -0
- package/dist/services/api/undici-client.js +294 -0
- package/dist/services/api/undici-client.js.map +1 -0
- package/dist/services/config/manager.js +1 -16
- package/dist/services/dev/process-manager.js +0 -32
- package/dist/services/github/client.d.ts +41 -0
- package/dist/services/github/client.d.ts.map +1 -1
- package/dist/services/github/client.js +28 -0
- package/dist/services/github/client.js.map +1 -1
- package/dist/services/payments/simulator.d.ts +28 -0
- package/dist/services/payments/simulator.d.ts.map +1 -0
- package/dist/services/payments/simulator.js +115 -0
- package/dist/services/payments/simulator.js.map +1 -0
- package/dist/services/team/service.d.ts +44 -0
- package/dist/services/team/service.d.ts.map +1 -0
- package/dist/services/team/service.js +153 -0
- package/dist/services/team/service.js.map +1 -0
- package/dist/types/paymongo.d.ts +36 -3
- package/dist/types/paymongo.d.ts.map +1 -1
- package/dist/types/paymongo.js +0 -1
- package/dist/types/schemas.js +0 -8
- package/dist/utils/bulk.d.ts +62 -0
- package/dist/utils/bulk.d.ts.map +1 -0
- package/dist/utils/bulk.js +123 -0
- package/dist/utils/bulk.js.map +1 -0
- package/dist/utils/cache.js +4 -16
- package/dist/utils/constants.js +2 -13
- package/dist/utils/errors.d.ts.map +1 -1
- package/dist/utils/errors.js +22 -7
- package/dist/utils/errors.js.map +1 -1
- package/dist/utils/logger.d.ts +3 -1
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +38 -25
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/spinner.js +0 -1
- package/dist/utils/validator.js +0 -3
- package/dist/utils/webhook-store.d.ts +22 -0
- package/dist/utils/webhook-store.d.ts.map +1 -0
- package/dist/utils/webhook-store.js +57 -0
- package/dist/utils/webhook-store.js.map +1 -0
- package/package.json +75 -76
- package/jest.config.ts +0 -30
- package/web/index.html +0 -688
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# PayMongo CLI - AI Agent Instructions
|
|
2
|
+
|
|
3
|
+
## Project Overview
|
|
4
|
+
PayMongo CLI is a TypeScript-based developer tool for PayMongo payment integration with local webhook forwarding via ngrok tunneling. It uses **ESM modules** (`"type": "module"`) with Commander.js for CLI commands.
|
|
5
|
+
|
|
6
|
+
## Architecture
|
|
7
|
+
|
|
8
|
+
### Code Structure
|
|
9
|
+
```
|
|
10
|
+
src/
|
|
11
|
+
├── commands/ # CLI commands (commander.js) - one file per top-level command
|
|
12
|
+
├── services/ # Core business logic
|
|
13
|
+
│ ├── api/ # ApiClient - PayMongo V1 API wrapper with retries & caching
|
|
14
|
+
│ ├── config/ # ConfigManager - .paymongo file handling via cosmiconfig
|
|
15
|
+
│ └── web/ # Express + Socket.io for GUI dashboard
|
|
16
|
+
├── types/ # TypeScript definitions + Zod schemas
|
|
17
|
+
└── utils/ # Shared utilities (errors, logging, cache, validation)
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### Key Patterns
|
|
21
|
+
|
|
22
|
+
**Error Handling** - Always use custom error classes from `src/utils/errors.ts`:
|
|
23
|
+
```typescript
|
|
24
|
+
import { PayMongoError, NetworkError, ConfigError, ApiKeyError } from '../utils/errors.js';
|
|
25
|
+
throw new PayMongoError('User-friendly message', 'ERROR_CODE', 400);
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
**Retry Logic** - Use `withRetry()` for network operations:
|
|
29
|
+
```typescript
|
|
30
|
+
import { withRetry } from '../utils/errors.js';
|
|
31
|
+
const result = await withRetry(() => apiCall(), { maxRetries: 3, silent: true });
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**Lazy Loading** - Import heavy dependencies inside functions to keep CLI startup fast (<100ms):
|
|
35
|
+
```typescript
|
|
36
|
+
// ✓ Correct - lazy load inside action
|
|
37
|
+
.action(async () => {
|
|
38
|
+
const { confirm } = await import('@inquirer/prompts');
|
|
39
|
+
});
|
|
40
|
+
// ✗ Wrong - top-level import slows startup
|
|
41
|
+
import { confirm } from '@inquirer/prompts';
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**ESM Imports** - Always use `.js` extension for local imports:
|
|
45
|
+
```typescript
|
|
46
|
+
import ConfigManager from '../services/config/manager.js';
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Configuration
|
|
50
|
+
- Project config: `.paymongo` (JSON, managed via `ConfigManager`)
|
|
51
|
+
- Global credentials: `~/.paymongo/credentials.enc` (AES-256-CBC encrypted)
|
|
52
|
+
- Validation: Zod schemas in `src/types/schemas.ts`
|
|
53
|
+
|
|
54
|
+
## Development Workflow
|
|
55
|
+
|
|
56
|
+
### Commands
|
|
57
|
+
```bash
|
|
58
|
+
npm run build # Compile TypeScript
|
|
59
|
+
npm run dev # Watch mode compilation
|
|
60
|
+
npm link # Test CLI globally as 'paymongo'
|
|
61
|
+
npm test # Jest with ESM (--experimental-vm-modules)
|
|
62
|
+
npm run lint:fix # ESLint auto-fix
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Testing Strategy
|
|
66
|
+
- **Mocking ESM**: Use `jest.unstable_mockModule()` before dynamic imports
|
|
67
|
+
- Structure: `tests/unit/`, `tests/integration/`, `tests/e2e/`
|
|
68
|
+
- Mock external services (axios, ngrok, filesystem)
|
|
69
|
+
|
|
70
|
+
Example test pattern:
|
|
71
|
+
```typescript
|
|
72
|
+
jest.unstable_mockModule('axios', () => ({ default: mockAxios }));
|
|
73
|
+
const { ApiClient } = await import('../../src/services/api/client.js');
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Code Conventions
|
|
77
|
+
|
|
78
|
+
### TypeScript
|
|
79
|
+
- Strict mode enabled with `noImplicitAny`, `noUncheckedIndexedAccess`
|
|
80
|
+
- Avoid `any` - use proper types from `src/types/paymongo.ts`
|
|
81
|
+
- Config validation via Zod: `validateConfig()` from `src/types/schemas.ts`
|
|
82
|
+
|
|
83
|
+
### Commit Messages
|
|
84
|
+
Follow conventional commits: `feat:`, `fix:`, `docs:`, `test:`, `refactor:`
|
|
85
|
+
|
|
86
|
+
### Security
|
|
87
|
+
- Never log API keys or sensitive data
|
|
88
|
+
- Use `ConfigManager` for credential access
|
|
89
|
+
- Keep `.paymongo` and `.env` in `.gitignore`
|
|
90
|
+
|
|
91
|
+
## Key Files Reference
|
|
92
|
+
- [src/services/api/client.ts](src/services/api/client.ts) - API wrapper with interceptors
|
|
93
|
+
- [src/utils/errors.ts](src/utils/errors.ts) - Error classes + `withRetry()`
|
|
94
|
+
- [src/types/schemas.ts](src/types/schemas.ts) - Zod validation schemas
|
|
95
|
+
- [src/services/config/manager.ts](src/services/config/manager.ts) - Config file handling
|
|
@@ -12,7 +12,7 @@ jobs:
|
|
|
12
12
|
strategy:
|
|
13
13
|
matrix:
|
|
14
14
|
os: [ubuntu-latest, windows-latest, macos-latest]
|
|
15
|
-
node-version: [
|
|
15
|
+
node-version: [20, 22]
|
|
16
16
|
|
|
17
17
|
steps:
|
|
18
18
|
- name: Checkout code
|
|
@@ -39,50 +39,6 @@ jobs:
|
|
|
39
39
|
|
|
40
40
|
- name: Upload coverage reports
|
|
41
41
|
uses: codecov/codecov-action@v3
|
|
42
|
-
if: matrix.os == 'ubuntu-latest' && matrix.node-version == '
|
|
42
|
+
if: matrix.os == 'ubuntu-latest' && matrix.node-version == '20'
|
|
43
43
|
with:
|
|
44
44
|
file: ./coverage/lcov.info
|
|
45
|
-
|
|
46
|
-
release:
|
|
47
|
-
needs: test
|
|
48
|
-
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
|
|
49
|
-
runs-on: ubuntu-latest
|
|
50
|
-
|
|
51
|
-
steps:
|
|
52
|
-
- name: Checkout code
|
|
53
|
-
uses: actions/checkout@v4
|
|
54
|
-
|
|
55
|
-
- name: Setup Node.js
|
|
56
|
-
uses: actions/setup-node@v4
|
|
57
|
-
with:
|
|
58
|
-
node-version: 18
|
|
59
|
-
registry-url: 'https://registry.npmjs.org'
|
|
60
|
-
|
|
61
|
-
- name: Install dependencies
|
|
62
|
-
run: npm ci
|
|
63
|
-
|
|
64
|
-
- name: Build project
|
|
65
|
-
run: npm run build
|
|
66
|
-
|
|
67
|
-
- name: Run tests
|
|
68
|
-
run: npm test -- --passWithNoTests
|
|
69
|
-
|
|
70
|
-
- name: Publish to npm
|
|
71
|
-
run: npm publish --access public
|
|
72
|
-
env:
|
|
73
|
-
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
74
|
-
|
|
75
|
-
- name: Create GitHub release
|
|
76
|
-
uses: actions/create-release@v1
|
|
77
|
-
env:
|
|
78
|
-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
79
|
-
with:
|
|
80
|
-
tag_name: v${{ github.run_number }}
|
|
81
|
-
release_name: Release v${{ github.run_number }}
|
|
82
|
-
body: |
|
|
83
|
-
## Changes
|
|
84
|
-
- Automated release from CI/CD pipeline
|
|
85
|
-
- All tests passed
|
|
86
|
-
- Code quality checks completed
|
|
87
|
-
draft: false
|
|
88
|
-
prerelease: false
|
package/.github/workflows/ci.yml
CHANGED
|
@@ -33,6 +33,21 @@ jobs:
|
|
|
33
33
|
env:
|
|
34
34
|
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
35
35
|
|
|
36
|
+
- name: Setup for GitHub Packages
|
|
37
|
+
uses: actions/setup-node@v4
|
|
38
|
+
with:
|
|
39
|
+
node-version: 20.x
|
|
40
|
+
registry-url: 'https://npm.pkg.github.com'
|
|
41
|
+
scope: '@leodyversemilla07'
|
|
42
|
+
|
|
43
|
+
- name: Publish to GitHub Packages
|
|
44
|
+
run: |
|
|
45
|
+
# Change package name to scoped version for GitHub Packages
|
|
46
|
+
npm pkg set name='@leodyversemilla07/paymongo-cli'
|
|
47
|
+
npm publish
|
|
48
|
+
env:
|
|
49
|
+
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
50
|
+
|
|
36
51
|
- name: Create GitHub Release
|
|
37
52
|
uses: actions/create-release@v1
|
|
38
53
|
env:
|
|
@@ -43,7 +58,7 @@ jobs:
|
|
|
43
58
|
body: |
|
|
44
59
|
## Changes
|
|
45
60
|
|
|
46
|
-
See [CHANGELOG.md](https://github.com/
|
|
61
|
+
See [CHANGELOG.md](https://github.com/leodyversemilla07/paymongo-cli/blob/main/CHANGELOG.md) for details.
|
|
47
62
|
|
|
48
63
|
## Installation
|
|
49
64
|
|
package/AGENTS.md
ADDED
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
# PayMongo CLI - Agent Guidelines
|
|
2
|
+
|
|
3
|
+
## Project Overview
|
|
4
|
+
|
|
5
|
+
PayMongo CLI is a developer-first command-line tool for PayMongo payment integration with local webhook forwarding. It uses **ESM modules** with Commander.js for CLI commands and provides both terminal and web-based interfaces.
|
|
6
|
+
|
|
7
|
+
**Tech Stack**: TypeScript, Node.js 18+, Express, Socket.io, ngrok, Axios, Zod, Winston, Jest
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Build & Development Commands
|
|
12
|
+
|
|
13
|
+
### Primary Commands
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm run build # Compile TypeScript to dist/
|
|
17
|
+
npm run dev # Watch mode compilation
|
|
18
|
+
npm start # Run compiled CLI
|
|
19
|
+
npm link # Test CLI globally during development
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### Quality Assurance
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm run lint # ESLint check
|
|
26
|
+
npm run lint:fix # Auto-fix ESLint issues
|
|
27
|
+
npm run format # Prettier formatting
|
|
28
|
+
npm run test # Run all tests
|
|
29
|
+
npm run test:watch # Jest watch mode
|
|
30
|
+
npm run benchmark # Performance benchmarking
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Testing Specific Files
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# Run single test file
|
|
37
|
+
npm run test -- tests/unit/errors.test.ts
|
|
38
|
+
npm run test -- tests/integration/config-commands.test.ts
|
|
39
|
+
|
|
40
|
+
# Run tests matching pattern
|
|
41
|
+
npm run test -- --testNamePattern="retry"
|
|
42
|
+
|
|
43
|
+
# Run tests for specific directory
|
|
44
|
+
npm run test -- tests/unit/
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Code Style Guidelines
|
|
50
|
+
|
|
51
|
+
### TypeScript Configuration
|
|
52
|
+
|
|
53
|
+
- **Target**: ES2022 with NodeNext modules
|
|
54
|
+
- **Strict mode**: Enabled with all strict checks
|
|
55
|
+
- **Module resolution**: NodeNext (ESM)
|
|
56
|
+
- **Imports**: Use `.js` extension for local imports (required for ESM)
|
|
57
|
+
- **Declarations**: Generate `.d.ts` files for npm publishing
|
|
58
|
+
|
|
59
|
+
### Import/Export Patterns
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
// ✓ Correct: ESM with .js extensions
|
|
63
|
+
import ConfigManager from '../services/config/manager.js';
|
|
64
|
+
import { PayMongoError } from '../utils/errors.js';
|
|
65
|
+
|
|
66
|
+
// ✗ Wrong: Missing .js extension
|
|
67
|
+
import ConfigManager from '../services/config/manager';
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Error Handling
|
|
71
|
+
|
|
72
|
+
Always use custom error classes from `src/utils/errors.ts`:
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
import { PayMongoError, NetworkError, ConfigError, ApiKeyError } from '../utils/errors.js';
|
|
76
|
+
|
|
77
|
+
try {
|
|
78
|
+
// operation
|
|
79
|
+
} catch (error) {
|
|
80
|
+
throw new PayMongoError('User-friendly message', 'ERROR_CODE', 400);
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Retry Logic
|
|
85
|
+
|
|
86
|
+
Use `withRetry()` for network operations:
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
import { withRetry } from '../utils/errors.js';
|
|
90
|
+
|
|
91
|
+
const result = await withRetry(() => apiCall(), { maxRetries: 3, delayMs: 1000, silent: true });
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Lazy Loading
|
|
95
|
+
|
|
96
|
+
Import heavy dependencies inside functions to keep CLI startup fast (<100ms):
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
// ✓ Correct: Lazy load @inquirer/prompts
|
|
100
|
+
.action(async () => {
|
|
101
|
+
const { confirm } = await import('@inquirer/prompts');
|
|
102
|
+
// use confirm
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
// ✗ Wrong: Top-level import slows startup
|
|
106
|
+
import { confirm } from '@inquirer/prompts';
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Naming Conventions
|
|
110
|
+
|
|
111
|
+
- **Files**: kebab-case (`config-manager.ts`, `api-client.ts`)
|
|
112
|
+
- **Classes**: PascalCase (`ApiClient`, `ConfigManager`)
|
|
113
|
+
- **Functions/Methods**: camelCase (`validateApiKey()`, `createWebhook()`)
|
|
114
|
+
- **Constants**: SCREAMING_SNAKE_CASE (`REQUEST_TIMEOUT`)
|
|
115
|
+
- **Interfaces**: PascalCase with `I` prefix (`IPayMongoConfig`)
|
|
116
|
+
- **Types**: PascalCase (`PayMongoConfig`, `ApiResponse<T>`)
|
|
117
|
+
|
|
118
|
+
### Type Safety
|
|
119
|
+
|
|
120
|
+
- **No `any`**: Use proper types from `src/types/paymongo.ts`
|
|
121
|
+
- **Optional properties**: Use `?:` instead of `| undefined`
|
|
122
|
+
- **Exact types**: Enable `exactOptionalPropertyTypes`
|
|
123
|
+
- **Indexed access**: Enable `noUncheckedIndexedAccess`
|
|
124
|
+
- **Non-null assertions**: Warn on `@typescript-eslint/no-non-null-assertion`
|
|
125
|
+
|
|
126
|
+
### Code Structure
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
src/
|
|
130
|
+
├── commands/ # CLI commands (one file per command)
|
|
131
|
+
│ ├── init.ts # paymongo init
|
|
132
|
+
│ ├── dev.ts # paymongo dev
|
|
133
|
+
│ └── ...
|
|
134
|
+
├── services/ # Business logic
|
|
135
|
+
│ ├── api/ # PayMongo API client
|
|
136
|
+
│ ├── config/ # Configuration management
|
|
137
|
+
│ ├── web/ # Express + Socket.io server
|
|
138
|
+
│ └── github/ # GitHub integration
|
|
139
|
+
├── types/ # TypeScript definitions + Zod schemas
|
|
140
|
+
├── utils/ # Shared utilities
|
|
141
|
+
└── index.ts # CLI entry point
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Async/Await Patterns
|
|
145
|
+
|
|
146
|
+
- **Always async**: Use `async/await` over Promises
|
|
147
|
+
- **Error propagation**: Let errors bubble up, handle at command level
|
|
148
|
+
- **Cleanup**: Use try/finally for resource cleanup
|
|
149
|
+
|
|
150
|
+
### Validation
|
|
151
|
+
|
|
152
|
+
Use Zod schemas from `src/types/schemas.ts`:
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
import { validateConfig } from '../types/schemas.js';
|
|
156
|
+
|
|
157
|
+
const config = validateConfig(input);
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Testing Guidelines
|
|
163
|
+
|
|
164
|
+
### Test Structure
|
|
165
|
+
|
|
166
|
+
```
|
|
167
|
+
tests/
|
|
168
|
+
├── unit/ # Unit tests (single functions/classes)
|
|
169
|
+
├── integration/ # Integration tests (command end-to-end)
|
|
170
|
+
└── e2e/ # End-to-end tests (full CLI workflows)
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Mocking ESM Modules
|
|
174
|
+
|
|
175
|
+
Use `jest.unstable_mockModule()` before dynamic imports:
|
|
176
|
+
|
|
177
|
+
```typescript
|
|
178
|
+
jest.unstable_mockModule('axios', () => ({
|
|
179
|
+
default: mockAxios,
|
|
180
|
+
}));
|
|
181
|
+
|
|
182
|
+
const { ApiClient } = await import('../../src/services/api/client.js');
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Test Patterns
|
|
186
|
+
|
|
187
|
+
- **Imports**: Use `@jest/globals` explicitly
|
|
188
|
+
- **Setup/Teardown**: Use `beforeEach`/`afterEach`
|
|
189
|
+
- **Fake timers**: Use `jest.useFakeTimers()` for time-dependent code
|
|
190
|
+
- **Console suppression**: Mock `console.log` during tests
|
|
191
|
+
- **Async tests**: Use `async/await` with `jest.advanceTimersByTimeAsync()`
|
|
192
|
+
|
|
193
|
+
### Coverage Requirements
|
|
194
|
+
|
|
195
|
+
- **Statements**: >80%
|
|
196
|
+
- **Branches**: >75%
|
|
197
|
+
- **Functions**: >85%
|
|
198
|
+
- **Lines**: >80%
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## Commit Guidelines
|
|
203
|
+
|
|
204
|
+
### Conventional Commits
|
|
205
|
+
|
|
206
|
+
```
|
|
207
|
+
feat: add payment intent creation command
|
|
208
|
+
fix: handle network timeouts in webhook forwarding
|
|
209
|
+
docs: update installation guide for Windows
|
|
210
|
+
test: add integration tests for config commands
|
|
211
|
+
refactor: extract webhook validation to separate module
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Atomic Commits
|
|
215
|
+
|
|
216
|
+
- **One logical change** per commit
|
|
217
|
+
- **Test with changes** when possible
|
|
218
|
+
- **Update docs** if behavior changes
|
|
219
|
+
- **Reference issues** in commit messages
|
|
220
|
+
|
|
221
|
+
### Commit Content
|
|
222
|
+
|
|
223
|
+
- **First line**: <50 chars, imperative mood
|
|
224
|
+
- **Body**: Explain what and why (not how)
|
|
225
|
+
- **Footer**: Breaking changes, issue references
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## Pull Request Process
|
|
230
|
+
|
|
231
|
+
### PR Template
|
|
232
|
+
|
|
233
|
+
Use the provided `.github/PULL_REQUEST_TEMPLATE.md` which includes:
|
|
234
|
+
|
|
235
|
+
- Description of changes
|
|
236
|
+
- Testing instructions
|
|
237
|
+
- Screenshots (if UI changes)
|
|
238
|
+
- Breaking changes notice
|
|
239
|
+
|
|
240
|
+
### Review Checklist
|
|
241
|
+
|
|
242
|
+
- [ ] **Tests pass**: `npm test`
|
|
243
|
+
- [ ] **Lint clean**: `npm run lint`
|
|
244
|
+
- [ ] **Type check**: `npm run build`
|
|
245
|
+
- [ ] **Documentation updated**: README, API docs
|
|
246
|
+
- [ ] **Breaking changes documented**: If any
|
|
247
|
+
|
|
248
|
+
### Code Review Focus
|
|
249
|
+
|
|
250
|
+
- **Type safety**: No `any`, proper error handling
|
|
251
|
+
- **Performance**: Lazy loading, efficient algorithms
|
|
252
|
+
- **Security**: No credential logging, proper validation
|
|
253
|
+
- **Testing**: Adequate coverage, proper mocking
|
|
254
|
+
- **Architecture**: Follows established patterns
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
|
|
258
|
+
## Security Guidelines
|
|
259
|
+
|
|
260
|
+
### API Keys & Credentials
|
|
261
|
+
|
|
262
|
+
- **Never log**: API keys, secrets, or sensitive data
|
|
263
|
+
- **Encryption**: Use `ConfigManager` for credential storage
|
|
264
|
+
- **Validation**: Validate keys on input, not in logs
|
|
265
|
+
- **Environment**: Separate test/live environments clearly
|
|
266
|
+
|
|
267
|
+
### Network Security
|
|
268
|
+
|
|
269
|
+
- **Timeouts**: 30-second default for API calls
|
|
270
|
+
- **Retries**: Exponential backoff with jitter
|
|
271
|
+
- **Headers**: Proper User-Agent, Content-Type
|
|
272
|
+
- **HTTPS**: All external requests use HTTPS
|
|
273
|
+
|
|
274
|
+
### File System Security
|
|
275
|
+
|
|
276
|
+
- **Permissions**: Check write permissions before operations
|
|
277
|
+
- **Paths**: Validate and sanitize file paths
|
|
278
|
+
- **Sensitive files**: Add to `.gitignore` (.env, .paymongo)
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
## Performance Guidelines
|
|
283
|
+
|
|
284
|
+
### Startup Time
|
|
285
|
+
|
|
286
|
+
- **Target**: <100ms CLI startup
|
|
287
|
+
- **Lazy loading**: Heavy imports inside command actions
|
|
288
|
+
- **Minimal bundle**: Only essential code in main entry
|
|
289
|
+
|
|
290
|
+
### Memory Usage
|
|
291
|
+
|
|
292
|
+
- **Caching**: 2-minute TTL for API responses
|
|
293
|
+
- **Cleanup**: Proper resource cleanup in finally blocks
|
|
294
|
+
- **Streaming**: Use streams for large data processing
|
|
295
|
+
|
|
296
|
+
### Network Efficiency
|
|
297
|
+
|
|
298
|
+
- **Timeouts**: Reasonable timeouts (30s default)
|
|
299
|
+
- **Retries**: Smart retry logic (network errors only)
|
|
300
|
+
- **Caching**: Cache GET requests when appropriate
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
|
|
304
|
+
## Documentation Standards
|
|
305
|
+
|
|
306
|
+
### Code Comments
|
|
307
|
+
|
|
308
|
+
- **Functions**: JSDoc for public APIs
|
|
309
|
+
- **Complex logic**: Explain why, not what
|
|
310
|
+
- **TODOs**: Use `// TODO: description` format
|
|
311
|
+
|
|
312
|
+
### README Updates
|
|
313
|
+
|
|
314
|
+
- **Commands**: Update when adding new commands
|
|
315
|
+
- **Examples**: Provide working examples
|
|
316
|
+
- **Troubleshooting**: Add common issues/solutions
|
|
317
|
+
|
|
318
|
+
### API Documentation
|
|
319
|
+
|
|
320
|
+
- **Types**: Export all public interfaces
|
|
321
|
+
- **Examples**: Include usage examples in JSDoc
|
|
322
|
+
- **Breaking changes**: Document in changelog
|
|
323
|
+
|
|
324
|
+
---
|
|
325
|
+
|
|
326
|
+
## Tooling & Editor Setup
|
|
327
|
+
|
|
328
|
+
### VS Code Extensions
|
|
329
|
+
|
|
330
|
+
- TypeScript and JavaScript Language Features
|
|
331
|
+
- ESLint
|
|
332
|
+
- Prettier - Code formatter
|
|
333
|
+
- Jest Runner
|
|
334
|
+
|
|
335
|
+
### EditorConfig
|
|
336
|
+
|
|
337
|
+
```
|
|
338
|
+
root = true
|
|
339
|
+
|
|
340
|
+
[*]
|
|
341
|
+
charset = utf-8
|
|
342
|
+
end_of_line = lf
|
|
343
|
+
insert_final_newline = true
|
|
344
|
+
trim_trailing_whitespace = true
|
|
345
|
+
|
|
346
|
+
[*.{ts,js,json,md}]
|
|
347
|
+
indent_style = space
|
|
348
|
+
indent_size = 2
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
### Git Hooks
|
|
352
|
+
|
|
353
|
+
- **pre-commit**: Run lint and tests
|
|
354
|
+
- **pre-push**: Run full test suite
|
|
355
|
+
- **commit-msg**: Validate conventional commit format
|
|
356
|
+
|
|
357
|
+
---
|
|
358
|
+
|
|
359
|
+
## Deployment & Release
|
|
360
|
+
|
|
361
|
+
### Version Management
|
|
362
|
+
|
|
363
|
+
- **Semantic versioning**: MAJOR.MINOR.PATCH
|
|
364
|
+
- **Breaking changes**: Increment MAJOR
|
|
365
|
+
- **New features**: Increment MINOR
|
|
366
|
+
- **Bug fixes**: Increment PATCH
|
|
367
|
+
|
|
368
|
+
### Release Process
|
|
369
|
+
|
|
370
|
+
1. **Update version** in `package.json`
|
|
371
|
+
2. **Update CHANGELOG.md**
|
|
372
|
+
3. **Create git tag**: `git tag v1.2.0`
|
|
373
|
+
4. **Push tag**: Triggers GitHub Actions release
|
|
374
|
+
5. **Publish to npm**: Automatic via workflow
|
|
375
|
+
|
|
376
|
+
### NPM Publishing
|
|
377
|
+
|
|
378
|
+
- **Public access**: `npm publish --access public`
|
|
379
|
+
- **GitHub Packages**: Scoped `@leodyversemilla07/paymongo-cli`
|
|
380
|
+
- **Pre-releases**: Use `--tag beta` for beta releases
|
|
381
|
+
|
|
382
|
+
---
|
|
383
|
+
|
|
384
|
+
## GitHub Copilot Instructions
|
|
385
|
+
|
|
386
|
+
See `.github/copilot-instructions.md` for AI agent guidelines specific to this codebase.
|
|
387
|
+
|
|
388
|
+
---
|
|
389
|
+
|
|
390
|
+
## Troubleshooting
|
|
391
|
+
|
|
392
|
+
### Common Issues
|
|
393
|
+
|
|
394
|
+
- **ESM imports failing**: Ensure `.js` extensions in imports
|
|
395
|
+
- **TypeScript compilation errors**: Run `npm run build` to check
|
|
396
|
+
- **Test failures**: Check mocking setup for ESM modules
|
|
397
|
+
- **CLI not found**: Run `npm link` for local development
|
|
398
|
+
|
|
399
|
+
### Debug Mode
|
|
400
|
+
|
|
401
|
+
```bash
|
|
402
|
+
# Enable debug logging
|
|
403
|
+
DEBUG=paymongo:* npm run dev
|
|
404
|
+
|
|
405
|
+
# Verbose test output
|
|
406
|
+
npm run test -- --verbose
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
### Getting Help
|
|
410
|
+
|
|
411
|
+
1. **Check existing issues** on GitHub
|
|
412
|
+
2. **Run diagnostics**: `npm run lint && npm test`
|
|
413
|
+
3. **Check logs**: Enable debug logging
|
|
414
|
+
4. **Create issue** with reproduction steps
|
|
415
|
+
|
|
416
|
+
---
|
|
417
|
+
|
|
418
|
+
_This document is maintained by the PayMongo CLI development team. Last updated: 2024_
|