@walkeros/server-source-aws 3.0.2 → 4.0.0-next-1773967844643
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 +16 -0
- package/dist/dev.d.mts +37 -3
- package/dist/dev.d.ts +37 -3
- package/dist/dev.js +1 -1
- package/dist/dev.js.map +1 -1
- package/dist/dev.mjs +1 -1
- package/dist/dev.mjs.map +1 -1
- package/dist/index.d.mts +35 -2
- package/dist/index.d.ts +35 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/walkerOS.json +22 -5
- package/package.json +6 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @walkeros/server-source-aws
|
|
2
2
|
|
|
3
|
+
## 4.0.0-next-1773967844643
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 956c337: Add createTrigger following unified Trigger.CreateFn interface. Step
|
|
8
|
+
examples updated with trigger metadata.
|
|
9
|
+
|
|
10
|
+
### Patch Changes
|
|
11
|
+
|
|
12
|
+
- Updated dependencies [dfc6738]
|
|
13
|
+
- Updated dependencies [966342b]
|
|
14
|
+
- Updated dependencies [bee8ba7]
|
|
15
|
+
- Updated dependencies [966342b]
|
|
16
|
+
- Updated dependencies [df990d4]
|
|
17
|
+
- @walkeros/core@4.0.0-next-1773967844643
|
|
18
|
+
|
|
3
19
|
## 3.0.2
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
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, Flow } from '@walkeros/core';
|
|
4
|
-
import { APIGatewayProxyEvent, APIGatewayProxyEventV2, Context } from 'aws-lambda';
|
|
3
|
+
import { Source, Flow, Trigger } from '@walkeros/core';
|
|
4
|
+
import { APIGatewayProxyEvent, APIGatewayProxyEventV2, Context, APIGatewayProxyResult } from 'aws-lambda';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* HTTP methods enum
|
|
@@ -83,6 +83,7 @@ declare namespace index$1 {
|
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
type LambdaEvent = APIGatewayProxyEvent | APIGatewayProxyEventV2;
|
|
86
|
+
type LambdaResult = APIGatewayProxyResult;
|
|
86
87
|
type LambdaContext = Context;
|
|
87
88
|
interface Env extends Source.Env {
|
|
88
89
|
lambdaEvent?: LambdaEvent;
|
|
@@ -113,10 +114,43 @@ declare namespace step {
|
|
|
113
114
|
export { step_apiGatewayV1Post as apiGatewayV1Post, step_lambdaGet as lambdaGet, step_lambdaPost as lambdaPost };
|
|
114
115
|
}
|
|
115
116
|
|
|
117
|
+
interface Content {
|
|
118
|
+
[key: string]: unknown;
|
|
119
|
+
}
|
|
120
|
+
interface Result {
|
|
121
|
+
statusCode: number;
|
|
122
|
+
body: unknown;
|
|
123
|
+
headers: Record<string, string>;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Lambda source createTrigger.
|
|
127
|
+
*
|
|
128
|
+
* Boots the collector via startFlow, then invokes the Lambda source's push()
|
|
129
|
+
* with a real API Gateway event and a minimal Lambda context.
|
|
130
|
+
*
|
|
131
|
+
* Content is the raw Lambda event object (API Gateway v1 or v2 format).
|
|
132
|
+
* Result contains statusCode, parsed body, and headers.
|
|
133
|
+
*
|
|
134
|
+
* @example
|
|
135
|
+
* const { trigger, flow } = await createTrigger(config);
|
|
136
|
+
* const result = await trigger('POST')({ version: '2.0', ... });
|
|
137
|
+
* console.log(result.statusCode, result.body);
|
|
138
|
+
*/
|
|
139
|
+
declare const createTrigger: Trigger.CreateFn<Content, Result>;
|
|
140
|
+
/**
|
|
141
|
+
* Legacy trigger — takes a source instance directly.
|
|
142
|
+
* Preserved for CLI simulate path.
|
|
143
|
+
*/
|
|
144
|
+
declare function trigger(source: {
|
|
145
|
+
push: (event: LambdaEvent, context: LambdaContext) => Promise<LambdaResult>;
|
|
146
|
+
}): (content: Content) => Promise<LambdaResult>;
|
|
147
|
+
|
|
148
|
+
declare const index_createTrigger: typeof createTrigger;
|
|
116
149
|
declare const index_env: typeof env;
|
|
117
150
|
declare const index_step: typeof step;
|
|
151
|
+
declare const index_trigger: typeof trigger;
|
|
118
152
|
declare namespace index {
|
|
119
|
-
export { index_env as env, index_step as step };
|
|
153
|
+
export { index_createTrigger as createTrigger, index_env as env, index_step as step, index_trigger as trigger };
|
|
120
154
|
}
|
|
121
155
|
|
|
122
156
|
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, Flow } from '@walkeros/core';
|
|
4
|
-
import { APIGatewayProxyEvent, APIGatewayProxyEventV2, Context } from 'aws-lambda';
|
|
3
|
+
import { Source, Flow, Trigger } from '@walkeros/core';
|
|
4
|
+
import { APIGatewayProxyEvent, APIGatewayProxyEventV2, Context, APIGatewayProxyResult } from 'aws-lambda';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* HTTP methods enum
|
|
@@ -83,6 +83,7 @@ declare namespace index$1 {
|
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
type LambdaEvent = APIGatewayProxyEvent | APIGatewayProxyEventV2;
|
|
86
|
+
type LambdaResult = APIGatewayProxyResult;
|
|
86
87
|
type LambdaContext = Context;
|
|
87
88
|
interface Env extends Source.Env {
|
|
88
89
|
lambdaEvent?: LambdaEvent;
|
|
@@ -113,10 +114,43 @@ declare namespace step {
|
|
|
113
114
|
export { step_apiGatewayV1Post as apiGatewayV1Post, step_lambdaGet as lambdaGet, step_lambdaPost as lambdaPost };
|
|
114
115
|
}
|
|
115
116
|
|
|
117
|
+
interface Content {
|
|
118
|
+
[key: string]: unknown;
|
|
119
|
+
}
|
|
120
|
+
interface Result {
|
|
121
|
+
statusCode: number;
|
|
122
|
+
body: unknown;
|
|
123
|
+
headers: Record<string, string>;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Lambda source createTrigger.
|
|
127
|
+
*
|
|
128
|
+
* Boots the collector via startFlow, then invokes the Lambda source's push()
|
|
129
|
+
* with a real API Gateway event and a minimal Lambda context.
|
|
130
|
+
*
|
|
131
|
+
* Content is the raw Lambda event object (API Gateway v1 or v2 format).
|
|
132
|
+
* Result contains statusCode, parsed body, and headers.
|
|
133
|
+
*
|
|
134
|
+
* @example
|
|
135
|
+
* const { trigger, flow } = await createTrigger(config);
|
|
136
|
+
* const result = await trigger('POST')({ version: '2.0', ... });
|
|
137
|
+
* console.log(result.statusCode, result.body);
|
|
138
|
+
*/
|
|
139
|
+
declare const createTrigger: Trigger.CreateFn<Content, Result>;
|
|
140
|
+
/**
|
|
141
|
+
* Legacy trigger — takes a source instance directly.
|
|
142
|
+
* Preserved for CLI simulate path.
|
|
143
|
+
*/
|
|
144
|
+
declare function trigger(source: {
|
|
145
|
+
push: (event: LambdaEvent, context: LambdaContext) => Promise<LambdaResult>;
|
|
146
|
+
}): (content: Content) => Promise<LambdaResult>;
|
|
147
|
+
|
|
148
|
+
declare const index_createTrigger: typeof createTrigger;
|
|
116
149
|
declare const index_env: typeof env;
|
|
117
150
|
declare const index_step: typeof step;
|
|
151
|
+
declare const index_trigger: typeof trigger;
|
|
118
152
|
declare namespace index {
|
|
119
|
-
export { index_env as env, index_step as step };
|
|
153
|
+
export { index_createTrigger as createTrigger, index_env as env, index_step as step, index_trigger as trigger };
|
|
120
154
|
}
|
|
121
155
|
|
|
122
156
|
export { index as examples, index$1 as schemas };
|
package/dist/dev.js
CHANGED
|
@@ -1 +1 @@
|
|
|
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:()=>z});var b={};i(b,{push:()=>y});var w=()=>()=>Promise.resolve({ok:!0}),v=()=>{},f={error:v,warn:v,info:v,debug:v,throw:e=>{throw"string"==typeof e?new Error(e):e},json:v,scope:()=>f},y={get push(){return w()},get command(){return w()},get elb(){return w()},logger:f},z={};i(z,{apiGatewayV1Post:()=>q,lambdaGet:()=>O,lambdaPost:()=>P});var P={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"}},q={in:{httpMethod:"POST",path:"/collect",requestContext:{requestId:"req-789",identity:{sourceIp:"203.0.113.42"}},queryStringParameters:null,body:JSON.stringify({name:"page view",data:{title:"Home"}}),isBase64Encoded:!1},out:{name:"page view",data:{title:"Home"},entity:"page",action:"view"}},O={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
|
|
1
|
+
"use strict";var e,n=Object.defineProperty,t=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyNames,s=Object.prototype.hasOwnProperty,r=(e,t)=>{for(var o in t)n(e,o,{get:t[o],enumerable:!0})},i={};r(i,{examples:()=>h,schemas:()=>f}),module.exports=(e=i,((e,r,i,a)=>{if(r&&"object"==typeof r||"function"==typeof r)for(let c of o(r))s.call(e,c)||c===i||n(e,c,{get:()=>r[c],enumerable:!(a=t(r,c))||a.enumerable});return e})(n({},"__esModule",{value:!0}),e));require("@walkeros/core");var a=require("@walkeros/core/dev"),c=require("@walkeros/core/dev"),u=c.z.enum(["GET","POST","PUT","PATCH","DELETE","OPTIONS","HEAD"]),l=c.z.union([c.z.string(),c.z.array(c.z.string()),c.z.literal("*")]),g=c.z.object({origin:l.describe("Allowed origins (* for all, URL string, or array of URLs)").optional(),methods:c.z.array(u).describe("Allowed HTTP methods").optional(),headers:c.z.array(c.z.string()).describe("Allowed request headers").optional(),credentials:c.z.boolean().describe("Allow credentials (cookies, authorization headers)").optional(),maxAge:c.z.number().int().positive().describe("Preflight cache duration in seconds").optional()}),d=a.z.object({cors:a.z.union([a.z.boolean(),g]).describe("CORS configuration: false = disabled, true = allow all origins, object = custom configuration").default(!0),timeout:a.z.number().int().positive().max(9e5).describe("Request timeout in milliseconds (max: 900000 for Lambda)").default(3e4),enablePixelTracking:a.z.boolean().describe("Enable GET requests with 1x1 transparent GIF response for pixel tracking").default(!0),healthPath:a.z.string().describe("Health check endpoint path (e.g., /health)").default("/health")}),f={};r(f,{CorsOptionsSchema:()=>g,CorsOrigin:()=>l,HttpMethod:()=>u,SettingsSchema:()=>d,settings:()=>p});var p=(0,require("@walkeros/core/dev").zodToSchema)(d),h={};r(h,{createTrigger:()=>re,env:()=>b,step:()=>k,trigger:()=>ie});var b={};r(b,{push:()=>v});var y=()=>()=>Promise.resolve({ok:!0}),m=()=>{},w={error:m,warn:m,info:m,debug:m,throw:e=>{throw"string"==typeof e?new Error(e):e},json:m,scope:()=>w},v={get push(){return y()},get command(){return y()},get elb(){return y()},logger:w},k={};r(k,{apiGatewayV1Post:()=>q,lambdaGet:()=>j,lambdaPost:()=>O});var O={trigger:{type:"POST"},in:{version:"2.0",requestContext:{http:{method:"POST",path:"/collect"},requestId:"req-123"},body:JSON.stringify({event:"page view",data:{title:"Home"}}),isBase64Encoded:!1},out:{name:"page view",data:{title:"Home"},entity:"page",action:"view"}},q={trigger:{type:"POST"},in:{httpMethod:"POST",path:"/collect",requestContext:{requestId:"req-789",identity:{sourceIp:"203.0.113.42"}},queryStringParameters:null,body:JSON.stringify({event:"page view",data:{title:"Home"}}),isBase64Encoded:!1},out:{name:"page view",data:{title:"Home"},entity:"page",action:"view"}},j={trigger:{type:"GET"},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"}},C=require("@walkeros/core"),P=require("@walkeros/core"),A=require("@walkeros/core"),S=require("@walkeros/core"),E=require("@walkeros/core"),x=require("@walkeros/core"),D=require("@walkeros/core"),T=require("@walkeros/core"),z=require("@walkeros/core"),H=require("@walkeros/core"),$=require("@walkeros/core"),R={Action:"action",Actions:"actions",Config:"config",Consent:"consent",Context:"context",Custom:"custom",Destination:"destination",Elb:"elb",Globals:"globals",Hook:"hook",Init:"init",Link:"link",On:"on",Prefix:"data-elb",Ready:"ready",Run:"run",Session:"session",Shutdown:"shutdown",User:"user",Walker:"walker"};function I(e){var n;const t={};for(const[o,s]of Object.entries(e))(null==(n=s.config)?void 0:n.next)?t[o]={next:s.config.next}:t[o]={};return t}function G(e,n){const t=e.config||{},o=e[n];return void 0!==o?{config:{...t,[n]:o},chainValue:o}:{config:t,chainValue:void 0}}function B(e,n={}){if(!e)return[];if(Array.isArray(e))return e;const t=[],o=new Set;let s=e;for(;s&&n[s]&&!o.has(s);){o.add(s),t.push(s);const e=n[s].next;if(Array.isArray(e)){t.push(...e);break}s=e}return t}async function M(e,n,t){if(n.init&&!n.config.init){const o=n.type||"unknown",s=e.logger.scope(`transformer:${o}`),r={collector:e,logger:s,id:t,config:n.config,env:J(n.config.env)};s.debug("init");const i=await(0,D.useHooks)(n.init,"TransformerInit",e.hooks)(r);if(!1===i)return!1;n.config={...i||n.config,env:(null==i?void 0:i.env)||n.config.env,init:!0},s.debug("init done")}return!0}async function N(e,n,t,o,s,r){const i=n.type||"unknown",a=e.logger.scope(`transformer:${i}`),c={collector:e,logger:a,id:t,ingest:s,config:n.config,env:{...J(n.config.env),...r?{respond:r}:{}}};a.debug("push",{event:o.name});const u=await(0,D.useHooks)(n.push,"TransformerPush",e.hooks)(o,c);return a.debug("push done"),u}async function L(e,n,t,o,s,r){let i=o,a=r;for(const o of t){const t=n[o];if(!t){e.logger.warn(`Transformer not found: ${o}`);continue}if(!await(0,D.tryCatchAsync)(M)(e,t,o))return e.logger.error(`Transformer init failed: ${o}`),null;const r=await(0,D.tryCatchAsync)(N,n=>(e.logger.scope(`transformer:${t.type||"unknown"}`).error("Push failed",{error:n}),!1))(e,t,o,i,s,a);if(!1===r)return null;if(r&&"object"==typeof r){const{event:t,respond:o,next:c}=r;if(o&&(a=o),c){const o=B(c,I(n));return o.length>0?L(e,n,o,t||i,s,a):(e.logger.warn(`Branch target not found: ${JSON.stringify(c)}`),null)}t&&(i=t)}}return i}function J(e){return e&&(0,D.isObject)(e)?e:{}}async function U(e,n,t){const{code:o,config:s={},env:r={},primary:i,next:a}=t;let c,u;const l=B(a,I(e.transformers)),g=e.logger.scope("source").scope(n),d={push:(t,o={})=>e.push(t,{...o,id:n,ingest:c,respond:u,mapping:s,preChain:l}),command:e.command,sources:e.sources,elb:e.sources.elb.push,logger:g,...r},f={collector:e,logger:g,id:n,config:s,env:d,setIngest:async n=>{c=s.ingest?await(0,x.getMappingValue)(n,s.ingest,{collector:e}):void 0},setRespond:e=>{u=e}},p=await(0,x.tryCatchAsync)(o)(f);if(!p)return;const h=p.type||"unknown",b=e.logger.scope(h).scope(n);return d.logger=b,i&&(p.config={...p.config,primary:i}),p}function F(e,n,t,o,s){if(!n.on)return;const r=n.type||"unknown",i=e.logger.scope(r).scope("on").scope(o),a={collector:e,logger:i,id:t,config:n.config,data:s,env:Z(n.env,n.config.env)};(0,E.tryCatch)(n.on)(o,a)}async function V(e,n,t,o){let s,r=t||[];switch(t||(r=e.on[n]||[]),n){case R.Consent:s=o||e.consent;break;case R.Session:s=e.session;break;case R.User:s=o||e.user;break;case R.Custom:s=o||e.custom;break;case R.Globals:s=o||e.globals;break;case R.Config:s=o||e.config;break;case R.Ready:case R.Run:default:s=void 0}let i=!1;for(const t of Object.values(e.sources))t.on&&!1===await(0,E.tryCatchAsync)(t.on)(n,s)&&(i=!0);if(Object.entries(e.destinations).forEach(([t,o])=>{if(o.on){if(!o.config.init)return o.queueOn=o.queueOn||[],void o.queueOn.push({type:n,data:s});F(e,o,t,n,s)}}),(Object.keys(e.pending.sources).length>0||Object.keys(e.pending.destinations).length>0)&&await async function(e,n){var t,o;for(const[o,s]of Object.entries(e.pending.sources)){if(!e.pending.sources[o]||e.sources[o])continue;const r=null==(t=s.config)?void 0:t.require;if(!r)continue;const i=r.indexOf(n);if(-1===i)continue;if(r.splice(i,1),r.length>0)continue;delete e.pending.sources[o];const a=await U(e,o,s);a&&(e.sources[o]=a)}for(const[t,s]of Object.entries(e.pending.destinations)){if(!e.pending.destinations[t]||e.destinations[t])continue;const r=null==(o=s.config)?void 0:o.require;if(!r)continue;const i=r.indexOf(n);if(-1===i)continue;if(r.splice(i,1),r.length>0)continue;delete e.pending.destinations[t];const a=Y(s);!1!==a.config.queue&&(a.queuePush=[...e.queue]),e.destinations[t]=a}}(e,n),!r.length)return!i;switch(n){case R.Consent:!function(e,n,t){const o=t||e.consent;n.forEach(n=>{Object.keys(o).filter(e=>e in n).forEach(t=>{(0,E.tryCatch)(n[t])(e,o)})})}(e,r,o);break;case R.Ready:case R.Run:c=r,(a=e).allowed&&c.forEach(e=>{(0,E.tryCatch)(e)(a)});break;case R.Session:!function(e,n){e.session&&n.forEach(n=>{(0,E.tryCatch)(n)(e,e.session)})}(e,r);break;default:r.forEach(n=>{"function"==typeof n&&(0,E.tryCatch)(n)(e,s)})}var a,c;return!i}async function _(e,n,t){const{code:o,config:s={},env:r={},before:i}=n;if(!(0,A.isFunction)(o.push))return X({ok:!1,failed:{invalid:{type:"invalid",error:"Destination code must have a push method"}}});const a=t||s||{init:!1},c=i?{...a,before:i}:a,u={...o,config:c,env:Z(o.env,r)};let l=u.config.id;if(!l)do{l=(0,A.getId)(4)}while(e.destinations[l]);return e.destinations[l]=u,!1!==u.config.queue&&(u.queuePush=[...e.queue]),Q(e,void 0,{},{[l]:u})}async function Q(e,n,t={},o){const{allowed:s,consent:r,globals:i,user:a}=e;if(!s)return X({ok:!1});n&&(e.queue.push(n),e.status.in++),o||(o=e.destinations);const c=await Promise.all(Object.entries(o||{}).map(async([o,s])=>{var c,u;let l=(s.queuePush||[]).map(e=>({...e,consent:r}));if(s.queuePush=[],n){const e=(0,A.clone)(n);l.push(e)}if(!l.length&&!(null==(c=s.queueOn)?void 0:c.length))return{id:o,destination:s,skipped:!0};if(!l.length&&(null==(u=s.queueOn)?void 0:u.length)){const n=await(0,A.tryCatchAsync)(W)(e,s,o);return{id:o,destination:s,skipped:!n}}const g=[],d=l.filter(e=>{const n=(0,A.getGrantedConsent)(s.config.consent,r,e.consent);return!n||(e.consent=n,g.push(e),!1)});if(s.queuePush.push(...d),!g.length)return{id:o,destination:s,queue:l};if(!await(0,A.tryCatchAsync)(W)(e,s,o))return{id:o,destination:s,queue:l};let f,p;s.dlq||(s.dlq=[]);const h=function(e,n){const t=e.config.before;return t?B(t,I(n)):[]}(s,e.transformers);let b=0;return await Promise.all(g.map(async n=>{n.globals=(0,A.assign)(i,n.globals),n.user=(0,A.assign)(a,n.user);let r=n;if(h.length>0&&e.transformers&&Object.keys(e.transformers).length>0){const o=await L(e,e.transformers,h,n,t.ingest,t.respond);if(null===o)return n;r=o}const c=Date.now(),u=await(0,A.tryCatchAsync)(K,n=>{const t=s.type||"unknown";e.logger.scope(t).error("Push failed",{error:n,event:r.name}),f=n,s.dlq.push([r,n])})(e,s,o,r,t.ingest,t.respond);return b+=Date.now()-c,void 0!==u&&(p=u),n})),{id:o,destination:s,error:f,response:p,totalDuration:b}})),u={},l={},g={};for(const n of c){if(n.skipped)continue;const t={type:n.destination.type||"unknown",data:n.response};e.status.destinations[n.id]||(e.status.destinations[n.id]={count:0,failed:0,duration:0});const o=e.status.destinations[n.id],s=Date.now();n.error?(t.error=n.error,g[n.id]=t,o.failed++,o.lastAt=s,o.duration+=n.totalDuration||0,e.status.failed++):n.queue&&n.queue.length?l[n.id]=t:(u[n.id]=t,o.count++,o.lastAt=s,o.duration+=n.totalDuration||0,e.status.out++)}return X({event:n,...Object.keys(u).length&&{done:u},...Object.keys(l).length&&{queued:l},...Object.keys(g).length&&{failed:g}})}async function W(e,n,t){var o;if(n.init&&!n.config.init){const s=n.type||"unknown",r=e.logger.scope(s),i={collector:e,logger:r,id:t,config:n.config,env:Z(n.env,n.config.env)};r.debug("init");const a=await(0,A.useHooks)(n.init,"DestinationInit",e.hooks)(i);if(!1===a)return a;if(n.config={...a||n.config,init:!0},null==(o=n.queueOn)?void 0:o.length){const o=n.queueOn;n.queueOn=[];for(const{type:s,data:r}of o)F(e,n,t,s,r)}r.debug("init done")}return!0}async function K(e,n,t,o,s,r){const{config:i}=n,a=await(0,A.processEventMapping)(o,i,e);if(a.ignore)return!1;const c=n.type||"unknown",u=e.logger.scope(c),l={collector:e,logger:u,id:t,config:i,data:a.data,rule:a.mapping,ingest:s,env:{...Z(n.env,i.env),...r?{respond:r}:{}}},g=a.mapping,d=a.mappingKey||"* *";if(!(null==g?void 0:g.batch)||!n.pushBatch){u.debug("push",{event:a.event.name});const t=await(0,A.useHooks)(n.push,"DestinationPush",e.hooks)(a.event,l);return u.debug("push done"),t}{if(n.batches=n.batches||{},!n.batches[d]){const o={key:d,events:[],data:[]};n.batches[d]={batched:o,batchFn:(0,A.debounce)(()=>{const o=n.batches[d].batched,a={collector:e,logger:u,id:t,config:i,data:void 0,rule:g,ingest:s,env:{...Z(n.env,i.env),...r?{respond:r}:{}}};u.debug("push batch",{events:o.events.length}),(0,A.useHooks)(n.pushBatch,"DestinationPushBatch",e.hooks)(o,a),u.debug("push batch done"),o.events=[],o.data=[]},g.batch)}}const o=n.batches[d];o.batched.events.push(a.event),(0,A.isDefined)(a.data)&&o.batched.data.push(a.data),o.batchFn()}return!0}function X(e){return{ok:!(null==e?void 0:e.failed),...e}}function Y(e){const{code:n,config:t={},env:o={}}=e,{config:s}=G(e,"before"),r={...n.config,...t,...s},i=Z(n.env,o);return{...n,config:r,env:i}}function Z(e,n){return e||n?n?e&&(0,A.isObject)(e)&&(0,A.isObject)(n)?{...e,...n}:n:e:{}}async function ee(e,n,t){const o=Object.entries(e).map(async([e,o])=>{var s;const r=o.destroy;if(!r)return;const i=o.type||"unknown",a=t.scope(i),c={id:e,config:o.config,env:null!=(s=o.env)?s:{},logger:a};try{await Promise.race([r(c),new Promise((t,o)=>setTimeout(()=>o(new Error(`${n} '${e}' destroy timed out`)),5e3))])}catch(t){a.error(`${n} '${e}' destroy failed: ${t}`)}});await Promise.allSettled(o)}async function ne(e,n,t,o){let s,r,i=!1,a=!1;switch(n){case R.Config:(0,z.isObject)(t)&&((0,T.assign)(e.config,t,{shallow:!1}),r=t,i=!0);break;case R.Consent:if((0,z.isObject)(t)){const{update:n,runQueue:o}=function(e,n){let t=!1;const o={};return Object.entries(n).forEach(([e,n])=>{const s=!!n;o[e]=s,t=t||s}),e.consent=(0,C.assign)(e.consent,o),{update:o,runQueue:t}}(e,t);r=n,i=!0,a=o}break;case R.Custom:(0,z.isObject)(t)&&(e.custom=(0,T.assign)(e.custom,t),r=t,i=!0);break;case R.Destination:(0,z.isObject)(t)&&("code"in t&&(0,z.isObject)(t.code)?s=await _(e,t,o):(0,T.isFunction)(t.push)&&(s=await _(e,{code:t},o)));break;case R.Globals:(0,z.isObject)(t)&&(e.globals=(0,T.assign)(e.globals,t),r=t,i=!0);break;case R.On:(0,T.isString)(t)&&await async function(e,n,t){const o=e.on,s=o[n]||[],r=(0,S.isArray)(t)?t:[t];r.forEach(e=>{s.push(e)}),o[n]=s,await V(e,n,r)}(e,t,o);break;case R.Ready:i=!0;break;case R.Run:s=await async function(e,n){return e.allowed=!0,e.count=0,e.group=(0,T.getId)(),e.timing=Date.now(),n&&(n.consent&&(e.consent=(0,T.assign)(e.consent,n.consent)),n.user&&(e.user=(0,T.assign)(e.user,n.user)),n.globals&&(e.globals=(0,T.assign)(e.config.globalsStatic||{},n.globals)),n.custom&&(e.custom=(0,T.assign)(e.custom,n.custom))),Object.values(e.destinations).forEach(e=>{e.queuePush=[]}),e.queue=[],e.round++,await Q(e)}(e,t),i=!0;break;case R.Session:i=!0;break;case R.Shutdown:await async function(e){const n=e.logger;await ee(e.sources,"source",n),await ee(e.destinations,"destination",n),await ee(e.transformers,"transformer",n),await ee(e.stores,"store",n)}(e);break;case R.User:(0,z.isObject)(t)&&((0,T.assign)(e.user,t,{shallow:!1}),r=t,i=!0)}return i&&await V(e,n,void 0,r),a&&(s=await Q(e)),s||X({ok:!0})}function te(e,n){return(0,H.useHooks)(async(t,o={})=>await(0,H.tryCatchAsync)(async()=>{const s=Date.now(),{id:r,ingest:i,respond:a,mapping:c,preChain:u}=o;let l=t;const g=i?Object.freeze(i):void 0;if(c){const n=await(0,H.processEventMapping)(l,c,e);if(n.ignore)return X({ok:!0});if(c.consent&&!(0,H.getGrantedConsent)(c.consent,e.consent,n.event.consent))return X({ok:!0});l=n.event}if((null==u?void 0:u.length)&&e.transformers&&Object.keys(e.transformers).length>0){const n=await L(e,e.transformers,u,l,g,a);if(null===n)return X({ok:!0});l=n}const d=n(l),f=function(e,n){if(!n.name)throw new Error("Event name is required");const[t,o]=n.name.split(" ");if(!t||!o)throw new Error("Event name is invalid");++e.count;const{timestamp:s=Date.now(),group:r=e.group,count:i=e.count}=n,{name:a=`${t} ${o}`,data:c={},context:u={},globals:l=e.globals,custom:g={},user:d=e.user,nested:f=[],consent:p=e.consent,id:h=`${s}-${r}-${i}`,trigger:b="",entity:y=t,action:m=o,timing:w=0,version:v={source:e.version,tagging:e.config.tagging||0},source:k={type:"collector",id:"",previous_id:""}}=n;return{name:a,data:c,context:u,globals:l,custom:g,user:d,nested:f,consent:p,id:h,trigger:b,entity:y,action:m,timestamp:s,timing:w,group:r,count:i,version:v,source:k}}(e,d),p=await Q(e,f,{id:r,ingest:g,respond:a});if(r){e.status.sources[r]||(e.status.sources[r]={count:0,duration:0});const n=e.status.sources[r];n.count++,n.lastAt=Date.now(),n.duration+=Date.now()-s}return p},()=>X({ok:!1}))(),"Push",e.hooks)}async function oe(e){var n,t;const o=(0,P.assign)({globalsStatic:{},sessionStatic:{},tagging:0,run:!0},e,{merge:!1,extend:!1}),s={level:null==(n=e.logger)?void 0:n.level,handler:null==(t=e.logger)?void 0:t.handler},r=(0,P.createLogger)(s),i={...o.globalsStatic,...e.globals},a={allowed:!1,config:o,consent:e.consent||{},count:0,custom:e.custom||{},destinations:{},transformers:{},stores:{},globals:i,group:"",hooks:{},logger:r,on:{},queue:[],round:0,session:void 0,status:{startedAt:Date.now(),in:0,out:0,failed:0,sources:{},destinations:{}},timing:Date.now(),user:e.user||{},version:"3.0.2",sources:{},pending:{sources:{},destinations:{}},push:void 0,command:void 0};var c,u;a.push=te(a,e=>({timing:Math.round((Date.now()-a.timing)/10)/100,source:{type:"collector",id:"",previous_id:""},...e})),a.command=(c=a,u=ne,(0,$.useHooks)(async(e,n,t)=>await(0,$.tryCatchAsync)(async()=>await u(c,e,n,t),()=>X({ok:!1}))(),"Command",c.hooks));const l=e.stores||{};return a.stores=await async function(e,n={}){const t={};for(const[o,s]of Object.entries(n)){const{code:n,config:r={},env:i={}}=s,a=e.logger.scope("store").scope(o),c={collector:e,logger:a,id:o,config:r,env:i},u=await n(c);t[o]=u}return t}(a,l),function(e,n,t){const o=new Map;for(const[t,s]of Object.entries(e))n[t]&&o.set(s,n[t]);if(0!==o.size)for(const e of[t.transformers,t.destinations,t.sources])if(e)for(const n of Object.values(e))s(n.env);function s(e){if(e)for(const[n,t]of Object.entries(e))if("object"==typeof t&&null!==t){const s=o.get(t);s&&(e[n]=s)}}}(l,a.stores,e),a.destinations=await async function(e,n={}){var t,o;const s={};for(const[r,i]of Object.entries(n))(null==(o=null==(t=i.config)?void 0:t.require)?void 0:o.length)?e.pending.destinations[r]=i:s[r]=Y(i);return s}(a,e.destinations||{}),a.transformers=await async function(e,n={}){const t={};for(const[o,s]of Object.entries(n)){const{code:n,env:r={}}=s,{config:i}=G(s,"next"),a=Object.keys(r).length>0?{...i,env:r}:i,c=e.logger.scope("transformer").scope(o),u={collector:e,logger:c,id:o,config:a,env:r},l=await n(u);t[o]=l}return t}(a,e.transformers||{}),a}async function se(e){e=e||{};const n=await oe(e),t=(o=n,{type:"elb",config:{},push:async(e,n,t,s,r,i)=>{if("string"==typeof e&&e.startsWith("walker ")){const s=e.replace("walker ","");return o.command(s,n,t)}let a;if("string"==typeof e)a={name:e},n&&"object"==typeof n&&!Array.isArray(n)&&(a.data=n);else{if(!e||"object"!=typeof e)return X({ok:!1});a=e,n&&"object"==typeof n&&!Array.isArray(n)&&(a.data={...a.data||{},...n})}return s&&"object"==typeof s&&(a.context=s),r&&Array.isArray(r)&&(a.nested=r),i&&"object"==typeof i&&(a.custom=i),o.push(a)}});var o;n.sources.elb=t;const s=await async function(e,n={}){const t={};for(const[o,s]of Object.entries(n)){const{config:n={}}=s;if(n.require&&n.require.length>0){e.pending.sources[o]=s;continue}const r=await U(e,o,s);r&&(t[o]=r)}return t}(n,e.sources||{});Object.assign(n.sources,s);const{consent:r,user:i,globals:a,custom:c}=e;r&&await n.command("consent",r),i&&await n.command("user",i),a&&Object.assign(n.globals,a),c&&Object.assign(n.custom,c),n.config.run&&await n.command("run");let u=t.push;const l=Object.values(n.sources).filter(e=>"elb"!==e.type),g=l.find(e=>e.config.primary);return g?u=g.push:l.length>0&&(u=l[0].push),{collector:n,elb:u}}var re=async e=>{let n;return{get flow(){return n},trigger:()=>async t=>{if(!n){const t=await se(e);n={collector:t.collector,elb:t.elb}}const o=function(e){for(const n of Object.values(e.sources||{}))if("lambda"===n.type)return n}(n.collector);if(!o)throw new Error("Lambda source not found in collector");const s={awsRequestId:`test-${Date.now()}`},r=o.push,i=await r(t,s);let a;try{a=JSON.parse(i.body||"{}")}catch(e){a=i.body}const c={};if(i.headers)for(const[e,n]of Object.entries(i.headers))void 0!==n&&(c[e]=String(n));return{statusCode:i.statusCode,body:a,headers:c}}}};function ie(e){return async n=>{const t={...n};if(t.body&&"string"==typeof t.body){const e=JSON.parse(t.body);e.name&&!e.event&&(t.body=JSON.stringify({...e,event:e.name,name:void 0}))}return e.push(t,{awsRequestId:"test-req"})}}//# 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/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 apiGatewayV1Post: Flow.StepExample = {\n in: {\n httpMethod: 'POST',\n path: '/collect',\n requestContext: {\n requestId: 'req-789',\n identity: { sourceIp: '203.0.113.42' },\n },\n queryStringParameters: null,\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":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEA,kBAA8B;;;ACF9B,IAAAA,cAAkB;;;ACAlB,iBAAkB;AAKX,IAAM,aAAa,aAAE,KAAK;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AASM,IAAM,aAAa,aAAE,MAAM;AAAA,EAChC,aAAE,OAAO;AAAA,EACT,aAAE,MAAM,aAAE,OAAO,CAAC;AAAA,EAClB,aAAE,QAAQ,GAAG;AACf,CAAC;AAMM,IAAM,oBAAoB,aAAE,OAAO;AAAA,EACxC,QAAQ,WAAW;AAAA,IACjB;AAAA,EACF,EAAE,SAAS;AAAA,EAEX,SAAS,aAAE,MAAM,UAAU,EAAE,SAAS,sBAAsB,EAAE,SAAS;AAAA,EAEvE,SAAS,aAAE,MAAM,aAAE,OAAO,CAAC,EAAE,SAAS,yBAAyB,EAAE,SAAS;AAAA,EAE1E,aAAa,aACV,QAAQ,EACR,SAAS,oDAAoD,EAC7D,SAAS;AAAA,EAEZ,QAAQ,aACL,OAAO,EACP,IAAI,EACJ,SAAS,EACT,SAAS,qCAAqC,EAC9C,SAAS;AACd,CAAC;;;AD9CM,IAAM,iBAAiB,cAAE,OAAO;AAAA,EACrC,MAAM,cACH,MAAM,CAAC,cAAE,QAAQ,GAAG,iBAAiB,CAAC,EACtC;AAAA,IACC;AAAA,EACF,EACC,QAAQ,IAAI;AAAA,EAEf,SAAS,cACN,OAAO,EACP,IAAI,EACJ,SAAS,EACT,IAAI,GAAM,EACV,SAAS,0DAA0D,EACnE,QAAQ,GAAK;AAAA,EAEhB,qBAAqB,cAClB,QAAQ,EACR;AAAA,IACC;AAAA,EACF,EACC,QAAQ,IAAI;AAAA,EAEf,YAAY,cACT,OAAO,EACP,SAAS,4CAA4C,EACrD,QAAQ,SAAS;AACtB,CAAC;;;AEjCD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAAC,cAA4B;AAUrB,IAAM,eAAW,yBAAY,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;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,mBAAqC;AAAA,EAChD,IAAI;AAAA,IACF,YAAY;AAAA,IACZ,MAAM;AAAA,IACN,gBAAgB;AAAA,MACd,WAAW;AAAA,MACX,UAAU,EAAE,UAAU,eAAe;AAAA,IACvC;AAAA,IACA,uBAAuB;AAAA,IACvB,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":["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","../src/lambda/examples/trigger.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';\nexport { createTrigger, trigger } from './trigger';\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 trigger: { type: 'POST' },\n in: {\n version: '2.0',\n requestContext: {\n http: { method: 'POST', path: '/collect' },\n requestId: 'req-123',\n },\n body: JSON.stringify({\n event: '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 apiGatewayV1Post: Flow.StepExample = {\n trigger: { type: 'POST' },\n in: {\n httpMethod: 'POST',\n path: '/collect',\n requestContext: {\n requestId: 'req-789',\n identity: { sourceIp: '203.0.113.42' },\n },\n queryStringParameters: null,\n body: JSON.stringify({\n event: '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 trigger: { type: 'GET' },\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","import type { Trigger, Collector } from '@walkeros/core';\nimport type { LambdaEvent, LambdaContext, LambdaResult } from '../types';\nimport { startFlow } from '@walkeros/collector';\n\nexport interface Content {\n [key: string]: unknown;\n}\n\nexport interface Result {\n statusCode: number;\n body: unknown;\n headers: Record<string, string>;\n}\n\n/**\n * Find the lambda source instance from the collector's registered sources.\n */\nfunction findLambdaSource(collector: Collector.Instance) {\n for (const source of Object.values(collector.sources || {})) {\n if ((source as { type?: string }).type === 'lambda') return source;\n }\n}\n\n/**\n * Lambda source createTrigger.\n *\n * Boots the collector via startFlow, then invokes the Lambda source's push()\n * with a real API Gateway event and a minimal Lambda context.\n *\n * Content is the raw Lambda event object (API Gateway v1 or v2 format).\n * Result contains statusCode, parsed body, and headers.\n *\n * @example\n * const { trigger, flow } = await createTrigger(config);\n * const result = await trigger('POST')({ version: '2.0', ... });\n * console.log(result.statusCode, result.body);\n */\nconst createTrigger: Trigger.CreateFn<Content, Result> = async (\n config: Collector.InitConfig,\n) => {\n let flow: Trigger.FlowHandle | undefined;\n\n const trigger: Trigger.Fn<Content, Result> =\n () =>\n async (content: Content): Promise<Result> => {\n // Lazy startFlow\n if (!flow) {\n const result = await startFlow(config);\n flow = { collector: result.collector, elb: result.elb };\n }\n\n const source = findLambdaSource(flow.collector);\n if (!source) throw new Error('Lambda source not found in collector');\n\n // Create minimal Lambda context\n const lambdaContext = {\n awsRequestId: `test-${Date.now()}`,\n } as unknown as LambdaContext;\n\n // Call source.push with the raw Lambda event + context\n const pushFn = (\n source as unknown as {\n push: (...args: unknown[]) => Promise<LambdaResult>;\n }\n ).push;\n const lambdaResult = await pushFn(\n content as unknown as LambdaEvent,\n lambdaContext,\n );\n\n // Parse response\n let body: unknown;\n try {\n body = JSON.parse(lambdaResult.body || '{}');\n } catch {\n body = lambdaResult.body;\n }\n\n const headers: Record<string, string> = {};\n if (lambdaResult.headers) {\n for (const [k, v] of Object.entries(lambdaResult.headers)) {\n if (v !== undefined) headers[k] = String(v);\n }\n }\n\n return {\n statusCode: lambdaResult.statusCode,\n body,\n headers,\n };\n };\n\n return {\n get flow() {\n return flow;\n },\n trigger,\n };\n};\n\n/**\n * Legacy trigger — takes a source instance directly.\n * Preserved for CLI simulate path.\n */\nfunction trigger(source: {\n push: (event: LambdaEvent, context: LambdaContext) => Promise<LambdaResult>;\n}): (content: Content) => Promise<LambdaResult> {\n return async (content: Content) => {\n const lambdaEvent = { ...(content as Record<string, unknown>) };\n\n // Adapt body format: step examples may use `name`, source expects `event`\n if (lambdaEvent.body && typeof lambdaEvent.body === 'string') {\n const body = JSON.parse(lambdaEvent.body);\n if (body.name && !body.event) {\n lambdaEvent.body = JSON.stringify({\n ...body,\n event: body.name,\n name: undefined,\n });\n }\n }\n\n const context: LambdaContext = {\n awsRequestId: 'test-req',\n } as unknown as LambdaContext;\n\n return source.push(lambdaEvent as unknown as LambdaEvent, context);\n };\n}\n\nexport { createTrigger, trigger };\n"],"mappings":"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","names":["import_core","import_dev","import_dev","fn","trigger","e","k","v"]}
|
package/dist/dev.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e=Object.defineProperty,t=(t,o)=>{for(var r in o)e(t,r,{get:o[r],enumerable:!0})};import{requestToData as o}from"@walkeros/core";import{z as r}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=r.object({cors:r.union([r.boolean(),s]).describe("CORS configuration: false = disabled, true = allow all origins, object = custom configuration").default(!0),timeout:r.number().int().positive().max(9e5).describe("Request timeout in milliseconds (max: 900000 for Lambda)").default(3e4),enablePixelTracking:r.boolean().describe("Enable GET requests with 1x1 transparent GIF response for pixel tracking").default(!0),healthPath:r.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:()=>u,step:()=>w});var u={};t(u,{push:()=>v});var g=()=>()=>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 g()},get command(){return g()},get elb(){return g()},logger:b},w={};t(w,{apiGatewayV1Post:()=>y,lambdaGet:()=>P,lambdaPost:()=>f});var f={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"}},y={in:{httpMethod:"POST",path:"/collect",requestContext:{requestId:"req-789",identity:{sourceIp:"203.0.113.42"}},queryStringParameters:null,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
|
|
1
|
+
var e=Object.defineProperty,n=(n,t)=>{for(var o in t)e(n,o,{get:t[o],enumerable:!0})};import{requestToData as t}from"@walkeros/core";import{z as o}from"@walkeros/core/dev";import{z as s}from"@walkeros/core/dev";var r=s.enum(["GET","POST","PUT","PATCH","DELETE","OPTIONS","HEAD"]),i=s.union([s.string(),s.array(s.string()),s.literal("*")]),a=s.object({origin:i.describe("Allowed origins (* for all, URL string, or array of URLs)").optional(),methods:s.array(r).describe("Allowed HTTP methods").optional(),headers:s.array(s.string()).describe("Allowed request headers").optional(),credentials:s.boolean().describe("Allow credentials (cookies, authorization headers)").optional(),maxAge:s.number().int().positive().describe("Preflight cache duration in seconds").optional()}),c=o.object({cors:o.union([o.boolean(),a]).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")}),u={};n(u,{CorsOptionsSchema:()=>a,CorsOrigin:()=>i,HttpMethod:()=>r,SettingsSchema:()=>c,settings:()=>d});import{zodToSchema as l}from"@walkeros/core/dev";var d=l(c),g={};n(g,{createTrigger:()=>je,env:()=>f,step:()=>y,trigger:()=>Pe});var f={};n(f,{push:()=>b});var p=()=>()=>Promise.resolve({ok:!0}),h=()=>{},m={error:h,warn:h,info:h,debug:h,throw:e=>{throw"string"==typeof e?new Error(e):e},json:h,scope:()=>m},b={get push(){return p()},get command(){return p()},get elb(){return p()},logger:m},y={};n(y,{apiGatewayV1Post:()=>w,lambdaGet:()=>k,lambdaPost:()=>v});var v={trigger:{type:"POST"},in:{version:"2.0",requestContext:{http:{method:"POST",path:"/collect"},requestId:"req-123"},body:JSON.stringify({event:"page view",data:{title:"Home"}}),isBase64Encoded:!1},out:{name:"page view",data:{title:"Home"},entity:"page",action:"view"}},w={trigger:{type:"POST"},in:{httpMethod:"POST",path:"/collect",requestContext:{requestId:"req-789",identity:{sourceIp:"203.0.113.42"}},queryStringParameters:null,body:JSON.stringify({event:"page view",data:{title:"Home"}}),isBase64Encoded:!1},out:{name:"page view",data:{title:"Home"},entity:"page",action:"view"}},k={trigger:{type:"GET"},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"}};import{assign as O}from"@walkeros/core";import{assign as q,createLogger as j}from"@walkeros/core";import{assign as P,clone as C,debounce as S,getId as A,getGrantedConsent as E,isDefined as x,isFunction as D,isObject as T,processEventMapping as $,tryCatchAsync as H,useHooks as R}from"@walkeros/core";import{isArray as I}from"@walkeros/core";import{tryCatch as G,tryCatchAsync as B}from"@walkeros/core";import{getMappingValue as L,tryCatchAsync as M}from"@walkeros/core";import{isObject as N,tryCatchAsync as J,useHooks as U}from"@walkeros/core";import{assign as F,getId as z,isFunction as V,isString as Q}from"@walkeros/core";import{isObject as W}from"@walkeros/core";import{getGrantedConsent as _,processEventMapping as K,tryCatchAsync as X,useHooks as Y}from"@walkeros/core";import{useHooks as Z,tryCatchAsync as ee}from"@walkeros/core";var ne={Action:"action",Actions:"actions",Config:"config",Consent:"consent",Context:"context",Custom:"custom",Destination:"destination",Elb:"elb",Globals:"globals",Hook:"hook",Init:"init",Link:"link",On:"on",Prefix:"data-elb",Ready:"ready",Run:"run",Session:"session",Shutdown:"shutdown",User:"user",Walker:"walker"};function te(e){var n;const t={};for(const[o,s]of Object.entries(e))(null==(n=s.config)?void 0:n.next)?t[o]={next:s.config.next}:t[o]={};return t}function oe(e,n){const t=e.config||{},o=e[n];return void 0!==o?{config:{...t,[n]:o},chainValue:o}:{config:t,chainValue:void 0}}function se(e,n={}){if(!e)return[];if(Array.isArray(e))return e;const t=[],o=new Set;let s=e;for(;s&&n[s]&&!o.has(s);){o.add(s),t.push(s);const e=n[s].next;if(Array.isArray(e)){t.push(...e);break}s=e}return t}async function re(e,n,t){if(n.init&&!n.config.init){const o=n.type||"unknown",s=e.logger.scope(`transformer:${o}`),r={collector:e,logger:s,id:t,config:n.config,env:ce(n.config.env)};s.debug("init");const i=await U(n.init,"TransformerInit",e.hooks)(r);if(!1===i)return!1;n.config={...i||n.config,env:(null==i?void 0:i.env)||n.config.env,init:!0},s.debug("init done")}return!0}async function ie(e,n,t,o,s,r){const i=n.type||"unknown",a=e.logger.scope(`transformer:${i}`),c={collector:e,logger:a,id:t,ingest:s,config:n.config,env:{...ce(n.config.env),...r?{respond:r}:{}}};a.debug("push",{event:o.name});const u=await U(n.push,"TransformerPush",e.hooks)(o,c);return a.debug("push done"),u}async function ae(e,n,t,o,s,r){let i=o,a=r;for(const o of t){const t=n[o];if(!t){e.logger.warn(`Transformer not found: ${o}`);continue}if(!await J(re)(e,t,o))return e.logger.error(`Transformer init failed: ${o}`),null;const r=await J(ie,n=>(e.logger.scope(`transformer:${t.type||"unknown"}`).error("Push failed",{error:n}),!1))(e,t,o,i,s,a);if(!1===r)return null;if(r&&"object"==typeof r){const{event:t,respond:o,next:c}=r;if(o&&(a=o),c){const o=se(c,te(n));return o.length>0?ae(e,n,o,t||i,s,a):(e.logger.warn(`Branch target not found: ${JSON.stringify(c)}`),null)}t&&(i=t)}}return i}function ce(e){return e&&N(e)?e:{}}async function ue(e,n,t){const{code:o,config:s={},env:r={},primary:i,next:a}=t;let c,u;const l=se(a,te(e.transformers)),d=e.logger.scope("source").scope(n),g={push:(t,o={})=>e.push(t,{...o,id:n,ingest:c,respond:u,mapping:s,preChain:l}),command:e.command,sources:e.sources,elb:e.sources.elb.push,logger:d,...r},f={collector:e,logger:d,id:n,config:s,env:g,setIngest:async n=>{c=s.ingest?await L(n,s.ingest,{collector:e}):void 0},setRespond:e=>{u=e}},p=await M(o)(f);if(!p)return;const h=p.type||"unknown",m=e.logger.scope(h).scope(n);return g.logger=m,i&&(p.config={...p.config,primary:i}),p}function le(e,n,t,o,s){if(!n.on)return;const r=n.type||"unknown",i=e.logger.scope(r).scope("on").scope(o),a={collector:e,logger:i,id:t,config:n.config,data:s,env:ye(n.env,n.config.env)};G(n.on)(o,a)}async function de(e,n,t,o){let s,r=t||[];switch(t||(r=e.on[n]||[]),n){case ne.Consent:s=o||e.consent;break;case ne.Session:s=e.session;break;case ne.User:s=o||e.user;break;case ne.Custom:s=o||e.custom;break;case ne.Globals:s=o||e.globals;break;case ne.Config:s=o||e.config;break;case ne.Ready:case ne.Run:default:s=void 0}let i=!1;for(const t of Object.values(e.sources))t.on&&!1===await B(t.on)(n,s)&&(i=!0);if(Object.entries(e.destinations).forEach(([t,o])=>{if(o.on){if(!o.config.init)return o.queueOn=o.queueOn||[],void o.queueOn.push({type:n,data:s});le(e,o,t,n,s)}}),(Object.keys(e.pending.sources).length>0||Object.keys(e.pending.destinations).length>0)&&await async function(e,n){var t,o;for(const[o,s]of Object.entries(e.pending.sources)){if(!e.pending.sources[o]||e.sources[o])continue;const r=null==(t=s.config)?void 0:t.require;if(!r)continue;const i=r.indexOf(n);if(-1===i)continue;if(r.splice(i,1),r.length>0)continue;delete e.pending.sources[o];const a=await ue(e,o,s);a&&(e.sources[o]=a)}for(const[t,s]of Object.entries(e.pending.destinations)){if(!e.pending.destinations[t]||e.destinations[t])continue;const r=null==(o=s.config)?void 0:o.require;if(!r)continue;const i=r.indexOf(n);if(-1===i)continue;if(r.splice(i,1),r.length>0)continue;delete e.pending.destinations[t];const a=be(s);!1!==a.config.queue&&(a.queuePush=[...e.queue]),e.destinations[t]=a}}(e,n),!r.length)return!i;switch(n){case ne.Consent:!function(e,n,t){const o=t||e.consent;n.forEach(n=>{Object.keys(o).filter(e=>e in n).forEach(t=>{G(n[t])(e,o)})})}(e,r,o);break;case ne.Ready:case ne.Run:c=r,(a=e).allowed&&c.forEach(e=>{G(e)(a)});break;case ne.Session:!function(e,n){e.session&&n.forEach(n=>{G(n)(e,e.session)})}(e,r);break;default:r.forEach(n=>{"function"==typeof n&&G(n)(e,s)})}var a,c;return!i}async function ge(e,n,t){const{code:o,config:s={},env:r={},before:i}=n;if(!D(o.push))return me({ok:!1,failed:{invalid:{type:"invalid",error:"Destination code must have a push method"}}});const a=t||s||{init:!1},c=i?{...a,before:i}:a,u={...o,config:c,env:ye(o.env,r)};let l=u.config.id;if(!l)do{l=A(4)}while(e.destinations[l]);return e.destinations[l]=u,!1!==u.config.queue&&(u.queuePush=[...e.queue]),fe(e,void 0,{},{[l]:u})}async function fe(e,n,t={},o){const{allowed:s,consent:r,globals:i,user:a}=e;if(!s)return me({ok:!1});n&&(e.queue.push(n),e.status.in++),o||(o=e.destinations);const c=await Promise.all(Object.entries(o||{}).map(async([o,s])=>{var c,u;let l=(s.queuePush||[]).map(e=>({...e,consent:r}));if(s.queuePush=[],n){const e=C(n);l.push(e)}if(!l.length&&!(null==(c=s.queueOn)?void 0:c.length))return{id:o,destination:s,skipped:!0};if(!l.length&&(null==(u=s.queueOn)?void 0:u.length)){const n=await H(pe)(e,s,o);return{id:o,destination:s,skipped:!n}}const d=[],g=l.filter(e=>{const n=E(s.config.consent,r,e.consent);return!n||(e.consent=n,d.push(e),!1)});if(s.queuePush.push(...g),!d.length)return{id:o,destination:s,queue:l};if(!await H(pe)(e,s,o))return{id:o,destination:s,queue:l};let f,p;s.dlq||(s.dlq=[]);const h=function(e,n){const t=e.config.before;return t?se(t,te(n)):[]}(s,e.transformers);let m=0;return await Promise.all(d.map(async n=>{n.globals=P(i,n.globals),n.user=P(a,n.user);let r=n;if(h.length>0&&e.transformers&&Object.keys(e.transformers).length>0){const o=await ae(e,e.transformers,h,n,t.ingest,t.respond);if(null===o)return n;r=o}const c=Date.now(),u=await H(he,n=>{const t=s.type||"unknown";e.logger.scope(t).error("Push failed",{error:n,event:r.name}),f=n,s.dlq.push([r,n])})(e,s,o,r,t.ingest,t.respond);return m+=Date.now()-c,void 0!==u&&(p=u),n})),{id:o,destination:s,error:f,response:p,totalDuration:m}})),u={},l={},d={};for(const n of c){if(n.skipped)continue;const t={type:n.destination.type||"unknown",data:n.response};e.status.destinations[n.id]||(e.status.destinations[n.id]={count:0,failed:0,duration:0});const o=e.status.destinations[n.id],s=Date.now();n.error?(t.error=n.error,d[n.id]=t,o.failed++,o.lastAt=s,o.duration+=n.totalDuration||0,e.status.failed++):n.queue&&n.queue.length?l[n.id]=t:(u[n.id]=t,o.count++,o.lastAt=s,o.duration+=n.totalDuration||0,e.status.out++)}return me({event:n,...Object.keys(u).length&&{done:u},...Object.keys(l).length&&{queued:l},...Object.keys(d).length&&{failed:d}})}async function pe(e,n,t){var o;if(n.init&&!n.config.init){const s=n.type||"unknown",r=e.logger.scope(s),i={collector:e,logger:r,id:t,config:n.config,env:ye(n.env,n.config.env)};r.debug("init");const a=await R(n.init,"DestinationInit",e.hooks)(i);if(!1===a)return a;if(n.config={...a||n.config,init:!0},null==(o=n.queueOn)?void 0:o.length){const o=n.queueOn;n.queueOn=[];for(const{type:s,data:r}of o)le(e,n,t,s,r)}r.debug("init done")}return!0}async function he(e,n,t,o,s,r){const{config:i}=n,a=await $(o,i,e);if(a.ignore)return!1;const c=n.type||"unknown",u=e.logger.scope(c),l={collector:e,logger:u,id:t,config:i,data:a.data,rule:a.mapping,ingest:s,env:{...ye(n.env,i.env),...r?{respond:r}:{}}},d=a.mapping,g=a.mappingKey||"* *";if(!(null==d?void 0:d.batch)||!n.pushBatch){u.debug("push",{event:a.event.name});const t=await R(n.push,"DestinationPush",e.hooks)(a.event,l);return u.debug("push done"),t}{if(n.batches=n.batches||{},!n.batches[g]){const o={key:g,events:[],data:[]};n.batches[g]={batched:o,batchFn:S(()=>{const o=n.batches[g].batched,a={collector:e,logger:u,id:t,config:i,data:void 0,rule:d,ingest:s,env:{...ye(n.env,i.env),...r?{respond:r}:{}}};u.debug("push batch",{events:o.events.length}),R(n.pushBatch,"DestinationPushBatch",e.hooks)(o,a),u.debug("push batch done"),o.events=[],o.data=[]},d.batch)}}const o=n.batches[g];o.batched.events.push(a.event),x(a.data)&&o.batched.data.push(a.data),o.batchFn()}return!0}function me(e){return{ok:!(null==e?void 0:e.failed),...e}}function be(e){const{code:n,config:t={},env:o={}}=e,{config:s}=oe(e,"before"),r={...n.config,...t,...s},i=ye(n.env,o);return{...n,config:r,env:i}}function ye(e,n){return e||n?n?e&&T(e)&&T(n)?{...e,...n}:n:e:{}}async function ve(e,n,t){const o=Object.entries(e).map(async([e,o])=>{var s;const r=o.destroy;if(!r)return;const i=o.type||"unknown",a=t.scope(i),c={id:e,config:o.config,env:null!=(s=o.env)?s:{},logger:a};try{await Promise.race([r(c),new Promise((t,o)=>setTimeout(()=>o(new Error(`${n} '${e}' destroy timed out`)),5e3))])}catch(t){a.error(`${n} '${e}' destroy failed: ${t}`)}});await Promise.allSettled(o)}async function we(e,n,t,o){let s,r,i=!1,a=!1;switch(n){case ne.Config:W(t)&&(F(e.config,t,{shallow:!1}),r=t,i=!0);break;case ne.Consent:if(W(t)){const{update:n,runQueue:o}=function(e,n){let t=!1;const o={};return Object.entries(n).forEach(([e,n])=>{const s=!!n;o[e]=s,t=t||s}),e.consent=O(e.consent,o),{update:o,runQueue:t}}(e,t);r=n,i=!0,a=o}break;case ne.Custom:W(t)&&(e.custom=F(e.custom,t),r=t,i=!0);break;case ne.Destination:W(t)&&("code"in t&&W(t.code)?s=await ge(e,t,o):V(t.push)&&(s=await ge(e,{code:t},o)));break;case ne.Globals:W(t)&&(e.globals=F(e.globals,t),r=t,i=!0);break;case ne.On:Q(t)&&await async function(e,n,t){const o=e.on,s=o[n]||[],r=I(t)?t:[t];r.forEach(e=>{s.push(e)}),o[n]=s,await de(e,n,r)}(e,t,o);break;case ne.Ready:i=!0;break;case ne.Run:s=await async function(e,n){return e.allowed=!0,e.count=0,e.group=z(),e.timing=Date.now(),n&&(n.consent&&(e.consent=F(e.consent,n.consent)),n.user&&(e.user=F(e.user,n.user)),n.globals&&(e.globals=F(e.config.globalsStatic||{},n.globals)),n.custom&&(e.custom=F(e.custom,n.custom))),Object.values(e.destinations).forEach(e=>{e.queuePush=[]}),e.queue=[],e.round++,await fe(e)}(e,t),i=!0;break;case ne.Session:i=!0;break;case ne.Shutdown:await async function(e){const n=e.logger;await ve(e.sources,"source",n),await ve(e.destinations,"destination",n),await ve(e.transformers,"transformer",n),await ve(e.stores,"store",n)}(e);break;case ne.User:W(t)&&(F(e.user,t,{shallow:!1}),r=t,i=!0)}return i&&await de(e,n,void 0,r),a&&(s=await fe(e)),s||me({ok:!0})}function ke(e,n){return Y(async(t,o={})=>await X(async()=>{const s=Date.now(),{id:r,ingest:i,respond:a,mapping:c,preChain:u}=o;let l=t;const d=i?Object.freeze(i):void 0;if(c){const n=await K(l,c,e);if(n.ignore)return me({ok:!0});if(c.consent&&!_(c.consent,e.consent,n.event.consent))return me({ok:!0});l=n.event}if((null==u?void 0:u.length)&&e.transformers&&Object.keys(e.transformers).length>0){const n=await ae(e,e.transformers,u,l,d,a);if(null===n)return me({ok:!0});l=n}const g=n(l),f=function(e,n){if(!n.name)throw new Error("Event name is required");const[t,o]=n.name.split(" ");if(!t||!o)throw new Error("Event name is invalid");++e.count;const{timestamp:s=Date.now(),group:r=e.group,count:i=e.count}=n,{name:a=`${t} ${o}`,data:c={},context:u={},globals:l=e.globals,custom:d={},user:g=e.user,nested:f=[],consent:p=e.consent,id:h=`${s}-${r}-${i}`,trigger:m="",entity:b=t,action:y=o,timing:v=0,version:w={source:e.version,tagging:e.config.tagging||0},source:k={type:"collector",id:"",previous_id:""}}=n;return{name:a,data:c,context:u,globals:l,custom:d,user:g,nested:f,consent:p,id:h,trigger:m,entity:b,action:y,timestamp:s,timing:v,group:r,count:i,version:w,source:k}}(e,g),p=await fe(e,f,{id:r,ingest:d,respond:a});if(r){e.status.sources[r]||(e.status.sources[r]={count:0,duration:0});const n=e.status.sources[r];n.count++,n.lastAt=Date.now(),n.duration+=Date.now()-s}return p},()=>me({ok:!1}))(),"Push",e.hooks)}async function Oe(e){var n,t;const o=q({globalsStatic:{},sessionStatic:{},tagging:0,run:!0},e,{merge:!1,extend:!1}),s={level:null==(n=e.logger)?void 0:n.level,handler:null==(t=e.logger)?void 0:t.handler},r=j(s),i={...o.globalsStatic,...e.globals},a={allowed:!1,config:o,consent:e.consent||{},count:0,custom:e.custom||{},destinations:{},transformers:{},stores:{},globals:i,group:"",hooks:{},logger:r,on:{},queue:[],round:0,session:void 0,status:{startedAt:Date.now(),in:0,out:0,failed:0,sources:{},destinations:{}},timing:Date.now(),user:e.user||{},version:"3.0.2",sources:{},pending:{sources:{},destinations:{}},push:void 0,command:void 0};var c,u;a.push=ke(a,e=>({timing:Math.round((Date.now()-a.timing)/10)/100,source:{type:"collector",id:"",previous_id:""},...e})),a.command=(u=we,Z(async(e,n,t)=>await ee(async()=>await u(c,e,n,t),()=>me({ok:!1}))(),"Command",(c=a).hooks));const l=e.stores||{};return a.stores=await async function(e,n={}){const t={};for(const[o,s]of Object.entries(n)){const{code:n,config:r={},env:i={}}=s,a=e.logger.scope("store").scope(o),c={collector:e,logger:a,id:o,config:r,env:i},u=await n(c);t[o]=u}return t}(a,l),function(e,n,t){const o=new Map;for(const[t,s]of Object.entries(e))n[t]&&o.set(s,n[t]);if(0!==o.size)for(const e of[t.transformers,t.destinations,t.sources])if(e)for(const n of Object.values(e))s(n.env);function s(e){if(e)for(const[n,t]of Object.entries(e))if("object"==typeof t&&null!==t){const s=o.get(t);s&&(e[n]=s)}}}(l,a.stores,e),a.destinations=await async function(e,n={}){var t,o;const s={};for(const[r,i]of Object.entries(n))(null==(o=null==(t=i.config)?void 0:t.require)?void 0:o.length)?e.pending.destinations[r]=i:s[r]=be(i);return s}(a,e.destinations||{}),a.transformers=await async function(e,n={}){const t={};for(const[o,s]of Object.entries(n)){const{code:n,env:r={}}=s,{config:i}=oe(s,"next"),a=Object.keys(r).length>0?{...i,env:r}:i,c=e.logger.scope("transformer").scope(o),u={collector:e,logger:c,id:o,config:a,env:r},l=await n(u);t[o]=l}return t}(a,e.transformers||{}),a}async function qe(e){e=e||{};const n=await Oe(e),t=(o=n,{type:"elb",config:{},push:async(e,n,t,s,r,i)=>{if("string"==typeof e&&e.startsWith("walker ")){const s=e.replace("walker ","");return o.command(s,n,t)}let a;if("string"==typeof e)a={name:e},n&&"object"==typeof n&&!Array.isArray(n)&&(a.data=n);else{if(!e||"object"!=typeof e)return me({ok:!1});a=e,n&&"object"==typeof n&&!Array.isArray(n)&&(a.data={...a.data||{},...n})}return s&&"object"==typeof s&&(a.context=s),r&&Array.isArray(r)&&(a.nested=r),i&&"object"==typeof i&&(a.custom=i),o.push(a)}});var o;n.sources.elb=t;const s=await async function(e,n={}){const t={};for(const[o,s]of Object.entries(n)){const{config:n={}}=s;if(n.require&&n.require.length>0){e.pending.sources[o]=s;continue}const r=await ue(e,o,s);r&&(t[o]=r)}return t}(n,e.sources||{});Object.assign(n.sources,s);const{consent:r,user:i,globals:a,custom:c}=e;r&&await n.command("consent",r),i&&await n.command("user",i),a&&Object.assign(n.globals,a),c&&Object.assign(n.custom,c),n.config.run&&await n.command("run");let u=t.push;const l=Object.values(n.sources).filter(e=>"elb"!==e.type),d=l.find(e=>e.config.primary);return d?u=d.push:l.length>0&&(u=l[0].push),{collector:n,elb:u}}var je=async e=>{let n;return{get flow(){return n},trigger:()=>async t=>{if(!n){const t=await qe(e);n={collector:t.collector,elb:t.elb}}const o=function(e){for(const n of Object.values(e.sources||{}))if("lambda"===n.type)return n}(n.collector);if(!o)throw new Error("Lambda source not found in collector");const s={awsRequestId:`test-${Date.now()}`},r=o.push,i=await r(t,s);let a;try{a=JSON.parse(i.body||"{}")}catch(e){a=i.body}const c={};if(i.headers)for(const[e,n]of Object.entries(i.headers))void 0!==n&&(c[e]=String(n));return{statusCode:i.statusCode,body:a,headers:c}}}};function Pe(e){return async n=>{const t={...n};if(t.body&&"string"==typeof t.body){const e=JSON.parse(t.body);e.name&&!e.event&&(t.body=JSON.stringify({...e,event:e.name,name:void 0}))}return e.push(t,{awsRequestId:"test-req"})}}export{g as examples,u 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/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 apiGatewayV1Post: Flow.StepExample = {\n in: {\n httpMethod: 'POST',\n path: '/collect',\n requestContext: {\n requestId: 'req-789',\n identity: { sourceIp: '203.0.113.42' },\n },\n queryStringParameters: null,\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":["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","../src/lambda/examples/trigger.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';\nexport { createTrigger, trigger } from './trigger';\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 trigger: { type: 'POST' },\n in: {\n version: '2.0',\n requestContext: {\n http: { method: 'POST', path: '/collect' },\n requestId: 'req-123',\n },\n body: JSON.stringify({\n event: '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 apiGatewayV1Post: Flow.StepExample = {\n trigger: { type: 'POST' },\n in: {\n httpMethod: 'POST',\n path: '/collect',\n requestContext: {\n requestId: 'req-789',\n identity: { sourceIp: '203.0.113.42' },\n },\n queryStringParameters: null,\n body: JSON.stringify({\n event: '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 trigger: { type: 'GET' },\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","import type { Trigger, Collector } from '@walkeros/core';\nimport type { LambdaEvent, LambdaContext, LambdaResult } from '../types';\nimport { startFlow } from '@walkeros/collector';\n\nexport interface Content {\n [key: string]: unknown;\n}\n\nexport interface Result {\n statusCode: number;\n body: unknown;\n headers: Record<string, string>;\n}\n\n/**\n * Find the lambda source instance from the collector's registered sources.\n */\nfunction findLambdaSource(collector: Collector.Instance) {\n for (const source of Object.values(collector.sources || {})) {\n if ((source as { type?: string }).type === 'lambda') return source;\n }\n}\n\n/**\n * Lambda source createTrigger.\n *\n * Boots the collector via startFlow, then invokes the Lambda source's push()\n * with a real API Gateway event and a minimal Lambda context.\n *\n * Content is the raw Lambda event object (API Gateway v1 or v2 format).\n * Result contains statusCode, parsed body, and headers.\n *\n * @example\n * const { trigger, flow } = await createTrigger(config);\n * const result = await trigger('POST')({ version: '2.0', ... });\n * console.log(result.statusCode, result.body);\n */\nconst createTrigger: Trigger.CreateFn<Content, Result> = async (\n config: Collector.InitConfig,\n) => {\n let flow: Trigger.FlowHandle | undefined;\n\n const trigger: Trigger.Fn<Content, Result> =\n () =>\n async (content: Content): Promise<Result> => {\n // Lazy startFlow\n if (!flow) {\n const result = await startFlow(config);\n flow = { collector: result.collector, elb: result.elb };\n }\n\n const source = findLambdaSource(flow.collector);\n if (!source) throw new Error('Lambda source not found in collector');\n\n // Create minimal Lambda context\n const lambdaContext = {\n awsRequestId: `test-${Date.now()}`,\n } as unknown as LambdaContext;\n\n // Call source.push with the raw Lambda event + context\n const pushFn = (\n source as unknown as {\n push: (...args: unknown[]) => Promise<LambdaResult>;\n }\n ).push;\n const lambdaResult = await pushFn(\n content as unknown as LambdaEvent,\n lambdaContext,\n );\n\n // Parse response\n let body: unknown;\n try {\n body = JSON.parse(lambdaResult.body || '{}');\n } catch {\n body = lambdaResult.body;\n }\n\n const headers: Record<string, string> = {};\n if (lambdaResult.headers) {\n for (const [k, v] of Object.entries(lambdaResult.headers)) {\n if (v !== undefined) headers[k] = String(v);\n }\n }\n\n return {\n statusCode: lambdaResult.statusCode,\n body,\n headers,\n };\n };\n\n return {\n get flow() {\n return flow;\n },\n trigger,\n };\n};\n\n/**\n * Legacy trigger — takes a source instance directly.\n * Preserved for CLI simulate path.\n */\nfunction trigger(source: {\n push: (event: LambdaEvent, context: LambdaContext) => Promise<LambdaResult>;\n}): (content: Content) => Promise<LambdaResult> {\n return async (content: Content) => {\n const lambdaEvent = { ...(content as Record<string, unknown>) };\n\n // Adapt body format: step examples may use `name`, source expects `event`\n if (lambdaEvent.body && typeof lambdaEvent.body === 'string') {\n const body = JSON.parse(lambdaEvent.body);\n if (body.name && !body.event) {\n lambdaEvent.body = JSON.stringify({\n ...body,\n event: body.name,\n name: undefined,\n });\n }\n }\n\n const context: LambdaContext = {\n awsRequestId: 'test-req',\n } as unknown as LambdaContext;\n\n return source.push(lambdaEvent as unknown as LambdaEvent, context);\n };\n}\n\nexport { createTrigger, trigger };\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;AAAA;AAAA;;;ACAA;AAAA;AAAA;AAAA;AAWA,IAAM,kBAAkB,MAAc;AACpC,QAAMC,OAAM,MACV,QAAQ,QAAQ;AAAA,IACd,IAAI;AAAA,EACN,CAAC;AACH,SAAOA;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;AAAA;AAEO,IAAM,aAA+B;AAAA,EAC1C,SAAS,EAAE,MAAM,OAAO;AAAA,EACxB,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,OAAO;AAAA,MACP,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,mBAAqC;AAAA,EAChD,SAAS,EAAE,MAAM,OAAO;AAAA,EACxB,IAAI;AAAA,IACF,YAAY;AAAA,IACZ,MAAM;AAAA,IACN,gBAAgB;AAAA,MACd,WAAW;AAAA,MACX,UAAU,EAAE,UAAU,eAAe;AAAA,IACvC;AAAA,IACA,uBAAuB;AAAA,IACvB,MAAM,KAAK,UAAU;AAAA,MACnB,OAAO;AAAA,MACP,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,SAAS,EAAE,MAAM,MAAM;AAAA,EACvB,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;A;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AChDA,SAAS,iBAAiB,WAA+B;AACvD,aAAW,UAAU,OAAO,OAAO,UAAU,WAAW,CAAC,CAAC,GAAG;AAC3D,QAAK,OAA6B,SAAS,SAAU,QAAO;AAAA,EAC9D;AACF;AAgBA,IAAM,gBAAmD,OACvD,WACG;AACH,MAAI;AAEJ,QAAMC,WACJ,MACA,OAAO,YAAsC;AAE3C,QAAI,CAAC,MAAM;AACT,YAAM,SAAS,MAAM,GAAU,MAAM;AACrC,aAAO,EAAE,WAAW,OAAO,WAAW,KAAK,OAAO,IAAI;AAAA,IACxD;AAEA,UAAM,SAAS,iBAAiB,KAAK,SAAS;AAC9C,QAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,sCAAsC;AAGnE,UAAM,gBAAgB;AAAA,MACpB,cAAc,QAAQ,KAAK,IAAI,CAAC;AAAA,IAClC;AAGA,UAAM,SACJ,OAGA;AACF,UAAM,eAAe,MAAM;AAAA,MACzB;AAAA,MACA;AAAA,IACF;AAGA,QAAI;AACJ,QAAI;AACF,aAAO,KAAK,MAAM,aAAa,QAAQ,IAAI;AAAA,IAC7C,SAAQC,IAAA;AACN,aAAO,aAAa;AAAA,IACtB;AAEA,UAAM,UAAkC,CAAC;AACzC,QAAI,aAAa,SAAS;AACxB,iBAAW,CAACC,IAAGC,EAAC,KAAK,OAAO,QAAQ,aAAa,OAAO,GAAG;AACzD,YAAIA,OAAM,OAAW,SAAQD,EAAC,IAAI,OAAOC,EAAC;AAAA,MAC5C;AAAA,IACF;AAEA,WAAO;AAAA,MACL,YAAY,aAAa;AAAA,MACzB;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEF,SAAO;AAAA,IACL,IAAI,OAAO;AACT,aAAO;AAAA,IACT;AAAA,IACA,SAAAH;AAAA,EACF;AACF;AAMA,SAAS,QAAQ,QAE+B;AAC9C,SAAO,OAAO,YAAqB;AACjC,UAAM,cAAc,EAAE,GAAI,QAAoC;AAG9D,QAAI,YAAY,QAAQ,OAAO,YAAY,SAAS,UAAU;AAC5D,YAAM,OAAO,KAAK,MAAM,YAAY,IAAI;AACxC,UAAI,KAAK,QAAQ,CAAC,KAAK,OAAO;AAC5B,oBAAY,OAAO,KAAK,UAAU;AAAA,UAChC,GAAG;AAAA,UACH,OAAO,KAAK;AAAA,UACZ,MAAM;AAAA,QACR,CAAC;AAAA,MACH;AAAA,IACF;AAEA,UAAM,UAAyB;AAAA,MAC7B,cAAc;AAAA,IAChB;AAEA,WAAO,OAAO,KAAK,aAAuC,OAAO;AAAA,EACnE;AACF;","names":["z","z","fn","trigger","e","k","v"]}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Source, WalkerOS, Flow } from '@walkeros/core';
|
|
1
|
+
import { Source, WalkerOS, Flow, Trigger } 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';
|
|
@@ -168,10 +168,43 @@ declare namespace step {
|
|
|
168
168
|
export { step_apiGatewayV1Post as apiGatewayV1Post, step_lambdaGet as lambdaGet, step_lambdaPost as lambdaPost };
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
+
interface Content {
|
|
172
|
+
[key: string]: unknown;
|
|
173
|
+
}
|
|
174
|
+
interface Result {
|
|
175
|
+
statusCode: number;
|
|
176
|
+
body: unknown;
|
|
177
|
+
headers: Record<string, string>;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Lambda source createTrigger.
|
|
181
|
+
*
|
|
182
|
+
* Boots the collector via startFlow, then invokes the Lambda source's push()
|
|
183
|
+
* with a real API Gateway event and a minimal Lambda context.
|
|
184
|
+
*
|
|
185
|
+
* Content is the raw Lambda event object (API Gateway v1 or v2 format).
|
|
186
|
+
* Result contains statusCode, parsed body, and headers.
|
|
187
|
+
*
|
|
188
|
+
* @example
|
|
189
|
+
* const { trigger, flow } = await createTrigger(config);
|
|
190
|
+
* const result = await trigger('POST')({ version: '2.0', ... });
|
|
191
|
+
* console.log(result.statusCode, result.body);
|
|
192
|
+
*/
|
|
193
|
+
declare const createTrigger: Trigger.CreateFn<Content, Result>;
|
|
194
|
+
/**
|
|
195
|
+
* Legacy trigger — takes a source instance directly.
|
|
196
|
+
* Preserved for CLI simulate path.
|
|
197
|
+
*/
|
|
198
|
+
declare function trigger(source: {
|
|
199
|
+
push: (event: LambdaEvent, context: LambdaContext) => Promise<LambdaResult>;
|
|
200
|
+
}): (content: Content) => Promise<LambdaResult>;
|
|
201
|
+
|
|
202
|
+
declare const index_createTrigger: typeof createTrigger;
|
|
171
203
|
declare const index_env: typeof env;
|
|
172
204
|
declare const index_step: typeof step;
|
|
205
|
+
declare const index_trigger: typeof trigger;
|
|
173
206
|
declare namespace index {
|
|
174
|
-
export { index_env as env, index_step as step };
|
|
207
|
+
export { index_createTrigger as createTrigger, index_env as env, index_step as step, index_trigger as trigger };
|
|
175
208
|
}
|
|
176
209
|
|
|
177
210
|
declare const sourceLambda: Source.Init<Types>;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Source, WalkerOS, Flow } from '@walkeros/core';
|
|
1
|
+
import { Source, WalkerOS, Flow, Trigger } 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';
|
|
@@ -168,10 +168,43 @@ declare namespace step {
|
|
|
168
168
|
export { step_apiGatewayV1Post as apiGatewayV1Post, step_lambdaGet as lambdaGet, step_lambdaPost as lambdaPost };
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
+
interface Content {
|
|
172
|
+
[key: string]: unknown;
|
|
173
|
+
}
|
|
174
|
+
interface Result {
|
|
175
|
+
statusCode: number;
|
|
176
|
+
body: unknown;
|
|
177
|
+
headers: Record<string, string>;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Lambda source createTrigger.
|
|
181
|
+
*
|
|
182
|
+
* Boots the collector via startFlow, then invokes the Lambda source's push()
|
|
183
|
+
* with a real API Gateway event and a minimal Lambda context.
|
|
184
|
+
*
|
|
185
|
+
* Content is the raw Lambda event object (API Gateway v1 or v2 format).
|
|
186
|
+
* Result contains statusCode, parsed body, and headers.
|
|
187
|
+
*
|
|
188
|
+
* @example
|
|
189
|
+
* const { trigger, flow } = await createTrigger(config);
|
|
190
|
+
* const result = await trigger('POST')({ version: '2.0', ... });
|
|
191
|
+
* console.log(result.statusCode, result.body);
|
|
192
|
+
*/
|
|
193
|
+
declare const createTrigger: Trigger.CreateFn<Content, Result>;
|
|
194
|
+
/**
|
|
195
|
+
* Legacy trigger — takes a source instance directly.
|
|
196
|
+
* Preserved for CLI simulate path.
|
|
197
|
+
*/
|
|
198
|
+
declare function trigger(source: {
|
|
199
|
+
push: (event: LambdaEvent, context: LambdaContext) => Promise<LambdaResult>;
|
|
200
|
+
}): (content: Content) => Promise<LambdaResult>;
|
|
201
|
+
|
|
202
|
+
declare const index_createTrigger: typeof createTrigger;
|
|
171
203
|
declare const index_env: typeof env;
|
|
172
204
|
declare const index_step: typeof step;
|
|
205
|
+
declare const index_trigger: typeof trigger;
|
|
173
206
|
declare namespace index {
|
|
174
|
-
export { index_env as env, index_step as step };
|
|
207
|
+
export { index_createTrigger as createTrigger, index_env as env, index_step as step, index_trigger as trigger };
|
|
175
208
|
}
|
|
176
209
|
|
|
177
210
|
declare const sourceLambda: Source.Init<Types>;
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var mod,__defProp=Object.defineProperty,__getOwnPropDesc=Object.getOwnPropertyDescriptor,__getOwnPropNames=Object.getOwnPropertyNames,__hasOwnProp=Object.prototype.hasOwnProperty,__export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})},index_exports={};__export(index_exports,{SourceLambda:()=>types_exports,examples:()=>examples_exports,schemas:()=>schemas_exports,sourceLambda:()=>lambda_default}),module.exports=(mod=index_exports,((to,from,except,desc)=>{if(from&&"object"==typeof from||"function"==typeof from)for(let key of __getOwnPropNames(from))__hasOwnProp.call(to,key)||key===except||__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable});return to})(__defProp({},"__esModule",{value:!0}),mod));var import_core=require("@walkeros/core");function isAPIGatewayV2(event){return"version"in event&&"2.0"===event.version}function createResponse(statusCode,body,headers={},requestId){const responseHeaders={"Content-Type":"object"==typeof body?"application/json":"text/plain",...headers};return requestId&&(responseHeaders["X-Request-ID"]=requestId),{statusCode:statusCode,headers:responseHeaders,body:"object"==typeof body?JSON.stringify(body):String(body),isBase64Encoded:!1}}var import_dev2=require("@walkeros/core/dev"),import_dev=require("@walkeros/core/dev"),HttpMethod=import_dev.z.enum(["GET","POST","PUT","PATCH","DELETE","OPTIONS","HEAD"]),CorsOrigin=import_dev.z.union([import_dev.z.string(),import_dev.z.array(import_dev.z.string()),import_dev.z.literal("*")]),CorsOptionsSchema=import_dev.z.object({origin:CorsOrigin.describe("Allowed origins (* for all, URL string, or array of URLs)").optional(),methods:import_dev.z.array(HttpMethod).describe("Allowed HTTP methods").optional(),headers:import_dev.z.array(import_dev.z.string()).describe("Allowed request headers").optional(),credentials:import_dev.z.boolean().describe("Allow credentials (cookies, authorization headers)").optional(),maxAge:import_dev.z.number().int().positive().describe("Preflight cache duration in seconds").optional()}),SettingsSchema=import_dev2.z.object({cors:import_dev2.z.union([import_dev2.z.boolean(),CorsOptionsSchema]).describe("CORS configuration: false = disabled, true = allow all origins, object = custom configuration").default(!0),timeout:import_dev2.z.number().int().positive().max(9e5).describe("Request timeout in milliseconds (max: 900000 for Lambda)").default(3e4),enablePixelTracking:import_dev2.z.boolean().describe("Enable GET requests with 1x1 transparent GIF response for pixel tracking").default(!0),healthPath:import_dev2.z.string().describe("Health check endpoint path (e.g., /health)").default("/health")}),types_exports={},schemas_exports={};__export(schemas_exports,{CorsOptionsSchema:()=>CorsOptionsSchema,CorsOrigin:()=>CorsOrigin,HttpMethod:()=>HttpMethod,SettingsSchema:()=>SettingsSchema,settings:()=>settings});var settings=(0,require("@walkeros/core/dev").zodToSchema)(SettingsSchema),examples_exports={};__export(examples_exports,{env:()=>env_exports,step:()=>step_exports});var env_exports={};__export(env_exports,{push:()=>push});var createMockElbFn=()=>()=>Promise.resolve({ok:!0}),noopFn=()=>{},noopLogger={error:noopFn,warn:noopFn,info:noopFn,debug:noopFn,throw:message=>{throw"string"==typeof message?new Error(message):message},json:noopFn,scope:()=>noopLogger},push={get push(){return createMockElbFn()},get command(){return createMockElbFn()},get elb(){return createMockElbFn()},logger:noopLogger},step_exports={};__export(step_exports,{apiGatewayV1Post:()=>apiGatewayV1Post,lambdaGet:()=>lambdaGet,lambdaPost:()=>lambdaPost});var lambdaPost={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"}},apiGatewayV1Post={in:{httpMethod:"POST",path:"/collect",requestContext:{requestId:"req-789",identity:{sourceIp:"203.0.113.42"}},queryStringParameters:null,body:JSON.stringify({name:"page view",data:{title:"Home"}}),isBase64Encoded:!1},out:{name:"page view",data:{title:"Home"},entity:"page",action:"view"}},lambdaGet={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"}},sourceLambda=async context=>{const{config:config={},env:env,setIngest:setIngest}=context,{push:envPush}=env,settings2=SettingsSchema.parse(config.settings||{});return{type:"lambda",config:{...config,settings:settings2},push:async(event,context2)=>{var _a;const requestId=context2.awsRequestId;let parsed;try{const corsHeaders=function(corsOptions){if(!corsOptions)return{};if(!0===corsOptions)return{"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization","Access-Control-Max-Age":"3600"};const headers={};if(corsOptions.origin){const origin=Array.isArray(corsOptions.origin)?corsOptions.origin.join(", "):corsOptions.origin;headers["Access-Control-Allow-Origin"]=origin}return corsOptions.methods&&(headers["Access-Control-Allow-Methods"]=corsOptions.methods.join(", ")),corsOptions.headers&&(headers["Access-Control-Allow-Headers"]=corsOptions.headers.join(", ")),corsOptions.credentials&&(headers["Access-Control-Allow-Credentials"]="true"),void 0!==corsOptions.maxAge&&(headers["Access-Control-Max-Age"]=corsOptions.maxAge.toString()),headers}(settings2.cors||!1);parsed=function(event){if(isAPIGatewayV2(event)){const headers={};return event.headers&&Object.entries(event.headers).forEach(([key,value])=>{value&&(headers[key.toLowerCase()]=value)}),{method:event.requestContext.http.method,body:event.body,queryString:event.rawQueryString||null,headers:headers,isBase64Encoded:event.isBase64Encoded||!1}}{const headers={};event.headers&&Object.entries(event.headers).forEach(([key,value])=>{value&&(headers[key.toLowerCase()]=value)});let queryString=null;if(event.queryStringParameters){const params=new URLSearchParams;Object.entries(event.queryStringParameters).forEach(([key,value])=>{value&¶ms.append(key,value)}),queryString=params.toString()||null}return{method:event.httpMethod,body:event.body,queryString:queryString,headers:headers,isBase64Encoded:event.isBase64Encoded||!1}}}(event);const path=function(event){return isAPIGatewayV2(event)?event.rawPath:event.path}(event);if(settings2.healthPath&&path===settings2.healthPath)return createResponse(200,{status:"ok",timestamp:Date.now(),source:"lambda",requestId:requestId},corsHeaders,requestId);if("OPTIONS"===parsed.method)return createResponse(204,"",corsHeaders,requestId);if(await setIngest(event),"GET"===parsed.method){if(!settings2.enablePixelTracking)return createResponse(405,{success:!1,error:"GET not allowed",requestId:requestId},corsHeaders,requestId);if(parsed.queryString){const parsedData=(0,import_core.requestToData)(parsed.queryString);parsedData&&"object"==typeof parsedData&&await envPush(parsedData)}return function(headers={},requestId){const responseHeaders={"Content-Type":"image/gif","Cache-Control":"no-cache, no-store, must-revalidate",...headers};return requestId&&(responseHeaders["X-Request-ID"]=requestId),{statusCode:200,headers:responseHeaders,body:"R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7",isBase64Encoded:!0}}(corsHeaders,requestId)}if("POST"===parsed.method){if(!parsed.body)return createResponse(400,{success:!1,error:"Request body is required",requestId:requestId},corsHeaders,requestId);const body=function(body,isBase64Encoded){if(!body||"string"!=typeof body)return body;try{const decoded=isBase64Encoded?Buffer.from(body,"base64").toString("utf8"):body;return JSON.parse(decoded)}catch(e){return body}}(parsed.body,parsed.isBase64Encoded);if(!body||"object"!=typeof body)return createResponse(400,{success:!1,error:"Invalid event body",requestId:requestId},corsHeaders,requestId);if(function(body){return"object"==typeof body&&null!==body&&"event"in body&&"string"==typeof body.event}(body)){const result=await async function(eventReq,push2,logger,requestId){var _a;try{const result=await push2({name:eventReq.event,data:eventReq.data||{},context:eventReq.context,user:eventReq.user,globals:eventReq.globals,consent:eventReq.consent});return{id:null==(_a=null==result?void 0:result.event)?void 0:_a.id}}catch(error){return null==logger||logger.error("Event processing failed",{error:error,eventName:eventReq.event,requestId:requestId}),{error:error instanceof Error?error.message:"Unknown error"}}}(body,envPush,env.logger,requestId);return result.error?createResponse(400,{success:!1,error:result.error,requestId:requestId},corsHeaders,requestId):createResponse(200,{success:!0,id:result.id,requestId:requestId},corsHeaders,requestId)}return createResponse(400,{success:!1,error:"Invalid request format",requestId:requestId},corsHeaders,requestId)}return createResponse(405,{success:!1,error:"Method not allowed",requestId:requestId},corsHeaders,requestId)}catch(error){return null==(_a=env.logger)||_a.error("Lambda handler error",{error:error,requestId:requestId,method:null==parsed?void 0:parsed.method}),createResponse(500,{success:!1,error:error instanceof Error?error.message:"Internal server error",requestId:requestId},{},requestId)}}}},lambda_default=sourceLambda;//# sourceMappingURL=index.js.map
|
|
1
|
+
"use strict";var mod,__defProp=Object.defineProperty,__getOwnPropDesc=Object.getOwnPropertyDescriptor,__getOwnPropNames=Object.getOwnPropertyNames,__hasOwnProp=Object.prototype.hasOwnProperty,__export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})},index_exports={};__export(index_exports,{SourceLambda:()=>types_exports,examples:()=>examples_exports,schemas:()=>schemas_exports,sourceLambda:()=>lambda_default}),module.exports=(mod=index_exports,((to,from,except,desc)=>{if(from&&"object"==typeof from||"function"==typeof from)for(let key of __getOwnPropNames(from))__hasOwnProp.call(to,key)||key===except||__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable});return to})(__defProp({},"__esModule",{value:!0}),mod));var import_core12=require("@walkeros/core");function isAPIGatewayV2(event){return"version"in event&&"2.0"===event.version}function createResponse(statusCode,body,headers={},requestId){const responseHeaders={"Content-Type":"object"==typeof body?"application/json":"text/plain",...headers};return requestId&&(responseHeaders["X-Request-ID"]=requestId),{statusCode:statusCode,headers:responseHeaders,body:"object"==typeof body?JSON.stringify(body):String(body),isBase64Encoded:!1}}var import_dev2=require("@walkeros/core/dev"),import_dev=require("@walkeros/core/dev"),HttpMethod=import_dev.z.enum(["GET","POST","PUT","PATCH","DELETE","OPTIONS","HEAD"]),CorsOrigin=import_dev.z.union([import_dev.z.string(),import_dev.z.array(import_dev.z.string()),import_dev.z.literal("*")]),CorsOptionsSchema=import_dev.z.object({origin:CorsOrigin.describe("Allowed origins (* for all, URL string, or array of URLs)").optional(),methods:import_dev.z.array(HttpMethod).describe("Allowed HTTP methods").optional(),headers:import_dev.z.array(import_dev.z.string()).describe("Allowed request headers").optional(),credentials:import_dev.z.boolean().describe("Allow credentials (cookies, authorization headers)").optional(),maxAge:import_dev.z.number().int().positive().describe("Preflight cache duration in seconds").optional()}),SettingsSchema=import_dev2.z.object({cors:import_dev2.z.union([import_dev2.z.boolean(),CorsOptionsSchema]).describe("CORS configuration: false = disabled, true = allow all origins, object = custom configuration").default(!0),timeout:import_dev2.z.number().int().positive().max(9e5).describe("Request timeout in milliseconds (max: 900000 for Lambda)").default(3e4),enablePixelTracking:import_dev2.z.boolean().describe("Enable GET requests with 1x1 transparent GIF response for pixel tracking").default(!0),healthPath:import_dev2.z.string().describe("Health check endpoint path (e.g., /health)").default("/health")}),types_exports={},schemas_exports={};__export(schemas_exports,{CorsOptionsSchema:()=>CorsOptionsSchema,CorsOrigin:()=>CorsOrigin,HttpMethod:()=>HttpMethod,SettingsSchema:()=>SettingsSchema,settings:()=>settings});var settings=(0,require("@walkeros/core/dev").zodToSchema)(SettingsSchema),examples_exports={};__export(examples_exports,{createTrigger:()=>createTrigger,env:()=>env_exports,step:()=>step_exports,trigger:()=>trigger});var env_exports={};__export(env_exports,{push:()=>push});var createMockElbFn=()=>()=>Promise.resolve({ok:!0}),noopFn=()=>{},noopLogger={error:noopFn,warn:noopFn,info:noopFn,debug:noopFn,throw:message=>{throw"string"==typeof message?new Error(message):message},json:noopFn,scope:()=>noopLogger},push={get push(){return createMockElbFn()},get command(){return createMockElbFn()},get elb(){return createMockElbFn()},logger:noopLogger},step_exports={};__export(step_exports,{apiGatewayV1Post:()=>apiGatewayV1Post,lambdaGet:()=>lambdaGet,lambdaPost:()=>lambdaPost});var lambdaPost={trigger:{type:"POST"},in:{version:"2.0",requestContext:{http:{method:"POST",path:"/collect"},requestId:"req-123"},body:JSON.stringify({event:"page view",data:{title:"Home"}}),isBase64Encoded:!1},out:{name:"page view",data:{title:"Home"},entity:"page",action:"view"}},apiGatewayV1Post={trigger:{type:"POST"},in:{httpMethod:"POST",path:"/collect",requestContext:{requestId:"req-789",identity:{sourceIp:"203.0.113.42"}},queryStringParameters:null,body:JSON.stringify({event:"page view",data:{title:"Home"}}),isBase64Encoded:!1},out:{name:"page view",data:{title:"Home"},entity:"page",action:"view"}},lambdaGet={trigger:{type:"GET"},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"}},import_core=require("@walkeros/core"),import_core2=require("@walkeros/core"),import_core3=require("@walkeros/core"),import_core4=require("@walkeros/core"),import_core5=require("@walkeros/core"),import_core6=require("@walkeros/core"),import_core7=require("@walkeros/core"),import_core8=require("@walkeros/core"),import_core9=require("@walkeros/core"),import_core10=require("@walkeros/core"),import_core11=require("@walkeros/core"),t_Commands={Action:"action",Actions:"actions",Config:"config",Consent:"consent",Context:"context",Custom:"custom",Destination:"destination",Elb:"elb",Globals:"globals",Hook:"hook",Init:"init",Link:"link",On:"on",Prefix:"data-elb",Ready:"ready",Run:"run",Session:"session",Shutdown:"shutdown",User:"user",Walker:"walker"};function D(n){var _a;const e2={};for(const[t2,o2]of Object.entries(n))(null==(_a=o2.config)?void 0:_a.next)?e2[t2]={next:o2.config.next}:e2[t2]={};return e2}function A(n,e2){const t2=n.config||{},o2=n[e2];return void 0!==o2?{config:{...t2,[e2]:o2},chainValue:o2}:{config:t2,chainValue:void 0}}function E(n,e2={}){if(!n)return[];if(Array.isArray(n))return n;const t2=[],o2=new Set;let s2=n;for(;s2&&e2[s2]&&!o2.has(s2);){o2.add(s2),t2.push(s2);const n2=e2[s2].next;if(Array.isArray(n2)){t2.push(...n2);break}s2=n2}return t2}async function x(n,e2,t2){if(e2.init&&!e2.config.init){const o2=e2.type||"unknown",s2=n.logger.scope(`transformer:${o2}`),r2={collector:n,logger:s2,id:t2,config:e2.config,env:$(e2.config.env)};s2.debug("init");const i2=await(0,import_core7.useHooks)(e2.init,"TransformerInit",n.hooks)(r2);if(!1===i2)return!1;e2.config={...i2||e2.config,env:(null==i2?void 0:i2.env)||e2.config.env,init:!0},s2.debug("init done")}return!0}async function P(n,e2,t2,o2,s2,r2){const i2=e2.type||"unknown",a2=n.logger.scope(`transformer:${i2}`),c2={collector:n,logger:a2,id:t2,ingest:s2,config:e2.config,env:{...$(e2.config.env),...r2?{respond:r2}:{}}};a2.debug("push",{event:o2.name});const u2=await(0,import_core7.useHooks)(e2.push,"TransformerPush",n.hooks)(o2,c2);return a2.debug("push done"),u2}async function S(n,e2,t2,o2,s2,r2){let i2=o2,a2=r2;for(const o3 of t2){const t3=e2[o3];if(!t3){n.logger.warn(`Transformer not found: ${o3}`);continue}if(!await(0,import_core7.tryCatchAsync)(x)(n,t3,o3))return n.logger.error(`Transformer init failed: ${o3}`),null;const r3=await(0,import_core7.tryCatchAsync)(P,e3=>(n.logger.scope(`transformer:${t3.type||"unknown"}`).error("Push failed",{error:e3}),!1))(n,t3,o3,i2,s2,a2);if(!1===r3)return null;if(r3&&"object"==typeof r3){const{event:t4,respond:o4,next:c2}=r3;if(o4&&(a2=o4),c2){const o5=E(c2,D(e2));return o5.length>0?S(n,e2,o5,t4||i2,s2,a2):(n.logger.warn(`Branch target not found: ${JSON.stringify(c2)}`),null)}t4&&(i2=t4)}}return i2}function $(n){return n&&(0,import_core7.isObject)(n)?n:{}}async function R(n,e2,t2){const{code:o2,config:s2={},env:r2={},primary:i2,next:a2}=t2;let c2,u2;const f2=E(a2,D(n.transformers)),l2=n.logger.scope("source").scope(e2),g2={push:(t3,o3={})=>n.push(t3,{...o3,id:e2,ingest:c2,respond:u2,mapping:s2,preChain:f2}),command:n.command,sources:n.sources,elb:n.sources.elb.push,logger:l2,...r2},d2={collector:n,logger:l2,id:e2,config:s2,env:g2,setIngest:async e3=>{c2=s2.ingest?await(0,import_core6.getMappingValue)(e3,s2.ingest,{collector:n}):void 0},setRespond:n2=>{u2=n2}},m2=await(0,import_core6.tryCatchAsync)(o2)(d2);if(!m2)return;const p2=m2.type||"unknown",h2=n.logger.scope(p2).scope(e2);return g2.logger=h2,i2&&(m2.config={...m2.config,primary:i2}),m2}function B(n,e2,t2,o2,s2){if(!e2.on)return;const r2=e2.type||"unknown",i2=n.logger.scope(r2).scope("on").scope(o2),a2={collector:n,logger:i2,id:t2,config:e2.config,data:s2,env:W(e2.env,e2.config.env)};(0,import_core5.tryCatch)(e2.on)(o2,a2)}async function G(n,e2,o2,s2){let r2,i2=o2||[];switch(o2||(i2=n.on[e2]||[]),e2){case t_Commands.Consent:r2=s2||n.consent;break;case t_Commands.Session:r2=n.session;break;case t_Commands.User:r2=s2||n.user;break;case t_Commands.Custom:r2=s2||n.custom;break;case t_Commands.Globals:r2=s2||n.globals;break;case t_Commands.Config:r2=s2||n.config;break;case t_Commands.Ready:case t_Commands.Run:default:r2=void 0}let a2=!1;for(const t2 of Object.values(n.sources))t2.on&&!1===await(0,import_core5.tryCatchAsync)(t2.on)(e2,r2)&&(a2=!0);if(Object.entries(n.destinations).forEach(([t2,o3])=>{if(o3.on){if(!o3.config.init)return o3.queueOn=o3.queueOn||[],void o3.queueOn.push({type:e2,data:r2});B(n,o3,t2,e2,r2)}}),(Object.keys(n.pending.sources).length>0||Object.keys(n.pending.destinations).length>0)&&await async function(n2,e3){var _a,_b;for(const[t2,o3]of Object.entries(n2.pending.sources)){if(!n2.pending.sources[t2]||n2.sources[t2])continue;const s3=null==(_a=o3.config)?void 0:_a.require;if(!s3)continue;const r3=s3.indexOf(e3);if(-1===r3)continue;if(s3.splice(r3,1),s3.length>0)continue;delete n2.pending.sources[t2];const i3=await R(n2,t2,o3);i3&&(n2.sources[t2]=i3)}for(const[t2,o3]of Object.entries(n2.pending.destinations)){if(!n2.pending.destinations[t2]||n2.destinations[t2])continue;const s3=null==(_b=o3.config)?void 0:_b.require;if(!s3)continue;const r3=s3.indexOf(e3);if(-1===r3)continue;if(s3.splice(r3,1),s3.length>0)continue;delete n2.pending.destinations[t2];const i3=M(o3);!1!==i3.config.queue&&(i3.queuePush=[...n2.queue]),n2.destinations[t2]=i3}}(n,e2),!i2.length)return!a2;switch(e2){case t_Commands.Consent:!function(n2,e3,t2){const o3=t2||n2.consent;e3.forEach(e4=>{Object.keys(o3).filter(n3=>n3 in e4).forEach(t3=>{(0,import_core5.tryCatch)(e4[t3])(n2,o3)})})}(n,i2,s2);break;case t_Commands.Ready:case t_Commands.Run:e3=i2,(n2=n).allowed&&e3.forEach(e4=>{(0,import_core5.tryCatch)(e4)(n2)});break;case t_Commands.Session:!function(n2,e3){n2.session&&e3.forEach(e4=>{(0,import_core5.tryCatch)(e4)(n2,n2.session)})}(n,i2);break;default:i2.forEach(e3=>{"function"==typeof e3&&(0,import_core5.tryCatch)(e3)(n,r2)})}var n2,e3;return!a2}async function H(n,e2,t2){const{code:o2,config:s2={},env:r2={},before:i2}=e2;if(!(0,import_core3.isFunction)(o2.push))return J({ok:!1,failed:{invalid:{type:"invalid",error:"Destination code must have a push method"}}});const a2=t2||s2||{init:!1},c2=i2?{...a2,before:i2}:a2,u2={...o2,config:c2,env:W(o2.env,r2)};let l2=u2.config.id;if(!l2)do{l2=(0,import_core3.getId)(4)}while(n.destinations[l2]);return n.destinations[l2]=u2,!1!==u2.config.queue&&(u2.queuePush=[...n.queue]),U(n,void 0,{},{[l2]:u2})}async function U(n,e2,t2={},o2){const{allowed:s2,consent:r2,globals:i2,user:u2}=n;if(!s2)return J({ok:!1});e2&&(n.queue.push(e2),n.status.in++),o2||(o2=n.destinations);const f2=await Promise.all(Object.entries(o2||{}).map(async([o3,s3])=>{var _a,_b;let f3=(s3.queuePush||[]).map(n2=>({...n2,consent:r2}));if(s3.queuePush=[],e2){const n2=(0,import_core3.clone)(e2);f3.push(n2)}if(!f3.length&&!(null==(_a=s3.queueOn)?void 0:_a.length))return{id:o3,destination:s3,skipped:!0};if(!f3.length&&(null==(_b=s3.queueOn)?void 0:_b.length)){const e3=await(0,import_core3.tryCatchAsync)(z3)(n,s3,o3);return{id:o3,destination:s3,skipped:!e3}}const g3=[],d3=f3.filter(n2=>{const e3=(0,import_core3.getGrantedConsent)(s3.config.consent,r2,n2.consent);return!e3||(n2.consent=e3,g3.push(n2),!1)});if(s3.queuePush.push(...d3),!g3.length)return{id:o3,destination:s3,queue:f3};if(!await(0,import_core3.tryCatchAsync)(z3)(n,s3,o3))return{id:o3,destination:s3,queue:f3};let m3,p2;s3.dlq||(s3.dlq=[]);const w2=function(n2,e3){const t3=n2.config.before;return t3?E(t3,D(e3)):[]}(s3,n.transformers);let b2=0;return await Promise.all(g3.map(async e3=>{e3.globals=(0,import_core3.assign)(i2,e3.globals),e3.user=(0,import_core3.assign)(u2,e3.user);let r3=e3;if(w2.length>0&&n.transformers&&Object.keys(n.transformers).length>0){const o4=await S(n,n.transformers,w2,e3,t2.ingest,t2.respond);if(null===o4)return e3;r3=o4}const c2=Date.now(),f4=await(0,import_core3.tryCatchAsync)(F,e4=>{const t3=s3.type||"unknown";n.logger.scope(t3).error("Push failed",{error:e4,event:r3.name}),m3=e4,s3.dlq.push([r3,e4])})(n,s3,o3,r3,t2.ingest,t2.respond);return b2+=Date.now()-c2,void 0!==f4&&(p2=f4),e3})),{id:o3,destination:s3,error:m3,response:p2,totalDuration:b2}})),g2={},d2={},m2={};for(const e3 of f2){if(e3.skipped)continue;const t3={type:e3.destination.type||"unknown",data:e3.response};n.status.destinations[e3.id]||(n.status.destinations[e3.id]={count:0,failed:0,duration:0});const o3=n.status.destinations[e3.id],s3=Date.now();e3.error?(t3.error=e3.error,m2[e3.id]=t3,o3.failed++,o3.lastAt=s3,o3.duration+=e3.totalDuration||0,n.status.failed++):e3.queue&&e3.queue.length?d2[e3.id]=t3:(g2[e3.id]=t3,o3.count++,o3.lastAt=s3,o3.duration+=e3.totalDuration||0,n.status.out++)}return J({event:e2,...Object.keys(g2).length&&{done:g2},...Object.keys(d2).length&&{queued:d2},...Object.keys(m2).length&&{failed:m2}})}async function z3(n,e2,t2){var _a;if(e2.init&&!e2.config.init){const o2=e2.type||"unknown",s2=n.logger.scope(o2),r2={collector:n,logger:s2,id:t2,config:e2.config,env:W(e2.env,e2.config.env)};s2.debug("init");const i2=await(0,import_core3.useHooks)(e2.init,"DestinationInit",n.hooks)(r2);if(!1===i2)return i2;if(e2.config={...i2||e2.config,init:!0},null==(_a=e2.queueOn)?void 0:_a.length){const o3=e2.queueOn;e2.queueOn=[];for(const{type:s3,data:r3}of o3)B(n,e2,t2,s3,r3)}s2.debug("init done")}return!0}async function F(n,e2,t2,o2,s2,r2){const{config:i2}=e2,a2=await(0,import_core3.processEventMapping)(o2,i2,n);if(a2.ignore)return!1;const c2=e2.type||"unknown",f2=n.logger.scope(c2),l2={collector:n,logger:f2,id:t2,config:i2,data:a2.data,rule:a2.mapping,ingest:s2,env:{...W(e2.env,i2.env),...r2?{respond:r2}:{}}},d2=a2.mapping,m2=a2.mappingKey||"* *";if(!(null==d2?void 0:d2.batch)||!e2.pushBatch){f2.debug("push",{event:a2.event.name});const t3=await(0,import_core3.useHooks)(e2.push,"DestinationPush",n.hooks)(a2.event,l2);return f2.debug("push done"),t3}{if(e2.batches=e2.batches||{},!e2.batches[m2]){const o4={key:m2,events:[],data:[]};e2.batches[m2]={batched:o4,batchFn:(0,import_core3.debounce)(()=>{const o5=e2.batches[m2].batched,a3={collector:n,logger:f2,id:t2,config:i2,data:void 0,rule:d2,ingest:s2,env:{...W(e2.env,i2.env),...r2?{respond:r2}:{}}};f2.debug("push batch",{events:o5.events.length}),(0,import_core3.useHooks)(e2.pushBatch,"DestinationPushBatch",n.hooks)(o5,a3),f2.debug("push batch done"),o5.events=[],o5.data=[]},d2.batch)}}const o3=e2.batches[m2];o3.batched.events.push(a2.event),(0,import_core3.isDefined)(a2.data)&&o3.batched.data.push(a2.data),o3.batchFn()}return!0}function J(n){return{ok:!(null==n?void 0:n.failed),...n}}function M(n){const{code:e2,config:t2={},env:o2={}}=n,{config:s2}=A(n,"before"),r2={...e2.config,...t2,...s2},i2=W(e2.env,o2);return{...e2,config:r2,env:i2}}function W(n,e2){return n||e2?e2?n&&(0,import_core3.isObject)(n)&&(0,import_core3.isObject)(e2)?{...n,...e2}:e2:n:{}}async function X(n,e2,t2){const o2=Object.entries(n).map(async([n2,o3])=>{var _a;const s2=o3.destroy;if(!s2)return;const r2=o3.type||"unknown",i2=t2.scope(r2),a2={id:n2,config:o3.config,env:null!=(_a=o3.env)?_a:{},logger:i2};try{await Promise.race([s2(a2),new Promise((t3,o4)=>setTimeout(()=>o4(new Error(`${e2} '${n2}' destroy timed out`)),5e3))])}catch(t3){i2.error(`${e2} '${n2}' destroy failed: ${t3}`)}});await Promise.allSettled(o2)}async function Y(n,e2,o2,r2){let i2,a2,c2=!1,u2=!1;switch(e2){case t_Commands.Config:(0,import_core9.isObject)(o2)&&((0,import_core8.assign)(n.config,o2,{shallow:!1}),a2=o2,c2=!0);break;case t_Commands.Consent:if((0,import_core9.isObject)(o2)){const{update:e3,runQueue:t2}=function(n,e2){let t2=!1;const s2={};return Object.entries(e2).forEach(([n2,e3])=>{const o2=!!e3;s2[n2]=o2,t2=t2||o2}),n.consent=(0,import_core.assign)(n.consent,s2),{update:s2,runQueue:t2}}(n,o2);a2=e3,c2=!0,u2=t2}break;case t_Commands.Custom:(0,import_core9.isObject)(o2)&&(n.custom=(0,import_core8.assign)(n.custom,o2),a2=o2,c2=!0);break;case t_Commands.Destination:(0,import_core9.isObject)(o2)&&("code"in o2&&(0,import_core9.isObject)(o2.code)?i2=await H(n,o2,r2):(0,import_core8.isFunction)(o2.push)&&(i2=await H(n,{code:o2},r2)));break;case t_Commands.Globals:(0,import_core9.isObject)(o2)&&(n.globals=(0,import_core8.assign)(n.globals,o2),a2=o2,c2=!0);break;case t_Commands.On:(0,import_core8.isString)(o2)&&await async function(n,e2,t2){const o2=n.on,s2=o2[e2]||[],r2=(0,import_core4.isArray)(t2)?t2:[t2];r2.forEach(n2=>{s2.push(n2)}),o2[e2]=s2,await G(n,e2,r2)}(n,o2,r2);break;case t_Commands.Ready:c2=!0;break;case t_Commands.Run:i2=await async function(n,e2){return n.allowed=!0,n.count=0,n.group=(0,import_core8.getId)(),n.timing=Date.now(),e2&&(e2.consent&&(n.consent=(0,import_core8.assign)(n.consent,e2.consent)),e2.user&&(n.user=(0,import_core8.assign)(n.user,e2.user)),e2.globals&&(n.globals=(0,import_core8.assign)(n.config.globalsStatic||{},e2.globals)),e2.custom&&(n.custom=(0,import_core8.assign)(n.custom,e2.custom))),Object.values(n.destinations).forEach(n2=>{n2.queuePush=[]}),n.queue=[],n.round++,await U(n)}(n,o2),c2=!0;break;case t_Commands.Session:c2=!0;break;case t_Commands.Shutdown:await async function(n2){const e3=n2.logger;await X(n2.sources,"source",e3),await X(n2.destinations,"destination",e3),await X(n2.transformers,"transformer",e3),await X(n2.stores,"store",e3)}(n);break;case t_Commands.User:(0,import_core9.isObject)(o2)&&((0,import_core8.assign)(n.user,o2,{shallow:!1}),a2=o2,c2=!0)}return c2&&await G(n,e2,void 0,a2),u2&&(i2=await U(n)),i2||J({ok:!0})}function rn(n,e2){return(0,import_core10.useHooks)(async(t2,o2={})=>await(0,import_core10.tryCatchAsync)(async()=>{const s2=Date.now(),{id:r2,ingest:i2,respond:a2,mapping:c2,preChain:u2}=o2;let f2=t2;const l2=i2?Object.freeze(i2):void 0;if(c2){const e3=await(0,import_core10.processEventMapping)(f2,c2,n);if(e3.ignore)return J({ok:!0});if(c2.consent&&!(0,import_core10.getGrantedConsent)(c2.consent,n.consent,e3.event.consent))return J({ok:!0});f2=e3.event}if((null==u2?void 0:u2.length)&&n.transformers&&Object.keys(n.transformers).length>0){const e3=await S(n,n.transformers,u2,f2,l2,a2);if(null===e3)return J({ok:!0});f2=e3}const g2=e2(f2),d2=function(n,e2){if(!e2.name)throw new Error("Event name is required");const[t2,o2]=e2.name.split(" ");if(!t2||!o2)throw new Error("Event name is invalid");++n.count;const{timestamp:s2=Date.now(),group:r2=n.group,count:i2=n.count}=e2,{name:a2=`${t2} ${o2}`,data:c2={},context:u2={},globals:f2=n.globals,custom:l2={},user:g2=n.user,nested:d2=[],consent:m2=n.consent,id:p2=`${s2}-${r2}-${i2}`,trigger:h2="",entity:w2=t2,action:b2=o2,timing:y2=0,version:v2={source:n.version,tagging:n.config.tagging||0},source:k2={type:"collector",id:"",previous_id:""}}=e2;return{name:a2,data:c2,context:u2,globals:f2,custom:l2,user:g2,nested:d2,consent:m2,id:p2,trigger:h2,entity:w2,action:b2,timestamp:s2,timing:y2,group:r2,count:i2,version:v2,source:k2}}(n,g2),m2=await U(n,d2,{id:r2,ingest:l2,respond:a2});if(r2){n.status.sources[r2]||(n.status.sources[r2]={count:0,duration:0});const e3=n.status.sources[r2];e3.count++,e3.lastAt=Date.now(),e3.duration+=Date.now()-s2}return m2},()=>J({ok:!1}))(),"Push",n.hooks)}async function un(n){var _a,_b;const e2=(0,import_core2.assign)({globalsStatic:{},sessionStatic:{},tagging:0,run:!0},n,{merge:!1,extend:!1}),t2={level:null==(_a=n.logger)?void 0:_a.level,handler:null==(_b=n.logger)?void 0:_b.handler},o2=(0,import_core2.createLogger)(t2),s2={...e2.globalsStatic,...n.globals},a2={allowed:!1,config:e2,consent:n.consent||{},count:0,custom:n.custom||{},destinations:{},transformers:{},stores:{},globals:s2,group:"",hooks:{},logger:o2,on:{},queue:[],round:0,session:void 0,status:{startedAt:Date.now(),in:0,out:0,failed:0,sources:{},destinations:{}},timing:Date.now(),user:n.user||{},version:"3.0.2",sources:{},pending:{sources:{},destinations:{}},push:void 0,command:void 0};var n2,e3;a2.push=rn(a2,n2=>({timing:Math.round((Date.now()-a2.timing)/10)/100,source:{type:"collector",id:"",previous_id:""},...n2})),a2.command=(n2=a2,e3=Y,(0,import_core11.useHooks)(async(t3,o3,s3)=>await(0,import_core11.tryCatchAsync)(async()=>await e3(n2,t3,o3,s3),()=>J({ok:!1}))(),"Command",n2.hooks));const c2=n.stores||{};return a2.stores=await async function(n2,e3={}){const t3={};for(const[o3,s3]of Object.entries(e3)){const{code:e4,config:r2={},env:i2={}}=s3,a3=n2.logger.scope("store").scope(o3),c3={collector:n2,logger:a3,id:o3,config:r2,env:i2},u2=await e4(c3);t3[o3]=u2}return t3}(a2,c2),function(n2,e3,t3){const o3=new Map;for(const[t4,s4]of Object.entries(n2))e3[t4]&&o3.set(s4,e3[t4]);if(0!==o3.size)for(const n3 of[t3.transformers,t3.destinations,t3.sources])if(n3)for(const e4 of Object.values(n3))s3(e4.env);function s3(n3){if(n3)for(const[e4,t4]of Object.entries(n3))if("object"==typeof t4&&null!==t4){const s4=o3.get(t4);s4&&(n3[e4]=s4)}}}(c2,a2.stores,n),a2.destinations=await async function(n,e2={}){var _a,_b;const t2={};for(const[o2,s2]of Object.entries(e2))(null==(_b=null==(_a=s2.config)?void 0:_a.require)?void 0:_b.length)?n.pending.destinations[o2]=s2:t2[o2]=M(s2);return t2}(a2,n.destinations||{}),a2.transformers=await async function(n2,e3={}){const t3={};for(const[o3,s3]of Object.entries(e3)){const{code:e4,env:r2={}}=s3,{config:i2}=A(s3,"next"),a3=Object.keys(r2).length>0?{...i2,env:r2}:i2,c3=n2.logger.scope("transformer").scope(o3),u2={collector:n2,logger:c3,id:o3,config:a3,env:r2},f2=await e4(u2);t3[o3]=f2}return t3}(a2,n.transformers||{}),a2}async function fn(n){n=n||{};const e2=await un(n),t2=(o2=e2,{type:"elb",config:{},push:async(n2,e3,t3,s3,r3,i3)=>{if("string"==typeof n2&&n2.startsWith("walker ")){const s4=n2.replace("walker ","");return o2.command(s4,e3,t3)}let a3;if("string"==typeof n2)a3={name:n2},e3&&"object"==typeof e3&&!Array.isArray(e3)&&(a3.data=e3);else{if(!n2||"object"!=typeof n2)return J({ok:!1});a3=n2,e3&&"object"==typeof e3&&!Array.isArray(e3)&&(a3.data={...a3.data||{},...e3})}return s3&&"object"==typeof s3&&(a3.context=s3),r3&&Array.isArray(r3)&&(a3.nested=r3),i3&&"object"==typeof i3&&(a3.custom=i3),o2.push(a3)}});var o2;e2.sources.elb=t2;const s2=await async function(n,e2={}){const t2={};for(const[o2,s2]of Object.entries(e2)){const{config:e3={}}=s2;if(e3.require&&e3.require.length>0){n.pending.sources[o2]=s2;continue}const r2=await R(n,o2,s2);r2&&(t2[o2]=r2)}return t2}(e2,n.sources||{});Object.assign(e2.sources,s2);const{consent:r2,user:i2,globals:a2,custom:c2}=n;r2&&await e2.command("consent",r2),i2&&await e2.command("user",i2),a2&&Object.assign(e2.globals,a2),c2&&Object.assign(e2.custom,c2),e2.config.run&&await e2.command("run");let u2=t2.push;const f2=Object.values(e2.sources).filter(n2=>"elb"!==n2.type),l2=f2.find(n2=>n2.config.primary);return l2?u2=l2.push:f2.length>0&&(u2=f2[0].push),{collector:e2,elb:u2}}var createTrigger=async config=>{let flow;return{get flow(){return flow},trigger:()=>async content=>{if(!flow){const result=await fn(config);flow={collector:result.collector,elb:result.elb}}const source=function(collector){for(const source of Object.values(collector.sources||{}))if("lambda"===source.type)return source}(flow.collector);if(!source)throw new Error("Lambda source not found in collector");const lambdaContext={awsRequestId:`test-${Date.now()}`},pushFn=source.push,lambdaResult=await pushFn(content,lambdaContext);let body;try{body=JSON.parse(lambdaResult.body||"{}")}catch(e2){body=lambdaResult.body}const headers={};if(lambdaResult.headers)for(const[k2,v2]of Object.entries(lambdaResult.headers))void 0!==v2&&(headers[k2]=String(v2));return{statusCode:lambdaResult.statusCode,body:body,headers:headers}}}};function trigger(source){return async content=>{const lambdaEvent={...content};if(lambdaEvent.body&&"string"==typeof lambdaEvent.body){const body=JSON.parse(lambdaEvent.body);body.name&&!body.event&&(lambdaEvent.body=JSON.stringify({...body,event:body.name,name:void 0}))}return source.push(lambdaEvent,{awsRequestId:"test-req"})}}var sourceLambda=async context=>{const{config:config={},env:env,setIngest:setIngest}=context,{push:envPush}=env,settings2=SettingsSchema.parse(config.settings||{});return{type:"lambda",config:{...config,settings:settings2},push:async(event,context2)=>{var _a;const requestId=context2.awsRequestId;let parsed;try{const corsHeaders=function(corsOptions){if(!corsOptions)return{};if(!0===corsOptions)return{"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization","Access-Control-Max-Age":"3600"};const headers={};if(corsOptions.origin){const origin=Array.isArray(corsOptions.origin)?corsOptions.origin.join(", "):corsOptions.origin;headers["Access-Control-Allow-Origin"]=origin}return corsOptions.methods&&(headers["Access-Control-Allow-Methods"]=corsOptions.methods.join(", ")),corsOptions.headers&&(headers["Access-Control-Allow-Headers"]=corsOptions.headers.join(", ")),corsOptions.credentials&&(headers["Access-Control-Allow-Credentials"]="true"),void 0!==corsOptions.maxAge&&(headers["Access-Control-Max-Age"]=corsOptions.maxAge.toString()),headers}(settings2.cors||!1);parsed=function(event){if(isAPIGatewayV2(event)){const headers={};return event.headers&&Object.entries(event.headers).forEach(([key,value])=>{value&&(headers[key.toLowerCase()]=value)}),{method:event.requestContext.http.method,body:event.body,queryString:event.rawQueryString||null,headers:headers,isBase64Encoded:event.isBase64Encoded||!1}}{const headers={};event.headers&&Object.entries(event.headers).forEach(([key,value])=>{value&&(headers[key.toLowerCase()]=value)});let queryString=null;if(event.queryStringParameters){const params=new URLSearchParams;Object.entries(event.queryStringParameters).forEach(([key,value])=>{value&¶ms.append(key,value)}),queryString=params.toString()||null}return{method:event.httpMethod,body:event.body,queryString:queryString,headers:headers,isBase64Encoded:event.isBase64Encoded||!1}}}(event);const path=function(event){return isAPIGatewayV2(event)?event.rawPath:event.path}(event);if(settings2.healthPath&&path===settings2.healthPath)return createResponse(200,{status:"ok",timestamp:Date.now(),source:"lambda",requestId:requestId},corsHeaders,requestId);if("OPTIONS"===parsed.method)return createResponse(204,"",corsHeaders,requestId);if(await setIngest(event),"GET"===parsed.method){if(!settings2.enablePixelTracking)return createResponse(405,{success:!1,error:"GET not allowed",requestId:requestId},corsHeaders,requestId);if(parsed.queryString){const parsedData=(0,import_core12.requestToData)(parsed.queryString);parsedData&&"object"==typeof parsedData&&await envPush(parsedData)}return function(headers={},requestId){const responseHeaders={"Content-Type":"image/gif","Cache-Control":"no-cache, no-store, must-revalidate",...headers};return requestId&&(responseHeaders["X-Request-ID"]=requestId),{statusCode:200,headers:responseHeaders,body:"R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7",isBase64Encoded:!0}}(corsHeaders,requestId)}if("POST"===parsed.method){if(!parsed.body)return createResponse(400,{success:!1,error:"Request body is required",requestId:requestId},corsHeaders,requestId);const body=function(body,isBase64Encoded){if(!body||"string"!=typeof body)return body;try{const decoded=isBase64Encoded?Buffer.from(body,"base64").toString("utf8"):body;return JSON.parse(decoded)}catch(e2){return body}}(parsed.body,parsed.isBase64Encoded);if(!body||"object"!=typeof body)return createResponse(400,{success:!1,error:"Invalid event body",requestId:requestId},corsHeaders,requestId);if(function(body){return"object"==typeof body&&null!==body&&"event"in body&&"string"==typeof body.event}(body)){const result=await async function(eventReq,push2,logger,requestId){var _a;try{const result=await push2({name:eventReq.event,data:eventReq.data||{},context:eventReq.context,user:eventReq.user,globals:eventReq.globals,consent:eventReq.consent});return{id:null==(_a=null==result?void 0:result.event)?void 0:_a.id}}catch(error){return null==logger||logger.error("Event processing failed",{error:error,eventName:eventReq.event,requestId:requestId}),{error:error instanceof Error?error.message:"Unknown error"}}}(body,envPush,env.logger,requestId);return result.error?createResponse(400,{success:!1,error:result.error,requestId:requestId},corsHeaders,requestId):createResponse(200,{success:!0,id:result.id,requestId:requestId},corsHeaders,requestId)}return createResponse(400,{success:!1,error:"Invalid request format",requestId:requestId},corsHeaders,requestId)}return createResponse(405,{success:!1,error:"Method not allowed",requestId:requestId},corsHeaders,requestId)}catch(error){return null==(_a=env.logger)||_a.error("Lambda handler error",{error:error,requestId:requestId,method:null==parsed?void 0:parsed.method}),createResponse(500,{success:!1,error:error instanceof Error?error.message:"Internal server error",requestId:requestId},{},requestId)}}}},lambda_default=sourceLambda;//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/lambda/index.ts","../src/lambda/utils.ts","../src/lambda/push.ts","../src/lambda/schemas/settings.ts","../src/lambda/schemas/primitives.ts","../src/lambda/types.ts","../src/lambda/schemas/index.ts","../src/lambda/examples/index.ts","../src/lambda/examples/env.ts","../src/lambda/examples/step.ts"],"sourcesContent":["export * from './lambda';\nexport { default as sourceLambda } 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 type { APIGatewayProxyEventV2, APIGatewayProxyResult } from 'aws-lambda';\nimport type {\n LambdaEvent,\n ParsedRequest,\n CorsOptions,\n RequestBody,\n EventRequest,\n} from './types';\n\nexport function isAPIGatewayV2(\n event: LambdaEvent,\n): event is APIGatewayProxyEventV2 {\n return 'version' in event && event.version === '2.0';\n}\n\nexport function parseEvent(event: LambdaEvent): ParsedRequest {\n if (isAPIGatewayV2(event)) {\n const headers: Record<string, string> = {};\n if (event.headers) {\n Object.entries(event.headers).forEach(([key, value]) => {\n if (value) headers[key.toLowerCase()] = value;\n });\n }\n return {\n method: event.requestContext.http.method,\n body: event.body,\n queryString: event.rawQueryString || null,\n headers,\n isBase64Encoded: event.isBase64Encoded || false,\n };\n } else {\n const headers: Record<string, string> = {};\n if (event.headers) {\n Object.entries(event.headers).forEach(([key, value]) => {\n if (value) headers[key.toLowerCase()] = value;\n });\n }\n let queryString: string | null = null;\n if (event.queryStringParameters) {\n const params = new URLSearchParams();\n Object.entries(event.queryStringParameters).forEach(([key, value]) => {\n if (value) params.append(key, value);\n });\n queryString = params.toString() || null;\n }\n return {\n method: event.httpMethod,\n body: event.body,\n queryString,\n headers,\n isBase64Encoded: event.isBase64Encoded || false,\n };\n }\n}\n\nexport function getPath(event: LambdaEvent): string {\n if (isAPIGatewayV2(event)) {\n return event.rawPath;\n } else {\n return event.path;\n }\n}\n\nexport function parseBody(body: unknown, isBase64Encoded: boolean): unknown {\n if (!body || typeof body !== 'string') return body;\n try {\n const decoded = isBase64Encoded\n ? Buffer.from(body, 'base64').toString('utf8')\n : body;\n return JSON.parse(decoded);\n } catch {\n return body;\n }\n}\n\nexport function isEventRequest(body: unknown): body is EventRequest {\n return (\n typeof body === 'object' &&\n body !== null &&\n 'event' in body &&\n typeof (body as EventRequest).event === 'string'\n );\n}\n\nexport function getCorsHeaders(\n corsOptions: boolean | CorsOptions,\n): Record<string, string> {\n if (!corsOptions) return {};\n if (corsOptions === true) {\n return {\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 }\n\n const headers: Record<string, string> = {};\n\n if (corsOptions.origin) {\n const origin = Array.isArray(corsOptions.origin)\n ? corsOptions.origin.join(', ')\n : corsOptions.origin;\n headers['Access-Control-Allow-Origin'] = origin;\n }\n if (corsOptions.methods) {\n headers['Access-Control-Allow-Methods'] = corsOptions.methods.join(', ');\n }\n if (corsOptions.headers) {\n headers['Access-Control-Allow-Headers'] = corsOptions.headers.join(', ');\n }\n if (corsOptions.credentials) {\n headers['Access-Control-Allow-Credentials'] = 'true';\n }\n if (corsOptions.maxAge !== undefined) {\n headers['Access-Control-Max-Age'] = corsOptions.maxAge.toString();\n }\n\n return headers;\n}\n\nexport function createResponse(\n statusCode: number,\n body: unknown,\n headers: Record<string, string> = {},\n requestId?: string,\n): APIGatewayProxyResult {\n const responseHeaders: Record<string, string> = {\n 'Content-Type':\n typeof body === 'object' ? 'application/json' : 'text/plain',\n ...headers,\n };\n\n if (requestId) {\n responseHeaders['X-Request-ID'] = requestId;\n }\n\n return {\n statusCode,\n headers: responseHeaders,\n body: typeof body === 'object' ? JSON.stringify(body) : String(body),\n isBase64Encoded: false,\n };\n}\n\nexport function createPixelResponse(\n headers: Record<string, string> = {},\n requestId?: string,\n): APIGatewayProxyResult {\n const responseHeaders: Record<string, string> = {\n 'Content-Type': 'image/gif',\n 'Cache-Control': 'no-cache, no-store, must-revalidate',\n ...headers,\n };\n\n if (requestId) {\n responseHeaders['X-Request-ID'] = requestId;\n }\n\n return {\n statusCode: 200,\n headers: responseHeaders,\n body: 'R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7',\n isBase64Encoded: true,\n };\n}\n","import type { Collector, WalkerOS, Logger } from '@walkeros/core';\nimport type { EventRequest } from './types';\n\nexport async function processEvent(\n eventReq: EventRequest,\n push: Collector.PushFn,\n logger?: Logger.Instance,\n requestId?: string,\n): Promise<{ id?: string; error?: string }> {\n try {\n const result = await push({\n name: eventReq.event,\n data: (eventReq.data || {}) as WalkerOS.Properties,\n context: eventReq.context as WalkerOS.OrderedProperties | undefined,\n user: eventReq.user as WalkerOS.User | undefined,\n globals: eventReq.globals as WalkerOS.Properties | undefined,\n consent: eventReq.consent as WalkerOS.Consent | undefined,\n });\n\n return { id: result?.event?.id };\n } catch (error) {\n // Log with structured context - per using-logger skill\n logger?.error('Event processing failed', {\n error,\n eventName: eventReq.event,\n requestId,\n });\n return { error: error instanceof Error ? error.message : 'Unknown error' };\n }\n}\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 type { WalkerOS, Source as CoreSource } from '@walkeros/core';\nimport type {\n APIGatewayProxyEvent,\n APIGatewayProxyEventV2,\n APIGatewayProxyResult,\n Context,\n} from 'aws-lambda';\nimport type { SettingsSchema, CorsOptionsSchema } from './schemas';\nimport { z } from '@walkeros/core/dev';\n\n// Lambda event types\nexport type LambdaEvent = APIGatewayProxyEvent | APIGatewayProxyEventV2;\nexport type LambdaResult = APIGatewayProxyResult;\nexport type LambdaContext = Context;\n\n// Types inferred from Zod schemas\nexport type Settings = z.infer<typeof SettingsSchema>;\nexport type CorsOptions = z.infer<typeof CorsOptionsSchema>;\n\n// InitSettings: user input (all optional)\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {\n // Custom source event mapping properties\n}\n\n// Lambda-specific push type\nexport type Push = (\n event: LambdaEvent,\n context: LambdaContext,\n) => Promise<LambdaResult>;\n\nexport interface Env extends CoreSource.Env {\n lambdaEvent?: LambdaEvent;\n lambdaContext?: LambdaContext;\n}\n\n// Type bundle (must be after Settings, Mapping, Push, Env are defined)\nexport type Types = CoreSource.Types<\n Settings,\n Mapping,\n Push,\n Env,\n InitSettings\n>;\n\nexport interface LambdaSource extends Omit<CoreSource.Instance<Types>, 'push'> {\n push: Push;\n}\n\n// Convenience Config type\nexport type Config = CoreSource.Config<Types>;\nexport type PartialConfig = CoreSource.PartialConfig<Types>;\n\n// Lambda source doesn't follow standard Source.Init pattern due to Lambda handler interface\n\nexport interface EventRequest {\n event: string;\n data?: WalkerOS.AnyObject;\n context?: WalkerOS.AnyObject;\n user?: WalkerOS.AnyObject;\n globals?: WalkerOS.AnyObject;\n consent?: WalkerOS.AnyObject;\n}\n\nexport interface EventResponse {\n success: boolean;\n id?: string;\n error?: string;\n}\n\nexport type RequestBody = EventRequest;\nexport type ResponseBody = EventResponse;\n\n// Parsed request data structure\nexport interface ParsedRequest {\n method: string;\n body: unknown;\n queryString: string | null;\n headers: Record<string, string>;\n isBase64Encoded: boolean;\n}\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 apiGatewayV1Post: Flow.StepExample = {\n in: {\n httpMethod: 'POST',\n path: '/collect',\n requestContext: {\n requestId: 'req-789',\n identity: { sourceIp: '203.0.113.42' },\n },\n queryStringParameters: null,\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":["push","import_dev","import_dev","settings","push","context"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/lambda/index.ts","../src/lambda/utils.ts","../src/lambda/push.ts","../src/lambda/schemas/settings.ts","../src/lambda/schemas/primitives.ts","../src/lambda/types.ts","../src/lambda/schemas/index.ts","../src/lambda/examples/index.ts","../src/lambda/examples/env.ts","../src/lambda/examples/step.ts","../src/lambda/examples/trigger.ts"],"sourcesContent":["export * from './lambda';\nexport { default as sourceLambda } 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 type { APIGatewayProxyEventV2, APIGatewayProxyResult } from 'aws-lambda';\nimport type {\n LambdaEvent,\n ParsedRequest,\n CorsOptions,\n RequestBody,\n EventRequest,\n} from './types';\n\nexport function isAPIGatewayV2(\n event: LambdaEvent,\n): event is APIGatewayProxyEventV2 {\n return 'version' in event && event.version === '2.0';\n}\n\nexport function parseEvent(event: LambdaEvent): ParsedRequest {\n if (isAPIGatewayV2(event)) {\n const headers: Record<string, string> = {};\n if (event.headers) {\n Object.entries(event.headers).forEach(([key, value]) => {\n if (value) headers[key.toLowerCase()] = value;\n });\n }\n return {\n method: event.requestContext.http.method,\n body: event.body,\n queryString: event.rawQueryString || null,\n headers,\n isBase64Encoded: event.isBase64Encoded || false,\n };\n } else {\n const headers: Record<string, string> = {};\n if (event.headers) {\n Object.entries(event.headers).forEach(([key, value]) => {\n if (value) headers[key.toLowerCase()] = value;\n });\n }\n let queryString: string | null = null;\n if (event.queryStringParameters) {\n const params = new URLSearchParams();\n Object.entries(event.queryStringParameters).forEach(([key, value]) => {\n if (value) params.append(key, value);\n });\n queryString = params.toString() || null;\n }\n return {\n method: event.httpMethod,\n body: event.body,\n queryString,\n headers,\n isBase64Encoded: event.isBase64Encoded || false,\n };\n }\n}\n\nexport function getPath(event: LambdaEvent): string {\n if (isAPIGatewayV2(event)) {\n return event.rawPath;\n } else {\n return event.path;\n }\n}\n\nexport function parseBody(body: unknown, isBase64Encoded: boolean): unknown {\n if (!body || typeof body !== 'string') return body;\n try {\n const decoded = isBase64Encoded\n ? Buffer.from(body, 'base64').toString('utf8')\n : body;\n return JSON.parse(decoded);\n } catch {\n return body;\n }\n}\n\nexport function isEventRequest(body: unknown): body is EventRequest {\n return (\n typeof body === 'object' &&\n body !== null &&\n 'event' in body &&\n typeof (body as EventRequest).event === 'string'\n );\n}\n\nexport function getCorsHeaders(\n corsOptions: boolean | CorsOptions,\n): Record<string, string> {\n if (!corsOptions) return {};\n if (corsOptions === true) {\n return {\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 }\n\n const headers: Record<string, string> = {};\n\n if (corsOptions.origin) {\n const origin = Array.isArray(corsOptions.origin)\n ? corsOptions.origin.join(', ')\n : corsOptions.origin;\n headers['Access-Control-Allow-Origin'] = origin;\n }\n if (corsOptions.methods) {\n headers['Access-Control-Allow-Methods'] = corsOptions.methods.join(', ');\n }\n if (corsOptions.headers) {\n headers['Access-Control-Allow-Headers'] = corsOptions.headers.join(', ');\n }\n if (corsOptions.credentials) {\n headers['Access-Control-Allow-Credentials'] = 'true';\n }\n if (corsOptions.maxAge !== undefined) {\n headers['Access-Control-Max-Age'] = corsOptions.maxAge.toString();\n }\n\n return headers;\n}\n\nexport function createResponse(\n statusCode: number,\n body: unknown,\n headers: Record<string, string> = {},\n requestId?: string,\n): APIGatewayProxyResult {\n const responseHeaders: Record<string, string> = {\n 'Content-Type':\n typeof body === 'object' ? 'application/json' : 'text/plain',\n ...headers,\n };\n\n if (requestId) {\n responseHeaders['X-Request-ID'] = requestId;\n }\n\n return {\n statusCode,\n headers: responseHeaders,\n body: typeof body === 'object' ? JSON.stringify(body) : String(body),\n isBase64Encoded: false,\n };\n}\n\nexport function createPixelResponse(\n headers: Record<string, string> = {},\n requestId?: string,\n): APIGatewayProxyResult {\n const responseHeaders: Record<string, string> = {\n 'Content-Type': 'image/gif',\n 'Cache-Control': 'no-cache, no-store, must-revalidate',\n ...headers,\n };\n\n if (requestId) {\n responseHeaders['X-Request-ID'] = requestId;\n }\n\n return {\n statusCode: 200,\n headers: responseHeaders,\n body: 'R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7',\n isBase64Encoded: true,\n };\n}\n","import type { Collector, WalkerOS, Logger } from '@walkeros/core';\nimport type { EventRequest } from './types';\n\nexport async function processEvent(\n eventReq: EventRequest,\n push: Collector.PushFn,\n logger?: Logger.Instance,\n requestId?: string,\n): Promise<{ id?: string; error?: string }> {\n try {\n const result = await push({\n name: eventReq.event,\n data: (eventReq.data || {}) as WalkerOS.Properties,\n context: eventReq.context as WalkerOS.OrderedProperties | undefined,\n user: eventReq.user as WalkerOS.User | undefined,\n globals: eventReq.globals as WalkerOS.Properties | undefined,\n consent: eventReq.consent as WalkerOS.Consent | undefined,\n });\n\n return { id: result?.event?.id };\n } catch (error) {\n // Log with structured context - per using-logger skill\n logger?.error('Event processing failed', {\n error,\n eventName: eventReq.event,\n requestId,\n });\n return { error: error instanceof Error ? error.message : 'Unknown error' };\n }\n}\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 type { WalkerOS, Source as CoreSource } from '@walkeros/core';\nimport type {\n APIGatewayProxyEvent,\n APIGatewayProxyEventV2,\n APIGatewayProxyResult,\n Context,\n} from 'aws-lambda';\nimport type { SettingsSchema, CorsOptionsSchema } from './schemas';\nimport { z } from '@walkeros/core/dev';\n\n// Lambda event types\nexport type LambdaEvent = APIGatewayProxyEvent | APIGatewayProxyEventV2;\nexport type LambdaResult = APIGatewayProxyResult;\nexport type LambdaContext = Context;\n\n// Types inferred from Zod schemas\nexport type Settings = z.infer<typeof SettingsSchema>;\nexport type CorsOptions = z.infer<typeof CorsOptionsSchema>;\n\n// InitSettings: user input (all optional)\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {\n // Custom source event mapping properties\n}\n\n// Lambda-specific push type\nexport type Push = (\n event: LambdaEvent,\n context: LambdaContext,\n) => Promise<LambdaResult>;\n\nexport interface Env extends CoreSource.Env {\n lambdaEvent?: LambdaEvent;\n lambdaContext?: LambdaContext;\n}\n\n// Type bundle (must be after Settings, Mapping, Push, Env are defined)\nexport type Types = CoreSource.Types<\n Settings,\n Mapping,\n Push,\n Env,\n InitSettings\n>;\n\nexport interface LambdaSource extends Omit<CoreSource.Instance<Types>, 'push'> {\n push: Push;\n}\n\n// Convenience Config type\nexport type Config = CoreSource.Config<Types>;\nexport type PartialConfig = CoreSource.PartialConfig<Types>;\n\n// Lambda source doesn't follow standard Source.Init pattern due to Lambda handler interface\n\nexport interface EventRequest {\n event: string;\n data?: WalkerOS.AnyObject;\n context?: WalkerOS.AnyObject;\n user?: WalkerOS.AnyObject;\n globals?: WalkerOS.AnyObject;\n consent?: WalkerOS.AnyObject;\n}\n\nexport interface EventResponse {\n success: boolean;\n id?: string;\n error?: string;\n}\n\nexport type RequestBody = EventRequest;\nexport type ResponseBody = EventResponse;\n\n// Parsed request data structure\nexport interface ParsedRequest {\n method: string;\n body: unknown;\n queryString: string | null;\n headers: Record<string, string>;\n isBase64Encoded: boolean;\n}\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';\nexport { createTrigger, trigger } from './trigger';\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 trigger: { type: 'POST' },\n in: {\n version: '2.0',\n requestContext: {\n http: { method: 'POST', path: '/collect' },\n requestId: 'req-123',\n },\n body: JSON.stringify({\n event: '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 apiGatewayV1Post: Flow.StepExample = {\n trigger: { type: 'POST' },\n in: {\n httpMethod: 'POST',\n path: '/collect',\n requestContext: {\n requestId: 'req-789',\n identity: { sourceIp: '203.0.113.42' },\n },\n queryStringParameters: null,\n body: JSON.stringify({\n event: '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 trigger: { type: 'GET' },\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","import type { Trigger, Collector } from '@walkeros/core';\nimport type { LambdaEvent, LambdaContext, LambdaResult } from '../types';\nimport { startFlow } from '@walkeros/collector';\n\nexport interface Content {\n [key: string]: unknown;\n}\n\nexport interface Result {\n statusCode: number;\n body: unknown;\n headers: Record<string, string>;\n}\n\n/**\n * Find the lambda source instance from the collector's registered sources.\n */\nfunction findLambdaSource(collector: Collector.Instance) {\n for (const source of Object.values(collector.sources || {})) {\n if ((source as { type?: string }).type === 'lambda') return source;\n }\n}\n\n/**\n * Lambda source createTrigger.\n *\n * Boots the collector via startFlow, then invokes the Lambda source's push()\n * with a real API Gateway event and a minimal Lambda context.\n *\n * Content is the raw Lambda event object (API Gateway v1 or v2 format).\n * Result contains statusCode, parsed body, and headers.\n *\n * @example\n * const { trigger, flow } = await createTrigger(config);\n * const result = await trigger('POST')({ version: '2.0', ... });\n * console.log(result.statusCode, result.body);\n */\nconst createTrigger: Trigger.CreateFn<Content, Result> = async (\n config: Collector.InitConfig,\n) => {\n let flow: Trigger.FlowHandle | undefined;\n\n const trigger: Trigger.Fn<Content, Result> =\n () =>\n async (content: Content): Promise<Result> => {\n // Lazy startFlow\n if (!flow) {\n const result = await startFlow(config);\n flow = { collector: result.collector, elb: result.elb };\n }\n\n const source = findLambdaSource(flow.collector);\n if (!source) throw new Error('Lambda source not found in collector');\n\n // Create minimal Lambda context\n const lambdaContext = {\n awsRequestId: `test-${Date.now()}`,\n } as unknown as LambdaContext;\n\n // Call source.push with the raw Lambda event + context\n const pushFn = (\n source as unknown as {\n push: (...args: unknown[]) => Promise<LambdaResult>;\n }\n ).push;\n const lambdaResult = await pushFn(\n content as unknown as LambdaEvent,\n lambdaContext,\n );\n\n // Parse response\n let body: unknown;\n try {\n body = JSON.parse(lambdaResult.body || '{}');\n } catch {\n body = lambdaResult.body;\n }\n\n const headers: Record<string, string> = {};\n if (lambdaResult.headers) {\n for (const [k, v] of Object.entries(lambdaResult.headers)) {\n if (v !== undefined) headers[k] = String(v);\n }\n }\n\n return {\n statusCode: lambdaResult.statusCode,\n body,\n headers,\n };\n };\n\n return {\n get flow() {\n return flow;\n },\n trigger,\n };\n};\n\n/**\n * Legacy trigger — takes a source instance directly.\n * Preserved for CLI simulate path.\n */\nfunction trigger(source: {\n push: (event: LambdaEvent, context: LambdaContext) => Promise<LambdaResult>;\n}): (content: Content) => Promise<LambdaResult> {\n return async (content: Content) => {\n const lambdaEvent = { ...(content as Record<string, unknown>) };\n\n // Adapt body format: step examples may use `name`, source expects `event`\n if (lambdaEvent.body && typeof lambdaEvent.body === 'string') {\n const body = JSON.parse(lambdaEvent.body);\n if (body.name && !body.event) {\n lambdaEvent.body = JSON.stringify({\n ...body,\n event: body.name,\n name: undefined,\n });\n }\n }\n\n const context: LambdaContext = {\n awsRequestId: 'test-req',\n } as unknown as LambdaContext;\n\n return source.push(lambdaEvent as unknown as LambdaEvent, context);\n };\n}\n\nexport { createTrigger, trigger };\n"],"mappings":"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","names":["import_core","e","push","import_dev","import_dev","fn","trigger","e","k","v","settings","push","context"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var __defProp=Object.defineProperty,__export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})};import{requestToData}from"@walkeros/core";function isAPIGatewayV2(event){return"version"in event&&"2.0"===event.version}function createResponse(statusCode,body,headers={},requestId){const responseHeaders={"Content-Type":"object"==typeof body?"application/json":"text/plain",...headers};return requestId&&(responseHeaders["X-Request-ID"]=requestId),{statusCode:statusCode,headers:responseHeaders,body:"object"==typeof body?JSON.stringify(body):String(body),isBase64Encoded:!1}}import{z as z2}from"@walkeros/core/dev";import{z}from"@walkeros/core/dev";var HttpMethod=z.enum(["GET","POST","PUT","PATCH","DELETE","OPTIONS","HEAD"]),CorsOrigin=z.union([z.string(),z.array(z.string()),z.literal("*")]),CorsOptionsSchema=z.object({origin:CorsOrigin.describe("Allowed origins (* for all, URL string, or array of URLs)").optional(),methods:z.array(HttpMethod).describe("Allowed HTTP methods").optional(),headers:z.array(z.string()).describe("Allowed request headers").optional(),credentials:z.boolean().describe("Allow credentials (cookies, authorization headers)").optional(),maxAge:z.number().int().positive().describe("Preflight cache duration in seconds").optional()}),SettingsSchema=z2.object({cors:z2.union([z2.boolean(),CorsOptionsSchema]).describe("CORS configuration: false = disabled, true = allow all origins, object = custom configuration").default(!0),timeout:z2.number().int().positive().max(9e5).describe("Request timeout in milliseconds (max: 900000 for Lambda)").default(3e4),enablePixelTracking:z2.boolean().describe("Enable GET requests with 1x1 transparent GIF response for pixel tracking").default(!0),healthPath:z2.string().describe("Health check endpoint path (e.g., /health)").default("/health")}),types_exports={},schemas_exports={};__export(schemas_exports,{CorsOptionsSchema:()=>CorsOptionsSchema,CorsOrigin:()=>CorsOrigin,HttpMethod:()=>HttpMethod,SettingsSchema:()=>SettingsSchema,settings:()=>settings});import{zodToSchema}from"@walkeros/core/dev";var settings=zodToSchema(SettingsSchema),examples_exports={};__export(examples_exports,{env:()=>env_exports,step:()=>step_exports});var env_exports={};__export(env_exports,{push:()=>push});var createMockElbFn=()=>()=>Promise.resolve({ok:!0}),noopFn=()=>{},noopLogger={error:noopFn,warn:noopFn,info:noopFn,debug:noopFn,throw:message=>{throw"string"==typeof message?new Error(message):message},json:noopFn,scope:()=>noopLogger},push={get push(){return createMockElbFn()},get command(){return createMockElbFn()},get elb(){return createMockElbFn()},logger:noopLogger},step_exports={};__export(step_exports,{apiGatewayV1Post:()=>apiGatewayV1Post,lambdaGet:()=>lambdaGet,lambdaPost:()=>lambdaPost});var lambdaPost={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"}},apiGatewayV1Post={in:{httpMethod:"POST",path:"/collect",requestContext:{requestId:"req-789",identity:{sourceIp:"203.0.113.42"}},queryStringParameters:null,body:JSON.stringify({name:"page view",data:{title:"Home"}}),isBase64Encoded:!1},out:{name:"page view",data:{title:"Home"},entity:"page",action:"view"}},lambdaGet={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"}},lambda_default=async context=>{const{config:config={},env:env,setIngest:setIngest}=context,{push:envPush}=env,settings2=SettingsSchema.parse(config.settings||{});return{type:"lambda",config:{...config,settings:settings2},push:async(event,context2)=>{var _a;const requestId=context2.awsRequestId;let parsed;try{const corsHeaders=function(corsOptions){if(!corsOptions)return{};if(!0===corsOptions)return{"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization","Access-Control-Max-Age":"3600"};const headers={};if(corsOptions.origin){const origin=Array.isArray(corsOptions.origin)?corsOptions.origin.join(", "):corsOptions.origin;headers["Access-Control-Allow-Origin"]=origin}return corsOptions.methods&&(headers["Access-Control-Allow-Methods"]=corsOptions.methods.join(", ")),corsOptions.headers&&(headers["Access-Control-Allow-Headers"]=corsOptions.headers.join(", ")),corsOptions.credentials&&(headers["Access-Control-Allow-Credentials"]="true"),void 0!==corsOptions.maxAge&&(headers["Access-Control-Max-Age"]=corsOptions.maxAge.toString()),headers}(settings2.cors||!1);parsed=function(event){if(isAPIGatewayV2(event)){const headers={};return event.headers&&Object.entries(event.headers).forEach(([key,value])=>{value&&(headers[key.toLowerCase()]=value)}),{method:event.requestContext.http.method,body:event.body,queryString:event.rawQueryString||null,headers:headers,isBase64Encoded:event.isBase64Encoded||!1}}{const headers={};event.headers&&Object.entries(event.headers).forEach(([key,value])=>{value&&(headers[key.toLowerCase()]=value)});let queryString=null;if(event.queryStringParameters){const params=new URLSearchParams;Object.entries(event.queryStringParameters).forEach(([key,value])=>{value&¶ms.append(key,value)}),queryString=params.toString()||null}return{method:event.httpMethod,body:event.body,queryString:queryString,headers:headers,isBase64Encoded:event.isBase64Encoded||!1}}}(event);const path=function(event){return isAPIGatewayV2(event)?event.rawPath:event.path}(event);if(settings2.healthPath&&path===settings2.healthPath)return createResponse(200,{status:"ok",timestamp:Date.now(),source:"lambda",requestId:requestId},corsHeaders,requestId);if("OPTIONS"===parsed.method)return createResponse(204,"",corsHeaders,requestId);if(await setIngest(event),"GET"===parsed.method){if(!settings2.enablePixelTracking)return createResponse(405,{success:!1,error:"GET not allowed",requestId:requestId},corsHeaders,requestId);if(parsed.queryString){const parsedData=requestToData(parsed.queryString);parsedData&&"object"==typeof parsedData&&await envPush(parsedData)}return function(headers={},requestId){const responseHeaders={"Content-Type":"image/gif","Cache-Control":"no-cache, no-store, must-revalidate",...headers};return requestId&&(responseHeaders["X-Request-ID"]=requestId),{statusCode:200,headers:responseHeaders,body:"R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7",isBase64Encoded:!0}}(corsHeaders,requestId)}if("POST"===parsed.method){if(!parsed.body)return createResponse(400,{success:!1,error:"Request body is required",requestId:requestId},corsHeaders,requestId);const body=function(body,isBase64Encoded){if(!body||"string"!=typeof body)return body;try{const decoded=isBase64Encoded?Buffer.from(body,"base64").toString("utf8"):body;return JSON.parse(decoded)}catch(e){return body}}(parsed.body,parsed.isBase64Encoded);if(!body||"object"!=typeof body)return createResponse(400,{success:!1,error:"Invalid event body",requestId:requestId},corsHeaders,requestId);if(function(body){return"object"==typeof body&&null!==body&&"event"in body&&"string"==typeof body.event}(body)){const result=await async function(eventReq,push2,logger,requestId){var _a;try{const result=await push2({name:eventReq.event,data:eventReq.data||{},context:eventReq.context,user:eventReq.user,globals:eventReq.globals,consent:eventReq.consent});return{id:null==(_a=null==result?void 0:result.event)?void 0:_a.id}}catch(error){return null==logger||logger.error("Event processing failed",{error:error,eventName:eventReq.event,requestId:requestId}),{error:error instanceof Error?error.message:"Unknown error"}}}(body,envPush,env.logger,requestId);return result.error?createResponse(400,{success:!1,error:result.error,requestId:requestId},corsHeaders,requestId):createResponse(200,{success:!0,id:result.id,requestId:requestId},corsHeaders,requestId)}return createResponse(400,{success:!1,error:"Invalid request format",requestId:requestId},corsHeaders,requestId)}return createResponse(405,{success:!1,error:"Method not allowed",requestId:requestId},corsHeaders,requestId)}catch(error){return null==(_a=env.logger)||_a.error("Lambda handler error",{error:error,requestId:requestId,method:null==parsed?void 0:parsed.method}),createResponse(500,{success:!1,error:error instanceof Error?error.message:"Internal server error",requestId:requestId},{},requestId)}}}};export{types_exports as SourceLambda,examples_exports as examples,schemas_exports as schemas,lambda_default as sourceLambda};//# sourceMappingURL=index.mjs.map
|
|
1
|
+
var __defProp=Object.defineProperty,__export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})};import{requestToData}from"@walkeros/core";function isAPIGatewayV2(event){return"version"in event&&"2.0"===event.version}function createResponse(statusCode,body,headers={},requestId){const responseHeaders={"Content-Type":"object"==typeof body?"application/json":"text/plain",...headers};return requestId&&(responseHeaders["X-Request-ID"]=requestId),{statusCode:statusCode,headers:responseHeaders,body:"object"==typeof body?JSON.stringify(body):String(body),isBase64Encoded:!1}}import{z as z2}from"@walkeros/core/dev";import{z}from"@walkeros/core/dev";var HttpMethod=z.enum(["GET","POST","PUT","PATCH","DELETE","OPTIONS","HEAD"]),CorsOrigin=z.union([z.string(),z.array(z.string()),z.literal("*")]),CorsOptionsSchema=z.object({origin:CorsOrigin.describe("Allowed origins (* for all, URL string, or array of URLs)").optional(),methods:z.array(HttpMethod).describe("Allowed HTTP methods").optional(),headers:z.array(z.string()).describe("Allowed request headers").optional(),credentials:z.boolean().describe("Allow credentials (cookies, authorization headers)").optional(),maxAge:z.number().int().positive().describe("Preflight cache duration in seconds").optional()}),SettingsSchema=z2.object({cors:z2.union([z2.boolean(),CorsOptionsSchema]).describe("CORS configuration: false = disabled, true = allow all origins, object = custom configuration").default(!0),timeout:z2.number().int().positive().max(9e5).describe("Request timeout in milliseconds (max: 900000 for Lambda)").default(3e4),enablePixelTracking:z2.boolean().describe("Enable GET requests with 1x1 transparent GIF response for pixel tracking").default(!0),healthPath:z2.string().describe("Health check endpoint path (e.g., /health)").default("/health")}),types_exports={},schemas_exports={};__export(schemas_exports,{CorsOptionsSchema:()=>CorsOptionsSchema,CorsOrigin:()=>CorsOrigin,HttpMethod:()=>HttpMethod,SettingsSchema:()=>SettingsSchema,settings:()=>settings});import{zodToSchema}from"@walkeros/core/dev";var settings=zodToSchema(SettingsSchema),examples_exports={};__export(examples_exports,{createTrigger:()=>createTrigger,env:()=>env_exports,step:()=>step_exports,trigger:()=>trigger});var env_exports={};__export(env_exports,{push:()=>push});var createMockElbFn=()=>()=>Promise.resolve({ok:!0}),noopFn=()=>{},noopLogger={error:noopFn,warn:noopFn,info:noopFn,debug:noopFn,throw:message=>{throw"string"==typeof message?new Error(message):message},json:noopFn,scope:()=>noopLogger},push={get push(){return createMockElbFn()},get command(){return createMockElbFn()},get elb(){return createMockElbFn()},logger:noopLogger},step_exports={};__export(step_exports,{apiGatewayV1Post:()=>apiGatewayV1Post,lambdaGet:()=>lambdaGet,lambdaPost:()=>lambdaPost});var lambdaPost={trigger:{type:"POST"},in:{version:"2.0",requestContext:{http:{method:"POST",path:"/collect"},requestId:"req-123"},body:JSON.stringify({event:"page view",data:{title:"Home"}}),isBase64Encoded:!1},out:{name:"page view",data:{title:"Home"},entity:"page",action:"view"}},apiGatewayV1Post={trigger:{type:"POST"},in:{httpMethod:"POST",path:"/collect",requestContext:{requestId:"req-789",identity:{sourceIp:"203.0.113.42"}},queryStringParameters:null,body:JSON.stringify({event:"page view",data:{title:"Home"}}),isBase64Encoded:!1},out:{name:"page view",data:{title:"Home"},entity:"page",action:"view"}},lambdaGet={trigger:{type:"GET"},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"}};import{assign as o}from"@walkeros/core";import{assign as r,createLogger as i}from"@walkeros/core";import{assign as a,clone as c,debounce as u,getId as f,getGrantedConsent as l,isDefined as g,isFunction as d,isObject as m,processEventMapping as p,tryCatchAsync as h,useHooks as w}from"@walkeros/core";import{isArray as b}from"@walkeros/core";import{tryCatch as y,tryCatchAsync as v}from"@walkeros/core";import{getMappingValue as k,tryCatchAsync as O}from"@walkeros/core";import{isObject as C,tryCatchAsync as j,useHooks as q}from"@walkeros/core";import{assign as L,getId as Q,isFunction as V,isString as _}from"@walkeros/core";import{isObject as K}from"@walkeros/core";import{getGrantedConsent as en,processEventMapping as tn,tryCatchAsync as on,useHooks as sn}from"@walkeros/core";import{useHooks as an,tryCatchAsync as cn}from"@walkeros/core";var t_Commands={Action:"action",Actions:"actions",Config:"config",Consent:"consent",Context:"context",Custom:"custom",Destination:"destination",Elb:"elb",Globals:"globals",Hook:"hook",Init:"init",Link:"link",On:"on",Prefix:"data-elb",Ready:"ready",Run:"run",Session:"session",Shutdown:"shutdown",User:"user",Walker:"walker"};function D(n){var _a;const e2={};for(const[t2,o2]of Object.entries(n))(null==(_a=o2.config)?void 0:_a.next)?e2[t2]={next:o2.config.next}:e2[t2]={};return e2}function A(n,e2){const t2=n.config||{},o2=n[e2];return void 0!==o2?{config:{...t2,[e2]:o2},chainValue:o2}:{config:t2,chainValue:void 0}}function E(n,e2={}){if(!n)return[];if(Array.isArray(n))return n;const t2=[],o2=new Set;let s2=n;for(;s2&&e2[s2]&&!o2.has(s2);){o2.add(s2),t2.push(s2);const n2=e2[s2].next;if(Array.isArray(n2)){t2.push(...n2);break}s2=n2}return t2}async function x(n,e2,t2){if(e2.init&&!e2.config.init){const o2=e2.type||"unknown",s2=n.logger.scope(`transformer:${o2}`),r2={collector:n,logger:s2,id:t2,config:e2.config,env:$(e2.config.env)};s2.debug("init");const i2=await q(e2.init,"TransformerInit",n.hooks)(r2);if(!1===i2)return!1;e2.config={...i2||e2.config,env:(null==i2?void 0:i2.env)||e2.config.env,init:!0},s2.debug("init done")}return!0}async function P(n,e2,t2,o2,s2,r2){const i2=e2.type||"unknown",a2=n.logger.scope(`transformer:${i2}`),c2={collector:n,logger:a2,id:t2,ingest:s2,config:e2.config,env:{...$(e2.config.env),...r2?{respond:r2}:{}}};a2.debug("push",{event:o2.name});const u2=await q(e2.push,"TransformerPush",n.hooks)(o2,c2);return a2.debug("push done"),u2}async function S(n,e2,t2,o2,s2,r2){let i2=o2,a2=r2;for(const o3 of t2){const t3=e2[o3];if(!t3){n.logger.warn(`Transformer not found: ${o3}`);continue}if(!await j(x)(n,t3,o3))return n.logger.error(`Transformer init failed: ${o3}`),null;const r3=await j(P,e3=>(n.logger.scope(`transformer:${t3.type||"unknown"}`).error("Push failed",{error:e3}),!1))(n,t3,o3,i2,s2,a2);if(!1===r3)return null;if(r3&&"object"==typeof r3){const{event:t4,respond:o4,next:c2}=r3;if(o4&&(a2=o4),c2){const o5=E(c2,D(e2));return o5.length>0?S(n,e2,o5,t4||i2,s2,a2):(n.logger.warn(`Branch target not found: ${JSON.stringify(c2)}`),null)}t4&&(i2=t4)}}return i2}function $(n){return n&&C(n)?n:{}}async function R(n,e2,t2){const{code:o2,config:s2={},env:r2={},primary:i2,next:a2}=t2;let c2,u2;const f2=E(a2,D(n.transformers)),l2=n.logger.scope("source").scope(e2),g2={push:(t3,o3={})=>n.push(t3,{...o3,id:e2,ingest:c2,respond:u2,mapping:s2,preChain:f2}),command:n.command,sources:n.sources,elb:n.sources.elb.push,logger:l2,...r2},d2={collector:n,logger:l2,id:e2,config:s2,env:g2,setIngest:async e3=>{c2=s2.ingest?await k(e3,s2.ingest,{collector:n}):void 0},setRespond:n2=>{u2=n2}},m2=await O(o2)(d2);if(!m2)return;const p2=m2.type||"unknown",h2=n.logger.scope(p2).scope(e2);return g2.logger=h2,i2&&(m2.config={...m2.config,primary:i2}),m2}function B(n,e2,t2,o2,s2){if(!e2.on)return;const r2=e2.type||"unknown",i2=n.logger.scope(r2).scope("on").scope(o2),a2={collector:n,logger:i2,id:t2,config:e2.config,data:s2,env:W(e2.env,e2.config.env)};y(e2.on)(o2,a2)}async function G(n,e2,o2,s2){let r2,i2=o2||[];switch(o2||(i2=n.on[e2]||[]),e2){case t_Commands.Consent:r2=s2||n.consent;break;case t_Commands.Session:r2=n.session;break;case t_Commands.User:r2=s2||n.user;break;case t_Commands.Custom:r2=s2||n.custom;break;case t_Commands.Globals:r2=s2||n.globals;break;case t_Commands.Config:r2=s2||n.config;break;case t_Commands.Ready:case t_Commands.Run:default:r2=void 0}let a2=!1;for(const t2 of Object.values(n.sources))t2.on&&!1===await v(t2.on)(e2,r2)&&(a2=!0);if(Object.entries(n.destinations).forEach(([t2,o3])=>{if(o3.on){if(!o3.config.init)return o3.queueOn=o3.queueOn||[],void o3.queueOn.push({type:e2,data:r2});B(n,o3,t2,e2,r2)}}),(Object.keys(n.pending.sources).length>0||Object.keys(n.pending.destinations).length>0)&&await async function(n2,e3){var _a,_b;for(const[t2,o3]of Object.entries(n2.pending.sources)){if(!n2.pending.sources[t2]||n2.sources[t2])continue;const s3=null==(_a=o3.config)?void 0:_a.require;if(!s3)continue;const r3=s3.indexOf(e3);if(-1===r3)continue;if(s3.splice(r3,1),s3.length>0)continue;delete n2.pending.sources[t2];const i3=await R(n2,t2,o3);i3&&(n2.sources[t2]=i3)}for(const[t2,o3]of Object.entries(n2.pending.destinations)){if(!n2.pending.destinations[t2]||n2.destinations[t2])continue;const s3=null==(_b=o3.config)?void 0:_b.require;if(!s3)continue;const r3=s3.indexOf(e3);if(-1===r3)continue;if(s3.splice(r3,1),s3.length>0)continue;delete n2.pending.destinations[t2];const i3=M(o3);!1!==i3.config.queue&&(i3.queuePush=[...n2.queue]),n2.destinations[t2]=i3}}(n,e2),!i2.length)return!a2;switch(e2){case t_Commands.Consent:!function(n2,e3,t2){const o3=t2||n2.consent;e3.forEach(e4=>{Object.keys(o3).filter(n3=>n3 in e4).forEach(t3=>{y(e4[t3])(n2,o3)})})}(n,i2,s2);break;case t_Commands.Ready:case t_Commands.Run:e3=i2,(n2=n).allowed&&e3.forEach(e4=>{y(e4)(n2)});break;case t_Commands.Session:!function(n2,e3){n2.session&&e3.forEach(e4=>{y(e4)(n2,n2.session)})}(n,i2);break;default:i2.forEach(e3=>{"function"==typeof e3&&y(e3)(n,r2)})}var n2,e3;return!a2}async function H(n,e2,t2){const{code:o2,config:s2={},env:r2={},before:i2}=e2;if(!d(o2.push))return J({ok:!1,failed:{invalid:{type:"invalid",error:"Destination code must have a push method"}}});const a2=t2||s2||{init:!1},c2=i2?{...a2,before:i2}:a2,u2={...o2,config:c2,env:W(o2.env,r2)};let l2=u2.config.id;if(!l2)do{l2=f(4)}while(n.destinations[l2]);return n.destinations[l2]=u2,!1!==u2.config.queue&&(u2.queuePush=[...n.queue]),U(n,void 0,{},{[l2]:u2})}async function U(n,e2,t2={},o2){const{allowed:s2,consent:r2,globals:i2,user:u2}=n;if(!s2)return J({ok:!1});e2&&(n.queue.push(e2),n.status.in++),o2||(o2=n.destinations);const f2=await Promise.all(Object.entries(o2||{}).map(async([o3,s3])=>{var _a,_b;let f3=(s3.queuePush||[]).map(n2=>({...n2,consent:r2}));if(s3.queuePush=[],e2){const n2=c(e2);f3.push(n2)}if(!f3.length&&!(null==(_a=s3.queueOn)?void 0:_a.length))return{id:o3,destination:s3,skipped:!0};if(!f3.length&&(null==(_b=s3.queueOn)?void 0:_b.length)){const e3=await h(z3)(n,s3,o3);return{id:o3,destination:s3,skipped:!e3}}const g3=[],d3=f3.filter(n2=>{const e3=l(s3.config.consent,r2,n2.consent);return!e3||(n2.consent=e3,g3.push(n2),!1)});if(s3.queuePush.push(...d3),!g3.length)return{id:o3,destination:s3,queue:f3};if(!await h(z3)(n,s3,o3))return{id:o3,destination:s3,queue:f3};let m3,p2;s3.dlq||(s3.dlq=[]);const w2=function(n2,e3){const t3=n2.config.before;return t3?E(t3,D(e3)):[]}(s3,n.transformers);let b2=0;return await Promise.all(g3.map(async e3=>{e3.globals=a(i2,e3.globals),e3.user=a(u2,e3.user);let r3=e3;if(w2.length>0&&n.transformers&&Object.keys(n.transformers).length>0){const o4=await S(n,n.transformers,w2,e3,t2.ingest,t2.respond);if(null===o4)return e3;r3=o4}const c2=Date.now(),f4=await h(F,e4=>{const t3=s3.type||"unknown";n.logger.scope(t3).error("Push failed",{error:e4,event:r3.name}),m3=e4,s3.dlq.push([r3,e4])})(n,s3,o3,r3,t2.ingest,t2.respond);return b2+=Date.now()-c2,void 0!==f4&&(p2=f4),e3})),{id:o3,destination:s3,error:m3,response:p2,totalDuration:b2}})),g2={},d2={},m2={};for(const e3 of f2){if(e3.skipped)continue;const t3={type:e3.destination.type||"unknown",data:e3.response};n.status.destinations[e3.id]||(n.status.destinations[e3.id]={count:0,failed:0,duration:0});const o3=n.status.destinations[e3.id],s3=Date.now();e3.error?(t3.error=e3.error,m2[e3.id]=t3,o3.failed++,o3.lastAt=s3,o3.duration+=e3.totalDuration||0,n.status.failed++):e3.queue&&e3.queue.length?d2[e3.id]=t3:(g2[e3.id]=t3,o3.count++,o3.lastAt=s3,o3.duration+=e3.totalDuration||0,n.status.out++)}return J({event:e2,...Object.keys(g2).length&&{done:g2},...Object.keys(d2).length&&{queued:d2},...Object.keys(m2).length&&{failed:m2}})}async function z3(n,e2,t2){var _a;if(e2.init&&!e2.config.init){const o2=e2.type||"unknown",s2=n.logger.scope(o2),r2={collector:n,logger:s2,id:t2,config:e2.config,env:W(e2.env,e2.config.env)};s2.debug("init");const i2=await w(e2.init,"DestinationInit",n.hooks)(r2);if(!1===i2)return i2;if(e2.config={...i2||e2.config,init:!0},null==(_a=e2.queueOn)?void 0:_a.length){const o3=e2.queueOn;e2.queueOn=[];for(const{type:s3,data:r3}of o3)B(n,e2,t2,s3,r3)}s2.debug("init done")}return!0}async function F(n,e2,t2,o2,s2,r2){const{config:i2}=e2,a2=await p(o2,i2,n);if(a2.ignore)return!1;const c2=e2.type||"unknown",f2=n.logger.scope(c2),l2={collector:n,logger:f2,id:t2,config:i2,data:a2.data,rule:a2.mapping,ingest:s2,env:{...W(e2.env,i2.env),...r2?{respond:r2}:{}}},d2=a2.mapping,m2=a2.mappingKey||"* *";if(!(null==d2?void 0:d2.batch)||!e2.pushBatch){f2.debug("push",{event:a2.event.name});const t3=await w(e2.push,"DestinationPush",n.hooks)(a2.event,l2);return f2.debug("push done"),t3}{if(e2.batches=e2.batches||{},!e2.batches[m2]){const o4={key:m2,events:[],data:[]};e2.batches[m2]={batched:o4,batchFn:u(()=>{const o5=e2.batches[m2].batched,a3={collector:n,logger:f2,id:t2,config:i2,data:void 0,rule:d2,ingest:s2,env:{...W(e2.env,i2.env),...r2?{respond:r2}:{}}};f2.debug("push batch",{events:o5.events.length}),w(e2.pushBatch,"DestinationPushBatch",n.hooks)(o5,a3),f2.debug("push batch done"),o5.events=[],o5.data=[]},d2.batch)}}const o3=e2.batches[m2];o3.batched.events.push(a2.event),g(a2.data)&&o3.batched.data.push(a2.data),o3.batchFn()}return!0}function J(n){return{ok:!(null==n?void 0:n.failed),...n}}function M(n){const{code:e2,config:t2={},env:o2={}}=n,{config:s2}=A(n,"before"),r2={...e2.config,...t2,...s2},i2=W(e2.env,o2);return{...e2,config:r2,env:i2}}function W(n,e2){return n||e2?e2?n&&m(n)&&m(e2)?{...n,...e2}:e2:n:{}}async function X(n,e2,t2){const o2=Object.entries(n).map(async([n2,o3])=>{var _a;const s2=o3.destroy;if(!s2)return;const r2=o3.type||"unknown",i2=t2.scope(r2),a2={id:n2,config:o3.config,env:null!=(_a=o3.env)?_a:{},logger:i2};try{await Promise.race([s2(a2),new Promise((t3,o4)=>setTimeout(()=>o4(new Error(`${e2} '${n2}' destroy timed out`)),5e3))])}catch(t3){i2.error(`${e2} '${n2}' destroy failed: ${t3}`)}});await Promise.allSettled(o2)}async function Y(n,e2,o2,r2){let i2,a2,c2=!1,u2=!1;switch(e2){case t_Commands.Config:K(o2)&&(L(n.config,o2,{shallow:!1}),a2=o2,c2=!0);break;case t_Commands.Consent:if(K(o2)){const{update:e3,runQueue:t2}=function(n,e2){let t2=!1;const s2={};return Object.entries(e2).forEach(([n2,e3])=>{const o2=!!e3;s2[n2]=o2,t2=t2||o2}),n.consent=o(n.consent,s2),{update:s2,runQueue:t2}}(n,o2);a2=e3,c2=!0,u2=t2}break;case t_Commands.Custom:K(o2)&&(n.custom=L(n.custom,o2),a2=o2,c2=!0);break;case t_Commands.Destination:K(o2)&&("code"in o2&&K(o2.code)?i2=await H(n,o2,r2):V(o2.push)&&(i2=await H(n,{code:o2},r2)));break;case t_Commands.Globals:K(o2)&&(n.globals=L(n.globals,o2),a2=o2,c2=!0);break;case t_Commands.On:_(o2)&&await async function(n,e2,t2){const o2=n.on,s2=o2[e2]||[],r2=b(t2)?t2:[t2];r2.forEach(n2=>{s2.push(n2)}),o2[e2]=s2,await G(n,e2,r2)}(n,o2,r2);break;case t_Commands.Ready:c2=!0;break;case t_Commands.Run:i2=await async function(n,e2){return n.allowed=!0,n.count=0,n.group=Q(),n.timing=Date.now(),e2&&(e2.consent&&(n.consent=L(n.consent,e2.consent)),e2.user&&(n.user=L(n.user,e2.user)),e2.globals&&(n.globals=L(n.config.globalsStatic||{},e2.globals)),e2.custom&&(n.custom=L(n.custom,e2.custom))),Object.values(n.destinations).forEach(n2=>{n2.queuePush=[]}),n.queue=[],n.round++,await U(n)}(n,o2),c2=!0;break;case t_Commands.Session:c2=!0;break;case t_Commands.Shutdown:await async function(n2){const e3=n2.logger;await X(n2.sources,"source",e3),await X(n2.destinations,"destination",e3),await X(n2.transformers,"transformer",e3),await X(n2.stores,"store",e3)}(n);break;case t_Commands.User:K(o2)&&(L(n.user,o2,{shallow:!1}),a2=o2,c2=!0)}return c2&&await G(n,e2,void 0,a2),u2&&(i2=await U(n)),i2||J({ok:!0})}function rn(n,e2){return sn(async(t2,o2={})=>await on(async()=>{const s2=Date.now(),{id:r2,ingest:i2,respond:a2,mapping:c2,preChain:u2}=o2;let f2=t2;const l2=i2?Object.freeze(i2):void 0;if(c2){const e3=await tn(f2,c2,n);if(e3.ignore)return J({ok:!0});if(c2.consent&&!en(c2.consent,n.consent,e3.event.consent))return J({ok:!0});f2=e3.event}if((null==u2?void 0:u2.length)&&n.transformers&&Object.keys(n.transformers).length>0){const e3=await S(n,n.transformers,u2,f2,l2,a2);if(null===e3)return J({ok:!0});f2=e3}const g2=e2(f2),d2=function(n,e2){if(!e2.name)throw new Error("Event name is required");const[t2,o2]=e2.name.split(" ");if(!t2||!o2)throw new Error("Event name is invalid");++n.count;const{timestamp:s2=Date.now(),group:r2=n.group,count:i2=n.count}=e2,{name:a2=`${t2} ${o2}`,data:c2={},context:u2={},globals:f2=n.globals,custom:l2={},user:g2=n.user,nested:d2=[],consent:m2=n.consent,id:p2=`${s2}-${r2}-${i2}`,trigger:h2="",entity:w2=t2,action:b2=o2,timing:y2=0,version:v2={source:n.version,tagging:n.config.tagging||0},source:k2={type:"collector",id:"",previous_id:""}}=e2;return{name:a2,data:c2,context:u2,globals:f2,custom:l2,user:g2,nested:d2,consent:m2,id:p2,trigger:h2,entity:w2,action:b2,timestamp:s2,timing:y2,group:r2,count:i2,version:v2,source:k2}}(n,g2),m2=await U(n,d2,{id:r2,ingest:l2,respond:a2});if(r2){n.status.sources[r2]||(n.status.sources[r2]={count:0,duration:0});const e3=n.status.sources[r2];e3.count++,e3.lastAt=Date.now(),e3.duration+=Date.now()-s2}return m2},()=>J({ok:!1}))(),"Push",n.hooks)}async function un(n){var _a,_b;const e2=r({globalsStatic:{},sessionStatic:{},tagging:0,run:!0},n,{merge:!1,extend:!1}),t2={level:null==(_a=n.logger)?void 0:_a.level,handler:null==(_b=n.logger)?void 0:_b.handler},o2=i(t2),s2={...e2.globalsStatic,...n.globals},a2={allowed:!1,config:e2,consent:n.consent||{},count:0,custom:n.custom||{},destinations:{},transformers:{},stores:{},globals:s2,group:"",hooks:{},logger:o2,on:{},queue:[],round:0,session:void 0,status:{startedAt:Date.now(),in:0,out:0,failed:0,sources:{},destinations:{}},timing:Date.now(),user:n.user||{},version:"3.0.2",sources:{},pending:{sources:{},destinations:{}},push:void 0,command:void 0};var n2,e3;a2.push=rn(a2,n2=>({timing:Math.round((Date.now()-a2.timing)/10)/100,source:{type:"collector",id:"",previous_id:""},...n2})),a2.command=(e3=Y,an(async(t3,o3,s3)=>await cn(async()=>await e3(n2,t3,o3,s3),()=>J({ok:!1}))(),"Command",(n2=a2).hooks));const c2=n.stores||{};return a2.stores=await async function(n2,e3={}){const t3={};for(const[o3,s3]of Object.entries(e3)){const{code:e4,config:r2={},env:i2={}}=s3,a3=n2.logger.scope("store").scope(o3),c3={collector:n2,logger:a3,id:o3,config:r2,env:i2},u2=await e4(c3);t3[o3]=u2}return t3}(a2,c2),function(n2,e3,t3){const o3=new Map;for(const[t4,s4]of Object.entries(n2))e3[t4]&&o3.set(s4,e3[t4]);if(0!==o3.size)for(const n3 of[t3.transformers,t3.destinations,t3.sources])if(n3)for(const e4 of Object.values(n3))s3(e4.env);function s3(n3){if(n3)for(const[e4,t4]of Object.entries(n3))if("object"==typeof t4&&null!==t4){const s4=o3.get(t4);s4&&(n3[e4]=s4)}}}(c2,a2.stores,n),a2.destinations=await async function(n,e2={}){var _a,_b;const t2={};for(const[o2,s2]of Object.entries(e2))(null==(_b=null==(_a=s2.config)?void 0:_a.require)?void 0:_b.length)?n.pending.destinations[o2]=s2:t2[o2]=M(s2);return t2}(a2,n.destinations||{}),a2.transformers=await async function(n2,e3={}){const t3={};for(const[o3,s3]of Object.entries(e3)){const{code:e4,env:r2={}}=s3,{config:i2}=A(s3,"next"),a3=Object.keys(r2).length>0?{...i2,env:r2}:i2,c3=n2.logger.scope("transformer").scope(o3),u2={collector:n2,logger:c3,id:o3,config:a3,env:r2},f2=await e4(u2);t3[o3]=f2}return t3}(a2,n.transformers||{}),a2}async function fn(n){n=n||{};const e2=await un(n),t2=(o2=e2,{type:"elb",config:{},push:async(n2,e3,t3,s3,r3,i3)=>{if("string"==typeof n2&&n2.startsWith("walker ")){const s4=n2.replace("walker ","");return o2.command(s4,e3,t3)}let a3;if("string"==typeof n2)a3={name:n2},e3&&"object"==typeof e3&&!Array.isArray(e3)&&(a3.data=e3);else{if(!n2||"object"!=typeof n2)return J({ok:!1});a3=n2,e3&&"object"==typeof e3&&!Array.isArray(e3)&&(a3.data={...a3.data||{},...e3})}return s3&&"object"==typeof s3&&(a3.context=s3),r3&&Array.isArray(r3)&&(a3.nested=r3),i3&&"object"==typeof i3&&(a3.custom=i3),o2.push(a3)}});var o2;e2.sources.elb=t2;const s2=await async function(n,e2={}){const t2={};for(const[o2,s2]of Object.entries(e2)){const{config:e3={}}=s2;if(e3.require&&e3.require.length>0){n.pending.sources[o2]=s2;continue}const r2=await R(n,o2,s2);r2&&(t2[o2]=r2)}return t2}(e2,n.sources||{});Object.assign(e2.sources,s2);const{consent:r2,user:i2,globals:a2,custom:c2}=n;r2&&await e2.command("consent",r2),i2&&await e2.command("user",i2),a2&&Object.assign(e2.globals,a2),c2&&Object.assign(e2.custom,c2),e2.config.run&&await e2.command("run");let u2=t2.push;const f2=Object.values(e2.sources).filter(n2=>"elb"!==n2.type),l2=f2.find(n2=>n2.config.primary);return l2?u2=l2.push:f2.length>0&&(u2=f2[0].push),{collector:e2,elb:u2}}var createTrigger=async config=>{let flow;return{get flow(){return flow},trigger:()=>async content=>{if(!flow){const result=await fn(config);flow={collector:result.collector,elb:result.elb}}const source=function(collector){for(const source of Object.values(collector.sources||{}))if("lambda"===source.type)return source}(flow.collector);if(!source)throw new Error("Lambda source not found in collector");const lambdaContext={awsRequestId:`test-${Date.now()}`},pushFn=source.push,lambdaResult=await pushFn(content,lambdaContext);let body;try{body=JSON.parse(lambdaResult.body||"{}")}catch(e2){body=lambdaResult.body}const headers={};if(lambdaResult.headers)for(const[k2,v2]of Object.entries(lambdaResult.headers))void 0!==v2&&(headers[k2]=String(v2));return{statusCode:lambdaResult.statusCode,body:body,headers:headers}}}};function trigger(source){return async content=>{const lambdaEvent={...content};if(lambdaEvent.body&&"string"==typeof lambdaEvent.body){const body=JSON.parse(lambdaEvent.body);body.name&&!body.event&&(lambdaEvent.body=JSON.stringify({...body,event:body.name,name:void 0}))}return source.push(lambdaEvent,{awsRequestId:"test-req"})}}var lambda_default=async context=>{const{config:config={},env:env,setIngest:setIngest}=context,{push:envPush}=env,settings2=SettingsSchema.parse(config.settings||{});return{type:"lambda",config:{...config,settings:settings2},push:async(event,context2)=>{var _a;const requestId=context2.awsRequestId;let parsed;try{const corsHeaders=function(corsOptions){if(!corsOptions)return{};if(!0===corsOptions)return{"Access-Control-Allow-Origin":"*","Access-Control-Allow-Methods":"GET, POST, OPTIONS","Access-Control-Allow-Headers":"Content-Type, Authorization","Access-Control-Max-Age":"3600"};const headers={};if(corsOptions.origin){const origin=Array.isArray(corsOptions.origin)?corsOptions.origin.join(", "):corsOptions.origin;headers["Access-Control-Allow-Origin"]=origin}return corsOptions.methods&&(headers["Access-Control-Allow-Methods"]=corsOptions.methods.join(", ")),corsOptions.headers&&(headers["Access-Control-Allow-Headers"]=corsOptions.headers.join(", ")),corsOptions.credentials&&(headers["Access-Control-Allow-Credentials"]="true"),void 0!==corsOptions.maxAge&&(headers["Access-Control-Max-Age"]=corsOptions.maxAge.toString()),headers}(settings2.cors||!1);parsed=function(event){if(isAPIGatewayV2(event)){const headers={};return event.headers&&Object.entries(event.headers).forEach(([key,value])=>{value&&(headers[key.toLowerCase()]=value)}),{method:event.requestContext.http.method,body:event.body,queryString:event.rawQueryString||null,headers:headers,isBase64Encoded:event.isBase64Encoded||!1}}{const headers={};event.headers&&Object.entries(event.headers).forEach(([key,value])=>{value&&(headers[key.toLowerCase()]=value)});let queryString=null;if(event.queryStringParameters){const params=new URLSearchParams;Object.entries(event.queryStringParameters).forEach(([key,value])=>{value&¶ms.append(key,value)}),queryString=params.toString()||null}return{method:event.httpMethod,body:event.body,queryString:queryString,headers:headers,isBase64Encoded:event.isBase64Encoded||!1}}}(event);const path=function(event){return isAPIGatewayV2(event)?event.rawPath:event.path}(event);if(settings2.healthPath&&path===settings2.healthPath)return createResponse(200,{status:"ok",timestamp:Date.now(),source:"lambda",requestId:requestId},corsHeaders,requestId);if("OPTIONS"===parsed.method)return createResponse(204,"",corsHeaders,requestId);if(await setIngest(event),"GET"===parsed.method){if(!settings2.enablePixelTracking)return createResponse(405,{success:!1,error:"GET not allowed",requestId:requestId},corsHeaders,requestId);if(parsed.queryString){const parsedData=requestToData(parsed.queryString);parsedData&&"object"==typeof parsedData&&await envPush(parsedData)}return function(headers={},requestId){const responseHeaders={"Content-Type":"image/gif","Cache-Control":"no-cache, no-store, must-revalidate",...headers};return requestId&&(responseHeaders["X-Request-ID"]=requestId),{statusCode:200,headers:responseHeaders,body:"R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7",isBase64Encoded:!0}}(corsHeaders,requestId)}if("POST"===parsed.method){if(!parsed.body)return createResponse(400,{success:!1,error:"Request body is required",requestId:requestId},corsHeaders,requestId);const body=function(body,isBase64Encoded){if(!body||"string"!=typeof body)return body;try{const decoded=isBase64Encoded?Buffer.from(body,"base64").toString("utf8"):body;return JSON.parse(decoded)}catch(e2){return body}}(parsed.body,parsed.isBase64Encoded);if(!body||"object"!=typeof body)return createResponse(400,{success:!1,error:"Invalid event body",requestId:requestId},corsHeaders,requestId);if(function(body){return"object"==typeof body&&null!==body&&"event"in body&&"string"==typeof body.event}(body)){const result=await async function(eventReq,push2,logger,requestId){var _a;try{const result=await push2({name:eventReq.event,data:eventReq.data||{},context:eventReq.context,user:eventReq.user,globals:eventReq.globals,consent:eventReq.consent});return{id:null==(_a=null==result?void 0:result.event)?void 0:_a.id}}catch(error){return null==logger||logger.error("Event processing failed",{error:error,eventName:eventReq.event,requestId:requestId}),{error:error instanceof Error?error.message:"Unknown error"}}}(body,envPush,env.logger,requestId);return result.error?createResponse(400,{success:!1,error:result.error,requestId:requestId},corsHeaders,requestId):createResponse(200,{success:!0,id:result.id,requestId:requestId},corsHeaders,requestId)}return createResponse(400,{success:!1,error:"Invalid request format",requestId:requestId},corsHeaders,requestId)}return createResponse(405,{success:!1,error:"Method not allowed",requestId:requestId},corsHeaders,requestId)}catch(error){return null==(_a=env.logger)||_a.error("Lambda handler error",{error:error,requestId:requestId,method:null==parsed?void 0:parsed.method}),createResponse(500,{success:!1,error:error instanceof Error?error.message:"Internal server error",requestId:requestId},{},requestId)}}}};export{types_exports as SourceLambda,examples_exports as examples,schemas_exports as schemas,lambda_default as sourceLambda};//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lambda/index.ts","../src/lambda/utils.ts","../src/lambda/push.ts","../src/lambda/schemas/settings.ts","../src/lambda/schemas/primitives.ts","../src/lambda/types.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 type { APIGatewayProxyEventV2, APIGatewayProxyResult } from 'aws-lambda';\nimport type {\n LambdaEvent,\n ParsedRequest,\n CorsOptions,\n RequestBody,\n EventRequest,\n} from './types';\n\nexport function isAPIGatewayV2(\n event: LambdaEvent,\n): event is APIGatewayProxyEventV2 {\n return 'version' in event && event.version === '2.0';\n}\n\nexport function parseEvent(event: LambdaEvent): ParsedRequest {\n if (isAPIGatewayV2(event)) {\n const headers: Record<string, string> = {};\n if (event.headers) {\n Object.entries(event.headers).forEach(([key, value]) => {\n if (value) headers[key.toLowerCase()] = value;\n });\n }\n return {\n method: event.requestContext.http.method,\n body: event.body,\n queryString: event.rawQueryString || null,\n headers,\n isBase64Encoded: event.isBase64Encoded || false,\n };\n } else {\n const headers: Record<string, string> = {};\n if (event.headers) {\n Object.entries(event.headers).forEach(([key, value]) => {\n if (value) headers[key.toLowerCase()] = value;\n });\n }\n let queryString: string | null = null;\n if (event.queryStringParameters) {\n const params = new URLSearchParams();\n Object.entries(event.queryStringParameters).forEach(([key, value]) => {\n if (value) params.append(key, value);\n });\n queryString = params.toString() || null;\n }\n return {\n method: event.httpMethod,\n body: event.body,\n queryString,\n headers,\n isBase64Encoded: event.isBase64Encoded || false,\n };\n }\n}\n\nexport function getPath(event: LambdaEvent): string {\n if (isAPIGatewayV2(event)) {\n return event.rawPath;\n } else {\n return event.path;\n }\n}\n\nexport function parseBody(body: unknown, isBase64Encoded: boolean): unknown {\n if (!body || typeof body !== 'string') return body;\n try {\n const decoded = isBase64Encoded\n ? Buffer.from(body, 'base64').toString('utf8')\n : body;\n return JSON.parse(decoded);\n } catch {\n return body;\n }\n}\n\nexport function isEventRequest(body: unknown): body is EventRequest {\n return (\n typeof body === 'object' &&\n body !== null &&\n 'event' in body &&\n typeof (body as EventRequest).event === 'string'\n );\n}\n\nexport function getCorsHeaders(\n corsOptions: boolean | CorsOptions,\n): Record<string, string> {\n if (!corsOptions) return {};\n if (corsOptions === true) {\n return {\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 }\n\n const headers: Record<string, string> = {};\n\n if (corsOptions.origin) {\n const origin = Array.isArray(corsOptions.origin)\n ? corsOptions.origin.join(', ')\n : corsOptions.origin;\n headers['Access-Control-Allow-Origin'] = origin;\n }\n if (corsOptions.methods) {\n headers['Access-Control-Allow-Methods'] = corsOptions.methods.join(', ');\n }\n if (corsOptions.headers) {\n headers['Access-Control-Allow-Headers'] = corsOptions.headers.join(', ');\n }\n if (corsOptions.credentials) {\n headers['Access-Control-Allow-Credentials'] = 'true';\n }\n if (corsOptions.maxAge !== undefined) {\n headers['Access-Control-Max-Age'] = corsOptions.maxAge.toString();\n }\n\n return headers;\n}\n\nexport function createResponse(\n statusCode: number,\n body: unknown,\n headers: Record<string, string> = {},\n requestId?: string,\n): APIGatewayProxyResult {\n const responseHeaders: Record<string, string> = {\n 'Content-Type':\n typeof body === 'object' ? 'application/json' : 'text/plain',\n ...headers,\n };\n\n if (requestId) {\n responseHeaders['X-Request-ID'] = requestId;\n }\n\n return {\n statusCode,\n headers: responseHeaders,\n body: typeof body === 'object' ? JSON.stringify(body) : String(body),\n isBase64Encoded: false,\n };\n}\n\nexport function createPixelResponse(\n headers: Record<string, string> = {},\n requestId?: string,\n): APIGatewayProxyResult {\n const responseHeaders: Record<string, string> = {\n 'Content-Type': 'image/gif',\n 'Cache-Control': 'no-cache, no-store, must-revalidate',\n ...headers,\n };\n\n if (requestId) {\n responseHeaders['X-Request-ID'] = requestId;\n }\n\n return {\n statusCode: 200,\n headers: responseHeaders,\n body: 'R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7',\n isBase64Encoded: true,\n };\n}\n","import type { Collector, WalkerOS, Logger } from '@walkeros/core';\nimport type { EventRequest } from './types';\n\nexport async function processEvent(\n eventReq: EventRequest,\n push: Collector.PushFn,\n logger?: Logger.Instance,\n requestId?: string,\n): Promise<{ id?: string; error?: string }> {\n try {\n const result = await push({\n name: eventReq.event,\n data: (eventReq.data || {}) as WalkerOS.Properties,\n context: eventReq.context as WalkerOS.OrderedProperties | undefined,\n user: eventReq.user as WalkerOS.User | undefined,\n globals: eventReq.globals as WalkerOS.Properties | undefined,\n consent: eventReq.consent as WalkerOS.Consent | undefined,\n });\n\n return { id: result?.event?.id };\n } catch (error) {\n // Log with structured context - per using-logger skill\n logger?.error('Event processing failed', {\n error,\n eventName: eventReq.event,\n requestId,\n });\n return { error: error instanceof Error ? error.message : 'Unknown error' };\n }\n}\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 type { WalkerOS, Source as CoreSource } from '@walkeros/core';\nimport type {\n APIGatewayProxyEvent,\n APIGatewayProxyEventV2,\n APIGatewayProxyResult,\n Context,\n} from 'aws-lambda';\nimport type { SettingsSchema, CorsOptionsSchema } from './schemas';\nimport { z } from '@walkeros/core/dev';\n\n// Lambda event types\nexport type LambdaEvent = APIGatewayProxyEvent | APIGatewayProxyEventV2;\nexport type LambdaResult = APIGatewayProxyResult;\nexport type LambdaContext = Context;\n\n// Types inferred from Zod schemas\nexport type Settings = z.infer<typeof SettingsSchema>;\nexport type CorsOptions = z.infer<typeof CorsOptionsSchema>;\n\n// InitSettings: user input (all optional)\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {\n // Custom source event mapping properties\n}\n\n// Lambda-specific push type\nexport type Push = (\n event: LambdaEvent,\n context: LambdaContext,\n) => Promise<LambdaResult>;\n\nexport interface Env extends CoreSource.Env {\n lambdaEvent?: LambdaEvent;\n lambdaContext?: LambdaContext;\n}\n\n// Type bundle (must be after Settings, Mapping, Push, Env are defined)\nexport type Types = CoreSource.Types<\n Settings,\n Mapping,\n Push,\n Env,\n InitSettings\n>;\n\nexport interface LambdaSource extends Omit<CoreSource.Instance<Types>, 'push'> {\n push: Push;\n}\n\n// Convenience Config type\nexport type Config = CoreSource.Config<Types>;\nexport type PartialConfig = CoreSource.PartialConfig<Types>;\n\n// Lambda source doesn't follow standard Source.Init pattern due to Lambda handler interface\n\nexport interface EventRequest {\n event: string;\n data?: WalkerOS.AnyObject;\n context?: WalkerOS.AnyObject;\n user?: WalkerOS.AnyObject;\n globals?: WalkerOS.AnyObject;\n consent?: WalkerOS.AnyObject;\n}\n\nexport interface EventResponse {\n success: boolean;\n id?: string;\n error?: string;\n}\n\nexport type RequestBody = EventRequest;\nexport type ResponseBody = EventResponse;\n\n// Parsed request data structure\nexport interface ParsedRequest {\n method: string;\n body: unknown;\n queryString: string | null;\n headers: Record<string, string>;\n isBase64Encoded: boolean;\n}\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 apiGatewayV1Post: Flow.StepExample = {\n in: {\n httpMethod: 'POST',\n path: '/collect',\n requestContext: {\n requestId: 'req-789',\n identity: { sourceIp: '203.0.113.42' },\n },\n queryStringParameters: null,\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":["push","z","z","settings","push","context"]}
|
|
1
|
+
{"version":3,"sources":["../src/lambda/index.ts","../src/lambda/utils.ts","../src/lambda/push.ts","../src/lambda/schemas/settings.ts","../src/lambda/schemas/primitives.ts","../src/lambda/types.ts","../src/lambda/schemas/index.ts","../src/lambda/examples/index.ts","../src/lambda/examples/env.ts","../src/lambda/examples/step.ts","../src/lambda/examples/trigger.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 type { APIGatewayProxyEventV2, APIGatewayProxyResult } from 'aws-lambda';\nimport type {\n LambdaEvent,\n ParsedRequest,\n CorsOptions,\n RequestBody,\n EventRequest,\n} from './types';\n\nexport function isAPIGatewayV2(\n event: LambdaEvent,\n): event is APIGatewayProxyEventV2 {\n return 'version' in event && event.version === '2.0';\n}\n\nexport function parseEvent(event: LambdaEvent): ParsedRequest {\n if (isAPIGatewayV2(event)) {\n const headers: Record<string, string> = {};\n if (event.headers) {\n Object.entries(event.headers).forEach(([key, value]) => {\n if (value) headers[key.toLowerCase()] = value;\n });\n }\n return {\n method: event.requestContext.http.method,\n body: event.body,\n queryString: event.rawQueryString || null,\n headers,\n isBase64Encoded: event.isBase64Encoded || false,\n };\n } else {\n const headers: Record<string, string> = {};\n if (event.headers) {\n Object.entries(event.headers).forEach(([key, value]) => {\n if (value) headers[key.toLowerCase()] = value;\n });\n }\n let queryString: string | null = null;\n if (event.queryStringParameters) {\n const params = new URLSearchParams();\n Object.entries(event.queryStringParameters).forEach(([key, value]) => {\n if (value) params.append(key, value);\n });\n queryString = params.toString() || null;\n }\n return {\n method: event.httpMethod,\n body: event.body,\n queryString,\n headers,\n isBase64Encoded: event.isBase64Encoded || false,\n };\n }\n}\n\nexport function getPath(event: LambdaEvent): string {\n if (isAPIGatewayV2(event)) {\n return event.rawPath;\n } else {\n return event.path;\n }\n}\n\nexport function parseBody(body: unknown, isBase64Encoded: boolean): unknown {\n if (!body || typeof body !== 'string') return body;\n try {\n const decoded = isBase64Encoded\n ? Buffer.from(body, 'base64').toString('utf8')\n : body;\n return JSON.parse(decoded);\n } catch {\n return body;\n }\n}\n\nexport function isEventRequest(body: unknown): body is EventRequest {\n return (\n typeof body === 'object' &&\n body !== null &&\n 'event' in body &&\n typeof (body as EventRequest).event === 'string'\n );\n}\n\nexport function getCorsHeaders(\n corsOptions: boolean | CorsOptions,\n): Record<string, string> {\n if (!corsOptions) return {};\n if (corsOptions === true) {\n return {\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 }\n\n const headers: Record<string, string> = {};\n\n if (corsOptions.origin) {\n const origin = Array.isArray(corsOptions.origin)\n ? corsOptions.origin.join(', ')\n : corsOptions.origin;\n headers['Access-Control-Allow-Origin'] = origin;\n }\n if (corsOptions.methods) {\n headers['Access-Control-Allow-Methods'] = corsOptions.methods.join(', ');\n }\n if (corsOptions.headers) {\n headers['Access-Control-Allow-Headers'] = corsOptions.headers.join(', ');\n }\n if (corsOptions.credentials) {\n headers['Access-Control-Allow-Credentials'] = 'true';\n }\n if (corsOptions.maxAge !== undefined) {\n headers['Access-Control-Max-Age'] = corsOptions.maxAge.toString();\n }\n\n return headers;\n}\n\nexport function createResponse(\n statusCode: number,\n body: unknown,\n headers: Record<string, string> = {},\n requestId?: string,\n): APIGatewayProxyResult {\n const responseHeaders: Record<string, string> = {\n 'Content-Type':\n typeof body === 'object' ? 'application/json' : 'text/plain',\n ...headers,\n };\n\n if (requestId) {\n responseHeaders['X-Request-ID'] = requestId;\n }\n\n return {\n statusCode,\n headers: responseHeaders,\n body: typeof body === 'object' ? JSON.stringify(body) : String(body),\n isBase64Encoded: false,\n };\n}\n\nexport function createPixelResponse(\n headers: Record<string, string> = {},\n requestId?: string,\n): APIGatewayProxyResult {\n const responseHeaders: Record<string, string> = {\n 'Content-Type': 'image/gif',\n 'Cache-Control': 'no-cache, no-store, must-revalidate',\n ...headers,\n };\n\n if (requestId) {\n responseHeaders['X-Request-ID'] = requestId;\n }\n\n return {\n statusCode: 200,\n headers: responseHeaders,\n body: 'R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7',\n isBase64Encoded: true,\n };\n}\n","import type { Collector, WalkerOS, Logger } from '@walkeros/core';\nimport type { EventRequest } from './types';\n\nexport async function processEvent(\n eventReq: EventRequest,\n push: Collector.PushFn,\n logger?: Logger.Instance,\n requestId?: string,\n): Promise<{ id?: string; error?: string }> {\n try {\n const result = await push({\n name: eventReq.event,\n data: (eventReq.data || {}) as WalkerOS.Properties,\n context: eventReq.context as WalkerOS.OrderedProperties | undefined,\n user: eventReq.user as WalkerOS.User | undefined,\n globals: eventReq.globals as WalkerOS.Properties | undefined,\n consent: eventReq.consent as WalkerOS.Consent | undefined,\n });\n\n return { id: result?.event?.id };\n } catch (error) {\n // Log with structured context - per using-logger skill\n logger?.error('Event processing failed', {\n error,\n eventName: eventReq.event,\n requestId,\n });\n return { error: error instanceof Error ? error.message : 'Unknown error' };\n }\n}\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 type { WalkerOS, Source as CoreSource } from '@walkeros/core';\nimport type {\n APIGatewayProxyEvent,\n APIGatewayProxyEventV2,\n APIGatewayProxyResult,\n Context,\n} from 'aws-lambda';\nimport type { SettingsSchema, CorsOptionsSchema } from './schemas';\nimport { z } from '@walkeros/core/dev';\n\n// Lambda event types\nexport type LambdaEvent = APIGatewayProxyEvent | APIGatewayProxyEventV2;\nexport type LambdaResult = APIGatewayProxyResult;\nexport type LambdaContext = Context;\n\n// Types inferred from Zod schemas\nexport type Settings = z.infer<typeof SettingsSchema>;\nexport type CorsOptions = z.infer<typeof CorsOptionsSchema>;\n\n// InitSettings: user input (all optional)\nexport type InitSettings = Partial<Settings>;\n\nexport interface Mapping {\n // Custom source event mapping properties\n}\n\n// Lambda-specific push type\nexport type Push = (\n event: LambdaEvent,\n context: LambdaContext,\n) => Promise<LambdaResult>;\n\nexport interface Env extends CoreSource.Env {\n lambdaEvent?: LambdaEvent;\n lambdaContext?: LambdaContext;\n}\n\n// Type bundle (must be after Settings, Mapping, Push, Env are defined)\nexport type Types = CoreSource.Types<\n Settings,\n Mapping,\n Push,\n Env,\n InitSettings\n>;\n\nexport interface LambdaSource extends Omit<CoreSource.Instance<Types>, 'push'> {\n push: Push;\n}\n\n// Convenience Config type\nexport type Config = CoreSource.Config<Types>;\nexport type PartialConfig = CoreSource.PartialConfig<Types>;\n\n// Lambda source doesn't follow standard Source.Init pattern due to Lambda handler interface\n\nexport interface EventRequest {\n event: string;\n data?: WalkerOS.AnyObject;\n context?: WalkerOS.AnyObject;\n user?: WalkerOS.AnyObject;\n globals?: WalkerOS.AnyObject;\n consent?: WalkerOS.AnyObject;\n}\n\nexport interface EventResponse {\n success: boolean;\n id?: string;\n error?: string;\n}\n\nexport type RequestBody = EventRequest;\nexport type ResponseBody = EventResponse;\n\n// Parsed request data structure\nexport interface ParsedRequest {\n method: string;\n body: unknown;\n queryString: string | null;\n headers: Record<string, string>;\n isBase64Encoded: boolean;\n}\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';\nexport { createTrigger, trigger } from './trigger';\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 trigger: { type: 'POST' },\n in: {\n version: '2.0',\n requestContext: {\n http: { method: 'POST', path: '/collect' },\n requestId: 'req-123',\n },\n body: JSON.stringify({\n event: '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 apiGatewayV1Post: Flow.StepExample = {\n trigger: { type: 'POST' },\n in: {\n httpMethod: 'POST',\n path: '/collect',\n requestContext: {\n requestId: 'req-789',\n identity: { sourceIp: '203.0.113.42' },\n },\n queryStringParameters: null,\n body: JSON.stringify({\n event: '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 trigger: { type: 'GET' },\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","import type { Trigger, Collector } from '@walkeros/core';\nimport type { LambdaEvent, LambdaContext, LambdaResult } from '../types';\nimport { startFlow } from '@walkeros/collector';\n\nexport interface Content {\n [key: string]: unknown;\n}\n\nexport interface Result {\n statusCode: number;\n body: unknown;\n headers: Record<string, string>;\n}\n\n/**\n * Find the lambda source instance from the collector's registered sources.\n */\nfunction findLambdaSource(collector: Collector.Instance) {\n for (const source of Object.values(collector.sources || {})) {\n if ((source as { type?: string }).type === 'lambda') return source;\n }\n}\n\n/**\n * Lambda source createTrigger.\n *\n * Boots the collector via startFlow, then invokes the Lambda source's push()\n * with a real API Gateway event and a minimal Lambda context.\n *\n * Content is the raw Lambda event object (API Gateway v1 or v2 format).\n * Result contains statusCode, parsed body, and headers.\n *\n * @example\n * const { trigger, flow } = await createTrigger(config);\n * const result = await trigger('POST')({ version: '2.0', ... });\n * console.log(result.statusCode, result.body);\n */\nconst createTrigger: Trigger.CreateFn<Content, Result> = async (\n config: Collector.InitConfig,\n) => {\n let flow: Trigger.FlowHandle | undefined;\n\n const trigger: Trigger.Fn<Content, Result> =\n () =>\n async (content: Content): Promise<Result> => {\n // Lazy startFlow\n if (!flow) {\n const result = await startFlow(config);\n flow = { collector: result.collector, elb: result.elb };\n }\n\n const source = findLambdaSource(flow.collector);\n if (!source) throw new Error('Lambda source not found in collector');\n\n // Create minimal Lambda context\n const lambdaContext = {\n awsRequestId: `test-${Date.now()}`,\n } as unknown as LambdaContext;\n\n // Call source.push with the raw Lambda event + context\n const pushFn = (\n source as unknown as {\n push: (...args: unknown[]) => Promise<LambdaResult>;\n }\n ).push;\n const lambdaResult = await pushFn(\n content as unknown as LambdaEvent,\n lambdaContext,\n );\n\n // Parse response\n let body: unknown;\n try {\n body = JSON.parse(lambdaResult.body || '{}');\n } catch {\n body = lambdaResult.body;\n }\n\n const headers: Record<string, string> = {};\n if (lambdaResult.headers) {\n for (const [k, v] of Object.entries(lambdaResult.headers)) {\n if (v !== undefined) headers[k] = String(v);\n }\n }\n\n return {\n statusCode: lambdaResult.statusCode,\n body,\n headers,\n };\n };\n\n return {\n get flow() {\n return flow;\n },\n trigger,\n };\n};\n\n/**\n * Legacy trigger — takes a source instance directly.\n * Preserved for CLI simulate path.\n */\nfunction trigger(source: {\n push: (event: LambdaEvent, context: LambdaContext) => Promise<LambdaResult>;\n}): (content: Content) => Promise<LambdaResult> {\n return async (content: Content) => {\n const lambdaEvent = { ...(content as Record<string, unknown>) };\n\n // Adapt body format: step examples may use `name`, source expects `event`\n if (lambdaEvent.body && typeof lambdaEvent.body === 'string') {\n const body = JSON.parse(lambdaEvent.body);\n if (body.name && !body.event) {\n lambdaEvent.body = JSON.stringify({\n ...body,\n event: body.name,\n name: undefined,\n });\n }\n }\n\n const context: LambdaContext = {\n awsRequestId: 'test-req',\n } as unknown as LambdaContext;\n\n return source.push(lambdaEvent as unknown as LambdaEvent, context);\n };\n}\n\nexport { createTrigger, trigger };\n"],"mappings":"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","names":["e","push","z","z","fn","trigger","e","k","v","settings","push","context"]}
|
package/dist/walkerOS.json
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$meta": {
|
|
3
3
|
"package": "@walkeros/server-source-aws",
|
|
4
|
-
"version": "3.0.
|
|
4
|
+
"version": "3.0.2",
|
|
5
5
|
"type": "source",
|
|
6
|
-
"platform":
|
|
6
|
+
"platform": [
|
|
7
|
+
"server"
|
|
8
|
+
],
|
|
7
9
|
"exports": {
|
|
8
10
|
"sourceLambda": "AWS Lambda event source"
|
|
9
11
|
},
|
|
@@ -109,6 +111,9 @@
|
|
|
109
111
|
}
|
|
110
112
|
},
|
|
111
113
|
"examples": {
|
|
114
|
+
"createTrigger": {
|
|
115
|
+
"$code": "async e=>{let n;return{get flow(){return n},trigger:()=>async t=>{if(!n){const t=await qe(e);n={collector:t.collector,elb:t.elb}}const o=function(e){for(const n of Object.values(e.sources||{}))if(\"lambda\"===n.type)return n}(n.collector);if(!o)throw new Error(\"Lambda source not found in collector\");const s={awsRequestId:`test-${Date.now()}`},r=o.push,i=await r(t,s);let a;try{a=JSON.parse(i.body||\"{}\")}catch(e){a=i.body}const c={};if(i.headers)for(const[e,n]of Object.entries(i.headers))void 0!==n&&(c[e]=String(n));return{statusCode:i.statusCode,body:a,headers:c}}}}"
|
|
116
|
+
},
|
|
112
117
|
"env": {
|
|
113
118
|
"push": {
|
|
114
119
|
"push": {
|
|
@@ -140,13 +145,16 @@
|
|
|
140
145
|
"$code": "()=>{}"
|
|
141
146
|
},
|
|
142
147
|
"scope": {
|
|
143
|
-
"$code": "()=>
|
|
148
|
+
"$code": "()=>m"
|
|
144
149
|
}
|
|
145
150
|
}
|
|
146
151
|
}
|
|
147
152
|
},
|
|
148
153
|
"step": {
|
|
149
154
|
"apiGatewayV1Post": {
|
|
155
|
+
"trigger": {
|
|
156
|
+
"type": "POST"
|
|
157
|
+
},
|
|
150
158
|
"in": {
|
|
151
159
|
"httpMethod": "POST",
|
|
152
160
|
"path": "/collect",
|
|
@@ -157,7 +165,7 @@
|
|
|
157
165
|
}
|
|
158
166
|
},
|
|
159
167
|
"queryStringParameters": null,
|
|
160
|
-
"body": "{\"
|
|
168
|
+
"body": "{\"event\":\"page view\",\"data\":{\"title\":\"Home\"}}",
|
|
161
169
|
"isBase64Encoded": false
|
|
162
170
|
},
|
|
163
171
|
"out": {
|
|
@@ -170,6 +178,9 @@
|
|
|
170
178
|
}
|
|
171
179
|
},
|
|
172
180
|
"lambdaGet": {
|
|
181
|
+
"trigger": {
|
|
182
|
+
"type": "GET"
|
|
183
|
+
},
|
|
173
184
|
"in": {
|
|
174
185
|
"version": "2.0",
|
|
175
186
|
"requestContext": {
|
|
@@ -192,6 +203,9 @@
|
|
|
192
203
|
}
|
|
193
204
|
},
|
|
194
205
|
"lambdaPost": {
|
|
206
|
+
"trigger": {
|
|
207
|
+
"type": "POST"
|
|
208
|
+
},
|
|
195
209
|
"in": {
|
|
196
210
|
"version": "2.0",
|
|
197
211
|
"requestContext": {
|
|
@@ -201,7 +215,7 @@
|
|
|
201
215
|
},
|
|
202
216
|
"requestId": "req-123"
|
|
203
217
|
},
|
|
204
|
-
"body": "{\"
|
|
218
|
+
"body": "{\"event\":\"page view\",\"data\":{\"title\":\"Home\"}}",
|
|
205
219
|
"isBase64Encoded": false
|
|
206
220
|
},
|
|
207
221
|
"out": {
|
|
@@ -213,6 +227,9 @@
|
|
|
213
227
|
"action": "view"
|
|
214
228
|
}
|
|
215
229
|
}
|
|
230
|
+
},
|
|
231
|
+
"trigger": {
|
|
232
|
+
"$code": "function Pe(e){return async n=>{const t={...n};if(t.body&&\"string\"==typeof t.body){const e=JSON.parse(t.body);e.name&&!e.event&&(t.body=JSON.stringify({...e,event:e.name,name:void 0}))}return e.push(t,{awsRequestId:\"test-req\"})}}"
|
|
216
233
|
}
|
|
217
234
|
}
|
|
218
235
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@walkeros/server-source-aws",
|
|
3
3
|
"description": "AWS server sources for walkerOS (Lambda, API Gateway, Function URLs)",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "4.0.0-next-1773967844643",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"module": "./dist/index.mjs",
|
|
@@ -21,14 +21,14 @@
|
|
|
21
21
|
"update": "npx npm-check-updates -u && npm update"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@walkeros/core": "
|
|
24
|
+
"@walkeros/core": "4.0.0-next-1773967844643"
|
|
25
25
|
},
|
|
26
26
|
"peerDependencies": {
|
|
27
27
|
"@types/aws-lambda": "^8.10.0"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@types/aws-lambda": "^8.10.159",
|
|
31
|
-
"@walkeros/collector": "
|
|
31
|
+
"@walkeros/collector": "4.0.0-next-1773967844643"
|
|
32
32
|
},
|
|
33
33
|
"repository": {
|
|
34
34
|
"url": "git+https://github.com/elbwalker/walkerOS.git",
|
|
@@ -41,7 +41,9 @@
|
|
|
41
41
|
},
|
|
42
42
|
"walkerOS": {
|
|
43
43
|
"type": "source",
|
|
44
|
-
"platform":
|
|
44
|
+
"platform": [
|
|
45
|
+
"server"
|
|
46
|
+
],
|
|
45
47
|
"docs": "https://www.walkeros.io/docs/sources/server/aws",
|
|
46
48
|
"exports": {
|
|
47
49
|
"sourceLambda": "AWS Lambda event source"
|