-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
138 lines (126 loc) · 4.22 KB
/
index.js
File metadata and controls
138 lines (126 loc) · 4.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/**
* @alt-javascript/boot-lambda — AWS Lambda adapter for the alt-javascript framework.
*
* Provides CDI-managed serverless handler with controller auto-registration.
* Same `__routes` convention as Express and Fastify adapters.
*
* Usage (idiomatic — Boot.boot() pattern):
* import { lambdaStarter } from '@alt-javascript/boot-lambda';
* import { Boot } from '@alt-javascript/boot';
* import { Context, Singleton } from '@alt-javascript/cdi';
*
* const context = new Context([...lambdaStarter(), new Singleton(MyController)]);
* const appCtx = await Boot.boot({ contexts: [context], run: false });
* export const handler = (event, ctx) => appCtx.get('lambdaAdapter').handle(event, ctx);
*/
import { ApplicationContext } from '@alt-javascript/cdi';
import {
RequestLoggerMiddleware,
ErrorHandlerMiddleware,
NotFoundMiddleware,
} from '@alt-javascript/boot';
import LambdaAdapter from './LambdaAdapter.js';
import LambdaControllerRegistrar from './LambdaControllerRegistrar.js';
/**
* @deprecated Use Boot.boot({ contexts: [...lambdaStarter(), ...], run: false }) instead.
*
* Create a Lambda handler function that boots CDI on cold start and
* dispatches API Gateway events to controller methods.
*/
export function createLambdaHandler(options) {
let adapter = null;
let bootPromise = null;
async function bootstrap() {
const appCtx = new ApplicationContext({
contexts: options.contexts,
config: options.config,
});
await appCtx.start({ run: false, ...options.startOptions });
adapter = new LambdaAdapter(appCtx);
}
return async function handler(event, lambdaContext) {
// Boot once on cold start, reuse on warm invocations
if (!adapter) {
if (!bootPromise) {
bootPromise = bootstrap();
}
await bootPromise;
}
return adapter.handle(event, lambdaContext);
};
}
/**
* Returns CDI component definitions that register a LambdaAdapter as a singleton.
*
* The adapter is created during init() after CDI wiring is complete.
* Access the handler via: `ctx.get('lambdaAdapter').handle(event, lambdaContext)`
*
* Registers:
* - `lambdaAdapter` — CDI-managed Lambda handler with route dispatch
* - `requestLoggerMiddleware` — per-request logging (order: 10)
* - `errorHandlerMiddleware` — exception → structured response (order: 20)
* - `notFoundMiddleware` — null route result → 404 (order: 30)
*
* @returns {Array} component definitions for CDI Context
*/
export function lambdaStarter() {
return [
{
name: 'lambdaAdapter',
Reference: LambdaAdapterFactory,
scope: 'singleton',
condition: (config, components) => !components.lambdaAdapter,
},
{
name: 'requestLoggerMiddleware',
Reference: RequestLoggerMiddleware,
scope: 'singleton',
condition: (config, components) => !components.requestLoggerMiddleware,
},
{
name: 'errorHandlerMiddleware',
Reference: ErrorHandlerMiddleware,
scope: 'singleton',
condition: (config, components) => !components.errorHandlerMiddleware,
},
{
name: 'notFoundMiddleware',
Reference: NotFoundMiddleware,
scope: 'singleton',
condition: (config, components) => !components.notFoundMiddleware,
},
];
}
/**
* Factory class that CDI instantiates as a singleton.
* Creates the LambdaAdapter during init() after all components are wired.
* Delegates handle() to the inner adapter.
*/
class LambdaAdapterFactory {
constructor() {
this._adapter = null;
this._applicationContext = null;
}
setApplicationContext(ctx) {
this._applicationContext = ctx;
}
init() {
this._adapter = new LambdaAdapter(this._applicationContext);
}
/** @returns {number} registered route count */
get routeCount() {
return this._adapter?.routeCount || 0;
}
/**
* Handle an API Gateway HTTP API v2 event.
* @param {object} event
* @param {object} [lambdaContext]
* @returns {Promise<{statusCode, body, headers}>}
*/
async handle(event, lambdaContext) {
return this._adapter.handle(event, lambdaContext);
}
}
export { LambdaAdapter, LambdaControllerRegistrar, LambdaAdapterFactory };
/** @deprecated Use lambdaStarter() */
export const lambdaAutoConfiguration = lambdaStarter;