@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.
@@ -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
- req.event.services = await this.getServices();
759
- req.event.db = await this.getDatabase();
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, ...e } = req.event;
765
- const rawEvent = e;
749
+ const { logger, ...rawEvent } = req.event;
766
750
  logger.info({ rawEvent });
767
- const events = [];
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
- if (event.events.length === 0) {
846
- this.logger.info("No subscribed events to process");
847
- return { batchItemFailures: [] };
848
- }
849
- const result = await this.subscriber.handler({
850
- events: event.events,
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
- //#region src/subscribers/SnsPushSubscriberAdaptor.ts
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