effortless-aws 0.20.0 → 0.22.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/dist/index.d.ts CHANGED
@@ -53,12 +53,12 @@ type EffortlessConfig = {
53
53
  */
54
54
  handlers?: string | string[];
55
55
  /**
56
- * Default settings applied to all handlers unless overridden.
56
+ * Default Lambda settings applied to all handlers unless overridden.
57
57
  *
58
58
  * All Lambdas run on ARM64 (Graviton2) architecture — ~20% cheaper than x86_64
59
59
  * with better price-performance for most workloads.
60
60
  */
61
- defaults?: {
61
+ lambda?: {
62
62
  /**
63
63
  * Lambda memory in MB. AWS allocates proportional CPU —
64
64
  * 1769 MB gives one full vCPU.
@@ -97,6 +97,22 @@ declare const defineConfig: (config: EffortlessConfig) => EffortlessConfig;
97
97
 
98
98
  type AwsService = "dynamodb" | "s3" | "sqs" | "sns" | "ses" | "ssm" | "lambda" | "events" | "secretsmanager" | "cognito-idp" | "logs";
99
99
  type Permission = `${AwsService}:${string}` | (string & {});
100
+ /**
101
+ * Human-readable duration. Accepts a plain number (seconds) or a string
102
+ * with a unit suffix: `"30s"`, `"5m"`, `"1h"`, `"2d"`.
103
+ *
104
+ * @example
105
+ * ```typescript
106
+ * timeout: 30 // 30 seconds
107
+ * timeout: "30s" // 30 seconds
108
+ * timeout: "5m" // 300 seconds
109
+ * timeout: "1h" // 3600 seconds
110
+ * retentionPeriod: "4d" // 345600 seconds
111
+ * ```
112
+ */
113
+ type Duration = number | `${number}s` | `${number}m` | `${number}h` | `${number}d`;
114
+ /** Convert a Duration to seconds. */
115
+ declare const toSeconds: (d: Duration) => number;
100
116
  /** Logging verbosity level for Lambda handlers */
101
117
  type LogLevel = "error" | "info" | "debug";
102
118
  /**
@@ -105,8 +121,8 @@ type LogLevel = "error" | "info" | "debug";
105
121
  type LambdaConfig = {
106
122
  /** Lambda memory in MB (default: 256) */
107
123
  memory?: number;
108
- /** Lambda timeout in seconds (default: 30) */
109
- timeout?: number;
124
+ /** Lambda timeout (default: 30s). Accepts seconds or duration string: `"30s"`, `"5m"` */
125
+ timeout?: Duration;
110
126
  /** Logging verbosity: "error" (errors only), "info" (+ execution summary), "debug" (+ input/output). Default: "info" */
111
127
  logLevel?: LogLevel;
112
128
  };
@@ -382,6 +398,31 @@ type HttpResponse = {
382
398
  contentType?: ContentType;
383
399
  /** Response headers (use for custom content-types not covered by contentType) */
384
400
  headers?: Record<string, string>;
401
+ /**
402
+ * Set to `true` to return binary data.
403
+ * When enabled, `body` must be a base64-encoded string and the response
404
+ * will include `isBase64Encoded: true` so Lambda Function URLs / API Gateway
405
+ * decode it back to binary for the client.
406
+ */
407
+ binary?: boolean;
408
+ };
409
+ /** Response helpers for defineApi handlers */
410
+ declare const result: {
411
+ /** Return a JSON response */
412
+ json: (body: unknown, status?: number) => HttpResponse;
413
+ /** Return a binary response. Accepts a Buffer and converts to base64 automatically. */
414
+ binary: (body: Buffer, contentType: string, headers?: Record<string, string>) => HttpResponse;
415
+ };
416
+ /** Stream helper injected into route args when `stream: true` is set on defineApi */
417
+ type ResponseStream = {
418
+ /** Write a raw string chunk to the response stream */
419
+ write(chunk: string): void;
420
+ /** End the response stream */
421
+ end(): void;
422
+ /** Switch to SSE mode: sets Content-Type to text/event-stream */
423
+ sse(): void;
424
+ /** Write an SSE event: `data: JSON.stringify(data)\n\n` */
425
+ event(data: unknown): void;
385
426
  };
386
427
  /** Service for reading static files bundled into the Lambda ZIP */
387
428
  type StaticFiles = {
@@ -422,7 +463,9 @@ type BucketClient = {
422
463
  /**
423
464
  * Configuration options for defineBucket.
424
465
  */
425
- type BucketConfig = LambdaWithPermissions & {
466
+ type BucketConfig = {
467
+ /** Lambda function settings (memory, timeout, permissions, etc.) */
468
+ lambda?: LambdaWithPermissions;
426
469
  /** S3 key prefix filter for event notifications (e.g., "uploads/") */
427
470
  prefix?: string;
428
471
  /** S3 key suffix filter for event notifications (e.g., ".jpg") */
@@ -630,6 +673,189 @@ type MailerHandler = {
630
673
  */
631
674
  declare const defineMailer: (options: MailerConfig) => MailerHandler;
632
675
 
676
+ /**
677
+ * Parsed SQS FIFO message passed to the handler callbacks.
678
+ *
679
+ * @typeParam T - Type of the decoded message body (from schema function)
680
+ */
681
+ type FifoQueueMessage<T = unknown> = {
682
+ /** Unique message identifier */
683
+ messageId: string;
684
+ /** Receipt handle for acknowledgement */
685
+ receiptHandle: string;
686
+ /** Parsed message body (JSON-decoded, then optionally schema-validated) */
687
+ body: T;
688
+ /** Raw unparsed message body string */
689
+ rawBody: string;
690
+ /** Message group ID (FIFO ordering key) */
691
+ messageGroupId: string;
692
+ /** Message deduplication ID */
693
+ messageDeduplicationId?: string;
694
+ /** SQS message attributes */
695
+ messageAttributes: Record<string, {
696
+ dataType?: string;
697
+ stringValue?: string;
698
+ }>;
699
+ /** Approximate first receive timestamp */
700
+ approximateFirstReceiveTimestamp?: string;
701
+ /** Approximate receive count */
702
+ approximateReceiveCount?: string;
703
+ /** Sent timestamp */
704
+ sentTimestamp?: string;
705
+ };
706
+ /**
707
+ * Configuration options for a FIFO queue handler
708
+ */
709
+ type FifoQueueConfig = {
710
+ /** Lambda function settings (memory, timeout, permissions, etc.) */
711
+ lambda?: LambdaWithPermissions;
712
+ /** Number of messages per Lambda invocation (1-10 for FIFO, default: 10) */
713
+ batchSize?: number;
714
+ /** Maximum time to gather messages before invoking (default: 0). Accepts `"5s"`, `"1m"`, etc. */
715
+ batchWindow?: Duration;
716
+ /** Visibility timeout (default: max of timeout or 30s). Accepts `"30s"`, `"5m"`, etc. */
717
+ visibilityTimeout?: Duration;
718
+ /** Message retention period (default: `"4d"`). Accepts `"1h"`, `"7d"`, etc. */
719
+ retentionPeriod?: Duration;
720
+ /** Delivery delay for all messages in the queue (default: 0). Accepts `"30s"`, `"5m"`, etc. */
721
+ delay?: Duration;
722
+ /** Enable content-based deduplication (default: true) */
723
+ contentBasedDeduplication?: boolean;
724
+ };
725
+ /**
726
+ * Setup factory type — always receives an args object.
727
+ * Args include `deps` and/or `config` when declared (empty `{}` otherwise).
728
+ */
729
+ type SetupFactory$2<C, D, P, S extends string[] | undefined = undefined> = (args: ([D] extends [undefined] ? {} : {
730
+ deps: ResolveDeps<D>;
731
+ }) & ([P] extends [undefined] ? {} : {
732
+ config: ResolveConfig<P & {}>;
733
+ }) & ([S] extends [undefined] ? {} : {
734
+ files: StaticFiles;
735
+ })) => C | Promise<C>;
736
+ /**
737
+ * Per-message handler function.
738
+ * Called once per message in the batch. Failures are reported individually.
739
+ */
740
+ type FifoQueueMessageFn<T = unknown, C = undefined, D = undefined, P = undefined, S extends string[] | undefined = undefined> = (args: {
741
+ message: FifoQueueMessage<T>;
742
+ } & ([C] extends [undefined] ? {} : {
743
+ ctx: C;
744
+ }) & ([D] extends [undefined] ? {} : {
745
+ deps: ResolveDeps<D>;
746
+ }) & ([P] extends [undefined] ? {} : {
747
+ config: ResolveConfig<P>;
748
+ }) & ([S] extends [undefined] ? {} : {
749
+ files: StaticFiles;
750
+ })) => Promise<void>;
751
+ /**
752
+ * Batch handler function.
753
+ * Called once with all messages in the batch.
754
+ */
755
+ type FifoQueueBatchFn<T = unknown, C = undefined, D = undefined, P = undefined, S extends string[] | undefined = undefined> = (args: {
756
+ messages: FifoQueueMessage<T>[];
757
+ } & ([C] extends [undefined] ? {} : {
758
+ ctx: C;
759
+ }) & ([D] extends [undefined] ? {} : {
760
+ deps: ResolveDeps<D>;
761
+ }) & ([P] extends [undefined] ? {} : {
762
+ config: ResolveConfig<P>;
763
+ }) & ([S] extends [undefined] ? {} : {
764
+ files: StaticFiles;
765
+ })) => Promise<void>;
766
+ /** Base options shared by all defineFifoQueue variants */
767
+ type DefineFifoQueueBase<T = unknown, C = undefined, D = undefined, P = undefined, S extends string[] | undefined = undefined> = FifoQueueConfig & {
768
+ /**
769
+ * Decode/validate function for the message body.
770
+ * Called with the JSON-parsed body; should return typed data or throw on validation failure.
771
+ */
772
+ schema?: (input: unknown) => T;
773
+ /**
774
+ * Error handler called when onMessage or onBatch throws.
775
+ * If not provided, defaults to `console.error`.
776
+ */
777
+ onError?: (error: unknown) => void;
778
+ /**
779
+ * Factory function to initialize shared state for the handler.
780
+ * Called once on cold start, result is cached and reused across invocations.
781
+ * When deps/params are declared, receives them as argument.
782
+ */
783
+ setup?: SetupFactory$2<C, D, P, S>;
784
+ /**
785
+ * Dependencies on other handlers (tables, queues, etc.).
786
+ * Typed clients are injected into the handler via the `deps` argument.
787
+ */
788
+ deps?: D;
789
+ /**
790
+ * SSM Parameter Store parameters.
791
+ * Declare with `param()` helper. Values are fetched and cached at cold start.
792
+ */
793
+ config?: P;
794
+ /**
795
+ * Static file glob patterns to bundle into the Lambda ZIP.
796
+ * Files are accessible at runtime via the `files` callback argument.
797
+ */
798
+ static?: S;
799
+ };
800
+ /** Per-message processing */
801
+ type DefineFifoQueueWithOnMessage<T = unknown, C = undefined, D = undefined, P = undefined, S extends string[] | undefined = undefined> = DefineFifoQueueBase<T, C, D, P, S> & {
802
+ onMessage: FifoQueueMessageFn<T, C, D, P, S>;
803
+ onBatch?: never;
804
+ };
805
+ /** Batch processing: all messages at once */
806
+ type DefineFifoQueueWithOnBatch<T = unknown, C = undefined, D = undefined, P = undefined, S extends string[] | undefined = undefined> = DefineFifoQueueBase<T, C, D, P, S> & {
807
+ onBatch: FifoQueueBatchFn<T, C, D, P, S>;
808
+ onMessage?: never;
809
+ };
810
+ type DefineFifoQueueOptions<T = unknown, C = undefined, D extends Record<string, AnyDepHandler> | undefined = undefined, P extends Record<string, AnyParamRef> | undefined = undefined, S extends string[] | undefined = undefined> = DefineFifoQueueWithOnMessage<T, C, D, P, S> | DefineFifoQueueWithOnBatch<T, C, D, P, S>;
811
+ /**
812
+ * Internal handler object created by defineFifoQueue
813
+ * @internal
814
+ */
815
+ type FifoQueueHandler<T = unknown, C = undefined, D = undefined, P = undefined, S extends string[] | undefined = undefined> = {
816
+ readonly __brand: "effortless-fifo-queue";
817
+ readonly __spec: FifoQueueConfig;
818
+ readonly schema?: (input: unknown) => T;
819
+ readonly onError?: (error: unknown) => void;
820
+ readonly setup?: (...args: any[]) => C | Promise<C>;
821
+ readonly deps?: D;
822
+ readonly config?: P;
823
+ readonly static?: string[];
824
+ readonly onMessage?: FifoQueueMessageFn<T, C, D, P, S>;
825
+ readonly onBatch?: FifoQueueBatchFn<T, C, D, P, S>;
826
+ };
827
+ /**
828
+ * Define a FIFO SQS queue with a Lambda message handler
829
+ *
830
+ * Creates:
831
+ * - SQS FIFO queue (with `.fifo` suffix)
832
+ * - Lambda function triggered by the queue
833
+ * - Event source mapping with partial batch failure support
834
+ *
835
+ * @example Per-message processing
836
+ * ```typescript
837
+ * type OrderEvent = { orderId: string; action: string };
838
+ *
839
+ * export const orderQueue = defineFifoQueue<OrderEvent>({
840
+ * onMessage: async ({ message }) => {
841
+ * console.log("Processing order:", message.body.orderId);
842
+ * }
843
+ * });
844
+ * ```
845
+ *
846
+ * @example Batch processing with schema
847
+ * ```typescript
848
+ * export const notifications = defineFifoQueue({
849
+ * schema: (input) => NotificationSchema.parse(input),
850
+ * batchSize: 5,
851
+ * onBatch: async ({ messages }) => {
852
+ * await sendAll(messages.map(m => m.body));
853
+ * }
854
+ * });
855
+ * ```
856
+ */
857
+ declare const defineFifoQueue: <T = unknown, C = undefined, D extends Record<string, AnyDepHandler> | undefined = undefined, P extends Record<string, AnyParamRef> | undefined = undefined, S extends string[] | undefined = undefined>(options: DefineFifoQueueOptions<T, C, D, P, S>) => FifoQueueHandler<T, C, D, P, S>;
858
+
633
859
  /**
634
860
  * Options for sending an email via EmailClient.send()
635
861
  */
@@ -659,14 +885,45 @@ type EmailClient = {
659
885
  send(opts: SendEmailOptions): Promise<void>;
660
886
  };
661
887
 
888
+ /**
889
+ * Input for QueueClient.send()
890
+ */
891
+ type SendMessageInput<T> = {
892
+ /** Message body (serialized as JSON) */
893
+ body: T;
894
+ /** Message group ID (FIFO ordering key) */
895
+ groupId: string;
896
+ /** Message deduplication ID. Required if content-based deduplication is disabled. */
897
+ deduplicationId?: string;
898
+ /** Optional message attributes */
899
+ messageAttributes?: Record<string, {
900
+ dataType: string;
901
+ stringValue: string;
902
+ }>;
903
+ };
904
+ /**
905
+ * Typed SQS FIFO queue client for sending messages.
906
+ *
907
+ * @typeParam T - Type of the message body (serialized as JSON)
908
+ */
909
+ type QueueClient<T = unknown> = {
910
+ /** Send a single message to the FIFO queue */
911
+ send(input: SendMessageInput<T>): Promise<void>;
912
+ /** Send a batch of messages (up to 10) to the FIFO queue */
913
+ sendBatch(messages: SendMessageInput<T>[]): Promise<void>;
914
+ /** The SQS queue name (without .fifo suffix) */
915
+ queueName: string;
916
+ };
917
+
662
918
  type AnyTableHandler = TableHandler<any, any, any, any, any, any>;
663
919
  type AnyBucketHandler = BucketHandler<any, any, any, any>;
664
920
  type AnyMailerHandler = MailerHandler;
921
+ type AnyFifoQueueHandler = FifoQueueHandler<any, any, any, any, any>;
665
922
  /** Dep value types supported by the deps declaration */
666
- type AnyDepHandler = AnyTableHandler | AnyBucketHandler | AnyMailerHandler;
923
+ type AnyDepHandler = AnyTableHandler | AnyBucketHandler | AnyMailerHandler | AnyFifoQueueHandler;
667
924
  /** Maps a deps declaration to resolved runtime client types */
668
925
  type ResolveDeps<D> = {
669
- [K in keyof D]: D[K] extends TableHandler<infer T, any, any, any, any> ? TableClient<T> : D[K] extends BucketHandler<any, any, any, any> ? BucketClient : D[K] extends MailerHandler ? EmailClient : never;
926
+ [K in keyof D]: D[K] extends TableHandler<infer T, any, any, any, any> ? TableClient<T> : D[K] extends BucketHandler<any, any, any, any> ? BucketClient : D[K] extends MailerHandler ? EmailClient : D[K] extends FifoQueueHandler<infer T, any, any, any, any> ? QueueClient<T> : never;
670
927
  };
671
928
 
672
929
  /** DynamoDB Streams view type - determines what data is captured in stream records */
@@ -677,15 +934,17 @@ type StreamView = "NEW_AND_OLD_IMAGES" | "NEW_IMAGE" | "OLD_IMAGE" | "KEYS_ONLY"
677
934
  * Tables always use `pk (S)` + `sk (S)` keys, `tag (S)` discriminator,
678
935
  * `data (M)` for domain fields, and `ttl (N)` for optional expiration.
679
936
  */
680
- type TableConfig = LambdaWithPermissions & {
937
+ type TableConfig = {
938
+ /** Lambda function settings (memory, timeout, permissions, etc.) */
939
+ lambda?: LambdaWithPermissions;
681
940
  /** DynamoDB billing mode (default: "PAY_PER_REQUEST") */
682
941
  billingMode?: "PAY_PER_REQUEST" | "PROVISIONED";
683
942
  /** Stream view type - what data to include in stream records (default: "NEW_AND_OLD_IMAGES") */
684
943
  streamView?: StreamView;
685
944
  /** Number of records to process in each Lambda invocation (1-10000, default: 100) */
686
945
  batchSize?: number;
687
- /** Maximum time in seconds to gather records before invoking (0-300, default: 2) */
688
- batchWindow?: number;
946
+ /** Maximum time to gather records before invoking (default: `"2s"`). Accepts `"5s"`, `"1m"`, etc. */
947
+ batchWindow?: Duration;
689
948
  /** Where to start reading the stream (default: "LATEST") */
690
949
  startingPosition?: "LATEST" | "TRIM_HORIZON";
691
950
  /**
@@ -744,7 +1003,7 @@ type FailedRecord<T = Record<string, unknown>> = {
744
1003
  * Always receives `table: TableClient<T>` (self-client for the handler's own table).
745
1004
  * Also receives `deps` and/or `config` when declared.
746
1005
  */
747
- type SetupFactory$2<C, T, D, P, S extends string[] | undefined = undefined> = (args: {
1006
+ type SetupFactory$1<C, T, D, P, S extends string[] | undefined = undefined> = (args: {
748
1007
  table: TableClient<T>;
749
1008
  } & ([D] extends [undefined] ? {} : {
750
1009
  deps: ResolveDeps<D>;
@@ -820,7 +1079,7 @@ type DefineTableBase<T = Record<string, unknown>, C = undefined, D = undefined,
820
1079
  * When deps/params are declared, receives them as argument.
821
1080
  * Supports both sync and async return values.
822
1081
  */
823
- setup?: SetupFactory$2<C, T, D, P, S>;
1082
+ setup?: SetupFactory$1<C, T, D, P, S>;
824
1083
  /**
825
1084
  * Dependencies on other handlers (tables, queues, etc.).
826
1085
  * Typed clients are injected into the handler via the `deps` argument.
@@ -907,7 +1166,9 @@ declare const defineTable: <T = Record<string, unknown>, C = undefined, R = void
907
1166
  * Configuration for deploying an SSR framework (Nuxt, Astro, etc.)
908
1167
  * via CloudFront + S3 (static assets) + Lambda Function URL (server-side rendering).
909
1168
  */
910
- type AppConfig = LambdaWithPermissions & {
1169
+ type AppConfig = {
1170
+ /** Lambda function settings (memory, timeout, permissions, etc.) */
1171
+ lambda?: LambdaWithPermissions;
911
1172
  /** Directory containing the Lambda server handler (e.g., ".output/server").
912
1173
  * Must contain an `index.mjs` (or `index.js`) that exports a `handler` function. */
913
1174
  server: string;
@@ -952,7 +1213,7 @@ type AppHandler = {
952
1213
  * build: "nuxt build",
953
1214
  * server: ".output/server",
954
1215
  * assets: ".output/public",
955
- * memory: 1024,
1216
+ * lambda: { memory: 1024 },
956
1217
  * });
957
1218
  * ```
958
1219
  */
@@ -1065,187 +1326,8 @@ type StaticSiteHandler = {
1065
1326
  */
1066
1327
  declare const defineStaticSite: (options: StaticSiteConfig) => StaticSiteHandler;
1067
1328
 
1068
- /**
1069
- * Parsed SQS FIFO message passed to the handler callbacks.
1070
- *
1071
- * @typeParam T - Type of the decoded message body (from schema function)
1072
- */
1073
- type FifoQueueMessage<T = unknown> = {
1074
- /** Unique message identifier */
1075
- messageId: string;
1076
- /** Receipt handle for acknowledgement */
1077
- receiptHandle: string;
1078
- /** Parsed message body (JSON-decoded, then optionally schema-validated) */
1079
- body: T;
1080
- /** Raw unparsed message body string */
1081
- rawBody: string;
1082
- /** Message group ID (FIFO ordering key) */
1083
- messageGroupId: string;
1084
- /** Message deduplication ID */
1085
- messageDeduplicationId?: string;
1086
- /** SQS message attributes */
1087
- messageAttributes: Record<string, {
1088
- dataType?: string;
1089
- stringValue?: string;
1090
- }>;
1091
- /** Approximate first receive timestamp */
1092
- approximateFirstReceiveTimestamp?: string;
1093
- /** Approximate receive count */
1094
- approximateReceiveCount?: string;
1095
- /** Sent timestamp */
1096
- sentTimestamp?: string;
1097
- };
1098
- /**
1099
- * Configuration options for a FIFO queue handler
1100
- */
1101
- type FifoQueueConfig = LambdaWithPermissions & {
1102
- /** Number of messages per Lambda invocation (1-10 for FIFO, default: 10) */
1103
- batchSize?: number;
1104
- /** Maximum time in seconds to gather messages before invoking (0-300, default: 0) */
1105
- batchWindow?: number;
1106
- /** Visibility timeout in seconds (default: max of timeout or 30) */
1107
- visibilityTimeout?: number;
1108
- /** Message retention period in seconds (60-1209600, default: 345600 = 4 days) */
1109
- retentionPeriod?: number;
1110
- /** Enable content-based deduplication (default: true) */
1111
- contentBasedDeduplication?: boolean;
1112
- };
1113
- /**
1114
- * Setup factory type — always receives an args object.
1115
- * Args include `deps` and/or `config` when declared (empty `{}` otherwise).
1116
- */
1117
- type SetupFactory$1<C, D, P, S extends string[] | undefined = undefined> = (args: ([D] extends [undefined] ? {} : {
1118
- deps: ResolveDeps<D>;
1119
- }) & ([P] extends [undefined] ? {} : {
1120
- config: ResolveConfig<P & {}>;
1121
- }) & ([S] extends [undefined] ? {} : {
1122
- files: StaticFiles;
1123
- })) => C | Promise<C>;
1124
- /**
1125
- * Per-message handler function.
1126
- * Called once per message in the batch. Failures are reported individually.
1127
- */
1128
- type FifoQueueMessageFn<T = unknown, C = undefined, D = undefined, P = undefined, S extends string[] | undefined = undefined> = (args: {
1129
- message: FifoQueueMessage<T>;
1130
- } & ([C] extends [undefined] ? {} : {
1131
- ctx: C;
1132
- }) & ([D] extends [undefined] ? {} : {
1133
- deps: ResolveDeps<D>;
1134
- }) & ([P] extends [undefined] ? {} : {
1135
- config: ResolveConfig<P>;
1136
- }) & ([S] extends [undefined] ? {} : {
1137
- files: StaticFiles;
1138
- })) => Promise<void>;
1139
- /**
1140
- * Batch handler function.
1141
- * Called once with all messages in the batch.
1142
- */
1143
- type FifoQueueBatchFn<T = unknown, C = undefined, D = undefined, P = undefined, S extends string[] | undefined = undefined> = (args: {
1144
- messages: FifoQueueMessage<T>[];
1145
- } & ([C] extends [undefined] ? {} : {
1146
- ctx: C;
1147
- }) & ([D] extends [undefined] ? {} : {
1148
- deps: ResolveDeps<D>;
1149
- }) & ([P] extends [undefined] ? {} : {
1150
- config: ResolveConfig<P>;
1151
- }) & ([S] extends [undefined] ? {} : {
1152
- files: StaticFiles;
1153
- })) => Promise<void>;
1154
- /** Base options shared by all defineFifoQueue variants */
1155
- type DefineFifoQueueBase<T = unknown, C = undefined, D = undefined, P = undefined, S extends string[] | undefined = undefined> = FifoQueueConfig & {
1156
- /**
1157
- * Decode/validate function for the message body.
1158
- * Called with the JSON-parsed body; should return typed data or throw on validation failure.
1159
- */
1160
- schema?: (input: unknown) => T;
1161
- /**
1162
- * Error handler called when onMessage or onBatch throws.
1163
- * If not provided, defaults to `console.error`.
1164
- */
1165
- onError?: (error: unknown) => void;
1166
- /**
1167
- * Factory function to initialize shared state for the handler.
1168
- * Called once on cold start, result is cached and reused across invocations.
1169
- * When deps/params are declared, receives them as argument.
1170
- */
1171
- setup?: SetupFactory$1<C, D, P, S>;
1172
- /**
1173
- * Dependencies on other handlers (tables, queues, etc.).
1174
- * Typed clients are injected into the handler via the `deps` argument.
1175
- */
1176
- deps?: D;
1177
- /**
1178
- * SSM Parameter Store parameters.
1179
- * Declare with `param()` helper. Values are fetched and cached at cold start.
1180
- */
1181
- config?: P;
1182
- /**
1183
- * Static file glob patterns to bundle into the Lambda ZIP.
1184
- * Files are accessible at runtime via the `files` callback argument.
1185
- */
1186
- static?: S;
1187
- };
1188
- /** Per-message processing */
1189
- type DefineFifoQueueWithOnMessage<T = unknown, C = undefined, D = undefined, P = undefined, S extends string[] | undefined = undefined> = DefineFifoQueueBase<T, C, D, P, S> & {
1190
- onMessage: FifoQueueMessageFn<T, C, D, P, S>;
1191
- onBatch?: never;
1192
- };
1193
- /** Batch processing: all messages at once */
1194
- type DefineFifoQueueWithOnBatch<T = unknown, C = undefined, D = undefined, P = undefined, S extends string[] | undefined = undefined> = DefineFifoQueueBase<T, C, D, P, S> & {
1195
- onBatch: FifoQueueBatchFn<T, C, D, P, S>;
1196
- onMessage?: never;
1197
- };
1198
- type DefineFifoQueueOptions<T = unknown, C = undefined, D extends Record<string, AnyDepHandler> | undefined = undefined, P extends Record<string, AnyParamRef> | undefined = undefined, S extends string[] | undefined = undefined> = DefineFifoQueueWithOnMessage<T, C, D, P, S> | DefineFifoQueueWithOnBatch<T, C, D, P, S>;
1199
- /**
1200
- * Internal handler object created by defineFifoQueue
1201
- * @internal
1202
- */
1203
- type FifoQueueHandler<T = unknown, C = undefined, D = undefined, P = undefined, S extends string[] | undefined = undefined> = {
1204
- readonly __brand: "effortless-fifo-queue";
1205
- readonly __spec: FifoQueueConfig;
1206
- readonly schema?: (input: unknown) => T;
1207
- readonly onError?: (error: unknown) => void;
1208
- readonly setup?: (...args: any[]) => C | Promise<C>;
1209
- readonly deps?: D;
1210
- readonly config?: P;
1211
- readonly static?: string[];
1212
- readonly onMessage?: FifoQueueMessageFn<T, C, D, P, S>;
1213
- readonly onBatch?: FifoQueueBatchFn<T, C, D, P, S>;
1214
- };
1215
- /**
1216
- * Define a FIFO SQS queue with a Lambda message handler
1217
- *
1218
- * Creates:
1219
- * - SQS FIFO queue (with `.fifo` suffix)
1220
- * - Lambda function triggered by the queue
1221
- * - Event source mapping with partial batch failure support
1222
- *
1223
- * @example Per-message processing
1224
- * ```typescript
1225
- * type OrderEvent = { orderId: string; action: string };
1226
- *
1227
- * export const orderQueue = defineFifoQueue<OrderEvent>({
1228
- * onMessage: async ({ message }) => {
1229
- * console.log("Processing order:", message.body.orderId);
1230
- * }
1231
- * });
1232
- * ```
1233
- *
1234
- * @example Batch processing with schema
1235
- * ```typescript
1236
- * export const notifications = defineFifoQueue({
1237
- * schema: (input) => NotificationSchema.parse(input),
1238
- * batchSize: 5,
1239
- * onBatch: async ({ messages }) => {
1240
- * await sendAll(messages.map(m => m.body));
1241
- * }
1242
- * });
1243
- * ```
1244
- */
1245
- declare const defineFifoQueue: <T = unknown, C = undefined, D extends Record<string, AnyDepHandler> | undefined = undefined, P extends Record<string, AnyParamRef> | undefined = undefined, S extends string[] | undefined = undefined>(options: DefineFifoQueueOptions<T, C, D, P, S>) => FifoQueueHandler<T, C, D, P, S>;
1246
-
1247
1329
  /** GET route handler — no schema, no data */
1248
- type ApiGetHandlerFn<C = undefined, D = undefined, P = undefined, S extends string[] | undefined = undefined> = (args: {
1330
+ type ApiGetHandlerFn<C = undefined, D = undefined, P = undefined, S extends string[] | undefined = undefined, ST extends boolean | undefined = undefined> = (args: {
1249
1331
  req: HttpRequest;
1250
1332
  } & ([C] extends [undefined] ? {} : {
1251
1333
  ctx: C;
@@ -1255,9 +1337,11 @@ type ApiGetHandlerFn<C = undefined, D = undefined, P = undefined, S extends stri
1255
1337
  config: ResolveConfig<P>;
1256
1338
  }) & ([S] extends [undefined] ? {} : {
1257
1339
  files: StaticFiles;
1258
- })) => Promise<HttpResponse> | HttpResponse;
1340
+ }) & ([ST] extends [true] ? {
1341
+ stream: ResponseStream;
1342
+ } : {})) => Promise<HttpResponse | void> | HttpResponse | void;
1259
1343
  /** POST handler — with typed data from schema */
1260
- type ApiPostHandlerFn<T = undefined, C = undefined, D = undefined, P = undefined, S extends string[] | undefined = undefined> = (args: {
1344
+ type ApiPostHandlerFn<T = undefined, C = undefined, D = undefined, P = undefined, S extends string[] | undefined = undefined, ST extends boolean | undefined = undefined> = (args: {
1261
1345
  req: HttpRequest;
1262
1346
  } & ([T] extends [undefined] ? {} : {
1263
1347
  data: T;
@@ -1269,7 +1353,9 @@ type ApiPostHandlerFn<T = undefined, C = undefined, D = undefined, P = undefined
1269
1353
  config: ResolveConfig<P>;
1270
1354
  }) & ([S] extends [undefined] ? {} : {
1271
1355
  files: StaticFiles;
1272
- })) => Promise<HttpResponse> | HttpResponse;
1356
+ }) & ([ST] extends [true] ? {
1357
+ stream: ResponseStream;
1358
+ } : {})) => Promise<HttpResponse | void> | HttpResponse | void;
1273
1359
  /** Setup factory — receives deps/config/files when declared */
1274
1360
  type SetupFactory<C, D, P, S extends string[] | undefined = undefined> = (args: ([D] extends [undefined] ? {} : {
1275
1361
  deps: ResolveDeps<D>;
@@ -1279,9 +1365,13 @@ type SetupFactory<C, D, P, S extends string[] | undefined = undefined> = (args:
1279
1365
  files: StaticFiles;
1280
1366
  })) => C | Promise<C>;
1281
1367
  /** Static config extracted by AST (no runtime callbacks) */
1282
- type ApiConfig = LambdaWithPermissions & {
1368
+ type ApiConfig = {
1369
+ /** Lambda function settings (memory, timeout, permissions, etc.) */
1370
+ lambda?: LambdaWithPermissions;
1283
1371
  /** Base path prefix for all routes (e.g., "/api") */
1284
1372
  basePath: string;
1373
+ /** Enable response streaming. When true, the Lambda Function URL uses RESPONSE_STREAM invoke mode. */
1374
+ stream?: boolean;
1285
1375
  };
1286
1376
  /**
1287
1377
  * Options for defining a CQRS-style API endpoint.
@@ -1289,9 +1379,13 @@ type ApiConfig = LambdaWithPermissions & {
1289
1379
  * - `get` routes handle queries (path-based routing, no body)
1290
1380
  * - `post` handles commands (single entry point, discriminated union via `schema`)
1291
1381
  */
1292
- type DefineApiOptions<T = undefined, C = undefined, D extends Record<string, AnyDepHandler> | undefined = undefined, P extends Record<string, AnyParamRef> | undefined = undefined, S extends string[] | undefined = undefined> = LambdaWithPermissions & {
1382
+ type DefineApiOptions<T = undefined, C = undefined, D extends Record<string, AnyDepHandler> | undefined = undefined, P extends Record<string, AnyParamRef> | undefined = undefined, S extends string[] | undefined = undefined, ST extends boolean | undefined = undefined> = {
1383
+ /** Lambda function settings (memory, timeout, permissions, etc.) */
1384
+ lambda?: LambdaWithPermissions;
1293
1385
  /** Base path prefix for all routes (e.g., "/api") */
1294
1386
  basePath: string;
1387
+ /** Enable response streaming. When true, routes receive a `stream` arg for SSE. Routes can still return HttpResponse normally. */
1388
+ stream?: ST;
1295
1389
  /**
1296
1390
  * Factory function to initialize shared state.
1297
1391
  * Called once on cold start, result is cached and reused across invocations.
@@ -1306,7 +1400,7 @@ type DefineApiOptions<T = undefined, C = undefined, D extends Record<string, Any
1306
1400
  /** Error handler called when schema validation or handler throws */
1307
1401
  onError?: (error: unknown, req: HttpRequest) => HttpResponse;
1308
1402
  /** GET routes — query handlers keyed by relative path (e.g., "/users/{id}") */
1309
- get?: Record<string, ApiGetHandlerFn<C, D, P, S>>;
1403
+ get?: Record<string, ApiGetHandlerFn<C, D, P, S, ST>>;
1310
1404
  /**
1311
1405
  * Schema for POST body validation. Use with discriminated unions:
1312
1406
  * ```typescript
@@ -1316,10 +1410,10 @@ type DefineApiOptions<T = undefined, C = undefined, D extends Record<string, Any
1316
1410
  */
1317
1411
  schema?: (input: unknown) => T;
1318
1412
  /** POST handler — single entry point for commands */
1319
- post?: ApiPostHandlerFn<T, C, D, P, S>;
1413
+ post?: ApiPostHandlerFn<T, C, D, P, S, ST>;
1320
1414
  };
1321
1415
  /** Internal handler object created by defineApi */
1322
- type ApiHandler<T = undefined, C = undefined, D = undefined, P = undefined, S extends string[] | undefined = undefined> = {
1416
+ type ApiHandler<T = undefined, C = undefined, D = undefined, P = undefined, S extends string[] | undefined = undefined, ST extends boolean | undefined = undefined> = {
1323
1417
  readonly __brand: "effortless-api";
1324
1418
  readonly __spec: ApiConfig;
1325
1419
  readonly schema?: (input: unknown) => T;
@@ -1328,8 +1422,8 @@ type ApiHandler<T = undefined, C = undefined, D = undefined, P = undefined, S ex
1328
1422
  readonly deps?: D;
1329
1423
  readonly config?: P;
1330
1424
  readonly static?: string[];
1331
- readonly get?: Record<string, ApiGetHandlerFn<C, D, P, S>>;
1332
- readonly post?: ApiPostHandlerFn<T, C, D, P, S>;
1425
+ readonly get?: Record<string, ApiGetHandlerFn<C, D, P, S, ST>>;
1426
+ readonly post?: ApiPostHandlerFn<T, C, D, P, S, ST>;
1333
1427
  };
1334
1428
  /**
1335
1429
  * Define a CQRS-style API with typed GET routes and POST commands.
@@ -1365,6 +1459,6 @@ type ApiHandler<T = undefined, C = undefined, D = undefined, P = undefined, S ex
1365
1459
  * })
1366
1460
  * ```
1367
1461
  */
1368
- declare const defineApi: <T = undefined, C = undefined, D extends Record<string, AnyDepHandler> | undefined = undefined, P extends Record<string, AnyParamRef> | undefined = undefined, S extends string[] | undefined = undefined>(options: DefineApiOptions<T, C, D, P, S>) => ApiHandler<T, C, D, P, S>;
1462
+ declare const defineApi: <T = undefined, C = undefined, D extends Record<string, AnyDepHandler> | undefined = undefined, P extends Record<string, AnyParamRef> | undefined = undefined, S extends string[] | undefined = undefined, ST extends boolean | undefined = undefined>(options: DefineApiOptions<T, C, D, P, S, ST>) => ApiHandler<T, C, D, P, S, ST>;
1369
1463
 
1370
- export { type AnyParamRef, type ApiConfig, type ApiGetHandlerFn, type ApiHandler, type ApiPostHandlerFn, type AppConfig, type AppHandler, type BucketClient, type BucketConfig, type BucketEvent, type BucketHandler, type BucketObjectCreatedFn, type BucketObjectRemovedFn, type ContentType, type DefineApiOptions, type DefineBucketOptions, type DefineFifoQueueOptions, type DefineTableOptions, type EffortlessConfig, type EmailClient, type FailedRecord, type FifoQueueBatchFn, type FifoQueueConfig, type FifoQueueHandler, type FifoQueueMessage, type FifoQueueMessageFn, type HttpMethod, type HttpRequest, type HttpResponse, type LambdaConfig, type LambdaWithPermissions, type LogLevel, type MailerConfig, type MailerHandler, type MiddlewareDeny, type MiddlewareHandler, type MiddlewareRedirect, type MiddlewareRequest, type MiddlewareResult, type ParamRef, type Permission, type PutInput, type PutOptions, type QueryByTagParams, type QueryParams, type ResolveConfig, type ResolveDeps, type SendEmailOptions, type SkCondition, type StaticFiles, type StaticSiteConfig, type StaticSiteHandler, type StaticSiteSeo, type StreamView, type TableBatchCompleteFn, type TableBatchFn, type TableClient, type TableConfig, type TableHandler, type TableItem, type TableKey, type TableRecord, type TableRecordFn, type UpdateActions, defineApi, defineApp, defineBucket, defineConfig, defineFifoQueue, defineMailer, defineStaticSite, defineTable, param, typed };
1464
+ export { type AnyParamRef, type ApiConfig, type ApiGetHandlerFn, type ApiHandler, type ApiPostHandlerFn, type AppConfig, type AppHandler, type BucketClient, type BucketConfig, type BucketEvent, type BucketHandler, type BucketObjectCreatedFn, type BucketObjectRemovedFn, type ContentType, type DefineApiOptions, type DefineBucketOptions, type DefineFifoQueueOptions, type DefineTableOptions, type Duration, type EffortlessConfig, type EmailClient, type FailedRecord, type FifoQueueBatchFn, type FifoQueueConfig, type FifoQueueHandler, type FifoQueueMessage, type FifoQueueMessageFn, type HttpMethod, type HttpRequest, type HttpResponse, type LambdaConfig, type LambdaWithPermissions, type LogLevel, type MailerConfig, type MailerHandler, type MiddlewareDeny, type MiddlewareHandler, type MiddlewareRedirect, type MiddlewareRequest, type MiddlewareResult, type ParamRef, type Permission, type PutInput, type PutOptions, type QueryByTagParams, type QueryParams, type QueueClient, type ResolveConfig, type ResolveDeps, type ResponseStream, type SendEmailOptions, type SendMessageInput, type SkCondition, type StaticFiles, type StaticSiteConfig, type StaticSiteHandler, type StaticSiteSeo, type StreamView, type TableBatchCompleteFn, type TableBatchFn, type TableClient, type TableConfig, type TableHandler, type TableItem, type TableKey, type TableRecord, type TableRecordFn, type UpdateActions, defineApi, defineApp, defineBucket, defineConfig, defineFifoQueue, defineMailer, defineStaticSite, defineTable, param, result, toSeconds, typed };