@beesolve/sqs-handler 0.1.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/README.md +13 -0
- package/dist/cdk.d.ts +23 -0
- package/dist/cdk.js +47 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.js +59 -0
- package/package.json +55 -0
package/README.md
ADDED
package/dist/cdk.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { EmailAlarms } from "@beesolve/cdk-email-alarms";
|
|
2
|
+
import { Function } from "aws-cdk-lib/aws-lambda";
|
|
3
|
+
import { NodejsFunction, NodejsFunctionProps } from "aws-cdk-lib/aws-lambda-nodejs";
|
|
4
|
+
import { Construct } from "constructs";
|
|
5
|
+
interface SqsHandlerProps {
|
|
6
|
+
/**
|
|
7
|
+
* Path to file where SDK handler is exported.
|
|
8
|
+
*/
|
|
9
|
+
readonly entry: string;
|
|
10
|
+
/**
|
|
11
|
+
* @default false
|
|
12
|
+
*/
|
|
13
|
+
readonly isProd?: boolean;
|
|
14
|
+
readonly alarms: EmailAlarms;
|
|
15
|
+
readonly handlerProps?: Pick<NodejsFunctionProps, "memorySize" | "timeout">;
|
|
16
|
+
}
|
|
17
|
+
declare class SqsHandler extends Construct {
|
|
18
|
+
private readonly queue;
|
|
19
|
+
readonly handler: NodejsFunction;
|
|
20
|
+
constructor(scope: Construct, id: string, props: SqsHandlerProps);
|
|
21
|
+
readonly grantAccess: (grantee: Function) => void;
|
|
22
|
+
}
|
|
23
|
+
export { SqsHandlerProps, SqsHandler };
|
package/dist/cdk.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// packages/sqs-handler/cdk.ts
|
|
2
|
+
import { Duration } from "aws-cdk-lib";
|
|
3
|
+
import { Architecture, Runtime } from "aws-cdk-lib/aws-lambda";
|
|
4
|
+
import {
|
|
5
|
+
NodejsFunction
|
|
6
|
+
} from "aws-cdk-lib/aws-lambda-nodejs";
|
|
7
|
+
import { Construct } from "constructs";
|
|
8
|
+
import { resolve } from "node:path";
|
|
9
|
+
var __dirname = "/Users/ivan/data/work/github.com/beesolve/p/packages/packages/sqs-handler";
|
|
10
|
+
|
|
11
|
+
class SqsHandler extends Construct {
|
|
12
|
+
queue;
|
|
13
|
+
handler;
|
|
14
|
+
constructor(scope, id, props) {
|
|
15
|
+
super(scope, id);
|
|
16
|
+
const { isProd = false, handlerProps = {} } = props;
|
|
17
|
+
this.handler = new NodejsFunction(this, "QueueHandler", {
|
|
18
|
+
description: "Tasks queue handler",
|
|
19
|
+
entry: resolve(__dirname, props.entry),
|
|
20
|
+
handler: "handler",
|
|
21
|
+
bundling: {
|
|
22
|
+
minify: isProd,
|
|
23
|
+
sourceMap: isProd,
|
|
24
|
+
sourcesContent: false,
|
|
25
|
+
target: "es2022"
|
|
26
|
+
},
|
|
27
|
+
memorySize: 1024,
|
|
28
|
+
timeout: Duration.seconds(30),
|
|
29
|
+
runtime: Runtime.NODEJS_24_X,
|
|
30
|
+
architecture: Architecture.ARM_64,
|
|
31
|
+
depsLockFilePath: resolve(`${__dirname}/../../bun.lock`),
|
|
32
|
+
...handlerProps
|
|
33
|
+
});
|
|
34
|
+
this.queue = SqsWithDlq.asLambdaInput({
|
|
35
|
+
lambda: this.handler
|
|
36
|
+
});
|
|
37
|
+
this.handler.addEnvironment("BEESOLVE_TASKS_QUEUE_URL", this.queue.queue.queueUrl);
|
|
38
|
+
props.alarms.reportSqsErrors(this.queue);
|
|
39
|
+
}
|
|
40
|
+
grantAccess = (grantee) => {
|
|
41
|
+
this.queue.queue.grantSendMessages(grantee);
|
|
42
|
+
grantee.addEnvironment("BEESOLVE_TASKS_QUEUE_URL", this.queue.queue.queueUrl);
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
export {
|
|
46
|
+
SqsHandler
|
|
47
|
+
};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { SQSClient } from "@aws-sdk/client-sqs";
|
|
2
|
+
import { SQSEvent } from "aws-lambda";
|
|
3
|
+
type Functions = Record<string, (...args: any[]) => Promise<void>>;
|
|
4
|
+
declare function createSqsHandlers<
|
|
5
|
+
TFunctions extends Functions,
|
|
6
|
+
Fifo extends boolean
|
|
7
|
+
>(props: {
|
|
8
|
+
readonly functions: TFunctions;
|
|
9
|
+
readonly queueUrl: string;
|
|
10
|
+
readonly localInvocation?: true;
|
|
11
|
+
readonly sqsClient: Pick<SQSClient, "send">;
|
|
12
|
+
readonly fifo: Fifo;
|
|
13
|
+
}): [(event: SQSEvent) => Promise<{
|
|
14
|
+
batchItemFailures: {
|
|
15
|
+
itemIdentifier: string;
|
|
16
|
+
}[];
|
|
17
|
+
}>, QueuedFunctions<TFunctions, Fifo>];
|
|
18
|
+
type QueuedFunctions<
|
|
19
|
+
T extends Functions,
|
|
20
|
+
Fifo extends boolean
|
|
21
|
+
> = { [key in keyof T] : AddParameters<T[key], [fifoOptions?: Fifo extends true ? {
|
|
22
|
+
readonly deduplicationId?: string;
|
|
23
|
+
readonly groupId?: string;
|
|
24
|
+
} : never]> };
|
|
25
|
+
type AddParameters<
|
|
26
|
+
TFunction extends (...args: any) => any,
|
|
27
|
+
TParameters extends [...args: any]
|
|
28
|
+
> = (...args: [...Parameters<TFunction>, ...TParameters]) => Promise<void>;
|
|
29
|
+
export { createSqsHandlers };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// packages/sqs-handler/index.ts
|
|
2
|
+
import { SendMessageCommand } from "@aws-sdk/client-sqs";
|
|
3
|
+
import {
|
|
4
|
+
decodeFromStringifiable,
|
|
5
|
+
encodeToStringifiable
|
|
6
|
+
} from "@beesolve/helpers";
|
|
7
|
+
import * as v from "valibot";
|
|
8
|
+
function createSqsHandlers(props) {
|
|
9
|
+
const handler = async (event) => {
|
|
10
|
+
const batchItemFailures = new Array;
|
|
11
|
+
for (const { body, messageId } of event.Records) {
|
|
12
|
+
try {
|
|
13
|
+
const result = v.safeParse(v.pipe(v.string(), v.parseJson(), v.object({
|
|
14
|
+
fName: v.picklist(Object.keys(props.functions)),
|
|
15
|
+
fArgs: v.array(v.any())
|
|
16
|
+
})), body);
|
|
17
|
+
if (!result.success)
|
|
18
|
+
throw new Error(`Wrong message format: ${JSON.stringify(v.flatten(result.issues), null, 2)}`);
|
|
19
|
+
const { fName, fArgs } = result.output;
|
|
20
|
+
console.info({
|
|
21
|
+
function: fName,
|
|
22
|
+
arguments: JSON.stringify(fArgs, null, 2)
|
|
23
|
+
});
|
|
24
|
+
await props.functions[fName]?.(...fArgs.map((args) => decodeFromStringifiable(args)));
|
|
25
|
+
} catch (error) {
|
|
26
|
+
console.error(error);
|
|
27
|
+
batchItemFailures.push({ itemIdentifier: messageId });
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return { batchItemFailures };
|
|
31
|
+
};
|
|
32
|
+
const functions = Object.entries(props.functions).reduce((result, [functionName]) => ({
|
|
33
|
+
...result,
|
|
34
|
+
[functionName](...args) {
|
|
35
|
+
const originalFunction = props.functions[functionName];
|
|
36
|
+
if (originalFunction == null)
|
|
37
|
+
throw Error(`Cannot invoke "${functionName}". Make sure the function is defined.`);
|
|
38
|
+
const functionArgs = args.slice(0, originalFunction.length);
|
|
39
|
+
const fifoOptions = args[originalFunction.length];
|
|
40
|
+
if (props.localInvocation) {
|
|
41
|
+
originalFunction(...functionArgs);
|
|
42
|
+
} else {
|
|
43
|
+
props.sqsClient.send(new SendMessageCommand({
|
|
44
|
+
QueueUrl: props.queueUrl,
|
|
45
|
+
MessageBody: JSON.stringify({
|
|
46
|
+
fName: functionName,
|
|
47
|
+
fArgs: functionArgs.map((args2) => encodeToStringifiable(args2))
|
|
48
|
+
}),
|
|
49
|
+
MessageDeduplicationId: fifoOptions?.deduplicationId,
|
|
50
|
+
MessageGroupId: fifoOptions?.groupId
|
|
51
|
+
}));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}), {});
|
|
55
|
+
return [handler, functions];
|
|
56
|
+
}
|
|
57
|
+
export {
|
|
58
|
+
createSqsHandlers
|
|
59
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@beesolve/sqs-handler",
|
|
3
|
+
"description": "",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist"
|
|
8
|
+
],
|
|
9
|
+
"module": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"import": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"default": "./dist/index.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"./cdk": {
|
|
19
|
+
"import": {
|
|
20
|
+
"types": "./dist/cdk.d.ts",
|
|
21
|
+
"default": "./dist/cdk.js"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"./package.json": "./package.json"
|
|
25
|
+
},
|
|
26
|
+
"homepage": "https://github.com/beesolve/packages/tree/main/packages/sqs-handler#readme",
|
|
27
|
+
"license": "MIT",
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "git+https://github.com/beesolve/packages.git"
|
|
31
|
+
},
|
|
32
|
+
"scripts": {
|
|
33
|
+
"type-check": "tsc --noEmit"
|
|
34
|
+
},
|
|
35
|
+
"peerDependencies": {
|
|
36
|
+
"typescript": "catalog:"
|
|
37
|
+
},
|
|
38
|
+
"peerDependenciesMeta": {
|
|
39
|
+
"typescript": {
|
|
40
|
+
"optional": true
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"aws-cdk-lib": "catalog:",
|
|
45
|
+
"constructs": "catalog:",
|
|
46
|
+
"@aws-sdk/client-sqs": "catalog:",
|
|
47
|
+
"valibot": "catalog:",
|
|
48
|
+
"@beesolve/helpers": "workspace:*",
|
|
49
|
+
"@beesolve/cdk-email-alarms": "workspace:*",
|
|
50
|
+
"@beesolve/cdk-constructs": "workspace:*"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@types/aws-lambda": "catalog:"
|
|
54
|
+
}
|
|
55
|
+
}
|