From a3eb155df8a16a42075362bec31df41ff184db97 Mon Sep 17 00:00:00 2001 From: naorpeled Date: Sat, 28 Feb 2026 20:50:15 +0200 Subject: [PATCH 1/4] Add CLAUDE.md for Claude Code repository guidance Provides development commands, architecture overview, code conventions, and contribution guidelines to help Claude Code navigate the codebase. Co-Authored-By: Claude Opus 4.6 --- CLAUDE.md | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..8853d66 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,58 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +lambda-api is a lightweight web framework for AWS Lambda with **zero external dependencies** (non-negotiable). It provides an Express.js-like API for serverless applications, supporting API Gateway v1/v2 and ALB event formats. + +## Commands + +```bash +npm test # Type tests (tsd) + Jest unit tests +npm run test:unit # Jest unit tests only +npm run test:unit -- __tests__/routes.unit.js # Run a single test file +npm run test:types # TypeScript definition tests (tsd) +npm run test-cov # Jest with coverage +npm run test-ci # Full CI: lint + format + tests + coverage +npm run lint:check # ESLint check +npm run lint:fix # ESLint auto-fix +npm run prettier:check # Prettier check +npm run prettier:write # Prettier auto-fix +``` + +## Architecture + +**Entry point**: `index.js` — the main `API` class (~1000 lines). Handles route registration, middleware management, and the `run()` method that processes Lambda events. + +**Core modules** in `lib/`: +- `request.js` — Parses Lambda event into Express-like request object (headers, query, params, body, auth) +- `response.js` — Response builder with methods like `json()`, `html()`, `send()`, `redirect()`, `sendFile()`, `cookie()`, `cors()` +- `utils.js` — Path parsing, URL encoding, HTML escaping, MIME lookup, body parsing +- `logger.js` — Built-in logging with sampling, custom levels, and serializers +- `errors.js` — Custom error classes: `RouteError`, `MethodError`, `ConfigurationError`, `ApiError`, `FileError`, `ResponseError` +- `compression.js` — Brotli/Gzip/Deflate response compression +- `s3-service.js` — S3 file operations and pre-signed URLs (uses `@aws-sdk/client-s3` as peer dep) + +**Request/response flow**: Lambda event → `REQUEST` class parses event → execution stack built from matched routes + middleware → handlers run sequentially via `next()` → `RESPONSE` class formats output for API Gateway/ALB. + +**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. + +**Type definitions**: `index.d.ts` with type tests in `index.test-d.ts` (validated via `tsd`). + +## Code Conventions + +- JavaScript ES6+ with `'use strict'` +- Single quotes (Prettier), no semicolons not enforced +- ESLint with `eslint:recommended` + `prettier` +- JSDoc file headers with author and license +- Custom error classes from `lib/errors.js` — use these, not raw Error +- Handlers accept `(req, res, next)`, error middleware uses `(err, req, res, next)` + +## Making Changes + +- Never add external npm dependencies +- Add unit tests in `__tests__/*.unit.js` for new features +- Update `index.d.ts` for public API changes +- Test with API Gateway v1, v2, and ALB event formats (sample events in `__tests__/sample-*.json`) +- Maintain backwards compatibility From eb2a1f7f4b96cbe96403eb33acab6c70a375752e Mon Sep 17 00:00:00 2001 From: naorpeled Date: Sat, 28 Feb 2026 20:55:44 +0200 Subject: [PATCH 2/4] Replace CLAUDE.md with AGENTS.md following open standard Rename to AGENTS.md format for broader AI coding agent compatibility. Restructured with best-practice sections: commands, architecture, code style with examples, testing, and explicit boundaries. Co-Authored-By: Claude Opus 4.6 --- AGENTS.md | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ CLAUDE.md | 58 ----------------------------------------- 2 files changed, 77 insertions(+), 58 deletions(-) create mode 100644 AGENTS.md delete mode 100644 CLAUDE.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..cb1b3dd --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,77 @@ +# AGENTS.md + +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. + +## Commands + +```bash +npm test # Type tests (tsd) + Jest unit tests +npm run test:unit # Jest unit tests only +npm run test:unit -- __tests__/routes.unit.js # Run a single test file +npm run test:types # TypeScript definition tests (tsd) +npm run test-cov # Jest with coverage +npm run test-ci # Full CI: lint + format + tests + coverage +npm run lint:check # ESLint check +npm run lint:fix # ESLint auto-fix +npm run prettier:check # Prettier check +npm run prettier:write # Prettier auto-fix +``` + +## Architecture + +**Entry point**: `index.js` — main `API` class. Handles route registration, middleware management, and the `run()` method that processes Lambda events. + +**Core modules** in `lib/`: +- `request.js` — Parses Lambda event into Express-like request object (headers, query, params, body, auth) +- `response.js` — Response builder: `json()`, `html()`, `send()`, `redirect()`, `sendFile()`, `cookie()`, `cors()` +- `utils.js` — Path parsing, URL encoding, HTML escaping, MIME lookup, body parsing +- `logger.js` — Built-in logging with sampling, custom levels, and serializers +- `errors.js` — Custom error classes: `RouteError`, `MethodError`, `ConfigurationError`, `ApiError`, `FileError`, `ResponseError` +- `compression.js` — Brotli/Gzip/Deflate response compression +- `s3-service.js` — S3 file operations and pre-signed URLs (`@aws-sdk/client-s3` peer dep) + +**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. + +**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. + +**Type definitions**: `index.d.ts` with type tests in `index.test-d.ts` (validated via `tsd`). + +## Code Style + +- JavaScript ES6+ with `'use strict'` +- Single quotes, enforced by Prettier +- ESLint with `eslint:recommended` + `prettier` +- JSDoc file headers with author and license +- Use custom error classes from `lib/errors.js`, not raw `Error` + +Example handler pattern: + +```javascript +// Route handler +api.get('/users/:id', async (req, res) => { + return { id: req.params.id } +}) + +// Error middleware (4 params) +api.use((err, req, res, next) => { + res.status(500).json({ error: err.message }) +}) +``` + +## Testing + +- Tests live in `__tests__/*.unit.js` +- Sample Lambda events in `__tests__/sample-*.json` +- Always test with API Gateway v1, v2, and ALB event formats +- Update type definitions in `index.d.ts` for public API changes, then run `npm run test:types` + +## Boundaries + +**Never do:** +- Add external npm dependencies (zero-dependency policy is non-negotiable) +- Introduce breaking changes to the public API + +**Always do:** +- Add unit tests in `__tests__/*.unit.js` for new features +- Update `index.d.ts` when changing the public API +- Maintain backwards compatibility diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100644 index 8853d66..0000000 --- a/CLAUDE.md +++ /dev/null @@ -1,58 +0,0 @@ -# CLAUDE.md - -This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. - -## Project Overview - -lambda-api is a lightweight web framework for AWS Lambda with **zero external dependencies** (non-negotiable). It provides an Express.js-like API for serverless applications, supporting API Gateway v1/v2 and ALB event formats. - -## Commands - -```bash -npm test # Type tests (tsd) + Jest unit tests -npm run test:unit # Jest unit tests only -npm run test:unit -- __tests__/routes.unit.js # Run a single test file -npm run test:types # TypeScript definition tests (tsd) -npm run test-cov # Jest with coverage -npm run test-ci # Full CI: lint + format + tests + coverage -npm run lint:check # ESLint check -npm run lint:fix # ESLint auto-fix -npm run prettier:check # Prettier check -npm run prettier:write # Prettier auto-fix -``` - -## Architecture - -**Entry point**: `index.js` — the main `API` class (~1000 lines). Handles route registration, middleware management, and the `run()` method that processes Lambda events. - -**Core modules** in `lib/`: -- `request.js` — Parses Lambda event into Express-like request object (headers, query, params, body, auth) -- `response.js` — Response builder with methods like `json()`, `html()`, `send()`, `redirect()`, `sendFile()`, `cookie()`, `cors()` -- `utils.js` — Path parsing, URL encoding, HTML escaping, MIME lookup, body parsing -- `logger.js` — Built-in logging with sampling, custom levels, and serializers -- `errors.js` — Custom error classes: `RouteError`, `MethodError`, `ConfigurationError`, `ApiError`, `FileError`, `ResponseError` -- `compression.js` — Brotli/Gzip/Deflate response compression -- `s3-service.js` — S3 file operations and pre-signed URLs (uses `@aws-sdk/client-s3` as peer dep) - -**Request/response flow**: Lambda event → `REQUEST` class parses event → execution stack built from matched routes + middleware → handlers run sequentially via `next()` → `RESPONSE` class formats output for API Gateway/ALB. - -**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. - -**Type definitions**: `index.d.ts` with type tests in `index.test-d.ts` (validated via `tsd`). - -## Code Conventions - -- JavaScript ES6+ with `'use strict'` -- Single quotes (Prettier), no semicolons not enforced -- ESLint with `eslint:recommended` + `prettier` -- JSDoc file headers with author and license -- Custom error classes from `lib/errors.js` — use these, not raw Error -- Handlers accept `(req, res, next)`, error middleware uses `(err, req, res, next)` - -## Making Changes - -- Never add external npm dependencies -- Add unit tests in `__tests__/*.unit.js` for new features -- Update `index.d.ts` for public API changes -- Test with API Gateway v1, v2, and ALB event formats (sample events in `__tests__/sample-*.json`) -- Maintain backwards compatibility From dcf345ae80155d0cba5dfdf55e7e6ad6efeb5b3a Mon Sep 17 00:00:00 2001 From: naorpeled Date: Sat, 28 Feb 2026 21:02:54 +0200 Subject: [PATCH 3/4] fix prettier --- AGENTS.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index cb1b3dd..1eddfa6 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -22,6 +22,7 @@ npm run prettier:write # Prettier auto-fix **Entry point**: `index.js` — main `API` class. Handles route registration, middleware management, and the `run()` method that processes Lambda events. **Core modules** in `lib/`: + - `request.js` — Parses Lambda event into Express-like request object (headers, query, params, body, auth) - `response.js` — Response builder: `json()`, `html()`, `send()`, `redirect()`, `sendFile()`, `cookie()`, `cors()` - `utils.js` — Path parsing, URL encoding, HTML escaping, MIME lookup, body parsing @@ -49,13 +50,13 @@ Example handler pattern: ```javascript // Route handler api.get('/users/:id', async (req, res) => { - return { id: req.params.id } -}) + return { id: req.params.id }; +}); // Error middleware (4 params) api.use((err, req, res, next) => { - res.status(500).json({ error: err.message }) -}) + res.status(500).json({ error: err.message }); +}); ``` ## Testing @@ -68,10 +69,12 @@ api.use((err, req, res, next) => { ## Boundaries **Never do:** + - Add external npm dependencies (zero-dependency policy is non-negotiable) - Introduce breaking changes to the public API **Always do:** + - Add unit tests in `__tests__/*.unit.js` for new features - Update `index.d.ts` when changing the public API - Maintain backwards compatibility From 0d3a5730f8f661003ef95e3a74b2885397bed0cd Mon Sep 17 00:00:00 2001 From: naorpeled Date: Sat, 28 Feb 2026 21:11:50 +0200 Subject: [PATCH 4/4] Address PR review comments on AGENTS.md - Fix single test file command: use npx jest directly instead of npm run test:unit which adds a conflicting testPathPattern - List both S3 peer dependencies (client-s3 and s3-request-presigner) Co-Authored-By: Claude Opus 4.6 --- AGENTS.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 1eddfa6..0956a3e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -7,7 +7,7 @@ Lightweight web framework for AWS Lambda with **zero external dependencies**. Ex ```bash npm test # Type tests (tsd) + Jest unit tests npm run test:unit # Jest unit tests only -npm run test:unit -- __tests__/routes.unit.js # Run a single test file +npx jest __tests__/routes.unit.js # Run a single test file npm run test:types # TypeScript definition tests (tsd) npm run test-cov # Jest with coverage npm run test-ci # Full CI: lint + format + tests + coverage @@ -29,7 +29,7 @@ npm run prettier:write # Prettier auto-fix - `logger.js` — Built-in logging with sampling, custom levels, and serializers - `errors.js` — Custom error classes: `RouteError`, `MethodError`, `ConfigurationError`, `ApiError`, `FileError`, `ResponseError` - `compression.js` — Brotli/Gzip/Deflate response compression -- `s3-service.js` — S3 file operations and pre-signed URLs (`@aws-sdk/client-s3` peer dep) +- `s3-service.js` — S3 file operations and pre-signed URLs (peer deps: `@aws-sdk/client-s3`, `@aws-sdk/s3-request-presigner`) **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.