@geekmidas/constructs 10.0.0-alpha.52 → 10.0.0-alpha.53
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/dist/adaptors/aws.cjs +12 -195
- package/dist/adaptors/aws.cjs.map +1 -1
- package/dist/adaptors/aws.d.cts +0 -55
- package/dist/adaptors/aws.d.cts.map +1 -1
- package/dist/adaptors/aws.d.mts +0 -55
- package/dist/adaptors/aws.d.mts.map +1 -1
- package/dist/adaptors/aws.mjs +13 -195
- package/dist/adaptors/aws.mjs.map +1 -1
- package/dist/runSubscriber-BRp9a_qi.cjs +126 -0
- package/dist/runSubscriber-BRp9a_qi.cjs.map +1 -0
- package/dist/runSubscriber-BYEY_bfA.mjs +109 -0
- package/dist/runSubscriber-BYEY_bfA.mjs.map +1 -0
- package/dist/subscribers/index.cjs +107 -0
- package/dist/subscribers/index.cjs.map +1 -0
- package/dist/subscribers/index.d.cts +48 -1
- package/dist/subscribers/index.d.cts.map +1 -0
- package/dist/subscribers/index.d.mts +48 -1
- package/dist/subscribers/index.d.mts.map +1 -0
- package/dist/subscribers/index.mjs +107 -1
- package/dist/subscribers/index.mjs.map +1 -0
- package/package.json +31 -31
package/dist/adaptors/aws.mjs
CHANGED
|
@@ -3,6 +3,7 @@ import { a as publishEvents, i as publishConstructEvents, t as FunctionBuilder }
|
|
|
3
3
|
import { i as require_lodash_set, n as ResponseBuilder, t as Endpoint } from "../Endpoint-CQ9RJ7p2.mjs";
|
|
4
4
|
import { n as envParserFor } from "../surfaceEnv-wMT5QzgZ.mjs";
|
|
5
5
|
import { t as createApiGatewayCookies } from "../lazyAccessors-CFanua0O.mjs";
|
|
6
|
+
import { n as subscribedEvents, r as subscriberContext, t as runSubscriber } from "../runSubscriber-BYEY_bfA.mjs";
|
|
6
7
|
import { n as executeWithAuditTransaction, t as createAuditContext } from "../processAudits-BpRlPQMW.mjs";
|
|
7
8
|
import { ForbiddenError, UnprocessableEntityError, wrapError } from "@geekmidas/errors";
|
|
8
9
|
import { ServiceDiscovery, runWithRequestContext } from "@geekmidas/services";
|
|
@@ -11,7 +12,6 @@ import qs from "qs";
|
|
|
11
12
|
import { DefaultAuditor } from "@geekmidas/audit";
|
|
12
13
|
import middy from "@middy/core";
|
|
13
14
|
import { withAuditableTransaction } from "@geekmidas/audit/kysely";
|
|
14
|
-
import { confirmSnsSubscription, toSnsEvent, verifySnsMessage } from "@geekmidas/events/sns";
|
|
15
15
|
//#region src/functions/FunctionExecutionWrapper.ts
|
|
16
16
|
var FunctionExecutionWrapper = class {
|
|
17
17
|
envParser;
|
|
@@ -710,7 +710,6 @@ var AWSLambdaSubscriber = class {
|
|
|
710
710
|
envParser;
|
|
711
711
|
subscriber;
|
|
712
712
|
_logger;
|
|
713
|
-
_services;
|
|
714
713
|
constructor(envParser, subscriber) {
|
|
715
714
|
this.envParser = envParser;
|
|
716
715
|
this.subscriber = subscriber;
|
|
@@ -719,21 +718,6 @@ var AWSLambdaSubscriber = class {
|
|
|
719
718
|
get logger() {
|
|
720
719
|
return this._logger;
|
|
721
720
|
}
|
|
722
|
-
async getServices() {
|
|
723
|
-
if (this._services) return this._services;
|
|
724
|
-
const serviceDiscovery = ServiceDiscovery.getInstance(this.envParser);
|
|
725
|
-
if (this.subscriber.services.length > 0) {
|
|
726
|
-
const registered = await serviceDiscovery.register(this.subscriber.services);
|
|
727
|
-
this._services = registered;
|
|
728
|
-
} else this._services = {};
|
|
729
|
-
return this._services;
|
|
730
|
-
}
|
|
731
|
-
/** The subscriber's database, registered as functions register theirs. */
|
|
732
|
-
async getDatabase() {
|
|
733
|
-
const service = this.subscriber.databaseService;
|
|
734
|
-
if (!service) return void 0;
|
|
735
|
-
return (await ServiceDiscovery.getInstance(this.envParser).register([service]))[service.serviceName];
|
|
736
|
-
}
|
|
737
721
|
error() {
|
|
738
722
|
return { onError: (req) => {
|
|
739
723
|
(req.event?.logger || this.subscriber.logger).error(req.error || {}, "Error processing subscriber");
|
|
@@ -755,112 +739,26 @@ var AWSLambdaSubscriber = class {
|
|
|
755
739
|
}
|
|
756
740
|
services() {
|
|
757
741
|
return { before: async (req) => {
|
|
758
|
-
|
|
759
|
-
req.event.
|
|
742
|
+
const { services, db } = await subscriberContext(this.subscriber, this.envParser);
|
|
743
|
+
req.event.services = services;
|
|
744
|
+
req.event.db = db;
|
|
760
745
|
} };
|
|
761
746
|
}
|
|
762
747
|
parseEvents() {
|
|
763
748
|
return { before: async (req) => {
|
|
764
|
-
const { logger, ...
|
|
765
|
-
const rawEvent = e;
|
|
749
|
+
const { logger, ...rawEvent } = req.event;
|
|
766
750
|
logger.info({ rawEvent });
|
|
767
|
-
|
|
768
|
-
if ("Records" in rawEvent) {
|
|
769
|
-
if (this.isSQSEvent(rawEvent)) for (const record of rawEvent.Records) try {
|
|
770
|
-
const event = this.parseSQSRecord(record);
|
|
771
|
-
if (this.shouldIncludeEvent(event)) events.push(event);
|
|
772
|
-
} catch (error) {
|
|
773
|
-
this.logger.error({
|
|
774
|
-
error,
|
|
775
|
-
record
|
|
776
|
-
}, "Failed to parse SQS record");
|
|
777
|
-
}
|
|
778
|
-
else if (this.isSNSEvent(rawEvent)) for (const record of rawEvent.Records) try {
|
|
779
|
-
const event = this.parseSNSRecord(record);
|
|
780
|
-
if (this.shouldIncludeEvent(event)) events.push(event);
|
|
781
|
-
} catch (error) {
|
|
782
|
-
this.logger.error({
|
|
783
|
-
error,
|
|
784
|
-
record
|
|
785
|
-
}, "Failed to parse SNS record");
|
|
786
|
-
}
|
|
787
|
-
}
|
|
788
|
-
req.event.events = events;
|
|
751
|
+
req.event.events = subscribedEvents(this.subscriber, rawEvent, this.logger);
|
|
789
752
|
} };
|
|
790
753
|
}
|
|
791
|
-
isSQSEvent(event) {
|
|
792
|
-
const firstRecord = event.Records[0];
|
|
793
|
-
return "Records" in event && event.Records.length > 0 && firstRecord !== void 0 && "eventSource" in firstRecord && firstRecord.eventSource === "aws:sqs";
|
|
794
|
-
}
|
|
795
|
-
isSNSEvent(event) {
|
|
796
|
-
const firstRecord = event.Records[0];
|
|
797
|
-
return "Records" in event && event.Records.length > 0 && firstRecord !== void 0 && "EventSource" in firstRecord && firstRecord.EventSource === "aws:sns";
|
|
798
|
-
}
|
|
799
|
-
parseSNSRecord(record) {
|
|
800
|
-
const message = this.safeJsonParse(record.Sns.Message);
|
|
801
|
-
const messageType = record.Sns.MessageAttributes?.type?.Value;
|
|
802
|
-
if (message === null) return messageType ? {
|
|
803
|
-
type: messageType,
|
|
804
|
-
payload: record.Sns.Message
|
|
805
|
-
} : record.Sns.Message;
|
|
806
|
-
const resolvedType = messageType ?? message.type;
|
|
807
|
-
if (message.type) return message;
|
|
808
|
-
return resolvedType ? {
|
|
809
|
-
type: resolvedType,
|
|
810
|
-
payload: message
|
|
811
|
-
} : message;
|
|
812
|
-
}
|
|
813
|
-
parseSQSRecord(record) {
|
|
814
|
-
const body = this.safeJsonParse(record.body);
|
|
815
|
-
if (body === null) return record.body;
|
|
816
|
-
if (body.Type === "Notification" && body.Message) {
|
|
817
|
-
const snsMessage = this.safeJsonParse(body.Message);
|
|
818
|
-
const messageType = body.MessageAttributes?.type?.Value;
|
|
819
|
-
if (snsMessage === null) return messageType ? {
|
|
820
|
-
type: messageType,
|
|
821
|
-
payload: body.Message
|
|
822
|
-
} : body.Message;
|
|
823
|
-
if (snsMessage.type) return snsMessage;
|
|
824
|
-
const resolvedType = messageType ?? snsMessage.type;
|
|
825
|
-
return resolvedType ? {
|
|
826
|
-
type: resolvedType,
|
|
827
|
-
payload: snsMessage
|
|
828
|
-
} : snsMessage;
|
|
829
|
-
}
|
|
830
|
-
return body;
|
|
831
|
-
}
|
|
832
|
-
safeJsonParse(value) {
|
|
833
|
-
try {
|
|
834
|
-
return JSON.parse(value);
|
|
835
|
-
} catch {
|
|
836
|
-
return null;
|
|
837
|
-
}
|
|
838
|
-
}
|
|
839
|
-
shouldIncludeEvent(event) {
|
|
840
|
-
if (typeof event !== "object" || !event?.type) return true;
|
|
841
|
-
if (!this.subscriber.subscribedEvents) return true;
|
|
842
|
-
return this.subscriber.subscribedEvents.includes(event.type);
|
|
843
|
-
}
|
|
844
754
|
async _handler(event) {
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
services: event.services,
|
|
852
|
-
logger: event.logger,
|
|
853
|
-
db: event.db
|
|
755
|
+
const { events, services, logger, db } = event;
|
|
756
|
+
return runSubscriber(this.subscriber, {
|
|
757
|
+
events,
|
|
758
|
+
services,
|
|
759
|
+
logger,
|
|
760
|
+
db
|
|
854
761
|
});
|
|
855
|
-
if (this.subscriber.outputSchema && result) {
|
|
856
|
-
const validationResult = await this.subscriber.outputSchema["~standard"].validate(result);
|
|
857
|
-
if (validationResult.issues) {
|
|
858
|
-
this.logger.error({ issues: validationResult.issues }, "Subscriber output validation failed");
|
|
859
|
-
throw new Error("Subscriber output validation failed");
|
|
860
|
-
}
|
|
861
|
-
return validationResult.value;
|
|
862
|
-
}
|
|
863
|
-
return result;
|
|
864
762
|
}
|
|
865
763
|
get handler() {
|
|
866
764
|
const handler = this._handler.bind(this);
|
|
@@ -879,86 +777,6 @@ var AWSLambdaSubscriber = class {
|
|
|
879
777
|
}
|
|
880
778
|
};
|
|
881
779
|
//#endregion
|
|
882
|
-
|
|
883
|
-
/**
|
|
884
|
-
* A topic subscriber run by SNS pushing to an HTTP endpoint, rather than by a
|
|
885
|
-
* poller.
|
|
886
|
-
*
|
|
887
|
-
* The notification is handed to {@link AWSLambdaSubscriber} as the Lambda
|
|
888
|
-
* event SNS would have invoked a function with, so the parsing, the services
|
|
889
|
-
* and the error handling are the ones that run deployed on Lambda — the
|
|
890
|
-
* endpoint is only a different way for the event to arrive.
|
|
891
|
-
*/
|
|
892
|
-
var SnsPushSubscriberAdaptor = class {
|
|
893
|
-
subscriber;
|
|
894
|
-
options;
|
|
895
|
-
lambda;
|
|
896
|
-
constructor(envParser, subscriber, options) {
|
|
897
|
-
this.subscriber = subscriber;
|
|
898
|
-
this.options = options;
|
|
899
|
-
this.lambda = new AWSLambdaSubscriber(envParser, subscriber);
|
|
900
|
-
}
|
|
901
|
-
async handle(body) {
|
|
902
|
-
const message = body;
|
|
903
|
-
if (typeof message?.Type !== "string" || !message.TopicArn) return refuse(400, "not an SNS message");
|
|
904
|
-
if (message.TopicArn !== this.options.topicArn) return refuse(403, `not subscribed to ${message.TopicArn}`);
|
|
905
|
-
if (this.options.verify) try {
|
|
906
|
-
await verifySnsMessage(message);
|
|
907
|
-
} catch (error) {
|
|
908
|
-
this.subscriber.logger.warn({
|
|
909
|
-
error,
|
|
910
|
-
topicArn: message.TopicArn
|
|
911
|
-
}, "Refused an SNS message that did not verify");
|
|
912
|
-
return refuse(403, error.name);
|
|
913
|
-
}
|
|
914
|
-
switch (message.Type) {
|
|
915
|
-
case "SubscriptionConfirmation":
|
|
916
|
-
await confirmSnsSubscription(this.options.emulatorEndpoint && message.SubscribeURL ? {
|
|
917
|
-
...message,
|
|
918
|
-
SubscribeURL: throughEndpoint(message.SubscribeURL, this.options.emulatorEndpoint)
|
|
919
|
-
} : message);
|
|
920
|
-
this.subscriber.logger.info({ topicArn: message.TopicArn }, "Confirmed SNS subscription");
|
|
921
|
-
return {
|
|
922
|
-
status: 200,
|
|
923
|
-
body: { status: "confirmed" }
|
|
924
|
-
};
|
|
925
|
-
case "Notification": try {
|
|
926
|
-
await this.lambda.handler(toSnsEvent(message), {
|
|
927
|
-
awsRequestId: message.MessageId,
|
|
928
|
-
functionName: this.subscriber.topicName ?? "subscriber"
|
|
929
|
-
}, () => {});
|
|
930
|
-
return {
|
|
931
|
-
status: 200,
|
|
932
|
-
body: { status: "ok" }
|
|
933
|
-
};
|
|
934
|
-
} catch (error) {
|
|
935
|
-
return refuse(500, error.name);
|
|
936
|
-
}
|
|
937
|
-
default: return {
|
|
938
|
-
status: 200,
|
|
939
|
-
body: { status: "ignored" }
|
|
940
|
-
};
|
|
941
|
-
}
|
|
942
|
-
}
|
|
943
|
-
};
|
|
944
|
-
/** `url`, sent to `endpoint`'s origin instead of its own. */
|
|
945
|
-
function throughEndpoint(url, endpoint) {
|
|
946
|
-
const target = new URL(url);
|
|
947
|
-
const origin = new URL(endpoint);
|
|
948
|
-
target.protocol = origin.protocol;
|
|
949
|
-
target.host = origin.host;
|
|
950
|
-
return target.toString();
|
|
951
|
-
}
|
|
952
|
-
function refuse(status, error) {
|
|
953
|
-
return {
|
|
954
|
-
status,
|
|
955
|
-
body: {
|
|
956
|
-
status: "refused",
|
|
957
|
-
error
|
|
958
|
-
}
|
|
959
|
-
};
|
|
960
|
-
}
|
|
961
|
-
//#endregion
|
|
962
|
-
export { AWSLambdaFunction, AWSLambdaQueue, AWSLambdaSubscriber, AWSScheduledFunction, AmazonApiGatewayV1Endpoint, AmazonApiGatewayV2Endpoint, SnsPushSubscriberAdaptor };
|
|
780
|
+
export { AWSLambdaFunction, AWSLambdaQueue, AWSLambdaSubscriber, AWSScheduledFunction, AmazonApiGatewayV1Endpoint, AmazonApiGatewayV2Endpoint };
|
|
963
781
|
|
|
964
782
|
//# sourceMappingURL=aws.mjs.map
|