@karmaniverous/smoz 0.2.3 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,151 +1,117 @@
1
+ import { ZodOpenApiOperationObject, ZodOpenApiPathItemObject, ZodOpenApiPathsObject } from 'zod-openapi';
2
+ import * as aws_lambda from 'aws-lambda';
3
+ import { APIGatewayProxyEvent, Context, APIGatewayProxyEventV2, ALBEvent, SQSEvent, SNSEvent, S3Event, DynamoDBStreamEvent, KinesisStreamEvent, EventBridgeEvent, CloudWatchLogsEvent, SESEvent, CloudFrontRequestEvent, FirehoseTransformationEvent, CognitoUserPoolTriggerEvent } from 'aws-lambda';
1
4
  import { AWS } from '@serverless/typescript';
2
- import { z, ZodObject, ZodRawShape } from 'zod';
3
- import { ZodOpenApiPathsObject, ZodOpenApiPathItemObject } from 'zod-openapi';
4
- import { buildStageArtifacts } from '@/src/core/buildStageArtifacts';
5
- import { EnvSchemaNode as EnvSchemaNode$1 } from '@/src/core/defineAppConfig';
6
- import { serverlessConfigSchema, AppServerlessConfig } from '@/src/core/serverlessConfig';
7
- import { ZodObj } from '@/src/core/types';
8
- import { AppHttpConfig as AppHttpConfig$1 } from '@/src/http/middleware/httpStackCustomization';
9
- import { MethodKey as MethodKey$1, FunctionConfig } from '@/src/types/FunctionConfig';
10
- import { HttpContext as HttpContext$1 } from '@/src/types/HttpContext';
11
- import { APIGatewayProxyEvent, APIGatewayProxyEventV2, ALBEvent, SQSEvent, SNSEvent, S3Event, DynamoDBStreamEvent, KinesisStreamEvent, EventBridgeEvent, CloudWatchLogsEvent, SESEvent, CloudFrontRequestEvent, FirehoseTransformationEvent, CognitoUserPoolTriggerEvent, Context } from 'aws-lambda';
12
- import { stagesFactory } from '@/src/serverless/stagesFactory';
13
- import { SecurityContextHttpEventMap as SecurityContextHttpEventMap$1 } from '@/src/types/SecurityContextHttpEventMap';
14
- import { BaseEventTypeMap } from '@/src/core/baseEventTypeMapSchema';
15
- import { EnvAttached } from '@/src/core/defineFunctionConfig';
16
- import { Handler as Handler$1 } from '@/src/types/Handler';
5
+ import { ZodObject, ZodRawShape, z } from 'zod';
17
6
  import { MiddlewareObj } from '@middy/core';
18
7
  import httpContentNegotiation from '@middy/http-content-negotiation';
19
8
  import httpCors from '@middy/http-cors';
20
9
  import httpErrorHandler from '@middy/http-error-handler';
21
10
  import httpHeaderNormalizer from '@middy/http-header-normalizer';
22
11
  import httpJsonBodyParser from '@middy/http-json-body-parser';
23
- import { HttpTransform, PhasedArrays } from '@/src/http/middleware/transformUtils';
24
- import { ConsoleLogger as ConsoleLogger$1 } from '@/src/types/Loggable';
25
- import { DeepOverride } from '@/src/types/DeepOverride';
26
- import { PropFromUnion } from '@/src/types/PropFromUnion';
27
12
 
28
- interface AppInit<GlobalParamsSchema extends ZodObj, StageParamsSchema extends ZodObj, EventTypeMapSchema extends ZodObj> {
29
- appRootAbs: string;
30
- globalParamsSchema: GlobalParamsSchema;
31
- stageParamsSchema: StageParamsSchema;
32
- eventTypeMapSchema?: EventTypeMapSchema;
33
- /** Accept raw serverless config; App will parse it internally. */
34
- serverless: z.input<typeof serverlessConfigSchema>;
35
- global: {
36
- params: z.infer<GlobalParamsSchema>;
37
- envKeys: readonly (keyof z.infer<GlobalParamsSchema>)[];
38
- };
39
- stage: {
40
- /** Accept raw stage param objects; App will parse with (global.partial + stage) */
41
- params: Record<string, Record<string, unknown>>;
42
- envKeys: readonly (keyof z.infer<StageParamsSchema>)[];
43
- };
44
- /**
45
- * HTTP tokens to treat as HTTP at runtime (widenable).
46
- * Defaults to ['rest', 'http'].
47
- */
48
- httpEventTypeTokens?: readonly (keyof z.infer<EventTypeMapSchema>)[];
49
- /**
50
- * Optional app-level HTTP middleware customization (defaults & profiles).
51
- */
52
- http?: AppHttpConfig$1;
53
- /** Optional defaults applied to every function (merged per registration). */
54
- functionDefaults?: {
55
- fnEnvKeys?: readonly string[];
13
+ /**
14
+ * Makes specified properties of `T` required.
15
+ *
16
+ * @typeParam T - The type to make properties required.
17
+ * @typeParam U - The properties to make required.
18
+ *
19
+ * @example
20
+ * interface A { x?: number; y?: string; z: boolean }
21
+ * // => { x: number; y?: string; z: boolean }
22
+ * type R = MakeRequired<A, 'x'>;
23
+ */
24
+ type MakeRequired<T extends object, U extends keyof T> = {
25
+ [P in keyof T as P extends U ? never : P]: T[P];
26
+ } & Required<Pick<T, U>>;
27
+
28
+ /**
29
+ * A base OpenAPI operation object, with the `summary` field required.
30
+ *
31
+ * @see https://spec.openapis.org/oas/v3.1.0#operation-object * @remarks
32
+ * Use this when registering per‑function OpenAPI operations via `fn.openapi(baseOperation)`.
33
+ * The SMOZ registry fills in `operationId`, augments `summary` with the context,
34
+ * and merges tags for each configured context.
35
+ */
36
+ type BaseOperation = MakeRequired<Omit<ZodOpenApiOperationObject, 'operationId'>, 'summary'>;
37
+
38
+ type Dict<T> = Record<string, T>;
39
+ type StagesFactoryInput<GlobalParams extends Record<string, unknown>, StageParams extends Record<string, unknown>> = {
40
+ globalParamsSchema: ZodObject<ZodRawShape>;
41
+ stageParamsSchema: ZodObject<ZodRawShape>;
42
+ globalParams: GlobalParams;
43
+ globalEnvKeys: readonly (keyof GlobalParams)[];
44
+ stageEnvKeys: readonly (keyof StageParams)[];
45
+ stages: Dict<StageParams>;
46
+ };
47
+ type StagesFactoryOutput<GlobalParams extends Record<string, unknown>, StageParams extends Record<string, unknown>> = {
48
+ /** Serverless 'params' object: { default: { params: GlobalParams }, <stage>: { params: StageParams } } */
49
+ stages: {
50
+ default: {
51
+ params: GlobalParams;
52
+ };
53
+ } & {
54
+ [K in keyof Dict<StageParams>]: {
55
+ params: StageParams;
56
+ };
56
57
  };
57
- }
58
+ /** Provider-level environment mapping for globally exposed keys */
59
+ environment: Record<string, string>;
60
+ /** Helper to build per-function environment mapping for additional keys */
61
+ buildFnEnv: (fnEnvKeys?: readonly (keyof (GlobalParams & StageParams))[]) => Record<string, string>;
62
+ };
58
63
  /**
59
- * Application class. *
60
- * @typeParam GlobalParamsSchema - Zod object schema for global parameters
61
- * @typeParam StageParamsSchema - Zod object schema for per‑stage parameters
62
- * @typeParam EventTypeMapSchema - Zod object schema mapping event tokens to runtime types
63
- */ declare class App<GlobalParamsSchema extends ZodObj, StageParamsSchema extends ZodObj, EventTypeMapSchema extends ZodObj> {
64
- /** Helper alias for stage artifacts type */
65
- private static readonly _stageArtifactsType;
66
- readonly appRootAbs: string;
67
- readonly globalParamsSchema: GlobalParamsSchema;
68
- readonly stageParamsSchema: StageParamsSchema;
69
- readonly eventTypeMapSchema: EventTypeMapSchema;
70
- readonly serverless: AppServerlessConfig;
71
- readonly global: EnvSchemaNode$1<GlobalParamsSchema>;
72
- readonly stage: EnvSchemaNode$1<StageParamsSchema>;
73
- readonly stages: ReturnType<typeof buildStageArtifacts>['stages'];
74
- readonly environment: ReturnType<typeof buildStageArtifacts>['environment'];
75
- readonly buildFnEnv: ReturnType<typeof buildStageArtifacts>['buildFnEnv'];
76
- readonly http: AppHttpConfig$1;
77
- readonly httpEventTypeTokens: readonly string[];
78
- private readonly registry;
79
- private constructor(); /**
80
- * Ergonomic constructor for schema‑first inference.
81
- *
82
- * @param init - initialization object (schemas, serverless defaults, params/envKeys)
83
- * @returns a new App instance
84
- */
85
- static create<GlobalParamsSchema extends ZodObj, StageParamsSchema extends ZodObj, EventTypeMapSchema extends ZodObj>(init: AppInit<GlobalParamsSchema, StageParamsSchema, EventTypeMapSchema>): App<GlobalParamsSchema, StageParamsSchema, EventTypeMapSchema>;
86
- /**
87
- * Register a function (HTTP or non‑HTTP).
88
- *
89
- * @typeParam EventType - A key from your eventTypeMapSchema (e.g., 'rest' | 'http' | 'sqs' | 'step')
90
- * @typeParam EventSchema - Optional Zod schema validated BEFORE the handler (refines event shape)
91
- * @typeParam ResponseSchema - Optional Zod schema validated AFTER the handler (refines response shape)
92
- * @param options - per‑function configuration (method/basePath/httpContexts for HTTP; serverless extras for non‑HTTP)
93
- * @returns a per‑function API: { handler(business), openapi(baseOperation), serverless(extras) }
94
- */
95
- defineFunction<EventType extends Extract<keyof z.infer<EventTypeMapSchema>, string>, EventSchema extends z.ZodType | undefined, ResponseSchema extends z.ZodType | undefined>(options: {
96
- functionName?: string;
97
- eventType: EventType;
98
- method?: MethodKey$1;
99
- basePath?: string;
100
- httpContexts?: readonly HttpContext$1[];
101
- contentType?: string;
102
- eventSchema?: EventSchema;
103
- responseSchema?: ResponseSchema;
104
- fnEnvKeys?: readonly (keyof (z.infer<GlobalParamsSchema> & z.infer<StageParamsSchema>))[];
105
- callerModuleUrl: string;
106
- endpointsRootAbs: string;
107
- }): any;
108
- /**
109
- * Aggregate Serverless function definitions across the registry.
110
- *
111
- * @returns An AWS['functions'] object suitable for serverless.ts
112
- */
113
- buildAllServerlessFunctions(): AWS['functions'];
114
- /**
115
- * Aggregate OpenAPI path items across the registry.
116
- *
117
- * @returns ZodOpenApiPathsObject to be embedded in a full OpenAPI document
118
- */
119
- buildAllOpenApiPaths(): ZodOpenApiPathsObject;
120
- }
64
+ * Create all stage artifacts from provided configs. This is generic and can
65
+ * be used by both production and tests.
66
+ *
67
+ * @typeParam GlobalParams - global params record
68
+ * @typeParam StageParams - stage params record
69
+ * @param input - schemas, concrete params, env exposure, and per‑stage values
70
+ * @returns stage params object, provider environment, and per‑function env builder
71
+ *
72
+ * @throws Error if a stage fails validation or a required global key is missing
73
+ */
74
+ declare const stagesFactory: <GlobalParams extends Record<string, unknown>, StageParams extends Record<string, unknown>>(input: StagesFactoryInput<GlobalParams, StageParams>) => StagesFactoryOutput<GlobalParams, StageParams>;
121
75
 
122
76
  /**
123
- * baseEventTypeMapSchema
124
- * - Schema-first companion to BaseEventTypeMap.
125
- * - Ensures z.infer<typeof baseEventTypeMapSchema> === BaseEventTypeMap.
77
+ * Compose stage artifacts (effective schema + parsed stages + env helpers).
78
+ * Extracted from App.ts to keep the class focused on orchestration.
79
+ */
80
+ declare function buildStageArtifacts<GlobalParamsSchema extends ZodObject<ZodRawShape>, StageParamsSchema extends ZodObject<ZodRawShape>>(globalParamsSchema: GlobalParamsSchema, stageParamsSchema: StageParamsSchema, global: {
81
+ params: z.infer<GlobalParamsSchema>;
82
+ envKeys: readonly (keyof z.infer<GlobalParamsSchema>)[];
83
+ }, stage: {
84
+ params: Record<string, Record<string, unknown>>;
85
+ envKeys: readonly (keyof z.infer<StageParamsSchema>)[];
86
+ }): StagesFactoryOutput<z.core.output<GlobalParamsSchema>, z.core.output<StageParamsSchema>>;
87
+
88
+ /** Security context classification used throughout the handlers. */
89
+ /**
90
+ * HTTP security context tokens.
91
+ */
92
+ type HttpContext = 'my' | 'private' | 'public';
93
+
94
+ /**
95
+ * Extract the property type `K` from a union of object types `U`.
126
96
  *
127
- * @remarks
128
- * Consumers typically extend this schema when creating an App to add
129
- * project‑local event tokens (e.g., 'step').
130
- * Only tokens listed in the app’s `httpEventTypeTokens` are treated as HTTP at runtime.
97
+ * @typeParam U - union of object types
98
+ * @typeParam K - property key to extract
99
+ *
100
+ * @example
101
+ * type U = { a: number } | { a: string; b: boolean };
102
+ * // => number | string
103
+ * type A = PropFromUnion<U, 'a'>;
131
104
  */
105
+ type PropFromUnion<U, K extends PropertyKey> = Extract<U, Record<K, unknown>>[K];
132
106
 
133
- declare const baseEventTypeMapSchema: z.ZodObject<{
134
- rest: z.ZodCustom<APIGatewayProxyEvent, APIGatewayProxyEvent>;
135
- http: z.ZodCustom<APIGatewayProxyEventV2, APIGatewayProxyEventV2>;
136
- alb: z.ZodCustom<ALBEvent, ALBEvent>;
137
- sqs: z.ZodCustom<SQSEvent, SQSEvent>;
138
- sns: z.ZodCustom<SNSEvent, SNSEvent>;
139
- s3: z.ZodCustom<S3Event, S3Event>;
140
- dynamodb: z.ZodCustom<DynamoDBStreamEvent, DynamoDBStreamEvent>;
141
- kinesis: z.ZodCustom<KinesisStreamEvent, KinesisStreamEvent>;
142
- eventbridge: z.ZodCustom<EventBridgeEvent<string, unknown>, EventBridgeEvent<string, unknown>>;
143
- 'cloudwatch-logs': z.ZodCustom<CloudWatchLogsEvent, CloudWatchLogsEvent>;
144
- ses: z.ZodCustom<SESEvent, SESEvent>;
145
- cloudfront: z.ZodCustom<CloudFrontRequestEvent, CloudFrontRequestEvent>;
146
- firehose: z.ZodCustom<FirehoseTransformationEvent, FirehoseTransformationEvent>;
147
- 'cognito-userpool': z.ZodCustom<CognitoUserPoolTriggerEvent, CognitoUserPoolTriggerEvent>;
148
- }, z.core.$strip>;
107
+ /**
108
+ * Opaque Serverless event fragments keyed by security context.
109
+ *
110
+ * @remarks
111
+ * Shape is intentionally platform‑specific; used by the App to decorate
112
+ * generated HTTP events based on 'my' | 'private' | 'public' contexts.
113
+ */
114
+ type SecurityContextHttpEventMap = Record<HttpContext, Partial<PropFromUnion<PropFromUnion<PropFromUnion<AWS['functions'], string>['events'], number>, 'http'>>>;
149
115
 
150
116
  /** Base: envKeys tied to a Zod schema’s inferred keys. */
151
117
  /**
@@ -204,7 +170,7 @@ interface DefineAppConfigInput<GlobalParamsSchema extends ZodObject<ZodRawShape>
204
170
  serverless: {
205
171
  defaultHandlerFileName: string;
206
172
  defaultHandlerFileExport: string;
207
- httpContextEventMap: SecurityContextHttpEventMap$1;
173
+ httpContextEventMap: SecurityContextHttpEventMap;
208
174
  };
209
175
  global: GlobalParamsNode<GlobalParamsSchema>;
210
176
  stage: StageParamsNode<StageParamsSchema>;
@@ -234,44 +200,75 @@ interface DefineAppConfigOutput<GlobalParamsSchema extends ZodObject<ZodRawShape
234
200
  */
235
201
  declare function defineAppConfig<GlobalParamsSchema extends ZodObject<ZodRawShape>, StageParamsSchema extends ZodObject<ZodRawShape>>(globalParamsSchema: GlobalParamsSchema, stageParamsSchema: StageParamsSchema, input: DefineAppConfigInput<GlobalParamsSchema, StageParamsSchema>): DefineAppConfigOutput<GlobalParamsSchema, StageParamsSchema>;
236
202
 
237
- /** Classify the security context from either API Gateway event version. */
238
203
  /**
239
- * Detect security context from API Gateway v1/v2 events.
204
+ * Zod schema for implementation-wide Serverless config.
240
205
  *
241
- * @param evt - unknown event
242
- * @returns 'my' when authorized (Cognito/JWT/IAM), 'private' when API key present, else 'public'
206
+ * Extracted to keep App.ts slim and focused on orchestration.
243
207
  */
244
- declare const detectSecurityContext: (evt: unknown) => HttpContext$1;
208
+ declare const serverlessConfigSchema: z.ZodObject<{
209
+ httpContextEventMap: z.ZodCustom<SecurityContextHttpEventMap, SecurityContextHttpEventMap>;
210
+ defaultHandlerFileName: z.ZodString;
211
+ defaultHandlerFileExport: z.ZodString;
212
+ }, z.core.$strip>;
213
+ type AppServerlessConfig = z.infer<typeof serverlessConfigSchema>;
245
214
 
246
215
  /**
247
- * Wrap a business handler with SMOZ runtime. *
248
- * - HTTP event tokens receive the full Middy pipeline (validation, shaping, CORS, etc.)
249
- * - Non‑HTTP tokens bypass Middy and call the business function directly.
216
+ * Convenience alias for App generics.
250
217
  *
251
- * @typeParam GlobalParamsSchema - global params schema type
252
- * @typeParam StageParamsSchema - stage params schema type
253
- * @typeParam EventTypeMap - event token → runtime type map
254
- * @typeParam EventType - a key of EventTypeMap
255
- * @typeParam EventSchema - optional Zod schema for event (validated before handler)
256
- * @typeParam ResponseSchema - optional Zod schema for response (validated after handler)
257
- * @param functionConfig - per‑function configuration (branded with env nodes)
258
- * @param business - the business handler implementation
259
- * @param opts - optional runtime overrides (e.g., widen HTTP tokens)
260
- * @returns a Lambda‑compatible handler function
218
+ * @remarks Use this to express “any Zod object schema in generic parameters.
261
219
  */
262
- declare function wrapHandler<GlobalParamsSchema extends ZodObject<ZodRawShape>, StageParamsSchema extends ZodObject<ZodRawShape>, EventTypeMap extends BaseEventTypeMap, EventType extends keyof EventTypeMap, EventSchema extends z.ZodType | undefined, ResponseSchema extends z.ZodType | undefined>(functionConfig: FunctionConfig<EventSchema, ResponseSchema, z.infer<GlobalParamsSchema>, z.infer<StageParamsSchema>, EventTypeMap, EventType> & EnvAttached<GlobalParamsSchema, StageParamsSchema>, business: Handler$1<EventSchema, ResponseSchema, EventTypeMap[EventType]>, opts?: {
263
- httpEventTypeTokens?: readonly string[];
264
- httpConfig?: AppHttpConfig$1;
265
- }): (event: unknown, context: Context) => Promise<any>;
220
+ type ZodObj = ZodObject<ZodRawShape>;
221
+
222
+ type ConsoleLogger = Pick<Console, 'debug' | 'error' | 'info' | 'log'>;
266
223
 
267
224
  /**
268
- * HTTP customization types and aliases.
225
+ * Transform helpers for HTTP middleware stacks.
226
+ *
227
+ * - Steps are identified by a non-enumerable __id property on MiddlewareObj.
228
+ * - Utilities operate on arrays immutably and return new arrays.
229
+ * * Requirements addressed:
230
+ * - insertBefore, insertAfter, replaceStep, removeStep, findIndex, getId
269
231
  */
270
232
 
271
233
  type ApiMiddleware$1 = MiddlewareObj<APIGatewayProxyEvent, Context>;
234
+ type StepId = 'head' | 'header-normalizer' | 'event-normalizer' | 'content-negotiation' | 'json-body-parser' | 'zod-before' | 'head-finalize' | 'zod-after' | 'error-expose' | 'error-handler' | 'cors' | 'preferred-media' | 'shape' | 'serializer';
235
+ /** Attach a non-enumerable __id to a middleware step. */
236
+ declare const tagStep: (mw: ApiMiddleware$1, id: StepId) => ApiMiddleware$1;
237
+ /** Retrieve a step's id, if present. */
238
+ declare const getId: (mw: ApiMiddleware$1) => StepId | undefined;
239
+ /** Find index of a step by id. */
240
+ declare const findIndex: (list: ApiMiddleware$1[], id: StepId) => number;
241
+ /** Insert a step before the step with given id. */
242
+ declare const insertBefore: (list: ApiMiddleware$1[], id: StepId, mw: ApiMiddleware$1) => ApiMiddleware$1[];
243
+ /** Insert a step after the step with given id. */
244
+ declare const insertAfter: (list: ApiMiddleware$1[], id: StepId, mw: ApiMiddleware$1) => ApiMiddleware$1[];
245
+ /** Replace a step with given id. */
246
+ declare const replaceStep: (list: ApiMiddleware$1[], id: StepId, mw: ApiMiddleware$1) => ApiMiddleware$1[];
247
+ /** Remove a step with given id. */
248
+ declare const removeStep: (list: ApiMiddleware$1[], id: StepId) => ApiMiddleware$1[];
249
+ type PhasedArrays = {
250
+ before?: ApiMiddleware$1[];
251
+ after?: ApiMiddleware$1[];
252
+ onError?: ApiMiddleware$1[];
253
+ };
254
+ type HttpTransform = (stack: {
255
+ before: ApiMiddleware$1[];
256
+ after: ApiMiddleware$1[];
257
+ onError: ApiMiddleware$1[];
258
+ }) => Partial<{
259
+ before: ApiMiddleware$1[];
260
+ after: ApiMiddleware$1[];
261
+ onError: ApiMiddleware$1[];
262
+ }>;
263
+
264
+ /**
265
+ * HTTP customization types and aliases.
266
+ */
267
+
268
+ type ApiMiddleware = MiddlewareObj<APIGatewayProxyEvent, Context>;
272
269
  type HttpStackOptions = {
273
270
  contentType?: string;
274
- logger?: ConsoleLogger$1;
271
+ logger?: ConsoleLogger;
275
272
  contentNegotiation?: Parameters<typeof httpContentNegotiation>[0];
276
273
  cors?: Parameters<typeof httpCors>[0];
277
274
  errorHandler?: Parameters<typeof httpErrorHandler>[0];
@@ -285,9 +282,9 @@ type HttpStackOptions = {
285
282
  headerNormalizer?: Parameters<typeof httpHeaderNormalizer>[0];
286
283
  };
287
284
  type Extend = {
288
- before?: ApiMiddleware$1[];
289
- after?: ApiMiddleware$1[];
290
- onError?: ApiMiddleware$1[];
285
+ before?: ApiMiddleware[];
286
+ after?: ApiMiddleware[];
287
+ onError?: ApiMiddleware[];
291
288
  };
292
289
  type HttpProfile = HttpStackOptions & {
293
290
  extend?: Extend;
@@ -310,10 +307,10 @@ type FunctionHttpConfig = {
310
307
  };
311
308
  };
312
309
 
313
- type M = ApiMiddleware$1;
310
+ type M = ApiMiddleware;
314
311
  declare const buildDefaultPhases: (args: {
315
312
  contentType: string;
316
- logger: ConsoleLogger$1;
313
+ logger: ConsoleLogger;
317
314
  opts?: HttpStackOptions;
318
315
  eventSchema?: z.ZodType | undefined;
319
316
  responseSchema?: z.ZodType | undefined;
@@ -331,33 +328,242 @@ declare const buildSafeDefaults: (args: BuildSafeDefaultsArgs) => {
331
328
  };
332
329
 
333
330
  /**
334
- * Transform helpers for HTTP middleware stacks.
331
+ * baseEventTypeMapSchema
332
+ * - Schema-first companion to BaseEventTypeMap.
333
+ * - Ensures z.infer<typeof baseEventTypeMapSchema> === BaseEventTypeMap.
335
334
  *
336
- * - Steps are identified by a non-enumerable __id property on MiddlewareObj.
337
- * - Utilities operate on arrays immutably and return new arrays.
338
- * * Requirements addressed:
339
- * - insertBefore, insertAfter, replaceStep, removeStep, findIndex, getId
335
+ * @remarks
336
+ * Consumers typically extend this schema when creating an App to add
337
+ * project‑local event tokens (e.g., 'step').
338
+ * Only tokens listed in the app’s `httpEventTypeTokens` are treated as HTTP at runtime.
340
339
  */
341
340
 
342
- type ApiMiddleware = MiddlewareObj<APIGatewayProxyEvent, Context>;
343
- type StepId = 'head' | 'header-normalizer' | 'event-normalizer' | 'content-negotiation' | 'json-body-parser' | 'zod-before' | 'head-finalize' | 'zod-after' | 'error-expose' | 'error-handler' | 'cors' | 'preferred-media' | 'shape' | 'serializer';
344
- /** Attach a non-enumerable __id to a middleware step. */
345
- declare const tagStep: (mw: ApiMiddleware, id: StepId) => ApiMiddleware;
346
- /** Retrieve a step's id, if present. */
347
- declare const getId: (mw: ApiMiddleware) => StepId | undefined;
348
- /** Find index of a step by id. */
349
- declare const findIndex: (list: ApiMiddleware[], id: StepId) => number;
350
- /** Insert a step before the step with given id. */
351
- declare const insertBefore: (list: ApiMiddleware[], id: StepId, mw: ApiMiddleware) => ApiMiddleware[];
352
- /** Insert a step after the step with given id. */
353
- declare const insertAfter: (list: ApiMiddleware[], id: StepId, mw: ApiMiddleware) => ApiMiddleware[];
354
- /** Replace a step with given id. */
355
- declare const replaceStep: (list: ApiMiddleware[], id: StepId, mw: ApiMiddleware) => ApiMiddleware[];
356
- /** Remove a step with given id. */
357
- declare const removeStep: (list: ApiMiddleware[], id: StepId) => ApiMiddleware[];
341
+ declare const baseEventTypeMapSchema: z.ZodObject<{
342
+ rest: z.ZodCustom<APIGatewayProxyEvent, APIGatewayProxyEvent>;
343
+ http: z.ZodCustom<APIGatewayProxyEventV2, APIGatewayProxyEventV2>;
344
+ alb: z.ZodCustom<ALBEvent, ALBEvent>;
345
+ sqs: z.ZodCustom<SQSEvent, SQSEvent>;
346
+ sns: z.ZodCustom<SNSEvent, SNSEvent>;
347
+ s3: z.ZodCustom<S3Event, S3Event>;
348
+ dynamodb: z.ZodCustom<DynamoDBStreamEvent, DynamoDBStreamEvent>;
349
+ kinesis: z.ZodCustom<KinesisStreamEvent, KinesisStreamEvent>;
350
+ eventbridge: z.ZodCustom<EventBridgeEvent<string, unknown>, EventBridgeEvent<string, unknown>>;
351
+ 'cloudwatch-logs': z.ZodCustom<CloudWatchLogsEvent, CloudWatchLogsEvent>;
352
+ ses: z.ZodCustom<SESEvent, SESEvent>;
353
+ cloudfront: z.ZodCustom<CloudFrontRequestEvent, CloudFrontRequestEvent>;
354
+ firehose: z.ZodCustom<FirehoseTransformationEvent, FirehoseTransformationEvent>;
355
+ 'cognito-userpool': z.ZodCustom<CognitoUserPoolTriggerEvent, CognitoUserPoolTriggerEvent>;
356
+ }, z.core.$strip>;
357
+ /** Canonical base event map type (schema‑first). Extend the schema in your App. */
358
+ type BaseEventTypeMap = z.infer<typeof baseEventTypeMapSchema>;
358
359
 
359
360
  /** HTTP methods supported from zod-openapi's PathItem shape (excluding helper 'id'). */
360
361
  type MethodKey = keyof Omit<ZodOpenApiPathItemObject, 'id'>;
362
+ /**
363
+ * FunctionConfig
364
+ * - Per-function schemas, env requirements, routing metadata.
365
+ * - EventTypeMap binds event tokens (e.g., 'rest'|'http'|'sqs') to runtime shapes.
366
+ * - HTTP-only options are permitted only when EventType is an HTTP token.
367
+ *
368
+ * @typeParam EventSchema - optional Zod schema for event (validated pre‑handler)
369
+ * @typeParam ResponseSchema- optional Zod schema for response (validated post‑handler)
370
+ * @typeParam GlobalParams - app global params record
371
+ * @typeParam StageParams - app stage params record
372
+ * @typeParam EventTypeMap - event token → runtime type map
373
+ * @typeParam EventType - selected event token
374
+ *
375
+ * @remarks
376
+ * The SMOZ wrapper reads env keys from this config’s brand and builds a typed `options.env`,
377
+ * then applies HTTP middleware iff the token is in the app’s HTTP tokens set.
378
+ */
379
+ type FunctionConfig<EventSchema extends z.ZodType | undefined, ResponseSchema extends z.ZodType | undefined, GlobalParams extends Record<string, unknown>, StageParams extends Record<string, unknown>, EventTypeMap extends BaseEventTypeMap, EventType extends keyof EventTypeMap> = {
380
+ /** Unique function name; used across serverless/OpenAPI outputs. */
381
+ functionName: string;
382
+ /** Compile-time token selecting the runtime event type (e.g., 'rest' | 'http' | 'sqs'). */
383
+ eventType: EventType;
384
+ /** Optional; defaults to [] wherever consumed. */
385
+ fnEnvKeys?: readonly (keyof GlobalParams | keyof StageParams)[];
386
+ /** Optional Zod schemas applied uniformly across all handlers. */
387
+ eventSchema?: EventSchema;
388
+ responseSchema?: ResponseSchema;
389
+ /** Optional extra serverless events (e.g., SQS triggers). */
390
+ events?: PropFromUnion<AWS['functions'], string>['events'];
391
+ /** Optional logger; wrapper will default to `console`. */
392
+ logger?: ConsoleLogger;
393
+ } & (EventType extends keyof Pick<BaseEventTypeMap, 'rest' | 'http'> ? {
394
+ /** HTTP-only options (permitted for base HTTP tokens). */
395
+ httpContexts?: readonly HttpContext[];
396
+ method?: MethodKey;
397
+ basePath?: string;
398
+ contentType?: string;
399
+ } : {
400
+ /** Non-HTTP: deny HTTP-only options via type system. */
401
+ httpContexts?: never;
402
+ method?: never;
403
+ basePath?: never;
404
+ contentType?: never;
405
+ });
406
+
407
+ interface AppInit<GlobalParamsSchema extends ZodObj, StageParamsSchema extends ZodObj, EventTypeMapSchema extends ZodObj> {
408
+ appRootAbs: string;
409
+ globalParamsSchema: GlobalParamsSchema;
410
+ stageParamsSchema: StageParamsSchema;
411
+ eventTypeMapSchema?: EventTypeMapSchema;
412
+ /** Accept raw serverless config; App will parse it internally. */
413
+ serverless: z.input<typeof serverlessConfigSchema>;
414
+ global: {
415
+ params: z.infer<GlobalParamsSchema>;
416
+ envKeys: readonly (keyof z.infer<GlobalParamsSchema>)[];
417
+ };
418
+ stage: {
419
+ /** Accept raw stage param objects; App will parse with (global.partial + stage) */
420
+ params: Record<string, Record<string, unknown>>;
421
+ envKeys: readonly (keyof z.infer<StageParamsSchema>)[];
422
+ };
423
+ /**
424
+ * HTTP tokens to treat as HTTP at runtime (widenable).
425
+ * Defaults to ['rest', 'http'].
426
+ */
427
+ httpEventTypeTokens?: readonly (keyof z.infer<EventTypeMapSchema>)[];
428
+ /**
429
+ * Optional app-level HTTP middleware customization (defaults & profiles).
430
+ */
431
+ http?: AppHttpConfig;
432
+ /** Optional defaults applied to every function (merged per registration). */
433
+ functionDefaults?: {
434
+ fnEnvKeys?: readonly string[];
435
+ };
436
+ }
437
+ /**
438
+ * Application class. *
439
+ * @typeParam GlobalParamsSchema - Zod object schema for global parameters
440
+ * @typeParam StageParamsSchema - Zod object schema for per‑stage parameters
441
+ * @typeParam EventTypeMapSchema - Zod object schema mapping event tokens to runtime types
442
+ */ declare class App<GlobalParamsSchema extends ZodObj, StageParamsSchema extends ZodObj, EventTypeMapSchema extends ZodObj> {
443
+ /** Helper alias for stage artifacts type */
444
+ private static readonly _stageArtifactsType;
445
+ readonly appRootAbs: string;
446
+ readonly globalParamsSchema: GlobalParamsSchema;
447
+ readonly stageParamsSchema: StageParamsSchema;
448
+ readonly eventTypeMapSchema: EventTypeMapSchema;
449
+ readonly serverless: AppServerlessConfig;
450
+ readonly global: EnvSchemaNode<GlobalParamsSchema>;
451
+ readonly stage: EnvSchemaNode<StageParamsSchema>;
452
+ readonly stages: ReturnType<typeof buildStageArtifacts>['stages'];
453
+ readonly environment: ReturnType<typeof buildStageArtifacts>['environment'];
454
+ readonly buildFnEnv: ReturnType<typeof buildStageArtifacts>['buildFnEnv'];
455
+ readonly http: AppHttpConfig;
456
+ readonly httpEventTypeTokens: readonly string[];
457
+ private readonly registry;
458
+ private constructor(); /**
459
+ * Ergonomic constructor for schema‑first inference.
460
+ *
461
+ * @param init - initialization object (schemas, serverless defaults, params/envKeys)
462
+ * @returns a new App instance
463
+ */
464
+ static create<GlobalParamsSchema extends ZodObj, StageParamsSchema extends ZodObj, EventTypeMapSchema extends ZodObj>(init: AppInit<GlobalParamsSchema, StageParamsSchema, EventTypeMapSchema>): App<GlobalParamsSchema, StageParamsSchema, EventTypeMapSchema>;
465
+ /**
466
+ * Register a function (HTTP or non‑HTTP).
467
+ *
468
+ * @typeParam EventType - A key from your eventTypeMapSchema (e.g., 'rest' | 'http' | 'sqs' | 'step')
469
+ * @typeParam EventSchema - Optional Zod schema validated BEFORE the handler (refines event shape)
470
+ * @typeParam ResponseSchema - Optional Zod schema validated AFTER the handler (refines response shape)
471
+ * @param options - per‑function configuration (method/basePath/httpContexts for HTTP; serverless extras for non‑HTTP)
472
+ * @returns a per‑function API: { handler(business), openapi(baseOperation), serverless(extras) }
473
+ */
474
+ defineFunction<EventType extends Extract<keyof z.infer<EventTypeMapSchema>, string>, EventSchema extends z.ZodType | undefined, ResponseSchema extends z.ZodType | undefined>(options: {
475
+ functionName?: string;
476
+ eventType: EventType;
477
+ method?: MethodKey;
478
+ basePath?: string;
479
+ httpContexts?: readonly HttpContext[];
480
+ contentType?: string;
481
+ eventSchema?: EventSchema;
482
+ responseSchema?: ResponseSchema;
483
+ fnEnvKeys?: readonly (keyof (z.infer<GlobalParamsSchema> & z.infer<StageParamsSchema>))[];
484
+ callerModuleUrl: string;
485
+ endpointsRootAbs: string;
486
+ }): {
487
+ handler: (business: Handler<EventSchema, ResponseSchema, (z.core.output<EventTypeMapSchema> & {
488
+ rest: aws_lambda.APIGatewayProxyEvent;
489
+ http: aws_lambda.APIGatewayProxyEventV2;
490
+ alb: aws_lambda.ALBEvent;
491
+ sqs: aws_lambda.SQSEvent;
492
+ sns: aws_lambda.SNSEvent;
493
+ s3: aws_lambda.S3Event;
494
+ dynamodb: aws_lambda.DynamoDBStreamEvent;
495
+ kinesis: aws_lambda.KinesisStreamEvent;
496
+ eventbridge: aws_lambda.EventBridgeEvent<string, unknown>;
497
+ 'cloudwatch-logs': aws_lambda.CloudWatchLogsEvent;
498
+ ses: aws_lambda.SESEvent;
499
+ cloudfront: aws_lambda.CloudFrontRequestEvent;
500
+ firehose: aws_lambda.FirehoseTransformationEvent;
501
+ 'cognito-userpool': aws_lambda.CognitoUserPoolTriggerEvent;
502
+ })[EventType]>) => (event: unknown, context: aws_lambda.Context) => Promise<ResponseSchema extends z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>> ? z.core.output<ResponseSchema> : unknown>;
503
+ openapi: (baseOperation: BaseOperation) => void;
504
+ serverless: (extras: unknown) => void;
505
+ };
506
+ /**
507
+ * Aggregate Serverless function definitions across the registry.
508
+ *
509
+ * @returns An AWS['functions'] object suitable for serverless.ts
510
+ */
511
+ buildAllServerlessFunctions(): AWS['functions'];
512
+ /**
513
+ * Aggregate OpenAPI path items across the registry.
514
+ *
515
+ * @returns ZodOpenApiPathsObject to be embedded in a full OpenAPI document
516
+ */
517
+ buildAllOpenApiPaths(): ZodOpenApiPathsObject;
518
+ }
519
+
520
+ /** Classify the security context from either API Gateway event version. */
521
+ /**
522
+ * Detect security context from API Gateway v1/v2 events.
523
+ *
524
+ * @param evt - unknown event
525
+ * @returns 'my' when authorized (Cognito/JWT/IAM), 'private' when API key present, else 'public'
526
+ */
527
+ declare const detectSecurityContext: (evt: unknown) => HttpContext;
528
+
529
+ /**
530
+ * Private symbol used to attach env (schemas + envKeys) to FunctionConfig instances.
531
+ */
532
+ declare const ENV_CONFIG: unique symbol;
533
+ /**
534
+ * Branding interface that attaches environment metadata to a function config.
535
+ *
536
+ * @typeParam GlobalParamsSchema - global params schema
537
+ * @typeParam StageParamsSchema - stage params schema
538
+ * @remarks The brand is read by {@link runtime/wrapHandler.wrapHandler | wrapHandler} to build the typed env object.
539
+ */
540
+ interface EnvAttached<GlobalParamsSchema extends ZodObject<ZodRawShape>, StageParamsSchema extends ZodObject<ZodRawShape>> {
541
+ [ENV_CONFIG]: {
542
+ global: EnvSchemaNode<GlobalParamsSchema>;
543
+ stage: EnvSchemaNode<StageParamsSchema>;
544
+ };
545
+ }
546
+
547
+ /**
548
+ * DeepOverride
549
+ * ----------- * For two object types T (base) and U (override), produce a new type where keys present in U
550
+ * replace those in T; nested objects are recursed. Arrays and primitives are replaced wholesale.
551
+ *
552
+ * - If T is `never`, we fall back to U (used when no explicit EventType is provided).
553
+ * - If U is `never`, we keep T.
554
+ *
555
+ * @typeParam T - base type to be overridden
556
+ * @typeParam U - override type whose keys replace the base
557
+ *
558
+ * @example
559
+ * type A = { x: { a: number }, y: string };
560
+ * type B = { x: { a: string }, z: boolean };
561
+ * // => { x: { a: string }, y: string, z: boolean }
562
+ * type R = DeepOverride<A, B>;
563
+ */
564
+ type DeepOverride<T, U> = [T] extends [never] ? U : [U] extends [never] ? T : T extends any[] ? U : U extends any[] ? U : T extends object ? U extends object ? {
565
+ [K in keyof (T & U)]: K extends keyof U ? DeepOverride<K extends keyof T ? T[K] : never, U[K & keyof U]> : K extends keyof T ? T[K] : never;
566
+ } : T : U;
361
567
 
362
568
  /** Event type after applying deep schema overrides. */
363
569
  /**
@@ -370,7 +576,7 @@ type HandlerOptions = {
370
576
  /** Present only for HTTP calls; omitted for SQS/Step/etc. */
371
577
  securityContext?: unknown;
372
578
  /** REQUIRED and must satisfy ConsoleLogger. */
373
- logger: ConsoleLogger$1;
579
+ logger: ConsoleLogger;
374
580
  };
375
581
  /** Business handler: returns raw payloads; wrapping layers handle HTTP shaping when applicable. */
376
582
  /**
@@ -380,11 +586,26 @@ type HandlerOptions = {
380
586
  */
381
587
  type Handler<EventSchema extends z.ZodType | undefined, ResponseSchema extends z.ZodType | undefined, EventType> = (event: ShapedEvent<EventSchema, EventType>, context: Context, options: HandlerOptions) => Promise<ResponseSchema extends z.ZodType ? z.infer<ResponseSchema> : unknown>;
382
588
 
383
- /** Security context classification used throughout the handlers. */
384
589
  /**
385
- * HTTP security context tokens.
590
+ * Wrap a business handler with SMOZ runtime. *
591
+ * - HTTP event tokens receive the full Middy pipeline (validation, shaping, CORS, etc.)
592
+ * - Non‑HTTP tokens bypass Middy and call the business function directly.
593
+ *
594
+ * @typeParam GlobalParamsSchema - global params schema type
595
+ * @typeParam StageParamsSchema - stage params schema type
596
+ * @typeParam EventTypeMap - event token → runtime type map
597
+ * @typeParam EventType - a key of EventTypeMap
598
+ * @typeParam EventSchema - optional Zod schema for event (validated before handler)
599
+ * @typeParam ResponseSchema - optional Zod schema for response (validated after handler)
600
+ * @param functionConfig - per‑function configuration (branded with env nodes)
601
+ * @param business - the business handler implementation
602
+ * @param opts - optional runtime overrides (e.g., widen HTTP tokens)
603
+ * @returns a Lambda‑compatible handler function
386
604
  */
387
- type HttpContext = 'my' | 'private' | 'public';
605
+ declare function wrapHandler<GlobalParamsSchema extends ZodObject<ZodRawShape>, StageParamsSchema extends ZodObject<ZodRawShape>, EventTypeMap extends BaseEventTypeMap, EventType extends keyof EventTypeMap, EventSchema extends z.ZodType | undefined, ResponseSchema extends z.ZodType | undefined>(functionConfig: FunctionConfig<EventSchema, ResponseSchema, z.infer<GlobalParamsSchema>, z.infer<StageParamsSchema>, EventTypeMap, EventType> & EnvAttached<GlobalParamsSchema, StageParamsSchema>, business: Handler<EventSchema, ResponseSchema, EventTypeMap[EventType]>, opts?: {
606
+ httpEventTypeTokens?: readonly string[];
607
+ httpConfig?: AppHttpConfig;
608
+ }): (event: unknown, context: Context) => Promise<ResponseSchema extends z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>> ? z.core.output<ResponseSchema> : unknown>;
388
609
 
389
610
  /**
390
611
  * REQUIREMENTS ADDRESSED
@@ -396,17 +617,6 @@ type HttpContext = 'my' | 'private' | 'public';
396
617
  */
397
618
  type LambdaEvent = Record<string, unknown>;
398
619
 
399
- type ConsoleLogger = Pick<Console, 'debug' | 'error' | 'info' | 'log'>;
400
-
401
- /**
402
- * Opaque Serverless event fragments keyed by security context.
403
- *
404
- * @remarks
405
- * Shape is intentionally platform‑specific; used by the App to decorate
406
- * generated HTTP events based on 'my' | 'private' | 'public' contexts.
407
- */
408
- type SecurityContextHttpEventMap = Record<HttpContext$1, Partial<PropFromUnion<PropFromUnion<PropFromUnion<AWS['functions'], string>['events'], number>, 'http'>>>;
409
-
410
620
  /** Normalize a path to POSIX separators. */
411
621
  declare const toPosixPath: (p: string) => string;
412
622
  /**