@walkeros/server-source-gcp 4.4.0-next-1785285516008 → 4.5.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/CHANGELOG.md CHANGED
@@ -1,15 +1,58 @@
1
1
  # @walkeros/server-source-gcp
2
2
 
3
- ## 4.4.0-next-1785285516008
3
+ ## 4.5.0
4
4
 
5
5
  ### Patch Changes
6
6
 
7
+ - 9fef968: The AWS Lambda and GCP Cloud Functions sources now forward every
8
+ field of the incoming request body to the collector, not just `event`, `data`,
9
+ `context`, `user`, `globals`, and `consent`. Fields such as `source` (release
10
+ and trace provenance) ride through and accumulate across crossings, matching
11
+ the Express and Fetch sources; as with those sources, a client can also supply
12
+ `id`, `timestamp`, `consent`, `user`, and `source`, which the collector treats
13
+ as values rather than overriding. Both sources now accept `name` as the
14
+ event-name field, the walkerOS standard; `{"event": "..."}` keeps working as a
15
+ legacy alias and is removed at the next major.
16
+ - 79cdcb0: Server sources answer rejected client input with 4xx JSON instead of
17
+ unhandled errors or 500s: unparseable bodies return 400 at the HTTP boundary,
18
+ and invalid events return 400 with the reason wherever the response is still
19
+ open (synchronous handling; in the express default respond-first mode the 200
20
+ ack has already been sent, so the rejection surfaces as a warn and a counter
21
+ instead) (`push` resolves `{ok: false, invalid: true, error}`). Genuine
22
+ pipeline failures return 500 instead of `success: true`. Invalid input now
23
+ counts on `collector.status.sources.<id>.rejected` instead of inflating
24
+ `status.failed`. The express source no longer sends `X-Powered-By` and now
25
+ sets `X-Content-Type-Options: nosniff` on every response.
26
+ - 756b571: Server sources now share one request scope and one event envelope, so
27
+ `config.ingest` paths and POST body forms behave identically on Express,
28
+ Fetch, Lambda and Cloud Functions. Batches and bare arrays are accepted
29
+ everywhere, and a destination before-chain fan-out no longer drops all but the
30
+ first event. Breaking: AWS `requestContext.*` moves under `raw.*`, Express
31
+ drops `protocol` and `hostname`, and Fetch `{ fn }` header mappings become
32
+ `{ key: 'headers.*' }`. See the migration guide.
33
+ - Updated dependencies [63845bb]
34
+ - Updated dependencies [79cdcb0]
35
+ - Updated dependencies [756b571]
36
+ - @walkeros/core@4.5.0
37
+ - @walkeros/collector@4.5.0
38
+
39
+ ## 4.4.0
40
+
41
+ ### Patch Changes
42
+
43
+ - 034b1de: Events pushed before the collector runs are now held and replayed at
44
+ run instead of being dropped, bounded by `queueMax`. `walker init <element>`
45
+ re-fires load triggers for already-tracked elements, restoring the SPA re-init
46
+ pattern. Queue sources start consuming at run and no longer acknowledge
47
+ messages the pipeline did not accept.
7
48
  - Updated dependencies [393b942]
8
49
  - Updated dependencies [6c89afb]
9
50
  - Updated dependencies [393b942]
10
51
  - Updated dependencies [35756dd]
11
- - @walkeros/collector@4.4.0-next-1785285516008
12
- - @walkeros/core@4.4.0-next-1785285516008
52
+ - Updated dependencies [034b1de]
53
+ - Updated dependencies [d00e2bd]
54
+ - @walkeros/collector@4.4.0
55
+ - @walkeros/core@4.4.0
13
56
 
14
57
  ## 4.3.2
15
58
 
package/dist/dev.d.mts CHANGED
@@ -63,6 +63,8 @@ declare const SettingsSchema$2: z.ZodObject<{
63
63
  credentials: z.ZodOptional<z.ZodBoolean>;
64
64
  maxAge: z.ZodOptional<z.ZodNumber>;
65
65
  }, z.core.$strip>]>>;
66
+ maxBatchSize: z.ZodDefault<z.ZodNumber>;
67
+ enablePixelTracking: z.ZodDefault<z.ZodBoolean>;
66
68
  timeout: z.ZodOptional<z.ZodNumber>;
67
69
  }, z.core.$strip>;
68
70
  type Settings$2 = z.infer<typeof SettingsSchema$2>;
@@ -90,6 +92,11 @@ interface Request$1 {
90
92
  body?: unknown;
91
93
  headers: Record<string, string | string[]>;
92
94
  get(name: string): string | undefined;
95
+ path?: string;
96
+ originalUrl?: string;
97
+ url?: string;
98
+ protocol?: string;
99
+ ip?: string;
93
100
  }
94
101
  interface Response$1 {
95
102
  status(code: number): Response$1;
@@ -116,11 +123,13 @@ declare namespace env$2 {
116
123
 
117
124
  declare const postEvent: Flow.StepExample;
118
125
  declare const orderEvent: Flow.StepExample;
126
+ declare const cloudFunctionPostForwardsSource: Flow.StepExample;
119
127
 
128
+ declare const step$2_cloudFunctionPostForwardsSource: typeof cloudFunctionPostForwardsSource;
120
129
  declare const step$2_orderEvent: typeof orderEvent;
121
130
  declare const step$2_postEvent: typeof postEvent;
122
131
  declare namespace step$2 {
123
- export { step$2_orderEvent as orderEvent, step$2_postEvent as postEvent };
132
+ export { step$2_cloudFunctionPostForwardsSource as cloudFunctionPostForwardsSource, step$2_orderEvent as orderEvent, step$2_postEvent as postEvent };
124
133
  }
125
134
 
126
135
  interface Content$2 {
package/dist/dev.d.ts CHANGED
@@ -63,6 +63,8 @@ declare const SettingsSchema$2: z.ZodObject<{
63
63
  credentials: z.ZodOptional<z.ZodBoolean>;
64
64
  maxAge: z.ZodOptional<z.ZodNumber>;
65
65
  }, z.core.$strip>]>>;
66
+ maxBatchSize: z.ZodDefault<z.ZodNumber>;
67
+ enablePixelTracking: z.ZodDefault<z.ZodBoolean>;
66
68
  timeout: z.ZodOptional<z.ZodNumber>;
67
69
  }, z.core.$strip>;
68
70
  type Settings$2 = z.infer<typeof SettingsSchema$2>;
@@ -90,6 +92,11 @@ interface Request$1 {
90
92
  body?: unknown;
91
93
  headers: Record<string, string | string[]>;
92
94
  get(name: string): string | undefined;
95
+ path?: string;
96
+ originalUrl?: string;
97
+ url?: string;
98
+ protocol?: string;
99
+ ip?: string;
93
100
  }
94
101
  interface Response$1 {
95
102
  status(code: number): Response$1;
@@ -116,11 +123,13 @@ declare namespace env$2 {
116
123
 
117
124
  declare const postEvent: Flow.StepExample;
118
125
  declare const orderEvent: Flow.StepExample;
126
+ declare const cloudFunctionPostForwardsSource: Flow.StepExample;
119
127
 
128
+ declare const step$2_cloudFunctionPostForwardsSource: typeof cloudFunctionPostForwardsSource;
120
129
  declare const step$2_orderEvent: typeof orderEvent;
121
130
  declare const step$2_postEvent: typeof postEvent;
122
131
  declare namespace step$2 {
123
- export { step$2_orderEvent as orderEvent, step$2_postEvent as postEvent };
132
+ export { step$2_cloudFunctionPostForwardsSource as cloudFunctionPostForwardsSource, step$2_orderEvent as orderEvent, step$2_postEvent as postEvent };
124
133
  }
125
134
 
126
135
  interface Content$2 {
package/dist/dev.js CHANGED
@@ -1 +1 @@
1
- "use strict";var e,t=Object.defineProperty,o=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,s=Object.prototype.hasOwnProperty,i=(e,o)=>{for(var r in o)t(e,r,{get:o[r],enumerable:!0})},n={};i(n,{examples:()=>f,pubsubPullExamples:()=>J,pubsubPullSchemas:()=>T,pubsubPushExamples:()=>oe,pubsubPushSchemas:()=>Y,schemas:()=>a}),module.exports=(e=n,((e,i,n,a)=>{if(i&&"object"==typeof i||"function"==typeof i)for(let c of r(i))s.call(e,c)||c===n||t(e,c,{get:()=>i[c],enumerable:!(a=o(i,c))||a.enumerable});return e})(t({},"__esModule",{value:!0}),e));var a={};i(a,{CorsOptionsSchema:()=>b,CorsOrigin:()=>p,HttpMethod:()=>u,SettingsSchema:()=>m,settings:()=>g});var c=require("@walkeros/core/dev"),l=require("@walkeros/core/dev"),d=require("@walkeros/core/dev"),u=d.z.enum(["GET","POST","PUT","PATCH","DELETE","OPTIONS","HEAD"]),p=d.z.union([d.z.string(),d.z.array(d.z.string()),d.z.literal("*")]),b=d.z.object({origin:p.describe("Allowed origins (* for all, URL string, or array of URLs)").optional(),methods:d.z.array(u).describe("Allowed HTTP methods").optional(),headers:d.z.array(d.z.string()).describe("Allowed request headers").optional(),credentials:d.z.boolean().describe("Allow credentials (cookies, authorization headers)").optional(),maxAge:d.z.number().int().positive().describe("Preflight cache duration in seconds").optional()}),m=l.z.object({cors:l.z.union([l.z.boolean(),b]).describe("CORS configuration: false = disabled, true = allow all origins, object = custom configuration").optional(),timeout:l.z.number().int().positive().max(54e4).describe("Request timeout in milliseconds (max: 540000 for GCP)").optional()}),g=(0,c.zodToSchema)(m),f={};i(f,{createTrigger:()=>P,env:()=>h,step:()=>z});var h={};i(h,{push:()=>S});var w=()=>()=>Promise.resolve({ok:!0}),y=()=>{},v={error:y,warn:y,info:y,debug:y,throw:e=>{throw"string"==typeof e?new Error(e):e},json:y,scope:()=>v},S={get push(){return w()},get command(){return w()},get elb(){return w()},logger:v},z={};i(z,{orderEvent:()=>O,postEvent:()=>k});var k={title:"POST event",description:"A GCP Cloud Function HTTP POST with a JSON body becomes a single walker elb event.",trigger:{type:"POST"},in:{method:"POST",body:{event:"page view",data:{title:"Home",url:"https://example.com/"}},headers:{"content-type":"application/json"}},out:[["elb",{name:"page view",data:{title:"Home",url:"https://example.com/"}}]]},O={title:"Order POST",description:"A Cloud Function HTTP POST carrying an order payload becomes a walker order complete event.",trigger:{type:"POST"},in:{method:"POST",body:{event:"order complete",data:{id:"ORD-700",total:99.99,currency:"EUR"}},headers:{"content-type":"application/json"}},out:[["elb",{name:"order complete",data:{id:"ORD-700",total:99.99,currency:"EUR"}}]]},j=require("@walkeros/collector");var P=async e=>{let t;return{get flow(){return t},trigger:()=>async o=>{if(!t){const o=await(0,j.startFlow)(e);t={collector:o.collector,elb:o.elb}}const r=function(e){for(const t of Object.values(e.sources||{}))if("cloudfunction"===t.type)return t}(t.collector);if(!r)throw new Error("CloudFunction source not found in collector — ensure it is configured in sources");const s={...o.body};s.name&&!s.event&&(s.event=s.name,delete s.name);const i=o.headers||{"content-type":"application/json"},n={method:o.method,body:s,headers:i,get:e=>i[e.toLowerCase()]};let a,c=200;const l={status:e=>(c=e,l),json:e=>(a=e,l),send:e=>(a=e,l),set:()=>l};return await r.push(n,l),{status:c,body:a}}}},T={};i(T,{SettingsSchema:()=>E,SetupSchema:()=>A,settings:()=>q,setup:()=>R});var D=require("@walkeros/core/dev"),x=require("@walkeros/core/dev"),E=x.z.object({client:x.z.any().describe("Pre-configured Google Cloud Pub/Sub client (like new PubSub({ projectId })). Bypasses credentials resolution when supplied.").optional(),projectId:x.z.string().min(1).describe("Google Cloud Project ID (like my-gcp-project)."),subscription:x.z.string().min(1).describe("Pub/Sub subscription short name (like events-sub). The full resource name projects/<projectId>/subscriptions/<subscription> is built by the SDK."),topic:x.z.string().describe("Pub/Sub topic short name. Required when setup.createTopic is true; otherwise informational.").optional(),credentials:x.z.any().describe("Service account credentials as a JSON string or an object with client_email and private_key. Default: Application Default Credentials (ADC). (deprecated: use config.credentials)").optional(),apiEndpoint:x.z.string().describe("Override Pub/Sub API endpoint. Useful for the local emulator (like localhost:8085).").optional(),decoder:x.z.enum(["json","text","raw"]).describe("Decoder for the message data field. json (default) parses JSON, text decodes UTF-8, raw forwards the Buffer.").optional(),flowControl:x.z.object({maxMessages:x.z.number().describe("Maximum in-flight messages. Default: 100.").optional(),maxBytes:x.z.number().describe("Maximum in-flight bytes. Default: 10485760 (10 MB).").optional()}).describe("Subscriber flow control. Tightens the SDK defaults.").optional(),ackDeadline:x.z.number().describe("Subscriber ack deadline in seconds. Default: 60.").optional(),shutdownTimeoutMs:x.z.number().describe("Graceful shutdown timeout in milliseconds. Default: 30000. After this window, destroy() force-closes the subscriber.").optional(),onPushError:x.z.enum(["nack","ack"]).describe("Behavior when forwarding to the collector throws. nack (default) redelivers the message; ack drops it.").optional()}),C=require("@walkeros/core/dev"),A=C.z.object({createTopic:C.z.boolean().describe("Create the topic if it does not exist. Requires settings.topic. Default: false (require pre-existing topic).").optional(),ackDeadlineSeconds:C.z.number().describe("Subscription ack deadline in seconds. Default: 60.").optional(),messageRetentionDuration:C.z.object({seconds:C.z.number().describe("Retention window in seconds. Default: project default.")}).describe("Subscription-level retention configuration.").optional(),filter:C.z.string().describe("Subscription filter expression. Only messages matching this filter are delivered.").optional(),deadLetterPolicy:C.z.object({deadLetterTopic:C.z.string().describe("Dead-letter topic short name."),maxDeliveryAttempts:C.z.number().describe("Maximum delivery attempts before forwarding to the dead-letter topic."),createDeadLetterTopic:C.z.boolean().describe("Auto-create the dead-letter topic if it does not exist. Default: false.").optional()}).describe("Dead-letter policy. Strongly recommended for production.").optional(),retryPolicy:C.z.object({minimumBackoff:C.z.object({seconds:C.z.number().describe("Minimum backoff in seconds.")}),maximumBackoff:C.z.object({seconds:C.z.number().describe("Maximum backoff in seconds.")})}).describe("Subscription retry policy.").optional(),enableMessageOrdering:C.z.boolean().describe("Enable message ordering on the subscription. Default: false.").optional(),labels:C.z.record(C.z.string(),C.z.string()).describe("Subscription labels for organization and billing.").optional(),expirationPolicy:C.z.object({ttl:C.z.object({seconds:C.z.number().describe("TTL in seconds. null means never expire.")}).nullable().optional()}).describe("Subscription expiration policy.").optional()}),q=(0,D.zodToSchema)(E),R=(0,D.zodToSchema)(A),J={};i(J,{createTrigger:()=>X,env:()=>N,step:()=>F});var N={};i(N,{push:()=>B,simulation:()=>L});var M=()=>{},I={error:M,warn:M,info:M,debug:M,throw:e=>{throw"string"==typeof e?new Error(e):e},json:M,scope:()=>I},U=()=>()=>Promise.resolve({ok:!0}),B={get push(){return U()},get command(){return U()},get elb(){return U()},logger:I},L=["PubSub"],F={};i(F,{decoderText:()=>_,malformedJson:()=>K,malformedJsonAck:()=>V,orderComplete:()=>G,pageView:()=>H});var H={title:"Page view",description:"A JSON-encoded page view event arrives on the subscription, decodes successfully, and is acked.",in:{id:"msg-1",dataString:JSON.stringify({name:"page view",data:{title:"Documentation",url:"https://example.com/docs"}}),attributes:{}},out:[["message.ack","msg-1"]]},G={title:"Order complete",description:"A JSON-encoded order event arrives and is acked after successful collector forwarding.",in:{id:"msg-2",dataString:JSON.stringify({name:"order complete",data:{id:"ORD-500",total:199.99,currency:"EUR"}}),attributes:{entity:"order",action:"complete"}},out:[["message.ack","msg-2"]]},_={title:"Text decoder",description:"With decoder=text on the source settings, the message data is forwarded to the collector as a UTF-8 string and acked.",in:{id:"msg-3",dataString:"plain text payload",attributes:{}},out:[["message.ack","msg-3"]]},K={title:"Malformed JSON nack",description:"A non-JSON body with the default json decoder fails to decode; the message is nacked for redelivery.",in:{id:"msg-4",dataString:"not-json{",attributes:{}},out:[["message.nack","msg-4"]]},V={title:"Malformed JSON ack-and-drop",description:"With onPushError=ack on the source settings, a malformed JSON message is acked-and-dropped instead of redelivered.",in:{id:"msg-5",dataString:"not-json{",attributes:{}},out:[["message.ack","msg-5"]]},W=require("@walkeros/collector");function Q(e){if("object"!=typeof e||null===e)return!1;const t=e;return"pubsub-pull"===t.type&&"function"==typeof t.push}var X=async e=>{let t;return{get flow(){return t},trigger:()=>async o=>{if(!t){const o=await(0,W.startFlow)(e);t={collector:o.collector,elb:o.elb}}const r=function(e){for(const t of Object.values(e.sources??{}))if(Q(t))return t}(t.collector);if(!r)throw new Error("pubsub-pull source not registered in collector — ensure it is configured in sources");const s={id:o.id,data:Buffer.from(o.dataString,"utf8"),attributes:o.attributes,orderingKey:o.orderingKey},i=await r.push(s),n=[];return i&&"object"==typeof i&&(i.acked&&n.push(["message.ack",o.id]),i.nacked&&n.push(["message.nack",o.id])),n}}},Y={};i(Y,{SettingsSchema:()=>ee,settings:()=>te});var Z=require("@walkeros/core/dev"),$=require("@walkeros/core/dev"),ee=$.z.object({projectId:$.z.string().describe("Google Cloud Project ID (informational, surfaced in error messages).").optional(),decoder:$.z.enum(["json","text","raw"]).describe("Decoder for the message data field. json (default) parses JSON, text decodes UTF-8, raw forwards the Buffer.").optional(),verifyOidc:$.z.boolean().describe("Verify the OIDC bearer token Pub/Sub attaches to push requests. Default: false.").optional(),audience:$.z.string().describe("OIDC audience (your endpoint URL or a custom audience). Required when verifyOidc is true.").optional()}),te=(0,Z.zodToSchema)(ee),oe={};i(oe,{createTrigger:()=>fe,env:()=>re,step:()=>le});var re={};i(re,{push:()=>ae,simulation:()=>ce});var se=()=>{},ie={error:se,warn:se,info:se,debug:se,throw:e=>{throw"string"==typeof e?new Error(e):e},json:se,scope:()=>ie},ne=()=>()=>Promise.resolve({ok:!0}),ae={get push(){return ne()},get command(){return ne()},get elb(){return ne()},logger:ie},ce=[],le={};i(le,{malformedEnvelope:()=>be,orderEnvelope:()=>pe,validEnvelope:()=>ue});function de(e){return Buffer.from(JSON.stringify(e),"utf8").toString("base64")}var ue={title:"Valid push envelope",description:"A well-formed Pub/Sub push envelope decodes the base64 data, parses JSON, and forwards the event to the collector with a 200 response.",in:{message:{messageId:"push-1",data:de({name:"page view",data:{title:"Documentation",url:"https://example.com/docs"}}),attributes:{source:"analytics"}},subscription:"projects/test/subscriptions/events-sub"},out:[["response",200,{success:!0,id:"push-1"}]]},pe={title:"Order envelope",description:"A push envelope carrying an order event is decoded and forwarded to the collector.",in:{message:{messageId:"push-2",data:de({name:"order complete",data:{id:"ORD-500",total:199.99,currency:"EUR"}}),attributes:{}},subscription:"projects/test/subscriptions/events-sub"},out:[["response",200,{success:!0,id:"push-2"}]]},be={title:"Malformed envelope",description:"A POST body lacking message.messageId returns 400 Bad Request without forwarding to the collector.",in:{not_a:"pubsub envelope"},out:[["response",400,{success:!1,error:"Malformed Pub/Sub envelope (missing message.messageId)."}]]},me=require("@walkeros/collector");function ge(e){if("object"!=typeof e||null===e)return!1;const t=e;return"string"==typeof t.type&&"pubsub-push"===t.type&&"function"==typeof t.push}var fe=async e=>{let t;return{get flow(){return t},trigger:(o,r)=>async o=>{if(!t){const o=await(0,me.startFlow)(e);t={collector:o.collector,elb:o.elb}}const s=("object"==typeof r&&null!==r?r:{}).headers??{},i=function(e){for(const t of Object.values(e.sources??{}))if(ge(t))return t}(t.collector);if(!i)throw new Error("pubsub-push source not registered");const n={},a=function(e,t){return{method:"POST",body:e,headers:t,get:e=>t[e.toLowerCase()]??t[e]}}(o,s),c=function(e){const t={status:o=>(e.statusCode=o,t),json:o=>(e.body=o,t),send:o=>(e.body=o,t),set:()=>t};return t}(n);await i.push(a,c);return[["response",n.statusCode??0,n.body??null]]}}};//# sourceMappingURL=dev.js.map
1
+ "use strict";var e,t=Object.defineProperty,o=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,s=Object.prototype.hasOwnProperty,i=(e,o)=>{for(var r in o)t(e,r,{get:o[r],enumerable:!0})},n={};i(n,{examples:()=>f,pubsubPullExamples:()=>M,pubsubPullSchemas:()=>x,pubsubPushExamples:()=>re,pubsubPushSchemas:()=>Z,schemas:()=>a}),module.exports=(e=n,((e,i,n,a)=>{if(i&&"object"==typeof i||"function"==typeof i)for(let c of r(i))s.call(e,c)||c===n||t(e,c,{get:()=>i[c],enumerable:!(a=o(i,c))||a.enumerable});return e})(t({},"__esModule",{value:!0}),e));var a={};i(a,{CorsOptionsSchema:()=>b,CorsOrigin:()=>p,HttpMethod:()=>u,SettingsSchema:()=>m,settings:()=>g});var c=require("@walkeros/core/dev"),l=require("@walkeros/core/dev"),d=require("@walkeros/core/dev"),u=d.z.enum(["GET","POST","PUT","PATCH","DELETE","OPTIONS","HEAD"]),p=d.z.union([d.z.string(),d.z.array(d.z.string()),d.z.literal("*")]),b=d.z.object({origin:p.describe("Allowed origins (* for all, URL string, or array of URLs)").optional(),methods:d.z.array(u).describe("Allowed HTTP methods").optional(),headers:d.z.array(d.z.string()).describe("Allowed request headers").optional(),credentials:d.z.boolean().describe("Allow credentials (cookies, authorization headers)").optional(),maxAge:d.z.number().int().positive().describe("Preflight cache duration in seconds").optional()}),m=l.z.object({cors:l.z.union([l.z.boolean(),b]).describe("CORS configuration: false = disabled, true = allow all origins, object = custom configuration").optional(),maxBatchSize:l.z.number().int().min(1).describe("Maximum number of events accepted in a single batch request").default(100),enablePixelTracking:l.z.boolean().describe("Serve a tracking pixel for GET requests").default(!0),timeout:l.z.number().int().positive().max(54e4).describe("Request timeout in milliseconds (max: 540000 for GCP)").optional()}),g=(0,c.zodToSchema)(m),f={};i(f,{createTrigger:()=>T,env:()=>h,step:()=>z});var h={};i(h,{push:()=>S});var w=()=>()=>Promise.resolve({ok:!0}),y=()=>{},v={error:y,warn:y,info:y,debug:y,throw:e=>{throw"string"==typeof e?new Error(e):e},json:y,scope:()=>v},S={get push(){return w()},get command(){return w()},get elb(){return w()},logger:v},z={};i(z,{cloudFunctionPostForwardsSource:()=>P,orderEvent:()=>k,postEvent:()=>O});var O={title:"POST event",description:"A GCP Cloud Function HTTP POST with a JSON body becomes a single walker elb event.",trigger:{type:"POST"},in:{method:"POST",body:{name:"page view",data:{title:"Home",url:"https://example.com/"}},headers:{"content-type":"application/json"}},out:[["elb",{name:"page view",data:{title:"Home",url:"https://example.com/"}}]]},k={title:"Order POST",description:"A Cloud Function HTTP POST carrying an order payload becomes a walker order complete event.",trigger:{type:"POST"},in:{method:"POST",body:{name:"order complete",data:{id:"ORD-700",total:99.99,currency:"EUR"}},headers:{"content-type":"application/json"}},out:[["elb",{name:"order complete",data:{id:"ORD-700",total:99.99,currency:"EUR"}}]]},P={title:"POST with provenance",description:"A POST body carrying a source map is forwarded in full, so release and trace provenance survive the crossing.",trigger:{type:"POST"},in:{method:"POST",body:{name:"page view",data:{title:"Home"},source:{release:{web:"r1"}}},headers:{"content-type":"application/json"}},out:[["elb",{name:"page view",data:{title:"Home"},source:{release:{web:"r1"}}}]]},j=require("@walkeros/collector");var T=async e=>{let t;return{get flow(){return t},trigger:()=>async o=>{if(!t){const o=await(0,j.startFlow)(e);t={collector:o.collector,elb:o.elb}}const r=function(e){for(const t of Object.values(e.sources||{}))if("cloudfunction"===t.type)return t}(t.collector);if(!r)throw new Error("CloudFunction source not found in collector — ensure it is configured in sources");const s={...o.body};s.name&&!s.event&&(s.event=s.name,delete s.name);const i=o.headers||{"content-type":"application/json"},n={method:o.method,body:s,headers:i,get:e=>i[e.toLowerCase()]};let a,c=200;const l={status:e=>(c=e,l),json:e=>(a=e,l),send:e=>(a=e,l),set:()=>l};return await r.push(n,l),{status:c,body:a}}}},x={};i(x,{SettingsSchema:()=>A,SetupSchema:()=>q,settings:()=>R,setup:()=>J});var D=require("@walkeros/core/dev"),E=require("@walkeros/core/dev"),A=E.z.object({client:E.z.any().describe("Pre-configured Google Cloud Pub/Sub client (like new PubSub({ projectId })). Bypasses credentials resolution when supplied.").optional(),projectId:E.z.string().min(1).describe("Google Cloud Project ID (like my-gcp-project)."),subscription:E.z.string().min(1).describe("Pub/Sub subscription short name (like events-sub). The full resource name projects/<projectId>/subscriptions/<subscription> is built by the SDK."),topic:E.z.string().describe("Pub/Sub topic short name. Required when setup.createTopic is true; otherwise informational.").optional(),credentials:E.z.any().describe("Service account credentials as a JSON string or an object with client_email and private_key. Default: Application Default Credentials (ADC). (deprecated: use config.credentials)").optional(),apiEndpoint:E.z.string().describe("Override Pub/Sub API endpoint. Useful for the local emulator (like localhost:8085).").optional(),decoder:E.z.enum(["json","text","raw"]).describe("Decoder for the message data field. json (default) parses JSON, text decodes UTF-8, raw forwards the Buffer.").optional(),flowControl:E.z.object({maxMessages:E.z.number().describe("Maximum in-flight messages. Default: 100.").optional(),maxBytes:E.z.number().describe("Maximum in-flight bytes. Default: 10485760 (10 MB).").optional()}).describe("Subscriber flow control. Tightens the SDK defaults.").optional(),ackDeadline:E.z.number().describe("Subscriber ack deadline in seconds. Default: 60.").optional(),shutdownTimeoutMs:E.z.number().describe("Graceful shutdown timeout in milliseconds. Default: 30000. After this window, destroy() force-closes the subscriber.").optional(),onPushError:E.z.enum(["nack","ack"]).describe("Behavior when forwarding to the collector throws. nack (default) redelivers the message; ack drops it.").optional()}),C=require("@walkeros/core/dev"),q=C.z.object({createTopic:C.z.boolean().describe("Create the topic if it does not exist. Requires settings.topic. Default: false (require pre-existing topic).").optional(),ackDeadlineSeconds:C.z.number().describe("Subscription ack deadline in seconds. Default: 60.").optional(),messageRetentionDuration:C.z.object({seconds:C.z.number().describe("Retention window in seconds. Default: project default.")}).describe("Subscription-level retention configuration.").optional(),filter:C.z.string().describe("Subscription filter expression. Only messages matching this filter are delivered.").optional(),deadLetterPolicy:C.z.object({deadLetterTopic:C.z.string().describe("Dead-letter topic short name."),maxDeliveryAttempts:C.z.number().describe("Maximum delivery attempts before forwarding to the dead-letter topic."),createDeadLetterTopic:C.z.boolean().describe("Auto-create the dead-letter topic if it does not exist. Default: false.").optional()}).describe("Dead-letter policy. Strongly recommended for production.").optional(),retryPolicy:C.z.object({minimumBackoff:C.z.object({seconds:C.z.number().describe("Minimum backoff in seconds.")}),maximumBackoff:C.z.object({seconds:C.z.number().describe("Maximum backoff in seconds.")})}).describe("Subscription retry policy.").optional(),enableMessageOrdering:C.z.boolean().describe("Enable message ordering on the subscription. Default: false.").optional(),labels:C.z.record(C.z.string(),C.z.string()).describe("Subscription labels for organization and billing.").optional(),expirationPolicy:C.z.object({ttl:C.z.object({seconds:C.z.number().describe("TTL in seconds. null means never expire.")}).nullable().optional()}).describe("Subscription expiration policy.").optional()}),R=(0,D.zodToSchema)(A),J=(0,D.zodToSchema)(q),M={};i(M,{createTrigger:()=>Y,env:()=>N,step:()=>L});var N={};i(N,{push:()=>F,simulation:()=>H});var I=()=>{},B={error:I,warn:I,info:I,debug:I,throw:e=>{throw"string"==typeof e?new Error(e):e},json:I,scope:()=>B},U=()=>()=>Promise.resolve({ok:!0}),F={get push(){return U()},get command(){return U()},get elb(){return U()},logger:B},H=["PubSub"],L={};i(L,{decoderText:()=>K,malformedJson:()=>V,malformedJsonAck:()=>W,orderComplete:()=>_,pageView:()=>G});var G={title:"Page view",description:"A JSON-encoded page view event arrives on the subscription, decodes successfully, and is acked.",in:{id:"msg-1",dataString:JSON.stringify({name:"page view",data:{title:"Documentation",url:"https://example.com/docs"}}),attributes:{}},out:[["message.ack","msg-1"]]},_={title:"Order complete",description:"A JSON-encoded order event arrives and is acked after successful collector forwarding.",in:{id:"msg-2",dataString:JSON.stringify({name:"order complete",data:{id:"ORD-500",total:199.99,currency:"EUR"}}),attributes:{entity:"order",action:"complete"}},out:[["message.ack","msg-2"]]},K={title:"Text decoder",description:"With decoder=text on the source settings, the message data is forwarded to the collector as a UTF-8 string and acked.",in:{id:"msg-3",dataString:"plain text payload",attributes:{}},out:[["message.ack","msg-3"]]},V={title:"Malformed JSON nack",description:"A non-JSON body with the default json decoder fails to decode; the message is nacked for redelivery.",in:{id:"msg-4",dataString:"not-json{",attributes:{}},out:[["message.nack","msg-4"]]},W={title:"Malformed JSON ack-and-drop",description:"With onPushError=ack on the source settings, a malformed JSON message is acked-and-dropped instead of redelivered.",in:{id:"msg-5",dataString:"not-json{",attributes:{}},out:[["message.ack","msg-5"]]},Q=require("@walkeros/collector");function X(e){if("object"!=typeof e||null===e)return!1;const t=e;return"pubsub-pull"===t.type&&"function"==typeof t.push}var Y=async e=>{let t;return{get flow(){return t},trigger:()=>async o=>{if(!t){const o=await(0,Q.startFlow)(e);t={collector:o.collector,elb:o.elb}}const r=function(e){for(const t of Object.values(e.sources??{}))if(X(t))return t}(t.collector);if(!r)throw new Error("pubsub-pull source not registered in collector — ensure it is configured in sources");const s={id:o.id,data:Buffer.from(o.dataString,"utf8"),attributes:o.attributes,orderingKey:o.orderingKey},i=await r.push(s),n=[];return i&&"object"==typeof i&&(i.acked&&n.push(["message.ack",o.id]),i.nacked&&n.push(["message.nack",o.id])),n}}},Z={};i(Z,{SettingsSchema:()=>te,settings:()=>oe});var $=require("@walkeros/core/dev"),ee=require("@walkeros/core/dev"),te=ee.z.object({projectId:ee.z.string().describe("Google Cloud Project ID (informational, surfaced in error messages).").optional(),decoder:ee.z.enum(["json","text","raw"]).describe("Decoder for the message data field. json (default) parses JSON, text decodes UTF-8, raw forwards the Buffer.").optional(),verifyOidc:ee.z.boolean().describe("Verify the OIDC bearer token Pub/Sub attaches to push requests. Default: false.").optional(),audience:ee.z.string().describe("OIDC audience (your endpoint URL or a custom audience). Required when verifyOidc is true.").optional()}),oe=(0,$.zodToSchema)(te),re={};i(re,{createTrigger:()=>he,env:()=>se,step:()=>de});var se={};i(se,{push:()=>ce,simulation:()=>le});var ie=()=>{},ne={error:ie,warn:ie,info:ie,debug:ie,throw:e=>{throw"string"==typeof e?new Error(e):e},json:ie,scope:()=>ne},ae=()=>()=>Promise.resolve({ok:!0}),ce={get push(){return ae()},get command(){return ae()},get elb(){return ae()},logger:ne},le=[],de={};i(de,{malformedEnvelope:()=>me,orderEnvelope:()=>be,validEnvelope:()=>pe});function ue(e){return Buffer.from(JSON.stringify(e),"utf8").toString("base64")}var pe={title:"Valid push envelope",description:"A well-formed Pub/Sub push envelope decodes the base64 data, parses JSON, and forwards the event to the collector with a 200 response.",in:{message:{messageId:"push-1",data:ue({name:"page view",data:{title:"Documentation",url:"https://example.com/docs"}}),attributes:{source:"analytics"}},subscription:"projects/test/subscriptions/events-sub"},out:[["response",200,{success:!0,id:"push-1"}]]},be={title:"Order envelope",description:"A push envelope carrying an order event is decoded and forwarded to the collector.",in:{message:{messageId:"push-2",data:ue({name:"order complete",data:{id:"ORD-500",total:199.99,currency:"EUR"}}),attributes:{}},subscription:"projects/test/subscriptions/events-sub"},out:[["response",200,{success:!0,id:"push-2"}]]},me={title:"Malformed envelope",description:"A POST body lacking message.messageId returns 400 Bad Request without forwarding to the collector.",in:{not_a:"pubsub envelope"},out:[["response",400,{success:!1,error:"Malformed Pub/Sub envelope (missing message.messageId)."}]]},ge=require("@walkeros/collector");function fe(e){if("object"!=typeof e||null===e)return!1;const t=e;return"string"==typeof t.type&&"pubsub-push"===t.type&&"function"==typeof t.push}var he=async e=>{let t;return{get flow(){return t},trigger:(o,r)=>async o=>{if(!t){const o=await(0,ge.startFlow)(e);t={collector:o.collector,elb:o.elb}}const s=("object"==typeof r&&null!==r?r:{}).headers??{},i=function(e){for(const t of Object.values(e.sources??{}))if(fe(t))return t}(t.collector);if(!i)throw new Error("pubsub-push source not registered");const n={},a=function(e,t){return{method:"POST",body:e,headers:t,get:e=>t[e.toLowerCase()]??t[e]}}(o,s),c=function(e){const t={status:o=>(e.statusCode=o,t),json:o=>(e.body=o,t),send:o=>(e.body=o,t),set:()=>t};return t}(n);await i.push(a,c);return[["response",n.statusCode??0,n.body??null]]}}};//# sourceMappingURL=dev.js.map
package/dist/dev.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/dev.ts","../src/cloudfunction/schemas/index.ts","../src/cloudfunction/schemas/settings.ts","../src/cloudfunction/schemas/primitives.ts","../src/cloudfunction/examples/index.ts","../src/cloudfunction/examples/env.ts","../src/cloudfunction/examples/step.ts","../src/cloudfunction/examples/trigger.ts","../src/pubsub/pull/schemas/index.ts","../src/pubsub/pull/schemas/settings.ts","../src/pubsub/pull/schemas/setup.ts","../src/pubsub/pull/examples/index.ts","../src/pubsub/pull/examples/env.ts","../src/pubsub/pull/examples/step.ts","../src/pubsub/pull/examples/trigger.ts","../src/pubsub/push/schemas/index.ts","../src/pubsub/push/schemas/settings.ts","../src/pubsub/push/examples/index.ts","../src/pubsub/push/examples/env.ts","../src/pubsub/push/examples/step.ts","../src/pubsub/push/examples/trigger.ts"],"sourcesContent":["export * as schemas from './cloudfunction/schemas';\nexport * as examples from './cloudfunction/examples';\nexport * as pubsubPullSchemas from './pubsub/pull/schemas';\nexport * as pubsubPullExamples from './pubsub/pull/examples';\nexport * as pubsubPushSchemas from './pubsub/push/schemas';\nexport * as pubsubPushExamples from './pubsub/push/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 * GCP CloudFunction 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 .optional(),\n\n timeout: z\n .number()\n .int()\n .positive()\n .max(540000) // GCP Cloud Functions max timeout: 9 minutes\n .describe('Request timeout in milliseconds (max: 540000 for GCP)')\n .optional(),\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 } from './trigger';\n","import type { Env } from '../types';\nimport type { Elb, Logger } from '@walkeros/core';\n\n/**\n * Example environment configurations for GCP Cloud Function source\n *\n * These environments provide standardized mock structures for testing\n * HTTP request handling without requiring actual cloud function 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 cloud function source\n *\n * Use this for testing HTTP event ingestion and request/response handling\n * without requiring a real GCP Cloud Function 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 postEvent: Flow.StepExample = {\n title: 'POST event',\n description:\n 'A GCP Cloud Function HTTP POST with a JSON body becomes a single walker elb event.',\n trigger: { type: 'POST' },\n in: {\n method: 'POST',\n body: {\n event: 'page view',\n data: { title: 'Home', url: 'https://example.com/' },\n },\n headers: { 'content-type': 'application/json' },\n },\n out: [\n [\n 'elb',\n {\n name: 'page view',\n data: { title: 'Home', url: 'https://example.com/' },\n },\n ],\n ],\n};\n\nexport const orderEvent: Flow.StepExample = {\n title: 'Order POST',\n description:\n 'A Cloud Function HTTP POST carrying an order payload becomes a walker order complete event.',\n trigger: { type: 'POST' },\n in: {\n method: 'POST',\n body: {\n event: 'order complete',\n data: { id: 'ORD-700', total: 99.99, currency: 'EUR' },\n },\n headers: { 'content-type': 'application/json' },\n },\n out: [\n [\n 'elb',\n {\n name: 'order complete',\n data: { id: 'ORD-700', total: 99.99, currency: 'EUR' },\n },\n ],\n ],\n};\n","import type { Trigger, Collector } from '@walkeros/core';\nimport type { CloudFunctionSource, Request, Response } from '../types';\nimport { startFlow } from '@walkeros/collector';\n\nexport interface Content {\n method: string;\n body: Record<string, unknown>;\n headers?: Record<string, string>;\n}\n\nexport interface Result {\n status: number;\n body: unknown;\n}\n\n/**\n * Find the cloudfunction source instance from collector.sources.\n */\nfunction findGcpSource(\n collector: Collector.Instance,\n): CloudFunctionSource | undefined {\n for (const source of Object.values(collector.sources || {})) {\n if ((source as { type?: string }).type === 'cloudfunction')\n return source as unknown as CloudFunctionSource;\n }\n return undefined;\n}\n\n/**\n * GCP CloudFunction source createTrigger.\n *\n * Boots a real collector via startFlow, then synthesizes mock req/res\n * (matching the GCP Functions Framework pattern) and calls source.push(req, res).\n * This is the realistic approach for GCP Cloud Functions - the Functions Framework\n * synthesizes these objects in production too.\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 = findGcpSource(flow.collector);\n if (!source)\n throw new Error(\n 'CloudFunction source not found in collector — ensure it is configured in sources',\n );\n\n // Adapt body: step examples use `name`, source expects `event`\n const body = { ...content.body };\n if (body.name && !body.event) {\n body.event = body.name;\n delete body.name;\n }\n\n const headers = content.headers || {\n 'content-type': 'application/json',\n };\n\n // Synthesize mock req matching GCP Functions Framework pattern\n const req = {\n method: content.method,\n body,\n headers,\n get: (h: string) => headers[h.toLowerCase()],\n } as Request;\n\n // Synthesize mock res that captures status and response body\n let statusCode = 200;\n let responseBody: unknown;\n const res = {\n status: (code: number) => {\n statusCode = code;\n return res;\n },\n json: (data: unknown) => {\n responseBody = data;\n return res;\n },\n send: (data: unknown) => {\n responseBody = data;\n return res;\n },\n set: () => res,\n } as unknown as Response;\n\n // GCP source awaits env.push() — no detached promises\n await source.push(req, res);\n\n return { status: statusCode, body: responseBody };\n };\n\n return {\n get flow() {\n return flow;\n },\n trigger,\n };\n};\n\nexport { createTrigger };\n","import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\nimport { SetupSchema } from './setup';\n\nexport { SettingsSchema, type Settings } from './settings';\nexport { SetupSchema, type Setup } from './setup';\n\n// JSON Schema\nexport const settings = zodToSchema(SettingsSchema);\nexport const setup = zodToSchema(SetupSchema);\n","import { z } from '@walkeros/core/dev';\n\n/**\n * GCP Pub/Sub pull source settings schema.\n *\n * Required: projectId, subscription. All other fields optional with sensible\n * defaults applied at runtime by `getConfig`.\n */\nexport const SettingsSchema = z.object({\n client: z\n .any()\n .describe(\n 'Pre-configured Google Cloud Pub/Sub client (like new PubSub({ projectId })). Bypasses credentials resolution when supplied.',\n )\n .optional(),\n projectId: z\n .string()\n .min(1)\n .describe('Google Cloud Project ID (like my-gcp-project).'),\n subscription: z\n .string()\n .min(1)\n .describe(\n 'Pub/Sub subscription short name (like events-sub). The full resource name projects/<projectId>/subscriptions/<subscription> is built by the SDK.',\n ),\n topic: z\n .string()\n .describe(\n 'Pub/Sub topic short name. Required when setup.createTopic is true; otherwise informational.',\n )\n .optional(),\n credentials: z\n .any()\n .describe(\n 'Service account credentials as a JSON string or an object with client_email and private_key. Default: Application Default Credentials (ADC). (deprecated: use config.credentials)',\n )\n .optional(),\n apiEndpoint: z\n .string()\n .describe(\n 'Override Pub/Sub API endpoint. Useful for the local emulator (like localhost:8085).',\n )\n .optional(),\n decoder: z\n .enum(['json', 'text', 'raw'])\n .describe(\n 'Decoder for the message data field. json (default) parses JSON, text decodes UTF-8, raw forwards the Buffer.',\n )\n .optional(),\n flowControl: z\n .object({\n maxMessages: z\n .number()\n .describe('Maximum in-flight messages. Default: 100.')\n .optional(),\n maxBytes: z\n .number()\n .describe('Maximum in-flight bytes. Default: 10485760 (10 MB).')\n .optional(),\n })\n .describe('Subscriber flow control. Tightens the SDK defaults.')\n .optional(),\n ackDeadline: z\n .number()\n .describe('Subscriber ack deadline in seconds. Default: 60.')\n .optional(),\n shutdownTimeoutMs: z\n .number()\n .describe(\n 'Graceful shutdown timeout in milliseconds. Default: 30000. After this window, destroy() force-closes the subscriber.',\n )\n .optional(),\n onPushError: z\n .enum(['nack', 'ack'])\n .describe(\n 'Behavior when forwarding to the collector throws. nack (default) redelivers the message; ack drops it.',\n )\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\n/**\n * GCP Pub/Sub pull source setup schema.\n *\n * Provisioning options for `walkeros setup source.<id>`. Idempotent\n * subscription creation, plus optional topic and dead-letter topic\n * auto-create. Triggered only by the explicit CLI command.\n */\nexport const SetupSchema = z.object({\n createTopic: z\n .boolean()\n .describe(\n 'Create the topic if it does not exist. Requires settings.topic. Default: false (require pre-existing topic).',\n )\n .optional(),\n ackDeadlineSeconds: z\n .number()\n .describe('Subscription ack deadline in seconds. Default: 60.')\n .optional(),\n messageRetentionDuration: z\n .object({\n seconds: z\n .number()\n .describe('Retention window in seconds. Default: project default.'),\n })\n .describe('Subscription-level retention configuration.')\n .optional(),\n filter: z\n .string()\n .describe(\n 'Subscription filter expression. Only messages matching this filter are delivered.',\n )\n .optional(),\n deadLetterPolicy: z\n .object({\n deadLetterTopic: z.string().describe('Dead-letter topic short name.'),\n maxDeliveryAttempts: z\n .number()\n .describe(\n 'Maximum delivery attempts before forwarding to the dead-letter topic.',\n ),\n createDeadLetterTopic: z\n .boolean()\n .describe(\n 'Auto-create the dead-letter topic if it does not exist. Default: false.',\n )\n .optional(),\n })\n .describe('Dead-letter policy. Strongly recommended for production.')\n .optional(),\n retryPolicy: z\n .object({\n minimumBackoff: z.object({\n seconds: z.number().describe('Minimum backoff in seconds.'),\n }),\n maximumBackoff: z.object({\n seconds: z.number().describe('Maximum backoff in seconds.'),\n }),\n })\n .describe('Subscription retry policy.')\n .optional(),\n enableMessageOrdering: z\n .boolean()\n .describe('Enable message ordering on the subscription. Default: false.')\n .optional(),\n labels: z\n .record(z.string(), z.string())\n .describe('Subscription labels for organization and billing.')\n .optional(),\n expirationPolicy: z\n .object({\n ttl: z\n .object({\n seconds: z\n .number()\n .describe('TTL in seconds. null means never expire.'),\n })\n .nullable()\n .optional(),\n })\n .describe('Subscription expiration policy.')\n .optional(),\n});\n\nexport type Setup = z.infer<typeof SetupSchema>;\n","export * as env from './env';\nexport * as step from './step';\nexport { createTrigger } from './trigger';\nexport type { Content, Result } from './trigger';\n","import type { Env } from '../types';\nimport type { Elb, Logger } from '@walkeros/core';\n\n/**\n * Example environment for the Pub/Sub pull source.\n *\n * Tests substitute the real SDK via `jest.mock('@google-cloud/pubsub')`,\n * which is the recommended pattern: imports of `@google-cloud/pubsub` get\n * replaced module-wide, no env-injection plumbing required at the call site.\n *\n * The `simulation` list documents which globals the source touches during a\n * simulated run, used by the simulator to know what to stub.\n */\n\nconst noopFn = (): void => undefined;\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\nconst createMockElbFn = (): Elb.Fn => {\n const fn: Elb.Fn = () => Promise.resolve({ ok: true });\n return fn;\n};\n\n/**\n * Standard mock environment for the pull source.\n *\n * `PubSub` is intentionally absent: the canonical pattern is module-level\n * `jest.mock('@google-cloud/pubsub')`, not env-injection.\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\nexport const simulation = ['PubSub'];\n","import type { Flow } from '@walkeros/core';\n\n/**\n * Pub/Sub pull step examples.\n *\n * Each example's `in` is a partial MessageLike (id, data Buffer, attributes,\n * publishTime). The trigger synthesizes the missing fields and invokes the\n * registered message handler. `out` is the array of recorded mock calls\n * produced by the handler. Recording shape is `[method, ...args]`.\n *\n * The `__triggerMessage` helper records each message's terminal state under\n * `message.ack` or `message.nack` so step examples can assert on that.\n */\n\nconst eventPayload = {\n name: 'page view',\n data: { title: 'Documentation', url: 'https://example.com/docs' },\n};\n\nconst orderPayload = {\n name: 'order complete',\n data: { id: 'ORD-500', total: 199.99, currency: 'EUR' },\n};\n\nexport const pageView: Flow.StepExample = {\n title: 'Page view',\n description:\n 'A JSON-encoded page view event arrives on the subscription, decodes successfully, and is acked.',\n in: {\n id: 'msg-1',\n dataString: JSON.stringify(eventPayload),\n attributes: {},\n },\n out: [['message.ack', 'msg-1']],\n};\n\nexport const orderComplete: Flow.StepExample = {\n title: 'Order complete',\n description:\n 'A JSON-encoded order event arrives and is acked after successful collector forwarding.',\n in: {\n id: 'msg-2',\n dataString: JSON.stringify(orderPayload),\n attributes: { entity: 'order', action: 'complete' },\n },\n out: [['message.ack', 'msg-2']],\n};\n\nexport const decoderText: Flow.StepExample = {\n title: 'Text decoder',\n description:\n 'With decoder=text on the source settings, the message data is forwarded to the collector as a UTF-8 string and acked.',\n in: {\n id: 'msg-3',\n dataString: 'plain text payload',\n attributes: {},\n },\n out: [['message.ack', 'msg-3']],\n};\n\nexport const malformedJson: Flow.StepExample = {\n title: 'Malformed JSON nack',\n description:\n 'A non-JSON body with the default json decoder fails to decode; the message is nacked for redelivery.',\n in: {\n id: 'msg-4',\n dataString: 'not-json{',\n attributes: {},\n },\n out: [['message.nack', 'msg-4']],\n};\n\nexport const malformedJsonAck: Flow.StepExample = {\n title: 'Malformed JSON ack-and-drop',\n description:\n 'With onPushError=ack on the source settings, a malformed JSON message is acked-and-dropped instead of redelivered.',\n in: {\n id: 'msg-5',\n dataString: 'not-json{',\n attributes: {},\n },\n out: [['message.ack', 'msg-5']],\n};\n","import type { Collector, Trigger } from '@walkeros/core';\nimport { startFlow } from '@walkeros/collector';\nimport type { SyntheticMessage, SyntheticPushResult } from '../types';\n\n/**\n * Content shape for the pull-source trigger.\n *\n * The trigger synthesizes a message from this partial input and dispatches\n * it through the source's `push()` (the same pipeline the SDK subscriber\n * callback uses). `dataString` is the user-friendly way to provide the\n * message body; the trigger encodes it to a Buffer.\n */\nexport interface Content {\n id: string;\n dataString: string;\n attributes?: Record<string, string>;\n orderingKey?: string;\n}\n\n/**\n * Result shape for the pull-source trigger.\n *\n * Returns the recorded ack/nack as `[method, id]` entries, mirroring the\n * destination's `[method, ...args]` recording shape used elsewhere.\n */\nexport type Result = Array<[string, ...unknown[]]>;\n\ninterface PubSubPullSourceLike {\n type: string;\n push: (content?: SyntheticMessage) => Promise<SyntheticPushResult | void>;\n}\n\nfunction isPubSubPullSource(value: unknown): value is PubSubPullSourceLike {\n if (typeof value !== 'object' || value === null) return false;\n const candidate: { type?: unknown; push?: unknown } = value;\n return (\n candidate.type === 'pubsub-pull' && typeof candidate.push === 'function'\n );\n}\n\nfunction findSource(\n collector: Collector.Instance,\n): PubSubPullSourceLike | undefined {\n for (const source of Object.values(collector.sources ?? {})) {\n if (isPubSubPullSource(source)) return source;\n }\n return undefined;\n}\n\n/**\n * Pub/Sub pull source createTrigger.\n *\n * Boots the collector via startFlow, finds the registered pubsub-pull source,\n * and invokes its `push()` with a synthesized message. The source dispatches\n * the synthetic message through the same handler the SDK subscriber callback\n * uses, exercising the full decode / forward / ack-nack pipeline without\n * touching real Pub/Sub.\n *\n * Matches the convention used by other source triggers (express, lambda,\n * cloudfunction): find the source by type from the collector and call its\n * public `push()` interface.\n */\nexport const 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 if (!flow) {\n const result = await startFlow(config);\n flow = { collector: result.collector, elb: result.elb };\n }\n\n const source = findSource(flow.collector);\n if (!source)\n throw new Error(\n 'pubsub-pull source not registered in collector — ensure it is configured in sources',\n );\n\n const synthetic: SyntheticMessage = {\n id: content.id,\n data: Buffer.from(content.dataString, 'utf8'),\n attributes: content.attributes,\n orderingKey: content.orderingKey,\n };\n\n const result = await source.push(synthetic);\n const recorded: Result = [];\n if (result && typeof result === 'object') {\n if (result.acked) recorded.push(['message.ack', content.id]);\n if (result.nacked) recorded.push(['message.nack', content.id]);\n }\n return recorded;\n };\n\n return {\n get flow() {\n return flow;\n },\n trigger,\n };\n};\n","import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\n\nexport { SettingsSchema, type Settings } from './settings';\n\nexport const settings = zodToSchema(SettingsSchema);\n","import { z } from '@walkeros/core/dev';\n\n/**\n * GCP Pub/Sub push source settings schema.\n *\n * No required fields. The push source is a request-handler; configuration\n * tunables live here, but operators wire `source.push` into their own\n * express/lambda runtime.\n */\nexport const SettingsSchema = z.object({\n projectId: z\n .string()\n .describe(\n 'Google Cloud Project ID (informational, surfaced in error messages).',\n )\n .optional(),\n decoder: z\n .enum(['json', 'text', 'raw'])\n .describe(\n 'Decoder for the message data field. json (default) parses JSON, text decodes UTF-8, raw forwards the Buffer.',\n )\n .optional(),\n verifyOidc: z\n .boolean()\n .describe(\n 'Verify the OIDC bearer token Pub/Sub attaches to push requests. Default: false.',\n )\n .optional(),\n audience: z\n .string()\n .describe(\n 'OIDC audience (your endpoint URL or a custom audience). Required when verifyOidc is true.',\n )\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","export * as env from './env';\nexport * as step from './step';\nexport { createTrigger } from './trigger';\nexport type { Content, Result } from './trigger';\n","import type { Env } from '../types';\nimport type { Elb, Logger } from '@walkeros/core';\n\n/**\n * Example environment for the Pub/Sub push source.\n *\n * Provides a no-op env compatible with `Source.Env` plus an optional\n * verifyOidcToken stub for tests that exercise OIDC verification.\n */\n\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\nconst createMockElbFn = (): Elb.Fn => {\n const fn = (() => Promise.resolve({ ok: true })) as Elb.Fn;\n return fn;\n};\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\nexport const simulation: string[] = [];\n","import type { Flow } from '@walkeros/core';\n\n/**\n * Pub/Sub push step examples.\n *\n * Each example's `in` is a partial Pub/Sub push envelope (with `message.data`\n * pre-encoded as base64). The trigger constructs an HTTP-like Request from\n * `in` and invokes the source handler. `out` is the recorded HTTP response\n * shape (statusCode + JSON body).\n */\n\nconst eventPayload = {\n name: 'page view',\n data: { title: 'Documentation', url: 'https://example.com/docs' },\n};\n\nconst orderPayload = {\n name: 'order complete',\n data: { id: 'ORD-500', total: 199.99, currency: 'EUR' },\n};\n\nfunction encodeData(value: unknown): string {\n return Buffer.from(JSON.stringify(value), 'utf8').toString('base64');\n}\n\nexport const validEnvelope: Flow.StepExample = {\n title: 'Valid push envelope',\n description:\n 'A well-formed Pub/Sub push envelope decodes the base64 data, parses JSON, and forwards the event to the collector with a 200 response.',\n in: {\n message: {\n messageId: 'push-1',\n data: encodeData(eventPayload),\n attributes: { source: 'analytics' },\n },\n subscription: 'projects/test/subscriptions/events-sub',\n },\n out: [['response', 200, { success: true, id: 'push-1' }]],\n};\n\nexport const orderEnvelope: Flow.StepExample = {\n title: 'Order envelope',\n description:\n 'A push envelope carrying an order event is decoded and forwarded to the collector.',\n in: {\n message: {\n messageId: 'push-2',\n data: encodeData(orderPayload),\n attributes: {},\n },\n subscription: 'projects/test/subscriptions/events-sub',\n },\n out: [['response', 200, { success: true, id: 'push-2' }]],\n};\n\nexport const malformedEnvelope: Flow.StepExample = {\n title: 'Malformed envelope',\n description:\n 'A POST body lacking message.messageId returns 400 Bad Request without forwarding to the collector.',\n in: {\n not_a: 'pubsub envelope',\n },\n out: [\n [\n 'response',\n 400,\n {\n success: false,\n error: 'Malformed Pub/Sub envelope (missing message.messageId).',\n },\n ],\n ],\n};\n","import type { Collector, Trigger } from '@walkeros/core';\nimport type { Request, Response } from '../types';\nimport { startFlow } from '@walkeros/collector';\n\n/** Content for the push trigger: a Pub/Sub envelope or any POST body. */\nexport type Content = Record<string, unknown>;\n\n/** Result: the recorded HTTP response (`status` + `json` body). */\nexport type Result = Array<[string, ...unknown[]]>;\n\ninterface RecordedResponse {\n statusCode?: number;\n body?: unknown;\n}\n\nfunction buildResponse(state: RecordedResponse): Response {\n const res: Response = {\n status(code: number) {\n state.statusCode = code;\n return res;\n },\n json(body: unknown) {\n state.body = body;\n return res;\n },\n send(body?: unknown) {\n state.body = body;\n return res;\n },\n set() {\n return res;\n },\n };\n return res;\n}\n\nfunction buildRequest(\n content: Content,\n headers: Record<string, string>,\n): Request {\n return {\n method: 'POST',\n body: content,\n headers,\n get(name: string) {\n const value = headers[name.toLowerCase()] ?? headers[name];\n return value;\n },\n };\n}\n\ninterface TriggerOptions {\n headers?: Record<string, string>;\n}\n\ninterface PushCapableSource {\n type: string;\n push: (req: Request, res: Response) => Promise<void>;\n}\n\nfunction isPushCapableSource(value: unknown): value is PushCapableSource {\n if (typeof value !== 'object' || value === null) return false;\n const candidate: { type?: unknown; push?: unknown } = value;\n return (\n typeof candidate.type === 'string' &&\n candidate.type === 'pubsub-push' &&\n typeof candidate.push === 'function'\n );\n}\n\nfunction findPushSource(\n collector: Collector.Instance,\n): PushCapableSource | undefined {\n for (const source of Object.values(collector.sources ?? {})) {\n if (isPushCapableSource(source)) return source;\n }\n return undefined;\n}\n\n/**\n * Pub/Sub push source createTrigger.\n *\n * Boots the collector via startFlow, builds a fake Request/Response pair\n * from the trigger Content, and invokes the source's HTTP handler. Returns\n * the recorded response as a Result entry.\n */\nexport const 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 (_type, options) =>\n async (content: Content): Promise<Result> => {\n if (!flow) {\n const result = await startFlow(config);\n flow = { collector: result.collector, elb: result.elb };\n }\n\n const triggerOptions: TriggerOptions =\n typeof options === 'object' && options !== null\n ? (options as TriggerOptions)\n : {};\n const headers = triggerOptions.headers ?? {};\n\n const source = findPushSource(flow.collector);\n if (!source) throw new Error('pubsub-push source not registered');\n\n const state: RecordedResponse = {};\n const req = buildRequest(content, headers);\n const res = buildResponse(state);\n\n await source.push(req, res);\n\n const recorded: Result = [\n ['response', state.statusCode ?? 0, state.body ?? null],\n ];\n return recorded;\n };\n\n return {\n get flow() {\n return flow;\n },\n trigger,\n };\n};\n"],"mappings":"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","names":["examples_exports","schemas_exports","import_dev","import_dev","schemas_exports","SettingsSchema","settings","import_dev","import_dev","SettingsSchema","import_dev","settings","SettingsSchema","examples_exports","createTrigger","env_exports","step_exports","env_exports","push","noopFn","noopLogger","createMockElbFn","step_exports","import_collector","createTrigger","result","schemas_exports","SettingsSchema","settings","import_dev","import_dev","SettingsSchema","settings","SettingsSchema","examples_exports","createTrigger","env_exports","step_exports","env_exports","push","simulation","noopFn","noopLogger","createMockElbFn","step_exports","eventPayload","orderPayload","import_collector","createTrigger"]}
1
+ {"version":3,"sources":["../src/dev.ts","../src/cloudfunction/schemas/index.ts","../src/cloudfunction/schemas/settings.ts","../src/cloudfunction/schemas/primitives.ts","../src/cloudfunction/examples/index.ts","../src/cloudfunction/examples/env.ts","../src/cloudfunction/examples/step.ts","../src/cloudfunction/examples/trigger.ts","../src/pubsub/pull/schemas/index.ts","../src/pubsub/pull/schemas/settings.ts","../src/pubsub/pull/schemas/setup.ts","../src/pubsub/pull/examples/index.ts","../src/pubsub/pull/examples/env.ts","../src/pubsub/pull/examples/step.ts","../src/pubsub/pull/examples/trigger.ts","../src/pubsub/push/schemas/index.ts","../src/pubsub/push/schemas/settings.ts","../src/pubsub/push/examples/index.ts","../src/pubsub/push/examples/env.ts","../src/pubsub/push/examples/step.ts","../src/pubsub/push/examples/trigger.ts"],"sourcesContent":["export * as schemas from './cloudfunction/schemas';\nexport * as examples from './cloudfunction/examples';\nexport * as pubsubPullSchemas from './pubsub/pull/schemas';\nexport * as pubsubPullExamples from './pubsub/pull/examples';\nexport * as pubsubPushSchemas from './pubsub/push/schemas';\nexport * as pubsubPushExamples from './pubsub/push/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 * GCP CloudFunction 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 .optional(),\n\n maxBatchSize: z\n .number()\n .int()\n .min(1)\n .describe('Maximum number of events accepted in a single batch request')\n .default(100),\n\n enablePixelTracking: z\n .boolean()\n .describe('Serve a tracking pixel for GET requests')\n .default(true),\n\n timeout: z\n .number()\n .int()\n .positive()\n .max(540000) // GCP Cloud Functions max timeout: 9 minutes\n .describe('Request timeout in milliseconds (max: 540000 for GCP)')\n .optional(),\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 } from './trigger';\n","import type { Env } from '../types';\nimport type { Elb, Logger } from '@walkeros/core';\n\n/**\n * Example environment configurations for GCP Cloud Function source\n *\n * These environments provide standardized mock structures for testing\n * HTTP request handling without requiring actual cloud function 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 cloud function source\n *\n * Use this for testing HTTP event ingestion and request/response handling\n * without requiring a real GCP Cloud Function 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 postEvent: Flow.StepExample = {\n title: 'POST event',\n description:\n 'A GCP Cloud Function HTTP POST with a JSON body becomes a single walker elb event.',\n trigger: { type: 'POST' },\n in: {\n method: 'POST',\n body: {\n name: 'page view',\n data: { title: 'Home', url: 'https://example.com/' },\n },\n headers: { 'content-type': 'application/json' },\n },\n out: [\n [\n 'elb',\n {\n name: 'page view',\n data: { title: 'Home', url: 'https://example.com/' },\n },\n ],\n ],\n};\n\nexport const orderEvent: Flow.StepExample = {\n title: 'Order POST',\n description:\n 'A Cloud Function HTTP POST carrying an order payload becomes a walker order complete event.',\n trigger: { type: 'POST' },\n in: {\n method: 'POST',\n body: {\n name: 'order complete',\n data: { id: 'ORD-700', total: 99.99, currency: 'EUR' },\n },\n headers: { 'content-type': 'application/json' },\n },\n out: [\n [\n 'elb',\n {\n name: 'order complete',\n data: { id: 'ORD-700', total: 99.99, currency: 'EUR' },\n },\n ],\n ],\n};\n\nexport const cloudFunctionPostForwardsSource: Flow.StepExample = {\n title: 'POST with provenance',\n description:\n 'A POST body carrying a source map is forwarded in full, so release and trace provenance survive the crossing.',\n trigger: { type: 'POST' },\n in: {\n method: 'POST',\n body: {\n name: 'page view',\n data: { title: 'Home' },\n source: { release: { web: 'r1' } },\n },\n headers: { 'content-type': 'application/json' },\n },\n out: [\n [\n 'elb',\n {\n name: 'page view',\n data: { title: 'Home' },\n source: { release: { web: 'r1' } },\n },\n ],\n ],\n};\n","import type { Trigger, Collector } from '@walkeros/core';\nimport type { CloudFunctionSource, Request, Response } from '../types';\nimport { startFlow } from '@walkeros/collector';\n\nexport interface Content {\n method: string;\n body: Record<string, unknown>;\n headers?: Record<string, string>;\n}\n\nexport interface Result {\n status: number;\n body: unknown;\n}\n\n/**\n * Find the cloudfunction source instance from collector.sources.\n */\nfunction findGcpSource(\n collector: Collector.Instance,\n): CloudFunctionSource | undefined {\n for (const source of Object.values(collector.sources || {})) {\n if ((source as { type?: string }).type === 'cloudfunction')\n return source as unknown as CloudFunctionSource;\n }\n return undefined;\n}\n\n/**\n * GCP CloudFunction source createTrigger.\n *\n * Boots a real collector via startFlow, then synthesizes mock req/res\n * (matching the GCP Functions Framework pattern) and calls source.push(req, res).\n * This is the realistic approach for GCP Cloud Functions - the Functions Framework\n * synthesizes these objects in production too.\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 = findGcpSource(flow.collector);\n if (!source)\n throw new Error(\n 'CloudFunction source not found in collector — ensure it is configured in sources',\n );\n\n // Adapt body: step examples use `name`, source expects `event`\n const body = { ...content.body };\n if (body.name && !body.event) {\n body.event = body.name;\n delete body.name;\n }\n\n const headers = content.headers || {\n 'content-type': 'application/json',\n };\n\n // Synthesize mock req matching GCP Functions Framework pattern\n const req = {\n method: content.method,\n body,\n headers,\n get: (h: string) => headers[h.toLowerCase()],\n } as Request;\n\n // Synthesize mock res that captures status and response body\n let statusCode = 200;\n let responseBody: unknown;\n const res = {\n status: (code: number) => {\n statusCode = code;\n return res;\n },\n json: (data: unknown) => {\n responseBody = data;\n return res;\n },\n send: (data: unknown) => {\n responseBody = data;\n return res;\n },\n set: () => res,\n } as unknown as Response;\n\n // GCP source awaits env.push() — no detached promises\n await source.push(req, res);\n\n return { status: statusCode, body: responseBody };\n };\n\n return {\n get flow() {\n return flow;\n },\n trigger,\n };\n};\n\nexport { createTrigger };\n","import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\nimport { SetupSchema } from './setup';\n\nexport { SettingsSchema, type Settings } from './settings';\nexport { SetupSchema, type Setup } from './setup';\n\n// JSON Schema\nexport const settings = zodToSchema(SettingsSchema);\nexport const setup = zodToSchema(SetupSchema);\n","import { z } from '@walkeros/core/dev';\n\n/**\n * GCP Pub/Sub pull source settings schema.\n *\n * Required: projectId, subscription. All other fields optional with sensible\n * defaults applied at runtime by `getConfig`.\n */\nexport const SettingsSchema = z.object({\n client: z\n .any()\n .describe(\n 'Pre-configured Google Cloud Pub/Sub client (like new PubSub({ projectId })). Bypasses credentials resolution when supplied.',\n )\n .optional(),\n projectId: z\n .string()\n .min(1)\n .describe('Google Cloud Project ID (like my-gcp-project).'),\n subscription: z\n .string()\n .min(1)\n .describe(\n 'Pub/Sub subscription short name (like events-sub). The full resource name projects/<projectId>/subscriptions/<subscription> is built by the SDK.',\n ),\n topic: z\n .string()\n .describe(\n 'Pub/Sub topic short name. Required when setup.createTopic is true; otherwise informational.',\n )\n .optional(),\n credentials: z\n .any()\n .describe(\n 'Service account credentials as a JSON string or an object with client_email and private_key. Default: Application Default Credentials (ADC). (deprecated: use config.credentials)',\n )\n .optional(),\n apiEndpoint: z\n .string()\n .describe(\n 'Override Pub/Sub API endpoint. Useful for the local emulator (like localhost:8085).',\n )\n .optional(),\n decoder: z\n .enum(['json', 'text', 'raw'])\n .describe(\n 'Decoder for the message data field. json (default) parses JSON, text decodes UTF-8, raw forwards the Buffer.',\n )\n .optional(),\n flowControl: z\n .object({\n maxMessages: z\n .number()\n .describe('Maximum in-flight messages. Default: 100.')\n .optional(),\n maxBytes: z\n .number()\n .describe('Maximum in-flight bytes. Default: 10485760 (10 MB).')\n .optional(),\n })\n .describe('Subscriber flow control. Tightens the SDK defaults.')\n .optional(),\n ackDeadline: z\n .number()\n .describe('Subscriber ack deadline in seconds. Default: 60.')\n .optional(),\n shutdownTimeoutMs: z\n .number()\n .describe(\n 'Graceful shutdown timeout in milliseconds. Default: 30000. After this window, destroy() force-closes the subscriber.',\n )\n .optional(),\n onPushError: z\n .enum(['nack', 'ack'])\n .describe(\n 'Behavior when forwarding to the collector throws. nack (default) redelivers the message; ack drops it.',\n )\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","import { z } from '@walkeros/core/dev';\n\n/**\n * GCP Pub/Sub pull source setup schema.\n *\n * Provisioning options for `walkeros setup source.<id>`. Idempotent\n * subscription creation, plus optional topic and dead-letter topic\n * auto-create. Triggered only by the explicit CLI command.\n */\nexport const SetupSchema = z.object({\n createTopic: z\n .boolean()\n .describe(\n 'Create the topic if it does not exist. Requires settings.topic. Default: false (require pre-existing topic).',\n )\n .optional(),\n ackDeadlineSeconds: z\n .number()\n .describe('Subscription ack deadline in seconds. Default: 60.')\n .optional(),\n messageRetentionDuration: z\n .object({\n seconds: z\n .number()\n .describe('Retention window in seconds. Default: project default.'),\n })\n .describe('Subscription-level retention configuration.')\n .optional(),\n filter: z\n .string()\n .describe(\n 'Subscription filter expression. Only messages matching this filter are delivered.',\n )\n .optional(),\n deadLetterPolicy: z\n .object({\n deadLetterTopic: z.string().describe('Dead-letter topic short name.'),\n maxDeliveryAttempts: z\n .number()\n .describe(\n 'Maximum delivery attempts before forwarding to the dead-letter topic.',\n ),\n createDeadLetterTopic: z\n .boolean()\n .describe(\n 'Auto-create the dead-letter topic if it does not exist. Default: false.',\n )\n .optional(),\n })\n .describe('Dead-letter policy. Strongly recommended for production.')\n .optional(),\n retryPolicy: z\n .object({\n minimumBackoff: z.object({\n seconds: z.number().describe('Minimum backoff in seconds.'),\n }),\n maximumBackoff: z.object({\n seconds: z.number().describe('Maximum backoff in seconds.'),\n }),\n })\n .describe('Subscription retry policy.')\n .optional(),\n enableMessageOrdering: z\n .boolean()\n .describe('Enable message ordering on the subscription. Default: false.')\n .optional(),\n labels: z\n .record(z.string(), z.string())\n .describe('Subscription labels for organization and billing.')\n .optional(),\n expirationPolicy: z\n .object({\n ttl: z\n .object({\n seconds: z\n .number()\n .describe('TTL in seconds. null means never expire.'),\n })\n .nullable()\n .optional(),\n })\n .describe('Subscription expiration policy.')\n .optional(),\n});\n\nexport type Setup = z.infer<typeof SetupSchema>;\n","export * as env from './env';\nexport * as step from './step';\nexport { createTrigger } from './trigger';\nexport type { Content, Result } from './trigger';\n","import type { Env } from '../types';\nimport type { Elb, Logger } from '@walkeros/core';\n\n/**\n * Example environment for the Pub/Sub pull source.\n *\n * Tests substitute the real SDK via `jest.mock('@google-cloud/pubsub')`,\n * which is the recommended pattern: imports of `@google-cloud/pubsub` get\n * replaced module-wide, no env-injection plumbing required at the call site.\n *\n * The `simulation` list documents which globals the source touches during a\n * simulated run, used by the simulator to know what to stub.\n */\n\nconst noopFn = (): void => undefined;\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\nconst createMockElbFn = (): Elb.Fn => {\n const fn: Elb.Fn = () => Promise.resolve({ ok: true });\n return fn;\n};\n\n/**\n * Standard mock environment for the pull source.\n *\n * `PubSub` is intentionally absent: the canonical pattern is module-level\n * `jest.mock('@google-cloud/pubsub')`, not env-injection.\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\nexport const simulation = ['PubSub'];\n","import type { Flow } from '@walkeros/core';\n\n/**\n * Pub/Sub pull step examples.\n *\n * Each example's `in` is a partial MessageLike (id, data Buffer, attributes,\n * publishTime). The trigger synthesizes the missing fields and invokes the\n * registered message handler. `out` is the array of recorded mock calls\n * produced by the handler. Recording shape is `[method, ...args]`.\n *\n * The `__triggerMessage` helper records each message's terminal state under\n * `message.ack` or `message.nack` so step examples can assert on that.\n */\n\nconst eventPayload = {\n name: 'page view',\n data: { title: 'Documentation', url: 'https://example.com/docs' },\n};\n\nconst orderPayload = {\n name: 'order complete',\n data: { id: 'ORD-500', total: 199.99, currency: 'EUR' },\n};\n\nexport const pageView: Flow.StepExample = {\n title: 'Page view',\n description:\n 'A JSON-encoded page view event arrives on the subscription, decodes successfully, and is acked.',\n in: {\n id: 'msg-1',\n dataString: JSON.stringify(eventPayload),\n attributes: {},\n },\n out: [['message.ack', 'msg-1']],\n};\n\nexport const orderComplete: Flow.StepExample = {\n title: 'Order complete',\n description:\n 'A JSON-encoded order event arrives and is acked after successful collector forwarding.',\n in: {\n id: 'msg-2',\n dataString: JSON.stringify(orderPayload),\n attributes: { entity: 'order', action: 'complete' },\n },\n out: [['message.ack', 'msg-2']],\n};\n\nexport const decoderText: Flow.StepExample = {\n title: 'Text decoder',\n description:\n 'With decoder=text on the source settings, the message data is forwarded to the collector as a UTF-8 string and acked.',\n in: {\n id: 'msg-3',\n dataString: 'plain text payload',\n attributes: {},\n },\n out: [['message.ack', 'msg-3']],\n};\n\nexport const malformedJson: Flow.StepExample = {\n title: 'Malformed JSON nack',\n description:\n 'A non-JSON body with the default json decoder fails to decode; the message is nacked for redelivery.',\n in: {\n id: 'msg-4',\n dataString: 'not-json{',\n attributes: {},\n },\n out: [['message.nack', 'msg-4']],\n};\n\nexport const malformedJsonAck: Flow.StepExample = {\n title: 'Malformed JSON ack-and-drop',\n description:\n 'With onPushError=ack on the source settings, a malformed JSON message is acked-and-dropped instead of redelivered.',\n in: {\n id: 'msg-5',\n dataString: 'not-json{',\n attributes: {},\n },\n out: [['message.ack', 'msg-5']],\n};\n","import type { Collector, Trigger } from '@walkeros/core';\nimport { startFlow } from '@walkeros/collector';\nimport type { SyntheticMessage, SyntheticPushResult } from '../types';\n\n/**\n * Content shape for the pull-source trigger.\n *\n * The trigger synthesizes a message from this partial input and dispatches\n * it through the source's `push()` (the same pipeline the SDK subscriber\n * callback uses). `dataString` is the user-friendly way to provide the\n * message body; the trigger encodes it to a Buffer.\n */\nexport interface Content {\n id: string;\n dataString: string;\n attributes?: Record<string, string>;\n orderingKey?: string;\n}\n\n/**\n * Result shape for the pull-source trigger.\n *\n * Returns the recorded ack/nack as `[method, id]` entries, mirroring the\n * destination's `[method, ...args]` recording shape used elsewhere.\n */\nexport type Result = Array<[string, ...unknown[]]>;\n\ninterface PubSubPullSourceLike {\n type: string;\n push: (content?: SyntheticMessage) => Promise<SyntheticPushResult | void>;\n}\n\nfunction isPubSubPullSource(value: unknown): value is PubSubPullSourceLike {\n if (typeof value !== 'object' || value === null) return false;\n const candidate: { type?: unknown; push?: unknown } = value;\n return (\n candidate.type === 'pubsub-pull' && typeof candidate.push === 'function'\n );\n}\n\nfunction findSource(\n collector: Collector.Instance,\n): PubSubPullSourceLike | undefined {\n for (const source of Object.values(collector.sources ?? {})) {\n if (isPubSubPullSource(source)) return source;\n }\n return undefined;\n}\n\n/**\n * Pub/Sub pull source createTrigger.\n *\n * Boots the collector via startFlow, finds the registered pubsub-pull source,\n * and invokes its `push()` with a synthesized message. The source dispatches\n * the synthetic message through the same handler the SDK subscriber callback\n * uses, exercising the full decode / forward / ack-nack pipeline without\n * touching real Pub/Sub.\n *\n * Matches the convention used by other source triggers (express, lambda,\n * cloudfunction): find the source by type from the collector and call its\n * public `push()` interface.\n */\nexport const 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 if (!flow) {\n const result = await startFlow(config);\n flow = { collector: result.collector, elb: result.elb };\n }\n\n const source = findSource(flow.collector);\n if (!source)\n throw new Error(\n 'pubsub-pull source not registered in collector — ensure it is configured in sources',\n );\n\n const synthetic: SyntheticMessage = {\n id: content.id,\n data: Buffer.from(content.dataString, 'utf8'),\n attributes: content.attributes,\n orderingKey: content.orderingKey,\n };\n\n const result = await source.push(synthetic);\n const recorded: Result = [];\n if (result && typeof result === 'object') {\n if (result.acked) recorded.push(['message.ack', content.id]);\n if (result.nacked) recorded.push(['message.nack', content.id]);\n }\n return recorded;\n };\n\n return {\n get flow() {\n return flow;\n },\n trigger,\n };\n};\n","import { zodToSchema } from '@walkeros/core/dev';\nimport { SettingsSchema } from './settings';\n\nexport { SettingsSchema, type Settings } from './settings';\n\nexport const settings = zodToSchema(SettingsSchema);\n","import { z } from '@walkeros/core/dev';\n\n/**\n * GCP Pub/Sub push source settings schema.\n *\n * No required fields. The push source is a request-handler; configuration\n * tunables live here, but operators wire `source.push` into their own\n * express/lambda runtime.\n */\nexport const SettingsSchema = z.object({\n projectId: z\n .string()\n .describe(\n 'Google Cloud Project ID (informational, surfaced in error messages).',\n )\n .optional(),\n decoder: z\n .enum(['json', 'text', 'raw'])\n .describe(\n 'Decoder for the message data field. json (default) parses JSON, text decodes UTF-8, raw forwards the Buffer.',\n )\n .optional(),\n verifyOidc: z\n .boolean()\n .describe(\n 'Verify the OIDC bearer token Pub/Sub attaches to push requests. Default: false.',\n )\n .optional(),\n audience: z\n .string()\n .describe(\n 'OIDC audience (your endpoint URL or a custom audience). Required when verifyOidc is true.',\n )\n .optional(),\n});\n\nexport type Settings = z.infer<typeof SettingsSchema>;\n","export * as env from './env';\nexport * as step from './step';\nexport { createTrigger } from './trigger';\nexport type { Content, Result } from './trigger';\n","import type { Env } from '../types';\nimport type { Elb, Logger } from '@walkeros/core';\n\n/**\n * Example environment for the Pub/Sub push source.\n *\n * Provides a no-op env compatible with `Source.Env` plus an optional\n * verifyOidcToken stub for tests that exercise OIDC verification.\n */\n\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\nconst createMockElbFn = (): Elb.Fn => {\n const fn = (() => Promise.resolve({ ok: true })) as Elb.Fn;\n return fn;\n};\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\nexport const simulation: string[] = [];\n","import type { Flow } from '@walkeros/core';\n\n/**\n * Pub/Sub push step examples.\n *\n * Each example's `in` is a partial Pub/Sub push envelope (with `message.data`\n * pre-encoded as base64). The trigger constructs an HTTP-like Request from\n * `in` and invokes the source handler. `out` is the recorded HTTP response\n * shape (statusCode + JSON body).\n */\n\nconst eventPayload = {\n name: 'page view',\n data: { title: 'Documentation', url: 'https://example.com/docs' },\n};\n\nconst orderPayload = {\n name: 'order complete',\n data: { id: 'ORD-500', total: 199.99, currency: 'EUR' },\n};\n\nfunction encodeData(value: unknown): string {\n return Buffer.from(JSON.stringify(value), 'utf8').toString('base64');\n}\n\nexport const validEnvelope: Flow.StepExample = {\n title: 'Valid push envelope',\n description:\n 'A well-formed Pub/Sub push envelope decodes the base64 data, parses JSON, and forwards the event to the collector with a 200 response.',\n in: {\n message: {\n messageId: 'push-1',\n data: encodeData(eventPayload),\n attributes: { source: 'analytics' },\n },\n subscription: 'projects/test/subscriptions/events-sub',\n },\n out: [['response', 200, { success: true, id: 'push-1' }]],\n};\n\nexport const orderEnvelope: Flow.StepExample = {\n title: 'Order envelope',\n description:\n 'A push envelope carrying an order event is decoded and forwarded to the collector.',\n in: {\n message: {\n messageId: 'push-2',\n data: encodeData(orderPayload),\n attributes: {},\n },\n subscription: 'projects/test/subscriptions/events-sub',\n },\n out: [['response', 200, { success: true, id: 'push-2' }]],\n};\n\nexport const malformedEnvelope: Flow.StepExample = {\n title: 'Malformed envelope',\n description:\n 'A POST body lacking message.messageId returns 400 Bad Request without forwarding to the collector.',\n in: {\n not_a: 'pubsub envelope',\n },\n out: [\n [\n 'response',\n 400,\n {\n success: false,\n error: 'Malformed Pub/Sub envelope (missing message.messageId).',\n },\n ],\n ],\n};\n","import type { Collector, Trigger } from '@walkeros/core';\nimport type { Request, Response } from '../types';\nimport { startFlow } from '@walkeros/collector';\n\n/** Content for the push trigger: a Pub/Sub envelope or any POST body. */\nexport type Content = Record<string, unknown>;\n\n/** Result: the recorded HTTP response (`status` + `json` body). */\nexport type Result = Array<[string, ...unknown[]]>;\n\ninterface RecordedResponse {\n statusCode?: number;\n body?: unknown;\n}\n\nfunction buildResponse(state: RecordedResponse): Response {\n const res: Response = {\n status(code: number) {\n state.statusCode = code;\n return res;\n },\n json(body: unknown) {\n state.body = body;\n return res;\n },\n send(body?: unknown) {\n state.body = body;\n return res;\n },\n set() {\n return res;\n },\n };\n return res;\n}\n\nfunction buildRequest(\n content: Content,\n headers: Record<string, string>,\n): Request {\n return {\n method: 'POST',\n body: content,\n headers,\n get(name: string) {\n const value = headers[name.toLowerCase()] ?? headers[name];\n return value;\n },\n };\n}\n\ninterface TriggerOptions {\n headers?: Record<string, string>;\n}\n\ninterface PushCapableSource {\n type: string;\n push: (req: Request, res: Response) => Promise<void>;\n}\n\nfunction isPushCapableSource(value: unknown): value is PushCapableSource {\n if (typeof value !== 'object' || value === null) return false;\n const candidate: { type?: unknown; push?: unknown } = value;\n return (\n typeof candidate.type === 'string' &&\n candidate.type === 'pubsub-push' &&\n typeof candidate.push === 'function'\n );\n}\n\nfunction findPushSource(\n collector: Collector.Instance,\n): PushCapableSource | undefined {\n for (const source of Object.values(collector.sources ?? {})) {\n if (isPushCapableSource(source)) return source;\n }\n return undefined;\n}\n\n/**\n * Pub/Sub push source createTrigger.\n *\n * Boots the collector via startFlow, builds a fake Request/Response pair\n * from the trigger Content, and invokes the source's HTTP handler. Returns\n * the recorded response as a Result entry.\n */\nexport const 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 (_type, options) =>\n async (content: Content): Promise<Result> => {\n if (!flow) {\n const result = await startFlow(config);\n flow = { collector: result.collector, elb: result.elb };\n }\n\n const triggerOptions: TriggerOptions =\n typeof options === 'object' && options !== null\n ? (options as TriggerOptions)\n : {};\n const headers = triggerOptions.headers ?? {};\n\n const source = findPushSource(flow.collector);\n if (!source) throw new Error('pubsub-push source not registered');\n\n const state: RecordedResponse = {};\n const req = buildRequest(content, headers);\n const res = buildResponse(state);\n\n await source.push(req, res);\n\n const recorded: Result = [\n ['response', state.statusCode ?? 0, state.body ?? null],\n ];\n return recorded;\n };\n\n return {\n get flow() {\n return flow;\n },\n trigger,\n };\n};\n"],"mappings":"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","names":["examples_exports","schemas_exports","import_dev","import_dev","schemas_exports","SettingsSchema","settings","import_dev","import_dev","SettingsSchema","import_dev","settings","SettingsSchema","examples_exports","createTrigger","env_exports","step_exports","env_exports","push","noopFn","noopLogger","createMockElbFn","step_exports","import_collector","createTrigger","result","schemas_exports","SettingsSchema","settings","import_dev","import_dev","SettingsSchema","settings","SettingsSchema","examples_exports","createTrigger","env_exports","step_exports","env_exports","push","simulation","noopFn","noopLogger","createMockElbFn","step_exports","eventPayload","orderPayload","import_collector","createTrigger"]}
package/dist/dev.mjs CHANGED
@@ -1 +1 @@
1
- var e=Object.defineProperty,t=(t,o)=>{for(var r in o)e(t,r,{get:o[r],enumerable:!0})},o={};t(o,{CorsOptionsSchema:()=>c,CorsOrigin:()=>a,HttpMethod:()=>n,SettingsSchema:()=>l,settings:()=>d});import{zodToSchema as r}from"@walkeros/core/dev";import{z as s}from"@walkeros/core/dev";import{z as i}from"@walkeros/core/dev";var n=i.enum(["GET","POST","PUT","PATCH","DELETE","OPTIONS","HEAD"]),a=i.union([i.string(),i.array(i.string()),i.literal("*")]),c=i.object({origin:a.describe("Allowed origins (* for all, URL string, or array of URLs)").optional(),methods:i.array(n).describe("Allowed HTTP methods").optional(),headers:i.array(i.string()).describe("Allowed request headers").optional(),credentials:i.boolean().describe("Allow credentials (cookies, authorization headers)").optional(),maxAge:i.number().int().positive().describe("Preflight cache duration in seconds").optional()}),l=s.object({cors:s.union([s.boolean(),c]).describe("CORS configuration: false = disabled, true = allow all origins, object = custom configuration").optional(),timeout:s.number().int().positive().max(54e4).describe("Request timeout in milliseconds (max: 540000 for GCP)").optional()}),d=r(l),u={};t(u,{createTrigger:()=>S,env:()=>p,step:()=>h});var p={};t(p,{push:()=>g});var m=()=>()=>Promise.resolve({ok:!0}),b=()=>{},f={error:b,warn:b,info:b,debug:b,throw:e=>{throw"string"==typeof e?new Error(e):e},json:b,scope:()=>f},g={get push(){return m()},get command(){return m()},get elb(){return m()},logger:f},h={};t(h,{orderEvent:()=>v,postEvent:()=>w});var w={title:"POST event",description:"A GCP Cloud Function HTTP POST with a JSON body becomes a single walker elb event.",trigger:{type:"POST"},in:{method:"POST",body:{event:"page view",data:{title:"Home",url:"https://example.com/"}},headers:{"content-type":"application/json"}},out:[["elb",{name:"page view",data:{title:"Home",url:"https://example.com/"}}]]},v={title:"Order POST",description:"A Cloud Function HTTP POST carrying an order payload becomes a walker order complete event.",trigger:{type:"POST"},in:{method:"POST",body:{event:"order complete",data:{id:"ORD-700",total:99.99,currency:"EUR"}},headers:{"content-type":"application/json"}},out:[["elb",{name:"order complete",data:{id:"ORD-700",total:99.99,currency:"EUR"}}]]};import{startFlow as y}from"@walkeros/collector";var S=async e=>{let t;return{get flow(){return t},trigger:()=>async o=>{if(!t){const o=await y(e);t={collector:o.collector,elb:o.elb}}const r=function(e){for(const t of Object.values(e.sources||{}))if("cloudfunction"===t.type)return t}(t.collector);if(!r)throw new Error("CloudFunction source not found in collector — ensure it is configured in sources");const s={...o.body};s.name&&!s.event&&(s.event=s.name,delete s.name);const i=o.headers||{"content-type":"application/json"},n={method:o.method,body:s,headers:i,get:e=>i[e.toLowerCase()]};let a,c=200;const l={status:e=>(c=e,l),json:e=>(a=e,l),send:e=>(a=e,l),set:()=>l};return await r.push(n,l),{status:c,body:a}}}},k={};t(k,{SettingsSchema:()=>P,SetupSchema:()=>D,settings:()=>x,setup:()=>E});import{zodToSchema as j}from"@walkeros/core/dev";import{z as O}from"@walkeros/core/dev";var P=O.object({client:O.any().describe("Pre-configured Google Cloud Pub/Sub client (like new PubSub({ projectId })). Bypasses credentials resolution when supplied.").optional(),projectId:O.string().min(1).describe("Google Cloud Project ID (like my-gcp-project)."),subscription:O.string().min(1).describe("Pub/Sub subscription short name (like events-sub). The full resource name projects/<projectId>/subscriptions/<subscription> is built by the SDK."),topic:O.string().describe("Pub/Sub topic short name. Required when setup.createTopic is true; otherwise informational.").optional(),credentials:O.any().describe("Service account credentials as a JSON string or an object with client_email and private_key. Default: Application Default Credentials (ADC). (deprecated: use config.credentials)").optional(),apiEndpoint:O.string().describe("Override Pub/Sub API endpoint. Useful for the local emulator (like localhost:8085).").optional(),decoder:O.enum(["json","text","raw"]).describe("Decoder for the message data field. json (default) parses JSON, text decodes UTF-8, raw forwards the Buffer.").optional(),flowControl:O.object({maxMessages:O.number().describe("Maximum in-flight messages. Default: 100.").optional(),maxBytes:O.number().describe("Maximum in-flight bytes. Default: 10485760 (10 MB).").optional()}).describe("Subscriber flow control. Tightens the SDK defaults.").optional(),ackDeadline:O.number().describe("Subscriber ack deadline in seconds. Default: 60.").optional(),shutdownTimeoutMs:O.number().describe("Graceful shutdown timeout in milliseconds. Default: 30000. After this window, destroy() force-closes the subscriber.").optional(),onPushError:O.enum(["nack","ack"]).describe("Behavior when forwarding to the collector throws. nack (default) redelivers the message; ack drops it.").optional()});import{z as T}from"@walkeros/core/dev";var D=T.object({createTopic:T.boolean().describe("Create the topic if it does not exist. Requires settings.topic. Default: false (require pre-existing topic).").optional(),ackDeadlineSeconds:T.number().describe("Subscription ack deadline in seconds. Default: 60.").optional(),messageRetentionDuration:T.object({seconds:T.number().describe("Retention window in seconds. Default: project default.")}).describe("Subscription-level retention configuration.").optional(),filter:T.string().describe("Subscription filter expression. Only messages matching this filter are delivered.").optional(),deadLetterPolicy:T.object({deadLetterTopic:T.string().describe("Dead-letter topic short name."),maxDeliveryAttempts:T.number().describe("Maximum delivery attempts before forwarding to the dead-letter topic."),createDeadLetterTopic:T.boolean().describe("Auto-create the dead-letter topic if it does not exist. Default: false.").optional()}).describe("Dead-letter policy. Strongly recommended for production.").optional(),retryPolicy:T.object({minimumBackoff:T.object({seconds:T.number().describe("Minimum backoff in seconds.")}),maximumBackoff:T.object({seconds:T.number().describe("Maximum backoff in seconds.")})}).describe("Subscription retry policy.").optional(),enableMessageOrdering:T.boolean().describe("Enable message ordering on the subscription. Default: false.").optional(),labels:T.record(T.string(),T.string()).describe("Subscription labels for organization and billing.").optional(),expirationPolicy:T.object({ttl:T.object({seconds:T.number().describe("TTL in seconds. null means never expire.")}).nullable().optional()}).describe("Subscription expiration policy.").optional()}),x=j(P),E=j(D),C={};t(C,{createTrigger:()=>K,env:()=>A,step:()=>U});var A={};t(A,{push:()=>I,simulation:()=>M});var R=()=>{},J={error:R,warn:R,info:R,debug:R,throw:e=>{throw"string"==typeof e?new Error(e):e},json:R,scope:()=>J},N=()=>()=>Promise.resolve({ok:!0}),I={get push(){return N()},get command(){return N()},get elb(){return N()},logger:J},M=["PubSub"],U={};t(U,{decoderText:()=>q,malformedJson:()=>z,malformedJsonAck:()=>F,orderComplete:()=>L,pageView:()=>B});var B={title:"Page view",description:"A JSON-encoded page view event arrives on the subscription, decodes successfully, and is acked.",in:{id:"msg-1",dataString:JSON.stringify({name:"page view",data:{title:"Documentation",url:"https://example.com/docs"}}),attributes:{}},out:[["message.ack","msg-1"]]},L={title:"Order complete",description:"A JSON-encoded order event arrives and is acked after successful collector forwarding.",in:{id:"msg-2",dataString:JSON.stringify({name:"order complete",data:{id:"ORD-500",total:199.99,currency:"EUR"}}),attributes:{entity:"order",action:"complete"}},out:[["message.ack","msg-2"]]},q={title:"Text decoder",description:"With decoder=text on the source settings, the message data is forwarded to the collector as a UTF-8 string and acked.",in:{id:"msg-3",dataString:"plain text payload",attributes:{}},out:[["message.ack","msg-3"]]},z={title:"Malformed JSON nack",description:"A non-JSON body with the default json decoder fails to decode; the message is nacked for redelivery.",in:{id:"msg-4",dataString:"not-json{",attributes:{}},out:[["message.nack","msg-4"]]},F={title:"Malformed JSON ack-and-drop",description:"With onPushError=ack on the source settings, a malformed JSON message is acked-and-dropped instead of redelivered.",in:{id:"msg-5",dataString:"not-json{",attributes:{}},out:[["message.ack","msg-5"]]};import{startFlow as H}from"@walkeros/collector";function G(e){if("object"!=typeof e||null===e)return!1;const t=e;return"pubsub-pull"===t.type&&"function"==typeof t.push}var K=async e=>{let t;return{get flow(){return t},trigger:()=>async o=>{if(!t){const o=await H(e);t={collector:o.collector,elb:o.elb}}const r=function(e){for(const t of Object.values(e.sources??{}))if(G(t))return t}(t.collector);if(!r)throw new Error("pubsub-pull source not registered in collector — ensure it is configured in sources");const s={id:o.id,data:Buffer.from(o.dataString,"utf8"),attributes:o.attributes,orderingKey:o.orderingKey},i=await r.push(s),n=[];return i&&"object"==typeof i&&(i.acked&&n.push(["message.ack",o.id]),i.nacked&&n.push(["message.nack",o.id])),n}}},V={};t(V,{SettingsSchema:()=>Q,settings:()=>X});import{zodToSchema as _}from"@walkeros/core/dev";import{z as W}from"@walkeros/core/dev";var Q=W.object({projectId:W.string().describe("Google Cloud Project ID (informational, surfaced in error messages).").optional(),decoder:W.enum(["json","text","raw"]).describe("Decoder for the message data field. json (default) parses JSON, text decodes UTF-8, raw forwards the Buffer.").optional(),verifyOidc:W.boolean().describe("Verify the OIDC bearer token Pub/Sub attaches to push requests. Default: false.").optional(),audience:W.string().describe("OIDC audience (your endpoint URL or a custom audience). Required when verifyOidc is true.").optional()}),X=_(Q),Y={};t(Y,{createTrigger:()=>ue,env:()=>Z,step:()=>se});var Z={};t(Z,{push:()=>oe,simulation:()=>re});var $=()=>{},ee={error:$,warn:$,info:$,debug:$,throw:e=>{throw"string"==typeof e?new Error(e):e},json:$,scope:()=>ee},te=()=>()=>Promise.resolve({ok:!0}),oe={get push(){return te()},get command(){return te()},get elb(){return te()},logger:ee},re=[],se={};t(se,{malformedEnvelope:()=>ce,orderEnvelope:()=>ae,validEnvelope:()=>ne});function ie(e){return Buffer.from(JSON.stringify(e),"utf8").toString("base64")}var ne={title:"Valid push envelope",description:"A well-formed Pub/Sub push envelope decodes the base64 data, parses JSON, and forwards the event to the collector with a 200 response.",in:{message:{messageId:"push-1",data:ie({name:"page view",data:{title:"Documentation",url:"https://example.com/docs"}}),attributes:{source:"analytics"}},subscription:"projects/test/subscriptions/events-sub"},out:[["response",200,{success:!0,id:"push-1"}]]},ae={title:"Order envelope",description:"A push envelope carrying an order event is decoded and forwarded to the collector.",in:{message:{messageId:"push-2",data:ie({name:"order complete",data:{id:"ORD-500",total:199.99,currency:"EUR"}}),attributes:{}},subscription:"projects/test/subscriptions/events-sub"},out:[["response",200,{success:!0,id:"push-2"}]]},ce={title:"Malformed envelope",description:"A POST body lacking message.messageId returns 400 Bad Request without forwarding to the collector.",in:{not_a:"pubsub envelope"},out:[["response",400,{success:!1,error:"Malformed Pub/Sub envelope (missing message.messageId)."}]]};import{startFlow as le}from"@walkeros/collector";function de(e){if("object"!=typeof e||null===e)return!1;const t=e;return"string"==typeof t.type&&"pubsub-push"===t.type&&"function"==typeof t.push}var ue=async e=>{let t;return{get flow(){return t},trigger:(o,r)=>async o=>{if(!t){const o=await le(e);t={collector:o.collector,elb:o.elb}}const s=("object"==typeof r&&null!==r?r:{}).headers??{},i=function(e){for(const t of Object.values(e.sources??{}))if(de(t))return t}(t.collector);if(!i)throw new Error("pubsub-push source not registered");const n={},a=function(e,t){return{method:"POST",body:e,headers:t,get:e=>t[e.toLowerCase()]??t[e]}}(o,s),c=function(e){const t={status:o=>(e.statusCode=o,t),json:o=>(e.body=o,t),send:o=>(e.body=o,t),set:()=>t};return t}(n);await i.push(a,c);return[["response",n.statusCode??0,n.body??null]]}}};export{u as examples,C as pubsubPullExamples,k as pubsubPullSchemas,Y as pubsubPushExamples,V as pubsubPushSchemas,o as schemas};//# sourceMappingURL=dev.mjs.map
1
+ var e=Object.defineProperty,t=(t,o)=>{for(var r in o)e(t,r,{get:o[r],enumerable:!0})},o={};t(o,{CorsOptionsSchema:()=>c,CorsOrigin:()=>a,HttpMethod:()=>n,SettingsSchema:()=>l,settings:()=>d});import{zodToSchema as r}from"@walkeros/core/dev";import{z as s}from"@walkeros/core/dev";import{z as i}from"@walkeros/core/dev";var n=i.enum(["GET","POST","PUT","PATCH","DELETE","OPTIONS","HEAD"]),a=i.union([i.string(),i.array(i.string()),i.literal("*")]),c=i.object({origin:a.describe("Allowed origins (* for all, URL string, or array of URLs)").optional(),methods:i.array(n).describe("Allowed HTTP methods").optional(),headers:i.array(i.string()).describe("Allowed request headers").optional(),credentials:i.boolean().describe("Allow credentials (cookies, authorization headers)").optional(),maxAge:i.number().int().positive().describe("Preflight cache duration in seconds").optional()}),l=s.object({cors:s.union([s.boolean(),c]).describe("CORS configuration: false = disabled, true = allow all origins, object = custom configuration").optional(),maxBatchSize:s.number().int().min(1).describe("Maximum number of events accepted in a single batch request").default(100),enablePixelTracking:s.boolean().describe("Serve a tracking pixel for GET requests").default(!0),timeout:s.number().int().positive().max(54e4).describe("Request timeout in milliseconds (max: 540000 for GCP)").optional()}),d=r(l),u={};t(u,{createTrigger:()=>k,env:()=>p,step:()=>h});var p={};t(p,{push:()=>g});var m=()=>()=>Promise.resolve({ok:!0}),b=()=>{},f={error:b,warn:b,info:b,debug:b,throw:e=>{throw"string"==typeof e?new Error(e):e},json:b,scope:()=>f},g={get push(){return m()},get command(){return m()},get elb(){return m()},logger:f},h={};t(h,{cloudFunctionPostForwardsSource:()=>y,orderEvent:()=>v,postEvent:()=>w});var w={title:"POST event",description:"A GCP Cloud Function HTTP POST with a JSON body becomes a single walker elb event.",trigger:{type:"POST"},in:{method:"POST",body:{name:"page view",data:{title:"Home",url:"https://example.com/"}},headers:{"content-type":"application/json"}},out:[["elb",{name:"page view",data:{title:"Home",url:"https://example.com/"}}]]},v={title:"Order POST",description:"A Cloud Function HTTP POST carrying an order payload becomes a walker order complete event.",trigger:{type:"POST"},in:{method:"POST",body:{name:"order complete",data:{id:"ORD-700",total:99.99,currency:"EUR"}},headers:{"content-type":"application/json"}},out:[["elb",{name:"order complete",data:{id:"ORD-700",total:99.99,currency:"EUR"}}]]},y={title:"POST with provenance",description:"A POST body carrying a source map is forwarded in full, so release and trace provenance survive the crossing.",trigger:{type:"POST"},in:{method:"POST",body:{name:"page view",data:{title:"Home"},source:{release:{web:"r1"}}},headers:{"content-type":"application/json"}},out:[["elb",{name:"page view",data:{title:"Home"},source:{release:{web:"r1"}}}]]};import{startFlow as S}from"@walkeros/collector";var k=async e=>{let t;return{get flow(){return t},trigger:()=>async o=>{if(!t){const o=await S(e);t={collector:o.collector,elb:o.elb}}const r=function(e){for(const t of Object.values(e.sources||{}))if("cloudfunction"===t.type)return t}(t.collector);if(!r)throw new Error("CloudFunction source not found in collector — ensure it is configured in sources");const s={...o.body};s.name&&!s.event&&(s.event=s.name,delete s.name);const i=o.headers||{"content-type":"application/json"},n={method:o.method,body:s,headers:i,get:e=>i[e.toLowerCase()]};let a,c=200;const l={status:e=>(c=e,l),json:e=>(a=e,l),send:e=>(a=e,l),set:()=>l};return await r.push(n,l),{status:c,body:a}}}},P={};t(P,{SettingsSchema:()=>T,SetupSchema:()=>D,settings:()=>E,setup:()=>A});import{zodToSchema as O}from"@walkeros/core/dev";import{z as j}from"@walkeros/core/dev";var T=j.object({client:j.any().describe("Pre-configured Google Cloud Pub/Sub client (like new PubSub({ projectId })). Bypasses credentials resolution when supplied.").optional(),projectId:j.string().min(1).describe("Google Cloud Project ID (like my-gcp-project)."),subscription:j.string().min(1).describe("Pub/Sub subscription short name (like events-sub). The full resource name projects/<projectId>/subscriptions/<subscription> is built by the SDK."),topic:j.string().describe("Pub/Sub topic short name. Required when setup.createTopic is true; otherwise informational.").optional(),credentials:j.any().describe("Service account credentials as a JSON string or an object with client_email and private_key. Default: Application Default Credentials (ADC). (deprecated: use config.credentials)").optional(),apiEndpoint:j.string().describe("Override Pub/Sub API endpoint. Useful for the local emulator (like localhost:8085).").optional(),decoder:j.enum(["json","text","raw"]).describe("Decoder for the message data field. json (default) parses JSON, text decodes UTF-8, raw forwards the Buffer.").optional(),flowControl:j.object({maxMessages:j.number().describe("Maximum in-flight messages. Default: 100.").optional(),maxBytes:j.number().describe("Maximum in-flight bytes. Default: 10485760 (10 MB).").optional()}).describe("Subscriber flow control. Tightens the SDK defaults.").optional(),ackDeadline:j.number().describe("Subscriber ack deadline in seconds. Default: 60.").optional(),shutdownTimeoutMs:j.number().describe("Graceful shutdown timeout in milliseconds. Default: 30000. After this window, destroy() force-closes the subscriber.").optional(),onPushError:j.enum(["nack","ack"]).describe("Behavior when forwarding to the collector throws. nack (default) redelivers the message; ack drops it.").optional()});import{z as x}from"@walkeros/core/dev";var D=x.object({createTopic:x.boolean().describe("Create the topic if it does not exist. Requires settings.topic. Default: false (require pre-existing topic).").optional(),ackDeadlineSeconds:x.number().describe("Subscription ack deadline in seconds. Default: 60.").optional(),messageRetentionDuration:x.object({seconds:x.number().describe("Retention window in seconds. Default: project default.")}).describe("Subscription-level retention configuration.").optional(),filter:x.string().describe("Subscription filter expression. Only messages matching this filter are delivered.").optional(),deadLetterPolicy:x.object({deadLetterTopic:x.string().describe("Dead-letter topic short name."),maxDeliveryAttempts:x.number().describe("Maximum delivery attempts before forwarding to the dead-letter topic."),createDeadLetterTopic:x.boolean().describe("Auto-create the dead-letter topic if it does not exist. Default: false.").optional()}).describe("Dead-letter policy. Strongly recommended for production.").optional(),retryPolicy:x.object({minimumBackoff:x.object({seconds:x.number().describe("Minimum backoff in seconds.")}),maximumBackoff:x.object({seconds:x.number().describe("Maximum backoff in seconds.")})}).describe("Subscription retry policy.").optional(),enableMessageOrdering:x.boolean().describe("Enable message ordering on the subscription. Default: false.").optional(),labels:x.record(x.string(),x.string()).describe("Subscription labels for organization and billing.").optional(),expirationPolicy:x.object({ttl:x.object({seconds:x.number().describe("TTL in seconds. null means never expire.")}).nullable().optional()}).describe("Subscription expiration policy.").optional()}),E=O(T),A=O(D),C={};t(C,{createTrigger:()=>V,env:()=>R,step:()=>U});var R={};t(R,{push:()=>I,simulation:()=>B});var J=()=>{},M={error:J,warn:J,info:J,debug:J,throw:e=>{throw"string"==typeof e?new Error(e):e},json:J,scope:()=>M},N=()=>()=>Promise.resolve({ok:!0}),I={get push(){return N()},get command(){return N()},get elb(){return N()},logger:M},B=["PubSub"],U={};t(U,{decoderText:()=>H,malformedJson:()=>L,malformedJsonAck:()=>z,orderComplete:()=>F,pageView:()=>q});var q={title:"Page view",description:"A JSON-encoded page view event arrives on the subscription, decodes successfully, and is acked.",in:{id:"msg-1",dataString:JSON.stringify({name:"page view",data:{title:"Documentation",url:"https://example.com/docs"}}),attributes:{}},out:[["message.ack","msg-1"]]},F={title:"Order complete",description:"A JSON-encoded order event arrives and is acked after successful collector forwarding.",in:{id:"msg-2",dataString:JSON.stringify({name:"order complete",data:{id:"ORD-500",total:199.99,currency:"EUR"}}),attributes:{entity:"order",action:"complete"}},out:[["message.ack","msg-2"]]},H={title:"Text decoder",description:"With decoder=text on the source settings, the message data is forwarded to the collector as a UTF-8 string and acked.",in:{id:"msg-3",dataString:"plain text payload",attributes:{}},out:[["message.ack","msg-3"]]},L={title:"Malformed JSON nack",description:"A non-JSON body with the default json decoder fails to decode; the message is nacked for redelivery.",in:{id:"msg-4",dataString:"not-json{",attributes:{}},out:[["message.nack","msg-4"]]},z={title:"Malformed JSON ack-and-drop",description:"With onPushError=ack on the source settings, a malformed JSON message is acked-and-dropped instead of redelivered.",in:{id:"msg-5",dataString:"not-json{",attributes:{}},out:[["message.ack","msg-5"]]};import{startFlow as G}from"@walkeros/collector";function K(e){if("object"!=typeof e||null===e)return!1;const t=e;return"pubsub-pull"===t.type&&"function"==typeof t.push}var V=async e=>{let t;return{get flow(){return t},trigger:()=>async o=>{if(!t){const o=await G(e);t={collector:o.collector,elb:o.elb}}const r=function(e){for(const t of Object.values(e.sources??{}))if(K(t))return t}(t.collector);if(!r)throw new Error("pubsub-pull source not registered in collector — ensure it is configured in sources");const s={id:o.id,data:Buffer.from(o.dataString,"utf8"),attributes:o.attributes,orderingKey:o.orderingKey},i=await r.push(s),n=[];return i&&"object"==typeof i&&(i.acked&&n.push(["message.ack",o.id]),i.nacked&&n.push(["message.nack",o.id])),n}}},_={};t(_,{SettingsSchema:()=>X,settings:()=>Y});import{zodToSchema as W}from"@walkeros/core/dev";import{z as Q}from"@walkeros/core/dev";var X=Q.object({projectId:Q.string().describe("Google Cloud Project ID (informational, surfaced in error messages).").optional(),decoder:Q.enum(["json","text","raw"]).describe("Decoder for the message data field. json (default) parses JSON, text decodes UTF-8, raw forwards the Buffer.").optional(),verifyOidc:Q.boolean().describe("Verify the OIDC bearer token Pub/Sub attaches to push requests. Default: false.").optional(),audience:Q.string().describe("OIDC audience (your endpoint URL or a custom audience). Required when verifyOidc is true.").optional()}),Y=W(X),Z={};t(Z,{createTrigger:()=>pe,env:()=>$,step:()=>ie});var $={};t($,{push:()=>re,simulation:()=>se});var ee=()=>{},te={error:ee,warn:ee,info:ee,debug:ee,throw:e=>{throw"string"==typeof e?new Error(e):e},json:ee,scope:()=>te},oe=()=>()=>Promise.resolve({ok:!0}),re={get push(){return oe()},get command(){return oe()},get elb(){return oe()},logger:te},se=[],ie={};t(ie,{malformedEnvelope:()=>le,orderEnvelope:()=>ce,validEnvelope:()=>ae});function ne(e){return Buffer.from(JSON.stringify(e),"utf8").toString("base64")}var ae={title:"Valid push envelope",description:"A well-formed Pub/Sub push envelope decodes the base64 data, parses JSON, and forwards the event to the collector with a 200 response.",in:{message:{messageId:"push-1",data:ne({name:"page view",data:{title:"Documentation",url:"https://example.com/docs"}}),attributes:{source:"analytics"}},subscription:"projects/test/subscriptions/events-sub"},out:[["response",200,{success:!0,id:"push-1"}]]},ce={title:"Order envelope",description:"A push envelope carrying an order event is decoded and forwarded to the collector.",in:{message:{messageId:"push-2",data:ne({name:"order complete",data:{id:"ORD-500",total:199.99,currency:"EUR"}}),attributes:{}},subscription:"projects/test/subscriptions/events-sub"},out:[["response",200,{success:!0,id:"push-2"}]]},le={title:"Malformed envelope",description:"A POST body lacking message.messageId returns 400 Bad Request without forwarding to the collector.",in:{not_a:"pubsub envelope"},out:[["response",400,{success:!1,error:"Malformed Pub/Sub envelope (missing message.messageId)."}]]};import{startFlow as de}from"@walkeros/collector";function ue(e){if("object"!=typeof e||null===e)return!1;const t=e;return"string"==typeof t.type&&"pubsub-push"===t.type&&"function"==typeof t.push}var pe=async e=>{let t;return{get flow(){return t},trigger:(o,r)=>async o=>{if(!t){const o=await de(e);t={collector:o.collector,elb:o.elb}}const s=("object"==typeof r&&null!==r?r:{}).headers??{},i=function(e){for(const t of Object.values(e.sources??{}))if(ue(t))return t}(t.collector);if(!i)throw new Error("pubsub-push source not registered");const n={},a=function(e,t){return{method:"POST",body:e,headers:t,get:e=>t[e.toLowerCase()]??t[e]}}(o,s),c=function(e){const t={status:o=>(e.statusCode=o,t),json:o=>(e.body=o,t),send:o=>(e.body=o,t),set:()=>t};return t}(n);await i.push(a,c);return[["response",n.statusCode??0,n.body??null]]}}};export{u as examples,C as pubsubPullExamples,P as pubsubPullSchemas,Z as pubsubPushExamples,_ as pubsubPushSchemas,o as schemas};//# sourceMappingURL=dev.mjs.map