effortless-aws 0.30.0 → 0.31.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
@@ -1,17 +1,7 @@
1
1
  /**
2
2
  * Configuration for an Effortless project.
3
3
  *
4
- * @example
5
- * ```typescript
6
- * // effortless.config.ts
7
- * import { defineConfig } from "effortless-aws";
8
- *
9
- * export default defineConfig({
10
- * name: "my-service",
11
- * region: "eu-central-1",
12
- * handlers: "src",
13
- * });
14
- * ```
4
+ * @see {@link https://effortless-aws.website/configuration | Configuration guide}
15
5
  */
16
6
  type EffortlessConfig = {
17
7
  /**
@@ -78,21 +68,7 @@ type EffortlessConfig = {
78
68
  runtime?: string;
79
69
  };
80
70
  };
81
- /**
82
- * Helper function for type-safe configuration.
83
- * Returns the config object as-is, but provides TypeScript autocompletion.
84
- *
85
- * @example
86
- * ```typescript
87
- * import { defineConfig } from "effortless-aws";
88
- *
89
- * export default defineConfig({
90
- * name: "my-service",
91
- * region: "eu-central-1",
92
- * handlers: "src",
93
- * });
94
- * ```
95
- */
71
+ /** Helper function for type-safe configuration with TypeScript autocompletion. */
96
72
  declare const defineConfig: (config: EffortlessConfig) => EffortlessConfig;
97
73
 
98
74
  /** Generator spec for auto-creating secrets at deploy time. */
@@ -136,6 +112,20 @@ type LambdaWithPermissions = LambdaConfig & {
136
112
  /** Additional IAM permissions for the Lambda */
137
113
  permissions?: Permission[];
138
114
  };
115
+ /**
116
+ * Lambda configuration passed as argument to `.setup()`.
117
+ * Common across all handler types that create a Lambda function.
118
+ */
119
+ type LambdaOptions = {
120
+ /** Lambda memory in MB (default: 256) */
121
+ memory?: number;
122
+ /** Lambda timeout (default: 30s). Accepts seconds or duration string: `"30s"`, `"5m"` */
123
+ timeout?: Duration;
124
+ /** Additional IAM permissions for the Lambda */
125
+ permissions?: Permission[];
126
+ /** Logging verbosity: "error" (errors only), "info" (+ execution summary), "debug" (+ input/output). Default: "info" */
127
+ logLevel?: LogLevel;
128
+ };
139
129
  type AnySecretRef = SecretRef<any>;
140
130
  /**
141
131
  * Reference to an SSM Parameter Store secret.
@@ -236,22 +226,6 @@ type PutInput<T> = {
236
226
  data: T;
237
227
  ttl?: number;
238
228
  };
239
- /**
240
- * Create a schema function that casts input to T without runtime validation.
241
- * Use when you need T inference alongside other generics (deps, config).
242
- * For handlers without deps/config, prefer `defineTable<Order>({...})`.
243
- * For untrusted input, prefer a real parser (Zod, Effect Schema).
244
- *
245
- * @example
246
- * ```typescript
247
- * export const orders = defineTable({
248
- * schema: unsafeAs<Order>(),
249
- * deps: () => ({ notifications }),
250
- * onRecord: async ({ record, deps }) => { ... }
251
- * });
252
- * ```
253
- */
254
- declare function unsafeAs<T>(): (input: unknown) => T;
255
229
 
256
230
  /** HTTP methods supported by Lambda Function URLs */
257
231
  type HttpMethod$1 = "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "ANY";
@@ -387,9 +361,9 @@ type BucketEvent = {
387
361
  bucketName: string;
388
362
  };
389
363
  /** Spread ctx into callback args (empty when no setup) */
390
- type SpreadCtx$3<C> = [C] extends [undefined] ? {} : C & {};
364
+ type SpreadCtx$4<C> = [C] extends [undefined] ? {} : C & {};
391
365
  /** Setup factory — receives bucket/deps/config/files based on what was declared */
392
- type SetupArgs$3<D, P, HasFiles extends boolean> = {
366
+ type SetupArgs$4<D, P, HasFiles extends boolean> = {
393
367
  bucket: BucketClient;
394
368
  } & ([D] extends [undefined] ? {} : {
395
369
  deps: ResolveDeps<D>;
@@ -403,13 +377,13 @@ type SetupArgs$3<D, P, HasFiles extends boolean> = {
403
377
  */
404
378
  type BucketObjectCreatedFn<C = undefined> = (args: {
405
379
  event: BucketEvent;
406
- } & SpreadCtx$3<C>) => Promise<void>;
380
+ } & SpreadCtx$4<C>) => Promise<void>;
407
381
  /**
408
382
  * Callback function type for S3 ObjectRemoved events
409
383
  */
410
384
  type BucketObjectRemovedFn<C = undefined> = (args: {
411
385
  event: BucketEvent;
412
- } & SpreadCtx$3<C>) => Promise<void>;
386
+ } & SpreadCtx$4<C>) => Promise<void>;
413
387
  /**
414
388
  * Internal handler object created by defineBucket
415
389
  * @internal
@@ -428,34 +402,30 @@ type BucketHandler<C = any> = {
428
402
  };
429
403
  /** Options passed to `defineBucket()` — static config */
430
404
  type BucketOptions = {
431
- /** Lambda memory in MB (default: 256) */
432
- memory?: number;
433
- /** Lambda timeout (default: 30s) */
434
- timeout?: Duration;
435
- /** Additional IAM permissions for the Lambda */
436
- permissions?: Permission[];
437
- /** Logging verbosity */
438
- logLevel?: LogLevel;
439
405
  /** S3 key prefix filter for event notifications (e.g., "uploads/") */
440
406
  prefix?: string;
441
407
  /** S3 key suffix filter for event notifications (e.g., ".jpg") */
442
408
  suffix?: string;
443
- /** Static file glob patterns to bundle into the Lambda ZIP */
444
- static?: string[];
445
409
  };
446
410
  interface BucketBuilder<D = undefined, P = undefined, C = undefined, HasFiles extends boolean = false> {
447
411
  /** Declare handler dependencies */
448
412
  deps<D2 extends Record<string, AnyDepHandler>>(fn: () => D2): BucketBuilder<D2, P, C, HasFiles>;
449
413
  /** Declare SSM secrets */
450
414
  config<P2 extends Record<string, AnySecretRef>>(fn: ConfigFactory<P2>): BucketBuilder<D, P2, C, HasFiles>;
415
+ /** Include static files in the Lambda ZIP */
416
+ include(glob: string): BucketBuilder<D, P, C, true>;
417
+ /** Initialize shared state on cold start with lambda options */
418
+ setup(lambda: LambdaOptions): BucketBuilder<D, P, C, HasFiles>;
451
419
  /** Initialize shared state on cold start. Receives bucket (self-client), deps, config, files. */
452
- setup<C2>(fn: (args: SetupArgs$3<D, P, HasFiles>) => C2 | Promise<C2>): BucketBuilder<D, P, C2, HasFiles>;
420
+ setup<C2>(fn: (args: SetupArgs$4<D, P, HasFiles>) => C2 | Promise<C2>): BucketBuilder<D, P, C2, HasFiles>;
421
+ /** Initialize shared state on cold start with lambda options. Receives bucket (self-client), deps, config, files. */
422
+ setup<C2>(fn: (args: SetupArgs$4<D, P, HasFiles>) => C2 | Promise<C2>, lambda: LambdaOptions): BucketBuilder<D, P, C2, HasFiles>;
453
423
  /** Handle errors thrown by callbacks */
454
424
  onError(fn: (args: {
455
425
  error: unknown;
456
- } & SpreadCtx$3<C>) => void): BucketBuilder<D, P, C, HasFiles>;
426
+ } & SpreadCtx$4<C>) => void): BucketBuilder<D, P, C, HasFiles>;
457
427
  /** Cleanup callback — runs after each invocation, before Lambda freezes */
458
- onCleanup(fn: (args: SpreadCtx$3<C>) => void | Promise<void>): BucketBuilder<D, P, C, HasFiles>;
428
+ onCleanup(fn: (args: SpreadCtx$4<C>) => void | Promise<void>): BucketBuilder<D, P, C, HasFiles>;
459
429
  /** Handle S3 ObjectCreated events (terminal — returns finalized handler) */
460
430
  onObjectCreated(fn: BucketObjectCreatedFn<C>): BucketHandler<C>;
461
431
  /** Handle S3 ObjectRemoved events (terminal — returns finalized handler) */
@@ -466,24 +436,17 @@ interface BucketBuilder<D = undefined, P = undefined, C = undefined, HasFiles ex
466
436
  /**
467
437
  * Define an S3 bucket with optional event handlers.
468
438
  *
469
- * @example Bucket with event handler
439
+ * @see {@link https://effortless-aws.website/use-cases/storage | Storage guide}
440
+ *
441
+ * @example
470
442
  * ```typescript
471
443
  * export const uploads = defineBucket({ prefix: "images/", suffix: ".jpg" })
472
444
  * .onObjectCreated(async ({ event, bucket }) => {
473
445
  * console.log("New upload:", event.key);
474
446
  * })
475
- *
476
- * ```
477
- *
478
- * @example Resource-only bucket (no Lambda)
479
- * ```typescript
480
- * export const assets = defineBucket().build()
481
447
  * ```
482
448
  */
483
449
  declare function defineBucket(): BucketBuilder;
484
- declare function defineBucket(options: BucketOptions & {
485
- static: string[];
486
- }): BucketBuilder<undefined, undefined, undefined, true>;
487
450
  declare function defineBucket(options: BucketOptions): BucketBuilder;
488
451
 
489
452
  /**
@@ -510,6 +473,8 @@ type MailerHandler = {
510
473
  * On first deploy, DKIM DNS records are printed to the console.
511
474
  * Add them to your DNS provider to verify the domain.
512
475
  *
476
+ * @see {@link https://effortless-aws.website/use-cases/email | Email guide}
477
+ *
513
478
  * @param options - Mailer configuration with the domain to send from
514
479
  * @returns Handler object used by the deployment system and as a `deps` value
515
480
  *
@@ -591,9 +556,9 @@ type FifoQueueConfig = {
591
556
  maxReceiveCount?: number;
592
557
  };
593
558
  /** Spread ctx into callback args (empty when no setup) */
594
- type SpreadCtx$2<C> = [C] extends [undefined] ? {} : C & {};
559
+ type SpreadCtx$3<C> = [C] extends [undefined] ? {} : C & {};
595
560
  /** Setup factory — receives deps/config/files based on what was declared */
596
- type SetupArgs$2<D, P, HasFiles extends boolean> = ([D] extends [undefined] ? {} : {
561
+ type SetupArgs$3<D, P, HasFiles extends boolean> = ([D] extends [undefined] ? {} : {
597
562
  deps: ResolveDeps<D>;
598
563
  }) & ([P] extends [undefined] ? {} : {
599
564
  config: ResolveConfig<P & {}>;
@@ -606,7 +571,7 @@ type SetupArgs$2<D, P, HasFiles extends boolean> = ([D] extends [undefined] ? {}
606
571
  */
607
572
  type FifoQueueMessageFn<T = unknown, C = undefined> = (args: {
608
573
  message: FifoQueueMessage<T>;
609
- } & SpreadCtx$2<C>) => Promise<void>;
574
+ } & SpreadCtx$3<C>) => Promise<void>;
610
575
  /**
611
576
  * Batch handler function.
612
577
  * Called once with all messages in the batch.
@@ -614,7 +579,7 @@ type FifoQueueMessageFn<T = unknown, C = undefined> = (args: {
614
579
  */
615
580
  type FifoQueueBatchFn<T = unknown, C = undefined> = (args: {
616
581
  messages: FifoQueueMessage<T>[];
617
- } & SpreadCtx$2<C>) => Promise<void | {
582
+ } & SpreadCtx$3<C>) => Promise<void | {
618
583
  failures: string[];
619
584
  }>;
620
585
  /**
@@ -636,14 +601,6 @@ type FifoQueueHandler<T = unknown, C = any> = {
636
601
  };
637
602
  /** Options passed to `defineFifoQueue()` — static config */
638
603
  type FifoQueueOptions<T> = {
639
- /** Lambda memory in MB (default: 256) */
640
- memory?: number;
641
- /** Lambda timeout (default: 30s) */
642
- timeout?: Duration;
643
- /** Additional IAM permissions for the Lambda */
644
- permissions?: Permission[];
645
- /** Logging verbosity */
646
- logLevel?: LogLevel;
647
604
  /** Number of messages per Lambda invocation (1-10 for FIFO, default: 10) */
648
605
  batchSize?: number;
649
606
  /** Maximum time to gather messages before invoking (default: 0) */
@@ -660,22 +617,26 @@ type FifoQueueOptions<T> = {
660
617
  maxReceiveCount?: number;
661
618
  /** Decode/validate function for the message body */
662
619
  schema?: (input: unknown) => T;
663
- /** Static file glob patterns to bundle into the Lambda ZIP */
664
- static?: string[];
665
620
  };
666
621
  interface FifoQueueBuilder<T = unknown, D = undefined, P = undefined, C = undefined, HasFiles extends boolean = false> {
667
622
  /** Declare handler dependencies */
668
623
  deps<D2 extends Record<string, AnyDepHandler>>(fn: () => D2): FifoQueueBuilder<T, D2, P, C, HasFiles>;
669
624
  /** Declare SSM secrets */
670
625
  config<P2 extends Record<string, AnySecretRef>>(fn: ConfigFactory<P2>): FifoQueueBuilder<T, D, P2, C, HasFiles>;
626
+ /** Include static files in the Lambda bundle. Chainable — call multiple times. */
627
+ include(glob: string): FifoQueueBuilder<T, D, P, C, true>;
628
+ /** Configure Lambda settings only (memory, timeout, permissions, etc.) */
629
+ setup(lambda: LambdaOptions): FifoQueueBuilder<T, D, P, C, HasFiles>;
671
630
  /** Initialize shared state on cold start. Receives deps, config, files. */
672
- setup<C2>(fn: (args: SetupArgs$2<D, P, HasFiles>) => C2 | Promise<C2>): FifoQueueBuilder<T, D, P, C2, HasFiles>;
631
+ setup<C2>(fn: (args: SetupArgs$3<D, P, HasFiles>) => C2 | Promise<C2>): FifoQueueBuilder<T, D, P, C2, HasFiles>;
632
+ /** Initialize shared state on cold start + configure Lambda settings. */
633
+ setup<C2>(fn: (args: SetupArgs$3<D, P, HasFiles>) => C2 | Promise<C2>, lambda: LambdaOptions): FifoQueueBuilder<T, D, P, C2, HasFiles>;
673
634
  /** Handle errors thrown by message handlers */
674
635
  onError(fn: (args: {
675
636
  error: unknown;
676
- } & SpreadCtx$2<C>) => void): FifoQueueBuilder<T, D, P, C, HasFiles>;
637
+ } & SpreadCtx$3<C>) => void): FifoQueueBuilder<T, D, P, C, HasFiles>;
677
638
  /** Cleanup callback — runs after each invocation, before Lambda freezes */
678
- onCleanup(fn: (args: SpreadCtx$2<C>) => void | Promise<void>): FifoQueueBuilder<T, D, P, C, HasFiles>;
639
+ onCleanup(fn: (args: SpreadCtx$3<C>) => void | Promise<void>): FifoQueueBuilder<T, D, P, C, HasFiles>;
679
640
  /** Per-message handler (terminal — returns finalized handler) */
680
641
  onMessage(fn: FifoQueueMessageFn<T, C>): FifoQueueHandler<T, C>;
681
642
  /** Batch handler (terminal — returns finalized handler) */
@@ -684,28 +645,17 @@ interface FifoQueueBuilder<T = unknown, D = undefined, P = undefined, C = undefi
684
645
  /**
685
646
  * Define a FIFO SQS queue with a Lambda message handler.
686
647
  *
687
- * @example Per-message processing
688
- * ```typescript
689
- * export const orderQueue = defineFifoQueue<OrderEvent>()
690
- * .onMessage(async ({ message }) => {
691
- * console.log("Processing order:", message.body.orderId);
692
- * })
693
- *
694
- * ```
648
+ * @see {@link https://effortless-aws.website/use-cases/queue | Queue guide}
695
649
  *
696
- * @example Batch processing with schema
650
+ * @example
697
651
  * ```typescript
698
652
  * export const notifications = defineFifoQueue({ batchSize: 5, schema: (i) => NotifSchema.parse(i) })
699
653
  * .onMessageBatch(async ({ messages }) => {
700
654
  * await sendAll(messages.map(m => m.body));
701
655
  * })
702
- *
703
656
  * ```
704
657
  */
705
658
  declare function defineFifoQueue<T = unknown>(): FifoQueueBuilder<T>;
706
- declare function defineFifoQueue<T = unknown>(options: FifoQueueOptions<T> & {
707
- static: string[];
708
- }): FifoQueueBuilder<T, undefined, undefined, undefined, true>;
709
659
  declare function defineFifoQueue<T = unknown>(options: FifoQueueOptions<T>): FifoQueueBuilder<T>;
710
660
 
711
661
  /**
@@ -939,7 +889,7 @@ type TableRecord<T = Record<string, unknown>> = {
939
889
  timestamp?: number;
940
890
  };
941
891
  /** Setup factory — receives table/deps/config/files based on what was declared */
942
- type SetupArgs$1<T, D, P, HasFiles extends boolean> = {
892
+ type SetupArgs$2<T, D, P, HasFiles extends boolean> = {
943
893
  table: TableClient<T>;
944
894
  } & ([D] extends [undefined] ? {} : {
945
895
  deps: ResolveDeps<D>;
@@ -949,7 +899,7 @@ type SetupArgs$1<T, D, P, HasFiles extends boolean> = {
949
899
  files: StaticFiles;
950
900
  } : {});
951
901
  /** Spread ctx into callback args (empty when no setup) */
952
- type SpreadCtx$1<C> = [C] extends [undefined] ? {} : C & {};
902
+ type SpreadCtx$2<C> = [C] extends [undefined] ? {} : C & {};
953
903
  /**
954
904
  * Callback function type for processing a single DynamoDB stream record.
955
905
  * Receives the current record and the full batch for context.
@@ -957,7 +907,7 @@ type SpreadCtx$1<C> = [C] extends [undefined] ? {} : C & {};
957
907
  type TableRecordFn<T = Record<string, unknown>, C = undefined> = (args: {
958
908
  record: TableRecord<T>;
959
909
  batch: readonly TableRecord<T>[];
960
- } & SpreadCtx$1<C>) => Promise<void>;
910
+ } & SpreadCtx$2<C>) => Promise<void>;
961
911
  /**
962
912
  * Batch handler function for DynamoDB stream records.
963
913
  * Called once with all records in the batch.
@@ -965,7 +915,7 @@ type TableRecordFn<T = Record<string, unknown>, C = undefined> = (args: {
965
915
  */
966
916
  type TableBatchFn<T = Record<string, unknown>, C = undefined> = (args: {
967
917
  records: readonly TableRecord<T>[];
968
- } & SpreadCtx$1<C>) => Promise<void | {
918
+ } & SpreadCtx$2<C>) => Promise<void | {
969
919
  failures: string[];
970
920
  }>;
971
921
  /** Static config extracted by AST (no runtime callbacks) */
@@ -987,16 +937,8 @@ type TableHandler<T = Record<string, unknown>, C = any> = {
987
937
  readonly onRecord?: (...args: any[]) => any;
988
938
  readonly onRecordBatch?: (...args: any[]) => any;
989
939
  };
990
- /** Options passed to `defineTable()` — static config, no generics needed for inference */
940
+ /** Options passed to `defineTable()` — resource config only, no Lambda settings */
991
941
  type TableOptions<T> = {
992
- /** Lambda memory in MB (default: 256) */
993
- memory?: number;
994
- /** Lambda timeout (default: 30s). Accepts seconds or duration string: `"30s"`, `"5m"` */
995
- timeout?: Duration;
996
- /** Additional IAM permissions for the Lambda */
997
- permissions?: Permission[];
998
- /** Logging verbosity */
999
- logLevel?: LogLevel;
1000
942
  /** DynamoDB billing mode (default: "PAY_PER_REQUEST") */
1001
943
  billingMode?: "PAY_PER_REQUEST" | "PROVISIONED";
1002
944
  /** Stream view type (default: "NEW_AND_OLD_IMAGES") */
@@ -1013,22 +955,26 @@ type TableOptions<T> = {
1013
955
  tagField?: Extract<keyof T, string>;
1014
956
  /** Decode/validate function for the `data` portion of stream records */
1015
957
  schema?: (input: unknown) => T;
1016
- /** Static file glob patterns to bundle into the Lambda ZIP */
1017
- static?: string[];
1018
958
  };
1019
959
  interface TableBuilder<T = Record<string, unknown>, D = undefined, P = undefined, C = undefined, HasFiles extends boolean = false> {
1020
960
  /** Declare handler dependencies (tables, queues, buckets, mailers) */
1021
961
  deps<D2 extends Record<string, AnyDepHandler>>(fn: () => D2): TableBuilder<T, D2, P, C, HasFiles>;
1022
962
  /** Declare SSM secrets */
1023
963
  config<P2 extends Record<string, AnySecretRef>>(fn: ConfigFactory<P2>): TableBuilder<T, D, P2, C, HasFiles>;
964
+ /** Include static files in the Lambda bundle. Chainable — call multiple times. */
965
+ include(glob: string): TableBuilder<T, D, P, C, true>;
966
+ /** Configure Lambda settings only (memory, timeout, permissions, etc.) */
967
+ setup(lambda: LambdaOptions): TableBuilder<T, D, P, C, HasFiles>;
1024
968
  /** Initialize shared state on cold start. Receives table (self-client), deps, config, files. */
1025
- setup<C2>(fn: (args: SetupArgs$1<T, D, P, HasFiles>) => C2 | Promise<C2>): TableBuilder<T, D, P, C2, HasFiles>;
969
+ setup<C2>(fn: (args: SetupArgs$2<T, D, P, HasFiles>) => C2 | Promise<C2>): TableBuilder<T, D, P, C2, HasFiles>;
970
+ /** Initialize shared state on cold start + configure Lambda settings. */
971
+ setup<C2>(fn: (args: SetupArgs$2<T, D, P, HasFiles>) => C2 | Promise<C2>, lambda: LambdaOptions): TableBuilder<T, D, P, C2, HasFiles>;
1026
972
  /** Handle errors thrown by onRecord/onRecordBatch */
1027
973
  onError(fn: (args: {
1028
974
  error: unknown;
1029
- } & SpreadCtx$1<C>) => void): TableBuilder<T, D, P, C, HasFiles>;
975
+ } & SpreadCtx$2<C>) => void): TableBuilder<T, D, P, C, HasFiles>;
1030
976
  /** Cleanup callback — runs after each invocation, before Lambda freezes */
1031
- onCleanup(fn: (args: SpreadCtx$1<C>) => void | Promise<void>): TableBuilder<T, D, P, C, HasFiles>;
977
+ onCleanup(fn: (args: SpreadCtx$2<C>) => void | Promise<void>): TableBuilder<T, D, P, C, HasFiles>;
1032
978
  /** Per-record stream handler (terminal — returns finalized handler) */
1033
979
  onRecord(fn: TableRecordFn<T, C>): TableHandler<T, C>;
1034
980
  /** Batch stream handler (terminal — returns finalized handler) */
@@ -1042,7 +988,9 @@ interface TableBuilder<T = Record<string, unknown>, D = undefined, P = undefined
1042
988
  * Creates a table with fixed key schema: `pk (S)` + `sk (S)`, plus `tag (S)`,
1043
989
  * `data (M)`, and `ttl (N)` attributes. TTL is always enabled.
1044
990
  *
1045
- * @example Table with stream handler
991
+ * @see {@link https://effortless-aws.website/use-cases/database | Database guide}
992
+ *
993
+ * @example
1046
994
  * ```typescript
1047
995
  * export const orders = defineTable<OrderData>({ batchSize: 10, concurrency: 5 })
1048
996
  * .setup(({ table }) => ({ table }))
@@ -1052,21 +1000,8 @@ interface TableBuilder<T = Record<string, unknown>, D = undefined, P = undefined
1052
1000
  * }
1053
1001
  * })
1054
1002
  * ```
1055
- *
1056
- * @example Table only (no Lambda)
1057
- * ```typescript
1058
- * export const users = defineTable<User>().build()
1059
- * ```
1060
- *
1061
- * @example Table as dependency (resource-only, no Lambda)
1062
- * ```typescript
1063
- * export const sessions = defineTable<Session>().build()
1064
- * ```
1065
1003
  */
1066
1004
  declare function defineTable<T = Record<string, unknown>>(): TableBuilder<T>;
1067
- declare function defineTable<T = Record<string, unknown>>(options: TableOptions<T> & {
1068
- static: string[];
1069
- }): TableBuilder<T, undefined, undefined, undefined, true>;
1070
1005
  declare function defineTable<T = Record<string, unknown>>(options: TableOptions<T>): TableBuilder<T>;
1071
1006
 
1072
1007
  /**
@@ -1111,18 +1046,10 @@ type AppHandler = {
1111
1046
  *
1112
1047
  * For static-only sites (no SSR), use {@link defineStaticSite} instead.
1113
1048
  *
1049
+ * @see {@link https://effortless-aws.website/use-cases/web-app | Web app guide}
1050
+ *
1114
1051
  * @param options - App configuration: server directory, assets directory, optional build command
1115
1052
  * @returns Handler object used by the deployment system
1116
- *
1117
- * @example Nuxt SSR
1118
- * ```typescript
1119
- * export const app = defineApp({
1120
- * build: "nuxt build",
1121
- * server: ".output/server",
1122
- * assets: ".output/public",
1123
- * lambda: { memory: 1024 },
1124
- * });
1125
- * ```
1126
1053
  */
1127
1054
  declare const defineApp: () => (options: AppConfig) => AppHandler;
1128
1055
 
@@ -1199,26 +1126,10 @@ type StaticSiteHandler = {
1199
1126
  /**
1200
1127
  * Deploy a static site via S3 + CloudFront CDN.
1201
1128
  *
1129
+ * @see {@link https://effortless-aws.website/use-cases/web-app | Web app guide}
1130
+ *
1202
1131
  * @param options - Static site configuration: directory, optional SPA mode, build command
1203
1132
  * @returns Handler object used by the deployment system
1204
- *
1205
- * @example Documentation site
1206
- * ```typescript
1207
- * export const docs = defineStaticSite({
1208
- * dir: "dist",
1209
- * build: "npx astro build",
1210
- * });
1211
- * ```
1212
- *
1213
- * @example SPA with client-side routing
1214
- * ```typescript
1215
- * export const app = defineStaticSite({
1216
- * dir: "dist",
1217
- * spa: true,
1218
- * build: "npm run build",
1219
- * });
1220
- * ```
1221
- *
1222
1133
  */
1223
1134
  declare const defineStaticSite: () => (options: StaticSiteConfig) => StaticSiteHandler;
1224
1135
 
@@ -1294,11 +1205,11 @@ type RouteEntry = {
1294
1205
  public?: boolean;
1295
1206
  };
1296
1207
  /** Spread ctx into route args: Omit auth config, add AuthHelpers if present */
1297
- type SpreadCtx<C> = ([C] extends [undefined] ? {} : Omit<C & {}, 'auth'>) & ([ExtractAuth<C>] extends [undefined] ? {} : {
1208
+ type SpreadCtx$1<C> = ([C] extends [undefined] ? {} : Omit<C & {}, 'auth'>) & ([ExtractAuth<C>] extends [undefined] ? {} : {
1298
1209
  auth: AuthHelpers<ExtractAuth<C>>;
1299
1210
  });
1300
1211
  /** Callback args available inside each route — ctx is spread into args */
1301
- type RouteArgs<C, ST> = SpreadCtx<C> & {
1212
+ type RouteArgs<C, ST> = SpreadCtx$1<C> & {
1302
1213
  req: HttpRequest;
1303
1214
  input: unknown;
1304
1215
  ok: OkHelper;
@@ -1313,7 +1224,7 @@ type RouteOptions = {
1313
1224
  public?: boolean;
1314
1225
  };
1315
1226
  /** Setup factory — receives deps/config/files/enableAuth based on what was declared */
1316
- type SetupArgs<D, P, HasFiles extends boolean> = {
1227
+ type SetupArgs$1<D, P, HasFiles extends boolean> = {
1317
1228
  enableAuth: EnableAuth;
1318
1229
  ok: OkHelper;
1319
1230
  fail: FailHelper;
@@ -1353,18 +1264,8 @@ type ApiHandler<C = undefined> = {
1353
1264
  type ApiOptions = {
1354
1265
  /** Base path prefix for all routes (e.g., "/api") */
1355
1266
  basePath: `/${string}`;
1356
- /** Lambda memory in MB (default: 256) */
1357
- memory?: number;
1358
- /** Lambda timeout (default: 30s). Accepts seconds or duration string: `"30s"`, `"5m"` */
1359
- timeout?: Duration;
1360
- /** Additional IAM permissions for the Lambda */
1361
- permissions?: Permission[];
1362
- /** Logging verbosity: "error" (errors only), "info" (+ execution summary), "debug" (+ input/output). Default: "info" */
1363
- logLevel?: LogLevel;
1364
1267
  /** Enable response streaming. When true, routes receive a `stream` arg for SSE. */
1365
1268
  stream?: boolean;
1366
- /** Static file glob patterns to bundle into the Lambda ZIP */
1367
- static?: string[];
1368
1269
  };
1369
1270
  /**
1370
1271
  * Finalized API handler with route-adding methods.
@@ -1388,17 +1289,23 @@ interface ApiBuilder<D = undefined, P = undefined, C = undefined, ST extends boo
1388
1289
  deps<D2 extends Record<string, AnyDepHandler>>(fn: () => D2): ApiBuilder<D2, P, C, ST, HasFiles>;
1389
1290
  /** Declare SSM secrets */
1390
1291
  config<P2 extends Record<string, AnySecretRef>>(fn: ConfigFactory<P2>): ApiBuilder<D, P2, C, ST, HasFiles>;
1292
+ /** Include static files by glob pattern */
1293
+ include(glob: string): ApiBuilder<D, P, C, ST, true>;
1294
+ /** Configure Lambda settings only (no init function) */
1295
+ setup(lambda: LambdaOptions): ApiBuilder<D, P, C, ST, HasFiles>;
1391
1296
  /** Initialize shared state on cold start. Receives deps/config/files based on what was declared. */
1392
- setup<C2>(fn: (args: SetupArgs<D, P, HasFiles>) => ValidateSetupReturn<C2> | Promise<ValidateSetupReturn<C2>>): ApiBuilder<D, P, C2, ST, HasFiles>;
1297
+ setup<C2>(fn: (args: SetupArgs$1<D, P, HasFiles>) => ValidateSetupReturn<C2> | Promise<ValidateSetupReturn<C2>>): ApiBuilder<D, P, C2, ST, HasFiles>;
1298
+ /** Initialize shared state on cold start with Lambda config. */
1299
+ setup<C2>(fn: (args: SetupArgs$1<D, P, HasFiles>) => ValidateSetupReturn<C2> | Promise<ValidateSetupReturn<C2>>, lambda: LambdaOptions): ApiBuilder<D, P, C2, ST, HasFiles>;
1393
1300
  /** Handle errors thrown by routes */
1394
1301
  onError(fn: (args: {
1395
1302
  error: unknown;
1396
1303
  req: HttpRequest;
1397
1304
  ok: OkHelper;
1398
1305
  fail: FailHelper;
1399
- } & SpreadCtx<C>) => HttpResponse): ApiBuilder<D, P, C, ST, HasFiles>;
1306
+ } & SpreadCtx$1<C>) => HttpResponse): ApiBuilder<D, P, C, ST, HasFiles>;
1400
1307
  /** Cleanup callback — runs after each invocation, before Lambda freezes */
1401
- onCleanup(fn: (args: SpreadCtx<C>) => void | Promise<void>): ApiBuilder<D, P, C, ST, HasFiles>;
1308
+ onCleanup(fn: (args: SpreadCtx$1<C>) => void | Promise<void>): ApiBuilder<D, P, C, ST, HasFiles>;
1402
1309
  /** Add a GET route (terminal — returns finalized handler with route methods) */
1403
1310
  get(path: `/${string}`, handler: RouteHandler<C, ST>, options?: RouteOptions): ApiRoutes<C, ST>;
1404
1311
  /** Add a POST route (terminal) */
@@ -1413,13 +1320,10 @@ interface ApiBuilder<D = undefined, P = undefined, C = undefined, ST extends boo
1413
1320
  /**
1414
1321
  * Define an API with typed routes using a builder pattern.
1415
1322
  *
1323
+ * @see {@link https://effortless-aws.website/use-cases/http-api | HTTP API guide}
1324
+ *
1416
1325
  * @example
1417
1326
  * ```typescript
1418
- * // Minimal
1419
- * export default defineApi({ basePath: "/hello" })
1420
- * .get("/", async ({ req, ok }) => ok({ message: "Hello!" }))
1421
- *
1422
- * // Full
1423
1327
  * export const api = defineApi({ basePath: "/api", timeout: "30s" })
1424
1328
  * .deps(() => ({ users }))
1425
1329
  * .config(({ defineSecret }) => ({ dbUrl: defineSecret() }))
@@ -1432,9 +1336,124 @@ interface ApiBuilder<D = undefined, P = undefined, C = undefined, ST extends boo
1432
1336
  * .post("/login", async ({ auth, ok }) => ok(await auth.createSession()), { public: true })
1433
1337
  * ```
1434
1338
  */
1435
- declare function defineApi(options: ApiOptions & {
1436
- static: string[];
1437
- }): ApiBuilder<undefined, undefined, undefined, false, true>;
1438
- declare function defineApi<const O extends ApiOptions>(options: O): ApiBuilder<undefined, undefined, undefined, O["stream"] extends true ? true : false, O["static"] extends string[] ? true : false>;
1339
+ declare function defineApi<const O extends ApiOptions>(options: O): ApiBuilder<undefined, undefined, undefined, O["stream"] extends true ? true : false, false>;
1340
+
1341
+ /**
1342
+ * All IANA time zones.
1343
+ * Generated from Intl.supportedValuesOf("timeZone") on Node.js 22.
1344
+ */
1345
+ type Timezone = "UTC" | "Africa/Abidjan" | "Africa/Accra" | "Africa/Addis_Ababa" | "Africa/Algiers" | "Africa/Asmera" | "Africa/Bamako" | "Africa/Bangui" | "Africa/Banjul" | "Africa/Bissau" | "Africa/Blantyre" | "Africa/Brazzaville" | "Africa/Bujumbura" | "Africa/Cairo" | "Africa/Casablanca" | "Africa/Ceuta" | "Africa/Conakry" | "Africa/Dakar" | "Africa/Dar_es_Salaam" | "Africa/Djibouti" | "Africa/Douala" | "Africa/El_Aaiun" | "Africa/Freetown" | "Africa/Gaborone" | "Africa/Harare" | "Africa/Johannesburg" | "Africa/Juba" | "Africa/Kampala" | "Africa/Khartoum" | "Africa/Kigali" | "Africa/Kinshasa" | "Africa/Lagos" | "Africa/Libreville" | "Africa/Lome" | "Africa/Luanda" | "Africa/Lubumbashi" | "Africa/Lusaka" | "Africa/Malabo" | "Africa/Maputo" | "Africa/Maseru" | "Africa/Mbabane" | "Africa/Mogadishu" | "Africa/Monrovia" | "Africa/Nairobi" | "Africa/Ndjamena" | "Africa/Niamey" | "Africa/Nouakchott" | "Africa/Ouagadougou" | "Africa/Porto-Novo" | "Africa/Sao_Tome" | "Africa/Tripoli" | "Africa/Tunis" | "Africa/Windhoek" | "America/Adak" | "America/Anchorage" | "America/Anguilla" | "America/Antigua" | "America/Araguaina" | "America/Argentina/La_Rioja" | "America/Argentina/Rio_Gallegos" | "America/Argentina/Salta" | "America/Argentina/San_Juan" | "America/Argentina/San_Luis" | "America/Argentina/Tucuman" | "America/Argentina/Ushuaia" | "America/Aruba" | "America/Asuncion" | "America/Bahia" | "America/Bahia_Banderas" | "America/Barbados" | "America/Belem" | "America/Belize" | "America/Blanc-Sablon" | "America/Boa_Vista" | "America/Bogota" | "America/Boise" | "America/Buenos_Aires" | "America/Cambridge_Bay" | "America/Campo_Grande" | "America/Cancun" | "America/Caracas" | "America/Catamarca" | "America/Cayenne" | "America/Cayman" | "America/Chicago" | "America/Chihuahua" | "America/Ciudad_Juarez" | "America/Coral_Harbour" | "America/Cordoba" | "America/Costa_Rica" | "America/Coyhaique" | "America/Creston" | "America/Cuiaba" | "America/Curacao" | "America/Danmarkshavn" | "America/Dawson" | "America/Dawson_Creek" | "America/Denver" | "America/Detroit" | "America/Dominica" | "America/Edmonton" | "America/Eirunepe" | "America/El_Salvador" | "America/Fort_Nelson" | "America/Fortaleza" | "America/Glace_Bay" | "America/Godthab" | "America/Goose_Bay" | "America/Grand_Turk" | "America/Grenada" | "America/Guadeloupe" | "America/Guatemala" | "America/Guayaquil" | "America/Guyana" | "America/Halifax" | "America/Havana" | "America/Hermosillo" | "America/Indiana/Knox" | "America/Indiana/Marengo" | "America/Indiana/Petersburg" | "America/Indiana/Tell_City" | "America/Indiana/Vevay" | "America/Indiana/Vincennes" | "America/Indiana/Winamac" | "America/Indianapolis" | "America/Inuvik" | "America/Iqaluit" | "America/Jamaica" | "America/Jujuy" | "America/Juneau" | "America/Kentucky/Monticello" | "America/Kralendijk" | "America/La_Paz" | "America/Lima" | "America/Los_Angeles" | "America/Louisville" | "America/Lower_Princes" | "America/Maceio" | "America/Managua" | "America/Manaus" | "America/Marigot" | "America/Martinique" | "America/Matamoros" | "America/Mazatlan" | "America/Mendoza" | "America/Menominee" | "America/Merida" | "America/Metlakatla" | "America/Mexico_City" | "America/Miquelon" | "America/Moncton" | "America/Monterrey" | "America/Montevideo" | "America/Montserrat" | "America/Nassau" | "America/New_York" | "America/Nome" | "America/Noronha" | "America/North_Dakota/Beulah" | "America/North_Dakota/Center" | "America/North_Dakota/New_Salem" | "America/Ojinaga" | "America/Panama" | "America/Paramaribo" | "America/Phoenix" | "America/Port-au-Prince" | "America/Port_of_Spain" | "America/Porto_Velho" | "America/Puerto_Rico" | "America/Punta_Arenas" | "America/Rankin_Inlet" | "America/Recife" | "America/Regina" | "America/Resolute" | "America/Rio_Branco" | "America/Santarem" | "America/Santiago" | "America/Santo_Domingo" | "America/Sao_Paulo" | "America/Scoresbysund" | "America/Sitka" | "America/St_Barthelemy" | "America/St_Johns" | "America/St_Kitts" | "America/St_Lucia" | "America/St_Thomas" | "America/St_Vincent" | "America/Swift_Current" | "America/Tegucigalpa" | "America/Thule" | "America/Tijuana" | "America/Toronto" | "America/Tortola" | "America/Vancouver" | "America/Whitehorse" | "America/Winnipeg" | "America/Yakutat" | "Antarctica/Casey" | "Antarctica/Davis" | "Antarctica/DumontDUrville" | "Antarctica/Macquarie" | "Antarctica/Mawson" | "Antarctica/McMurdo" | "Antarctica/Palmer" | "Antarctica/Rothera" | "Antarctica/Syowa" | "Antarctica/Troll" | "Antarctica/Vostok" | "Arctic/Longyearbyen" | "Asia/Aden" | "Asia/Almaty" | "Asia/Amman" | "Asia/Anadyr" | "Asia/Aqtau" | "Asia/Aqtobe" | "Asia/Ashgabat" | "Asia/Atyrau" | "Asia/Baghdad" | "Asia/Bahrain" | "Asia/Baku" | "Asia/Bangkok" | "Asia/Barnaul" | "Asia/Beirut" | "Asia/Bishkek" | "Asia/Brunei" | "Asia/Calcutta" | "Asia/Chita" | "Asia/Colombo" | "Asia/Damascus" | "Asia/Dhaka" | "Asia/Dili" | "Asia/Dubai" | "Asia/Dushanbe" | "Asia/Famagusta" | "Asia/Gaza" | "Asia/Hebron" | "Asia/Hong_Kong" | "Asia/Hovd" | "Asia/Irkutsk" | "Asia/Jakarta" | "Asia/Jayapura" | "Asia/Jerusalem" | "Asia/Kabul" | "Asia/Kamchatka" | "Asia/Karachi" | "Asia/Katmandu" | "Asia/Khandyga" | "Asia/Krasnoyarsk" | "Asia/Kuala_Lumpur" | "Asia/Kuching" | "Asia/Kuwait" | "Asia/Macau" | "Asia/Magadan" | "Asia/Makassar" | "Asia/Manila" | "Asia/Muscat" | "Asia/Nicosia" | "Asia/Novokuznetsk" | "Asia/Novosibirsk" | "Asia/Omsk" | "Asia/Oral" | "Asia/Phnom_Penh" | "Asia/Pontianak" | "Asia/Pyongyang" | "Asia/Qatar" | "Asia/Qostanay" | "Asia/Qyzylorda" | "Asia/Rangoon" | "Asia/Riyadh" | "Asia/Saigon" | "Asia/Sakhalin" | "Asia/Samarkand" | "Asia/Seoul" | "Asia/Shanghai" | "Asia/Singapore" | "Asia/Srednekolymsk" | "Asia/Taipei" | "Asia/Tashkent" | "Asia/Tbilisi" | "Asia/Tehran" | "Asia/Thimphu" | "Asia/Tokyo" | "Asia/Tomsk" | "Asia/Ulaanbaatar" | "Asia/Urumqi" | "Asia/Ust-Nera" | "Asia/Vientiane" | "Asia/Vladivostok" | "Asia/Yakutsk" | "Asia/Yekaterinburg" | "Asia/Yerevan" | "Atlantic/Azores" | "Atlantic/Bermuda" | "Atlantic/Canary" | "Atlantic/Cape_Verde" | "Atlantic/Faeroe" | "Atlantic/Madeira" | "Atlantic/Reykjavik" | "Atlantic/South_Georgia" | "Atlantic/St_Helena" | "Atlantic/Stanley" | "Australia/Adelaide" | "Australia/Brisbane" | "Australia/Broken_Hill" | "Australia/Darwin" | "Australia/Eucla" | "Australia/Hobart" | "Australia/Lindeman" | "Australia/Lord_Howe" | "Australia/Melbourne" | "Australia/Perth" | "Australia/Sydney" | "Europe/Amsterdam" | "Europe/Andorra" | "Europe/Astrakhan" | "Europe/Athens" | "Europe/Belgrade" | "Europe/Berlin" | "Europe/Bratislava" | "Europe/Brussels" | "Europe/Bucharest" | "Europe/Budapest" | "Europe/Busingen" | "Europe/Chisinau" | "Europe/Copenhagen" | "Europe/Dublin" | "Europe/Gibraltar" | "Europe/Guernsey" | "Europe/Helsinki" | "Europe/Isle_of_Man" | "Europe/Istanbul" | "Europe/Jersey" | "Europe/Kaliningrad" | "Europe/Kiev" | "Europe/Kirov" | "Europe/Lisbon" | "Europe/Ljubljana" | "Europe/London" | "Europe/Luxembourg" | "Europe/Madrid" | "Europe/Malta" | "Europe/Mariehamn" | "Europe/Minsk" | "Europe/Monaco" | "Europe/Moscow" | "Europe/Oslo" | "Europe/Paris" | "Europe/Podgorica" | "Europe/Prague" | "Europe/Riga" | "Europe/Rome" | "Europe/Samara" | "Europe/San_Marino" | "Europe/Sarajevo" | "Europe/Saratov" | "Europe/Simferopol" | "Europe/Skopje" | "Europe/Sofia" | "Europe/Stockholm" | "Europe/Tallinn" | "Europe/Tirane" | "Europe/Ulyanovsk" | "Europe/Vaduz" | "Europe/Vatican" | "Europe/Vienna" | "Europe/Vilnius" | "Europe/Volgograd" | "Europe/Warsaw" | "Europe/Zagreb" | "Europe/Zurich" | "Indian/Antananarivo" | "Indian/Chagos" | "Indian/Christmas" | "Indian/Cocos" | "Indian/Comoro" | "Indian/Kerguelen" | "Indian/Mahe" | "Indian/Maldives" | "Indian/Mauritius" | "Indian/Mayotte" | "Indian/Reunion" | "Pacific/Apia" | "Pacific/Auckland" | "Pacific/Bougainville" | "Pacific/Chatham" | "Pacific/Easter" | "Pacific/Efate" | "Pacific/Enderbury" | "Pacific/Fakaofo" | "Pacific/Fiji" | "Pacific/Funafuti" | "Pacific/Galapagos" | "Pacific/Gambier" | "Pacific/Guadalcanal" | "Pacific/Guam" | "Pacific/Honolulu" | "Pacific/Kiritimati" | "Pacific/Kosrae" | "Pacific/Kwajalein" | "Pacific/Majuro" | "Pacific/Marquesas" | "Pacific/Midway" | "Pacific/Nauru" | "Pacific/Niue" | "Pacific/Norfolk" | "Pacific/Noumea" | "Pacific/Pago_Pago" | "Pacific/Palau" | "Pacific/Pitcairn" | "Pacific/Ponape" | "Pacific/Port_Moresby" | "Pacific/Rarotonga" | "Pacific/Saipan" | "Pacific/Tahiti" | "Pacific/Tarawa" | "Pacific/Tongatapu" | "Pacific/Truk" | "Pacific/Wake" | "Pacific/Wallis";
1346
+
1347
+ /** Singular/plural unit for rate expressions */
1348
+ type RateUnit = "minute" | "minutes" | "hour" | "hours" | "day" | "days";
1349
+ /**
1350
+ * Rate expression: `rate(1 hour)`, `rate(5 minutes)`, `rate(2 days)`
1351
+ *
1352
+ * Strictly typed — autocomplete and compile-time validation for unit.
1353
+ */
1354
+ type RateExpression = `rate(${number} ${RateUnit})`;
1355
+ /**
1356
+ * Cron expression: `cron(min hour dom month dow year)`
1357
+ *
1358
+ * Not deeply typed (too combinatorial for TS), but the `cron(...)` wrapper is enforced.
1359
+ *
1360
+ * @example
1361
+ * ```
1362
+ * "cron(0 9 * * ? *)" // daily at 9:00 UTC
1363
+ * "cron(0 9 ? * MON-FRI *)" // weekdays at 9:00
1364
+ * "cron(0/15 * * * ? *)" // every 15 minutes
1365
+ * ```
1366
+ */
1367
+ type CronExpression = `cron(${string})`;
1368
+ /**
1369
+ * EventBridge Scheduler schedule expression.
1370
+ *
1371
+ * - **Rate**: `"rate(5 minutes)"`, `"rate(1 hour)"`, `"rate(1 day)"` — strictly typed units
1372
+ * - **Cron**: `"cron(0 9 * * ? *)"` — 6 fields: min hour dom month dow year
1373
+ */
1374
+ type ScheduleExpression = RateExpression | CronExpression;
1375
+ /** Static config extracted at deploy time */
1376
+ type CronConfig = {
1377
+ /** Lambda function settings (memory, timeout, permissions, etc.) */
1378
+ lambda?: LambdaWithPermissions;
1379
+ /** EventBridge Scheduler schedule expression */
1380
+ schedule: ScheduleExpression;
1381
+ /** IANA timezone for the schedule (default: UTC) */
1382
+ timezone?: Timezone;
1383
+ };
1384
+ /** Setup factory — receives deps/config/files based on what was declared */
1385
+ type SetupArgs<D, P, HasFiles extends boolean> = ([D] extends [undefined] ? {} : {
1386
+ deps: ResolveDeps<D>;
1387
+ }) & ([P] extends [undefined] ? {} : {
1388
+ config: ResolveConfig<P & {}>;
1389
+ }) & (HasFiles extends true ? {
1390
+ files: StaticFiles;
1391
+ } : {});
1392
+ /** Spread ctx into callback args (empty when no setup) */
1393
+ type SpreadCtx<C> = [C] extends [undefined] ? {} : C & {};
1394
+ /** Callback function for cron tick */
1395
+ type CronTickFn<C = undefined> = (args: SpreadCtx<C>) => Promise<void> | void;
1396
+ /**
1397
+ * Handler object created by defineCron.
1398
+ * @internal
1399
+ */
1400
+ type CronHandler<C = any> = {
1401
+ readonly __brand: "effortless-cron";
1402
+ readonly __spec: CronConfig;
1403
+ readonly onError?: (...args: any[]) => any;
1404
+ readonly onCleanup?: (...args: any[]) => any;
1405
+ readonly setup?: (...args: any[]) => C | Promise<C>;
1406
+ readonly deps?: Record<string, unknown> | (() => Record<string, unknown>);
1407
+ readonly config?: Record<string, unknown>;
1408
+ readonly static?: string[];
1409
+ readonly onTick?: (...args: any[]) => any;
1410
+ };
1411
+ /** Options passed to `defineCron()` — resource config only */
1412
+ type CronOptions = {
1413
+ /** EventBridge Scheduler schedule expression: `"rate(5 minutes)"` or `"cron(0 9 * * ? *)"` */
1414
+ schedule: ScheduleExpression;
1415
+ /** IANA timezone for the schedule (default: UTC). Full autocomplete for all timezones. */
1416
+ timezone?: Timezone;
1417
+ };
1418
+ interface CronBuilder<D = undefined, P = undefined, C = undefined, HasFiles extends boolean = false> {
1419
+ /** Declare handler dependencies (tables, queues, buckets, mailers) */
1420
+ deps<D2 extends Record<string, AnyDepHandler>>(fn: () => D2): CronBuilder<D2, P, C, HasFiles>;
1421
+ /** Declare SSM secrets */
1422
+ config<P2 extends Record<string, AnySecretRef>>(fn: ConfigFactory<P2>): CronBuilder<D, P2, C, HasFiles>;
1423
+ /** Include static files in the Lambda bundle. Chainable — call multiple times. */
1424
+ include(glob: string): CronBuilder<D, P, C, true>;
1425
+ /** Configure Lambda settings only (memory, timeout, permissions, logLevel) */
1426
+ setup(lambda: LambdaOptions): CronBuilder<D, P, C, HasFiles>;
1427
+ /** Initialize shared state on cold start. Receives deps, config, files. */
1428
+ setup<C2>(fn: (args: SetupArgs<D, P, HasFiles>) => C2 | Promise<C2>): CronBuilder<D, P, C2, HasFiles>;
1429
+ /** Initialize shared state on cold start + configure Lambda settings. */
1430
+ setup<C2>(fn: (args: SetupArgs<D, P, HasFiles>) => C2 | Promise<C2>, lambda: LambdaOptions): CronBuilder<D, P, C2, HasFiles>;
1431
+ /** Handle errors thrown by onTick */
1432
+ onError(fn: (args: {
1433
+ error: unknown;
1434
+ } & SpreadCtx<C>) => void): CronBuilder<D, P, C, HasFiles>;
1435
+ /** Cleanup callback — runs after each invocation, before Lambda freezes */
1436
+ onCleanup(fn: (args: SpreadCtx<C>) => void | Promise<void>): CronBuilder<D, P, C, HasFiles>;
1437
+ /** Tick handler — called on each scheduled invocation (terminal) */
1438
+ onTick(fn: CronTickFn<C>): CronHandler<C>;
1439
+ }
1440
+ /**
1441
+ * Define a cron job — scheduled Lambda invocation via EventBridge Scheduler.
1442
+ *
1443
+ * @example
1444
+ * ```typescript
1445
+ * export const sync = defineCron({ schedule: "cron(0 9 * * ? *)" })
1446
+ * .deps(() => ({ orders }))
1447
+ * .config(({ defineSecret }) => ({ apiKey: defineSecret() }))
1448
+ * .include("templates/*.html")
1449
+ * .setup(async ({ deps, config, files }) => ({
1450
+ * db: deps.orders, key: config.apiKey, tpl: files,
1451
+ * }), { memory: 512 })
1452
+ * .onTick(async ({ db, key, tpl }) => {
1453
+ * const html = tpl.read("templates/report.html")
1454
+ * })
1455
+ * ```
1456
+ */
1457
+ declare function defineCron(options: CronOptions): CronBuilder;
1439
1458
 
1440
- 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 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 UpdateActions, defineApi, defineApp, defineBucket, defineConfig, defineFifoQueue, defineMailer, defineSecret, defineStaticSite, defineTable, generateBase64, generateHex, generateUuid, param, secret, toSeconds, unsafeAs };
1459
+ 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, defineApi, defineApp, defineBucket, defineConfig, defineCron, defineFifoQueue, defineMailer, defineSecret, defineStaticSite, defineTable, generateBase64, generateHex, generateUuid, param, secret, toSeconds };