Skip to content

Commit 1821677

Browse files
committed
.
1 parent 0d8fd88 commit 1821677

File tree

3 files changed

+72
-53
lines changed

3 files changed

+72
-53
lines changed

README.md

Lines changed: 53 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,14 @@ For a full tutorial see [How To: Build a Serverless API with Serverless, AWS Lam
3939
Lambda API includes comprehensive TypeScript definitions out of the box. You can leverage type safety across your entire API:
4040

4141
```typescript
42-
import {
43-
API,
44-
Request,
42+
import {
43+
API,
44+
Request,
4545
Response,
4646
SourceAgnosticHandler,
4747
SourceAgnosticMiddleware,
4848
isApiGatewayContext,
49-
isAlbContext
49+
isAlbContext,
5050
} from 'lambda-api';
5151

5252
// Define your response type
@@ -63,18 +63,18 @@ const api = new API();
6363
const handler: SourceAgnosticHandler<UserResponse> = (req, res) => {
6464
// Common properties are always available
6565
console.log(req.method, req.path);
66-
66+
6767
// Type-safe access to source-specific features
6868
if (isApiGatewayContext(req.requestContext)) {
6969
console.log(req.requestContext.identity);
7070
} else if (isAlbContext(req.requestContext)) {
7171
console.log(req.requestContext.elb);
7272
}
73-
73+
7474
res.json({
7575
id: '1',
7676
name: 'John',
77-
77+
7878
});
7979
};
8080

@@ -89,29 +89,37 @@ const middleware: SourceAgnosticMiddleware = (req, res, next) => {
8989
api.get('/users', middleware, handler);
9090

9191
// For source-specific handlers, you can specify the context type
92-
interface UserQuery { fields: string }
93-
interface UserParams { id: string }
94-
interface UserBody { name: string; email: string }
92+
interface UserQuery {
93+
fields: string;
94+
}
95+
interface UserParams {
96+
id: string;
97+
}
98+
interface UserBody {
99+
name: string;
100+
email: string;
101+
}
95102

96103
api.post<UserResponse, APIGatewayContext, UserQuery, UserParams, UserBody>(
97104
'/users',
98105
(req, res) => {
99106
// Full type safety for:
100-
req.query.fields; // UserQuery
101-
req.params.id; // UserParams
102-
req.body.name; // UserBody
103-
req.requestContext; // APIGatewayContext
104-
107+
req.query.fields; // UserQuery
108+
req.params.id; // UserParams
109+
req.body.name; // UserBody
110+
req.requestContext; // APIGatewayContext
111+
105112
res.json({
106113
id: '1',
107114
name: req.body.name,
108-
email: req.body.email
115+
email: req.body.email,
109116
});
110117
}
111118
);
112119
```
113120

114121
Key TypeScript Features:
122+
115123
- Source-agnostic types that work with any Lambda trigger
116124
- Type guards for safe context type checking
117125
- Full type inference for request and response objects
@@ -127,13 +135,13 @@ Key TypeScript Features:
127135
Lambda API provides type guards to safely work with different request sources:
128136

129137
```typescript
130-
import {
138+
import {
131139
isApiGatewayContext,
132-
isApiGatewayV2Context,
140+
isApiGatewayV2Context,
133141
isAlbContext,
134142
isApiGatewayRequest,
135143
isApiGatewayV2Request,
136-
isAlbRequest
144+
isAlbRequest,
137145
} from 'lambda-api';
138146

139147
// Check request context type
@@ -154,11 +162,11 @@ if (isApiGatewayRequest(req)) {
154162
Lambda API provides type-safe support for different AWS Lambda triggers. You can write source-specific handlers or use source-agnostic handlers that work with any trigger:
155163

156164
```typescript
157-
import {
158-
isApiGatewayContext,
159-
isApiGatewayV2Context,
165+
import {
166+
isApiGatewayContext,
167+
isApiGatewayV2Context,
160168
isAlbContext,
161-
SourceAgnosticHandler
169+
SourceAgnosticHandler,
162170
} from 'lambda-api';
163171

164172
// Source-specific handler
@@ -177,14 +185,15 @@ const handler: SourceAgnosticHandler = (req, res) => {
177185
} else if (isAlbContext(req.requestContext)) {
178186
console.log(req.requestContext.elb);
179187
}
180-
188+
181189
res.json({ status: 'ok' });
182190
};
183191

184192
api.get('/any', handler);
185193
```
186194

187195
Key features for handling multiple sources:
196+
188197
- Type guards for safe context type checking
189198
- Source-agnostic types that work with any trigger
190199
- Full type safety for source-specific properties
@@ -1661,15 +1670,17 @@ declare module 'lambda-api' {
16611670
}
16621671
}
16631672

1664-
function hasUser(req: Request): req is Request & { user: { id: string; roles: string[]; email: string; } } {
1673+
function hasUser(
1674+
req: Request
1675+
): req is Request & { user: { id: string; roles: string[]; email: string } } {
16651676
return 'user' in req && req.user !== undefined;
16661677
}
16671678

16681679
const authMiddleware: Middleware = (req, res, next) => {
16691680
req.user = {
16701681
id: '123',
16711682
roles: ['admin'],
1672-
1683+
16731684
};
16741685
next();
16751686
};
@@ -1695,7 +1706,7 @@ const responseEnhancer: Middleware = (req, res, next) => {
16951706
res.sendWithTimestamp = (data: any) => {
16961707
res.json({
16971708
...data,
1698-
timestamp: Date.now()
1709+
timestamp: Date.now(),
16991710
});
17001711
};
17011712
next();
@@ -1725,7 +1736,7 @@ const authMiddleware: Middleware = (req, res, next) => {
17251736
userId: '123',
17261737
roles: ['user'],
17271738
type: 'Bearer',
1728-
value: 'token123'
1739+
value: 'token123',
17291740
};
17301741
next();
17311742
};
@@ -1743,13 +1754,12 @@ interface QueryParams {
17431754
offset?: string;
17441755
}
17451756

1746-
api.get<UserResponse, APIGatewayContext, QueryParams>(
1747-
'/users',
1748-
(req, res) => {
1749-
const { limit, offset } = req.query;
1750-
res.json({ /* ... */ });
1751-
}
1752-
);
1757+
api.get<UserResponse, APIGatewayContext, QueryParams>('/users', (req, res) => {
1758+
const { limit, offset } = req.query;
1759+
res.json({
1760+
/* ... */
1761+
});
1762+
});
17531763

17541764
interface CreateUserBody {
17551765
name: string;
@@ -1760,7 +1770,9 @@ api.post<UserResponse, APIGatewayContext, never, never, CreateUserBody>(
17601770
'/users',
17611771
(req, res) => {
17621772
const { name, email } = req.body;
1763-
res.json({ /* ... */ });
1773+
res.json({
1774+
/* ... */
1775+
});
17641776
}
17651777
);
17661778

@@ -1779,7 +1791,11 @@ api.get('/protected', withUser(handler));
17791791
## Handling Multiple Request Sources
17801792

17811793
```typescript
1782-
import { isApiGatewayContext, isApiGatewayV2Context, isAlbContext } from 'lambda-api';
1794+
import {
1795+
isApiGatewayContext,
1796+
isApiGatewayV2Context,
1797+
isAlbContext,
1798+
} from 'lambda-api';
17831799

17841800
api.get<Response, APIGatewayRequestContext>('/api-gateway', (req, res) => {
17851801
console.log(req.requestContext.identity);
@@ -1797,4 +1813,3 @@ api.get('/any', (req, res) => {
17971813
}
17981814
});
17991815
```
1800-

index.js

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@ const LOGGER = require('./lib/logger');
1212
const S3 = () => require('./lib/s3-service');
1313
const prettyPrint = require('./lib/prettyPrint');
1414
const { ConfigurationError } = require('./lib/errors');
15-
const { isApiGatewayContext, isApiGatewayV2Context, isAlbContext } = require('./lib/typeguards');
15+
const {
16+
isApiGatewayContext,
17+
isApiGatewayV2Context,
18+
isAlbContext,
19+
} = require('./lib/typeguards');
1620

1721
class API {
1822
constructor(props) {
@@ -43,8 +47,8 @@ class API {
4347
: {};
4448
this._compression =
4549
props &&
46-
(typeof props.compression === 'boolean' ||
47-
Array.isArray(props.compression))
50+
(typeof props.compression === 'boolean' ||
51+
Array.isArray(props.compression))
4852
? props.compression
4953
: false;
5054

@@ -85,7 +89,7 @@ class API {
8589
this._app = {};
8690

8791
// Executed after the callback
88-
this._finally = () => { };
92+
this._finally = () => {};
8993

9094
// Global error status (used for response parsing errors)
9195
this._errorStatus = 500;
@@ -214,8 +218,8 @@ class API {
214218
stack: _stack['m'][method]
215219
? _stack['m'][method].concat(stack)
216220
: _stack['*'][method]
217-
? _stack['*'][method].concat(stack)
218-
: stack,
221+
? _stack['*'][method].concat(stack)
222+
: stack,
219223
// inherited: _stack[method] ? _stack[method] : [],
220224
route: '/' + parsedPath.join('/'),
221225
path: '/' + this._prefix.concat(parsedPath).join('/'),
@@ -451,8 +455,8 @@ class API {
451455
typeof args[0] === 'string'
452456
? Array.of(args.shift())
453457
: Array.isArray(args[0])
454-
? args.shift()
455-
: ['/*'];
458+
? args.shift()
459+
: ['/*'];
456460

457461
// Init middleware stack
458462
let middleware = [];

lib/typeguards.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
'use strict';
22

33
const isApiGatewayContext = (context) => {
4-
return 'identity' in context;
4+
return 'identity' in context;
55
};
66

77
const isApiGatewayV2Context = (context) => {
8-
return 'http' in context;
8+
return 'http' in context;
99
};
1010

1111
const isAlbContext = (context) => {
12-
return 'elb' in context;
12+
return 'elb' in context;
1313
};
1414

1515
module.exports = {
16-
isApiGatewayContext,
17-
isApiGatewayV2Context,
18-
isAlbContext
19-
};
16+
isApiGatewayContext,
17+
isApiGatewayV2Context,
18+
isAlbContext,
19+
};

0 commit comments

Comments
 (0)