effortless-aws 0.7.0 → 0.7.2

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
@@ -88,6 +88,117 @@ type EffortlessConfig = {
88
88
  */
89
89
  declare const defineConfig: (config: EffortlessConfig) => EffortlessConfig;
90
90
 
91
+ type AwsService = "dynamodb" | "s3" | "sqs" | "sns" | "ses" | "ssm" | "lambda" | "events" | "secretsmanager" | "cognito-idp" | "logs";
92
+ type Permission = `${AwsService}:${string}` | (string & {});
93
+ /** Logging verbosity level for Lambda handlers */
94
+ type LogLevel = "error" | "info" | "debug";
95
+ /**
96
+ * Common Lambda configuration shared by all handler types.
97
+ */
98
+ type LambdaConfig = {
99
+ /** Handler name. Defaults to export name if not specified */
100
+ name?: string;
101
+ /** Lambda memory in MB (default: 256) */
102
+ memory?: number;
103
+ /** Lambda timeout in seconds (default: 30) */
104
+ timeout?: number;
105
+ /** Logging verbosity: "error" (errors only), "info" (+ execution summary), "debug" (+ input/output). Default: "info" */
106
+ logLevel?: LogLevel;
107
+ };
108
+ /**
109
+ * Lambda configuration with additional IAM permissions.
110
+ * Used by handler types that support custom permissions (http, table, fifo-queue).
111
+ */
112
+ type LambdaWithPermissions = LambdaConfig & {
113
+ /** Additional IAM permissions for the Lambda */
114
+ permissions?: Permission[];
115
+ };
116
+ type AnyParamRef = ParamRef<any>;
117
+ /**
118
+ * Reference to an SSM Parameter Store parameter.
119
+ *
120
+ * @typeParam T - The resolved type after optional transform (default: string)
121
+ */
122
+ type ParamRef<T = string> = {
123
+ readonly __brand: "effortless-param";
124
+ readonly key: string;
125
+ readonly transform?: (raw: string) => T;
126
+ };
127
+ /**
128
+ * Maps a params declaration to resolved value types.
129
+ *
130
+ * @typeParam P - Record of param names to ParamRef instances
131
+ */
132
+ type ResolveParams<P> = {
133
+ [K in keyof P]: P[K] extends ParamRef<infer T> ? T : never;
134
+ };
135
+ /**
136
+ * Declare an SSM Parameter Store parameter.
137
+ *
138
+ * The key is combined with project and stage at deploy time to form the full
139
+ * SSM path: `/${project}/${stage}/${key}`.
140
+ *
141
+ * @param key - Parameter key (e.g., "database-url")
142
+ * @param transform - Optional function to transform the raw string value
143
+ * @returns A ParamRef used by the deployment and runtime systems
144
+ *
145
+ * @example Simple string parameter
146
+ * ```typescript
147
+ * params: {
148
+ * dbUrl: param("database-url"),
149
+ * }
150
+ * ```
151
+ *
152
+ * @example With transform (e.g., TOML parsing)
153
+ * ```typescript
154
+ * import TOML from "smol-toml";
155
+ *
156
+ * params: {
157
+ * config: param("app-config", TOML.parse),
158
+ * }
159
+ * ```
160
+ */
161
+ declare function param(key: string): ParamRef<string>;
162
+ declare function param<T>(key: string, transform: (raw: string) => T): ParamRef<T>;
163
+ /**
164
+ * Type-only schema helper for handlers.
165
+ *
166
+ * Use this instead of explicit generic parameters like `defineTable<Order>(...)`.
167
+ * It enables TypeScript to infer all generic types from the options object,
168
+ * avoiding the partial-inference problem where specifying one generic
169
+ * forces all others to their defaults.
170
+ *
171
+ * At runtime this is a no-op identity function — it simply returns the input unchanged.
172
+ * The type narrowing happens entirely at the TypeScript level.
173
+ *
174
+ * @example Resource-only table
175
+ * ```typescript
176
+ * type User = { id: string; email: string };
177
+ *
178
+ * // Before (breaks inference for context, deps, params):
179
+ * export const users = defineTable<User>({ pk: { name: "id", type: "string" } });
180
+ *
181
+ * // After (all generics inferred correctly):
182
+ * export const users = defineTable({
183
+ * pk: { name: "id", type: "string" },
184
+ * schema: typed<User>(),
185
+ * });
186
+ * ```
187
+ *
188
+ * @example Table with stream handler
189
+ * ```typescript
190
+ * export const orders = defineTable({
191
+ * pk: { name: "id", type: "string" },
192
+ * schema: typed<Order>(),
193
+ * context: async () => ({ db: createClient() }),
194
+ * onRecord: async ({ record, ctx }) => {
195
+ * // record.new is Order, ctx is { db: Client } — all inferred
196
+ * },
197
+ * });
198
+ * ```
199
+ */
200
+ declare function typed<T>(): (input: unknown) => T;
201
+
91
202
  /**
92
203
  * Query parameters for TableClient.query()
93
204
  */
@@ -374,87 +485,286 @@ type TableHandler<T = Record<string, unknown>, C = undefined, R = void, D = unde
374
485
  */
375
486
  declare const defineTable: <T = Record<string, unknown>, C = undefined, R = void, D extends Record<string, AnyTableHandler$2> | undefined = undefined, P extends Record<string, AnyParamRef> | undefined = undefined, S extends string[] | undefined = undefined>(options: DefineTableOptions<T, C, R, D, P, S>) => TableHandler<T, C, R, D, P, S>;
376
487
 
488
+ type AnyTableHandler$1 = TableHandler<any, any, any, any, any, any>;
489
+ /** Maps a deps declaration to resolved runtime client types */
490
+ type ResolveDeps$1<D> = {
491
+ [K in keyof D]: D[K] extends TableHandler<infer T, any, any, any, any> ? TableClient<T> : never;
492
+ };
493
+ /** HTTP methods supported by API Gateway */
494
+ type HttpMethod = "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
495
+ /** Short content-type aliases for common response formats */
496
+ type ContentType = "json" | "html" | "text" | "css" | "js" | "xml" | "csv" | "svg";
377
497
  /**
378
- * Configuration for a Lambda-served static site (API Gateway + Lambda)
498
+ * Incoming HTTP request object passed to the handler
379
499
  */
380
- type AppConfig = LambdaConfig & {
381
- /** Base URL path the site is served under (e.g., "/app") */
382
- path?: string;
383
- /** Directory containing the static site files, relative to project root */
384
- dir: string;
385
- /** Default file for directory requests (default: "index.html") */
386
- index?: string;
387
- /** SPA mode: serve index.html for all paths that don't match a file (default: false) */
388
- spa?: boolean;
389
- /** Shell command to run before deploy to generate site content (e.g., "npx astro build") */
390
- build?: string;
500
+ type HttpRequest = {
501
+ /** HTTP method (GET, POST, etc.) */
502
+ method: string;
503
+ /** Request path (e.g., "/users/123") */
504
+ path: string;
505
+ /** Request headers */
506
+ headers: Record<string, string | undefined>;
507
+ /** Query string parameters */
508
+ query: Record<string, string | undefined>;
509
+ /** Path parameters extracted from route (e.g., {id} -> params.id) */
510
+ params: Record<string, string | undefined>;
511
+ /** Parsed request body (JSON parsed if Content-Type is application/json) */
512
+ body: unknown;
513
+ /** Raw unparsed request body */
514
+ rawBody?: string;
391
515
  };
392
516
  /**
393
- * Internal handler object created by defineApp
394
- * @internal
517
+ * HTTP response returned from the handler
395
518
  */
396
- type AppHandler = {
397
- readonly __brand: "effortless-app";
398
- readonly config: AppConfig;
519
+ type HttpResponse = {
520
+ /** HTTP status code (e.g., 200, 404, 500) */
521
+ status: number;
522
+ /** Response body — JSON-serialized by default, or sent as string when contentType is set */
523
+ body?: unknown;
524
+ /**
525
+ * Short content-type alias. Resolves to full MIME type automatically:
526
+ * - `"json"` → `application/json` (default if omitted)
527
+ * - `"html"` → `text/html; charset=utf-8`
528
+ * - `"text"` → `text/plain; charset=utf-8`
529
+ * - `"css"` → `text/css; charset=utf-8`
530
+ * - `"js"` → `application/javascript; charset=utf-8`
531
+ * - `"xml"` → `application/xml; charset=utf-8`
532
+ * - `"csv"` → `text/csv; charset=utf-8`
533
+ * - `"svg"` → `image/svg+xml; charset=utf-8`
534
+ */
535
+ contentType?: ContentType;
536
+ /** Response headers (use for custom content-types not covered by contentType) */
537
+ headers?: Record<string, string>;
399
538
  };
400
539
  /**
401
- * Deploy a static site via Lambda + API Gateway.
402
- * Files are bundled into the Lambda ZIP and served with auto-detected content types.
403
- *
404
- * For CDN-backed sites (S3 + CloudFront), use {@link defineStaticSite} instead.
405
- *
406
- * @param options - Site configuration: path, directory, optional SPA mode
407
- * @returns Handler object used by the deployment system
408
- *
409
- * @example Basic static site
410
- * ```typescript
411
- * export const app = defineApp({
412
- * path: "/app",
413
- * dir: "src/webapp",
414
- * });
415
- * ```
540
+ * Configuration options extracted from DefineHttpOptions (without onRequest callback)
416
541
  */
417
- declare const defineApp: (options: AppConfig) => AppHandler;
418
-
542
+ type HttpConfig = LambdaWithPermissions & {
543
+ /** HTTP method for the route */
544
+ method: HttpMethod;
545
+ /** Route path (e.g., "/api/users", "/api/users/{id}") */
546
+ path: string;
547
+ };
419
548
  /**
420
- * Configuration for a static site handler (S3 + CloudFront)
549
+ * Handler function type for HTTP endpoints
550
+ *
551
+ * @typeParam T - Type of the validated request body (from schema function)
552
+ * @typeParam C - Type of the context/dependencies (from context function)
553
+ * @typeParam D - Type of the deps (from deps declaration)
554
+ * @typeParam P - Type of the params (from params declaration)
421
555
  */
422
- type StaticSiteConfig = {
423
- /** Handler name. Defaults to export name if not specified */
424
- name?: string;
425
- /** Directory containing the static site files, relative to project root */
426
- dir: string;
427
- /** Default file for directory requests (default: "index.html") */
428
- index?: string;
429
- /** SPA mode: serve index.html for all paths that don't match a file (default: false) */
430
- spa?: boolean;
431
- /** Shell command to run before deploy to generate site content (e.g., "npx astro build") */
432
- build?: string;
433
- };
556
+ type HttpHandlerFn<T = undefined, C = undefined, D = undefined, P = undefined, S extends string[] | undefined = undefined> = (args: {
557
+ req: HttpRequest;
558
+ } & ([T] extends [undefined] ? {} : {
559
+ data: T;
560
+ }) & ([C] extends [undefined] ? {} : {
561
+ ctx: C;
562
+ }) & ([D] extends [undefined] ? {} : {
563
+ deps: ResolveDeps$1<D>;
564
+ }) & ([P] extends [undefined] ? {} : {
565
+ params: ResolveParams<P>;
566
+ }) & ([S] extends [undefined] ? {} : {
567
+ readStatic: (path: string) => string;
568
+ })) => Promise<HttpResponse>;
434
569
  /**
435
- * Internal handler object created by defineStaticSite
436
- * @internal
570
+ * Context factory type conditional on whether params are declared.
571
+ * Without params: `() => C | Promise<C>`
572
+ * With params: `(args: { params: ResolveParams<P> }) => C | Promise<C>`
437
573
  */
438
- type StaticSiteHandler = {
439
- readonly __brand: "effortless-static-site";
440
- readonly config: StaticSiteConfig;
441
- };
574
+ type ContextFactory$1<C, P> = [P] extends [undefined] ? () => C | Promise<C> : (args: {
575
+ params: ResolveParams<P & {}>;
576
+ }) => C | Promise<C>;
442
577
  /**
443
- * Deploy a static site via S3 + CloudFront CDN.
444
- *
445
- * @param options - Static site configuration: directory, optional SPA mode, build command
446
- * @returns Handler object used by the deployment system
447
- *
448
- * @example Documentation site
449
- * ```typescript
450
- * export const docs = defineStaticSite({
451
- * dir: "dist",
452
- * build: "npx astro build",
453
- * });
454
- * ```
578
+ * Options for defining an HTTP endpoint
455
579
  *
456
- * @example SPA with client-side routing
457
- * ```typescript
580
+ * @typeParam T - Type of the validated request body (inferred from schema function)
581
+ * @typeParam C - Type of the context/dependencies returned by context function
582
+ * @typeParam D - Type of the deps (from deps declaration)
583
+ * @typeParam P - Type of the params (from params declaration)
584
+ */
585
+ type DefineHttpOptions<T = undefined, C = undefined, D extends Record<string, AnyTableHandler$1> | undefined = undefined, P extends Record<string, AnyParamRef> | undefined = undefined, S extends string[] | undefined = undefined> = HttpConfig & {
586
+ /**
587
+ * Decode/validate function for the request body.
588
+ * Called with the parsed body; should return typed data or throw on validation failure.
589
+ * When provided, the handler receives validated `data` and invalid requests get a 400 response.
590
+ *
591
+ * Works with any validation library:
592
+ * - Effect: `S.decodeUnknownSync(MySchema)`
593
+ * - Zod: `(body) => myZodSchema.parse(body)`
594
+ */
595
+ schema?: (input: unknown) => T;
596
+ /**
597
+ * Error handler called when schema validation or onRequest throws.
598
+ * Receives the error and request, returns an HttpResponse.
599
+ * If not provided, defaults to 400 for validation errors and 500 for handler errors.
600
+ */
601
+ onError?: (error: unknown, req: HttpRequest) => HttpResponse;
602
+ /**
603
+ * Factory function to create context/dependencies for the request handler.
604
+ * Called once on cold start, result is cached and reused across invocations.
605
+ * When params are declared, receives resolved params as argument.
606
+ * Supports both sync and async return values.
607
+ */
608
+ context?: ContextFactory$1<C, P>;
609
+ /**
610
+ * Dependencies on other handlers (tables, queues, etc.).
611
+ * Typed clients are injected into the handler via the `deps` argument.
612
+ */
613
+ deps?: D;
614
+ /**
615
+ * SSM Parameter Store parameters.
616
+ * Declare with `param()` helper. Values are fetched and cached at cold start.
617
+ * Typed values are injected into the handler via the `params` argument.
618
+ */
619
+ params?: P;
620
+ /**
621
+ * Static file glob patterns to bundle into the Lambda ZIP.
622
+ * Files are accessible at runtime via the `readStatic` callback argument.
623
+ */
624
+ static?: S;
625
+ /** HTTP request handler function */
626
+ onRequest: HttpHandlerFn<T, C, D, P, S>;
627
+ };
628
+ /**
629
+ * Internal handler object created by defineHttp
630
+ * @internal
631
+ */
632
+ type HttpHandler<T = undefined, C = undefined, D = undefined, P = undefined, S extends string[] | undefined = undefined> = {
633
+ readonly __brand: "effortless-http";
634
+ readonly config: HttpConfig;
635
+ readonly schema?: (input: unknown) => T;
636
+ readonly onError?: (error: unknown, req: HttpRequest) => HttpResponse;
637
+ readonly context?: (...args: any[]) => C | Promise<C>;
638
+ readonly deps?: D;
639
+ readonly params?: P;
640
+ readonly static?: string[];
641
+ readonly onRequest: HttpHandlerFn<T, C, D, P, S>;
642
+ };
643
+ /**
644
+ * Define an HTTP endpoint that creates an API Gateway route + Lambda function
645
+ *
646
+ * @typeParam T - Type of the validated request body (inferred from schema function)
647
+ * @typeParam C - Type of the context/dependencies (inferred from context function)
648
+ * @typeParam D - Type of the deps (from deps declaration)
649
+ * @typeParam P - Type of the params (from params declaration)
650
+ * @param options - Configuration, optional schema, optional context factory, and request handler
651
+ * @returns Handler object used by the deployment system
652
+ *
653
+ * @example Basic GET endpoint
654
+ * ```typescript
655
+ * export const hello = defineHttp({
656
+ * method: "GET",
657
+ * path: "/hello",
658
+ * onRequest: async ({ req }) => ({
659
+ * status: 200,
660
+ * body: { message: "Hello World!" }
661
+ * })
662
+ * });
663
+ * ```
664
+ *
665
+ * @example With SSM parameters
666
+ * ```typescript
667
+ * import { param } from "effortless-aws";
668
+ *
669
+ * export const api = defineHttp({
670
+ * method: "GET",
671
+ * path: "/orders",
672
+ * params: {
673
+ * dbUrl: param("database-url"),
674
+ * },
675
+ * context: async ({ params }) => ({
676
+ * pool: createPool(params.dbUrl),
677
+ * }),
678
+ * onRequest: async ({ req, ctx, params }) => ({
679
+ * status: 200,
680
+ * body: { dbUrl: params.dbUrl }
681
+ * })
682
+ * });
683
+ * ```
684
+ */
685
+ declare const defineHttp: <T = undefined, C = undefined, D extends Record<string, AnyTableHandler$1> | undefined = undefined, P extends Record<string, AnyParamRef> | undefined = undefined, S extends string[] | undefined = undefined>(options: DefineHttpOptions<T, C, D, P, S>) => HttpHandler<T, C, D, P, S>;
686
+
687
+ /**
688
+ * Configuration for a Lambda-served static site (API Gateway + Lambda)
689
+ */
690
+ type AppConfig = LambdaConfig & {
691
+ /** Base URL path the site is served under (e.g., "/app") */
692
+ path?: string;
693
+ /** Directory containing the static site files, relative to project root */
694
+ dir: string;
695
+ /** Default file for directory requests (default: "index.html") */
696
+ index?: string;
697
+ /** SPA mode: serve index.html for all paths that don't match a file (default: false) */
698
+ spa?: boolean;
699
+ /** Shell command to run before deploy to generate site content (e.g., "npx astro build") */
700
+ build?: string;
701
+ };
702
+ /**
703
+ * Internal handler object created by defineApp
704
+ * @internal
705
+ */
706
+ type AppHandler = {
707
+ readonly __brand: "effortless-app";
708
+ readonly config: AppConfig;
709
+ };
710
+ /**
711
+ * Deploy a static site via Lambda + API Gateway.
712
+ * Files are bundled into the Lambda ZIP and served with auto-detected content types.
713
+ *
714
+ * For CDN-backed sites (S3 + CloudFront), use {@link defineStaticSite} instead.
715
+ *
716
+ * @param options - Site configuration: path, directory, optional SPA mode
717
+ * @returns Handler object used by the deployment system
718
+ *
719
+ * @example Basic static site
720
+ * ```typescript
721
+ * export const app = defineApp({
722
+ * path: "/app",
723
+ * dir: "src/webapp",
724
+ * });
725
+ * ```
726
+ */
727
+ declare const defineApp: (options: AppConfig) => AppHandler;
728
+
729
+ /**
730
+ * Configuration for a static site handler (S3 + CloudFront)
731
+ */
732
+ type StaticSiteConfig = {
733
+ /** Handler name. Defaults to export name if not specified */
734
+ name?: string;
735
+ /** Directory containing the static site files, relative to project root */
736
+ dir: string;
737
+ /** Default file for directory requests (default: "index.html") */
738
+ index?: string;
739
+ /** SPA mode: serve index.html for all paths that don't match a file (default: false) */
740
+ spa?: boolean;
741
+ /** Shell command to run before deploy to generate site content (e.g., "npx astro build") */
742
+ build?: string;
743
+ };
744
+ /**
745
+ * Internal handler object created by defineStaticSite
746
+ * @internal
747
+ */
748
+ type StaticSiteHandler = {
749
+ readonly __brand: "effortless-static-site";
750
+ readonly config: StaticSiteConfig;
751
+ };
752
+ /**
753
+ * Deploy a static site via S3 + CloudFront CDN.
754
+ *
755
+ * @param options - Static site configuration: directory, optional SPA mode, build command
756
+ * @returns Handler object used by the deployment system
757
+ *
758
+ * @example Documentation site
759
+ * ```typescript
760
+ * export const docs = defineStaticSite({
761
+ * dir: "dist",
762
+ * build: "npx astro build",
763
+ * });
764
+ * ```
765
+ *
766
+ * @example SPA with client-side routing
767
+ * ```typescript
458
768
  * export const app = defineStaticSite({
459
769
  * dir: "dist",
460
770
  * spa: true,
@@ -464,9 +774,9 @@ type StaticSiteHandler = {
464
774
  */
465
775
  declare const defineStaticSite: (options: StaticSiteConfig) => StaticSiteHandler;
466
776
 
467
- type AnyTableHandler$1 = TableHandler<any, any, any, any, any, any>;
777
+ type AnyTableHandler = TableHandler<any, any, any, any, any, any>;
468
778
  /** Maps a deps declaration to resolved runtime client types */
469
- type ResolveDeps$1<D> = {
779
+ type ResolveDeps<D> = {
470
780
  [K in keyof D]: D[K] extends TableHandler<infer T, any, any, any, any> ? TableClient<T> : never;
471
781
  };
472
782
  /**
@@ -519,7 +829,7 @@ type FifoQueueConfig = LambdaWithPermissions & {
519
829
  * Without params: `() => C | Promise<C>`
520
830
  * With params: `(args: { params: ResolveParams<P> }) => C | Promise<C>`
521
831
  */
522
- type ContextFactory$1<C, P> = [P] extends [undefined] ? () => C | Promise<C> : (args: {
832
+ type ContextFactory<C, P> = [P] extends [undefined] ? () => C | Promise<C> : (args: {
523
833
  params: ResolveParams<P & {}>;
524
834
  }) => C | Promise<C>;
525
835
  /**
@@ -531,7 +841,7 @@ type FifoQueueMessageFn<T = unknown, C = undefined, D = undefined, P = undefined
531
841
  } & ([C] extends [undefined] ? {} : {
532
842
  ctx: C;
533
843
  }) & ([D] extends [undefined] ? {} : {
534
- deps: ResolveDeps$1<D>;
844
+ deps: ResolveDeps<D>;
535
845
  }) & ([P] extends [undefined] ? {} : {
536
846
  params: ResolveParams<P>;
537
847
  }) & ([S] extends [undefined] ? {} : {
@@ -546,7 +856,7 @@ type FifoQueueBatchFn<T = unknown, C = undefined, D = undefined, P = undefined,
546
856
  } & ([C] extends [undefined] ? {} : {
547
857
  ctx: C;
548
858
  }) & ([D] extends [undefined] ? {} : {
549
- deps: ResolveDeps$1<D>;
859
+ deps: ResolveDeps<D>;
550
860
  }) & ([P] extends [undefined] ? {} : {
551
861
  params: ResolveParams<P>;
552
862
  }) & ([S] extends [undefined] ? {} : {
@@ -569,7 +879,7 @@ type DefineFifoQueueBase<T = unknown, C = undefined, D = undefined, P = undefine
569
879
  * Called once on cold start, result is cached and reused across invocations.
570
880
  * When params are declared, receives resolved params as argument.
571
881
  */
572
- context?: ContextFactory$1<C, P>;
882
+ context?: ContextFactory<C, P>;
573
883
  /**
574
884
  * Dependencies on other handlers (tables, queues, etc.).
575
885
  * Typed clients are injected into the handler via the `deps` argument.
@@ -596,7 +906,7 @@ type DefineFifoQueueWithOnBatch<T = unknown, C = undefined, D = undefined, P = u
596
906
  onBatch: FifoQueueBatchFn<T, C, D, P, S>;
597
907
  onMessage?: never;
598
908
  };
599
- type DefineFifoQueueOptions<T = unknown, C = undefined, D extends Record<string, AnyTableHandler$1> | undefined = undefined, P extends Record<string, AnyParamRef> | undefined = undefined, S extends string[] | undefined = undefined> = DefineFifoQueueWithOnMessage<T, C, D, P, S> | DefineFifoQueueWithOnBatch<T, C, D, P, S>;
909
+ type DefineFifoQueueOptions<T = unknown, C = undefined, D extends Record<string, AnyTableHandler> | undefined = undefined, P extends Record<string, AnyParamRef> | undefined = undefined, S extends string[] | undefined = undefined> = DefineFifoQueueWithOnMessage<T, C, D, P, S> | DefineFifoQueueWithOnBatch<T, C, D, P, S>;
600
910
  /**
601
911
  * Internal handler object created by defineFifoQueue
602
912
  * @internal
@@ -643,316 +953,6 @@ type FifoQueueHandler<T = unknown, C = undefined, D = undefined, P = undefined,
643
953
  * });
644
954
  * ```
645
955
  */
646
- declare const defineFifoQueue: <T = unknown, C = undefined, D extends Record<string, AnyTableHandler$1> | undefined = undefined, P extends Record<string, AnyParamRef> | undefined = undefined, S extends string[] | undefined = undefined>(options: DefineFifoQueueOptions<T, C, D, P, S>) => FifoQueueHandler<T, C, D, P, S>;
647
-
648
- type AwsService = "dynamodb" | "s3" | "sqs" | "sns" | "ses" | "ssm" | "lambda" | "events" | "secretsmanager" | "cognito-idp" | "logs";
649
- type Permission = `${AwsService}:${string}` | (string & {});
650
- /** Logging verbosity level for Lambda handlers */
651
- type LogLevel = "error" | "info" | "debug";
652
- /**
653
- * Common Lambda configuration shared by all handler types.
654
- */
655
- type LambdaConfig = {
656
- /** Handler name. Defaults to export name if not specified */
657
- name?: string;
658
- /** Lambda memory in MB (default: 256) */
659
- memory?: number;
660
- /** Lambda timeout in seconds (default: 30) */
661
- timeout?: number;
662
- /** Logging verbosity: "error" (errors only), "info" (+ execution summary), "debug" (+ input/output). Default: "info" */
663
- logLevel?: LogLevel;
664
- };
665
- /**
666
- * Lambda configuration with additional IAM permissions.
667
- * Used by handler types that support custom permissions (http, table, fifo-queue).
668
- */
669
- type LambdaWithPermissions = LambdaConfig & {
670
- /** Additional IAM permissions for the Lambda */
671
- permissions?: Permission[];
672
- };
673
- type AnyParamRef = ParamRef<any>;
674
- /**
675
- * Reference to an SSM Parameter Store parameter.
676
- *
677
- * @typeParam T - The resolved type after optional transform (default: string)
678
- */
679
- type ParamRef<T = string> = {
680
- readonly __brand: "effortless-param";
681
- readonly key: string;
682
- readonly transform?: (raw: string) => T;
683
- };
684
- /**
685
- * Maps a params declaration to resolved value types.
686
- *
687
- * @typeParam P - Record of param names to ParamRef instances
688
- */
689
- type ResolveParams<P> = {
690
- [K in keyof P]: P[K] extends ParamRef<infer T> ? T : never;
691
- };
692
- /**
693
- * Declare an SSM Parameter Store parameter.
694
- *
695
- * The key is combined with project and stage at deploy time to form the full
696
- * SSM path: `/${project}/${stage}/${key}`.
697
- *
698
- * @param key - Parameter key (e.g., "database-url")
699
- * @param transform - Optional function to transform the raw string value
700
- * @returns A ParamRef used by the deployment and runtime systems
701
- *
702
- * @example Simple string parameter
703
- * ```typescript
704
- * params: {
705
- * dbUrl: param("database-url"),
706
- * }
707
- * ```
708
- *
709
- * @example With transform (e.g., TOML parsing)
710
- * ```typescript
711
- * import TOML from "smol-toml";
712
- *
713
- * params: {
714
- * config: param("app-config", TOML.parse),
715
- * }
716
- * ```
717
- */
718
- declare function param(key: string): ParamRef<string>;
719
- declare function param<T>(key: string, transform: (raw: string) => T): ParamRef<T>;
720
- /**
721
- * Type-only schema helper for handlers.
722
- *
723
- * Use this instead of explicit generic parameters like `defineTable<Order>(...)`.
724
- * It enables TypeScript to infer all generic types from the options object,
725
- * avoiding the partial-inference problem where specifying one generic
726
- * forces all others to their defaults.
727
- *
728
- * At runtime this is a no-op identity function — it simply returns the input unchanged.
729
- * The type narrowing happens entirely at the TypeScript level.
730
- *
731
- * @example Resource-only table
732
- * ```typescript
733
- * type User = { id: string; email: string };
734
- *
735
- * // Before (breaks inference for context, deps, params):
736
- * export const users = defineTable<User>({ pk: { name: "id", type: "string" } });
737
- *
738
- * // After (all generics inferred correctly):
739
- * export const users = defineTable({
740
- * pk: { name: "id", type: "string" },
741
- * schema: typed<User>(),
742
- * });
743
- * ```
744
- *
745
- * @example Table with stream handler
746
- * ```typescript
747
- * export const orders = defineTable({
748
- * pk: { name: "id", type: "string" },
749
- * schema: typed<Order>(),
750
- * context: async () => ({ db: createClient() }),
751
- * onRecord: async ({ record, ctx }) => {
752
- * // record.new is Order, ctx is { db: Client } — all inferred
753
- * },
754
- * });
755
- * ```
756
- */
757
- declare function typed<T>(): (input: unknown) => T;
758
-
759
- type AnyTableHandler = TableHandler<any, any, any, any, any, any>;
760
- /** Maps a deps declaration to resolved runtime client types */
761
- type ResolveDeps<D> = {
762
- [K in keyof D]: D[K] extends TableHandler<infer T, any, any, any, any> ? TableClient<T> : never;
763
- };
764
- /** HTTP methods supported by API Gateway */
765
- type HttpMethod = "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
766
- /** Short content-type aliases for common response formats */
767
- type ContentType = "json" | "html" | "text" | "css" | "js" | "xml" | "csv" | "svg";
768
- /**
769
- * Incoming HTTP request object passed to the handler
770
- */
771
- type HttpRequest = {
772
- /** HTTP method (GET, POST, etc.) */
773
- method: string;
774
- /** Request path (e.g., "/users/123") */
775
- path: string;
776
- /** Request headers */
777
- headers: Record<string, string | undefined>;
778
- /** Query string parameters */
779
- query: Record<string, string | undefined>;
780
- /** Path parameters extracted from route (e.g., {id} -> params.id) */
781
- params: Record<string, string | undefined>;
782
- /** Parsed request body (JSON parsed if Content-Type is application/json) */
783
- body: unknown;
784
- /** Raw unparsed request body */
785
- rawBody?: string;
786
- };
787
- /**
788
- * HTTP response returned from the handler
789
- */
790
- type HttpResponse = {
791
- /** HTTP status code (e.g., 200, 404, 500) */
792
- status: number;
793
- /** Response body — JSON-serialized by default, or sent as string when contentType is set */
794
- body?: unknown;
795
- /**
796
- * Short content-type alias. Resolves to full MIME type automatically:
797
- * - `"json"` → `application/json` (default if omitted)
798
- * - `"html"` → `text/html; charset=utf-8`
799
- * - `"text"` → `text/plain; charset=utf-8`
800
- * - `"css"` → `text/css; charset=utf-8`
801
- * - `"js"` → `application/javascript; charset=utf-8`
802
- * - `"xml"` → `application/xml; charset=utf-8`
803
- * - `"csv"` → `text/csv; charset=utf-8`
804
- * - `"svg"` → `image/svg+xml; charset=utf-8`
805
- */
806
- contentType?: ContentType;
807
- /** Response headers (use for custom content-types not covered by contentType) */
808
- headers?: Record<string, string>;
809
- };
810
- /**
811
- * Configuration options extracted from DefineHttpOptions (without onRequest callback)
812
- */
813
- type HttpConfig = LambdaWithPermissions & {
814
- /** HTTP method for the route */
815
- method: HttpMethod;
816
- /** Route path (e.g., "/api/users", "/api/users/{id}") */
817
- path: string;
818
- };
819
- /**
820
- * Handler function type for HTTP endpoints
821
- *
822
- * @typeParam T - Type of the validated request body (from schema function)
823
- * @typeParam C - Type of the context/dependencies (from context function)
824
- * @typeParam D - Type of the deps (from deps declaration)
825
- * @typeParam P - Type of the params (from params declaration)
826
- */
827
- type HttpHandlerFn<T = undefined, C = undefined, D = undefined, P = undefined, S extends string[] | undefined = undefined> = (args: {
828
- req: HttpRequest;
829
- } & ([T] extends [undefined] ? {} : {
830
- data: T;
831
- }) & ([C] extends [undefined] ? {} : {
832
- ctx: C;
833
- }) & ([D] extends [undefined] ? {} : {
834
- deps: ResolveDeps<D>;
835
- }) & ([P] extends [undefined] ? {} : {
836
- params: ResolveParams<P>;
837
- }) & ([S] extends [undefined] ? {} : {
838
- readStatic: (path: string) => string;
839
- })) => Promise<HttpResponse>;
840
- /**
841
- * Context factory type — conditional on whether params are declared.
842
- * Without params: `() => C | Promise<C>`
843
- * With params: `(args: { params: ResolveParams<P> }) => C | Promise<C>`
844
- */
845
- type ContextFactory<C, P> = [P] extends [undefined] ? () => C | Promise<C> : (args: {
846
- params: ResolveParams<P & {}>;
847
- }) => C | Promise<C>;
848
- /**
849
- * Options for defining an HTTP endpoint
850
- *
851
- * @typeParam T - Type of the validated request body (inferred from schema function)
852
- * @typeParam C - Type of the context/dependencies returned by context function
853
- * @typeParam D - Type of the deps (from deps declaration)
854
- * @typeParam P - Type of the params (from params declaration)
855
- */
856
- type DefineHttpOptions<T = undefined, C = undefined, D extends Record<string, AnyTableHandler> | undefined = undefined, P extends Record<string, AnyParamRef> | undefined = undefined, S extends string[] | undefined = undefined> = HttpConfig & {
857
- /**
858
- * Decode/validate function for the request body.
859
- * Called with the parsed body; should return typed data or throw on validation failure.
860
- * When provided, the handler receives validated `data` and invalid requests get a 400 response.
861
- *
862
- * Works with any validation library:
863
- * - Effect: `S.decodeUnknownSync(MySchema)`
864
- * - Zod: `(body) => myZodSchema.parse(body)`
865
- */
866
- schema?: (input: unknown) => T;
867
- /**
868
- * Error handler called when schema validation or onRequest throws.
869
- * Receives the error and request, returns an HttpResponse.
870
- * If not provided, defaults to 400 for validation errors and 500 for handler errors.
871
- */
872
- onError?: (error: unknown, req: HttpRequest) => HttpResponse;
873
- /**
874
- * Factory function to create context/dependencies for the request handler.
875
- * Called once on cold start, result is cached and reused across invocations.
876
- * When params are declared, receives resolved params as argument.
877
- * Supports both sync and async return values.
878
- */
879
- context?: ContextFactory<C, P>;
880
- /**
881
- * Dependencies on other handlers (tables, queues, etc.).
882
- * Typed clients are injected into the handler via the `deps` argument.
883
- */
884
- deps?: D;
885
- /**
886
- * SSM Parameter Store parameters.
887
- * Declare with `param()` helper. Values are fetched and cached at cold start.
888
- * Typed values are injected into the handler via the `params` argument.
889
- */
890
- params?: P;
891
- /**
892
- * Static file glob patterns to bundle into the Lambda ZIP.
893
- * Files are accessible at runtime via the `readStatic` callback argument.
894
- */
895
- static?: S;
896
- /** HTTP request handler function */
897
- onRequest: HttpHandlerFn<T, C, D, P, S>;
898
- };
899
- /**
900
- * Internal handler object created by defineHttp
901
- * @internal
902
- */
903
- type HttpHandler<T = undefined, C = undefined, D = undefined, P = undefined, S extends string[] | undefined = undefined> = {
904
- readonly __brand: "effortless-http";
905
- readonly config: HttpConfig;
906
- readonly schema?: (input: unknown) => T;
907
- readonly onError?: (error: unknown, req: HttpRequest) => HttpResponse;
908
- readonly context?: (...args: any[]) => C | Promise<C>;
909
- readonly deps?: D;
910
- readonly params?: P;
911
- readonly static?: string[];
912
- readonly onRequest: HttpHandlerFn<T, C, D, P, S>;
913
- };
914
- /**
915
- * Define an HTTP endpoint that creates an API Gateway route + Lambda function
916
- *
917
- * @typeParam T - Type of the validated request body (inferred from schema function)
918
- * @typeParam C - Type of the context/dependencies (inferred from context function)
919
- * @typeParam D - Type of the deps (from deps declaration)
920
- * @typeParam P - Type of the params (from params declaration)
921
- * @param options - Configuration, optional schema, optional context factory, and request handler
922
- * @returns Handler object used by the deployment system
923
- *
924
- * @example Basic GET endpoint
925
- * ```typescript
926
- * export const hello = defineHttp({
927
- * method: "GET",
928
- * path: "/hello",
929
- * onRequest: async ({ req }) => ({
930
- * status: 200,
931
- * body: { message: "Hello World!" }
932
- * })
933
- * });
934
- * ```
935
- *
936
- * @example With SSM parameters
937
- * ```typescript
938
- * import { param } from "effortless-aws";
939
- *
940
- * export const api = defineHttp({
941
- * method: "GET",
942
- * path: "/orders",
943
- * params: {
944
- * dbUrl: param("database-url"),
945
- * },
946
- * context: async ({ params }) => ({
947
- * pool: createPool(params.dbUrl),
948
- * }),
949
- * onRequest: async ({ req, ctx, params }) => ({
950
- * status: 200,
951
- * body: { dbUrl: params.dbUrl }
952
- * })
953
- * });
954
- * ```
955
- */
956
- declare const defineHttp: <T = undefined, C = undefined, D extends Record<string, AnyTableHandler> | undefined = undefined, P extends Record<string, AnyParamRef> | undefined = undefined, S extends string[] | undefined = undefined>(options: DefineHttpOptions<T, C, D, P, S>) => HttpHandler<T, C, D, P, S>;
956
+ declare const defineFifoQueue: <T = unknown, C = undefined, D extends Record<string, AnyTableHandler> | undefined = undefined, P extends Record<string, AnyParamRef> | undefined = undefined, S extends string[] | undefined = undefined>(options: DefineFifoQueueOptions<T, C, D, P, S>) => FifoQueueHandler<T, C, D, P, S>;
957
957
 
958
- export { type AppConfig, type AppHandler, type ContentType, type DefineFifoQueueOptions, type DefineHttpOptions, type DefineTableOptions, type EffortlessConfig, type FailedRecord, type FifoQueueBatchFn, type FifoQueueConfig, type FifoQueueHandler, type FifoQueueMessage, type FifoQueueMessageFn, type HttpConfig, type HttpHandler, type HttpHandlerFn, type HttpMethod, type HttpRequest, type HttpResponse, type KeyType, type LambdaConfig, type LambdaWithPermissions, type LogLevel, type ParamRef, type QueryParams, type ResolveDeps, type ResolveParams, type StaticSiteConfig, type StaticSiteHandler, type StreamView, type TableBatchCompleteFn, type TableBatchFn, type TableClient, type TableConfig, type TableHandler, type TableKey, type TableRecord, type TableRecordFn, defineApp, defineConfig, defineFifoQueue, defineHttp, defineStaticSite, defineTable, param, typed };
958
+ export { type AppConfig, type AppHandler, type ContentType, type DefineFifoQueueOptions, type DefineHttpOptions, type DefineTableOptions, type EffortlessConfig, type FailedRecord, type FifoQueueBatchFn, type FifoQueueConfig, type FifoQueueHandler, type FifoQueueMessage, type FifoQueueMessageFn, type HttpConfig, type HttpHandler, type HttpHandlerFn, type HttpMethod, type HttpRequest, type HttpResponse, type KeyType, type LambdaConfig, type LambdaWithPermissions, type LogLevel, type ParamRef, type QueryParams, type ResolveDeps$1 as ResolveDeps, type ResolveParams, type StaticSiteConfig, type StaticSiteHandler, type StreamView, type TableBatchCompleteFn, type TableBatchFn, type TableClient, type TableConfig, type TableHandler, type TableKey, type TableRecord, type TableRecordFn, defineApp, defineConfig, defineFifoQueue, defineHttp, defineStaticSite, defineTable, param, typed };