effortless-aws 0.32.1 → 0.33.1

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
@@ -4,13 +4,6 @@
4
4
  * @see {@link https://effortless-aws.website/configuration | Configuration guide}
5
5
  */
6
6
  type EffortlessConfig = {
7
- /**
8
- * Project root directory. All relative paths (handlers, server, assets, etc.)
9
- * are resolved from this directory.
10
- * Resolved relative to where the CLI runs (process.cwd()).
11
- * @default "." (current working directory)
12
- */
13
- root?: string;
14
7
  /**
15
8
  * Project name used for resource naming and tagging.
16
9
  * This becomes part of Lambda function names, IAM roles, etc.
@@ -177,8 +170,6 @@ declare const defineSecret: DefineSecretFn;
177
170
  declare const secret: DefineSecretFn;
178
171
  /** @deprecated Use `SecretRef` instead */
179
172
  type ParamRef<T = string> = SecretRef<T>;
180
- /** @deprecated Use `AnySecretRef` instead */
181
- type AnyParamRef = AnySecretRef;
182
173
  /** @deprecated Use `defineSecret()` instead. */
183
174
  declare const param: <T = string>(key: string, transform?: (raw: string) => T) => SecretRef<T>;
184
175
  /** @deprecated Use `defineSecret({ generate: "hex:N" })` instead. */
@@ -272,6 +263,12 @@ type HttpResponse = {
272
263
  contentType?: ContentType;
273
264
  /** Response headers (use for custom content-types not covered by contentType) */
274
265
  headers?: Record<string, string>;
266
+ /**
267
+ * Multiple Set-Cookie values. Used by Lambda Function URLs to set multiple cookies
268
+ * in a single response (e.g., session cookie + CloudFront signed cookies).
269
+ * When present, takes precedence over `set-cookie` in `headers`.
270
+ */
271
+ cookies?: string[];
275
272
  /**
276
273
  * Set to `true` to return binary data.
277
274
  * When enabled, `body` must be a base64-encoded string and the response
@@ -326,7 +323,37 @@ type BucketClient = {
326
323
  /** The underlying S3 bucket name */
327
324
  bucketName: string;
328
325
  };
326
+ /**
327
+ * Typed client for a single entity stored as JSON in a bucket.
328
+ * Objects are stored at `{entityName}/{id}.json`.
329
+ */
330
+ type StoreEntityClient<T> = {
331
+ /** Store a JSON document by id */
332
+ put(id: string, data: T): Promise<void>;
333
+ /** Retrieve a JSON document by id. Returns undefined if not found. */
334
+ get(id: string): Promise<T | undefined>;
335
+ /** Delete a document by id */
336
+ delete(id: string): Promise<void>;
337
+ /** List all documents for this entity */
338
+ list(): Promise<{
339
+ id: string;
340
+ data: T;
341
+ }[]>;
342
+ };
343
+ /**
344
+ * BucketClient extended with typed entity clients.
345
+ */
346
+ type BucketClientWithEntities<Entities extends Record<string, any>> = BucketClient & {
347
+ [K in keyof Entities]: StoreEntityClient<Entities[K]>;
348
+ };
329
349
 
350
+ /**
351
+ * Per-entity configuration for typed JSON key-value storage within a bucket.
352
+ */
353
+ type BucketEntityConfig = {
354
+ /** Cache duration for CloudFront/browser caching (e.g., "10s", "5m", "1h"). No caching if omitted. */
355
+ cache?: Duration;
356
+ };
330
357
  /**
331
358
  * Configuration options for defineBucket.
332
359
  */
@@ -342,6 +369,8 @@ type BucketConfig = {
342
369
  prefix?: string;
343
370
  /** S3 key suffix filter for event notifications (e.g., ".jpg") */
344
371
  suffix?: string;
372
+ /** Typed JSON entity definitions for key-value storage */
373
+ entities?: Record<string, BucketEntityConfig>;
345
374
  };
346
375
  /**
347
376
  * S3 event record passed to onObjectCreated/onObjectRemoved callbacks.
@@ -361,10 +390,10 @@ type BucketEvent = {
361
390
  bucketName: string;
362
391
  };
363
392
  /** Spread ctx into callback args (empty when no setup) */
364
- type SpreadCtx$5<C> = [C] extends [undefined] ? {} : C & {};
393
+ type SpreadCtx$6<C> = [C] extends [undefined] ? {} : C & {};
365
394
  /** Setup factory — receives bucket/deps/config/files based on what was declared */
366
- type SetupArgs$5<D, P, HasFiles extends boolean> = {
367
- bucket: BucketClient;
395
+ type SetupArgs$6<D, P, HasFiles extends boolean, Entities extends Record<string, any> = {}> = {
396
+ bucket: {} extends Entities ? BucketClient : BucketClientWithEntities<Entities>;
368
397
  } & ([D] extends [undefined] ? {} : {
369
398
  deps: ResolveDeps<D>;
370
399
  }) & ([P] extends [undefined] ? {} : {
@@ -377,18 +406,18 @@ type SetupArgs$5<D, P, HasFiles extends boolean> = {
377
406
  */
378
407
  type BucketObjectCreatedFn<C = undefined> = (args: {
379
408
  event: BucketEvent;
380
- } & SpreadCtx$5<C>) => Promise<void>;
409
+ } & SpreadCtx$6<C>) => Promise<void>;
381
410
  /**
382
411
  * Callback function type for S3 ObjectRemoved events
383
412
  */
384
413
  type BucketObjectRemovedFn<C = undefined> = (args: {
385
414
  event: BucketEvent;
386
- } & SpreadCtx$5<C>) => Promise<void>;
415
+ } & SpreadCtx$6<C>) => Promise<void>;
387
416
  /**
388
417
  * Internal handler object created by defineBucket
389
418
  * @internal
390
419
  */
391
- type BucketHandler<C = any> = {
420
+ type BucketHandler$1<C = any, Entities extends Record<string, any> = {}> = {
392
421
  readonly __brand: "effortless-bucket";
393
422
  readonly __spec: BucketConfig;
394
423
  readonly onError?: (...args: any[]) => any;
@@ -407,31 +436,35 @@ type BucketOptions = {
407
436
  /** S3 key suffix filter for event notifications (e.g., ".jpg") */
408
437
  suffix?: string;
409
438
  };
410
- interface BucketBuilder<D = undefined, P = undefined, C = undefined, HasFiles extends boolean = false> {
439
+ interface BucketBuilder<D = undefined, P = undefined, C = undefined, HasFiles extends boolean = false, Entities extends Record<string, any> = {}> {
411
440
  /** Declare handler dependencies */
412
- deps<D2 extends Record<string, AnyDepHandler>>(fn: () => D2): BucketBuilder<D2, P, C, HasFiles>;
441
+ deps<D2 extends Record<string, AnyDepHandler>>(fn: () => D2): BucketBuilder<D2, P, C, HasFiles, Entities>;
413
442
  /** Declare SSM secrets */
414
- config<P2 extends Record<string, AnySecretRef>>(fn: ConfigFactory<P2>): BucketBuilder<D, P2, C, HasFiles>;
443
+ config<P2 extends Record<string, AnySecretRef>>(fn: ConfigFactory<P2>): BucketBuilder<D, P2, C, HasFiles, Entities>;
415
444
  /** Include static files in the Lambda ZIP */
416
- include(glob: string): BucketBuilder<D, P, C, true>;
445
+ include(glob: string): BucketBuilder<D, P, C, true, Entities>;
446
+ /** Register a typed JSON entity stored as `{name}/{id}.json` in the bucket */
447
+ entity<N extends string, T>(name: N, options?: BucketEntityConfig): BucketBuilder<D, P, C, HasFiles, Entities & {
448
+ [K in N]: T;
449
+ }>;
417
450
  /** Initialize shared state on cold start with lambda options */
418
- setup(lambda: LambdaOptions): BucketBuilder<D, P, C, HasFiles>;
451
+ setup(lambda: LambdaOptions): BucketBuilder<D, P, C, HasFiles, Entities>;
419
452
  /** Initialize shared state on cold start. Receives bucket (self-client), deps, config, files. */
420
- setup<C2>(fn: (args: SetupArgs$5<D, P, HasFiles>) => C2 | Promise<C2>): BucketBuilder<D, P, C2, HasFiles>;
453
+ setup<C2>(fn: (args: SetupArgs$6<D, P, HasFiles, Entities>) => C2 | Promise<C2>): BucketBuilder<D, P, C2, HasFiles, Entities>;
421
454
  /** Initialize shared state on cold start with lambda options. Receives bucket (self-client), deps, config, files. */
422
- setup<C2>(fn: (args: SetupArgs$5<D, P, HasFiles>) => C2 | Promise<C2>, lambda: LambdaOptions): BucketBuilder<D, P, C2, HasFiles>;
455
+ setup<C2>(fn: (args: SetupArgs$6<D, P, HasFiles, Entities>) => C2 | Promise<C2>, lambda: LambdaOptions): BucketBuilder<D, P, C2, HasFiles, Entities>;
423
456
  /** Handle errors thrown by callbacks */
424
457
  onError(fn: (args: {
425
458
  error: unknown;
426
- } & SpreadCtx$5<C>) => void | Promise<void>): BucketBuilder<D, P, C, HasFiles>;
459
+ } & SpreadCtx$6<C>) => void | Promise<void>): BucketBuilder<D, P, C, HasFiles, Entities>;
427
460
  /** Cleanup callback — runs after each invocation, before Lambda freezes */
428
- onCleanup(fn: (args: SpreadCtx$5<C>) => void | Promise<void>): BucketBuilder<D, P, C, HasFiles>;
461
+ onCleanup(fn: (args: SpreadCtx$6<C>) => void | Promise<void>): BucketBuilder<D, P, C, HasFiles, Entities>;
429
462
  /** Handle S3 ObjectCreated events (terminal — returns finalized handler) */
430
- onObjectCreated(fn: BucketObjectCreatedFn<C>): BucketHandler<C>;
463
+ onObjectCreated(fn: BucketObjectCreatedFn<C>): BucketHandler$1<C, Entities>;
431
464
  /** Handle S3 ObjectRemoved events (terminal — returns finalized handler) */
432
- onObjectRemoved(fn: BucketObjectRemovedFn<C>): BucketHandler<C>;
465
+ onObjectRemoved(fn: BucketObjectRemovedFn<C>): BucketHandler$1<C, Entities>;
433
466
  /** Finalize as resource-only bucket (no Lambda) */
434
- build(): BucketHandler<C>;
467
+ build(): BucketHandler$1<C, Entities>;
435
468
  }
436
469
  /**
437
470
  * Define an S3 bucket with optional event handlers.
@@ -556,9 +589,9 @@ type FifoQueueConfig = {
556
589
  maxReceiveCount?: number;
557
590
  };
558
591
  /** Spread ctx into callback args (empty when no setup) */
559
- type SpreadCtx$4<C> = [C] extends [undefined] ? {} : C & {};
592
+ type SpreadCtx$5<C> = [C] extends [undefined] ? {} : C & {};
560
593
  /** Setup factory — receives deps/config/files based on what was declared */
561
- type SetupArgs$4<D, P, HasFiles extends boolean> = ([D] extends [undefined] ? {} : {
594
+ type SetupArgs$5<D, P, HasFiles extends boolean> = ([D] extends [undefined] ? {} : {
562
595
  deps: ResolveDeps<D>;
563
596
  }) & ([P] extends [undefined] ? {} : {
564
597
  config: ResolveConfig<P & {}>;
@@ -571,7 +604,7 @@ type SetupArgs$4<D, P, HasFiles extends boolean> = ([D] extends [undefined] ? {}
571
604
  */
572
605
  type FifoQueueMessageFn<T = unknown, C = undefined> = (args: {
573
606
  message: FifoQueueMessage<T>;
574
- } & SpreadCtx$4<C>) => Promise<void>;
607
+ } & SpreadCtx$5<C>) => Promise<void>;
575
608
  /**
576
609
  * Batch handler function.
577
610
  * Called once with all messages in the batch.
@@ -579,14 +612,14 @@ type FifoQueueMessageFn<T = unknown, C = undefined> = (args: {
579
612
  */
580
613
  type FifoQueueBatchFn<T = unknown, C = undefined> = (args: {
581
614
  messages: FifoQueueMessage<T>[];
582
- } & SpreadCtx$4<C>) => Promise<void | {
615
+ } & SpreadCtx$5<C>) => Promise<void | {
583
616
  failures: string[];
584
617
  }>;
585
618
  /**
586
619
  * Internal handler object created by defineFifoQueue
587
620
  * @internal
588
621
  */
589
- type FifoQueueHandler<T = unknown, C = any> = {
622
+ type FifoQueueHandler$1<T = unknown, C = any> = {
590
623
  readonly __brand: "effortless-fifo-queue";
591
624
  readonly __spec: FifoQueueConfig;
592
625
  readonly schema?: (input: unknown) => T;
@@ -628,19 +661,19 @@ interface FifoQueueBuilder<T = unknown, D = undefined, P = undefined, C = undefi
628
661
  /** Configure Lambda settings only (memory, timeout, permissions, etc.) */
629
662
  setup(lambda: LambdaOptions): FifoQueueBuilder<T, D, P, C, HasFiles>;
630
663
  /** Initialize shared state on cold start. Receives deps, config, files. */
631
- setup<C2>(fn: (args: SetupArgs$4<D, P, HasFiles>) => C2 | Promise<C2>): FifoQueueBuilder<T, D, P, C2, HasFiles>;
664
+ setup<C2>(fn: (args: SetupArgs$5<D, P, HasFiles>) => C2 | Promise<C2>): FifoQueueBuilder<T, D, P, C2, HasFiles>;
632
665
  /** Initialize shared state on cold start + configure Lambda settings. */
633
- setup<C2>(fn: (args: SetupArgs$4<D, P, HasFiles>) => C2 | Promise<C2>, lambda: LambdaOptions): FifoQueueBuilder<T, D, P, C2, HasFiles>;
666
+ setup<C2>(fn: (args: SetupArgs$5<D, P, HasFiles>) => C2 | Promise<C2>, lambda: LambdaOptions): FifoQueueBuilder<T, D, P, C2, HasFiles>;
634
667
  /** Handle errors thrown by message handlers */
635
668
  onError(fn: (args: {
636
669
  error: unknown;
637
- } & SpreadCtx$4<C>) => void | Promise<void>): FifoQueueBuilder<T, D, P, C, HasFiles>;
670
+ } & SpreadCtx$5<C>) => void | Promise<void>): FifoQueueBuilder<T, D, P, C, HasFiles>;
638
671
  /** Cleanup callback — runs after each invocation, before Lambda freezes */
639
- onCleanup(fn: (args: SpreadCtx$4<C>) => void | Promise<void>): FifoQueueBuilder<T, D, P, C, HasFiles>;
672
+ onCleanup(fn: (args: SpreadCtx$5<C>) => void | Promise<void>): FifoQueueBuilder<T, D, P, C, HasFiles>;
640
673
  /** Per-message handler (terminal — returns finalized handler) */
641
- onMessage(fn: FifoQueueMessageFn<T, C>): FifoQueueHandler<T, C>;
674
+ onMessage(fn: FifoQueueMessageFn<T, C>): FifoQueueHandler$1<T, C>;
642
675
  /** Batch handler (terminal — returns finalized handler) */
643
- onMessageBatch(fn: FifoQueueBatchFn<T, C>): FifoQueueHandler<T, C>;
676
+ onMessageBatch(fn: FifoQueueBatchFn<T, C>): FifoQueueHandler$1<T, C>;
644
677
  }
645
678
  /**
646
679
  * Define a FIFO SQS queue with a Lambda message handler.
@@ -672,7 +705,7 @@ type WorkerConfig = {
672
705
  concurrency?: number;
673
706
  };
674
707
  /** Setup factory — receives deps/config/files based on what was declared */
675
- type SetupArgs$3<D, P, HasFiles extends boolean> = ([D] extends [undefined] ? {} : {
708
+ type SetupArgs$4<D, P, HasFiles extends boolean> = ([D] extends [undefined] ? {} : {
676
709
  deps: ResolveDeps<D>;
677
710
  }) & ([P] extends [undefined] ? {} : {
678
711
  config: ResolveConfig<P & {}>;
@@ -680,14 +713,14 @@ type SetupArgs$3<D, P, HasFiles extends boolean> = ([D] extends [undefined] ? {}
680
713
  files: StaticFiles;
681
714
  } : {});
682
715
  /** Spread ctx into callback args (empty when no setup) */
683
- type SpreadCtx$3<C> = [C] extends [undefined] ? {} : C & {};
716
+ type SpreadCtx$4<C> = [C] extends [undefined] ? {} : C & {};
684
717
  /** Callback function for the worker's onMessage */
685
- type WorkerMessageFn<T, C = undefined> = (msg: T, ctx: SpreadCtx$3<C>) => Promise<void> | void;
718
+ type WorkerMessageFn<T, C = undefined> = (msg: T, ctx: SpreadCtx$4<C>) => Promise<void> | void;
686
719
  /**
687
720
  * Handler object created by defineWorker.
688
721
  * @internal
689
722
  */
690
- type WorkerHandler<T = any, C = any> = {
723
+ type WorkerHandler$1<T = any, C = any> = {
691
724
  readonly __brand: "effortless-worker";
692
725
  readonly __spec: WorkerConfig;
693
726
  readonly onError?: (...args: any[]) => any;
@@ -717,19 +750,19 @@ interface WorkerBuilder<T, D = undefined, P = undefined, C = undefined, HasFiles
717
750
  /** Configure Lambda settings only (memory, timeout, permissions, logLevel) */
718
751
  setup(lambda: LambdaOptions): WorkerBuilder<T, D, P, C, HasFiles>;
719
752
  /** Initialize shared state on cold start. Receives deps, config, files. */
720
- setup<C2>(fn: (args: SetupArgs$3<D, P, HasFiles>) => C2 | Promise<C2>): WorkerBuilder<T, D, P, C2, HasFiles>;
753
+ setup<C2>(fn: (args: SetupArgs$4<D, P, HasFiles>) => C2 | Promise<C2>): WorkerBuilder<T, D, P, C2, HasFiles>;
721
754
  /** Initialize shared state on cold start + configure Lambda settings. */
722
- setup<C2>(fn: (args: SetupArgs$3<D, P, HasFiles>) => C2 | Promise<C2>, lambda: LambdaOptions): WorkerBuilder<T, D, P, C2, HasFiles>;
755
+ setup<C2>(fn: (args: SetupArgs$4<D, P, HasFiles>) => C2 | Promise<C2>, lambda: LambdaOptions): WorkerBuilder<T, D, P, C2, HasFiles>;
723
756
  /** Handle errors thrown by onMessage. Return "delete" to discard, "retry" to reprocess (default). */
724
757
  onError(fn: (args: {
725
758
  error: unknown;
726
759
  msg: T;
727
760
  retryCount: number;
728
- } & SpreadCtx$3<C>) => "retry" | "delete" | void | Promise<"retry" | "delete" | void>): WorkerBuilder<T, D, P, C, HasFiles>;
761
+ } & SpreadCtx$4<C>) => "retry" | "delete" | void | Promise<"retry" | "delete" | void>): WorkerBuilder<T, D, P, C, HasFiles>;
729
762
  /** Cleanup callback — runs when the worker shuts down */
730
- onCleanup(fn: (args: SpreadCtx$3<C>) => void | Promise<void>): WorkerBuilder<T, D, P, C, HasFiles>;
763
+ onCleanup(fn: (args: SpreadCtx$4<C>) => void | Promise<void>): WorkerBuilder<T, D, P, C, HasFiles>;
731
764
  /** Process a single message from the queue (terminal) */
732
- onMessage(fn: WorkerMessageFn<T, C>): WorkerHandler<T, C>;
765
+ onMessage(fn: WorkerMessageFn<T, C>): WorkerHandler$1<T, C>;
733
766
  }
734
767
  /**
735
768
  * Define a worker — a long-running Fargate container with an SQS queue.
@@ -935,10 +968,10 @@ type WorkerClient<T = unknown> = {
935
968
  };
936
969
 
937
970
  /** Dep value types supported by the deps declaration */
938
- type AnyDepHandler = TableHandler<any, any> | BucketHandler<any> | MailerHandler | FifoQueueHandler<any, any> | WorkerHandler<any, any>;
971
+ type AnyDepHandler = TableHandler$1<any, any> | BucketHandler$1<any, any> | MailerHandler | FifoQueueHandler$1<any, any> | WorkerHandler$1<any, any>;
939
972
  /** Maps a deps declaration to resolved runtime client types */
940
973
  type ResolveDeps<D> = {
941
- [K in keyof D]: D[K] extends TableHandler<infer T> ? TableClient<T> : D[K] extends BucketHandler ? BucketClient : D[K] extends MailerHandler ? EmailClient : D[K] extends FifoQueueHandler<infer T> ? QueueClient<T> : D[K] extends WorkerHandler<infer T> ? WorkerClient<T> : never;
974
+ [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 FifoQueueHandler$1<infer T> ? QueueClient<T> : D[K] extends WorkerHandler$1<infer T> ? WorkerClient<T> : never;
942
975
  };
943
976
 
944
977
  /** DynamoDB Streams view type - determines what data is captured in stream records */
@@ -1001,7 +1034,7 @@ type TableRecord<T = Record<string, unknown>> = {
1001
1034
  timestamp?: number;
1002
1035
  };
1003
1036
  /** Setup factory — receives table/deps/config/files based on what was declared */
1004
- type SetupArgs$2<T, D, P, HasFiles extends boolean> = {
1037
+ type SetupArgs$3<T, D, P, HasFiles extends boolean> = {
1005
1038
  table: TableClient<T>;
1006
1039
  } & ([D] extends [undefined] ? {} : {
1007
1040
  deps: ResolveDeps<D>;
@@ -1011,7 +1044,7 @@ type SetupArgs$2<T, D, P, HasFiles extends boolean> = {
1011
1044
  files: StaticFiles;
1012
1045
  } : {});
1013
1046
  /** Spread ctx into callback args (empty when no setup) */
1014
- type SpreadCtx$2<C> = [C] extends [undefined] ? {} : C & {};
1047
+ type SpreadCtx$3<C> = [C] extends [undefined] ? {} : C & {};
1015
1048
  /**
1016
1049
  * Callback function type for processing a single DynamoDB stream record.
1017
1050
  * Receives the current record and the full batch for context.
@@ -1019,7 +1052,7 @@ type SpreadCtx$2<C> = [C] extends [undefined] ? {} : C & {};
1019
1052
  type TableRecordFn<T = Record<string, unknown>, C = undefined> = (args: {
1020
1053
  record: TableRecord<T>;
1021
1054
  batch: readonly TableRecord<T>[];
1022
- } & SpreadCtx$2<C>) => Promise<void>;
1055
+ } & SpreadCtx$3<C>) => Promise<void>;
1023
1056
  /**
1024
1057
  * Batch handler function for DynamoDB stream records.
1025
1058
  * Called once with all records in the batch.
@@ -1027,7 +1060,7 @@ type TableRecordFn<T = Record<string, unknown>, C = undefined> = (args: {
1027
1060
  */
1028
1061
  type TableBatchFn<T = Record<string, unknown>, C = undefined> = (args: {
1029
1062
  records: readonly TableRecord<T>[];
1030
- } & SpreadCtx$2<C>) => Promise<void | {
1063
+ } & SpreadCtx$3<C>) => Promise<void | {
1031
1064
  failures: string[];
1032
1065
  }>;
1033
1066
  /** Static config extracted by AST (no runtime callbacks) */
@@ -1036,7 +1069,7 @@ type TableBatchFn<T = Record<string, unknown>, C = undefined> = (args: {
1036
1069
  * Used by runtime wrappers and as type annotation for circular deps.
1037
1070
  * @internal
1038
1071
  */
1039
- type TableHandler<T = Record<string, unknown>, C = any> = {
1072
+ type TableHandler$1<T = Record<string, unknown>, C = any> = {
1040
1073
  readonly __brand: "effortless-table";
1041
1074
  readonly __spec: TableConfig;
1042
1075
  readonly schema?: (input: unknown) => T;
@@ -1078,21 +1111,21 @@ interface TableBuilder<T = Record<string, unknown>, D = undefined, P = undefined
1078
1111
  /** Configure Lambda settings only (memory, timeout, permissions, etc.) */
1079
1112
  setup(lambda: LambdaOptions): TableBuilder<T, D, P, C, HasFiles>;
1080
1113
  /** Initialize shared state on cold start. Receives table (self-client), deps, config, files. */
1081
- setup<C2>(fn: (args: SetupArgs$2<T, D, P, HasFiles>) => C2 | Promise<C2>): TableBuilder<T, D, P, C2, HasFiles>;
1114
+ setup<C2>(fn: (args: SetupArgs$3<T, D, P, HasFiles>) => C2 | Promise<C2>): TableBuilder<T, D, P, C2, HasFiles>;
1082
1115
  /** Initialize shared state on cold start + configure Lambda settings. */
1083
- setup<C2>(fn: (args: SetupArgs$2<T, D, P, HasFiles>) => C2 | Promise<C2>, lambda: LambdaOptions): TableBuilder<T, D, P, C2, HasFiles>;
1116
+ setup<C2>(fn: (args: SetupArgs$3<T, D, P, HasFiles>) => C2 | Promise<C2>, lambda: LambdaOptions): TableBuilder<T, D, P, C2, HasFiles>;
1084
1117
  /** Handle errors thrown by onRecord/onRecordBatch */
1085
1118
  onError(fn: (args: {
1086
1119
  error: unknown;
1087
- } & SpreadCtx$2<C>) => void | Promise<void>): TableBuilder<T, D, P, C, HasFiles>;
1120
+ } & SpreadCtx$3<C>) => void | Promise<void>): TableBuilder<T, D, P, C, HasFiles>;
1088
1121
  /** Cleanup callback — runs after each invocation, before Lambda freezes */
1089
- onCleanup(fn: (args: SpreadCtx$2<C>) => void | Promise<void>): TableBuilder<T, D, P, C, HasFiles>;
1122
+ onCleanup(fn: (args: SpreadCtx$3<C>) => void | Promise<void>): TableBuilder<T, D, P, C, HasFiles>;
1090
1123
  /** Per-record stream handler (terminal — returns finalized handler) */
1091
- onRecord(fn: TableRecordFn<T, C>): TableHandler<T, C>;
1124
+ onRecord(fn: TableRecordFn<T, C>): TableHandler$1<T, C>;
1092
1125
  /** Batch stream handler (terminal — returns finalized handler) */
1093
- onRecordBatch(fn: TableBatchFn<T, C>): TableHandler<T, C>;
1126
+ onRecordBatch(fn: TableBatchFn<T, C>): TableHandler$1<T, C>;
1094
1127
  /** Finalize as resource-only table (no Lambda) */
1095
- build(): TableHandler<T, C>;
1128
+ build(): TableHandler$1<T, C>;
1096
1129
  }
1097
1130
  /**
1098
1131
  * Define a DynamoDB table with optional stream handler (single-table design).
@@ -1169,6 +1202,18 @@ declare const defineApp: () => (options: AppConfig) => AppHandler;
1169
1202
  type AnyRoutableHandler = {
1170
1203
  readonly __brand: string;
1171
1204
  };
1205
+ /** Route configuration for serving bucket content through CloudFront */
1206
+ type BucketRouteConfig = {
1207
+ bucket: {
1208
+ readonly __brand: "effortless-bucket";
1209
+ };
1210
+ /** Access control: "private" requires CloudFront signed cookies, "public" serves openly. Default: "public" */
1211
+ access?: "private" | "public";
1212
+ };
1213
+ /** A route value: either an API handler or a bucket route config */
1214
+ type RouteValue = AnyRoutableHandler | BucketRouteConfig;
1215
+ /** Type guard for bucket route entries */
1216
+ declare const isBucketRoute: (v: unknown) => v is BucketRouteConfig;
1172
1217
  /** Simplified request object passed to middleware */
1173
1218
  type MiddlewareRequest = {
1174
1219
  uri: string;
@@ -1215,10 +1260,10 @@ type StaticSiteConfig = {
1215
1260
  build?: string;
1216
1261
  /** Custom domain name. Accepts a string (same domain for all stages) or a Record mapping stage names to domains (e.g., `{ prod: "example.com", dev: "dev.example.com" }`). Requires an ACM certificate in us-east-1. If the cert also covers www, a 301 redirect from www to non-www is set up automatically. */
1217
1262
  domain?: string | Record<string, string>;
1218
- /** CloudFront route overrides: path patterns forwarded to API Gateway instead of S3.
1219
- * Keys are CloudFront path patterns (e.g., "/api/*"), values are HTTP handlers.
1220
- * Example: `routes: { "/api/*": api }` */
1221
- routes?: Record<string, AnyRoutableHandler>;
1263
+ /** CloudFront route overrides: path patterns forwarded to API Gateway or S3 bucket origins.
1264
+ * Keys are CloudFront path patterns (e.g., "/api/*"), values are HTTP handlers or bucket route configs.
1265
+ * Example: `routes: { "/api/*": api, "/files/*": { bucket: storage, access: "private" } }` */
1266
+ routes?: Record<string, RouteValue>;
1222
1267
  /** Custom 404 error page path relative to `dir` (e.g. "404.html").
1223
1268
  * For non-SPA sites only. If not set, a default page is generated automatically. */
1224
1269
  errorPage?: string;
@@ -1245,17 +1290,27 @@ type StaticSiteHandler = {
1245
1290
  */
1246
1291
  declare const defineStaticSite: () => (options: StaticSiteConfig) => StaticSiteHandler;
1247
1292
 
1293
+ /** Options for CloudFront signed cookie policy */
1294
+ type CdnPolicyOptions = {
1295
+ /** Path pattern to grant access to (e.g., "/files/users/123/*"). Supports `*` and `?` wildcards. */
1296
+ path: string;
1297
+ /** How long the CDN access is valid (e.g., "1h", "30m") */
1298
+ ttl: Duration;
1299
+ };
1248
1300
  /** Options for creating a session */
1249
1301
  type SessionOptions = {
1250
1302
  expiresIn?: Duration;
1303
+ /** CloudFront signed cookie policy for CDN-level access control */
1304
+ cdnPolicy?: CdnPolicyOptions;
1251
1305
  };
1252
- /** Session response with Set-Cookie header */
1306
+ /** Session response with Set-Cookie headers */
1253
1307
  type SessionResponse = {
1254
1308
  status: 200;
1255
1309
  body: {
1256
1310
  ok: true;
1257
1311
  };
1258
1312
  headers: Record<string, string>;
1313
+ cookies?: string[];
1259
1314
  };
1260
1315
  /**
1261
1316
  * Auth helpers injected into API handler callback args when `auth` is configured.
@@ -1309,19 +1364,35 @@ type OkHelper = (body?: unknown, status?: number) => HttpResponse;
1309
1364
  /** Error response helper: `fail("message")` → `{ status: 400, body: { error: "message" } }` */
1310
1365
  type FailHelper = (message: string, status?: number) => HttpResponse;
1311
1366
  type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
1367
+ /** Cache options for a GET route. Duration shorthand (e.g. "30s", "5m") or object for fine-grained control. */
1368
+ type CacheOptions = Duration | {
1369
+ ttl: Duration;
1370
+ swr?: Duration;
1371
+ scope?: "public" | "private";
1372
+ };
1373
+ /** Resolved cache config with numeric seconds */
1374
+ type ResolvedCache = {
1375
+ private?: false;
1376
+ ttl: number;
1377
+ swr: number;
1378
+ } | {
1379
+ private: true;
1380
+ ttl: number;
1381
+ };
1312
1382
  /** Parsed route definition stored at runtime */
1313
1383
  type RouteEntry = {
1314
1384
  method: HttpMethod;
1315
1385
  path: string;
1316
1386
  onRequest: (...args: any[]) => any;
1317
1387
  public?: boolean;
1388
+ cache?: ResolvedCache;
1318
1389
  };
1319
1390
  /** Spread ctx into route args: Omit auth config, add AuthHelpers if present */
1320
- type SpreadCtx$1<C> = ([C] extends [undefined] ? {} : Omit<C & {}, 'auth'>) & ([ExtractAuth<C>] extends [undefined] ? {} : {
1391
+ type SpreadCtx$2<C> = ([C] extends [undefined] ? {} : Omit<C & {}, 'auth'>) & ([ExtractAuth<C>] extends [undefined] ? {} : {
1321
1392
  auth: AuthHelpers<ExtractAuth<C>>;
1322
1393
  });
1323
1394
  /** Callback args available inside each route — ctx is spread into args */
1324
- type RouteArgs<C, ST> = SpreadCtx$1<C> & {
1395
+ type RouteArgs<C, ST> = SpreadCtx$2<C> & {
1325
1396
  req: HttpRequest;
1326
1397
  input: unknown;
1327
1398
  ok: OkHelper;
@@ -1331,12 +1402,16 @@ type RouteArgs<C, ST> = SpreadCtx$1<C> & {
1331
1402
  } : {});
1332
1403
  /** Route handler function */
1333
1404
  type RouteHandler<C, ST> = (args: RouteArgs<C, ST>) => Promise<HttpResponse | void> | HttpResponse | void;
1334
- /** Route options (e.g. public) */
1405
+ /** Route options for all methods */
1335
1406
  type RouteOptions = {
1336
1407
  public?: boolean;
1337
1408
  };
1409
+ /** Route options for GET — supports caching */
1410
+ type GetRouteOptions = RouteOptions & {
1411
+ cache?: CacheOptions;
1412
+ };
1338
1413
  /** Setup factory — receives deps/config/files/enableAuth based on what was declared */
1339
- type SetupArgs$1<D, P, HasFiles extends boolean> = {
1414
+ type SetupArgs$2<D, P, HasFiles extends boolean> = {
1340
1415
  enableAuth: EnableAuth;
1341
1416
  ok: OkHelper;
1342
1417
  fail: FailHelper;
@@ -1384,7 +1459,7 @@ type ApiOptions = {
1384
1459
  * Has `__brand` so CLI discovers it. Each `.get()/.post()` adds a route and returns self.
1385
1460
  */
1386
1461
  interface ApiRoutes<C = undefined, ST extends boolean = false> extends ApiHandler<C> {
1387
- get(path: `/${string}`, handler: RouteHandler<C, ST>, options?: RouteOptions): ApiRoutes<C, ST>;
1462
+ get(path: `/${string}`, handler: RouteHandler<C, ST>, options?: GetRouteOptions): ApiRoutes<C, ST>;
1388
1463
  post(path: `/${string}`, handler: RouteHandler<C, ST>, options?: RouteOptions): ApiRoutes<C, ST>;
1389
1464
  put(path: `/${string}`, handler: RouteHandler<C, ST>, options?: RouteOptions): ApiRoutes<C, ST>;
1390
1465
  patch(path: `/${string}`, handler: RouteHandler<C, ST>, options?: RouteOptions): ApiRoutes<C, ST>;
@@ -1406,20 +1481,20 @@ interface ApiBuilder<D = undefined, P = undefined, C = undefined, ST extends boo
1406
1481
  /** Configure Lambda settings only (no init function) */
1407
1482
  setup(lambda: LambdaOptions): ApiBuilder<D, P, C, ST, HasFiles>;
1408
1483
  /** Initialize shared state on cold start. Receives deps/config/files based on what was declared. */
1409
- setup<C2>(fn: (args: SetupArgs$1<D, P, HasFiles>) => ValidateSetupReturn<C2> | Promise<ValidateSetupReturn<C2>>): ApiBuilder<D, P, C2, ST, HasFiles>;
1484
+ setup<C2>(fn: (args: SetupArgs$2<D, P, HasFiles>) => ValidateSetupReturn<C2> | Promise<ValidateSetupReturn<C2>>): ApiBuilder<D, P, C2, ST, HasFiles>;
1410
1485
  /** Initialize shared state on cold start with Lambda config. */
1411
- setup<C2>(fn: (args: SetupArgs$1<D, P, HasFiles>) => ValidateSetupReturn<C2> | Promise<ValidateSetupReturn<C2>>, lambda: LambdaOptions): ApiBuilder<D, P, C2, ST, HasFiles>;
1486
+ setup<C2>(fn: (args: SetupArgs$2<D, P, HasFiles>) => ValidateSetupReturn<C2> | Promise<ValidateSetupReturn<C2>>, lambda: LambdaOptions): ApiBuilder<D, P, C2, ST, HasFiles>;
1412
1487
  /** Handle errors thrown by routes */
1413
1488
  onError(fn: (args: {
1414
1489
  error: unknown;
1415
1490
  req: HttpRequest;
1416
1491
  ok: OkHelper;
1417
1492
  fail: FailHelper;
1418
- } & SpreadCtx$1<C>) => HttpResponse | Promise<HttpResponse>): ApiBuilder<D, P, C, ST, HasFiles>;
1493
+ } & SpreadCtx$2<C>) => HttpResponse | Promise<HttpResponse>): ApiBuilder<D, P, C, ST, HasFiles>;
1419
1494
  /** Cleanup callback — runs after each invocation, before Lambda freezes */
1420
- onCleanup(fn: (args: SpreadCtx$1<C>) => void | Promise<void>): ApiBuilder<D, P, C, ST, HasFiles>;
1495
+ onCleanup(fn: (args: SpreadCtx$2<C>) => void | Promise<void>): ApiBuilder<D, P, C, ST, HasFiles>;
1421
1496
  /** Add a GET route (terminal — returns finalized handler with route methods) */
1422
- get(path: `/${string}`, handler: RouteHandler<C, ST>, options?: RouteOptions): ApiRoutes<C, ST>;
1497
+ get(path: `/${string}`, handler: RouteHandler<C, ST>, options?: GetRouteOptions): ApiRoutes<C, ST>;
1423
1498
  /** Add a POST route (terminal) */
1424
1499
  post(path: `/${string}`, handler: RouteHandler<C, ST>, options?: RouteOptions): ApiRoutes<C, ST>;
1425
1500
  /** Add a PUT route (terminal) */
@@ -1494,7 +1569,7 @@ type CronConfig = {
1494
1569
  timezone?: Timezone;
1495
1570
  };
1496
1571
  /** Setup factory — receives deps/config/files based on what was declared */
1497
- type SetupArgs<D, P, HasFiles extends boolean> = ([D] extends [undefined] ? {} : {
1572
+ type SetupArgs$1<D, P, HasFiles extends boolean> = ([D] extends [undefined] ? {} : {
1498
1573
  deps: ResolveDeps<D>;
1499
1574
  }) & ([P] extends [undefined] ? {} : {
1500
1575
  config: ResolveConfig<P & {}>;
@@ -1502,14 +1577,14 @@ type SetupArgs<D, P, HasFiles extends boolean> = ([D] extends [undefined] ? {} :
1502
1577
  files: StaticFiles;
1503
1578
  } : {});
1504
1579
  /** Spread ctx into callback args (empty when no setup) */
1505
- type SpreadCtx<C> = [C] extends [undefined] ? {} : C & {};
1580
+ type SpreadCtx$1<C> = [C] extends [undefined] ? {} : C & {};
1506
1581
  /** Callback function for cron tick */
1507
- type CronTickFn<C = undefined> = (args: SpreadCtx<C>) => Promise<void> | void;
1582
+ type CronTickFn<C = undefined> = (args: SpreadCtx$1<C>) => Promise<void> | void;
1508
1583
  /**
1509
1584
  * Handler object created by defineCron.
1510
1585
  * @internal
1511
1586
  */
1512
- type CronHandler<C = any> = {
1587
+ type CronHandler$1<C = any> = {
1513
1588
  readonly __brand: "effortless-cron";
1514
1589
  readonly __spec: CronConfig;
1515
1590
  readonly onError?: (...args: any[]) => any;
@@ -1537,17 +1612,17 @@ interface CronBuilder<D = undefined, P = undefined, C = undefined, HasFiles exte
1537
1612
  /** Configure Lambda settings only (memory, timeout, permissions, logLevel) */
1538
1613
  setup(lambda: LambdaOptions): CronBuilder<D, P, C, HasFiles>;
1539
1614
  /** Initialize shared state on cold start. Receives deps, config, files. */
1540
- setup<C2>(fn: (args: SetupArgs<D, P, HasFiles>) => C2 | Promise<C2>): CronBuilder<D, P, C2, HasFiles>;
1615
+ setup<C2>(fn: (args: SetupArgs$1<D, P, HasFiles>) => C2 | Promise<C2>): CronBuilder<D, P, C2, HasFiles>;
1541
1616
  /** Initialize shared state on cold start + configure Lambda settings. */
1542
- setup<C2>(fn: (args: SetupArgs<D, P, HasFiles>) => C2 | Promise<C2>, lambda: LambdaOptions): CronBuilder<D, P, C2, HasFiles>;
1617
+ setup<C2>(fn: (args: SetupArgs$1<D, P, HasFiles>) => C2 | Promise<C2>, lambda: LambdaOptions): CronBuilder<D, P, C2, HasFiles>;
1543
1618
  /** Handle errors thrown by onTick */
1544
1619
  onError(fn: (args: {
1545
1620
  error: unknown;
1546
- } & SpreadCtx<C>) => void | Promise<void>): CronBuilder<D, P, C, HasFiles>;
1621
+ } & SpreadCtx$1<C>) => void | Promise<void>): CronBuilder<D, P, C, HasFiles>;
1547
1622
  /** Cleanup callback — runs after each invocation, before Lambda freezes */
1548
- onCleanup(fn: (args: SpreadCtx<C>) => void | Promise<void>): CronBuilder<D, P, C, HasFiles>;
1623
+ onCleanup(fn: (args: SpreadCtx$1<C>) => void | Promise<void>): CronBuilder<D, P, C, HasFiles>;
1549
1624
  /** Tick handler — called on each scheduled invocation (terminal) */
1550
- onTick(fn: CronTickFn<C>): CronHandler<C>;
1625
+ onTick(fn: CronTickFn<C>): CronHandler$1<C>;
1551
1626
  }
1552
1627
  /**
1553
1628
  * Define a cron job — scheduled Lambda invocation via EventBridge Scheduler.
@@ -1568,4 +1643,135 @@ interface CronBuilder<D = undefined, P = undefined, C = undefined, HasFiles exte
1568
1643
  */
1569
1644
  declare function defineCron(options: CronOptions): CronBuilder;
1570
1645
 
1571
- export { type AnyParamRef, type AnySecretRef, type ApiAuthConfig, type ApiConfig, type ApiHandler, type ApiRoutes, type AppConfig, type AppHandler, type AuthHelpers, type BucketClient, type BucketConfig, type BucketEvent, type BucketHandler, type ConfigHelpers, type ContentType, type CronConfig, type CronHandler, type DefineSecretFn, type Duration, type EffortlessConfig, type EmailClient, type FifoQueueConfig, type FifoQueueHandler, type FifoQueueMessage, type GenerateSpec, type HttpMethod$1 as 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 ResponseStream, type SecretRef, type SendEmailOptions, type SendMessageInput, type SkCondition, type StaticFiles, type StaticSiteConfig, type StaticSiteHandler, type StaticSiteSeo, 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, defineFifoQueue, defineMailer, defineSecret, defineStaticSite, defineTable, defineWorker, generateBase64, generateHex, generateUuid, param, secret, toSeconds };
1646
+ /** Static config extracted at deploy time */
1647
+ type McpConfig = {
1648
+ /** MCP server name (used in server info) */
1649
+ name: string;
1650
+ /** MCP server version (default: "1.0.0") */
1651
+ version?: string;
1652
+ /** Lambda function settings (memory, timeout, permissions, etc.) */
1653
+ lambda?: LambdaWithPermissions;
1654
+ };
1655
+ /** JSON Schema for a tool's input parameters */
1656
+ type McpInputSchema = {
1657
+ type: "object";
1658
+ properties: Record<string, unknown>;
1659
+ required?: string[];
1660
+ };
1661
+ /** Content block returned by a tool handler */
1662
+ type McpToolContent = {
1663
+ type: "text";
1664
+ text: string;
1665
+ } | {
1666
+ type: "image";
1667
+ data: string;
1668
+ mimeType: string;
1669
+ } | {
1670
+ type: "resource";
1671
+ resource: {
1672
+ uri: string;
1673
+ text: string;
1674
+ mimeType?: string;
1675
+ };
1676
+ };
1677
+ /** Result returned by a tool handler */
1678
+ type McpToolResult = {
1679
+ content: McpToolContent[];
1680
+ isError?: boolean;
1681
+ };
1682
+ /** A single MCP tool definition */
1683
+ type McpToolDef<C = undefined> = {
1684
+ /** Human-readable description of the tool */
1685
+ description: string;
1686
+ /** JSON Schema describing the tool's input parameters */
1687
+ input: McpInputSchema;
1688
+ /** Handler function called when the tool is invoked */
1689
+ handler: (input: any, ctx: SpreadCtx<C>) => McpToolResult | Promise<McpToolResult>;
1690
+ };
1691
+ /** Setup factory — receives deps/config/files based on what was declared */
1692
+ type SetupArgs<D, P, HasFiles extends boolean> = ([D] extends [undefined] ? {} : {
1693
+ deps: ResolveDeps<D>;
1694
+ }) & ([P] extends [undefined] ? {} : {
1695
+ config: ResolveConfig<P & {}>;
1696
+ }) & (HasFiles extends true ? {
1697
+ files: StaticFiles;
1698
+ } : {});
1699
+ /** Spread ctx into callback args (empty when no setup) */
1700
+ type SpreadCtx<C> = [C] extends [undefined] ? {} : C & {};
1701
+ /**
1702
+ * Handler object created by defineMcp.
1703
+ * @internal
1704
+ */
1705
+ type McpHandler$1<C = any> = {
1706
+ readonly __brand: "effortless-mcp";
1707
+ readonly __spec: McpConfig;
1708
+ readonly onError?: (...args: any[]) => any;
1709
+ readonly onCleanup?: (...args: any[]) => any;
1710
+ readonly setup?: (...args: any[]) => C | Promise<C>;
1711
+ readonly deps?: Record<string, unknown> | (() => Record<string, unknown>);
1712
+ readonly config?: Record<string, unknown>;
1713
+ readonly static?: string[];
1714
+ readonly tools?: (...args: any[]) => any;
1715
+ };
1716
+ /** Options passed to `defineMcp()` */
1717
+ type McpOptions = {
1718
+ /** MCP server name (used in server info) */
1719
+ name: string;
1720
+ /** MCP server version (default: "1.0.0") */
1721
+ version?: string;
1722
+ };
1723
+ interface McpBuilder<D = undefined, P = undefined, C = undefined, HasFiles extends boolean = false> {
1724
+ /** Declare handler dependencies (tables, queues, buckets, mailers, workers) */
1725
+ deps<D2 extends Record<string, AnyDepHandler>>(fn: () => D2): McpBuilder<D2, P, C, HasFiles>;
1726
+ /** Declare SSM secrets */
1727
+ config<P2 extends Record<string, AnySecretRef>>(fn: ConfigFactory<P2>): McpBuilder<D, P2, C, HasFiles>;
1728
+ /** Include static files in the bundle. Chainable — call multiple times. */
1729
+ include(glob: string): McpBuilder<D, P, C, true>;
1730
+ /** Configure Lambda settings only (memory, timeout, permissions, logLevel) */
1731
+ setup(lambda: LambdaOptions): McpBuilder<D, P, C, HasFiles>;
1732
+ /** Initialize shared state on cold start. Receives deps, config, files. */
1733
+ setup<C2>(fn: (args: SetupArgs<D, P, HasFiles>) => C2 | Promise<C2>): McpBuilder<D, P, C2, HasFiles>;
1734
+ /** Initialize shared state on cold start + configure Lambda settings. */
1735
+ setup<C2>(fn: (args: SetupArgs<D, P, HasFiles>) => C2 | Promise<C2>, lambda: LambdaOptions): McpBuilder<D, P, C2, HasFiles>;
1736
+ /** Handle errors thrown by tool handlers */
1737
+ onError(fn: (args: {
1738
+ error: unknown;
1739
+ toolName: string;
1740
+ } & SpreadCtx<C>) => void | Promise<void>): McpBuilder<D, P, C, HasFiles>;
1741
+ /** Cleanup callback — runs on shutdown */
1742
+ onCleanup(fn: (args: SpreadCtx<C>) => void | Promise<void>): McpBuilder<D, P, C, HasFiles>;
1743
+ /** Define MCP tools (terminal) */
1744
+ tools(fn: (ctx: SpreadCtx<C>) => Record<string, McpToolDef<C>>): McpHandler$1<C>;
1745
+ }
1746
+ /**
1747
+ * Define an MCP (Model Context Protocol) server endpoint.
1748
+ *
1749
+ * Creates a Lambda-backed MCP server that exposes tools for AI models
1750
+ * and MCP-compatible clients to discover and invoke.
1751
+ *
1752
+ * @example
1753
+ * ```typescript
1754
+ * export const mcp = defineMcp({ name: "my-tools" })
1755
+ * .deps(() => ({ users: usersTable }))
1756
+ * .setup(({ deps }) => ({ db: deps.users }))
1757
+ * .tools(({ db }) => ({
1758
+ * get_user: {
1759
+ * description: "Get a user by ID",
1760
+ * input: { type: "object", properties: { id: { type: "string" } }, required: ["id"] },
1761
+ * handler: async (input) => ({
1762
+ * content: [{ type: "text", text: JSON.stringify(await db.get({ pk: input.id, sk: "profile" })) }]
1763
+ * })
1764
+ * }
1765
+ * }))
1766
+ * ```
1767
+ */
1768
+ declare function defineMcp(options: McpOptions): McpBuilder;
1769
+
1770
+ type TableHandler<T = Record<string, unknown>> = TableHandler$1<T, any>;
1771
+ type FifoQueueHandler<T = unknown> = FifoQueueHandler$1<T, any>;
1772
+ type BucketHandler<Entities extends Record<string, any> = {}> = BucketHandler$1<any, Entities>;
1773
+ type CronHandler = CronHandler$1<any>;
1774
+ type WorkerHandler<T = any> = WorkerHandler$1<T, any>;
1775
+ type McpHandler = McpHandler$1<any>;
1776
+
1777
+ export { type ApiAuthConfig, type ApiConfig, type ApiHandler, type ApiRoutes, type AppConfig, type AppHandler, type AuthHelpers, type BucketClient, type BucketClientWithEntities, type BucketConfig, type BucketEntityConfig, type BucketEvent, type BucketHandler, type BucketRouteConfig, type CacheOptions, type CdnPolicyOptions, type ConfigHelpers, type ContentType, type CronConfig, type CronHandler, type DefineSecretFn, type Duration, type EffortlessConfig, type EmailClient, type FifoQueueConfig, type FifoQueueHandler, type FifoQueueMessage, type HttpMethod$1 as HttpMethod, type HttpRequest, type HttpResponse, type LogLevel, type MailerConfig, type MailerHandler, type McpConfig, type McpHandler, type McpInputSchema, 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 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, defineFifoQueue, defineMailer, defineMcp, defineSecret, defineStaticSite, defineTable, defineWorker, generateBase64, generateHex, generateUuid, isBucketRoute, param, secret, toSeconds };