effortless-aws 0.30.0 → 0.32.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-ISJC6CHC.js → chunk-HGSMOO4A.js} +60 -1
- package/dist/index.d.ts +319 -188
- package/dist/index.js +199 -54
- package/dist/index.js.map +1 -1
- package/dist/runtime/wrap-api.js +2 -2
- package/dist/runtime/wrap-bucket.js +2 -2
- package/dist/runtime/wrap-cron.js +40 -0
- package/dist/runtime/wrap-fifo-queue.js +4 -4
- package/dist/runtime/wrap-table-stream.js +5 -5
- package/dist/runtime/wrap-worker.js +109 -0
- package/package.json +2 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,17 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Configuration for an Effortless project.
|
|
3
3
|
*
|
|
4
|
-
* @
|
|
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$
|
|
364
|
+
type SpreadCtx$5<C> = [C] extends [undefined] ? {} : C & {};
|
|
391
365
|
/** Setup factory — receives bucket/deps/config/files based on what was declared */
|
|
392
|
-
type SetupArgs$
|
|
366
|
+
type SetupArgs$5<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$
|
|
380
|
+
} & SpreadCtx$5<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$
|
|
386
|
+
} & SpreadCtx$5<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$
|
|
420
|
+
setup<C2>(fn: (args: SetupArgs$5<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$5<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$
|
|
426
|
+
} & SpreadCtx$5<C>) => void | Promise<void>): BucketBuilder<D, P, C, HasFiles>;
|
|
457
427
|
/** Cleanup callback — runs after each invocation, before Lambda freezes */
|
|
458
|
-
onCleanup(fn: (args: SpreadCtx$
|
|
428
|
+
onCleanup(fn: (args: SpreadCtx$5<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
|
-
* @
|
|
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$
|
|
559
|
+
type SpreadCtx$4<C> = [C] extends [undefined] ? {} : C & {};
|
|
595
560
|
/** Setup factory — receives deps/config/files based on what was declared */
|
|
596
|
-
type SetupArgs$
|
|
561
|
+
type SetupArgs$4<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$
|
|
574
|
+
} & SpreadCtx$4<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$
|
|
582
|
+
} & SpreadCtx$4<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$
|
|
631
|
+
setup<C2>(fn: (args: SetupArgs$4<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$4<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$
|
|
637
|
+
} & SpreadCtx$4<C>) => void | Promise<void>): FifoQueueBuilder<T, D, P, C, HasFiles>;
|
|
677
638
|
/** Cleanup callback — runs after each invocation, before Lambda freezes */
|
|
678
|
-
onCleanup(fn: (args: SpreadCtx$
|
|
639
|
+
onCleanup(fn: (args: SpreadCtx$4<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,30 +645,115 @@ 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
|
-
* @
|
|
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
|
|
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
|
|
|
661
|
+
/** Fargate container size presets */
|
|
662
|
+
type FargateSize = "0.25vCPU-512mb" | "0.5vCPU-1gb" | "1vCPU-2gb" | "2vCPU-4gb" | "4vCPU-8gb";
|
|
663
|
+
/** Static config extracted at deploy time */
|
|
664
|
+
type WorkerConfig = {
|
|
665
|
+
/** Lambda function settings (memory, timeout, permissions, etc.) */
|
|
666
|
+
lambda?: LambdaWithPermissions;
|
|
667
|
+
/** Fargate size (default: "0.5vCPU-1gb") */
|
|
668
|
+
size?: FargateSize;
|
|
669
|
+
/** How long the worker stays alive without messages before shutting down (default: "5m") */
|
|
670
|
+
idleTimeout?: Duration;
|
|
671
|
+
/** Max messages processed in parallel (default: 1, max: 10) */
|
|
672
|
+
concurrency?: number;
|
|
673
|
+
};
|
|
674
|
+
/** Setup factory — receives deps/config/files based on what was declared */
|
|
675
|
+
type SetupArgs$3<D, P, HasFiles extends boolean> = ([D] extends [undefined] ? {} : {
|
|
676
|
+
deps: ResolveDeps<D>;
|
|
677
|
+
}) & ([P] extends [undefined] ? {} : {
|
|
678
|
+
config: ResolveConfig<P & {}>;
|
|
679
|
+
}) & (HasFiles extends true ? {
|
|
680
|
+
files: StaticFiles;
|
|
681
|
+
} : {});
|
|
682
|
+
/** Spread ctx into callback args (empty when no setup) */
|
|
683
|
+
type SpreadCtx$3<C> = [C] extends [undefined] ? {} : C & {};
|
|
684
|
+
/** Callback function for the worker's onMessage */
|
|
685
|
+
type WorkerMessageFn<T, C = undefined> = (msg: T, ctx: SpreadCtx$3<C>) => Promise<void> | void;
|
|
686
|
+
/**
|
|
687
|
+
* Handler object created by defineWorker.
|
|
688
|
+
* @internal
|
|
689
|
+
*/
|
|
690
|
+
type WorkerHandler<T = any, C = any> = {
|
|
691
|
+
readonly __brand: "effortless-worker";
|
|
692
|
+
readonly __spec: WorkerConfig;
|
|
693
|
+
readonly onError?: (...args: any[]) => any;
|
|
694
|
+
readonly onCleanup?: (...args: any[]) => any;
|
|
695
|
+
readonly setup?: (...args: any[]) => C | Promise<C>;
|
|
696
|
+
readonly deps?: Record<string, unknown> | (() => Record<string, unknown>);
|
|
697
|
+
readonly config?: Record<string, unknown>;
|
|
698
|
+
readonly static?: string[];
|
|
699
|
+
readonly onMessage?: (...args: any[]) => any;
|
|
700
|
+
};
|
|
701
|
+
/** Options passed to `defineWorker()` — resource config only */
|
|
702
|
+
type WorkerOptions = {
|
|
703
|
+
/** Fargate size (default: "0.5vCPU-1gb") */
|
|
704
|
+
size?: FargateSize;
|
|
705
|
+
/** How long the worker stays alive without messages before shutting down (default: "5m") */
|
|
706
|
+
idleTimeout?: Duration;
|
|
707
|
+
/** Max messages processed in parallel (default: 1, max: 10) */
|
|
708
|
+
concurrency?: number;
|
|
709
|
+
};
|
|
710
|
+
interface WorkerBuilder<T, D = undefined, P = undefined, C = undefined, HasFiles extends boolean = false> {
|
|
711
|
+
/** Declare handler dependencies (tables, queues, buckets, mailers, workers) */
|
|
712
|
+
deps<D2 extends Record<string, AnyDepHandler>>(fn: () => D2): WorkerBuilder<T, D2, P, C, HasFiles>;
|
|
713
|
+
/** Declare SSM secrets */
|
|
714
|
+
config<P2 extends Record<string, AnySecretRef>>(fn: ConfigFactory<P2>): WorkerBuilder<T, D, P2, C, HasFiles>;
|
|
715
|
+
/** Include static files in the bundle. Chainable — call multiple times. */
|
|
716
|
+
include(glob: string): WorkerBuilder<T, D, P, C, true>;
|
|
717
|
+
/** Configure Lambda settings only (memory, timeout, permissions, logLevel) */
|
|
718
|
+
setup(lambda: LambdaOptions): WorkerBuilder<T, D, P, C, HasFiles>;
|
|
719
|
+
/** 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>;
|
|
721
|
+
/** 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>;
|
|
723
|
+
/** Handle errors thrown by onMessage. Return "delete" to discard, "retry" to reprocess (default). */
|
|
724
|
+
onError(fn: (args: {
|
|
725
|
+
error: unknown;
|
|
726
|
+
msg: T;
|
|
727
|
+
retryCount: number;
|
|
728
|
+
} & SpreadCtx$3<C>) => "retry" | "delete" | void | Promise<"retry" | "delete" | void>): WorkerBuilder<T, D, P, C, HasFiles>;
|
|
729
|
+
/** Cleanup callback — runs when the worker shuts down */
|
|
730
|
+
onCleanup(fn: (args: SpreadCtx$3<C>) => void | Promise<void>): WorkerBuilder<T, D, P, C, HasFiles>;
|
|
731
|
+
/** Process a single message from the queue (terminal) */
|
|
732
|
+
onMessage(fn: WorkerMessageFn<T, C>): WorkerHandler<T, C>;
|
|
733
|
+
}
|
|
734
|
+
/**
|
|
735
|
+
* Define a worker — a long-running Fargate container with an SQS queue.
|
|
736
|
+
*
|
|
737
|
+
* The worker stays alive while processing messages and shuts down after
|
|
738
|
+
* an idle timeout with no new messages. Other handlers can send messages
|
|
739
|
+
* to the worker via `deps.worker.send(msg)`.
|
|
740
|
+
*
|
|
741
|
+
* @typeParam T - Type of messages the worker receives via its queue
|
|
742
|
+
*
|
|
743
|
+
* @example
|
|
744
|
+
* ```typescript
|
|
745
|
+
* type Job = { type: "export"; userId: string }
|
|
746
|
+
*
|
|
747
|
+
* export const worker = defineWorker<Job>({ memory: 2048, concurrency: 5 })
|
|
748
|
+
* .deps(() => ({ orders }))
|
|
749
|
+
* .setup(async ({ deps }) => ({ db: deps.orders }))
|
|
750
|
+
* .onMessage(async (msg, { db }) => {
|
|
751
|
+
* await processJob(msg, db)
|
|
752
|
+
* })
|
|
753
|
+
* ```
|
|
754
|
+
*/
|
|
755
|
+
declare function defineWorker<T = unknown>(options?: WorkerOptions): WorkerBuilder<T>;
|
|
756
|
+
|
|
711
757
|
/**
|
|
712
758
|
* Sort key condition for TableClient.query()
|
|
713
759
|
*/
|
|
@@ -872,11 +918,27 @@ type QueueClient<T = unknown> = {
|
|
|
872
918
|
queueName: string;
|
|
873
919
|
};
|
|
874
920
|
|
|
921
|
+
/** Options for sending a message to a worker */
|
|
922
|
+
type WorkerSendOptions = {
|
|
923
|
+
/** Delay before the message becomes visible in the queue (max "15m") */
|
|
924
|
+
delay?: Duration;
|
|
925
|
+
/** Whether to start the worker container (default: true) */
|
|
926
|
+
start?: boolean;
|
|
927
|
+
};
|
|
928
|
+
type WorkerClient<T = unknown> = {
|
|
929
|
+
/** Send a message to the worker's queue. Wakes up the worker by default. */
|
|
930
|
+
send(msg: T, options?: WorkerSendOptions): Promise<void>;
|
|
931
|
+
/** Check if the worker is currently running */
|
|
932
|
+
status(): Promise<"running" | "idle">;
|
|
933
|
+
/** Stop the worker (scale ECS service to 0) */
|
|
934
|
+
stop(): Promise<void>;
|
|
935
|
+
};
|
|
936
|
+
|
|
875
937
|
/** Dep value types supported by the deps declaration */
|
|
876
|
-
type AnyDepHandler = TableHandler<any, any> | BucketHandler<any> | MailerHandler | FifoQueueHandler<any, any>;
|
|
938
|
+
type AnyDepHandler = TableHandler<any, any> | BucketHandler<any> | MailerHandler | FifoQueueHandler<any, any> | WorkerHandler<any, any>;
|
|
877
939
|
/** Maps a deps declaration to resolved runtime client types */
|
|
878
940
|
type ResolveDeps<D> = {
|
|
879
|
-
[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> : never;
|
|
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;
|
|
880
942
|
};
|
|
881
943
|
|
|
882
944
|
/** DynamoDB Streams view type - determines what data is captured in stream records */
|
|
@@ -939,7 +1001,7 @@ type TableRecord<T = Record<string, unknown>> = {
|
|
|
939
1001
|
timestamp?: number;
|
|
940
1002
|
};
|
|
941
1003
|
/** Setup factory — receives table/deps/config/files based on what was declared */
|
|
942
|
-
type SetupArgs$
|
|
1004
|
+
type SetupArgs$2<T, D, P, HasFiles extends boolean> = {
|
|
943
1005
|
table: TableClient<T>;
|
|
944
1006
|
} & ([D] extends [undefined] ? {} : {
|
|
945
1007
|
deps: ResolveDeps<D>;
|
|
@@ -949,7 +1011,7 @@ type SetupArgs$1<T, D, P, HasFiles extends boolean> = {
|
|
|
949
1011
|
files: StaticFiles;
|
|
950
1012
|
} : {});
|
|
951
1013
|
/** Spread ctx into callback args (empty when no setup) */
|
|
952
|
-
type SpreadCtx$
|
|
1014
|
+
type SpreadCtx$2<C> = [C] extends [undefined] ? {} : C & {};
|
|
953
1015
|
/**
|
|
954
1016
|
* Callback function type for processing a single DynamoDB stream record.
|
|
955
1017
|
* Receives the current record and the full batch for context.
|
|
@@ -957,7 +1019,7 @@ type SpreadCtx$1<C> = [C] extends [undefined] ? {} : C & {};
|
|
|
957
1019
|
type TableRecordFn<T = Record<string, unknown>, C = undefined> = (args: {
|
|
958
1020
|
record: TableRecord<T>;
|
|
959
1021
|
batch: readonly TableRecord<T>[];
|
|
960
|
-
} & SpreadCtx$
|
|
1022
|
+
} & SpreadCtx$2<C>) => Promise<void>;
|
|
961
1023
|
/**
|
|
962
1024
|
* Batch handler function for DynamoDB stream records.
|
|
963
1025
|
* Called once with all records in the batch.
|
|
@@ -965,7 +1027,7 @@ type TableRecordFn<T = Record<string, unknown>, C = undefined> = (args: {
|
|
|
965
1027
|
*/
|
|
966
1028
|
type TableBatchFn<T = Record<string, unknown>, C = undefined> = (args: {
|
|
967
1029
|
records: readonly TableRecord<T>[];
|
|
968
|
-
} & SpreadCtx$
|
|
1030
|
+
} & SpreadCtx$2<C>) => Promise<void | {
|
|
969
1031
|
failures: string[];
|
|
970
1032
|
}>;
|
|
971
1033
|
/** Static config extracted by AST (no runtime callbacks) */
|
|
@@ -987,16 +1049,8 @@ type TableHandler<T = Record<string, unknown>, C = any> = {
|
|
|
987
1049
|
readonly onRecord?: (...args: any[]) => any;
|
|
988
1050
|
readonly onRecordBatch?: (...args: any[]) => any;
|
|
989
1051
|
};
|
|
990
|
-
/** Options passed to `defineTable()` —
|
|
1052
|
+
/** Options passed to `defineTable()` — resource config only, no Lambda settings */
|
|
991
1053
|
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
1054
|
/** DynamoDB billing mode (default: "PAY_PER_REQUEST") */
|
|
1001
1055
|
billingMode?: "PAY_PER_REQUEST" | "PROVISIONED";
|
|
1002
1056
|
/** Stream view type (default: "NEW_AND_OLD_IMAGES") */
|
|
@@ -1013,22 +1067,26 @@ type TableOptions<T> = {
|
|
|
1013
1067
|
tagField?: Extract<keyof T, string>;
|
|
1014
1068
|
/** Decode/validate function for the `data` portion of stream records */
|
|
1015
1069
|
schema?: (input: unknown) => T;
|
|
1016
|
-
/** Static file glob patterns to bundle into the Lambda ZIP */
|
|
1017
|
-
static?: string[];
|
|
1018
1070
|
};
|
|
1019
1071
|
interface TableBuilder<T = Record<string, unknown>, D = undefined, P = undefined, C = undefined, HasFiles extends boolean = false> {
|
|
1020
1072
|
/** Declare handler dependencies (tables, queues, buckets, mailers) */
|
|
1021
1073
|
deps<D2 extends Record<string, AnyDepHandler>>(fn: () => D2): TableBuilder<T, D2, P, C, HasFiles>;
|
|
1022
1074
|
/** Declare SSM secrets */
|
|
1023
1075
|
config<P2 extends Record<string, AnySecretRef>>(fn: ConfigFactory<P2>): TableBuilder<T, D, P2, C, HasFiles>;
|
|
1076
|
+
/** Include static files in the Lambda bundle. Chainable — call multiple times. */
|
|
1077
|
+
include(glob: string): TableBuilder<T, D, P, C, true>;
|
|
1078
|
+
/** Configure Lambda settings only (memory, timeout, permissions, etc.) */
|
|
1079
|
+
setup(lambda: LambdaOptions): TableBuilder<T, D, P, C, HasFiles>;
|
|
1024
1080
|
/** Initialize shared state on cold start. Receives table (self-client), deps, config, files. */
|
|
1025
|
-
setup<C2>(fn: (args: SetupArgs$
|
|
1081
|
+
setup<C2>(fn: (args: SetupArgs$2<T, D, P, HasFiles>) => C2 | Promise<C2>): TableBuilder<T, D, P, C2, HasFiles>;
|
|
1082
|
+
/** 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>;
|
|
1026
1084
|
/** Handle errors thrown by onRecord/onRecordBatch */
|
|
1027
1085
|
onError(fn: (args: {
|
|
1028
1086
|
error: unknown;
|
|
1029
|
-
} & SpreadCtx$
|
|
1087
|
+
} & SpreadCtx$2<C>) => void | Promise<void>): TableBuilder<T, D, P, C, HasFiles>;
|
|
1030
1088
|
/** Cleanup callback — runs after each invocation, before Lambda freezes */
|
|
1031
|
-
onCleanup(fn: (args: SpreadCtx$
|
|
1089
|
+
onCleanup(fn: (args: SpreadCtx$2<C>) => void | Promise<void>): TableBuilder<T, D, P, C, HasFiles>;
|
|
1032
1090
|
/** Per-record stream handler (terminal — returns finalized handler) */
|
|
1033
1091
|
onRecord(fn: TableRecordFn<T, C>): TableHandler<T, C>;
|
|
1034
1092
|
/** Batch stream handler (terminal — returns finalized handler) */
|
|
@@ -1042,7 +1100,9 @@ interface TableBuilder<T = Record<string, unknown>, D = undefined, P = undefined
|
|
|
1042
1100
|
* Creates a table with fixed key schema: `pk (S)` + `sk (S)`, plus `tag (S)`,
|
|
1043
1101
|
* `data (M)`, and `ttl (N)` attributes. TTL is always enabled.
|
|
1044
1102
|
*
|
|
1045
|
-
* @
|
|
1103
|
+
* @see {@link https://effortless-aws.website/use-cases/database | Database guide}
|
|
1104
|
+
*
|
|
1105
|
+
* @example
|
|
1046
1106
|
* ```typescript
|
|
1047
1107
|
* export const orders = defineTable<OrderData>({ batchSize: 10, concurrency: 5 })
|
|
1048
1108
|
* .setup(({ table }) => ({ table }))
|
|
@@ -1052,21 +1112,8 @@ interface TableBuilder<T = Record<string, unknown>, D = undefined, P = undefined
|
|
|
1052
1112
|
* }
|
|
1053
1113
|
* })
|
|
1054
1114
|
* ```
|
|
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
1115
|
*/
|
|
1066
1116
|
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
1117
|
declare function defineTable<T = Record<string, unknown>>(options: TableOptions<T>): TableBuilder<T>;
|
|
1071
1118
|
|
|
1072
1119
|
/**
|
|
@@ -1111,18 +1158,10 @@ type AppHandler = {
|
|
|
1111
1158
|
*
|
|
1112
1159
|
* For static-only sites (no SSR), use {@link defineStaticSite} instead.
|
|
1113
1160
|
*
|
|
1161
|
+
* @see {@link https://effortless-aws.website/use-cases/web-app | Web app guide}
|
|
1162
|
+
*
|
|
1114
1163
|
* @param options - App configuration: server directory, assets directory, optional build command
|
|
1115
1164
|
* @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
1165
|
*/
|
|
1127
1166
|
declare const defineApp: () => (options: AppConfig) => AppHandler;
|
|
1128
1167
|
|
|
@@ -1199,26 +1238,10 @@ type StaticSiteHandler = {
|
|
|
1199
1238
|
/**
|
|
1200
1239
|
* Deploy a static site via S3 + CloudFront CDN.
|
|
1201
1240
|
*
|
|
1241
|
+
* @see {@link https://effortless-aws.website/use-cases/web-app | Web app guide}
|
|
1242
|
+
*
|
|
1202
1243
|
* @param options - Static site configuration: directory, optional SPA mode, build command
|
|
1203
1244
|
* @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
1245
|
*/
|
|
1223
1246
|
declare const defineStaticSite: () => (options: StaticSiteConfig) => StaticSiteHandler;
|
|
1224
1247
|
|
|
@@ -1294,11 +1317,11 @@ type RouteEntry = {
|
|
|
1294
1317
|
public?: boolean;
|
|
1295
1318
|
};
|
|
1296
1319
|
/** 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] ? {} : {
|
|
1320
|
+
type SpreadCtx$1<C> = ([C] extends [undefined] ? {} : Omit<C & {}, 'auth'>) & ([ExtractAuth<C>] extends [undefined] ? {} : {
|
|
1298
1321
|
auth: AuthHelpers<ExtractAuth<C>>;
|
|
1299
1322
|
});
|
|
1300
1323
|
/** Callback args available inside each route — ctx is spread into args */
|
|
1301
|
-
type RouteArgs<C, ST> = SpreadCtx<C> & {
|
|
1324
|
+
type RouteArgs<C, ST> = SpreadCtx$1<C> & {
|
|
1302
1325
|
req: HttpRequest;
|
|
1303
1326
|
input: unknown;
|
|
1304
1327
|
ok: OkHelper;
|
|
@@ -1313,7 +1336,7 @@ type RouteOptions = {
|
|
|
1313
1336
|
public?: boolean;
|
|
1314
1337
|
};
|
|
1315
1338
|
/** Setup factory — receives deps/config/files/enableAuth based on what was declared */
|
|
1316
|
-
type SetupArgs<D, P, HasFiles extends boolean> = {
|
|
1339
|
+
type SetupArgs$1<D, P, HasFiles extends boolean> = {
|
|
1317
1340
|
enableAuth: EnableAuth;
|
|
1318
1341
|
ok: OkHelper;
|
|
1319
1342
|
fail: FailHelper;
|
|
@@ -1341,7 +1364,7 @@ type ApiConfig = {
|
|
|
1341
1364
|
type ApiHandler<C = undefined> = {
|
|
1342
1365
|
readonly __brand: "effortless-api";
|
|
1343
1366
|
readonly __spec: ApiConfig;
|
|
1344
|
-
readonly onError?: (...args: any[]) => any
|
|
1367
|
+
readonly onError?: (...args: any[]) => any | Promise<any>;
|
|
1345
1368
|
readonly onCleanup?: (...args: any[]) => any;
|
|
1346
1369
|
readonly setup?: (...args: any[]) => C | Promise<C>;
|
|
1347
1370
|
readonly deps?: Record<string, unknown> | (() => Record<string, unknown>);
|
|
@@ -1353,18 +1376,8 @@ type ApiHandler<C = undefined> = {
|
|
|
1353
1376
|
type ApiOptions = {
|
|
1354
1377
|
/** Base path prefix for all routes (e.g., "/api") */
|
|
1355
1378
|
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
1379
|
/** Enable response streaming. When true, routes receive a `stream` arg for SSE. */
|
|
1365
1380
|
stream?: boolean;
|
|
1366
|
-
/** Static file glob patterns to bundle into the Lambda ZIP */
|
|
1367
|
-
static?: string[];
|
|
1368
1381
|
};
|
|
1369
1382
|
/**
|
|
1370
1383
|
* Finalized API handler with route-adding methods.
|
|
@@ -1388,17 +1401,23 @@ interface ApiBuilder<D = undefined, P = undefined, C = undefined, ST extends boo
|
|
|
1388
1401
|
deps<D2 extends Record<string, AnyDepHandler>>(fn: () => D2): ApiBuilder<D2, P, C, ST, HasFiles>;
|
|
1389
1402
|
/** Declare SSM secrets */
|
|
1390
1403
|
config<P2 extends Record<string, AnySecretRef>>(fn: ConfigFactory<P2>): ApiBuilder<D, P2, C, ST, HasFiles>;
|
|
1404
|
+
/** Include static files by glob pattern */
|
|
1405
|
+
include(glob: string): ApiBuilder<D, P, C, ST, true>;
|
|
1406
|
+
/** Configure Lambda settings only (no init function) */
|
|
1407
|
+
setup(lambda: LambdaOptions): ApiBuilder<D, P, C, ST, HasFiles>;
|
|
1391
1408
|
/** 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>;
|
|
1409
|
+
setup<C2>(fn: (args: SetupArgs$1<D, P, HasFiles>) => ValidateSetupReturn<C2> | Promise<ValidateSetupReturn<C2>>): ApiBuilder<D, P, C2, ST, HasFiles>;
|
|
1410
|
+
/** 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>;
|
|
1393
1412
|
/** Handle errors thrown by routes */
|
|
1394
1413
|
onError(fn: (args: {
|
|
1395
1414
|
error: unknown;
|
|
1396
1415
|
req: HttpRequest;
|
|
1397
1416
|
ok: OkHelper;
|
|
1398
1417
|
fail: FailHelper;
|
|
1399
|
-
} & SpreadCtx<C>) => HttpResponse): ApiBuilder<D, P, C, ST, HasFiles>;
|
|
1418
|
+
} & SpreadCtx$1<C>) => HttpResponse | Promise<HttpResponse>): ApiBuilder<D, P, C, ST, HasFiles>;
|
|
1400
1419
|
/** Cleanup callback — runs after each invocation, before Lambda freezes */
|
|
1401
|
-
onCleanup(fn: (args: SpreadCtx<C>) => void | Promise<void>): ApiBuilder<D, P, C, ST, HasFiles>;
|
|
1420
|
+
onCleanup(fn: (args: SpreadCtx$1<C>) => void | Promise<void>): ApiBuilder<D, P, C, ST, HasFiles>;
|
|
1402
1421
|
/** Add a GET route (terminal — returns finalized handler with route methods) */
|
|
1403
1422
|
get(path: `/${string}`, handler: RouteHandler<C, ST>, options?: RouteOptions): ApiRoutes<C, ST>;
|
|
1404
1423
|
/** Add a POST route (terminal) */
|
|
@@ -1413,13 +1432,10 @@ interface ApiBuilder<D = undefined, P = undefined, C = undefined, ST extends boo
|
|
|
1413
1432
|
/**
|
|
1414
1433
|
* Define an API with typed routes using a builder pattern.
|
|
1415
1434
|
*
|
|
1435
|
+
* @see {@link https://effortless-aws.website/use-cases/http-api | HTTP API guide}
|
|
1436
|
+
*
|
|
1416
1437
|
* @example
|
|
1417
1438
|
* ```typescript
|
|
1418
|
-
* // Minimal
|
|
1419
|
-
* export default defineApi({ basePath: "/hello" })
|
|
1420
|
-
* .get("/", async ({ req, ok }) => ok({ message: "Hello!" }))
|
|
1421
|
-
*
|
|
1422
|
-
* // Full
|
|
1423
1439
|
* export const api = defineApi({ basePath: "/api", timeout: "30s" })
|
|
1424
1440
|
* .deps(() => ({ users }))
|
|
1425
1441
|
* .config(({ defineSecret }) => ({ dbUrl: defineSecret() }))
|
|
@@ -1432,9 +1448,124 @@ interface ApiBuilder<D = undefined, P = undefined, C = undefined, ST extends boo
|
|
|
1432
1448
|
* .post("/login", async ({ auth, ok }) => ok(await auth.createSession()), { public: true })
|
|
1433
1449
|
* ```
|
|
1434
1450
|
*/
|
|
1435
|
-
declare function defineApi(options:
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1451
|
+
declare function defineApi<const O extends ApiOptions>(options: O): ApiBuilder<undefined, undefined, undefined, O["stream"] extends true ? true : false, false>;
|
|
1452
|
+
|
|
1453
|
+
/**
|
|
1454
|
+
* All IANA time zones.
|
|
1455
|
+
* Generated from Intl.supportedValuesOf("timeZone") on Node.js 22.
|
|
1456
|
+
*/
|
|
1457
|
+
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";
|
|
1458
|
+
|
|
1459
|
+
/** Singular/plural unit for rate expressions */
|
|
1460
|
+
type RateUnit = "minute" | "minutes" | "hour" | "hours" | "day" | "days";
|
|
1461
|
+
/**
|
|
1462
|
+
* Rate expression: `rate(1 hour)`, `rate(5 minutes)`, `rate(2 days)`
|
|
1463
|
+
*
|
|
1464
|
+
* Strictly typed — autocomplete and compile-time validation for unit.
|
|
1465
|
+
*/
|
|
1466
|
+
type RateExpression = `rate(${number} ${RateUnit})`;
|
|
1467
|
+
/**
|
|
1468
|
+
* Cron expression: `cron(min hour dom month dow year)`
|
|
1469
|
+
*
|
|
1470
|
+
* Not deeply typed (too combinatorial for TS), but the `cron(...)` wrapper is enforced.
|
|
1471
|
+
*
|
|
1472
|
+
* @example
|
|
1473
|
+
* ```
|
|
1474
|
+
* "cron(0 9 * * ? *)" // daily at 9:00 UTC
|
|
1475
|
+
* "cron(0 9 ? * MON-FRI *)" // weekdays at 9:00
|
|
1476
|
+
* "cron(0/15 * * * ? *)" // every 15 minutes
|
|
1477
|
+
* ```
|
|
1478
|
+
*/
|
|
1479
|
+
type CronExpression = `cron(${string})`;
|
|
1480
|
+
/**
|
|
1481
|
+
* EventBridge Scheduler schedule expression.
|
|
1482
|
+
*
|
|
1483
|
+
* - **Rate**: `"rate(5 minutes)"`, `"rate(1 hour)"`, `"rate(1 day)"` — strictly typed units
|
|
1484
|
+
* - **Cron**: `"cron(0 9 * * ? *)"` — 6 fields: min hour dom month dow year
|
|
1485
|
+
*/
|
|
1486
|
+
type ScheduleExpression = RateExpression | CronExpression;
|
|
1487
|
+
/** Static config extracted at deploy time */
|
|
1488
|
+
type CronConfig = {
|
|
1489
|
+
/** Lambda function settings (memory, timeout, permissions, etc.) */
|
|
1490
|
+
lambda?: LambdaWithPermissions;
|
|
1491
|
+
/** EventBridge Scheduler schedule expression */
|
|
1492
|
+
schedule: ScheduleExpression;
|
|
1493
|
+
/** IANA timezone for the schedule (default: UTC) */
|
|
1494
|
+
timezone?: Timezone;
|
|
1495
|
+
};
|
|
1496
|
+
/** Setup factory — receives deps/config/files based on what was declared */
|
|
1497
|
+
type SetupArgs<D, P, HasFiles extends boolean> = ([D] extends [undefined] ? {} : {
|
|
1498
|
+
deps: ResolveDeps<D>;
|
|
1499
|
+
}) & ([P] extends [undefined] ? {} : {
|
|
1500
|
+
config: ResolveConfig<P & {}>;
|
|
1501
|
+
}) & (HasFiles extends true ? {
|
|
1502
|
+
files: StaticFiles;
|
|
1503
|
+
} : {});
|
|
1504
|
+
/** Spread ctx into callback args (empty when no setup) */
|
|
1505
|
+
type SpreadCtx<C> = [C] extends [undefined] ? {} : C & {};
|
|
1506
|
+
/** Callback function for cron tick */
|
|
1507
|
+
type CronTickFn<C = undefined> = (args: SpreadCtx<C>) => Promise<void> | void;
|
|
1508
|
+
/**
|
|
1509
|
+
* Handler object created by defineCron.
|
|
1510
|
+
* @internal
|
|
1511
|
+
*/
|
|
1512
|
+
type CronHandler<C = any> = {
|
|
1513
|
+
readonly __brand: "effortless-cron";
|
|
1514
|
+
readonly __spec: CronConfig;
|
|
1515
|
+
readonly onError?: (...args: any[]) => any;
|
|
1516
|
+
readonly onCleanup?: (...args: any[]) => any;
|
|
1517
|
+
readonly setup?: (...args: any[]) => C | Promise<C>;
|
|
1518
|
+
readonly deps?: Record<string, unknown> | (() => Record<string, unknown>);
|
|
1519
|
+
readonly config?: Record<string, unknown>;
|
|
1520
|
+
readonly static?: string[];
|
|
1521
|
+
readonly onTick?: (...args: any[]) => any;
|
|
1522
|
+
};
|
|
1523
|
+
/** Options passed to `defineCron()` — resource config only */
|
|
1524
|
+
type CronOptions = {
|
|
1525
|
+
/** EventBridge Scheduler schedule expression: `"rate(5 minutes)"` or `"cron(0 9 * * ? *)"` */
|
|
1526
|
+
schedule: ScheduleExpression;
|
|
1527
|
+
/** IANA timezone for the schedule (default: UTC). Full autocomplete for all timezones. */
|
|
1528
|
+
timezone?: Timezone;
|
|
1529
|
+
};
|
|
1530
|
+
interface CronBuilder<D = undefined, P = undefined, C = undefined, HasFiles extends boolean = false> {
|
|
1531
|
+
/** Declare handler dependencies (tables, queues, buckets, mailers) */
|
|
1532
|
+
deps<D2 extends Record<string, AnyDepHandler>>(fn: () => D2): CronBuilder<D2, P, C, HasFiles>;
|
|
1533
|
+
/** Declare SSM secrets */
|
|
1534
|
+
config<P2 extends Record<string, AnySecretRef>>(fn: ConfigFactory<P2>): CronBuilder<D, P2, C, HasFiles>;
|
|
1535
|
+
/** Include static files in the Lambda bundle. Chainable — call multiple times. */
|
|
1536
|
+
include(glob: string): CronBuilder<D, P, C, true>;
|
|
1537
|
+
/** Configure Lambda settings only (memory, timeout, permissions, logLevel) */
|
|
1538
|
+
setup(lambda: LambdaOptions): CronBuilder<D, P, C, HasFiles>;
|
|
1539
|
+
/** 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>;
|
|
1541
|
+
/** 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>;
|
|
1543
|
+
/** Handle errors thrown by onTick */
|
|
1544
|
+
onError(fn: (args: {
|
|
1545
|
+
error: unknown;
|
|
1546
|
+
} & SpreadCtx<C>) => void | Promise<void>): CronBuilder<D, P, C, HasFiles>;
|
|
1547
|
+
/** Cleanup callback — runs after each invocation, before Lambda freezes */
|
|
1548
|
+
onCleanup(fn: (args: SpreadCtx<C>) => void | Promise<void>): CronBuilder<D, P, C, HasFiles>;
|
|
1549
|
+
/** Tick handler — called on each scheduled invocation (terminal) */
|
|
1550
|
+
onTick(fn: CronTickFn<C>): CronHandler<C>;
|
|
1551
|
+
}
|
|
1552
|
+
/**
|
|
1553
|
+
* Define a cron job — scheduled Lambda invocation via EventBridge Scheduler.
|
|
1554
|
+
*
|
|
1555
|
+
* @example
|
|
1556
|
+
* ```typescript
|
|
1557
|
+
* export const sync = defineCron({ schedule: "cron(0 9 * * ? *)" })
|
|
1558
|
+
* .deps(() => ({ orders }))
|
|
1559
|
+
* .config(({ defineSecret }) => ({ apiKey: defineSecret() }))
|
|
1560
|
+
* .include("templates/*.html")
|
|
1561
|
+
* .setup(async ({ deps, config, files }) => ({
|
|
1562
|
+
* db: deps.orders, key: config.apiKey, tpl: files,
|
|
1563
|
+
* }), { memory: 512 })
|
|
1564
|
+
* .onTick(async ({ db, key, tpl }) => {
|
|
1565
|
+
* const html = tpl.read("templates/report.html")
|
|
1566
|
+
* })
|
|
1567
|
+
* ```
|
|
1568
|
+
*/
|
|
1569
|
+
declare function defineCron(options: CronOptions): CronBuilder;
|
|
1439
1570
|
|
|
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
|
|
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 };
|