|
| 1 | +# AGENTS.md |
| 2 | + |
| 3 | +Lightweight web framework for AWS Lambda with **zero external dependencies**. Express.js-like API for serverless apps, supporting API Gateway v1/v2 and ALB event formats. |
| 4 | + |
| 5 | +## Commands |
| 6 | + |
| 7 | +```bash |
| 8 | +npm test # Type tests (tsd) + Jest unit tests |
| 9 | +npm run test:unit # Jest unit tests only |
| 10 | +npx jest __tests__/routes.unit.js # Run a single test file |
| 11 | +npm run test:types # TypeScript definition tests (tsd) |
| 12 | +npm run test-cov # Jest with coverage |
| 13 | +npm run test-ci # Full CI: lint + format + tests + coverage |
| 14 | +npm run lint:check # ESLint check |
| 15 | +npm run lint:fix # ESLint auto-fix |
| 16 | +npm run prettier:check # Prettier check |
| 17 | +npm run prettier:write # Prettier auto-fix |
| 18 | +``` |
| 19 | + |
| 20 | +## Architecture |
| 21 | + |
| 22 | +**Entry point**: `index.js` — main `API` class. Handles route registration, middleware management, and the `run()` method that processes Lambda events. |
| 23 | + |
| 24 | +**Core modules** in `lib/`: |
| 25 | + |
| 26 | +- `request.js` — Parses Lambda event into Express-like request object (headers, query, params, body, auth) |
| 27 | +- `response.js` — Response builder: `json()`, `html()`, `send()`, `redirect()`, `sendFile()`, `cookie()`, `cors()` |
| 28 | +- `utils.js` — Path parsing, URL encoding, HTML escaping, MIME lookup, body parsing |
| 29 | +- `logger.js` — Built-in logging with sampling, custom levels, and serializers |
| 30 | +- `errors.js` — Custom error classes: `RouteError`, `MethodError`, `ConfigurationError`, `ApiError`, `FileError`, `ResponseError` |
| 31 | +- `compression.js` — Brotli/Gzip/Deflate response compression |
| 32 | +- `s3-service.js` — S3 file operations and pre-signed URLs (peer deps: `@aws-sdk/client-s3`, `@aws-sdk/s3-request-presigner`) |
| 33 | + |
| 34 | +**Request/response flow**: Lambda event → `REQUEST` parses event → execution stack built from matched routes + middleware → handlers run sequentially via `next()` → `RESPONSE` formats output for API Gateway/ALB. |
| 35 | + |
| 36 | +**Routing internals**: Routes stored in a hierarchical tree (`_routes` object). Path parameters become `__VAR__` markers. Wildcard routes (`/*`) supported. Execution stacks are method-specific with middleware inheritance. |
| 37 | + |
| 38 | +**Type definitions**: `index.d.ts` with type tests in `index.test-d.ts` (validated via `tsd`). |
| 39 | + |
| 40 | +## Code Style |
| 41 | + |
| 42 | +- JavaScript ES6+ with `'use strict'` |
| 43 | +- Single quotes, enforced by Prettier |
| 44 | +- ESLint with `eslint:recommended` + `prettier` |
| 45 | +- JSDoc file headers with author and license |
| 46 | +- Use custom error classes from `lib/errors.js`, not raw `Error` |
| 47 | + |
| 48 | +Example handler pattern: |
| 49 | + |
| 50 | +```javascript |
| 51 | +// Route handler |
| 52 | +api.get('/users/:id', async (req, res) => { |
| 53 | + return { id: req.params.id }; |
| 54 | +}); |
| 55 | + |
| 56 | +// Error middleware (4 params) |
| 57 | +api.use((err, req, res, next) => { |
| 58 | + res.status(500).json({ error: err.message }); |
| 59 | +}); |
| 60 | +``` |
| 61 | + |
| 62 | +## Testing |
| 63 | + |
| 64 | +- Tests live in `__tests__/*.unit.js` |
| 65 | +- Sample Lambda events in `__tests__/sample-*.json` |
| 66 | +- Always test with API Gateway v1, v2, and ALB event formats |
| 67 | +- Update type definitions in `index.d.ts` for public API changes, then run `npm run test:types` |
| 68 | + |
| 69 | +## Boundaries |
| 70 | + |
| 71 | +**Never do:** |
| 72 | + |
| 73 | +- Add external npm dependencies (zero-dependency policy is non-negotiable) |
| 74 | +- Introduce breaking changes to the public API |
| 75 | + |
| 76 | +**Always do:** |
| 77 | + |
| 78 | +- Add unit tests in `__tests__/*.unit.js` for new features |
| 79 | +- Update `index.d.ts` when changing the public API |
| 80 | +- Maintain backwards compatibility |
0 commit comments