@lafken/common 0.12.29 → 0.13.0
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/lib/decorators/index.d.ts +1 -0
- package/lib/decorators/index.js +1 -0
- package/lib/decorators/lambda/lambda.d.ts +1 -0
- package/lib/decorators/lambda/lambda.js +19 -3
- package/lib/decorators/lambda/lambda.types.d.ts +3 -1
- package/lib/decorators/lambda/lambda.types.js +1 -0
- package/lib/decorators/streaming/index.d.ts +2 -0
- package/lib/decorators/streaming/index.js +18 -0
- package/lib/decorators/streaming/streaming.d.ts +34 -0
- package/lib/decorators/streaming/streaming.js +46 -0
- package/lib/decorators/streaming/streaming.types.d.ts +4 -0
- package/lib/decorators/streaming/streaming.types.js +7 -0
- package/package.json +7 -6
package/lib/decorators/index.js
CHANGED
|
@@ -5,3 +5,4 @@ export declare const reflectArgumentMethod: (target: Function, methodName: strin
|
|
|
5
5
|
export declare const createLambdaDecorator: <T, M>({ getLambdaMetadata, descriptorValue, validateEvent, argumentParser, }: CreateLambdaDecoratorProps<T, M>) => (props?: T) => (target: any, methodName: string, descriptor: PropertyDescriptor) => any;
|
|
6
6
|
export declare const createEventDecorator: ({ enableInLambdaInvocation, prefix }: CreateEventDecoratorProps) => (eventField: AllowedTypes) => (target: any, methodName: string, _number: number) => void;
|
|
7
7
|
export declare const Context: () => (target: any, methodName: string, _number: number) => void;
|
|
8
|
+
export declare const ResponseStreaming: () => (target: any, methodName: string, _number: number) => void;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Context = exports.createEventDecorator = exports.createLambdaDecorator = exports.reflectArgumentMethod = void 0;
|
|
3
|
+
exports.ResponseStreaming = exports.Context = exports.createEventDecorator = exports.createLambdaDecorator = exports.reflectArgumentMethod = void 0;
|
|
4
4
|
require("reflect-metadata");
|
|
5
5
|
const utils_1 = require("../../utils");
|
|
6
6
|
const field_1 = require("../field");
|
|
@@ -8,6 +8,7 @@ const lambda_types_1 = require("./lambda.types");
|
|
|
8
8
|
const argumentsByType = {
|
|
9
9
|
[lambda_types_1.LambdaArgumentTypes.event]: ({ event }) => event,
|
|
10
10
|
[lambda_types_1.LambdaArgumentTypes.context]: ({ context }) => context,
|
|
11
|
+
[lambda_types_1.LambdaArgumentTypes.responseStream]: ({ responseStream }) => responseStream,
|
|
11
12
|
};
|
|
12
13
|
const reflectArgumentMethod = (target, methodName, type) => {
|
|
13
14
|
const properties = Reflect.getMetadata(lambda_types_1.LambdaReflectKeys.arguments, target) || {};
|
|
@@ -29,11 +30,22 @@ const createLambdaDecorator = ({ getLambdaMetadata, descriptorValue, validateEve
|
|
|
29
30
|
...argumentsByType,
|
|
30
31
|
...argumentParser,
|
|
31
32
|
};
|
|
32
|
-
descriptor.value = async function (
|
|
33
|
+
descriptor.value = async function (...args) {
|
|
34
|
+
const [event, responseStreamOrContext, lambdaContext] = args;
|
|
33
35
|
if (!(0, utils_1.isBuildEnvironment)() && event && validateEvent) {
|
|
34
36
|
validateEvent(target, methodName, event);
|
|
35
37
|
}
|
|
36
|
-
const
|
|
38
|
+
const responseStream = typeof responseStreamOrContext?.write === 'function'
|
|
39
|
+
? responseStreamOrContext
|
|
40
|
+
: undefined;
|
|
41
|
+
const context = responseStream === undefined ? responseStreamOrContext : lambdaContext;
|
|
42
|
+
const methodArguments = (lambdaArguments?.[methodName] || []).map((argumentType) => mapArgumentMethod[argumentType]({
|
|
43
|
+
event,
|
|
44
|
+
context,
|
|
45
|
+
methodName,
|
|
46
|
+
target,
|
|
47
|
+
responseStream,
|
|
48
|
+
}));
|
|
37
49
|
const response = await originalValue.apply(this, methodArguments);
|
|
38
50
|
return response;
|
|
39
51
|
};
|
|
@@ -62,3 +74,7 @@ const Context = () => (target, methodName, _number) => {
|
|
|
62
74
|
(0, exports.reflectArgumentMethod)(target, methodName, lambda_types_1.LambdaArgumentTypes.context);
|
|
63
75
|
};
|
|
64
76
|
exports.Context = Context;
|
|
77
|
+
const ResponseStreaming = () => (target, methodName, _number) => {
|
|
78
|
+
(0, exports.reflectArgumentMethod)(target, methodName, lambda_types_1.LambdaArgumentTypes.responseStream);
|
|
79
|
+
};
|
|
80
|
+
exports.ResponseStreaming = ResponseStreaming;
|
|
@@ -303,7 +303,8 @@ export declare enum LambdaReflectKeys {
|
|
|
303
303
|
}
|
|
304
304
|
export declare enum LambdaArgumentTypes {
|
|
305
305
|
event = "event",
|
|
306
|
-
context = "context"
|
|
306
|
+
context = "context",
|
|
307
|
+
responseStream = "responseStream"
|
|
307
308
|
}
|
|
308
309
|
export type CallbackParam = (error: boolean | null, response?: any) => void;
|
|
309
310
|
export type LambdaArguments = Record<string, LambdaArgumentTypes[]>;
|
|
@@ -312,6 +313,7 @@ export type LambdaArgumentsType = Record<LambdaArgumentTypes, ({ event, context,
|
|
|
312
313
|
context: any;
|
|
313
314
|
methodName: string;
|
|
314
315
|
target: any;
|
|
316
|
+
responseStream?: any;
|
|
315
317
|
}) => any>;
|
|
316
318
|
export interface CreateLambdaDecoratorProps<T, M> {
|
|
317
319
|
getLambdaMetadata: (params: T, methodName: string) => M;
|
|
@@ -12,4 +12,5 @@ var LambdaArgumentTypes;
|
|
|
12
12
|
(function (LambdaArgumentTypes) {
|
|
13
13
|
LambdaArgumentTypes["event"] = "event";
|
|
14
14
|
LambdaArgumentTypes["context"] = "context";
|
|
15
|
+
LambdaArgumentTypes["responseStream"] = "responseStream";
|
|
15
16
|
})(LambdaArgumentTypes || (exports.LambdaArgumentTypes = LambdaArgumentTypes = {}));
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./streaming"), exports);
|
|
18
|
+
__exportStar(require("./streaming.types"), exports);
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
/**
|
|
3
|
+
* Method decorator factory that marks a Lambda handler as a response-streaming
|
|
4
|
+
* handler.
|
|
5
|
+
*
|
|
6
|
+
* It only records, per method name, that the handler is a streaming one under
|
|
7
|
+
* `StreamingReflectKeys.streaming` on the class prototype (during synth). The
|
|
8
|
+
* actual `awslambda.streamifyResponse` wrapping is applied later by the build
|
|
9
|
+
* step, when the handler is exported as the Lambda entry point, so the
|
|
10
|
+
* streaming marker ends up on the final exported function (a decorator wrap
|
|
11
|
+
* would be dropped by `Function.prototype.bind` when the handler is bound to
|
|
12
|
+
* its instance at export time).
|
|
13
|
+
*
|
|
14
|
+
* The decorated method's runtime signature is `(event, responseStream, context)`
|
|
15
|
+
* instead of the usual `(event, context)`. When combined with a method decorator
|
|
16
|
+
* built from `createLambdaDecorator` (e.g. `Get`/`Handler`), that decorator's
|
|
17
|
+
* generated wrapper tells both signatures apart by checking whether the second
|
|
18
|
+
* argument exposes a `write` function: if it does it is treated as the response
|
|
19
|
+
* stream and forwarded to any parameter decorated with `ResponseStreaming()`,
|
|
20
|
+
* and `context` is read from the third argument; otherwise the second argument
|
|
21
|
+
* is the `context`. The check is structural rather than `instanceof Stream`
|
|
22
|
+
* because the runtime hands over its own stream implementation, which does not
|
|
23
|
+
* necessarily inherit from the `stream` module of this bundle.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* @Streaming()
|
|
27
|
+
* @Handler()
|
|
28
|
+
* myHandler(@ResponseStreaming() responseStream: Writable, @Context() context: any) {
|
|
29
|
+
* responseStream.write('chunk');
|
|
30
|
+
* responseStream.end();
|
|
31
|
+
* }
|
|
32
|
+
*/
|
|
33
|
+
export declare const createStreamingDecorator: () => () => (target: any, methodName: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
|
|
34
|
+
export declare const Streaming: () => (target: any, methodName: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Streaming = exports.createStreamingDecorator = void 0;
|
|
4
|
+
require("reflect-metadata");
|
|
5
|
+
const utils_1 = require("../../utils");
|
|
6
|
+
const streaming_types_1 = require("./streaming.types");
|
|
7
|
+
/**
|
|
8
|
+
* Method decorator factory that marks a Lambda handler as a response-streaming
|
|
9
|
+
* handler.
|
|
10
|
+
*
|
|
11
|
+
* It only records, per method name, that the handler is a streaming one under
|
|
12
|
+
* `StreamingReflectKeys.streaming` on the class prototype (during synth). The
|
|
13
|
+
* actual `awslambda.streamifyResponse` wrapping is applied later by the build
|
|
14
|
+
* step, when the handler is exported as the Lambda entry point, so the
|
|
15
|
+
* streaming marker ends up on the final exported function (a decorator wrap
|
|
16
|
+
* would be dropped by `Function.prototype.bind` when the handler is bound to
|
|
17
|
+
* its instance at export time).
|
|
18
|
+
*
|
|
19
|
+
* The decorated method's runtime signature is `(event, responseStream, context)`
|
|
20
|
+
* instead of the usual `(event, context)`. When combined with a method decorator
|
|
21
|
+
* built from `createLambdaDecorator` (e.g. `Get`/`Handler`), that decorator's
|
|
22
|
+
* generated wrapper tells both signatures apart by checking whether the second
|
|
23
|
+
* argument exposes a `write` function: if it does it is treated as the response
|
|
24
|
+
* stream and forwarded to any parameter decorated with `ResponseStreaming()`,
|
|
25
|
+
* and `context` is read from the third argument; otherwise the second argument
|
|
26
|
+
* is the `context`. The check is structural rather than `instanceof Stream`
|
|
27
|
+
* because the runtime hands over its own stream implementation, which does not
|
|
28
|
+
* necessarily inherit from the `stream` module of this bundle.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* @Streaming()
|
|
32
|
+
* @Handler()
|
|
33
|
+
* myHandler(@ResponseStreaming() responseStream: Writable, @Context() context: any) {
|
|
34
|
+
* responseStream.write('chunk');
|
|
35
|
+
* responseStream.end();
|
|
36
|
+
* }
|
|
37
|
+
*/
|
|
38
|
+
const createStreamingDecorator = () => () => (target, methodName, descriptor) => {
|
|
39
|
+
if ((0, utils_1.isBuildEnvironment)()) {
|
|
40
|
+
const streamingMethods = Reflect.getMetadata(streaming_types_1.StreamingReflectKeys.streaming, target) || {};
|
|
41
|
+
Reflect.defineMetadata(streaming_types_1.StreamingReflectKeys.streaming, { ...streamingMethods, [methodName]: true }, target);
|
|
42
|
+
}
|
|
43
|
+
return descriptor;
|
|
44
|
+
};
|
|
45
|
+
exports.createStreamingDecorator = createStreamingDecorator;
|
|
46
|
+
exports.Streaming = (0, exports.createStreamingDecorator)();
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.StreamingReflectKeys = void 0;
|
|
4
|
+
var StreamingReflectKeys;
|
|
5
|
+
(function (StreamingReflectKeys) {
|
|
6
|
+
StreamingReflectKeys["streaming"] = "streaming:handlers";
|
|
7
|
+
})(StreamingReflectKeys || (exports.StreamingReflectKeys = StreamingReflectKeys = {}));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lafken/common",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Lafken utilities - TypeScript decorator factories and metadata reflection for infrastructure-as-code decorators",
|
|
6
6
|
"keywords": [
|
|
@@ -28,16 +28,17 @@
|
|
|
28
28
|
"lib"
|
|
29
29
|
],
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"
|
|
31
|
+
"@types/aws-lambda": "^8.10.162",
|
|
32
|
+
"reflect-metadata": "^0.2.2"
|
|
32
33
|
},
|
|
33
34
|
"devDependencies": {
|
|
34
|
-
"@swc/core": "^1.15.
|
|
35
|
+
"@swc/core": "^1.15.43",
|
|
35
36
|
"@swc/helpers": "^0.5.23",
|
|
36
|
-
"@vitest/runner": "^4.1.
|
|
37
|
+
"@vitest/runner": "^4.1.10",
|
|
37
38
|
"cdktn-vitest": "^1.0.0",
|
|
38
|
-
"typescript": "
|
|
39
|
+
"typescript": "7.0.2",
|
|
39
40
|
"unplugin-swc": "^1.5.9",
|
|
40
|
-
"vitest": "^4.1.
|
|
41
|
+
"vitest": "^4.1.10"
|
|
41
42
|
},
|
|
42
43
|
"engines": {
|
|
43
44
|
"node": ">=20.19"
|