@walkeros/server-source-fetch 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";var e,t=Object.defineProperty,r=Object.getOwnPropertyDescriptor,s=Object.getOwnPropertyNames,o=Object.prototype.hasOwnProperty,a=(e,r)=>{for(var s in r)t(e,s,{get:r[s],enumerable:!0})},n={};a(n,{SourceFetch:()=>T,TRANSPARENT_GIF_BASE64:()=>O,createCorsHeaders:()=>x,createJsonResponse:()=>R,createPixelResponse:()=>P,examples:()=>q,schemas:()=>c,sourceFetch:()=>L}),module.exports=(e=n,((e,a,n,i)=>{if(a&&"object"==typeof a||"function"==typeof a)for(let c of s(a))o.call(e,c)||c===n||t(e,c,{get:()=>a[c],enumerable:!(i=r(a,c))||i.enumerable});return e})(t({},"__esModule",{value:!0}),e));var i=require("@walkeros/core"),c={};a(c,{CorsOptionsSchema:()=>p,CorsOrigin:()=>d,EventSchema:()=>w,HttpMethod:()=>u,SettingsSchema:()=>g});var l=require("@walkeros/core/dev"),u=l.z.enum(["GET","POST","PUT","PATCH","DELETE","OPTIONS","HEAD"]),d=l.z.union([l.z.string(),l.z.array(l.z.string()),l.z.literal("*")]),p=l.z.object({origin:d.optional(),methods:l.z.array(u).optional(),headers:l.z.array(l.z.string()).optional(),credentials:l.z.boolean().optional(),maxAge:l.z.number().int().positive().optional()}),m=require("@walkeros/core/dev"),g=m.z.object({path:m.z.string().default("/collect"),cors:m.z.union([m.z.boolean(),p]).default(!0),healthPath:m.z.string().default("/health"),maxRequestSize:m.z.number().int().positive().default(102400),maxBatchSize:m.z.number().int().positive().default(100)}),h=require("@walkeros/core/dev"),z=h.z.record(h.z.string(),h.z.union([h.z.string(),h.z.number(),h.z.boolean(),h.z.record(h.z.string(),h.z.any())])),f=h.z.record(h.z.string(),h.z.tuple([h.z.union([h.z.string(),h.z.number(),h.z.boolean(),h.z.record(h.z.string(),h.z.any())]),h.z.number()])),y=h.z.object({id:h.z.string().optional(),device:h.z.string().optional(),session:h.z.string().optional(),email:h.z.string().optional(),hash:h.z.string().optional()}).passthrough(),A=h.z.record(h.z.string(),h.z.boolean()),b=h.z.lazy(()=>h.z.object({entity:h.z.string(),data:z.optional(),nested:h.z.array(b).optional(),context:f.optional()}).passthrough()),v=h.z.object({source:h.z.string(),tagging:h.z.number()}),S=h.z.object({type:h.z.string(),id:h.z.string(),previous_id:h.z.string()}).passthrough(),w=h.z.object({name:h.z.string().min(1,"Event name is required"),data:z.optional(),context:f.optional(),globals:z.optional(),custom:z.optional(),user:y.optional(),nested:h.z.array(b).optional(),consent:A.optional(),id:h.z.string().optional(),trigger:h.z.string().optional(),entity:h.z.string().optional(),action:h.z.string().optional(),timestamp:h.z.number().optional(),timing:h.z.number().optional(),group:h.z.string().optional(),count:h.z.number().optional(),version:v.optional(),source:S.optional()}).passthrough();function x(e=!0,t){const r=new Headers;if(!1===e)return r;if(!0===e)r.set("Access-Control-Allow-Origin","*"),r.set("Access-Control-Allow-Methods","GET, POST, OPTIONS"),r.set("Access-Control-Allow-Headers","Content-Type");else{if(e.origin){let s;s=Array.isArray(e.origin)?t&&e.origin.includes(t)?t:e.origin[0]:e.origin,r.set("Access-Control-Allow-Origin",s)}e.methods&&r.set("Access-Control-Allow-Methods",e.methods.join(", ")),e.headers&&r.set("Access-Control-Allow-Headers",e.headers.join(", ")),e.credentials&&r.set("Access-Control-Allow-Credentials","true"),e.maxAge&&r.set("Access-Control-Max-Age",String(e.maxAge))}return r}var O="R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";function P(e){const t=atob(O),r=new Uint8Array(t.length);for(let e=0;e<t.length;e++)r[e]=t.charCodeAt(e);const s=new Headers(e);return s.set("Content-Type","image/gif"),s.set("Cache-Control","no-cache, no-store, must-revalidate"),new Response(r,{status:200,headers:s})}function R(e,t=200,r){const s=new Headers(r);return s.set("Content-Type","application/json"),new Response(JSON.stringify(e),{status:t,headers:s})}var T={},q={};a(q,{inputs:()=>C,requests:()=>N});var C={};a(C,{batch:()=>I,completeEvent:()=>k,minimal:()=>H,pageView:()=>E,productAdd:()=>j});var E={name:"page view",data:{title:"Home Page",path:"/",referrer:"https://google.com"},user:{id:"user-123",session:"session-456"},timestamp:17e11},j={name:"product add",data:{id:"P-123",name:"Laptop",price:999.99,quantity:1},context:{stage:["shopping",1]},globals:{language:"en",currency:"USD"},user:{id:"user-123"},nested:[{entity:"category",data:{name:"Electronics",path:"/electronics"}}],consent:{functional:!0,marketing:!0}},k={name:"order complete",data:{id:"ORDER-123",total:999.99,currency:"USD"},context:{stage:["checkout",3],test:["variant-A",0]},globals:{language:"en",country:"US"},custom:{campaignId:"summer-sale",source:"email"},user:{id:"user-123",email:"user@example.com",session:"session-456"},nested:[{entity:"product",data:{id:"P-123",price:999.99}}],consent:{functional:!0,marketing:!0,analytics:!1},trigger:"click",group:"ecommerce"},H={name:"ping"},I=[E,j,{name:"button click",data:{id:"cta"}}],N={};a(N,{batchPostRequest:()=>D,healthCheckRequest:()=>M,invalidJsonRequest:()=>G,optionsRequest:()=>U,oversizedRequest:()=>$,pixelGetRequest:()=>J,validPostRequest:()=>B});var B={method:"POST",url:"https://example.com/collect",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:"page view",data:{title:"Home"}})},D={method:"POST",url:"https://example.com/collect",headers:{"Content-Type":"application/json"},body:JSON.stringify({batch:[{name:"page view",data:{title:"Home"}},{name:"button click",data:{id:"cta"}}]})},J={method:"GET",url:"https://example.com/collect?event=page%20view&data[title]=Home&user[id]=user123"},M={method:"GET",url:"https://example.com/health"},U={method:"OPTIONS",url:"https://example.com/collect",headers:{Origin:"https://example.com"}},G={method:"POST",url:"https://example.com/collect",headers:{"Content-Type":"application/json"},body:"invalid json{"},$={method:"POST",url:"https://example.com/collect",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:"test",data:{payload:"x".repeat(2e5)}})},L=async(e,t)=>{const r=g.parse(e.settings||{}),{logger:s}=t;return{type:"fetch",config:{...e,settings:r},push:async e=>{Date.now();try{const o=new URL(e.url),a=e.method.toUpperCase(),n=e.headers.get("Origin"),c=x(r.cors,n);if(r.healthPath&&o.pathname===r.healthPath)return R({status:"ok",timestamp:Date.now(),source:"fetch"},200,c);if("OPTIONS"===a)return new Response(null,{status:204,headers:c});if("GET"===a){const e=(0,i.requestToData)(o.search);return e&&(0,i.isObject)(e)&&await t.push(e),P(c)}if("POST"===a){const o=e.headers.get("Content-Length");if(o){const e=parseInt(o,10);if(e>r.maxRequestSize)return s.error("Request too large",{size:e,limit:r.maxRequestSize}),R({success:!1,error:`Request too large. Maximum size: ${r.maxRequestSize} bytes`},413,c)}let a,n;try{if(n=await e.text(),n.length>r.maxRequestSize)return s.error("Request body too large",{size:n.length,limit:r.maxRequestSize}),R({success:!1,error:`Request too large. Maximum size: ${r.maxRequestSize} bytes`},413,c);a=JSON.parse(n)}catch(e){return s.error("Failed to parse JSON",e),R({success:!1,error:"Invalid JSON body"},400,c)}if(!(0,i.isDefined)(a)||!(0,i.isObject)(a))return s.error("Invalid event body type"),R({success:!1,error:"Invalid event: body must be an object"},400,c);if("batch"in a&&Array.isArray(a.batch)){const e=a.batch;if(e.length>r.maxBatchSize)return s.error("Batch too large",{size:e.length,limit:r.maxBatchSize}),R({success:!1,error:`Batch too large. Maximum size: ${r.maxBatchSize} events`},400,c);const o=await async function(e,t,r){const s={successful:0,failed:0,ids:[],errors:[]};for(let o=0;o<e.length;o++){const a=e[o],n=w.safeParse(a);if(n.success)try{const e=await t(n.data);e?.event?.id&&s.ids.push(e.event.id),s.successful++}catch(e){s.failed++,s.errors.push({index:o,error:e instanceof Error?e.message:"Unknown error"}),r.error(`Batch event ${o} processing failed`,e)}else s.failed++,s.errors.push({index:o,error:`Validation failed: ${n.error.issues[0].message}`}),r.error(`Batch event ${o} validation failed`,{errors:n.error.issues})}return s}(e,t.push,s);return o.failed>0?R({success:!1,processed:o.successful,failed:o.failed,errors:o.errors},207,c):R({success:!0,processed:o.successful,ids:o.ids},200,c)}const l=w.safeParse(a);if(!l.success){const e=l.error.issues.map(e=>({path:e.path.join("."),message:e.message}));return s.error("Event validation failed",{errors:e}),R({success:!1,error:"Event validation failed",validationErrors:e},400,c)}const u=await async function(e,t){try{const r=await t(e);return{id:r?.event?.id}}catch(e){return{error:e instanceof Error?e.message:"Unknown error"}}}(l.data,t.push);return u.error?(s.error("Event processing failed",{error:u.error}),R({success:!1,error:u.error},400,c)):R({success:!0,id:u.id,timestamp:Date.now()},200,c)}return R({success:!1,error:"Method not allowed"},405,c)}catch(e){s.error("Internal server error",e);const t=x(r.cors);return R({success:!1,error:e instanceof Error?e.message:"Internal server error"},500,t)}}}};//# sourceMappingURL=index.js.map
1
+ "use strict";var mod,__defProp=Object.defineProperty,__getOwnPropDesc=Object.getOwnPropertyDescriptor,__getOwnPropNames=Object.getOwnPropertyNames,__hasOwnProp=Object.prototype.hasOwnProperty,__export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})},index_exports={};__export(index_exports,{SourceFetch:()=>types_exports,TRANSPARENT_GIF_BASE64:()=>TRANSPARENT_GIF_BASE64,createCorsHeaders:()=>createCorsHeaders,createJsonResponse:()=>createJsonResponse,createPixelResponse:()=>createPixelResponse,examples:()=>examples_exports,schemas:()=>schemas_exports,sourceFetch:()=>sourceFetch}),module.exports=(mod=index_exports,((to,from,except,desc)=>{if(from&&"object"==typeof from||"function"==typeof from)for(let key of __getOwnPropNames(from))__hasOwnProp.call(to,key)||key===except||__defProp(to,key,{get:()=>from[key],enumerable:!(desc=__getOwnPropDesc(from,key))||desc.enumerable});return to})(__defProp({},"__esModule",{value:!0}),mod));var import_core=require("@walkeros/core"),schemas_exports={};__export(schemas_exports,{CorsOptionsSchema:()=>CorsOptionsSchema,CorsOrigin:()=>CorsOrigin,EventSchema:()=>EventSchema,HttpMethod:()=>HttpMethod,SettingsSchema:()=>SettingsSchema});var import_dev=require("@walkeros/core/dev"),HttpMethod=import_dev.z.enum(["GET","POST","PUT","PATCH","DELETE","OPTIONS","HEAD"]),CorsOrigin=import_dev.z.union([import_dev.z.string(),import_dev.z.array(import_dev.z.string()),import_dev.z.literal("*")]),CorsOptionsSchema=import_dev.z.object({origin:CorsOrigin.optional(),methods:import_dev.z.array(HttpMethod).optional(),headers:import_dev.z.array(import_dev.z.string()).optional(),credentials:import_dev.z.boolean().optional(),maxAge:import_dev.z.number().int().positive().optional()}),import_dev2=require("@walkeros/core/dev"),SettingsSchema=import_dev2.z.object({path:import_dev2.z.string().default("/collect"),cors:import_dev2.z.union([import_dev2.z.boolean(),CorsOptionsSchema]).default(!0),healthPath:import_dev2.z.string().default("/health"),maxRequestSize:import_dev2.z.number().int().positive().default(102400),maxBatchSize:import_dev2.z.number().int().positive().default(100)}),import_dev3=require("@walkeros/core/dev"),PropertiesSchema=import_dev3.z.record(import_dev3.z.string(),import_dev3.z.union([import_dev3.z.string(),import_dev3.z.number(),import_dev3.z.boolean(),import_dev3.z.record(import_dev3.z.string(),import_dev3.z.any())])),OrderedPropertiesSchema=import_dev3.z.record(import_dev3.z.string(),import_dev3.z.tuple([import_dev3.z.union([import_dev3.z.string(),import_dev3.z.number(),import_dev3.z.boolean(),import_dev3.z.record(import_dev3.z.string(),import_dev3.z.any())]),import_dev3.z.number()])),UserSchema=import_dev3.z.object({id:import_dev3.z.string().optional(),device:import_dev3.z.string().optional(),session:import_dev3.z.string().optional(),email:import_dev3.z.string().optional(),hash:import_dev3.z.string().optional()}).passthrough(),ConsentSchema=import_dev3.z.record(import_dev3.z.string(),import_dev3.z.boolean()),EntitySchema=import_dev3.z.lazy(()=>import_dev3.z.object({entity:import_dev3.z.string(),data:PropertiesSchema.optional(),nested:import_dev3.z.array(EntitySchema).optional(),context:OrderedPropertiesSchema.optional()}).passthrough()),VersionSchema=import_dev3.z.object({source:import_dev3.z.string(),tagging:import_dev3.z.number()}),SourceSchema=import_dev3.z.object({type:import_dev3.z.string(),id:import_dev3.z.string(),previous_id:import_dev3.z.string()}).passthrough(),EventSchema=import_dev3.z.object({name:import_dev3.z.string().min(1,"Event name is required"),data:PropertiesSchema.optional(),context:OrderedPropertiesSchema.optional(),globals:PropertiesSchema.optional(),custom:PropertiesSchema.optional(),user:UserSchema.optional(),nested:import_dev3.z.array(EntitySchema).optional(),consent:ConsentSchema.optional(),id:import_dev3.z.string().optional(),trigger:import_dev3.z.string().optional(),entity:import_dev3.z.string().optional(),action:import_dev3.z.string().optional(),timestamp:import_dev3.z.number().optional(),timing:import_dev3.z.number().optional(),group:import_dev3.z.string().optional(),count:import_dev3.z.number().optional(),version:VersionSchema.optional(),source:SourceSchema.optional()}).passthrough();function createCorsHeaders(corsConfig=!0,requestOrigin){const headers=new Headers;if(!1===corsConfig)return headers;if(!0===corsConfig)headers.set("Access-Control-Allow-Origin","*"),headers.set("Access-Control-Allow-Methods","GET, POST, OPTIONS"),headers.set("Access-Control-Allow-Headers","Content-Type");else{if(corsConfig.origin){let origin;origin=Array.isArray(corsConfig.origin)?requestOrigin&&corsConfig.origin.includes(requestOrigin)?requestOrigin:corsConfig.origin[0]:corsConfig.origin,headers.set("Access-Control-Allow-Origin",origin)}corsConfig.methods&&headers.set("Access-Control-Allow-Methods",corsConfig.methods.join(", ")),corsConfig.headers&&headers.set("Access-Control-Allow-Headers",corsConfig.headers.join(", ")),corsConfig.credentials&&headers.set("Access-Control-Allow-Credentials","true"),corsConfig.maxAge&&headers.set("Access-Control-Max-Age",String(corsConfig.maxAge))}return headers}var TRANSPARENT_GIF_BASE64="R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";function createPixelResponse(corsHeaders){const binaryString=atob(TRANSPARENT_GIF_BASE64),bytes=new Uint8Array(binaryString.length);for(let i=0;i<binaryString.length;i++)bytes[i]=binaryString.charCodeAt(i);const headers=new Headers(corsHeaders);return headers.set("Content-Type","image/gif"),headers.set("Cache-Control","no-cache, no-store, must-revalidate"),new Response(bytes,{status:200,headers:headers})}function createJsonResponse(body,status=200,corsHeaders){const headers=new Headers(corsHeaders);return headers.set("Content-Type","application/json"),new Response(JSON.stringify(body),{status:status,headers:headers})}var types_exports={},examples_exports={};__export(examples_exports,{inputs:()=>inputs_exports,requests:()=>requests_exports});var inputs_exports={};__export(inputs_exports,{batch:()=>batch,completeEvent:()=>completeEvent,minimal:()=>minimal,pageView:()=>pageView,productAdd:()=>productAdd});var pageView={name:"page view",data:{title:"Home Page",path:"/",referrer:"https://google.com"},user:{id:"user-123",session:"session-456"},timestamp:17e11},productAdd={name:"product add",data:{id:"P-123",name:"Laptop",price:999.99,quantity:1},context:{stage:["shopping",1]},globals:{language:"en",currency:"USD"},user:{id:"user-123"},nested:[{entity:"category",data:{name:"Electronics",path:"/electronics"}}],consent:{functional:!0,marketing:!0}},completeEvent={name:"order complete",data:{id:"ORDER-123",total:999.99,currency:"USD"},context:{stage:["checkout",3],test:["variant-A",0]},globals:{language:"en",country:"US"},custom:{campaignId:"summer-sale",source:"email"},user:{id:"user-123",email:"user@example.com",session:"session-456"},nested:[{entity:"product",data:{id:"P-123",price:999.99}}],consent:{functional:!0,marketing:!0,analytics:!1},trigger:"click",group:"ecommerce"},minimal={name:"ping"},batch=[pageView,productAdd,{name:"button click",data:{id:"cta"}}],requests_exports={};__export(requests_exports,{batchPostRequest:()=>batchPostRequest,healthCheckRequest:()=>healthCheckRequest,invalidJsonRequest:()=>invalidJsonRequest,optionsRequest:()=>optionsRequest,oversizedRequest:()=>oversizedRequest,pixelGetRequest:()=>pixelGetRequest,validPostRequest:()=>validPostRequest});var validPostRequest={method:"POST",url:"https://example.com/collect",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:"page view",data:{title:"Home"}})},batchPostRequest={method:"POST",url:"https://example.com/collect",headers:{"Content-Type":"application/json"},body:JSON.stringify({batch:[{name:"page view",data:{title:"Home"}},{name:"button click",data:{id:"cta"}}]})},pixelGetRequest={method:"GET",url:"https://example.com/collect?event=page%20view&data[title]=Home&user[id]=user123"},healthCheckRequest={method:"GET",url:"https://example.com/health"},optionsRequest={method:"OPTIONS",url:"https://example.com/collect",headers:{Origin:"https://example.com"}},invalidJsonRequest={method:"POST",url:"https://example.com/collect",headers:{"Content-Type":"application/json"},body:"invalid json{"},oversizedRequest={method:"POST",url:"https://example.com/collect",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:"test",data:{payload:"x".repeat(2e5)}})},sourceFetch=async(config,env)=>{const settings=SettingsSchema.parse(config.settings||{}),{logger:logger}=env;return{type:"fetch",config:{...config,settings:settings},push:async request=>{Date.now();try{const url=new URL(request.url),method=request.method.toUpperCase(),origin=request.headers.get("Origin"),corsHeaders=createCorsHeaders(settings.cors,origin);if(settings.healthPath&&url.pathname===settings.healthPath)return createJsonResponse({status:"ok",timestamp:Date.now(),source:"fetch"},200,corsHeaders);if("OPTIONS"===method)return new Response(null,{status:204,headers:corsHeaders});if("GET"===method){const parsedData=(0,import_core.requestToData)(url.search);return parsedData&&(0,import_core.isObject)(parsedData)&&await env.push(parsedData),createPixelResponse(corsHeaders)}if("POST"===method){const contentLength=request.headers.get("Content-Length");if(contentLength){const size=parseInt(contentLength,10);if(size>settings.maxRequestSize)return logger.error("Request too large",{size:size,limit:settings.maxRequestSize}),createJsonResponse({success:!1,error:`Request too large. Maximum size: ${settings.maxRequestSize} bytes`},413,corsHeaders)}let eventData,bodyText;try{if(bodyText=await request.text(),bodyText.length>settings.maxRequestSize)return logger.error("Request body too large",{size:bodyText.length,limit:settings.maxRequestSize}),createJsonResponse({success:!1,error:`Request too large. Maximum size: ${settings.maxRequestSize} bytes`},413,corsHeaders);eventData=JSON.parse(bodyText)}catch(error){return logger.error("Failed to parse JSON",error),createJsonResponse({success:!1,error:"Invalid JSON body"},400,corsHeaders)}if(!(0,import_core.isDefined)(eventData)||!(0,import_core.isObject)(eventData))return logger.error("Invalid event body type"),createJsonResponse({success:!1,error:"Invalid event: body must be an object"},400,corsHeaders);if("batch"in eventData&&Array.isArray(eventData.batch)){const batch2=eventData.batch;if(batch2.length>settings.maxBatchSize)return logger.error("Batch too large",{size:batch2.length,limit:settings.maxBatchSize}),createJsonResponse({success:!1,error:`Batch too large. Maximum size: ${settings.maxBatchSize} events`},400,corsHeaders);const results=await async function(events,push,logger){const results={successful:0,failed:0,ids:[],errors:[]};for(let i=0;i<events.length;i++){const event=events[i],validation=EventSchema.safeParse(event);if(validation.success)try{const result=await push(validation.data);result?.event?.id&&results.ids.push(result.event.id),results.successful++}catch(error){results.failed++,results.errors.push({index:i,error:error instanceof Error?error.message:"Unknown error"}),logger.error(`Batch event ${i} processing failed`,error)}else results.failed++,results.errors.push({index:i,error:`Validation failed: ${validation.error.issues[0].message}`}),logger.error(`Batch event ${i} validation failed`,{errors:validation.error.issues})}return results}(batch2,env.push,logger);return results.failed>0?createJsonResponse({success:!1,processed:results.successful,failed:results.failed,errors:results.errors},207,corsHeaders):createJsonResponse({success:!0,processed:results.successful,ids:results.ids},200,corsHeaders)}const validation=EventSchema.safeParse(eventData);if(!validation.success){const errors=validation.error.issues.map(issue=>({path:issue.path.join("."),message:issue.message}));return logger.error("Event validation failed",{errors:errors}),createJsonResponse({success:!1,error:"Event validation failed",validationErrors:errors},400,corsHeaders)}const result=await async function(event,push){try{const result=await push(event);return{id:result?.event?.id}}catch(error){return{error:error instanceof Error?error.message:"Unknown error"}}}(validation.data,env.push);return result.error?(logger.error("Event processing failed",{error:result.error}),createJsonResponse({success:!1,error:result.error},400,corsHeaders)):createJsonResponse({success:!0,id:result.id,timestamp:Date.now()},200,corsHeaders)}return createJsonResponse({success:!1,error:"Method not allowed"},405,corsHeaders)}catch(error){logger.error("Internal server error",error);const corsHeaders=createCorsHeaders(settings.cors);return createJsonResponse({success:!1,error:error instanceof Error?error.message:"Internal server error"},500,corsHeaders)}}}};//# sourceMappingURL=index.js.map
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- var e=Object.defineProperty,t=(t,r)=>{for(var s in r)e(t,s,{get:r[s],enumerable:!0})};import{requestToData as r,isObject as s,isDefined as o}from"@walkeros/core";var a={};t(a,{CorsOptionsSchema:()=>l,CorsOrigin:()=>c,EventSchema:()=>b,HttpMethod:()=>i,SettingsSchema:()=>d});import{z as n}from"@walkeros/core/dev";var i=n.enum(["GET","POST","PUT","PATCH","DELETE","OPTIONS","HEAD"]),c=n.union([n.string(),n.array(n.string()),n.literal("*")]),l=n.object({origin:c.optional(),methods:n.array(i).optional(),headers:n.array(n.string()).optional(),credentials:n.boolean().optional(),maxAge:n.number().int().positive().optional()});import{z as u}from"@walkeros/core/dev";var d=u.object({path:u.string().default("/collect"),cors:u.union([u.boolean(),l]).default(!0),healthPath:u.string().default("/health"),maxRequestSize:u.number().int().positive().default(102400),maxBatchSize:u.number().int().positive().default(100)});import{z as p}from"@walkeros/core/dev";var m=p.record(p.string(),p.union([p.string(),p.number(),p.boolean(),p.record(p.string(),p.any())])),g=p.record(p.string(),p.tuple([p.union([p.string(),p.number(),p.boolean(),p.record(p.string(),p.any())]),p.number()])),h=p.object({id:p.string().optional(),device:p.string().optional(),session:p.string().optional(),email:p.string().optional(),hash:p.string().optional()}).passthrough(),f=p.record(p.string(),p.boolean()),y=p.lazy(()=>p.object({entity:p.string(),data:m.optional(),nested:p.array(y).optional(),context:g.optional()}).passthrough()),A=p.object({source:p.string(),tagging:p.number()}),v=p.object({type:p.string(),id:p.string(),previous_id:p.string()}).passthrough(),b=p.object({name:p.string().min(1,"Event name is required"),data:m.optional(),context:g.optional(),globals:m.optional(),custom:m.optional(),user:h.optional(),nested:p.array(y).optional(),consent:f.optional(),id:p.string().optional(),trigger:p.string().optional(),entity:p.string().optional(),action:p.string().optional(),timestamp:p.number().optional(),timing:p.number().optional(),group:p.string().optional(),count:p.number().optional(),version:A.optional(),source:v.optional()}).passthrough();function x(e=!0,t){const r=new Headers;if(!1===e)return r;if(!0===e)r.set("Access-Control-Allow-Origin","*"),r.set("Access-Control-Allow-Methods","GET, POST, OPTIONS"),r.set("Access-Control-Allow-Headers","Content-Type");else{if(e.origin){let s;s=Array.isArray(e.origin)?t&&e.origin.includes(t)?t:e.origin[0]:e.origin,r.set("Access-Control-Allow-Origin",s)}e.methods&&r.set("Access-Control-Allow-Methods",e.methods.join(", ")),e.headers&&r.set("Access-Control-Allow-Headers",e.headers.join(", ")),e.credentials&&r.set("Access-Control-Allow-Credentials","true"),e.maxAge&&r.set("Access-Control-Max-Age",String(e.maxAge))}return r}var S="R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";function w(e){const t=atob(S),r=new Uint8Array(t.length);for(let e=0;e<t.length;e++)r[e]=t.charCodeAt(e);const s=new Headers(e);return s.set("Content-Type","image/gif"),s.set("Cache-Control","no-cache, no-store, must-revalidate"),new Response(r,{status:200,headers:s})}function O(e,t=200,r){const s=new Headers(r);return s.set("Content-Type","application/json"),new Response(JSON.stringify(e),{status:t,headers:s})}var R={},T={};t(T,{inputs:()=>C,requests:()=>k});var C={};t(C,{batch:()=>j,completeEvent:()=>q,minimal:()=>z,pageView:()=>P,productAdd:()=>E});var P={name:"page view",data:{title:"Home Page",path:"/",referrer:"https://google.com"},user:{id:"user-123",session:"session-456"},timestamp:17e11},E={name:"product add",data:{id:"P-123",name:"Laptop",price:999.99,quantity:1},context:{stage:["shopping",1]},globals:{language:"en",currency:"USD"},user:{id:"user-123"},nested:[{entity:"category",data:{name:"Electronics",path:"/electronics"}}],consent:{functional:!0,marketing:!0}},q={name:"order complete",data:{id:"ORDER-123",total:999.99,currency:"USD"},context:{stage:["checkout",3],test:["variant-A",0]},globals:{language:"en",country:"US"},custom:{campaignId:"summer-sale",source:"email"},user:{id:"user-123",email:"user@example.com",session:"session-456"},nested:[{entity:"product",data:{id:"P-123",price:999.99}}],consent:{functional:!0,marketing:!0,analytics:!1},trigger:"click",group:"ecommerce"},z={name:"ping"},j=[P,E,{name:"button click",data:{id:"cta"}}],k={};t(k,{batchPostRequest:()=>I,healthCheckRequest:()=>N,invalidJsonRequest:()=>U,optionsRequest:()=>D,oversizedRequest:()=>J,pixelGetRequest:()=>B,validPostRequest:()=>H});var H={method:"POST",url:"https://example.com/collect",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:"page view",data:{title:"Home"}})},I={method:"POST",url:"https://example.com/collect",headers:{"Content-Type":"application/json"},body:JSON.stringify({batch:[{name:"page view",data:{title:"Home"}},{name:"button click",data:{id:"cta"}}]})},B={method:"GET",url:"https://example.com/collect?event=page%20view&data[title]=Home&user[id]=user123"},N={method:"GET",url:"https://example.com/health"},D={method:"OPTIONS",url:"https://example.com/collect",headers:{Origin:"https://example.com"}},U={method:"POST",url:"https://example.com/collect",headers:{"Content-Type":"application/json"},body:"invalid json{"},J={method:"POST",url:"https://example.com/collect",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:"test",data:{payload:"x".repeat(2e5)}})},M=async(e,t)=>{const a=d.parse(e.settings||{}),{logger:n}=t;return{type:"fetch",config:{...e,settings:a},push:async e=>{Date.now();try{const i=new URL(e.url),c=e.method.toUpperCase(),l=e.headers.get("Origin"),u=x(a.cors,l);if(a.healthPath&&i.pathname===a.healthPath)return O({status:"ok",timestamp:Date.now(),source:"fetch"},200,u);if("OPTIONS"===c)return new Response(null,{status:204,headers:u});if("GET"===c){const e=r(i.search);return e&&s(e)&&await t.push(e),w(u)}if("POST"===c){const r=e.headers.get("Content-Length");if(r){const e=parseInt(r,10);if(e>a.maxRequestSize)return n.error("Request too large",{size:e,limit:a.maxRequestSize}),O({success:!1,error:`Request too large. Maximum size: ${a.maxRequestSize} bytes`},413,u)}let i,c;try{if(c=await e.text(),c.length>a.maxRequestSize)return n.error("Request body too large",{size:c.length,limit:a.maxRequestSize}),O({success:!1,error:`Request too large. Maximum size: ${a.maxRequestSize} bytes`},413,u);i=JSON.parse(c)}catch(e){return n.error("Failed to parse JSON",e),O({success:!1,error:"Invalid JSON body"},400,u)}if(!o(i)||!s(i))return n.error("Invalid event body type"),O({success:!1,error:"Invalid event: body must be an object"},400,u);if("batch"in i&&Array.isArray(i.batch)){const e=i.batch;if(e.length>a.maxBatchSize)return n.error("Batch too large",{size:e.length,limit:a.maxBatchSize}),O({success:!1,error:`Batch too large. Maximum size: ${a.maxBatchSize} events`},400,u);const r=await async function(e,t,r){const s={successful:0,failed:0,ids:[],errors:[]};for(let o=0;o<e.length;o++){const a=e[o],n=b.safeParse(a);if(n.success)try{const e=await t(n.data);e?.event?.id&&s.ids.push(e.event.id),s.successful++}catch(e){s.failed++,s.errors.push({index:o,error:e instanceof Error?e.message:"Unknown error"}),r.error(`Batch event ${o} processing failed`,e)}else s.failed++,s.errors.push({index:o,error:`Validation failed: ${n.error.issues[0].message}`}),r.error(`Batch event ${o} validation failed`,{errors:n.error.issues})}return s}(e,t.push,n);return r.failed>0?O({success:!1,processed:r.successful,failed:r.failed,errors:r.errors},207,u):O({success:!0,processed:r.successful,ids:r.ids},200,u)}const l=b.safeParse(i);if(!l.success){const e=l.error.issues.map(e=>({path:e.path.join("."),message:e.message}));return n.error("Event validation failed",{errors:e}),O({success:!1,error:"Event validation failed",validationErrors:e},400,u)}const d=await async function(e,t){try{const r=await t(e);return{id:r?.event?.id}}catch(e){return{error:e instanceof Error?e.message:"Unknown error"}}}(l.data,t.push);return d.error?(n.error("Event processing failed",{error:d.error}),O({success:!1,error:d.error},400,u)):O({success:!0,id:d.id,timestamp:Date.now()},200,u)}return O({success:!1,error:"Method not allowed"},405,u)}catch(e){n.error("Internal server error",e);const t=x(a.cors);return O({success:!1,error:e instanceof Error?e.message:"Internal server error"},500,t)}}}};export{R as SourceFetch,S as TRANSPARENT_GIF_BASE64,x as createCorsHeaders,O as createJsonResponse,w as createPixelResponse,T as examples,a as schemas,M as sourceFetch};//# sourceMappingURL=index.mjs.map
1
+ var __defProp=Object.defineProperty,__export=(target,all)=>{for(var name in all)__defProp(target,name,{get:all[name],enumerable:!0})};import{requestToData,isObject,isDefined}from"@walkeros/core";var schemas_exports={};__export(schemas_exports,{CorsOptionsSchema:()=>CorsOptionsSchema,CorsOrigin:()=>CorsOrigin,EventSchema:()=>EventSchema,HttpMethod:()=>HttpMethod,SettingsSchema:()=>SettingsSchema});import{z}from"@walkeros/core/dev";var HttpMethod=z.enum(["GET","POST","PUT","PATCH","DELETE","OPTIONS","HEAD"]),CorsOrigin=z.union([z.string(),z.array(z.string()),z.literal("*")]),CorsOptionsSchema=z.object({origin:CorsOrigin.optional(),methods:z.array(HttpMethod).optional(),headers:z.array(z.string()).optional(),credentials:z.boolean().optional(),maxAge:z.number().int().positive().optional()});import{z as z2}from"@walkeros/core/dev";var SettingsSchema=z2.object({path:z2.string().default("/collect"),cors:z2.union([z2.boolean(),CorsOptionsSchema]).default(!0),healthPath:z2.string().default("/health"),maxRequestSize:z2.number().int().positive().default(102400),maxBatchSize:z2.number().int().positive().default(100)});import{z as z3}from"@walkeros/core/dev";var PropertiesSchema=z3.record(z3.string(),z3.union([z3.string(),z3.number(),z3.boolean(),z3.record(z3.string(),z3.any())])),OrderedPropertiesSchema=z3.record(z3.string(),z3.tuple([z3.union([z3.string(),z3.number(),z3.boolean(),z3.record(z3.string(),z3.any())]),z3.number()])),UserSchema=z3.object({id:z3.string().optional(),device:z3.string().optional(),session:z3.string().optional(),email:z3.string().optional(),hash:z3.string().optional()}).passthrough(),ConsentSchema=z3.record(z3.string(),z3.boolean()),EntitySchema=z3.lazy(()=>z3.object({entity:z3.string(),data:PropertiesSchema.optional(),nested:z3.array(EntitySchema).optional(),context:OrderedPropertiesSchema.optional()}).passthrough()),VersionSchema=z3.object({source:z3.string(),tagging:z3.number()}),SourceSchema=z3.object({type:z3.string(),id:z3.string(),previous_id:z3.string()}).passthrough(),EventSchema=z3.object({name:z3.string().min(1,"Event name is required"),data:PropertiesSchema.optional(),context:OrderedPropertiesSchema.optional(),globals:PropertiesSchema.optional(),custom:PropertiesSchema.optional(),user:UserSchema.optional(),nested:z3.array(EntitySchema).optional(),consent:ConsentSchema.optional(),id:z3.string().optional(),trigger:z3.string().optional(),entity:z3.string().optional(),action:z3.string().optional(),timestamp:z3.number().optional(),timing:z3.number().optional(),group:z3.string().optional(),count:z3.number().optional(),version:VersionSchema.optional(),source:SourceSchema.optional()}).passthrough();function createCorsHeaders(corsConfig=!0,requestOrigin){const headers=new Headers;if(!1===corsConfig)return headers;if(!0===corsConfig)headers.set("Access-Control-Allow-Origin","*"),headers.set("Access-Control-Allow-Methods","GET, POST, OPTIONS"),headers.set("Access-Control-Allow-Headers","Content-Type");else{if(corsConfig.origin){let origin;origin=Array.isArray(corsConfig.origin)?requestOrigin&&corsConfig.origin.includes(requestOrigin)?requestOrigin:corsConfig.origin[0]:corsConfig.origin,headers.set("Access-Control-Allow-Origin",origin)}corsConfig.methods&&headers.set("Access-Control-Allow-Methods",corsConfig.methods.join(", ")),corsConfig.headers&&headers.set("Access-Control-Allow-Headers",corsConfig.headers.join(", ")),corsConfig.credentials&&headers.set("Access-Control-Allow-Credentials","true"),corsConfig.maxAge&&headers.set("Access-Control-Max-Age",String(corsConfig.maxAge))}return headers}var TRANSPARENT_GIF_BASE64="R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";function createPixelResponse(corsHeaders){const binaryString=atob("R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"),bytes=new Uint8Array(binaryString.length);for(let i=0;i<binaryString.length;i++)bytes[i]=binaryString.charCodeAt(i);const headers=new Headers(corsHeaders);return headers.set("Content-Type","image/gif"),headers.set("Cache-Control","no-cache, no-store, must-revalidate"),new Response(bytes,{status:200,headers:headers})}function createJsonResponse(body,status=200,corsHeaders){const headers=new Headers(corsHeaders);return headers.set("Content-Type","application/json"),new Response(JSON.stringify(body),{status:status,headers:headers})}var types_exports={},examples_exports={};__export(examples_exports,{inputs:()=>inputs_exports,requests:()=>requests_exports});var inputs_exports={};__export(inputs_exports,{batch:()=>batch,completeEvent:()=>completeEvent,minimal:()=>minimal,pageView:()=>pageView,productAdd:()=>productAdd});var pageView={name:"page view",data:{title:"Home Page",path:"/",referrer:"https://google.com"},user:{id:"user-123",session:"session-456"},timestamp:17e11},productAdd={name:"product add",data:{id:"P-123",name:"Laptop",price:999.99,quantity:1},context:{stage:["shopping",1]},globals:{language:"en",currency:"USD"},user:{id:"user-123"},nested:[{entity:"category",data:{name:"Electronics",path:"/electronics"}}],consent:{functional:!0,marketing:!0}},completeEvent={name:"order complete",data:{id:"ORDER-123",total:999.99,currency:"USD"},context:{stage:["checkout",3],test:["variant-A",0]},globals:{language:"en",country:"US"},custom:{campaignId:"summer-sale",source:"email"},user:{id:"user-123",email:"user@example.com",session:"session-456"},nested:[{entity:"product",data:{id:"P-123",price:999.99}}],consent:{functional:!0,marketing:!0,analytics:!1},trigger:"click",group:"ecommerce"},minimal={name:"ping"},batch=[pageView,productAdd,{name:"button click",data:{id:"cta"}}],requests_exports={};__export(requests_exports,{batchPostRequest:()=>batchPostRequest,healthCheckRequest:()=>healthCheckRequest,invalidJsonRequest:()=>invalidJsonRequest,optionsRequest:()=>optionsRequest,oversizedRequest:()=>oversizedRequest,pixelGetRequest:()=>pixelGetRequest,validPostRequest:()=>validPostRequest});var validPostRequest={method:"POST",url:"https://example.com/collect",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:"page view",data:{title:"Home"}})},batchPostRequest={method:"POST",url:"https://example.com/collect",headers:{"Content-Type":"application/json"},body:JSON.stringify({batch:[{name:"page view",data:{title:"Home"}},{name:"button click",data:{id:"cta"}}]})},pixelGetRequest={method:"GET",url:"https://example.com/collect?event=page%20view&data[title]=Home&user[id]=user123"},healthCheckRequest={method:"GET",url:"https://example.com/health"},optionsRequest={method:"OPTIONS",url:"https://example.com/collect",headers:{Origin:"https://example.com"}},invalidJsonRequest={method:"POST",url:"https://example.com/collect",headers:{"Content-Type":"application/json"},body:"invalid json{"},oversizedRequest={method:"POST",url:"https://example.com/collect",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:"test",data:{payload:"x".repeat(2e5)}})},sourceFetch=async(config,env)=>{const settings=SettingsSchema.parse(config.settings||{}),{logger:logger}=env;return{type:"fetch",config:{...config,settings:settings},push:async request=>{Date.now();try{const url=new URL(request.url),method=request.method.toUpperCase(),origin=request.headers.get("Origin"),corsHeaders=createCorsHeaders(settings.cors,origin);if(settings.healthPath&&url.pathname===settings.healthPath)return createJsonResponse({status:"ok",timestamp:Date.now(),source:"fetch"},200,corsHeaders);if("OPTIONS"===method)return new Response(null,{status:204,headers:corsHeaders});if("GET"===method){const parsedData=requestToData(url.search);return parsedData&&isObject(parsedData)&&await env.push(parsedData),createPixelResponse(corsHeaders)}if("POST"===method){const contentLength=request.headers.get("Content-Length");if(contentLength){const size=parseInt(contentLength,10);if(size>settings.maxRequestSize)return logger.error("Request too large",{size:size,limit:settings.maxRequestSize}),createJsonResponse({success:!1,error:`Request too large. Maximum size: ${settings.maxRequestSize} bytes`},413,corsHeaders)}let eventData,bodyText;try{if(bodyText=await request.text(),bodyText.length>settings.maxRequestSize)return logger.error("Request body too large",{size:bodyText.length,limit:settings.maxRequestSize}),createJsonResponse({success:!1,error:`Request too large. Maximum size: ${settings.maxRequestSize} bytes`},413,corsHeaders);eventData=JSON.parse(bodyText)}catch(error){return logger.error("Failed to parse JSON",error),createJsonResponse({success:!1,error:"Invalid JSON body"},400,corsHeaders)}if(!isDefined(eventData)||!isObject(eventData))return logger.error("Invalid event body type"),createJsonResponse({success:!1,error:"Invalid event: body must be an object"},400,corsHeaders);if("batch"in eventData&&Array.isArray(eventData.batch)){const batch2=eventData.batch;if(batch2.length>settings.maxBatchSize)return logger.error("Batch too large",{size:batch2.length,limit:settings.maxBatchSize}),createJsonResponse({success:!1,error:`Batch too large. Maximum size: ${settings.maxBatchSize} events`},400,corsHeaders);const results=await async function(events,push,logger){const results={successful:0,failed:0,ids:[],errors:[]};for(let i=0;i<events.length;i++){const event=events[i],validation=EventSchema.safeParse(event);if(validation.success)try{const result=await push(validation.data);result?.event?.id&&results.ids.push(result.event.id),results.successful++}catch(error){results.failed++,results.errors.push({index:i,error:error instanceof Error?error.message:"Unknown error"}),logger.error(`Batch event ${i} processing failed`,error)}else results.failed++,results.errors.push({index:i,error:`Validation failed: ${validation.error.issues[0].message}`}),logger.error(`Batch event ${i} validation failed`,{errors:validation.error.issues})}return results}(batch2,env.push,logger);return results.failed>0?createJsonResponse({success:!1,processed:results.successful,failed:results.failed,errors:results.errors},207,corsHeaders):createJsonResponse({success:!0,processed:results.successful,ids:results.ids},200,corsHeaders)}const validation=EventSchema.safeParse(eventData);if(!validation.success){const errors=validation.error.issues.map(issue=>({path:issue.path.join("."),message:issue.message}));return logger.error("Event validation failed",{errors:errors}),createJsonResponse({success:!1,error:"Event validation failed",validationErrors:errors},400,corsHeaders)}const result=await async function(event,push){try{const result=await push(event);return{id:result?.event?.id}}catch(error){return{error:error instanceof Error?error.message:"Unknown error"}}}(validation.data,env.push);return result.error?(logger.error("Event processing failed",{error:result.error}),createJsonResponse({success:!1,error:result.error},400,corsHeaders)):createJsonResponse({success:!0,id:result.id,timestamp:Date.now()},200,corsHeaders)}return createJsonResponse({success:!1,error:"Method not allowed"},405,corsHeaders)}catch(error){logger.error("Internal server error",error);const corsHeaders=createCorsHeaders(settings.cors);return createJsonResponse({success:!1,error:error instanceof Error?error.message:"Internal server error"},500,corsHeaders)}}}};export{types_exports as SourceFetch,TRANSPARENT_GIF_BASE64,createCorsHeaders,createJsonResponse,createPixelResponse,examples_exports as examples,schemas_exports as schemas,sourceFetch};//# sourceMappingURL=index.mjs.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@walkeros/server-source-fetch",
3
3
  "description": "Web Standard Fetch API source for walkerOS (Cloudflare Workers, Vercel Edge, Deno, Bun)",
4
- "version": "0.5.0",
4
+ "version": "0.6.0",
5
5
  "license": "MIT",
6
6
  "main": "./dist/index.js",
7
7
  "module": "./dist/index.mjs",
@@ -18,7 +18,7 @@
18
18
  "update": "npx npm-check-updates -u && npm update"
19
19
  },
20
20
  "dependencies": {
21
- "@walkeros/core": "*"
21
+ "@walkeros/core": "0.6.0"
22
22
  },
23
23
  "devDependencies": {},
24
24
  "repository": {