effortless-aws 0.37.0 → 0.39.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/{chunk-3NKYT4OX.js → chunk-GQKZZ7G7.js} +1 -1
- package/dist/index.d.ts +122 -167
- package/dist/index.js +17 -4
- package/dist/index.js.map +1 -1
- package/dist/runtime/wrap-api.js +37 -11
- package/dist/runtime/wrap-bucket.js +1 -1
- package/dist/runtime/wrap-cron.js +1 -1
- package/dist/runtime/wrap-mcp.js +1 -1
- package/dist/runtime/{wrap-fifo-queue.js → wrap-queue.js} +6 -6
- package/dist/runtime/wrap-table-stream.js +2 -2
- package/dist/runtime/wrap-worker.js +1 -1
- package/package.json +1 -1
|
@@ -112,7 +112,7 @@ var buildParams = async (params) => {
|
|
|
112
112
|
var resolvePath = (filePath) => join(process.cwd(), filePath);
|
|
113
113
|
var staticFiles = {
|
|
114
114
|
read: (filePath) => readFileSync(resolvePath(filePath), "utf-8"),
|
|
115
|
-
|
|
115
|
+
readBytes: (filePath) => readFileSync(resolvePath(filePath)),
|
|
116
116
|
path: resolvePath
|
|
117
117
|
};
|
|
118
118
|
var createHandlerRuntime = (handler, handlerType, logLevel = "info", extraSetupArgs) => {
|
package/dist/index.d.ts
CHANGED
|
@@ -101,7 +101,7 @@ type LambdaConfig = {
|
|
|
101
101
|
};
|
|
102
102
|
/**
|
|
103
103
|
* Lambda configuration with additional IAM permissions.
|
|
104
|
-
* Used by handler types that support custom permissions (http, table,
|
|
104
|
+
* Used by handler types that support custom permissions (http, table, queue).
|
|
105
105
|
*/
|
|
106
106
|
type LambdaWithPermissions = LambdaConfig & {
|
|
107
107
|
/** Additional IAM permissions for the Lambda */
|
|
@@ -249,7 +249,12 @@ type HttpRequest = {
|
|
|
249
249
|
type HttpResponse = {
|
|
250
250
|
/** HTTP status code (e.g., 200, 404, 500) */
|
|
251
251
|
status: number;
|
|
252
|
-
/**
|
|
252
|
+
/**
|
|
253
|
+
* Response body. Type determines serialization:
|
|
254
|
+
* - `Uint8Array` (incl. `Buffer`) — sent as binary, base64-encoded
|
|
255
|
+
* - `Blob` — sent as binary, base64-encoded; `Blob.type` is used as Content-Type when not set explicitly
|
|
256
|
+
* - other values — JSON-serialized by default, or sent as string when `contentType` is set
|
|
257
|
+
*/
|
|
253
258
|
body?: unknown;
|
|
254
259
|
/**
|
|
255
260
|
* Short content-type alias. Resolves to full MIME type automatically:
|
|
@@ -272,10 +277,14 @@ type HttpResponse = {
|
|
|
272
277
|
*/
|
|
273
278
|
cookies?: string[];
|
|
274
279
|
/**
|
|
275
|
-
*
|
|
276
|
-
*
|
|
277
|
-
*
|
|
278
|
-
|
|
280
|
+
* Force the client to download the response as a file with the given filename.
|
|
281
|
+
* Sets `Content-Disposition: attachment; filename="<value>"`. Works with any body type
|
|
282
|
+
* (JSON, text, binary). An explicit `Content-Disposition` header overrides this.
|
|
283
|
+
*/
|
|
284
|
+
downloadAs?: string;
|
|
285
|
+
/**
|
|
286
|
+
* Set to `true` to return binary data when `body` is already a base64-encoded string.
|
|
287
|
+
* Prefer returning `Uint8Array` / `Buffer` / `Blob` directly — the runtime detects them automatically.
|
|
279
288
|
*/
|
|
280
289
|
binary?: boolean;
|
|
281
290
|
};
|
|
@@ -294,8 +303,8 @@ type ResponseStream = {
|
|
|
294
303
|
type StaticFiles = {
|
|
295
304
|
/** Read file as UTF-8 string */
|
|
296
305
|
read(path: string): string;
|
|
297
|
-
/** Read file as
|
|
298
|
-
|
|
306
|
+
/** Read file as raw bytes (for binary content) */
|
|
307
|
+
readBytes(path: string): Uint8Array;
|
|
299
308
|
/** Resolve absolute path to the bundled file */
|
|
300
309
|
path(path: string): string;
|
|
301
310
|
};
|
|
@@ -480,14 +489,6 @@ interface BucketBuilder<D = undefined, P = undefined, C = undefined, HasFiles ex
|
|
|
480
489
|
* Define an S3 bucket with optional event handlers.
|
|
481
490
|
*
|
|
482
491
|
* @see {@link https://effortless-aws.website/use-cases/storage | Storage guide}
|
|
483
|
-
*
|
|
484
|
-
* @example
|
|
485
|
-
* ```typescript
|
|
486
|
-
* export const uploads = defineBucket({ prefix: "images/", suffix: ".jpg" })
|
|
487
|
-
* .onObjectCreated(async ({ event, bucket }) => {
|
|
488
|
-
* console.log("New upload:", event.key);
|
|
489
|
-
* })
|
|
490
|
-
* ```
|
|
491
492
|
*/
|
|
492
493
|
declare function defineBucket(): BucketBuilder;
|
|
493
494
|
declare function defineBucket(options: BucketOptions): BucketBuilder;
|
|
@@ -517,37 +518,15 @@ type MailerHandler = {
|
|
|
517
518
|
* Add them to your DNS provider to verify the domain.
|
|
518
519
|
*
|
|
519
520
|
* @see {@link https://effortless-aws.website/use-cases/email | Email guide}
|
|
520
|
-
*
|
|
521
|
-
* @param options - Mailer configuration with the domain to send from
|
|
522
|
-
* @returns Handler object used by the deployment system and as a `deps` value
|
|
523
|
-
*
|
|
524
|
-
* @example Basic mailer with HTTP handler
|
|
525
|
-
* ```typescript
|
|
526
|
-
* export const mailer = defineMailer({ domain: "myapp.com" });
|
|
527
|
-
*
|
|
528
|
-
* export const api = defineApi({
|
|
529
|
-
* basePath: "/signup",
|
|
530
|
-
* deps: { mailer },
|
|
531
|
-
* post: async ({ req, deps }) => {
|
|
532
|
-
* await deps.mailer.send({
|
|
533
|
-
* from: "hello@myapp.com",
|
|
534
|
-
* to: req.body.email,
|
|
535
|
-
* subject: "Welcome!",
|
|
536
|
-
* html: "<h1>Hi!</h1>",
|
|
537
|
-
* });
|
|
538
|
-
* return { status: 200, body: { ok: true } };
|
|
539
|
-
* },
|
|
540
|
-
* });
|
|
541
|
-
* ```
|
|
542
521
|
*/
|
|
543
522
|
declare const defineMailer: () => (options: MailerConfig) => MailerHandler;
|
|
544
523
|
|
|
545
524
|
/**
|
|
546
|
-
* Parsed SQS
|
|
525
|
+
* Parsed SQS message passed to the handler callbacks.
|
|
547
526
|
*
|
|
548
527
|
* @typeParam T - Type of the decoded message body (from schema function)
|
|
549
528
|
*/
|
|
550
|
-
type
|
|
529
|
+
type QueueMessage<T = unknown> = {
|
|
551
530
|
/** Unique message identifier */
|
|
552
531
|
messageId: string;
|
|
553
532
|
/** Receipt handle for acknowledgement */
|
|
@@ -556,9 +535,9 @@ type FifoQueueMessage<T = unknown> = {
|
|
|
556
535
|
body: T;
|
|
557
536
|
/** Raw unparsed message body string */
|
|
558
537
|
rawBody: string;
|
|
559
|
-
/** Message group ID (FIFO ordering key) */
|
|
538
|
+
/** Message group ID (FIFO ordering key, empty string for standard queues) */
|
|
560
539
|
messageGroupId: string;
|
|
561
|
-
/** Message deduplication ID */
|
|
540
|
+
/** Message deduplication ID (FIFO only) */
|
|
562
541
|
messageDeduplicationId?: string;
|
|
563
542
|
/** SQS message attributes */
|
|
564
543
|
messageAttributes: Record<string, {
|
|
@@ -573,9 +552,18 @@ type FifoQueueMessage<T = unknown> = {
|
|
|
573
552
|
sentTimestamp?: string;
|
|
574
553
|
};
|
|
575
554
|
/**
|
|
576
|
-
*
|
|
555
|
+
* Event source mapping (poller) configuration — how Lambda consumes the queue.
|
|
577
556
|
*/
|
|
578
|
-
type
|
|
557
|
+
type QueuePollerConfig = {
|
|
558
|
+
/** Number of messages per Lambda invocation (1-10 for FIFO, default: 10) */
|
|
559
|
+
batchSize?: number;
|
|
560
|
+
/** Maximum time to gather messages before invoking (default: 0). Accepts `"5s"`, `"1m"`, etc. */
|
|
561
|
+
batchWindow?: Duration;
|
|
562
|
+
};
|
|
563
|
+
/**
|
|
564
|
+
* Configuration options for a queue handler.
|
|
565
|
+
*/
|
|
566
|
+
type QueueConfig = {
|
|
579
567
|
/** Lambda function settings (memory, timeout, permissions, etc.) */
|
|
580
568
|
lambda?: {
|
|
581
569
|
memory?: number;
|
|
@@ -583,20 +571,23 @@ type FifoQueueConfig = {
|
|
|
583
571
|
logLevel?: LogLevel;
|
|
584
572
|
permissions?: Permission[];
|
|
585
573
|
};
|
|
586
|
-
/**
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
574
|
+
/**
|
|
575
|
+
* Whether this is a FIFO queue (ordered, exactly-once).
|
|
576
|
+
* Currently only `true` is supported — standard queue support is planned.
|
|
577
|
+
*/
|
|
578
|
+
fifo?: boolean;
|
|
590
579
|
/** Visibility timeout (default: max of timeout or 30s). Accepts `"30s"`, `"5m"`, etc. */
|
|
591
580
|
visibilityTimeout?: Duration;
|
|
592
581
|
/** Message retention period (default: `"4d"`). Accepts `"1h"`, `"7d"`, etc. */
|
|
593
582
|
retentionPeriod?: Duration;
|
|
594
583
|
/** Delivery delay for all messages in the queue (default: 0). Accepts `"30s"`, `"5m"`, etc. */
|
|
595
584
|
delay?: Duration;
|
|
596
|
-
/** Enable content-based deduplication (default: true) */
|
|
585
|
+
/** Enable content-based deduplication for FIFO queues (default: true) */
|
|
597
586
|
contentBasedDeduplication?: boolean;
|
|
598
587
|
/** Max number of receives before a message is sent to the dead-letter queue (default: 3) */
|
|
599
588
|
maxReceiveCount?: number;
|
|
589
|
+
/** Event source mapping config — set via `.poller({...})` builder method. */
|
|
590
|
+
poller?: QueuePollerConfig;
|
|
600
591
|
};
|
|
601
592
|
/** Spread ctx into callback args (empty when no setup) */
|
|
602
593
|
type SpreadCtx$5<C> = [C] extends [undefined] ? {} : C & {};
|
|
@@ -612,26 +603,26 @@ type SetupArgs$5<D, P, HasFiles extends boolean> = ([D] extends [undefined] ? {}
|
|
|
612
603
|
* Per-message handler function.
|
|
613
604
|
* Called once per message in the batch. Failures are reported individually.
|
|
614
605
|
*/
|
|
615
|
-
type
|
|
616
|
-
message:
|
|
606
|
+
type QueueMessageFn<T = unknown, C = undefined> = (args: {
|
|
607
|
+
message: QueueMessage<T>;
|
|
617
608
|
} & SpreadCtx$5<C>) => Promise<void>;
|
|
618
609
|
/**
|
|
619
610
|
* Batch handler function.
|
|
620
611
|
* Called once with all messages in the batch.
|
|
621
612
|
* Return `{ failures: string[] }` (messageIds) for partial batch failure reporting.
|
|
622
613
|
*/
|
|
623
|
-
type
|
|
624
|
-
messages:
|
|
614
|
+
type QueueBatchFn<T = unknown, C = undefined> = (args: {
|
|
615
|
+
messages: QueueMessage<T>[];
|
|
625
616
|
} & SpreadCtx$5<C>) => Promise<void | {
|
|
626
617
|
failures: string[];
|
|
627
618
|
}>;
|
|
628
619
|
/**
|
|
629
|
-
* Internal handler object created by
|
|
620
|
+
* Internal handler object created by defineQueue.
|
|
630
621
|
* @internal
|
|
631
622
|
*/
|
|
632
|
-
type
|
|
633
|
-
readonly __brand: "effortless-
|
|
634
|
-
readonly __spec:
|
|
623
|
+
type QueueHandler$1<T = unknown, C = any> = {
|
|
624
|
+
readonly __brand: "effortless-queue";
|
|
625
|
+
readonly __spec: QueueConfig;
|
|
635
626
|
readonly schema?: (input: unknown) => T;
|
|
636
627
|
readonly onError?: (...args: any[]) => any;
|
|
637
628
|
readonly onCleanup?: (...args: any[]) => any;
|
|
@@ -642,64 +633,69 @@ type FifoQueueHandler$1<T = unknown, C = any> = {
|
|
|
642
633
|
readonly onMessage?: (...args: any[]) => any;
|
|
643
634
|
readonly onMessageBatch?: (...args: any[]) => any;
|
|
644
635
|
};
|
|
645
|
-
/** Options passed to `
|
|
646
|
-
type
|
|
647
|
-
/**
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
636
|
+
/** Options passed to `defineQueue()` — queue resource config */
|
|
637
|
+
type QueueOptions<T> = {
|
|
638
|
+
/**
|
|
639
|
+
* Whether this is a FIFO queue (ordered, exactly-once).
|
|
640
|
+
* Currently only `true` is supported — standard queue support is planned.
|
|
641
|
+
*/
|
|
642
|
+
fifo?: boolean;
|
|
651
643
|
/** Visibility timeout (default: max of timeout or 30s) */
|
|
652
644
|
visibilityTimeout?: Duration;
|
|
653
645
|
/** Message retention period (default: "4d") */
|
|
654
646
|
retentionPeriod?: Duration;
|
|
655
647
|
/** Delivery delay for all messages in the queue (default: 0) */
|
|
656
648
|
delay?: Duration;
|
|
657
|
-
/** Enable content-based deduplication (default: true) */
|
|
649
|
+
/** Enable content-based deduplication for FIFO queues (default: true) */
|
|
658
650
|
contentBasedDeduplication?: boolean;
|
|
659
651
|
/** Max number of receives before DLQ (default: 3) */
|
|
660
652
|
maxReceiveCount?: number;
|
|
661
653
|
/** Decode/validate function for the message body */
|
|
662
654
|
schema?: (input: unknown) => T;
|
|
663
655
|
};
|
|
664
|
-
interface
|
|
656
|
+
interface QueueBuilder<T = unknown, D = undefined, P = undefined, C = undefined, HasFiles extends boolean = false> {
|
|
665
657
|
/** Declare handler dependencies */
|
|
666
|
-
deps<D2 extends Record<string, AnyDepHandler>>(fn: () => D2):
|
|
658
|
+
deps<D2 extends Record<string, AnyDepHandler>>(fn: () => D2): QueueBuilder<T, D2, P, C, HasFiles>;
|
|
667
659
|
/** Declare SSM secrets */
|
|
668
|
-
config<P2 extends Record<string, AnySecretRef>>(fn: ConfigFactory<P2>):
|
|
660
|
+
config<P2 extends Record<string, AnySecretRef>>(fn: ConfigFactory<P2>): QueueBuilder<T, D, P2, C, HasFiles>;
|
|
669
661
|
/** Include static files in the Lambda bundle. Chainable — call multiple times. */
|
|
670
|
-
include(glob: string):
|
|
662
|
+
include(glob: string): QueueBuilder<T, D, P, C, true>;
|
|
671
663
|
/** Configure Lambda settings only (memory, timeout, permissions, etc.) */
|
|
672
|
-
setup(lambda: LambdaOptions):
|
|
664
|
+
setup(lambda: LambdaOptions): QueueBuilder<T, D, P, C, HasFiles>;
|
|
673
665
|
/** Initialize shared state on cold start. Receives deps, config, files. */
|
|
674
|
-
setup<C2>(fn: (args: SetupArgs$5<D, P, HasFiles>) => C2 | Promise<C2>):
|
|
666
|
+
setup<C2>(fn: (args: SetupArgs$5<D, P, HasFiles>) => C2 | Promise<C2>): QueueBuilder<T, D, P, C2, HasFiles>;
|
|
675
667
|
/** Initialize shared state on cold start + configure Lambda settings. */
|
|
676
|
-
setup<C2>(fn: (args: SetupArgs$5<D, P, HasFiles>) => C2 | Promise<C2>, lambda: LambdaOptions):
|
|
668
|
+
setup<C2>(fn: (args: SetupArgs$5<D, P, HasFiles>) => C2 | Promise<C2>, lambda: LambdaOptions): QueueBuilder<T, D, P, C2, HasFiles>;
|
|
669
|
+
/**
|
|
670
|
+
* Configure the event source mapping (poller) that delivers messages to the Lambda.
|
|
671
|
+
* Call before the terminal `.onMessage` / `.onMessageBatch`.
|
|
672
|
+
*/
|
|
673
|
+
poller(options: QueuePollerConfig): QueueBuilder<T, D, P, C, HasFiles>;
|
|
677
674
|
/** Handle errors thrown by message handlers */
|
|
678
675
|
onError(fn: (args: {
|
|
679
676
|
error: unknown;
|
|
680
|
-
} & SpreadCtx$5<C>) => void | Promise<void>):
|
|
677
|
+
} & SpreadCtx$5<C>) => void | Promise<void>): QueueBuilder<T, D, P, C, HasFiles>;
|
|
681
678
|
/** Cleanup callback — runs after each invocation, before Lambda freezes */
|
|
682
|
-
onCleanup(fn: (args: SpreadCtx$5<C>) => void | Promise<void>):
|
|
679
|
+
onCleanup(fn: (args: SpreadCtx$5<C>) => void | Promise<void>): QueueBuilder<T, D, P, C, HasFiles>;
|
|
683
680
|
/** Per-message handler (terminal — returns finalized handler) */
|
|
684
|
-
onMessage(fn:
|
|
681
|
+
onMessage(fn: QueueMessageFn<T, C>): QueueHandler$1<T, C>;
|
|
685
682
|
/** Batch handler (terminal — returns finalized handler) */
|
|
686
|
-
onMessageBatch(fn:
|
|
683
|
+
onMessageBatch(fn: QueueBatchFn<T, C>): QueueHandler$1<T, C>;
|
|
684
|
+
/** Finalize as a resource-only queue (no Lambda). Use when the SQS queue is consumed by an external system. */
|
|
685
|
+
build(): QueueHandler$1<T, C>;
|
|
687
686
|
}
|
|
688
687
|
/**
|
|
689
|
-
* Define
|
|
688
|
+
* Define an SQS queue with a Lambda message handler.
|
|
690
689
|
*
|
|
691
|
-
*
|
|
690
|
+
* Currently only FIFO queues are supported — pass `{ fifo: true }` explicitly
|
|
691
|
+
* (standard queue support is planned). Poller/batch settings live on the
|
|
692
|
+
* `.poller({...})` builder method; queue-level properties stay in the options
|
|
693
|
+
* object.
|
|
692
694
|
*
|
|
693
|
-
* @
|
|
694
|
-
* ```typescript
|
|
695
|
-
* export const notifications = defineFifoQueue({ batchSize: 5, schema: (i) => NotifSchema.parse(i) })
|
|
696
|
-
* .onMessageBatch(async ({ messages }) => {
|
|
697
|
-
* await sendAll(messages.map(m => m.body));
|
|
698
|
-
* })
|
|
699
|
-
* ```
|
|
695
|
+
* @see {@link https://effortless-aws.website/use-cases/queue | Queue guide}
|
|
700
696
|
*/
|
|
701
|
-
declare function
|
|
702
|
-
declare function
|
|
697
|
+
declare function defineQueue<T = unknown>(): QueueBuilder<T>;
|
|
698
|
+
declare function defineQueue<T = unknown>(options: QueueOptions<T>): QueueBuilder<T>;
|
|
703
699
|
|
|
704
700
|
/** Fargate container size presets */
|
|
705
701
|
type FargateSize = "0.25vCPU-512mb" | "0.5vCPU-1gb" | "1vCPU-2gb" | "2vCPU-4gb" | "4vCPU-8gb";
|
|
@@ -783,17 +779,7 @@ interface WorkerBuilder<T, D = undefined, P = undefined, C = undefined, HasFiles
|
|
|
783
779
|
*
|
|
784
780
|
* @typeParam T - Type of messages the worker receives via its queue
|
|
785
781
|
*
|
|
786
|
-
* @
|
|
787
|
-
* ```typescript
|
|
788
|
-
* type Job = { type: "export"; userId: string }
|
|
789
|
-
*
|
|
790
|
-
* export const worker = defineWorker<Job>({ memory: 2048, concurrency: 5 })
|
|
791
|
-
* .deps(() => ({ orders }))
|
|
792
|
-
* .setup(async ({ deps }) => ({ db: deps.orders }))
|
|
793
|
-
* .onMessage(async (msg, { db }) => {
|
|
794
|
-
* await processJob(msg, db)
|
|
795
|
-
* })
|
|
796
|
-
* ```
|
|
782
|
+
* @see {@link https://effortless-aws.website/definitions#defineworker | Worker reference}
|
|
797
783
|
*/
|
|
798
784
|
declare function defineWorker<T = unknown>(options?: WorkerOptions): WorkerBuilder<T>;
|
|
799
785
|
|
|
@@ -978,14 +964,32 @@ type WorkerClient<T = unknown> = {
|
|
|
978
964
|
};
|
|
979
965
|
|
|
980
966
|
/** Dep value types supported by the deps declaration */
|
|
981
|
-
type AnyDepHandler = TableHandler$1<any, any> | BucketHandler$1<any, any> | MailerHandler |
|
|
967
|
+
type AnyDepHandler = TableHandler$1<any, any> | BucketHandler$1<any, any> | MailerHandler | QueueHandler$1<any, any> | WorkerHandler$1<any, any>;
|
|
982
968
|
/** Maps a deps declaration to resolved runtime client types */
|
|
983
969
|
type ResolveDeps<D> = {
|
|
984
|
-
[K in keyof D]: D[K] extends TableHandler$1<infer T> ? TableClient<T> : D[K] extends BucketHandler$1<any, infer E> ? ({} extends E ? BucketClient : BucketClientWithEntities<E>) : D[K] extends MailerHandler ? EmailClient : D[K] extends
|
|
970
|
+
[K in keyof D]: D[K] extends TableHandler$1<infer T> ? TableClient<T> : D[K] extends BucketHandler$1<any, infer E> ? ({} extends E ? BucketClient : BucketClientWithEntities<E>) : D[K] extends MailerHandler ? EmailClient : D[K] extends QueueHandler$1<infer T> ? QueueClient<T> : D[K] extends WorkerHandler$1<infer T> ? WorkerClient<T> : never;
|
|
985
971
|
};
|
|
986
972
|
|
|
987
973
|
/** DynamoDB Streams view type - determines what data is captured in stream records */
|
|
988
974
|
type StreamView = "NEW_AND_OLD_IMAGES" | "NEW_IMAGE" | "OLD_IMAGE" | "KEYS_ONLY";
|
|
975
|
+
/**
|
|
976
|
+
* Stream event source mapping configuration.
|
|
977
|
+
* @internal
|
|
978
|
+
*/
|
|
979
|
+
type TableStreamConfig = {
|
|
980
|
+
/** Stream view type - what data to include in stream records (default: "NEW_AND_OLD_IMAGES") */
|
|
981
|
+
streamView?: StreamView;
|
|
982
|
+
/** Number of records to process in each Lambda invocation (1-10000, default: 100) */
|
|
983
|
+
batchSize?: number;
|
|
984
|
+
/** Maximum time to gather records before invoking (default: `"2s"`). Accepts `"5s"`, `"1m"`, etc. */
|
|
985
|
+
batchWindow?: Duration;
|
|
986
|
+
/** Where to start reading the stream (default: "LATEST") */
|
|
987
|
+
startingPosition?: "LATEST" | "TRIM_HORIZON";
|
|
988
|
+
/** Number of records to process concurrently within a batch (default: 1 — sequential) */
|
|
989
|
+
concurrency?: number;
|
|
990
|
+
/** Max retry attempts for failed records before sending to DLQ (default: 1) */
|
|
991
|
+
maxRetries?: number;
|
|
992
|
+
};
|
|
989
993
|
/**
|
|
990
994
|
* Configuration options for defineTable (single-table design).
|
|
991
995
|
*
|
|
@@ -1002,22 +1006,14 @@ type TableConfig = {
|
|
|
1002
1006
|
};
|
|
1003
1007
|
/** DynamoDB billing mode (default: "PAY_PER_REQUEST") */
|
|
1004
1008
|
billingMode?: "PAY_PER_REQUEST" | "PROVISIONED";
|
|
1005
|
-
/** Stream view type - what data to include in stream records (default: "NEW_AND_OLD_IMAGES") */
|
|
1006
|
-
streamView?: StreamView;
|
|
1007
|
-
/** Number of records to process in each Lambda invocation (1-10000, default: 100) */
|
|
1008
|
-
batchSize?: number;
|
|
1009
|
-
/** Maximum time to gather records before invoking (default: `"2s"`). Accepts `"5s"`, `"1m"`, etc. */
|
|
1010
|
-
batchWindow?: Duration;
|
|
1011
|
-
/** Where to start reading the stream (default: "LATEST") */
|
|
1012
|
-
startingPosition?: "LATEST" | "TRIM_HORIZON";
|
|
1013
|
-
/** Number of records to process concurrently within a batch (default: 1 — sequential) */
|
|
1014
|
-
concurrency?: number;
|
|
1015
1009
|
/**
|
|
1016
1010
|
* Name of the field in `data` that serves as the entity type discriminant.
|
|
1017
1011
|
* Effortless auto-copies `data[tagField]` to the top-level DynamoDB `tag` attribute on `put()`.
|
|
1018
1012
|
* Defaults to `"tag"`.
|
|
1019
1013
|
*/
|
|
1020
1014
|
tagField?: string;
|
|
1015
|
+
/** Stream event source mapping config — set via `.stream({...})` builder method. */
|
|
1016
|
+
stream?: TableStreamConfig;
|
|
1021
1017
|
};
|
|
1022
1018
|
/**
|
|
1023
1019
|
* DynamoDB stream record passed to onRecord callback.
|
|
@@ -1092,44 +1088,36 @@ type TableHandler$1<T = Record<string, unknown>, C = any> = {
|
|
|
1092
1088
|
readonly onRecord?: (...args: any[]) => any;
|
|
1093
1089
|
readonly onRecordBatch?: (...args: any[]) => any;
|
|
1094
1090
|
};
|
|
1095
|
-
/** Options passed to `defineTable()` — resource config only
|
|
1091
|
+
/** Options passed to `defineTable()` — resource config only. Stream options go in `.stream({...})`. */
|
|
1096
1092
|
type TableOptions<T> = {
|
|
1097
1093
|
/** DynamoDB billing mode (default: "PAY_PER_REQUEST") */
|
|
1098
1094
|
billingMode?: "PAY_PER_REQUEST" | "PROVISIONED";
|
|
1099
|
-
/** Stream view type (default: "NEW_AND_OLD_IMAGES") */
|
|
1100
|
-
streamView?: StreamView;
|
|
1101
|
-
/** Number of records to process in each Lambda invocation (1-10000, default: 100) */
|
|
1102
|
-
batchSize?: number;
|
|
1103
|
-
/** Maximum time to gather records before invoking (default: "2s") */
|
|
1104
|
-
batchWindow?: Duration;
|
|
1105
|
-
/** Where to start reading the stream (default: "LATEST") */
|
|
1106
|
-
startingPosition?: "LATEST" | "TRIM_HORIZON";
|
|
1107
|
-
/** Number of records to process concurrently within a batch (default: 1) */
|
|
1108
|
-
concurrency?: number;
|
|
1109
1095
|
/** Name of the field in `data` that serves as the entity type discriminant (default: "tag") */
|
|
1110
1096
|
tagField?: Extract<keyof T, string>;
|
|
1111
1097
|
/** Decode/validate function for the `data` portion of stream records */
|
|
1112
1098
|
schema?: (input: unknown) => T;
|
|
1113
1099
|
};
|
|
1114
|
-
interface TableBuilder<T = Record<string, unknown>, D = undefined, P = undefined, C = undefined, HasFiles extends boolean = false> {
|
|
1100
|
+
interface TableBuilder<T = Record<string, unknown>, D = undefined, P = undefined, C = undefined, HasFiles extends boolean = false, HasStream extends boolean = false> {
|
|
1115
1101
|
/** Declare handler dependencies (tables, queues, buckets, mailers) */
|
|
1116
|
-
deps<D2 extends Record<string, AnyDepHandler>>(fn: () => D2): TableBuilder<T, D2, P, C, HasFiles>;
|
|
1102
|
+
deps<D2 extends Record<string, AnyDepHandler>>(fn: () => D2): TableBuilder<T, D2, P, C, HasFiles, HasStream>;
|
|
1117
1103
|
/** Declare SSM secrets */
|
|
1118
|
-
config<P2 extends Record<string, AnySecretRef>>(fn: ConfigFactory<P2>): TableBuilder<T, D, P2, C, HasFiles>;
|
|
1104
|
+
config<P2 extends Record<string, AnySecretRef>>(fn: ConfigFactory<P2>): TableBuilder<T, D, P2, C, HasFiles, HasStream>;
|
|
1119
1105
|
/** Include static files in the Lambda bundle. Chainable — call multiple times. */
|
|
1120
|
-
include(glob: string): TableBuilder<T, D, P, C, true>;
|
|
1106
|
+
include(glob: string): TableBuilder<T, D, P, C, true, HasStream>;
|
|
1107
|
+
/** Configure the DynamoDB stream event source mapping (batch size, retries, concurrency, etc.). */
|
|
1108
|
+
stream: HasStream extends true ? never : (opts: TableStreamConfig) => TableBuilder<T, D, P, C, HasFiles, true>;
|
|
1121
1109
|
/** Configure Lambda settings only (memory, timeout, permissions, etc.) */
|
|
1122
|
-
setup(lambda: LambdaOptions): TableBuilder<T, D, P, C, HasFiles>;
|
|
1110
|
+
setup(lambda: LambdaOptions): TableBuilder<T, D, P, C, HasFiles, HasStream>;
|
|
1123
1111
|
/** Initialize shared state on cold start. Receives table (self-client), deps, config, files. */
|
|
1124
|
-
setup<C2>(fn: (args: SetupArgs$3<T, D, P, HasFiles>) => C2 | Promise<C2>): TableBuilder<T, D, P, C2, HasFiles>;
|
|
1112
|
+
setup<C2>(fn: (args: SetupArgs$3<T, D, P, HasFiles>) => C2 | Promise<C2>): TableBuilder<T, D, P, C2, HasFiles, HasStream>;
|
|
1125
1113
|
/** Initialize shared state on cold start + configure Lambda settings. */
|
|
1126
|
-
setup<C2>(fn: (args: SetupArgs$3<T, D, P, HasFiles>) => C2 | Promise<C2>, lambda: LambdaOptions): TableBuilder<T, D, P, C2, HasFiles>;
|
|
1114
|
+
setup<C2>(fn: (args: SetupArgs$3<T, D, P, HasFiles>) => C2 | Promise<C2>, lambda: LambdaOptions): TableBuilder<T, D, P, C2, HasFiles, HasStream>;
|
|
1127
1115
|
/** Handle errors thrown by onRecord/onRecordBatch */
|
|
1128
1116
|
onError(fn: (args: {
|
|
1129
1117
|
error: unknown;
|
|
1130
|
-
} & SpreadCtx$3<C>) => void | Promise<void>): TableBuilder<T, D, P, C, HasFiles>;
|
|
1118
|
+
} & SpreadCtx$3<C>) => void | Promise<void>): TableBuilder<T, D, P, C, HasFiles, HasStream>;
|
|
1131
1119
|
/** Cleanup callback — runs after each invocation, before Lambda freezes */
|
|
1132
|
-
onCleanup(fn: (args: SpreadCtx$3<C>) => void | Promise<void>): TableBuilder<T, D, P, C, HasFiles>;
|
|
1120
|
+
onCleanup(fn: (args: SpreadCtx$3<C>) => void | Promise<void>): TableBuilder<T, D, P, C, HasFiles, HasStream>;
|
|
1133
1121
|
/** Per-record stream handler (terminal — returns finalized handler) */
|
|
1134
1122
|
onRecord(fn: TableRecordFn<T, C>): TableHandler$1<T, C>;
|
|
1135
1123
|
/** Batch stream handler (terminal — returns finalized handler) */
|
|
@@ -1144,17 +1132,6 @@ interface TableBuilder<T = Record<string, unknown>, D = undefined, P = undefined
|
|
|
1144
1132
|
* `data (M)`, and `ttl (N)` attributes. TTL is always enabled.
|
|
1145
1133
|
*
|
|
1146
1134
|
* @see {@link https://effortless-aws.website/use-cases/database | Database guide}
|
|
1147
|
-
*
|
|
1148
|
-
* @example
|
|
1149
|
-
* ```typescript
|
|
1150
|
-
* export const orders = defineTable<OrderData>({ batchSize: 10, concurrency: 5 })
|
|
1151
|
-
* .setup(({ table }) => ({ table }))
|
|
1152
|
-
* .onRecord(async ({ record, table }) => {
|
|
1153
|
-
* if (record.eventName === "INSERT") {
|
|
1154
|
-
* console.log("New order:", record.new?.data);
|
|
1155
|
-
* }
|
|
1156
|
-
* })
|
|
1157
|
-
* ```
|
|
1158
1135
|
*/
|
|
1159
1136
|
declare function defineTable<T = Record<string, unknown>>(): TableBuilder<T>;
|
|
1160
1137
|
declare function defineTable<T = Record<string, unknown>>(options: TableOptions<T>): TableBuilder<T>;
|
|
@@ -1509,16 +1486,6 @@ interface ApiBuilder<D = undefined, P = undefined, C = undefined, ST extends boo
|
|
|
1509
1486
|
* Define an API with typed routes using a builder pattern.
|
|
1510
1487
|
*
|
|
1511
1488
|
* @see {@link https://effortless-aws.website/use-cases/http-api | HTTP API guide}
|
|
1512
|
-
*
|
|
1513
|
-
* @example
|
|
1514
|
-
* ```typescript
|
|
1515
|
-
* export const api = defineApi({ basePath: "/api" })
|
|
1516
|
-
* .deps(() => ({ users }))
|
|
1517
|
-
* .config(({ defineSecret }) => ({ authSecret: defineSecret() }))
|
|
1518
|
-
* .auth<Session>(({ config }) => ({ secret: config.authSecret, expiresIn: "1h" }))
|
|
1519
|
-
* .get({ path: "/me" }, async ({ users, auth, ok }) => ok(auth.session))
|
|
1520
|
-
* .post({ path: "/login", public: true }, async ({ auth, ok }) => ok(await auth.createSession()))
|
|
1521
|
-
* ```
|
|
1522
1489
|
*/
|
|
1523
1490
|
declare function defineApi<const O extends ApiOptions>(options: O): ApiBuilder<undefined, undefined, undefined, O["stream"] extends true ? true : false, false>;
|
|
1524
1491
|
|
|
@@ -1624,19 +1591,7 @@ interface CronBuilder<D = undefined, P = undefined, C = undefined, HasFiles exte
|
|
|
1624
1591
|
/**
|
|
1625
1592
|
* Define a cron job — scheduled Lambda invocation via EventBridge Scheduler.
|
|
1626
1593
|
*
|
|
1627
|
-
* @
|
|
1628
|
-
* ```typescript
|
|
1629
|
-
* export const sync = defineCron({ schedule: "cron(0 9 * * ? *)" })
|
|
1630
|
-
* .deps(() => ({ orders }))
|
|
1631
|
-
* .config(({ defineSecret }) => ({ apiKey: defineSecret() }))
|
|
1632
|
-
* .include("templates/*.html")
|
|
1633
|
-
* .setup(async ({ deps, config, files }) => ({
|
|
1634
|
-
* db: deps.orders, key: config.apiKey, tpl: files,
|
|
1635
|
-
* }), { memory: 512 })
|
|
1636
|
-
* .onTick(async ({ db, key, tpl }) => {
|
|
1637
|
-
* const html = tpl.read("templates/report.html")
|
|
1638
|
-
* })
|
|
1639
|
-
* ```
|
|
1594
|
+
* @see {@link https://effortless-aws.website/definitions#definecron | Cron reference}
|
|
1640
1595
|
*/
|
|
1641
1596
|
declare function defineCron(options: CronOptions): CronBuilder;
|
|
1642
1597
|
|
|
@@ -1892,8 +1847,8 @@ interface McpBuilder<D = undefined, P = undefined, C = undefined, HasFiles exten
|
|
|
1892
1847
|
* Creates a Lambda-backed MCP server that exposes tools, resources, and prompts
|
|
1893
1848
|
* for AI models and MCP-compatible clients via Streamable HTTP (JSON-RPC over POST).
|
|
1894
1849
|
*
|
|
1895
|
-
* @see https://
|
|
1896
|
-
* @see https://
|
|
1850
|
+
* @see {@link https://effortless-aws.website/use-cases/mcp-server | MCP Server guide}
|
|
1851
|
+
* @see {@link https://modelcontextprotocol.io/specification/2025-03-26 | MCP specification}
|
|
1897
1852
|
*/
|
|
1898
1853
|
declare function defineMcp(options: McpOptions): McpBuilder;
|
|
1899
1854
|
|
|
@@ -1904,10 +1859,10 @@ type McpResourceMap = McpResourceMap$1;
|
|
|
1904
1859
|
type McpPromptDef = McpPromptDef$1;
|
|
1905
1860
|
|
|
1906
1861
|
type TableHandler<T = Record<string, unknown>> = TableHandler$1<T, any>;
|
|
1907
|
-
type
|
|
1862
|
+
type QueueHandler<T = unknown> = QueueHandler$1<T, any>;
|
|
1908
1863
|
type BucketHandler<Entities extends Record<string, any> = {}> = BucketHandler$1<any, Entities>;
|
|
1909
1864
|
type CronHandler = CronHandler$1<any>;
|
|
1910
1865
|
type WorkerHandler<T = any> = WorkerHandler$1<T, any>;
|
|
1911
1866
|
type McpHandler = McpHandler$1<any>;
|
|
1912
1867
|
|
|
1913
|
-
export { type ApiConfig, type ApiHandler, type ApiRoutes, type AppConfig, type AppHandler, type AuthHelpers, type AuthOptions, type BucketClient, type BucketClientWithEntities, type BucketConfig, type BucketEntityConfig, type BucketEvent, type BucketHandler, type CacheOptions, type CdnPolicyOptions, type ConfigHelpers, type ContentType, type CronConfig, type CronHandler, type DefineSecretFn, type Duration, type EffortlessConfig, type EmailClient, type
|
|
1868
|
+
export { type ApiConfig, type ApiHandler, type ApiRoutes, type AppConfig, type AppHandler, type AuthHelpers, type AuthOptions, type BucketClient, type BucketClientWithEntities, type BucketConfig, type BucketEntityConfig, type BucketEvent, type BucketHandler, type CacheOptions, type CdnPolicyOptions, type ConfigHelpers, type ContentType, type CronConfig, type CronHandler, type DefineSecretFn, type Duration, type EffortlessConfig, type EmailClient, type HttpMethod$1 as HttpMethod, type HttpRequest, type HttpResponse, type LogLevel, type MailerConfig, type MailerHandler, type McpConfig, type McpEntries, type McpHandler, type McpInputSchema, type McpPromptArgument, type McpPromptContent, type McpPromptDef, type McpPromptMessage, type McpPromptResult, type McpResourceContent, type McpResourceDef, type McpResourceMap, type McpResourceTemplateDef, type McpToolContent, type McpToolDef, type McpToolResult, 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 QueueConfig, type QueueHandler, type QueueMessage, type QueuePollerConfig, type ResponseStream, type SecretRef, type SendEmailOptions, type SendMessageInput, type SkCondition, type StaticFiles, type StaticSiteConfig, type StaticSiteHandler, type StaticSiteSeo, type StoreEntityClient, type StreamView, type TableClient, type TableConfig, type TableHandler, type TableItem, type TableKey, type TableRecord, type Timezone, type UpdateActions, type WorkerClient, type WorkerConfig, type WorkerHandler, type WorkerSendOptions, defineApi, defineApp, defineBucket, defineConfig, defineCron, defineMailer, defineMcp, defineQueue, defineSecret, defineStaticSite, defineTable, defineWorker, generateBase64, generateHex, generateUuid, param, secret, toSeconds };
|
package/dist/index.js
CHANGED
|
@@ -77,6 +77,10 @@ function defineTable(options) {
|
|
|
77
77
|
state.static = [...state.static ?? [], glob];
|
|
78
78
|
return builder;
|
|
79
79
|
},
|
|
80
|
+
stream(opts) {
|
|
81
|
+
state.spec = { ...state.spec, stream: { ...state.spec.stream, ...opts } };
|
|
82
|
+
return builder;
|
|
83
|
+
},
|
|
80
84
|
setup(fnOrLambda, maybeLambda) {
|
|
81
85
|
if (typeof fnOrLambda === "function") {
|
|
82
86
|
state.setup = fnOrLambda;
|
|
@@ -143,8 +147,8 @@ function defineStaticSite(options) {
|
|
|
143
147
|
return builder;
|
|
144
148
|
}
|
|
145
149
|
|
|
146
|
-
// src/handlers/define-
|
|
147
|
-
function
|
|
150
|
+
// src/handlers/define-queue.ts
|
|
151
|
+
function defineQueue(options) {
|
|
148
152
|
const {
|
|
149
153
|
schema,
|
|
150
154
|
...queueConfig
|
|
@@ -160,7 +164,7 @@ function defineFifoQueue(options) {
|
|
|
160
164
|
}
|
|
161
165
|
};
|
|
162
166
|
const finalize = () => ({
|
|
163
|
-
__brand: "effortless-
|
|
167
|
+
__brand: "effortless-queue",
|
|
164
168
|
__spec: state.spec,
|
|
165
169
|
...state.schema ? { schema: state.schema } : {},
|
|
166
170
|
...state.onError ? { onError: state.onError } : {},
|
|
@@ -194,6 +198,12 @@ function defineFifoQueue(options) {
|
|
|
194
198
|
}
|
|
195
199
|
return builder;
|
|
196
200
|
},
|
|
201
|
+
poller(options2) {
|
|
202
|
+
if (Object.keys(options2).length > 0) {
|
|
203
|
+
state.spec = { ...state.spec, poller: { ...state.spec.poller, ...options2 } };
|
|
204
|
+
}
|
|
205
|
+
return builder;
|
|
206
|
+
},
|
|
197
207
|
onMessage(fn) {
|
|
198
208
|
state.onMessage = fn;
|
|
199
209
|
return finalize();
|
|
@@ -209,6 +219,9 @@ function defineFifoQueue(options) {
|
|
|
209
219
|
onCleanup(fn) {
|
|
210
220
|
state.onCleanup = fn;
|
|
211
221
|
return builder;
|
|
222
|
+
},
|
|
223
|
+
build() {
|
|
224
|
+
return finalize();
|
|
212
225
|
}
|
|
213
226
|
};
|
|
214
227
|
return builder;
|
|
@@ -658,9 +671,9 @@ export {
|
|
|
658
671
|
defineBucket,
|
|
659
672
|
defineConfig,
|
|
660
673
|
defineCron,
|
|
661
|
-
defineFifoQueue,
|
|
662
674
|
defineMailer,
|
|
663
675
|
defineMcp,
|
|
676
|
+
defineQueue,
|
|
664
677
|
defineSecret,
|
|
665
678
|
defineStaticSite,
|
|
666
679
|
defineTable,
|