@walkeros/server-source-aws 2.0.1 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,35 @@
1
1
  # @walkeros/server-source-aws
2
2
 
3
+ ## 2.1.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [fab477d]
8
+ - @walkeros/core@2.1.1
9
+
10
+ ## 2.1.0
11
+
12
+ ### Minor Changes
13
+
14
+ - 97df0b2: Step examples: upgrade all packages to blueprint pattern with inline
15
+ mapping, no intermediate variables, no `all` export
16
+
17
+ ### Patch Changes
18
+
19
+ - 97df0b2: Remove legacy events/mapping/outputs example files; tests now derive
20
+ from step examples
21
+ - Updated dependencies [7fc4cee]
22
+ - Updated dependencies [7fc4cee]
23
+ - Updated dependencies [cb2da05]
24
+ - Updated dependencies [2bbe8c8]
25
+ - Updated dependencies [3eb6416]
26
+ - Updated dependencies [02a7958]
27
+ - Updated dependencies [97df0b2]
28
+ - Updated dependencies [97df0b2]
29
+ - Updated dependencies [026c412]
30
+ - Updated dependencies [7d38d9d]
31
+ - @walkeros/core@2.1.0
32
+
3
33
  ## 2.0.1
4
34
 
5
35
  ## 1.0.6
package/dist/dev.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as _walkeros_core_dev from '@walkeros/core/dev';
2
2
  import { z } from '@walkeros/core/dev';
3
- import { Source, WalkerOS } from '@walkeros/core';
4
- import { APIGatewayProxyEvent, APIGatewayProxyEventV2, Context, APIGatewayProxyResult } from 'aws-lambda';
3
+ import { Source, Flow } from '@walkeros/core';
4
+ import { APIGatewayProxyEvent, APIGatewayProxyEventV2, Context } from 'aws-lambda';
5
5
 
6
6
  /**
7
7
  * HTTP methods enum
@@ -102,65 +102,19 @@ declare namespace env {
102
102
  export { env_push as push };
103
103
  }
104
104
 
105
- /**
106
- * Real examples of Lambda events this source will receive.
107
- * These define the CONTRACT - implementation must handle these inputs.
108
- */
109
- declare const apiGatewayV2PostEvent: APIGatewayProxyEventV2;
110
- declare const apiGatewayV2GetEvent: APIGatewayProxyEventV2;
111
- declare const apiGatewayV1PostEvent: APIGatewayProxyEvent;
112
- declare const healthCheckEvent: APIGatewayProxyEventV2;
113
- declare const invalidJsonEvent: APIGatewayProxyEventV2;
114
- declare const missingEventField: APIGatewayProxyEventV2;
115
-
116
- declare const inputs_apiGatewayV1PostEvent: typeof apiGatewayV1PostEvent;
117
- declare const inputs_apiGatewayV2GetEvent: typeof apiGatewayV2GetEvent;
118
- declare const inputs_apiGatewayV2PostEvent: typeof apiGatewayV2PostEvent;
119
- declare const inputs_healthCheckEvent: typeof healthCheckEvent;
120
- declare const inputs_invalidJsonEvent: typeof invalidJsonEvent;
121
- declare const inputs_missingEventField: typeof missingEventField;
122
- declare namespace inputs {
123
- export { inputs_apiGatewayV1PostEvent as apiGatewayV1PostEvent, inputs_apiGatewayV2GetEvent as apiGatewayV2GetEvent, inputs_apiGatewayV2PostEvent as apiGatewayV2PostEvent, inputs_healthCheckEvent as healthCheckEvent, inputs_invalidJsonEvent as invalidJsonEvent, inputs_missingEventField as missingEventField };
124
- }
125
-
126
- /**
127
- * Expected walkerOS events from Lambda inputs.
128
- * These are what processEvent should produce.
129
- */
130
- declare const pageViewEvent: Partial<WalkerOS.Event>;
131
- declare const buttonClickEvent: Partial<WalkerOS.Event>;
132
- declare const productAddEvent: Partial<WalkerOS.Event>;
133
-
134
- declare const events_buttonClickEvent: typeof buttonClickEvent;
135
- declare const events_pageViewEvent: typeof pageViewEvent;
136
- declare const events_productAddEvent: typeof productAddEvent;
137
- declare namespace events {
138
- export { events_buttonClickEvent as buttonClickEvent, events_pageViewEvent as pageViewEvent, events_productAddEvent as productAddEvent };
139
- }
140
-
141
- /**
142
- * Expected Lambda response outputs.
143
- * Tests verify implementation produces these.
144
- */
145
- declare const successResponse: APIGatewayProxyResult;
146
- declare const healthResponse: APIGatewayProxyResult;
147
- declare const pixelResponse: APIGatewayProxyResult;
148
- declare const invalidBodyResponse: APIGatewayProxyResult;
105
+ declare const lambdaPost: Flow.StepExample;
106
+ declare const lambdaGet: Flow.StepExample;
149
107
 
150
- declare const outputs_healthResponse: typeof healthResponse;
151
- declare const outputs_invalidBodyResponse: typeof invalidBodyResponse;
152
- declare const outputs_pixelResponse: typeof pixelResponse;
153
- declare const outputs_successResponse: typeof successResponse;
154
- declare namespace outputs {
155
- export { outputs_healthResponse as healthResponse, outputs_invalidBodyResponse as invalidBodyResponse, outputs_pixelResponse as pixelResponse, outputs_successResponse as successResponse };
108
+ declare const step_lambdaGet: typeof lambdaGet;
109
+ declare const step_lambdaPost: typeof lambdaPost;
110
+ declare namespace step {
111
+ export { step_lambdaGet as lambdaGet, step_lambdaPost as lambdaPost };
156
112
  }
157
113
 
158
114
  declare const index_env: typeof env;
159
- declare const index_events: typeof events;
160
- declare const index_inputs: typeof inputs;
161
- declare const index_outputs: typeof outputs;
115
+ declare const index_step: typeof step;
162
116
  declare namespace index {
163
- export { index_env as env, index_events as events, index_inputs as inputs, index_outputs as outputs };
117
+ export { index_env as env, index_step as step };
164
118
  }
165
119
 
166
120
  export { index as examples, index$1 as schemas };
package/dist/dev.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as _walkeros_core_dev from '@walkeros/core/dev';
2
2
  import { z } from '@walkeros/core/dev';
3
- import { Source, WalkerOS } from '@walkeros/core';
4
- import { APIGatewayProxyEvent, APIGatewayProxyEventV2, Context, APIGatewayProxyResult } from 'aws-lambda';
3
+ import { Source, Flow } from '@walkeros/core';
4
+ import { APIGatewayProxyEvent, APIGatewayProxyEventV2, Context } from 'aws-lambda';
5
5
 
6
6
  /**
7
7
  * HTTP methods enum
@@ -102,65 +102,19 @@ declare namespace env {
102
102
  export { env_push as push };
103
103
  }
104
104
 
105
- /**
106
- * Real examples of Lambda events this source will receive.
107
- * These define the CONTRACT - implementation must handle these inputs.
108
- */
109
- declare const apiGatewayV2PostEvent: APIGatewayProxyEventV2;
110
- declare const apiGatewayV2GetEvent: APIGatewayProxyEventV2;
111
- declare const apiGatewayV1PostEvent: APIGatewayProxyEvent;
112
- declare const healthCheckEvent: APIGatewayProxyEventV2;
113
- declare const invalidJsonEvent: APIGatewayProxyEventV2;
114
- declare const missingEventField: APIGatewayProxyEventV2;
115
-
116
- declare const inputs_apiGatewayV1PostEvent: typeof apiGatewayV1PostEvent;
117
- declare const inputs_apiGatewayV2GetEvent: typeof apiGatewayV2GetEvent;
118
- declare const inputs_apiGatewayV2PostEvent: typeof apiGatewayV2PostEvent;
119
- declare const inputs_healthCheckEvent: typeof healthCheckEvent;
120
- declare const inputs_invalidJsonEvent: typeof invalidJsonEvent;
121
- declare const inputs_missingEventField: typeof missingEventField;
122
- declare namespace inputs {
123
- export { inputs_apiGatewayV1PostEvent as apiGatewayV1PostEvent, inputs_apiGatewayV2GetEvent as apiGatewayV2GetEvent, inputs_apiGatewayV2PostEvent as apiGatewayV2PostEvent, inputs_healthCheckEvent as healthCheckEvent, inputs_invalidJsonEvent as invalidJsonEvent, inputs_missingEventField as missingEventField };
124
- }
125
-
126
- /**
127
- * Expected walkerOS events from Lambda inputs.
128
- * These are what processEvent should produce.
129
- */
130
- declare const pageViewEvent: Partial<WalkerOS.Event>;
131
- declare const buttonClickEvent: Partial<WalkerOS.Event>;
132
- declare const productAddEvent: Partial<WalkerOS.Event>;
133
-
134
- declare const events_buttonClickEvent: typeof buttonClickEvent;
135
- declare const events_pageViewEvent: typeof pageViewEvent;
136
- declare const events_productAddEvent: typeof productAddEvent;
137
- declare namespace events {
138
- export { events_buttonClickEvent as buttonClickEvent, events_pageViewEvent as pageViewEvent, events_productAddEvent as productAddEvent };
139
- }
140
-
141
- /**
142
- * Expected Lambda response outputs.
143
- * Tests verify implementation produces these.
144
- */
145
- declare const successResponse: APIGatewayProxyResult;
146
- declare const healthResponse: APIGatewayProxyResult;
147
- declare const pixelResponse: APIGatewayProxyResult;
148
- declare const invalidBodyResponse: APIGatewayProxyResult;
105
+ declare const lambdaPost: Flow.StepExample;
106
+ declare const lambdaGet: Flow.StepExample;
149
107
 
150
- declare const outputs_healthResponse: typeof healthResponse;
151
- declare const outputs_invalidBodyResponse: typeof invalidBodyResponse;
152
- declare const outputs_pixelResponse: typeof pixelResponse;
153
- declare const outputs_successResponse: typeof successResponse;
154
- declare namespace outputs {
155
- export { outputs_healthResponse as healthResponse, outputs_invalidBodyResponse as invalidBodyResponse, outputs_pixelResponse as pixelResponse, outputs_successResponse as successResponse };
108
+ declare const step_lambdaGet: typeof lambdaGet;
109
+ declare const step_lambdaPost: typeof lambdaPost;
110
+ declare namespace step {
111
+ export { step_lambdaGet as lambdaGet, step_lambdaPost as lambdaPost };
156
112
  }
157
113
 
158
114
  declare const index_env: typeof env;
159
- declare const index_events: typeof events;
160
- declare const index_inputs: typeof inputs;
161
- declare const index_outputs: typeof outputs;
115
+ declare const index_step: typeof step;
162
116
  declare namespace index {
163
- export { index_env as env, index_events as events, index_inputs as inputs, index_outputs as outputs };
117
+ export { index_env as env, index_step as step };
164
118
  }
165
119
 
166
120
  export { index as examples, index$1 as schemas };
package/dist/dev.js CHANGED
@@ -1 +1 @@
1
- "use strict";var e,t=Object.defineProperty,o=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,a=Object.prototype.hasOwnProperty,n=(e,o)=>{for(var r in o)t(e,r,{get:o[r],enumerable:!0})},s={};n(s,{examples:()=>g,schemas:()=>h}),module.exports=(e=s,((e,n,s,i)=>{if(n&&"object"==typeof n||"function"==typeof n)for(let l of r(n))a.call(e,l)||l===s||t(e,l,{get:()=>n[l],enumerable:!(i=o(n,l))||i.enumerable});return e})(t({},"__esModule",{value:!0}),e));require("@walkeros/core");var i=require("@walkeros/core/dev"),l=require("@walkeros/core/dev"),c=l.z.enum(["GET","POST","PUT","PATCH","DELETE","OPTIONS","HEAD"]),d=l.z.union([l.z.string(),l.z.array(l.z.string()),l.z.literal("*")]),u=l.z.object({origin:d.describe("Allowed origins (* for all, URL string, or array of URLs)").optional(),methods:l.z.array(c).describe("Allowed HTTP methods").optional(),headers:l.z.array(l.z.string()).describe("Allowed request headers").optional(),credentials:l.z.boolean().describe("Allow credentials (cookies, authorization headers)").optional(),maxAge:l.z.number().int().positive().describe("Preflight cache duration in seconds").optional()}),p=i.z.object({cors:i.z.union([i.z.boolean(),u]).describe("CORS configuration: false = disabled, true = allow all origins, object = custom configuration").default(!0),timeout:i.z.number().int().positive().max(9e5).describe("Request timeout in milliseconds (max: 900000 for Lambda)").default(3e4),enablePixelTracking:i.z.boolean().describe("Enable GET requests with 1x1 transparent GIF response for pixel tracking").default(!0),healthPath:i.z.string().describe("Health check endpoint path (e.g., /health)").default("/health")}),h={};n(h,{CorsOptionsSchema:()=>u,CorsOrigin:()=>d,HttpMethod:()=>c,SettingsSchema:()=>p,settings:()=>A});var A=(0,require("@walkeros/core/dev").zodToSchema)(p),g={};n(g,{env:()=>m,events:()=>z,inputs:()=>T,outputs:()=>H});var m={};n(m,{push:()=>C});var y=()=>()=>Promise.resolve({ok:!0}),P=()=>{},b={error:P,info:P,debug:P,throw:e=>{throw"string"==typeof e?new Error(e):e},scope:()=>b},C={get push(){return y()},get command(){return y()},get elb(){return y()},logger:b},T={};n(T,{apiGatewayV1PostEvent:()=>O,apiGatewayV2GetEvent:()=>w,apiGatewayV2PostEvent:()=>v,healthCheckEvent:()=>f,invalidJsonEvent:()=>E,missingEventField:()=>S});var v={version:"2.0",routeKey:"$default",rawPath:"/collect",rawQueryString:"",headers:{"content-type":"application/json","user-agent":"Mozilla/5.0"},body:JSON.stringify({event:"page view",data:{title:"Home Page",path:"/"},user:{id:"user-123"}}),isBase64Encoded:!1,requestContext:{accountId:"123456789012",apiId:"api-id",domainName:"api.example.com",domainPrefix:"api",http:{method:"POST",path:"/collect",protocol:"HTTP/1.1",sourceIp:"1.2.3.4",userAgent:"Mozilla/5.0"},requestId:"request-123",routeKey:"$default",stage:"prod",time:"01/Jan/2024:00:00:00 +0000",timeEpoch:17040672e5}},w={version:"2.0",routeKey:"$default",rawPath:"/collect",rawQueryString:"event=button%20click&data[id]=cta&data[text]=Sign%20Up",headers:{},isBase64Encoded:!1,requestContext:{accountId:"123456789012",apiId:"api-id",domainName:"api.example.com",domainPrefix:"api",http:{method:"GET",path:"/collect",protocol:"HTTP/1.1",sourceIp:"1.2.3.4",userAgent:"Mozilla/5.0"},requestId:"request-456",routeKey:"$default",stage:"prod",time:"01/Jan/2024:00:00:01 +0000",timeEpoch:1704067201e3}},O={httpMethod:"POST",path:"/collect",body:JSON.stringify({event:"product add",data:{id:"P123",name:"Laptop",price:999}}),headers:{"content-type":"application/json"},multiValueHeaders:{},isBase64Encoded:!1,pathParameters:null,queryStringParameters:null,multiValueQueryStringParameters:null,stageVariables:null,resource:"/collect",requestContext:{accountId:"123456789012",apiId:"api-id",protocol:"HTTP/1.1",httpMethod:"POST",path:"/collect",stage:"prod",requestId:"request-789",requestTimeEpoch:1704067202e3,resourceId:"resource-id",resourcePath:"/collect",identity:{sourceIp:"1.2.3.4",userAgent:"Mozilla/5.0",accessKey:null,accountId:null,apiKey:null,apiKeyId:null,caller:null,clientCert:null,cognitoAuthenticationProvider:null,cognitoAuthenticationType:null,cognitoIdentityId:null,cognitoIdentityPoolId:null,principalOrgId:null,user:null,userArn:null},authorizer:null}},f={...w,rawPath:"/health",rawQueryString:"",requestContext:{...w.requestContext,http:{...w.requestContext.http,path:"/health"}}},E={...v,body:"{invalid json"},S={...v,body:JSON.stringify({data:{foo:"bar"}})},z={};n(z,{buttonClickEvent:()=>x,pageViewEvent:()=>I,productAddEvent:()=>q});var I={name:"page view",data:{title:"Home Page",path:"/"},user:{id:"user-123"}},x={name:"button click",data:{id:"cta",text:"Sign Up"}},q={name:"product add",data:{id:"P123",name:"Laptop",price:999}},H={};n(H,{healthResponse:()=>j,invalidBodyResponse:()=>N,pixelResponse:()=>k,successResponse:()=>M});var M={statusCode:200,headers:{"Content-Type":"application/json","Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization","Access-Control-Max-Age":"3600"},body:JSON.stringify({success:!0}),isBase64Encoded:!1},j={statusCode:200,headers:{"Content-Type":"application/json","Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization","Access-Control-Max-Age":"3600"},body:JSON.stringify({status:"ok"}),isBase64Encoded:!1},k={statusCode:200,headers:{"Content-Type":"image/gif","Cache-Control":"no-cache, no-store, must-revalidate","Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization","Access-Control-Max-Age":"3600"},body:"R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7",isBase64Encoded:!0},N={statusCode:400,headers:{"Content-Type":"application/json","Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization","Access-Control-Max-Age":"3600"},body:JSON.stringify({success:!1,error:"Invalid request"}),isBase64Encoded:!1};//# sourceMappingURL=dev.js.map
1
+ "use strict";var e,t=Object.defineProperty,r=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyNames,a=Object.prototype.hasOwnProperty,i=(e,r)=>{for(var o in r)t(e,o,{get:r[o],enumerable:!0})},n={};i(n,{examples:()=>h,schemas:()=>g}),module.exports=(e=n,((e,i,n,s)=>{if(i&&"object"==typeof i||"function"==typeof i)for(let l of o(i))a.call(e,l)||l===n||t(e,l,{get:()=>i[l],enumerable:!(s=r(i,l))||s.enumerable});return e})(t({},"__esModule",{value:!0}),e));require("@walkeros/core");var s=require("@walkeros/core/dev"),l=require("@walkeros/core/dev"),d=l.z.enum(["GET","POST","PUT","PATCH","DELETE","OPTIONS","HEAD"]),c=l.z.union([l.z.string(),l.z.array(l.z.string()),l.z.literal("*")]),u=l.z.object({origin:c.describe("Allowed origins (* for all, URL string, or array of URLs)").optional(),methods:l.z.array(d).describe("Allowed HTTP methods").optional(),headers:l.z.array(l.z.string()).describe("Allowed request headers").optional(),credentials:l.z.boolean().describe("Allow credentials (cookies, authorization headers)").optional(),maxAge:l.z.number().int().positive().describe("Preflight cache duration in seconds").optional()}),p=s.z.object({cors:s.z.union([s.z.boolean(),u]).describe("CORS configuration: false = disabled, true = allow all origins, object = custom configuration").default(!0),timeout:s.z.number().int().positive().max(9e5).describe("Request timeout in milliseconds (max: 900000 for Lambda)").default(3e4),enablePixelTracking:s.z.boolean().describe("Enable GET requests with 1x1 transparent GIF response for pixel tracking").default(!0),healthPath:s.z.string().describe("Health check endpoint path (e.g., /health)").default("/health")}),g={};i(g,{CorsOptionsSchema:()=>u,CorsOrigin:()=>c,HttpMethod:()=>d,SettingsSchema:()=>p,settings:()=>m});var m=(0,require("@walkeros/core/dev").zodToSchema)(p),h={};i(h,{env:()=>b,step:()=>y});var b={};i(b,{push:()=>z});var w=()=>()=>Promise.resolve({ok:!0}),f=()=>{},v={error:f,warn:f,info:f,debug:f,throw:e=>{throw"string"==typeof e?new Error(e):e},json:f,scope:()=>v},z={get push(){return w()},get command(){return w()},get elb(){return w()},logger:v},y={};i(y,{lambdaGet:()=>P,lambdaPost:()=>O});var O={in:{version:"2.0",requestContext:{http:{method:"POST",path:"/collect"},requestId:"req-123"},body:JSON.stringify({name:"page view",data:{title:"Home"}}),isBase64Encoded:!1},out:{name:"page view",data:{title:"Home"},entity:"page",action:"view"}},P={in:{version:"2.0",requestContext:{http:{method:"GET",path:"/collect"},requestId:"req-456"},rawQueryString:"e=page+view&d=%7B%22title%22%3A%22Home%22%7D",isBase64Encoded:!1},out:{name:"page view",data:{title:"Home"},entity:"page",action:"view"}};//# sourceMappingURL=dev.js.map
package/dist/dev.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/dev.ts","../src/lambda/index.ts","../src/lambda/schemas/settings.ts","../src/lambda/schemas/primitives.ts","../src/lambda/schemas/index.ts","../src/lambda/examples/index.ts","../src/lambda/examples/env.ts","../src/lambda/examples/inputs.ts","../src/lambda/examples/events.ts","../src/lambda/examples/outputs.ts"],"sourcesContent":["export { schemas, examples } from './lambda';\n","import type { LambdaSource, EventRequest, Types } from './types';\nimport type { Source } from '@walkeros/core';\nimport { requestToData } from '@walkeros/core';\nimport {\n parseEvent,\n parseBody,\n isEventRequest,\n getCorsHeaders,\n createResponse,\n createPixelResponse,\n getPath,\n} from './utils';\nimport { processEvent } from './push';\nimport { SettingsSchema } from './schemas/settings';\n\nexport * as SourceLambda from './types';\nexport * as schemas from './schemas';\n\n// Export examples\nexport * as examples from './examples';\n\nexport const sourceLambda: Source.Init<Types> = async (context) => {\n const { config = {}, env, setIngest } = context;\n const { push: envPush } = env;\n\n const settings = SettingsSchema.parse(config.settings || {});\n\n const fullConfig: Source.Config<Types> = {\n ...config,\n settings,\n };\n\n const push: Types['push'] = async (event, context) => {\n const requestId = context.awsRequestId;\n let parsed;\n\n try {\n const corsHeaders = getCorsHeaders(settings.cors || false);\n parsed = parseEvent(event);\n const path = getPath(event);\n\n // Health check\n if (settings.healthPath && path === settings.healthPath) {\n return createResponse(\n 200,\n {\n status: 'ok',\n timestamp: Date.now(),\n source: 'lambda',\n requestId,\n },\n corsHeaders,\n requestId,\n );\n }\n\n // Handle OPTIONS for CORS preflight\n if (parsed.method === 'OPTIONS') {\n return createResponse(204, '', corsHeaders, requestId);\n }\n\n // Extract ingest metadata from Lambda event (if config.ingest is defined)\n await setIngest(event);\n\n // Handle GET for pixel tracking\n if (parsed.method === 'GET') {\n if (!settings.enablePixelTracking) {\n return createResponse(\n 405,\n { success: false, error: 'GET not allowed', requestId },\n corsHeaders,\n requestId,\n );\n }\n if (parsed.queryString) {\n const parsedData = requestToData(parsed.queryString);\n if (parsedData && typeof parsedData === 'object') {\n await envPush(parsedData);\n }\n }\n return createPixelResponse(corsHeaders, requestId);\n }\n\n // Handle POST for event data\n if (parsed.method === 'POST') {\n if (!parsed.body) {\n return createResponse(\n 400,\n { success: false, error: 'Request body is required', requestId },\n corsHeaders,\n requestId,\n );\n }\n\n const body = parseBody(parsed.body, parsed.isBase64Encoded);\n\n if (!body || typeof body !== 'object') {\n return createResponse(\n 400,\n { success: false, error: 'Invalid event body', requestId },\n corsHeaders,\n requestId,\n );\n }\n\n if (isEventRequest(body)) {\n const result = await processEvent(\n body as EventRequest,\n envPush,\n env.logger,\n requestId,\n );\n\n if (result.error) {\n return createResponse(\n 400,\n { success: false, error: result.error, requestId },\n corsHeaders,\n requestId,\n );\n }\n\n return createResponse(\n 200,\n { success: true, id: result.id, requestId },\n corsHeaders,\n requestId,\n );\n }\n\n return createResponse(\n 400,\n { success: false, error: 'Invalid request format', requestId },\n corsHeaders,\n requestId,\n );\n }\n\n return createResponse(\n 405,\n { success: false, error: 'Method not allowed', requestId },\n corsHeaders,\n requestId,\n );\n } catch (error) {\n // Log handler errors with context - per using-logger skill\n env.logger?.error('Lambda handler error', {\n error,\n requestId,\n method: parsed?.method,\n });\n return createResponse(\n 500,\n {\n success: false,\n error:\n error instanceof Error ? error.message : 'Internal server error',\n requestId,\n },\n {},\n requestId,\n );\n }\n };\n\n return {\n type: 'lambda',\n config: fullConfig,\n push,\n };\n};\n\nexport default sourceLambda;\n","import { z } from '@walkeros/core/dev';\nimport { CorsOptionsSchema } from './primitives';\n\n/**\n * AWS Lambda source settings schema\n */\nexport const SettingsSchema = z.object({\n cors: z\n .union([z.boolean(), CorsOptionsSchema])\n .describe(\n 'CORS configuration: false = disabled, true = allow all origins, object = custom configuration',\n )\n .default(true),\n\n timeout: z\n .number()\n .int()\n .positive()\n .max(900000) // AWS Lambda max timeout: 15 minutes\n .describe('Request timeout in milliseconds (max: 900000 for Lambda)')\n .default(30000),\n\n enablePixelTracking: z\n .boolean()\n .describe(\n 'Enable GET requests with 1x1 transparent GIF response for pixel tracking',\n )\n .default(true),\n\n healthPath: z\n .string()\n .describe('Health check endpoint path (e.g., /health)')\n .default('/health'),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\n/**\n * HTTP methods enum\n */\nexport const HttpMethod = z.enum([\n 'GET',\n 'POST',\n 'PUT',\n 'PATCH',\n 'DELETE',\n 'OPTIONS',\n 'HEAD',\n]);\n\n/**\n * CORS origin configuration\n * Accepts:\n * - '*' for all origins\n * - Single URL string\n * - Array of URL strings\n */\nexport const CorsOrigin = z.union([\n z.string(),\n z.array(z.string()),\n z.literal('*'),\n]);\n\n/**\n * CORS options schema\n * Configuration for Cross-Origin Resource Sharing\n */\nexport const CorsOptionsSchema = z.object({\n origin: CorsOrigin.describe(\n 'Allowed origins (* for all, URL string, or array of URLs)',\n ).optional(),\n\n methods: z.array(HttpMethod).describe('Allowed HTTP methods').optional(),\n\n headers: z.array(z.string()).describe('Allowed request headers').optional(),\n\n credentials: z\n .boolean()\n .describe('Allow credentials (cookies, authorization headers)')\n .optional(),\n\n maxAge: z\n .number()\n .int()\n .positive()\n .describe('Preflight cache duration in seconds')\n .optional(),\n});\n\nexport type CorsOptions = z.infer<typeof CorsOptionsSchema>;\n","import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\n\n// Export primitives\nexport * from './primitives';\n\n// Export Zod schemas and types\nexport { SettingsSchema, type Settings } from './settings';\n\n// JSON Schema exports (for website PropertyTable and documentation tools)\nexport const settings = zodToSchema(SettingsSchema);\n","export * as env from './env';\nexport * as inputs from './inputs';\nexport * as events from './events';\nexport * as outputs from './outputs';\n","import type { Env } from '../types';\nimport type { Elb, Logger } from '@walkeros/core';\n\n/**\n * Example environment configurations for AWS Lambda source\n *\n * These environments provide standardized mock structures for testing\n * Lambda event handling without requiring actual Lambda deployment.\n */\n\n// Create a properly typed elb/push/command function that returns a promise with PushResult\nconst createMockElbFn = (): Elb.Fn => {\n const fn = (() =>\n Promise.resolve({\n ok: true,\n })) as Elb.Fn;\n return fn;\n};\n\n// Simple no-op logger for demo purposes\nconst noopFn = () => {};\nconst noopLogger: Logger.Instance = {\n error: noopFn,\n info: noopFn,\n debug: noopFn,\n throw: (message: string | Error) => {\n throw typeof message === 'string' ? new Error(message) : message;\n },\n scope: () => noopLogger,\n};\n\n/**\n * Standard mock environment for testing Lambda source\n *\n * Use this for testing Lambda event ingestion and request/response handling\n * without requiring a real AWS Lambda environment.\n */\nexport const push: Env = {\n get push() {\n return createMockElbFn();\n },\n get command() {\n return createMockElbFn();\n },\n get elb() {\n return createMockElbFn();\n },\n logger: noopLogger,\n};\n","import type { APIGatewayProxyEvent, APIGatewayProxyEventV2 } from 'aws-lambda';\n\n/**\n * Real examples of Lambda events this source will receive.\n * These define the CONTRACT - implementation must handle these inputs.\n */\n\n// API Gateway v2 (HTTP API) - POST with walker event\nexport const apiGatewayV2PostEvent: APIGatewayProxyEventV2 = {\n version: '2.0',\n routeKey: '$default',\n rawPath: '/collect',\n rawQueryString: '',\n headers: {\n 'content-type': 'application/json',\n 'user-agent': 'Mozilla/5.0',\n },\n body: JSON.stringify({\n event: 'page view',\n data: { title: 'Home Page', path: '/' },\n user: { id: 'user-123' },\n }),\n isBase64Encoded: false,\n requestContext: {\n accountId: '123456789012',\n apiId: 'api-id',\n domainName: 'api.example.com',\n domainPrefix: 'api',\n http: {\n method: 'POST',\n path: '/collect',\n protocol: 'HTTP/1.1',\n sourceIp: '1.2.3.4',\n userAgent: 'Mozilla/5.0',\n },\n requestId: 'request-123',\n routeKey: '$default',\n stage: 'prod',\n time: '01/Jan/2024:00:00:00 +0000',\n timeEpoch: 1704067200000,\n },\n};\n\n// API Gateway v2 - GET with query params (pixel tracking)\nexport const apiGatewayV2GetEvent: APIGatewayProxyEventV2 = {\n version: '2.0',\n routeKey: '$default',\n rawPath: '/collect',\n rawQueryString: 'event=button%20click&data[id]=cta&data[text]=Sign%20Up',\n headers: {},\n isBase64Encoded: false,\n requestContext: {\n accountId: '123456789012',\n apiId: 'api-id',\n domainName: 'api.example.com',\n domainPrefix: 'api',\n http: {\n method: 'GET',\n path: '/collect',\n protocol: 'HTTP/1.1',\n sourceIp: '1.2.3.4',\n userAgent: 'Mozilla/5.0',\n },\n requestId: 'request-456',\n routeKey: '$default',\n stage: 'prod',\n time: '01/Jan/2024:00:00:01 +0000',\n timeEpoch: 1704067201000,\n },\n};\n\n// API Gateway v1 (REST API) - POST with walker event\nexport const apiGatewayV1PostEvent: APIGatewayProxyEvent = {\n httpMethod: 'POST',\n path: '/collect',\n body: JSON.stringify({\n event: 'product add',\n data: { id: 'P123', name: 'Laptop', price: 999 },\n }),\n headers: { 'content-type': 'application/json' },\n multiValueHeaders: {},\n isBase64Encoded: false,\n pathParameters: null,\n queryStringParameters: null,\n multiValueQueryStringParameters: null,\n stageVariables: null,\n resource: '/collect',\n requestContext: {\n accountId: '123456789012',\n apiId: 'api-id',\n protocol: 'HTTP/1.1',\n httpMethod: 'POST',\n path: '/collect',\n stage: 'prod',\n requestId: 'request-789',\n requestTimeEpoch: 1704067202000,\n resourceId: 'resource-id',\n resourcePath: '/collect',\n identity: {\n sourceIp: '1.2.3.4',\n userAgent: 'Mozilla/5.0',\n accessKey: null,\n accountId: null,\n apiKey: null,\n apiKeyId: null,\n caller: null,\n clientCert: null,\n cognitoAuthenticationProvider: null,\n cognitoAuthenticationType: null,\n cognitoIdentityId: null,\n cognitoIdentityPoolId: null,\n principalOrgId: null,\n user: null,\n userArn: null,\n },\n authorizer: null,\n },\n};\n\n// Health check request\nexport const healthCheckEvent: APIGatewayProxyEventV2 = {\n ...apiGatewayV2GetEvent,\n rawPath: '/health',\n rawQueryString: '',\n requestContext: {\n ...apiGatewayV2GetEvent.requestContext,\n http: {\n ...apiGatewayV2GetEvent.requestContext.http,\n path: '/health',\n },\n },\n};\n\n// Invalid event - malformed JSON\nexport const invalidJsonEvent: APIGatewayProxyEventV2 = {\n ...apiGatewayV2PostEvent,\n body: '{invalid json',\n};\n\n// Missing event field\nexport const missingEventField: APIGatewayProxyEventV2 = {\n ...apiGatewayV2PostEvent,\n body: JSON.stringify({ data: { foo: 'bar' } }),\n};\n","import type { WalkerOS } from '@walkeros/core';\n\n/**\n * Expected walkerOS events from Lambda inputs.\n * These are what processEvent should produce.\n */\n\n// From apiGatewayV2PostEvent\nexport const pageViewEvent: Partial<WalkerOS.Event> = {\n name: 'page view',\n data: { title: 'Home Page', path: '/' },\n user: { id: 'user-123' },\n};\n\n// From apiGatewayV2GetEvent\nexport const buttonClickEvent: Partial<WalkerOS.Event> = {\n name: 'button click',\n data: { id: 'cta', text: 'Sign Up' },\n};\n\n// From apiGatewayV1PostEvent\nexport const productAddEvent: Partial<WalkerOS.Event> = {\n name: 'product add',\n data: { id: 'P123', name: 'Laptop', price: 999 },\n};\n","import type { APIGatewayProxyResult } from 'aws-lambda';\n\n/**\n * Expected Lambda response outputs.\n * Tests verify implementation produces these.\n */\n\n// Successful event processing\n// Shape from: createResponse(200, { success: true, ... }, corsHeaders, requestId)\nexport const successResponse: APIGatewayProxyResult = {\n statusCode: 200,\n headers: {\n 'Content-Type': 'application/json',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Authorization',\n 'Access-Control-Max-Age': '3600',\n },\n body: JSON.stringify({ success: true }),\n isBase64Encoded: false,\n};\n\n// Health check response\n// Shape from: createResponse(200, { status: 'ok', ... }, corsHeaders, requestId)\nexport const healthResponse: APIGatewayProxyResult = {\n statusCode: 200,\n headers: {\n 'Content-Type': 'application/json',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Authorization',\n 'Access-Control-Max-Age': '3600',\n },\n body: JSON.stringify({ status: 'ok' }),\n isBase64Encoded: false,\n};\n\n// Pixel tracking response\n// Shape from: createPixelResponse(corsHeaders, requestId)\nexport const pixelResponse: APIGatewayProxyResult = {\n statusCode: 200,\n headers: {\n 'Content-Type': 'image/gif',\n 'Cache-Control': 'no-cache, no-store, must-revalidate',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Authorization',\n 'Access-Control-Max-Age': '3600',\n },\n body: 'R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7',\n isBase64Encoded: true,\n};\n\n// Error responses\n// Shape from: createResponse(400, { success: false, error: '...' }, corsHeaders, requestId)\nexport const invalidBodyResponse: APIGatewayProxyResult = {\n statusCode: 400,\n headers: {\n 'Content-Type': 'application/json',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Authorization',\n 'Access-Control-Max-Age': '3600',\n },\n body: JSON.stringify({ success: false, error: 'Invalid request' }),\n isBase64Encoded: false,\n};\n"],"mappings":"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","names":["import_dev","import_dev"]}
1
+ {"version":3,"sources":["../src/dev.ts","../src/lambda/index.ts","../src/lambda/schemas/settings.ts","../src/lambda/schemas/primitives.ts","../src/lambda/schemas/index.ts","../src/lambda/examples/index.ts","../src/lambda/examples/env.ts","../src/lambda/examples/step.ts"],"sourcesContent":["export { schemas, examples } from './lambda';\n","import type { LambdaSource, EventRequest, Types } from './types';\nimport type { Source } from '@walkeros/core';\nimport { requestToData } from '@walkeros/core';\nimport {\n parseEvent,\n parseBody,\n isEventRequest,\n getCorsHeaders,\n createResponse,\n createPixelResponse,\n getPath,\n} from './utils';\nimport { processEvent } from './push';\nimport { SettingsSchema } from './schemas/settings';\n\nexport * as SourceLambda from './types';\nexport * as schemas from './schemas';\n\n// Export examples\nexport * as examples from './examples';\n\nexport const sourceLambda: Source.Init<Types> = async (context) => {\n const { config = {}, env, setIngest } = context;\n const { push: envPush } = env;\n\n const settings = SettingsSchema.parse(config.settings || {});\n\n const fullConfig: Source.Config<Types> = {\n ...config,\n settings,\n };\n\n const push: Types['push'] = async (event, context) => {\n const requestId = context.awsRequestId;\n let parsed;\n\n try {\n const corsHeaders = getCorsHeaders(settings.cors || false);\n parsed = parseEvent(event);\n const path = getPath(event);\n\n // Health check\n if (settings.healthPath && path === settings.healthPath) {\n return createResponse(\n 200,\n {\n status: 'ok',\n timestamp: Date.now(),\n source: 'lambda',\n requestId,\n },\n corsHeaders,\n requestId,\n );\n }\n\n // Handle OPTIONS for CORS preflight\n if (parsed.method === 'OPTIONS') {\n return createResponse(204, '', corsHeaders, requestId);\n }\n\n // Extract ingest metadata from Lambda event (if config.ingest is defined)\n await setIngest(event);\n\n // Handle GET for pixel tracking\n if (parsed.method === 'GET') {\n if (!settings.enablePixelTracking) {\n return createResponse(\n 405,\n { success: false, error: 'GET not allowed', requestId },\n corsHeaders,\n requestId,\n );\n }\n if (parsed.queryString) {\n const parsedData = requestToData(parsed.queryString);\n if (parsedData && typeof parsedData === 'object') {\n await envPush(parsedData);\n }\n }\n return createPixelResponse(corsHeaders, requestId);\n }\n\n // Handle POST for event data\n if (parsed.method === 'POST') {\n if (!parsed.body) {\n return createResponse(\n 400,\n { success: false, error: 'Request body is required', requestId },\n corsHeaders,\n requestId,\n );\n }\n\n const body = parseBody(parsed.body, parsed.isBase64Encoded);\n\n if (!body || typeof body !== 'object') {\n return createResponse(\n 400,\n { success: false, error: 'Invalid event body', requestId },\n corsHeaders,\n requestId,\n );\n }\n\n if (isEventRequest(body)) {\n const result = await processEvent(\n body as EventRequest,\n envPush,\n env.logger,\n requestId,\n );\n\n if (result.error) {\n return createResponse(\n 400,\n { success: false, error: result.error, requestId },\n corsHeaders,\n requestId,\n );\n }\n\n return createResponse(\n 200,\n { success: true, id: result.id, requestId },\n corsHeaders,\n requestId,\n );\n }\n\n return createResponse(\n 400,\n { success: false, error: 'Invalid request format', requestId },\n corsHeaders,\n requestId,\n );\n }\n\n return createResponse(\n 405,\n { success: false, error: 'Method not allowed', requestId },\n corsHeaders,\n requestId,\n );\n } catch (error) {\n // Log handler errors with context - per using-logger skill\n env.logger?.error('Lambda handler error', {\n error,\n requestId,\n method: parsed?.method,\n });\n return createResponse(\n 500,\n {\n success: false,\n error:\n error instanceof Error ? error.message : 'Internal server error',\n requestId,\n },\n {},\n requestId,\n );\n }\n };\n\n return {\n type: 'lambda',\n config: fullConfig,\n push,\n };\n};\n\nexport default sourceLambda;\n","import { z } from '@walkeros/core/dev';\nimport { CorsOptionsSchema } from './primitives';\n\n/**\n * AWS Lambda source settings schema\n */\nexport const SettingsSchema = z.object({\n cors: z\n .union([z.boolean(), CorsOptionsSchema])\n .describe(\n 'CORS configuration: false = disabled, true = allow all origins, object = custom configuration',\n )\n .default(true),\n\n timeout: z\n .number()\n .int()\n .positive()\n .max(900000) // AWS Lambda max timeout: 15 minutes\n .describe('Request timeout in milliseconds (max: 900000 for Lambda)')\n .default(30000),\n\n enablePixelTracking: z\n .boolean()\n .describe(\n 'Enable GET requests with 1x1 transparent GIF response for pixel tracking',\n )\n .default(true),\n\n healthPath: z\n .string()\n .describe('Health check endpoint path (e.g., /health)')\n .default('/health'),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\n/**\n * HTTP methods enum\n */\nexport const HttpMethod = z.enum([\n 'GET',\n 'POST',\n 'PUT',\n 'PATCH',\n 'DELETE',\n 'OPTIONS',\n 'HEAD',\n]);\n\n/**\n * CORS origin configuration\n * Accepts:\n * - '*' for all origins\n * - Single URL string\n * - Array of URL strings\n */\nexport const CorsOrigin = z.union([\n z.string(),\n z.array(z.string()),\n z.literal('*'),\n]);\n\n/**\n * CORS options schema\n * Configuration for Cross-Origin Resource Sharing\n */\nexport const CorsOptionsSchema = z.object({\n origin: CorsOrigin.describe(\n 'Allowed origins (* for all, URL string, or array of URLs)',\n ).optional(),\n\n methods: z.array(HttpMethod).describe('Allowed HTTP methods').optional(),\n\n headers: z.array(z.string()).describe('Allowed request headers').optional(),\n\n credentials: z\n .boolean()\n .describe('Allow credentials (cookies, authorization headers)')\n .optional(),\n\n maxAge: z\n .number()\n .int()\n .positive()\n .describe('Preflight cache duration in seconds')\n .optional(),\n});\n\nexport type CorsOptions = z.infer<typeof CorsOptionsSchema>;\n","import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\n\n// Export primitives\nexport * from './primitives';\n\n// Export Zod schemas and types\nexport { SettingsSchema, type Settings } from './settings';\n\n// JSON Schema exports (for website PropertyTable and documentation tools)\nexport const settings = zodToSchema(SettingsSchema);\n","export * as env from './env';\nexport * as step from './step';\n","import type { Env } from '../types';\nimport type { Elb, Logger } from '@walkeros/core';\n\n/**\n * Example environment configurations for AWS Lambda source\n *\n * These environments provide standardized mock structures for testing\n * Lambda event handling without requiring actual Lambda deployment.\n */\n\n// Create a properly typed elb/push/command function that returns a promise with PushResult\nconst createMockElbFn = (): Elb.Fn => {\n const fn = (() =>\n Promise.resolve({\n ok: true,\n })) as Elb.Fn;\n return fn;\n};\n\n// Simple no-op logger for demo purposes\nconst noopFn = () => {};\nconst noopLogger: Logger.Instance = {\n error: noopFn,\n warn: noopFn,\n info: noopFn,\n debug: noopFn,\n throw: (message: string | Error) => {\n throw typeof message === 'string' ? new Error(message) : message;\n },\n json: noopFn,\n scope: () => noopLogger,\n};\n\n/**\n * Standard mock environment for testing Lambda source\n *\n * Use this for testing Lambda event ingestion and request/response handling\n * without requiring a real AWS Lambda environment.\n */\nexport const push: Env = {\n get push() {\n return createMockElbFn();\n },\n get command() {\n return createMockElbFn();\n },\n get elb() {\n return createMockElbFn();\n },\n logger: noopLogger,\n};\n","import type { Flow } from '@walkeros/core';\n\nexport const lambdaPost: Flow.StepExample = {\n in: {\n version: '2.0',\n requestContext: {\n http: { method: 'POST', path: '/collect' },\n requestId: 'req-123',\n },\n body: JSON.stringify({\n name: 'page view',\n data: { title: 'Home' },\n }),\n isBase64Encoded: false,\n },\n out: {\n name: 'page view',\n data: { title: 'Home' },\n entity: 'page',\n action: 'view',\n },\n};\n\nexport const lambdaGet: Flow.StepExample = {\n in: {\n version: '2.0',\n requestContext: {\n http: { method: 'GET', path: '/collect' },\n requestId: 'req-456',\n },\n rawQueryString: 'e=page+view&d=%7B%22title%22%3A%22Home%22%7D',\n isBase64Encoded: false,\n },\n out: {\n name: 'page view',\n data: { title: 'Home' },\n entity: 'page',\n action: 'view',\n },\n};\n"],"mappings":"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","names":["import_dev","import_dev"]}
package/dist/dev.mjs CHANGED
@@ -1 +1 @@
1
- var e=Object.defineProperty,t=(t,o)=>{for(var a in o)e(t,a,{get:o[a],enumerable:!0})};import{requestToData as o}from"@walkeros/core";import{z as a}from"@walkeros/core/dev";import{z as r}from"@walkeros/core/dev";var n=r.enum(["GET","POST","PUT","PATCH","DELETE","OPTIONS","HEAD"]),s=r.union([r.string(),r.array(r.string()),r.literal("*")]),i=r.object({origin:s.describe("Allowed origins (* for all, URL string, or array of URLs)").optional(),methods:r.array(n).describe("Allowed HTTP methods").optional(),headers:r.array(r.string()).describe("Allowed request headers").optional(),credentials:r.boolean().describe("Allow credentials (cookies, authorization headers)").optional(),maxAge:r.number().int().positive().describe("Preflight cache duration in seconds").optional()}),l=a.object({cors:a.union([a.boolean(),i]).describe("CORS configuration: false = disabled, true = allow all origins, object = custom configuration").default(!0),timeout:a.number().int().positive().max(9e5).describe("Request timeout in milliseconds (max: 900000 for Lambda)").default(3e4),enablePixelTracking:a.boolean().describe("Enable GET requests with 1x1 transparent GIF response for pixel tracking").default(!0),healthPath:a.string().describe("Health check endpoint path (e.g., /health)").default("/health")}),c={};t(c,{CorsOptionsSchema:()=>i,CorsOrigin:()=>s,HttpMethod:()=>n,SettingsSchema:()=>l,settings:()=>u});import{zodToSchema as d}from"@walkeros/core/dev";var u=d(l),p={};t(p,{env:()=>h,events:()=>E,inputs:()=>C,outputs:()=>x});var h={};t(h,{push:()=>y});var A=()=>()=>Promise.resolve({ok:!0}),g=()=>{},m={error:g,info:g,debug:g,throw:e=>{throw"string"==typeof e?new Error(e):e},scope:()=>m},y={get push(){return A()},get command(){return A()},get elb(){return A()},logger:m},C={};t(C,{apiGatewayV1PostEvent:()=>v,apiGatewayV2GetEvent:()=>T,apiGatewayV2PostEvent:()=>P,healthCheckEvent:()=>b,invalidJsonEvent:()=>w,missingEventField:()=>f});var P={version:"2.0",routeKey:"$default",rawPath:"/collect",rawQueryString:"",headers:{"content-type":"application/json","user-agent":"Mozilla/5.0"},body:JSON.stringify({event:"page view",data:{title:"Home Page",path:"/"},user:{id:"user-123"}}),isBase64Encoded:!1,requestContext:{accountId:"123456789012",apiId:"api-id",domainName:"api.example.com",domainPrefix:"api",http:{method:"POST",path:"/collect",protocol:"HTTP/1.1",sourceIp:"1.2.3.4",userAgent:"Mozilla/5.0"},requestId:"request-123",routeKey:"$default",stage:"prod",time:"01/Jan/2024:00:00:00 +0000",timeEpoch:17040672e5}},T={version:"2.0",routeKey:"$default",rawPath:"/collect",rawQueryString:"event=button%20click&data[id]=cta&data[text]=Sign%20Up",headers:{},isBase64Encoded:!1,requestContext:{accountId:"123456789012",apiId:"api-id",domainName:"api.example.com",domainPrefix:"api",http:{method:"GET",path:"/collect",protocol:"HTTP/1.1",sourceIp:"1.2.3.4",userAgent:"Mozilla/5.0"},requestId:"request-456",routeKey:"$default",stage:"prod",time:"01/Jan/2024:00:00:01 +0000",timeEpoch:1704067201e3}},v={httpMethod:"POST",path:"/collect",body:JSON.stringify({event:"product add",data:{id:"P123",name:"Laptop",price:999}}),headers:{"content-type":"application/json"},multiValueHeaders:{},isBase64Encoded:!1,pathParameters:null,queryStringParameters:null,multiValueQueryStringParameters:null,stageVariables:null,resource:"/collect",requestContext:{accountId:"123456789012",apiId:"api-id",protocol:"HTTP/1.1",httpMethod:"POST",path:"/collect",stage:"prod",requestId:"request-789",requestTimeEpoch:1704067202e3,resourceId:"resource-id",resourcePath:"/collect",identity:{sourceIp:"1.2.3.4",userAgent:"Mozilla/5.0",accessKey:null,accountId:null,apiKey:null,apiKeyId:null,caller:null,clientCert:null,cognitoAuthenticationProvider:null,cognitoAuthenticationType:null,cognitoIdentityId:null,cognitoIdentityPoolId:null,principalOrgId:null,user:null,userArn:null},authorizer:null}},b={...T,rawPath:"/health",rawQueryString:"",requestContext:{...T.requestContext,http:{...T.requestContext.http,path:"/health"}}},w={...P,body:"{invalid json"},f={...P,body:JSON.stringify({data:{foo:"bar"}})},E={};t(E,{buttonClickEvent:()=>S,pageViewEvent:()=>O,productAddEvent:()=>I});var O={name:"page view",data:{title:"Home Page",path:"/"},user:{id:"user-123"}},S={name:"button click",data:{id:"cta",text:"Sign Up"}},I={name:"product add",data:{id:"P123",name:"Laptop",price:999}},x={};t(x,{healthResponse:()=>H,invalidBodyResponse:()=>k,pixelResponse:()=>M,successResponse:()=>q});var q={statusCode:200,headers:{"Content-Type":"application/json","Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization","Access-Control-Max-Age":"3600"},body:JSON.stringify({success:!0}),isBase64Encoded:!1},H={statusCode:200,headers:{"Content-Type":"application/json","Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization","Access-Control-Max-Age":"3600"},body:JSON.stringify({status:"ok"}),isBase64Encoded:!1},M={statusCode:200,headers:{"Content-Type":"image/gif","Cache-Control":"no-cache, no-store, must-revalidate","Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization","Access-Control-Max-Age":"3600"},body:"R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7",isBase64Encoded:!0},k={statusCode:400,headers:{"Content-Type":"application/json","Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization","Access-Control-Max-Age":"3600"},body:JSON.stringify({success:!1,error:"Invalid request"}),isBase64Encoded:!1};export{p as examples,c as schemas};//# sourceMappingURL=dev.mjs.map
1
+ var e=Object.defineProperty,t=(t,r)=>{for(var o in r)e(t,o,{get:r[o],enumerable:!0})};import{requestToData as r}from"@walkeros/core";import{z as o}from"@walkeros/core/dev";import{z as a}from"@walkeros/core/dev";var i=a.enum(["GET","POST","PUT","PATCH","DELETE","OPTIONS","HEAD"]),n=a.union([a.string(),a.array(a.string()),a.literal("*")]),s=a.object({origin:n.describe("Allowed origins (* for all, URL string, or array of URLs)").optional(),methods:a.array(i).describe("Allowed HTTP methods").optional(),headers:a.array(a.string()).describe("Allowed request headers").optional(),credentials:a.boolean().describe("Allow credentials (cookies, authorization headers)").optional(),maxAge:a.number().int().positive().describe("Preflight cache duration in seconds").optional()}),l=o.object({cors:o.union([o.boolean(),s]).describe("CORS configuration: false = disabled, true = allow all origins, object = custom configuration").default(!0),timeout:o.number().int().positive().max(9e5).describe("Request timeout in milliseconds (max: 900000 for Lambda)").default(3e4),enablePixelTracking:o.boolean().describe("Enable GET requests with 1x1 transparent GIF response for pixel tracking").default(!0),healthPath:o.string().describe("Health check endpoint path (e.g., /health)").default("/health")}),d={};t(d,{CorsOptionsSchema:()=>s,CorsOrigin:()=>n,HttpMethod:()=>i,SettingsSchema:()=>l,settings:()=>m});import{zodToSchema as c}from"@walkeros/core/dev";var m=c(l),p={};t(p,{env:()=>g,step:()=>f});var g={};t(g,{push:()=>v});var u=()=>()=>Promise.resolve({ok:!0}),h=()=>{},b={error:h,warn:h,info:h,debug:h,throw:e=>{throw"string"==typeof e?new Error(e):e},json:h,scope:()=>b},v={get push(){return u()},get command(){return u()},get elb(){return u()},logger:b},f={};t(f,{lambdaGet:()=>P,lambdaPost:()=>w});var w={in:{version:"2.0",requestContext:{http:{method:"POST",path:"/collect"},requestId:"req-123"},body:JSON.stringify({name:"page view",data:{title:"Home"}}),isBase64Encoded:!1},out:{name:"page view",data:{title:"Home"},entity:"page",action:"view"}},P={in:{version:"2.0",requestContext:{http:{method:"GET",path:"/collect"},requestId:"req-456"},rawQueryString:"e=page+view&d=%7B%22title%22%3A%22Home%22%7D",isBase64Encoded:!1},out:{name:"page view",data:{title:"Home"},entity:"page",action:"view"}};export{p as examples,d as schemas};//# sourceMappingURL=dev.mjs.map
package/dist/dev.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/lambda/index.ts","../src/lambda/schemas/settings.ts","../src/lambda/schemas/primitives.ts","../src/lambda/schemas/index.ts","../src/lambda/examples/index.ts","../src/lambda/examples/env.ts","../src/lambda/examples/inputs.ts","../src/lambda/examples/events.ts","../src/lambda/examples/outputs.ts"],"sourcesContent":["import type { LambdaSource, EventRequest, Types } from './types';\nimport type { Source } from '@walkeros/core';\nimport { requestToData } from '@walkeros/core';\nimport {\n parseEvent,\n parseBody,\n isEventRequest,\n getCorsHeaders,\n createResponse,\n createPixelResponse,\n getPath,\n} from './utils';\nimport { processEvent } from './push';\nimport { SettingsSchema } from './schemas/settings';\n\nexport * as SourceLambda from './types';\nexport * as schemas from './schemas';\n\n// Export examples\nexport * as examples from './examples';\n\nexport const sourceLambda: Source.Init<Types> = async (context) => {\n const { config = {}, env, setIngest } = context;\n const { push: envPush } = env;\n\n const settings = SettingsSchema.parse(config.settings || {});\n\n const fullConfig: Source.Config<Types> = {\n ...config,\n settings,\n };\n\n const push: Types['push'] = async (event, context) => {\n const requestId = context.awsRequestId;\n let parsed;\n\n try {\n const corsHeaders = getCorsHeaders(settings.cors || false);\n parsed = parseEvent(event);\n const path = getPath(event);\n\n // Health check\n if (settings.healthPath && path === settings.healthPath) {\n return createResponse(\n 200,\n {\n status: 'ok',\n timestamp: Date.now(),\n source: 'lambda',\n requestId,\n },\n corsHeaders,\n requestId,\n );\n }\n\n // Handle OPTIONS for CORS preflight\n if (parsed.method === 'OPTIONS') {\n return createResponse(204, '', corsHeaders, requestId);\n }\n\n // Extract ingest metadata from Lambda event (if config.ingest is defined)\n await setIngest(event);\n\n // Handle GET for pixel tracking\n if (parsed.method === 'GET') {\n if (!settings.enablePixelTracking) {\n return createResponse(\n 405,\n { success: false, error: 'GET not allowed', requestId },\n corsHeaders,\n requestId,\n );\n }\n if (parsed.queryString) {\n const parsedData = requestToData(parsed.queryString);\n if (parsedData && typeof parsedData === 'object') {\n await envPush(parsedData);\n }\n }\n return createPixelResponse(corsHeaders, requestId);\n }\n\n // Handle POST for event data\n if (parsed.method === 'POST') {\n if (!parsed.body) {\n return createResponse(\n 400,\n { success: false, error: 'Request body is required', requestId },\n corsHeaders,\n requestId,\n );\n }\n\n const body = parseBody(parsed.body, parsed.isBase64Encoded);\n\n if (!body || typeof body !== 'object') {\n return createResponse(\n 400,\n { success: false, error: 'Invalid event body', requestId },\n corsHeaders,\n requestId,\n );\n }\n\n if (isEventRequest(body)) {\n const result = await processEvent(\n body as EventRequest,\n envPush,\n env.logger,\n requestId,\n );\n\n if (result.error) {\n return createResponse(\n 400,\n { success: false, error: result.error, requestId },\n corsHeaders,\n requestId,\n );\n }\n\n return createResponse(\n 200,\n { success: true, id: result.id, requestId },\n corsHeaders,\n requestId,\n );\n }\n\n return createResponse(\n 400,\n { success: false, error: 'Invalid request format', requestId },\n corsHeaders,\n requestId,\n );\n }\n\n return createResponse(\n 405,\n { success: false, error: 'Method not allowed', requestId },\n corsHeaders,\n requestId,\n );\n } catch (error) {\n // Log handler errors with context - per using-logger skill\n env.logger?.error('Lambda handler error', {\n error,\n requestId,\n method: parsed?.method,\n });\n return createResponse(\n 500,\n {\n success: false,\n error:\n error instanceof Error ? error.message : 'Internal server error',\n requestId,\n },\n {},\n requestId,\n );\n }\n };\n\n return {\n type: 'lambda',\n config: fullConfig,\n push,\n };\n};\n\nexport default sourceLambda;\n","import { z } from '@walkeros/core/dev';\nimport { CorsOptionsSchema } from './primitives';\n\n/**\n * AWS Lambda source settings schema\n */\nexport const SettingsSchema = z.object({\n cors: z\n .union([z.boolean(), CorsOptionsSchema])\n .describe(\n 'CORS configuration: false = disabled, true = allow all origins, object = custom configuration',\n )\n .default(true),\n\n timeout: z\n .number()\n .int()\n .positive()\n .max(900000) // AWS Lambda max timeout: 15 minutes\n .describe('Request timeout in milliseconds (max: 900000 for Lambda)')\n .default(30000),\n\n enablePixelTracking: z\n .boolean()\n .describe(\n 'Enable GET requests with 1x1 transparent GIF response for pixel tracking',\n )\n .default(true),\n\n healthPath: z\n .string()\n .describe('Health check endpoint path (e.g., /health)')\n .default('/health'),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\n/**\n * HTTP methods enum\n */\nexport const HttpMethod = z.enum([\n 'GET',\n 'POST',\n 'PUT',\n 'PATCH',\n 'DELETE',\n 'OPTIONS',\n 'HEAD',\n]);\n\n/**\n * CORS origin configuration\n * Accepts:\n * - '*' for all origins\n * - Single URL string\n * - Array of URL strings\n */\nexport const CorsOrigin = z.union([\n z.string(),\n z.array(z.string()),\n z.literal('*'),\n]);\n\n/**\n * CORS options schema\n * Configuration for Cross-Origin Resource Sharing\n */\nexport const CorsOptionsSchema = z.object({\n origin: CorsOrigin.describe(\n 'Allowed origins (* for all, URL string, or array of URLs)',\n ).optional(),\n\n methods: z.array(HttpMethod).describe('Allowed HTTP methods').optional(),\n\n headers: z.array(z.string()).describe('Allowed request headers').optional(),\n\n credentials: z\n .boolean()\n .describe('Allow credentials (cookies, authorization headers)')\n .optional(),\n\n maxAge: z\n .number()\n .int()\n .positive()\n .describe('Preflight cache duration in seconds')\n .optional(),\n});\n\nexport type CorsOptions = z.infer<typeof CorsOptionsSchema>;\n","import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\n\n// Export primitives\nexport * from './primitives';\n\n// Export Zod schemas and types\nexport { SettingsSchema, type Settings } from './settings';\n\n// JSON Schema exports (for website PropertyTable and documentation tools)\nexport const settings = zodToSchema(SettingsSchema);\n","export * as env from './env';\nexport * as inputs from './inputs';\nexport * as events from './events';\nexport * as outputs from './outputs';\n","import type { Env } from '../types';\nimport type { Elb, Logger } from '@walkeros/core';\n\n/**\n * Example environment configurations for AWS Lambda source\n *\n * These environments provide standardized mock structures for testing\n * Lambda event handling without requiring actual Lambda deployment.\n */\n\n// Create a properly typed elb/push/command function that returns a promise with PushResult\nconst createMockElbFn = (): Elb.Fn => {\n const fn = (() =>\n Promise.resolve({\n ok: true,\n })) as Elb.Fn;\n return fn;\n};\n\n// Simple no-op logger for demo purposes\nconst noopFn = () => {};\nconst noopLogger: Logger.Instance = {\n error: noopFn,\n info: noopFn,\n debug: noopFn,\n throw: (message: string | Error) => {\n throw typeof message === 'string' ? new Error(message) : message;\n },\n scope: () => noopLogger,\n};\n\n/**\n * Standard mock environment for testing Lambda source\n *\n * Use this for testing Lambda event ingestion and request/response handling\n * without requiring a real AWS Lambda environment.\n */\nexport const push: Env = {\n get push() {\n return createMockElbFn();\n },\n get command() {\n return createMockElbFn();\n },\n get elb() {\n return createMockElbFn();\n },\n logger: noopLogger,\n};\n","import type { APIGatewayProxyEvent, APIGatewayProxyEventV2 } from 'aws-lambda';\n\n/**\n * Real examples of Lambda events this source will receive.\n * These define the CONTRACT - implementation must handle these inputs.\n */\n\n// API Gateway v2 (HTTP API) - POST with walker event\nexport const apiGatewayV2PostEvent: APIGatewayProxyEventV2 = {\n version: '2.0',\n routeKey: '$default',\n rawPath: '/collect',\n rawQueryString: '',\n headers: {\n 'content-type': 'application/json',\n 'user-agent': 'Mozilla/5.0',\n },\n body: JSON.stringify({\n event: 'page view',\n data: { title: 'Home Page', path: '/' },\n user: { id: 'user-123' },\n }),\n isBase64Encoded: false,\n requestContext: {\n accountId: '123456789012',\n apiId: 'api-id',\n domainName: 'api.example.com',\n domainPrefix: 'api',\n http: {\n method: 'POST',\n path: '/collect',\n protocol: 'HTTP/1.1',\n sourceIp: '1.2.3.4',\n userAgent: 'Mozilla/5.0',\n },\n requestId: 'request-123',\n routeKey: '$default',\n stage: 'prod',\n time: '01/Jan/2024:00:00:00 +0000',\n timeEpoch: 1704067200000,\n },\n};\n\n// API Gateway v2 - GET with query params (pixel tracking)\nexport const apiGatewayV2GetEvent: APIGatewayProxyEventV2 = {\n version: '2.0',\n routeKey: '$default',\n rawPath: '/collect',\n rawQueryString: 'event=button%20click&data[id]=cta&data[text]=Sign%20Up',\n headers: {},\n isBase64Encoded: false,\n requestContext: {\n accountId: '123456789012',\n apiId: 'api-id',\n domainName: 'api.example.com',\n domainPrefix: 'api',\n http: {\n method: 'GET',\n path: '/collect',\n protocol: 'HTTP/1.1',\n sourceIp: '1.2.3.4',\n userAgent: 'Mozilla/5.0',\n },\n requestId: 'request-456',\n routeKey: '$default',\n stage: 'prod',\n time: '01/Jan/2024:00:00:01 +0000',\n timeEpoch: 1704067201000,\n },\n};\n\n// API Gateway v1 (REST API) - POST with walker event\nexport const apiGatewayV1PostEvent: APIGatewayProxyEvent = {\n httpMethod: 'POST',\n path: '/collect',\n body: JSON.stringify({\n event: 'product add',\n data: { id: 'P123', name: 'Laptop', price: 999 },\n }),\n headers: { 'content-type': 'application/json' },\n multiValueHeaders: {},\n isBase64Encoded: false,\n pathParameters: null,\n queryStringParameters: null,\n multiValueQueryStringParameters: null,\n stageVariables: null,\n resource: '/collect',\n requestContext: {\n accountId: '123456789012',\n apiId: 'api-id',\n protocol: 'HTTP/1.1',\n httpMethod: 'POST',\n path: '/collect',\n stage: 'prod',\n requestId: 'request-789',\n requestTimeEpoch: 1704067202000,\n resourceId: 'resource-id',\n resourcePath: '/collect',\n identity: {\n sourceIp: '1.2.3.4',\n userAgent: 'Mozilla/5.0',\n accessKey: null,\n accountId: null,\n apiKey: null,\n apiKeyId: null,\n caller: null,\n clientCert: null,\n cognitoAuthenticationProvider: null,\n cognitoAuthenticationType: null,\n cognitoIdentityId: null,\n cognitoIdentityPoolId: null,\n principalOrgId: null,\n user: null,\n userArn: null,\n },\n authorizer: null,\n },\n};\n\n// Health check request\nexport const healthCheckEvent: APIGatewayProxyEventV2 = {\n ...apiGatewayV2GetEvent,\n rawPath: '/health',\n rawQueryString: '',\n requestContext: {\n ...apiGatewayV2GetEvent.requestContext,\n http: {\n ...apiGatewayV2GetEvent.requestContext.http,\n path: '/health',\n },\n },\n};\n\n// Invalid event - malformed JSON\nexport const invalidJsonEvent: APIGatewayProxyEventV2 = {\n ...apiGatewayV2PostEvent,\n body: '{invalid json',\n};\n\n// Missing event field\nexport const missingEventField: APIGatewayProxyEventV2 = {\n ...apiGatewayV2PostEvent,\n body: JSON.stringify({ data: { foo: 'bar' } }),\n};\n","import type { WalkerOS } from '@walkeros/core';\n\n/**\n * Expected walkerOS events from Lambda inputs.\n * These are what processEvent should produce.\n */\n\n// From apiGatewayV2PostEvent\nexport const pageViewEvent: Partial<WalkerOS.Event> = {\n name: 'page view',\n data: { title: 'Home Page', path: '/' },\n user: { id: 'user-123' },\n};\n\n// From apiGatewayV2GetEvent\nexport const buttonClickEvent: Partial<WalkerOS.Event> = {\n name: 'button click',\n data: { id: 'cta', text: 'Sign Up' },\n};\n\n// From apiGatewayV1PostEvent\nexport const productAddEvent: Partial<WalkerOS.Event> = {\n name: 'product add',\n data: { id: 'P123', name: 'Laptop', price: 999 },\n};\n","import type { APIGatewayProxyResult } from 'aws-lambda';\n\n/**\n * Expected Lambda response outputs.\n * Tests verify implementation produces these.\n */\n\n// Successful event processing\n// Shape from: createResponse(200, { success: true, ... }, corsHeaders, requestId)\nexport const successResponse: APIGatewayProxyResult = {\n statusCode: 200,\n headers: {\n 'Content-Type': 'application/json',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Authorization',\n 'Access-Control-Max-Age': '3600',\n },\n body: JSON.stringify({ success: true }),\n isBase64Encoded: false,\n};\n\n// Health check response\n// Shape from: createResponse(200, { status: 'ok', ... }, corsHeaders, requestId)\nexport const healthResponse: APIGatewayProxyResult = {\n statusCode: 200,\n headers: {\n 'Content-Type': 'application/json',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Authorization',\n 'Access-Control-Max-Age': '3600',\n },\n body: JSON.stringify({ status: 'ok' }),\n isBase64Encoded: false,\n};\n\n// Pixel tracking response\n// Shape from: createPixelResponse(corsHeaders, requestId)\nexport const pixelResponse: APIGatewayProxyResult = {\n statusCode: 200,\n headers: {\n 'Content-Type': 'image/gif',\n 'Cache-Control': 'no-cache, no-store, must-revalidate',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Authorization',\n 'Access-Control-Max-Age': '3600',\n },\n body: 'R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7',\n isBase64Encoded: true,\n};\n\n// Error responses\n// Shape from: createResponse(400, { success: false, error: '...' }, corsHeaders, requestId)\nexport const invalidBodyResponse: APIGatewayProxyResult = {\n statusCode: 400,\n headers: {\n 'Content-Type': 'application/json',\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, Authorization',\n 'Access-Control-Max-Age': '3600',\n },\n body: JSON.stringify({ success: false, error: 'Invalid request' }),\n isBase64Encoded: false,\n};\n"],"mappings":"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","names":["z","z"]}
1
+ {"version":3,"sources":["../src/lambda/index.ts","../src/lambda/schemas/settings.ts","../src/lambda/schemas/primitives.ts","../src/lambda/schemas/index.ts","../src/lambda/examples/index.ts","../src/lambda/examples/env.ts","../src/lambda/examples/step.ts"],"sourcesContent":["import type { LambdaSource, EventRequest, Types } from './types';\nimport type { Source } from '@walkeros/core';\nimport { requestToData } from '@walkeros/core';\nimport {\n parseEvent,\n parseBody,\n isEventRequest,\n getCorsHeaders,\n createResponse,\n createPixelResponse,\n getPath,\n} from './utils';\nimport { processEvent } from './push';\nimport { SettingsSchema } from './schemas/settings';\n\nexport * as SourceLambda from './types';\nexport * as schemas from './schemas';\n\n// Export examples\nexport * as examples from './examples';\n\nexport const sourceLambda: Source.Init<Types> = async (context) => {\n const { config = {}, env, setIngest } = context;\n const { push: envPush } = env;\n\n const settings = SettingsSchema.parse(config.settings || {});\n\n const fullConfig: Source.Config<Types> = {\n ...config,\n settings,\n };\n\n const push: Types['push'] = async (event, context) => {\n const requestId = context.awsRequestId;\n let parsed;\n\n try {\n const corsHeaders = getCorsHeaders(settings.cors || false);\n parsed = parseEvent(event);\n const path = getPath(event);\n\n // Health check\n if (settings.healthPath && path === settings.healthPath) {\n return createResponse(\n 200,\n {\n status: 'ok',\n timestamp: Date.now(),\n source: 'lambda',\n requestId,\n },\n corsHeaders,\n requestId,\n );\n }\n\n // Handle OPTIONS for CORS preflight\n if (parsed.method === 'OPTIONS') {\n return createResponse(204, '', corsHeaders, requestId);\n }\n\n // Extract ingest metadata from Lambda event (if config.ingest is defined)\n await setIngest(event);\n\n // Handle GET for pixel tracking\n if (parsed.method === 'GET') {\n if (!settings.enablePixelTracking) {\n return createResponse(\n 405,\n { success: false, error: 'GET not allowed', requestId },\n corsHeaders,\n requestId,\n );\n }\n if (parsed.queryString) {\n const parsedData = requestToData(parsed.queryString);\n if (parsedData && typeof parsedData === 'object') {\n await envPush(parsedData);\n }\n }\n return createPixelResponse(corsHeaders, requestId);\n }\n\n // Handle POST for event data\n if (parsed.method === 'POST') {\n if (!parsed.body) {\n return createResponse(\n 400,\n { success: false, error: 'Request body is required', requestId },\n corsHeaders,\n requestId,\n );\n }\n\n const body = parseBody(parsed.body, parsed.isBase64Encoded);\n\n if (!body || typeof body !== 'object') {\n return createResponse(\n 400,\n { success: false, error: 'Invalid event body', requestId },\n corsHeaders,\n requestId,\n );\n }\n\n if (isEventRequest(body)) {\n const result = await processEvent(\n body as EventRequest,\n envPush,\n env.logger,\n requestId,\n );\n\n if (result.error) {\n return createResponse(\n 400,\n { success: false, error: result.error, requestId },\n corsHeaders,\n requestId,\n );\n }\n\n return createResponse(\n 200,\n { success: true, id: result.id, requestId },\n corsHeaders,\n requestId,\n );\n }\n\n return createResponse(\n 400,\n { success: false, error: 'Invalid request format', requestId },\n corsHeaders,\n requestId,\n );\n }\n\n return createResponse(\n 405,\n { success: false, error: 'Method not allowed', requestId },\n corsHeaders,\n requestId,\n );\n } catch (error) {\n // Log handler errors with context - per using-logger skill\n env.logger?.error('Lambda handler error', {\n error,\n requestId,\n method: parsed?.method,\n });\n return createResponse(\n 500,\n {\n success: false,\n error:\n error instanceof Error ? error.message : 'Internal server error',\n requestId,\n },\n {},\n requestId,\n );\n }\n };\n\n return {\n type: 'lambda',\n config: fullConfig,\n push,\n };\n};\n\nexport default sourceLambda;\n","import { z } from '@walkeros/core/dev';\nimport { CorsOptionsSchema } from './primitives';\n\n/**\n * AWS Lambda source settings schema\n */\nexport const SettingsSchema = z.object({\n cors: z\n .union([z.boolean(), CorsOptionsSchema])\n .describe(\n 'CORS configuration: false = disabled, true = allow all origins, object = custom configuration',\n )\n .default(true),\n\n timeout: z\n .number()\n .int()\n .positive()\n .max(900000) // AWS Lambda max timeout: 15 minutes\n .describe('Request timeout in milliseconds (max: 900000 for Lambda)')\n .default(30000),\n\n enablePixelTracking: z\n .boolean()\n .describe(\n 'Enable GET requests with 1x1 transparent GIF response for pixel tracking',\n )\n .default(true),\n\n healthPath: z\n .string()\n .describe('Health check endpoint path (e.g., /health)')\n .default('/health'),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\n/**\n * HTTP methods enum\n */\nexport const HttpMethod = z.enum([\n 'GET',\n 'POST',\n 'PUT',\n 'PATCH',\n 'DELETE',\n 'OPTIONS',\n 'HEAD',\n]);\n\n/**\n * CORS origin configuration\n * Accepts:\n * - '*' for all origins\n * - Single URL string\n * - Array of URL strings\n */\nexport const CorsOrigin = z.union([\n z.string(),\n z.array(z.string()),\n z.literal('*'),\n]);\n\n/**\n * CORS options schema\n * Configuration for Cross-Origin Resource Sharing\n */\nexport const CorsOptionsSchema = z.object({\n origin: CorsOrigin.describe(\n 'Allowed origins (* for all, URL string, or array of URLs)',\n ).optional(),\n\n methods: z.array(HttpMethod).describe('Allowed HTTP methods').optional(),\n\n headers: z.array(z.string()).describe('Allowed request headers').optional(),\n\n credentials: z\n .boolean()\n .describe('Allow credentials (cookies, authorization headers)')\n .optional(),\n\n maxAge: z\n .number()\n .int()\n .positive()\n .describe('Preflight cache duration in seconds')\n .optional(),\n});\n\nexport type CorsOptions = z.infer<typeof CorsOptionsSchema>;\n","import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\n\n// Export primitives\nexport * from './primitives';\n\n// Export Zod schemas and types\nexport { SettingsSchema, type Settings } from './settings';\n\n// JSON Schema exports (for website PropertyTable and documentation tools)\nexport const settings = zodToSchema(SettingsSchema);\n","export * as env from './env';\nexport * as step from './step';\n","import type { Env } from '../types';\nimport type { Elb, Logger } from '@walkeros/core';\n\n/**\n * Example environment configurations for AWS Lambda source\n *\n * These environments provide standardized mock structures for testing\n * Lambda event handling without requiring actual Lambda deployment.\n */\n\n// Create a properly typed elb/push/command function that returns a promise with PushResult\nconst createMockElbFn = (): Elb.Fn => {\n const fn = (() =>\n Promise.resolve({\n ok: true,\n })) as Elb.Fn;\n return fn;\n};\n\n// Simple no-op logger for demo purposes\nconst noopFn = () => {};\nconst noopLogger: Logger.Instance = {\n error: noopFn,\n warn: noopFn,\n info: noopFn,\n debug: noopFn,\n throw: (message: string | Error) => {\n throw typeof message === 'string' ? new Error(message) : message;\n },\n json: noopFn,\n scope: () => noopLogger,\n};\n\n/**\n * Standard mock environment for testing Lambda source\n *\n * Use this for testing Lambda event ingestion and request/response handling\n * without requiring a real AWS Lambda environment.\n */\nexport const push: Env = {\n get push() {\n return createMockElbFn();\n },\n get command() {\n return createMockElbFn();\n },\n get elb() {\n return createMockElbFn();\n },\n logger: noopLogger,\n};\n","import type { Flow } from '@walkeros/core';\n\nexport const lambdaPost: Flow.StepExample = {\n in: {\n version: '2.0',\n requestContext: {\n http: { method: 'POST', path: '/collect' },\n requestId: 'req-123',\n },\n body: JSON.stringify({\n name: 'page view',\n data: { title: 'Home' },\n }),\n isBase64Encoded: false,\n },\n out: {\n name: 'page view',\n data: { title: 'Home' },\n entity: 'page',\n action: 'view',\n },\n};\n\nexport const lambdaGet: Flow.StepExample = {\n in: {\n version: '2.0',\n requestContext: {\n http: { method: 'GET', path: '/collect' },\n requestId: 'req-456',\n },\n rawQueryString: 'e=page+view&d=%7B%22title%22%3A%22Home%22%7D',\n isBase64Encoded: false,\n },\n out: {\n name: 'page view',\n data: { title: 'Home' },\n entity: 'page',\n action: 'view',\n },\n};\n"],"mappings":";;;;;;;AAEA,SAAS,qBAAqB;;;ACF9B,SAAS,KAAAA,UAAS;;;ACAlB,SAAS,SAAS;AAKX,IAAM,aAAa,EAAE,KAAK;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AASM,IAAM,aAAa,EAAE,MAAM;AAAA,EAChC,EAAE,OAAO;AAAA,EACT,EAAE,MAAM,EAAE,OAAO,CAAC;AAAA,EAClB,EAAE,QAAQ,GAAG;AACf,CAAC;AAMM,IAAM,oBAAoB,EAAE,OAAO;AAAA,EACxC,QAAQ,WAAW;AAAA,IACjB;AAAA,EACF,EAAE,SAAS;AAAA,EAEX,SAAS,EAAE,MAAM,UAAU,EAAE,SAAS,sBAAsB,EAAE,SAAS;AAAA,EAEvE,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,yBAAyB,EAAE,SAAS;AAAA,EAE1E,aAAa,EACV,QAAQ,EACR,SAAS,oDAAoD,EAC7D,SAAS;AAAA,EAEZ,QAAQ,EACL,OAAO,EACP,IAAI,EACJ,SAAS,EACT,SAAS,qCAAqC,EAC9C,SAAS;AACd,CAAC;;;AD9CM,IAAM,iBAAiBC,GAAE,OAAO;AAAA,EACrC,MAAMA,GACH,MAAM,CAACA,GAAE,QAAQ,GAAG,iBAAiB,CAAC,EACtC;AAAA,IACC;AAAA,EACF,EACC,QAAQ,IAAI;AAAA,EAEf,SAASA,GACN,OAAO,EACP,IAAI,EACJ,SAAS,EACT,IAAI,GAAM,EACV,SAAS,0DAA0D,EACnE,QAAQ,GAAK;AAAA,EAEhB,qBAAqBA,GAClB,QAAQ,EACR;AAAA,IACC;AAAA,EACF,EACC,QAAQ,IAAI;AAAA,EAEf,YAAYA,GACT,OAAO,EACP,SAAS,4CAA4C,EACrD,QAAQ,SAAS;AACtB,CAAC;;;AEjCD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAAS,mBAAmB;AAUrB,IAAM,WAAW,YAAY,cAAc;;;ACVlD;AAAA;AAAA;AAAA;AAAA;;;ACAA;AAAA;AAAA;AAAA;AAWA,IAAM,kBAAkB,MAAc;AACpC,QAAM,MAAM,MACV,QAAQ,QAAQ;AAAA,IACd,IAAI;AAAA,EACN,CAAC;AACH,SAAO;AACT;AAGA,IAAM,SAAS,MAAM;AAAC;AACtB,IAAM,aAA8B;AAAA,EAClC,OAAO;AAAA,EACP,MAAM;AAAA,EACN,MAAM;AAAA,EACN,OAAO;AAAA,EACP,OAAO,CAAC,YAA4B;AAClC,UAAM,OAAO,YAAY,WAAW,IAAI,MAAM,OAAO,IAAI;AAAA,EAC3D;AAAA,EACA,MAAM;AAAA,EACN,OAAO,MAAM;AACf;AAQO,IAAM,OAAY;AAAA,EACvB,IAAI,OAAO;AACT,WAAO,gBAAgB;AAAA,EACzB;AAAA,EACA,IAAI,UAAU;AACZ,WAAO,gBAAgB;AAAA,EACzB;AAAA,EACA,IAAI,MAAM;AACR,WAAO,gBAAgB;AAAA,EACzB;AAAA,EACA,QAAQ;AACV;;;AClDA;AAAA;AAAA;AAAA;AAAA;AAEO,IAAM,aAA+B;AAAA,EAC1C,IAAI;AAAA,IACF,SAAS;AAAA,IACT,gBAAgB;AAAA,MACd,MAAM,EAAE,QAAQ,QAAQ,MAAM,WAAW;AAAA,MACzC,WAAW;AAAA,IACb;AAAA,IACA,MAAM,KAAK,UAAU;AAAA,MACnB,MAAM;AAAA,MACN,MAAM,EAAE,OAAO,OAAO;AAAA,IACxB,CAAC;AAAA,IACD,iBAAiB;AAAA,EACnB;AAAA,EACA,KAAK;AAAA,IACH,MAAM;AAAA,IACN,MAAM,EAAE,OAAO,OAAO;AAAA,IACtB,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV;AACF;AAEO,IAAM,YAA8B;AAAA,EACzC,IAAI;AAAA,IACF,SAAS;AAAA,IACT,gBAAgB;AAAA,MACd,MAAM,EAAE,QAAQ,OAAO,MAAM,WAAW;AAAA,MACxC,WAAW;AAAA,IACb;AAAA,IACA,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,EACnB;AAAA,EACA,KAAK;AAAA,IACH,MAAM;AAAA,IACN,MAAM,EAAE,OAAO,OAAO;AAAA,IACtB,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV;AACF;","names":["z","z"]}
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { Source, WalkerOS } from '@walkeros/core';
1
+ import { Source, WalkerOS, Flow } from '@walkeros/core';
2
2
  import { APIGatewayProxyEvent, APIGatewayProxyEventV2, Context, APIGatewayProxyResult } from 'aws-lambda';
3
3
  import * as _walkeros_core_dev from '@walkeros/core/dev';
4
4
  import { z } from '@walkeros/core/dev';
@@ -157,65 +157,19 @@ declare namespace env {
157
157
  export { env_push as push };
158
158
  }
159
159
 
160
- /**
161
- * Real examples of Lambda events this source will receive.
162
- * These define the CONTRACT - implementation must handle these inputs.
163
- */
164
- declare const apiGatewayV2PostEvent: APIGatewayProxyEventV2;
165
- declare const apiGatewayV2GetEvent: APIGatewayProxyEventV2;
166
- declare const apiGatewayV1PostEvent: APIGatewayProxyEvent;
167
- declare const healthCheckEvent: APIGatewayProxyEventV2;
168
- declare const invalidJsonEvent: APIGatewayProxyEventV2;
169
- declare const missingEventField: APIGatewayProxyEventV2;
170
-
171
- declare const inputs_apiGatewayV1PostEvent: typeof apiGatewayV1PostEvent;
172
- declare const inputs_apiGatewayV2GetEvent: typeof apiGatewayV2GetEvent;
173
- declare const inputs_apiGatewayV2PostEvent: typeof apiGatewayV2PostEvent;
174
- declare const inputs_healthCheckEvent: typeof healthCheckEvent;
175
- declare const inputs_invalidJsonEvent: typeof invalidJsonEvent;
176
- declare const inputs_missingEventField: typeof missingEventField;
177
- declare namespace inputs {
178
- export { inputs_apiGatewayV1PostEvent as apiGatewayV1PostEvent, inputs_apiGatewayV2GetEvent as apiGatewayV2GetEvent, inputs_apiGatewayV2PostEvent as apiGatewayV2PostEvent, inputs_healthCheckEvent as healthCheckEvent, inputs_invalidJsonEvent as invalidJsonEvent, inputs_missingEventField as missingEventField };
179
- }
180
-
181
- /**
182
- * Expected walkerOS events from Lambda inputs.
183
- * These are what processEvent should produce.
184
- */
185
- declare const pageViewEvent: Partial<WalkerOS.Event>;
186
- declare const buttonClickEvent: Partial<WalkerOS.Event>;
187
- declare const productAddEvent: Partial<WalkerOS.Event>;
188
-
189
- declare const events_buttonClickEvent: typeof buttonClickEvent;
190
- declare const events_pageViewEvent: typeof pageViewEvent;
191
- declare const events_productAddEvent: typeof productAddEvent;
192
- declare namespace events {
193
- export { events_buttonClickEvent as buttonClickEvent, events_pageViewEvent as pageViewEvent, events_productAddEvent as productAddEvent };
194
- }
195
-
196
- /**
197
- * Expected Lambda response outputs.
198
- * Tests verify implementation produces these.
199
- */
200
- declare const successResponse: APIGatewayProxyResult;
201
- declare const healthResponse: APIGatewayProxyResult;
202
- declare const pixelResponse: APIGatewayProxyResult;
203
- declare const invalidBodyResponse: APIGatewayProxyResult;
160
+ declare const lambdaPost: Flow.StepExample;
161
+ declare const lambdaGet: Flow.StepExample;
204
162
 
205
- declare const outputs_healthResponse: typeof healthResponse;
206
- declare const outputs_invalidBodyResponse: typeof invalidBodyResponse;
207
- declare const outputs_pixelResponse: typeof pixelResponse;
208
- declare const outputs_successResponse: typeof successResponse;
209
- declare namespace outputs {
210
- export { outputs_healthResponse as healthResponse, outputs_invalidBodyResponse as invalidBodyResponse, outputs_pixelResponse as pixelResponse, outputs_successResponse as successResponse };
163
+ declare const step_lambdaGet: typeof lambdaGet;
164
+ declare const step_lambdaPost: typeof lambdaPost;
165
+ declare namespace step {
166
+ export { step_lambdaGet as lambdaGet, step_lambdaPost as lambdaPost };
211
167
  }
212
168
 
213
169
  declare const index_env: typeof env;
214
- declare const index_events: typeof events;
215
- declare const index_inputs: typeof inputs;
216
- declare const index_outputs: typeof outputs;
170
+ declare const index_step: typeof step;
217
171
  declare namespace index {
218
- export { index_env as env, index_events as events, index_inputs as inputs, index_outputs as outputs };
172
+ export { index_env as env, index_step as step };
219
173
  }
220
174
 
221
175
  declare const sourceLambda: Source.Init<Types>;
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Source, WalkerOS } from '@walkeros/core';
1
+ import { Source, WalkerOS, Flow } from '@walkeros/core';
2
2
  import { APIGatewayProxyEvent, APIGatewayProxyEventV2, Context, APIGatewayProxyResult } from 'aws-lambda';
3
3
  import * as _walkeros_core_dev from '@walkeros/core/dev';
4
4
  import { z } from '@walkeros/core/dev';
@@ -157,65 +157,19 @@ declare namespace env {
157
157
  export { env_push as push };
158
158
  }
159
159
 
160
- /**
161
- * Real examples of Lambda events this source will receive.
162
- * These define the CONTRACT - implementation must handle these inputs.
163
- */
164
- declare const apiGatewayV2PostEvent: APIGatewayProxyEventV2;
165
- declare const apiGatewayV2GetEvent: APIGatewayProxyEventV2;
166
- declare const apiGatewayV1PostEvent: APIGatewayProxyEvent;
167
- declare const healthCheckEvent: APIGatewayProxyEventV2;
168
- declare const invalidJsonEvent: APIGatewayProxyEventV2;
169
- declare const missingEventField: APIGatewayProxyEventV2;
170
-
171
- declare const inputs_apiGatewayV1PostEvent: typeof apiGatewayV1PostEvent;
172
- declare const inputs_apiGatewayV2GetEvent: typeof apiGatewayV2GetEvent;
173
- declare const inputs_apiGatewayV2PostEvent: typeof apiGatewayV2PostEvent;
174
- declare const inputs_healthCheckEvent: typeof healthCheckEvent;
175
- declare const inputs_invalidJsonEvent: typeof invalidJsonEvent;
176
- declare const inputs_missingEventField: typeof missingEventField;
177
- declare namespace inputs {
178
- export { inputs_apiGatewayV1PostEvent as apiGatewayV1PostEvent, inputs_apiGatewayV2GetEvent as apiGatewayV2GetEvent, inputs_apiGatewayV2PostEvent as apiGatewayV2PostEvent, inputs_healthCheckEvent as healthCheckEvent, inputs_invalidJsonEvent as invalidJsonEvent, inputs_missingEventField as missingEventField };
179
- }
180
-
181
- /**
182
- * Expected walkerOS events from Lambda inputs.
183
- * These are what processEvent should produce.
184
- */
185
- declare const pageViewEvent: Partial<WalkerOS.Event>;
186
- declare const buttonClickEvent: Partial<WalkerOS.Event>;
187
- declare const productAddEvent: Partial<WalkerOS.Event>;
188
-
189
- declare const events_buttonClickEvent: typeof buttonClickEvent;
190
- declare const events_pageViewEvent: typeof pageViewEvent;
191
- declare const events_productAddEvent: typeof productAddEvent;
192
- declare namespace events {
193
- export { events_buttonClickEvent as buttonClickEvent, events_pageViewEvent as pageViewEvent, events_productAddEvent as productAddEvent };
194
- }
195
-
196
- /**
197
- * Expected Lambda response outputs.
198
- * Tests verify implementation produces these.
199
- */
200
- declare const successResponse: APIGatewayProxyResult;
201
- declare const healthResponse: APIGatewayProxyResult;
202
- declare const pixelResponse: APIGatewayProxyResult;
203
- declare const invalidBodyResponse: APIGatewayProxyResult;
160
+ declare const lambdaPost: Flow.StepExample;
161
+ declare const lambdaGet: Flow.StepExample;
204
162
 
205
- declare const outputs_healthResponse: typeof healthResponse;
206
- declare const outputs_invalidBodyResponse: typeof invalidBodyResponse;
207
- declare const outputs_pixelResponse: typeof pixelResponse;
208
- declare const outputs_successResponse: typeof successResponse;
209
- declare namespace outputs {
210
- export { outputs_healthResponse as healthResponse, outputs_invalidBodyResponse as invalidBodyResponse, outputs_pixelResponse as pixelResponse, outputs_successResponse as successResponse };
163
+ declare const step_lambdaGet: typeof lambdaGet;
164
+ declare const step_lambdaPost: typeof lambdaPost;
165
+ declare namespace step {
166
+ export { step_lambdaGet as lambdaGet, step_lambdaPost as lambdaPost };
211
167
  }
212
168
 
213
169
  declare const index_env: typeof env;
214
- declare const index_events: typeof events;
215
- declare const index_inputs: typeof inputs;
216
- declare const index_outputs: typeof outputs;
170
+ declare const index_step: typeof step;
217
171
  declare namespace index {
218
- export { index_env as env, index_events as events, index_inputs as inputs, index_outputs as outputs };
172
+ export { index_env as env, index_step as step };
219
173
  }
220
174
 
221
175
  declare const sourceLambda: Source.Init<Types>;