@beesolve/sqs-handler 0.1.8 → 0.1.10
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/README.md +5 -0
- package/dist/cdk.d.ts +45 -12
- package/dist/cdk.js +65 -27
- package/dist/index.d.ts +11 -5
- package/dist/index.js +12 -8
- package/package.json +4 -4
package/README.md
CHANGED
package/dist/cdk.d.ts
CHANGED
|
@@ -1,31 +1,64 @@
|
|
|
1
|
+
import { Nodejs24FunctionProps, SqsWithDlqLambdaInputProps } from "@beesolve/cdk-constructs";
|
|
1
2
|
import { EmailAlarms } from "@beesolve/cdk-email-alarms";
|
|
2
3
|
import { Function } from "aws-cdk-lib/aws-lambda";
|
|
3
|
-
import { NodejsFunction
|
|
4
|
+
import { NodejsFunction } from "aws-cdk-lib/aws-lambda-nodejs";
|
|
4
5
|
import { Construct } from "constructs";
|
|
5
6
|
interface SqsHandlerProps {
|
|
6
7
|
/**
|
|
7
|
-
*
|
|
8
|
+
* SqsHandler will deploy NodejsFunction handler.
|
|
9
|
+
*
|
|
10
|
+
* This configuration is reused for all additional configurations.
|
|
11
|
+
* The only required properties are `memorySize`, `timeout` and `entry`.
|
|
12
|
+
* `entry` should point to file where your handler from `createSqsHandlers` is exported.
|
|
13
|
+
*
|
|
14
|
+
* @default
|
|
15
|
+
*
|
|
16
|
+
* {
|
|
17
|
+
* runtime: Runtime.NODEJS_24_X,
|
|
18
|
+
* architecture: Architecture.ARM_64,
|
|
19
|
+
* bundling: {
|
|
20
|
+
* minify: true,
|
|
21
|
+
* sourceMap: true,
|
|
22
|
+
* sourcesContent: false,
|
|
23
|
+
* target: "es2022",
|
|
24
|
+
* }
|
|
25
|
+
* }
|
|
26
|
+
*
|
|
8
27
|
*/
|
|
9
|
-
readonly
|
|
28
|
+
readonly handlerProps: Nodejs24FunctionProps & Required<Pick<Nodejs24FunctionProps, "memorySize" | "timeout" | "entry">>;
|
|
10
29
|
/**
|
|
11
|
-
*
|
|
30
|
+
* You can set up additional properties through this config.
|
|
31
|
+
*
|
|
32
|
+
* For example you can set up FIFO queue here.
|
|
12
33
|
*/
|
|
13
|
-
readonly
|
|
34
|
+
readonly queueProps?: Omit<SqsWithDlqLambdaInputProps, "lambda">;
|
|
14
35
|
/**
|
|
15
|
-
* You can
|
|
36
|
+
* You can specify additional handler configurations here.
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
16
39
|
*
|
|
17
|
-
* @default
|
|
18
40
|
* {
|
|
19
|
-
*
|
|
20
|
-
*
|
|
41
|
+
* longRunning: {
|
|
42
|
+
* // memory from `handlerProps` will be reused here
|
|
43
|
+
* timeout: Duration.minutes(15)
|
|
44
|
+
* },
|
|
45
|
+
* multipleCpu: {
|
|
46
|
+
* memorySize: 10240,
|
|
47
|
+
* timeout: Duration.minutes(5)
|
|
48
|
+
* }
|
|
21
49
|
* }
|
|
22
50
|
*/
|
|
23
|
-
readonly
|
|
51
|
+
readonly additionalConfigurations?: Record<string, Pick<Nodejs24FunctionProps, "memorySize" | "timeout">>;
|
|
52
|
+
/**
|
|
53
|
+
* If you set up EmailAlarms you can pass it here and alarms for SQS and DLQ will be added automatically.
|
|
54
|
+
*/
|
|
55
|
+
readonly alarms?: EmailAlarms;
|
|
24
56
|
}
|
|
25
57
|
declare class SqsHandler extends Construct {
|
|
26
|
-
private readonly
|
|
27
|
-
readonly handler: NodejsFunction;
|
|
58
|
+
private readonly configurations;
|
|
28
59
|
constructor(scope: Construct, id: string, props: SqsHandlerProps);
|
|
29
60
|
readonly grantAccess: (grantee: Function) => void;
|
|
61
|
+
readonly forEachHandler: (callback: (handler: NodejsFunction) => void) => void;
|
|
62
|
+
private readonly toEnvironmentVariables;
|
|
30
63
|
}
|
|
31
64
|
export { SqsHandlerProps, SqsHandler };
|
package/dist/cdk.js
CHANGED
|
@@ -1,42 +1,80 @@
|
|
|
1
1
|
// packages/sqs-handler/cdk.ts
|
|
2
2
|
import {
|
|
3
|
-
|
|
3
|
+
Nodejs24Function,
|
|
4
4
|
SqsWithDlq
|
|
5
5
|
} from "@beesolve/cdk-constructs";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
NodejsFunction
|
|
9
|
-
} from "aws-cdk-lib/aws-lambda-nodejs";
|
|
6
|
+
import { capitalizeFirstLetter } from "@beesolve/helpers";
|
|
10
7
|
import { Construct } from "constructs";
|
|
11
|
-
|
|
12
|
-
var __dirname = "/Users/ivan/data/work/github.com/beesolve/p/packages/packages/sqs-handler";
|
|
8
|
+
var mainQueueLabel = "main";
|
|
13
9
|
|
|
14
10
|
class SqsHandler extends Construct {
|
|
15
|
-
|
|
16
|
-
handler;
|
|
11
|
+
configurations = {};
|
|
17
12
|
constructor(scope, id, props) {
|
|
18
13
|
super(scope, id);
|
|
19
|
-
const {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
14
|
+
const {
|
|
15
|
+
handlerProps,
|
|
16
|
+
queueProps,
|
|
17
|
+
additionalConfigurations: additionalHandlerConfigurations = {},
|
|
18
|
+
alarms
|
|
19
|
+
} = props;
|
|
20
|
+
const configurations = {
|
|
21
|
+
...additionalHandlerConfigurations,
|
|
22
|
+
[mainQueueLabel]: {
|
|
23
|
+
memorySize: handlerProps.memorySize,
|
|
24
|
+
timeout: handlerProps.timeout
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
const { description, memorySize, timeout, ...mainConfig } = handlerProps;
|
|
28
|
+
for (const [name, config] of Object.entries(configurations)) {
|
|
29
|
+
const prefix = capitalizeFirstLetter(name);
|
|
30
|
+
const handlerId = `${prefix}Handler`;
|
|
31
|
+
const handler = new Nodejs24Function(this, handlerId, {
|
|
32
|
+
description: `${description ?? "Tasks queue handler"} - ${name}`,
|
|
33
|
+
...mainConfig,
|
|
34
|
+
...config
|
|
35
|
+
});
|
|
36
|
+
const queue = SqsWithDlq.asLambdaInput({
|
|
37
|
+
lambda: handler,
|
|
38
|
+
...queueProps
|
|
39
|
+
});
|
|
40
|
+
alarms?.reportSqsErrors(queue);
|
|
41
|
+
this.configurations[name] = {
|
|
42
|
+
handler,
|
|
43
|
+
queue
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
const env = this.toEnvironmentVariables();
|
|
47
|
+
this.forEachHandler((handler) => {
|
|
48
|
+
env.forEach(({ key, value }) => handler.addEnvironment(key, value));
|
|
32
49
|
});
|
|
33
|
-
this.handler.addEnvironment("BEESOLVE_TASKS_QUEUE_URL", this.queue.queue.queueUrl);
|
|
34
|
-
props.alarms?.reportSqsErrors(this.queue);
|
|
35
|
-
props.alarms?.reportLambdaErrors(this.handler);
|
|
36
50
|
}
|
|
37
51
|
grantAccess = (grantee) => {
|
|
38
|
-
this.
|
|
39
|
-
|
|
52
|
+
Object.values(this.configurations).forEach(({ queue }) => {
|
|
53
|
+
queue.queue.grantSendMessages(grantee);
|
|
54
|
+
});
|
|
55
|
+
const env = this.toEnvironmentVariables();
|
|
56
|
+
env.forEach(({ key, value }) => grantee.addEnvironment(key, value));
|
|
57
|
+
};
|
|
58
|
+
forEachHandler = (callback) => {
|
|
59
|
+
Object.values(this.configurations).forEach(({ handler }) => callback(handler));
|
|
60
|
+
};
|
|
61
|
+
toEnvironmentVariables = () => {
|
|
62
|
+
const { [mainQueueLabel]: main, ...rest } = this.configurations;
|
|
63
|
+
if (main == null)
|
|
64
|
+
throw Error(`Unexpected error. Main queue and handler not set.`);
|
|
65
|
+
return [
|
|
66
|
+
{
|
|
67
|
+
key: "BEESOLVE_TASKS_MAIN_QUEUE_URL",
|
|
68
|
+
value: main.queue.queue.queueUrl
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
key: "BEESOLVE_TASKS_ADDITIONAL_QUEUE_URLS",
|
|
72
|
+
value: JSON.stringify(Object.fromEntries(Object.entries(rest).map(([key, { queue }]) => [
|
|
73
|
+
key,
|
|
74
|
+
queue.queue.queueUrl
|
|
75
|
+
])))
|
|
76
|
+
}
|
|
77
|
+
];
|
|
40
78
|
};
|
|
41
79
|
}
|
|
42
80
|
export {
|
package/dist/index.d.ts
CHANGED
|
@@ -3,10 +3,12 @@ import { SQSEvent } from "aws-lambda";
|
|
|
3
3
|
type Functions = Record<string, (...args: any[]) => Promise<void>>;
|
|
4
4
|
declare function createSqsHandlers<
|
|
5
5
|
TFunctions extends Functions,
|
|
6
|
+
const TQueueName extends string,
|
|
6
7
|
Fifo extends boolean
|
|
7
8
|
>(props: {
|
|
8
9
|
readonly functions: TFunctions;
|
|
9
|
-
readonly
|
|
10
|
+
readonly queueUrls: Record<TQueueName | "main", string>;
|
|
11
|
+
readonly queueUrlOverride?: Partial<Record<keyof TFunctions, TQueueName>>;
|
|
10
12
|
readonly localInvocation?: true;
|
|
11
13
|
readonly sqsClient: Pick<SQSClient, "send">;
|
|
12
14
|
readonly fifo: Fifo;
|
|
@@ -14,14 +16,18 @@ declare function createSqsHandlers<
|
|
|
14
16
|
batchItemFailures: {
|
|
15
17
|
itemIdentifier: string;
|
|
16
18
|
}[];
|
|
17
|
-
}>, QueuedFunctions<TFunctions, Fifo>];
|
|
19
|
+
}>, QueuedFunctions<TFunctions, Fifo, TQueueName>];
|
|
18
20
|
type QueuedFunctions<
|
|
19
21
|
T extends Functions,
|
|
20
|
-
Fifo extends boolean
|
|
21
|
-
|
|
22
|
+
Fifo extends boolean,
|
|
23
|
+
QueueName extends string
|
|
24
|
+
> = { [key in keyof T] : AddParameters<T[key], [options?: Fifo extends true ? {
|
|
25
|
+
readonly queueName?: QueueName;
|
|
22
26
|
readonly deduplicationId?: string;
|
|
23
27
|
readonly groupId?: string;
|
|
24
|
-
} :
|
|
28
|
+
} : {
|
|
29
|
+
readonly queueName?: QueueName;
|
|
30
|
+
}]> };
|
|
25
31
|
type AddParameters<
|
|
26
32
|
TFunction extends (...args: any) => any,
|
|
27
33
|
TParameters extends [...args: any]
|
package/dist/index.js
CHANGED
|
@@ -15,9 +15,12 @@ function createSqsHandlers(props) {
|
|
|
15
15
|
args: v.array(v.any())
|
|
16
16
|
})), body);
|
|
17
17
|
if (!result.success)
|
|
18
|
-
throw new Error(`Wrong message format: ${JSON.stringify(v.flatten(result.issues))}`);
|
|
18
|
+
throw new Error(`Wrong message format: ${JSON.stringify(v.flatten(result.issues), null, 2)}`);
|
|
19
19
|
const { fn, args } = result.output;
|
|
20
|
-
console.info(
|
|
20
|
+
console.info({
|
|
21
|
+
function: fn,
|
|
22
|
+
arguments: JSON.stringify(args)
|
|
23
|
+
});
|
|
21
24
|
await props.functions[fn]?.(...args.map((args2) => decodeFromStringifiable(args2)));
|
|
22
25
|
} catch (error) {
|
|
23
26
|
console.error(error);
|
|
@@ -28,23 +31,24 @@ function createSqsHandlers(props) {
|
|
|
28
31
|
};
|
|
29
32
|
const functions = Object.entries(props.functions).reduce((result, [functionName]) => ({
|
|
30
33
|
...result,
|
|
31
|
-
|
|
34
|
+
[functionName](...args) {
|
|
32
35
|
const originalFunction = props.functions[functionName];
|
|
33
36
|
if (originalFunction == null)
|
|
34
37
|
throw Error(`Cannot invoke "${functionName}". Make sure the function is defined.`);
|
|
35
38
|
const functionArgs = args.slice(0, originalFunction.length);
|
|
36
|
-
const
|
|
39
|
+
const options = args[originalFunction.length];
|
|
37
40
|
if (props.localInvocation) {
|
|
38
41
|
originalFunction(...functionArgs);
|
|
39
42
|
} else {
|
|
40
|
-
|
|
41
|
-
|
|
43
|
+
const queueUrl = options?.queueName ?? props.queueUrls[props.queueUrlOverride?.[functionName] ?? "main"];
|
|
44
|
+
props.sqsClient.send(new SendMessageCommand({
|
|
45
|
+
QueueUrl: queueUrl,
|
|
42
46
|
MessageBody: JSON.stringify({
|
|
43
47
|
fn: functionName,
|
|
44
48
|
args: functionArgs.map((args2) => encodeToStringifiable(args2))
|
|
45
49
|
}),
|
|
46
|
-
MessageDeduplicationId:
|
|
47
|
-
MessageGroupId:
|
|
50
|
+
MessageDeduplicationId: options?.deduplicationId,
|
|
51
|
+
MessageGroupId: options?.groupId
|
|
48
52
|
}));
|
|
49
53
|
}
|
|
50
54
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@beesolve/sqs-handler",
|
|
3
3
|
"description": "",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.10",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
7
7
|
"dist"
|
|
@@ -41,13 +41,13 @@
|
|
|
41
41
|
}
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"aws-cdk-lib": "^2.
|
|
44
|
+
"aws-cdk-lib": "^2.238.0",
|
|
45
45
|
"constructs": "^10.4.5",
|
|
46
|
-
"@aws-sdk/client-sqs": "^3.
|
|
46
|
+
"@aws-sdk/client-sqs": "^3.990.0",
|
|
47
47
|
"valibot": "^1.2.0",
|
|
48
48
|
"@beesolve/helpers": "0.1.4",
|
|
49
49
|
"@beesolve/cdk-email-alarms": "0.1.1",
|
|
50
|
-
"@beesolve/cdk-constructs": "0.1.
|
|
50
|
+
"@beesolve/cdk-constructs": "0.1.6"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@types/aws-lambda": "^8.10.160"
|