@walkeros/server-source-aws 4.0.0-next-1773967844643 → 4.0.0-next-1777882869103

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,6 +1,123 @@
1
1
  # @walkeros/server-source-aws
2
2
 
3
- ## 4.0.0-next-1773967844643
3
+ ## 4.0.0-next-1777882869103
4
+
5
+ ### Major Changes
6
+
7
+ - 93ea9c4: Event model v4: breaking changes to the `Event`, `Source`, and
8
+ `Entity` shapes.
9
+ - `event.id` is now a W3C span_id (16 lowercase hex chars), generated by the
10
+ collector. Reference: W3C Trace Context (W3C Recommendation, January 2020).
11
+ - `event.version`, `event.group`, `event.count` are removed.
12
+ - `source.type` is now the source kind (e.g. `browser`, `gtag`, `mcp`, `cli`).
13
+ New `source.platform` holds the runtime (`web` | `server` | `app` | ...).
14
+ - `source.id` and `source.previous_id` are removed.
15
+ - Browser source now sets `source.url` and `source.referrer`.
16
+ - MCP source sets `source.tool` per emission. CLI source sets
17
+ `source.command`.
18
+ - `Entity.nested` and `Entity.context` are now optional. Root `event.nested`
19
+ and `event.context` remain required.
20
+ - Each source self-registers via TypeScript module augmentation of `SourceMap`
21
+ in `@walkeros/core`.
22
+ - App-side coordination (`/workspaces/developer/app`) is a follow-up plan, not
23
+ part of this release. Telemetry from v4 CLI/MCP will not validate against
24
+ the existing app schema until that follow-up ships.
25
+ - `Mapping.Rule.skip` is renamed to `Mapping.Rule.silent`. Customer flow.json
26
+ configs using `skip: true` in mapping rules must rename to `silent: true`.
27
+ Hard cut: no legacy alias, the field is gone.
28
+
29
+ ### Patch Changes
30
+
31
+ - Updated dependencies [93ea9c4]
32
+ - Updated dependencies [465775c]
33
+ - Updated dependencies [942a7fe]
34
+ - Updated dependencies [cfc7469]
35
+ - Updated dependencies [8e06b1f]
36
+ - Updated dependencies [3d50dd6]
37
+ - Updated dependencies [1ef33d9]
38
+ - @walkeros/core@4.0.0-next-1777882869103
39
+
40
+ ## 3.4.2
41
+
42
+ ### Patch Changes
43
+
44
+ - @walkeros/core@3.4.2
45
+
46
+ ## 3.4.1
47
+
48
+ ### Patch Changes
49
+
50
+ - Updated dependencies [12adf24]
51
+ - Updated dependencies [75aa26b]
52
+ - @walkeros/core@3.4.1
53
+
54
+ ## 3.4.0
55
+
56
+ ### Minor Changes
57
+
58
+ - 724f97e: Migrate every step example in every walkerOS package to the
59
+ standardized `[callable, ...args][]` shape introduced in `@walkeros/core`.
60
+ Every step example's `out` is now an array of effect tuples whose first
61
+ element is the callable's public SDK name (`'gtag'`, `'analytics.track'`,
62
+ `'fbq'`, `'dataLayer.push'`, `'sendServer'`, `'fetch'`, `'trackClient.track'`,
63
+ `'amplitude.track'`, `'fs.writeFile'`, `'producer.send'`, `'client.xadd'`,
64
+ `'client.send'`, `'dataset.table.insert'`, etc.). Source examples use `'elb'`
65
+ as the callable; transformer examples use the reserved `'return'` keyword;
66
+ store examples use store-operation callables (`'get'`, `'set'`). Tests capture
67
+ real calls on each component's spy and assert against `example.out` directly —
68
+ the hardcoded `PACKAGE_CALLS` registry in the app is no longer consulted
69
+ (emptied; plan #3 removes it structurally).
70
+
71
+ ### Patch Changes
72
+
73
+ - Updated dependencies [74940cc]
74
+ - Updated dependencies [525f5d9]
75
+ - @walkeros/core@3.4.0
76
+
77
+ ## 3.3.1
78
+
79
+ ### Patch Changes
80
+
81
+ - @walkeros/core@3.3.1
82
+
83
+ ## 3.3.0
84
+
85
+ ### Patch Changes
86
+
87
+ - Updated dependencies [2849acb]
88
+ - Updated dependencies [08c365a]
89
+ - Updated dependencies [08c365a]
90
+ - Updated dependencies [08c365a]
91
+ - Updated dependencies [08c365a]
92
+ - @walkeros/core@3.3.0
93
+
94
+ ## 3.2.0
95
+
96
+ ### Minor Changes
97
+
98
+ - f47d251: Accept non-JSON POST bodies in all server sources
99
+
100
+ Server sources no longer reject non-JSON bodies with HTTP 400. Instead, they
101
+ push an empty event `{}` to the collector, enabling `source.before`
102
+ transformers to process raw input via ingest. Raw body is available through
103
+ ingest mapping (e.g., `"rawBody": "body"`).
104
+
105
+ ### Patch Changes
106
+
107
+ - Updated dependencies [eb865e1]
108
+ - Updated dependencies [c0a53f9]
109
+ - Updated dependencies [f007c9f]
110
+ - Updated dependencies [bf2dc5b]
111
+ - Updated dependencies [da0b640]
112
+ - @walkeros/core@3.2.0
113
+
114
+ ## 3.1.1
115
+
116
+ ### Patch Changes
117
+
118
+ - @walkeros/core@3.1.1
119
+
120
+ ## 3.1.0
4
121
 
5
122
  ### Minor Changes
6
123
 
@@ -14,7 +131,7 @@
14
131
  - Updated dependencies [bee8ba7]
15
132
  - Updated dependencies [966342b]
16
133
  - Updated dependencies [df990d4]
17
- - @walkeros/core@4.0.0-next-1773967844643
134
+ - @walkeros/core@3.1.0
18
135
 
19
136
  ## 3.0.2
20
137
 
package/dist/dev.d.mts CHANGED
@@ -82,6 +82,14 @@ declare namespace index$1 {
82
82
  export { type index$1_CorsOptions as CorsOptions, index$1_CorsOptionsSchema as CorsOptionsSchema, index$1_CorsOrigin as CorsOrigin, index$1_HttpMethod as HttpMethod, type index$1_Settings as Settings, index$1_SettingsSchema as SettingsSchema, index$1_settings as settings };
83
83
  }
84
84
 
85
+ declare module '@walkeros/core' {
86
+ interface SourceMap {
87
+ lambda: {
88
+ type: 'lambda';
89
+ platform: 'server';
90
+ };
91
+ }
92
+ }
85
93
  type LambdaEvent = APIGatewayProxyEvent | APIGatewayProxyEventV2;
86
94
  type LambdaResult = APIGatewayProxyResult;
87
95
  type LambdaContext = Context;
package/dist/dev.d.ts CHANGED
@@ -82,6 +82,14 @@ declare namespace index$1 {
82
82
  export { type index$1_CorsOptions as CorsOptions, index$1_CorsOptionsSchema as CorsOptionsSchema, index$1_CorsOrigin as CorsOrigin, index$1_HttpMethod as HttpMethod, type index$1_Settings as Settings, index$1_SettingsSchema as SettingsSchema, index$1_settings as settings };
83
83
  }
84
84
 
85
+ declare module '@walkeros/core' {
86
+ interface SourceMap {
87
+ lambda: {
88
+ type: 'lambda';
89
+ platform: 'server';
90
+ };
91
+ }
92
+ }
85
93
  type LambdaEvent = APIGatewayProxyEvent | APIGatewayProxyEventV2;
86
94
  type LambdaResult = APIGatewayProxyResult;
87
95
  type LambdaContext = Context;
package/dist/dev.js CHANGED
@@ -1 +1 @@
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
1
+ "use strict";var e,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyNames,s=Object.prototype.hasOwnProperty,r=(e,n)=>{for(var o in n)t(e,o,{get:n[o],enumerable:!0})},i={};r(i,{examples:()=>b,schemas:()=>a}),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||t(e,c,{get:()=>r[c],enumerable:!(a=n(r,c))||a.enumerable});return e})(t({},"__esModule",{value:!0}),e));var a={};r(a,{CorsOptionsSchema:()=>g,CorsOrigin:()=>f,HttpMethod:()=>d,SettingsSchema:()=>p,settings:()=>h});var c=require("@walkeros/core/dev"),u=require("@walkeros/core/dev"),l=require("@walkeros/core/dev"),d=l.z.enum(["GET","POST","PUT","PATCH","DELETE","OPTIONS","HEAD"]),f=l.z.union([l.z.string(),l.z.array(l.z.string()),l.z.literal("*")]),g=l.z.object({origin:f.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=u.z.object({cors:u.z.union([u.z.boolean(),g]).describe("CORS configuration: false = disabled, true = allow all origins, object = custom configuration").default(!0),timeout:u.z.number().int().positive().max(9e5).describe("Request timeout in milliseconds (max: 900000 for Lambda)").default(3e4),enablePixelTracking:u.z.boolean().describe("Enable GET requests with 1x1 transparent GIF response for pixel tracking").default(!0),healthPath:u.z.string().describe("Health check endpoint path (e.g., /health)").default("/health")}),h=(0,c.zodToSchema)(p),b={};r(b,{createTrigger:()=>le,env:()=>y,step:()=>O,trigger:()=>de});var y={};r(y,{push:()=>k});var m=()=>()=>Promise.resolve({ok:!0}),v=()=>{},w={error:v,warn:v,info:v,debug:v,throw:e=>{throw"string"==typeof e?new Error(e):e},json:v,scope:()=>w},k={get push(){return m()},get command(){return m()},get elb(){return m()},logger:w},O={};r(O,{apiGatewayV1Post:()=>C,lambdaGet:()=>q,lambdaPost:()=>x});var x={title:"Lambda POST",description:"An API Gateway v2 HTTP POST with a JSON body is converted into a walker elb event.",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:[["elb",{name:"page view",data:{title:"Home"}}]]},C={title:"API Gateway v1 POST",description:"A REST API Gateway v1 POST request with a JSON body is converted into a walker elb event.",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:[["elb",{name:"page view",data:{title:"Home"}}]]},q={title:"Lambda GET",description:"An API Gateway v2 HTTP GET with query parameters is parsed into an elb event payload.",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:[["elb",{e:"page view",d:'{"title":"Home"}'}]]},A=require("@walkeros/core"),j=require("@walkeros/core"),S=require("@walkeros/core"),P=require("@walkeros/core"),I=require("@walkeros/core"),T=require("@walkeros/core"),E=require("@walkeros/core"),D=require("@walkeros/core"),H=require("@walkeros/core"),R=require("@walkeros/core"),N=require("@walkeros/core"),$=require("@walkeros/core"),_={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 z(e,t){return e.storeId&&t.stores[e.storeId]?t.stores[e.storeId]:t.stores.__cache}function G(e){const t={};for(const[n,o]of Object.entries(e)){const e=o.config?.next;e&&!(0,E.isRouteArray)(e)?t[n]={next:e}:t[n]={}}return t}function M(e,t){const n=e.config||{},o=e[t];return void 0!==o?{config:{...n,[t]:o},chainValue:o}:{config:n,chainValue:void 0}}function L(e,t={}){if(!e)return[];if(Array.isArray(e))return e;const n=[],o=new Set;let s=e;for(;s&&t[s]&&!o.has(s);){o.add(s),n.push(s);const e=t[s].next;if(Array.isArray(e)){n.push(...e);break}s=e}return n}async function U(e,t,n){if(t.init&&!t.config.init){const o=t.type||"unknown",s=e.logger.scope(`transformer:${o}`),r={collector:e,logger:s,id:n,ingest:(0,E.createIngest)(n),config:t.config,env:F(t.config.env)};s.debug("init");const i=await(0,E.useHooks)(t.init,"TransformerInit",e.hooks,e.logger)(r);if(!1===i)return!1;t.config={...i||t.config,env:i?.env||t.config.env,init:!0},s.debug("init done")}return!0}async function B(e,t,n,o,s,r){const i=t.type||"unknown",a=e.logger.scope(`transformer:${i}`),c={collector:e,logger:a,id:n,ingest:s,config:t.config,env:{...F(t.config.env),...r?{respond:r}:{}}};a.debug("push",{event:o.name});const u=await(0,E.useHooks)(t.push,"TransformerPush",e.hooks,e.logger)(o,c);return a.debug("push done"),u}async function J(e,t,n,o,s,r,i){i&&s?._meta&&(s._meta.chainPath=i);let a=o,c=r;for(const o of n){const r=t[o];if(!r){e.logger.warn(`Transformer not found: ${o}`);continue}if(s&&s._meta&&s._meta.path.length>256)return e.logger.error(`Max path length exceeded at ${o}`),{event:null,respond:c};if(s&&s._meta&&(s._meta.hops++,s._meta.path.push(o)),!await(0,E.tryCatchAsync)(U)(e,r,o))return e.logger.error(`Transformer init failed: ${o}`),{event:null,respond:c};if(i&&void 0!==r.config?.chainMocks?.[i]){const t=r.config.chainMocks[i];e.logger.scope(`transformer:${r.type||"unknown"}`).debug("chainMock",{chain:i}),a=t;continue}if(void 0!==r.config?.mock){e.logger.scope(`transformer:${r.type||"unknown"}`).debug("mock"),a=r.config.mock;continue}if(r.config?.disabled)continue;const u=r.config?.cache,l=u?(0,E.compileCache)(u):void 0,d=l?z(l,e):void 0;let f;if(l&&d){const e=(0,E.buildCacheContext)(s,a),t=(0,E.checkCache)(l,d,e,`t:${o}`);if("HIT"===t?.status&&t.value){if(a=t.value,l.full)return{event:a,respond:c};continue}"MISS"===t?.status&&(f={key:t.key,ttl:t.rule.ttl})}const g=r.config.before;if(g){const n=L("string"==typeof g||Array.isArray(g)&&!(0,E.isRouteArray)(g)?g:(0,E.resolveNext)((0,E.compileNext)(g),(0,E.buildCacheContext)(s,a))||void 0,G(t));if(n.length>0){const o=await J(e,t,n,a,s,c,i);if(null===o.event)return{event:null,respond:o.respond??c};o.respond&&(c=o.respond),a=Array.isArray(o.event)?o.event[0]:o.event}}const p=await(0,E.tryCatchAsync)(B,t=>(e.logger.scope(`transformer:${r.type||"unknown"}`).error("Push failed",{error:t}),!1))(e,r,o,a,s,c);if(!1===p)return{event:null,respond:c};if(Array.isArray(p)){const r=n.slice(n.indexOf(o)+1),u=await Promise.all(p.map(async n=>{const o=n.event||a,u=s?{...s,_meta:{...s._meta,path:[...s._meta.path]}}:(0,E.createIngest)("unknown");if(n.next){let s=n.next;if((0,E.isRouteArray)(n.next)){const e=(0,E.compileNext)(n.next);s=(0,E.resolveNext)(e,(0,E.buildCacheContext)(u,o))}if(s){const n=L(s,G(t));if(n.length>0)return J(e,t,n,o,u,c,i)}return{event:o,respond:c}}return r.length>0?J(e,t,r,o,u,c,i):{event:o,respond:c}}));let l=c;const d=[];for(const e of u.flat())if(null!==e)if(e&&"object"==typeof e&&"event"in e){const t=e;if(t.respond&&(l=t.respond),null===t.event)continue;Array.isArray(t.event)?d.push(...t.event):d.push(t.event)}else d.push(e);return 0===d.length?{event:null,respond:l}:1===d.length?{event:d[0],respond:l}:{event:d,respond:l}}if(p&&"object"==typeof p){const{event:n,respond:o,next:r}=p;if(o&&(c=o),r){let o=r;if((0,E.isRouteArray)(r)){const e=(0,E.compileNext)(r);if(o=(0,E.resolveNext)(e,(0,E.buildCacheContext)(s,a)),!o){n&&(a=n);continue}}const u=L(o,G(t));return u.length>0?J(e,t,u,n||a,s,c,i):(e.logger.warn(`Branch target not found: ${JSON.stringify(r)}`),{event:null,respond:c})}n&&(a=n)}if(f&&d&&(0,E.storeCache)(d,f.key,a,f.ttl),(!p||"object"==typeof p&&!p.next)&&r.config.next&&(0,E.isRouteArray)(r.config.next)){const n=r.config.next,o=(0,E.compileNext)(n),u=(0,E.resolveNext)(o,(0,E.buildCacheContext)(s,a));if(u){const n=L(u,G(t));if(n.length>0)return J(e,t,n,a,s,c,i)}return{event:a,respond:c}}}return{event:a,respond:c}}function F(e){return e&&(0,E.isObject)(e)?e:{}}async function V(e,t,n){const{code:o,config:s={},env:r={},primary:i,next:a,before:c,cache:u}=n;let l,d=(0,T.createIngest)(t);const f=u?(0,T.compileCache)({...u,full:u.full??!0}):void 0,g=(0,T.compileNext)(a),p=Array.isArray(a)&&(0,T.isRouteArray)(a)||!g?void 0:L((0,T.resolveNext)(g),G(e.transformers)),h=(0,T.compileNext)(c),b=Array.isArray(c)&&(0,T.isRouteArray)(c)||!h?void 0:L((0,T.resolveNext)(h),G(e.transformers)),y=e.logger.scope("source").scope(t),m={push:async(n,o={})=>{let r,i=n;const a=b??(h?L((0,T.resolveNext)(h,(0,T.buildCacheContext)(d)),G(e.transformers)):[]);if(a.length>0&&e.transformers&&Object.keys(e.transformers).length>0){const n=await J(e,e.transformers,a,i,d,l,`source.${t}.before`);if(null===n.event)return{ok:!0};n.respond&&(l=n.respond),i=Array.isArray(n.event)?n.event[0]:n.event}if(f){const n=z(f,e);if(n){const o=(0,T.buildCacheContext)(d),s=(0,T.checkCache)(f,n,o,`s:${t}`);if(s){if("HIT"===s.status&&void 0!==s.value&&f.full){let t=s.value;return s.rule.update&&(t=await(0,T.applyUpdate)(t,s.rule.update,{...o,cache:{status:"HIT"}},e)),l?.(t),{ok:!0}}if("MISS"===s.status&&f.full&&l){const t=l,i=s.rule.update,a={...o,cache:{status:"MISS"}},c=s.key,u=s.rule.ttl;l=o=>{(0,T.storeCache)(n,c,o,u),i?r=(async()=>{const n=await(0,T.applyUpdate)(o,i,a,e);t(n)})():t(o)}}"MISS"!==s.status||f.full||(0,T.storeCache)(n,s.key,!0,s.rule.ttl)}}}const c=p??(g?L((0,T.resolveNext)(g,(0,T.buildCacheContext)(d)),G(e.transformers)):[]),u=await e.push(i,{...o,id:t,ingest:d,respond:l,mapping:s,preChain:c});return r&&await r,u},command:e.command,sources:e.sources,elb:e.sources.elb.push,logger:y,...r},v={collector:e,logger:y,id:t,config:s,env:m,setIngest:async n=>{if(!s.ingest)return void(d=(0,T.createIngest)(t));const o=await(0,T.getMappingValue)(n,s.ingest,{collector:e}),r=(0,T.createIngest)(t);d={...r,...o,_meta:r._meta}},setRespond:e=>{l=e}},w=await(0,T.tryCatchAsync)(o)(v);if(!w)return;const k=w.type||"unknown",O=e.logger.scope(k).scope(t);return m.logger=O,i&&(w.config={...w.config,primary:i}),w}function W(e,t){return{collector:e,logger:e.logger.scope("on").scope(String(t))}}function K(e,t,n,o,s){if(!t.on)return;const r=t.type||"unknown",i=e.logger.scope(r).scope("on").scope(o),a={collector:e,logger:i,id:n,config:t.config,data:s,env:se(t.env,t.config.env)};(0,I.tryCatch)(t.on)(o,a)}function Q(e,t,n,o){let s;switch(t){case _.Consent:s=o||e.consent;break;case _.Session:s=e.session;break;case _.User:s=o||e.user;break;case _.Custom:s=o||e.custom;break;case _.Globals:s=o||e.globals;break;case _.Config:s=o||e.config;break;case _.Ready:case _.Run:default:s=void 0}if(n.length)switch(t){case _.Consent:!function(e,t,n){const o=n||e.consent,s=W(e,_.Consent);t.forEach(e=>{Object.keys(o).filter(t=>t in e).forEach(t=>{(0,I.tryCatch)(e[t])(o,s)})})}(e,n,o);break;case _.Ready:!function(e,t){if(!e.allowed)return;const n=W(e,_.Ready);t.forEach(e=>{(0,I.tryCatch)(e)(void 0,n)})}(e,n);break;case _.Run:!function(e,t){if(!e.allowed)return;const n=W(e,_.Run);t.forEach(e=>{(0,I.tryCatch)(e)(void 0,n)})}(e,n);break;case _.Session:!function(e,t){if(!e.session)return;const n=W(e,_.Session);t.forEach(t=>{(0,I.tryCatch)(t)(e.session,n)})}(e,n);break;default:{const o=W(e,t);n.forEach(e=>{"function"==typeof e&&(0,I.tryCatch)(e)(s,o)});break}}}function X(e,t,n,o){if(!e)return[];if(t){const e=(0,S.resolveNext)(t,(0,S.buildCacheContext)(o));return e?L(e,G(n)):[]}return L(e,G(n))}async function Y(e,t,n){const{code:o,config:s={},env:r={},before:i,next:a,cache:c}=t;if(!(0,S.isFunction)(o.push))return ne({ok:!1,failed:{invalid:{type:"invalid",error:"Destination code must have a push method"}}});const u=n||s||{init:!1};let l=i?{...u,before:i}:{...u};a&&(l={...l,next:a}),c&&(l={...l,cache:c});const d={...o,config:l,env:se(o.env,r)};let f=d.config.id;if(!f)do{f=(0,S.getId)(5,"abcdefghijklmnopqrstuvwxyz")}while(e.destinations[f]);return e.destinations[f]=d,!1!==d.config.queue&&(d.queuePush=[...e.queue]),Z(e,void 0,{},{[f]:d})}async function Z(e,t,n={},o){const{allowed:s,consent:r,globals:i,user:a}=e;if(!s)return ne({ok:!1});t&&(e.queue.push(t),e.status.in++),o||(o=e.destinations);const c=await Promise.all(Object.entries(o||{}).map(async([o,s])=>{if(s.config.disabled)return{id:o,destination:s,skipped:!0};let c=(s.queuePush||[]).map(e=>({...e,consent:r}));s.queuePush=[],t&&c.push((0,S.clone)(t));const u=n.ingest?{...n.ingest,_meta:{...n.ingest._meta,path:[...n.ingest._meta.path]}}:(0,S.createIngest)("unknown");if(!c.length&&!s.queueOn?.length)return{id:o,destination:s,skipped:!0};if(!c.length&&s.queueOn?.length){const t=await(0,S.tryCatchAsync)(ee)(e,s,o);return{id:o,destination:s,skipped:!t}}const l=[],d=c.filter(e=>{const t=(0,S.getGrantedConsent)(s.config.consent,r,e.consent);return!t||(e.consent=t,l.push(e),!1)});if(s.queuePush.push(...d),!l.length)return{id:o,destination:s,queue:c};if(!await(0,S.tryCatchAsync)(ee)(e,s,o))return{id:o,destination:s,queue:c};let f,g;s.dlq||(s.dlq=[]);const p=s.config.before,h=X(p,p&&(0,S.isRouteArray)(p)?(0,S.compileNext)(p):void 0,e.transformers,u),b=s.config.next,y=b&&(0,S.isRouteArray)(b)?(0,S.compileNext)(b):void 0,m=s.config?.cache,v=m?(0,S.compileCache)(m):void 0,w=v?z(v,e):void 0;let k=0;return await Promise.all(l.map(async t=>{let r;if(t.globals=(0,S.assign)(i,t.globals),t.user=(0,S.assign)(a,t.user),v?.full&&w){const e=(0,S.buildCacheContext)(u,t),n=(0,S.checkCache)(v,w,e,`d:${o}`);if("HIT"===n?.status)return t;"MISS"===n?.status&&(r={key:n.key,ttl:n.rule.ttl})}let c=t,l=n.respond;if(h.length>0&&e.transformers&&Object.keys(e.transformers).length>0){const s=await J(e,e.transformers,h,t,u,n.respond,`destination.${o}.before`);if(null===s.event)return t;s.respond&&(l=s.respond),c=Array.isArray(s.event)?s.event[0]:s.event}if(v&&!v.full&&w){const e=(0,S.buildCacheContext)(u,c),n=(0,S.checkCache)(v,w,e,`d:${o}`);if("HIT"===n?.status)return t;"MISS"===n?.status&&(r={key:n.key,ttl:n.rule.ttl})}const d=Date.now();let p=!1;const m=await(0,S.tryCatchAsync)(te,t=>{const n=s.type||"unknown";e.logger.scope(n).error("Push failed",{error:t,event:c.name}),f=t,p=!0,s.dlq.push([c,t])})(e,s,o,c,u,l);if(k+=Date.now()-d,r&&w&&void 0===s.config.mock&&(0,S.storeCache)(w,r.key,m??!0,r.ttl),void 0!==m&&(g=m),!p&&b){void 0!==m&&(u._response=m);const t=X(b,y,e.transformers,u);if(t.length>0&&e.transformers&&Object.keys(e.transformers).length>0){const n=await J(e,e.transformers,t,c,u,l,`destination.${o}.next`);n.respond&&(l=n.respond)}}return t})),{id:o,destination:s,error:f,response:g,totalDuration:k}})),u={},l={},d={};for(const t of c){if(t.skipped)continue;const n={type:t.destination.type||"unknown",data:t.response};e.status.destinations[t.id]||(e.status.destinations[t.id]={count:0,failed:0,duration:0});const o=e.status.destinations[t.id],s=Date.now();t.error?(n.error=t.error,d[t.id]=n,o.failed++,o.lastAt=s,o.duration+=t.totalDuration||0,e.status.failed++):t.queue&&t.queue.length?l[t.id]=n:(u[t.id]=n,o.count++,o.lastAt=s,o.duration+=t.totalDuration||0,e.status.out++)}return ne({event:t,...Object.keys(u).length&&{done:u},...Object.keys(l).length&&{queued:l},...Object.keys(d).length&&{failed:d}})}async function ee(e,t,n){if(t.init&&!t.config.init){const o=t.type||"unknown",s=e.logger.scope(o),r={collector:e,logger:s,id:n,config:t.config,env:se(t.env,t.config.env)};s.debug("init");const i=await(0,S.useHooks)(t.init,"DestinationInit",e.hooks,e.logger)(r);if(!1===i)return i;if(t.config={...i||t.config,init:!0},t.queueOn?.length){const o=t.queueOn;t.queueOn=[];for(const{type:s,data:r}of o)K(e,t,n,s,r)}s.debug("init done")}return!0}async function te(e,t,n,o,s,r){const{config:i}=t,a=await(0,S.processEventMapping)(o,i,e);if(a.ignore)return!1;const c=t.type||"unknown",u=e.logger.scope(c),l={collector:e,logger:u,id:n,config:i,data:a.data,rule:a.mapping,ingest:s,env:{...se(t.env,i.env),...r?{respond:r}:{}}};if(void 0!==i.mock)return u.debug("mock",{event:a.event.name}),i.mock;const d=a.mapping,f=a.mappingKey||"* *";if(!d?.batch||!t.pushBatch||void 0!==i.mock){u.debug("push",{event:a.event.name});const n=await(0,S.useHooks)(t.push,"DestinationPush",e.hooks,e.logger)(a.event,l);return u.debug("push done"),n}{if(t.batches=t.batches||{},!t.batches[f]){const o={key:f,events:[],data:[]};t.batches[f]={batched:o,batchFn:(0,S.debounce)(()=>{const o=t.batches[f].batched,a={collector:e,logger:u,id:n,config:i,data:void 0,rule:d,ingest:s,env:{...se(t.env,i.env),...r?{respond:r}:{}}};u.debug("push batch",{events:o.events.length}),(0,S.useHooks)(t.pushBatch,"DestinationPushBatch",e.hooks,e.logger)(o,a),u.debug("push batch done"),o.events=[],o.data=[]},d.batch)}}const o=t.batches[f];o.batched.events.push(a.event),(0,S.isDefined)(a.data)&&o.batched.data.push(a.data),o.batchFn()}return!0}function ne(e){return{ok:!e?.failed,...e}}function oe(e){const{code:t,config:n={},env:o={},cache:s}=e,{config:r}=M(e,"before"),{config:i}=M({...e,config:r},"next"),a={...t.config,...n,...i};s&&(a.cache=s);const c=se(t.env,o);return{...t,config:a,env:c}}function se(e,t){return e||t?t?e&&(0,S.isObject)(e)&&(0,S.isObject)(t)?{...e,...t}:t:e:{}}async function re(e,t,n){const o=Object.entries(e).map(async([e,o])=>{const s=o.destroy;if(!s)return;const r=o.type||"unknown",i=n.scope(r),a={id:e,config:o.config,env:o.env??{},logger:i};try{await Promise.race([s(a),new Promise((n,o)=>setTimeout(()=>o(new Error(`${t} '${e}' destroy timed out`)),5e3))])}catch(n){i.error(`${t} '${e}' destroy failed: ${n}`)}});await Promise.allSettled(o)}async function ie(e,t,n,o){let s,r,i=!1;switch(t){case _.Config:(0,H.isObject)(n)&&((0,D.assign)(e.config,n,{shallow:!1}),r=n,i=!0);break;case _.Consent:if((0,H.isObject)(n)){const{update:t}=function(e,t){const n={};return Object.entries(t).forEach(([e,t])=>{n[e]=!!t}),e.consent=(0,A.assign)(e.consent,n),{update:n}}(e,n);r=t,i=!0}break;case _.Custom:(0,H.isObject)(n)&&(e.custom=(0,D.assign)(e.custom,n),r=n,i=!0);break;case _.Destination:(0,H.isObject)(n)&&("code"in n&&(0,H.isObject)(n.code)?s=await Y(e,n,o):(0,D.isFunction)(n.push)&&(s=await Y(e,{code:n},o)));break;case _.Globals:(0,H.isObject)(n)&&(e.globals=(0,D.assign)(e.globals,n),r=n,i=!0);break;case _.On:(0,D.isString)(n)&&await async function(e,t,n){const o=e.on,s=o[t]||[],r=(0,P.isArray)(n)?n:[n];r.forEach(e=>{s.push(e)}),o[t]=s,Q(e,t,r)}(e,n,o);break;case _.Ready:i=!0;break;case _.Run:s=await async function(e,t){return e.allowed=!0,e.timing=Date.now(),t&&(t.consent&&(e.consent=(0,D.assign)(e.consent,t.consent)),t.user&&(e.user=(0,D.assign)(e.user,t.user)),t.globals&&(e.globals=(0,D.assign)(e.config.globalsStatic||{},t.globals)),t.custom&&(e.custom=(0,D.assign)(e.custom,t.custom))),Object.values(e.destinations).forEach(e=>{e.queuePush=[]}),e.queue=[],e.round++,await Z(e)}(e,n),i=!0;break;case _.Session:i=!0;break;case _.Shutdown:await async function(e){const t=e.logger;await re(e.sources,"source",t),await re(e.destinations,"destination",t),await re(e.transformers,"transformer",t),await re(e.stores,"store",t)}(e);break;case _.User:(0,H.isObject)(n)&&((0,D.assign)(e.user,n,{shallow:!1}),r=n,i=!0)}return i&&(await async function(e,t,n,o){let s,r=n||[];switch(n||(r=e.on[t]||[]),t){case _.Consent:s=o||e.consent;break;case _.Session:s=e.session;break;case _.User:s=o||e.user;break;case _.Custom:s=o||e.custom;break;case _.Globals:s=o||e.globals;break;case _.Config:s=o||e.config;break;case _.Ready:case _.Run:default:s=void 0}let i=!1;for(const n of Object.values(e.sources))n.on&&!1===await(0,I.tryCatchAsync)(n.on)(t,s)&&(i=!0);return Object.entries(e.destinations).forEach(([n,o])=>{if(o.on){if(!o.config.init)return o.queueOn=o.queueOn||[],void o.queueOn.push({type:t,data:s});K(e,o,n,t,s)}}),(Object.keys(e.pending.sources).length>0||Object.keys(e.pending.destinations).length>0)&&await async function(e,t){for(const[n,o]of Object.entries(e.pending.sources)){if(!e.pending.sources[n]||e.sources[n])continue;const s=o.config?.require;if(!s)continue;const r=s.indexOf(t);if(-1===r)continue;if(s.splice(r,1),s.length>0)continue;delete e.pending.sources[n];const i=await V(e,n,o);i&&(e.sources[n]=i)}for(const[n,o]of Object.entries(e.pending.destinations)){if(!e.pending.destinations[n]||e.destinations[n])continue;const s=o.config?.require;if(!s)continue;const r=s.indexOf(t);if(-1===r)continue;if(s.splice(r,1),s.length>0)continue;delete e.pending.destinations[n];const i=oe(o);!1!==i.config.queue&&(i.queuePush=[...e.queue]),e.destinations[n]=i}}(e,t),Q(e,t,r,o),!i}(e,t,void 0,r),s=await Z(e)),s||ne({ok:!0})}function ae(e,t){if(!t.name)throw new Error("Event name is required");const[n,o]=t.name.split(" ");if(!n||!o)throw new Error("Event name is invalid");const{timestamp:s=Date.now(),name:r=`${n} ${o}`,data:i={},context:a={},globals:c=e.globals,custom:u={},user:l=e.user,nested:d=[],consent:f=e.consent,id:g=(0,D.getSpanId)(),trigger:p="",entity:h=n,action:b=o,timing:y=0,source:m={type:"collector",schema:"4"}}=t;return{name:r,data:i,context:a,globals:c,custom:u,user:l,nested:d,consent:f,id:g,trigger:p,entity:h,action:b,timestamp:s,timing:y,source:m}}async function ce(e){const t=(0,j.assign)({globalsStatic:{},sessionStatic:{},run:!0},e,{merge:!1,extend:!1}),n={level:e.logger?.level,handler:e.logger?.handler},o=(0,j.createLogger)(n),s={...t.globalsStatic,...e.globals},r={allowed:!1,config:t,consent:e.consent||{},custom:e.custom||{},destinations:{},transformers:{},stores:{},globals:s,hooks:e.hooks||{},logger:o,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||{},sources:{},pending:{sources:{},destinations:{}},push:void 0,command:void 0};var i,a;r.push=function(e,t){return(0,R.useHooks)(async(n,o={})=>await(0,R.tryCatchAsync)(async()=>{const s=Date.now(),{id:r,ingest:i,respond:a,mapping:c,preChain:u,include:l,exclude:d}=o;let f=a,g=n;const p=l||d?function(e,t,n){let o=e;return t&&(o=Object.fromEntries(Object.entries(o).filter(([e])=>t.includes(e)))),n&&(o=Object.fromEntries(Object.entries(o).filter(([e])=>!n.includes(e)))),o}(e.destinations,l,d):void 0,h=i??(0,R.createIngest)(r||"unknown");if(c){const t=await(0,R.processEventMapping)(g,c,e);if(t.ignore)return ne({ok:!0});if(c.consent&&!(0,R.getGrantedConsent)(c.consent,e.consent,t.event.consent))return ne({ok:!0});g=t.event}if(u?.length&&e.transformers&&Object.keys(e.transformers).length>0){const n=await J(e,e.transformers,u,g,h,f,r?`source.${r}.next`:void 0);if(null===n.event)return ne({ok:!0});if(n.respond&&(f=n.respond),Array.isArray(n.event)){const o=await Promise.all(n.event.map(async n=>{const o=t(n),s=ae(e,o);return Z(e,s,{id:r,ingest:h,respond:f},p)}));if(r){e.status.sources[r]||(e.status.sources[r]={count:0,duration:0});const t=e.status.sources[r];t.count+=n.event.length,t.lastAt=Date.now(),t.duration+=Date.now()-s}return o[0]??ne({ok:!0})}g=n.event}const b=t(g),y=ae(e,b),m=await Z(e,y,{id:r,ingest:h,respond:f},p);if(r){e.status.sources[r]||(e.status.sources[r]={count:0,duration:0});const t=e.status.sources[r];t.count++,t.lastAt=Date.now(),t.duration+=Date.now()-s}return m},()=>ne({ok:!1}))(),"Push",e.hooks,e.logger)}(r,e=>({timing:Math.round((Date.now()-r.timing)/10)/100,source:{type:"collector",schema:"4",version:"4.0.0-next-1777882869103"},...e})),r.command=(i=r,a=ie,(0,N.useHooks)(async(e,t,n)=>await(0,N.tryCatchAsync)(async()=>await a(i,e,t,n),()=>ne({ok:!1}))(),"Command",i.hooks,i.logger));const c=e.stores||{};if(r.stores=await async function(e,t={}){const n={};for(const[o,s]of Object.entries(t)){const{code:t,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 t(c),l=u.get,d=u.set,f=u.delete;u.get=(0,$.useHooks)(l,"StoreGet",e.hooks,e.logger),u.set=(0,$.useHooks)(d,"StoreSet",e.hooks,e.logger),u.delete=(0,$.useHooks)(f,"StoreDelete",e.hooks,e.logger),n[o]=u}return n}(r,c),function(e,t,n){const o=new Map;for(const[n,s]of Object.entries(e))t[n]&&o.set(s,t[n]);if(0!==o.size)for(const e of[n.transformers,n.destinations,n.sources])if(e)for(const t of Object.values(e))s(t.env);function s(e){if(e)for(const[t,n]of Object.entries(e))if("object"==typeof n&&null!==n){const s=o.get(n);s&&(e[t]=s)}}}(c,r.stores,e),!r.stores.__cache){const e=new Map;r.stores.__cache={type:"memory",config:{},get:t=>{const n=e.get(t);if(n){if(!(n.expires&&Date.now()>n.expires))return n.value;e.delete(t)}},set:(t,n,o)=>{e.set(t,{value:n,expires:o?Date.now()+o:void 0})},delete:t=>{e.delete(t)}}}return r.destinations=await async function(e,t={}){const n={};for(const[o,s]of Object.entries(t))s.config?.require?.length?e.pending.destinations[o]=s:n[o]=oe(s);return n}(r,e.destinations||{}),r.transformers=await async function(e,t={}){const n={};for(const[o,s]of Object.entries(t)){const{code:t,env:r={}}=s,{config:i}=M(s,"before"),{config:a}=M({...s,config:i},"next"),c=Object.keys(r).length>0?{...a,env:r}:a,{cache:u}=s,l=u?{...c,cache:u}:c,d=e.logger.scope("transformer").scope(o),f={collector:e,logger:d,id:o,ingest:(0,E.createIngest)(o),config:l,env:r},g=await t(f);n[o]=g}return n}(r,e.transformers||{}),r}async function ue(e){e=e||{};const t=await ce(e),n=(o=t,{type:"elb",config:{},push:async(e,t,n,s,r,i)=>{if("string"==typeof e&&e.startsWith("walker ")){const s=e.replace("walker ","");return o.command(s,t,n)}let a;if("string"==typeof e)a={name:e},t&&"object"==typeof t&&!Array.isArray(t)&&(a.data=t);else{if(!e||"object"!=typeof e)return ne({ok:!1});a=e,t&&"object"==typeof t&&!Array.isArray(t)&&(a.data={...a.data||{},...t})}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;t.sources.elb=n;const s=await async function(e,t={}){const n={};for(const[o,s]of Object.entries(t)){const{config:t={}}=s;if(t.require&&t.require.length>0){e.pending.sources[o]=s;continue}const r=await V(e,o,s);r&&(n[o]=r)}return n}(t,e.sources||{});Object.assign(t.sources,s);const{consent:r,user:i,globals:a,custom:c}=e;r&&await t.command("consent",r),i&&await t.command("user",i),a&&Object.assign(t.globals,a),c&&Object.assign(t.custom,c),t.config.run&&await t.command("run");let u=n.push;const l=Object.values(t.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:t,elb:u}}var le=async e=>{let t;return{get flow(){return t},trigger:()=>async n=>{if(!t){const n=await ue(e);t={collector:n.collector,elb:n.elb}}const o=function(e){for(const t of Object.values(e.sources||{}))if("lambda"===t.type)return t}(t.collector);if(!o)throw new Error("Lambda source not found in collector");const s={awsRequestId:`test-${Date.now()}`},r=o.push,i=await r(n,s);let a;try{a=JSON.parse(i.body||"{}")}catch{a=i.body}const c={};if(i.headers)for(const[e,t]of Object.entries(i.headers))void 0!==t&&(c[e]=String(t));return{statusCode:i.statusCode,body:a,headers:c}}}};function de(e){return async t=>{const n={...t};if(n.body&&"string"==typeof n.body){const e=JSON.parse(n.body);e.name&&!e.event&&(n.body=JSON.stringify({...e,event:e.name,name:void 0}))}return e.push(n,{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","../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"]}
1
+ {"version":3,"sources":["../src/dev.ts","../src/lambda/schemas/index.ts","../src/lambda/schemas/settings.ts","../src/lambda/schemas/primitives.ts","../src/lambda/examples/index.ts","../src/lambda/examples/env.ts","../src/lambda/examples/step.ts","../src/lambda/examples/trigger.ts"],"sourcesContent":["export * as schemas from './lambda/schemas';\nexport * as examples from './lambda/examples';\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","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","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 title: 'Lambda POST',\n description:\n 'An API Gateway v2 HTTP POST with a JSON body is converted into a walker elb event.',\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 [\n 'elb',\n {\n name: 'page view',\n data: { title: 'Home' },\n },\n ],\n ],\n};\n\nexport const apiGatewayV1Post: Flow.StepExample = {\n title: 'API Gateway v1 POST',\n description:\n 'A REST API Gateway v1 POST request with a JSON body is converted into a walker elb event.',\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 [\n 'elb',\n {\n name: 'page view',\n data: { title: 'Home' },\n },\n ],\n ],\n};\n\nexport const lambdaGet: Flow.StepExample = {\n title: 'Lambda GET',\n description:\n 'An API Gateway v2 HTTP GET with query parameters is parsed into an elb event payload.',\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 [\n 'elb',\n {\n e: 'page view',\n d: '{\"title\":\"Home\"}',\n },\n ],\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":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAAA,cAA4B;;;ACA5B,IAAAC,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;;;ADvBM,IAAM,eAAW,yBAAY,cAAc;;;AGVlD;AAAA;AAAA;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,OAAO;AAAA,EACP,aACE;AAAA,EACF,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;AAAA,MACE;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM,EAAE,OAAO,OAAO;AAAA,MACxB;AAAA,IACF;AAAA,EACF;AACF;AAEO,IAAM,mBAAqC;AAAA,EAChD,OAAO;AAAA,EACP,aACE;AAAA,EACF,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;AAAA,MACE;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM,EAAE,OAAO,OAAO;AAAA,MACxB;AAAA,IACF;AAAA,EACF;AACF;AAEO,IAAM,YAA8B;AAAA,EACzC,OAAO;AAAA,EACP,aACE;AAAA,EACF,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;AAAA,MACE;AAAA,MACA;AAAA,QACE,GAAG;AAAA,QACH,GAAG;AAAA,MACL;AAAA,IACF;AAAA,EACF;AACF;A;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AClEA,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,QAAQ;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,SAAAF;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":["import_dev","import_dev","trigger","k","v"]}
package/dist/dev.mjs CHANGED
@@ -1 +1 @@
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
1
+ var e=Object.defineProperty,t=(t,n)=>{for(var o in n)e(t,o,{get:n[o],enumerable:!0})},n={};t(n,{CorsOptionsSchema:()=>c,CorsOrigin:()=>i,HttpMethod:()=>a,SettingsSchema:()=>u,settings:()=>l});import{zodToSchema as o}from"@walkeros/core/dev";import{z as s}from"@walkeros/core/dev";import{z as r}from"@walkeros/core/dev";var a=r.enum(["GET","POST","PUT","PATCH","DELETE","OPTIONS","HEAD"]),i=r.union([r.string(),r.array(r.string()),r.literal("*")]),c=r.object({origin:i.describe("Allowed origins (* for all, URL string, or array of URLs)").optional(),methods:r.array(a).describe("Allowed HTTP methods").optional(),headers:r.array(r.string()).describe("Allowed request headers").optional(),credentials:r.boolean().describe("Allow credentials (cookies, authorization headers)").optional(),maxAge:r.number().int().positive().describe("Preflight cache duration in seconds").optional()}),u=s.object({cors:s.union([s.boolean(),c]).describe("CORS configuration: false = disabled, true = allow all origins, object = custom configuration").default(!0),timeout:s.number().int().positive().max(9e5).describe("Request timeout in milliseconds (max: 900000 for Lambda)").default(3e4),enablePixelTracking:s.boolean().describe("Enable GET requests with 1x1 transparent GIF response for pixel tracking").default(!0),healthPath:s.string().describe("Health check endpoint path (e.g., /health)").default("/health")}),l=o(u),f={};t(f,{createTrigger:()=>Ze,env:()=>d,step:()=>b,trigger:()=>et});var d={};t(d,{push:()=>m});var g=()=>()=>Promise.resolve({ok:!0}),p=()=>{},h={error:p,warn:p,info:p,debug:p,throw:e=>{throw"string"==typeof e?new Error(e):e},json:p,scope:()=>h},m={get push(){return g()},get command(){return g()},get elb(){return g()},logger:h},b={};t(b,{apiGatewayV1Post:()=>v,lambdaGet:()=>w,lambdaPost:()=>y});var y={title:"Lambda POST",description:"An API Gateway v2 HTTP POST with a JSON body is converted into a walker elb event.",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:[["elb",{name:"page view",data:{title:"Home"}}]]},v={title:"API Gateway v1 POST",description:"A REST API Gateway v1 POST request with a JSON body is converted into a walker elb event.",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:[["elb",{name:"page view",data:{title:"Home"}}]]},w={title:"Lambda GET",description:"An API Gateway v2 HTTP GET with query parameters is parsed into an elb event payload.",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:[["elb",{e:"page view",d:'{"title":"Home"}'}]]};import{assign as k}from"@walkeros/core";import{assign as O,createLogger as A}from"@walkeros/core";import{assign as S,buildCacheContext as x,clone as j,compileCache as q,checkCache as C,storeCache as P,compileNext as T,createIngest as E,debounce as I,getId as D,getGrantedConsent as $,isDefined as H,isFunction as R,isObject as _,isRouteArray as G,processEventMapping as M,resolveNext as N,tryCatchAsync as L,useHooks as B}from"@walkeros/core";import{isArray as J}from"@walkeros/core";import{tryCatch as U,tryCatchAsync as F}from"@walkeros/core";import{createIngest as z,getMappingValue as V,tryCatchAsync as W,compileNext as K,resolveNext as Q,isRouteArray as X,compileCache as Y,checkCache as Z,storeCache as ee,applyUpdate as te,buildCacheContext as ne}from"@walkeros/core";import{createIngest as oe,isObject as se,tryCatchAsync as re,useHooks as ae,compileNext as ie,resolveNext as ce,isRouteArray as ue,compileCache as le,checkCache as fe,storeCache as de,buildCacheContext as ge}from"@walkeros/core";import{assign as pe,getSpanId as he,isFunction as me,isString as be}from"@walkeros/core";import{isObject as ye}from"@walkeros/core";import{createIngest as ve,getGrantedConsent as we,processEventMapping as ke,tryCatchAsync as Oe,useHooks as Ae}from"@walkeros/core";import{useHooks as Se,tryCatchAsync as xe}from"@walkeros/core";import{useHooks as je}from"@walkeros/core";var qe={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 Ce(e,t){return e.storeId&&t.stores[e.storeId]?t.stores[e.storeId]:t.stores.__cache}function Pe(e){const t={};for(const[n,o]of Object.entries(e)){const e=o.config?.next;e&&!ue(e)?t[n]={next:e}:t[n]={}}return t}function Te(e,t){const n=e.config||{},o=e[t];return void 0!==o?{config:{...n,[t]:o},chainValue:o}:{config:n,chainValue:void 0}}function Ee(e,t={}){if(!e)return[];if(Array.isArray(e))return e;const n=[],o=new Set;let s=e;for(;s&&t[s]&&!o.has(s);){o.add(s),n.push(s);const e=t[s].next;if(Array.isArray(e)){n.push(...e);break}s=e}return n}async function Ie(e,t,n){if(t.init&&!t.config.init){const o=t.type||"unknown",s=e.logger.scope(`transformer:${o}`),r={collector:e,logger:s,id:n,ingest:oe(n),config:t.config,env:He(t.config.env)};s.debug("init");const a=await ae(t.init,"TransformerInit",e.hooks,e.logger)(r);if(!1===a)return!1;t.config={...a||t.config,env:a?.env||t.config.env,init:!0},s.debug("init done")}return!0}async function De(e,t,n,o,s,r){const a=t.type||"unknown",i=e.logger.scope(`transformer:${a}`),c={collector:e,logger:i,id:n,ingest:s,config:t.config,env:{...He(t.config.env),...r?{respond:r}:{}}};i.debug("push",{event:o.name});const u=await ae(t.push,"TransformerPush",e.hooks,e.logger)(o,c);return i.debug("push done"),u}async function $e(e,t,n,o,s,r,a){a&&s?._meta&&(s._meta.chainPath=a);let i=o,c=r;for(const o of n){const r=t[o];if(!r){e.logger.warn(`Transformer not found: ${o}`);continue}if(s&&s._meta&&s._meta.path.length>256)return e.logger.error(`Max path length exceeded at ${o}`),{event:null,respond:c};if(s&&s._meta&&(s._meta.hops++,s._meta.path.push(o)),!await re(Ie)(e,r,o))return e.logger.error(`Transformer init failed: ${o}`),{event:null,respond:c};if(a&&void 0!==r.config?.chainMocks?.[a]){const t=r.config.chainMocks[a];e.logger.scope(`transformer:${r.type||"unknown"}`).debug("chainMock",{chain:a}),i=t;continue}if(void 0!==r.config?.mock){e.logger.scope(`transformer:${r.type||"unknown"}`).debug("mock"),i=r.config.mock;continue}if(r.config?.disabled)continue;const u=r.config?.cache,l=u?le(u):void 0,f=l?Ce(l,e):void 0;let d;if(l&&f){const e=ge(s,i),t=fe(l,f,e,`t:${o}`);if("HIT"===t?.status&&t.value){if(i=t.value,l.full)return{event:i,respond:c};continue}"MISS"===t?.status&&(d={key:t.key,ttl:t.rule.ttl})}const g=r.config.before;if(g){const n=Ee("string"==typeof g||Array.isArray(g)&&!ue(g)?g:ce(ie(g),ge(s,i))||void 0,Pe(t));if(n.length>0){const o=await $e(e,t,n,i,s,c,a);if(null===o.event)return{event:null,respond:o.respond??c};o.respond&&(c=o.respond),i=Array.isArray(o.event)?o.event[0]:o.event}}const p=await re(De,t=>(e.logger.scope(`transformer:${r.type||"unknown"}`).error("Push failed",{error:t}),!1))(e,r,o,i,s,c);if(!1===p)return{event:null,respond:c};if(Array.isArray(p)){const r=n.slice(n.indexOf(o)+1),u=await Promise.all(p.map(async n=>{const o=n.event||i,u=s?{...s,_meta:{...s._meta,path:[...s._meta.path]}}:oe("unknown");if(n.next){let s=n.next;if(ue(n.next)){const e=ie(n.next);s=ce(e,ge(u,o))}if(s){const n=Ee(s,Pe(t));if(n.length>0)return $e(e,t,n,o,u,c,a)}return{event:o,respond:c}}return r.length>0?$e(e,t,r,o,u,c,a):{event:o,respond:c}}));let l=c;const f=[];for(const e of u.flat())if(null!==e)if(e&&"object"==typeof e&&"event"in e){const t=e;if(t.respond&&(l=t.respond),null===t.event)continue;Array.isArray(t.event)?f.push(...t.event):f.push(t.event)}else f.push(e);return 0===f.length?{event:null,respond:l}:1===f.length?{event:f[0],respond:l}:{event:f,respond:l}}if(p&&"object"==typeof p){const{event:n,respond:o,next:r}=p;if(o&&(c=o),r){let o=r;if(ue(r)){const e=ie(r);if(o=ce(e,ge(s,i)),!o){n&&(i=n);continue}}const u=Ee(o,Pe(t));return u.length>0?$e(e,t,u,n||i,s,c,a):(e.logger.warn(`Branch target not found: ${JSON.stringify(r)}`),{event:null,respond:c})}n&&(i=n)}if(d&&f&&de(f,d.key,i,d.ttl),(!p||"object"==typeof p&&!p.next)&&r.config.next&&ue(r.config.next)){const n=r.config.next,o=ie(n),u=ce(o,ge(s,i));if(u){const n=Ee(u,Pe(t));if(n.length>0)return $e(e,t,n,i,s,c,a)}return{event:i,respond:c}}}return{event:i,respond:c}}function He(e){return e&&se(e)?e:{}}async function Re(e,t,n){const{code:o,config:s={},env:r={},primary:a,next:i,before:c,cache:u}=n;let l,f=z(t);const d=u?Y({...u,full:u.full??!0}):void 0,g=K(i),p=Array.isArray(i)&&X(i)||!g?void 0:Ee(Q(g),Pe(e.transformers)),h=K(c),m=Array.isArray(c)&&X(c)||!h?void 0:Ee(Q(h),Pe(e.transformers)),b=e.logger.scope("source").scope(t),y={push:async(n,o={})=>{let r,a=n;const i=m??(h?Ee(Q(h,ne(f)),Pe(e.transformers)):[]);if(i.length>0&&e.transformers&&Object.keys(e.transformers).length>0){const n=await $e(e,e.transformers,i,a,f,l,`source.${t}.before`);if(null===n.event)return{ok:!0};n.respond&&(l=n.respond),a=Array.isArray(n.event)?n.event[0]:n.event}if(d){const n=Ce(d,e);if(n){const o=ne(f),s=Z(d,n,o,`s:${t}`);if(s){if("HIT"===s.status&&void 0!==s.value&&d.full){let t=s.value;return s.rule.update&&(t=await te(t,s.rule.update,{...o,cache:{status:"HIT"}},e)),l?.(t),{ok:!0}}if("MISS"===s.status&&d.full&&l){const t=l,a=s.rule.update,i={...o,cache:{status:"MISS"}},c=s.key,u=s.rule.ttl;l=o=>{ee(n,c,o,u),a?r=(async()=>{const n=await te(o,a,i,e);t(n)})():t(o)}}"MISS"!==s.status||d.full||ee(n,s.key,!0,s.rule.ttl)}}}const c=p??(g?Ee(Q(g,ne(f)),Pe(e.transformers)):[]),u=await e.push(a,{...o,id:t,ingest:f,respond:l,mapping:s,preChain:c});return r&&await r,u},command:e.command,sources:e.sources,elb:e.sources.elb.push,logger:b,...r},v={collector:e,logger:b,id:t,config:s,env:y,setIngest:async n=>{if(!s.ingest)return void(f=z(t));const o=await V(n,s.ingest,{collector:e}),r=z(t);f={...r,...o,_meta:r._meta}},setRespond:e=>{l=e}},w=await W(o)(v);if(!w)return;const k=w.type||"unknown",O=e.logger.scope(k).scope(t);return y.logger=O,a&&(w.config={...w.config,primary:a}),w}function _e(e,t){return{collector:e,logger:e.logger.scope("on").scope(String(t))}}function Ge(e,t,n,o,s){if(!t.on)return;const r=t.type||"unknown",a=e.logger.scope(r).scope("on").scope(o),i={collector:e,logger:a,id:n,config:t.config,data:s,env:Ve(t.env,t.config.env)};U(t.on)(o,i)}function Me(e,t,n,o){let s;switch(t){case qe.Consent:s=o||e.consent;break;case qe.Session:s=e.session;break;case qe.User:s=o||e.user;break;case qe.Custom:s=o||e.custom;break;case qe.Globals:s=o||e.globals;break;case qe.Config:s=o||e.config;break;case qe.Ready:case qe.Run:default:s=void 0}if(n.length)switch(t){case qe.Consent:!function(e,t,n){const o=n||e.consent,s=_e(e,qe.Consent);t.forEach(e=>{Object.keys(o).filter(t=>t in e).forEach(t=>{U(e[t])(o,s)})})}(e,n,o);break;case qe.Ready:!function(e,t){if(!e.allowed)return;const n=_e(e,qe.Ready);t.forEach(e=>{U(e)(void 0,n)})}(e,n);break;case qe.Run:!function(e,t){if(!e.allowed)return;const n=_e(e,qe.Run);t.forEach(e=>{U(e)(void 0,n)})}(e,n);break;case qe.Session:!function(e,t){if(!e.session)return;const n=_e(e,qe.Session);t.forEach(t=>{U(t)(e.session,n)})}(e,n);break;default:{const o=_e(e,t);n.forEach(e=>{"function"==typeof e&&U(e)(s,o)});break}}}function Ne(e,t,n,o){if(!e)return[];if(t){const e=N(t,x(o));return e?Ee(e,Pe(n)):[]}return Ee(e,Pe(n))}async function Le(e,t,n){const{code:o,config:s={},env:r={},before:a,next:i,cache:c}=t;if(!R(o.push))return Fe({ok:!1,failed:{invalid:{type:"invalid",error:"Destination code must have a push method"}}});const u=n||s||{init:!1};let l=a?{...u,before:a}:{...u};i&&(l={...l,next:i}),c&&(l={...l,cache:c});const f={...o,config:l,env:Ve(o.env,r)};let d=f.config.id;if(!d)do{d=D(5,"abcdefghijklmnopqrstuvwxyz")}while(e.destinations[d]);return e.destinations[d]=f,!1!==f.config.queue&&(f.queuePush=[...e.queue]),Be(e,void 0,{},{[d]:f})}async function Be(e,t,n={},o){const{allowed:s,consent:r,globals:a,user:i}=e;if(!s)return Fe({ok:!1});t&&(e.queue.push(t),e.status.in++),o||(o=e.destinations);const c=await Promise.all(Object.entries(o||{}).map(async([o,s])=>{if(s.config.disabled)return{id:o,destination:s,skipped:!0};let c=(s.queuePush||[]).map(e=>({...e,consent:r}));s.queuePush=[],t&&c.push(j(t));const u=n.ingest?{...n.ingest,_meta:{...n.ingest._meta,path:[...n.ingest._meta.path]}}:E("unknown");if(!c.length&&!s.queueOn?.length)return{id:o,destination:s,skipped:!0};if(!c.length&&s.queueOn?.length){const t=await L(Je)(e,s,o);return{id:o,destination:s,skipped:!t}}const l=[],f=c.filter(e=>{const t=$(s.config.consent,r,e.consent);return!t||(e.consent=t,l.push(e),!1)});if(s.queuePush.push(...f),!l.length)return{id:o,destination:s,queue:c};if(!await L(Je)(e,s,o))return{id:o,destination:s,queue:c};let d,g;s.dlq||(s.dlq=[]);const p=s.config.before,h=Ne(p,p&&G(p)?T(p):void 0,e.transformers,u),m=s.config.next,b=m&&G(m)?T(m):void 0,y=s.config?.cache,v=y?q(y):void 0,w=v?Ce(v,e):void 0;let k=0;return await Promise.all(l.map(async t=>{let r;if(t.globals=S(a,t.globals),t.user=S(i,t.user),v?.full&&w){const e=x(u,t),n=C(v,w,e,`d:${o}`);if("HIT"===n?.status)return t;"MISS"===n?.status&&(r={key:n.key,ttl:n.rule.ttl})}let c=t,l=n.respond;if(h.length>0&&e.transformers&&Object.keys(e.transformers).length>0){const s=await $e(e,e.transformers,h,t,u,n.respond,`destination.${o}.before`);if(null===s.event)return t;s.respond&&(l=s.respond),c=Array.isArray(s.event)?s.event[0]:s.event}if(v&&!v.full&&w){const e=x(u,c),n=C(v,w,e,`d:${o}`);if("HIT"===n?.status)return t;"MISS"===n?.status&&(r={key:n.key,ttl:n.rule.ttl})}const f=Date.now();let p=!1;const y=await L(Ue,t=>{const n=s.type||"unknown";e.logger.scope(n).error("Push failed",{error:t,event:c.name}),d=t,p=!0,s.dlq.push([c,t])})(e,s,o,c,u,l);if(k+=Date.now()-f,r&&w&&void 0===s.config.mock&&P(w,r.key,y??!0,r.ttl),void 0!==y&&(g=y),!p&&m){void 0!==y&&(u._response=y);const t=Ne(m,b,e.transformers,u);if(t.length>0&&e.transformers&&Object.keys(e.transformers).length>0){const n=await $e(e,e.transformers,t,c,u,l,`destination.${o}.next`);n.respond&&(l=n.respond)}}return t})),{id:o,destination:s,error:d,response:g,totalDuration:k}})),u={},l={},f={};for(const t of c){if(t.skipped)continue;const n={type:t.destination.type||"unknown",data:t.response};e.status.destinations[t.id]||(e.status.destinations[t.id]={count:0,failed:0,duration:0});const o=e.status.destinations[t.id],s=Date.now();t.error?(n.error=t.error,f[t.id]=n,o.failed++,o.lastAt=s,o.duration+=t.totalDuration||0,e.status.failed++):t.queue&&t.queue.length?l[t.id]=n:(u[t.id]=n,o.count++,o.lastAt=s,o.duration+=t.totalDuration||0,e.status.out++)}return Fe({event:t,...Object.keys(u).length&&{done:u},...Object.keys(l).length&&{queued:l},...Object.keys(f).length&&{failed:f}})}async function Je(e,t,n){if(t.init&&!t.config.init){const o=t.type||"unknown",s=e.logger.scope(o),r={collector:e,logger:s,id:n,config:t.config,env:Ve(t.env,t.config.env)};s.debug("init");const a=await B(t.init,"DestinationInit",e.hooks,e.logger)(r);if(!1===a)return a;if(t.config={...a||t.config,init:!0},t.queueOn?.length){const o=t.queueOn;t.queueOn=[];for(const{type:s,data:r}of o)Ge(e,t,n,s,r)}s.debug("init done")}return!0}async function Ue(e,t,n,o,s,r){const{config:a}=t,i=await M(o,a,e);if(i.ignore)return!1;const c=t.type||"unknown",u=e.logger.scope(c),l={collector:e,logger:u,id:n,config:a,data:i.data,rule:i.mapping,ingest:s,env:{...Ve(t.env,a.env),...r?{respond:r}:{}}};if(void 0!==a.mock)return u.debug("mock",{event:i.event.name}),a.mock;const f=i.mapping,d=i.mappingKey||"* *";if(!f?.batch||!t.pushBatch||void 0!==a.mock){u.debug("push",{event:i.event.name});const n=await B(t.push,"DestinationPush",e.hooks,e.logger)(i.event,l);return u.debug("push done"),n}{if(t.batches=t.batches||{},!t.batches[d]){const o={key:d,events:[],data:[]};t.batches[d]={batched:o,batchFn:I(()=>{const o=t.batches[d].batched,i={collector:e,logger:u,id:n,config:a,data:void 0,rule:f,ingest:s,env:{...Ve(t.env,a.env),...r?{respond:r}:{}}};u.debug("push batch",{events:o.events.length}),B(t.pushBatch,"DestinationPushBatch",e.hooks,e.logger)(o,i),u.debug("push batch done"),o.events=[],o.data=[]},f.batch)}}const o=t.batches[d];o.batched.events.push(i.event),H(i.data)&&o.batched.data.push(i.data),o.batchFn()}return!0}function Fe(e){return{ok:!e?.failed,...e}}function ze(e){const{code:t,config:n={},env:o={},cache:s}=e,{config:r}=Te(e,"before"),{config:a}=Te({...e,config:r},"next"),i={...t.config,...n,...a};s&&(i.cache=s);const c=Ve(t.env,o);return{...t,config:i,env:c}}function Ve(e,t){return e||t?t?e&&_(e)&&_(t)?{...e,...t}:t:e:{}}async function We(e,t,n){const o=Object.entries(e).map(async([e,o])=>{const s=o.destroy;if(!s)return;const r=o.type||"unknown",a=n.scope(r),i={id:e,config:o.config,env:o.env??{},logger:a};try{await Promise.race([s(i),new Promise((n,o)=>setTimeout(()=>o(new Error(`${t} '${e}' destroy timed out`)),5e3))])}catch(n){a.error(`${t} '${e}' destroy failed: ${n}`)}});await Promise.allSettled(o)}async function Ke(e,t,n,o){let s,r,a=!1;switch(t){case qe.Config:ye(n)&&(pe(e.config,n,{shallow:!1}),r=n,a=!0);break;case qe.Consent:if(ye(n)){const{update:t}=function(e,t){const n={};return Object.entries(t).forEach(([e,t])=>{n[e]=!!t}),e.consent=k(e.consent,n),{update:n}}(e,n);r=t,a=!0}break;case qe.Custom:ye(n)&&(e.custom=pe(e.custom,n),r=n,a=!0);break;case qe.Destination:ye(n)&&("code"in n&&ye(n.code)?s=await Le(e,n,o):me(n.push)&&(s=await Le(e,{code:n},o)));break;case qe.Globals:ye(n)&&(e.globals=pe(e.globals,n),r=n,a=!0);break;case qe.On:be(n)&&await async function(e,t,n){const o=e.on,s=o[t]||[],r=J(n)?n:[n];r.forEach(e=>{s.push(e)}),o[t]=s,Me(e,t,r)}(e,n,o);break;case qe.Ready:a=!0;break;case qe.Run:s=await async function(e,t){return e.allowed=!0,e.timing=Date.now(),t&&(t.consent&&(e.consent=pe(e.consent,t.consent)),t.user&&(e.user=pe(e.user,t.user)),t.globals&&(e.globals=pe(e.config.globalsStatic||{},t.globals)),t.custom&&(e.custom=pe(e.custom,t.custom))),Object.values(e.destinations).forEach(e=>{e.queuePush=[]}),e.queue=[],e.round++,await Be(e)}(e,n),a=!0;break;case qe.Session:a=!0;break;case qe.Shutdown:await async function(e){const t=e.logger;await We(e.sources,"source",t),await We(e.destinations,"destination",t),await We(e.transformers,"transformer",t),await We(e.stores,"store",t)}(e);break;case qe.User:ye(n)&&(pe(e.user,n,{shallow:!1}),r=n,a=!0)}return a&&(await async function(e,t,n,o){let s,r=n||[];switch(n||(r=e.on[t]||[]),t){case qe.Consent:s=o||e.consent;break;case qe.Session:s=e.session;break;case qe.User:s=o||e.user;break;case qe.Custom:s=o||e.custom;break;case qe.Globals:s=o||e.globals;break;case qe.Config:s=o||e.config;break;case qe.Ready:case qe.Run:default:s=void 0}let a=!1;for(const n of Object.values(e.sources))n.on&&!1===await F(n.on)(t,s)&&(a=!0);return Object.entries(e.destinations).forEach(([n,o])=>{if(o.on){if(!o.config.init)return o.queueOn=o.queueOn||[],void o.queueOn.push({type:t,data:s});Ge(e,o,n,t,s)}}),(Object.keys(e.pending.sources).length>0||Object.keys(e.pending.destinations).length>0)&&await async function(e,t){for(const[n,o]of Object.entries(e.pending.sources)){if(!e.pending.sources[n]||e.sources[n])continue;const s=o.config?.require;if(!s)continue;const r=s.indexOf(t);if(-1===r)continue;if(s.splice(r,1),s.length>0)continue;delete e.pending.sources[n];const a=await Re(e,n,o);a&&(e.sources[n]=a)}for(const[n,o]of Object.entries(e.pending.destinations)){if(!e.pending.destinations[n]||e.destinations[n])continue;const s=o.config?.require;if(!s)continue;const r=s.indexOf(t);if(-1===r)continue;if(s.splice(r,1),s.length>0)continue;delete e.pending.destinations[n];const a=ze(o);!1!==a.config.queue&&(a.queuePush=[...e.queue]),e.destinations[n]=a}}(e,t),Me(e,t,r,o),!a}(e,t,void 0,r),s=await Be(e)),s||Fe({ok:!0})}function Qe(e,t){if(!t.name)throw new Error("Event name is required");const[n,o]=t.name.split(" ");if(!n||!o)throw new Error("Event name is invalid");const{timestamp:s=Date.now(),name:r=`${n} ${o}`,data:a={},context:i={},globals:c=e.globals,custom:u={},user:l=e.user,nested:f=[],consent:d=e.consent,id:g=he(),trigger:p="",entity:h=n,action:m=o,timing:b=0,source:y={type:"collector",schema:"4"}}=t;return{name:r,data:a,context:i,globals:c,custom:u,user:l,nested:f,consent:d,id:g,trigger:p,entity:h,action:m,timestamp:s,timing:b,source:y}}async function Xe(e){const t=O({globalsStatic:{},sessionStatic:{},run:!0},e,{merge:!1,extend:!1}),n={level:e.logger?.level,handler:e.logger?.handler},o=A(n),s={...t.globalsStatic,...e.globals},r={allowed:!1,config:t,consent:e.consent||{},custom:e.custom||{},destinations:{},transformers:{},stores:{},globals:s,hooks:e.hooks||{},logger:o,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||{},sources:{},pending:{sources:{},destinations:{}},push:void 0,command:void 0};var a,i;r.push=function(e,t){return Ae(async(n,o={})=>await Oe(async()=>{const s=Date.now(),{id:r,ingest:a,respond:i,mapping:c,preChain:u,include:l,exclude:f}=o;let d=i,g=n;const p=l||f?function(e,t,n){let o=e;return t&&(o=Object.fromEntries(Object.entries(o).filter(([e])=>t.includes(e)))),n&&(o=Object.fromEntries(Object.entries(o).filter(([e])=>!n.includes(e)))),o}(e.destinations,l,f):void 0,h=a??ve(r||"unknown");if(c){const t=await ke(g,c,e);if(t.ignore)return Fe({ok:!0});if(c.consent&&!we(c.consent,e.consent,t.event.consent))return Fe({ok:!0});g=t.event}if(u?.length&&e.transformers&&Object.keys(e.transformers).length>0){const n=await $e(e,e.transformers,u,g,h,d,r?`source.${r}.next`:void 0);if(null===n.event)return Fe({ok:!0});if(n.respond&&(d=n.respond),Array.isArray(n.event)){const o=await Promise.all(n.event.map(async n=>{const o=t(n),s=Qe(e,o);return Be(e,s,{id:r,ingest:h,respond:d},p)}));if(r){e.status.sources[r]||(e.status.sources[r]={count:0,duration:0});const t=e.status.sources[r];t.count+=n.event.length,t.lastAt=Date.now(),t.duration+=Date.now()-s}return o[0]??Fe({ok:!0})}g=n.event}const m=t(g),b=Qe(e,m),y=await Be(e,b,{id:r,ingest:h,respond:d},p);if(r){e.status.sources[r]||(e.status.sources[r]={count:0,duration:0});const t=e.status.sources[r];t.count++,t.lastAt=Date.now(),t.duration+=Date.now()-s}return y},()=>Fe({ok:!1}))(),"Push",e.hooks,e.logger)}(r,e=>({timing:Math.round((Date.now()-r.timing)/10)/100,source:{type:"collector",schema:"4",version:"4.0.0-next-1777882869103"},...e})),r.command=(i=Ke,Se(async(e,t,n)=>await xe(async()=>await i(a,e,t,n),()=>Fe({ok:!1}))(),"Command",(a=r).hooks,a.logger));const c=e.stores||{};if(r.stores=await async function(e,t={}){const n={};for(const[o,s]of Object.entries(t)){const{code:t,config:r={},env:a={}}=s,i=e.logger.scope("store").scope(o),c={collector:e,logger:i,id:o,config:r,env:a},u=await t(c),l=u.get,f=u.set,d=u.delete;u.get=je(l,"StoreGet",e.hooks,e.logger),u.set=je(f,"StoreSet",e.hooks,e.logger),u.delete=je(d,"StoreDelete",e.hooks,e.logger),n[o]=u}return n}(r,c),function(e,t,n){const o=new Map;for(const[n,s]of Object.entries(e))t[n]&&o.set(s,t[n]);if(0!==o.size)for(const e of[n.transformers,n.destinations,n.sources])if(e)for(const t of Object.values(e))s(t.env);function s(e){if(e)for(const[t,n]of Object.entries(e))if("object"==typeof n&&null!==n){const s=o.get(n);s&&(e[t]=s)}}}(c,r.stores,e),!r.stores.__cache){const e=new Map;r.stores.__cache={type:"memory",config:{},get:t=>{const n=e.get(t);if(n){if(!(n.expires&&Date.now()>n.expires))return n.value;e.delete(t)}},set:(t,n,o)=>{e.set(t,{value:n,expires:o?Date.now()+o:void 0})},delete:t=>{e.delete(t)}}}return r.destinations=await async function(e,t={}){const n={};for(const[o,s]of Object.entries(t))s.config?.require?.length?e.pending.destinations[o]=s:n[o]=ze(s);return n}(r,e.destinations||{}),r.transformers=await async function(e,t={}){const n={};for(const[o,s]of Object.entries(t)){const{code:t,env:r={}}=s,{config:a}=Te(s,"before"),{config:i}=Te({...s,config:a},"next"),c=Object.keys(r).length>0?{...i,env:r}:i,{cache:u}=s,l=u?{...c,cache:u}:c,f=e.logger.scope("transformer").scope(o),d={collector:e,logger:f,id:o,ingest:oe(o),config:l,env:r},g=await t(d);n[o]=g}return n}(r,e.transformers||{}),r}async function Ye(e){e=e||{};const t=await Xe(e),n=(o=t,{type:"elb",config:{},push:async(e,t,n,s,r,a)=>{if("string"==typeof e&&e.startsWith("walker ")){const s=e.replace("walker ","");return o.command(s,t,n)}let i;if("string"==typeof e)i={name:e},t&&"object"==typeof t&&!Array.isArray(t)&&(i.data=t);else{if(!e||"object"!=typeof e)return Fe({ok:!1});i=e,t&&"object"==typeof t&&!Array.isArray(t)&&(i.data={...i.data||{},...t})}return s&&"object"==typeof s&&(i.context=s),r&&Array.isArray(r)&&(i.nested=r),a&&"object"==typeof a&&(i.custom=a),o.push(i)}});var o;t.sources.elb=n;const s=await async function(e,t={}){const n={};for(const[o,s]of Object.entries(t)){const{config:t={}}=s;if(t.require&&t.require.length>0){e.pending.sources[o]=s;continue}const r=await Re(e,o,s);r&&(n[o]=r)}return n}(t,e.sources||{});Object.assign(t.sources,s);const{consent:r,user:a,globals:i,custom:c}=e;r&&await t.command("consent",r),a&&await t.command("user",a),i&&Object.assign(t.globals,i),c&&Object.assign(t.custom,c),t.config.run&&await t.command("run");let u=n.push;const l=Object.values(t.sources).filter(e=>"elb"!==e.type),f=l.find(e=>e.config.primary);return f?u=f.push:l.length>0&&(u=l[0].push),{collector:t,elb:u}}var Ze=async e=>{let t;return{get flow(){return t},trigger:()=>async n=>{if(!t){const n=await Ye(e);t={collector:n.collector,elb:n.elb}}const o=function(e){for(const t of Object.values(e.sources||{}))if("lambda"===t.type)return t}(t.collector);if(!o)throw new Error("Lambda source not found in collector");const s={awsRequestId:`test-${Date.now()}`},r=o.push,a=await r(n,s);let i;try{i=JSON.parse(a.body||"{}")}catch{i=a.body}const c={};if(a.headers)for(const[e,t]of Object.entries(a.headers))void 0!==t&&(c[e]=String(t));return{statusCode:a.statusCode,body:i,headers:c}}}};function et(e){return async t=>{const n={...t};if(n.body&&"string"==typeof n.body){const e=JSON.parse(n.body);e.name&&!e.event&&(n.body=JSON.stringify({...e,event:e.name,name:void 0}))}return e.push(n,{awsRequestId:"test-req"})}}export{f as examples,n 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","../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":"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","names":["z","z","fn","trigger","e","k","v"]}
1
+ {"version":3,"sources":["../src/lambda/schemas/index.ts","../src/lambda/schemas/settings.ts","../src/lambda/schemas/primitives.ts","../src/lambda/examples/index.ts","../src/lambda/examples/env.ts","../src/lambda/examples/step.ts","../src/lambda/examples/trigger.ts"],"sourcesContent":["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","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","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 title: 'Lambda POST',\n description:\n 'An API Gateway v2 HTTP POST with a JSON body is converted into a walker elb event.',\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 [\n 'elb',\n {\n name: 'page view',\n data: { title: 'Home' },\n },\n ],\n ],\n};\n\nexport const apiGatewayV1Post: Flow.StepExample = {\n title: 'API Gateway v1 POST',\n description:\n 'A REST API Gateway v1 POST request with a JSON body is converted into a walker elb event.',\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 [\n 'elb',\n {\n name: 'page view',\n data: { title: 'Home' },\n },\n ],\n ],\n};\n\nexport const lambdaGet: Flow.StepExample = {\n title: 'Lambda GET',\n description:\n 'An API Gateway v2 HTTP GET with query parameters is parsed into an elb event payload.',\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 [\n 'elb',\n {\n e: 'page view',\n d: '{\"title\":\"Home\"}',\n },\n ],\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":["z","z","trigger","k","v"]}